diff options
414 files changed, 8105 insertions, 4839 deletions
diff --git a/.bazelversion b/.bazelversion new file mode 100644 index 0000000000..30f6cf8d98 --- /dev/null +++ b/.bazelversion @@ -0,0 +1 @@ +0.26.1 diff --git a/.gitignore b/.gitignore index 3679a3365b..553ecac486 100644 --- a/.gitignore +++ b/.gitignore @@ -1,6 +1,9 @@ /.project /target -.DS_Store infer-out bazel-* -*~ + +# Do not add editor- and OS-specific files like *~ (Emacs) and .DS_Store +# (macOS). Instead, add them to $XDG_CONFIG_HOME/git/ignore +# (~/.config/git/ignore if $XDG_CONFIG_HOME is not set) or +# $GIT_DIR/info/exclude. See "git help gitignore" for details. @@ -4,14 +4,14 @@ load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive") http_archive( name = "bazel_skylib", - sha256 = "bbccf674aa441c266df9894182d80de104cabd19be98be002f6d478aaa31574d", - strip_prefix = "bazel-skylib-2169ae1c374aab4a09aa90e65efe1a3aad4e279b", - urls = ["https://github.com/bazelbuild/bazel-skylib/archive/2169ae1c374aab4a09aa90e65efe1a3aad4e279b.tar.gz"], + sha256 = "2ea8a5ed2b448baf4a6855d3ce049c4c452a6470b1efd1504fdb7c1c134d220a", + strip_prefix = "bazel-skylib-0.8.0", + urls = ["https://github.com/bazelbuild/bazel-skylib/archive/0.8.0.tar.gz"], ) load("@bazel_skylib//lib:versions.bzl", "versions") -versions.check(minimum_bazel_version = "0.19.0") +versions.check(minimum_bazel_version = "0.26.1") load("//tools:bazlets.bzl", "load_bazlets") @@ -59,15 +59,15 @@ maven_jar( ) maven_jar( - name = "sshd-core", - artifact = "org.apache.sshd:sshd-core:2.0.0", - sha1 = "f4275079a2463cfd2bf1548a80e1683288a8e86b", + name = "sshd-osgi", + artifact = "org.apache.sshd:sshd-osgi:2.2.0", + sha1 = "a45d48cb53678e699816e8e054e55fa33f5a4558", ) maven_jar( name = "sshd-sftp", - artifact = "org.apache.sshd:sshd-sftp:2.0.0", - sha1 = "a12d64dc2d5d23271a4dc58075e55f9c64a68494", + artifact = "org.apache.sshd:sshd-sftp:2.2.0", + sha1 = "3d011e00adf38e49bb8711a9dd762fe908a2170c", ) maven_jar( @@ -212,25 +212,25 @@ maven_jar( src_sha1 = "94e89a8c9f82e38555e95b9f7f58344a247e862c", ) -BOUNCYCASTLE_VER = "1.60" +BOUNCYCASTLE_VER = "1.61" maven_jar( - name = "bcpg-jdk15on", + name = "bcpg", artifact = "org.bouncycastle:bcpg-jdk15on:" + BOUNCYCASTLE_VER, - sha1 = "13c7a199c484127daad298996e95818478431a2c", - src_sha1 = "edcd9e86d95e39b4da39bb295efd93bc4f56266e", + sha1 = "422656435514ab8a28752b117d5d2646660a0ace", + src_sha1 = "836da34e11114cbce8fa99f54175f8f3278d1cce", ) maven_jar( - name = "bcprov-jdk15on", + name = "bcprov", artifact = "org.bouncycastle:bcprov-jdk15on:" + BOUNCYCASTLE_VER, - sha1 = "bd47ad3bd14b8e82595c7adaa143501e60842a84", - src_sha1 = "7c57a4d13fe53d9abb967bba600dd0b293dafd6a", + sha1 = "00df4b474e71be02c1349c3292d98886f888d1f7", + src_sha1 = "3bf88046a16098ea6cc41576dd50d512854d39e1", ) maven_jar( - name = "bcpkix-jdk15on", + name = "bcpkix", artifact = "org.bouncycastle:bcpkix-jdk15on:" + BOUNCYCASTLE_VER, - sha1 = "d0c46320fbc07be3a24eb13a56cee4e3d38e0c75", - src_sha1 = "a25f041293f401af08efba63ff4bbdce98134a03", + sha1 = "89bb3aa5b98b48e584eee2a7401b7682a46779b4", + src_sha1 = "a0498d09200a18737eccc05aa81bbd05c1be0f8c", ) @@ -69,14 +69,14 @@ java_library( ) java_library( - name = "sshd-core", + name = "sshd-osgi", visibility = [ "//org.eclipse.jgit.junit.ssh:__pkg__", "//org.eclipse.jgit.ssh.apache:__pkg__", "//org.eclipse.jgit.ssh.apache.test:__pkg__", "//org.eclipse.jgit.test:__pkg__", ], - exports = ["@sshd-core//jar"], + exports = ["@sshd-osgi//jar"], ) java_library( @@ -154,7 +154,7 @@ java_library( "//org.eclipse.jgit:__pkg__", "//org.eclipse.jgit.test:__pkg__", ], - exports = ["@bcpg-jdk15on//jar"], + exports = ["@bcpg//jar"], ) java_library( @@ -163,7 +163,7 @@ java_library( "//org.eclipse.jgit:__pkg__", "//org.eclipse.jgit.test:__pkg__", ], - exports = ["@bcprov-jdk15on//jar"], + exports = ["@bcprov//jar"], ) java_library( @@ -172,7 +172,7 @@ java_library( "//org.eclipse.jgit:__pkg__", "//org.eclipse.jgit.test:__pkg__", ], - exports = ["@bcpkix-jdk15on//jar"], + exports = ["@bcpkix//jar"], ) java_library( diff --git a/org.eclipse.jgit.ant.test/.settings/org.eclipse.pde.prefs b/org.eclipse.jgit.ant.test/.settings/org.eclipse.pde.prefs new file mode 100644 index 0000000000..2174e4fd5b --- /dev/null +++ b/org.eclipse.jgit.ant.test/.settings/org.eclipse.pde.prefs @@ -0,0 +1,34 @@ +compilers.f.unresolved-features=1 +compilers.f.unresolved-plugins=1 +compilers.incompatible-environment=1 +compilers.p.build=1 +compilers.p.build.bin.includes=1 +compilers.p.build.encodings=2 +compilers.p.build.java.compiler=2 +compilers.p.build.java.compliance=1 +compilers.p.build.missing.output=2 +compilers.p.build.output.library=1 +compilers.p.build.source.library=1 +compilers.p.build.src.includes=1 +compilers.p.deprecated=1 +compilers.p.discouraged-class=1 +compilers.p.internal=1 +compilers.p.missing-packages=2 +compilers.p.missing-version-export-package=2 +compilers.p.missing-version-import-package=2 +compilers.p.missing-version-require-bundle=2 +compilers.p.no-required-att=0 +compilers.p.no.automatic.module=1 +compilers.p.not-externalized-att=2 +compilers.p.service.component.without.lazyactivation=1 +compilers.p.unknown-attribute=1 +compilers.p.unknown-class=1 +compilers.p.unknown-element=1 +compilers.p.unknown-identifier=1 +compilers.p.unknown-resource=1 +compilers.p.unresolved-ex-points=0 +compilers.p.unresolved-import=0 +compilers.s.create-docs=false +compilers.s.doc-folder=doc +compilers.s.open-tags=1 +eclipse.preferences.version=1 diff --git a/org.eclipse.jgit.ant.test/META-INF/MANIFEST.MF b/org.eclipse.jgit.ant.test/META-INF/MANIFEST.MF index 708fad886e..9e38b4339b 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.3.3.qualifier +Bundle-Version: 5.4.1.qualifier Bundle-ActivationPolicy: lazy Bundle-RequiredExecutionEnvironment: JavaSE-1.8 Import-Package: org.apache.tools.ant, - org.eclipse.jgit.ant.tasks;version="[5.3.3,5.4.0)", - org.eclipse.jgit.junit;version="[5.3.3,5.4.0)", - org.eclipse.jgit.lib;version="[5.3.3,5.4.0)", - org.eclipse.jgit.util;version="[5.3.3,5.4.0)", + org.eclipse.jgit.ant.tasks;version="[5.4.1,5.5.0)", + org.eclipse.jgit.junit;version="[5.4.1,5.5.0)", + org.eclipse.jgit.lib;version="[5.4.1,5.5.0)", + org.eclipse.jgit.util;version="[5.4.1,5.5.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 b9f5fb6460..8e8208f408 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.3.3-SNAPSHOT</version> + <version>5.4.1-SNAPSHOT</version> </parent> <artifactId>org.eclipse.jgit.ant.test</artifactId> @@ -105,7 +105,7 @@ <plugin> <artifactId>maven-surefire-plugin</artifactId> <configuration> - <argLine>@{argLine} -Xmx256m -Dfile.encoding=UTF-8 -Djava.io.tmpdir=${project.build.directory}</argLine> + <argLine>@{argLine} -Xmx512m -Dfile.encoding=UTF-8 -Djava.io.tmpdir=${project.build.directory}</argLine> </configuration> </plugin> </plugins> diff --git a/org.eclipse.jgit.ant/META-INF/MANIFEST.MF b/org.eclipse.jgit.ant/META-INF/MANIFEST.MF index 804d90ce0d..15359e727d 100644 --- a/org.eclipse.jgit.ant/META-INF/MANIFEST.MF +++ b/org.eclipse.jgit.ant/META-INF/MANIFEST.MF @@ -3,11 +3,13 @@ Bundle-ManifestVersion: 2 Bundle-Name: %Bundle-Name Automatic-Module-Name: org.eclipse.jgit.ant Bundle-SymbolicName: org.eclipse.jgit.ant -Bundle-Version: 5.3.3.qualifier +Bundle-Version: 5.4.1.qualifier Bundle-RequiredExecutionEnvironment: JavaSE-1.8 Import-Package: org.apache.tools.ant, - org.eclipse.jgit.storage.file;version="[5.3.3,5.4.0)" + org.eclipse.jgit.storage.file;version="[5.4.1,5.5.0)" Bundle-Localization: plugin Bundle-Vendor: %Provider-Name -Export-Package: org.eclipse.jgit.ant.tasks;version="5.3.3"; - uses:="org.apache.tools.ant.types,org.apache.tools.ant" +Export-Package: org.eclipse.jgit.ant;version="5.4.1", + org.eclipse.jgit.ant.tasks;version="5.4.1"; + uses:="org.apache.tools.ant, + org.apache.tools.ant.types" diff --git a/org.eclipse.jgit.ant/META-INF/SOURCE-MANIFEST.MF b/org.eclipse.jgit.ant/META-INF/SOURCE-MANIFEST.MF new file mode 100644 index 0000000000..8e62fb4415 --- /dev/null +++ b/org.eclipse.jgit.ant/META-INF/SOURCE-MANIFEST.MF @@ -0,0 +1,7 @@ +Manifest-Version: 1.0 +Bundle-ManifestVersion: 2 +Bundle-Name: org.eclipse.jgit.ant - Sources +Bundle-SymbolicName: org.eclipse.jgit.ant.source +Bundle-Vendor: Eclipse.org - JGit +Bundle-Version: 5.4.1.qualifier +Eclipse-SourceBundle: org.eclipse.jgit.ant;version="5.4.1.qualifier";roots="." diff --git a/org.eclipse.jgit.ant/pom.xml b/org.eclipse.jgit.ant/pom.xml index ffbe8db63e..c7fb95aa07 100644 --- a/org.eclipse.jgit.ant/pom.xml +++ b/org.eclipse.jgit.ant/pom.xml @@ -45,62 +45,103 @@ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"> <modelVersion>4.0.0</modelVersion> - <parent> - <groupId>org.eclipse.jgit</groupId> - <artifactId>org.eclipse.jgit-parent</artifactId> - <version>5.3.3-SNAPSHOT</version> - </parent> - - <artifactId>org.eclipse.jgit.ant</artifactId> - <name>JGit - Ant Tasks</name> - - <description> - Ant based user interface for Git - </description> - - <properties> - <translate-qualifier /> - </properties> - - <dependencies> - <dependency> - <groupId>org.eclipse.jgit</groupId> - <artifactId>org.eclipse.jgit</artifactId> - <version>${project.version}</version> - </dependency> - - <dependency> - <groupId>org.apache.ant</groupId> - <artifactId>ant</artifactId> - <version>1.10.5</version> - </dependency> - </dependencies> - - <build> - <sourceDirectory>src/</sourceDirectory> - - <resources> - <resource> - <directory>.</directory> - <includes> - <include>plugin.properties</include> - <include>about.html</include> - </includes> - </resource> - <resource> - <directory>resources/</directory> - </resource> - </resources> - - <plugins> - <plugin> - <artifactId>maven-jar-plugin</artifactId> - <configuration> - <archive> - <manifestFile>${bundle-manifest}</manifestFile> - </archive> - </configuration> - </plugin> + <parent> + <groupId>org.eclipse.jgit</groupId> + <artifactId>org.eclipse.jgit-parent</artifactId> + <version>5.4.1-SNAPSHOT</version> + </parent> + + <artifactId>org.eclipse.jgit.ant</artifactId> + <name>JGit - Ant Tasks</name> + + <description>Ant based user interface for Git</description> + + <properties> + <translate-qualifier /> + <source-bundle-manifest>${project.build.directory}/META-INF/SOURCE-MANIFEST.MF</source-bundle-manifest> + </properties> + + <dependencies> + <dependency> + <groupId>org.eclipse.jgit</groupId> + <artifactId>org.eclipse.jgit</artifactId> + <version>${project.version}</version> + </dependency> + + <dependency> + <groupId>org.apache.ant</groupId> + <artifactId>ant</artifactId> + <version>1.10.5</version> + </dependency> + </dependencies> + + <build> + <sourceDirectory>src/</sourceDirectory> + + <resources> + <resource> + <directory>.</directory> + <includes> + <include>plugin.properties</include> + <include>about.html</include> + </includes> + </resource> + <resource> + <directory>resources/</directory> + </resource> + </resources> + + <plugins> + <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-antrun-plugin</artifactId> + <executions> + <execution> + <id>translate-source-qualifier</id> + <phase>generate-resources</phase> + <configuration> + <target> + <copy file="META-INF/SOURCE-MANIFEST.MF" tofile="${source-bundle-manifest}" overwrite="true"/> + <replace file="${source-bundle-manifest}"> + <replacefilter token=".qualifier" value=".${maven.build.timestamp}"/> + </replace> + </target> + </configuration> + <goals> + <goal>run</goal> + </goals> + </execution> + </executions> + </plugin> + + <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-source-plugin</artifactId> + <inherited>true</inherited> + <executions> + <execution> + <id>attach-sources</id> + <phase>process-classes</phase> + <goals> + <goal>jar</goal> + </goals> + <configuration> + <archive> + <manifestFile>${source-bundle-manifest}</manifestFile> + </archive> + </configuration> + </execution> + </executions> + </plugin> + + <plugin> + <artifactId>maven-jar-plugin</artifactId> + <configuration> + <archive> + <manifestFile>${bundle-manifest}</manifestFile> + </archive> + </configuration> + </plugin> <plugin> <groupId>com.github.siom79.japicmp</groupId> @@ -143,10 +184,10 @@ </execution> </executions> </plugin> - </plugins> - </build> + </plugins> + </build> - <reporting> + <reporting> <plugins> <plugin> <groupId>com.github.siom79.japicmp</groupId> diff --git a/org.eclipse.jgit.archive/META-INF/MANIFEST.MF b/org.eclipse.jgit.archive/META-INF/MANIFEST.MF index a172543712..0eb38eb41b 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.3.3.qualifier +Bundle-Version: 5.4.1.qualifier Bundle-Vendor: %provider_name Bundle-Localization: plugin Bundle-RequiredExecutionEnvironment: JavaSE-1.8 @@ -13,16 +13,17 @@ 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.3.3,5.4.0)", - org.eclipse.jgit.lib;version="[5.3.3,5.4.0)", - org.eclipse.jgit.nls;version="[5.3.3,5.4.0)", - org.eclipse.jgit.revwalk;version="[5.3.3,5.4.0)", - org.eclipse.jgit.util;version="[5.3.3,5.4.0)", + org.eclipse.jgit.api;version="[5.4.1,5.5.0)", + org.eclipse.jgit.lib;version="[5.4.1,5.5.0)", + org.eclipse.jgit.nls;version="[5.4.1,5.5.0)", + org.eclipse.jgit.revwalk;version="[5.4.1,5.5.0)", + org.eclipse.jgit.util;version="[5.4.1,5.5.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.3.3"; +Export-Package: org.eclipse.jgit.archive;version="5.4.1"; uses:="org.eclipse.jgit.lib, org.eclipse.jgit.api, org.apache.commons.compress.archivers, - org.osgi.framework" + org.osgi.framework", + org.eclipse.jgit.archive.internal;version="5.4.1";x-internal:=true diff --git a/org.eclipse.jgit.archive/META-INF/SOURCE-MANIFEST.MF b/org.eclipse.jgit.archive/META-INF/SOURCE-MANIFEST.MF index b1183743eb..30928f83f6 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.3.3.qualifier -Eclipse-SourceBundle: org.eclipse.jgit.archive;version="5.3.3.qualifier";roots="." +Bundle-Version: 5.4.1.qualifier +Eclipse-SourceBundle: org.eclipse.jgit.archive;version="5.4.1.qualifier";roots="." diff --git a/org.eclipse.jgit.archive/pom.xml b/org.eclipse.jgit.archive/pom.xml index 95e1e44982..a3f9520ac3 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.3.3-SNAPSHOT</version> + <version>5.4.1-SNAPSHOT</version> </parent> <artifactId>org.eclipse.jgit.archive</artifactId> @@ -64,6 +64,7 @@ <properties> <translate-qualifier/> + <source-bundle-manifest>${project.build.directory}/META-INF/SOURCE-MANIFEST.MF</source-bundle-manifest> </properties> <dependencies> @@ -99,6 +100,48 @@ <plugins> <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-antrun-plugin</artifactId> + <executions> + <execution> + <id>translate-source-qualifier</id> + <phase>generate-resources</phase> + <configuration> + <target> + <copy file="META-INF/SOURCE-MANIFEST.MF" tofile="${source-bundle-manifest}" overwrite="true"/> + <replace file="${source-bundle-manifest}"> + <replacefilter token=".qualifier" value=".${maven.build.timestamp}"/> + </replace> + </target> + </configuration> + <goals> + <goal>run</goal> + </goals> + </execution> + </executions> + </plugin> + + <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-source-plugin</artifactId> + <inherited>true</inherited> + <executions> + <execution> + <id>attach-sources</id> + <phase>process-classes</phase> + <goals> + <goal>jar</goal> + </goals> + <configuration> + <archive> + <manifestFile>${source-bundle-manifest}</manifestFile> + </archive> + </configuration> + </execution> + </executions> + </plugin> + + <plugin> <artifactId>maven-jar-plugin</artifactId> <configuration> <archive> diff --git a/org.eclipse.jgit.coverage/pom.xml b/org.eclipse.jgit.coverage/pom.xml index 0819e8ecfd..12c75527e6 100644 --- a/org.eclipse.jgit.coverage/pom.xml +++ b/org.eclipse.jgit.coverage/pom.xml @@ -5,7 +5,7 @@ <parent> <groupId>org.eclipse.jgit</groupId> <artifactId>org.eclipse.jgit-parent</artifactId> - <version>5.3.3-SNAPSHOT</version> + <version>5.4.1-SNAPSHOT</version> </parent> <modelVersion>4.0.0</modelVersion> @@ -18,88 +18,88 @@ <dependency> <groupId>org.eclipse.jgit</groupId> <artifactId>org.eclipse.jgit</artifactId> - <version>5.3.3-SNAPSHOT</version> + <version>5.4.1-SNAPSHOT</version> </dependency> <dependency> <groupId>org.eclipse.jgit</groupId> <artifactId>org.eclipse.jgit.ant</artifactId> - <version>5.3.3-SNAPSHOT</version> + <version>5.4.1-SNAPSHOT</version> </dependency> <dependency> <groupId>org.eclipse.jgit</groupId> <artifactId>org.eclipse.jgit.archive</artifactId> - <version>5.3.3-SNAPSHOT</version> + <version>5.4.1-SNAPSHOT</version> </dependency> <dependency> <groupId>org.eclipse.jgit</groupId> <artifactId>org.eclipse.jgit.http.apache</artifactId> - <version>5.3.3-SNAPSHOT</version> + <version>5.4.1-SNAPSHOT</version> </dependency> <dependency> <groupId>org.eclipse.jgit</groupId> <artifactId>org.eclipse.jgit.http.server</artifactId> - <version>5.3.3-SNAPSHOT</version> + <version>5.4.1-SNAPSHOT</version> </dependency> <dependency> <groupId>org.eclipse.jgit</groupId> <artifactId>org.eclipse.jgit.lfs</artifactId> - <version>5.3.3-SNAPSHOT</version> + <version>5.4.1-SNAPSHOT</version> </dependency> <dependency> <groupId>org.eclipse.jgit</groupId> <artifactId>org.eclipse.jgit.lfs.server</artifactId> - <version>5.3.3-SNAPSHOT</version> + <version>5.4.1-SNAPSHOT</version> </dependency> <dependency> <groupId>org.eclipse.jgit</groupId> <artifactId>org.eclipse.jgit.pgm</artifactId> - <version>5.3.3-SNAPSHOT</version> + <version>5.4.1-SNAPSHOT</version> </dependency> <dependency> <groupId>org.eclipse.jgit</groupId> <artifactId>org.eclipse.jgit.ui</artifactId> - <version>5.3.3-SNAPSHOT</version> + <version>5.4.1-SNAPSHOT</version> </dependency> <dependency> <groupId>org.eclipse.jgit</groupId> <artifactId>org.eclipse.jgit.ssh.apache</artifactId> - <version>5.3.3-SNAPSHOT</version> + <version>5.4.1-SNAPSHOT</version> </dependency> <dependency> <groupId>org.eclipse.jgit</groupId> <artifactId>org.eclipse.jgit.test</artifactId> - <version>5.3.3-SNAPSHOT</version> + <version>5.4.1-SNAPSHOT</version> </dependency> <dependency> <groupId>org.eclipse.jgit</groupId> <artifactId>org.eclipse.jgit.ant.test</artifactId> - <version>5.3.3-SNAPSHOT</version> + <version>5.4.1-SNAPSHOT</version> </dependency> <dependency> <groupId>org.eclipse.jgit</groupId> <artifactId>org.eclipse.jgit.http.test</artifactId> - <version>5.3.3-SNAPSHOT</version> + <version>5.4.1-SNAPSHOT</version> </dependency> <dependency> <groupId>org.eclipse.jgit</groupId> <artifactId>org.eclipse.jgit.pgm.test</artifactId> - <version>5.3.3-SNAPSHOT</version> + <version>5.4.1-SNAPSHOT</version> </dependency> <dependency> <groupId>org.eclipse.jgit</groupId> <artifactId>org.eclipse.jgit.lfs.test</artifactId> - <version>5.3.3-SNAPSHOT</version> + <version>5.4.1-SNAPSHOT</version> </dependency> <dependency> <groupId>org.eclipse.jgit</groupId> <artifactId>org.eclipse.jgit.lfs.server.test</artifactId> - <version>5.3.3-SNAPSHOT</version> + <version>5.4.1-SNAPSHOT</version> </dependency> <dependency> <groupId>org.eclipse.jgit</groupId> <artifactId>org.eclipse.jgit.ssh.apache.test</artifactId> - <version>5.3.3-SNAPSHOT</version> + <version>5.4.1-SNAPSHOT</version> </dependency> </dependencies> diff --git a/org.eclipse.jgit.http.apache/META-INF/MANIFEST.MF b/org.eclipse.jgit.http.apache/META-INF/MANIFEST.MF index 6905939aa4..8206e8a9d1 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.3.3.qualifier +Bundle-Version: 5.4.1.qualifier Bundle-RequiredExecutionEnvironment: JavaSE-1.8 Bundle-Localization: plugin Bundle-Vendor: %Provider-Name @@ -23,11 +23,11 @@ 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.annotations;version="[5.3.3,5.4.0)", - org.eclipse.jgit.nls;version="[5.3.3,5.4.0)", - org.eclipse.jgit.transport.http;version="[5.3.3,5.4.0)", - org.eclipse.jgit.util;version="[5.3.3,5.4.0)" -Export-Package: org.eclipse.jgit.transport.http.apache;version="5.3.3"; + org.eclipse.jgit.annotations;version="[5.4.1,5.5.0)", + org.eclipse.jgit.nls;version="[5.4.1,5.5.0)", + org.eclipse.jgit.transport.http;version="[5.4.1,5.5.0)", + org.eclipse.jgit.util;version="[5.4.1,5.5.0)" +Export-Package: org.eclipse.jgit.transport.http.apache;version="5.4.1"; uses:="org.apache.http.client, org.eclipse.jgit.transport.http, org.apache.http.entity, diff --git a/org.eclipse.jgit.http.apache/META-INF/SOURCE-MANIFEST.MF b/org.eclipse.jgit.http.apache/META-INF/SOURCE-MANIFEST.MF new file mode 100644 index 0000000000..5aeb331cb7 --- /dev/null +++ b/org.eclipse.jgit.http.apache/META-INF/SOURCE-MANIFEST.MF @@ -0,0 +1,7 @@ +Manifest-Version: 1.0 +Bundle-ManifestVersion: 2 +Bundle-Name: org.eclipse.jgit.http.apache - Sources +Bundle-SymbolicName: org.eclipse.jgit.http.apache.source +Bundle-Vendor: Eclipse.org - JGit +Bundle-Version: 5.4.1.qualifier +Eclipse-SourceBundle: org.eclipse.jgit.http.apache;version="5.4.1.qualifier";roots="." diff --git a/org.eclipse.jgit.http.apache/pom.xml b/org.eclipse.jgit.http.apache/pom.xml index c2ea27d7b6..d2665c04c8 100644 --- a/org.eclipse.jgit.http.apache/pom.xml +++ b/org.eclipse.jgit.http.apache/pom.xml @@ -45,64 +45,107 @@ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"> <modelVersion>4.0.0</modelVersion> - <parent> - <groupId>org.eclipse.jgit</groupId> - <artifactId>org.eclipse.jgit-parent</artifactId> - <version>5.3.3-SNAPSHOT</version> - </parent> + <parent> + <groupId>org.eclipse.jgit</groupId> + <artifactId>org.eclipse.jgit-parent</artifactId> + <version>5.4.1-SNAPSHOT</version> + </parent> - <artifactId>org.eclipse.jgit.http.apache</artifactId> - <name>JGit - Apache httpclient based HTTP support</name> + <artifactId>org.eclipse.jgit.http.apache</artifactId> + <name>JGit - Apache httpclient based HTTP support</name> - <description> + <description> Apache httpclient based HTTP support - </description> - - <properties> - <translate-qualifier /> - </properties> - - <dependencies> - <dependency> - <groupId>org.eclipse.jgit</groupId> - <artifactId>org.eclipse.jgit</artifactId> - <version>${project.version}</version> - </dependency> - <dependency> - <groupId>org.apache.httpcomponents</groupId> - <artifactId>httpclient</artifactId> - </dependency> - <dependency> - <groupId>org.apache.httpcomponents</groupId> - <artifactId>httpcore</artifactId> - </dependency> - </dependencies> - - <build> - <sourceDirectory>src/</sourceDirectory> - - <resources> - <resource> - <directory>.</directory> - <includes> - <include>plugin.properties</include> - <include>about.html</include> - </includes> - </resource> - <resource> - <directory>resources/</directory> - </resource> - </resources> - - <plugins> - <plugin> - <artifactId>maven-jar-plugin</artifactId> - <configuration> - <archive> - <manifestFile>${bundle-manifest}</manifestFile> - </archive> - </configuration> - </plugin> + </description> + + <properties> + <translate-qualifier /> + <source-bundle-manifest>${project.build.directory}/META-INF/SOURCE-MANIFEST.MF</source-bundle-manifest> + </properties> + + <dependencies> + <dependency> + <groupId>org.eclipse.jgit</groupId> + <artifactId>org.eclipse.jgit</artifactId> + <version>${project.version}</version> + </dependency> + <dependency> + <groupId>org.apache.httpcomponents</groupId> + <artifactId>httpclient</artifactId> + </dependency> + <dependency> + <groupId>org.apache.httpcomponents</groupId> + <artifactId>httpcore</artifactId> + </dependency> + </dependencies> + + <build> + <sourceDirectory>src/</sourceDirectory> + + <resources> + <resource> + <directory>.</directory> + <includes> + <include>plugin.properties</include> + <include>about.html</include> + </includes> + </resource> + <resource> + <directory>resources/</directory> + </resource> + </resources> + + <plugins> + <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-antrun-plugin</artifactId> + <executions> + <execution> + <id>translate-source-qualifier</id> + <phase>generate-resources</phase> + <configuration> + <target> + <copy file="META-INF/SOURCE-MANIFEST.MF" tofile="${source-bundle-manifest}" overwrite="true"/> + <replace file="${source-bundle-manifest}"> + <replacefilter token=".qualifier" value=".${maven.build.timestamp}"/> + </replace> + </target> + </configuration> + <goals> + <goal>run</goal> + </goals> + </execution> + </executions> + </plugin> + + <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-source-plugin</artifactId> + <inherited>true</inherited> + <executions> + <execution> + <id>attach-sources</id> + <phase>process-classes</phase> + <goals> + <goal>jar</goal> + </goals> + <configuration> + <archive> + <manifestFile>${source-bundle-manifest}</manifestFile> + </archive> + </configuration> + </execution> + </executions> + </plugin> + + <plugin> + <artifactId>maven-jar-plugin</artifactId> + <configuration> + <archive> + <manifestFile>${bundle-manifest}</manifestFile> + </archive> + </configuration> + </plugin> <plugin> <groupId>com.github.siom79.japicmp</groupId> @@ -145,10 +188,10 @@ </execution> </executions> </plugin> - </plugins> - </build> + </plugins> + </build> - <reporting> + <reporting> <plugins> <plugin> <groupId>com.github.siom79.japicmp</groupId> diff --git a/org.eclipse.jgit.http.server/META-INF/MANIFEST.MF b/org.eclipse.jgit.http.server/META-INF/MANIFEST.MF index 18910618b7..a231f58282 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.3.3.qualifier +Bundle-Version: 5.4.1.qualifier Bundle-Localization: plugin Bundle-Vendor: %provider_name -Export-Package: org.eclipse.jgit.http.server;version="5.3.3", - org.eclipse.jgit.http.server.glue;version="5.3.3"; +Export-Package: org.eclipse.jgit.http.server;version="5.4.1", + org.eclipse.jgit.http.server.glue;version="5.4.1"; uses:="javax.servlet,javax.servlet.http", - org.eclipse.jgit.http.server.resolver;version="5.3.3"; + org.eclipse.jgit.http.server.resolver;version="5.4.1"; uses:="org.eclipse.jgit.transport.resolver, org.eclipse.jgit.lib, org.eclipse.jgit.transport, @@ -18,13 +18,13 @@ 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.3.3,5.4.0)", - org.eclipse.jgit.internal.storage.dfs;version="[5.3.3,5.4.0)", - org.eclipse.jgit.internal.storage.file;version="[5.3.3,5.4.0)", - org.eclipse.jgit.internal.transport.parser;version="[5.3.3,5.4.0)", - org.eclipse.jgit.lib;version="[5.3.3,5.4.0)", - org.eclipse.jgit.nls;version="[5.3.3,5.4.0)", - org.eclipse.jgit.revwalk;version="[5.3.3,5.4.0)", - org.eclipse.jgit.transport;version="[5.3.3,5.4.0)", - org.eclipse.jgit.transport.resolver;version="[5.3.3,5.4.0)", - org.eclipse.jgit.util;version="[5.3.3,5.4.0)" + org.eclipse.jgit.errors;version="[5.4.1,5.5.0)", + org.eclipse.jgit.internal.storage.dfs;version="[5.4.1,5.5.0)", + org.eclipse.jgit.internal.storage.file;version="[5.4.1,5.5.0)", + org.eclipse.jgit.internal.transport.parser;version="[5.4.1,5.5.0)", + org.eclipse.jgit.lib;version="[5.4.1,5.5.0)", + org.eclipse.jgit.nls;version="[5.4.1,5.5.0)", + org.eclipse.jgit.revwalk;version="[5.4.1,5.5.0)", + org.eclipse.jgit.transport;version="[5.4.1,5.5.0)", + org.eclipse.jgit.transport.resolver;version="[5.4.1,5.5.0)", + org.eclipse.jgit.util;version="[5.4.1,5.5.0)" diff --git a/org.eclipse.jgit.http.server/META-INF/SOURCE-MANIFEST.MF b/org.eclipse.jgit.http.server/META-INF/SOURCE-MANIFEST.MF new file mode 100644 index 0000000000..3a0655288f --- /dev/null +++ b/org.eclipse.jgit.http.server/META-INF/SOURCE-MANIFEST.MF @@ -0,0 +1,7 @@ +Manifest-Version: 1.0 +Bundle-ManifestVersion: 2 +Bundle-Name: org.eclipse.jgit.http.server - Sources +Bundle-SymbolicName: org.eclipse.jgit.http.server.source +Bundle-Vendor: Eclipse.org - JGit +Bundle-Version: 5.4.1.qualifier +Eclipse-SourceBundle: org.eclipse.jgit.http.server;version="5.4.1.qualifier";roots="." diff --git a/org.eclipse.jgit.http.server/pom.xml b/org.eclipse.jgit.http.server/pom.xml index 6aff14f450..f795038602 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.3.3-SNAPSHOT</version> + <version>5.4.1-SNAPSHOT</version> </parent> <artifactId>org.eclipse.jgit.http.server</artifactId> @@ -64,6 +64,7 @@ <properties> <translate-qualifier/> + <source-bundle-manifest>${project.build.directory}/META-INF/SOURCE-MANIFEST.MF</source-bundle-manifest> </properties> <dependencies> @@ -99,6 +100,28 @@ <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-antrun-plugin</artifactId> + <executions> + <execution> + <id>translate-source-qualifier</id> + <phase>generate-resources</phase> + <configuration> + <target> + <copy file="META-INF/SOURCE-MANIFEST.MF" tofile="${source-bundle-manifest}" overwrite="true"/> + <replace file="${source-bundle-manifest}"> + <replacefilter token=".qualifier" value=".${maven.build.timestamp}"/> + </replace> + </target> + </configuration> + <goals> + <goal>run</goal> + </goals> + </execution> + </executions> + </plugin> + + <plugin> + <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-source-plugin</artifactId> <inherited>true</inherited> <executions> diff --git a/org.eclipse.jgit.http.server/src/org/eclipse/jgit/http/server/GitFilter.java b/org.eclipse.jgit.http.server/src/org/eclipse/jgit/http/server/GitFilter.java index 2ebe1b7d2f..51de8abd0e 100644 --- a/org.eclipse.jgit.http.server/src/org/eclipse/jgit/http/server/GitFilter.java +++ b/org.eclipse.jgit.http.server/src/org/eclipse/jgit/http/server/GitFilter.java @@ -202,7 +202,7 @@ public class GitFilter extends MetaFilter { if (resolver == null) { File root = getFile(filterConfig, "base-path"); boolean exportAll = getBoolean(filterConfig, "export-all"); - setRepositoryResolver(new FileResolver<HttpServletRequest>(root, exportAll)); + setRepositoryResolver(new FileResolver<>(root, exportAll)); } initialized = true; diff --git a/org.eclipse.jgit.http.server/src/org/eclipse/jgit/http/server/ServletUtils.java b/org.eclipse.jgit.http.server/src/org/eclipse/jgit/http/server/ServletUtils.java index b6d73b5591..256279bfed 100644 --- a/org.eclipse.jgit.http.server/src/org/eclipse/jgit/http/server/ServletUtils.java +++ b/org.eclipse.jgit.http.server/src/org/eclipse/jgit/http/server/ServletUtils.java @@ -64,7 +64,6 @@ import javax.servlet.ServletRequest; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; -import org.eclipse.jgit.internal.storage.dfs.DfsRepository; import org.eclipse.jgit.lib.Constants; import org.eclipse.jgit.lib.ObjectId; import org.eclipse.jgit.lib.Repository; @@ -276,12 +275,11 @@ public final class ServletUtils { } static String identify(Repository git) { - if (git instanceof DfsRepository) { - return ((DfsRepository) git).getDescription().getRepositoryName(); - } else if (git.getDirectory() != null) { - return git.getDirectory().getPath(); + String identifier = git.getIdentifier(); + if (identifier == null) { + return "unknown"; } - return "unknown"; + return identifier; } private ServletUtils() { diff --git a/org.eclipse.jgit.http.server/src/org/eclipse/jgit/http/server/glue/MetaServlet.java b/org.eclipse.jgit.http.server/src/org/eclipse/jgit/http/server/glue/MetaServlet.java index d8fa712ebf..14b6506ad3 100644 --- a/org.eclipse.jgit.http.server/src/org/eclipse/jgit/http/server/glue/MetaServlet.java +++ b/org.eclipse.jgit.http.server/src/org/eclipse/jgit/http/server/glue/MetaServlet.java @@ -47,7 +47,6 @@ import static javax.servlet.http.HttpServletResponse.SC_NOT_FOUND; import java.io.IOException; -import javax.servlet.FilterChain; import javax.servlet.ServletConfig; import javax.servlet.ServletContext; import javax.servlet.ServletException; @@ -140,14 +139,10 @@ public class MetaServlet extends HttpServlet { @Override protected void service(HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException { - filter.doFilter(req, res, new FilterChain() { - @Override - public void doFilter(ServletRequest request, - ServletResponse response) throws IOException, - ServletException { - ((HttpServletResponse) response).sendError(SC_NOT_FOUND); - } - }); + filter.doFilter(req, res, + (ServletRequest request, ServletResponse response) -> { + ((HttpServletResponse) response).sendError(SC_NOT_FOUND); + }); } /** diff --git a/org.eclipse.jgit.http.test/.settings/org.eclipse.pde.prefs b/org.eclipse.jgit.http.test/.settings/org.eclipse.pde.prefs new file mode 100644 index 0000000000..2174e4fd5b --- /dev/null +++ b/org.eclipse.jgit.http.test/.settings/org.eclipse.pde.prefs @@ -0,0 +1,34 @@ +compilers.f.unresolved-features=1 +compilers.f.unresolved-plugins=1 +compilers.incompatible-environment=1 +compilers.p.build=1 +compilers.p.build.bin.includes=1 +compilers.p.build.encodings=2 +compilers.p.build.java.compiler=2 +compilers.p.build.java.compliance=1 +compilers.p.build.missing.output=2 +compilers.p.build.output.library=1 +compilers.p.build.source.library=1 +compilers.p.build.src.includes=1 +compilers.p.deprecated=1 +compilers.p.discouraged-class=1 +compilers.p.internal=1 +compilers.p.missing-packages=2 +compilers.p.missing-version-export-package=2 +compilers.p.missing-version-import-package=2 +compilers.p.missing-version-require-bundle=2 +compilers.p.no-required-att=0 +compilers.p.no.automatic.module=1 +compilers.p.not-externalized-att=2 +compilers.p.service.component.without.lazyactivation=1 +compilers.p.unknown-attribute=1 +compilers.p.unknown-class=1 +compilers.p.unknown-element=1 +compilers.p.unknown-identifier=1 +compilers.p.unknown-resource=1 +compilers.p.unresolved-ex-points=0 +compilers.p.unresolved-import=0 +compilers.s.create-docs=false +compilers.s.doc-folder=doc +compilers.s.open-tags=1 +eclipse.preferences.version=1 diff --git a/org.eclipse.jgit.http.test/META-INF/MANIFEST.MF b/org.eclipse.jgit.http.test/META-INF/MANIFEST.MF index 40e7c2952c..4d4b3e4606 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.3.3.qualifier +Bundle-Version: 5.4.1.qualifier Bundle-Vendor: %provider_name Bundle-Localization: plugin Bundle-RequiredExecutionEnvironment: JavaSE-1.8 @@ -28,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.3.3,5.4.0)", - org.eclipse.jgit.http.server;version="[5.3.3,5.4.0)", - org.eclipse.jgit.http.server.glue;version="[5.3.3,5.4.0)", - org.eclipse.jgit.http.server.resolver;version="[5.3.3,5.4.0)", - org.eclipse.jgit.internal;version="[5.3.3,5.4.0)", - org.eclipse.jgit.internal.storage.dfs;version="[5.3.3,5.4.0)", - org.eclipse.jgit.internal.storage.file;version="[5.3.3,5.4.0)", - org.eclipse.jgit.internal.storage.reftable;version="[5.3.3,5.4.0)", - org.eclipse.jgit.junit;version="[5.3.3,5.4.0)", - org.eclipse.jgit.junit.http;version="[5.3.3,5.4.0)", - org.eclipse.jgit.lib;version="[5.3.3,5.4.0)", - org.eclipse.jgit.nls;version="[5.3.3,5.4.0)", - org.eclipse.jgit.revwalk;version="[5.3.3,5.4.0)", - org.eclipse.jgit.storage.file;version="[5.3.3,5.4.0)", - org.eclipse.jgit.transport;version="[5.3.3,5.4.0)", - org.eclipse.jgit.transport.http;version="[5.3.3,5.4.0)", - org.eclipse.jgit.transport.http.apache;version="[5.3.3,5.4.0)", - org.eclipse.jgit.transport.resolver;version="[5.3.3,5.4.0)", - org.eclipse.jgit.util;version="[5.3.3,5.4.0)", + org.eclipse.jgit.errors;version="[5.4.1,5.5.0)", + org.eclipse.jgit.http.server;version="[5.4.1,5.5.0)", + org.eclipse.jgit.http.server.glue;version="[5.4.1,5.5.0)", + org.eclipse.jgit.http.server.resolver;version="[5.4.1,5.5.0)", + org.eclipse.jgit.internal;version="[5.4.1,5.5.0)", + org.eclipse.jgit.internal.storage.dfs;version="[5.4.1,5.5.0)", + org.eclipse.jgit.internal.storage.file;version="[5.4.1,5.5.0)", + org.eclipse.jgit.internal.storage.reftable;version="[5.4.1,5.5.0)", + org.eclipse.jgit.junit;version="[5.4.1,5.5.0)", + org.eclipse.jgit.junit.http;version="[5.4.1,5.5.0)", + org.eclipse.jgit.lib;version="[5.4.1,5.5.0)", + org.eclipse.jgit.nls;version="[5.4.1,5.5.0)", + org.eclipse.jgit.revwalk;version="[5.4.1,5.5.0)", + org.eclipse.jgit.storage.file;version="[5.4.1,5.5.0)", + org.eclipse.jgit.transport;version="[5.4.1,5.5.0)", + org.eclipse.jgit.transport.http;version="[5.4.1,5.5.0)", + org.eclipse.jgit.transport.http.apache;version="[5.4.1,5.5.0)", + org.eclipse.jgit.transport.resolver;version="[5.4.1,5.5.0)", + org.eclipse.jgit.util;version="[5.4.1,5.5.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 fbd583e3ff..df99448f22 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.3.3-SNAPSHOT</version> + <version>5.4.1-SNAPSHOT</version> </parent> <artifactId>org.eclipse.jgit.http.test</artifactId> @@ -139,7 +139,7 @@ <plugin> <artifactId>maven-surefire-plugin</artifactId> <configuration> - <argLine>@{argLine} -Djava.io.tmpdir=${project.build.directory} -Xmx300m</argLine> + <argLine>@{argLine} -Djava.io.tmpdir=${project.build.directory} -Xmx512m</argLine> <includes> <include>**/*Test.java</include> <include>**/*Tests.java</include> diff --git a/org.eclipse.jgit.http.test/tst/org/eclipse/jgit/http/test/AdvertiseErrorTest.java b/org.eclipse.jgit.http.test/tst/org/eclipse/jgit/http/test/AdvertiseErrorTest.java index 5a46967766..ec9ced0f70 100644 --- a/org.eclipse.jgit.http.test/tst/org/eclipse/jgit/http/test/AdvertiseErrorTest.java +++ b/org.eclipse.jgit.http.test/tst/org/eclipse/jgit/http/test/AdvertiseErrorTest.java @@ -69,7 +69,6 @@ import org.eclipse.jgit.transport.ReceivePack; import org.eclipse.jgit.transport.RemoteRefUpdate; import org.eclipse.jgit.transport.Transport; import org.eclipse.jgit.transport.URIish; -import org.eclipse.jgit.transport.resolver.RepositoryResolver; import org.eclipse.jgit.transport.resolver.ServiceNotAuthorizedException; import org.eclipse.jgit.transport.resolver.ServiceNotEnabledException; import org.junit.Before; @@ -90,18 +89,13 @@ public class AdvertiseErrorTest extends HttpTestCase { ServletContextHandler app = server.addContext("/git"); GitServlet gs = new GitServlet(); - gs.setRepositoryResolver(new RepositoryResolver<HttpServletRequest>() { - @Override - public Repository open(HttpServletRequest req, String name) - throws RepositoryNotFoundException, - ServiceNotEnabledException { - if (!name.equals(srcName)) - throw new RepositoryNotFoundException(name); - - final Repository db = src.getRepository(); - db.incrementOpen(); - return db; + gs.setRepositoryResolver((HttpServletRequest req, String name) -> { + if (!name.equals(srcName)) { + throw new RepositoryNotFoundException(name); } + final Repository db = src.getRepository(); + db.incrementOpen(); + return db; }); gs.setReceivePackFactory(new DefaultReceivePackFactory() { @Override diff --git a/org.eclipse.jgit.http.test/tst/org/eclipse/jgit/http/test/GitServletResponseTests.java b/org.eclipse.jgit.http.test/tst/org/eclipse/jgit/http/test/GitServletResponseTests.java index 8dce98beef..eb19365074 100644 --- a/org.eclipse.jgit.http.test/tst/org/eclipse/jgit/http/test/GitServletResponseTests.java +++ b/org.eclipse.jgit.http.test/tst/org/eclipse/jgit/http/test/GitServletResponseTests.java @@ -75,7 +75,6 @@ import org.eclipse.jgit.transport.ReceivePack; import org.eclipse.jgit.transport.RemoteRefUpdate; import org.eclipse.jgit.transport.Transport; import org.eclipse.jgit.transport.URIish; -import org.eclipse.jgit.transport.resolver.RepositoryResolver; import org.eclipse.jgit.transport.resolver.ServiceNotAuthorizedException; import org.eclipse.jgit.transport.resolver.ServiceNotEnabledException; import org.junit.Before; @@ -117,18 +116,13 @@ public class GitServletResponseTests extends HttpTestCase { ServletContextHandler app = server.addContext("/git"); gs = new GitServlet(); - gs.setRepositoryResolver(new RepositoryResolver<HttpServletRequest>() { - @Override - public Repository open(HttpServletRequest req, String name) - throws RepositoryNotFoundException, - ServiceNotEnabledException { - if (!name.equals(repoName)) - throw new RepositoryNotFoundException(name); - - final Repository db = srv.getRepository(); - db.incrementOpen(); - return db; + gs.setRepositoryResolver((HttpServletRequest req, String name) -> { + if (!name.equals(repoName)) { + throw new RepositoryNotFoundException(name); } + final Repository db = srv.getRepository(); + db.incrementOpen(); + return db; }); gs.setReceivePackFactory(new DefaultReceivePackFactory() { @Override @@ -179,12 +173,8 @@ public class GitServletResponseTests extends HttpTestCase { maxPackSize = 0; postHook = null; - preHook = new PreReceiveHook() { - @Override - public void onPreReceive(ReceivePack rp, - Collection<ReceiveCommand> commands) { - throw new IllegalStateException(); - } + preHook = (ReceivePack rp, Collection<ReceiveCommand> commands) -> { + throw new IllegalStateException(); }; try (Transport t = Transport.open(clientRepo, srvURI)) { @@ -263,15 +253,11 @@ public class GitServletResponseTests extends HttpTestCase { maxPackSize = 100; // this PostReceiveHook when called after an unsuccesfull unpack will // lead to an IllegalStateException - postHook = new PostReceiveHook() { - @Override - public void onPostReceive(ReceivePack rp, - Collection<ReceiveCommand> commands) { - // the maxPackSize setting caused that the packfile couldn't be - // saved to disk. Calling getPackSize() now will lead to a - // IllegalStateException. - rp.getPackSize(); - } + postHook = (ReceivePack rp, Collection<ReceiveCommand> commands) -> { + // the maxPackSize setting caused that the packfile couldn't be + // saved to disk. Calling getPackSize() now will lead to a + // IllegalStateException. + rp.getPackSize(); }; try (Transport t = Transport.open(clientRepo, srvURI)) { diff --git a/org.eclipse.jgit.http.test/tst/org/eclipse/jgit/http/test/HookMessageTest.java b/org.eclipse.jgit.http.test/tst/org/eclipse/jgit/http/test/HookMessageTest.java index 5a5ff1a8ae..49ff51a5b1 100644 --- a/org.eclipse.jgit.http.test/tst/org/eclipse/jgit/http/test/HookMessageTest.java +++ b/org.eclipse.jgit.http.test/tst/org/eclipse/jgit/http/test/HookMessageTest.java @@ -70,14 +70,12 @@ import org.eclipse.jgit.lib.Repository; import org.eclipse.jgit.lib.StoredConfig; import org.eclipse.jgit.revwalk.RevBlob; import org.eclipse.jgit.revwalk.RevCommit; -import org.eclipse.jgit.transport.PreReceiveHook; import org.eclipse.jgit.transport.PushResult; import org.eclipse.jgit.transport.ReceiveCommand; import org.eclipse.jgit.transport.ReceivePack; import org.eclipse.jgit.transport.RemoteRefUpdate; import org.eclipse.jgit.transport.Transport; import org.eclipse.jgit.transport.URIish; -import org.eclipse.jgit.transport.resolver.RepositoryResolver; import org.eclipse.jgit.transport.resolver.ServiceNotAuthorizedException; import org.eclipse.jgit.transport.resolver.ServiceNotEnabledException; import org.junit.Before; @@ -98,18 +96,13 @@ public class HookMessageTest extends HttpTestCase { ServletContextHandler app = server.addContext("/git"); GitServlet gs = new GitServlet(); - gs.setRepositoryResolver(new RepositoryResolver<HttpServletRequest>() { - @Override - public Repository open(HttpServletRequest req, String name) - throws RepositoryNotFoundException, - ServiceNotEnabledException { - if (!name.equals(srcName)) - throw new RepositoryNotFoundException(name); - - final Repository db = src.getRepository(); - db.incrementOpen(); - return db; + gs.setRepositoryResolver((HttpServletRequest req, String name) -> { + if (!name.equals(srcName)) { + throw new RepositoryNotFoundException(name); } + final Repository db = src.getRepository(); + db.incrementOpen(); + return db; }); gs.setReceivePackFactory(new DefaultReceivePackFactory() { @Override @@ -117,14 +110,11 @@ public class HookMessageTest extends HttpTestCase { throws ServiceNotEnabledException, ServiceNotAuthorizedException { ReceivePack recv = super.create(req, db); - recv.setPreReceiveHook(new PreReceiveHook() { - @Override - public void onPreReceive(ReceivePack rp, - Collection<ReceiveCommand> commands) { - rp.sendMessage("message line 1"); - rp.sendError("no soup for you!"); - rp.sendMessage("come back next year!"); - } + recv.setPreReceiveHook((ReceivePack rp, + Collection<ReceiveCommand> commands) -> { + rp.sendMessage("message line 1"); + rp.sendError("no soup for you!"); + rp.sendMessage("come back next year!"); }); return recv; } 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 53626b1b2e..8ec2f51cff 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 @@ -44,7 +44,6 @@ package org.eclipse.jgit.http.test; import static org.hamcrest.Matchers.is; -import static org.hamcrest.Matchers.theInstance; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertNotNull; @@ -87,8 +86,6 @@ import org.eclipse.jgit.transport.URIish; import org.eclipse.jgit.transport.UsernamePasswordCredentialsProvider; import org.eclipse.jgit.transport.http.HttpConnection; import org.eclipse.jgit.transport.http.JDKHttpConnectionFactory; -import org.eclipse.jgit.transport.resolver.RepositoryResolver; -import org.eclipse.jgit.transport.resolver.ServiceNotEnabledException; import org.junit.Before; import org.junit.Test; @@ -141,18 +138,13 @@ public class HttpClientTests extends HttpTestCase { private ServletContextHandler smart(String path) { GitServlet gs = new GitServlet(); - gs.setRepositoryResolver(new RepositoryResolver<HttpServletRequest>() { - @Override - public Repository open(HttpServletRequest req, String name) - throws RepositoryNotFoundException, - ServiceNotEnabledException { - final Repository db = remoteRepository.getRepository(); - if (!name.equals(nameOf(db))) - throw new RepositoryNotFoundException(name); - - db.incrementOpen(); - return db; + gs.setRepositoryResolver((HttpServletRequest req, String name) -> { + final Repository db = remoteRepository.getRepository(); + if (!name.equals(nameOf(db))) { + throw new RepositoryNotFoundException(name); } + db.incrementOpen(); + return db; }); ServletContextHandler ctx = server.addContext(path); @@ -373,7 +365,7 @@ public class HttpClientTests extends HttpTestCase { // Check that we get a v0 response. assertThat(pckIn.readString(), is("# service=git-upload-pack")); - assertThat(pckIn.readString(), theInstance(PacketLineIn.END)); + assertTrue(PacketLineIn.isEnd(pckIn.readString())); assertTrue(pckIn.readString().matches("[0-9a-f]{40} HEAD.*")); } @@ -395,8 +387,7 @@ public class HttpClientTests extends HttpTestCase { // What remains are capabilities - ensure that all of them are // non-empty strings, and that we see END at the end. - String s; - while ((s = pckIn.readString()) != PacketLineIn.END) { + for (String s : pckIn.readStrings()) { assertTrue(!s.isEmpty()); } } @@ -429,8 +420,7 @@ public class HttpClientTests extends HttpTestCase { PacketLineIn pckIn = new PacketLineIn(c.getInputStream()); // Just check that we get what looks like a ref advertisement. - String s; - while ((s = pckIn.readString()) != PacketLineIn.END) { + for (String s : pckIn.readStrings()) { assertTrue(s.matches("[0-9a-f]{40} [A-Za-z/]*")); } diff --git a/org.eclipse.jgit.http.test/tst/org/eclipse/jgit/http/test/MeasurePackSizeTest.java b/org.eclipse.jgit.http.test/tst/org/eclipse/jgit/http/test/MeasurePackSizeTest.java index 0415bcbb55..79df5a2ab2 100644 --- a/org.eclipse.jgit.http.test/tst/org/eclipse/jgit/http/test/MeasurePackSizeTest.java +++ b/org.eclipse.jgit.http.test/tst/org/eclipse/jgit/http/test/MeasurePackSizeTest.java @@ -63,14 +63,12 @@ import org.eclipse.jgit.lib.Repository; import org.eclipse.jgit.lib.StoredConfig; import org.eclipse.jgit.revwalk.RevBlob; import org.eclipse.jgit.revwalk.RevCommit; -import org.eclipse.jgit.transport.PostReceiveHook; import org.eclipse.jgit.transport.PushResult; import org.eclipse.jgit.transport.ReceiveCommand; import org.eclipse.jgit.transport.ReceivePack; import org.eclipse.jgit.transport.RemoteRefUpdate; import org.eclipse.jgit.transport.Transport; import org.eclipse.jgit.transport.URIish; -import org.eclipse.jgit.transport.resolver.RepositoryResolver; import org.eclipse.jgit.transport.resolver.ServiceNotAuthorizedException; import org.eclipse.jgit.transport.resolver.ServiceNotEnabledException; import org.junit.Before; @@ -93,18 +91,13 @@ public class MeasurePackSizeTest extends HttpTestCase { ServletContextHandler app = server.addContext("/git"); GitServlet gs = new GitServlet(); - gs.setRepositoryResolver(new RepositoryResolver<HttpServletRequest>() { - @Override - public Repository open(HttpServletRequest req, String name) - throws RepositoryNotFoundException, - ServiceNotEnabledException { - if (!name.equals(srcName)) - throw new RepositoryNotFoundException(name); - - final Repository db = src.getRepository(); - db.incrementOpen(); - return db; + gs.setRepositoryResolver((HttpServletRequest req, String name) -> { + if (!name.equals(srcName)) { + throw new RepositoryNotFoundException(name); } + final Repository db = src.getRepository(); + db.incrementOpen(); + return db; }); gs.setReceivePackFactory(new DefaultReceivePackFactory() { @Override @@ -112,13 +105,9 @@ public class MeasurePackSizeTest extends HttpTestCase { throws ServiceNotEnabledException, ServiceNotAuthorizedException { ReceivePack recv = super.create(req, db); - recv.setPostReceiveHook(new PostReceiveHook() { - - @Override - public void onPostReceive(ReceivePack rp, - Collection<ReceiveCommand> commands) { - packSize = rp.getPackSize(); - } + recv.setPostReceiveHook((ReceivePack rp, + Collection<ReceiveCommand> commands) -> { + packSize = rp.getPackSize(); }); return recv; } diff --git a/org.eclipse.jgit.http.test/tst/org/eclipse/jgit/http/test/ProtocolErrorTest.java b/org.eclipse.jgit.http.test/tst/org/eclipse/jgit/http/test/ProtocolErrorTest.java index a1baae3b26..6a3d8829bb 100644 --- a/org.eclipse.jgit.http.test/tst/org/eclipse/jgit/http/test/ProtocolErrorTest.java +++ b/org.eclipse.jgit.http.test/tst/org/eclipse/jgit/http/test/ProtocolErrorTest.java @@ -44,7 +44,7 @@ package org.eclipse.jgit.http.test; import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertSame; +import static org.junit.Assert.assertTrue; import java.io.ByteArrayOutputStream; import java.io.IOException; @@ -71,8 +71,6 @@ import org.eclipse.jgit.revwalk.RevBlob; import org.eclipse.jgit.transport.PacketLineIn; import org.eclipse.jgit.transport.PacketLineOut; import org.eclipse.jgit.transport.URIish; -import org.eclipse.jgit.transport.resolver.RepositoryResolver; -import org.eclipse.jgit.transport.resolver.ServiceNotEnabledException; import org.eclipse.jgit.util.NB; import org.junit.Before; import org.junit.Test; @@ -94,18 +92,13 @@ public class ProtocolErrorTest extends HttpTestCase { ServletContextHandler app = server.addContext("/git"); GitServlet gs = new GitServlet(); - gs.setRepositoryResolver(new RepositoryResolver<HttpServletRequest>() { - @Override - public Repository open(HttpServletRequest req, String name) - throws RepositoryNotFoundException, - ServiceNotEnabledException { - if (!name.equals(srcName)) - throw new RepositoryNotFoundException(name); - - final Repository db = src.getRepository(); - db.incrementOpen(); - return db; + gs.setRepositoryResolver((HttpServletRequest req, String name) -> { + if (!name.equals(srcName)) { + throw new RepositoryNotFoundException(name); } + final Repository db = src.getRepository(); + db.incrementOpen(); + return db; }); app.addServlet(new ServletHolder(gs), "/*"); @@ -164,7 +157,7 @@ public class ProtocolErrorTest extends HttpTestCase { pckin.readString()); assertEquals("ng refs/objects/A n/a (unpacker error)", pckin.readString()); - assertSame(PacketLineIn.END, pckin.readString()); + assertTrue(PacketLineIn.isEnd(pckin.readString())); } } finally { c.disconnect(); 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 017e2c7aa3..8b85bef305 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 @@ -123,9 +123,6 @@ import org.eclipse.jgit.transport.UsernamePasswordCredentialsProvider; import org.eclipse.jgit.transport.http.HttpConnectionFactory; import org.eclipse.jgit.transport.http.JDKHttpConnectionFactory; import org.eclipse.jgit.transport.http.apache.HttpClientConnectionFactory; -import org.eclipse.jgit.transport.resolver.ServiceNotAuthorizedException; -import org.eclipse.jgit.transport.resolver.ServiceNotEnabledException; -import org.eclipse.jgit.transport.resolver.UploadPackFactory; import org.eclipse.jgit.util.HttpSupport; import org.eclipse.jgit.util.SystemReader; import org.hamcrest.Matchers; @@ -190,18 +187,13 @@ public class SmartClientSmartServerTest extends HttpTestCase { ConfigConstants.CONFIG_KEY_LOGALLREFUPDATES, true); GitServlet gs = new GitServlet(); - gs.setUploadPackFactory(new UploadPackFactory<HttpServletRequest>() { - @Override - public UploadPack create(HttpServletRequest req, Repository db) - throws ServiceNotEnabledException, - ServiceNotAuthorizedException { - DefaultUploadPackFactory f = new DefaultUploadPackFactory(); - UploadPack up = f.create(req, db); - if (advertiseRefsHook != null) { - up.setAdvertiseRefsHook(advertiseRefsHook); - } - return up; + gs.setUploadPackFactory((HttpServletRequest req, Repository db) -> { + DefaultUploadPackFactory f = new DefaultUploadPackFactory(); + UploadPack up = f.create(req, db); + if (advertiseRefsHook != null) { + up.setAdvertiseRefsHook(advertiseRefsHook); } + return up; }); ServletContextHandler app = addNormalContext(gs, src, srcName); diff --git a/org.eclipse.jgit.junit.http/META-INF/MANIFEST.MF b/org.eclipse.jgit.junit.http/META-INF/MANIFEST.MF index c8b48dc197..ba38a8b656 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.3.3.qualifier +Bundle-Version: 5.4.1.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.3.3,5.4.0)", - org.eclipse.jgit.http.server;version="[5.3.3,5.4.0)", - org.eclipse.jgit.internal.storage.file;version="[5.3.3,5.4.0)", - org.eclipse.jgit.junit;version="[5.3.3,5.4.0)", - org.eclipse.jgit.lib;version="[5.3.3,5.4.0)", - org.eclipse.jgit.revwalk;version="[5.3.3,5.4.0)", - org.eclipse.jgit.transport;version="[5.3.3,5.4.0)", - org.eclipse.jgit.transport.resolver;version="[5.3.3,5.4.0)", + org.eclipse.jgit.errors;version="[5.4.1,5.5.0)", + org.eclipse.jgit.http.server;version="[5.4.1,5.5.0)", + org.eclipse.jgit.internal.storage.file;version="[5.4.1,5.5.0)", + org.eclipse.jgit.junit;version="[5.4.1,5.5.0)", + org.eclipse.jgit.lib;version="[5.4.1,5.5.0)", + org.eclipse.jgit.revwalk;version="[5.4.1,5.5.0)", + org.eclipse.jgit.transport;version="[5.4.1,5.5.0)", + org.eclipse.jgit.transport.resolver;version="[5.4.1,5.5.0)", org.junit;version="[4.12,5.0.0)" -Export-Package: org.eclipse.jgit.junit.http;version="5.3.3"; +Export-Package: org.eclipse.jgit.junit.http;version="5.4.1"; uses:="org.eclipse.jgit.transport, org.eclipse.jgit.junit, javax.servlet.http, diff --git a/org.eclipse.jgit.junit.http/META-INF/SOURCE-MANIFEST.MF b/org.eclipse.jgit.junit.http/META-INF/SOURCE-MANIFEST.MF new file mode 100644 index 0000000000..0243f2f691 --- /dev/null +++ b/org.eclipse.jgit.junit.http/META-INF/SOURCE-MANIFEST.MF @@ -0,0 +1,7 @@ +Manifest-Version: 1.0 +Bundle-ManifestVersion: 2 +Bundle-Name: org.eclipse.jgit.junit.http - Sources +Bundle-SymbolicName: org.eclipse.jgit.junit.http.source +Bundle-Vendor: Eclipse.org - JGit +Bundle-Version: 5.4.1.qualifier +Eclipse-SourceBundle: org.eclipse.jgit.junit.http;version="5.4.1.qualifier";roots="." diff --git a/org.eclipse.jgit.junit.http/pom.xml b/org.eclipse.jgit.junit.http/pom.xml index 9c984c0533..9bf2a2156f 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.3.3-SNAPSHOT</version> + <version>5.4.1-SNAPSHOT</version> </parent> <artifactId>org.eclipse.jgit.junit.http</artifactId> @@ -62,6 +62,7 @@ <properties> <translate-qualifier/> + <source-bundle-manifest>${project.build.directory}/META-INF/SOURCE-MANIFEST.MF</source-bundle-manifest> </properties> <dependencies> @@ -109,6 +110,48 @@ <plugins> <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-antrun-plugin</artifactId> + <executions> + <execution> + <id>translate-source-qualifier</id> + <phase>generate-resources</phase> + <configuration> + <target> + <copy file="META-INF/SOURCE-MANIFEST.MF" tofile="${source-bundle-manifest}" overwrite="true"/> + <replace file="${source-bundle-manifest}"> + <replacefilter token=".qualifier" value=".${maven.build.timestamp}"/> + </replace> + </target> + </configuration> + <goals> + <goal>run</goal> + </goals> + </execution> + </executions> + </plugin> + + <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-source-plugin</artifactId> + <inherited>true</inherited> + <executions> + <execution> + <id>attach-sources</id> + <phase>process-classes</phase> + <goals> + <goal>jar</goal> + </goals> + <configuration> + <archive> + <manifestFile>${source-bundle-manifest}</manifestFile> + </archive> + </configuration> + </execution> + </executions> + </plugin> + + <plugin> <artifactId>maven-jar-plugin</artifactId> <configuration> <archive> diff --git a/org.eclipse.jgit.junit.http/src/org/eclipse/jgit/junit/http/SimpleHttpServer.java b/org.eclipse.jgit.junit.http/src/org/eclipse/jgit/junit/http/SimpleHttpServer.java index 245b510fe1..7c78330828 100644 --- a/org.eclipse.jgit.junit.http/src/org/eclipse/jgit/junit/http/SimpleHttpServer.java +++ b/org.eclipse.jgit.junit.http/src/org/eclipse/jgit/junit/http/SimpleHttpServer.java @@ -54,8 +54,6 @@ import org.eclipse.jgit.errors.RepositoryNotFoundException; import org.eclipse.jgit.http.server.GitServlet; import org.eclipse.jgit.lib.Repository; import org.eclipse.jgit.transport.URIish; -import org.eclipse.jgit.transport.resolver.RepositoryResolver; -import org.eclipse.jgit.transport.resolver.ServiceNotEnabledException; /** * Simple http server for testing http access to Git repositories. @@ -136,17 +134,12 @@ public class SimpleHttpServer { private ServletContextHandler smart(String path) { GitServlet gs = new GitServlet(); - gs.setRepositoryResolver(new RepositoryResolver<HttpServletRequest>() { - @Override - public Repository open(HttpServletRequest req, String name) - throws RepositoryNotFoundException, - ServiceNotEnabledException { - if (!name.equals(nameOf(db))) - throw new RepositoryNotFoundException(name); - - db.incrementOpen(); - return db; + gs.setRepositoryResolver((HttpServletRequest req, String name) -> { + if (!name.equals(nameOf(db))) { + throw new RepositoryNotFoundException(name); } + db.incrementOpen(); + return db; }); ServletContextHandler ctx = server.addContext(path); diff --git a/org.eclipse.jgit.junit.ssh/BUILD b/org.eclipse.jgit.junit.ssh/BUILD index e9a04c7173..8c17cb7238 100644 --- a/org.eclipse.jgit.junit.ssh/BUILD +++ b/org.eclipse.jgit.junit.ssh/BUILD @@ -7,7 +7,7 @@ java_library( resource_strip_prefix = "org.eclipse.jgit.junit.ssh/resources", resources = glob(["resources/**"]), deps = [ - "//lib:sshd-core", + "//lib:sshd-osgi", "//lib:sshd-sftp", # We want these deps to be provided_deps "//org.eclipse.jgit:jgit", diff --git a/org.eclipse.jgit.junit.ssh/META-INF/MANIFEST.MF b/org.eclipse.jgit.junit.ssh/META-INF/MANIFEST.MF index ed11de9997..6b443f374c 100644 --- a/org.eclipse.jgit.junit.ssh/META-INF/MANIFEST.MF +++ b/org.eclipse.jgit.junit.ssh/META-INF/MANIFEST.MF @@ -3,34 +3,35 @@ Bundle-ManifestVersion: 2 Bundle-Name: %plugin_name Automatic-Module-Name: org.eclipse.jgit.junit.ssh Bundle-SymbolicName: org.eclipse.jgit.junit.ssh -Bundle-Version: 5.3.3.qualifier +Bundle-Version: 5.4.1.qualifier Bundle-Localization: plugin Bundle-Vendor: %provider_name Bundle-ActivationPolicy: lazy Bundle-RequiredExecutionEnvironment: JavaSE-1.8 -Import-Package: org.apache.sshd.common;version="[2.0.0,2.1.0)", - org.apache.sshd.common.config.keys;version="[2.0.0,2.1.0)", - org.apache.sshd.common.file.virtualfs;version="[2.0.0,2.1.0)", - org.apache.sshd.common.helpers;version="[2.0.0,2.1.0)", - org.apache.sshd.common.io;version="[2.0.0,2.1.0)", - org.apache.sshd.common.kex;version="[2.0.0,2.1.0)", - org.apache.sshd.common.keyprovider;version="[2.0.0,2.1.0)", - org.apache.sshd.common.session;version="[2.0.0,2.1.0)", - org.apache.sshd.common.util.buffer;version="[2.0.0,2.1.0)", - org.apache.sshd.common.util.logging;version="[2.0.0,2.1.0)", - org.apache.sshd.common.util.security;version="[2.0.0,2.1.0)", - org.apache.sshd.server;version="[2.0.0,2.1.0)", - org.apache.sshd.server.auth;version="[2.0.0,2.1.0)", - org.apache.sshd.server.auth.gss;version="[2.0.0,2.1.0)", - org.apache.sshd.server.auth.keyboard;version="[2.0.0,2.1.0)", - org.apache.sshd.server.auth.password;version="[2.0.0,2.1.0)", - org.apache.sshd.server.command;version="[2.0.0,2.1.0)", - org.apache.sshd.server.session;version="[2.0.0,2.1.0)", - org.apache.sshd.server.shell;version="[2.0.0,2.1.0)", - org.apache.sshd.server.subsystem;version="[2.0.0,2.1.0)", - org.apache.sshd.server.subsystem.sftp;version="[2.0.0,2.1.0)", - org.eclipse.jgit.annotations;version="[5.3.3,5.4.0)", - org.eclipse.jgit.lib;version="[5.3.3,5.4.0)", - org.eclipse.jgit.transport;version="[5.3.3,5.4.0)", +Import-Package: org.apache.sshd.common;version="[2.2.0,2.3.0)", + org.apache.sshd.common.config.keys;version="[2.2.0,2.3.0)", + org.apache.sshd.common.file.virtualfs;version="[2.2.0,2.3.0)", + org.apache.sshd.common.helpers;version="[2.2.0,2.3.0)", + org.apache.sshd.common.io;version="[2.2.0,2.3.0)", + org.apache.sshd.common.kex;version="[2.2.0,2.3.0)", + org.apache.sshd.common.keyprovider;version="[2.2.0,2.3.0)", + org.apache.sshd.common.session;version="[2.2.0,2.3.0)", + org.apache.sshd.common.util.buffer;version="[2.2.0,2.3.0)", + org.apache.sshd.common.util.logging;version="[2.2.0,2.3.0)", + org.apache.sshd.common.util.security;version="[2.2.0,2.3.0)", + org.apache.sshd.common.util.threads;version="[2.2.0,2.3.0)", + org.apache.sshd.server;version="[2.2.0,2.3.0)", + org.apache.sshd.server.auth;version="[2.2.0,2.3.0)", + org.apache.sshd.server.auth.gss;version="[2.2.0,2.3.0)", + org.apache.sshd.server.auth.keyboard;version="[2.2.0,2.3.0)", + org.apache.sshd.server.auth.password;version="[2.2.0,2.3.0)", + org.apache.sshd.server.command;version="[2.2.0,2.3.0)", + org.apache.sshd.server.session;version="[2.2.0,2.3.0)", + org.apache.sshd.server.shell;version="[2.2.0,2.3.0)", + org.apache.sshd.server.subsystem;version="[2.2.0,2.3.0)", + org.apache.sshd.server.subsystem.sftp;version="[2.2.0,2.3.0)", + org.eclipse.jgit.annotations;version="[5.4.1,5.5.0)", + org.eclipse.jgit.lib;version="[5.4.1,5.5.0)", + org.eclipse.jgit.transport;version="[5.4.1,5.5.0)", org.slf4j;version="[1.7.0,2.0.0)" -Export-Package: org.eclipse.jgit.junit.ssh;version="5.3.3" +Export-Package: org.eclipse.jgit.junit.ssh;version="5.4.1" diff --git a/org.eclipse.jgit.junit.ssh/META-INF/SOURCE-MANIFEST.MF b/org.eclipse.jgit.junit.ssh/META-INF/SOURCE-MANIFEST.MF new file mode 100644 index 0000000000..62fb41b023 --- /dev/null +++ b/org.eclipse.jgit.junit.ssh/META-INF/SOURCE-MANIFEST.MF @@ -0,0 +1,7 @@ +Manifest-Version: 1.0 +Bundle-ManifestVersion: 2 +Bundle-Name: org.eclipse.jgit.junit.ssh - Sources +Bundle-SymbolicName: org.eclipse.jgit.junit.ssh.source +Bundle-Vendor: Eclipse.org - JGit +Bundle-Version: 5.4.1.qualifier +Eclipse-SourceBundle: org.eclipse.jgit.junit.ssh;version="5.4.1.qualifier";roots="." diff --git a/org.eclipse.jgit.junit.ssh/pom.xml b/org.eclipse.jgit.junit.ssh/pom.xml index 0194faa74b..92fd1615c1 100644 --- a/org.eclipse.jgit.junit.ssh/pom.xml +++ b/org.eclipse.jgit.junit.ssh/pom.xml @@ -50,7 +50,7 @@ <parent> <groupId>org.eclipse.jgit</groupId> <artifactId>org.eclipse.jgit-parent</artifactId> - <version>5.3.3-SNAPSHOT</version> + <version>5.4.1-SNAPSHOT</version> </parent> <artifactId>org.eclipse.jgit.junit.ssh</artifactId> @@ -62,6 +62,7 @@ <properties> <translate-qualifier/> + <source-bundle-manifest>${project.build.directory}/META-INF/SOURCE-MANIFEST.MF</source-bundle-manifest> </properties> <dependencies> @@ -73,7 +74,7 @@ <dependency> <groupId>org.apache.sshd</groupId> - <artifactId>sshd-core</artifactId> + <artifactId>sshd-osgi</artifactId> <version>${apache-sshd-version}</version> </dependency> @@ -104,6 +105,48 @@ <plugins> <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-antrun-plugin</artifactId> + <executions> + <execution> + <id>translate-source-qualifier</id> + <phase>generate-resources</phase> + <configuration> + <target> + <copy file="META-INF/SOURCE-MANIFEST.MF" tofile="${source-bundle-manifest}" overwrite="true"/> + <replace file="${source-bundle-manifest}"> + <replacefilter token=".qualifier" value=".${maven.build.timestamp}"/> + </replace> + </target> + </configuration> + <goals> + <goal>run</goal> + </goals> + </execution> + </executions> + </plugin> + + <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-source-plugin</artifactId> + <inherited>true</inherited> + <executions> + <execution> + <id>attach-sources</id> + <phase>process-classes</phase> + <goals> + <goal>jar</goal> + </goals> + <configuration> + <archive> + <manifestFile>${source-bundle-manifest}</manifestFile> + </archive> + </configuration> + </execution> + </executions> + </plugin> + + <plugin> <artifactId>maven-jar-plugin</artifactId> <configuration> <archive> diff --git a/org.eclipse.jgit.junit.ssh/src/org/eclipse/jgit/junit/ssh/SshTestGitServer.java b/org.eclipse.jgit.junit.ssh/src/org/eclipse/jgit/junit/ssh/SshTestGitServer.java index f5af2e5ce1..25d952f189 100644 --- a/org.eclipse.jgit.junit.ssh/src/org/eclipse/jgit/junit/ssh/SshTestGitServer.java +++ b/org.eclipse.jgit.junit.ssh/src/org/eclipse/jgit/junit/ssh/SshTestGitServer.java @@ -55,10 +55,9 @@ import java.util.ArrayList; import java.util.Collections; import java.util.List; import java.util.Locale; -import java.util.concurrent.ExecutorService; -import java.util.concurrent.Executors; import org.apache.sshd.common.NamedFactory; +import org.apache.sshd.common.NamedResource; import org.apache.sshd.common.SshConstants; import org.apache.sshd.common.config.keys.AuthorizedKeyEntry; import org.apache.sshd.common.config.keys.KeyUtils; @@ -67,6 +66,8 @@ import org.apache.sshd.common.file.virtualfs.VirtualFileSystemFactory; import org.apache.sshd.common.session.Session; import org.apache.sshd.common.util.buffer.Buffer; import org.apache.sshd.common.util.security.SecurityUtils; +import org.apache.sshd.common.util.threads.CloseableExecutorService; +import org.apache.sshd.common.util.threads.ThreadUtils; import org.apache.sshd.server.ServerAuthenticationManager; import org.apache.sshd.server.SshServer; import org.apache.sshd.server.auth.UserAuth; @@ -110,8 +111,8 @@ public class SshTestGitServer { @NonNull protected PublicKey testKey; - private final ExecutorService executorService = Executors - .newFixedThreadPool(2); + private final CloseableExecutorService executorService = ThreadUtils + .newFixedThreadPool("SshTestGitServerPool", 2); /** * Creates a ssh git <em>test</em> server. It serves one single repository, @@ -138,11 +139,12 @@ public class SshTestGitServer { server = SshServer.setUpDefaultServer(); // Set host key try (ByteArrayInputStream in = new ByteArrayInputStream(hostKey)) { - hostKeys.add(SecurityUtils.loadKeyPairIdentity("", in, null)); + SecurityUtils.loadKeyPairIdentities(null, null, in, null) + .forEach((k) -> hostKeys.add(k)); } catch (IOException | GeneralSecurityException e) { // Ignore. } - server.setKeyPairProvider(() -> hostKeys); + server.setKeyPairProvider((session) -> hostKeys); configureAuthentication(); @@ -276,8 +278,10 @@ public class SshTestGitServer { public void addHostKey(@NonNull Path key, boolean inFront) throws IOException, GeneralSecurityException { try (InputStream in = Files.newInputStream(key)) { - KeyPair pair = SecurityUtils.loadKeyPairIdentity(key.toString(), in, - null); + KeyPair pair = SecurityUtils + .loadKeyPairIdentities(null, + NamedResource.ofName(key.toString()), in, null) + .iterator().next(); if (inFront) { hostKeys.add(0, pair); } else { @@ -335,14 +339,14 @@ public class SshTestGitServer { public void setTestUserPublicKey(Path key) throws IOException, GeneralSecurityException { this.testKey = AuthorizedKeyEntry.readAuthorizedKeys(key).get(0) - .resolvePublicKey(PublicKeyEntryResolver.IGNORING); + .resolvePublicKey(null, PublicKeyEntryResolver.IGNORING); } private class GitUploadPackCommand extends AbstractCommandSupport { protected GitUploadPackCommand(String command, - ExecutorService executorService) { - super(command, executorService, false); + CloseableExecutorService executorService) { + super(command, ThreadUtils.noClose(executorService)); } @Override @@ -370,8 +374,8 @@ public class SshTestGitServer { private class GitReceivePackCommand extends AbstractCommandSupport { protected GitReceivePackCommand(String command, - ExecutorService executorService) { - super(command, executorService, false); + CloseableExecutorService executorService) { + super(command, ThreadUtils.noClose(executorService)); } @Override diff --git a/org.eclipse.jgit.junit/META-INF/MANIFEST.MF b/org.eclipse.jgit.junit/META-INF/MANIFEST.MF index a104bc1218..637fad0180 100644 --- a/org.eclipse.jgit.junit/META-INF/MANIFEST.MF +++ b/org.eclipse.jgit.junit/META-INF/MANIFEST.MF @@ -3,34 +3,34 @@ Bundle-ManifestVersion: 2 Bundle-Name: %plugin_name Automatic-Module-Name: org.eclipse.jgit.junit Bundle-SymbolicName: org.eclipse.jgit.junit -Bundle-Version: 5.3.3.qualifier +Bundle-Version: 5.4.1.qualifier Bundle-Localization: plugin Bundle-Vendor: %provider_name Bundle-ActivationPolicy: lazy Bundle-RequiredExecutionEnvironment: JavaSE-1.8 -Import-Package: org.eclipse.jgit.annotations;version="[5.3.3,5.4.0)", - org.eclipse.jgit.api;version="[5.3.3,5.4.0)", - org.eclipse.jgit.api.errors;version="[5.3.3,5.4.0)", - org.eclipse.jgit.dircache;version="[5.3.3,5.4.0)", - org.eclipse.jgit.errors;version="[5.3.3,5.4.0)", - org.eclipse.jgit.internal.storage.file;version="[5.3.3,5.4.0)", - org.eclipse.jgit.internal.storage.pack;version="[5.3.3,5.4.0)", - org.eclipse.jgit.lib;version="[5.3.3,5.4.0)", - org.eclipse.jgit.merge;version="[5.3.3,5.4.0)", - org.eclipse.jgit.revwalk;version="[5.3.3,5.4.0)", - org.eclipse.jgit.storage.file;version="[5.3.3,5.4.0)", - org.eclipse.jgit.transport;version="5.3.3", - org.eclipse.jgit.treewalk;version="[5.3.3,5.4.0)", - org.eclipse.jgit.treewalk.filter;version="[5.3.3,5.4.0)", - org.eclipse.jgit.util;version="[5.3.3,5.4.0)", - org.eclipse.jgit.util.io;version="[5.3.3,5.4.0)", - org.eclipse.jgit.util.time;version="[5.3.3,5.4.0)", +Import-Package: org.eclipse.jgit.annotations;version="[5.4.1,5.5.0)", + org.eclipse.jgit.api;version="[5.4.1,5.5.0)", + org.eclipse.jgit.api.errors;version="[5.4.1,5.5.0)", + org.eclipse.jgit.dircache;version="[5.4.1,5.5.0)", + org.eclipse.jgit.errors;version="[5.4.1,5.5.0)", + org.eclipse.jgit.internal.storage.file;version="[5.4.1,5.5.0)", + org.eclipse.jgit.internal.storage.pack;version="[5.4.1,5.5.0)", + org.eclipse.jgit.lib;version="[5.4.1,5.5.0)", + org.eclipse.jgit.merge;version="[5.4.1,5.5.0)", + org.eclipse.jgit.revwalk;version="[5.4.1,5.5.0)", + org.eclipse.jgit.storage.file;version="[5.4.1,5.5.0)", + org.eclipse.jgit.transport;version="5.4.1", + org.eclipse.jgit.treewalk;version="[5.4.1,5.5.0)", + org.eclipse.jgit.treewalk.filter;version="[5.4.1,5.5.0)", + org.eclipse.jgit.util;version="[5.4.1,5.5.0)", + org.eclipse.jgit.util.io;version="[5.4.1,5.5.0)", + org.eclipse.jgit.util.time;version="[5.4.1,5.5.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)", org.slf4j;version="[1.7.0,2.0.0)" -Export-Package: org.eclipse.jgit.junit;version="5.3.3"; +Export-Package: org.eclipse.jgit.junit;version="5.4.1"; uses:="org.eclipse.jgit.dircache, org.eclipse.jgit.lib, org.eclipse.jgit.revwalk, @@ -43,4 +43,4 @@ Export-Package: org.eclipse.jgit.junit;version="5.3.3"; org.junit.runners.model, org.junit.runner, org.eclipse.jgit.util.time", - org.eclipse.jgit.junit.time;version="5.3.3";uses:="org.eclipse.jgit.util.time" + org.eclipse.jgit.junit.time;version="5.4.1";uses:="org.eclipse.jgit.util.time" diff --git a/org.eclipse.jgit.junit/META-INF/SOURCE-MANIFEST.MF b/org.eclipse.jgit.junit/META-INF/SOURCE-MANIFEST.MF new file mode 100644 index 0000000000..f244ece298 --- /dev/null +++ b/org.eclipse.jgit.junit/META-INF/SOURCE-MANIFEST.MF @@ -0,0 +1,7 @@ +Manifest-Version: 1.0 +Bundle-ManifestVersion: 2 +Bundle-Name: org.eclipse.jgit.junit - Sources +Bundle-SymbolicName: org.eclipse.jgit.junit.source +Bundle-Vendor: Eclipse.org - JGit +Bundle-Version: 5.4.1.qualifier +Eclipse-SourceBundle: org.eclipse.jgit.junit;version="5.4.1.qualifier";roots="." diff --git a/org.eclipse.jgit.junit/pom.xml b/org.eclipse.jgit.junit/pom.xml index e67a9cdc3d..392fd5142d 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.3.3-SNAPSHOT</version> + <version>5.4.1-SNAPSHOT</version> </parent> <artifactId>org.eclipse.jgit.junit</artifactId> @@ -64,6 +64,7 @@ <properties> <translate-qualifier/> + <source-bundle-manifest>${project.build.directory}/META-INF/SOURCE-MANIFEST.MF</source-bundle-manifest> </properties> <dependencies> @@ -94,6 +95,48 @@ <plugins> <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-antrun-plugin</artifactId> + <executions> + <execution> + <id>translate-source-qualifier</id> + <phase>generate-resources</phase> + <configuration> + <target> + <copy file="META-INF/SOURCE-MANIFEST.MF" tofile="${source-bundle-manifest}" overwrite="true"/> + <replace file="${source-bundle-manifest}"> + <replacefilter token=".qualifier" value=".${maven.build.timestamp}"/> + </replace> + </target> + </configuration> + <goals> + <goal>run</goal> + </goals> + </execution> + </executions> + </plugin> + + <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-source-plugin</artifactId> + <inherited>true</inherited> + <executions> + <execution> + <id>attach-sources</id> + <phase>process-classes</phase> + <goals> + <goal>jar</goal> + </goals> + <configuration> + <archive> + <manifestFile>${source-bundle-manifest}</manifestFile> + </archive> + </configuration> + </execution> + </executions> + </plugin> + + <plugin> <artifactId>maven-jar-plugin</artifactId> <configuration> <archive> 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 3b7cdde496..5c2cd6ac65 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 @@ -373,7 +373,9 @@ public abstract class LocalDiskRepositoryTestCase { /** * Creates a new empty bare repository. * - * @return the newly created repository, opened for access + * @return the newly created bare repository, opened for access. The + * repository will not be closed in {@link #tearDown()}; the caller + * is responsible for closing it. * @throws IOException * the repository could not be created in the temporary area */ @@ -384,7 +386,9 @@ public abstract class LocalDiskRepositoryTestCase { /** * Creates a new empty repository within a new empty working directory. * - * @return the newly created repository, opened for access + * @return the newly created repository, opened for access. The repository + * will not be closed in {@link #tearDown()}; the caller is + * responsible for closing it. * @throws IOException * the repository could not be created in the temporary area */ @@ -398,7 +402,9 @@ public abstract class LocalDiskRepositoryTestCase { * @param bare * true to create a bare repository; false to make a repository * within its working directory - * @return the newly created repository, opened for access + * @return the newly created repository, opened for access. The repository + * will not be closed in {@link #tearDown()}; the caller is + * responsible for closing it. * @throws IOException * the repository could not be created in the temporary area * @since 5.3 @@ -555,13 +561,7 @@ public abstract class LocalDiskRepositoryTestCase { try { write(f, body); return f; - } catch (Error e) { - f.delete(); - throw e; - } catch (RuntimeException e) { - f.delete(); - throw e; - } catch (IOException e) { + } catch (Error | RuntimeException | IOException e) { f.delete(); throw e; } diff --git a/org.eclipse.jgit.junit/src/org/eclipse/jgit/junit/MockSystemReader.java b/org.eclipse.jgit.junit/src/org/eclipse/jgit/junit/MockSystemReader.java index 123fdb305f..13c2932282 100644 --- a/org.eclipse.jgit.junit/src/org/eclipse/jgit/junit/MockSystemReader.java +++ b/org.eclipse.jgit.junit/src/org/eclipse/jgit/junit/MockSystemReader.java @@ -220,22 +220,20 @@ public class MockSystemReader extends SystemReader { /** {@inheritDoc} */ @Override public MonotonicClock getClock() { - return new MonotonicClock() { - @Override - public ProposedTimestamp propose() { - long t = getCurrentTime(); - return new ProposedTimestamp() { - @Override - public long read(TimeUnit unit) { - return unit.convert(t, TimeUnit.MILLISECONDS); - } - - @Override - public void blockUntil(Duration maxWait) { - // Do not wait. - } - }; - } + return () -> { + long t = getCurrentTime(); + return new ProposedTimestamp() { + + @Override + public long read(TimeUnit unit) { + return unit.convert(t, TimeUnit.MILLISECONDS); + } + + @Override + public void blockUntil(Duration maxWait) { + // Do not wait. + } + }; }; } 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 5aacbbadec..23f49a4752 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 @@ -496,9 +496,7 @@ public abstract class RepositoryTestCase extends LocalDiskRepositoryTestCase { git.branchCreate().setName(branch).setStartPoint(commit).call(); return commit; - } catch (IOException e) { - throw new RuntimeException(e); - } catch (GitAPIException e) { + } catch (IOException | GitAPIException e) { throw new RuntimeException(e); } } 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 02ffe4f409..e89cf0fb83 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 @@ -728,7 +728,7 @@ public class TestRepository<R extends Repository> implements AutoCloseable { ThreeWayMerger merger = MergeStrategy.RECURSIVE.newMerger(db, true); merger.setBase(parent.getTree()); if (merger.merge(head, commit)) { - if (AnyObjectId.equals(head.getTree(), merger.getResultTreeId())) + if (AnyObjectId.isEqual(head.getTree(), merger.getResultTreeId())) return null; tick(1); org.eclipse.jgit.lib.CommitBuilder b = @@ -1368,7 +1368,7 @@ public class TestRepository<R extends Repository> implements AutoCloseable { firstParentId = parents.get(0); ObjectId cid; - if (changeId.equals("")) + if (changeId.isEmpty()) cid = ChangeIdUtil.computeChangeId(c.getTreeId(), firstParentId, c.getAuthor(), c.getCommitter(), message); else diff --git a/org.eclipse.jgit.lfs.server.test/.settings/org.eclipse.pde.prefs b/org.eclipse.jgit.lfs.server.test/.settings/org.eclipse.pde.prefs new file mode 100644 index 0000000000..2174e4fd5b --- /dev/null +++ b/org.eclipse.jgit.lfs.server.test/.settings/org.eclipse.pde.prefs @@ -0,0 +1,34 @@ +compilers.f.unresolved-features=1 +compilers.f.unresolved-plugins=1 +compilers.incompatible-environment=1 +compilers.p.build=1 +compilers.p.build.bin.includes=1 +compilers.p.build.encodings=2 +compilers.p.build.java.compiler=2 +compilers.p.build.java.compliance=1 +compilers.p.build.missing.output=2 +compilers.p.build.output.library=1 +compilers.p.build.source.library=1 +compilers.p.build.src.includes=1 +compilers.p.deprecated=1 +compilers.p.discouraged-class=1 +compilers.p.internal=1 +compilers.p.missing-packages=2 +compilers.p.missing-version-export-package=2 +compilers.p.missing-version-import-package=2 +compilers.p.missing-version-require-bundle=2 +compilers.p.no-required-att=0 +compilers.p.no.automatic.module=1 +compilers.p.not-externalized-att=2 +compilers.p.service.component.without.lazyactivation=1 +compilers.p.unknown-attribute=1 +compilers.p.unknown-class=1 +compilers.p.unknown-element=1 +compilers.p.unknown-identifier=1 +compilers.p.unknown-resource=1 +compilers.p.unresolved-ex-points=0 +compilers.p.unresolved-import=0 +compilers.s.create-docs=false +compilers.s.doc-folder=doc +compilers.s.open-tags=1 +eclipse.preferences.version=1 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 4bef1de931..d5bf494448 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.3.3.qualifier +Bundle-Version: 5.4.1.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.3.3,5.4.0)", - org.eclipse.jgit.api.errors;version="[5.3.3,5.4.0)", - org.eclipse.jgit.internal.storage.file;version="[5.3.3,5.4.0)", - org.eclipse.jgit.junit;version="[5.3.3,5.4.0)", - org.eclipse.jgit.junit.http;version="[5.3.3,5.4.0)", - org.eclipse.jgit.lfs;version="[5.3.3,5.4.0)", - org.eclipse.jgit.lfs.errors;version="[5.3.3,5.4.0)", - org.eclipse.jgit.lfs.lib;version="[5.3.3,5.4.0)", - org.eclipse.jgit.lfs.server;version="[5.3.3,5.4.0)", - org.eclipse.jgit.lfs.server.fs;version="[5.3.3,5.4.0)", - org.eclipse.jgit.lfs.test;version="[5.3.3,5.4.0)", - org.eclipse.jgit.lib;version="[5.3.3,5.4.0)", - org.eclipse.jgit.revwalk;version="[5.3.3,5.4.0)", - org.eclipse.jgit.storage.file;version="[5.3.3,5.4.0)", - org.eclipse.jgit.transport;version="[5.3.3,5.4.0)", - org.eclipse.jgit.treewalk;version="[5.3.3,5.4.0)", - org.eclipse.jgit.treewalk.filter;version="[5.3.3,5.4.0)", - org.eclipse.jgit.util;version="[5.3.3,5.4.0)", + org.eclipse.jgit.api;version="[5.4.1,5.5.0)", + org.eclipse.jgit.api.errors;version="[5.4.1,5.5.0)", + org.eclipse.jgit.internal.storage.file;version="[5.4.1,5.5.0)", + org.eclipse.jgit.junit;version="[5.4.1,5.5.0)", + org.eclipse.jgit.junit.http;version="[5.4.1,5.5.0)", + org.eclipse.jgit.lfs;version="[5.4.1,5.5.0)", + org.eclipse.jgit.lfs.errors;version="[5.4.1,5.5.0)", + org.eclipse.jgit.lfs.lib;version="[5.4.1,5.5.0)", + org.eclipse.jgit.lfs.server;version="[5.4.1,5.5.0)", + org.eclipse.jgit.lfs.server.fs;version="[5.4.1,5.5.0)", + org.eclipse.jgit.lfs.test;version="[5.4.1,5.5.0)", + org.eclipse.jgit.lib;version="[5.4.1,5.5.0)", + org.eclipse.jgit.revwalk;version="[5.4.1,5.5.0)", + org.eclipse.jgit.storage.file;version="[5.4.1,5.5.0)", + org.eclipse.jgit.transport;version="[5.4.1,5.5.0)", + org.eclipse.jgit.treewalk;version="[5.4.1,5.5.0)", + org.eclipse.jgit.treewalk.filter;version="[5.4.1,5.5.0)", + org.eclipse.jgit.util;version="[5.4.1,5.5.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 44f166b2c7..7194449b09 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.3.3-SNAPSHOT</version> + <version>5.4.1-SNAPSHOT</version> </parent> <artifactId>org.eclipse.jgit.lfs.server.test</artifactId> @@ -137,7 +137,7 @@ <plugin> <artifactId>maven-surefire-plugin</artifactId> <configuration> - <argLine>@{argLine} -Djava.io.tmpdir=${project.build.directory} -Xmx300m</argLine> + <argLine>@{argLine} -Djava.io.tmpdir=${project.build.directory} -Xmx512m</argLine> </configuration> </plugin> </plugins> diff --git a/org.eclipse.jgit.lfs.server.test/tst/org/eclipse/jgit/lfs/server/fs/UploadTest.java b/org.eclipse.jgit.lfs.server.test/tst/org/eclipse/jgit/lfs/server/fs/UploadTest.java index 09f8d0aeaf..2334ec37af 100644 --- a/org.eclipse.jgit.lfs.server.test/tst/org/eclipse/jgit/lfs/server/fs/UploadTest.java +++ b/org.eclipse.jgit.lfs.server.test/tst/org/eclipse/jgit/lfs/server/fs/UploadTest.java @@ -44,6 +44,7 @@ package org.eclipse.jgit.lfs.server.fs; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; @@ -53,10 +54,10 @@ import java.nio.file.Paths; import java.text.MessageFormat; import java.util.ArrayList; import java.util.List; -import java.util.concurrent.Callable; import java.util.concurrent.CyclicBarrier; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; +import java.util.concurrent.Future; import java.util.concurrent.TimeUnit; import org.eclipse.jgit.lfs.lib.AnyLongObjectId; @@ -123,14 +124,12 @@ public class UploadTest extends LfsServerTest { ExecutorService e = Executors.newFixedThreadPool(count); try { for (Path p : paths) { - e.submit(new Callable<Void>() { - @Override - public Void call() throws Exception { - barrier.await(); - putContent(p); - return null; - } + Future<Object> result = e.submit(() -> { + barrier.await(); + putContent(p); + return null; }); + assertNotNull(result); } } finally { e.shutdown(); diff --git a/org.eclipse.jgit.lfs.server/.settings/.api_filters b/org.eclipse.jgit.lfs.server/.settings/.api_filters deleted file mode 100644 index 72beb7cdfa..0000000000 --- a/org.eclipse.jgit.lfs.server/.settings/.api_filters +++ /dev/null @@ -1,27 +0,0 @@ -<?xml version="1.0" encoding="UTF-8" standalone="no"?> -<component id="org.eclipse.jgit.lfs.server" version="2"> - <resource path="META-INF/MANIFEST.MF"> - <filter id="924844039"> - <message_arguments> - <message_argument value="5.3.3"/> - <message_argument value="5.3.0"/> - </message_arguments> - </filter> - </resource> - <resource path="src/org/eclipse/jgit/lfs/server/fs/ObjectUploadListener.java" type="org.eclipse.jgit.lfs.server.fs.ObjectUploadListener"> - <filter id="1142947843"> - <message_arguments> - <message_argument value="5.1.7"/> - <message_argument value="setCallback(ObjectUploadListener.Callback)"/> - </message_arguments> - </filter> - </resource> - <resource path="src/org/eclipse/jgit/lfs/server/fs/ObjectUploadListener.java" type="org.eclipse.jgit.lfs.server.fs.ObjectUploadListener$Callback"> - <filter id="1142947843"> - <message_arguments> - <message_argument value="5.1.7"/> - <message_argument value="Callback"/> - </message_arguments> - </filter> - </resource> -</component> diff --git a/org.eclipse.jgit.lfs.server/META-INF/MANIFEST.MF b/org.eclipse.jgit.lfs.server/META-INF/MANIFEST.MF index 0df2eeaf25..ab14a1682b 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.3.3.qualifier +Bundle-Version: 5.4.1.qualifier Bundle-Localization: plugin Bundle-Vendor: %provider_name -Export-Package: org.eclipse.jgit.lfs.server;version="5.3.3"; +Export-Package: org.eclipse.jgit.lfs.server;version="5.4.1"; uses:="javax.servlet.http, org.eclipse.jgit.lfs.lib", - org.eclipse.jgit.lfs.server.fs;version="5.3.3"; + org.eclipse.jgit.lfs.server.fs;version="5.4.1"; uses:="javax.servlet, javax.servlet.http, org.eclipse.jgit.lfs.server, org.eclipse.jgit.lfs.lib", - org.eclipse.jgit.lfs.server.internal;version="5.3.3";x-internal:=true, - org.eclipse.jgit.lfs.server.s3;version="5.3.3"; + org.eclipse.jgit.lfs.server.internal;version="5.4.1";x-internal:=true, + org.eclipse.jgit.lfs.server.s3;version="5.4.1"; 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.3.3,5.4.0)", - org.eclipse.jgit.internal;version="[5.3.3,5.4.0)", - org.eclipse.jgit.internal.storage.file;version="[5.3.3,5.4.0)", - org.eclipse.jgit.lfs.errors;version="[5.3.3,5.4.0)", - org.eclipse.jgit.lfs.internal;version="[5.3.3,5.4.0)", - org.eclipse.jgit.lfs.lib;version="[5.3.3,5.4.0)", - org.eclipse.jgit.lib;version="[5.3.3,5.4.0)", - org.eclipse.jgit.nls;version="[5.3.3,5.4.0)", - org.eclipse.jgit.transport.http;version="[5.3.3,5.4.0)", - org.eclipse.jgit.transport.http.apache;version="[5.3.3,5.4.0)", - org.eclipse.jgit.util;version="[5.3.3,5.4.0)", + org.eclipse.jgit.annotations;version="[5.4.1,5.5.0)", + org.eclipse.jgit.internal;version="[5.4.1,5.5.0)", + org.eclipse.jgit.internal.storage.file;version="[5.4.1,5.5.0)", + org.eclipse.jgit.lfs.errors;version="[5.4.1,5.5.0)", + org.eclipse.jgit.lfs.internal;version="[5.4.1,5.5.0)", + org.eclipse.jgit.lfs.lib;version="[5.4.1,5.5.0)", + org.eclipse.jgit.lib;version="[5.4.1,5.5.0)", + org.eclipse.jgit.nls;version="[5.4.1,5.5.0)", + org.eclipse.jgit.transport.http;version="[5.4.1,5.5.0)", + org.eclipse.jgit.transport.http.apache;version="[5.4.1,5.5.0)", + org.eclipse.jgit.util;version="[5.4.1,5.5.0)", org.slf4j;version="[1.7.0,2.0.0)" diff --git a/org.eclipse.jgit.lfs.server/META-INF/SOURCE-MANIFEST.MF b/org.eclipse.jgit.lfs.server/META-INF/SOURCE-MANIFEST.MF new file mode 100644 index 0000000000..abf1dd223b --- /dev/null +++ b/org.eclipse.jgit.lfs.server/META-INF/SOURCE-MANIFEST.MF @@ -0,0 +1,7 @@ +Manifest-Version: 1.0 +Bundle-ManifestVersion: 2 +Bundle-Name: org.eclipse.jgit.lfs.server - Sources +Bundle-SymbolicName: org.eclipse.jgit.lfs.server.source +Bundle-Vendor: Eclipse.org - JGit +Bundle-Version: 5.4.1.qualifier +Eclipse-SourceBundle: org.eclipse.jgit.lfs.server;version="5.4.1.qualifier";roots="." diff --git a/org.eclipse.jgit.lfs.server/pom.xml b/org.eclipse.jgit.lfs.server/pom.xml index 729665c769..8a954bb7c1 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.3.3-SNAPSHOT</version> + <version>5.4.1-SNAPSHOT</version> </parent> <artifactId>org.eclipse.jgit.lfs.server</artifactId> @@ -62,6 +62,7 @@ <properties> <translate-qualifier/> + <source-bundle-manifest>${project.build.directory}/META-INF/SOURCE-MANIFEST.MF</source-bundle-manifest> </properties> <dependencies> @@ -114,6 +115,28 @@ <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-antrun-plugin</artifactId> + <executions> + <execution> + <id>translate-source-qualifier</id> + <phase>generate-resources</phase> + <configuration> + <target> + <copy file="META-INF/SOURCE-MANIFEST.MF" tofile="${source-bundle-manifest}" overwrite="true"/> + <replace file="${source-bundle-manifest}"> + <replacefilter token=".qualifier" value=".${maven.build.timestamp}"/> + </replace> + </target> + </configuration> + <goals> + <goal>run</goal> + </goals> + </execution> + </executions> + </plugin> + + <plugin> + <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-source-plugin</artifactId> <inherited>true</inherited> <executions> diff --git a/org.eclipse.jgit.lfs.server/src/org/eclipse/jgit/lfs/server/TransferHandler.java b/org.eclipse.jgit.lfs.server/src/org/eclipse/jgit/lfs/server/TransferHandler.java index 4fea92e111..6c36661c3e 100644 --- a/org.eclipse.jgit.lfs.server/src/org/eclipse/jgit/lfs/server/TransferHandler.java +++ b/org.eclipse.jgit.lfs.server/src/org/eclipse/jgit/lfs/server/TransferHandler.java @@ -84,7 +84,7 @@ abstract class TransferHandler { @Override Body process() throws IOException { Response.Body body = new Response.Body(); - if (objects.size() > 0) { + if (!objects.isEmpty()) { body.objects = new ArrayList<>(); for (LfsObject o : objects) { addObjectInfo(body, o); @@ -122,7 +122,7 @@ abstract class TransferHandler { @Override Body process() throws IOException { Response.Body body = new Response.Body(); - if (objects.size() > 0) { + if (!objects.isEmpty()) { body.objects = new ArrayList<>(); for (LfsObject o : objects) { addObjectInfo(body, o); diff --git a/org.eclipse.jgit.lfs.test/.settings/org.eclipse.pde.prefs b/org.eclipse.jgit.lfs.test/.settings/org.eclipse.pde.prefs new file mode 100644 index 0000000000..2174e4fd5b --- /dev/null +++ b/org.eclipse.jgit.lfs.test/.settings/org.eclipse.pde.prefs @@ -0,0 +1,34 @@ +compilers.f.unresolved-features=1 +compilers.f.unresolved-plugins=1 +compilers.incompatible-environment=1 +compilers.p.build=1 +compilers.p.build.bin.includes=1 +compilers.p.build.encodings=2 +compilers.p.build.java.compiler=2 +compilers.p.build.java.compliance=1 +compilers.p.build.missing.output=2 +compilers.p.build.output.library=1 +compilers.p.build.source.library=1 +compilers.p.build.src.includes=1 +compilers.p.deprecated=1 +compilers.p.discouraged-class=1 +compilers.p.internal=1 +compilers.p.missing-packages=2 +compilers.p.missing-version-export-package=2 +compilers.p.missing-version-import-package=2 +compilers.p.missing-version-require-bundle=2 +compilers.p.no-required-att=0 +compilers.p.no.automatic.module=1 +compilers.p.not-externalized-att=2 +compilers.p.service.component.without.lazyactivation=1 +compilers.p.unknown-attribute=1 +compilers.p.unknown-class=1 +compilers.p.unknown-element=1 +compilers.p.unknown-identifier=1 +compilers.p.unknown-resource=1 +compilers.p.unresolved-ex-points=0 +compilers.p.unresolved-import=0 +compilers.s.create-docs=false +compilers.s.doc-folder=doc +compilers.s.open-tags=1 +eclipse.preferences.version=1 diff --git a/org.eclipse.jgit.lfs.test/META-INF/MANIFEST.MF b/org.eclipse.jgit.lfs.test/META-INF/MANIFEST.MF index 64d7c05752..a4f55a61b9 100644 --- a/org.eclipse.jgit.lfs.test/META-INF/MANIFEST.MF +++ b/org.eclipse.jgit.lfs.test/META-INF/MANIFEST.MF @@ -3,23 +3,22 @@ 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.3.3.qualifier +Bundle-Version: 5.4.1.qualifier Bundle-Vendor: %provider_name Bundle-Localization: plugin Bundle-RequiredExecutionEnvironment: JavaSE-1.8 -Import-Package: org.eclipse.jgit.internal.storage.dfs;version="[5.3.3,5.4.0)", - org.eclipse.jgit.junit;version="[5.3.3,5.4.0)", - org.eclipse.jgit.lfs;version="[5.3.3,5.4.0)", - org.eclipse.jgit.lfs.errors;version="[5.3.3,5.4.0)", - org.eclipse.jgit.lfs.lib;version="[5.3.3,5.4.0)", - org.eclipse.jgit.lib;version="[5.3.3,5.4.0)", - org.eclipse.jgit.revwalk;version="[5.3.3,5.4.0)", - org.eclipse.jgit.treewalk;version="[5.3.3,5.4.0)", - org.eclipse.jgit.treewalk.filter;version="[5.3.3,5.4.0)", - org.eclipse.jgit.util;version="[5.3.3,5.4.0)", +Import-Package: org.eclipse.jgit.internal.storage.dfs;version="[5.4.1,5.5.0)", + org.eclipse.jgit.junit;version="[5.4.1,5.5.0)", + org.eclipse.jgit.lfs;version="[5.4.1,5.5.0)", + org.eclipse.jgit.lfs.errors;version="[5.4.1,5.5.0)", + org.eclipse.jgit.lfs.lib;version="[5.4.1,5.5.0)", + org.eclipse.jgit.lib;version="[5.4.1,5.5.0)", + org.eclipse.jgit.revwalk;version="[5.4.1,5.5.0)", + org.eclipse.jgit.treewalk;version="[5.4.1,5.5.0)", + org.eclipse.jgit.treewalk.filter;version="[5.4.1,5.5.0)", + org.eclipse.jgit.util;version="[5.4.1,5.5.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.3.3";x-friends:="org.eclipse.jgit.lfs.server.test" - +Export-Package: org.eclipse.jgit.lfs.test;version="5.4.1";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 7138969827..ee74f0ec93 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.3.3-SNAPSHOT</version> + <version>5.4.1-SNAPSHOT</version> </parent> <artifactId>org.eclipse.jgit.lfs.test</artifactId> @@ -111,7 +111,7 @@ <plugin> <artifactId>maven-surefire-plugin</artifactId> <configuration> - <argLine>@{argLine} -Djava.io.tmpdir=${project.build.directory} -Xmx300m</argLine> + <argLine>@{argLine} -Djava.io.tmpdir=${project.build.directory} -Xmx512m</argLine> </configuration> </plugin> </plugins> diff --git a/org.eclipse.jgit.lfs/.settings/.api_filters b/org.eclipse.jgit.lfs/.settings/.api_filters index 371f35376d..5b8ece617a 100644 --- a/org.eclipse.jgit.lfs/.settings/.api_filters +++ b/org.eclipse.jgit.lfs/.settings/.api_filters @@ -3,8 +3,8 @@ <resource path="META-INF/MANIFEST.MF"> <filter id="924844039"> <message_arguments> - <message_argument value="5.3.3"/> - <message_argument value="5.3.0"/> + <message_argument value="5.4.1"/> + <message_argument value="5.4.0"/> </message_arguments> </filter> </resource> diff --git a/org.eclipse.jgit.lfs/META-INF/MANIFEST.MF b/org.eclipse.jgit.lfs/META-INF/MANIFEST.MF index a13f990df7..ad36094f48 100644 --- a/org.eclipse.jgit.lfs/META-INF/MANIFEST.MF +++ b/org.eclipse.jgit.lfs/META-INF/MANIFEST.MF @@ -3,33 +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.3.3.qualifier +Bundle-Version: 5.4.1.qualifier Bundle-Localization: plugin Bundle-Vendor: %provider_name -Export-Package: org.eclipse.jgit.lfs;version="5.3.3", - org.eclipse.jgit.lfs.errors;version="5.3.3", - org.eclipse.jgit.lfs.internal;version="5.3.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.3.3" +Export-Package: org.eclipse.jgit.lfs;version="5.4.1", + org.eclipse.jgit.lfs.errors;version="5.4.1", + org.eclipse.jgit.lfs.internal;version="5.4.1";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.4.1" 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.3.3,5.4.0)";resolution:=optional, - org.eclipse.jgit.api.errors;version="[5.3.3,5.4.0)", - org.eclipse.jgit.attributes;version="[5.3.3,5.4.0)", - org.eclipse.jgit.diff;version="[5.3.3,5.4.0)", - org.eclipse.jgit.errors;version="[5.3.3,5.4.0)", - org.eclipse.jgit.hooks;version="[5.3.3,5.4.0)", - org.eclipse.jgit.internal.storage.file;version="[5.3.3,5.4.0)", - org.eclipse.jgit.lib;version="[5.3.3,5.4.0)", - org.eclipse.jgit.nls;version="[5.3.3,5.4.0)", - org.eclipse.jgit.revwalk;version="[5.3.3,5.4.0)", - org.eclipse.jgit.storage.file;version="[5.3.3,5.4.0)", - org.eclipse.jgit.storage.pack;version="[5.3.3,5.4.0)", - org.eclipse.jgit.transport;version="[5.3.3,5.4.0)", - org.eclipse.jgit.transport.http;version="[5.3.3,5.4.0)", - org.eclipse.jgit.treewalk;version="[5.3.3,5.4.0)", - org.eclipse.jgit.treewalk.filter;version="[5.3.3,5.4.0)", - org.eclipse.jgit.util;version="[5.3.3,5.4.0)", - org.eclipse.jgit.util.io;version="[5.3.3,5.4.0)" + org.eclipse.jgit.annotations;version="[5.4.1,5.5.0)";resolution:=optional, + org.eclipse.jgit.api.errors;version="[5.4.1,5.5.0)", + org.eclipse.jgit.attributes;version="[5.4.1,5.5.0)", + org.eclipse.jgit.diff;version="[5.4.1,5.5.0)", + org.eclipse.jgit.errors;version="[5.4.1,5.5.0)", + org.eclipse.jgit.hooks;version="[5.4.1,5.5.0)", + org.eclipse.jgit.internal.storage.file;version="[5.4.1,5.5.0)", + org.eclipse.jgit.lib;version="[5.4.1,5.5.0)", + org.eclipse.jgit.nls;version="[5.4.1,5.5.0)", + org.eclipse.jgit.revwalk;version="[5.4.1,5.5.0)", + org.eclipse.jgit.storage.file;version="[5.4.1,5.5.0)", + org.eclipse.jgit.storage.pack;version="[5.4.1,5.5.0)", + org.eclipse.jgit.transport;version="[5.4.1,5.5.0)", + org.eclipse.jgit.transport.http;version="[5.4.1,5.5.0)", + org.eclipse.jgit.treewalk;version="[5.4.1,5.5.0)", + org.eclipse.jgit.treewalk.filter;version="[5.4.1,5.5.0)", + org.eclipse.jgit.util;version="[5.4.1,5.5.0)", + org.eclipse.jgit.util.io;version="[5.4.1,5.5.0)" diff --git a/org.eclipse.jgit.lfs/META-INF/SOURCE-MANIFEST.MF b/org.eclipse.jgit.lfs/META-INF/SOURCE-MANIFEST.MF new file mode 100644 index 0000000000..517ec19120 --- /dev/null +++ b/org.eclipse.jgit.lfs/META-INF/SOURCE-MANIFEST.MF @@ -0,0 +1,7 @@ +Manifest-Version: 1.0 +Bundle-ManifestVersion: 2 +Bundle-Name: org.eclipse.jgit.lfs - Sources +Bundle-SymbolicName: org.eclipse.jgit.lfs.source +Bundle-Vendor: Eclipse.org - JGit +Bundle-Version: 5.4.1.qualifier +Eclipse-SourceBundle: org.eclipse.jgit.lfs;version="5.4.1.qualifier";roots="." diff --git a/org.eclipse.jgit.lfs/pom.xml b/org.eclipse.jgit.lfs/pom.xml index b7d739febd..65532f1925 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.3.3-SNAPSHOT</version> + <version>5.4.1-SNAPSHOT</version> </parent> <artifactId>org.eclipse.jgit.lfs</artifactId> @@ -62,6 +62,7 @@ <properties> <translate-qualifier/> + <source-bundle-manifest>${project.build.directory}/META-INF/SOURCE-MANIFEST.MF</source-bundle-manifest> </properties> <dependencies> @@ -94,6 +95,28 @@ <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-antrun-plugin</artifactId> + <executions> + <execution> + <id>translate-source-qualifier</id> + <phase>generate-resources</phase> + <configuration> + <target> + <copy file="META-INF/SOURCE-MANIFEST.MF" tofile="${source-bundle-manifest}" overwrite="true"/> + <replace file="${source-bundle-manifest}"> + <replacefilter token=".qualifier" value=".${maven.build.timestamp}"/> + </replace> + </target> + </configuration> + <goals> + <goal>run</goal> + </goals> + </execution> + </executions> + </plugin> + + <plugin> + <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-source-plugin</artifactId> <inherited>true</inherited> <executions> diff --git a/org.eclipse.jgit.lfs/src/org/eclipse/jgit/lfs/CleanFilter.java b/org.eclipse.jgit.lfs/src/org/eclipse/jgit/lfs/CleanFilter.java index 217e46f48e..80da802db4 100644 --- a/org.eclipse.jgit.lfs/src/org/eclipse/jgit/lfs/CleanFilter.java +++ b/org.eclipse.jgit.lfs/src/org/eclipse/jgit/lfs/CleanFilter.java @@ -78,14 +78,7 @@ public class CleanFilter extends FilterCommand { * The factory is responsible for creating instances of * {@link org.eclipse.jgit.lfs.CleanFilter} */ - public final static FilterCommandFactory FACTORY = new FilterCommandFactory() { - - @Override - public FilterCommand create(Repository db, InputStream in, - OutputStream out) throws IOException { - return new CleanFilter(db, in, out); - } - }; + public final static FilterCommandFactory FACTORY = CleanFilter::new; /** * Registers this filter by calling 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 7bacf49269..6b30da343e 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 @@ -92,13 +92,7 @@ public class SmudgeFilter extends FilterCommand { * The factory is responsible for creating instances of * {@link org.eclipse.jgit.lfs.SmudgeFilter} */ - public final static FilterCommandFactory FACTORY = new FilterCommandFactory() { - @Override - public FilterCommand create(Repository db, InputStream in, - OutputStream out) throws IOException { - return new SmudgeFilter(db, in, out); - } - }; + public final static FilterCommandFactory FACTORY = SmudgeFilter::new; /** * Register this filter in JGit diff --git a/org.eclipse.jgit.lfs/src/org/eclipse/jgit/lfs/lib/AbbreviatedLongObjectId.java b/org.eclipse.jgit.lfs/src/org/eclipse/jgit/lfs/lib/AbbreviatedLongObjectId.java index bdd1b39c0d..5109d9bbba 100644 --- a/org.eclipse.jgit.lfs/src/org/eclipse/jgit/lfs/lib/AbbreviatedLongObjectId.java +++ b/org.eclipse.jgit.lfs/src/org/eclipse/jgit/lfs/lib/AbbreviatedLongObjectId.java @@ -170,7 +170,7 @@ public final class AbbreviatedLongObjectId implements Serializable { r |= RawParseUtils.parseHexInt4(bs[p++]); n++; } - return r << (16 - n) * 4; + return r << ((16 - n) * 4); } static long mask(int nibbles, long word, long v) { diff --git a/org.eclipse.jgit.lfs/src/org/eclipse/jgit/lfs/lib/AnyLongObjectId.java b/org.eclipse.jgit.lfs/src/org/eclipse/jgit/lfs/lib/AnyLongObjectId.java index 0788922639..b095d20e63 100644 --- a/org.eclipse.jgit.lfs/src/org/eclipse/jgit/lfs/lib/AnyLongObjectId.java +++ b/org.eclipse.jgit.lfs/src/org/eclipse/jgit/lfs/lib/AnyLongObjectId.java @@ -50,6 +50,7 @@ import java.nio.ByteBuffer; import org.eclipse.jgit.lib.AnyObjectId; import org.eclipse.jgit.util.NB; +import org.eclipse.jgit.util.References; /** * A (possibly mutable) SHA-256 abstraction. @@ -73,11 +74,31 @@ public abstract class AnyLongObjectId implements Comparable<AnyLongObjectId> { * @param secondObjectId * the second identifier to compare. Must not be null. * @return true if the two identifiers are the same. + * @deprecated use {@link #isEqual(AnyLongObjectId, AnyLongObjectId)} + * instead. */ + @Deprecated + @SuppressWarnings("AmbiguousMethodReference") public static boolean equals(final AnyLongObjectId firstObjectId, final AnyLongObjectId secondObjectId) { - if (firstObjectId == secondObjectId) + return isEqual(firstObjectId, secondObjectId); + } + + /** + * Compare two object identifier byte sequences for equality. + * + * @param firstObjectId + * the first identifier to compare. Must not be null. + * @param secondObjectId + * the second identifier to compare. Must not be null. + * @return true if the two identifiers are the same. + * @since 5.4 + */ + public static boolean isEqual(final AnyLongObjectId firstObjectId, + final AnyLongObjectId secondObjectId) { + if (References.isSameObject(firstObjectId, secondObjectId)) { return true; + } // We test word 2 first as odds are someone already used our // word 1 as a hash code, and applying that came up with these @@ -274,6 +295,7 @@ public abstract class AnyLongObjectId implements Comparable<AnyLongObjectId> { * the other id to compare to. May be null. * @return true only if both LongObjectIds have identical bits. */ + @SuppressWarnings({ "NonOverridingEquals", "AmbiguousMethodReference" }) public final boolean equals(AnyLongObjectId other) { return other != null ? equals(this, other) : false; } 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 2551f34cb2..3a4c04875e 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.3.3.qualifier" + version="5.4.1.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 68cb1cdc91..33d8567f4e 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.3.3-SNAPSHOT</version> + <version>5.4.1-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 e85a302355..91264db593 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.3.3.qualifier" + version="5.4.1.qualifier" provider-name="%providerName"> <description url="http://www.eclipse.org/jgit/"> @@ -23,7 +23,7 @@ </url> <requires> - <import plugin="org.eclipse.jgit"/> + <import plugin="org.eclipse.jgit" version="5.4.1" match="equivalent"/> </requires> <plugin 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 d9a7bb4280..cdf1cbd516 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.3.3-SNAPSHOT</version> + <version>5.4.1-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 3b42f10e3a..52faeeca55 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.3.3.qualifier" + version="5.4.1.qualifier" provider-name="%providerName"> <description url="http://www.eclipse.org/jgit/"> @@ -24,6 +24,7 @@ <requires> <import plugin="com.jcraft.jsch"/> + <import plugin="org.eclipse.jgit" version="5.4.1" match="equivalent"/> </requires> <plugin @@ -62,7 +63,7 @@ unpack="false"/> <plugin - id="org.apache.sshd.core" + id="org.apache.sshd.osgi" download-size="0" install-size="0" version="0.0.0" 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 817e3b6d52..79a2e84cb5 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.3.3-SNAPSHOT</version> + <version>5.4.1-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 db8168726d..39db64a06f 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.3.3.qualifier" + version="5.4.1.qualifier" provider-name="%providerName"> <description url="http://www.eclipse.org/jgit/"> @@ -23,7 +23,7 @@ </url> <requires> - <import plugin="org.eclipse.jgit"/> + <import feature="org.eclipse.jgit" version="5.4.1" match="equivalent"/> </requires> <plugin 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 5e9fddb397..2825df61ad 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.3.3-SNAPSHOT</version> + <version>5.4.1-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 692af1e2c8..14bfd0138e 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.3.3.qualifier" + version="5.4.1.qualifier" provider-name="%providerName"> <description url="http://www.eclipse.org/jgit/"> @@ -30,10 +30,14 @@ id="org.eclipse.jgit.lfs" version="0.0.0"/> + <includes + id="org.eclipse.jgit.ssh.apache" + version="0.0.0"/> + <requires> - <import feature="org.eclipse.jgit" version="5.3.3" match="equivalent"/> - <import feature="org.eclipse.jgit.lfs" version="5.3.3" match="equivalent"/> - <import feature="org.eclipse.jgit.ssh.apache" version="5.3.3" match="equivalent"/> + <import feature="org.eclipse.jgit" version="5.4.1" match="equivalent"/> + <import feature="org.eclipse.jgit.lfs" version="5.4.1" match="equivalent"/> + <import feature="org.eclipse.jgit.ssh.apache" version="5.4.1" 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 bffe350e2f..39772c7645 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.3.3-SNAPSHOT</version> + <version>5.4.1-SNAPSHOT</version> </parent> <groupId>org.eclipse.jgit.feature</groupId> diff --git a/org.eclipse.jgit.packaging/org.eclipse.jgit.pgm.source.feature/.gitignore b/org.eclipse.jgit.packaging/org.eclipse.jgit.pgm.source.feature/.gitignore deleted file mode 100644 index eb5a316cbd..0000000000 --- a/org.eclipse.jgit.packaging/org.eclipse.jgit.pgm.source.feature/.gitignore +++ /dev/null @@ -1 +0,0 @@ -target diff --git a/org.eclipse.jgit.packaging/org.eclipse.jgit.pgm.source.feature/.project b/org.eclipse.jgit.packaging/org.eclipse.jgit.pgm.source.feature/.project deleted file mode 100644 index 5f57483873..0000000000 --- a/org.eclipse.jgit.packaging/org.eclipse.jgit.pgm.source.feature/.project +++ /dev/null @@ -1,17 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<projectDescription> - <name>org.eclipse.jgit.pgm.source.feature</name> - <comment></comment> - <projects> - </projects> - <buildSpec> - <buildCommand> - <name>org.eclipse.pde.FeatureBuilder</name> - <arguments> - </arguments> - </buildCommand> - </buildSpec> - <natures> - <nature>org.eclipse.pde.FeatureNature</nature> - </natures> -</projectDescription> diff --git a/org.eclipse.jgit.packaging/org.eclipse.jgit.pgm.source.feature/.settings/org.eclipse.core.resources.prefs b/org.eclipse.jgit.packaging/org.eclipse.jgit.pgm.source.feature/.settings/org.eclipse.core.resources.prefs deleted file mode 100644 index 6f96ce809a..0000000000 --- a/org.eclipse.jgit.packaging/org.eclipse.jgit.pgm.source.feature/.settings/org.eclipse.core.resources.prefs +++ /dev/null @@ -1,3 +0,0 @@ -#Fri Jun 18 23:33:45 CEST 2010
-eclipse.preferences.version=1
-encoding/<project>=UTF-8
diff --git a/org.eclipse.jgit.packaging/org.eclipse.jgit.pgm.source.feature/.settings/org.eclipse.core.runtime.prefs b/org.eclipse.jgit.packaging/org.eclipse.jgit.pgm.source.feature/.settings/org.eclipse.core.runtime.prefs deleted file mode 100644 index 1a32dba177..0000000000 --- a/org.eclipse.jgit.packaging/org.eclipse.jgit.pgm.source.feature/.settings/org.eclipse.core.runtime.prefs +++ /dev/null @@ -1,3 +0,0 @@ -#Fri Jun 18 23:33:45 CEST 2010
-eclipse.preferences.version=1
-line.separator=\n
diff --git a/org.eclipse.jgit.packaging/org.eclipse.jgit.pgm.source.feature/.settings/org.eclipse.mylyn.tasks.ui.prefs b/org.eclipse.jgit.packaging/org.eclipse.jgit.pgm.source.feature/.settings/org.eclipse.mylyn.tasks.ui.prefs deleted file mode 100644 index 823c0f56ae..0000000000 --- a/org.eclipse.jgit.packaging/org.eclipse.jgit.pgm.source.feature/.settings/org.eclipse.mylyn.tasks.ui.prefs +++ /dev/null @@ -1,4 +0,0 @@ -#Tue Jul 19 20:11:28 CEST 2011 -eclipse.preferences.version=1 -project.repository.kind=bugzilla -project.repository.url=https\://bugs.eclipse.org/bugs diff --git a/org.eclipse.jgit.packaging/org.eclipse.jgit.pgm.source.feature/.settings/org.eclipse.mylyn.team.ui.prefs b/org.eclipse.jgit.packaging/org.eclipse.jgit.pgm.source.feature/.settings/org.eclipse.mylyn.team.ui.prefs deleted file mode 100644 index 2fca432276..0000000000 --- a/org.eclipse.jgit.packaging/org.eclipse.jgit.pgm.source.feature/.settings/org.eclipse.mylyn.team.ui.prefs +++ /dev/null @@ -1,3 +0,0 @@ -#Tue Jul 19 20:11:28 CEST 2011 -commit.comment.template=${task.description}\n\nBug\: ${task.key} -eclipse.preferences.version=1 diff --git a/org.eclipse.jgit.packaging/org.eclipse.jgit.pgm.source.feature/build.properties b/org.eclipse.jgit.packaging/org.eclipse.jgit.pgm.source.feature/build.properties deleted file mode 100644 index b4a8dde9e5..0000000000 --- a/org.eclipse.jgit.packaging/org.eclipse.jgit.pgm.source.feature/build.properties +++ /dev/null @@ -1,4 +0,0 @@ -bin.includes = feature.xml,\ - edl-v10.html,\ - feature.properties,\ - license.html diff --git a/org.eclipse.jgit.packaging/org.eclipse.jgit.pgm.source.feature/edl-v10.html b/org.eclipse.jgit.packaging/org.eclipse.jgit.pgm.source.feature/edl-v10.html deleted file mode 100644 index 8caddac569..0000000000 --- a/org.eclipse.jgit.packaging/org.eclipse.jgit.pgm.source.feature/edl-v10.html +++ /dev/null @@ -1,59 +0,0 @@ -<?xml version="1.0" encoding="ISO-8859-1" ?> -<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> -<html xmlns="http://www.w3.org/1999/xhtml"> - -<head> -<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1" /> -<title>Eclipse Distribution License - Version 1.0</title> -<style type="text/css"> - body { - size: 8.5in 11.0in; - margin: 0.25in 0.5in 0.25in 0.5in; - tab-interval: 0.5in; - } - p { - margin-left: auto; - margin-top: 0.5em; - margin-bottom: 0.5em; - } - p.list { - margin-left: 0.5in; - margin-top: 0.05em; - margin-bottom: 0.05em; - } -</style> - -</head> - -<body lang="EN-US"> - -<p><b>Eclipse Distribution License - v 1.0</b></p> - -<p>Copyright (c) 2007, Eclipse Foundation, Inc. and its licensors. </p> - -<p>All rights reserved.</p> -<p>Redistribution and use in source and binary forms, with or without modification, - are permitted provided that the following conditions are met: -<ul><li>Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. </li> -<li>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. </li> -<li>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. </li></ul> -</p> -<p>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.</p> - -</body> - -</html> diff --git a/org.eclipse.jgit.packaging/org.eclipse.jgit.pgm.source.feature/feature.properties b/org.eclipse.jgit.packaging/org.eclipse.jgit.pgm.source.feature/feature.properties deleted file mode 100644 index 73701b291a..0000000000 --- a/org.eclipse.jgit.packaging/org.eclipse.jgit.pgm.source.feature/feature.properties +++ /dev/null @@ -1,178 +0,0 @@ -############################################################################### -# Copyright (c) 2000, 2010 IBM Corporation and others. -# -# All rights reserved. This program and the accompanying materials -# are made available under the terms of the Eclipse Public License v1.0 -# which accompanies this distribution, and is available at -# http://www.eclipse.org/legal/epl-v10.html -# -############################################################################### - -featureName=Java implementation of Git - Command Line Interface - Source Code -providerName=Eclipse JGit - -updateSiteName=Eclipse JGit Update Site - -# description property - text of the "Feature Description" -description=\ -Do not install in your IDE: this feature is meant to provision Target Platforms.\n\ -Source code for the support for PDE's JUnit runner for a Target Platform\n -################ end of description property ################################## - -# "copyright" property - text of the "Feature Update Copyright" -copyright=\ -Copyright (c) 2005, 2012 Shawn Pearce, Robin Rosenberg, et.al.\n\ -All rights reserved. This program and the accompanying materials\n\ -are made available under the terms of the Eclipse Distribution License v1.0\n\ -which accompanies this distribution, and is available at\n\ -http://www.eclipse.org/org/documents/edl-v10.html\n -################ end of copyright property #################################### - -# "licenseURL" property - URL of the "Feature License" -# do not translate value - just change to point to a locale-specific HTML page -licenseURL=license.html - -# "license" property - text of the "Feature Update License" -# should be plain text version of license agreement pointed to be "licenseURL" -license=\ -Eclipse Foundation Software User Agreement\n\ -\n\ -November 22, 2017\n\ -\n\ -Usage Of Content\n\ -\n\ -THE ECLIPSE FOUNDATION MAKES AVAILABLE SOFTWARE, DOCUMENTATION, INFORMATION\n\ -AND/OR OTHER MATERIALS FOR OPEN SOURCE PROJECTS (COLLECTIVELY "CONTENT"). USE OF\n\ -THE CONTENT IS GOVERNED BY THE TERMS AND CONDITIONS OF THIS AGREEMENT AND/OR THE\n\ -TERMS AND CONDITIONS OF LICENSE AGREEMENTS OR NOTICES INDICATED OR REFERENCED\n\ -BELOW. BY USING THE CONTENT, YOU AGREE THAT YOUR USE OF THE CONTENT IS GOVERNED\n\ -BY THIS AGREEMENT AND/OR THE TERMS AND CONDITIONS OF ANY APPLICABLE LICENSE\n\ -AGREEMENTS OR NOTICES INDICATED OR REFERENCED BELOW. IF YOU DO NOT AGREE TO THE\n\ -TERMS AND CONDITIONS OF THIS AGREEMENT AND THE TERMS AND CONDITIONS OF ANY\n\ -APPLICABLE LICENSE AGREEMENTS OR NOTICES INDICATED OR REFERENCED BELOW, THEN YOU\n\ -MAY NOT USE THE CONTENT.\n\ -\n\ -Applicable Licenses\n\ -\n\ -Unless otherwise indicated, all Content made available by the Eclipse Foundation\n\ -is provided to you under the terms and conditions of the Eclipse Public License\n\ -Version 2.0 ("EPL"). A copy of the EPL is provided with this Content and is also\n\ -available at http://www.eclipse.org/legal/epl-2.0. For purposes of the EPL,\n\ -"Program" will mean the Content.\n\ -\n\ -Content includes, but is not limited to, source code, object code, documentation\n\ -and other files maintained in the Eclipse Foundation source code repository\n\ -("Repository") in software modules ("Modules") and made available as\n\ -downloadable archives ("Downloads").\n\ -\n\ -- Content may be structured and packaged into modules to facilitate\n\ - delivering, extending, and upgrading the Content. Typical modules may\n\ - include plug-ins ("Plug-ins"), plug-in fragments ("Fragments"), and\n\ - features ("Features").\n\ -- Each Plug-in or Fragment may be packaged as a sub-directory or JAR\n\ - (Javaâ„¢ ARchive) in a directory named "plugins".\n\ -- A Feature is a bundle of one or more Plug-ins and/or Fragments and\n\ - associated material. Each Feature may be packaged as a sub-directory in a\n\ - directory named "features". Within a Feature, files named "feature.xml" may\n\ - contain a list of the names and version numbers of the Plug-ins and/or\n\ - Fragments associated with that Feature.\n\ -- Features may also include other Features ("Included Features"). Within a\n\ - Feature, files named "feature.xml" may contain a list of the names and\n\ - version numbers of Included Features.\n\ -\n\ -The terms and conditions governing Plug-ins and Fragments should be contained in\n\ -files named "about.html" ("Abouts"). The terms and conditions governing Features\n\ -and Included Features should be contained in files named "license.html"\n\ -("Feature Licenses"). Abouts and Feature Licenses may be located in any\n\ -directory of a Download or Module including, but not limited to the following\n\ -locations:\n\ -\n\ -- The top-level (root) directory\n\ -- Plug-in and Fragment directories\n\ -- Inside Plug-ins and Fragments packaged as JARs\n\ -- Sub-directories of the directory named "src" of certain Plug-ins\n\ -- Feature directories\n\ -\n\ -Note: if a Feature made available by the Eclipse Foundation is installed using\n\ -the Provisioning Technology (as defined below), you must agree to a license\n\ -("Feature Update License") during the installation process. If the Feature\n\ -contains Included Features, the Feature Update License should either provide you\n\ -with the terms and conditions governing the Included Features or inform you\n\ -where you can locate them. Feature Update Licenses may be found in the "license"\n\ -property of files named "feature.properties" found within a Feature. Such\n\ -Abouts, Feature Licenses, and Feature Update Licenses contain the terms and\n\ -conditions (or references to such terms and conditions) that govern your use of\n\ -the associated Content in that directory.\n\ -\n\ -THE ABOUTS, FEATURE LICENSES, AND FEATURE UPDATE LICENSES MAY REFER TO THE EPL\n\ -OR OTHER LICENSE AGREEMENTS, NOTICES OR TERMS AND CONDITIONS. SOME OF THESE\n\ -OTHER LICENSE AGREEMENTS MAY INCLUDE (BUT ARE NOT LIMITED TO):\n\ -\n\ -- Eclipse Public License Version 1.0 (available at\n\ - http://www.eclipse.org/legal/epl-v10.html)\n\ -- Eclipse Distribution License Version 1.0 (available at\n\ - http://www.eclipse.org/licenses/edl-v1.0.html)\n\ -- Common Public License Version 1.0 (available at\n\ - http://www.eclipse.org/legal/cpl-v10.html)\n\ -- Apache Software License 1.1 (available at\n\ - http://www.apache.org/licenses/LICENSE)\n\ -- Apache Software License 2.0 (available at\n\ - http://www.apache.org/licenses/LICENSE-2.0)\n\ -- Mozilla Public License Version 1.1 (available at\n\ - http://www.mozilla.org/MPL/MPL-1.1.html)\n\ -\n\ -IT IS YOUR OBLIGATION TO READ AND ACCEPT ALL SUCH TERMS AND CONDITIONS PRIOR TO\n\ -USE OF THE CONTENT. If no About, Feature License, or Feature Update License is\n\ -provided, please contact the Eclipse Foundation to determine what terms and\n\ -conditions govern that particular Content.\n\ -\n\ -Use of Provisioning Technology\n\ -\n\ -The Eclipse Foundation makes available provisioning software, examples of which\n\ -include, but are not limited to, p2 and the Eclipse Update Manager\n\ -("Provisioning Technology") for the purpose of allowing users to install\n\ -software, documentation, information and/or other materials (collectively\n\ -"Installable Software"). This capability is provided with the intent of allowing\n\ -such users to install, extend and update Eclipse-based products. Information\n\ -about packaging Installable Software is available at\n\ -http://eclipse.org/equinox/p2/repository_packaging.html ("Specification").\n\ -\n\ -You may use Provisioning Technology to allow other parties to install\n\ -Installable Software. You shall be responsible for enabling the applicable\n\ -license agreements relating to the Installable Software to be presented to, and\n\ -accepted by, the users of the Provisioning Technology in accordance with the\n\ -Specification. By using Provisioning Technology in such a manner and making it\n\ -available in accordance with the Specification, you further acknowledge your\n\ -agreement to, and the acquisition of all necessary rights to permit the\n\ -following:\n\ -\n\ -1. A series of actions may occur ("Provisioning Process") in which a user may\n\ - execute the Provisioning Technology on a machine ("Target Machine") with the\n\ - intent of installing, extending or updating the functionality of an\n\ - Eclipse-based product.\n\ -2. During the Provisioning Process, the Provisioning Technology may cause third\n\ - party Installable Software or a portion thereof to be accessed and copied to\n\ - the Target Machine.\n\ -3. Pursuant to the Specification, you will provide to the user the terms and\n\ - conditions that govern the use of the Installable Software ("Installable\n\ - Software Agreement") and such Installable Software Agreement shall be\n\ - accessed from the Target Machine in accordance with the Specification. Such\n\ - Installable Software Agreement must inform the user of the terms and\n\ - conditions that govern the Installable Software and must solicit acceptance\n\ - by the end user in the manner prescribed in such Installable\n\ - Software Agreement. Upon such indication of agreement by the user, the\n\ - provisioning Technology will complete installation of the\n\ - Installable Software.\n\ -\n\ -Cryptography\n\ -\n\ -Content may contain encryption software. The country in which you are currently\n\ -may have restrictions on the import, possession, and use, and/or re-export to\n\ -another country, of encryption software. BEFORE using any encryption software,\n\ -please check the country's laws, regulations and policies concerning the import,\n\ -possession, or use, and re-export of encryption software, to see if this is\n\ -permitted.\n\ -\n\ -Java and all Java-based trademarks are trademarks of Oracle Corporation in the\n\ -United States, other countries, or both.\n -########### end of license property ########################################## 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 deleted file mode 100644 index 075aea19a0..0000000000 --- a/org.eclipse.jgit.packaging/org.eclipse.jgit.pgm.source.feature/feature.xml +++ /dev/null @@ -1,31 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<feature - id="org.eclipse.jgit.pgm.source" - label="%featureName" - version="5.3.3.qualifier" - provider-name="%providerName"> - - <description url="http://www.eclipse.org/jgit/"> - %description - </description> - - <copyright> - %copyright - </copyright> - - <license url="%licenseURL"> - %license - </license> - - <url> - <update label="%updateSiteName" url="http://download.eclipse.org/egit/updates"/> - <discovery label="%updateSiteName" url="http://download.eclipse.org/egit/updates"/> - </url> - - <plugin - id="org.eclipse.jgit.pgm.source" - download-size="0" - install-size="0" - version="0.0.0" - unpack="false"/> -</feature> diff --git a/org.eclipse.jgit.packaging/org.eclipse.jgit.pgm.source.feature/license.html b/org.eclipse.jgit.packaging/org.eclipse.jgit.pgm.source.feature/license.html deleted file mode 100644 index 008b8018db..0000000000 --- a/org.eclipse.jgit.packaging/org.eclipse.jgit.pgm.source.feature/license.html +++ /dev/null @@ -1,189 +0,0 @@ -<?xml version="1.0" encoding="ISO-8859-1" ?> -<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> -<html xmlns="http://www.w3.org/1999/xhtml"> -<head> -<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1" /> -<title>Eclipse Foundation Software User Agreement</title> -</head> - -<body lang="EN-US"> - <h2>Eclipse Foundation Software User Agreement</h2> - <p>November 22, 2017</p> - - <h3>Usage Of Content</h3> - - <p>THE ECLIPSE FOUNDATION MAKES AVAILABLE SOFTWARE, DOCUMENTATION, - INFORMATION AND/OR OTHER MATERIALS FOR OPEN SOURCE PROJECTS - (COLLECTIVELY "CONTENT"). USE OF THE CONTENT IS GOVERNED BY - THE TERMS AND CONDITIONS OF THIS AGREEMENT AND/OR THE TERMS AND - CONDITIONS OF LICENSE AGREEMENTS OR NOTICES INDICATED OR REFERENCED - BELOW. BY USING THE CONTENT, YOU AGREE THAT YOUR USE OF THE CONTENT IS - GOVERNED BY THIS AGREEMENT AND/OR THE TERMS AND CONDITIONS OF ANY - APPLICABLE LICENSE AGREEMENTS OR NOTICES INDICATED OR REFERENCED - BELOW. IF YOU DO NOT AGREE TO THE TERMS AND CONDITIONS OF THIS - AGREEMENT AND THE TERMS AND CONDITIONS OF ANY APPLICABLE LICENSE - AGREEMENTS OR NOTICES INDICATED OR REFERENCED BELOW, THEN YOU MAY NOT - USE THE CONTENT.</p> - - <h3>Applicable Licenses</h3> - - <p> - Unless otherwise indicated, all Content made available by the Eclipse - Foundation is provided to you under the terms and conditions of the - Eclipse Public License Version 2.0 ("EPL"). A copy of the - EPL is provided with this Content and is also available at <a - href="http://www.eclipse.org/legal/epl-2.0">http://www.eclipse.org/legal/epl-2.0</a>. - For purposes of the EPL, "Program" will mean the Content. - </p> - - <p>Content includes, but is not limited to, source code, object - code, documentation and other files maintained in the Eclipse - Foundation source code repository ("Repository") in software - modules ("Modules") and made available as downloadable - archives ("Downloads").</p> - - <ul> - <li>Content may be structured and packaged into modules to - facilitate delivering, extending, and upgrading the Content. Typical - modules may include plug-ins ("Plug-ins"), plug-in - fragments ("Fragments"), and features - ("Features").</li> - <li>Each Plug-in or Fragment may be packaged as a sub-directory - or JAR (Java™ ARchive) in a directory named - "plugins".</li> - <li>A Feature is a bundle of one or more Plug-ins and/or - Fragments and associated material. Each Feature may be packaged as a - sub-directory in a directory named "features". Within a - Feature, files named "feature.xml" may contain a list of - the names and version numbers of the Plug-ins and/or Fragments - associated with that Feature.</li> - <li>Features may also include other Features ("Included - Features"). Within a Feature, files named - "feature.xml" may contain a list of the names and version - numbers of Included Features.</li> - </ul> - - <p>The terms and conditions governing Plug-ins and Fragments should - be contained in files named "about.html" - ("Abouts"). The terms and conditions governing Features and - Included Features should be contained in files named - "license.html" ("Feature Licenses"). Abouts and - Feature Licenses may be located in any directory of a Download or - Module including, but not limited to the following locations:</p> - - <ul> - <li>The top-level (root) directory</li> - <li>Plug-in and Fragment directories</li> - <li>Inside Plug-ins and Fragments packaged as JARs</li> - <li>Sub-directories of the directory named "src" of - certain Plug-ins</li> - <li>Feature directories</li> - </ul> - - <p>Note: if a Feature made available by the Eclipse Foundation is - installed using the Provisioning Technology (as defined below), you - must agree to a license ("Feature Update License") during - the installation process. If the Feature contains Included Features, - the Feature Update License should either provide you with the terms - and conditions governing the Included Features or inform you where you - can locate them. Feature Update Licenses may be found in the - "license" property of files named - "feature.properties" found within a Feature. Such Abouts, - Feature Licenses, and Feature Update Licenses contain the terms and - conditions (or references to such terms and conditions) that govern - your use of the associated Content in that directory.</p> - - <p>THE ABOUTS, FEATURE LICENSES, AND FEATURE UPDATE LICENSES MAY - REFER TO THE EPL OR OTHER LICENSE AGREEMENTS, NOTICES OR TERMS AND - CONDITIONS. SOME OF THESE OTHER LICENSE AGREEMENTS MAY INCLUDE (BUT - ARE NOT LIMITED TO):</p> - - <ul> - <li>Eclipse Public License Version 1.0 (available at <a - href="http://www.eclipse.org/legal/epl-v10.html">http://www.eclipse.org/legal/epl-v10.html</a>) - </li> - <li>Eclipse Distribution License Version 1.0 (available at <a - href="http://www.eclipse.org/licenses/edl-v10.html">http://www.eclipse.org/licenses/edl-v1.0.html</a>) - </li> - <li>Common Public License Version 1.0 (available at <a - href="http://www.eclipse.org/legal/cpl-v10.html">http://www.eclipse.org/legal/cpl-v10.html</a>) - </li> - <li>Apache Software License 1.1 (available at <a - href="http://www.apache.org/licenses/LICENSE">http://www.apache.org/licenses/LICENSE</a>) - </li> - <li>Apache Software License 2.0 (available at <a - href="http://www.apache.org/licenses/LICENSE-2.0">http://www.apache.org/licenses/LICENSE-2.0</a>) - </li> - <li>Mozilla Public License Version 1.1 (available at <a - href="http://www.mozilla.org/MPL/MPL-1.1.html">http://www.mozilla.org/MPL/MPL-1.1.html</a>) - </li> - </ul> - - <p>IT IS YOUR OBLIGATION TO READ AND ACCEPT ALL SUCH TERMS AND - CONDITIONS PRIOR TO USE OF THE CONTENT. If no About, Feature License, - or Feature Update License is provided, please contact the Eclipse - Foundation to determine what terms and conditions govern that - particular Content.</p> - - - <h3>Use of Provisioning Technology</h3> - - <p> - The Eclipse Foundation makes available provisioning software, examples - of which include, but are not limited to, p2 and the Eclipse Update - Manager ("Provisioning Technology") for the purpose of - allowing users to install software, documentation, information and/or - other materials (collectively "Installable Software"). This - capability is provided with the intent of allowing such users to - install, extend and update Eclipse-based products. Information about - packaging Installable Software is available at <a - href="http://eclipse.org/equinox/p2/repository_packaging.html">http://eclipse.org/equinox/p2/repository_packaging.html</a> - ("Specification"). - </p> - - <p>You may use Provisioning Technology to allow other parties to - install Installable Software. You shall be responsible for enabling - the applicable license agreements relating to the Installable Software - to be presented to, and accepted by, the users of the Provisioning - Technology in accordance with the Specification. By using Provisioning - Technology in such a manner and making it available in accordance with - the Specification, you further acknowledge your agreement to, and the - acquisition of all necessary rights to permit the following:</p> - - <ol> - <li>A series of actions may occur ("Provisioning - Process") in which a user may execute the Provisioning - Technology on a machine ("Target Machine") with the intent - of installing, extending or updating the functionality of an - Eclipse-based product.</li> - <li>During the Provisioning Process, the Provisioning Technology - may cause third party Installable Software or a portion thereof to be - accessed and copied to the Target Machine.</li> - <li>Pursuant to the Specification, you will provide to the user - the terms and conditions that govern the use of the Installable - Software ("Installable Software Agreement") and such - Installable Software Agreement shall be accessed from the Target - Machine in accordance with the Specification. Such Installable - Software Agreement must inform the user of the terms and conditions - that govern the Installable Software and must solicit acceptance by - the end user in the manner prescribed in such Installable Software - Agreement. Upon such indication of agreement by the user, the - provisioning Technology will complete installation of the Installable - Software.</li> - </ol> - - <h3>Cryptography</h3> - - <p>Content may contain encryption software. The country in which - you are currently may have restrictions on the import, possession, and - use, and/or re-export to another country, of encryption software. - BEFORE using any encryption software, please check the country's laws, - regulations and policies concerning the import, possession, or use, - and re-export of encryption software, to see if this is permitted.</p> - - <p> - <small>Java and all Java-based trademarks are trademarks of - Oracle Corporation in the United States, other countries, or both.</small> - </p> -</body> -</html> 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 deleted file mode 100644 index 605a23a9fc..0000000000 --- a/org.eclipse.jgit.packaging/org.eclipse.jgit.pgm.source.feature/pom.xml +++ /dev/null @@ -1,62 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<!-- - Copyright (C) 2012, 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. ---> - -<project xmlns="http://maven.apache.org/POM/4.0.0" - xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" - xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"> - <modelVersion>4.0.0</modelVersion> - - <parent> - <groupId>org.eclipse.jgit</groupId> - <artifactId>jgit.tycho.parent</artifactId> - <version>5.3.3-SNAPSHOT</version> - </parent> - - <groupId>org.eclipse.jgit.feature</groupId> - <artifactId>org.eclipse.jgit.pgm.source</artifactId> - <packaging>eclipse-feature</packaging> - - <name>JGit Command Line Interface Source Feature</name> - -</project> diff --git a/org.eclipse.jgit.packaging/org.eclipse.jgit.repository/category.xml b/org.eclipse.jgit.packaging/org.eclipse.jgit.repository/category.xml index 995bd21b18..e2aeee38c6 100644 --- a/org.eclipse.jgit.packaging/org.eclipse.jgit.repository/category.xml +++ b/org.eclipse.jgit.packaging/org.eclipse.jgit.repository/category.xml @@ -15,24 +15,32 @@ <feature url="features/org.eclipse.jgit.source_0.0.0.qualifier.jar" id="org.eclipse.jgit.source" version="0.0.0" patch="true"> <category name="JGit"/> </feature> - <feature url="features/org.eclipse.jgit.pgm.source_0.0.0.qualifier.jar" id="org.eclipse.jgit.pgm.source" version="0.0.0" patch="true"> - <category name="JGit"/> - </feature> - <feature url="features/org.eclipse.jgit.ssh.apache.source_0.0.0.qualifier.jar" id="org.eclipse.jgit.ssh.apache.source" version="0.0.0" patch="true"> - <category name="JGit"/> - </feature> <feature url="features/org.eclipse.jgit.junit_0.0.0.qualifier.jar" id="org.eclipse.jgit.junit" version="0.0.0" patch="true"> <category name="JGit"/> </feature> <feature url="features/org.eclipse.jgit.http.apache_0.0.0.qualifier.jar" id="org.eclipse.jgit.http.apache" version="0.0.0" patch="true"> <category name="JGit"/> </feature> - <feature url="features/org.eclipse.jgit.lfs_0.0.0.qualifier.jar" id="org.eclipse.jgit.lfs" version="0.0.0"> + <feature url="features/org.eclipse.jgit.lfs_0.0.0.qualifier.jar" id="org.eclipse.jgit.lfs" version="0.0.0" patch="true"> <category name="JGit"/> </feature> + <bundle id="org.eclipse.jgit.ant" version="0.0.0"> + <category name="JGit-additional-bundles"/> + </bundle> + <bundle id="org.eclipse.jgit.archive" version="0.0.0"> + <category name="JGit-additional-bundles"/> + </bundle> + <bundle id="org.eclipse.jgit.ui" version="0.0.0"> + <category name="JGit-additional-bundles"/> + </bundle> <category-def name="JGit" label="Java implementation of Git"> <description> Java implementation of Git </description> </category-def> + <category-def name="JGit-additional-bundles" label="Java implementation of Git - additional bundles"> + <description> + Java implementation of Git - additional bundles + </description> + </category-def> </site> 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 dd9dba7cbc..dc2ad15ec8 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.3.3-SNAPSHOT</version> + <version>5.4.1-SNAPSHOT</version> </parent> <artifactId>org.eclipse.jgit.repository</artifactId> @@ -64,24 +64,24 @@ <artifactId>org.eclipse.jgit</artifactId> <version>${project.version}</version> </dependency> - <dependency> - <groupId>org.eclipse.jgit</groupId> - <artifactId>org.eclipse.jgit.http.apache</artifactId> - <version>${project.version}</version> - </dependency> <dependency> - <groupId>org.eclipse.jgit</groupId> - <artifactId>org.eclipse.jgit.lfs</artifactId> - <version>${project.version}</version> - </dependency> + <groupId>org.eclipse.jgit</groupId> + <artifactId>org.eclipse.jgit.ant</artifactId> + <version>${project.version}</version> + </dependency> <dependency> <groupId>org.eclipse.jgit</groupId> - <artifactId>org.eclipse.jgit.lfs.server</artifactId> + <artifactId>org.eclipse.jgit.archive</artifactId> <version>${project.version}</version> </dependency> <dependency> <groupId>org.eclipse.jgit</groupId> - <artifactId>org.eclipse.jgit.pgm</artifactId> + <artifactId>org.eclipse.jgit.http.apache</artifactId> + <version>${project.version}</version> + </dependency> + <dependency> + <groupId>org.eclipse.jgit</groupId> + <artifactId>org.eclipse.jgit.http.server</artifactId> <version>${project.version}</version> </dependency> <dependency> @@ -101,7 +101,17 @@ </dependency> <dependency> <groupId>org.eclipse.jgit</groupId> - <artifactId>org.eclipse.jgit.http.server</artifactId> + <artifactId>org.eclipse.jgit.lfs</artifactId> + <version>${project.version}</version> + </dependency> + <dependency> + <groupId>org.eclipse.jgit</groupId> + <artifactId>org.eclipse.jgit.lfs.server</artifactId> + <version>${project.version}</version> + </dependency> + <dependency> + <groupId>org.eclipse.jgit</groupId> + <artifactId>org.eclipse.jgit.pgm</artifactId> <version>${project.version}</version> </dependency> <dependency> @@ -109,5 +119,10 @@ <artifactId>org.eclipse.jgit.ssh.apache</artifactId> <version>${project.version}</version> </dependency> + <dependency> + <groupId>org.eclipse.jgit</groupId> + <artifactId>org.eclipse.jgit.ui</artifactId> + <version>${project.version}</version> + </dependency> </dependencies> </project> 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 68c5efa974..8e8fd8a18a 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,19 +2,19 @@ <feature id="org.eclipse.jgit.source" label="%featureName" - version="5.3.3.qualifier" + version="5.4.1.qualifier" provider-name="%providerName"> <description url="http://www.eclipse.org/jgit/"> - %description + %description </description> <copyright> - %copyright + %copyright </copyright> <license url="%licenseURL"> - %license + %license </license> <url> @@ -22,10 +22,99 @@ <discovery label="%updateSiteName" url="http://download.eclipse.org/egit/updates"/> </url> + <requires> + <import feature="org.eclipse.jgit" version="5.4.1" match="equivalent"/> + </requires> + <plugin id="org.eclipse.jgit.source" download-size="0" install-size="0" version="0.0.0" unpack="false"/> + + <plugin + id="org.eclipse.jgit.ant.source" + download-size="0" + install-size="0" + version="0.0.0" + unpack="false"/> + + <plugin + id="org.eclipse.jgit.archive.source" + download-size="0" + install-size="0" + version="0.0.0" + unpack="false"/> + + <plugin + id="org.eclipse.jgit.http.apache.source" + download-size="0" + install-size="0" + version="0.0.0" + unpack="false"/> + + <plugin + id="org.eclipse.jgit.http.server.source" + download-size="0" + install-size="0" + version="0.0.0" + unpack="false"/> + + <plugin + id="org.eclipse.jgit.junit.source" + download-size="0" + install-size="0" + version="0.0.0" + unpack="false"/> + + <plugin + id="org.eclipse.jgit.junit.http.source" + download-size="0" + install-size="0" + version="0.0.0" + unpack="false"/> + + <plugin + id="org.eclipse.jgit.junit.ssh.source" + download-size="0" + install-size="0" + version="0.0.0" + unpack="false"/> + + <plugin + id="org.eclipse.jgit.lfs.source" + download-size="0" + install-size="0" + version="0.0.0" + unpack="false"/> + + <plugin + id="org.eclipse.jgit.lfs.server.source" + download-size="0" + install-size="0" + version="0.0.0" + unpack="false"/> + + <plugin + id="org.eclipse.jgit.pgm.source" + download-size="0" + install-size="0" + version="0.0.0" + unpack="false"/> + + <plugin + id="org.eclipse.jgit.ssh.apache.source" + download-size="0" + install-size="0" + version="0.0.0" + unpack="false"/> + + <plugin + id="org.eclipse.jgit.ui.source" + download-size="0" + install-size="0" + version="0.0.0" + unpack="false"/> + </feature> 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 d260f837bf..813271028b 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.3.3-SNAPSHOT</version> + <version>5.4.1-SNAPSHOT</version> </parent> <groupId>org.eclipse.jgit.feature</groupId> @@ -59,4 +59,12 @@ <name>JGit Source Feature</name> + <dependencies> + <dependency> + <groupId>org.eclipse.jgit.feature</groupId> + <artifactId>org.eclipse.jgit</artifactId> + <version>5.4.1-SNAPSHOT</version> + </dependency> + </dependencies> + </project> diff --git a/org.eclipse.jgit.packaging/org.eclipse.jgit.ssh.apache.feature/feature.xml b/org.eclipse.jgit.packaging/org.eclipse.jgit.ssh.apache.feature/feature.xml index 7a957df994..b7420dc47c 100644 --- a/org.eclipse.jgit.packaging/org.eclipse.jgit.ssh.apache.feature/feature.xml +++ b/org.eclipse.jgit.packaging/org.eclipse.jgit.ssh.apache.feature/feature.xml @@ -2,7 +2,7 @@ <feature id="org.eclipse.jgit.ssh.apache" label="%featureName" - version="5.3.3.qualifier" + version="5.4.1.qualifier" provider-name="%providerName"> <description url="http://www.eclipse.org/jgit/"> @@ -23,7 +23,7 @@ </url> <requires> - <import plugin="org.eclipse.jgit"/> + <import feature="org.eclipse.jgit" version="5.4.1" match="equivalent"/> </requires> <plugin @@ -34,7 +34,7 @@ unpack="false"/> <plugin - id="org.apache.sshd.core" + id="org.apache.sshd.osgi" download-size="0" install-size="0" version="0.0.0" diff --git a/org.eclipse.jgit.packaging/org.eclipse.jgit.ssh.apache.feature/pom.xml b/org.eclipse.jgit.packaging/org.eclipse.jgit.ssh.apache.feature/pom.xml index fb549a2786..167b295fb2 100644 --- a/org.eclipse.jgit.packaging/org.eclipse.jgit.ssh.apache.feature/pom.xml +++ b/org.eclipse.jgit.packaging/org.eclipse.jgit.ssh.apache.feature/pom.xml @@ -50,7 +50,7 @@ <parent> <groupId>org.eclipse.jgit</groupId> <artifactId>jgit.tycho.parent</artifactId> - <version>5.3.3-SNAPSHOT</version> + <version>5.4.1-SNAPSHOT</version> </parent> <groupId>org.eclipse.jgit.feature</groupId> diff --git a/org.eclipse.jgit.packaging/org.eclipse.jgit.ssh.apache.source.feature/.gitignore b/org.eclipse.jgit.packaging/org.eclipse.jgit.ssh.apache.source.feature/.gitignore deleted file mode 100644 index eb5a316cbd..0000000000 --- a/org.eclipse.jgit.packaging/org.eclipse.jgit.ssh.apache.source.feature/.gitignore +++ /dev/null @@ -1 +0,0 @@ -target diff --git a/org.eclipse.jgit.packaging/org.eclipse.jgit.ssh.apache.source.feature/.project b/org.eclipse.jgit.packaging/org.eclipse.jgit.ssh.apache.source.feature/.project deleted file mode 100644 index 55620844ff..0000000000 --- a/org.eclipse.jgit.packaging/org.eclipse.jgit.ssh.apache.source.feature/.project +++ /dev/null @@ -1,17 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<projectDescription> - <name>org.eclipse.jgit.ssh.apache.source.feature</name> - <comment></comment> - <projects> - </projects> - <buildSpec> - <buildCommand> - <name>org.eclipse.pde.FeatureBuilder</name> - <arguments> - </arguments> - </buildCommand> - </buildSpec> - <natures> - <nature>org.eclipse.pde.FeatureNature</nature> - </natures> -</projectDescription> diff --git a/org.eclipse.jgit.packaging/org.eclipse.jgit.ssh.apache.source.feature/.settings/org.eclipse.core.resources.prefs b/org.eclipse.jgit.packaging/org.eclipse.jgit.ssh.apache.source.feature/.settings/org.eclipse.core.resources.prefs deleted file mode 100644 index 6f96ce809a..0000000000 --- a/org.eclipse.jgit.packaging/org.eclipse.jgit.ssh.apache.source.feature/.settings/org.eclipse.core.resources.prefs +++ /dev/null @@ -1,3 +0,0 @@ -#Fri Jun 18 23:33:45 CEST 2010
-eclipse.preferences.version=1
-encoding/<project>=UTF-8
diff --git a/org.eclipse.jgit.packaging/org.eclipse.jgit.ssh.apache.source.feature/.settings/org.eclipse.core.runtime.prefs b/org.eclipse.jgit.packaging/org.eclipse.jgit.ssh.apache.source.feature/.settings/org.eclipse.core.runtime.prefs deleted file mode 100644 index 1a32dba177..0000000000 --- a/org.eclipse.jgit.packaging/org.eclipse.jgit.ssh.apache.source.feature/.settings/org.eclipse.core.runtime.prefs +++ /dev/null @@ -1,3 +0,0 @@ -#Fri Jun 18 23:33:45 CEST 2010
-eclipse.preferences.version=1
-line.separator=\n
diff --git a/org.eclipse.jgit.packaging/org.eclipse.jgit.ssh.apache.source.feature/.settings/org.eclipse.mylyn.tasks.ui.prefs b/org.eclipse.jgit.packaging/org.eclipse.jgit.ssh.apache.source.feature/.settings/org.eclipse.mylyn.tasks.ui.prefs deleted file mode 100644 index 823c0f56ae..0000000000 --- a/org.eclipse.jgit.packaging/org.eclipse.jgit.ssh.apache.source.feature/.settings/org.eclipse.mylyn.tasks.ui.prefs +++ /dev/null @@ -1,4 +0,0 @@ -#Tue Jul 19 20:11:28 CEST 2011 -eclipse.preferences.version=1 -project.repository.kind=bugzilla -project.repository.url=https\://bugs.eclipse.org/bugs diff --git a/org.eclipse.jgit.packaging/org.eclipse.jgit.ssh.apache.source.feature/.settings/org.eclipse.mylyn.team.ui.prefs b/org.eclipse.jgit.packaging/org.eclipse.jgit.ssh.apache.source.feature/.settings/org.eclipse.mylyn.team.ui.prefs deleted file mode 100644 index 2fca432276..0000000000 --- a/org.eclipse.jgit.packaging/org.eclipse.jgit.ssh.apache.source.feature/.settings/org.eclipse.mylyn.team.ui.prefs +++ /dev/null @@ -1,3 +0,0 @@ -#Tue Jul 19 20:11:28 CEST 2011 -commit.comment.template=${task.description}\n\nBug\: ${task.key} -eclipse.preferences.version=1 diff --git a/org.eclipse.jgit.packaging/org.eclipse.jgit.ssh.apache.source.feature/build.properties b/org.eclipse.jgit.packaging/org.eclipse.jgit.ssh.apache.source.feature/build.properties deleted file mode 100644 index b4a8dde9e5..0000000000 --- a/org.eclipse.jgit.packaging/org.eclipse.jgit.ssh.apache.source.feature/build.properties +++ /dev/null @@ -1,4 +0,0 @@ -bin.includes = feature.xml,\ - edl-v10.html,\ - feature.properties,\ - license.html diff --git a/org.eclipse.jgit.packaging/org.eclipse.jgit.ssh.apache.source.feature/edl-v10.html b/org.eclipse.jgit.packaging/org.eclipse.jgit.ssh.apache.source.feature/edl-v10.html deleted file mode 100644 index 8caddac569..0000000000 --- a/org.eclipse.jgit.packaging/org.eclipse.jgit.ssh.apache.source.feature/edl-v10.html +++ /dev/null @@ -1,59 +0,0 @@ -<?xml version="1.0" encoding="ISO-8859-1" ?> -<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> -<html xmlns="http://www.w3.org/1999/xhtml"> - -<head> -<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1" /> -<title>Eclipse Distribution License - Version 1.0</title> -<style type="text/css"> - body { - size: 8.5in 11.0in; - margin: 0.25in 0.5in 0.25in 0.5in; - tab-interval: 0.5in; - } - p { - margin-left: auto; - margin-top: 0.5em; - margin-bottom: 0.5em; - } - p.list { - margin-left: 0.5in; - margin-top: 0.05em; - margin-bottom: 0.05em; - } -</style> - -</head> - -<body lang="EN-US"> - -<p><b>Eclipse Distribution License - v 1.0</b></p> - -<p>Copyright (c) 2007, Eclipse Foundation, Inc. and its licensors. </p> - -<p>All rights reserved.</p> -<p>Redistribution and use in source and binary forms, with or without modification, - are permitted provided that the following conditions are met: -<ul><li>Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. </li> -<li>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. </li> -<li>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. </li></ul> -</p> -<p>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.</p> - -</body> - -</html> diff --git a/org.eclipse.jgit.packaging/org.eclipse.jgit.ssh.apache.source.feature/feature.properties b/org.eclipse.jgit.packaging/org.eclipse.jgit.ssh.apache.source.feature/feature.properties deleted file mode 100644 index 9935431824..0000000000 --- a/org.eclipse.jgit.packaging/org.eclipse.jgit.ssh.apache.source.feature/feature.properties +++ /dev/null @@ -1,178 +0,0 @@ -############################################################################### -# Copyright (c) 2000, 2010 IBM Corporation and others. -# -# All rights reserved. This program and the accompanying materials -# are made available under the terms of the Eclipse Public License v1.0 -# which accompanies this distribution, and is available at -# http://www.eclipse.org/legal/epl-v10.html -# -############################################################################### - -featureName=Java implementation of Git - ssh support using Apache MINA sshd - Source Code -providerName=Eclipse JGit - -updateSiteName=Eclipse JGit Update Site - -# description property - text of the "Feature Description" -description=\ -Do not install in your IDE: this feature is meant to provision Target Platforms.\n\ -Source code for the JGit ssh support using Apache MINA sshd.\n -################ end of description property ################################## - -# "copyright" property - text of the "Feature Update Copyright" -copyright=\ -Copyright (c) 2018 Thomas Wolf and others\n\ -All rights reserved. This program and the accompanying materials\n\ -are made available under the terms of the Eclipse Distribution License v1.0\n\ -which accompanies this distribution, and is available at\n\ -http://www.eclipse.org/org/documents/edl-v10.html\n -################ end of copyright property #################################### - -# "licenseURL" property - URL of the "Feature License" -# do not translate value - just change to point to a locale-specific HTML page -licenseURL=license.html - -# "license" property - text of the "Feature Update License" -# should be plain text version of license agreement pointed to be "licenseURL" -license=\ -Eclipse Foundation Software User Agreement\n\ -\n\ -November 22, 2017\n\ -\n\ -Usage Of Content\n\ -\n\ -THE ECLIPSE FOUNDATION MAKES AVAILABLE SOFTWARE, DOCUMENTATION, INFORMATION\n\ -AND/OR OTHER MATERIALS FOR OPEN SOURCE PROJECTS (COLLECTIVELY "CONTENT"). USE OF\n\ -THE CONTENT IS GOVERNED BY THE TERMS AND CONDITIONS OF THIS AGREEMENT AND/OR THE\n\ -TERMS AND CONDITIONS OF LICENSE AGREEMENTS OR NOTICES INDICATED OR REFERENCED\n\ -BELOW. BY USING THE CONTENT, YOU AGREE THAT YOUR USE OF THE CONTENT IS GOVERNED\n\ -BY THIS AGREEMENT AND/OR THE TERMS AND CONDITIONS OF ANY APPLICABLE LICENSE\n\ -AGREEMENTS OR NOTICES INDICATED OR REFERENCED BELOW. IF YOU DO NOT AGREE TO THE\n\ -TERMS AND CONDITIONS OF THIS AGREEMENT AND THE TERMS AND CONDITIONS OF ANY\n\ -APPLICABLE LICENSE AGREEMENTS OR NOTICES INDICATED OR REFERENCED BELOW, THEN YOU\n\ -MAY NOT USE THE CONTENT.\n\ -\n\ -Applicable Licenses\n\ -\n\ -Unless otherwise indicated, all Content made available by the Eclipse Foundation\n\ -is provided to you under the terms and conditions of the Eclipse Public License\n\ -Version 2.0 ("EPL"). A copy of the EPL is provided with this Content and is also\n\ -available at http://www.eclipse.org/legal/epl-2.0. For purposes of the EPL,\n\ -"Program" will mean the Content.\n\ -\n\ -Content includes, but is not limited to, source code, object code, documentation\n\ -and other files maintained in the Eclipse Foundation source code repository\n\ -("Repository") in software modules ("Modules") and made available as\n\ -downloadable archives ("Downloads").\n\ -\n\ -- Content may be structured and packaged into modules to facilitate\n\ - delivering, extending, and upgrading the Content. Typical modules may\n\ - include plug-ins ("Plug-ins"), plug-in fragments ("Fragments"), and\n\ - features ("Features").\n\ -- Each Plug-in or Fragment may be packaged as a sub-directory or JAR\n\ - (Javaâ„¢ ARchive) in a directory named "plugins".\n\ -- A Feature is a bundle of one or more Plug-ins and/or Fragments and\n\ - associated material. Each Feature may be packaged as a sub-directory in a\n\ - directory named "features". Within a Feature, files named "feature.xml" may\n\ - contain a list of the names and version numbers of the Plug-ins and/or\n\ - Fragments associated with that Feature.\n\ -- Features may also include other Features ("Included Features"). Within a\n\ - Feature, files named "feature.xml" may contain a list of the names and\n\ - version numbers of Included Features.\n\ -\n\ -The terms and conditions governing Plug-ins and Fragments should be contained in\n\ -files named "about.html" ("Abouts"). The terms and conditions governing Features\n\ -and Included Features should be contained in files named "license.html"\n\ -("Feature Licenses"). Abouts and Feature Licenses may be located in any\n\ -directory of a Download or Module including, but not limited to the following\n\ -locations:\n\ -\n\ -- The top-level (root) directory\n\ -- Plug-in and Fragment directories\n\ -- Inside Plug-ins and Fragments packaged as JARs\n\ -- Sub-directories of the directory named "src" of certain Plug-ins\n\ -- Feature directories\n\ -\n\ -Note: if a Feature made available by the Eclipse Foundation is installed using\n\ -the Provisioning Technology (as defined below), you must agree to a license\n\ -("Feature Update License") during the installation process. If the Feature\n\ -contains Included Features, the Feature Update License should either provide you\n\ -with the terms and conditions governing the Included Features or inform you\n\ -where you can locate them. Feature Update Licenses may be found in the "license"\n\ -property of files named "feature.properties" found within a Feature. Such\n\ -Abouts, Feature Licenses, and Feature Update Licenses contain the terms and\n\ -conditions (or references to such terms and conditions) that govern your use of\n\ -the associated Content in that directory.\n\ -\n\ -THE ABOUTS, FEATURE LICENSES, AND FEATURE UPDATE LICENSES MAY REFER TO THE EPL\n\ -OR OTHER LICENSE AGREEMENTS, NOTICES OR TERMS AND CONDITIONS. SOME OF THESE\n\ -OTHER LICENSE AGREEMENTS MAY INCLUDE (BUT ARE NOT LIMITED TO):\n\ -\n\ -- Eclipse Public License Version 1.0 (available at\n\ - http://www.eclipse.org/legal/epl-v10.html)\n\ -- Eclipse Distribution License Version 1.0 (available at\n\ - http://www.eclipse.org/licenses/edl-v1.0.html)\n\ -- Common Public License Version 1.0 (available at\n\ - http://www.eclipse.org/legal/cpl-v10.html)\n\ -- Apache Software License 1.1 (available at\n\ - http://www.apache.org/licenses/LICENSE)\n\ -- Apache Software License 2.0 (available at\n\ - http://www.apache.org/licenses/LICENSE-2.0)\n\ -- Mozilla Public License Version 1.1 (available at\n\ - http://www.mozilla.org/MPL/MPL-1.1.html)\n\ -\n\ -IT IS YOUR OBLIGATION TO READ AND ACCEPT ALL SUCH TERMS AND CONDITIONS PRIOR TO\n\ -USE OF THE CONTENT. If no About, Feature License, or Feature Update License is\n\ -provided, please contact the Eclipse Foundation to determine what terms and\n\ -conditions govern that particular Content.\n\ -\n\ -Use of Provisioning Technology\n\ -\n\ -The Eclipse Foundation makes available provisioning software, examples of which\n\ -include, but are not limited to, p2 and the Eclipse Update Manager\n\ -("Provisioning Technology") for the purpose of allowing users to install\n\ -software, documentation, information and/or other materials (collectively\n\ -"Installable Software"). This capability is provided with the intent of allowing\n\ -such users to install, extend and update Eclipse-based products. Information\n\ -about packaging Installable Software is available at\n\ -http://eclipse.org/equinox/p2/repository_packaging.html ("Specification").\n\ -\n\ -You may use Provisioning Technology to allow other parties to install\n\ -Installable Software. You shall be responsible for enabling the applicable\n\ -license agreements relating to the Installable Software to be presented to, and\n\ -accepted by, the users of the Provisioning Technology in accordance with the\n\ -Specification. By using Provisioning Technology in such a manner and making it\n\ -available in accordance with the Specification, you further acknowledge your\n\ -agreement to, and the acquisition of all necessary rights to permit the\n\ -following:\n\ -\n\ -1. A series of actions may occur ("Provisioning Process") in which a user may\n\ - execute the Provisioning Technology on a machine ("Target Machine") with the\n\ - intent of installing, extending or updating the functionality of an\n\ - Eclipse-based product.\n\ -2. During the Provisioning Process, the Provisioning Technology may cause third\n\ - party Installable Software or a portion thereof to be accessed and copied to\n\ - the Target Machine.\n\ -3. Pursuant to the Specification, you will provide to the user the terms and\n\ - conditions that govern the use of the Installable Software ("Installable\n\ - Software Agreement") and such Installable Software Agreement shall be\n\ - accessed from the Target Machine in accordance with the Specification. Such\n\ - Installable Software Agreement must inform the user of the terms and\n\ - conditions that govern the Installable Software and must solicit acceptance\n\ - by the end user in the manner prescribed in such Installable\n\ - Software Agreement. Upon such indication of agreement by the user, the\n\ - provisioning Technology will complete installation of the\n\ - Installable Software.\n\ -\n\ -Cryptography\n\ -\n\ -Content may contain encryption software. The country in which you are currently\n\ -may have restrictions on the import, possession, and use, and/or re-export to\n\ -another country, of encryption software. BEFORE using any encryption software,\n\ -please check the country's laws, regulations and policies concerning the import,\n\ -possession, or use, and re-export of encryption software, to see if this is\n\ -permitted.\n\ -\n\ -Java and all Java-based trademarks are trademarks of Oracle Corporation in the\n\ -United States, other countries, or both.\n -########### end of license property ########################################## diff --git a/org.eclipse.jgit.packaging/org.eclipse.jgit.ssh.apache.source.feature/feature.xml b/org.eclipse.jgit.packaging/org.eclipse.jgit.ssh.apache.source.feature/feature.xml deleted file mode 100644 index e0ef793a54..0000000000 --- a/org.eclipse.jgit.packaging/org.eclipse.jgit.ssh.apache.source.feature/feature.xml +++ /dev/null @@ -1,31 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<feature - id="org.eclipse.jgit.ssh.apache.source" - label="%featureName" - version="5.3.3.qualifier" - provider-name="%providerName"> - - <description url="http://www.eclipse.org/jgit/"> - %description - </description> - - <copyright> - %copyright - </copyright> - - <license url="%licenseURL"> - %license - </license> - - <url> - <update label="%updateSiteName" url="http://download.eclipse.org/egit/updates"/> - <discovery label="%updateSiteName" url="http://download.eclipse.org/egit/updates"/> - </url> - - <plugin - id="org.eclipse.jgit.ssh.apache.source" - download-size="0" - install-size="0" - version="0.0.0" - unpack="false"/> -</feature> diff --git a/org.eclipse.jgit.packaging/org.eclipse.jgit.ssh.apache.source.feature/license.html b/org.eclipse.jgit.packaging/org.eclipse.jgit.ssh.apache.source.feature/license.html deleted file mode 100644 index 008b8018db..0000000000 --- a/org.eclipse.jgit.packaging/org.eclipse.jgit.ssh.apache.source.feature/license.html +++ /dev/null @@ -1,189 +0,0 @@ -<?xml version="1.0" encoding="ISO-8859-1" ?> -<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> -<html xmlns="http://www.w3.org/1999/xhtml"> -<head> -<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1" /> -<title>Eclipse Foundation Software User Agreement</title> -</head> - -<body lang="EN-US"> - <h2>Eclipse Foundation Software User Agreement</h2> - <p>November 22, 2017</p> - - <h3>Usage Of Content</h3> - - <p>THE ECLIPSE FOUNDATION MAKES AVAILABLE SOFTWARE, DOCUMENTATION, - INFORMATION AND/OR OTHER MATERIALS FOR OPEN SOURCE PROJECTS - (COLLECTIVELY "CONTENT"). USE OF THE CONTENT IS GOVERNED BY - THE TERMS AND CONDITIONS OF THIS AGREEMENT AND/OR THE TERMS AND - CONDITIONS OF LICENSE AGREEMENTS OR NOTICES INDICATED OR REFERENCED - BELOW. BY USING THE CONTENT, YOU AGREE THAT YOUR USE OF THE CONTENT IS - GOVERNED BY THIS AGREEMENT AND/OR THE TERMS AND CONDITIONS OF ANY - APPLICABLE LICENSE AGREEMENTS OR NOTICES INDICATED OR REFERENCED - BELOW. IF YOU DO NOT AGREE TO THE TERMS AND CONDITIONS OF THIS - AGREEMENT AND THE TERMS AND CONDITIONS OF ANY APPLICABLE LICENSE - AGREEMENTS OR NOTICES INDICATED OR REFERENCED BELOW, THEN YOU MAY NOT - USE THE CONTENT.</p> - - <h3>Applicable Licenses</h3> - - <p> - Unless otherwise indicated, all Content made available by the Eclipse - Foundation is provided to you under the terms and conditions of the - Eclipse Public License Version 2.0 ("EPL"). A copy of the - EPL is provided with this Content and is also available at <a - href="http://www.eclipse.org/legal/epl-2.0">http://www.eclipse.org/legal/epl-2.0</a>. - For purposes of the EPL, "Program" will mean the Content. - </p> - - <p>Content includes, but is not limited to, source code, object - code, documentation and other files maintained in the Eclipse - Foundation source code repository ("Repository") in software - modules ("Modules") and made available as downloadable - archives ("Downloads").</p> - - <ul> - <li>Content may be structured and packaged into modules to - facilitate delivering, extending, and upgrading the Content. Typical - modules may include plug-ins ("Plug-ins"), plug-in - fragments ("Fragments"), and features - ("Features").</li> - <li>Each Plug-in or Fragment may be packaged as a sub-directory - or JAR (Java™ ARchive) in a directory named - "plugins".</li> - <li>A Feature is a bundle of one or more Plug-ins and/or - Fragments and associated material. Each Feature may be packaged as a - sub-directory in a directory named "features". Within a - Feature, files named "feature.xml" may contain a list of - the names and version numbers of the Plug-ins and/or Fragments - associated with that Feature.</li> - <li>Features may also include other Features ("Included - Features"). Within a Feature, files named - "feature.xml" may contain a list of the names and version - numbers of Included Features.</li> - </ul> - - <p>The terms and conditions governing Plug-ins and Fragments should - be contained in files named "about.html" - ("Abouts"). The terms and conditions governing Features and - Included Features should be contained in files named - "license.html" ("Feature Licenses"). Abouts and - Feature Licenses may be located in any directory of a Download or - Module including, but not limited to the following locations:</p> - - <ul> - <li>The top-level (root) directory</li> - <li>Plug-in and Fragment directories</li> - <li>Inside Plug-ins and Fragments packaged as JARs</li> - <li>Sub-directories of the directory named "src" of - certain Plug-ins</li> - <li>Feature directories</li> - </ul> - - <p>Note: if a Feature made available by the Eclipse Foundation is - installed using the Provisioning Technology (as defined below), you - must agree to a license ("Feature Update License") during - the installation process. If the Feature contains Included Features, - the Feature Update License should either provide you with the terms - and conditions governing the Included Features or inform you where you - can locate them. Feature Update Licenses may be found in the - "license" property of files named - "feature.properties" found within a Feature. Such Abouts, - Feature Licenses, and Feature Update Licenses contain the terms and - conditions (or references to such terms and conditions) that govern - your use of the associated Content in that directory.</p> - - <p>THE ABOUTS, FEATURE LICENSES, AND FEATURE UPDATE LICENSES MAY - REFER TO THE EPL OR OTHER LICENSE AGREEMENTS, NOTICES OR TERMS AND - CONDITIONS. SOME OF THESE OTHER LICENSE AGREEMENTS MAY INCLUDE (BUT - ARE NOT LIMITED TO):</p> - - <ul> - <li>Eclipse Public License Version 1.0 (available at <a - href="http://www.eclipse.org/legal/epl-v10.html">http://www.eclipse.org/legal/epl-v10.html</a>) - </li> - <li>Eclipse Distribution License Version 1.0 (available at <a - href="http://www.eclipse.org/licenses/edl-v10.html">http://www.eclipse.org/licenses/edl-v1.0.html</a>) - </li> - <li>Common Public License Version 1.0 (available at <a - href="http://www.eclipse.org/legal/cpl-v10.html">http://www.eclipse.org/legal/cpl-v10.html</a>) - </li> - <li>Apache Software License 1.1 (available at <a - href="http://www.apache.org/licenses/LICENSE">http://www.apache.org/licenses/LICENSE</a>) - </li> - <li>Apache Software License 2.0 (available at <a - href="http://www.apache.org/licenses/LICENSE-2.0">http://www.apache.org/licenses/LICENSE-2.0</a>) - </li> - <li>Mozilla Public License Version 1.1 (available at <a - href="http://www.mozilla.org/MPL/MPL-1.1.html">http://www.mozilla.org/MPL/MPL-1.1.html</a>) - </li> - </ul> - - <p>IT IS YOUR OBLIGATION TO READ AND ACCEPT ALL SUCH TERMS AND - CONDITIONS PRIOR TO USE OF THE CONTENT. If no About, Feature License, - or Feature Update License is provided, please contact the Eclipse - Foundation to determine what terms and conditions govern that - particular Content.</p> - - - <h3>Use of Provisioning Technology</h3> - - <p> - The Eclipse Foundation makes available provisioning software, examples - of which include, but are not limited to, p2 and the Eclipse Update - Manager ("Provisioning Technology") for the purpose of - allowing users to install software, documentation, information and/or - other materials (collectively "Installable Software"). This - capability is provided with the intent of allowing such users to - install, extend and update Eclipse-based products. Information about - packaging Installable Software is available at <a - href="http://eclipse.org/equinox/p2/repository_packaging.html">http://eclipse.org/equinox/p2/repository_packaging.html</a> - ("Specification"). - </p> - - <p>You may use Provisioning Technology to allow other parties to - install Installable Software. You shall be responsible for enabling - the applicable license agreements relating to the Installable Software - to be presented to, and accepted by, the users of the Provisioning - Technology in accordance with the Specification. By using Provisioning - Technology in such a manner and making it available in accordance with - the Specification, you further acknowledge your agreement to, and the - acquisition of all necessary rights to permit the following:</p> - - <ol> - <li>A series of actions may occur ("Provisioning - Process") in which a user may execute the Provisioning - Technology on a machine ("Target Machine") with the intent - of installing, extending or updating the functionality of an - Eclipse-based product.</li> - <li>During the Provisioning Process, the Provisioning Technology - may cause third party Installable Software or a portion thereof to be - accessed and copied to the Target Machine.</li> - <li>Pursuant to the Specification, you will provide to the user - the terms and conditions that govern the use of the Installable - Software ("Installable Software Agreement") and such - Installable Software Agreement shall be accessed from the Target - Machine in accordance with the Specification. Such Installable - Software Agreement must inform the user of the terms and conditions - that govern the Installable Software and must solicit acceptance by - the end user in the manner prescribed in such Installable Software - Agreement. Upon such indication of agreement by the user, the - provisioning Technology will complete installation of the Installable - Software.</li> - </ol> - - <h3>Cryptography</h3> - - <p>Content may contain encryption software. The country in which - you are currently may have restrictions on the import, possession, and - use, and/or re-export to another country, of encryption software. - BEFORE using any encryption software, please check the country's laws, - regulations and policies concerning the import, possession, or use, - and re-export of encryption software, to see if this is permitted.</p> - - <p> - <small>Java and all Java-based trademarks are trademarks of - Oracle Corporation in the United States, other countries, or both.</small> - </p> -</body> -</html> diff --git a/org.eclipse.jgit.packaging/org.eclipse.jgit.ssh.apache.source.feature/pom.xml b/org.eclipse.jgit.packaging/org.eclipse.jgit.ssh.apache.source.feature/pom.xml deleted file mode 100644 index 1ac70b0634..0000000000 --- a/org.eclipse.jgit.packaging/org.eclipse.jgit.ssh.apache.source.feature/pom.xml +++ /dev/null @@ -1,62 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<!-- - 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. ---> - -<project xmlns="http://maven.apache.org/POM/4.0.0" - xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" - xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"> - <modelVersion>4.0.0</modelVersion> - - <parent> - <groupId>org.eclipse.jgit</groupId> - <artifactId>jgit.tycho.parent</artifactId> - <version>5.3.3-SNAPSHOT</version> - </parent> - - <groupId>org.eclipse.jgit.feature</groupId> - <artifactId>org.eclipse.jgit.ssh.apache.source</artifactId> - <packaging>eclipse-feature</packaging> - - <name>JGit Apache MINA ssh Source Feature</name> - -</project> diff --git a/org.eclipse.jgit.packaging/org.eclipse.jgit.target/.classpath b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/.classpath deleted file mode 100644 index eca7bdba8f..0000000000 --- a/org.eclipse.jgit.packaging/org.eclipse.jgit.target/.classpath +++ /dev/null @@ -1,7 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<classpath> - <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.8"/> - <classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/> - <classpathentry kind="src" path="src"/> - <classpathentry kind="output" path="bin"/> -</classpath> diff --git a/org.eclipse.jgit.packaging/org.eclipse.jgit.target/.project b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/.project index 48c2bd1de3..ed148da848 100644 --- a/org.eclipse.jgit.packaging/org.eclipse.jgit.target/.project +++ b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/.project @@ -10,14 +10,8 @@ <arguments> </arguments> </buildCommand> - <buildCommand> - <name>org.eclipse.pde.ManifestBuilder</name> - <arguments> - </arguments> - </buildCommand> </buildSpec> <natures> - <nature>org.eclipse.pde.PluginNature</nature> <nature>org.eclipse.xtext.ui.shared.xtextNature</nature> </natures> </projectDescription> 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 deleted file mode 100644 index f28abfa1ac..0000000000 --- a/org.eclipse.jgit.packaging/org.eclipse.jgit.target/META-INF/MANIFEST.MF +++ /dev/null @@ -1,5 +0,0 @@ -Manifest-Version: 1.0 -Bundle-ManifestVersion: 2 -Bundle-Name: JGit Target Platform Bundle -Bundle-SymbolicName: org.eclipse.jgit.target -Bundle-Version: 5.3.3.qualifier diff --git a/org.eclipse.jgit.packaging/org.eclipse.jgit.target/build.properties b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/build.properties deleted file mode 100644 index 34d2e4d2da..0000000000 --- a/org.eclipse.jgit.packaging/org.eclipse.jgit.target/build.properties +++ /dev/null @@ -1,4 +0,0 @@ -source.. = src/ -output.. = bin/ -bin.includes = META-INF/,\ - . diff --git a/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.10.target b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.10.target index 86653bef02..36660ff3e6 100644 --- a/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.10.target +++ b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.10.target @@ -1,7 +1,7 @@ <?xml version="1.0" encoding="UTF-8" standalone="no"?> <?pde?> <!-- generated with https://github.com/eclipse-cbi/targetplatform-dsl --> -<target name="jgit-4.10" sequenceNumber="1566244557"> +<target name="jgit-4.10" sequenceNumber="1566251637"> <locations> <location includeMode="slicer" includeAllPlatforms="false" includeSource="true" includeConfigurePhase="true" type="InstallableUnit"> <unit id="org.eclipse.jetty.client" version="9.4.14.v20181114"/> @@ -37,12 +37,12 @@ <unit id="org.apache.httpcomponents.httpcore.source" version="4.4.10.v20190123-2214"/> <unit id="org.apache.log4j" version="1.2.15.v201012070815"/> <unit id="org.apache.log4j.source" version="1.2.15.v201012070815"/> - <unit id="org.bouncycastle.bcpg" version="1.60.0.v20181210-2057"/> - <unit id="org.bouncycastle.bcpg.source" version="1.60.0.v20181210-2057"/> - <unit id="org.bouncycastle.bcpkix" version="1.60.0.v20181210-2057"/> - <unit id="org.bouncycastle.bcpkix.source" version="1.60.0.v20181210-2057"/> - <unit id="org.bouncycastle.bcprov" version="1.60.0.v20181210-2057"/> - <unit id="org.bouncycastle.bcprov.source" version="1.60.0.v20181210-2057"/> + <unit id="org.bouncycastle.bcpg" version="1.61.0.v20190602-1335"/> + <unit id="org.bouncycastle.bcpg.source" version="1.61.0.v20190602-1335"/> + <unit id="org.bouncycastle.bcpkix" version="1.61.0.v20190602-1335"/> + <unit id="org.bouncycastle.bcpkix.source" version="1.61.0.v20190602-1335"/> + <unit id="org.bouncycastle.bcprov" version="1.61.0.v20190602-1335"/> + <unit id="org.bouncycastle.bcprov.source" version="1.61.0.v20190602-1335"/> <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"/> @@ -78,11 +78,11 @@ <unit id="com.jcraft.jzlib.source" version="1.1.1.v201205102305"/> <unit id="net.i2p.crypto.eddsa" version="0.3.0.v20181102-1323"/> <unit id="net.i2p.crypto.eddsa.source" version="0.3.0.v20181102-1323"/> - <unit id="org.apache.sshd.core" version="2.0.0.v20181102-1323"/> - <unit id="org.apache.sshd.core.source" version="2.0.0.v20181102-1323"/> - <unit id="org.apache.sshd.sftp" version="2.0.0.v20181102-1323"/> - <unit id="org.apache.sshd.sftp.source" version="2.0.0.v20181102-1323"/> - <repository location="http://download.eclipse.org/tools/orbit/downloads/drops/R20190602212107/repository"/> + <unit id="org.apache.sshd.osgi" version="2.2.0.v20190425-2127"/> + <unit id="org.apache.sshd.osgi.source" version="2.2.0.v20190425-2127"/> + <unit id="org.apache.sshd.sftp" version="2.2.0.v20190425-2127"/> + <unit id="org.apache.sshd.sftp.source" version="2.2.0.v20190425-2127"/> + <repository location="https://download.eclipse.org/tools/orbit/downloads/drops/R20190602212107/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.11-staging.tpd b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.11-staging.tpd deleted file mode 100644 index 4fc23eda87..0000000000 --- a/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.11-staging.tpd +++ /dev/null @@ -1,8 +0,0 @@ -target "jgit-4.11-staging" with source configurePhase - -include "projects/jetty-9.4.14.tpd" -include "orbit/R20190602212107-2019-06.tpd" - -location "http://download.eclipse.org/staging/2019-03/" { - org.eclipse.osgi lazy -} diff --git a/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.11.target b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.11.target new file mode 100644 index 0000000000..afa4b3da2c --- /dev/null +++ b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.11.target @@ -0,0 +1,92 @@ +<?xml version="1.0" encoding="UTF-8" standalone="no"?> +<?pde?> +<!-- generated with https://github.com/eclipse-cbi/targetplatform-dsl --> +<target name="jgit-4.11" sequenceNumber="1566251633"> + <locations> + <location includeMode="slicer" includeAllPlatforms="false" includeSource="true" includeConfigurePhase="true" type="InstallableUnit"> + <unit id="org.eclipse.jetty.client" version="9.4.14.v20181114"/> + <unit id="org.eclipse.jetty.client.source" version="9.4.14.v20181114"/> + <unit id="org.eclipse.jetty.continuation" version="9.4.14.v20181114"/> + <unit id="org.eclipse.jetty.continuation.source" version="9.4.14.v20181114"/> + <unit id="org.eclipse.jetty.http" version="9.4.14.v20181114"/> + <unit id="org.eclipse.jetty.http.source" version="9.4.14.v20181114"/> + <unit id="org.eclipse.jetty.io" version="9.4.14.v20181114"/> + <unit id="org.eclipse.jetty.io.source" version="9.4.14.v20181114"/> + <unit id="org.eclipse.jetty.security" version="9.4.14.v20181114"/> + <unit id="org.eclipse.jetty.security.source" version="9.4.14.v20181114"/> + <unit id="org.eclipse.jetty.server" version="9.4.14.v20181114"/> + <unit id="org.eclipse.jetty.server.source" version="9.4.14.v20181114"/> + <unit id="org.eclipse.jetty.servlet" version="9.4.14.v20181114"/> + <unit id="org.eclipse.jetty.servlet.source" version="9.4.14.v20181114"/> + <unit id="org.eclipse.jetty.util" version="9.4.14.v20181114"/> + <unit id="org.eclipse.jetty.util.source" version="9.4.14.v20181114"/> + <repository id="jetty-9.4.14" location="http://download.eclipse.org/jetty/updates/jetty-bundles-9.x/9.4.14.v20181114"/> + </location> + <location includeMode="slicer" includeAllPlatforms="false" includeSource="true" includeConfigurePhase="true" type="InstallableUnit"> + <unit id="org.apache.ant" version="1.10.5.v20190526-1402"/> + <unit id="org.apache.ant.source" version="1.10.5.v20190526-1402"/> + <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.18.0.v20181121-2221"/> + <unit id="org.apache.commons.compress.source" version="1.18.0.v20181121-2221"/> + <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.6.v20190503-0009"/> + <unit id="org.apache.httpcomponents.httpclient.source" version="4.5.6.v20190503-0009"/> + <unit id="org.apache.httpcomponents.httpcore" version="4.4.10.v20190123-2214"/> + <unit id="org.apache.httpcomponents.httpcore.source" version="4.4.10.v20190123-2214"/> + <unit id="org.apache.log4j" version="1.2.15.v201012070815"/> + <unit id="org.apache.log4j.source" version="1.2.15.v201012070815"/> + <unit id="org.bouncycastle.bcpg" version="1.61.0.v20190602-1335"/> + <unit id="org.bouncycastle.bcpg.source" version="1.61.0.v20190602-1335"/> + <unit id="org.bouncycastle.bcpkix" version="1.61.0.v20190602-1335"/> + <unit id="org.bouncycastle.bcpkix.source" version="1.61.0.v20190602-1335"/> + <unit id="org.bouncycastle.bcprov" version="1.61.0.v20190602-1335"/> + <unit id="org.bouncycastle.bcprov.source" version="1.61.0.v20190602-1335"/> + <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="2.6.0.v20180420-1519"/> + <unit id="org.objenesis.source" version="2.6.0.v20180420-1519"/> + <unit id="org.mockito" version="2.23.0.v20190527-1420"/> + <unit id="org.mockito.source" version="2.23.0.v20190527-1420"/> + <unit id="net.bytebuddy.byte-buddy" version="1.9.0.v20181107-1410"/> + <unit id="net.bytebuddy.byte-buddy.source" version="1.9.0.v20181107-1410"/> + <unit id="net.bytebuddy.byte-buddy-agent" version="1.9.0.v20181106-1534"/> + <unit id="net.bytebuddy.byte-buddy-agent.source" version="1.9.0.v20181106-1534"/> + <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.55.v20190404-1902"/> + <unit id="com.jcraft.jsch.source" version="0.1.55.v20190404-1902"/> + <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.8.0.v20180207-1613"/> + <unit id="org.tukaani.xz.source" version="1.8.0.v20180207-1613"/> + <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"/> + <unit id="net.i2p.crypto.eddsa" version="0.3.0.v20181102-1323"/> + <unit id="net.i2p.crypto.eddsa.source" version="0.3.0.v20181102-1323"/> + <unit id="org.apache.sshd.osgi" version="2.2.0.v20190425-2127"/> + <unit id="org.apache.sshd.osgi.source" version="2.2.0.v20190425-2127"/> + <unit id="org.apache.sshd.sftp" version="2.2.0.v20190425-2127"/> + <unit id="org.apache.sshd.sftp.source" version="2.2.0.v20190425-2127"/> + <repository location="https://download.eclipse.org/tools/orbit/downloads/drops/R20190602212107/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/releases/2019-03/"/> + </location> + </locations> +</target> diff --git a/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.11.tpd b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.11.tpd new file mode 100644 index 0000000000..e09e8c387d --- /dev/null +++ b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.11.tpd @@ -0,0 +1,8 @@ +target "jgit-4.11" with source configurePhase + +include "projects/jetty-9.4.14.tpd" +include "orbit/R20190602212107-2019-06.tpd" + +location "http://download.eclipse.org/releases/2019-03/" { + org.eclipse.osgi lazy +} diff --git a/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.11-staging.target b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.12-staging.target index 0857af3979..92c9a88366 100644 --- a/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.11-staging.target +++ b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.12-staging.target @@ -1,7 +1,7 @@ <?xml version="1.0" encoding="UTF-8" standalone="no"?> <?pde?> <!-- generated with https://github.com/eclipse-cbi/targetplatform-dsl --> -<target name="jgit-4.11-staging" sequenceNumber="1566244434"> +<target name="jgit-4.12-staging" sequenceNumber="1566251632"> <locations> <location includeMode="slicer" includeAllPlatforms="false" includeSource="true" includeConfigurePhase="true" type="InstallableUnit"> <unit id="org.eclipse.jetty.client" version="9.4.14.v20181114"/> @@ -37,12 +37,12 @@ <unit id="org.apache.httpcomponents.httpcore.source" version="4.4.10.v20190123-2214"/> <unit id="org.apache.log4j" version="1.2.15.v201012070815"/> <unit id="org.apache.log4j.source" version="1.2.15.v201012070815"/> - <unit id="org.bouncycastle.bcpg" version="1.60.0.v20181210-2057"/> - <unit id="org.bouncycastle.bcpg.source" version="1.60.0.v20181210-2057"/> - <unit id="org.bouncycastle.bcpkix" version="1.60.0.v20181210-2057"/> - <unit id="org.bouncycastle.bcpkix.source" version="1.60.0.v20181210-2057"/> - <unit id="org.bouncycastle.bcprov" version="1.60.0.v20181210-2057"/> - <unit id="org.bouncycastle.bcprov.source" version="1.60.0.v20181210-2057"/> + <unit id="org.bouncycastle.bcpg" version="1.61.0.v20190602-1335"/> + <unit id="org.bouncycastle.bcpg.source" version="1.61.0.v20190602-1335"/> + <unit id="org.bouncycastle.bcpkix" version="1.61.0.v20190602-1335"/> + <unit id="org.bouncycastle.bcpkix.source" version="1.61.0.v20190602-1335"/> + <unit id="org.bouncycastle.bcprov" version="1.61.0.v20190602-1335"/> + <unit id="org.bouncycastle.bcprov.source" version="1.61.0.v20190602-1335"/> <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"/> @@ -78,15 +78,15 @@ <unit id="com.jcraft.jzlib.source" version="1.1.1.v201205102305"/> <unit id="net.i2p.crypto.eddsa" version="0.3.0.v20181102-1323"/> <unit id="net.i2p.crypto.eddsa.source" version="0.3.0.v20181102-1323"/> - <unit id="org.apache.sshd.core" version="2.0.0.v20181102-1323"/> - <unit id="org.apache.sshd.core.source" version="2.0.0.v20181102-1323"/> - <unit id="org.apache.sshd.sftp" version="2.0.0.v20181102-1323"/> - <unit id="org.apache.sshd.sftp.source" version="2.0.0.v20181102-1323"/> - <repository location="http://download.eclipse.org/tools/orbit/downloads/drops/R20190602212107/repository"/> + <unit id="org.apache.sshd.osgi" version="2.2.0.v20190425-2127"/> + <unit id="org.apache.sshd.osgi.source" version="2.2.0.v20190425-2127"/> + <unit id="org.apache.sshd.sftp" version="2.2.0.v20190425-2127"/> + <unit id="org.apache.sshd.sftp.source" version="2.2.0.v20190425-2127"/> + <repository location="https://download.eclipse.org/tools/orbit/downloads/drops/R20190602212107/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/2019-03/"/> + <repository location="http://download.eclipse.org/staging/2019-06/"/> </location> </locations> </target> diff --git a/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.12-staging.tpd b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.12-staging.tpd new file mode 100644 index 0000000000..43b64a0301 --- /dev/null +++ b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.12-staging.tpd @@ -0,0 +1,8 @@ +target "jgit-4.12-staging" with source configurePhase + +include "projects/jetty-9.4.14.tpd" +include "orbit/R20190602212107-2019-06.tpd" + +location "http://download.eclipse.org/staging/2019-06/" { + 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 05488b9c3d..9724939f8a 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,7 +1,7 @@ <?xml version="1.0" encoding="UTF-8" standalone="no"?> <?pde?> <!-- generated with https://github.com/eclipse-cbi/targetplatform-dsl --> -<target name="jgit-4.6" sequenceNumber="1566244561"> +<target name="jgit-4.6" sequenceNumber="1566251641"> <locations> <location includeMode="slicer" includeAllPlatforms="false" includeSource="true" includeConfigurePhase="true" type="InstallableUnit"> <unit id="org.eclipse.jetty.client" version="9.4.14.v20181114"/> @@ -37,12 +37,12 @@ <unit id="org.apache.httpcomponents.httpcore.source" version="4.4.10.v20190123-2214"/> <unit id="org.apache.log4j" version="1.2.15.v201012070815"/> <unit id="org.apache.log4j.source" version="1.2.15.v201012070815"/> - <unit id="org.bouncycastle.bcpg" version="1.60.0.v20181210-2057"/> - <unit id="org.bouncycastle.bcpg.source" version="1.60.0.v20181210-2057"/> - <unit id="org.bouncycastle.bcpkix" version="1.60.0.v20181210-2057"/> - <unit id="org.bouncycastle.bcpkix.source" version="1.60.0.v20181210-2057"/> - <unit id="org.bouncycastle.bcprov" version="1.60.0.v20181210-2057"/> - <unit id="org.bouncycastle.bcprov.source" version="1.60.0.v20181210-2057"/> + <unit id="org.bouncycastle.bcpg" version="1.61.0.v20190602-1335"/> + <unit id="org.bouncycastle.bcpg.source" version="1.61.0.v20190602-1335"/> + <unit id="org.bouncycastle.bcpkix" version="1.61.0.v20190602-1335"/> + <unit id="org.bouncycastle.bcpkix.source" version="1.61.0.v20190602-1335"/> + <unit id="org.bouncycastle.bcprov" version="1.61.0.v20190602-1335"/> + <unit id="org.bouncycastle.bcprov.source" version="1.61.0.v20190602-1335"/> <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"/> @@ -78,11 +78,11 @@ <unit id="com.jcraft.jzlib.source" version="1.1.1.v201205102305"/> <unit id="net.i2p.crypto.eddsa" version="0.3.0.v20181102-1323"/> <unit id="net.i2p.crypto.eddsa.source" version="0.3.0.v20181102-1323"/> - <unit id="org.apache.sshd.core" version="2.0.0.v20181102-1323"/> - <unit id="org.apache.sshd.core.source" version="2.0.0.v20181102-1323"/> - <unit id="org.apache.sshd.sftp" version="2.0.0.v20181102-1323"/> - <unit id="org.apache.sshd.sftp.source" version="2.0.0.v20181102-1323"/> - <repository location="http://download.eclipse.org/tools/orbit/downloads/drops/R20190602212107/repository"/> + <unit id="org.apache.sshd.osgi" version="2.2.0.v20190425-2127"/> + <unit id="org.apache.sshd.osgi.source" version="2.2.0.v20190425-2127"/> + <unit id="org.apache.sshd.sftp" version="2.2.0.v20190425-2127"/> + <unit id="org.apache.sshd.sftp.source" version="2.2.0.v20190425-2127"/> + <repository location="https://download.eclipse.org/tools/orbit/downloads/drops/R20190602212107/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.target b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.7.target index e82222a0c5..6bd70e0160 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,7 +1,7 @@ <?xml version="1.0" encoding="UTF-8" standalone="no"?> <?pde?> <!-- generated with https://github.com/eclipse-cbi/targetplatform-dsl --> -<target name="jgit-4.7" sequenceNumber="1566244564"> +<target name="jgit-4.7" sequenceNumber="1566251627"> <locations> <location includeMode="slicer" includeAllPlatforms="false" includeSource="true" includeConfigurePhase="true" type="InstallableUnit"> <unit id="org.eclipse.jetty.client" version="9.4.14.v20181114"/> @@ -37,12 +37,12 @@ <unit id="org.apache.httpcomponents.httpcore.source" version="4.4.10.v20190123-2214"/> <unit id="org.apache.log4j" version="1.2.15.v201012070815"/> <unit id="org.apache.log4j.source" version="1.2.15.v201012070815"/> - <unit id="org.bouncycastle.bcpg" version="1.60.0.v20181210-2057"/> - <unit id="org.bouncycastle.bcpg.source" version="1.60.0.v20181210-2057"/> - <unit id="org.bouncycastle.bcpkix" version="1.60.0.v20181210-2057"/> - <unit id="org.bouncycastle.bcpkix.source" version="1.60.0.v20181210-2057"/> - <unit id="org.bouncycastle.bcprov" version="1.60.0.v20181210-2057"/> - <unit id="org.bouncycastle.bcprov.source" version="1.60.0.v20181210-2057"/> + <unit id="org.bouncycastle.bcpg" version="1.61.0.v20190602-1335"/> + <unit id="org.bouncycastle.bcpg.source" version="1.61.0.v20190602-1335"/> + <unit id="org.bouncycastle.bcpkix" version="1.61.0.v20190602-1335"/> + <unit id="org.bouncycastle.bcpkix.source" version="1.61.0.v20190602-1335"/> + <unit id="org.bouncycastle.bcprov" version="1.61.0.v20190602-1335"/> + <unit id="org.bouncycastle.bcprov.source" version="1.61.0.v20190602-1335"/> <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"/> @@ -78,11 +78,11 @@ <unit id="com.jcraft.jzlib.source" version="1.1.1.v201205102305"/> <unit id="net.i2p.crypto.eddsa" version="0.3.0.v20181102-1323"/> <unit id="net.i2p.crypto.eddsa.source" version="0.3.0.v20181102-1323"/> - <unit id="org.apache.sshd.core" version="2.0.0.v20181102-1323"/> - <unit id="org.apache.sshd.core.source" version="2.0.0.v20181102-1323"/> - <unit id="org.apache.sshd.sftp" version="2.0.0.v20181102-1323"/> - <unit id="org.apache.sshd.sftp.source" version="2.0.0.v20181102-1323"/> - <repository location="http://download.eclipse.org/tools/orbit/downloads/drops/R20190602212107/repository"/> + <unit id="org.apache.sshd.osgi" version="2.2.0.v20190425-2127"/> + <unit id="org.apache.sshd.osgi.source" version="2.2.0.v20190425-2127"/> + <unit id="org.apache.sshd.sftp" version="2.2.0.v20190425-2127"/> + <unit id="org.apache.sshd.sftp.source" version="2.2.0.v20190425-2127"/> + <repository location="https://download.eclipse.org/tools/orbit/downloads/drops/R20190602212107/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.target b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.8.target index 0b353db260..e33ece710a 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,7 +1,7 @@ <?xml version="1.0" encoding="UTF-8" standalone="no"?> <?pde?> <!-- generated with https://github.com/eclipse-cbi/targetplatform-dsl --> -<target name="jgit-4.8" sequenceNumber="1566244569"> +<target name="jgit-4.8" sequenceNumber="1566251616"> <locations> <location includeMode="slicer" includeAllPlatforms="false" includeSource="true" includeConfigurePhase="true" type="InstallableUnit"> <unit id="org.eclipse.jetty.client" version="9.4.14.v20181114"/> @@ -37,12 +37,12 @@ <unit id="org.apache.httpcomponents.httpcore.source" version="4.4.10.v20190123-2214"/> <unit id="org.apache.log4j" version="1.2.15.v201012070815"/> <unit id="org.apache.log4j.source" version="1.2.15.v201012070815"/> - <unit id="org.bouncycastle.bcpg" version="1.60.0.v20181210-2057"/> - <unit id="org.bouncycastle.bcpg.source" version="1.60.0.v20181210-2057"/> - <unit id="org.bouncycastle.bcpkix" version="1.60.0.v20181210-2057"/> - <unit id="org.bouncycastle.bcpkix.source" version="1.60.0.v20181210-2057"/> - <unit id="org.bouncycastle.bcprov" version="1.60.0.v20181210-2057"/> - <unit id="org.bouncycastle.bcprov.source" version="1.60.0.v20181210-2057"/> + <unit id="org.bouncycastle.bcpg" version="1.61.0.v20190602-1335"/> + <unit id="org.bouncycastle.bcpg.source" version="1.61.0.v20190602-1335"/> + <unit id="org.bouncycastle.bcpkix" version="1.61.0.v20190602-1335"/> + <unit id="org.bouncycastle.bcpkix.source" version="1.61.0.v20190602-1335"/> + <unit id="org.bouncycastle.bcprov" version="1.61.0.v20190602-1335"/> + <unit id="org.bouncycastle.bcprov.source" version="1.61.0.v20190602-1335"/> <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"/> @@ -78,11 +78,11 @@ <unit id="com.jcraft.jzlib.source" version="1.1.1.v201205102305"/> <unit id="net.i2p.crypto.eddsa" version="0.3.0.v20181102-1323"/> <unit id="net.i2p.crypto.eddsa.source" version="0.3.0.v20181102-1323"/> - <unit id="org.apache.sshd.core" version="2.0.0.v20181102-1323"/> - <unit id="org.apache.sshd.core.source" version="2.0.0.v20181102-1323"/> - <unit id="org.apache.sshd.sftp" version="2.0.0.v20181102-1323"/> - <unit id="org.apache.sshd.sftp.source" version="2.0.0.v20181102-1323"/> - <repository location="http://download.eclipse.org/tools/orbit/downloads/drops/R20190602212107/repository"/> + <unit id="org.apache.sshd.osgi" version="2.2.0.v20190425-2127"/> + <unit id="org.apache.sshd.osgi.source" version="2.2.0.v20190425-2127"/> + <unit id="org.apache.sshd.sftp" version="2.2.0.v20190425-2127"/> + <unit id="org.apache.sshd.sftp.source" version="2.2.0.v20190425-2127"/> + <repository location="https://download.eclipse.org/tools/orbit/downloads/drops/R20190602212107/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.9.target b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.9.target index 94a752c74c..9b3fe1b930 100644 --- a/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.9.target +++ b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.9.target @@ -1,7 +1,7 @@ <?xml version="1.0" encoding="UTF-8" standalone="no"?> <?pde?> <!-- generated with https://github.com/eclipse-cbi/targetplatform-dsl --> -<target name="jgit-4.9" sequenceNumber="1566244572"> +<target name="jgit-4.9" sequenceNumber="1566251604"> <locations> <location includeMode="slicer" includeAllPlatforms="false" includeSource="true" includeConfigurePhase="true" type="InstallableUnit"> <unit id="org.eclipse.jetty.client" version="9.4.14.v20181114"/> @@ -37,12 +37,12 @@ <unit id="org.apache.httpcomponents.httpcore.source" version="4.4.10.v20190123-2214"/> <unit id="org.apache.log4j" version="1.2.15.v201012070815"/> <unit id="org.apache.log4j.source" version="1.2.15.v201012070815"/> - <unit id="org.bouncycastle.bcpg" version="1.60.0.v20181210-2057"/> - <unit id="org.bouncycastle.bcpg.source" version="1.60.0.v20181210-2057"/> - <unit id="org.bouncycastle.bcpkix" version="1.60.0.v20181210-2057"/> - <unit id="org.bouncycastle.bcpkix.source" version="1.60.0.v20181210-2057"/> - <unit id="org.bouncycastle.bcprov" version="1.60.0.v20181210-2057"/> - <unit id="org.bouncycastle.bcprov.source" version="1.60.0.v20181210-2057"/> + <unit id="org.bouncycastle.bcpg" version="1.61.0.v20190602-1335"/> + <unit id="org.bouncycastle.bcpg.source" version="1.61.0.v20190602-1335"/> + <unit id="org.bouncycastle.bcpkix" version="1.61.0.v20190602-1335"/> + <unit id="org.bouncycastle.bcpkix.source" version="1.61.0.v20190602-1335"/> + <unit id="org.bouncycastle.bcprov" version="1.61.0.v20190602-1335"/> + <unit id="org.bouncycastle.bcprov.source" version="1.61.0.v20190602-1335"/> <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"/> @@ -78,11 +78,11 @@ <unit id="com.jcraft.jzlib.source" version="1.1.1.v201205102305"/> <unit id="net.i2p.crypto.eddsa" version="0.3.0.v20181102-1323"/> <unit id="net.i2p.crypto.eddsa.source" version="0.3.0.v20181102-1323"/> - <unit id="org.apache.sshd.core" version="2.0.0.v20181102-1323"/> - <unit id="org.apache.sshd.core.source" version="2.0.0.v20181102-1323"/> - <unit id="org.apache.sshd.sftp" version="2.0.0.v20181102-1323"/> - <unit id="org.apache.sshd.sftp.source" version="2.0.0.v20181102-1323"/> - <repository location="http://download.eclipse.org/tools/orbit/downloads/drops/R20190602212107/repository"/> + <unit id="org.apache.sshd.osgi" version="2.2.0.v20190425-2127"/> + <unit id="org.apache.sshd.osgi.source" version="2.2.0.v20190425-2127"/> + <unit id="org.apache.sshd.sftp" version="2.2.0.v20190425-2127"/> + <unit id="org.apache.sshd.sftp.source" version="2.2.0.v20190425-2127"/> + <repository location="https://download.eclipse.org/tools/orbit/downloads/drops/R20190602212107/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/orbit/R20190602212107-2019-06.tpd b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/orbit/R20190602212107-2019-06.tpd index 65d5c9f1f5..db674493b5 100644 --- a/org.eclipse.jgit.packaging/org.eclipse.jgit.target/orbit/R20190602212107-2019-06.tpd +++ b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/orbit/R20190602212107-2019-06.tpd @@ -1,7 +1,7 @@ target "R20190602212107-2019-06" with source configurePhase // see http://download.eclipse.org/tools/orbit/downloads/ -location "http://download.eclipse.org/tools/orbit/downloads/drops/R20190602212107/repository" { +location "https://download.eclipse.org/tools/orbit/downloads/drops/R20190602212107/repository" { org.apache.ant [1.10.5.v20190526-1402,1.10.5.v20190526-1402] org.apache.ant.source [1.10.5.v20190526-1402,1.10.5.v20190526-1402] org.apache.commons.codec [1.10.0.v20180409-1845,1.10.0.v20180409-1845] @@ -16,12 +16,12 @@ location "http://download.eclipse.org/tools/orbit/downloads/drops/R2019060221210 org.apache.httpcomponents.httpcore.source [4.4.10.v20190123-2214,4.4.10.v20190123-2214] org.apache.log4j [1.2.15.v201012070815,1.2.15.v201012070815] org.apache.log4j.source [1.2.15.v201012070815,1.2.15.v201012070815] - org.bouncycastle.bcpg [1.60.0.v20181210-2057,1.60.0.v20181210-2057] - org.bouncycastle.bcpg.source [1.60.0.v20181210-2057,1.60.0.v20181210-2057] - org.bouncycastle.bcpkix [1.60.0.v20181210-2057,1.60.0.v20181210-2057] - org.bouncycastle.bcpkix.source [1.60.0.v20181210-2057,1.60.0.v20181210-2057] - org.bouncycastle.bcprov [1.60.0.v20181210-2057,1.60.0.v20181210-2057] - org.bouncycastle.bcprov.source [1.60.0.v20181210-2057,1.60.0.v20181210-2057] + org.bouncycastle.bcpg [1.61.0.v20190602-1335,1.61.0.v20190602-1335] + org.bouncycastle.bcpg.source [1.61.0.v20190602-1335,1.61.0.v20190602-1335] + org.bouncycastle.bcpkix [1.61.0.v20190602-1335,1.61.0.v20190602-1335] + org.bouncycastle.bcpkix.source [1.61.0.v20190602-1335,1.61.0.v20190602-1335] + org.bouncycastle.bcprov [1.61.0.v20190602-1335,1.61.0.v20190602-1335] + org.bouncycastle.bcprov.source [1.61.0.v20190602-1335,1.61.0.v20190602-1335] 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] @@ -57,8 +57,9 @@ location "http://download.eclipse.org/tools/orbit/downloads/drops/R2019060221210 com.jcraft.jzlib.source [1.1.1.v201205102305,1.1.1.v201205102305] net.i2p.crypto.eddsa [0.3.0.v20181102-1323,0.3.0.v20181102-1323] net.i2p.crypto.eddsa.source [0.3.0.v20181102-1323,0.3.0.v20181102-1323] - org.apache.sshd.core [2.0.0.v20181102-1323,2.0.0.v20181102-1323] - org.apache.sshd.core.source [2.0.0.v20181102-1323,2.0.0.v20181102-1323] - org.apache.sshd.sftp [2.0.0.v20181102-1323,2.0.0.v20181102-1323] - org.apache.sshd.sftp.source [2.0.0.v20181102-1323,2.0.0.v20181102-1323] + org.apache.sshd.osgi [2.2.0.v20190425-2127,2.2.0.v20190425-2127] + org.apache.sshd.osgi.source [2.2.0.v20190425-2127,2.2.0.v20190425-2127] + org.apache.sshd.sftp [2.2.0.v20190425-2127,2.2.0.v20190425-2127] + org.apache.sshd.sftp.source [2.2.0.v20190425-2127,2.2.0.v20190425-2127] } + 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 532100be96..e632224b92 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.3.3-SNAPSHOT</version> + <version>5.4.1-SNAPSHOT</version> </parent> <artifactId>org.eclipse.jgit.target</artifactId> diff --git a/org.eclipse.jgit.packaging/pom.xml b/org.eclipse.jgit.packaging/pom.xml index 22f47f59df..6c5ced32ea 100644 --- a/org.eclipse.jgit.packaging/pom.xml +++ b/org.eclipse.jgit.packaging/pom.xml @@ -49,13 +49,13 @@ <groupId>org.eclipse.jgit</groupId> <artifactId>jgit.tycho.parent</artifactId> - <version>5.3.3-SNAPSHOT</version> + <version>5.4.1-SNAPSHOT</version> <packaging>pom</packaging> <name>JGit Tycho Parent</name> <properties> - <tycho-version>1.3.0</tycho-version> + <tycho-version>1.4.0</tycho-version> <tycho-extras-version>${tycho-version}</tycho-extras-version> <target-platform>jgit-4.6</target-platform> </properties> @@ -79,8 +79,6 @@ <module>org.eclipse.jgit.lfs.feature</module> <module>org.eclipse.jgit.pgm.feature</module> <module>org.eclipse.jgit.source.feature</module> - <module>org.eclipse.jgit.pgm.source.feature</module> - <module>org.eclipse.jgit.ssh.apache.source.feature</module> <module>org.eclipse.jgit.junit.feature</module> <module>org.eclipse.jgit.repository</module> </modules> @@ -109,6 +107,60 @@ </dependency> <dependency> <groupId>org.eclipse.jgit</groupId> + <artifactId>org.eclipse.jgit.ant</artifactId> + <version>${project.version}</version> + <classifier>sources</classifier> + </dependency> + <dependency> + <groupId>org.eclipse.jgit</groupId> + <artifactId>org.eclipse.jgit.archive</artifactId> + <version>${project.version}</version> + <classifier>sources</classifier> + </dependency> + <dependency> + <groupId>org.eclipse.jgit</groupId> + <artifactId>org.eclipse.jgit.http.apache</artifactId> + <version>${project.version}</version> + <classifier>sources</classifier> + </dependency> + <dependency> + <groupId>org.eclipse.jgit</groupId> + <artifactId>org.eclipse.jgit.http.server</artifactId> + <version>${project.version}</version> + <classifier>sources</classifier> + </dependency> + <dependency> + <groupId>org.eclipse.jgit</groupId> + <artifactId>org.eclipse.jgit.junit</artifactId> + <version>${project.version}</version> + <classifier>sources</classifier> + </dependency> + <dependency> + <groupId>org.eclipse.jgit</groupId> + <artifactId>org.eclipse.jgit.junit.http</artifactId> + <version>${project.version}</version> + <classifier>sources</classifier> + </dependency> + <dependency> + <groupId>org.eclipse.jgit</groupId> + <artifactId>org.eclipse.jgit.junit.ssh</artifactId> + <version>${project.version}</version> + <classifier>sources</classifier> + </dependency> + <dependency> + <groupId>org.eclipse.jgit</groupId> + <artifactId>org.eclipse.jgit.lfs</artifactId> + <version>${project.version}</version> + <classifier>sources</classifier> + </dependency> + <dependency> + <groupId>org.eclipse.jgit</groupId> + <artifactId>org.eclipse.jgit.lfs.server</artifactId> + <version>${project.version}</version> + <classifier>sources</classifier> + </dependency> + <dependency> + <groupId>org.eclipse.jgit</groupId> <artifactId>org.eclipse.jgit.pgm</artifactId> <version>${project.version}</version> <classifier>sources</classifier> @@ -119,6 +171,12 @@ <version>${project.version}</version> <classifier>sources</classifier> </dependency> + <dependency> + <groupId>org.eclipse.jgit</groupId> + <artifactId>org.eclipse.jgit.ui</artifactId> + <version>${project.version}</version> + <classifier>sources</classifier> + </dependency> </dependencies> <build> diff --git a/org.eclipse.jgit.pgm.test/.settings/org.eclipse.pde.prefs b/org.eclipse.jgit.pgm.test/.settings/org.eclipse.pde.prefs new file mode 100644 index 0000000000..2174e4fd5b --- /dev/null +++ b/org.eclipse.jgit.pgm.test/.settings/org.eclipse.pde.prefs @@ -0,0 +1,34 @@ +compilers.f.unresolved-features=1 +compilers.f.unresolved-plugins=1 +compilers.incompatible-environment=1 +compilers.p.build=1 +compilers.p.build.bin.includes=1 +compilers.p.build.encodings=2 +compilers.p.build.java.compiler=2 +compilers.p.build.java.compliance=1 +compilers.p.build.missing.output=2 +compilers.p.build.output.library=1 +compilers.p.build.source.library=1 +compilers.p.build.src.includes=1 +compilers.p.deprecated=1 +compilers.p.discouraged-class=1 +compilers.p.internal=1 +compilers.p.missing-packages=2 +compilers.p.missing-version-export-package=2 +compilers.p.missing-version-import-package=2 +compilers.p.missing-version-require-bundle=2 +compilers.p.no-required-att=0 +compilers.p.no.automatic.module=1 +compilers.p.not-externalized-att=2 +compilers.p.service.component.without.lazyactivation=1 +compilers.p.unknown-attribute=1 +compilers.p.unknown-class=1 +compilers.p.unknown-element=1 +compilers.p.unknown-identifier=1 +compilers.p.unknown-resource=1 +compilers.p.unresolved-ex-points=0 +compilers.p.unresolved-import=0 +compilers.s.create-docs=false +compilers.s.doc-folder=doc +compilers.s.open-tags=1 +eclipse.preferences.version=1 diff --git a/org.eclipse.jgit.pgm.test/META-INF/MANIFEST.MF b/org.eclipse.jgit.pgm.test/META-INF/MANIFEST.MF index b0e6506e36..920c0cf897 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.3.3.qualifier +Bundle-Version: 5.4.1.qualifier Bundle-Vendor: %provider_name Bundle-Localization: plugin Bundle-ActivationPolicy: lazy Bundle-RequiredExecutionEnvironment: JavaSE-1.8 -Import-Package: org.eclipse.jgit.api;version="[5.3.3,5.4.0)", - org.eclipse.jgit.api.errors;version="[5.3.3,5.4.0)", - org.eclipse.jgit.diff;version="[5.3.3,5.4.0)", - org.eclipse.jgit.dircache;version="[5.3.3,5.4.0)", - org.eclipse.jgit.internal.storage.file;version="5.3.3", - org.eclipse.jgit.junit;version="[5.3.3,5.4.0)", - org.eclipse.jgit.lib;version="[5.3.3,5.4.0)", - org.eclipse.jgit.merge;version="[5.3.3,5.4.0)", - org.eclipse.jgit.pgm;version="[5.3.3,5.4.0)", - org.eclipse.jgit.pgm.internal;version="[5.3.3,5.4.0)", - org.eclipse.jgit.pgm.opt;version="[5.3.3,5.4.0)", - org.eclipse.jgit.revwalk;version="[5.3.3,5.4.0)", - org.eclipse.jgit.storage.file;version="[5.3.3,5.4.0)", - org.eclipse.jgit.transport;version="[5.3.3,5.4.0)", - org.eclipse.jgit.treewalk;version="[5.3.3,5.4.0)", - org.eclipse.jgit.util;version="[5.3.3,5.4.0)", - org.eclipse.jgit.util.io;version="[5.3.3,5.4.0)", +Import-Package: org.eclipse.jgit.api;version="[5.4.1,5.5.0)", + org.eclipse.jgit.api.errors;version="[5.4.1,5.5.0)", + org.eclipse.jgit.diff;version="[5.4.1,5.5.0)", + org.eclipse.jgit.dircache;version="[5.4.1,5.5.0)", + org.eclipse.jgit.internal.storage.file;version="5.4.1", + org.eclipse.jgit.junit;version="[5.4.1,5.5.0)", + org.eclipse.jgit.lib;version="[5.4.1,5.5.0)", + org.eclipse.jgit.merge;version="[5.4.1,5.5.0)", + org.eclipse.jgit.pgm;version="[5.4.1,5.5.0)", + org.eclipse.jgit.pgm.internal;version="[5.4.1,5.5.0)", + org.eclipse.jgit.pgm.opt;version="[5.4.1,5.5.0)", + org.eclipse.jgit.revwalk;version="[5.4.1,5.5.0)", + org.eclipse.jgit.storage.file;version="[5.4.1,5.5.0)", + org.eclipse.jgit.transport;version="[5.4.1,5.5.0)", + org.eclipse.jgit.treewalk;version="[5.4.1,5.5.0)", + org.eclipse.jgit.util;version="[5.4.1,5.5.0)", + org.eclipse.jgit.util.io;version="[5.4.1,5.5.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 601f0e0c57..fb493f8c54 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.3.3-SNAPSHOT</version> + <version>5.4.1-SNAPSHOT</version> </parent> <artifactId>org.eclipse.jgit.pgm.test</artifactId> @@ -109,7 +109,7 @@ <plugin> <artifactId>maven-surefire-plugin</artifactId> <configuration> - <argLine>@{argLine} -Djava.io.tmpdir=${project.build.directory}</argLine> + <argLine>@{argLine} -Xmx512m -Djava.io.tmpdir=${project.build.directory}</argLine> </configuration> </plugin> </plugins> diff --git a/org.eclipse.jgit.pgm.test/src/org/eclipse/jgit/lib/CLIRepositoryTestCase.java b/org.eclipse.jgit.pgm.test/src/org/eclipse/jgit/lib/CLIRepositoryTestCase.java index 0d1894b644..a830ff2849 100644 --- a/org.eclipse.jgit.pgm.test/src/org/eclipse/jgit/lib/CLIRepositoryTestCase.java +++ b/org.eclipse.jgit.pgm.test/src/org/eclipse/jgit/lib/CLIRepositoryTestCase.java @@ -214,7 +214,7 @@ public class CLIRepositoryTestCase extends LocalDiskRepositoryTestCase { protected void assertStringArrayEquals(String expected, String[] actual) { // if there is more than one line, ignore last one if empty assertEquals(1, - actual.length > 1 && actual[actual.length - 1].equals("") + actual.length > 1 && actual[actual.length - 1].isEmpty() ? actual.length - 1 : actual.length); assertEquals(expected, actual[0]); } 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 47eb156c55..e07fdd50d2 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 @@ -60,7 +60,6 @@ import java.io.OutputStream; import java.util.ArrayList; import java.util.Arrays; import java.util.List; -import java.util.concurrent.Callable; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.Future; @@ -703,15 +702,12 @@ public class ArchiveTest extends CLIRepositoryTestCase { private static Future<Object> writeAsync(OutputStream stream, byte[] data) { ExecutorService executor = Executors.newSingleThreadExecutor(); - return executor.submit(new Callable<Object>() { - @Override - public Object call() throws IOException { - try { - stream.write(data); - return null; - } finally { - stream.close(); - } + return executor.submit(() -> { + try { + stream.write(data); + return null; + } finally { + stream.close(); } }); } diff --git a/org.eclipse.jgit.pgm/META-INF/MANIFEST.MF b/org.eclipse.jgit.pgm/META-INF/MANIFEST.MF index 4551c1c3ab..9c313aab84 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.3.3.qualifier +Bundle-Version: 5.4.1.qualifier Bundle-Vendor: %provider_name Bundle-ActivationPolicy: lazy Bundle-Localization: plugin @@ -28,50 +28,50 @@ 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.3.3,5.4.0)", - org.eclipse.jgit.api.errors;version="[5.3.3,5.4.0)", - org.eclipse.jgit.archive;version="[5.3.3,5.4.0)", - org.eclipse.jgit.awtui;version="[5.3.3,5.4.0)", - org.eclipse.jgit.blame;version="[5.3.3,5.4.0)", - org.eclipse.jgit.diff;version="[5.3.3,5.4.0)", - org.eclipse.jgit.dircache;version="[5.3.3,5.4.0)", - org.eclipse.jgit.errors;version="[5.3.3,5.4.0)", - org.eclipse.jgit.gitrepo;version="[5.3.3,5.4.0)", - org.eclipse.jgit.internal.ketch;version="[5.3.3,5.4.0)", - org.eclipse.jgit.internal.storage.dfs;version="[5.3.3,5.4.0)", - org.eclipse.jgit.internal.storage.file;version="[5.3.3,5.4.0)", - org.eclipse.jgit.internal.storage.io;version="[5.3.3,5.4.0)", - org.eclipse.jgit.internal.storage.pack;version="[5.3.3,5.4.0)", - org.eclipse.jgit.internal.storage.reftable;version="[5.3.3,5.4.0)", - org.eclipse.jgit.internal.storage.reftree;version="[5.3.3,5.4.0)", - org.eclipse.jgit.lfs;version="[5.3.3,5.4.0)", - org.eclipse.jgit.lfs.lib;version="[5.3.3,5.4.0)", - org.eclipse.jgit.lfs.server;version="[5.3.3,5.4.0)", - org.eclipse.jgit.lfs.server.fs;version="[5.3.3,5.4.0)", - org.eclipse.jgit.lfs.server.s3;version="[5.3.3,5.4.0)", - org.eclipse.jgit.lib;version="[5.3.3,5.4.0)", - org.eclipse.jgit.merge;version="[5.3.3,5.4.0)", - org.eclipse.jgit.nls;version="[5.3.3,5.4.0)", - org.eclipse.jgit.notes;version="[5.3.3,5.4.0)", - org.eclipse.jgit.revplot;version="[5.3.3,5.4.0)", - org.eclipse.jgit.revwalk;version="[5.3.3,5.4.0)", - org.eclipse.jgit.revwalk.filter;version="[5.3.3,5.4.0)", - org.eclipse.jgit.storage.file;version="[5.3.3,5.4.0)", - org.eclipse.jgit.storage.pack;version="[5.3.3,5.4.0)", - org.eclipse.jgit.transport;version="[5.3.3,5.4.0)", - org.eclipse.jgit.transport.http.apache;version="[5.3.3,5.4.0)", - org.eclipse.jgit.transport.resolver;version="[5.3.3,5.4.0)", - org.eclipse.jgit.transport.sshd;version="[5.3.3,5.4.0)", - org.eclipse.jgit.treewalk;version="[5.3.3,5.4.0)", - org.eclipse.jgit.treewalk.filter;version="[5.3.3,5.4.0)", - org.eclipse.jgit.util;version="[5.3.3,5.4.0)", - org.eclipse.jgit.util.io;version="[5.3.3,5.4.0)", + org.eclipse.jgit.api;version="[5.4.1,5.5.0)", + org.eclipse.jgit.api.errors;version="[5.4.1,5.5.0)", + org.eclipse.jgit.archive;version="[5.4.1,5.5.0)", + org.eclipse.jgit.awtui;version="[5.4.1,5.5.0)", + org.eclipse.jgit.blame;version="[5.4.1,5.5.0)", + org.eclipse.jgit.diff;version="[5.4.1,5.5.0)", + org.eclipse.jgit.dircache;version="[5.4.1,5.5.0)", + org.eclipse.jgit.errors;version="[5.4.1,5.5.0)", + org.eclipse.jgit.gitrepo;version="[5.4.1,5.5.0)", + org.eclipse.jgit.internal.ketch;version="[5.4.1,5.5.0)", + org.eclipse.jgit.internal.storage.dfs;version="[5.4.1,5.5.0)", + org.eclipse.jgit.internal.storage.file;version="[5.4.1,5.5.0)", + org.eclipse.jgit.internal.storage.io;version="[5.4.1,5.5.0)", + org.eclipse.jgit.internal.storage.pack;version="[5.4.1,5.5.0)", + org.eclipse.jgit.internal.storage.reftable;version="[5.4.1,5.5.0)", + org.eclipse.jgit.internal.storage.reftree;version="[5.4.1,5.5.0)", + org.eclipse.jgit.lfs;version="[5.4.1,5.5.0)", + org.eclipse.jgit.lfs.lib;version="[5.4.1,5.5.0)", + org.eclipse.jgit.lfs.server;version="[5.4.1,5.5.0)", + org.eclipse.jgit.lfs.server.fs;version="[5.4.1,5.5.0)", + org.eclipse.jgit.lfs.server.s3;version="[5.4.1,5.5.0)", + org.eclipse.jgit.lib;version="[5.4.1,5.5.0)", + org.eclipse.jgit.merge;version="[5.4.1,5.5.0)", + org.eclipse.jgit.nls;version="[5.4.1,5.5.0)", + org.eclipse.jgit.notes;version="[5.4.1,5.5.0)", + org.eclipse.jgit.revplot;version="[5.4.1,5.5.0)", + org.eclipse.jgit.revwalk;version="[5.4.1,5.5.0)", + org.eclipse.jgit.revwalk.filter;version="[5.4.1,5.5.0)", + org.eclipse.jgit.storage.file;version="[5.4.1,5.5.0)", + org.eclipse.jgit.storage.pack;version="[5.4.1,5.5.0)", + org.eclipse.jgit.transport;version="[5.4.1,5.5.0)", + org.eclipse.jgit.transport.http.apache;version="[5.4.1,5.5.0)", + org.eclipse.jgit.transport.resolver;version="[5.4.1,5.5.0)", + org.eclipse.jgit.transport.sshd;version="[5.4.1,5.5.0)", + org.eclipse.jgit.treewalk;version="[5.4.1,5.5.0)", + org.eclipse.jgit.treewalk.filter;version="[5.4.1,5.5.0)", + org.eclipse.jgit.util;version="[5.4.1,5.5.0)", + org.eclipse.jgit.util.io;version="[5.4.1,5.5.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.3.3"; +Export-Package: org.eclipse.jgit.console;version="5.4.1"; uses:="org.eclipse.jgit.transport, org.eclipse.jgit.util", - org.eclipse.jgit.pgm;version="5.3.3"; + org.eclipse.jgit.pgm;version="5.4.1"; uses:="org.eclipse.jgit.revwalk, org.eclipse.jgit.treewalk.filter, org.eclipse.jgit.pgm.opt, @@ -82,11 +82,11 @@ Export-Package: org.eclipse.jgit.console;version="5.3.3"; org.eclipse.jgit.treewalk, javax.swing, org.eclipse.jgit.transport", - org.eclipse.jgit.pgm.debug;version="5.3.3"; + org.eclipse.jgit.pgm.debug;version="5.4.1"; uses:="org.eclipse.jgit.util.io, org.eclipse.jgit.pgm", - org.eclipse.jgit.pgm.internal;version="5.3.3";x-friends:="org.eclipse.jgit.pgm.test,org.eclipse.jgit.test", - org.eclipse.jgit.pgm.opt;version="5.3.3"; + org.eclipse.jgit.pgm.internal;version="5.4.1";x-friends:="org.eclipse.jgit.pgm.test,org.eclipse.jgit.test", + org.eclipse.jgit.pgm.opt;version="5.4.1"; 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 c225dab96b..9be8fb228b 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.3.3.qualifier -Eclipse-SourceBundle: org.eclipse.jgit.pgm;version="5.3.3.qualifier";roots="." +Bundle-Version: 5.4.1.qualifier +Eclipse-SourceBundle: org.eclipse.jgit.pgm;version="5.4.1.qualifier";roots="." diff --git a/org.eclipse.jgit.pgm/pom.xml b/org.eclipse.jgit.pgm/pom.xml index 272cd1f635..389b180331 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.3.3-SNAPSHOT</version> + <version>5.4.1-SNAPSHOT</version> </parent> <artifactId>org.eclipse.jgit.pgm</artifactId> @@ -142,6 +142,12 @@ <artifactId>org.eclipse.jgit.lfs.server</artifactId> <version>${project.version}</version> </dependency> + + <dependency> + <groupId>org.tukaani</groupId> + <artifactId>xz</artifactId> + <optional>true</optional> + </dependency> </dependencies> <build> 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 a482ce3f38..2a5a31eba8 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 @@ -24,7 +24,6 @@ branchNameRequired=branch name required branchNotFound=branch ''{0}'' not found. cacheTreePathInfo="{0}": {1} entries, {2} children cannotBeRenamed={0} cannot be renamed -cannotChekoutNoHeadsAdvertisedByRemote=cannot checkout; no HEAD advertised by remote cannotCombineSquashWithNoff=You cannot combine --squash with --no-ff. cannotCreateCommand=Cannot create command {0} cannotCreateOutputStream=cannot create output stream @@ -223,6 +222,7 @@ unsupportedOperation=Unsupported operation: {0} untrackedFiles=Untracked files: updating=Updating {0}..{1} usage_Aggressive=This option will cause gc to more aggressively optimize the repository at the expense of taking much more time +usage_AlwaysFallback=Show uniquely abbreviated commit object as fallback usage_bareClone=Make a bare Git repository. That is, instead of creating [DIRECTORY] and placing the administrative files in [DIRECTORY]/.git, make the [DIRECTORY] itself the $GIT_DIR. usage_Blame=Show what revision and author last modified each line usage_Clean=Remove untracked files from the working tree @@ -290,6 +290,7 @@ usage_Status=Show the working tree status usage_StopTrackingAFile=Stop tracking a file usage_TextHashFunctions=Scan repository to compute maximum number of collisions for hash functions usage_UpdateRemoteRepositoryFromLocalRefs=Update remote repository from local refs +usage_UseTags=Use any tag including lightweight tags usage_WriteDirCache=Write the DirCache usage_abbrevCommits=abbreviate commits to N + 1 digits usage_abortConnectionIfNoActivity=abort connection if no activity @@ -315,7 +316,7 @@ usage_blameSuppressAuthor=do not show author name and timestamp usage_beMoreVerbose=be more verbose usage_beVerbose=be verbose usage_cached=compare against index -usage_checkout=Checkout a branch to the working tree +usage_checkout=Check out a branch to the working tree usage_cloneRepositoryIntoNewDir=Clone a repository into a new directory usage_configFile=configuration file usage_configGlobal=use global configuration in ~/.gitconfig @@ -323,7 +324,7 @@ usage_configList=List all variables set in config file usage_configLocal=use local configuration in .git/config usage_configSystem=use system-wide configuration in $(prefix)/etc/gitconfig usage_configureTheServiceInDaemonServicename=configure the service in daemon.servicename -usage_createBranchAndCheckout=create branch and checkout +usage_createBranchAndCheckout=create branch and check out usage_deleteBranchEvenIfNotMerged=delete branch (even if not merged) usage_deleteFullyMergedBranch=delete fully merged branch usage_date=date format, one of default, rfc, local, iso, short, raw (as defined by git-log(1) ), locale or localelocal (jgit extensions) @@ -416,7 +417,7 @@ usage_untrackedFilesMode=show untracked files usage_updateRef=reference to update usage_updateRemoteRefsFromAnotherRepository=Update remote refs from another repository usage_useNameInsteadOfOriginToTrackUpstream=use <name> instead of 'origin' to track upstream -usage_checkoutBranchAfterClone=checkout named branch instead of remote's HEAD +usage_checkoutBranchAfterClone=check out named branch instead of remote's HEAD usage_viewCommitHistory=View commit history usage_orphan=Create a new orphan branch. The first commit made on this new branch will have no parents and it will be the root of a new history totally disconnected from other branches and commits. usernameFor=Username for {0}: diff --git a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/Blame.java b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/Blame.java index 3858b3dd0e..e38cb468d9 100644 --- a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/Blame.java +++ b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/Blame.java @@ -218,7 +218,8 @@ class Blame extends TextBuiltin { dateWidth = Math.max(dateWidth, date(line).length()); pathWidth = Math.max(pathWidth, path(line).length()); } - while (line + 1 < end && blame.getSourceCommit(line + 1) == c) { + while (line + 1 < end + && sameCommit(blame.getSourceCommit(line + 1), c)) { line++; } maxSourceLine = Math.max(maxSourceLine, blame.getSourceLine(line)); @@ -257,13 +258,22 @@ class Blame extends TextBuiltin { blame.getResultContents().writeLine(outs, line); outs.flush(); outw.print('\n'); - } while (++line < end && blame.getSourceCommit(line) == c); + } while (++line < end + && sameCommit(blame.getSourceCommit(line), c)); } } catch (NoWorkTreeException | IOException e) { throw die(e.getMessage(), e); } } + @SuppressWarnings("ReferenceEquality") + private static boolean sameCommit(RevCommit a, RevCommit b) { + // Reference comparison is intentional; BlameGenerator uses a single + // RevWalk which caches the RevCommit objects, and if a given commit + // is cached the RevWalk returns the same instance. + return a == b; + } + private int uniqueAbbrevLen(ObjectReader reader, RevCommit commit) throws IOException { return reader.abbreviate(commit, abbrev).length(); @@ -295,14 +305,14 @@ class Blame extends TextBuiltin { } } - if (beginStr.equals("")) //$NON-NLS-1$ + if (beginStr.isEmpty()) begin = 0; else if (beginStr.startsWith("/")) //$NON-NLS-1$ begin = findLine(0, beginStr); else begin = Math.max(0, Integer.parseInt(beginStr) - 1); - if (endStr.equals("")) //$NON-NLS-1$ + if (endStr.isEmpty()) end = blame.getResultContents().size(); else if (endStr.startsWith("/")) //$NON-NLS-1$ end = findLine(begin, endStr); diff --git a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/Checkout.java b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/Checkout.java index 7e1737f872..3df37e51c3 100644 --- a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/Checkout.java +++ b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/Checkout.java @@ -96,7 +96,7 @@ class Checkout extends TextBuiltin { try (Git git = new Git(db)) { CheckoutCommand command = git.checkout() .setProgressMonitor(new TextProgressMonitor(errw)); - if (paths.size() > 0) { + if (!paths.isEmpty()) { command.setStartPoint(name); if (paths.size() == 1 && paths.get(0).equals(".")) { //$NON-NLS-1$ command.setAllPaths(true); 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 dbdccc10e2..dab52f6ce9 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 @@ -52,7 +52,6 @@ import java.net.URL; import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; -import java.util.Comparator; import java.util.Enumeration; import java.util.HashMap; import java.util.Map; @@ -115,12 +114,8 @@ public class CommandCatalog { private static CommandRef[] toSortedArray(Collection<CommandRef> c) { final CommandRef[] r = c.toArray(new CommandRef[0]); - Arrays.sort(r, new Comparator<CommandRef>() { - @Override - public int compare(CommandRef o1, CommandRef o2) { - return o1.getName().compareTo(o2.getName()); - } - }); + Arrays.sort(r, (CommandRef o1, CommandRef o2) -> o1.getName() + .compareTo(o2.getName())); return r; } @@ -163,13 +158,9 @@ public class CommandCatalog { final Class<? extends TextBuiltin> clazz; try { clazz = Class.forName(cn, false, ldr).asSubclass(TextBuiltin.class); - } catch (ClassNotFoundException notBuiltin) { + } catch (ClassNotFoundException | ClassCastException notBuiltin) { // Doesn't exist, even though the service entry is present. - // - return; - } catch (ClassCastException notBuiltin) { // Isn't really a builtin, even though its listed as such. - // return; } diff --git a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/CommandRef.java b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/CommandRef.java index 1773de5d78..85ace3a077 100644 --- a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/CommandRef.java +++ b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/CommandRef.java @@ -156,24 +156,19 @@ public class CommandRef { final Constructor<? extends TextBuiltin> c; try { c = impl.getDeclaredConstructor(); - } catch (SecurityException e) { - throw new RuntimeException(MessageFormat.format(CLIText.get().cannotCreateCommand, getName(), e)); - } catch (NoSuchMethodException e) { - throw new RuntimeException(MessageFormat.format(CLIText.get().cannotCreateCommand, getName(), e)); + } catch (SecurityException | NoSuchMethodException e) { + throw new RuntimeException(MessageFormat + .format(CLIText.get().cannotCreateCommand, getName(), e)); } c.setAccessible(true); final TextBuiltin r; try { r = c.newInstance(); - } catch (InstantiationException e) { - throw new RuntimeException(MessageFormat.format(CLIText.get().cannotCreateCommand, getName(), e)); - } catch (IllegalAccessException e) { - throw new RuntimeException(MessageFormat.format(CLIText.get().cannotCreateCommand, getName(), e)); - } catch (IllegalArgumentException e) { - throw new RuntimeException(MessageFormat.format(CLIText.get().cannotCreateCommand, getName(), e)); - } catch (InvocationTargetException e) { - throw new RuntimeException(MessageFormat.format(CLIText.get().cannotCreateCommand, getName(), e)); + } catch (InstantiationException | IllegalAccessException + | IllegalArgumentException | InvocationTargetException e) { + throw new RuntimeException(MessageFormat + .format(CLIText.get().cannotCreateCommand, getName(), e)); } r.setCommandName(getName()); return r; diff --git a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/Daemon.java b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/Daemon.java index 319b5e39dc..43826636aa 100644 --- a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/Daemon.java +++ b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/Daemon.java @@ -66,7 +66,6 @@ import org.eclipse.jgit.transport.DaemonService; import org.eclipse.jgit.transport.ReceivePack; import org.eclipse.jgit.transport.resolver.FileResolver; import org.eclipse.jgit.transport.resolver.ReceivePackFactory; -import org.eclipse.jgit.transport.resolver.ServiceNotAuthorizedException; import org.eclipse.jgit.transport.resolver.ServiceNotEnabledException; import org.eclipse.jgit.util.FS; import org.kohsuke.args4j.Argument; @@ -188,22 +187,17 @@ class Daemon extends TextBuiltin { final ReceivePackFactory<DaemonClient> factory; factory = daemon.getReceivePackFactory(); - daemon.setReceivePackFactory(new ReceivePackFactory<DaemonClient>() { - @Override - public ReceivePack create(DaemonClient req, Repository repo) - throws ServiceNotEnabledException, - ServiceNotAuthorizedException { - ReceivePack rp = factory.create(req, repo); - KetchLeader leader; - try { - leader = leaders.get(repo); - } catch (URISyntaxException err) { - throw new ServiceNotEnabledException( - KetchText.get().invalidFollowerUri, err); - } - rp.setPreReceiveHook(new KetchPreReceive(leader)); - return rp; + daemon.setReceivePackFactory((DaemonClient req, Repository repo) -> { + ReceivePack rp = factory.create(req, repo); + KetchLeader leader; + try { + leader = leaders.get(repo); + } catch (URISyntaxException err) { + throw new ServiceNotEnabledException( + KetchText.get().invalidFollowerUri, err); } + rp.setPreReceiveHook(new KetchPreReceive(leader)); + return rp; }); } } 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 d89fee6239..8a572f44b4 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 @@ -65,6 +65,12 @@ class Describe extends TextBuiltin { @Option(name = "--long", usage = "usage_LongFormat") private boolean longDesc; + @Option(name = "--tags", usage = "usage_UseTags") + private boolean useTags; + + @Option(name = "--always", usage = "usage_AlwaysFallback") + private boolean always; + @Option(name = "--match", usage = "usage_Match", metaVar = "metaVar_pattern") private List<String> patterns = new ArrayList<>(); @@ -77,6 +83,8 @@ class Describe extends TextBuiltin { cmd.setTarget(tree); } cmd.setLong(longDesc); + cmd.setTags(useTags); + cmd.setAlways(always); cmd.setMatch(patterns.toArray(new String[0])); String result = null; try { diff --git a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/Diff.java b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/Diff.java index 7747dc7dd7..3d6ebfd8b6 100644 --- a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/Diff.java +++ b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/Diff.java @@ -87,7 +87,7 @@ class Diff extends TextBuiltin { @Argument(index = 1, metaVar = "metaVar_treeish") private AbstractTreeIterator newTree; - @Option(name = "--cached", usage = "usage_cached") + @Option(name = "--cached", aliases = { "--staged" }, usage = "usage_cached") private boolean cached; @Option(name = "--", metaVar = "metaVar_paths", handler = PathTreeFilterHandler.class) diff --git a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/Glog.java b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/Glog.java index 2b5af5d7b7..00bbfb788b 100644 --- a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/Glog.java +++ b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/Glog.java @@ -47,7 +47,6 @@ package org.eclipse.jgit.pgm; import java.awt.BorderLayout; import java.awt.FlowLayout; import java.awt.event.ActionEvent; -import java.awt.event.ActionListener; import java.awt.event.WindowAdapter; import java.awt.event.WindowEvent; import java.io.File; @@ -87,11 +86,8 @@ class Glog extends RevWalkTextBuiltin { final JPanel buttons = new JPanel(new FlowLayout()); final JButton repaint = new JButton(); repaint.setText(CLIText.get().repaint); - repaint.addActionListener(new ActionListener() { - @Override - public void actionPerformed(ActionEvent e) { - graphPane.repaint(); - } + repaint.addActionListener((ActionEvent e) -> { + graphPane.repaint(); }); buttons.add(repaint); 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 index ef25844973..e3ed30dc40 100644 --- a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/LsFiles.java +++ b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/LsFiles.java @@ -85,7 +85,7 @@ class LsFiles extends TextBuiltin { 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) { + if (!paths.isEmpty()) { tw.setFilter(PathFilterGroup.createFromStrings(paths)); } tw.addTree(p); diff --git a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/LsRemote.java b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/LsRemote.java index 1c2564dd7c..708fcde683 100644 --- a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/LsRemote.java +++ b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/LsRemote.java @@ -46,7 +46,6 @@ package org.eclipse.jgit.pgm; import java.io.IOException; -import java.util.Comparator; import java.util.TreeSet; import org.eclipse.jgit.api.Git; @@ -76,13 +75,8 @@ class LsRemote extends TextBuiltin { protected void run() { LsRemoteCommand command = Git.lsRemoteRepository().setRemote(remote) .setTimeout(timeout).setHeads(heads).setTags(tags); - TreeSet<Ref> refs = new TreeSet<>(new Comparator<Ref>() { - - @Override - public int compare(Ref r1, Ref r2) { - return r1.getName().compareTo(r2.getName()); - } - }); + TreeSet<Ref> refs = new TreeSet<>( + (Ref r1, Ref r2) -> r1.getName().compareTo(r2.getName())); try { refs.addAll(command.call()); for (Ref r : refs) { diff --git a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/LsTree.java b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/LsTree.java index 2a2bb7cc91..19f2d7ae4f 100644 --- a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/LsTree.java +++ b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/LsTree.java @@ -76,7 +76,7 @@ class LsTree extends TextBuiltin { protected void run() { try (TreeWalk walk = new TreeWalk(db)) { walk.reset(); // drop the first empty tree, which we do not need here - if (paths.size() > 0) { + if (!paths.isEmpty()) { walk.setFilter(PathFilterGroup.createFromStrings(paths)); } walk.setRecursive(recursive); 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 ad10ec9e44..9952f5cfc1 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 @@ -330,22 +330,12 @@ public class Main { install("org.eclipse.jgit.console.ConsoleAuthenticator"); //$NON-NLS-1$ install("org.eclipse.jgit.console.ConsoleCredentialsProvider"); //$NON-NLS-1$ return true; - } catch (ClassNotFoundException e) { + } catch (ClassNotFoundException | NoClassDefFoundError + | UnsupportedClassVersionError e) { return false; - } catch (NoClassDefFoundError e) { - return false; - } catch (UnsupportedClassVersionError e) { - return false; - - } catch (IllegalArgumentException e) { - throw new RuntimeException(CLIText.get().cannotSetupConsole, e); - } catch (SecurityException e) { - throw new RuntimeException(CLIText.get().cannotSetupConsole, e); - } catch (IllegalAccessException e) { - throw new RuntimeException(CLIText.get().cannotSetupConsole, e); - } catch (InvocationTargetException e) { - throw new RuntimeException(CLIText.get().cannotSetupConsole, e); - } catch (NoSuchMethodException e) { + } catch (IllegalArgumentException | SecurityException + | IllegalAccessException | InvocationTargetException + | NoSuchMethodException e) { throw new RuntimeException(CLIText.get().cannotSetupConsole, e); } } @@ -390,12 +380,12 @@ public class Main { if (s == null && protocol.equals("https")) { //$NON-NLS-1$ s = System.getenv("HTTPS_PROXY"); //$NON-NLS-1$ } - if (s == null || s.equals("")) { //$NON-NLS-1$ + if (s == null || s.isEmpty()) { continue; } final URL u = new URL( - (s.indexOf("://") == -1) ? protocol + "://" + s : s); //$NON-NLS-1$ //$NON-NLS-2$ + (!s.contains("://")) ? protocol + "://" + s : s); //$NON-NLS-1$ //$NON-NLS-2$ if (!u.getProtocol().startsWith("http")) //$NON-NLS-1$ throw new MalformedURLException(MessageFormat.format( CLIText.get().invalidHttpProxyOnlyHttpSupported, s)); diff --git a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/Reset.java b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/Reset.java index b3e81c6d65..e1a290731c 100644 --- a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/Reset.java +++ b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/Reset.java @@ -80,7 +80,7 @@ class Reset extends TextBuiltin { try (Git git = new Git(db)) { ResetCommand command = git.reset(); command.setRef(commit); - if (paths.size() > 0) { + if (!paths.isEmpty()) { for (String path : paths) { command.addPath(path); } diff --git a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/Status.java b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/Status.java index dfc8a9436f..c3887fe9c3 100644 --- a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/Status.java +++ b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/Status.java @@ -93,7 +93,7 @@ class Status extends TextBuiltin { protected void run() { try (Git git = new Git(db)) { StatusCommand statusCommand = git.status(); - if (filterPaths != null && filterPaths.size() > 0) { + if (filterPaths != null) { for (String path : filterPaths) { statusCommand.addPath(path); } @@ -282,7 +282,7 @@ class Status extends TextBuiltin { if (!porcelain) { outw.println(CLIText.formatLine(MessageFormat.format(pattern, arguments))); - if (!pattern.equals("")) //$NON-NLS-1$ + if (!pattern.isEmpty()) outw.println(CLIText.formatLine("")); //$NON-NLS-1$ outw.flush(); } diff --git a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/TextBuiltin.java b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/TextBuiltin.java index 05f237837f..d81a3aedc7 100644 --- a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/TextBuiltin.java +++ b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/TextBuiltin.java @@ -45,8 +45,8 @@ package org.eclipse.jgit.pgm; import static java.nio.charset.StandardCharsets.UTF_8; -import static org.eclipse.jgit.lib.ConfigConstants.CONFIG_SECTION_I18N; import static org.eclipse.jgit.lib.ConfigConstants.CONFIG_KEY_LOG_OUTPUT_ENCODING; +import static org.eclipse.jgit.lib.ConfigConstants.CONFIG_SECTION_I18N; import static org.eclipse.jgit.lib.Constants.R_HEADS; import static org.eclipse.jgit.lib.Constants.R_REMOTES; import static org.eclipse.jgit.lib.Constants.R_TAGS; diff --git a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/debug/DiffAlgorithms.java b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/debug/DiffAlgorithms.java index 0e1b398a73..85a74448f7 100644 --- a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/debug/DiffAlgorithms.java +++ b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/debug/DiffAlgorithms.java @@ -52,7 +52,6 @@ import java.lang.management.ThreadMXBean; import java.lang.reflect.Field; import java.util.ArrayList; import java.util.Collections; -import java.util.Comparator; import java.util.List; import org.eclipse.jgit.diff.DiffAlgorithm; @@ -235,15 +234,12 @@ class DiffAlgorithms extends TextBuiltin { } } - Collections.sort(all, new Comparator<Test>() { - @Override - public int compare(Test a, Test b) { - int result = Long.signum(a.runningTimeNanos - b.runningTimeNanos); - if (result == 0) { - result = a.algorithm.name.compareTo(b.algorithm.name); - } - return result; + Collections.sort(all, (Test a, Test b) -> { + int result = Long.signum(a.runningTimeNanos - b.runningTimeNanos); + if (result == 0) { + result = a.algorithm.name.compareTo(b.algorithm.name); } + return result; }); File directory = repo.getDirectory(); @@ -338,12 +334,9 @@ class DiffAlgorithms extends TextBuiltin { } } } - } catch (IllegalArgumentException e) { - throw die("Cannot determine names", e); //$NON-NLS-1$ - } catch (IllegalAccessException e) { + } catch (IllegalArgumentException | IllegalAccessException e) { throw die("Cannot determine names", e); //$NON-NLS-1$ } - return all; } diff --git a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/debug/TextHashFunctions.java b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/debug/TextHashFunctions.java index 300a01d246..a2ea8c20b4 100644 --- a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/debug/TextHashFunctions.java +++ b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/debug/TextHashFunctions.java @@ -403,9 +403,7 @@ class TextHashFunctions extends TextBuiltin { folds.add(fold); } } - } catch (IllegalArgumentException e) { - throw new RuntimeException("Cannot determine names", e); //$NON-NLS-1$ - } catch (IllegalAccessException e) { + } catch (IllegalArgumentException | IllegalAccessException e) { throw new RuntimeException("Cannot determine names", e); //$NON-NLS-1$ } diff --git a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/debug/VerifyReftable.java b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/debug/VerifyReftable.java index b38de14af9..15b6ff9a9a 100644 --- a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/debug/VerifyReftable.java +++ b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/debug/VerifyReftable.java @@ -189,7 +189,7 @@ class VerifyReftable extends TextBuiltin { return; } - if (!AnyObjectId.equals(exp.getObjectId(), act.getObjectId())) { + if (!AnyObjectId.isEqual(exp.getObjectId(), act.getObjectId())) { throw die(String.format("expected %s to be %s, found %s", exp.getName(), id(exp.getObjectId()), @@ -197,7 +197,8 @@ class VerifyReftable extends TextBuiltin { } if (exp.getPeeledObjectId() != null - && !AnyObjectId.equals(exp.getPeeledObjectId(), act.getPeeledObjectId())) { + && !AnyObjectId.isEqual(exp.getPeeledObjectId(), + act.getPeeledObjectId())) { throw die(String.format("expected %s to be %s, found %s", exp.getName(), id(exp.getPeeledObjectId()), diff --git a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/internal/CLIText.java b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/internal/CLIText.java index d0288a809e..7b9401f362 100644 --- a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/internal/CLIText.java +++ b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/internal/CLIText.java @@ -138,7 +138,6 @@ public class CLIText extends TranslationBundle { /***/ public String cacheTreePathInfo; /***/ public String configFileNotFound; /***/ public String cannotBeRenamed; - /***/ public String cannotChekoutNoHeadsAdvertisedByRemote; /***/ public String cannotCombineSquashWithNoff; /***/ public String cannotCreateCommand; /***/ public String cannotCreateOutputStream; diff --git a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/opt/AbstractTreeIteratorHandler.java b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/opt/AbstractTreeIteratorHandler.java index a14f6514fe..213d9875db 100644 --- a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/opt/AbstractTreeIteratorHandler.java +++ b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/opt/AbstractTreeIteratorHandler.java @@ -133,10 +133,7 @@ public class AbstractTreeIteratorHandler extends final CanonicalTreeParser p = new CanonicalTreeParser(); try (ObjectReader curs = clp.getRepository().newObjectReader()) { p.reset(curs, clp.getRevWalk().parseTree(id)); - } catch (MissingObjectException e) { - throw new CmdLineException(clp, - CLIText.format(CLIText.get().notATree), name); - } catch (IncorrectObjectTypeException e) { + } catch (MissingObjectException | IncorrectObjectTypeException e) { throw new CmdLineException(clp, CLIText.format(CLIText.get().notATree), name); } catch (IOException e) { diff --git a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/opt/PathTreeFilterHandler.java b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/opt/PathTreeFilterHandler.java index d99f88e35b..4a50708b4c 100644 --- a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/opt/PathTreeFilterHandler.java +++ b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/opt/PathTreeFilterHandler.java @@ -96,7 +96,7 @@ public class PathTreeFilterHandler extends OptionHandler<TreeFilter> { filters.add(PathFilter.create(path)); } - if (filters.size() == 0) + if (filters.isEmpty()) return 0; if (filters.size() == 1) { setter.addValue(filters.get(0)); diff --git a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/opt/RevCommitHandler.java b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/opt/RevCommitHandler.java index b925e31f85..d4effa3a10 100644 --- a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/opt/RevCommitHandler.java +++ b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/opt/RevCommitHandler.java @@ -130,10 +130,7 @@ public class RevCommitHandler extends OptionHandler<RevCommit> { final RevCommit c; try { c = clp.getRevWalk().parseCommit(id); - } catch (MissingObjectException e) { - throw new CmdLineException(clp, - CLIText.format(CLIText.get().notACommit), name); - } catch (IncorrectObjectTypeException e) { + } catch (MissingObjectException | IncorrectObjectTypeException e) { throw new CmdLineException(clp, CLIText.format(CLIText.get().notACommit), name); } catch (IOException e) { diff --git a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/opt/RevTreeHandler.java b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/opt/RevTreeHandler.java index 85922a27ba..19841f633a 100644 --- a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/opt/RevTreeHandler.java +++ b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/opt/RevTreeHandler.java @@ -102,10 +102,7 @@ public class RevTreeHandler extends OptionHandler<RevTree> { final RevTree c; try { c = clp.getRevWalk().parseTree(id); - } catch (MissingObjectException e) { - throw new CmdLineException(clp, - CLIText.format(CLIText.get().notATree), name); - } catch (IncorrectObjectTypeException e) { + } catch (MissingObjectException | IncorrectObjectTypeException e) { throw new CmdLineException(clp, CLIText.format(CLIText.get().notATree), name); } catch (IOException e) { diff --git a/org.eclipse.jgit.ssh.apache.test/.settings/org.eclipse.pde.prefs b/org.eclipse.jgit.ssh.apache.test/.settings/org.eclipse.pde.prefs new file mode 100644 index 0000000000..2174e4fd5b --- /dev/null +++ b/org.eclipse.jgit.ssh.apache.test/.settings/org.eclipse.pde.prefs @@ -0,0 +1,34 @@ +compilers.f.unresolved-features=1 +compilers.f.unresolved-plugins=1 +compilers.incompatible-environment=1 +compilers.p.build=1 +compilers.p.build.bin.includes=1 +compilers.p.build.encodings=2 +compilers.p.build.java.compiler=2 +compilers.p.build.java.compliance=1 +compilers.p.build.missing.output=2 +compilers.p.build.output.library=1 +compilers.p.build.source.library=1 +compilers.p.build.src.includes=1 +compilers.p.deprecated=1 +compilers.p.discouraged-class=1 +compilers.p.internal=1 +compilers.p.missing-packages=2 +compilers.p.missing-version-export-package=2 +compilers.p.missing-version-import-package=2 +compilers.p.missing-version-require-bundle=2 +compilers.p.no-required-att=0 +compilers.p.no.automatic.module=1 +compilers.p.not-externalized-att=2 +compilers.p.service.component.without.lazyactivation=1 +compilers.p.unknown-attribute=1 +compilers.p.unknown-class=1 +compilers.p.unknown-element=1 +compilers.p.unknown-identifier=1 +compilers.p.unknown-resource=1 +compilers.p.unresolved-ex-points=0 +compilers.p.unresolved-import=0 +compilers.s.create-docs=false +compilers.s.doc-folder=doc +compilers.s.open-tags=1 +eclipse.preferences.version=1 diff --git a/org.eclipse.jgit.ssh.apache.test/BUILD b/org.eclipse.jgit.ssh.apache.test/BUILD index a13cf0b30f..18a48dca09 100644 --- a/org.eclipse.jgit.ssh.apache.test/BUILD +++ b/org.eclipse.jgit.ssh.apache.test/BUILD @@ -10,7 +10,7 @@ junit_tests( deps = [ "//lib:eddsa", "//lib:junit", - "//lib:sshd-core", + "//lib:sshd-osgi", "//lib:sshd-sftp", "//org.eclipse.jgit:jgit", "//org.eclipse.jgit.ssh.apache:ssh-apache", diff --git a/org.eclipse.jgit.ssh.apache.test/META-INF/MANIFEST.MF b/org.eclipse.jgit.ssh.apache.test/META-INF/MANIFEST.MF index 35b27fecec..a97bf780f3 100644 --- a/org.eclipse.jgit.ssh.apache.test/META-INF/MANIFEST.MF +++ b/org.eclipse.jgit.ssh.apache.test/META-INF/MANIFEST.MF @@ -3,17 +3,17 @@ Bundle-ManifestVersion: 2 Bundle-Name: %Bundle-Name Automatic-Module-Name: org.eclipse.jgit.ssh.apache.test Bundle-SymbolicName: org.eclipse.jgit.ssh.apache.test -Bundle-Version: 5.3.3.qualifier +Bundle-Version: 5.4.1.qualifier Bundle-Vendor: %Provider-Name Bundle-RequiredExecutionEnvironment: JavaSE-1.8 -Import-Package: org.eclipse.jgit.internal.transport.sshd.proxy;version="[5.3.3,5.4.0)", - org.eclipse.jgit.junit;version="[5.3.3,5.4.0)", - org.eclipse.jgit.junit.ssh;version="[5.3.3,5.4.0)", - org.eclipse.jgit.lib;version="[5.3.3,5.4.0)", - org.eclipse.jgit.transport;version="[5.3.3,5.4.0)", - org.eclipse.jgit.transport.ssh;version="[5.3.3,5.4.0)", - org.eclipse.jgit.transport.sshd;version="[5.3.3,5.4.0)", - org.eclipse.jgit.util;version="[5.3.3,5.4.0)", +Import-Package: org.eclipse.jgit.internal.transport.sshd.proxy;version="[5.4.1,5.5.0)", + org.eclipse.jgit.junit;version="[5.4.1,5.5.0)", + org.eclipse.jgit.junit.ssh;version="[5.4.1,5.5.0)", + org.eclipse.jgit.lib;version="[5.4.1,5.5.0)", + org.eclipse.jgit.transport;version="[5.4.1,5.5.0)", + org.eclipse.jgit.transport.ssh;version="[5.4.1,5.5.0)", + org.eclipse.jgit.transport.sshd;version="[5.4.1,5.5.0)", + org.eclipse.jgit.util;version="[5.4.1,5.5.0)", org.junit;version="[4.12,5.0.0)", org.junit.experimental.theories;version="[4.12,5.0.0)", org.junit.runner;version="[4.12,5.0.0)" diff --git a/org.eclipse.jgit.ssh.apache.test/pom.xml b/org.eclipse.jgit.ssh.apache.test/pom.xml index 40bdbbbad7..00bd403437 100644 --- a/org.eclipse.jgit.ssh.apache.test/pom.xml +++ b/org.eclipse.jgit.ssh.apache.test/pom.xml @@ -50,7 +50,7 @@ <parent> <groupId>org.eclipse.jgit</groupId> <artifactId>org.eclipse.jgit-parent</artifactId> - <version>5.3.3-SNAPSHOT</version> + <version>5.4.1-SNAPSHOT</version> </parent> <artifactId>org.eclipse.jgit.ssh.apache.test</artifactId> diff --git a/org.eclipse.jgit.ssh.apache/BUILD b/org.eclipse.jgit.ssh.apache/BUILD index a1a6c8e24c..372cfc228f 100644 --- a/org.eclipse.jgit.ssh.apache/BUILD +++ b/org.eclipse.jgit.ssh.apache/BUILD @@ -12,7 +12,7 @@ java_library( deps = [ "//lib:eddsa", "//lib:slf4j-api", - "//lib:sshd-core", + "//lib:sshd-osgi", "//lib:sshd-sftp", "//org.eclipse.jgit:jgit", ], diff --git a/org.eclipse.jgit.ssh.apache/META-INF/MANIFEST.MF b/org.eclipse.jgit.ssh.apache/META-INF/MANIFEST.MF index 105b0a1812..1aecee0542 100644 --- a/org.eclipse.jgit.ssh.apache/META-INF/MANIFEST.MF +++ b/org.eclipse.jgit.ssh.apache/META-INF/MANIFEST.MF @@ -5,9 +5,9 @@ Automatic-Module-Name: org.eclipse.jgit.ssh.apache Bundle-SymbolicName: org.eclipse.jgit.ssh.apache Bundle-Vendor: %Provider-Name Bundle-ActivationPolicy: lazy -Bundle-Version: 5.3.3.qualifier +Bundle-Version: 5.4.1.qualifier Bundle-RequiredExecutionEnvironment: JavaSE-1.8 -Export-Package: org.eclipse.jgit.internal.transport.sshd;version="5.3.3";x-internal:=true; +Export-Package: org.eclipse.jgit.internal.transport.sshd;version="5.4.1";x-internal:=true; uses:="org.apache.sshd.client, org.apache.sshd.client.auth, org.apache.sshd.client.auth.keyboard, @@ -22,9 +22,9 @@ Export-Package: org.eclipse.jgit.internal.transport.sshd;version="5.3.3";x-inter org.apache.sshd.common.signature, org.apache.sshd.common.util.buffer, org.eclipse.jgit.transport", - org.eclipse.jgit.internal.transport.sshd.auth;version="5.3.3";x-internal:=true, - org.eclipse.jgit.internal.transport.sshd.proxy;version="5.3.3";x-friends:="org.eclipse.jgit.ssh.apache.test", - org.eclipse.jgit.transport.sshd;version="5.3.3"; + org.eclipse.jgit.internal.transport.sshd.auth;version="5.4.1";x-internal:=true, + org.eclipse.jgit.internal.transport.sshd.proxy;version="5.4.1";x-friends:="org.eclipse.jgit.ssh.apache.test", + org.eclipse.jgit.transport.sshd;version="5.4.1"; uses:="org.eclipse.jgit.transport, org.apache.sshd.client.config.hosts, org.apache.sshd.common.keyprovider, @@ -32,52 +32,54 @@ Export-Package: org.eclipse.jgit.internal.transport.sshd;version="5.3.3";x-inter org.apache.sshd.client.session, org.apache.sshd.client.keyverifier" Import-Package: net.i2p.crypto.eddsa;version="[0.3.0,0.4.0)", - org.apache.sshd.agent;version="[2.0.0,2.1.0)", - org.apache.sshd.client;version="[2.0.0,2.1.0)", - org.apache.sshd.client.auth;version="[2.0.0,2.1.0)", - org.apache.sshd.client.auth.keyboard;version="[2.0.0,2.1.0)", - org.apache.sshd.client.auth.password;version="[2.0.0,2.1.0)", - org.apache.sshd.client.auth.pubkey;version="[2.0.0,2.1.0)", - org.apache.sshd.client.channel;version="[2.0.0,2.1.0)", - org.apache.sshd.client.config.hosts;version="[2.0.0,2.1.0)", - org.apache.sshd.client.config.keys;version="[2.0.0,2.1.0)", - org.apache.sshd.client.future;version="[2.0.0,2.1.0)", - org.apache.sshd.client.keyverifier;version="[2.0.0,2.1.0)", - org.apache.sshd.client.session;version="[2.0.0,2.1.0)", - org.apache.sshd.client.subsystem.sftp;version="[2.0.0,2.1.0)", - org.apache.sshd.common;version="[2.0.0,2.1.0)", - org.apache.sshd.common.auth;version="[2.0.0,2.1.0)", - org.apache.sshd.common.channel;version="[2.0.0,2.1.0)", - org.apache.sshd.common.compression;version="[2.0.0,2.1.0)", - org.apache.sshd.common.config.keys;version="[2.0.0,2.1.0)", - org.apache.sshd.common.config.keys.loader;version="[2.0.0,2.1.0)", - org.apache.sshd.common.digest;version="[2.0.0,2.1.0)", - org.apache.sshd.common.forward;version="[2.0.0,2.1.0)", - org.apache.sshd.common.future;version="[2.0.0,2.1.0)", - org.apache.sshd.common.helpers;version="[2.0.0,2.1.0)", - org.apache.sshd.common.io;version="[2.0.0,2.1.0)", - org.apache.sshd.common.kex;version="[2.0.0,2.1.0)", - org.apache.sshd.common.keyprovider;version="[2.0.0,2.1.0)", - org.apache.sshd.common.mac;version="[2.0.0,2.1.0)", - org.apache.sshd.common.random;version="[2.0.0,2.1.0)", - org.apache.sshd.common.session;version="[2.0.0,2.1.0)", - org.apache.sshd.common.session.helpers;version="[2.0.0,2.1.0)", - org.apache.sshd.common.signature;version="[2.0.0,2.1.0)", - org.apache.sshd.common.subsystem.sftp;version="[2.0.0,2.1.0)", - org.apache.sshd.common.util;version="[2.0.0,2.1.0)", - org.apache.sshd.common.util.buffer;version="[2.0.0,2.1.0)", - org.apache.sshd.common.util.closeable;version="[2.0.0,2.1.0)", - org.apache.sshd.common.util.io;version="[2.0.0,2.1.0)", - org.apache.sshd.common.util.logging;version="[2.0.0,2.1.0)", - org.apache.sshd.common.util.net;version="[2.0.0,2.1.0)", - org.apache.sshd.common.util.security;version="[2.0.0,2.1.0)", - org.apache.sshd.server.auth;version="[2.0.0,2.1.0)", - org.eclipse.jgit.annotations;version="[5.3.3,5.4.0)", - org.eclipse.jgit.errors;version="[5.3.3,5.4.0)", - org.eclipse.jgit.fnmatch;version="[5.3.3,5.4.0)", - org.eclipse.jgit.internal.storage.file;version="[5.3.3,5.4.0)", - org.eclipse.jgit.internal.transport.ssh;version="[5.3.3,5.4.0)", - org.eclipse.jgit.nls;version="[5.3.3,5.4.0)", - org.eclipse.jgit.transport;version="[5.3.3,5.4.0)", - org.eclipse.jgit.util;version="[5.3.3,5.4.0)", + org.apache.sshd.agent;version="[2.2.0,2.3.0)", + org.apache.sshd.client;version="[2.2.0,2.3.0)", + org.apache.sshd.client.auth;version="[2.2.0,2.3.0)", + org.apache.sshd.client.auth.keyboard;version="[2.2.0,2.3.0)", + org.apache.sshd.client.auth.password;version="[2.2.0,2.3.0)", + org.apache.sshd.client.auth.pubkey;version="[2.2.0,2.3.0)", + org.apache.sshd.client.channel;version="[2.2.0,2.3.0)", + org.apache.sshd.client.config.hosts;version="[2.2.0,2.3.0)", + org.apache.sshd.client.config.keys;version="[2.2.0,2.3.0)", + org.apache.sshd.client.future;version="[2.2.0,2.3.0)", + org.apache.sshd.client.keyverifier;version="[2.2.0,2.3.0)", + org.apache.sshd.client.session;version="[2.2.0,2.3.0)", + org.apache.sshd.client.subsystem.sftp;version="[2.2.0,2.3.0)", + org.apache.sshd.common;version="[2.2.0,2.3.0)", + org.apache.sshd.common.auth;version="[2.2.0,2.3.0)", + org.apache.sshd.common.channel;version="[2.2.0,2.3.0)", + org.apache.sshd.common.compression;version="[2.2.0,2.3.0)", + org.apache.sshd.common.config.keys;version="[2.2.0,2.3.0)", + org.apache.sshd.common.config.keys.loader;version="[2.2.0,2.3.0)", + org.apache.sshd.common.config.keys.loader.openssh.kdf;version="[2.2.0,2.3.0)", + org.apache.sshd.common.digest;version="[2.2.0,2.3.0)", + org.apache.sshd.common.forward;version="[2.2.0,2.3.0)", + org.apache.sshd.common.future;version="[2.2.0,2.3.0)", + org.apache.sshd.common.helpers;version="[2.2.0,2.3.0)", + org.apache.sshd.common.io;version="[2.2.0,2.3.0)", + org.apache.sshd.common.kex;version="[2.2.0,2.3.0)", + org.apache.sshd.common.keyprovider;version="[2.2.0,2.3.0)", + org.apache.sshd.common.mac;version="[2.2.0,2.3.0)", + org.apache.sshd.common.random;version="[2.2.0,2.3.0)", + org.apache.sshd.common.session;version="[2.2.0,2.3.0)", + org.apache.sshd.common.session.helpers;version="[2.2.0,2.3.0)", + org.apache.sshd.common.signature;version="[2.2.0,2.3.0)", + org.apache.sshd.common.subsystem.sftp;version="[2.2.0,2.3.0)", + org.apache.sshd.common.util;version="[2.2.0,2.3.0)", + org.apache.sshd.common.util.buffer;version="[2.2.0,2.3.0)", + org.apache.sshd.common.util.closeable;version="[2.2.0,2.3.0)", + org.apache.sshd.common.util.io;version="[2.2.0,2.3.0)", + org.apache.sshd.common.util.io.resource;version="[2.2.0,2.3.0)", + org.apache.sshd.common.util.logging;version="[2.2.0,2.3.0)", + org.apache.sshd.common.util.net;version="[2.2.0,2.3.0)", + org.apache.sshd.common.util.security;version="[2.2.0,2.3.0)", + org.apache.sshd.server.auth;version="[2.2.0,2.3.0)", + org.eclipse.jgit.annotations;version="[5.4.1,5.5.0)", + org.eclipse.jgit.errors;version="[5.4.1,5.5.0)", + org.eclipse.jgit.fnmatch;version="[5.4.1,5.5.0)", + org.eclipse.jgit.internal.storage.file;version="[5.4.1,5.5.0)", + org.eclipse.jgit.internal.transport.ssh;version="[5.4.1,5.5.0)", + org.eclipse.jgit.nls;version="[5.4.1,5.5.0)", + org.eclipse.jgit.transport;version="[5.4.1,5.5.0)", + org.eclipse.jgit.util;version="[5.4.1,5.5.0)", org.slf4j;version="[1.7.0,2.0.0)" diff --git a/org.eclipse.jgit.ssh.apache/META-INF/SOURCE-MANIFEST.MF b/org.eclipse.jgit.ssh.apache/META-INF/SOURCE-MANIFEST.MF index c76ba5a30d..deae0d4cf0 100644 --- a/org.eclipse.jgit.ssh.apache/META-INF/SOURCE-MANIFEST.MF +++ b/org.eclipse.jgit.ssh.apache/META-INF/SOURCE-MANIFEST.MF @@ -3,5 +3,5 @@ Bundle-ManifestVersion: 2 Bundle-Name: org.eclipse.jgit.ssh.apache - Sources Bundle-SymbolicName: org.eclipse.jgit.ssh.apache.source Bundle-Vendor: Eclipse.org - JGit -Bundle-Version: 5.3.3.qualifier -Eclipse-SourceBundle: org.eclipse.jgit.ssh.apache;version="5.3.3.qualifier";roots="." +Bundle-Version: 5.4.1.qualifier +Eclipse-SourceBundle: org.eclipse.jgit.ssh.apache;version="5.4.1.qualifier";roots="." diff --git a/org.eclipse.jgit.ssh.apache/pom.xml b/org.eclipse.jgit.ssh.apache/pom.xml index 99100cdc9c..a7f5bae354 100644 --- a/org.eclipse.jgit.ssh.apache/pom.xml +++ b/org.eclipse.jgit.ssh.apache/pom.xml @@ -50,7 +50,7 @@ <parent> <groupId>org.eclipse.jgit</groupId> <artifactId>org.eclipse.jgit-parent</artifactId> - <version>5.3.3-SNAPSHOT</version> + <version>5.4.1-SNAPSHOT</version> </parent> <artifactId>org.eclipse.jgit.ssh.apache</artifactId> @@ -75,7 +75,7 @@ <dependency> <groupId>org.apache.sshd</groupId> - <artifactId>sshd-core</artifactId> + <artifactId>sshd-osgi</artifactId> <version>${apache-sshd-version}</version> </dependency> diff --git a/org.eclipse.jgit.ssh.apache/src/org/eclipse/jgit/internal/transport/sshd/CachingKeyPairProvider.java b/org.eclipse.jgit.ssh.apache/src/org/eclipse/jgit/internal/transport/sshd/CachingKeyPairProvider.java index 1072f32548..a1ec31883d 100644 --- a/org.eclipse.jgit.ssh.apache/src/org/eclipse/jgit/internal/transport/sshd/CachingKeyPairProvider.java +++ b/org.eclipse.jgit.ssh.apache/src/org/eclipse/jgit/internal/transport/sshd/CachingKeyPairProvider.java @@ -45,10 +45,13 @@ package org.eclipse.jgit.internal.transport.sshd; import static java.text.MessageFormat.format; import java.io.IOException; +import java.io.InputStream; import java.nio.file.Files; import java.nio.file.Path; import java.security.GeneralSecurityException; +import java.security.InvalidKeyException; import java.security.KeyPair; +import java.security.PrivateKey; import java.util.ArrayList; import java.util.Collection; import java.util.Collections; @@ -57,13 +60,20 @@ import java.util.List; import java.util.NoSuchElementException; import java.util.concurrent.CancellationException; +import javax.security.auth.DestroyFailedException; + +import org.apache.sshd.common.NamedResource; +import org.apache.sshd.common.config.keys.FilePasswordProvider; +import org.apache.sshd.common.keyprovider.FileKeyPairProvider; +import org.apache.sshd.common.session.SessionContext; +import org.apache.sshd.common.util.io.resource.IoResource; +import org.apache.sshd.common.util.security.SecurityUtils; import org.eclipse.jgit.transport.sshd.KeyCache; /** - * A {@link EncryptedFileKeyPairProvider} that uses an external - * {@link KeyCache}. + * A {@link FileKeyPairProvider} that uses an external {@link KeyCache}. */ -public class CachingKeyPairProvider extends EncryptedFileKeyPairProvider +public class CachingKeyPairProvider extends FileKeyPairProvider implements Iterable<KeyPair> { private final KeyCache cache; @@ -71,7 +81,7 @@ public class CachingKeyPairProvider extends EncryptedFileKeyPairProvider /** * Creates a new {@link CachingKeyPairProvider} using the given * {@link KeyCache}. If the cache is {@code null}, this is a simple - * {@link EncryptedFileKeyPairProvider}. + * {@link FileKeyPairProvider}. * * @param paths * to load keys from @@ -85,36 +95,36 @@ public class CachingKeyPairProvider extends EncryptedFileKeyPairProvider @Override public Iterator<KeyPair> iterator() { + return iterator(null); + } + + private Iterator<KeyPair> iterator(SessionContext session) { Collection<? extends Path> resources = getPaths(); if (resources.isEmpty()) { return Collections.emptyListIterator(); } - return new CancellingKeyPairIterator(resources); + return new CancellingKeyPairIterator(session, resources); } @Override - public Iterable<KeyPair> loadKeys() { - return this; + public Iterable<KeyPair> loadKeys(SessionContext session) { + return () -> iterator(session); } - @Override - protected KeyPair doLoadKey(Path resource) + private KeyPair loadKey(SessionContext session, Path path) throws IOException, GeneralSecurityException { - if (!Files.exists(resource)) { - log.warn(format(SshdText.get().identityFileNotFound, resource)); + if (!Files.exists(path)) { + log.warn(format(SshdText.get().identityFileNotFound, path)); return null; } - // By calling doLoadKey(String, Path, FilePasswordProvider) instead of - // super.doLoadKey(Path) we can bypass the key caching in - // AbstractResourceKeyPairProvider, over which we have no real control. - String resourceId = resource.toString(); + IoResource<Path> resource = getIoResource(session, path); if (cache == null) { - return doLoadKey(resourceId, resource, getPasswordFinder()); + return loadKey(session, resource, path, getPasswordFinder()); } Throwable t[] = { null }; - KeyPair key = cache.get(resource, p -> { + KeyPair key = cache.get(path, p -> { try { - return doLoadKey(resourceId, p, getPasswordFinder()); + return loadKey(session, resource, p, getPasswordFinder()); } catch (IOException | GeneralSecurityException e) { t[0] = e; return null; @@ -130,18 +140,55 @@ public class CachingKeyPairProvider extends EncryptedFileKeyPairProvider return key; } + private KeyPair loadKey(SessionContext session, NamedResource resource, + Path path, FilePasswordProvider passwordProvider) + throws IOException, GeneralSecurityException { + try (InputStream stream = Files.newInputStream(path)) { + Iterable<KeyPair> ids = SecurityUtils.loadKeyPairIdentities(session, + resource, stream, passwordProvider); + if (ids == null) { + throw new InvalidKeyException( + format(SshdText.get().identityFileNoKey, path)); + } + Iterator<KeyPair> keys = ids.iterator(); + if (!keys.hasNext()) { + throw new InvalidKeyException(format( + SshdText.get().identityFileUnsupportedFormat, path)); + } + KeyPair result = keys.next(); + if (keys.hasNext()) { + log.warn(format(SshdText.get().identityFileMultipleKeys, path)); + keys.forEachRemaining(k -> { + PrivateKey pk = k.getPrivate(); + if (pk != null) { + try { + pk.destroy(); + } catch (DestroyFailedException e) { + // Ignore + } + } + }); + } + return result; + } + } + private class CancellingKeyPairIterator implements Iterator<KeyPair> { + private final SessionContext context; + private final Iterator<Path> paths; private KeyPair nextItem; private boolean nextSet; - public CancellingKeyPairIterator(Collection<? extends Path> resources) { + public CancellingKeyPairIterator(SessionContext session, + Collection<? extends Path> resources) { List<Path> copy = new ArrayList<>(resources.size()); copy.addAll(resources); paths = copy.iterator(); + context = session; } @Override @@ -152,7 +199,7 @@ public class CachingKeyPairProvider extends EncryptedFileKeyPairProvider nextSet = true; while (nextItem == null && paths.hasNext()) { try { - nextItem = doLoadKey(paths.next()); + nextItem = loadKey(context, paths.next()); } catch (CancellationException cancelled) { throw cancelled; } catch (Exception other) { diff --git a/org.eclipse.jgit.ssh.apache/src/org/eclipse/jgit/internal/transport/sshd/EncryptedFileKeyPairProvider.java b/org.eclipse.jgit.ssh.apache/src/org/eclipse/jgit/internal/transport/sshd/EncryptedFileKeyPairProvider.java deleted file mode 100644 index ef8e611811..0000000000 --- a/org.eclipse.jgit.ssh.apache/src/org/eclipse/jgit/internal/transport/sshd/EncryptedFileKeyPairProvider.java +++ /dev/null @@ -1,158 +0,0 @@ -/* - * 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.internal.transport.sshd; - -import static java.text.MessageFormat.format; - -import java.io.IOException; -import java.io.InputStream; -import java.nio.file.Path; -import java.security.GeneralSecurityException; -import java.security.InvalidKeyException; -import java.security.KeyPair; -import java.security.NoSuchProviderException; -import java.security.PrivateKey; -import java.util.Collection; -import java.util.Iterator; -import java.util.List; - -import javax.security.auth.DestroyFailedException; - -import org.apache.sshd.common.config.keys.FilePasswordProvider; -import org.apache.sshd.common.config.keys.loader.KeyPairResourceParser; -import org.apache.sshd.common.keyprovider.FileKeyPairProvider; -import org.apache.sshd.common.util.io.IoUtils; -import org.apache.sshd.common.util.security.SecurityUtils; -import org.eclipse.jgit.internal.transport.sshd.RepeatingFilePasswordProvider.ResourceDecodeResult; - -/** - * A {@link FileKeyPairProvider} that asks repeatedly for a passphrase for an - * encrypted private key if the {@link FilePasswordProvider} is a - * {@link RepeatingFilePasswordProvider}. - */ -public abstract class EncryptedFileKeyPairProvider extends FileKeyPairProvider { - - // TODO: remove this class once we're based on sshd > 2.1.0. See upstream - // issue SSHD-850 https://issues.apache.org/jira/browse/SSHD-850 and commit - // https://github.com/apache/mina-sshd/commit/f19bd2e34 - - /** - * Creates a new {@link EncryptedFileKeyPairProvider} for the given - * {@link Path}s. - * - * @param paths - * to read keys from - */ - public EncryptedFileKeyPairProvider(List<Path> paths) { - super(paths); - } - - @Override - protected KeyPair doLoadKey(String resourceKey, InputStream inputStream, - FilePasswordProvider provider) - throws IOException, GeneralSecurityException { - if (!(provider instanceof RepeatingFilePasswordProvider)) { - return super.doLoadKey(resourceKey, inputStream, provider); - } - KeyPairResourceParser parser = SecurityUtils.getKeyPairResourceParser(); - if (parser == null) { - // This is an internal configuration error, thus no translation. - throw new NoSuchProviderException( - "No registered key-pair resource parser"); //$NON-NLS-1$ - } - RepeatingFilePasswordProvider realProvider = (RepeatingFilePasswordProvider) provider; - // Read the stream now so that we can process the content several - // times. - List<String> lines = IoUtils.readAllLines(inputStream); - Collection<KeyPair> ids = null; - while (ids == null) { - try { - ids = parser.loadKeyPairs(resourceKey, realProvider, lines); - realProvider.handleDecodeAttemptResult(resourceKey, "", null); //$NON-NLS-1$ - // No exception; success. Exit the loop even if ids is still - // null! - break; - } catch (IOException | GeneralSecurityException - | RuntimeException e) { - ResourceDecodeResult loadResult = realProvider - .handleDecodeAttemptResult(resourceKey, "", e); //$NON-NLS-1$ - if (loadResult == null - || loadResult == ResourceDecodeResult.TERMINATE) { - throw e; - } else if (loadResult == ResourceDecodeResult.RETRY) { - continue; - } - // IGNORE doesn't make any sense here, but OK, let's ignore it. - // ids == null, so we'll throw an exception below. - break; - } - } - if (ids == null) { - // The javadoc on loadKeyPairs says it might return null if no - // key pair found. Bad API. - throw new InvalidKeyException( - format(SshdText.get().identityFileNoKey, resourceKey)); - } - Iterator<KeyPair> keys = ids.iterator(); - if (!keys.hasNext()) { - throw new InvalidKeyException(format( - SshdText.get().identityFileUnsupportedFormat, resourceKey)); - } - KeyPair result = keys.next(); - if (keys.hasNext()) { - log.warn(format(SshdText.get().identityFileMultipleKeys, - resourceKey)); - keys.forEachRemaining(k -> { - PrivateKey pk = k.getPrivate(); - if (pk != null) { - try { - pk.destroy(); - } catch (DestroyFailedException e) { - // Ignore - } - } - }); - } - return result; - } -} diff --git a/org.eclipse.jgit.ssh.apache/src/org/eclipse/jgit/internal/transport/sshd/JGitClientSession.java b/org.eclipse.jgit.ssh.apache/src/org/eclipse/jgit/internal/transport/sshd/JGitClientSession.java index dcf330a2a4..56f8ade667 100644 --- a/org.eclipse.jgit.ssh.apache/src/org/eclipse/jgit/internal/transport/sshd/JGitClientSession.java +++ b/org.eclipse.jgit.ssh.apache/src/org/eclipse/jgit/internal/transport/sshd/JGitClientSession.java @@ -46,6 +46,7 @@ import static java.text.MessageFormat.format; import java.io.IOException; import java.net.SocketAddress; +import java.security.GeneralSecurityException; import java.security.PublicKey; import java.util.ArrayList; import java.util.Iterator; @@ -173,7 +174,8 @@ public class JGitClientSession extends ClientSessionImpl { } @Override - protected byte[] sendKexInit() throws IOException { + protected byte[] sendKexInit() + throws IOException, GeneralSecurityException { StatefulProxyConnector proxy = proxyHandler; if (proxy != null) { try { @@ -187,7 +189,7 @@ public class JGitClientSession extends ClientSessionImpl { // This is called only from the ClientSessionImpl // constructor, where the return value is ignored. return null; - } catch (IOException e) { + } catch (IOException | GeneralSecurityException e) { throw e; } catch (Exception other) { throw new IOException(other.getLocalizedMessage(), other); diff --git a/org.eclipse.jgit.ssh.apache/src/org/eclipse/jgit/internal/transport/sshd/JGitHostConfigEntry.java b/org.eclipse.jgit.ssh.apache/src/org/eclipse/jgit/internal/transport/sshd/JGitHostConfigEntry.java index 7b22b88ab7..21e8beaeb4 100644 --- a/org.eclipse.jgit.ssh.apache/src/org/eclipse/jgit/internal/transport/sshd/JGitHostConfigEntry.java +++ b/org.eclipse.jgit.ssh.apache/src/org/eclipse/jgit/internal/transport/sshd/JGitHostConfigEntry.java @@ -53,28 +53,11 @@ import org.eclipse.jgit.annotations.NonNull; * A {@link HostConfigEntry} that provides access to the multi-valued keys as * lists of strings. The super class treats them as single strings containing * comma-separated lists. - * */ public class JGitHostConfigEntry extends HostConfigEntry { private Map<String, List<String>> multiValuedOptions; - @Override - public String getProperty(String name, String defaultValue) { - // Upstream bug fix (SSHD-867): if there are _no_ properties at all, the - // super implementation returns always null even if a default value is - // given. - // - // See https://issues.apache.org/jira/projects/SSHD/issues/SSHD-867 - // - // TODO: remove this override once we're based on sshd > 2.1.0 - Map<String, String> properties = getProperties(); - if (properties == null || properties.isEmpty()) { - return defaultValue; - } - return super.getProperty(name, defaultValue); - } - /** * Sets the multi-valued options. * diff --git a/org.eclipse.jgit.ssh.apache/src/org/eclipse/jgit/internal/transport/sshd/JGitPublicKeyIterator.java b/org.eclipse.jgit.ssh.apache/src/org/eclipse/jgit/internal/transport/sshd/JGitPublicKeyIterator.java deleted file mode 100644 index cda12623d8..0000000000 --- a/org.eclipse.jgit.ssh.apache/src/org/eclipse/jgit/internal/transport/sshd/JGitPublicKeyIterator.java +++ /dev/null @@ -1,275 +0,0 @@ -/* - * 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.internal.transport.sshd; - -import java.io.IOException; -import java.nio.channels.Channel; -import java.security.KeyPair; -import java.security.PublicKey; -import java.util.ArrayList; -import java.util.Iterator; -import java.util.List; -import java.util.Map; -import java.util.NoSuchElementException; -import java.util.concurrent.atomic.AtomicBoolean; - -import org.apache.sshd.agent.SshAgent; -import org.apache.sshd.agent.SshAgentFactory; -import org.apache.sshd.client.auth.pubkey.AbstractKeyPairIterator; -import org.apache.sshd.client.auth.pubkey.KeyAgentIdentity; -import org.apache.sshd.client.auth.pubkey.KeyPairIdentity; -import org.apache.sshd.client.auth.pubkey.PublicKeyIdentity; -import org.apache.sshd.client.config.hosts.HostConfigEntry; -import org.apache.sshd.client.session.ClientSession; -import org.apache.sshd.common.FactoryManager; -import org.apache.sshd.common.keyprovider.KeyIdentityProvider; -import org.apache.sshd.common.signature.SignatureFactoriesManager; - -/** - * A new iterator over key pairs that we use instead of the default - * {@link org.apache.sshd.client.auth.pubkey.UserAuthPublicKeyIterator}, which - * in its constructor does some strange {@link java.util.stream.Stream} "magic" - * that ends up loading keys prematurely. This class uses plain - * {@link Iterator}s instead to avoid that problem. Used in - * {@link JGitPublicKeyAuthentication}. - * - * @see <a href= - * "https://issues.apache.org/jira/projects/SSHD/issues/SSHD-860">Upstream - * issue SSHD-860</a> - */ -public class JGitPublicKeyIterator - extends AbstractKeyPairIterator<PublicKeyIdentity> implements Channel { - - // Re: the cause for the problem mentioned above has not been determined. - // It looks as if either the Apache code inadvertently calls - // GenericUtils.isEmpty() on all streams (which would load the first key - // of each stream), or the Java stream implementation does some prefetching. - // It's not entirely clear. Using Iterators we have more control over - // what happens when. - - private final AtomicBoolean open = new AtomicBoolean(true); - - private SshAgent agent; - - private final List<Iterator<PublicKeyIdentity>> keys = new ArrayList<>(3); - - private final Iterator<Iterator<PublicKeyIdentity>> keyIter; - - private Iterator<PublicKeyIdentity> current; - - private Boolean hasElement; - - /** - * Creates a new {@link JGitPublicKeyIterator}. - * - * @param session - * we're trying to authenticate - * @param signatureFactories - * to use - * @throws Exception - * if an {@link SshAgentFactory} is configured and getting - * identities from the agent fails - */ - public JGitPublicKeyIterator(ClientSession session, - SignatureFactoriesManager signatureFactories) throws Exception { - super(session); - boolean useAgent = true; - if (session instanceof JGitClientSession) { - HostConfigEntry config = ((JGitClientSession) session) - .getHostConfigEntry(); - useAgent = !config.isIdentitiesOnly(); - } - if (useAgent) { - FactoryManager manager = session.getFactoryManager(); - SshAgentFactory factory = manager == null ? null - : manager.getAgentFactory(); - if (factory != null) { - try { - agent = factory.createClient(manager); - keys.add(new AgentIdentityIterator(agent)); - } catch (IOException e) { - try { - closeAgent(); - } catch (IOException err) { - e.addSuppressed(err); - } - throw e; - } - } - } - keys.add( - new KeyPairIdentityIterator(session.getRegisteredIdentities(), - session, signatureFactories)); - keys.add(new KeyPairIdentityIterator(session.getKeyPairProvider(), - session, signatureFactories)); - keyIter = keys.iterator(); - } - - @Override - public boolean isOpen() { - return open.get(); - } - - @Override - public void close() throws IOException { - if (open.getAndSet(false)) { - closeAgent(); - } - } - - @Override - public boolean hasNext() { - if (!isOpen()) { - return false; - } - if (hasElement != null) { - return hasElement.booleanValue(); - } - while (current == null || !current.hasNext()) { - if (keyIter.hasNext()) { - current = keyIter.next(); - } else { - current = null; - hasElement = Boolean.FALSE; - return false; - } - } - hasElement = Boolean.TRUE; - return true; - } - - @Override - public PublicKeyIdentity next() { - if (!isOpen() || hasElement == null && !hasNext() - || !hasElement.booleanValue()) { - throw new NoSuchElementException(); - } - hasElement = null; - PublicKeyIdentity result; - try { - result = current.next(); - } catch (NoSuchElementException e) { - result = null; - } - return result; - } - - private void closeAgent() throws IOException { - if (agent == null) { - return; - } - try { - agent.close(); - } finally { - agent = null; - } - } - - /** - * An {@link Iterator} that maps the data obtained from an agent to - * {@link PublicKeyIdentity}. - */ - private static class AgentIdentityIterator - implements Iterator<PublicKeyIdentity> { - - private final SshAgent agent; - - private final Iterator<? extends Map.Entry<PublicKey, String>> iter; - - public AgentIdentityIterator(SshAgent agent) throws IOException { - this.agent = agent; - iter = agent == null ? null : agent.getIdentities().iterator(); - } - - @Override - public boolean hasNext() { - return iter != null && iter.hasNext(); - } - - @Override - public PublicKeyIdentity next() { - if (iter == null) { - throw new NoSuchElementException(); - } - Map.Entry<PublicKey, String> entry = iter.next(); - return new KeyAgentIdentity(agent, entry.getKey(), - entry.getValue()); - } - } - - /** - * An {@link Iterator} that maps {@link KeyPair} to - * {@link PublicKeyIdentity}. - */ - private static class KeyPairIdentityIterator - implements Iterator<PublicKeyIdentity> { - - private final Iterator<KeyPair> keyPairs; - - private final ClientSession session; - - private final SignatureFactoriesManager signatureFactories; - - public KeyPairIdentityIterator(KeyIdentityProvider provider, - ClientSession session, - SignatureFactoriesManager signatureFactories) { - this.session = session; - this.signatureFactories = signatureFactories; - keyPairs = provider == null ? null : provider.loadKeys().iterator(); - } - - @Override - public boolean hasNext() { - return keyPairs != null && keyPairs.hasNext(); - } - - @Override - public PublicKeyIdentity next() { - if (keyPairs == null) { - throw new NoSuchElementException(); - } - KeyPair key = keyPairs.next(); - return new KeyPairIdentity(signatureFactories, session, key); - } - } -} diff --git a/org.eclipse.jgit.ssh.apache/src/org/eclipse/jgit/internal/transport/sshd/JGitSshClient.java b/org.eclipse.jgit.ssh.apache/src/org/eclipse/jgit/internal/transport/sshd/JGitSshClient.java index b9ff5e5208..98e71dfe4b 100644 --- a/org.eclipse.jgit.ssh.apache/src/org/eclipse/jgit/internal/transport/sshd/JGitSshClient.java +++ b/org.eclipse.jgit.ssh.apache/src/org/eclipse/jgit/internal/transport/sshd/JGitSshClient.java @@ -48,10 +48,12 @@ import static org.eclipse.jgit.internal.transport.ssh.OpenSshConfigFile.positive import java.io.IOException; import java.net.InetSocketAddress; import java.net.Proxy; +import java.net.SocketAddress; import java.nio.file.Files; import java.nio.file.InvalidPathException; import java.nio.file.Path; import java.nio.file.Paths; +import java.security.GeneralSecurityException; import java.security.KeyPair; import java.util.Arrays; import java.util.Iterator; @@ -66,12 +68,14 @@ import org.apache.sshd.client.future.ConnectFuture; import org.apache.sshd.client.future.DefaultConnectFuture; import org.apache.sshd.client.session.ClientSessionImpl; import org.apache.sshd.client.session.SessionFactory; +import org.apache.sshd.common.AttributeRepository; import org.apache.sshd.common.config.keys.FilePasswordProvider; import org.apache.sshd.common.future.SshFutureListener; import org.apache.sshd.common.io.IoConnectFuture; import org.apache.sshd.common.io.IoSession; import org.apache.sshd.common.keyprovider.AbstractResourceKeyPairProvider; -import org.apache.sshd.common.keyprovider.KeyPairProvider; +import org.apache.sshd.common.keyprovider.KeyIdentityProvider; +import org.apache.sshd.common.session.SessionContext; import org.apache.sshd.common.session.helpers.AbstractSession; import org.apache.sshd.common.util.ValidateUtils; import org.eclipse.jgit.internal.transport.sshd.proxy.HttpClientConnector; @@ -117,7 +121,8 @@ public class JGitSshClient extends SshClient { } @Override - public ConnectFuture connect(HostConfigEntry hostConfig) + public ConnectFuture connect(HostConfigEntry hostConfig, + AttributeRepository context, SocketAddress localAddress) throws IOException { if (connector == null) { throw new IllegalStateException("SshClient not started."); //$NON-NLS-1$ @@ -149,7 +154,7 @@ public class JGitSshClient extends SshClient { address = configureProxy(proxy, address); proxy.clearPassword(); } - connector.connect(address).addListener(listener); + connector.connect(address, this, localAddress).addListener(listener); return connectFuture; } @@ -263,16 +268,16 @@ public class JGitSshClient extends SshClient { identities, keyCache); ourConfiguredKeysProvider.setPasswordFinder(passwordProvider); if (hostConfig.isIdentitiesOnly()) { - session.setKeyPairProvider(ourConfiguredKeysProvider); + session.setKeyIdentityProvider(ourConfiguredKeysProvider); } else { - KeyPairProvider defaultKeysProvider = getKeyPairProvider(); + KeyIdentityProvider defaultKeysProvider = getKeyIdentityProvider(); if (defaultKeysProvider instanceof AbstractResourceKeyPairProvider<?>) { ((AbstractResourceKeyPairProvider<?>) defaultKeysProvider) .setPasswordFinder(passwordProvider); } - KeyPairProvider combinedProvider = new CombinedKeyPairProvider( + KeyIdentityProvider combinedProvider = new CombinedKeyIdentityProvider( ourConfiguredKeysProvider, defaultKeysProvider); - session.setKeyPairProvider(combinedProvider); + session.setKeyIdentityProvider(combinedProvider); } return session; } @@ -363,39 +368,30 @@ public class JGitSshClient extends SshClient { } /** - * A {@link KeyPairProvider} that iterates over the {@link Iterable}s - * returned by other {@link KeyPairProvider}s. + * A {@link KeyIdentityProvider} that iterates over the {@link Iterable}s + * returned by other {@link KeyIdentityProvider}s. */ - private static class CombinedKeyPairProvider implements KeyPairProvider { + private static class CombinedKeyIdentityProvider + implements KeyIdentityProvider { - private final List<KeyPairProvider> providers; + private final List<KeyIdentityProvider> providers; - public CombinedKeyPairProvider(KeyPairProvider... providers) { + public CombinedKeyIdentityProvider(KeyIdentityProvider... providers) { this(Arrays.stream(providers).filter(Objects::nonNull) .collect(Collectors.toList())); } - public CombinedKeyPairProvider(List<KeyPairProvider> providers) { + public CombinedKeyIdentityProvider( + List<KeyIdentityProvider> providers) { this.providers = providers; } @Override - public Iterable<String> getKeyTypes() { - throw new UnsupportedOperationException( - "Should not have been called in a ssh client"); //$NON-NLS-1$ - } - - @Override - public KeyPair loadKey(String type) { - throw new UnsupportedOperationException( - "Should not have been called in a ssh client"); //$NON-NLS-1$ - } - - @Override - public Iterable<KeyPair> loadKeys() { + public Iterable<KeyPair> loadKeys(SessionContext context) { return () -> new Iterator<KeyPair>() { - private Iterator<KeyPairProvider> factories = providers.iterator(); + private Iterator<KeyIdentityProvider> factories = providers + .iterator(); private Iterator<KeyPair> current; private Boolean hasElement; @@ -407,7 +403,12 @@ public class JGitSshClient extends SshClient { } while (current == null || !current.hasNext()) { if (factories.hasNext()) { - current = factories.next().loadKeys().iterator(); + try { + current = factories.next().loadKeys(context) + .iterator(); + } catch (IOException | GeneralSecurityException e) { + throw new RuntimeException(e); + } } else { current = null; hasElement = Boolean.FALSE; diff --git a/org.eclipse.jgit.ssh.apache/src/org/eclipse/jgit/internal/transport/sshd/JGitSshConfig.java b/org.eclipse.jgit.ssh.apache/src/org/eclipse/jgit/internal/transport/sshd/JGitSshConfig.java index 984643961f..6468b3e276 100644 --- a/org.eclipse.jgit.ssh.apache/src/org/eclipse/jgit/internal/transport/sshd/JGitSshConfig.java +++ b/org.eclipse.jgit.ssh.apache/src/org/eclipse/jgit/internal/transport/sshd/JGitSshConfig.java @@ -47,11 +47,13 @@ import static org.eclipse.jgit.internal.transport.ssh.OpenSshConfigFile.positive import java.io.File; import java.io.IOException; +import java.net.SocketAddress; import java.util.Map; import java.util.TreeMap; import org.apache.sshd.client.config.hosts.HostConfigEntry; import org.apache.sshd.client.config.hosts.HostConfigEntryResolver; +import org.apache.sshd.common.AttributeRepository; import org.apache.sshd.common.util.net.SshdSocketAddress; import org.eclipse.jgit.annotations.NonNull; import org.eclipse.jgit.internal.transport.ssh.OpenSshConfigFile; @@ -101,7 +103,8 @@ public class JGitSshConfig implements HostConfigEntryResolver { @Override public HostConfigEntry resolveEffectiveHost(String host, int port, - String username) throws IOException { + SocketAddress localAddress, String username, + AttributeRepository attributes) throws IOException { HostEntry entry = configFile.lookup(host, port, username); JGitHostConfigEntry config = new JGitHostConfigEntry(); // Apache MINA conflates all keys, even multi-valued ones, in one map diff --git a/org.eclipse.jgit.ssh.apache/src/org/eclipse/jgit/internal/transport/sshd/OpenSshServerKeyVerifier.java b/org.eclipse.jgit.ssh.apache/src/org/eclipse/jgit/internal/transport/sshd/OpenSshServerKeyVerifier.java index 7d8f3fd39c..381f7cfc22 100644 --- a/org.eclipse.jgit.ssh.apache/src/org/eclipse/jgit/internal/transport/sshd/OpenSshServerKeyVerifier.java +++ b/org.eclipse.jgit.ssh.apache/src/org/eclipse/jgit/internal/transport/sshd/OpenSshServerKeyVerifier.java @@ -60,6 +60,7 @@ import java.nio.file.Paths; import java.security.GeneralSecurityException; import java.security.PublicKey; import java.util.ArrayList; +import java.util.Arrays; import java.util.Collection; import java.util.Collections; import java.util.LinkedList; @@ -586,9 +587,7 @@ public class OpenSshServerKeyVerifier KeyUtils.getFingerPrint(BuiltinDigests.sha256, expected), KeyUtils.getFingerPrint(BuiltinDigests.md5, actual), KeyUtils.getFingerPrint(BuiltinDigests.sha256, actual)); - for (String line : warning.split("\n")) { //$NON-NLS-1$ - messages.add(line); - } + messages.addAll(Arrays.asList(warning.split("\n"))); //$NON-NLS-1$ CredentialsProvider provider = getCredentialsProvider( clientSession); @@ -673,7 +672,7 @@ public class OpenSshServerKeyVerifier continue; } try { - PublicKey serverKey = keyPart.resolvePublicKey( + PublicKey serverKey = keyPart.resolvePublicKey(null, PublicKeyEntryResolver.IGNORING); if (serverKey == null) { LOG.warn(format( diff --git a/org.eclipse.jgit.ssh.apache/src/org/eclipse/jgit/internal/transport/sshd/PasswordProviderWrapper.java b/org.eclipse.jgit.ssh.apache/src/org/eclipse/jgit/internal/transport/sshd/PasswordProviderWrapper.java index 93bd10285a..bec65f1d3a 100644 --- a/org.eclipse.jgit.ssh.apache/src/org/eclipse/jgit/internal/transport/sshd/PasswordProviderWrapper.java +++ b/org.eclipse.jgit.ssh.apache/src/org/eclipse/jgit/internal/transport/sshd/PasswordProviderWrapper.java @@ -50,6 +50,8 @@ import java.util.Map; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.atomic.AtomicInteger; +import org.apache.sshd.common.NamedResource; +import org.apache.sshd.common.session.SessionContext; import org.eclipse.jgit.annotations.NonNull; import org.eclipse.jgit.transport.CredentialsProvider; import org.eclipse.jgit.transport.URIish; @@ -83,10 +85,12 @@ public class PasswordProviderWrapper implements RepeatingFilePasswordProvider { } @Override - public String getPassword(String resourceKey) throws IOException { + public String getPassword(SessionContext session, NamedResource resource, + int attemptIndex) throws IOException { + String key = resource.getName(); int attempt = counts - .computeIfAbsent(resourceKey, k -> new AtomicInteger()).get(); - char[] passphrase = delegate.getPassphrase(toUri(resourceKey), attempt); + .computeIfAbsent(key, k -> new AtomicInteger()).get(); + char[] passphrase = delegate.getPassphrase(toUri(key), attempt); if (passphrase == null) { return null; } @@ -98,21 +102,23 @@ public class PasswordProviderWrapper implements RepeatingFilePasswordProvider { } @Override - public ResourceDecodeResult handleDecodeAttemptResult(String resourceKey, + public ResourceDecodeResult handleDecodeAttemptResult( + SessionContext session, NamedResource resource, int retryIndex, String password, Exception err) throws IOException, GeneralSecurityException { - AtomicInteger count = counts.get(resourceKey); + String key = resource.getName(); + AtomicInteger count = counts.get(key); int numberOfAttempts = count == null ? 0 : count.incrementAndGet(); ResourceDecodeResult result = null; try { - if (delegate.keyLoaded(toUri(resourceKey), numberOfAttempts, err)) { + if (delegate.keyLoaded(toUri(key), numberOfAttempts, err)) { result = ResourceDecodeResult.RETRY; } else { result = ResourceDecodeResult.TERMINATE; } } finally { if (result != ResourceDecodeResult.RETRY) { - counts.remove(resourceKey); + counts.remove(key); } } return result; diff --git a/org.eclipse.jgit.ssh.apache/src/org/eclipse/jgit/internal/transport/sshd/RepeatingFilePasswordProvider.java b/org.eclipse.jgit.ssh.apache/src/org/eclipse/jgit/internal/transport/sshd/RepeatingFilePasswordProvider.java index e491cae130..977f1a22fe 100644 --- a/org.eclipse.jgit.ssh.apache/src/org/eclipse/jgit/internal/transport/sshd/RepeatingFilePasswordProvider.java +++ b/org.eclipse.jgit.ssh.apache/src/org/eclipse/jgit/internal/transport/sshd/RepeatingFilePasswordProvider.java @@ -42,9 +42,6 @@ */ package org.eclipse.jgit.internal.transport.sshd; -import java.io.IOException; -import java.security.GeneralSecurityException; - import org.apache.sshd.common.config.keys.FilePasswordProvider; /** @@ -74,42 +71,4 @@ public interface RepeatingFilePasswordProvider extends FilePasswordProvider { return 1; } - // The following part of this interface is from the upstream resolution of - // SSHD-850. See https://github.com/apache/mina-sshd/commit/f19bd2e34 . - // TODO: remove this once we move to sshd > 2.1.0 - - /** - * Result value of - * {@link RepeatingFilePasswordProvider#handleDecodeAttemptResult(String, String, Exception)}. - */ - public enum ResourceDecodeResult { - /** Re-throw the decoding exception. */ - TERMINATE, - /** Retry the decoding process - including password prompt. */ - RETRY, - /** Skip attempt and see if we can proceed without the key. */ - IGNORE; - } - - /** - * Invoked to inform the password provider about the decoding result. - * <b>Note:</b> any exception thrown from this method (including if called - * to inform about success) will be propagated instead of the original (if - * any was reported) - * - * @param resourceKey - * The resource key representing the <U>private</U> file - * @param password - * The password that was attempted - * @param err - * The attempt result - {@code null} for success - * @return How to proceed in case of error - <u>ignored</u> if invoked in - * order to report success. <b>Note:</b> {@code null} is same as - * {@link ResourceDecodeResult#TERMINATE}. - * @throws IOException - * @throws GeneralSecurityException - */ - ResourceDecodeResult handleDecodeAttemptResult(String resourceKey, - String password, Exception err) - throws IOException, GeneralSecurityException; } diff --git a/org.eclipse.jgit.ssh.apache/src/org/eclipse/jgit/internal/transport/sshd/auth/BasicAuthentication.java b/org.eclipse.jgit.ssh.apache/src/org/eclipse/jgit/internal/transport/sshd/auth/BasicAuthentication.java index a257a5ebc8..6fa528daf5 100644 --- a/org.eclipse.jgit.ssh.apache/src/org/eclipse/jgit/internal/transport/sshd/auth/BasicAuthentication.java +++ b/org.eclipse.jgit.ssh.apache/src/org/eclipse/jgit/internal/transport/sshd/auth/BasicAuthentication.java @@ -145,18 +145,13 @@ public abstract class BasicAuthentication<ParameterType, TokenType> */ protected void askCredentials() { clearPassword(); - PasswordAuthentication auth = AccessController - .doPrivileged(new PrivilegedAction<PasswordAuthentication>() { - - @Override - public PasswordAuthentication run() { - return Authenticator.requestPasswordAuthentication( - proxy.getHostString(), proxy.getAddress(), - proxy.getPort(), SshConstants.SSH_SCHEME, + PasswordAuthentication auth = AccessController.doPrivileged( + (PrivilegedAction<PasswordAuthentication>) () -> Authenticator + .requestPasswordAuthentication(proxy.getHostString(), + proxy.getAddress(), proxy.getPort(), + SshConstants.SSH_SCHEME, SshdText.get().proxyPasswordPrompt, "Basic", //$NON-NLS-1$ - null, RequestorType.PROXY); - } - }); + null, RequestorType.PROXY)); if (auth == null) { user = ""; //$NON-NLS-1$ throw new CancellationException( diff --git a/org.eclipse.jgit.ssh.apache/src/org/eclipse/jgit/transport/sshd/SshdSession.java b/org.eclipse.jgit.ssh.apache/src/org/eclipse/jgit/transport/sshd/SshdSession.java index 7d0e686a28..1e8d7d1e1e 100644 --- a/org.eclipse.jgit.ssh.apache/src/org/eclipse/jgit/transport/sshd/SshdSession.java +++ b/org.eclipse.jgit.ssh.apache/src/org/eclipse/jgit/transport/sshd/SshdSession.java @@ -177,10 +177,7 @@ public class SshdSession implements RemoteSession { timeoutMillis -= TimeUnit.NANOSECONDS .toMillis(System.nanoTime() - start); } - } catch (IOException e) { - exec.close(true); - throw e; - } catch (RuntimeException e) { + } catch (IOException | RuntimeException e) { exec.close(true); throw e; } diff --git a/org.eclipse.jgit.ssh.apache/src/org/eclipse/jgit/transport/sshd/SshdSessionFactory.java b/org.eclipse.jgit.ssh.apache/src/org/eclipse/jgit/transport/sshd/SshdSessionFactory.java index cdd47bf323..90dc8ca500 100644 --- a/org.eclipse.jgit.ssh.apache/src/org/eclipse/jgit/transport/sshd/SshdSessionFactory.java +++ b/org.eclipse.jgit.ssh.apache/src/org/eclipse/jgit/transport/sshd/SshdSessionFactory.java @@ -64,18 +64,19 @@ import org.apache.sshd.client.ClientBuilder; import org.apache.sshd.client.SshClient; import org.apache.sshd.client.auth.UserAuth; import org.apache.sshd.client.auth.keyboard.UserAuthKeyboardInteractiveFactory; +import org.apache.sshd.client.auth.pubkey.UserAuthPublicKeyFactory; import org.apache.sshd.client.config.hosts.HostConfigEntryResolver; import org.apache.sshd.client.keyverifier.ServerKeyVerifier; import org.apache.sshd.common.NamedFactory; import org.apache.sshd.common.compression.BuiltinCompressions; import org.apache.sshd.common.config.keys.FilePasswordProvider; -import org.apache.sshd.common.keyprovider.KeyPairProvider; +import org.apache.sshd.common.config.keys.loader.openssh.kdf.BCryptKdfOptions; +import org.apache.sshd.common.keyprovider.KeyIdentityProvider; import org.eclipse.jgit.annotations.NonNull; import org.eclipse.jgit.errors.TransportException; import org.eclipse.jgit.internal.transport.sshd.CachingKeyPairProvider; import org.eclipse.jgit.internal.transport.sshd.GssApiWithMicAuthFactory; import org.eclipse.jgit.internal.transport.sshd.JGitPasswordAuthFactory; -import org.eclipse.jgit.internal.transport.sshd.JGitPublicKeyAuthFactory; import org.eclipse.jgit.internal.transport.sshd.JGitSshClient; import org.eclipse.jgit.internal.transport.sshd.JGitSshConfig; import org.eclipse.jgit.internal.transport.sshd.JGitUserInteraction; @@ -157,6 +158,11 @@ public class SshdSessionFactory extends SshSessionFactory implements Closeable { super(); this.keyCache = keyCache; this.proxies = proxies; + // sshd limits the number of BCrypt KDF rounds to 255 by default. + // Decrypting such a key takes about two seconds on my machine. + // I consider this limit too low. The time increases linearly with the + // number of rounds. + BCryptKdfOptions.setMaxAllowedRounds(16384); } /** A simple general map key. */ @@ -211,7 +217,7 @@ public class SshdSessionFactory extends SshSessionFactory implements Closeable { } HostConfigEntryResolver configFile = getHostConfigEntryResolver( home, sshDir); - KeyPairProvider defaultKeysProvider = toKeyPairProvider( + KeyIdentityProvider defaultKeysProvider = toKeyIdentityProvider( getDefaultKeys(sshDir)); KeyPasswordProvider passphrases = createKeyPasswordProvider( credentialsProvider); @@ -227,7 +233,7 @@ public class SshdSessionFactory extends SshSessionFactory implements Closeable { client.setUserInteraction( new JGitUserInteraction(credentialsProvider)); client.setUserAuthFactories(getUserAuthFactories()); - client.setKeyPairProvider(defaultKeysProvider); + client.setKeyIdentityProvider(defaultKeysProvider); // JGit-specific things: JGitSshClient jgitClient = (JGitSshClient) client; jgitClient.setKeyCache(getKeyCache()); @@ -438,17 +444,18 @@ public class SshdSessionFactory extends SshSessionFactory implements Closeable { /** * Converts an {@link Iterable} of {link KeyPair}s into a - * {@link KeyPairProvider}. + * {@link KeyIdentityProvider}. * * @param keys - * to provide via the returned {@link KeyPairProvider} - * @return a {@link KeyPairProvider} that provides the given {@code keys} + * to provide via the returned {@link KeyIdentityProvider} + * @return a {@link KeyIdentityProvider} that provides the given + * {@code keys} */ - private KeyPairProvider toKeyPairProvider(Iterable<KeyPair> keys) { - if (keys instanceof KeyPairProvider) { - return (KeyPairProvider) keys; + private KeyIdentityProvider toKeyIdentityProvider(Iterable<KeyPair> keys) { + if (keys instanceof KeyIdentityProvider) { + return (KeyIdentityProvider) keys; } - return () -> keys; + return (session) -> keys; } /** @@ -522,7 +529,7 @@ public class SshdSessionFactory extends SshSessionFactory implements Closeable { // Password auth doesn't have this problem. return Collections.unmodifiableList( Arrays.asList(GssApiWithMicAuthFactory.INSTANCE, - JGitPublicKeyAuthFactory.INSTANCE, + UserAuthPublicKeyFactory.INSTANCE, JGitPasswordAuthFactory.INSTANCE, UserAuthKeyboardInteractiveFactory.INSTANCE)); } diff --git a/org.eclipse.jgit.test/.settings/org.eclipse.pde.prefs b/org.eclipse.jgit.test/.settings/org.eclipse.pde.prefs new file mode 100644 index 0000000000..2174e4fd5b --- /dev/null +++ b/org.eclipse.jgit.test/.settings/org.eclipse.pde.prefs @@ -0,0 +1,34 @@ +compilers.f.unresolved-features=1 +compilers.f.unresolved-plugins=1 +compilers.incompatible-environment=1 +compilers.p.build=1 +compilers.p.build.bin.includes=1 +compilers.p.build.encodings=2 +compilers.p.build.java.compiler=2 +compilers.p.build.java.compliance=1 +compilers.p.build.missing.output=2 +compilers.p.build.output.library=1 +compilers.p.build.source.library=1 +compilers.p.build.src.includes=1 +compilers.p.deprecated=1 +compilers.p.discouraged-class=1 +compilers.p.internal=1 +compilers.p.missing-packages=2 +compilers.p.missing-version-export-package=2 +compilers.p.missing-version-import-package=2 +compilers.p.missing-version-require-bundle=2 +compilers.p.no-required-att=0 +compilers.p.no.automatic.module=1 +compilers.p.not-externalized-att=2 +compilers.p.service.component.without.lazyactivation=1 +compilers.p.unknown-attribute=1 +compilers.p.unknown-class=1 +compilers.p.unknown-element=1 +compilers.p.unknown-identifier=1 +compilers.p.unknown-resource=1 +compilers.p.unresolved-ex-points=0 +compilers.p.unresolved-import=0 +compilers.s.create-docs=false +compilers.s.doc-folder=doc +compilers.s.open-tags=1 +eclipse.preferences.version=1 diff --git a/org.eclipse.jgit.test/BUILD b/org.eclipse.jgit.test/BUILD index ca5b42e48d..f90a28030d 100644 --- a/org.eclipse.jgit.test/BUILD +++ b/org.eclipse.jgit.test/BUILD @@ -19,6 +19,7 @@ HELPERS = glob( "nls/MissingPropertyBundle.java", "nls/NoPropertiesBundle.java", "nls/NonTranslatedBundle.java", + "revwalk/ReachabilityCheckerTestCase.java", "revwalk/RevQueueTestCase.java", "revwalk/RevWalkTestCase.java", "transport/ObjectIdMatcher.java", @@ -26,6 +27,7 @@ HELPERS = glob( "treewalk/filter/AlwaysCloneTreeFilter.java", "test/resources/SampleDataRepositoryTestCase.java", "util/CPUTimeStopWatch.java", + "util/http/HttpCookiesMatcher.java", "util/io/Strings.java", ]] @@ -68,7 +70,7 @@ java_library( deps = [ "//lib:jsch", "//lib:junit", - "//lib:sshd-core", + "//lib:sshd-osgi", "//lib:sshd-sftp", "//org.eclipse.jgit:jgit", "//org.eclipse.jgit.junit:junit", diff --git a/org.eclipse.jgit.test/META-INF/MANIFEST.MF b/org.eclipse.jgit.test/META-INF/MANIFEST.MF index a1e94bfaa2..c6adef0bcf 100644 --- a/org.eclipse.jgit.test/META-INF/MANIFEST.MF +++ b/org.eclipse.jgit.test/META-INF/MANIFEST.MF @@ -3,7 +3,7 @@ Bundle-ManifestVersion: 2 Bundle-Name: %plugin_name Automatic-Module-Name: org.eclipse.jgit.test Bundle-SymbolicName: org.eclipse.jgit.test -Bundle-Version: 5.3.3.qualifier +Bundle-Version: 5.4.1.qualifier Bundle-Localization: plugin Bundle-Vendor: %provider_name Bundle-ActivationPolicy: lazy @@ -17,57 +17,58 @@ Import-Package: com.googlecode.javaewah;version="[1.1.6,2.0.0)", org.apache.commons.compress.compressors.bzip2;version="[1.15.0,2.0)", org.apache.commons.compress.compressors.gzip;version="[1.15.0,2.0)", org.apache.commons.compress.compressors.xz;version="[1.15.0,2.0)", - org.bouncycastle.util.encoders;version="[1.60.0,2.0.0)", - org.eclipse.jgit.annotations;version="[5.3.3,5.4.0)", - org.eclipse.jgit.api;version="[5.3.3,5.4.0)", - org.eclipse.jgit.api.errors;version="[5.3.3,5.4.0)", - org.eclipse.jgit.archive;version="[5.3.3,5.4.0)", - org.eclipse.jgit.attributes;version="[5.3.3,5.4.0)", - org.eclipse.jgit.awtui;version="[5.3.3,5.4.0)", - org.eclipse.jgit.blame;version="[5.3.3,5.4.0)", - org.eclipse.jgit.diff;version="[5.3.3,5.4.0)", - org.eclipse.jgit.dircache;version="[5.3.3,5.4.0)", - org.eclipse.jgit.errors;version="[5.3.3,5.4.0)", - org.eclipse.jgit.events;version="[5.3.3,5.4.0)", - org.eclipse.jgit.fnmatch;version="[5.3.3,5.4.0)", - org.eclipse.jgit.gitrepo;version="[5.3.3,5.4.0)", - org.eclipse.jgit.hooks;version="[5.3.3,5.4.0)", - org.eclipse.jgit.ignore;version="[5.3.3,5.4.0)", - org.eclipse.jgit.ignore.internal;version="[5.3.3,5.4.0)", - org.eclipse.jgit.internal;version="[5.3.3,5.4.0)", - org.eclipse.jgit.internal.fsck;version="[5.3.3,5.4.0)", - org.eclipse.jgit.internal.storage.dfs;version="[5.3.3,5.4.0)", - org.eclipse.jgit.internal.storage.file;version="[5.3.3,5.4.0)", - org.eclipse.jgit.internal.storage.io;version="[5.3.3,5.4.0)", - org.eclipse.jgit.internal.storage.pack;version="[5.3.3,5.4.0)", - org.eclipse.jgit.internal.storage.reftable;version="[5.3.3,5.4.0)", - org.eclipse.jgit.internal.storage.reftree;version="[5.3.3,5.4.0)", - org.eclipse.jgit.internal.transport.parser;version="[5.3.3,5.4.0)", - org.eclipse.jgit.junit;version="[5.3.3,5.4.0)", - org.eclipse.jgit.junit.ssh;version="[5.3.3,5.4.0)", - org.eclipse.jgit.junit.time;version="[5.3.3,5.4.0)", - org.eclipse.jgit.lfs;version="[5.3.3,5.4.0)", - org.eclipse.jgit.lib;version="[5.3.3,5.4.0)", - org.eclipse.jgit.merge;version="[5.3.3,5.4.0)", - org.eclipse.jgit.nls;version="[5.3.3,5.4.0)", - org.eclipse.jgit.notes;version="[5.3.3,5.4.0)", - org.eclipse.jgit.patch;version="[5.3.3,5.4.0)", - org.eclipse.jgit.pgm;version="[5.3.3,5.4.0)", - org.eclipse.jgit.pgm.internal;version="[5.3.3,5.4.0)", - org.eclipse.jgit.revplot;version="[5.3.3,5.4.0)", - org.eclipse.jgit.revwalk;version="[5.3.3,5.4.0)", - org.eclipse.jgit.revwalk.filter;version="[5.3.3,5.4.0)", - org.eclipse.jgit.storage.file;version="[5.3.3,5.4.0)", - org.eclipse.jgit.storage.pack;version="[5.3.3,5.4.0)", - org.eclipse.jgit.submodule;version="[5.3.3,5.4.0)", - org.eclipse.jgit.transport;version="[5.3.3,5.4.0)", - org.eclipse.jgit.transport.http;version="[5.3.3,5.4.0)", - org.eclipse.jgit.transport.resolver;version="[5.3.3,5.4.0)", - org.eclipse.jgit.treewalk;version="[5.3.3,5.4.0)", - org.eclipse.jgit.treewalk.filter;version="[5.3.3,5.4.0)", - org.eclipse.jgit.util;version="[5.3.3,5.4.0)", - org.eclipse.jgit.util.io;version="[5.3.3,5.4.0)", - org.eclipse.jgit.util.sha1;version="[5.3.3,5.4.0)", + org.bouncycastle.util.encoders;version="[1.61.0,2.0.0)", + org.eclipse.jgit.annotations;version="[5.4.1,5.5.0)", + org.eclipse.jgit.api;version="[5.4.1,5.5.0)", + org.eclipse.jgit.api.errors;version="[5.4.1,5.5.0)", + org.eclipse.jgit.archive;version="[5.4.1,5.5.0)", + org.eclipse.jgit.attributes;version="[5.4.1,5.5.0)", + org.eclipse.jgit.awtui;version="[5.4.1,5.5.0)", + org.eclipse.jgit.blame;version="[5.4.1,5.5.0)", + org.eclipse.jgit.diff;version="[5.4.1,5.5.0)", + org.eclipse.jgit.dircache;version="[5.4.1,5.5.0)", + org.eclipse.jgit.errors;version="[5.4.1,5.5.0)", + org.eclipse.jgit.events;version="[5.4.1,5.5.0)", + org.eclipse.jgit.fnmatch;version="[5.4.1,5.5.0)", + org.eclipse.jgit.gitrepo;version="[5.4.1,5.5.0)", + org.eclipse.jgit.hooks;version="[5.4.1,5.5.0)", + org.eclipse.jgit.ignore;version="[5.4.1,5.5.0)", + org.eclipse.jgit.ignore.internal;version="[5.4.1,5.5.0)", + org.eclipse.jgit.internal;version="[5.4.1,5.5.0)", + org.eclipse.jgit.internal.fsck;version="[5.4.1,5.5.0)", + org.eclipse.jgit.internal.storage.dfs;version="[5.4.1,5.5.0)", + org.eclipse.jgit.internal.storage.file;version="[5.4.1,5.5.0)", + org.eclipse.jgit.internal.storage.io;version="[5.4.1,5.5.0)", + org.eclipse.jgit.internal.storage.pack;version="[5.4.1,5.5.0)", + org.eclipse.jgit.internal.storage.reftable;version="[5.4.1,5.5.0)", + org.eclipse.jgit.internal.storage.reftree;version="[5.4.1,5.5.0)", + org.eclipse.jgit.internal.transport.http;version="[5.4.1,5.5.0)", + org.eclipse.jgit.internal.transport.parser;version="[5.4.1,5.5.0)", + org.eclipse.jgit.junit;version="[5.4.1,5.5.0)", + org.eclipse.jgit.junit.ssh;version="[5.4.1,5.5.0)", + org.eclipse.jgit.junit.time;version="[5.4.1,5.5.0)", + org.eclipse.jgit.lfs;version="[5.4.1,5.5.0)", + org.eclipse.jgit.lib;version="[5.4.1,5.5.0)", + org.eclipse.jgit.merge;version="[5.4.1,5.5.0)", + org.eclipse.jgit.nls;version="[5.4.1,5.5.0)", + org.eclipse.jgit.notes;version="[5.4.1,5.5.0)", + org.eclipse.jgit.patch;version="[5.4.1,5.5.0)", + org.eclipse.jgit.pgm;version="[5.4.1,5.5.0)", + org.eclipse.jgit.pgm.internal;version="[5.4.1,5.5.0)", + org.eclipse.jgit.revplot;version="[5.4.1,5.5.0)", + org.eclipse.jgit.revwalk;version="[5.4.1,5.5.0)", + org.eclipse.jgit.revwalk.filter;version="[5.4.1,5.5.0)", + org.eclipse.jgit.storage.file;version="[5.4.1,5.5.0)", + org.eclipse.jgit.storage.pack;version="[5.4.1,5.5.0)", + org.eclipse.jgit.submodule;version="[5.4.1,5.5.0)", + org.eclipse.jgit.transport;version="[5.4.1,5.5.0)", + org.eclipse.jgit.transport.http;version="[5.4.1,5.5.0)", + org.eclipse.jgit.transport.resolver;version="[5.4.1,5.5.0)", + org.eclipse.jgit.treewalk;version="[5.4.1,5.5.0)", + org.eclipse.jgit.treewalk.filter;version="[5.4.1,5.5.0)", + org.eclipse.jgit.util;version="[5.4.1,5.5.0)", + org.eclipse.jgit.util.io;version="[5.4.1,5.5.0)", + org.eclipse.jgit.util.sha1;version="[5.4.1,5.5.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)", @@ -82,4 +83,4 @@ Import-Package: com.googlecode.javaewah;version="[1.1.6,2.0.0)", org.tukaani.xz;version="[1.6.0,2.0)" Require-Bundle: org.hamcrest.core;bundle-version="[1.1.0,2.0.0)", org.hamcrest.library;bundle-version="[1.1.0,2.0.0)" -Export-Package: org.eclipse.jgit.transport.ssh;version="5.3.3";x-friends:="org.eclipse.jgit.ssh.apache.test" +Export-Package: org.eclipse.jgit.transport.ssh;version="5.4.1";x-friends:="org.eclipse.jgit.ssh.apache.test" diff --git a/org.eclipse.jgit.test/pom.xml b/org.eclipse.jgit.test/pom.xml index e6ba6f8e69..7d930ff117 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.3.3-SNAPSHOT</version> + <version>5.4.1-SNAPSHOT</version> </parent> <artifactId>org.eclipse.jgit.test</artifactId> @@ -197,7 +197,7 @@ <plugin> <artifactId>maven-surefire-plugin</artifactId> <configuration> - <argLine>@{argLine} -Xmx1024m -Dfile.encoding=UTF-8 -Djava.io.tmpdir=${project.build.directory}</argLine> + <argLine>@{argLine} -Xmx768m -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/resources/org/eclipse/jgit/transport/ssh/id_ed25519_expensive_testpass b/org.eclipse.jgit.test/resources/org/eclipse/jgit/transport/ssh/id_ed25519_expensive_testpass new file mode 100644 index 0000000000..904cf302c2 --- /dev/null +++ b/org.eclipse.jgit.test/resources/org/eclipse/jgit/transport/ssh/id_ed25519_expensive_testpass @@ -0,0 +1,8 @@ +-----BEGIN OPENSSH PRIVATE KEY----- +b3BlbnNzaC1rZXktdjEAAAAACmFlczI1Ni1jdHIAAAAGYmNyeXB0AAAAGAAAABAsFN8vig +Nw4/Ow6xbb7MAZAAABAAAAAAEAAAAzAAAAC3NzaC1lZDI1NTE5AAAAIEZXZRjuttLufaP8 +wFD/i4lYPnKk01z46Jwv/9U4mPioAAAAkHLErPaXeC179rzXMaSwClstzsKvJ/Gqh2cY8d +cWzymXtKZcivWMKesRHbC+1qRx53ofx15IzT5Fmg6NuNk4sm2s+lH8x8HN3CPWBfjGIelP +iQUR6M6Y91mPigpRC2HUJmJIaFNdrRqFF84a5+qyK//tdy1fv4gNMLi5yPdXiL/Ttw05FS +LkFikjfvSGZSO/MA== +-----END OPENSSH PRIVATE KEY----- diff --git a/org.eclipse.jgit.test/resources/org/eclipse/jgit/transport/ssh/id_ed25519_expensive_testpass.pub b/org.eclipse.jgit.test/resources/org/eclipse/jgit/transport/ssh/id_ed25519_expensive_testpass.pub new file mode 100644 index 0000000000..65038b5f4c --- /dev/null +++ b/org.eclipse.jgit.test/resources/org/eclipse/jgit/transport/ssh/id_ed25519_expensive_testpass.pub @@ -0,0 +1 @@ +ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIEZXZRjuttLufaP8wFD/i4lYPnKk01z46Jwv/9U4mPio test diff --git a/org.eclipse.jgit.test/src/org/eclipse/jgit/lib/Sets.java b/org.eclipse.jgit.test/src/org/eclipse/jgit/lib/Sets.java index 5a01eae9b5..e6100e225d 100644 --- a/org.eclipse.jgit.test/src/org/eclipse/jgit/lib/Sets.java +++ b/org.eclipse.jgit.test/src/org/eclipse/jgit/lib/Sets.java @@ -43,6 +43,7 @@ package org.eclipse.jgit.lib; +import java.util.Arrays; import java.util.HashSet; import java.util.Set; @@ -50,8 +51,7 @@ public class Sets { @SafeVarargs public static <T> Set<T> of(T... elements) { Set<T> ret = new HashSet<>(); - for (T element : elements) - ret.add(element); + ret.addAll(Arrays.asList(elements)); return ret; } } diff --git a/org.eclipse.jgit.test/src/org/eclipse/jgit/transport/ssh/SshTestBase.java b/org.eclipse.jgit.test/src/org/eclipse/jgit/transport/ssh/SshTestBase.java index 2f367ba51f..b8c90b2a40 100644 --- a/org.eclipse.jgit.test/src/org/eclipse/jgit/transport/ssh/SshTestBase.java +++ b/org.eclipse.jgit.test/src/org/eclipse/jgit/transport/ssh/SshTestBase.java @@ -89,7 +89,9 @@ public abstract class SshTestBase extends SshTestHarness { "id_rsa_4096_testpass", // "id_ecdsa_256_testpass", // "id_ecdsa_384_testpass", // - "id_ecdsa_521_testpass" }; + "id_ecdsa_521_testpass", // + "id_ed25519_testpass", // + "id_ed25519_expensive_testpass" }; protected File defaultCloneDir; diff --git a/org.eclipse.jgit.test/tests.bzl b/org.eclipse.jgit.test/tests.bzl index d2f6d705b6..f27efccc23 100644 --- a/org.eclipse.jgit.test/tests.bzl +++ b/org.eclipse.jgit.test/tests.bzl @@ -46,7 +46,7 @@ def tests(tests): additional_deps = [ "//lib:jsch", "//lib:jzlib", - "//lib:sshd-core", + "//lib:sshd-osgi", "//lib:sshd-sftp", ":sshd-helpers", ] @@ -54,6 +54,10 @@ def tests(tests): additional_deps = [ "//lib:mockito", ] + if src.endswith("TransportHttpTest.java"): + additional_deps = [ + "//lib:mockito", + ] if src.endswith("ArchiveCommandTest.java"): additional_deps = [ "//lib:commons-compress", diff --git a/org.eclipse.jgit.test/tst-rsrc/org/eclipse/jgit/internal/transport/http/cookies-invalid.txt b/org.eclipse.jgit.test/tst-rsrc/org/eclipse/jgit/internal/transport/http/cookies-invalid.txt new file mode 100644 index 0000000000..bbc6a7329a --- /dev/null +++ b/org.eclipse.jgit.test/tst-rsrc/org/eclipse/jgit/internal/transport/http/cookies-invalid.txt @@ -0,0 +1 @@ +some-domain /some/path1 FALSE 0 key1 value1
\ No newline at end of file diff --git a/org.eclipse.jgit.test/tst-rsrc/org/eclipse/jgit/internal/transport/http/cookies-simple1.txt b/org.eclipse.jgit.test/tst-rsrc/org/eclipse/jgit/internal/transport/http/cookies-simple1.txt new file mode 100644 index 0000000000..e06b38c712 --- /dev/null +++ b/org.eclipse.jgit.test/tst-rsrc/org/eclipse/jgit/internal/transport/http/cookies-simple1.txt @@ -0,0 +1,2 @@ +some-domain1 TRUE /some/path1 FALSE 1893499200000 key1 valueFromSimple1 +some-domain1 TRUE /some/path1 FALSE 1893499200000 key2 valueFromSimple1
\ No newline at end of file diff --git a/org.eclipse.jgit.test/tst-rsrc/org/eclipse/jgit/internal/transport/http/cookies-simple2.txt b/org.eclipse.jgit.test/tst-rsrc/org/eclipse/jgit/internal/transport/http/cookies-simple2.txt new file mode 100644 index 0000000000..4bf6723fda --- /dev/null +++ b/org.eclipse.jgit.test/tst-rsrc/org/eclipse/jgit/internal/transport/http/cookies-simple2.txt @@ -0,0 +1,2 @@ +some-domain1 TRUE /some/path1 FALSE 1893499200000 key1 valueFromSimple2 +some-domain1 TRUE /some/path1 FALSE 1893499200000 key3 valueFromSimple2
\ No newline at end of file diff --git a/org.eclipse.jgit.test/tst-rsrc/org/eclipse/jgit/internal/transport/http/cookies-with-empty-and-comment-lines.txt b/org.eclipse.jgit.test/tst-rsrc/org/eclipse/jgit/internal/transport/http/cookies-with-empty-and-comment-lines.txt new file mode 100644 index 0000000000..a9b8a28153 --- /dev/null +++ b/org.eclipse.jgit.test/tst-rsrc/org/eclipse/jgit/internal/transport/http/cookies-with-empty-and-comment-lines.txt @@ -0,0 +1,8 @@ +# first line is a comment +# the next cookie is supposed to be removed, because it has expired already +some-domain1 TRUE /some/path1 FALSE 0 key1 value1 + +# expires date is 01/01/2030 @ 12:00am (UTC) +#HttpOnly_.some-domain2 TRUE /some/path2 TRUE 1893499200000 key2 value2 + +some-domain3 TRUE /some/path3 FALSE 1893499200000 key3 value3
\ No newline at end of file diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/CleanCommandTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/CleanCommandTest.java index 139f199f7a..c9852e8b83 100644 --- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/CleanCommandTest.java +++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/CleanCommandTest.java @@ -98,7 +98,7 @@ public class CleanCommandTest extends RepositoryTestCase { StatusCommand command = git.status(); Status status = command.call(); Set<String> files = status.getUntracked(); - assertTrue(files.size() > 0); + assertFalse(files.isEmpty()); // run clean Set<String> cleanedFiles = git.clean().call(); @@ -120,7 +120,7 @@ public class CleanCommandTest extends RepositoryTestCase { StatusCommand command = git.status(); Status status = command.call(); Set<String> files = status.getUntracked(); - assertTrue(files.size() > 0); + assertFalse(files.isEmpty()); // run clean Set<String> cleanedFiles = git.clean().setCleanDirectories(true).call(); @@ -128,7 +128,7 @@ public class CleanCommandTest extends RepositoryTestCase { status = git.status().call(); files = status.getUntracked(); - assertTrue(files.size() == 0); + assertTrue(files.isEmpty()); assertTrue(cleanedFiles.contains("File2.txt")); assertTrue(cleanedFiles.contains("File3.txt")); assertTrue(!cleanedFiles.contains("sub-noclean/File1.txt")); @@ -143,7 +143,7 @@ public class CleanCommandTest extends RepositoryTestCase { StatusCommand command = git.status(); Status status = command.call(); Set<String> files = status.getUntracked(); - assertTrue(files.size() > 0); + assertFalse(files.isEmpty()); // run clean with setPaths Set<String> paths = new TreeSet<>(); @@ -164,7 +164,7 @@ public class CleanCommandTest extends RepositoryTestCase { StatusCommand command = git.status(); Status status = command.call(); Set<String> files = status.getUntracked(); - assertTrue(files.size() > 0); + assertFalse(files.isEmpty()); // run clean Set<String> cleanedFiles = git.clean().setDryRun(true).call(); @@ -186,7 +186,7 @@ public class CleanCommandTest extends RepositoryTestCase { StatusCommand command = git.status(); Status status = command.call(); Set<String> files = status.getUntracked(); - assertTrue(files.size() > 0); + assertFalse(files.isEmpty()); // run clean Set<String> cleanedFiles = git.clean().setDryRun(true) diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/CloneCommandTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/CloneCommandTest.java index 383436c51b..2270a6a8be 100644 --- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/CloneCommandTest.java +++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/CloneCommandTest.java @@ -718,6 +718,34 @@ public class CloneCommandTest extends RepositoryTestCase { } + @Test + public void testCloneWithPullMerge() throws Exception { + File directory = createTempDirectory("testCloneRepository1"); + try (Git g = Git.init().setDirectory(directory).setBare(false).call()) { + g.remoteAdd().setName(Constants.DEFAULT_REMOTE_NAME) + .setUri(new URIish(fileUri())).call(); + PullResult result = g.pull().setRebase(false).call(); + assertTrue(result.isSuccessful()); + assertEquals("refs/heads/master", + g.getRepository().getFullBranch()); + checkFile(new File(directory, "Test.txt"), "Hello world"); + } + } + + @Test + public void testCloneWithPullRebase() throws Exception { + File directory = createTempDirectory("testCloneRepository1"); + try (Git g = Git.init().setDirectory(directory).setBare(false).call()) { + g.remoteAdd().setName(Constants.DEFAULT_REMOTE_NAME) + .setUri(new URIish(fileUri())).call(); + PullResult result = g.pull().setRebase(true).call(); + assertTrue(result.isSuccessful()); + assertEquals("refs/heads/master", + g.getRepository().getFullBranch()); + checkFile(new File(directory, "Test.txt"), "Hello world"); + } + } + private String fileUri() { return "file://" + git.getRepository().getWorkTree().getAbsolutePath(); } diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/CommitCommandTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/CommitCommandTest.java index e4b7ed7ba7..3bde0eb33f 100644 --- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/CommitCommandTest.java +++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/CommitCommandTest.java @@ -487,7 +487,7 @@ public class CommitCommandTest extends RepositoryTestCase { } private static String reflogComments(List<ReflogEntry> entries) { - StringBuffer b = new StringBuffer(); + StringBuilder b = new StringBuilder(); for (ReflogEntry e : entries) { b.append(e.getComment()).append(";"); } @@ -663,6 +663,54 @@ public class CommitCommandTest extends RepositoryTestCase { } } + @Test + public void testDeletionConflictWithAutoCrlf() throws Exception { + try (Git git = new Git(db)) { + // Commit a file with CR/LF into the index + FileBasedConfig config = db.getConfig(); + config.setString("core", null, "autocrlf", "false"); + config.save(); + File file = writeTrashFile("file.txt", "foo\r\n"); + git.add().addFilepattern("file.txt").call(); + git.commit().setMessage("Initial").call(); + // Switch to side branch + git.checkout().setCreateBranch(true).setName("side").call(); + assertTrue(file.delete()); + git.rm().addFilepattern("file.txt").call(); + git.commit().setMessage("Side").call(); + // Switch on autocrlf=true + config.setString("core", null, "autocrlf", "true"); + config.save(); + // Switch back to master and commit a conflict + git.checkout().setName("master").call(); + writeTrashFile("file.txt", "foob\r\n"); + git.add().addFilepattern("file.txt").call(); + assertEquals("[file.txt, mode:100644, content:foob\r\n]", + indexState(CONTENT)); + writeTrashFile("g", "file2.txt", "anything"); + git.add().addFilepattern("g/file2.txt"); + RevCommit master = git.commit().setMessage("Second").call(); + // Switch to side branch again so that the deletion is "ours" + git.checkout().setName("side").call(); + // Cherry pick master: produces a delete-modify conflict. + CherryPickResult pick = git.cherryPick().include(master).call(); + assertEquals("Expected a cherry-pick conflict", + CherryPickStatus.CONFLICTING, pick.getStatus()); + // XXX: g/file2.txt should actually be staged already, but isn't. + git.add().addFilepattern("g/file2.txt").call(); + // Resolve the conflict by taking the master version + writeTrashFile("file.txt", "foob\r\n"); + git.add().addFilepattern("file.txt").call(); + git.commit().setMessage("Cherry").call(); + // We expect this to be committed with a single LF since there is no + // "ours" stage. + assertEquals( + "[file.txt, mode:100644, content:foob\n]" + + "[g/file2.txt, mode:100644, content:anything]", + indexState(CONTENT)); + } + } + private void testConflictWithAutoCrlf(String baseLf, String lf) throws Exception { try (Git git = new Git(db)) { diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/DescribeCommandTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/DescribeCommandTest.java index 807079eb23..df9ae6a0fb 100644 --- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/DescribeCommandTest.java +++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/DescribeCommandTest.java @@ -109,7 +109,7 @@ public class DescribeCommandTest extends RepositoryTestCase { assertNameStartsWith(c4, "3e563c5"); assertNull(describe(c1)); - assertNull(describe(c1, true)); + assertNull(describe(c1, true, false)); assertNull(describe(c1, "a*", "b*", "c*")); assertNull(describe(c2, "bob*")); assertNull(describe(c2, "?ob*")); @@ -120,7 +120,7 @@ public class DescribeCommandTest extends RepositoryTestCase { assertEquals("alice-t1", describe(c2, "a*", "b*", "c*")); assertEquals("bob-t2", describe(c3)); - assertEquals("bob-t2-0-g44579eb", describe(c3, true)); + assertEquals("bob-t2-0-g44579eb", describe(c3, true, false)); assertEquals("alice-t1-1-g44579eb", describe(c3, "alice*")); assertEquals("alice-t1-1-g44579eb", describe(c3, "a??c?-t*")); assertEquals("bob-t2", describe(c3, "bob*")); @@ -129,7 +129,7 @@ public class DescribeCommandTest extends RepositoryTestCase { // the value verified with git-describe(1) assertEquals("bob-t2-1-g3e563c5", describe(c4)); - assertEquals("bob-t2-1-g3e563c5", describe(c4, true)); + assertEquals("bob-t2-1-g3e563c5", describe(c4, true, false)); assertEquals("alice-t1-2-g3e563c5", describe(c4, "alice*")); assertEquals("bob-t2-1-g3e563c5", describe(c4, "bob*")); assertEquals("bob-t2-1-g3e563c5", describe(c4, "a*", "b*", "c*")); @@ -137,6 +137,10 @@ public class DescribeCommandTest extends RepositoryTestCase { assertEquals(null, describe(c2)); assertEquals(null, describe(c3)); assertEquals(null, describe(c4)); + + assertEquals("3747db3", describe(c2, false, true)); + assertEquals("44579eb", describe(c3, false, true)); + assertEquals("3e563c5", describe(c4, false, true)); } // test default target @@ -169,6 +173,10 @@ public class DescribeCommandTest extends RepositoryTestCase { if (!useAnnotatedTags && !describeUseAllTags) { assertEquals(null, describe(c1)); assertEquals(null, describe(c2)); + + assertEquals("fd70040", describe(c1, false, true)); + assertEquals("b89dead", describe(c2, false, true)); + return; } @@ -203,7 +211,6 @@ public class DescribeCommandTest extends RepositoryTestCase { assertNotNull(describe(c1, "v1.1*", "v1.0*")); assertNotNull(describe(c2, "v1.0*", "v1.1*")); assertNotNull(describe(c2, "v1.1*", "v1.0*")); - } } @@ -236,9 +243,11 @@ public class DescribeCommandTest extends RepositoryTestCase { assertEquals("2 commits: c4 and c3", "t-2-g119892b", describe(c4)); } else { assertEquals(null, describe(c4)); + + assertEquals("119892b", describe(c4, false, true)); } assertNull(describe(c3)); - assertNull(describe(c3, true)); + assertNull(describe(c3, true, false)); } private void branch(String name, ObjectId base) throws GitAPIException { @@ -280,6 +289,9 @@ public class DescribeCommandTest extends RepositoryTestCase { } else { assertEquals(null, describe(c4)); assertEquals(null, describe(c3)); + + assertEquals("119892b", describe(c4, false, true)); + assertEquals("0244e7f", describe(c3, false, true)); } } @@ -369,6 +381,8 @@ public class DescribeCommandTest extends RepositoryTestCase { assertEquals("t1-3-gbb389a4", describe(c4)); } else { assertEquals(null, describe(c4)); + + assertEquals("bb389a4", describe(c4, false, true)); } } @@ -402,6 +416,25 @@ public class DescribeCommandTest extends RepositoryTestCase { assertEquals("t2-4-gbb389a4", describe(c4)); } else { assertEquals(null, describe(c4)); + + assertEquals("bb389a4", describe(c4, false, true)); + } + } + + @Test + public void globMatchWithSlashes() throws Exception { + ObjectId c1 = modify("aaa"); + tag("a/b/version"); + ObjectId c2 = modify("bbb"); + tag("a/b/version2"); + if (useAnnotatedTags || describeUseAllTags) { + assertEquals("a/b/version", describe(c1, "*/version*")); + assertEquals("a/b/version2", describe(c2, "*/version*")); + } else { + assertNull(describe(c1)); + assertNull(describe(c1, "*/version*")); + assertNull(describe(c2)); + assertNull(describe(c2, "*/version*")); } } @@ -434,14 +467,14 @@ public class DescribeCommandTest extends RepositoryTestCase { } } - private String describe(ObjectId c1, boolean longDesc) + private String describe(ObjectId c1, boolean longDesc, boolean always) throws GitAPIException, IOException { return git.describe().setTarget(c1).setTags(describeUseAllTags) - .setLong(longDesc).call(); + .setLong(longDesc).setAlways(always).call(); } private String describe(ObjectId c1) throws GitAPIException, IOException { - return describe(c1, false); + return describe(c1, false, false); } private String describe(ObjectId c1, String... patterns) throws Exception { 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 9461c42500..2fd378842f 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 @@ -346,14 +346,11 @@ public class PullCommandTest extends RepositoryTestCase { @Test /** global rebase config should be respected */ public void testPullWithRebasePreserve1Config() throws Exception { - Callable<PullResult> setup = new Callable<PullResult>() { - @Override - public PullResult call() throws Exception { - StoredConfig config = dbTarget.getConfig(); - config.setString("pull", null, "rebase", "preserve"); - config.save(); - return target.pull().call(); - } + Callable<PullResult> setup = () -> { + StoredConfig config = dbTarget.getConfig(); + config.setString("pull", null, "rebase", "preserve"); + config.save(); + return target.pull().call(); }; doTestPullWithRebase(setup, TestPullMode.REBASE_PREASERVE); } @@ -361,15 +358,12 @@ public class PullCommandTest extends RepositoryTestCase { @Test /** the branch-local config should win over the global config */ public void testPullWithRebasePreserveConfig2() throws Exception { - Callable<PullResult> setup = new Callable<PullResult>() { - @Override - public PullResult call() throws Exception { - StoredConfig config = dbTarget.getConfig(); - config.setString("pull", null, "rebase", "false"); - config.setString("branch", "master", "rebase", "preserve"); - config.save(); - return target.pull().call(); - } + Callable<PullResult> setup = () -> { + StoredConfig config = dbTarget.getConfig(); + config.setString("pull", null, "rebase", "false"); + config.setString("branch", "master", "rebase", "preserve"); + config.save(); + return target.pull().call(); }; doTestPullWithRebase(setup, TestPullMode.REBASE_PREASERVE); } @@ -377,14 +371,11 @@ public class PullCommandTest extends RepositoryTestCase { @Test /** the branch-local config should be respected */ public void testPullWithRebasePreserveConfig3() throws Exception { - Callable<PullResult> setup = new Callable<PullResult>() { - @Override - public PullResult call() throws Exception { - StoredConfig config = dbTarget.getConfig(); - config.setString("branch", "master", "rebase", "preserve"); - config.save(); - return target.pull().call(); - } + Callable<PullResult> setup = () -> { + StoredConfig config = dbTarget.getConfig(); + config.setString("branch", "master", "rebase", "preserve"); + config.save(); + return target.pull().call(); }; doTestPullWithRebase(setup, TestPullMode.REBASE_PREASERVE); } @@ -392,14 +383,11 @@ public class PullCommandTest extends RepositoryTestCase { @Test /** global rebase config should be respected */ public void testPullWithRebaseConfig1() throws Exception { - Callable<PullResult> setup = new Callable<PullResult>() { - @Override - public PullResult call() throws Exception { - StoredConfig config = dbTarget.getConfig(); - config.setString("pull", null, "rebase", "true"); - config.save(); - return target.pull().call(); - } + Callable<PullResult> setup = () -> { + StoredConfig config = dbTarget.getConfig(); + config.setString("pull", null, "rebase", "true"); + config.save(); + return target.pull().call(); }; doTestPullWithRebase(setup, TestPullMode.REBASE); } @@ -407,15 +395,12 @@ public class PullCommandTest extends RepositoryTestCase { @Test /** the branch-local config should win over the global config */ public void testPullWithRebaseConfig2() throws Exception { - Callable<PullResult> setup = new Callable<PullResult>() { - @Override - public PullResult call() throws Exception { - StoredConfig config = dbTarget.getConfig(); - config.setString("pull", null, "rebase", "preserve"); - config.setString("branch", "master", "rebase", "true"); - config.save(); - return target.pull().call(); - } + Callable<PullResult> setup = () -> { + StoredConfig config = dbTarget.getConfig(); + config.setString("pull", null, "rebase", "preserve"); + config.setString("branch", "master", "rebase", "true"); + config.save(); + return target.pull().call(); }; doTestPullWithRebase(setup, TestPullMode.REBASE); } @@ -423,14 +408,11 @@ public class PullCommandTest extends RepositoryTestCase { @Test /** the branch-local config should be respected */ public void testPullWithRebaseConfig3() throws Exception { - Callable<PullResult> setup = new Callable<PullResult>() { - @Override - public PullResult call() throws Exception { - StoredConfig config = dbTarget.getConfig(); - config.setString("branch", "master", "rebase", "true"); - config.save(); - return target.pull().call(); - } + Callable<PullResult> setup = () -> { + StoredConfig config = dbTarget.getConfig(); + config.setString("branch", "master", "rebase", "true"); + config.save(); + return target.pull().call(); }; doTestPullWithRebase(setup, TestPullMode.REBASE); } @@ -438,27 +420,19 @@ public class PullCommandTest extends RepositoryTestCase { @Test /** without config it should merge */ public void testPullWithoutConfig() throws Exception { - Callable<PullResult> setup = new Callable<PullResult>() { - @Override - public PullResult call() throws Exception { - return target.pull().call(); - } - }; + Callable<PullResult> setup = target.pull()::call; doTestPullWithRebase(setup, TestPullMode.MERGE); } @Test /** the branch local config should win over the global config */ public void testPullWithMergeConfig() throws Exception { - Callable<PullResult> setup = new Callable<PullResult>() { - @Override - public PullResult call() throws Exception { - StoredConfig config = dbTarget.getConfig(); - config.setString("pull", null, "rebase", "true"); - config.setString("branch", "master", "rebase", "false"); - config.save(); - return target.pull().call(); - } + Callable<PullResult> setup = () -> { + StoredConfig config = dbTarget.getConfig(); + config.setString("pull", null, "rebase", "true"); + config.setString("branch", "master", "rebase", "false"); + config.save(); + return target.pull().call(); }; doTestPullWithRebase(setup, TestPullMode.MERGE); } @@ -466,14 +440,11 @@ public class PullCommandTest extends RepositoryTestCase { @Test /** the branch local config should win over the global config */ public void testPullWithMergeConfig2() throws Exception { - Callable<PullResult> setup = new Callable<PullResult>() { - @Override - public PullResult call() throws Exception { - StoredConfig config = dbTarget.getConfig(); - config.setString("pull", null, "rebase", "false"); - config.save(); - return target.pull().call(); - } + Callable<PullResult> setup = () -> { + StoredConfig config = dbTarget.getConfig(); + config.setString("pull", null, "rebase", "false"); + config.save(); + return target.pull().call(); }; doTestPullWithRebase(setup, TestPullMode.MERGE); } diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/attributes/TreeWalkAttributeTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/attributes/TreeWalkAttributeTest.java index 1d9cd78140..d6aead4a52 100644 --- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/attributes/TreeWalkAttributeTest.java +++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/attributes/TreeWalkAttributeTest.java @@ -49,6 +49,7 @@ import static org.junit.Assert.assertTrue; import java.io.File; import java.io.IOException; import java.util.ArrayList; +import java.util.Arrays; import java.util.Collection; import java.util.Collections; import java.util.HashSet; @@ -854,8 +855,7 @@ public class TreeWalkAttributeTest extends RepositoryTestCase { static Set<Attribute> asSet(Attribute... attrs) { HashSet<Attribute> result = new HashSet<>(); - for (Attribute attr : attrs) - result.add(attr); + result.addAll(Arrays.asList(attrs)); return result; } diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/dircache/DirCacheBasicTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/dircache/DirCacheBasicTest.java index 014406eb98..972dc60156 100644 --- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/dircache/DirCacheBasicTest.java +++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/dircache/DirCacheBasicTest.java @@ -205,8 +205,9 @@ public class DirCacheBasicTest extends RepositoryTestCase { } final DirCacheBuilder b = dc.builder(); - for (int i = 0; i < ents.length; i++) - b.add(ents[i]); + for (DirCacheEntry ent : ents) { + b.add(ent); + } b.finish(); assertFalse(dc.hasUnmergedPaths()); @@ -229,8 +230,9 @@ public class DirCacheBasicTest extends RepositoryTestCase { ents[2].setFileMode(FileMode.REGULAR_FILE); final DirCacheBuilder b = dc.builder(); - for (int i = 0; i < ents.length; i++) - b.add(ents[i]); + for (DirCacheEntry ent : ents) { + b.add(ent); + } b.finish(); assertTrue(dc.hasUnmergedPaths()); } diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/dircache/DirCacheBuilderIteratorTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/dircache/DirCacheBuilderIteratorTest.java index 3598f3a4a1..6020a748aa 100644 --- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/dircache/DirCacheBuilderIteratorTest.java +++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/dircache/DirCacheBuilderIteratorTest.java @@ -71,8 +71,9 @@ public class DirCacheBuilderIteratorTest extends RepositoryTestCase { } { final DirCacheBuilder b = dc.builder(); - for (int i = 0; i < ents.length; i++) - b.add(ents[i]); + for (DirCacheEntry ent : ents) { + b.add(ent); + } b.finish(); } diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/dircache/DirCacheBuilderTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/dircache/DirCacheBuilderTest.java index 50753ae1bd..cdf86f00a9 100644 --- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/dircache/DirCacheBuilderTest.java +++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/dircache/DirCacheBuilderTest.java @@ -211,12 +211,8 @@ public class DirCacheBuilderTest extends RepositoryTestCase { boolean receivedEvent = false; DirCache dc = db.lockDirCache(); - IndexChangedListener listener = new IndexChangedListener() { - - @Override - public void onIndexChanged(IndexChangedEvent event) { - throw new ReceivedEventMarkerException(); - } + IndexChangedListener listener = (IndexChangedEvent event) -> { + throw new ReceivedEventMarkerException(); }; ListenerList l = db.getListenerList(); @@ -239,12 +235,8 @@ public class DirCacheBuilderTest extends RepositoryTestCase { // do the same again, as this doesn't change index compared to first // round we should get no event this time dc = db.lockDirCache(); - listener = new IndexChangedListener() { - - @Override - public void onIndexChanged(IndexChangedEvent event) { - throw new ReceivedEventMarkerException(); - } + listener = (IndexChangedEvent event) -> { + throw new ReceivedEventMarkerException(); }; l = db.getListenerList(); @@ -302,8 +294,9 @@ public class DirCacheBuilderTest extends RepositoryTestCase { } final DirCacheBuilder b = dc.builder(); - for (int i = 0; i < ents.length; i++) - b.add(ents[i]); + for (DirCacheEntry ent : ents) { + b.add(ent); + } b.finish(); assertEquals(paths.length, dc.getEntryCount()); @@ -352,8 +345,9 @@ public class DirCacheBuilderTest extends RepositoryTestCase { } { final DirCacheBuilder b = dc.builder(); - for (int i = 0; i < ents.length; i++) - b.add(ents[i]); + for (DirCacheEntry ent : ents) { + b.add(ent); + } b.finish(); } assertEquals(paths.length, dc.getEntryCount()); diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/dircache/DirCacheFindTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/dircache/DirCacheFindTest.java index 3b8c6ee7b4..7fc28018f6 100644 --- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/dircache/DirCacheFindTest.java +++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/dircache/DirCacheFindTest.java @@ -66,8 +66,9 @@ public class DirCacheFindTest extends RepositoryTestCase { final int aLast = 3; final DirCacheBuilder b = dc.builder(); - for (int i = 0; i < ents.length; i++) - b.add(ents[i]); + for (DirCacheEntry ent : ents) { + b.add(ent); + } b.finish(); assertEquals(paths.length, dc.getEntryCount()); diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/dircache/DirCacheIteratorTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/dircache/DirCacheIteratorTest.java index 82565fceec..bc99aeef2f 100644 --- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/dircache/DirCacheIteratorTest.java +++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/dircache/DirCacheIteratorTest.java @@ -94,8 +94,9 @@ public class DirCacheIteratorTest extends RepositoryTestCase { } final DirCacheBuilder b = dc.builder(); - for (int i = 0; i < ents.length; i++) - b.add(ents[i]); + for (DirCacheEntry ent : ents) { + b.add(ent); + } b.finish(); final DirCacheIterator i = new DirCacheIterator(dc); @@ -121,8 +122,9 @@ public class DirCacheIteratorTest extends RepositoryTestCase { } final DirCacheBuilder b = dc.builder(); - for (int i = 0; i < ents.length; i++) - b.add(ents[i]); + for (DirCacheEntry ent : ents) { + b.add(ent); + } b.finish(); final DirCacheIterator i = new DirCacheIterator(dc); @@ -154,8 +156,9 @@ public class DirCacheIteratorTest extends RepositoryTestCase { } final DirCacheBuilder b = dc.builder(); - for (int i = 0; i < ents.length; i++) - b.add(ents[i]); + for (DirCacheEntry ent : ents) { + b.add(ent); + } b.finish(); final String[] expPaths = { "a-", "a", "a0b" }; @@ -200,8 +203,9 @@ public class DirCacheIteratorTest extends RepositoryTestCase { } final DirCacheBuilder b = dc.builder(); - for (int i = 0; i < ents.length; i++) - b.add(ents[i]); + for (DirCacheEntry ent : ents) { + b.add(ent); + } b.finish(); final DirCacheIterator i = new DirCacheIterator(dc); @@ -236,8 +240,9 @@ public class DirCacheIteratorTest extends RepositoryTestCase { } final DirCacheBuilder b = dc.builder(); - for (int i = 0; i < ents.length; i++) - b.add(ents[i]); + for (DirCacheEntry ent : ents) { + b.add(ent); + } b.finish(); try (TreeWalk tw = new TreeWalk(db)) { @@ -271,8 +276,9 @@ public class DirCacheIteratorTest extends RepositoryTestCase { } final DirCacheBuilder b = dc.builder(); - for (int i = 0; i < ents.length; i++) - b.add(ents[i]); + for (DirCacheEntry ent : ents) { + b.add(ent); + } b.finish(); DirCacheIterator dci = new DirCacheIterator(dc); @@ -365,8 +371,9 @@ public class DirCacheIteratorTest extends RepositoryTestCase { } final DirCacheBuilder b = dc.builder(); - for (int i = 0; i < ents.length; i++) - b.add(ents[i]); + for (DirCacheEntry ent : ents) { + b.add(ent); + } b.finish(); DirCacheIterator dci = new DirCacheIterator(dc); @@ -398,8 +405,9 @@ public class DirCacheIteratorTest extends RepositoryTestCase { } final DirCacheBuilder b = dc.builder(); - for (int i = 0; i < ents.length; i++) - b.add(ents[i]); + for (DirCacheEntry ent : ents) { + b.add(ent); + } b.finish(); try (TreeWalk tw = new TreeWalk(db)) { diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/dircache/DirCacheTreeTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/dircache/DirCacheTreeTest.java index f662e2660c..513db75323 100644 --- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/dircache/DirCacheTreeTest.java +++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/dircache/DirCacheTreeTest.java @@ -102,8 +102,9 @@ public class DirCacheTreeTest extends RepositoryTestCase { final int aLast = 3; final DirCacheBuilder b = dc.builder(); - for (int i = 0; i < ents.length; i++) - b.add(ents[i]); + for (DirCacheEntry ent : ents) { + b.add(ent); + } b.finish(); assertNull(dc.getCacheTree(false)); @@ -142,8 +143,9 @@ public class DirCacheTreeTest extends RepositoryTestCase { final int acLast = 3; final DirCacheBuilder b = dc.builder(); - for (int i = 0; i < ents.length; i++) - b.add(ents[i]); + for (DirCacheEntry ent : ents) { + b.add(ent); + } b.finish(); assertNull(dc.getCacheTree(false)); @@ -198,8 +200,9 @@ public class DirCacheTreeTest extends RepositoryTestCase { } final DirCacheBuilder b = dc.builder(); - for (int i = 0; i < ents.length; i++) - b.add(ents[i]); + for (DirCacheEntry ent : ents) { + b.add(ent); + } b.commit(); DirCache read = db.readDirCache(); diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/events/ConfigChangeEventTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/events/ConfigChangeEventTest.java index 3624100671..b6f312dfec 100644 --- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/events/ConfigChangeEventTest.java +++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/events/ConfigChangeEventTest.java @@ -54,12 +54,9 @@ public class ConfigChangeEventTest extends RepositoryTestCase { @Test public void testFileRepository_ChangeEventsOnlyOnSave() throws Exception { final ConfigChangedEvent[] events = new ConfigChangedEvent[1]; - db.getListenerList().addConfigChangedListener( - new ConfigChangedListener() { - @Override - public void onConfigChanged(ConfigChangedEvent event) { - events[0] = event; - } + db.getListenerList() + .addConfigChangedListener((ConfigChangedEvent event) -> { + events[0] = event; }); FileBasedConfig config = db.getConfig(); assertNull(events[0]); 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 bfa30d5b4b..5a5ae1d7a3 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 @@ -976,7 +976,7 @@ public class DfsGarbageCollectorTest { rw.markStart(rw.parseCommit(ref.getObjectId())); } for (RevCommit next; (next = rw.next()) != null;) { - if (AnyObjectId.equals(next, id)) { + if (AnyObjectId.isEqual(next, id)) { return true; } } diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/dfs/InMemoryRepositoryTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/dfs/InMemoryRepositoryTest.java new file mode 100644 index 0000000000..bab6110ce6 --- /dev/null +++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/dfs/InMemoryRepositoryTest.java @@ -0,0 +1,150 @@ +/* + * Copyright (C) 2019, 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.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; + +import java.util.Set; + +import org.eclipse.jgit.junit.TestRepository; +import org.eclipse.jgit.lib.ObjectIdRef; +import org.eclipse.jgit.lib.Ref; +import org.eclipse.jgit.lib.Ref.Storage; +import org.eclipse.jgit.revwalk.RevCommit; +import org.eclipse.jgit.revwalk.RevTag; +import org.junit.Test; + +public class InMemoryRepositoryTest { + + @Test + public void keepUpdateIndexPeelingTag() throws Exception { + InMemoryRepository repo = new InMemoryRepository( + new DfsRepositoryDescription()); + try (TestRepository<InMemoryRepository> git = new TestRepository<>( + repo)) { + RevCommit commit = git.branch("master").commit() + .message("first commit").create(); + RevTag tag = git.tag("v0.1", commit); + git.update("refs/tags/v0.1", tag); + + Ref unpeeledTag = new ObjectIdRef.Unpeeled(Storage.LOOSE, + "refs/tags/v0.1", tag.getId(), 1000); + + Ref peeledTag = repo.getRefDatabase().peel(unpeeledTag); + assertTrue(peeledTag instanceof ObjectIdRef.PeeledTag); + assertEquals(1000, peeledTag.getUpdateIndex()); + } + } + + @Test + public void keepUpdateIndexPeelingNonTag() throws Exception { + InMemoryRepository repo = new InMemoryRepository( + new DfsRepositoryDescription()); + try (TestRepository<InMemoryRepository> git = new TestRepository<>( + repo)) { + RevCommit commit = git.branch("master").commit() + .message("first commit").create(); + + Ref unpeeledRef = new ObjectIdRef.Unpeeled(Storage.LOOSE, + "refs/heads/master", commit.getId(), 1000); + Ref peeledRef = repo.getRefDatabase().peel(unpeeledRef); + assertTrue(peeledRef instanceof ObjectIdRef.PeeledNonTag); + assertEquals(1000, peeledRef.getUpdateIndex()); + } + } + + @Test + public void sha1ToTip_ref() throws Exception { + InMemoryRepository repo = new InMemoryRepository( + new DfsRepositoryDescription()); + try (TestRepository<InMemoryRepository> git = new TestRepository<>( + repo)) { + RevCommit commit = git.branch("master").commit() + .message("first commit").create(); + + Set<Ref> tipsWithSha1 = repo.getRefDatabase() + .getTipsWithSha1(commit.getId()); + assertEquals(1, tipsWithSha1.size()); + Ref ref = tipsWithSha1.iterator().next(); + assertEquals(ref.getName(), "refs/heads/master"); + assertEquals(commit.getId(), ref.getObjectId()); + } + } + + @Test + public void sha1ToTip_annotatedTag() throws Exception { + InMemoryRepository repo = new InMemoryRepository( + new DfsRepositoryDescription()); + try (TestRepository<InMemoryRepository> git = new TestRepository<>( + repo)) { + RevCommit commit = git.commit() + .message("first commit").create(); + RevTag tagObj = git.tag("v0.1", commit); + git.update("refs/tags/v0.1", tagObj); + Set<Ref> tipsWithSha1 = repo.getRefDatabase() + .getTipsWithSha1(commit.getId()); + assertEquals(1, tipsWithSha1.size()); + Ref ref = tipsWithSha1.iterator().next(); + assertEquals(ref.getName(), "refs/tags/v0.1"); + assertEquals(commit.getId(), ref.getPeeledObjectId()); + } + } + + @Test + public void sha1ToTip_tag() throws Exception { + InMemoryRepository repo = new InMemoryRepository( + new DfsRepositoryDescription()); + try (TestRepository<InMemoryRepository> git = new TestRepository<>( + repo)) { + RevCommit commit = git.commit().message("first commit").create(); + git.update("refs/tags/v0.2", commit); + Set<Ref> tipsWithSha1 = repo.getRefDatabase() + .getTipsWithSha1(commit.getId()); + assertEquals(1, tipsWithSha1.size()); + Ref ref = tipsWithSha1.iterator().next(); + assertEquals(ref.getName(), "refs/tags/v0.2"); + assertEquals(commit.getId(), ref.getObjectId()); + } + } +} diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/file/BatchRefUpdateTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/file/BatchRefUpdateTest.java index 3c4b8cf4bc..501b788f89 100644 --- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/file/BatchRefUpdateTest.java +++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/file/BatchRefUpdateTest.java @@ -938,6 +938,7 @@ public class BatchRefUpdateTest extends LocalDiskRepositoryTestCase { REJECTED_MISSING_OBJECT(ReceiveCommand.Result.REJECTED_MISSING_OBJECT), TRANSACTION_ABORTED(ReceiveCommand::isTransactionAborted); + @SuppressWarnings("ImmutableEnumChecker") final Predicate<? super ReceiveCommand> p; private Result(Predicate<? super ReceiveCommand> p) { diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/file/GcConcurrentTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/file/GcConcurrentTest.java index 05f7c65fa8..9e7d41a693 100644 --- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/file/GcConcurrentTest.java +++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/file/GcConcurrentTest.java @@ -239,20 +239,15 @@ public class GcConcurrentTest extends GcTestCase { SampleDataRepositoryTestCase.copyCGitTestPacks(repo); ExecutorService executor = Executors.newSingleThreadExecutor(); final CountDownLatch latch = new CountDownLatch(1); - Future<Collection<PackFile>> result = executor - .submit(new Callable<Collection<PackFile>>() { - - @Override - public Collection<PackFile> call() throws Exception { - long start = System.currentTimeMillis(); - System.out.println("starting gc"); - latch.countDown(); - Collection<PackFile> r = gc.gc(); - System.out.println("gc took " - + (System.currentTimeMillis() - start) + " ms"); - return r; - } - }); + Future<Collection<PackFile>> result = executor.submit(() -> { + long start = System.currentTimeMillis(); + System.out.println("starting gc"); + latch.countDown(); + Collection<PackFile> r = gc.gc(); + System.out.println( + "gc took " + (System.currentTimeMillis() - start) + " ms"); + return r; + }); try { latch.await(); Thread.sleep(5); diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/file/GcPackRefsTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/file/GcPackRefsTest.java index c43bdbd298..54708da03c 100644 --- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/file/GcPackRefsTest.java +++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/file/GcPackRefsTest.java @@ -155,41 +155,34 @@ public class GcPackRefsTest extends GcTestCase { final CyclicBarrier packRefsDone = new CyclicBarrier(2); ExecutorService pool = Executors.newFixedThreadPool(2); try { - Future<Result> result = pool.submit(new Callable<Result>() { - - @Override - public Result call() throws Exception { - RefUpdate update = new RefDirectoryUpdate( - (RefDirectory) repo.getRefDatabase(), - repo.exactRef("refs/tags/t")) { - @Override - public boolean isForceUpdate() { - try { - refUpdateLockedRef.await(); - packRefsDone.await(); - } catch (InterruptedException e) { - Thread.currentThread().interrupt(); - } catch (BrokenBarrierException e) { - Thread.currentThread().interrupt(); - } - return super.isForceUpdate(); + Future<Result> result = pool.submit(() -> { + RefUpdate update = new RefDirectoryUpdate( + (RefDirectory) repo.getRefDatabase(), + repo.exactRef("refs/tags/t")) { + @Override + public boolean isForceUpdate() { + try { + refUpdateLockedRef.await(); + packRefsDone.await(); + } catch (InterruptedException + | BrokenBarrierException e) { + Thread.currentThread().interrupt(); } - }; - update.setForceUpdate(true); - update.setNewObjectId(b); - return update.update(); - } + return super.isForceUpdate(); + } + }; + update.setForceUpdate(true); + update.setNewObjectId(b); + return update.update(); }); - pool.submit(new Callable<Void>() { - @Override - public Void call() throws Exception { - refUpdateLockedRef.await(); - gc.packRefs(); - packRefsDone.await(); - return null; - } + Future<Result> result2 = pool.submit(() -> { + refUpdateLockedRef.await(); + gc.packRefs(); + packRefsDone.await(); + return null; }); + assertNull(result2.get()); assertSame(result.get(), Result.FORCED); diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/file/ObjectDirectoryTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/file/ObjectDirectoryTest.java index 9d47c7e3bc..97c56385bd 100644 --- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/file/ObjectDirectoryTest.java +++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/file/ObjectDirectoryTest.java @@ -47,7 +47,6 @@ import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; import java.io.File; -import java.io.FilenameFilter; import java.io.IOException; import java.io.PrintWriter; import java.text.MessageFormat; @@ -169,12 +168,8 @@ public class ObjectDirectoryTest extends RepositoryTestCase { // 2500ms Thread.sleep(2600); - File[] ret = packsFolder.listFiles(new FilenameFilter() { - @Override - public boolean accept(File dir, String name) { - return name.endsWith(".pack"); - } - }); + File[] ret = packsFolder.listFiles( + (File dir, String name) -> name.endsWith(".pack")); assertTrue(ret != null && ret.length == 1); FS fs = db.getFS(); Assume.assumeTrue(fs.lastModifiedInstant(tmpFile) @@ -224,12 +219,8 @@ public class ObjectDirectoryTest extends RepositoryTestCase { private Collection<Callable<ObjectId>> blobInsertersForTheSameFanOutDir( final ObjectDirectory dir) { - Callable<ObjectId> callable = new Callable<ObjectId>() { - @Override - public ObjectId call() throws Exception { - return dir.newInserter().insert(Constants.OBJ_BLOB, new byte[0]); - } - }; + Callable<ObjectId> callable = () -> dir.newInserter() + .insert(Constants.OBJ_BLOB, new byte[0]); return Collections.nCopies(4, callable); } diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/file/PackWriterTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/file/PackWriterTest.java index ca4486256b..5d0a7e2a0b 100644 --- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/file/PackWriterTest.java +++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/file/PackWriterTest.java @@ -60,7 +60,6 @@ import java.text.ParseException; import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; -import java.util.Comparator; import java.util.HashSet; import java.util.List; import java.util.Set; @@ -881,12 +880,8 @@ public class PackWriterTest extends SampleDataRepositoryTestCase { for (MutableEntry me : pack) { entries.add(me.cloneEntry()); } - Collections.sort(entries, new Comparator<PackIndex.MutableEntry>() { - @Override - public int compare(MutableEntry o1, MutableEntry o2) { - return Long.signum(o1.getOffset() - o2.getOffset()); - } - }); + Collections.sort(entries, (MutableEntry o1, MutableEntry o2) -> Long + .signum(o1.getOffset() - o2.getOffset())); int i = 0; for (MutableEntry me : entries) { diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/file/RefDirectoryTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/file/RefDirectoryTest.java index 2357edf6cb..d8e16858e5 100644 --- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/file/RefDirectoryTest.java +++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/file/RefDirectoryTest.java @@ -71,7 +71,6 @@ import java.util.concurrent.atomic.AtomicReference; import org.eclipse.jgit.errors.LockFailedException; import org.eclipse.jgit.events.ListenerHandle; import org.eclipse.jgit.events.RefsChangedEvent; -import org.eclipse.jgit.events.RefsChangedListener; import org.eclipse.jgit.junit.LocalDiskRepositoryTestCase; import org.eclipse.jgit.junit.Repeat; import org.eclipse.jgit.junit.TestRepository; @@ -573,12 +572,8 @@ public class RefDirectoryTest extends LocalDiskRepositoryTestCase { final int[] count = new int[1]; ListenerHandle listener = Repository.getGlobalListenerList() - .addRefsChangedListener(new RefsChangedListener() { - - @Override - public void onRefsChanged(RefsChangedEvent event) { - count[0]++; - } + .addRefsChangedListener((RefsChangedEvent event) -> { + count[0]++; }); refs = refdir.getRefs(RefDatabase.ALL); @@ -1320,19 +1315,15 @@ public class RefDirectoryTest extends LocalDiskRepositoryTestCase { final AtomicReference<StackOverflowError> error = new AtomicReference<>(); final AtomicReference<IOException> exception = new AtomicReference<>(); final AtomicInteger changeCount = new AtomicInteger(); - newRepo.getListenerList().addRefsChangedListener( - new RefsChangedListener() { - - @Override - public void onRefsChanged(RefsChangedEvent event) { - try { - refDb.getRefsByPrefix("ref"); - changeCount.incrementAndGet(); - } catch (StackOverflowError soe) { - error.set(soe); - } catch (IOException ioe) { - exception.set(ioe); - } + newRepo.getListenerList() + .addRefsChangedListener((RefsChangedEvent event) -> { + try { + refDb.getRefsByPrefix("ref"); + changeCount.incrementAndGet(); + } catch (StackOverflowError soe) { + error.set(soe); + } catch (IOException ioe) { + exception.set(ioe); } }); refDb.getRefsByPrefix("ref"); diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/reftree/RefTreeDatabaseTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/reftree/RefTreeDatabaseTest.java index 8ef21e6da7..c3f5baa67b 100644 --- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/reftree/RefTreeDatabaseTest.java +++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/reftree/RefTreeDatabaseTest.java @@ -633,35 +633,23 @@ public class RefTreeDatabaseTest { private void symref(String name, String dst) throws IOException { - commit(new Function() { - @Override - public boolean apply(ObjectReader reader, RefTree tree) - throws IOException { - Ref old = tree.exactRef(reader, name); - Command n = new Command( - old, - new SymbolicRef( - name, - new ObjectIdRef.Unpeeled(Ref.Storage.NEW, dst, null))); - return tree.apply(Collections.singleton(n)); - } + commit((ObjectReader reader, RefTree tree) -> { + Ref old = tree.exactRef(reader, name); + Command n = new Command(old, new SymbolicRef(name, + new ObjectIdRef.Unpeeled(Ref.Storage.NEW, dst, null))); + return tree.apply(Collections.singleton(n)); }); } private void update(String name, ObjectId id) throws IOException { - commit(new Function() { - @Override - public boolean apply(ObjectReader reader, RefTree tree) - throws IOException { - Ref old = tree.exactRef(reader, name); - Command n; - try (RevWalk rw = new RevWalk(repo)) { - n = new Command(old, - Command.toRef(rw, id, null, name, true)); - } - return tree.apply(Collections.singleton(n)); + commit((ObjectReader reader, RefTree tree) -> { + Ref old = tree.exactRef(reader, name); + Command n; + try (RevWalk rw = new RevWalk(repo)) { + n = new Command(old, Command.toRef(rw, id, null, name, true)); } + return tree.apply(Collections.singleton(n)); }); } diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/transport/http/NetscapeCookieFileTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/transport/http/NetscapeCookieFileTest.java new file mode 100644 index 0000000000..0a3f89e238 --- /dev/null +++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/transport/http/NetscapeCookieFileTest.java @@ -0,0 +1,339 @@ +/* + * Copyright (C) 2018, Konrad Windszus <konrad_w@gmx.de> + * 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.transport.http; + +import java.io.IOException; +import java.io.InputStream; +import java.io.Writer; +import java.net.HttpCookie; +import java.net.URL; +import java.nio.charset.StandardCharsets; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.StandardCopyOption; +import java.time.Instant; +import java.util.Arrays; +import java.util.Date; +import java.util.LinkedHashSet; +import java.util.List; +import java.util.Set; +import java.util.regex.Pattern; + +import org.eclipse.jgit.internal.storage.file.LockFile; +import org.eclipse.jgit.internal.transport.http.NetscapeCookieFile; +import org.eclipse.jgit.util.http.HttpCookiesMatcher; +import org.hamcrest.CoreMatchers; +import org.junit.Assert; +import org.junit.Before; +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.TemporaryFolder; + +public class NetscapeCookieFileTest { + + @Rule + public TemporaryFolder folder = new TemporaryFolder(); + + private Path tmpFile; + + private URL baseUrl; + + /** + * This is the expiration date that is used in the test cookie files + */ + private static long JAN_01_2030_NOON = Instant + .parse("2030-01-01T12:00:00.000Z").toEpochMilli(); + + @Before + public void setUp() throws IOException { + // this will not only return a new file name but also create new empty + // file! + tmpFile = folder.newFile().toPath(); + baseUrl = new URL("http://domain.com/my/path"); + } + + @Test + public void testMergeCookies() { + Set<HttpCookie> cookieSet1 = new LinkedHashSet<>(); + HttpCookie cookie = new HttpCookie("key1", "valueFromSet1"); + cookieSet1.add(cookie); + cookie = new HttpCookie("key2", "valueFromSet1"); + cookieSet1.add(cookie); + + Set<HttpCookie> cookieSet2 = new LinkedHashSet<>(); + cookie = new HttpCookie("key1", "valueFromSet2"); + cookieSet2.add(cookie); + cookie = new HttpCookie("key3", "valueFromSet2"); + cookieSet2.add(cookie); + + Set<HttpCookie> cookiesExpectedMergedSet = new LinkedHashSet<>(); + cookie = new HttpCookie("key1", "valueFromSet1"); + cookiesExpectedMergedSet.add(cookie); + cookie = new HttpCookie("key2", "valueFromSet1"); + cookiesExpectedMergedSet.add(cookie); + cookie = new HttpCookie("key3", "valueFromSet2"); + cookiesExpectedMergedSet.add(cookie); + + Assert.assertThat( + NetscapeCookieFile.mergeCookies(cookieSet1, cookieSet2), + HttpCookiesMatcher.containsInOrder(cookiesExpectedMergedSet)); + + Assert.assertThat(NetscapeCookieFile.mergeCookies(cookieSet1, null), + HttpCookiesMatcher.containsInOrder(cookieSet1)); + } + + @Test + public void testWriteToNewFile() throws IOException { + Set<HttpCookie> cookies = new LinkedHashSet<>(); + cookies.add(new HttpCookie("key1", "value")); + // first cookie is a session cookie (and should be ignored) + + HttpCookie cookie = new HttpCookie("key2", "value"); + cookie.setSecure(true); + cookie.setDomain("mydomain.com"); + cookie.setPath("/"); + cookie.setMaxAge(1000); + cookies.add(cookie); + Date creationDate = new Date(); + try (Writer writer = Files.newBufferedWriter(tmpFile, + StandardCharsets.US_ASCII)) { + NetscapeCookieFile.write(writer, cookies, baseUrl, creationDate); + } + + String expectedExpiration = String + .valueOf(creationDate.getTime() + (cookie.getMaxAge() * 1000)); + + Assert.assertThat( + Files.readAllLines(tmpFile, StandardCharsets.US_ASCII), + CoreMatchers + .equalTo(Arrays.asList("mydomain.com\tTRUE\t/\tTRUE\t" + + expectedExpiration + "\tkey2\tvalue"))); + } + + @Test + public void testWriteToExistingFile() throws IOException { + try (InputStream input = this.getClass() + .getResourceAsStream("cookies-simple1.txt")) { + Files.copy(input, tmpFile, StandardCopyOption.REPLACE_EXISTING); + } + + Set<HttpCookie> cookies = new LinkedHashSet<>(); + HttpCookie cookie = new HttpCookie("key2", "value2"); + cookie.setMaxAge(1000); + cookies.add(cookie); + Date creationDate = new Date(); + try (Writer writer = Files.newBufferedWriter(tmpFile, + StandardCharsets.US_ASCII)) { + NetscapeCookieFile.write(writer, cookies, baseUrl, creationDate); + } + String expectedExpiration = String + .valueOf(creationDate.getTime() + (cookie.getMaxAge() * 1000)); + + Assert.assertThat( + Files.readAllLines(tmpFile, StandardCharsets.US_ASCII), + CoreMatchers.equalTo( + Arrays.asList("domain.com\tTRUE\t/my/path\tFALSE\t" + + expectedExpiration + "\tkey2\tvalue2"))); + } + + @Test(expected = IOException.class) + public void testWriteWhileSomeoneIsHoldingTheLock() + throws IllegalArgumentException, IOException, InterruptedException { + try (InputStream input = this.getClass() + .getResourceAsStream("cookies-simple1.txt")) { + Files.copy(input, tmpFile, StandardCopyOption.REPLACE_EXISTING); + } + NetscapeCookieFile cookieFile = new NetscapeCookieFile(tmpFile); + // now imitate another process/thread holding the lock file + LockFile lockFile = new LockFile(tmpFile.toFile()); + try { + Assert.assertTrue("Could not acquire lock", lockFile.lock()); + cookieFile.write(baseUrl); + } finally { + lockFile.unlock(); + } + } + + @Test + public void testWriteAfterAnotherJgitProcessModifiedTheFile() + throws IOException, InterruptedException { + try (InputStream input = this.getClass() + .getResourceAsStream("cookies-simple1.txt")) { + Files.copy(input, tmpFile, StandardCopyOption.REPLACE_EXISTING); + } + NetscapeCookieFile cookieFile = new NetscapeCookieFile(tmpFile); + cookieFile.getCookies(true); + // now modify file externally + try (InputStream input = this.getClass() + .getResourceAsStream("cookies-simple2.txt")) { + Files.copy(input, tmpFile, StandardCopyOption.REPLACE_EXISTING); + } + // now try to write + cookieFile.write(baseUrl); + + // validate that the external changes are there as well + // due to rounding errors (conversion from ms to sec to ms) + // the expiration date might not be exact + List<String> lines = Files.readAllLines(tmpFile, + StandardCharsets.US_ASCII); + + Assert.assertEquals("Expected 3 lines", 3, lines.size()); + assertStringMatchesPatternWithInexactNumber(lines.get(0), + "some-domain1\tTRUE\t/some/path1\tFALSE\t(\\d*)\tkey1\tvalueFromSimple2", + JAN_01_2030_NOON, 1000); + assertStringMatchesPatternWithInexactNumber(lines.get(1), + "some-domain1\tTRUE\t/some/path1\tFALSE\t(\\d*)\tkey3\tvalueFromSimple2", + JAN_01_2030_NOON, 1000); + assertStringMatchesPatternWithInexactNumber(lines.get(2), + "some-domain1\tTRUE\t/some/path1\tFALSE\t(\\d*)\tkey2\tvalueFromSimple1", + JAN_01_2030_NOON, 1000); + } + + @SuppressWarnings("boxing") + private static final void assertStringMatchesPatternWithInexactNumber( + String string, String pattern, long expectedNumericValue, + long delta) { + java.util.regex.Matcher matcher = Pattern.compile(pattern) + .matcher(string); + Assert.assertTrue("Given string '" + string + "' does not match '" + + pattern + "'", matcher.matches()); + // extract numeric value + Long actualNumericValue = Long.decode(matcher.group(1)); + + Assert.assertTrue( + "Value is supposed to be close to " + expectedNumericValue + + " but is " + actualNumericValue + ".", + Math.abs(expectedNumericValue - actualNumericValue) <= delta); + } + + @Test + public void testWriteAndReadCycle() throws IOException { + Set<HttpCookie> cookies = new LinkedHashSet<>(); + + HttpCookie cookie = new HttpCookie("key1", "value1"); + cookie.setPath("/some/path1"); + cookie.setDomain("some-domain1"); + cookie.setMaxAge(1000); + cookies.add(cookie); + cookie = new HttpCookie("key2", "value2"); + cookie.setSecure(true); + cookie.setPath("/some/path2"); + cookie.setDomain("some-domain2"); + cookie.setMaxAge(1000); + cookie.setHttpOnly(true); + cookies.add(cookie); + + Date creationDate = new Date(); + + try (Writer writer = Files.newBufferedWriter(tmpFile, + StandardCharsets.US_ASCII)) { + NetscapeCookieFile.write(writer, cookies, baseUrl, creationDate); + } + Set<HttpCookie> actualCookies = new NetscapeCookieFile(tmpFile, + creationDate).getCookies(true); + Assert.assertThat(actualCookies, + HttpCookiesMatcher.containsInOrder(cookies)); + } + + @Test + public void testReadAndWriteCycle() throws IOException { + try (InputStream input = this.getClass() + .getResourceAsStream("cookies-simple1.txt")) { + Files.copy(input, tmpFile, StandardCopyOption.REPLACE_EXISTING); + } + // round up to the next second (to prevent rounding errors) + Date creationDate = new Date( + (System.currentTimeMillis() / 1000) * 1000); + Set<HttpCookie> cookies = new NetscapeCookieFile(tmpFile, creationDate) + .getCookies(true); + Path tmpFile2 = folder.newFile().toPath(); + try (Writer writer = Files.newBufferedWriter(tmpFile2, + StandardCharsets.US_ASCII)) { + NetscapeCookieFile.write(writer, cookies, baseUrl, creationDate); + } + // compare original file with newly written one, they should not differ + Assert.assertEquals(Files.readAllLines(tmpFile), + Files.readAllLines(tmpFile2)); + } + + @Test + public void testReadWithEmptyAndCommentLines() throws IOException { + try (InputStream input = this.getClass().getResourceAsStream( + "cookies-with-empty-and-comment-lines.txt")) { + Files.copy(input, tmpFile, StandardCopyOption.REPLACE_EXISTING); + } + + Date creationDate = new Date(); + Set<HttpCookie> cookies = new LinkedHashSet<>(); + + HttpCookie cookie = new HttpCookie("key2", "value2"); + cookie.setDomain("some-domain2"); + cookie.setPath("/some/path2"); + cookie.setMaxAge((JAN_01_2030_NOON - creationDate.getTime()) / 1000); + cookie.setSecure(true); + cookie.setHttpOnly(true); + cookies.add(cookie); + + cookie = new HttpCookie("key3", "value3"); + cookie.setDomain("some-domain3"); + cookie.setPath("/some/path3"); + cookie.setMaxAge((JAN_01_2030_NOON - creationDate.getTime()) / 1000); + cookies.add(cookie); + + Set<HttpCookie> actualCookies = new NetscapeCookieFile(tmpFile, creationDate) + .getCookies(true); + Assert.assertThat(actualCookies, + HttpCookiesMatcher.containsInOrder(cookies)); + } + + @Test + public void testReadInvalidFile() throws IOException { + try (InputStream input = this.getClass() + .getResourceAsStream("cookies-invalid.txt")) { + Files.copy(input, tmpFile, StandardCopyOption.REPLACE_EXISTING); + } + + new NetscapeCookieFile(tmpFile) + .getCookies(true); + } +} diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/lib/ConfigTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/lib/ConfigTest.java index 22dc471552..e839545250 100644 --- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/lib/ConfigTest.java +++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/lib/ConfigTest.java @@ -1462,6 +1462,48 @@ public class ConfigTest { assertEquals("xt", parseEscapedSubsection("\"x\\t\"")); } + @Test + public void testInvalidGroupHeader() throws ConfigInvalidException { + expectedEx.expect(ConfigInvalidException.class); + expectedEx.expectMessage(JGitText.get().badGroupHeader); + parse("[foo \"bar\" ]\nfoo=bar\n"); + } + + @Test + public void testCrLf() throws ConfigInvalidException { + assertEquals("true", parseEscapedValue("true\r\n")); + } + + @Test + public void testLfContinuation() throws ConfigInvalidException { + assertEquals("true", parseEscapedValue("tr\\\nue")); + } + + @Test + public void testCrCharContinuation() throws ConfigInvalidException { + expectedEx.expect(ConfigInvalidException.class); + expectedEx.expectMessage("Bad escape: \\u000d"); + parseEscapedValue("tr\\\rue"); + } + + @Test + public void testCrEOFContinuation() throws ConfigInvalidException { + expectedEx.expect(ConfigInvalidException.class); + expectedEx.expectMessage("Bad escape: \\u000d"); + parseEscapedValue("tr\\\r"); + } + + @Test + public void testCrLfContinuation() throws ConfigInvalidException { + assertEquals("true", parseEscapedValue("tr\\\r\nue")); + } + + @Test + public void testWhitespaceContinuation() throws ConfigInvalidException { + assertEquals("tr ue", parseEscapedValue("tr \\\n ue")); + assertEquals("tr ue", parseEscapedValue("tr \\\r\n ue")); + } + private static void assertValueRoundTrip(String value) throws ConfigInvalidException { assertValueRoundTrip(value, value); 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 531c918e9b..e7a5b286dd 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 @@ -1678,7 +1678,6 @@ public class ObjectCheckerTest { rejectName('>'); rejectName(':'); rejectName('"'); - rejectName('/'); rejectName('\\'); rejectName('|'); rejectName('?'); @@ -1693,7 +1692,8 @@ public class ObjectCheckerTest { checkOneName("te" + c + "st"); fail("incorrectly accepted with " + c); } catch (CorruptObjectException e) { - assertEquals("name contains '" + c + "'", e.getMessage()); + + assertEquals("char '" + c + "' not allowed in Windows filename", e.getMessage()); } } @@ -1703,7 +1703,19 @@ public class ObjectCheckerTest { checkOneName("te" + ((char) c) + "st"); fail("incorrectly accepted with 0x" + h); } catch (CorruptObjectException e) { - assertEquals("name contains byte 0x" + h, e.getMessage()); + assertEquals("byte 0x" + h + " not allowed in Windows filename", e.getMessage()); + } + } + + + @Test + public void testRejectInvalidCharacter() { + try { + checkOneName("te/st"); + fail("incorrectly accepted with /"); + } catch (CorruptObjectException e) { + + assertEquals("name contains '/'", e.getMessage()); } } @@ -1763,16 +1775,13 @@ public class ObjectCheckerTest { } private static ObjectIdSet set(ObjectId... ids) { - return new ObjectIdSet() { - @Override - public boolean contains(AnyObjectId objectId) { - for (ObjectId id : ids) { - if (id.equals(objectId)) { - return true; - } + return (AnyObjectId objectId) -> { + for (ObjectId id : ids) { + if (id.equals(objectId)) { + return true; } - return false; } + return false; }; } diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/lib/RebaseTodoFileTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/lib/RebaseTodoFileTest.java new file mode 100644 index 0000000000..5cfc75ca93 --- /dev/null +++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/lib/RebaseTodoFileTest.java @@ -0,0 +1,142 @@ +/* + * Copyright (C) 2019, 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.assertEquals; +import static org.junit.Assert.fail; + +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.util.Arrays; +import java.util.List; + +import org.eclipse.jgit.junit.RepositoryTestCase; +import org.junit.Test; + +public class RebaseTodoFileTest extends RepositoryTestCase { + + private static final String TEST_TODO = "test.todo"; + + private void createTodoList(String... lines) throws IOException { + Path p = Paths.get(db.getDirectory().getAbsolutePath(), TEST_TODO); + Files.write(p, Arrays.asList(lines)); + } + + @Test + public void testReadTodoFile() throws Exception { + String[] expected = { "reword " + ObjectId.zeroId().name() + " Foo", + "# A comment in the the todo list", + "pick " + ObjectId.zeroId().name() + " Foo fie", + "squash " + ObjectId.zeroId().name() + " F", + "fixup " + ObjectId.zeroId().name(), + "edit " + ObjectId.zeroId().name() + " f", + "edit " + ObjectId.zeroId().name() + ' ' }; + createTodoList(expected); + RebaseTodoFile todo = new RebaseTodoFile(db); + List<RebaseTodoLine> lines = todo.readRebaseTodo(TEST_TODO, true); + assertEquals("Expected 7 lines", 7, lines.size()); + int i = 0; + for (RebaseTodoLine line : lines) { + switch (i) { + case 0: + assertEquals("Expected REWORD", RebaseTodoLine.Action.REWORD, + line.getAction()); + assertEquals("Unexpected ID", ObjectId.zeroId().abbreviate(40), + line.getCommit()); + assertEquals("Unexpected Message", "Foo", + line.getShortMessage()); + break; + case 1: + assertEquals("Expected COMMENT", RebaseTodoLine.Action.COMMENT, + line.getAction()); + assertEquals("Unexpected Message", + "# A comment in the the todo list", + line.getComment()); + break; + case 2: + assertEquals("Expected PICK", RebaseTodoLine.Action.PICK, + line.getAction()); + assertEquals("Unexpected ID", ObjectId.zeroId().abbreviate(40), + line.getCommit()); + assertEquals("Unexpected Message", "Foo fie", + line.getShortMessage()); + break; + case 3: + assertEquals("Expected SQUASH", RebaseTodoLine.Action.SQUASH, + line.getAction()); + assertEquals("Unexpected ID", ObjectId.zeroId().abbreviate(40), + line.getCommit()); + assertEquals("Unexpected Message", "F", line.getShortMessage()); + break; + case 4: + assertEquals("Expected FIXUP", RebaseTodoLine.Action.FIXUP, + line.getAction()); + assertEquals("Unexpected ID", ObjectId.zeroId().abbreviate(40), + line.getCommit()); + assertEquals("Unexpected Message", "", line.getShortMessage()); + break; + case 5: + assertEquals("Expected EDIT", RebaseTodoLine.Action.EDIT, + line.getAction()); + assertEquals("Unexpected ID", ObjectId.zeroId().abbreviate(40), + line.getCommit()); + assertEquals("Unexpected Message", "f", line.getShortMessage()); + break; + case 6: + assertEquals("Expected EDIT", RebaseTodoLine.Action.EDIT, + line.getAction()); + assertEquals("Unexpected ID", ObjectId.zeroId().abbreviate(40), + line.getCommit()); + assertEquals("Unexpected Message", "", line.getShortMessage()); + break; + default: + fail("Too many lines"); + return; + } + i++; + } + } +} 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 7d2c4a2784..b53d5b9448 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,8 +58,10 @@ import static org.junit.Assert.fail; import java.io.File; import java.io.FileOutputStream; import java.io.IOException; +import java.util.Collection; import java.util.List; import java.util.Optional; +import java.util.Set; import java.util.TreeSet; import org.eclipse.jgit.lib.Ref.Storage; @@ -313,7 +315,7 @@ public class RefTest extends SampleDataRepositoryTestCase { assertEquals(dst.isPeeled(), ref.isPeeled()); } - private static void checkContainsRef(List<Ref> haystack, Ref needle) { + private static void checkContainsRef(Collection<Ref> haystack, Ref needle) { for (Ref ref : haystack) { if (ref.getName().equals(needle.getName()) && ref.getObjectId().equals(needle.getObjectId())) { @@ -347,4 +349,17 @@ public class RefTest extends SampleDataRepositoryTestCase { checkContainsRef(refs, db.exactRef("refs/heads/prefix/a")); checkContainsRef(refs, db.exactRef("refs/tags/A")); } + + @Test + public void testResolveTipSha1() throws IOException { + ObjectId masterId = db.resolve("refs/heads/master"); + Set<Ref> resolved = db.getRefDatabase().getTipsWithSha1(masterId); + + assertEquals(2, resolved.size()); + checkContainsRef(resolved, db.exactRef("refs/heads/master")); + checkContainsRef(resolved, db.exactRef("HEAD")); + + assertEquals(db.getRefDatabase() + .getTipsWithSha1(ObjectId.zeroId()).size(), 0); + } } diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/lib/ReflogConfigTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/lib/ReflogConfigTest.java index df1a52dc09..f2f277c6ea 100644 --- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/lib/ReflogConfigTest.java +++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/lib/ReflogConfigTest.java @@ -45,7 +45,6 @@ package org.eclipse.jgit.lib; -import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; @@ -63,7 +62,8 @@ public class ReflogConfigTest extends RepositoryTestCase { // check that there are no entries in the reflog and turn off writing // reflogs - assertEquals(0, db.getReflogReader(Constants.HEAD).getReverseEntries().size()); + assertTrue(db.getReflogReader(Constants.HEAD).getReverseEntries() + .isEmpty()); final FileBasedConfig cfg = db.getConfig(); cfg.setBoolean("core", null, "logallrefupdates", false); cfg.save(); @@ -72,9 +72,8 @@ public class ReflogConfigTest extends RepositoryTestCase { // written commit("A Commit\n", commitTime, tz); commitTime += 60 * 1000; - assertTrue( - "Reflog for HEAD still contain no entry", - db.getReflogReader(Constants.HEAD).getReverseEntries().size() == 0); + assertTrue("Reflog for HEAD still contain no entry", db + .getReflogReader(Constants.HEAD).getReverseEntries().isEmpty()); // set the logAllRefUpdates parameter to true and check it cfg.setBoolean("core", null, "logallrefupdates", true); diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/lib/ThreadSafeProgressMonitorTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/lib/ThreadSafeProgressMonitorTest.java index 545a188a98..682982226e 100644 --- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/lib/ThreadSafeProgressMonitorTest.java +++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/lib/ThreadSafeProgressMonitorTest.java @@ -61,29 +61,26 @@ public class ThreadSafeProgressMonitorTest { final MockProgressMonitor mock = new MockProgressMonitor(); final ThreadSafeProgressMonitor pm = new ThreadSafeProgressMonitor(mock); - runOnThread(new Runnable() { - @Override - public void run() { - try { - pm.start(1); - fail("start did not fail on background thread"); - } catch (IllegalStateException notMainThread) { - // Expected result - } - - try { - pm.beginTask("title", 1); - fail("beginTask did not fail on background thread"); - } catch (IllegalStateException notMainThread) { - // Expected result - } - - try { - pm.endTask(); - fail("endTask did not fail on background thread"); - } catch (IllegalStateException notMainThread) { - // Expected result - } + runOnThread(() -> { + try { + pm.start(1); + fail("start did not fail on background thread"); + } catch (IllegalStateException notMainThread) { + // Expected result + } + + try { + pm.beginTask("title", 1); + fail("beginTask did not fail on background thread"); + } catch (IllegalStateException notMainThread) { + // Expected result + } + + try { + pm.endTask(); + fail("endTask did not fail on background thread"); + } catch (IllegalStateException notMainThread) { + // Expected result } }); 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 2ae9c11a7d..62495fb023 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 @@ -842,9 +842,9 @@ public class MergerTest extends RepositoryTestCase { * Throws an exception if reading beyond limit. */ static class BigReadForbiddenStream extends ObjectStream.Filter { - int limit; + long limit; - BigReadForbiddenStream(ObjectStream orig, int limit) { + BigReadForbiddenStream(ObjectStream orig, long limit) { super(orig.getType(), orig.getSize(), orig); this.limit = limit; } diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/revwalk/BitmapCalculatorTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/revwalk/BitmapCalculatorTest.java new file mode 100644 index 0000000000..c5d4d4238d --- /dev/null +++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/revwalk/BitmapCalculatorTest.java @@ -0,0 +1,181 @@ +/* + * Copyright (C) 2019, 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.revwalk; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; + +import org.eclipse.jgit.internal.storage.file.FileRepository; +import org.eclipse.jgit.internal.storage.file.GC; +import org.eclipse.jgit.junit.LocalDiskRepositoryTestCase; +import org.eclipse.jgit.junit.TestRepository; +import org.eclipse.jgit.lib.BitmapIndex.BitmapBuilder; +import org.eclipse.jgit.lib.NullProgressMonitor; +import org.eclipse.jgit.lib.ProgressMonitor; +import org.junit.Before; +import org.junit.Test; + +public class BitmapCalculatorTest extends LocalDiskRepositoryTestCase { + TestRepository<FileRepository> repo; + + /** {@inheritDoc} */ + @Override + @Before + public void setUp() throws Exception { + super.setUp(); + FileRepository db = createWorkRepository(); + repo = new TestRepository<>(db); + } + + @Test + public void addOnlyCommits() throws Exception { + RevBlob abBlob = repo.blob("a_b_content"); + RevCommit root = repo.commit().add("a/b", abBlob).create(); + repo.update("refs/heads/master", root); + + // GC creates bitmap index with ALL objects + GC gc = new GC(repo.getRepository()); + gc.setAuto(false); + gc.gc(); + + // These objects are not in the bitmap index. + RevBlob acBlob = repo.blob("a_c_content"); + RevCommit head = repo.commit().parent(root).add("a/c", acBlob).create(); + repo.update("refs/heads/master", head); + + BitmapCalculator bitmapWalker = new BitmapCalculator(repo.getRevWalk()); + BitmapBuilder bitmap = bitmapWalker + .getBitmap(head, NullProgressMonitor.INSTANCE); + + assertTrue(bitmap.contains(root.getId())); + assertTrue(bitmap.contains(root.getTree().getId())); + assertTrue(bitmap.contains(abBlob.getId())); + + // BitmapCalculator added only the commit, no other objects. + assertTrue(bitmap.contains(head.getId())); + assertFalse(bitmap.contains(head.getTree().getId())); + assertFalse(bitmap.contains(acBlob.getId())); + } + + @Test + public void walkUntilBitmap() throws Exception { + RevCommit root = repo.commit().create(); + repo.update("refs/heads/master", root); + + // GC creates bitmap index with ALL objects + GC gc = new GC(repo.getRepository()); + gc.setAuto(false); + gc.gc(); + + // These objects are not in the bitmap index. + RevCommit commit1 = repo.commit(root); + RevCommit commit2 = repo.commit(commit1); + repo.update("refs/heads/master", commit2); + + CounterProgressMonitor monitor = new CounterProgressMonitor(); + BitmapCalculator bitmapWalker = new BitmapCalculator(repo.getRevWalk()); + BitmapBuilder bitmap = bitmapWalker.getBitmap(commit2, monitor); + + assertTrue(bitmap.contains(root)); + assertTrue(bitmap.contains(commit1)); + assertTrue(bitmap.contains(commit2)); + assertEquals(2, monitor.getUpdates()); + } + + @Test + public void noNeedToWalk() throws Exception { + RevCommit root = repo.commit().create(); + RevCommit commit1 = repo.commit(root); + RevCommit commit2 = repo.commit(commit1); + repo.update("refs/heads/master", commit2); + + // GC creates bitmap index with ALL objects + GC gc = new GC(repo.getRepository()); + gc.setAuto(false); + gc.gc(); + + CounterProgressMonitor monitor = new CounterProgressMonitor(); + BitmapCalculator bitmapWalker = new BitmapCalculator(repo.getRevWalk()); + BitmapBuilder bitmap = bitmapWalker.getBitmap(commit2, monitor); + + assertTrue(bitmap.contains(root)); + assertTrue(bitmap.contains(commit1)); + assertTrue(bitmap.contains(commit2)); + assertEquals(0, monitor.getUpdates()); + } + + private static class CounterProgressMonitor implements ProgressMonitor { + + private int counter; + + @Override + public void start(int totalTasks) { + // Nothing to do in tests + } + + @Override + public void beginTask(String title, int totalWork) { + // Nothing to to in tests + } + + @Override + public void update(int completed) { + counter += 1; + } + + @Override + public void endTask() { + // Nothing to do in tests + } + + @Override + public boolean isCancelled() { + return false; + } + + int getUpdates() { + return counter; + } + } +}
\ No newline at end of file diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/revwalk/BitmappedReachabilityCheckerTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/revwalk/BitmappedReachabilityCheckerTest.java new file mode 100644 index 0000000000..5d3adf5eab --- /dev/null +++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/revwalk/BitmappedReachabilityCheckerTest.java @@ -0,0 +1,69 @@ +/* + * Copyright (C) 2019, 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.revwalk; + +import static org.junit.Assert.assertNotNull; + +import org.eclipse.jgit.internal.storage.file.FileRepository; +import org.eclipse.jgit.internal.storage.file.GC; +import org.eclipse.jgit.junit.TestRepository; + +public class BitmappedReachabilityCheckerTest + extends ReachabilityCheckerTestCase { + + @Override + protected ReachabilityChecker getChecker( + TestRepository<FileRepository> repository) throws Exception { + // GC generates the bitmaps + GC gc = new GC(repo.getRepository()); + gc.setAuto(false); + gc.gc(); + + // This is null when the test didn't create any branch + assertNotNull("Probably the test didn't define any ref", + repo.getRevWalk().getObjectReader().getBitmapIndex()); + + return new BitmappedReachabilityChecker(repository.getRevWalk()); + } + +} diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/revwalk/PedestrianReachabilityCheckerTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/revwalk/PedestrianReachabilityCheckerTest.java new file mode 100644 index 0000000000..8d3e78c1fe --- /dev/null +++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/revwalk/PedestrianReachabilityCheckerTest.java @@ -0,0 +1,57 @@ +/* + * Copyright (C) 2019, 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.revwalk; + +import org.eclipse.jgit.internal.storage.file.FileRepository; +import org.eclipse.jgit.junit.TestRepository; + +public class PedestrianReachabilityCheckerTest + extends ReachabilityCheckerTestCase { + + @Override + protected ReachabilityChecker getChecker( + TestRepository<FileRepository> repository) { + return new PedestrianReachabilityChecker(true, repository.getRevWalk()); + } + +} diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/revwalk/ReachabilityCheckerTestCase.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/revwalk/ReachabilityCheckerTestCase.java new file mode 100644 index 0000000000..dd73e35727 --- /dev/null +++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/revwalk/ReachabilityCheckerTestCase.java @@ -0,0 +1,168 @@ +/* + * Copyright (C) 2019, 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.revwalk; + +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; + +import java.util.Arrays; +import java.util.Optional; + +import org.eclipse.jgit.internal.storage.file.FileRepository; +import org.eclipse.jgit.junit.LocalDiskRepositoryTestCase; +import org.eclipse.jgit.junit.TestRepository; +import org.junit.Before; +import org.junit.Test; + +public abstract class ReachabilityCheckerTestCase + extends LocalDiskRepositoryTestCase { + + protected abstract ReachabilityChecker getChecker( + TestRepository<FileRepository> repository) throws Exception; + + TestRepository<FileRepository> repo; + + /** {@inheritDoc} */ + @Override + @Before + public void setUp() throws Exception { + super.setUp(); + FileRepository db = createWorkRepository(); + repo = new TestRepository<>(db); + } + + @Test + public void reachable() throws Exception { + RevCommit a = repo.commit().create(); + RevCommit b1 = repo.commit(a); + RevCommit b2 = repo.commit(b1); + RevCommit c1 = repo.commit(a); + RevCommit c2 = repo.commit(c1); + repo.update("refs/heads/checker", b2); + + ReachabilityChecker checker = getChecker(repo); + + assertReachable("reachable from one tip", + checker.areAllReachable(Arrays.asList(a), Arrays.asList(c2))); + assertReachable("reachable from another tip", + checker.areAllReachable(Arrays.asList(a), Arrays.asList(b2))); + assertReachable("reachable from itself", + checker.areAllReachable(Arrays.asList(a), Arrays.asList(b2))); + } + + @Test + public void reachable_merge() throws Exception { + RevCommit a = repo.commit().create(); + RevCommit b1 = repo.commit(a); + RevCommit b2 = repo.commit(b1); + RevCommit c1 = repo.commit(a); + RevCommit c2 = repo.commit(c1); + RevCommit merge = repo.commit(c2, b2); + repo.update("refs/heads/checker", merge); + + ReachabilityChecker checker = getChecker(repo); + + assertReachable("reachable through one branch", + checker.areAllReachable(Arrays.asList(b1), + Arrays.asList(merge))); + assertReachable("reachable through another branch", + checker.areAllReachable(Arrays.asList(c1), + Arrays.asList(merge))); + assertReachable("reachable, before the branching", + checker.areAllReachable(Arrays.asList(a), + Arrays.asList(merge))); + } + + @Test + public void unreachable_isLaterCommit() throws Exception { + RevCommit a = repo.commit().create(); + RevCommit b1 = repo.commit(a); + RevCommit b2 = repo.commit(b1); + repo.update("refs/heads/checker", b2); + + ReachabilityChecker checker = getChecker(repo); + + assertUnreachable("unreachable from the future", + checker.areAllReachable(Arrays.asList(b2), Arrays.asList(b1))); + } + + @Test + public void unreachable_differentBranch() throws Exception { + RevCommit a = repo.commit().create(); + RevCommit b1 = repo.commit(a); + RevCommit b2 = repo.commit(b1); + RevCommit c1 = repo.commit(a); + repo.update("refs/heads/checker", b2); + + ReachabilityChecker checker = getChecker(repo); + + assertUnreachable("unreachable from different branch", + checker.areAllReachable(Arrays.asList(c1), Arrays.asList(b2))); + } + + @Test + public void reachable_longChain() throws Exception { + RevCommit root = repo.commit().create(); + RevCommit head = root; + for (int i = 0; i < 10000; i++) { + head = repo.commit(head); + } + repo.update("refs/heads/master", head); + + ReachabilityChecker checker = getChecker(repo); + + assertReachable("reachable with long chain in the middle", checker + .areAllReachable(Arrays.asList(root), Arrays.asList(head))); + } + + private static void assertReachable(String msg, + Optional<RevCommit> result) { + assertFalse(msg, result.isPresent()); + } + + private static void assertUnreachable(String msg, + Optional<RevCommit> result) { + assertTrue(msg, result.isPresent()); + } + +} 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 4969305de0..e3972207f7 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 @@ -89,8 +89,8 @@ public class RevObjectTest extends RevWalkTestCase { assertEquals(a1.hashCode(), a2.hashCode()); assertEquals(b1.hashCode(), b2.hashCode()); - assertTrue(AnyObjectId.equals(a1, a2)); - assertTrue(AnyObjectId.equals(b1, b2)); + assertTrue(AnyObjectId.isEqual(a1, a2)); + assertTrue(AnyObjectId.isEqual(b1, b2)); } @Test diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/transport/PacketLineInTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/transport/PacketLineInTest.java index 8b1d860059..f512d2849b 100644 --- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/transport/PacketLineInTest.java +++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/transport/PacketLineInTest.java @@ -44,7 +44,8 @@ package org.eclipse.jgit.transport; import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNotSame; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; import static org.junit.Assert.assertSame; import static org.junit.Assert.fail; @@ -142,21 +143,21 @@ public class PacketLineInTest { init("0004"); final String act = in.readString(); assertEquals("", act); - assertNotSame(PacketLineIn.END, act); + assertFalse(PacketLineIn.isEnd(act)); assertEOF(); } @Test public void testReadString_End() throws IOException { init("0000"); - assertSame(PacketLineIn.END, in.readString()); + assertTrue(PacketLineIn.isEnd(in.readString())); assertEOF(); } @Test public void testReadString_Delim() throws IOException { init("0001"); - assertSame(PacketLineIn.DELIM, in.readString()); + assertTrue(PacketLineIn.isDelimiter(in.readString())); assertEOF(); } @@ -183,14 +184,14 @@ public class PacketLineInTest { init("0004"); final String act = in.readStringRaw(); assertEquals("", act); - assertNotSame(PacketLineIn.END, act); + assertFalse(PacketLineIn.isEnd(act)); assertEOF(); } @Test public void testReadStringRaw_End() throws IOException { init("0000"); - assertSame(PacketLineIn.END, in.readStringRaw()); + assertTrue(PacketLineIn.isEnd(in.readString())); assertEOF(); } diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/transport/ProtocolV0ParserTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/transport/ProtocolV0ParserTest.java index 2c98c84ae5..6e8327c792 100644 --- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/transport/ProtocolV0ParserTest.java +++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/transport/ProtocolV0ParserTest.java @@ -64,9 +64,9 @@ public class ProtocolV0ParserTest { ByteArrayOutputStream send = new ByteArrayOutputStream(); PacketLineOut pckOut = new PacketLineOut(send); for (String line : inputLines) { - if (line == PacketLineIn.END) { + if (PacketLineIn.isEnd(line)) { pckOut.end(); - } else if (line == PacketLineIn.DELIM) { + } else if (PacketLineIn.isDelimiter(line)) { pckOut.writeDelim(); } else { pckOut.writeString(line); @@ -90,7 +90,7 @@ public class ProtocolV0ParserTest { "4624442d68ee402a94364191085b77137618633e", "thin-pack", "no-progress", "include-tag", "ofs-delta", "\n"), "want f900c8326a43303685c46b279b9f70411bff1a4b\n", - PacketLineIn.END); + PacketLineIn.end()); ProtocolV0Parser parser = new ProtocolV0Parser(defaultConfig()); FetchV0Request request = parser.recvWants(pckIn); assertTrue(request.getClientCapabilities() @@ -114,7 +114,7 @@ public class ProtocolV0ParserTest { "4624442d68ee402a94364191085b77137618633e", "thin-pack", "agent=JGit.test/0.0.1", "\n"), "want f900c8326a43303685c46b279b9f70411bff1a4b\n", - PacketLineIn.END); + PacketLineIn.end()); ProtocolV0Parser parser = new ProtocolV0Parser(defaultConfig()); FetchV0Request request = parser.recvWants(pckIn); assertTrue(request.getClientCapabilities() @@ -136,7 +136,7 @@ public class ProtocolV0ParserTest { PacketLineIn pckIn = formatAsPacketLine( "want 4624442d68ee402a94364191085b77137618633e\n", "want f900c8326a43303685c46b279b9f70411bff1a4b\n", - PacketLineIn.END); + PacketLineIn.end()); ProtocolV0Parser parser = new ProtocolV0Parser(defaultConfig()); FetchV0Request request = parser.recvWants(pckIn); assertTrue(request.getClientCapabilities().isEmpty()); @@ -151,7 +151,7 @@ public class ProtocolV0ParserTest { PacketLineIn pckIn = formatAsPacketLine( "want 4624442d68ee402a94364191085b77137618633e\n", "want f900c8326a43303685c46b279b9f70411bff1a4b\n", "deepen 3\n", - PacketLineIn.END); + PacketLineIn.end()); ProtocolV0Parser parser = new ProtocolV0Parser(defaultConfig()); FetchV0Request request = parser.recvWants(pckIn); assertTrue(request.getClientCapabilities().isEmpty()); @@ -168,7 +168,7 @@ public class ProtocolV0ParserTest { "want 4624442d68ee402a94364191085b77137618633e\n", "want f900c8326a43303685c46b279b9f70411bff1a4b\n", "shallow 4b643d0ef739a1b494e7d6926d8d8ed80d35edf4\n", - PacketLineIn.END); + PacketLineIn.end()); ProtocolV0Parser parser = new ProtocolV0Parser(defaultConfig()); FetchV0Request request = parser.recvWants(pckIn); assertTrue(request.getClientCapabilities().isEmpty()); @@ -186,14 +186,15 @@ public class ProtocolV0ParserTest { "want 4624442d68ee402a94364191085b77137618633e\n", "want f900c8326a43303685c46b279b9f70411bff1a4b\n", "filter blob:limit=13000\n", - PacketLineIn.END); + PacketLineIn.end()); ProtocolV0Parser parser = new ProtocolV0Parser(defaultConfig()); FetchV0Request request = parser.recvWants(pckIn); assertTrue(request.getClientCapabilities().isEmpty()); assertThat(request.getWantIds(), hasOnlyObjectIds("4624442d68ee402a94364191085b77137618633e", "f900c8326a43303685c46b279b9f70411bff1a4b")); - assertEquals(13000, request.getFilterBlobLimit()); + assertEquals(13000, request.getFilterSpec().getBlobLimit()); + assertEquals(-1, request.getFilterSpec().getTreeDepthLimit()); } } diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/transport/ProtocolV2ParserTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/transport/ProtocolV2ParserTest.java index dafa81ecd0..0d70cd6121 100644 --- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/transport/ProtocolV2ParserTest.java +++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/transport/ProtocolV2ParserTest.java @@ -123,9 +123,9 @@ public class ProtocolV2ParserTest { ByteArrayOutputStream send = new ByteArrayOutputStream(); PacketLineOut pckOut = new PacketLineOut(send); for (String line : inputLines) { - if (line == PacketLineIn.END) { + if (PacketLineIn.isEnd(line)) { pckOut.end(); - } else if (line == PacketLineIn.DELIM) { + } else if (PacketLineIn.isDelimiter(line)) { pckOut.writeDelim(); } else { pckOut.writeString(line); @@ -136,19 +136,19 @@ public class ProtocolV2ParserTest { } /* - * Succesful fetch with the basic core commands of the protocol. + * Successful fetch with the basic core commands of the protocol. */ @Test public void testFetchBasicArguments() throws PackProtocolException, IOException { PacketLineIn pckIn = formatAsPacketLine( - PacketLineIn.DELIM, + PacketLineIn.delimiter(), "thin-pack", "no-progress", "include-tag", "ofs-delta", "want 4624442d68ee402a94364191085b77137618633e", "want f900c8326a43303685c46b279b9f70411bff1a4b", "have 554f6e41067b9e3e565b6988a8294fac1cb78f4b", "have abc760ab9ad72f08209943251b36cb886a578f87", "done", - PacketLineIn.END); + PacketLineIn.end()); ProtocolV2Parser parser = new ProtocolV2Parser( ConfigBuilder.getDefault()); FetchV2Request request = parser.parseFetchRequest(pckIn); @@ -173,12 +173,12 @@ public class ProtocolV2ParserTest { @Test public void testFetchWithShallow_deepen() throws IOException { PacketLineIn pckIn = formatAsPacketLine( - PacketLineIn.DELIM, + PacketLineIn.delimiter(), "deepen 15", "deepen-relative", "shallow 28274d02c489f4c7e68153056e9061a46f62d7a0", "shallow 145e683b229dcab9d0e2ccb01b386f9ecc17d29d", - PacketLineIn.END); + PacketLineIn.end()); ProtocolV2Parser parser = new ProtocolV2Parser( ConfigBuilder.getDefault()); FetchV2Request request = parser.parseFetchRequest(pckIn); @@ -193,11 +193,11 @@ public class ProtocolV2ParserTest { @Test public void testFetchWithShallow_deepenNot() throws IOException { - PacketLineIn pckIn = formatAsPacketLine(PacketLineIn.DELIM, + PacketLineIn pckIn = formatAsPacketLine(PacketLineIn.delimiter(), "shallow 28274d02c489f4c7e68153056e9061a46f62d7a0", "shallow 145e683b229dcab9d0e2ccb01b386f9ecc17d29d", "deepen-not a08595f76159b09d57553e37a5123f1091bb13e7", - PacketLineIn.END); + PacketLineIn.end()); ProtocolV2Parser parser = new ProtocolV2Parser( ConfigBuilder.getDefault()); FetchV2Request request = parser.parseFetchRequest(pckIn); @@ -210,11 +210,11 @@ public class ProtocolV2ParserTest { @Test public void testFetchWithShallow_deepenSince() throws IOException { - PacketLineIn pckIn = formatAsPacketLine(PacketLineIn.DELIM, + PacketLineIn pckIn = formatAsPacketLine(PacketLineIn.delimiter(), "shallow 28274d02c489f4c7e68153056e9061a46f62d7a0", "shallow 145e683b229dcab9d0e2ccb01b386f9ecc17d29d", "deepen-since 123123123", - PacketLineIn.END); + PacketLineIn.end()); ProtocolV2Parser parser = new ProtocolV2Parser( ConfigBuilder.getDefault()); FetchV2Request request = parser.parseFetchRequest(pckIn); @@ -226,32 +226,46 @@ public class ProtocolV2ParserTest { @Test public void testFetchWithNoneFilter() throws IOException { - PacketLineIn pckIn = formatAsPacketLine(PacketLineIn.DELIM, + PacketLineIn pckIn = formatAsPacketLine(PacketLineIn.delimiter(), "filter blob:none", - PacketLineIn.END); + PacketLineIn.end()); ProtocolV2Parser parser = new ProtocolV2Parser( ConfigBuilder.start().allowFilter().done()); FetchV2Request request = parser.parseFetchRequest(pckIn); - assertEquals(0, request.getFilterBlobLimit()); + assertEquals(0, request.getFilterSpec().getBlobLimit()); + assertEquals(-1, request.getFilterSpec().getTreeDepthLimit()); } @Test public void testFetchWithBlobSizeFilter() throws IOException { - PacketLineIn pckIn = formatAsPacketLine(PacketLineIn.DELIM, + PacketLineIn pckIn = formatAsPacketLine(PacketLineIn.delimiter(), "filter blob:limit=15", - PacketLineIn.END); + PacketLineIn.end()); ProtocolV2Parser parser = new ProtocolV2Parser( ConfigBuilder.start().allowFilter().done()); FetchV2Request request = parser.parseFetchRequest(pckIn); - assertEquals(15, request.getFilterBlobLimit()); + assertEquals(15, request.getFilterSpec().getBlobLimit()); + assertEquals(-1, request.getFilterSpec().getTreeDepthLimit()); + } + + @Test + public void testFetchWithTreeDepthFilter() throws IOException { + PacketLineIn pckIn = formatAsPacketLine(PacketLineIn.delimiter(), + "filter tree:3", + PacketLineIn.end()); + ProtocolV2Parser parser = new ProtocolV2Parser( + ConfigBuilder.start().allowFilter().done()); + FetchV2Request request = parser.parseFetchRequest(pckIn); + assertEquals(-1, request.getFilterSpec().getBlobLimit()); + assertEquals(3, request.getFilterSpec().getTreeDepthLimit()); } @Test public void testFetchMustNotHaveMultipleFilters() throws IOException { - PacketLineIn pckIn = formatAsPacketLine(PacketLineIn.DELIM, + PacketLineIn pckIn = formatAsPacketLine(PacketLineIn.delimiter(), "filter blob:none", "filter blob:limit=12", - PacketLineIn.END); + PacketLineIn.end()); ProtocolV2Parser parser = new ProtocolV2Parser( ConfigBuilder.start().allowFilter().done()); @@ -261,8 +275,8 @@ public class ProtocolV2ParserTest { @Test public void testFetchFilterWithoutAllowFilter() throws IOException { - PacketLineIn pckIn = formatAsPacketLine(PacketLineIn.DELIM, - "filter blob:limit=12", PacketLineIn.END); + PacketLineIn pckIn = formatAsPacketLine(PacketLineIn.delimiter(), + "filter blob:limit=12", PacketLineIn.end()); ProtocolV2Parser parser = new ProtocolV2Parser( ConfigBuilder.getDefault()); @@ -277,10 +291,10 @@ public class ProtocolV2ParserTest { testRepo.update("branchA", one); testRepo.update("branchB", two); - PacketLineIn pckIn = formatAsPacketLine(PacketLineIn.DELIM, + PacketLineIn pckIn = formatAsPacketLine(PacketLineIn.delimiter(), "want e4980cdc48cfa1301493ca94eb70523f6788b819", "want-ref refs/heads/branchA", - PacketLineIn.END); + PacketLineIn.end()); ProtocolV2Parser parser = new ProtocolV2Parser( ConfigBuilder.start().allowRefInWant().done()); @@ -295,10 +309,10 @@ public class ProtocolV2ParserTest { @Test public void testFetchWithRefInWantUnknownRef() throws Exception { - PacketLineIn pckIn = formatAsPacketLine(PacketLineIn.DELIM, + PacketLineIn pckIn = formatAsPacketLine(PacketLineIn.delimiter(), "want e4980cdc48cfa1301493ca94eb70523f6788b819", "want-ref refs/heads/branchC", - PacketLineIn.END); + PacketLineIn.end()); ProtocolV2Parser parser = new ProtocolV2Parser( ConfigBuilder.start().allowRefInWant().done()); @@ -314,8 +328,8 @@ public class ProtocolV2ParserTest { @Test public void testLsRefsMinimalReq() throws IOException { - PacketLineIn pckIn = formatAsPacketLine(PacketLineIn.DELIM, - PacketLineIn.END); + PacketLineIn pckIn = formatAsPacketLine(PacketLineIn.delimiter(), + PacketLineIn.end()); ProtocolV2Parser parser = new ProtocolV2Parser( ConfigBuilder.getDefault()); @@ -327,8 +341,8 @@ public class ProtocolV2ParserTest { @Test public void testLsRefsSymrefs() throws IOException { - PacketLineIn pckIn = formatAsPacketLine(PacketLineIn.DELIM, "symrefs", - PacketLineIn.END); + PacketLineIn pckIn = formatAsPacketLine(PacketLineIn.delimiter(), "symrefs", + PacketLineIn.end()); ProtocolV2Parser parser = new ProtocolV2Parser( ConfigBuilder.getDefault()); @@ -342,9 +356,9 @@ public class ProtocolV2ParserTest { @Test public void testLsRefsPeel() throws IOException { PacketLineIn pckIn = formatAsPacketLine( - PacketLineIn.DELIM, + PacketLineIn.delimiter(), "peel", - PacketLineIn.END); + PacketLineIn.end()); ProtocolV2Parser parser = new ProtocolV2Parser( ConfigBuilder.getDefault()); @@ -356,9 +370,9 @@ public class ProtocolV2ParserTest { @Test public void testLsRefsRefPrefixes() throws IOException { - PacketLineIn pckIn = formatAsPacketLine(PacketLineIn.DELIM, + PacketLineIn pckIn = formatAsPacketLine(PacketLineIn.delimiter(), "ref-prefix refs/for", "ref-prefix refs/heads", - PacketLineIn.END); + PacketLineIn.end()); ProtocolV2Parser parser = new ProtocolV2Parser( ConfigBuilder.getDefault()); diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/transport/PushConnectionTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/transport/PushConnectionTest.java index cea432e34c..89d02d7527 100644 --- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/transport/PushConnectionTest.java +++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/transport/PushConnectionTest.java @@ -67,9 +67,6 @@ import org.eclipse.jgit.lib.ObjectId; import org.eclipse.jgit.lib.ObjectInserter; import org.eclipse.jgit.lib.RefUpdate; import org.eclipse.jgit.lib.Repository; -import org.eclipse.jgit.transport.resolver.ReceivePackFactory; -import org.eclipse.jgit.transport.resolver.ServiceNotAuthorizedException; -import org.eclipse.jgit.transport.resolver.ServiceNotEnabledException; import org.junit.After; import org.junit.Before; import org.junit.Test; @@ -91,27 +88,16 @@ public class PushConnectionTest { server = newRepo("server"); client = newRepo("client"); processedRefs = new ArrayList<>(); - testProtocol = new TestProtocol<>( - null, - new ReceivePackFactory<Object>() { - @Override - public ReceivePack create(Object req, Repository db) - throws ServiceNotEnabledException, - ServiceNotAuthorizedException { - ReceivePack rp = new ReceivePack(db); - rp.setPreReceiveHook( - new PreReceiveHook() { - @Override - public void onPreReceive(ReceivePack receivePack, - Collection<ReceiveCommand> cmds) { - for (ReceiveCommand cmd : cmds) { - processedRefs.add(cmd.getRefName()); - } - } - }); - return rp; - } - }); + testProtocol = new TestProtocol<>(null, (Object req, Repository db) -> { + ReceivePack rp = new ReceivePack(db); + rp.setPreReceiveHook((ReceivePack receivePack, + Collection<ReceiveCommand> cmds) -> { + for (ReceiveCommand cmd : cmds) { + processedRefs.add(cmd.getRefName()); + } + }); + return rp; + }); uri = testProtocol.register(ctx, server); try (ObjectInserter ins = server.newObjectInserter()) { diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/transport/PushOptionsTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/transport/PushOptionsTest.java index f26201d56d..fd1c3bf8b8 100644 --- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/transport/PushOptionsTest.java +++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/transport/PushOptionsTest.java @@ -69,9 +69,6 @@ import org.eclipse.jgit.lib.ObjectInserter; import org.eclipse.jgit.lib.Repository; import org.eclipse.jgit.lib.StoredConfig; import org.eclipse.jgit.revwalk.RevCommit; -import org.eclipse.jgit.transport.resolver.ReceivePackFactory; -import org.eclipse.jgit.transport.resolver.ServiceNotAuthorizedException; -import org.eclipse.jgit.transport.resolver.ServiceNotEnabledException; import org.junit.After; import org.junit.Before; import org.junit.Test; @@ -95,16 +92,11 @@ public class PushOptionsTest extends RepositoryTestCase { client = newRepo("client"); testProtocol = new TestProtocol<>(null, - new ReceivePackFactory<Object>() { - @Override - public ReceivePack create(Object req, Repository git) - throws ServiceNotEnabledException, - ServiceNotAuthorizedException { - receivePack = new ReceivePack(git); - receivePack.setAllowPushOptions(true); - receivePack.setAtomic(true); - return receivePack; - } + (Object req, Repository git) -> { + receivePack = new ReceivePack(git); + receivePack.setAllowPushOptions(true); + receivePack.setAtomic(true); + return receivePack; }); uri = testProtocol.register(ctx, server); 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 50c8a29543..5d208eea73 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 @@ -306,11 +306,11 @@ public class ReceivePackAdvertiseRefsHookTest extends LocalDiskRepositoryTestCas int nul = master.indexOf('\0'); assertTrue("has capability list", nul > 0); assertEquals(B.name() + ' ' + R_MASTER, master.substring(0, nul)); - assertSame(PacketLineIn.END, r.readString()); + assertTrue(PacketLineIn.isEnd(r.readString())); assertEquals("unpack error Missing commit " + P.name(), r.readString()); assertEquals("ng refs/heads/s n/a (unpacker error)", r.readString()); - assertSame(PacketLineIn.END, r.readString()); + assertTrue(PacketLineIn.isEnd(r.readString())); } private static void receive(final ReceivePack rp, @@ -366,13 +366,13 @@ public class ReceivePackAdvertiseRefsHookTest extends LocalDiskRepositoryTestCas int nul = master.indexOf('\0'); assertTrue("has capability list", nul > 0); assertEquals(B.name() + ' ' + R_MASTER, master.substring(0, nul)); - assertSame(PacketLineIn.END, r.readString()); + assertTrue(PacketLineIn.isEnd(r.readString())); assertEquals("unpack error Missing blob " + b.name(), r.readString()); assertEquals("ng refs/heads/s n/a (unpacker error)", r.readString()); - assertSame(PacketLineIn.END, r.readString()); + assertTrue(PacketLineIn.isEnd(r.readString())); } } @@ -419,13 +419,13 @@ public class ReceivePackAdvertiseRefsHookTest extends LocalDiskRepositoryTestCas int nul = master.indexOf('\0'); assertTrue("has capability list", nul > 0); assertEquals(B.name() + ' ' + R_MASTER, master.substring(0, nul)); - assertSame(PacketLineIn.END, r.readString()); + assertTrue(PacketLineIn.isEnd(r.readString())); assertEquals("unpack error Missing blob " + b.name(), r.readString()); assertEquals("ng refs/heads/s n/a (unpacker error)", r.readString()); - assertSame(PacketLineIn.END, r.readString()); + assertTrue(PacketLineIn.isEnd(r.readString())); } } @@ -473,13 +473,13 @@ public class ReceivePackAdvertiseRefsHookTest extends LocalDiskRepositoryTestCas int nul = master.indexOf('\0'); assertTrue("has capability list", nul > 0); assertEquals(B.name() + ' ' + R_MASTER, master.substring(0, nul)); - assertSame(PacketLineIn.END, r.readString()); + assertTrue(PacketLineIn.isEnd(r.readString())); assertEquals("unpack error Missing blob " + n.name(), r.readString()); assertEquals("ng refs/heads/s n/a (unpacker error)", r.readString()); - assertSame(PacketLineIn.END, r.readString()); + assertTrue(PacketLineIn.isEnd(r.readString())); } } @@ -504,13 +504,13 @@ public class ReceivePackAdvertiseRefsHookTest extends LocalDiskRepositoryTestCas int nul = master.indexOf('\0'); assertTrue("has capability list", nul > 0); assertEquals(B.name() + ' ' + R_MASTER, master.substring(0, nul)); - assertSame(PacketLineIn.END, r.readString()); + assertTrue(PacketLineIn.isEnd(r.readString())); String errorLine = r.readString(); assertTrue(errorLine.startsWith("unpack error")); assertTrue(errorLine.contains("Invalid submodule URL '-")); assertEquals("ng refs/heads/s n/a (unpacker error)", r.readString()); - assertSame(PacketLineIn.END, r.readString()); + assertTrue(PacketLineIn.isEnd(r.readString())); } private TemporaryBuffer.Heap setupSourceRepoInvalidGitmodules() @@ -589,13 +589,13 @@ public class ReceivePackAdvertiseRefsHookTest extends LocalDiskRepositoryTestCas int nul = master.indexOf('\0'); assertTrue("has capability list", nul > 0); assertEquals(B.name() + ' ' + R_MASTER, master.substring(0, nul)); - assertSame(PacketLineIn.END, r.readString()); + assertTrue(PacketLineIn.isEnd(r.readString())); assertEquals("unpack error Missing tree " + t.name(), r.readString()); assertEquals("ng refs/heads/s n/a (unpacker error)", r.readString()); - assertSame(PacketLineIn.END, r.readString()); + assertTrue(PacketLineIn.isEnd(r.readString())); } } diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/transport/RefAdvertiserTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/transport/RefAdvertiserTest.java index ce69adf9c1..ccb548d919 100644 --- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/transport/RefAdvertiserTest.java +++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/transport/RefAdvertiserTest.java @@ -45,7 +45,7 @@ package org.eclipse.jgit.transport; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertSame; +import static org.junit.Assert.assertTrue; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; @@ -95,7 +95,7 @@ public class RefAdvertiserTest { assertEquals(id(3).name() + " refs/Iñtërnâtiônà lizætiøn☃💩\n", s); s = pckIn.readStringRaw(); - assertSame(PacketLineIn.END, s); + assertTrue(PacketLineIn.isEnd(s)); } private static ObjectId id(int i) { 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 1c4d0cfe24..f4c55aa50a 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 @@ -92,11 +92,8 @@ public class TestProtocolTest { @Override public UploadPack create(User req, Repository db) { UploadPack up = new UploadPack(db); - up.setPostUploadHook(new PostUploadHook() { - @Override - public void onPostUpload(PackStatistics stats) { - havesCount = stats.getHaves(); - } + up.setPostUploadHook((PackStatistics stats) -> { + havesCount = stats.getHaves(); }); return up; } @@ -217,16 +214,12 @@ public class TestProtocolTest { ObjectId master = remote.branch("master").commit().create(); final AtomicInteger rejected = new AtomicInteger(); - TestProtocol<User> proto = registerProto(new UploadPackFactory<User>() { - @Override - public UploadPack create(User req, Repository db) - throws ServiceNotAuthorizedException { - if (!"user2".equals(req.name)) { - rejected.incrementAndGet(); - throw new ServiceNotAuthorizedException(); - } - return new UploadPack(db); + TestProtocol<User> proto = registerProto((User req, Repository db) -> { + if (!"user2".equals(req.name)) { + rejected.incrementAndGet(); + throw new ServiceNotAuthorizedException(); } + return new UploadPack(db); }, new DefaultReceive()); // Same repository, different users. @@ -262,16 +255,12 @@ public class TestProtocolTest { final AtomicInteger rejected = new AtomicInteger(); TestProtocol<User> proto = registerProto(new DefaultUpload(), - new ReceivePackFactory<User>() { - @Override - public ReceivePack create(User req, Repository db) - throws ServiceNotAuthorizedException { - if (!"user2".equals(req.name)) { - rejected.incrementAndGet(); - throw new ServiceNotAuthorizedException(); - } - return new ReceivePack(db); + (User req, Repository db) -> { + if (!"user2".equals(req.name)) { + rejected.incrementAndGet(); + throw new ServiceNotAuthorizedException(); } + return new ReceivePack(db); }); // Same repository, different users. diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/transport/TransportHttpTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/transport/TransportHttpTest.java new file mode 100644 index 0000000000..ee0e0af8c4 --- /dev/null +++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/transport/TransportHttpTest.java @@ -0,0 +1,189 @@ +/* + * Copyright (C) 2018, Konrad Windszus <konrad_w@gmx.de> + * 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.io.File; +import java.io.IOException; +import java.net.HttpCookie; +import java.time.Instant; +import java.util.Arrays; +import java.util.Collections; +import java.util.Date; +import java.util.LinkedHashSet; +import java.util.Set; + +import org.eclipse.jgit.internal.transport.http.NetscapeCookieFile; +import org.eclipse.jgit.lib.Config; +import org.eclipse.jgit.test.resources.SampleDataRepositoryTestCase; +import org.eclipse.jgit.transport.http.HttpConnection; +import org.eclipse.jgit.util.http.HttpCookiesMatcher; +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; +import org.mockito.ArgumentMatchers; +import org.mockito.Mockito; + +public class TransportHttpTest extends SampleDataRepositoryTestCase { + private URIish uri; + private File cookieFile; + + @Override + @Before + public void setUp() throws Exception { + super.setUp(); + uri = new URIish("https://everyones.loves.git/u/2"); + + final Config config = db.getConfig(); + config.setBoolean("http", null, "saveCookies", true); + cookieFile = createTempFile(); + config.setString("http", null, "cookieFile", + cookieFile.getAbsolutePath()); + } + + @Test + public void testMatchesCookieDomain() { + Assert.assertTrue(TransportHttp.matchesCookieDomain("example.com", + "example.com")); + Assert.assertTrue(TransportHttp.matchesCookieDomain("Example.Com", + "example.cOM")); + Assert.assertTrue(TransportHttp.matchesCookieDomain( + "some.subdomain.example.com", "example.com")); + Assert.assertFalse(TransportHttp + .matchesCookieDomain("someotherexample.com", "example.com")); + Assert.assertFalse(TransportHttp.matchesCookieDomain("example.com", + "example1.com")); + Assert.assertFalse(TransportHttp + .matchesCookieDomain("sub.sub.example.com", ".example.com")); + Assert.assertTrue(TransportHttp.matchesCookieDomain("host.example.com", + "example.com")); + Assert.assertTrue(TransportHttp.matchesCookieDomain( + "something.example.com", "something.example.com")); + Assert.assertTrue(TransportHttp.matchesCookieDomain( + "host.something.example.com", "something.example.com")); + } + + @Test + public void testMatchesCookiePath() { + Assert.assertTrue( + TransportHttp.matchesCookiePath("/some/path", "/some/path")); + Assert.assertTrue(TransportHttp.matchesCookiePath("/some/path/child", + "/some/path")); + Assert.assertTrue(TransportHttp.matchesCookiePath("/some/path/child", + "/some/path/")); + Assert.assertFalse(TransportHttp.matchesCookiePath("/some/pathother", + "/some/path")); + Assert.assertFalse( + TransportHttp.matchesCookiePath("otherpath", "/some/path")); + } + + @Test + public void testProcessResponseCookies() throws IOException { + HttpConnection connection = Mockito.mock(HttpConnection.class); + Mockito.when( + connection.getHeaderFields(ArgumentMatchers.eq("Set-Cookie"))) + .thenReturn(Arrays.asList( + "id=a3fWa; Expires=Fri, 01 Jan 2100 11:00:00 GMT; Secure; HttpOnly", + "sessionid=38afes7a8; HttpOnly; Path=/")); + Mockito.when( + connection.getHeaderFields(ArgumentMatchers.eq("Set-Cookie2"))) + .thenReturn(Collections + .singletonList("cookie2=some value; Max-Age=1234; Path=/")); + + try (TransportHttp transportHttp = new TransportHttp(db, uri)) { + Date creationDate = new Date(); + transportHttp.processResponseCookies(connection); + + // evaluate written cookie file + Set<HttpCookie> expectedCookies = new LinkedHashSet<>(); + + HttpCookie cookie = new HttpCookie("id", "a3fWa"); + cookie.setDomain("everyones.loves.git"); + cookie.setPath("/u/2/"); + + cookie.setMaxAge( + (Instant.parse("2100-01-01T11:00:00.000Z").toEpochMilli() + - creationDate.getTime()) / 1000); + cookie.setSecure(true); + cookie.setHttpOnly(true); + expectedCookies.add(cookie); + + cookie = new HttpCookie("cookie2", "some value"); + cookie.setDomain("everyones.loves.git"); + cookie.setPath("/"); + cookie.setMaxAge(1234); + expectedCookies.add(cookie); + + Assert.assertThat( + new NetscapeCookieFile(cookieFile.toPath()) + .getCookies(true), + HttpCookiesMatcher.containsInOrder(expectedCookies, 5)); + } + } + + @Test + public void testProcessResponseCookiesNotPersistingWithSaveCookiesFalse() + throws IOException { + HttpConnection connection = Mockito.mock(HttpConnection.class); + Mockito.when( + connection.getHeaderFields(ArgumentMatchers.eq("Set-Cookie"))) + .thenReturn(Arrays.asList( + "id=a3fWa; Expires=Thu, 21 Oct 2100 11:00:00 GMT; Secure; HttpOnly", + "sessionid=38afes7a8; HttpOnly; Path=/")); + Mockito.when( + connection.getHeaderFields(ArgumentMatchers.eq("Set-Cookie2"))) + .thenReturn(Collections.singletonList( + "cookie2=some value; Max-Age=1234; Path=/")); + + // tweak config + final Config config = db.getConfig(); + config.setBoolean("http", null, "saveCookies", false); + + try (TransportHttp transportHttp = new TransportHttp(db, uri)) { + transportHttp.processResponseCookies(connection); + + // evaluate written cookie file + Assert.assertFalse("Cookie file was not supposed to be written!", + cookieFile.exists()); + } + } +} 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 1cbe8a4312..260130b2bd 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 @@ -4,7 +4,6 @@ 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.assertNotNull; @@ -16,11 +15,16 @@ import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.StringWriter; +import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; import java.util.HashMap; +import java.util.List; import java.util.Map; +import org.eclipse.jgit.dircache.DirCache; +import org.eclipse.jgit.dircache.DirCacheBuilder; +import org.eclipse.jgit.dircache.DirCacheEntry; import org.eclipse.jgit.errors.PackProtocolException; import org.eclipse.jgit.errors.TransportException; import org.eclipse.jgit.internal.storage.dfs.DfsGarbageCollector; @@ -28,6 +32,8 @@ 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.NullProgressMonitor; +import org.eclipse.jgit.lib.ObjectId; +import org.eclipse.jgit.lib.ObjectInserter; import org.eclipse.jgit.lib.PersonIdent; import org.eclipse.jgit.lib.ProgressMonitor; import org.eclipse.jgit.lib.Ref; @@ -38,10 +44,8 @@ import org.eclipse.jgit.revwalk.RevBlob; import org.eclipse.jgit.revwalk.RevCommit; import org.eclipse.jgit.revwalk.RevTag; import org.eclipse.jgit.revwalk.RevTree; +import org.eclipse.jgit.storage.pack.PackStatistics; import org.eclipse.jgit.transport.UploadPack.RequestPolicy; -import org.eclipse.jgit.transport.resolver.ServiceNotAuthorizedException; -import org.eclipse.jgit.transport.resolver.ServiceNotEnabledException; -import org.eclipse.jgit.transport.resolver.UploadPackFactory; import org.eclipse.jgit.util.io.NullOutputStream; import org.hamcrest.Matchers; import org.junit.After; @@ -69,6 +73,8 @@ public class UploadPackTest { private TestRepository<InMemoryRepository> remote; + private PackStatistics stats; + @Before public void setUp() throws Exception { server = newRepo("server"); @@ -92,17 +98,11 @@ public class UploadPackTest { } private static TestProtocol<Object> generateReachableCommitUploadPackProtocol() { - return new TestProtocol<>( - new UploadPackFactory<Object>() { - @Override - public UploadPack create(Object req, Repository db) - throws ServiceNotEnabledException, - ServiceNotAuthorizedException { - UploadPack up = new UploadPack(db); - up.setRequestPolicy(RequestPolicy.REACHABLE_COMMIT); - return up; - } - }, null); + return new TestProtocol<>((Object req, Repository db) -> { + UploadPack up = new UploadPack(db); + up.setRequestPolicy(RequestPolicy.REACHABLE_COMMIT); + return up; + }, null); } @Test @@ -112,20 +112,14 @@ public class UploadPackTest { RevCommit tip = remote.commit().message("2").parent(commit1).create(); remote.update("master", tip); - testProtocol = new TestProtocol<>( - new UploadPackFactory<Object>() { - @Override - public UploadPack create(Object req, Repository db) - throws ServiceNotEnabledException, - ServiceNotAuthorizedException { - UploadPack up = new UploadPack(db); - up.setRequestPolicy(RequestPolicy.REACHABLE_COMMIT); - // assume client has a shallow commit - up.getRevWalk().assumeShallow( - Collections.singleton(commit1.getId())); - return up; - } - }, null); + testProtocol = new TestProtocol<>((Object req, Repository db) -> { + UploadPack up = new UploadPack(db); + up.setRequestPolicy(RequestPolicy.REACHABLE_COMMIT); + // assume client has a shallow commit + up.getRevWalk() + .assumeShallow(Collections.singleton(commit1.getId())); + return up; + }, null); uri = testProtocol.register(ctx, server); assertFalse(client.getObjectDatabase().has(commit0.toObjectId())); @@ -212,19 +206,14 @@ public class UploadPackTest { 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; - } + testProtocol = new TestProtocol<>((Object req, Repository db) -> { + 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.setFilterSpec(FilterSpec.withBlobLimit(0)); tn.fetch(NullProgressMonitor.INSTANCE, Collections.singletonList(new RefSpec(commit.name()))); assertTrue(client.getObjectDatabase().has(tree.toObjectId())); @@ -250,19 +239,14 @@ public class UploadPackTest { 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; - } + testProtocol = new TestProtocol<>((Object req, Repository db) -> { + 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.setFilterSpec(FilterSpec.withBlobLimit(0)); tn.fetch(NullProgressMonitor.INSTANCE, Arrays.asList( new RefSpec(commit.name()), new RefSpec(blob1.name()))); assertTrue(client.getObjectDatabase().has(tree.toObjectId())); @@ -287,19 +271,14 @@ public class UploadPackTest { 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; - } + testProtocol = new TestProtocol<>((Object req, Repository db) -> { + UploadPack up = new UploadPack(db); + return up; }, null); uri = testProtocol.register(ctx, server2); try (Transport tn = testProtocol.open(uri, client, "server2")) { - tn.setFilterBlobLimit(5); + tn.setFilterSpec(FilterSpec.withBlobLimit(5)); tn.fetch(NullProgressMonitor.INSTANCE, Collections.singletonList(new RefSpec(commit.name()))); assertFalse( @@ -330,19 +309,14 @@ public class UploadPackTest { 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; - } + testProtocol = new TestProtocol<>((Object req, Repository db) -> { + 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.setFilterSpec(FilterSpec.withBlobLimit(0)); tn.fetch(NullProgressMonitor.INSTANCE, Arrays.asList( new RefSpec(commit.name()), new RefSpec(blob1.name()))); assertTrue(client.getObjectDatabase().has(blob1.toObjectId())); @@ -370,19 +344,14 @@ public class UploadPackTest { 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; - } + testProtocol = new TestProtocol<>((Object req, Repository db) -> { + UploadPack up = new UploadPack(db); + return up; }, null); uri = testProtocol.register(ctx, server2); try (Transport tn = testProtocol.open(uri, client, "server2")) { - tn.setFilterBlobLimit(5); + tn.setFilterSpec(FilterSpec.withBlobLimit(5)); tn.fetch(NullProgressMonitor.INSTANCE, Collections.singletonList(new RefSpec(commit.name()))); assertFalse( @@ -406,19 +375,14 @@ public class UploadPackTest { server2.getConfig().setBoolean("uploadpack", null, "allowfilter", false); - testProtocol = new TestProtocol<>(new UploadPackFactory<Object>() { - @Override - public UploadPack create(Object req, Repository db) - throws ServiceNotEnabledException, - ServiceNotAuthorizedException { - UploadPack up = new UploadPack(db); - return up; - } + testProtocol = new TestProtocol<>((Object req, Repository db) -> { + 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.setFilterSpec(FilterSpec.withBlobLimit(0)); thrown.expect(TransportException.class); thrown.expectMessage( @@ -453,6 +417,7 @@ public class UploadPackTest { ByteArrayOutputStream recv = new ByteArrayOutputStream(); up.upload(send, recv, null); + stats = up.getStatistics(); return new ByteArrayInputStream(recv.toByteArray()); } @@ -462,9 +427,9 @@ public class UploadPackTest { try (ByteArrayOutputStream send = new ByteArrayOutputStream()) { PacketLineOut pckOut = new PacketLineOut(send); for (String line : inputLines) { - if (line == PacketLineIn.END) { + if (PacketLineIn.isEnd(line)) { pckOut.end(); - } else if (line == PacketLineIn.DELIM) { + } else if (PacketLineIn.isDelimiter(line)) { pckOut.writeDelim(); } else { pckOut.writeString(line); @@ -487,7 +452,7 @@ public class UploadPackTest { PacketLineIn pckIn = new PacketLineIn(recvStream); // drain capabilities - while (pckIn.readString() != PacketLineIn.END) { + while (!PacketLineIn.isEnd(pckIn.readString())) { // do nothing } return recvStream; @@ -524,7 +489,7 @@ public class UploadPackTest { public void testV2Capabilities() throws Exception { TestV2Hook hook = new TestV2Hook(); ByteArrayInputStream recvStream = - uploadPackV2Setup(null, null, hook, PacketLineIn.END); + uploadPackV2Setup(null, null, hook, PacketLineIn.end()); PacketLineIn pckIn = new PacketLineIn(recvStream); assertThat(hook.capabilitiesRequest, notNullValue()); assertThat(pckIn.readString(), is("version 2")); @@ -538,14 +503,14 @@ public class UploadPackTest { // and additional capabilities to be added to existing // commands without requiring test changes. hasItems("ls-refs", "fetch=shallow", "server-option")); - assertTrue(pckIn.readString() == PacketLineIn.END); + assertTrue(PacketLineIn.isEnd(pckIn.readString())); } @Test public void testV2CapabilitiesAllowFilter() throws Exception { server.getConfig().setBoolean("uploadpack", null, "allowfilter", true); ByteArrayInputStream recvStream = - uploadPackV2Setup(null, null, null, PacketLineIn.END); + uploadPackV2Setup(null, null, null, PacketLineIn.end()); PacketLineIn pckIn = new PacketLineIn(recvStream); assertThat(pckIn.readString(), is("version 2")); @@ -555,14 +520,14 @@ public class UploadPackTest { // TODO(jonathantanmy) This check overspecifies the // order of the capabilities of "fetch". hasItems("ls-refs", "fetch=filter shallow", "server-option")); - assertTrue(pckIn.readString() == PacketLineIn.END); + assertTrue(PacketLineIn.isEnd(pckIn.readString())); } @Test public void testV2CapabilitiesRefInWant() throws Exception { server.getConfig().setBoolean("uploadpack", null, "allowrefinwant", true); ByteArrayInputStream recvStream = - uploadPackV2Setup(null, null, null, PacketLineIn.END); + uploadPackV2Setup(null, null, null, PacketLineIn.end()); PacketLineIn pckIn = new PacketLineIn(recvStream); assertThat(pckIn.readString(), is("version 2")); @@ -573,14 +538,14 @@ public class UploadPackTest { // order of the capabilities of "fetch". hasItems("ls-refs", "fetch=ref-in-want shallow", "server-option")); - assertTrue(pckIn.readString() == PacketLineIn.END); + assertTrue(PacketLineIn.isEnd(pckIn.readString())); } @Test public void testV2CapabilitiesRefInWantNotAdvertisedIfUnallowed() throws Exception { server.getConfig().setBoolean("uploadpack", null, "allowrefinwant", false); ByteArrayInputStream recvStream = - uploadPackV2Setup(null, null, null, PacketLineIn.END); + uploadPackV2Setup(null, null, null, PacketLineIn.end()); PacketLineIn pckIn = new PacketLineIn(recvStream); assertThat(pckIn.readString(), is("version 2")); @@ -588,7 +553,7 @@ public class UploadPackTest { Arrays.asList(pckIn.readString(), pckIn.readString(), pckIn.readString()), hasItems("ls-refs", "fetch=shallow", "server-option")); - assertTrue(pckIn.readString() == PacketLineIn.END); + assertTrue(PacketLineIn.isEnd(pckIn.readString())); } @Test @@ -596,7 +561,7 @@ public class UploadPackTest { server.getConfig().setBoolean("uploadpack", null, "allowrefinwant", true); server.getConfig().setBoolean("uploadpack", null, "advertiserefinwant", false); ByteArrayInputStream recvStream = - uploadPackV2Setup(null, null, null, PacketLineIn.END); + uploadPackV2Setup(null, null, null, PacketLineIn.end()); PacketLineIn pckIn = new PacketLineIn(recvStream); assertThat(pckIn.readString(), is("version 2")); @@ -604,12 +569,12 @@ public class UploadPackTest { Arrays.asList(pckIn.readString(), pckIn.readString(), pckIn.readString()), hasItems("ls-refs", "fetch=shallow", "server-option")); - assertTrue(pckIn.readString() == PacketLineIn.END); + assertTrue(PacketLineIn.isEnd(pckIn.readString())); } @Test public void testV2EmptyRequest() throws Exception { - ByteArrayInputStream recvStream = uploadPackV2(PacketLineIn.END); + ByteArrayInputStream recvStream = uploadPackV2(PacketLineIn.end()); // Verify that there is nothing more after the capability // advertisement. assertEquals(0, recvStream.available()); @@ -625,14 +590,14 @@ public class UploadPackTest { TestV2Hook hook = new TestV2Hook(); ByteArrayInputStream recvStream = uploadPackV2(null, null, hook, - "command=ls-refs\n", PacketLineIn.END); + "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")); - assertTrue(pckIn.readString() == PacketLineIn.END); + assertTrue(PacketLineIn.isEnd(pckIn.readString())); } @Test @@ -643,13 +608,14 @@ public class UploadPackTest { RevTag tag = remote.tag("tag", tip); remote.update("refs/tags/tag", tag); - ByteArrayInputStream recvStream = uploadPackV2("command=ls-refs\n", PacketLineIn.DELIM, "symrefs", PacketLineIn.END); + ByteArrayInputStream recvStream = uploadPackV2("command=ls-refs\n", + PacketLineIn.delimiter(), "symrefs", PacketLineIn.end()); PacketLineIn pckIn = new PacketLineIn(recvStream); assertThat(pckIn.readString(), is(tip.toObjectId().getName() + " HEAD symref-target:refs/heads/master")); assertThat(pckIn.readString(), is(tip.toObjectId().getName() + " refs/heads/master")); assertThat(pckIn.readString(), is(tag.toObjectId().getName() + " refs/tags/tag")); - assertTrue(pckIn.readString() == PacketLineIn.END); + assertTrue(PacketLineIn.isEnd(pckIn.readString())); } @Test @@ -660,7 +626,8 @@ public class UploadPackTest { RevTag tag = remote.tag("tag", tip); remote.update("refs/tags/tag", tag); - ByteArrayInputStream recvStream = uploadPackV2("command=ls-refs\n", PacketLineIn.DELIM, "peel", PacketLineIn.END); + ByteArrayInputStream recvStream = uploadPackV2("command=ls-refs\n", + PacketLineIn.delimiter(), "peel", PacketLineIn.end()); PacketLineIn pckIn = new PacketLineIn(recvStream); assertThat(pckIn.readString(), is(tip.toObjectId().getName() + " HEAD")); @@ -669,7 +636,7 @@ public class UploadPackTest { pckIn.readString(), is(tag.toObjectId().getName() + " refs/tags/tag peeled:" + tip.toObjectId().getName())); - assertTrue(pckIn.readString() == PacketLineIn.END); + assertTrue(PacketLineIn.isEnd(pckIn.readString())); } @Test @@ -681,8 +648,9 @@ public class UploadPackTest { remote.update("refs/tags/tag", tag); ByteArrayInputStream recvStream = uploadPackV2( - "command=ls-refs\n", PacketLineIn.DELIM, "symrefs", "peel", PacketLineIn.END, - "command=ls-refs\n", PacketLineIn.DELIM, PacketLineIn.END); + "command=ls-refs\n", PacketLineIn.delimiter(), "symrefs", + "peel", PacketLineIn.end(), "command=ls-refs\n", + PacketLineIn.delimiter(), PacketLineIn.end()); PacketLineIn pckIn = new PacketLineIn(recvStream); assertThat(pckIn.readString(), is(tip.toObjectId().getName() + " HEAD symref-target:refs/heads/master")); @@ -691,11 +659,11 @@ public class UploadPackTest { pckIn.readString(), is(tag.toObjectId().getName() + " refs/tags/tag peeled:" + tip.toObjectId().getName())); - assertTrue(pckIn.readString() == PacketLineIn.END); + assertTrue(PacketLineIn.isEnd(pckIn.readString())); 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")); - assertTrue(pckIn.readString() == PacketLineIn.END); + assertTrue(PacketLineIn.isEnd(pckIn.readString())); } @Test @@ -707,15 +675,15 @@ public class UploadPackTest { ByteArrayInputStream recvStream = uploadPackV2( "command=ls-refs\n", - PacketLineIn.DELIM, + PacketLineIn.delimiter(), "ref-prefix refs/heads/maste", "ref-prefix refs/heads/other", - PacketLineIn.END); + PacketLineIn.end()); PacketLineIn pckIn = new PacketLineIn(recvStream); assertThat(pckIn.readString(), is(tip.toObjectId().getName() + " refs/heads/master")); assertThat(pckIn.readString(), is(tip.toObjectId().getName() + " refs/heads/other")); - assertTrue(pckIn.readString() == PacketLineIn.END); + assertTrue(PacketLineIn.isEnd(pckIn.readString())); } @Test @@ -726,15 +694,15 @@ public class UploadPackTest { ByteArrayInputStream recvStream = uploadPackV2( "command=ls-refs\n", - PacketLineIn.DELIM, + PacketLineIn.delimiter(), "ref-prefix refs/heads/maste", "ref-prefix r", - PacketLineIn.END); + PacketLineIn.end()); PacketLineIn pckIn = new PacketLineIn(recvStream); assertThat(pckIn.readString(), is(tip.toObjectId().getName() + " refs/heads/master")); assertThat(pckIn.readString(), is(tip.toObjectId().getName() + " refs/heads/other")); - assertTrue(pckIn.readString() == PacketLineIn.END); + assertTrue(PacketLineIn.isEnd(pckIn.readString())); } @Test @@ -743,17 +711,17 @@ public class UploadPackTest { thrown.expectMessage("unexpected invalid-argument"); uploadPackV2( "command=ls-refs\n", - PacketLineIn.DELIM, + PacketLineIn.delimiter(), "invalid-argument\n", - PacketLineIn.END); + PacketLineIn.end()); } @Test public void testV2LsRefsServerOptions() throws Exception { String[] lines = { "command=ls-refs\n", "server-option=one\n", "server-option=two\n", - PacketLineIn.DELIM, - PacketLineIn.END }; + PacketLineIn.delimiter(), + PacketLineIn.end() }; TestV2Hook testHook = new TestV2Hook(); uploadPackV2Setup(null, null, testHook, lines); @@ -797,9 +765,9 @@ public class UploadPackTest { null, null, "command=fetch\n", - PacketLineIn.DELIM, + PacketLineIn.delimiter(), "want " + advertized.name() + "\n", - PacketLineIn.END); + PacketLineIn.end()); // This doesn't thrown.expect(TransportException.class); @@ -810,9 +778,9 @@ public class UploadPackTest { null, null, "command=fetch\n", - PacketLineIn.DELIM, + PacketLineIn.delimiter(), "want " + unadvertized.name() + "\n", - PacketLineIn.END); + PacketLineIn.end()); } @Test @@ -828,9 +796,9 @@ public class UploadPackTest { null, null, "command=fetch\n", - PacketLineIn.DELIM, + PacketLineIn.delimiter(), "want " + reachable.name() + "\n", - PacketLineIn.END); + PacketLineIn.end()); // This doesn't thrown.expect(TransportException.class); @@ -841,9 +809,9 @@ public class UploadPackTest { null, null, "command=fetch\n", - PacketLineIn.DELIM, + PacketLineIn.delimiter(), "want " + unreachable.name() + "\n", - PacketLineIn.END); + PacketLineIn.end()); } @Test @@ -858,9 +826,9 @@ public class UploadPackTest { new RejectAllRefFilter(), null, "command=fetch\n", - PacketLineIn.DELIM, + PacketLineIn.delimiter(), "want " + tip.name() + "\n", - PacketLineIn.END); + PacketLineIn.end()); // This doesn't thrown.expect(TransportException.class); @@ -871,9 +839,9 @@ public class UploadPackTest { new RejectAllRefFilter(), null, "command=fetch\n", - PacketLineIn.DELIM, + PacketLineIn.delimiter(), "want " + parentOfTip.name() + "\n", - PacketLineIn.END); + PacketLineIn.end()); } @Test @@ -889,9 +857,9 @@ public class UploadPackTest { new RejectAllRefFilter(), null, "command=fetch\n", - PacketLineIn.DELIM, + PacketLineIn.delimiter(), "want " + parentOfTip.name() + "\n", - PacketLineIn.END); + PacketLineIn.end()); // This doesn't thrown.expect(TransportException.class); @@ -902,9 +870,9 @@ public class UploadPackTest { new RejectAllRefFilter(), null, "command=fetch\n", - PacketLineIn.DELIM, + PacketLineIn.delimiter(), "want " + unreachable.name() + "\n", - PacketLineIn.END); + PacketLineIn.end()); } @Test @@ -917,9 +885,9 @@ public class UploadPackTest { null, null, "command=fetch\n", - PacketLineIn.DELIM, + PacketLineIn.delimiter(), "want " + unreachable.name() + "\n", - PacketLineIn.END); + PacketLineIn.end()); } @Test @@ -933,16 +901,16 @@ public class UploadPackTest { ByteArrayInputStream recvStream = uploadPackV2( "command=fetch\n", - PacketLineIn.DELIM, + PacketLineIn.delimiter(), "want " + fooChild.toObjectId().getName() + "\n", "want " + barChild.toObjectId().getName() + "\n", "have " + fooParent.toObjectId().getName() + "\n", - PacketLineIn.END); + PacketLineIn.end()); PacketLineIn pckIn = new PacketLineIn(recvStream); assertThat(pckIn.readString(), is("acknowledgments")); assertThat(pckIn.readString(), is("ACK " + fooParent.toObjectId().getName())); - assertThat(pckIn.readString(), theInstance(PacketLineIn.END)); + assertTrue(PacketLineIn.isEnd(pckIn.readString())); } @Test @@ -956,12 +924,12 @@ public class UploadPackTest { ByteArrayInputStream recvStream = uploadPackV2( "command=fetch\n", - PacketLineIn.DELIM, + PacketLineIn.delimiter(), "want " + fooChild.toObjectId().getName() + "\n", "want " + barChild.toObjectId().getName() + "\n", "have " + fooParent.toObjectId().getName() + "\n", "have " + barParent.toObjectId().getName() + "\n", - PacketLineIn.END); + PacketLineIn.end()); PacketLineIn pckIn = new PacketLineIn(recvStream); assertThat(pckIn.readString(), is("acknowledgments")); @@ -971,7 +939,7 @@ public class UploadPackTest { "ACK " + fooParent.toObjectId().getName(), "ACK " + barParent.toObjectId().getName())); assertThat(pckIn.readString(), is("ready")); - assertThat(pckIn.readString(), theInstance(PacketLineIn.DELIM)); + assertTrue(PacketLineIn.isDelimiter(pckIn.readString())); assertThat(pckIn.readString(), is("packfile")); parsePack(recvStream); assertFalse(client.getObjectDatabase().has(fooParent.toObjectId())); @@ -991,12 +959,12 @@ public class UploadPackTest { ByteArrayInputStream recvStream = uploadPackV2( "command=fetch\n", - PacketLineIn.DELIM, + PacketLineIn.delimiter(), "want " + fooChild.toObjectId().getName() + "\n", "want " + barChild.toObjectId().getName() + "\n", "have " + fooParent.toObjectId().getName() + "\n", "done\n", - PacketLineIn.END); + PacketLineIn.end()); PacketLineIn pckIn = new PacketLineIn(recvStream); assertThat(pckIn.readString(), is("packfile")); @@ -1020,12 +988,12 @@ public class UploadPackTest { // Pretend that we have parent to get a thin pack based on it. ByteArrayInputStream recvStream = uploadPackV2( "command=fetch\n", - PacketLineIn.DELIM, + PacketLineIn.delimiter(), "want " + child.toObjectId().getName() + "\n", "have " + parent.toObjectId().getName() + "\n", "thin-pack\n", "done\n", - PacketLineIn.END); + PacketLineIn.end()); PacketLineIn pckIn = new PacketLineIn(recvStream); assertThat(pckIn.readString(), is("packfile")); @@ -1046,10 +1014,10 @@ public class UploadPackTest { StringWriter sw = new StringWriter(); ByteArrayInputStream recvStream = uploadPackV2( "command=fetch\n", - PacketLineIn.DELIM, + PacketLineIn.delimiter(), "want " + commit.toObjectId().getName() + "\n", "done\n", - PacketLineIn.END); + PacketLineIn.end()); PacketLineIn pckIn = new PacketLineIn(recvStream); assertThat(pckIn.readString(), is("packfile")); parsePack(recvStream, new TextProgressMonitor(sw)); @@ -1059,11 +1027,11 @@ public class UploadPackTest { sw = new StringWriter(); recvStream = uploadPackV2( "command=fetch\n", - PacketLineIn.DELIM, + PacketLineIn.delimiter(), "want " + commit.toObjectId().getName() + "\n", "no-progress\n", "done\n", - PacketLineIn.END); + PacketLineIn.end()); pckIn = new PacketLineIn(recvStream); assertThat(pckIn.readString(), is("packfile")); parsePack(recvStream, new TextProgressMonitor(sw)); @@ -1080,10 +1048,10 @@ public class UploadPackTest { // Without include-tag. ByteArrayInputStream recvStream = uploadPackV2( "command=fetch\n", - PacketLineIn.DELIM, + PacketLineIn.delimiter(), "want " + commit.toObjectId().getName() + "\n", "done\n", - PacketLineIn.END); + PacketLineIn.end()); PacketLineIn pckIn = new PacketLineIn(recvStream); assertThat(pckIn.readString(), is("packfile")); parsePack(recvStream); @@ -1092,11 +1060,11 @@ public class UploadPackTest { // With tag. recvStream = uploadPackV2( "command=fetch\n", - PacketLineIn.DELIM, + PacketLineIn.delimiter(), "want " + commit.toObjectId().getName() + "\n", "include-tag\n", "done\n", - PacketLineIn.END); + PacketLineIn.end()); pckIn = new PacketLineIn(recvStream); assertThat(pckIn.readString(), is("packfile")); parsePack(recvStream); @@ -1116,27 +1084,27 @@ public class UploadPackTest { // Without ofs-delta. ByteArrayInputStream recvStream = uploadPackV2( "command=fetch\n", - PacketLineIn.DELIM, + PacketLineIn.delimiter(), "want " + child.toObjectId().getName() + "\n", "done\n", - PacketLineIn.END); + PacketLineIn.end()); PacketLineIn pckIn = new PacketLineIn(recvStream); assertThat(pckIn.readString(), is("packfile")); - ReceivedPackStatistics stats = parsePack(recvStream); - assertTrue(stats.getNumOfsDelta() == 0); + ReceivedPackStatistics receivedStats = parsePack(recvStream); + assertTrue(receivedStats.getNumOfsDelta() == 0); // With ofs-delta. recvStream = uploadPackV2( "command=fetch\n", - PacketLineIn.DELIM, + PacketLineIn.delimiter(), "want " + child.toObjectId().getName() + "\n", "ofs-delta\n", "done\n", - PacketLineIn.END); + PacketLineIn.end()); pckIn = new PacketLineIn(recvStream); assertThat(pckIn.readString(), is("packfile")); - stats = parsePack(recvStream); - assertTrue(stats.getNumOfsDelta() != 0); + receivedStats = parsePack(recvStream); + assertTrue(receivedStats.getNumOfsDelta() != 0); } @Test @@ -1150,11 +1118,11 @@ public class UploadPackTest { // commonParent, so it doesn't send it. ByteArrayInputStream recvStream = uploadPackV2( "command=fetch\n", - PacketLineIn.DELIM, + PacketLineIn.delimiter(), "want " + barChild.toObjectId().getName() + "\n", "have " + fooChild.toObjectId().getName() + "\n", "done\n", - PacketLineIn.END); + PacketLineIn.end()); PacketLineIn pckIn = new PacketLineIn(recvStream); assertThat(pckIn.readString(), is("packfile")); parsePack(recvStream); @@ -1165,12 +1133,12 @@ public class UploadPackTest { // commonParent, so it sends it. recvStream = uploadPackV2( "command=fetch\n", - PacketLineIn.DELIM, + PacketLineIn.delimiter(), "want " + barChild.toObjectId().getName() + "\n", "have " + fooChild.toObjectId().getName() + "\n", "shallow " + fooChild.toObjectId().getName() + "\n", "done\n", - PacketLineIn.END); + PacketLineIn.end()); pckIn = new PacketLineIn(recvStream); assertThat(pckIn.readString(), is("packfile")); parsePack(recvStream); @@ -1186,15 +1154,15 @@ public class UploadPackTest { // "deepen 1" sends only the child. ByteArrayInputStream recvStream = uploadPackV2( "command=fetch\n", - PacketLineIn.DELIM, + PacketLineIn.delimiter(), "want " + child.toObjectId().getName() + "\n", "deepen 1\n", "done\n", - PacketLineIn.END); + PacketLineIn.end()); PacketLineIn pckIn = new PacketLineIn(recvStream); assertThat(pckIn.readString(), is("shallow-info")); assertThat(pckIn.readString(), is("shallow " + child.toObjectId().getName())); - assertThat(pckIn.readString(), theInstance(PacketLineIn.DELIM)); + assertTrue(PacketLineIn.isDelimiter(pckIn.readString())); assertThat(pckIn.readString(), is("packfile")); parsePack(recvStream); assertTrue(client.getObjectDatabase().has(child.toObjectId())); @@ -1203,10 +1171,10 @@ public class UploadPackTest { // Without that, the parent is sent too. recvStream = uploadPackV2( "command=fetch\n", - PacketLineIn.DELIM, + PacketLineIn.delimiter(), "want " + child.toObjectId().getName() + "\n", "done\n", - PacketLineIn.END); + PacketLineIn.end()); pckIn = new PacketLineIn(recvStream); assertThat(pckIn.readString(), is("packfile")); parsePack(recvStream); @@ -1221,10 +1189,10 @@ public class UploadPackTest { ByteArrayInputStream recvStream = uploadPackV2( "command=fetch\n", - PacketLineIn.DELIM, + PacketLineIn.delimiter(), "want " + child.toObjectId().getName() + "\n", "deepen 1\n", - PacketLineIn.END); + PacketLineIn.end()); PacketLineIn pckIn = new PacketLineIn(recvStream); // Verify that only the correct section is sent. "shallow-info" @@ -1232,7 +1200,7 @@ public class UploadPackTest { // sent only if a packfile is sent. assertThat(pckIn.readString(), is("acknowledgments")); assertThat(pckIn.readString(), is("NAK")); - assertThat(pckIn.readString(), theInstance(PacketLineIn.END)); + assertTrue(PacketLineIn.isEnd(pckIn.readString())); } @Test @@ -1253,13 +1221,13 @@ public class UploadPackTest { // Report that we only have "boundary" as a shallow boundary. ByteArrayInputStream recvStream = uploadPackV2( "command=fetch\n", - PacketLineIn.DELIM, + PacketLineIn.delimiter(), "shallow " + boundary.toObjectId().getName() + "\n", "deepen-since 1510000\n", "want " + merge.toObjectId().getName() + "\n", "have " + boundary.toObjectId().getName() + "\n", "done\n", - PacketLineIn.END); + PacketLineIn.end()); PacketLineIn pckIn = new PacketLineIn(recvStream); assertThat(pckIn.readString(), is("shallow-info")); @@ -1271,7 +1239,7 @@ public class UploadPackTest { // later than the given deepen-since time. assertThat(pckIn.readString(), is("unshallow " + boundary.toObjectId().getName())); - assertThat(pckIn.readString(), theInstance(PacketLineIn.DELIM)); + assertTrue(PacketLineIn.isDelimiter(pckIn.readString())); assertThat(pckIn.readString(), is("packfile")); parsePack(recvStream); @@ -1304,12 +1272,12 @@ public class UploadPackTest { ByteArrayInputStream recvStream = uploadPackV2( "command=fetch\n", - PacketLineIn.DELIM, + PacketLineIn.delimiter(), "deepen-since 1510000\n", "want " + child1.toObjectId().getName() + "\n", "want " + child2.toObjectId().getName() + "\n", "done\n", - PacketLineIn.END); + PacketLineIn.end()); PacketLineIn pckIn = new PacketLineIn(recvStream); assertThat(pckIn.readString(), is("shallow-info")); @@ -1320,7 +1288,7 @@ public class UploadPackTest { "shallow " + child1.toObjectId().getName(), "shallow " + child2.toObjectId().getName())); - assertThat(pckIn.readString(), theInstance(PacketLineIn.DELIM)); + assertTrue(PacketLineIn.isDelimiter(pckIn.readString())); assertThat(pckIn.readString(), is("packfile")); parsePack(recvStream); @@ -1343,11 +1311,11 @@ public class UploadPackTest { thrown.expectMessage("No commits selected for shallow request"); uploadPackV2( "command=fetch\n", - PacketLineIn.DELIM, + PacketLineIn.delimiter(), "deepen-since 1510000\n", "want " + tooOld.toObjectId().getName() + "\n", "done\n", - PacketLineIn.END); + PacketLineIn.end()); } @Test @@ -1366,13 +1334,13 @@ public class UploadPackTest { // wants "merge" while excluding "side". ByteArrayInputStream recvStream = uploadPackV2( "command=fetch\n", - PacketLineIn.DELIM, + PacketLineIn.delimiter(), "shallow " + three.toObjectId().getName() + "\n", "deepen-not side\n", "want " + merge.toObjectId().getName() + "\n", "have " + three.toObjectId().getName() + "\n", "done\n", - PacketLineIn.END); + PacketLineIn.end()); PacketLineIn pckIn = new PacketLineIn(recvStream); assertThat(pckIn.readString(), is("shallow-info")); @@ -1387,7 +1355,7 @@ public class UploadPackTest { // "three" is unshallow because its parent "two" is now available. assertThat(pckIn.readString(), is("unshallow " + three.toObjectId().getName())); - assertThat(pckIn.readString(), theInstance(PacketLineIn.DELIM)); + assertTrue(PacketLineIn.isDelimiter(pckIn.readString())); assertThat(pckIn.readString(), is("packfile")); parsePack(recvStream); @@ -1419,11 +1387,11 @@ public class UploadPackTest { thrown.expectMessage("No commits selected for shallow request"); uploadPackV2( "command=fetch\n", - PacketLineIn.DELIM, + PacketLineIn.delimiter(), "deepen-not four\n", "want " + two.toObjectId().getName() + "\n", "done\n", - PacketLineIn.END); + PacketLineIn.end()); } @Test @@ -1439,15 +1407,15 @@ public class UploadPackTest { ByteArrayInputStream recvStream = uploadPackV2( "command=fetch\n", - PacketLineIn.DELIM, + PacketLineIn.delimiter(), "deepen-not twotag\n", "want " + four.toObjectId().getName() + "\n", "done\n", - PacketLineIn.END); + PacketLineIn.end()); PacketLineIn pckIn = new PacketLineIn(recvStream); assertThat(pckIn.readString(), is("shallow-info")); assertThat(pckIn.readString(), is("shallow " + three.toObjectId().getName())); - assertThat(pckIn.readString(), theInstance(PacketLineIn.DELIM)); + assertTrue(PacketLineIn.isDelimiter(pckIn.readString())); assertThat(pckIn.readString(), is("packfile")); parsePack(recvStream); assertFalse(client.getObjectDatabase().has(one.toObjectId())); @@ -1473,12 +1441,12 @@ public class UploadPackTest { ByteArrayInputStream recvStream = uploadPackV2( "command=fetch\n", - PacketLineIn.DELIM, + PacketLineIn.delimiter(), "deepen-not base\n", "want " + child1.toObjectId().getName() + "\n", "want " + child2.toObjectId().getName() + "\n", "done\n", - PacketLineIn.END); + PacketLineIn.end()); PacketLineIn pckIn = new PacketLineIn(recvStream); assertThat(pckIn.readString(), is("shallow-info")); @@ -1489,7 +1457,7 @@ public class UploadPackTest { "shallow " + child1.toObjectId().getName(), "shallow " + child2.toObjectId().getName())); - assertThat(pckIn.readString(), theInstance(PacketLineIn.DELIM)); + assertTrue(PacketLineIn.isDelimiter(pckIn.readString())); assertThat(pckIn.readString(), is("packfile")); parsePack(recvStream); @@ -1505,16 +1473,16 @@ public class UploadPackTest { thrown.expectMessage("unexpected invalid-argument"); uploadPackV2( "command=fetch\n", - PacketLineIn.DELIM, + PacketLineIn.delimiter(), "invalid-argument\n", - PacketLineIn.END); + PacketLineIn.end()); } @Test public void testV2FetchServerOptions() throws Exception { String[] lines = { "command=fetch\n", "server-option=one\n", - "server-option=two\n", PacketLineIn.DELIM, - PacketLineIn.END }; + "server-option=two\n", PacketLineIn.delimiter(), + PacketLineIn.end() }; TestV2Hook testHook = new TestV2Hook(); uploadPackV2Setup(null, null, testHook, lines); @@ -1538,11 +1506,11 @@ public class UploadPackTest { ByteArrayInputStream recvStream = uploadPackV2( "command=fetch\n", - PacketLineIn.DELIM, + PacketLineIn.delimiter(), "want " + commit.toObjectId().getName() + "\n", "filter blob:limit=5\n", "done\n", - PacketLineIn.END); + PacketLineIn.end()); PacketLineIn pckIn = new PacketLineIn(recvStream); assertThat(pckIn.readString(), is("packfile")); parsePack(recvStream); @@ -1551,6 +1519,324 @@ public class UploadPackTest { assertTrue(client.getObjectDatabase().has(small.toObjectId())); } + abstract class TreeBuilder { + abstract void addElements(DirCacheBuilder dcBuilder) throws Exception; + + RevTree build() throws Exception { + DirCache dc = DirCache.newInCore(); + DirCacheBuilder dcBuilder = dc.builder(); + addElements(dcBuilder); + dcBuilder.finish(); + ObjectId id; + try (ObjectInserter ins = + remote.getRepository().newObjectInserter()) { + id = dc.writeTree(ins); + ins.flush(); + } + return remote.getRevWalk().parseTree(id); + } + } + + class DeepTreePreparator { + RevBlob blobLowDepth = remote.blob("lo"); + RevBlob blobHighDepth = remote.blob("hi"); + + RevTree subtree = remote.tree(remote.file("1", blobHighDepth)); + RevTree rootTree = (new TreeBuilder() { + @Override + void addElements(DirCacheBuilder dcBuilder) throws Exception { + dcBuilder.add(remote.file("1", blobLowDepth)); + dcBuilder.addTree(new byte[] {'2'}, DirCacheEntry.STAGE_0, + remote.getRevWalk().getObjectReader(), subtree); + } + }).build(); + RevCommit commit = remote.commit(rootTree); + + DeepTreePreparator() throws Exception {} + } + + private void uploadV2WithTreeDepthFilter( + long depth, ObjectId... wants) throws Exception { + server.getConfig().setBoolean("uploadpack", null, "allowfilter", true); + + List<String> input = new ArrayList<>(); + input.add("command=fetch\n"); + input.add(PacketLineIn.delimiter()); + for (ObjectId want : wants) { + input.add("want " + want.getName() + "\n"); + } + input.add("filter tree:" + depth + "\n"); + input.add("done\n"); + input.add(PacketLineIn.end()); + ByteArrayInputStream recvStream = + uploadPackV2(RequestPolicy.ANY, /*refFilter=*/null, + /*hook=*/null, input.toArray(new String[0])); + PacketLineIn pckIn = new PacketLineIn(recvStream); + assertThat(pckIn.readString(), is("packfile")); + parsePack(recvStream); + } + + @Test + public void testV2FetchFilterTreeDepth0() throws Exception { + DeepTreePreparator preparator = new DeepTreePreparator(); + remote.update("master", preparator.commit); + + uploadV2WithTreeDepthFilter(0, preparator.commit.toObjectId()); + + assertFalse(client.getObjectDatabase() + .has(preparator.rootTree.toObjectId())); + assertFalse(client.getObjectDatabase() + .has(preparator.subtree.toObjectId())); + assertFalse(client.getObjectDatabase() + .has(preparator.blobLowDepth.toObjectId())); + assertFalse(client.getObjectDatabase() + .has(preparator.blobHighDepth.toObjectId())); + assertEquals(1, stats.getTreesTraversed()); + } + + @Test + public void testV2FetchFilterTreeDepth1_serverHasBitmap() throws Exception { + DeepTreePreparator preparator = new DeepTreePreparator(); + remote.update("master", preparator.commit); + + // The bitmap should be ignored since we need to track the depth while + // traversing the trees. + generateBitmaps(server); + + uploadV2WithTreeDepthFilter(1, preparator.commit.toObjectId()); + + assertTrue(client.getObjectDatabase() + .has(preparator.rootTree.toObjectId())); + assertFalse(client.getObjectDatabase() + .has(preparator.subtree.toObjectId())); + assertFalse(client.getObjectDatabase() + .has(preparator.blobLowDepth.toObjectId())); + assertFalse(client.getObjectDatabase() + .has(preparator.blobHighDepth.toObjectId())); + assertEquals(1, stats.getTreesTraversed()); + } + + @Test + public void testV2FetchFilterTreeDepth2() throws Exception { + DeepTreePreparator preparator = new DeepTreePreparator(); + remote.update("master", preparator.commit); + + uploadV2WithTreeDepthFilter(2, preparator.commit.toObjectId()); + + assertTrue(client.getObjectDatabase() + .has(preparator.rootTree.toObjectId())); + assertTrue(client.getObjectDatabase() + .has(preparator.subtree.toObjectId())); + assertTrue(client.getObjectDatabase() + .has(preparator.blobLowDepth.toObjectId())); + assertFalse(client.getObjectDatabase() + .has(preparator.blobHighDepth.toObjectId())); + assertEquals(2, stats.getTreesTraversed()); + } + + /** + * Creates a commit with the following files: + * <pre> + * a/x/b/foo + * x/b/foo + * </pre> + * which has an identical tree in two locations: once at / and once at /a + */ + class RepeatedSubtreePreparator { + RevBlob foo = remote.blob("foo"); + RevTree subtree3 = remote.tree(remote.file("foo", foo)); + RevTree subtree2 = (new TreeBuilder() { + @Override + void addElements(DirCacheBuilder dcBuilder) throws Exception { + dcBuilder.addTree(new byte[] {'b'}, DirCacheEntry.STAGE_0, + remote.getRevWalk().getObjectReader(), subtree3); + } + }).build(); + RevTree subtree1 = (new TreeBuilder() { + @Override + void addElements(DirCacheBuilder dcBuilder) throws Exception { + dcBuilder.addTree(new byte[] {'x'}, DirCacheEntry.STAGE_0, + remote.getRevWalk().getObjectReader(), subtree2); + } + }).build(); + RevTree rootTree = (new TreeBuilder() { + @Override + void addElements(DirCacheBuilder dcBuilder) throws Exception { + dcBuilder.addTree(new byte[] {'a'}, DirCacheEntry.STAGE_0, + remote.getRevWalk().getObjectReader(), subtree1); + dcBuilder.addTree(new byte[] {'x'}, DirCacheEntry.STAGE_0, + remote.getRevWalk().getObjectReader(), subtree2); + } + }).build(); + RevCommit commit = remote.commit(rootTree); + + RepeatedSubtreePreparator() throws Exception {} + } + + @Test + public void testV2FetchFilterTreeDepth_iterateOverTreeAtTwoLevels() + throws Exception { + // Test tree:<depth> where a tree is iterated to twice - once where a + // subentry is too deep to be included, and again where the blob inside + // it is shallow enough to be included. + RepeatedSubtreePreparator preparator = new RepeatedSubtreePreparator(); + remote.update("master", preparator.commit); + + uploadV2WithTreeDepthFilter(4, preparator.commit.toObjectId()); + + assertTrue(client.getObjectDatabase() + .has(preparator.foo.toObjectId())); + } + + /** + * Creates a commit with the following files: + * <pre> + * a/x/b/foo + * b/u/c/baz + * y/x/b/foo + * z/v/c/baz + * </pre> + * which has two pairs of identical trees: + * <ul> + * <li>one at /a and /y + * <li>one at /b/u and /z/v + * </ul> + * Note that this class defines unique 8 trees (rootTree and subtree1-7) + * which means PackStatistics should report having visited 8 trees. + */ + class RepeatedSubtreeAtSameLevelPreparator { + RevBlob foo = remote.blob("foo"); + + /** foo */ + RevTree subtree1 = remote.tree(remote.file("foo", foo)); + + /** b/foo */ + RevTree subtree2 = (new TreeBuilder() { + @Override + void addElements(DirCacheBuilder dcBuilder) throws Exception { + dcBuilder.addTree(new byte[] {'b'}, DirCacheEntry.STAGE_0, + remote.getRevWalk().getObjectReader(), subtree1); + } + }).build(); + + /** x/b/foo */ + RevTree subtree3 = (new TreeBuilder() { + @Override + void addElements(DirCacheBuilder dcBuilder) throws Exception { + dcBuilder.addTree(new byte[] {'x'}, DirCacheEntry.STAGE_0, + remote.getRevWalk().getObjectReader(), subtree2); + } + }).build(); + + RevBlob baz = remote.blob("baz"); + + /** baz */ + RevTree subtree4 = remote.tree(remote.file("baz", baz)); + + /** c/baz */ + RevTree subtree5 = (new TreeBuilder() { + @Override + void addElements(DirCacheBuilder dcBuilder) throws Exception { + dcBuilder.addTree(new byte[] {'c'}, DirCacheEntry.STAGE_0, + remote.getRevWalk().getObjectReader(), subtree4); + } + }).build(); + + /** u/c/baz */ + RevTree subtree6 = (new TreeBuilder() { + @Override + void addElements(DirCacheBuilder dcBuilder) throws Exception { + dcBuilder.addTree(new byte[] {'u'}, DirCacheEntry.STAGE_0, + remote.getRevWalk().getObjectReader(), subtree5); + } + }).build(); + + /** v/c/baz */ + RevTree subtree7 = (new TreeBuilder() { + @Override + void addElements(DirCacheBuilder dcBuilder) throws Exception { + dcBuilder.addTree(new byte[] {'v'}, DirCacheEntry.STAGE_0, + remote.getRevWalk().getObjectReader(), subtree5); + } + }).build(); + + RevTree rootTree = (new TreeBuilder() { + @Override + void addElements(DirCacheBuilder dcBuilder) throws Exception { + dcBuilder.addTree(new byte[] {'a'}, DirCacheEntry.STAGE_0, + remote.getRevWalk().getObjectReader(), subtree3); + dcBuilder.addTree(new byte[] {'b'}, DirCacheEntry.STAGE_0, + remote.getRevWalk().getObjectReader(), subtree6); + dcBuilder.addTree(new byte[] {'y'}, DirCacheEntry.STAGE_0, + remote.getRevWalk().getObjectReader(), subtree3); + dcBuilder.addTree(new byte[] {'z'}, DirCacheEntry.STAGE_0, + remote.getRevWalk().getObjectReader(), subtree7); + } + }).build(); + RevCommit commit = remote.commit(rootTree); + + RepeatedSubtreeAtSameLevelPreparator() throws Exception {} + } + + @Test + public void testV2FetchFilterTreeDepth_repeatTreeAtSameLevelIncludeFile() + throws Exception { + RepeatedSubtreeAtSameLevelPreparator preparator = + new RepeatedSubtreeAtSameLevelPreparator(); + remote.update("master", preparator.commit); + + uploadV2WithTreeDepthFilter(5, preparator.commit.toObjectId()); + + assertTrue(client.getObjectDatabase() + .has(preparator.foo.toObjectId())); + assertTrue(client.getObjectDatabase() + .has(preparator.baz.toObjectId())); + assertEquals(8, stats.getTreesTraversed()); + } + + @Test + public void testV2FetchFilterTreeDepth_repeatTreeAtSameLevelExcludeFile() + throws Exception { + RepeatedSubtreeAtSameLevelPreparator preparator = + new RepeatedSubtreeAtSameLevelPreparator(); + remote.update("master", preparator.commit); + + uploadV2WithTreeDepthFilter(4, preparator.commit.toObjectId()); + + assertFalse(client.getObjectDatabase() + .has(preparator.foo.toObjectId())); + assertFalse(client.getObjectDatabase() + .has(preparator.baz.toObjectId())); + assertEquals(8, stats.getTreesTraversed()); + } + + @Test + public void testWantFilteredObject() throws Exception { + RepeatedSubtreePreparator preparator = new RepeatedSubtreePreparator(); + remote.update("master", preparator.commit); + + // Specify wanted blob objects that are deep enough to be filtered. We + // should still upload them. + uploadV2WithTreeDepthFilter( + 3, + preparator.commit.toObjectId(), + preparator.foo.toObjectId()); + assertTrue(client.getObjectDatabase() + .has(preparator.foo.toObjectId())); + + client = newRepo("client"); + // Specify a wanted tree object that is deep enough to be filtered. We + // should still upload it. + uploadV2WithTreeDepthFilter( + 2, + preparator.commit.toObjectId(), + preparator.subtree3.toObjectId()); + assertTrue(client.getObjectDatabase() + .has(preparator.foo.toObjectId())); + assertTrue(client.getObjectDatabase() + .has(preparator.subtree3.toObjectId())); + } + @Test public void testV2FetchFilterWhenNotAllowed() throws Exception { RevCommit commit = remote.commit().message("0").create(); @@ -1562,11 +1848,11 @@ public class UploadPackTest { thrown.expectMessage("unexpected filter blob:limit=5"); uploadPackV2( "command=fetch\n", - PacketLineIn.DELIM, + PacketLineIn.delimiter(), "want " + commit.toObjectId().getName() + "\n", "filter blob:limit=5\n", "done\n", - PacketLineIn.END); + PacketLineIn.end()); } @Test @@ -1577,10 +1863,10 @@ public class UploadPackTest { try { uploadPackV2( "command=fetch\n", - PacketLineIn.DELIM, + PacketLineIn.delimiter(), "want-ref refs/heads/one\n", "done\n", - PacketLineIn.END); + PacketLineIn.end()); } catch (PackProtocolException e) { assertThat( e.getMessage(), @@ -1603,11 +1889,11 @@ public class UploadPackTest { ByteArrayInputStream recvStream = uploadPackV2( "command=fetch\n", - PacketLineIn.DELIM, + PacketLineIn.delimiter(), "want-ref refs/heads/one\n", "want-ref refs/heads/two\n", "done\n", - PacketLineIn.END); + PacketLineIn.end()); PacketLineIn pckIn = new PacketLineIn(recvStream); assertThat(pckIn.readString(), is("wanted-refs")); assertThat( @@ -1615,7 +1901,7 @@ public class UploadPackTest { hasItems( one.toObjectId().getName() + " refs/heads/one", two.toObjectId().getName() + " refs/heads/two")); - assertThat(pckIn.readString(), theInstance(PacketLineIn.DELIM)); + assertTrue(PacketLineIn.isDelimiter(pckIn.readString())); assertThat(pckIn.readString(), is("packfile")); parsePack(recvStream); @@ -1634,11 +1920,11 @@ public class UploadPackTest { try { uploadPackV2( "command=fetch\n", - PacketLineIn.DELIM, + PacketLineIn.delimiter(), "want-ref refs/heads/one\n", "want-ref refs/heads/nonExistentRef\n", "done\n", - PacketLineIn.END); + PacketLineIn.end()); } catch (PackProtocolException e) { assertThat( e.getMessage(), @@ -1661,17 +1947,17 @@ public class UploadPackTest { ByteArrayInputStream recvStream = uploadPackV2( "command=fetch\n", - PacketLineIn.DELIM, + PacketLineIn.delimiter(), "want-ref refs/heads/one\n", "want " + two.toObjectId().getName() + "\n", "done\n", - PacketLineIn.END); + 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)); + assertTrue(PacketLineIn.isDelimiter(pckIn.readString())); assertThat(pckIn.readString(), is("packfile")); parsePack(recvStream); @@ -1689,11 +1975,11 @@ public class UploadPackTest { ByteArrayInputStream recvStream = uploadPackV2( "command=fetch\n", - PacketLineIn.DELIM, + PacketLineIn.delimiter(), "want-ref refs/heads/one\n", "have " + one.toObjectId().getName(), "done\n", - PacketLineIn.END); + PacketLineIn.end()); PacketLineIn pckIn = new PacketLineIn(recvStream); // The client still needs to know the hash of the object that @@ -1703,7 +1989,7 @@ public class UploadPackTest { assertThat( pckIn.readString(), is(one.toObjectId().getName() + " refs/heads/one")); - assertThat(pckIn.readString(), theInstance(PacketLineIn.DELIM)); + assertTrue(PacketLineIn.isDelimiter(pckIn.readString())); // ... but the client does not need the object itself. assertThat(pckIn.readString(), is("packfile")); @@ -1721,20 +2007,20 @@ public class UploadPackTest { ByteArrayInputStream recvStream = uploadPackV2( "command=fetch\n", - PacketLineIn.DELIM, + PacketLineIn.delimiter(), "want-ref refs/heads/branch1\n", "deepen 1\n", "done\n", - PacketLineIn.END); + 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)); + assertTrue(PacketLineIn.isDelimiter(pckIn.readString())); assertThat(pckIn.readString(), is("wanted-refs")); assertThat(pckIn.readString(), is(child.toObjectId().getName() + " refs/heads/branch1")); - assertThat(pckIn.readString(), theInstance(PacketLineIn.DELIM)); + assertTrue(PacketLineIn.isDelimiter(pckIn.readString())); assertThat(pckIn.readString(), is("packfile")); parsePack(recvStream); assertTrue(client.getObjectDatabase().has(child.toObjectId())); @@ -1752,13 +2038,13 @@ public class UploadPackTest { true); ByteArrayInputStream recvStream = uploadPackV2("command=fetch\n", - PacketLineIn.DELIM, + PacketLineIn.delimiter(), "want-ref refs/heads/three\n", "deepen 3", "shallow 0123012301230123012301230123012301230123", "shallow " + two.getName() + '\n', "done\n", - PacketLineIn.END); + PacketLineIn.end()); PacketLineIn pckIn = new PacketLineIn(recvStream); assertThat(pckIn.readString(), is("shallow-info")); @@ -1766,11 +2052,11 @@ public class UploadPackTest { is("shallow " + one.toObjectId().getName())); assertThat(pckIn.readString(), is("unshallow " + two.toObjectId().getName())); - assertThat(pckIn.readString(), theInstance(PacketLineIn.DELIM)); + assertTrue(PacketLineIn.isDelimiter(pckIn.readString())); assertThat(pckIn.readString(), is("wanted-refs")); assertThat(pckIn.readString(), is(three.toObjectId().getName() + " refs/heads/three")); - assertThat(pckIn.readString(), theInstance(PacketLineIn.DELIM)); + assertTrue(PacketLineIn.isDelimiter(pckIn.readString())); assertThat(pckIn.readString(), is("packfile")); parsePack(recvStream); @@ -1787,7 +2073,7 @@ public class UploadPackTest { UploadPack up = new UploadPack(server); ByteArrayInputStream send = linesAsInputStream( "want " + one.getName() + " agent=JGit-test/1.2.3\n", - PacketLineIn.END, + PacketLineIn.end(), "have 11cedf1b796d44207da702f7d420684022fc0f09\n", "done\n"); ByteArrayOutputStream recv = new ByteArrayOutputStream(); @@ -1808,9 +2094,9 @@ public class UploadPackTest { ByteArrayInputStream send = linesAsInputStream( "command=fetch\n", "agent=JGit-test/1.2.4\n", - PacketLineIn.DELIM, "want " + one.getName() + "\n", + PacketLineIn.delimiter(), "want " + one.getName() + "\n", "have 11cedf1b796d44207da702f7d420684022fc0f09\n", "done\n", - PacketLineIn.END); + PacketLineIn.end()); ByteArrayOutputStream recv = new ByteArrayOutputStream(); up.upload(send, recv, null); 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 754341dfea..a3ce4ae94f 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 @@ -584,26 +584,23 @@ public class FileTreeIteratorTest extends RepositoryTestCase { } } - private final FileTreeIterator.FileModeStrategy NO_GITLINKS_STRATEGY = - new FileTreeIterator.FileModeStrategy() { - @Override - public FileMode getMode(File f, FS.Attributes attributes) { - if (attributes.isSymbolicLink()) { - return FileMode.SYMLINK; - } else if (attributes.isDirectory()) { - // NOTE: in the production DefaultFileModeStrategy, there is - // a check here for a subdirectory called '.git', and if it - // exists, we create a GITLINK instead of recursing into the - // tree. In this custom strategy, we ignore nested git dirs - // and treat all directories the same. - return FileMode.TREE; - } else if (attributes.isExecutable()) { - return FileMode.EXECUTABLE_FILE; - } else { - return FileMode.REGULAR_FILE; - } - } - }; + private final FileTreeIterator.FileModeStrategy NO_GITLINKS_STRATEGY = ( + File f, FS.Attributes attributes) -> { + if (attributes.isSymbolicLink()) { + return FileMode.SYMLINK; + } else if (attributes.isDirectory()) { + // NOTE: in the production DefaultFileModeStrategy, there is + // a check here for a subdirectory called '.git', and if it + // exists, we create a GITLINK instead of recursing into the + // tree. In this custom strategy, we ignore nested git dirs + // and treat all directories the same. + return FileMode.TREE; + } else if (attributes.isExecutable()) { + return FileMode.EXECUTABLE_FILE; + } else { + return FileMode.REGULAR_FILE; + } + }; private Repository createNestedRepo() throws IOException { File gitdir = createUniqueTestGitDir(false); diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/util/FileUtilsTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/util/FileUtilsTest.java index c0f4965668..9ee9613f79 100644 --- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/util/FileUtilsTest.java +++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/util/FileUtilsTest.java @@ -137,7 +137,6 @@ public class FileUtilsTest { } @Test - public void testDeleteRecursiveEmpty() throws IOException { File f1 = new File(trash, "test/test/a"); File f2 = new File(trash, "test/a"); diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/util/LRUMapTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/util/LRUMapTest.java new file mode 100644 index 0000000000..da59533aeb --- /dev/null +++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/util/LRUMapTest.java @@ -0,0 +1,78 @@ +/* + * Copyright (C) 2018, Konrad Windszus <konrad_w@gmx.de> + * 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.util; + +import java.util.LinkedHashMap; +import java.util.Map; + +import org.hamcrest.collection.IsIterableContainingInOrder; +import org.junit.Assert; +import org.junit.Test; + +public class LRUMapTest { + + @SuppressWarnings("boxing") + @Test + public void testLRUEntriesAreEvicted() { + Map<Integer, Integer> map = new LRUMap<>(3, 3); + for (int i = 0; i < 3; i++) { + map.put(i, i); + } + // access the last ones + map.get(2); + map.get(0); + + // put another one which exceeds the limit (entry with key "1" is + // evicted) + map.put(3, 3); + + Map<Integer, Integer> expectedMap = new LinkedHashMap<>(); + expectedMap.put(2, 2); + expectedMap.put(0, 0); + expectedMap.put(3, 3); + + Assert.assertThat(map.entrySet(), + IsIterableContainingInOrder + .contains(expectedMap.entrySet().toArray())); + } +} diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/util/RefListTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/util/RefListTest.java index d124d7365c..9981bd6514 100644 --- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/util/RefListTest.java +++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/util/RefListTest.java @@ -128,6 +128,41 @@ public class RefListTest { } @Test + public void testBuilder_AddThenDedupe() { + RefList.Builder<Ref> builder = new RefList.Builder<>(1); + builder.add(REF_B); + builder.add(REF_A); + builder.add(REF_A); + builder.add(REF_B); + builder.add(REF_c); + + builder.sort(); + builder.dedupe((a, b) -> b); + RefList<Ref> list = builder.toRefList(); + + assertEquals(3, list.size()); + assertSame(REF_A, list.get(0)); + assertSame(REF_B, list.get(1)); + assertSame(REF_c, list.get(2)); + } + + @Test + public void testBuilder_AddThenDedupe_Border() { + RefList.Builder<Ref> builder = new RefList.Builder<>(1); + builder.sort(); + builder.dedupe((a, b) -> b); + RefList<Ref> list = builder.toRefList(); + assertTrue(list.isEmpty()); + + builder = new RefList.Builder<>(1); + builder.add(REF_A); + builder.sort(); + builder.dedupe((a, b) -> b); + list = builder.toRefList(); + assertEquals(1, list.size()); + } + + @Test public void testBuilder_AddAll() { RefList.Builder<Ref> builder = new RefList.Builder<>(1); Ref[] src = { REF_A, REF_B, REF_c, REF_A }; diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/util/http/HttpCookiesMatcher.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/util/http/HttpCookiesMatcher.java new file mode 100644 index 0000000000..8c5b127de2 --- /dev/null +++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/util/http/HttpCookiesMatcher.java @@ -0,0 +1,150 @@ +/* + * Copyright (C) 2018, Konrad Windszus <konrad_w@gmx.de> + * 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.util.http; + +import java.net.HttpCookie; +import java.util.LinkedList; +import java.util.List; + +import org.hamcrest.Description; +import org.hamcrest.Matcher; +import org.hamcrest.TypeSafeMatcher; +import org.hamcrest.collection.IsIterableContainingInOrder; + +public final class HttpCookiesMatcher { + public static Matcher<Iterable<? extends HttpCookie>> containsInOrder( + Iterable<HttpCookie> expectedCookies) { + return containsInOrder(expectedCookies, 0); + } + + public static Matcher<Iterable<? extends HttpCookie>> containsInOrder( + Iterable<HttpCookie> expectedCookies, int allowedMaxAgeDelta) { + final List<Matcher<? super HttpCookie>> cookieMatchers = new LinkedList<>(); + for (HttpCookie cookie : expectedCookies) { + cookieMatchers + .add(new HttpCookieMatcher(cookie, allowedMaxAgeDelta)); + } + return new IsIterableContainingInOrder<>(cookieMatchers); + } + + /** + * The default {@link HttpCookie#equals(Object)} is not good enough for + * testing purposes. Also the {@link HttpCookie#toString()} only emits some + * of the cookie attributes. For testing a dedicated matcher is needed which + * takes into account all attributes. + */ + private static final class HttpCookieMatcher + extends TypeSafeMatcher<HttpCookie> { + + private final HttpCookie cookie; + + private final int allowedMaxAgeDelta; + + public HttpCookieMatcher(HttpCookie cookie, int allowedMaxAgeDelta) { + this.cookie = cookie; + this.allowedMaxAgeDelta = allowedMaxAgeDelta; + } + + @Override + public void describeTo(Description description) { + describeCookie(description, cookie); + } + + @Override + protected void describeMismatchSafely(HttpCookie item, + Description mismatchDescription) { + mismatchDescription.appendText("was "); + describeCookie(mismatchDescription, item); + } + + @Override + protected boolean matchesSafely(HttpCookie otherCookie) { + // the equals method in HttpCookie is not specific enough, we want + // to consider all attributes! + return (equals(cookie.getName(), otherCookie.getName()) + && equals(cookie.getValue(), otherCookie.getValue()) + && equals(cookie.getDomain(), otherCookie.getDomain()) + && equals(cookie.getPath(), otherCookie.getPath()) + && (cookie.getMaxAge() >= otherCookie.getMaxAge() + - allowedMaxAgeDelta) + && (cookie.getMaxAge() <= otherCookie.getMaxAge() + + allowedMaxAgeDelta) + && cookie.isHttpOnly() == otherCookie.isHttpOnly() + && cookie.getSecure() == otherCookie.getSecure() + && cookie.getVersion() == otherCookie.getVersion()); + } + + private static boolean equals(String value1, String value2) { + if (value1 == null && value2 == null) { + return true; + } + if (value1 == null || value2 == null) { + return false; + } + return value1.equals(value2); + } + + @SuppressWarnings("boxing") + protected static void describeCookie(Description description, + HttpCookie cookie) { + description.appendText("HttpCookie["); + description.appendText("name: ").appendValue(cookie.getName()) + .appendText(", "); + description.appendText("value: ").appendValue(cookie.getValue()) + .appendText(", "); + description.appendText("domain: ").appendValue(cookie.getDomain()) + .appendText(", "); + description.appendText("path: ").appendValue(cookie.getPath()) + .appendText(", "); + description.appendText("maxAge: ").appendValue(cookie.getMaxAge()) + .appendText(", "); + description.appendText("httpOnly: ") + .appendValue(cookie.isHttpOnly()).appendText(", "); + description.appendText("secure: ").appendValue(cookie.getSecure()) + .appendText(", "); + description.appendText("version: ").appendValue(cookie.getVersion()) + .appendText(", "); + description.appendText("]"); + } + } +}
\ No newline at end of file diff --git a/org.eclipse.jgit.ui/META-INF/MANIFEST.MF b/org.eclipse.jgit.ui/META-INF/MANIFEST.MF index d5e51b6c76..531d28779d 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.3.3.qualifier +Bundle-Version: 5.4.1.qualifier Bundle-Vendor: %provider_name Bundle-RequiredExecutionEnvironment: JavaSE-1.8 -Export-Package: org.eclipse.jgit.awtui;version="5.3.3" -Import-Package: org.eclipse.jgit.errors;version="[5.3.3,5.4.0)", - org.eclipse.jgit.lib;version="[5.3.3,5.4.0)", - org.eclipse.jgit.nls;version="[5.3.3,5.4.0)", - org.eclipse.jgit.revplot;version="[5.3.3,5.4.0)", - org.eclipse.jgit.revwalk;version="[5.3.3,5.4.0)", - org.eclipse.jgit.transport;version="[5.3.3,5.4.0)", - org.eclipse.jgit.util;version="[5.3.3,5.4.0)" +Export-Package: org.eclipse.jgit.awtui;version="5.4.1" +Import-Package: org.eclipse.jgit.errors;version="[5.4.1,5.5.0)", + org.eclipse.jgit.lib;version="[5.4.1,5.5.0)", + org.eclipse.jgit.nls;version="[5.4.1,5.5.0)", + org.eclipse.jgit.revplot;version="[5.4.1,5.5.0)", + org.eclipse.jgit.revwalk;version="[5.4.1,5.5.0)", + org.eclipse.jgit.transport;version="[5.4.1,5.5.0)", + org.eclipse.jgit.util;version="[5.4.1,5.5.0)" diff --git a/org.eclipse.jgit.ui/META-INF/SOURCE-MANIFEST.MF b/org.eclipse.jgit.ui/META-INF/SOURCE-MANIFEST.MF new file mode 100644 index 0000000000..2fdfc4ef32 --- /dev/null +++ b/org.eclipse.jgit.ui/META-INF/SOURCE-MANIFEST.MF @@ -0,0 +1,7 @@ +Manifest-Version: 1.0 +Bundle-ManifestVersion: 2 +Bundle-Name: org.eclipse.jgit.ui - Sources +Bundle-SymbolicName: org.eclipse.jgit.ui.source +Bundle-Vendor: Eclipse.org - JGit +Bundle-Version: 5.4.1.qualifier +Eclipse-SourceBundle: org.eclipse.jgit.ui;version="5.4.1.qualifier";roots="." diff --git a/org.eclipse.jgit.ui/pom.xml b/org.eclipse.jgit.ui/pom.xml index 792ba4306e..990dfe4700 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.3.3-SNAPSHOT</version> + <version>5.4.1-SNAPSHOT</version> </parent> <artifactId>org.eclipse.jgit.ui</artifactId> @@ -64,6 +64,7 @@ <properties> <translate-qualifier/> + <source-bundle-manifest>${project.build.directory}/META-INF/SOURCE-MANIFEST.MF</source-bundle-manifest> </properties> <dependencies> @@ -92,6 +93,48 @@ <plugins> <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-antrun-plugin</artifactId> + <executions> + <execution> + <id>translate-source-qualifier</id> + <phase>generate-resources</phase> + <configuration> + <target> + <copy file="META-INF/SOURCE-MANIFEST.MF" tofile="${source-bundle-manifest}" overwrite="true"/> + <replace file="${source-bundle-manifest}"> + <replacefilter token=".qualifier" value=".${maven.build.timestamp}"/> + </replace> + </target> + </configuration> + <goals> + <goal>run</goal> + </goals> + </execution> + </executions> + </plugin> + + <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-source-plugin</artifactId> + <inherited>true</inherited> + <executions> + <execution> + <id>attach-sources</id> + <phase>process-classes</phase> + <goals> + <goal>jar</goal> + </goals> + <configuration> + <archive> + <manifestFile>${source-bundle-manifest}</manifestFile> + </archive> + </configuration> + </execution> + </executions> + </plugin> + + <plugin> <artifactId>maven-jar-plugin</artifactId> <configuration> <archive> diff --git a/org.eclipse.jgit.ui/src/org/eclipse/jgit/awtui/CommitGraphPane.java b/org.eclipse.jgit.ui/src/org/eclipse/jgit/awtui/CommitGraphPane.java index 943a3256fb..b898cafca0 100644 --- a/org.eclipse.jgit.ui/src/org/eclipse/jgit/awtui/CommitGraphPane.java +++ b/org.eclipse.jgit.ui/src/org/eclipse/jgit/awtui/CommitGraphPane.java @@ -64,6 +64,7 @@ import org.eclipse.jgit.awtui.SwingCommitList.SwingLane; import org.eclipse.jgit.lib.PersonIdent; import org.eclipse.jgit.revplot.PlotCommit; import org.eclipse.jgit.revplot.PlotCommitList; +import org.eclipse.jgit.util.References; /** * Draws a commit graph in a JTable. @@ -176,7 +177,7 @@ public class CommitGraphPane extends JTable { } PersonIdent authorFor(PlotCommit<SwingLane> c) { - if (c != lastCommit) { + if (!References.isSameObject(c, lastCommit)) { lastCommit = c; lastAuthor = c.getAuthorIdent(); } diff --git a/org.eclipse.jgit/.settings/.api_filters b/org.eclipse.jgit/.settings/.api_filters index bb37dd8c8a..5ca7c0f664 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.3.3"/> - <message_argument value="5.3.0"/> + <message_argument value="5.4.1"/> + <message_argument value="5.4.0"/> </message_arguments> </filter> </resource> @@ -28,20 +28,6 @@ </message_arguments> </filter> </resource> - <resource path="src/org/eclipse/jgit/errors/PackInvalidException.java" type="org.eclipse.jgit.errors.PackInvalidException"> - <filter id="1142947843"> - <message_arguments> - <message_argument value="4.5.7"/> - <message_argument value="PackInvalidException(File, Throwable)"/> - </message_arguments> - </filter> - <filter id="1142947843"> - <message_arguments> - <message_argument value="4.5.7"/> - <message_argument value="PackInvalidException(String, Throwable)"/> - </message_arguments> - </filter> - </resource> <resource path="src/org/eclipse/jgit/lib/ConfigConstants.java" type="org.eclipse.jgit.lib.ConfigConstants"> <filter id="1142947843"> <message_arguments> @@ -62,62 +48,6 @@ </message_arguments> </filter> </resource> - <resource path="src/org/eclipse/jgit/storage/pack/PackConfig.java" type="org.eclipse.jgit.storage.pack.PackConfig"> - <filter id="336658481"> - <message_arguments> - <message_argument value="org.eclipse.jgit.storage.pack.PackConfig"/> - <message_argument value="DEFAULT_MINSIZE_PREVENT_RACY_PACK"/> - </message_arguments> - </filter> - <filter id="336658481"> - <message_arguments> - <message_argument value="org.eclipse.jgit.storage.pack.PackConfig"/> - <message_argument value="DEFAULT_WAIT_PREVENT_RACY_PACK"/> - </message_arguments> - </filter> - <filter id="1142947843"> - <message_arguments> - <message_argument value="5.1.8"/> - <message_argument value="DEFAULT_MINSIZE_PREVENT_RACY_PACK"/> - </message_arguments> - </filter> - <filter id="1142947843"> - <message_arguments> - <message_argument value="5.1.8"/> - <message_argument value="DEFAULT_WAIT_PREVENT_RACY_PACK"/> - </message_arguments> - </filter> - <filter id="1142947843"> - <message_arguments> - <message_argument value="5.1.8"/> - <message_argument value="doWaitPreventRacyPack(long)"/> - </message_arguments> - </filter> - <filter id="1142947843"> - <message_arguments> - <message_argument value="5.1.8"/> - <message_argument value="getMinSizePreventRacyPack()"/> - </message_arguments> - </filter> - <filter id="1142947843"> - <message_arguments> - <message_argument value="5.1.8"/> - <message_argument value="isWaitPreventRacyPack()"/> - </message_arguments> - </filter> - <filter id="1142947843"> - <message_arguments> - <message_argument value="5.1.8"/> - <message_argument value="setMinSizePreventRacyPack(long)"/> - </message_arguments> - </filter> - <filter id="1142947843"> - <message_arguments> - <message_argument value="5.1.8"/> - <message_argument value="setWaitPreventRacyPack(boolean)"/> - </message_arguments> - </filter> - </resource> <resource path="src/org/eclipse/jgit/treewalk/WorkingTreeIterator.java" type="org.eclipse.jgit.treewalk.WorkingTreeIterator"> <filter id="1142947843"> <message_arguments> @@ -141,6 +71,12 @@ </filter> </resource> <resource path="src/org/eclipse/jgit/util/FS.java" type="org.eclipse.jgit.util.FS"> + <filter id="338792546"> + <message_arguments> + <message_argument value="org.eclipse.jgit.util.FS"/> + <message_argument value="getFsTimerResolution(Path)"/> + </message_arguments> + </filter> <filter id="1142947843"> <message_arguments> <message_argument value="5.1.9"/> @@ -188,14 +124,6 @@ </message_arguments> </filter> </resource> - <resource path="src/org/eclipse/jgit/util/FileUtils.java" type="org.eclipse.jgit.util.FileUtils"> - <filter id="1142947843"> - <message_arguments> - <message_argument value="5.1.8"/> - <message_argument value="touch(Path)"/> - </message_arguments> - </filter> - </resource> <resource path="src/org/eclipse/jgit/util/SimpleLruCache.java" type="org.eclipse.jgit.util.SimpleLruCache"> <filter id="1109393411"> <message_arguments> diff --git a/org.eclipse.jgit/META-INF/MANIFEST.MF b/org.eclipse.jgit/META-INF/MANIFEST.MF index d4226925bd..493cab4d2e 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.3.3.qualifier +Bundle-Version: 5.4.1.qualifier Bundle-Localization: plugin Bundle-Vendor: %provider_name Bundle-ActivationPolicy: lazy -Export-Package: org.eclipse.jgit.annotations;version="5.3.3", - org.eclipse.jgit.api;version="5.3.3"; +Export-Package: org.eclipse.jgit.annotations;version="5.4.1", + org.eclipse.jgit.api;version="5.4.1"; uses:="org.eclipse.jgit.revwalk, org.eclipse.jgit.treewalk.filter, org.eclipse.jgit.diff, @@ -22,53 +22,53 @@ Export-Package: org.eclipse.jgit.annotations;version="5.3.3", org.eclipse.jgit.submodule, org.eclipse.jgit.transport, org.eclipse.jgit.merge", - org.eclipse.jgit.api.errors;version="5.3.3";uses:="org.eclipse.jgit.lib,org.eclipse.jgit.errors", - org.eclipse.jgit.attributes;version="5.3.3", - org.eclipse.jgit.blame;version="5.3.3"; + org.eclipse.jgit.api.errors;version="5.4.1";uses:="org.eclipse.jgit.lib,org.eclipse.jgit.errors", + org.eclipse.jgit.attributes;version="5.4.1", + org.eclipse.jgit.blame;version="5.4.1"; uses:="org.eclipse.jgit.lib, org.eclipse.jgit.revwalk, org.eclipse.jgit.treewalk.filter, org.eclipse.jgit.diff", - org.eclipse.jgit.diff;version="5.3.3"; + org.eclipse.jgit.diff;version="5.4.1"; 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.3.3"; + org.eclipse.jgit.dircache;version="5.4.1"; 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.3.3"; + org.eclipse.jgit.errors;version="5.4.1"; 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.3.3";uses:="org.eclipse.jgit.lib", - org.eclipse.jgit.fnmatch;version="5.3.3", - org.eclipse.jgit.gitrepo;version="5.3.3"; + org.eclipse.jgit.events;version="5.4.1";uses:="org.eclipse.jgit.lib", + org.eclipse.jgit.fnmatch;version="5.4.1", + org.eclipse.jgit.gitrepo;version="5.4.1"; 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.3.3";x-internal:=true, - org.eclipse.jgit.hooks;version="5.3.3";uses:="org.eclipse.jgit.lib", - org.eclipse.jgit.ignore;version="5.3.3", - org.eclipse.jgit.ignore.internal;version="5.3.3";x-friends:="org.eclipse.jgit.test", - org.eclipse.jgit.internal;version="5.3.3";x-friends:="org.eclipse.jgit.test,org.eclipse.jgit.http.test", - org.eclipse.jgit.internal.fsck;version="5.3.3";x-friends:="org.eclipse.jgit.test", - org.eclipse.jgit.internal.ketch;version="5.3.3";x-friends:="org.eclipse.jgit.junit,org.eclipse.jgit.test,org.eclipse.jgit.pgm", - org.eclipse.jgit.internal.revwalk;version="5.3.3";x-internal:=true, - org.eclipse.jgit.internal.storage.dfs;version="5.3.3"; + org.eclipse.jgit.gitrepo.internal;version="5.4.1";x-internal:=true, + org.eclipse.jgit.hooks;version="5.4.1";uses:="org.eclipse.jgit.lib", + org.eclipse.jgit.ignore;version="5.4.1", + org.eclipse.jgit.ignore.internal;version="5.4.1";x-friends:="org.eclipse.jgit.test", + org.eclipse.jgit.internal;version="5.4.1";x-friends:="org.eclipse.jgit.test,org.eclipse.jgit.http.test", + org.eclipse.jgit.internal.fsck;version="5.4.1";x-friends:="org.eclipse.jgit.test", + org.eclipse.jgit.internal.ketch;version="5.4.1";x-friends:="org.eclipse.jgit.junit,org.eclipse.jgit.test,org.eclipse.jgit.pgm", + org.eclipse.jgit.internal.revwalk;version="5.4.1";x-internal:=true, + org.eclipse.jgit.internal.storage.dfs;version="5.4.1"; 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.3.3"; + org.eclipse.jgit.internal.storage.file;version="5.4.1"; x-friends:="org.eclipse.jgit.test, org.eclipse.jgit.junit, org.eclipse.jgit.junit.http, @@ -77,18 +77,19 @@ Export-Package: org.eclipse.jgit.annotations;version="5.3.3", org.eclipse.jgit.pgm, org.eclipse.jgit.pgm.test, org.eclipse.jgit.ssh.apache", - org.eclipse.jgit.internal.storage.io;version="5.3.3";x-friends:="org.eclipse.jgit.junit,org.eclipse.jgit.test,org.eclipse.jgit.pgm", - org.eclipse.jgit.internal.storage.pack;version="5.3.3";x-friends:="org.eclipse.jgit.junit,org.eclipse.jgit.test,org.eclipse.jgit.pgm", - org.eclipse.jgit.internal.storage.reftable;version="5.3.3"; + org.eclipse.jgit.internal.storage.io;version="5.4.1";x-friends:="org.eclipse.jgit.junit,org.eclipse.jgit.test,org.eclipse.jgit.pgm", + org.eclipse.jgit.internal.storage.pack;version="5.4.1";x-friends:="org.eclipse.jgit.junit,org.eclipse.jgit.test,org.eclipse.jgit.pgm", + org.eclipse.jgit.internal.storage.reftable;version="5.4.1"; 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.3.3";x-friends:="org.eclipse.jgit.junit,org.eclipse.jgit.test,org.eclipse.jgit.pgm", - org.eclipse.jgit.internal.submodule;version="5.3.3";x-internal:=true, - org.eclipse.jgit.internal.transport.parser;version="5.3.3";x-friends:="org.eclipse.jgit.http.server,org.eclipse.jgit.test", - org.eclipse.jgit.internal.transport.ssh;version="5.3.3";x-friends:="org.eclipse.jgit.ssh.apache", - org.eclipse.jgit.lib;version="5.3.3"; + org.eclipse.jgit.internal.storage.reftree;version="5.4.1";x-friends:="org.eclipse.jgit.junit,org.eclipse.jgit.test,org.eclipse.jgit.pgm", + org.eclipse.jgit.internal.submodule;version="5.4.1";x-internal:=true, + org.eclipse.jgit.internal.transport.http;version="5.4.1";x-friends:="org.eclipse.jgit.test", + org.eclipse.jgit.internal.transport.parser;version="5.4.1";x-friends:="org.eclipse.jgit.http.server,org.eclipse.jgit.test", + org.eclipse.jgit.internal.transport.ssh;version="5.4.1";x-friends:="org.eclipse.jgit.ssh.apache", + org.eclipse.jgit.lib;version="5.4.1"; uses:="org.eclipse.jgit.revwalk, org.eclipse.jgit.treewalk.filter, org.eclipse.jgit.util, @@ -98,33 +99,33 @@ Export-Package: org.eclipse.jgit.annotations;version="5.3.3", org.eclipse.jgit.treewalk, org.eclipse.jgit.transport, org.eclipse.jgit.submodule", - org.eclipse.jgit.lib.internal;version="5.3.3";x-internal:=true, - org.eclipse.jgit.merge;version="5.3.3"; + org.eclipse.jgit.lib.internal;version="5.4.1";x-internal:=true, + org.eclipse.jgit.merge;version="5.4.1"; 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.3.3", - org.eclipse.jgit.notes;version="5.3.3"; + org.eclipse.jgit.nls;version="5.4.1", + org.eclipse.jgit.notes;version="5.4.1"; uses:="org.eclipse.jgit.lib, org.eclipse.jgit.treewalk, org.eclipse.jgit.revwalk, org.eclipse.jgit.merge", - org.eclipse.jgit.patch;version="5.3.3";uses:="org.eclipse.jgit.lib,org.eclipse.jgit.diff", - org.eclipse.jgit.revplot;version="5.3.3";uses:="org.eclipse.jgit.lib,org.eclipse.jgit.revwalk", - org.eclipse.jgit.revwalk;version="5.3.3"; + org.eclipse.jgit.patch;version="5.4.1";uses:="org.eclipse.jgit.lib,org.eclipse.jgit.diff", + org.eclipse.jgit.revplot;version="5.4.1";uses:="org.eclipse.jgit.lib,org.eclipse.jgit.revwalk", + org.eclipse.jgit.revwalk;version="5.4.1"; 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.3.3";uses:="org.eclipse.jgit.revwalk,org.eclipse.jgit.lib,org.eclipse.jgit.util", - org.eclipse.jgit.storage.file;version="5.3.3";uses:="org.eclipse.jgit.lib,org.eclipse.jgit.util", - org.eclipse.jgit.storage.pack;version="5.3.3";uses:="org.eclipse.jgit.lib", - org.eclipse.jgit.submodule;version="5.3.3";uses:="org.eclipse.jgit.lib,org.eclipse.jgit.treewalk.filter,org.eclipse.jgit.treewalk", - org.eclipse.jgit.transport;version="5.3.3"; + org.eclipse.jgit.revwalk.filter;version="5.4.1";uses:="org.eclipse.jgit.revwalk,org.eclipse.jgit.lib,org.eclipse.jgit.util", + org.eclipse.jgit.storage.file;version="5.4.1";uses:="org.eclipse.jgit.lib,org.eclipse.jgit.util", + org.eclipse.jgit.storage.pack;version="5.4.1";uses:="org.eclipse.jgit.lib", + org.eclipse.jgit.submodule;version="5.4.1";uses:="org.eclipse.jgit.lib,org.eclipse.jgit.treewalk.filter,org.eclipse.jgit.treewalk", + org.eclipse.jgit.transport;version="5.4.1"; uses:="org.eclipse.jgit.transport.resolver, org.eclipse.jgit.revwalk, org.eclipse.jgit.internal.storage.pack, @@ -137,39 +138,40 @@ Export-Package: org.eclipse.jgit.annotations;version="5.3.3", org.eclipse.jgit.transport.http, org.eclipse.jgit.errors, org.eclipse.jgit.storage.pack", - org.eclipse.jgit.transport.http;version="5.3.3";uses:="javax.net.ssl", - org.eclipse.jgit.transport.resolver;version="5.3.3";uses:="org.eclipse.jgit.lib,org.eclipse.jgit.transport", - org.eclipse.jgit.treewalk;version="5.3.3"; + org.eclipse.jgit.transport.http;version="5.4.1";uses:="javax.net.ssl", + org.eclipse.jgit.transport.resolver;version="5.4.1";uses:="org.eclipse.jgit.lib,org.eclipse.jgit.transport", + org.eclipse.jgit.treewalk;version="5.4.1"; 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.3.3";uses:="org.eclipse.jgit.treewalk", - org.eclipse.jgit.util;version="5.3.3"; + org.eclipse.jgit.treewalk.filter;version="5.4.1";uses:="org.eclipse.jgit.treewalk", + org.eclipse.jgit.util;version="5.4.1"; 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.3.3", - org.eclipse.jgit.util.sha1;version="5.3.3", - org.eclipse.jgit.util.time;version="5.3.3" + org.eclipse.jgit.util.io;version="5.4.1", + org.eclipse.jgit.util.sha1;version="5.4.1", + org.eclipse.jgit.util.time;version="5.4.1" 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)", javax.crypto, javax.net.ssl, - org.bouncycastle;version="[1.60.0,2.0.0)", - org.bouncycastle.bcpg;version="[1.60.0,2.0.0)", - org.bouncycastle.gpg;version="[1.60.0,2.0.0)", - org.bouncycastle.gpg.keybox;version="[1.60.0,2.0.0)", - org.bouncycastle.jce.provider;version="[1.60.0,2.0.0)", - org.bouncycastle.openpgp;version="[1.60.0,2.0.0)", - org.bouncycastle.openpgp.jcajce;version="[1.60.0,2.0.0)", - org.bouncycastle.openpgp.operator;version="[1.60.0,2.0.0)", - org.bouncycastle.openpgp.operator.jcajce;version="[1.60.0,2.0.0)", - org.bouncycastle.util.encoders;version="[1.60.0,2.0.0)", + org.bouncycastle;version="[1.61.0,2.0.0)", + org.bouncycastle.bcpg;version="[1.61.0,2.0.0)", + org.bouncycastle.gpg;version="[1.61.0,2.0.0)", + org.bouncycastle.gpg.keybox;version="[1.61.0,2.0.0)", + org.bouncycastle.gpg.keybox.jcajce;version="[1.61.0,2.0.0)", + org.bouncycastle.jce.provider;version="[1.61.0,2.0.0)", + org.bouncycastle.openpgp;version="[1.61.0,2.0.0)", + org.bouncycastle.openpgp.jcajce;version="[1.61.0,2.0.0)", + org.bouncycastle.openpgp.operator;version="[1.61.0,2.0.0)", + org.bouncycastle.openpgp.operator.jcajce;version="[1.61.0,2.0.0)", + org.bouncycastle.util.encoders;version="[1.61.0,2.0.0)", org.slf4j;version="[1.7.0,2.0.0)", org.xml.sax, org.xml.sax.helpers diff --git a/org.eclipse.jgit/META-INF/SOURCE-MANIFEST.MF b/org.eclipse.jgit/META-INF/SOURCE-MANIFEST.MF index e3fd47d5c7..e21d20789b 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.3.3.qualifier -Eclipse-SourceBundle: org.eclipse.jgit;version="5.3.3.qualifier";roots="." +Bundle-Version: 5.4.1.qualifier +Eclipse-SourceBundle: org.eclipse.jgit;version="5.4.1.qualifier";roots="." diff --git a/org.eclipse.jgit/pom.xml b/org.eclipse.jgit/pom.xml index 6097858185..1856716494 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.3.3-SNAPSHOT</version> + <version>5.4.1-SNAPSHOT</version> </parent> <artifactId>org.eclipse.jgit</artifactId> @@ -115,7 +115,7 @@ <includes> <include>plugin.properties</include> <include>about.html</include> - <include>META-INF/eclipse.inf</include> + <include>META-INF/eclipse.inf</include> </includes> </resource> <resource> 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 91136620c4..a10d1d7ed9 100644 --- a/org.eclipse.jgit/resources/org/eclipse/jgit/internal/JGitText.properties +++ b/org.eclipse.jgit/resources/org/eclipse/jgit/internal/JGitText.properties @@ -55,7 +55,7 @@ cannotBeCombined=Cannot be combined. cannotBeRecursiveWhenTreesAreIncluded=TreeWalk shouldn't be recursive when tree objects are included. cannotChangeActionOnComment=Cannot change action on comment line in git-rebase-todo file, old action: {0}, new action: {1}. cannotChangeToComment=Cannot change a non-comment line to a comment line. -cannotCheckoutFromUnbornBranch=Cannot checkout from unborn branch +cannotCheckoutFromUnbornBranch=Cannot check out from unborn branch cannotCheckoutOursSwitchBranch=Checking out ours/theirs is only possible when checking out index, not when switching branches. cannotCombineSquashWithNoff=Cannot combine --squash with --no-ff. cannotCombineTreeFilterWithRevFilter=Cannot combine TreeFilter {0} with RevFilter {1}. @@ -141,6 +141,7 @@ configSubsectionContainsNewline=config subsection name contains newline configSubsectionContainsNullByte=config subsection name contains byte 0x00 configValueContainsNullByte=config value contains byte 0x00 configHandleIsStale=config file handle is stale, {0}. retry +configHandleMayBeLocked=config file handle may be locked by other process, {0}. retry connectionFailed=connection failed connectionTimeOut=Connection time out: {0} contextMustBeNonNegative=context must be >= 0 @@ -177,8 +178,8 @@ corruptObjectInvalidType=invalid type corruptObjectInvalidType2=invalid type {0} corruptObjectMalformedHeader=malformed header: {0} corruptObjectMissingEmail=missing email -corruptObjectNameContainsByte=name contains byte 0x%x -corruptObjectNameContainsChar=name contains '%c' +corruptObjectNameContainsByte=byte 0x%x not allowed in Windows filename +corruptObjectNameContainsChar=char '%c' not allowed in Windows filename corruptObjectNameContainsNullByte=name contains byte 0x00 corruptObjectNameContainsSlash=name contains '/' corruptObjectNameDot=invalid name '.' @@ -210,6 +211,10 @@ couldNotDeleteTemporaryIndexFileShouldNotHappen=Could not delete temporary index couldNotGetAdvertisedRef=Remote {0} did not advertise Ref for branch {1}. This Ref may not exist in the remote or may be hidden by permission settings. couldNotGetRepoStatistics=Could not get repository statistics couldNotLockHEAD=Could not lock HEAD +couldNotFindTabInLine=Could not find tab in line {0}. Tab is the mandatory separator for the Netscape Cookie File Format. +couldNotFindSixTabsInLine=Could not find 6 tabs but only {0} in line '{1}'. 7 tab separated columns per line are mandatory for the Netscape Cookie File Format. +couldNotPersistCookies=Could not persist received cookies in file ''{0}'' +couldNotReadCookieFile=Could not read cookie file ''{0}'' couldNotReadIndexInOneGo=Could not read index in one go, only {0} out of {1} read couldNotReadObjectWhileParsingCommit=Could not read an object while parsing commit {0} couldNotRenameDeleteOldIndex=Could not rename delete old index @@ -333,6 +338,7 @@ gpgNoKeyring=neither pubring.kbx nor secring.gpg files found gpgNoKeyInLegacySecring=no matching secret key found in legacy secring.gpg for key or user id: {0} gpgNoPublicKeyFound=Unable to find a public-key with key or user id: {0} gpgNoSecretKeyForPublicKey=unable to find associated secret key for public key: {0} +gpgNotASigningKey=Secret key ({0}) is not suitable for signing gpgKeyInfo=GPG Key (fingerprint {0}) gpgSigningCancelled=Signing was cancelled headRequiredToStash=HEAD required to stash local changes @@ -459,6 +465,7 @@ mismatchOffset=mismatch offset for object {0} mismatchCRC=mismatch CRC for object {0} missingAccesskey=Missing accesskey. missingConfigurationForKey=No value for key {0} found in configuration +missingCookieFile=Configured http.cookieFile ''{0}'' is missing missingCRC=missing CRC for object {0} missingDeltaBase=delta base missingForwardImageInGITBinaryPatch=Missing forward-image in GIT binary patch @@ -632,6 +639,7 @@ rewinding=Rewinding to commit {0} s3ActionDeletion=Deletion s3ActionReading=Reading s3ActionWriting=Writing +searchForReachableBranches=Finding reachable branches saveFileStoreAttributesFailed=Saving measured FileStore attributes to user config failed searchForReuse=Finding sources searchForSizes=Getting sizes diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/api/CherryPickCommand.java b/org.eclipse.jgit/src/org/eclipse/jgit/api/CherryPickCommand.java index 65b72f7d95..c9dd547b49 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/api/CherryPickCommand.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/api/CherryPickCommand.java @@ -157,8 +157,8 @@ public class CherryPickCommand extends GitCommand<CherryPickResult> { merger.setCommitNames(new String[] { "BASE", ourName, //$NON-NLS-1$ cherryPickName }); if (merger.merge(newHead, srcCommit)) { - if (AnyObjectId.equals(newHead.getTree().getId(), merger - .getResultTreeId())) + if (AnyObjectId.isEqual(newHead.getTree().getId(), + merger.getResultTreeId())) continue; DirCacheCheckout dco = new DirCacheCheckout(repo, newHead.getTree(), repo.lockDirCache(), diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/api/CommitCommand.java b/org.eclipse.jgit/src/org/eclipse/jgit/api/CommitCommand.java index 61d51cc913..b55987ead4 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/api/CommitCommand.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/api/CommitCommand.java @@ -282,7 +282,7 @@ public class CommitCommand extends GitCommand<RevCommit> { ru.setRefLogMessage(reflogComment, false); } else { String prefix = amend ? "commit (amend): " //$NON-NLS-1$ - : parents.size() == 0 ? "commit (initial): " //$NON-NLS-1$ + : parents.isEmpty() ? "commit (initial): " //$NON-NLS-1$ : "commit: "; //$NON-NLS-1$ ru.setRefLogMessage(prefix + revCommit.getShortMessage(), false); diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/api/DeleteBranchCommand.java b/org.eclipse.jgit/src/org/eclipse/jgit/api/DeleteBranchCommand.java index 31e7281d64..c3feaeffca 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/api/DeleteBranchCommand.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/api/DeleteBranchCommand.java @@ -46,6 +46,7 @@ package org.eclipse.jgit.api; import java.io.IOException; import java.text.MessageFormat; import java.util.ArrayList; +import java.util.Arrays; import java.util.HashSet; import java.util.List; import java.util.Set; @@ -188,8 +189,7 @@ public class DeleteBranchCommand extends GitCommand<List<String>> { public DeleteBranchCommand setBranchNames(String... branchnames) { checkCallable(); this.branchNames.clear(); - for (String branch : branchnames) - this.branchNames.add(branch); + this.branchNames.addAll(Arrays.asList(branchnames)); return this; } diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/api/DeleteTagCommand.java b/org.eclipse.jgit/src/org/eclipse/jgit/api/DeleteTagCommand.java index 63a090cafc..1970240621 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/api/DeleteTagCommand.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/api/DeleteTagCommand.java @@ -45,6 +45,7 @@ package org.eclipse.jgit.api; import java.io.IOException; import java.text.MessageFormat; import java.util.ArrayList; +import java.util.Arrays; import java.util.HashSet; import java.util.List; import java.util.Set; @@ -135,8 +136,7 @@ public class DeleteTagCommand extends GitCommand<List<String>> { public DeleteTagCommand setTags(String... tags) { checkCallable(); this.tags.clear(); - for (String tagName : tags) - this.tags.add(tagName); + this.tags.addAll(Arrays.asList(tags)); return this; } } diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/api/DescribeCommand.java b/org.eclipse.jgit/src/org/eclipse/jgit/api/DescribeCommand.java index a484742e08..9ad77e65fd 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/api/DescribeCommand.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/api/DescribeCommand.java @@ -63,8 +63,7 @@ import org.eclipse.jgit.api.errors.RefNotFoundException; import org.eclipse.jgit.errors.IncorrectObjectTypeException; import org.eclipse.jgit.errors.InvalidPatternException; import org.eclipse.jgit.errors.MissingObjectException; -import org.eclipse.jgit.ignore.internal.IMatcher; -import org.eclipse.jgit.ignore.internal.PathMatcher; +import org.eclipse.jgit.fnmatch.FileNameMatcher; import org.eclipse.jgit.internal.JGitText; import org.eclipse.jgit.lib.Constants; import org.eclipse.jgit.lib.ObjectId; @@ -102,14 +101,19 @@ public class DescribeCommand extends GitCommand<String> { private boolean longDesc; /** - * Pattern matchers to be applied to tags under consideration + * Pattern matchers to be applied to tags under consideration. */ - private List<IMatcher> matchers = new ArrayList<>(); + private List<FileNameMatcher> matchers = new ArrayList<>(); /** - * Whether to use all tags (incl. lightweight) or not + * Whether to use all tags (incl. lightweight) or not. */ - private boolean useTags = false; + private boolean useTags; + + /** + * Whether to show a uniquely abbreviated commit hash as a fallback or not. + */ + private boolean always; /** * Constructor for DescribeCommand. @@ -197,6 +201,21 @@ public class DescribeCommand extends GitCommand<String> { return this; } + /** + * Always describe the commit by eventually falling back to a uniquely + * abbreviated commit hash if no other name matches. + * + * @param always + * <code>true</code> enables falling back to a uniquely + * abbreviated commit hash + * @return {@code this} + * @since 5.4 + */ + public DescribeCommand setAlways(boolean always) { + this.always = always; + return this; + } + private String longDescription(Ref tag, int depth, ObjectId tip) throws IOException { return String.format( @@ -222,7 +241,7 @@ public class DescribeCommand extends GitCommand<String> { */ public DescribeCommand setMatch(String... patterns) throws InvalidPatternException { for (String p : patterns) { - matchers.add(PathMatcher.createPathMatcher(p, null, false)); + matchers.add(new FileNameMatcher(p, null)); } return this; } @@ -246,18 +265,24 @@ public class DescribeCommand extends GitCommand<String> { }; private Optional<Ref> getBestMatch(List<Ref> tags) { - if (tags == null || tags.size() == 0) { + if (tags == null || tags.isEmpty()) { return Optional.empty(); - } else if (matchers.size() == 0) { + } else if (matchers.isEmpty()) { Collections.sort(tags, TAG_TIE_BREAKER); return Optional.of(tags.get(0)); } else { // Find the first tag that matches in the stream of all tags // filtered by matchers ordered by tie break order Stream<Ref> matchingTags = Stream.empty(); - for (IMatcher matcher : matchers) { + for (FileNameMatcher matcher : matchers) { Stream<Ref> m = tags.stream().filter( - tag -> matcher.matches(tag.getName(), false, false)); + tag -> { + matcher.append( + tag.getName().substring(R_TAGS.length())); + boolean result = matcher.isMatch(); + matcher.reset(); + return result; + }); matchingTags = Stream.of(matchingTags, m).flatMap(i -> i); } return matchingTags.sorted(TAG_TIE_BREAKER).findFirst(); @@ -399,15 +424,12 @@ public class DescribeCommand extends GitCommand<String> { } // if all the nodes are dominated by all the tags, the walk stops - if (candidates.isEmpty()) - return null; + if (candidates.isEmpty()) { + return always ? w.getObjectReader().abbreviate(target).name() : null; + } - Candidate best = Collections.min(candidates, new Comparator<Candidate>() { - @Override - public int compare(Candidate o1, Candidate o2) { - return o1.depth - o2.depth; - } - }); + Candidate best = Collections.min(candidates, + (Candidate o1, Candidate o2) -> o1.depth - o2.depth); return best.describe(target); } catch (IOException e) { diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/api/Git.java b/org.eclipse.jgit/src/org/eclipse/jgit/api/Git.java index 400a7dfe48..835e7b5fd2 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/api/Git.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/api/Git.java @@ -43,6 +43,8 @@ */ package org.eclipse.jgit.api; +import static java.util.Objects.requireNonNull; + import java.io.File; import java.io.IOException; @@ -220,9 +222,7 @@ public class Git implements AutoCloseable { } Git(Repository repo, boolean closeRepo) { - if (repo == null) - throw new NullPointerException(); - this.repo = repo; + this.repo = requireNonNull(repo); this.closeRepo = closeRepo; } diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/api/ListBranchCommand.java b/org.eclipse.jgit/src/org/eclipse/jgit/api/ListBranchCommand.java index 29a51a0f02..e0eafc7533 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/api/ListBranchCommand.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/api/ListBranchCommand.java @@ -53,7 +53,6 @@ import java.text.MessageFormat; import java.util.ArrayList; import java.util.Collection; import java.util.Collections; -import java.util.Comparator; import java.util.List; import org.eclipse.jgit.api.errors.GitAPIException; @@ -134,12 +133,8 @@ public class ListBranchCommand extends GitCommand<List<Ref>> { throw new JGitInternalException(e.getMessage(), e); } - Collections.sort(resultRefs, new Comparator<Ref>() { - @Override - public int compare(Ref o1, Ref o2) { - return o1.getName().compareTo(o2.getName()); - } - }); + Collections.sort(resultRefs, + (Ref o1, Ref o2) -> o1.getName().compareTo(o2.getName())); setCallable(false); return resultRefs; } diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/api/ListTagCommand.java b/org.eclipse.jgit/src/org/eclipse/jgit/api/ListTagCommand.java index 01c1991846..c894d056a0 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/api/ListTagCommand.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/api/ListTagCommand.java @@ -45,7 +45,6 @@ package org.eclipse.jgit.api; import java.io.IOException; import java.util.ArrayList; import java.util.Collections; -import java.util.Comparator; import java.util.List; import org.eclipse.jgit.api.errors.GitAPIException; @@ -87,12 +86,8 @@ public class ListTagCommand extends GitCommand<List<Ref>> { } catch (IOException e) { throw new JGitInternalException(e.getMessage(), e); } - Collections.sort(tags, new Comparator<Ref>() { - @Override - public int compare(Ref o1, Ref o2) { - return o1.getName().compareTo(o2.getName()); - } - }); + Collections.sort(tags, + (Ref o1, Ref o2) -> o1.getName().compareTo(o2.getName())); setCallable(false); return tags; } diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/api/LogCommand.java b/org.eclipse.jgit/src/org/eclipse/jgit/api/LogCommand.java index cf3d35fe89..66de8ae131 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/api/LogCommand.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/api/LogCommand.java @@ -133,7 +133,7 @@ public class LogCommand extends GitCommand<Iterable<RevCommit>> { @Override public Iterable<RevCommit> call() throws GitAPIException, NoHeadException { checkCallable(); - if (pathFilters.size() > 0) + if (!pathFilters.isEmpty()) walk.setTreeFilter(AndTreeFilter.create( PathFilterGroup.create(pathFilters), TreeFilter.ANY_DIFF)); if (skip > -1 && maxCount > -1) @@ -282,13 +282,11 @@ public class LogCommand extends GitCommand<Iterable<RevCommit>> { RevCommit commit = null; try { commit = walk.parseCommit(objectId); - } catch (MissingObjectException e) { - // ignore: the ref points to an object that does not exist; - // it should be ignored as traversal starting point. - } catch (IncorrectObjectTypeException e) { - // ignore: the ref points to an object that is not a commit - // (e.g. a tree or a blob); - // it should be ignored as traversal starting point. + } catch (MissingObjectException | IncorrectObjectTypeException e) { + // ignore as traversal starting point: + // - the ref points to an object that does not exist + // - the ref points to an object that is not a commit (e.g. a + // tree or a blob) } if (commit != null) add(commit); @@ -348,9 +346,7 @@ public class LogCommand extends GitCommand<Iterable<RevCommit>> { } else walk.markUninteresting(walk.lookupCommit(start)); return this; - } catch (MissingObjectException e) { - throw e; - } catch (IncorrectObjectTypeException e) { + } catch (MissingObjectException | IncorrectObjectTypeException e) { throw e; } catch (IOException e) { throw new JGitInternalException(MessageFormat.format( diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/api/PullCommand.java b/org.eclipse.jgit/src/org/eclipse/jgit/api/PullCommand.java index f0ad29db49..bdb2d1bbc5 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/api/PullCommand.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/api/PullCommand.java @@ -60,6 +60,7 @@ import org.eclipse.jgit.api.errors.NoHeadException; import org.eclipse.jgit.api.errors.RefNotAdvertisedException; import org.eclipse.jgit.api.errors.RefNotFoundException; import org.eclipse.jgit.api.errors.WrongRepositoryStateException; +import org.eclipse.jgit.dircache.DirCacheCheckout; import org.eclipse.jgit.internal.JGitText; import org.eclipse.jgit.lib.AnyObjectId; import org.eclipse.jgit.lib.BranchConfig.BranchRebaseMode; @@ -67,12 +68,17 @@ import org.eclipse.jgit.lib.Config; import org.eclipse.jgit.lib.ConfigConstants; import org.eclipse.jgit.lib.Constants; import org.eclipse.jgit.lib.NullProgressMonitor; +import org.eclipse.jgit.lib.ObjectId; import org.eclipse.jgit.lib.ProgressMonitor; import org.eclipse.jgit.lib.Ref; +import org.eclipse.jgit.lib.RefUpdate; +import org.eclipse.jgit.lib.RefUpdate.Result; import org.eclipse.jgit.lib.Repository; import org.eclipse.jgit.lib.RepositoryState; import org.eclipse.jgit.lib.SubmoduleConfig.FetchRecurseSubmodulesMode; import org.eclipse.jgit.merge.MergeStrategy; +import org.eclipse.jgit.revwalk.RevCommit; +import org.eclipse.jgit.revwalk.RevWalk; import org.eclipse.jgit.transport.FetchResult; import org.eclipse.jgit.transport.TagOpt; @@ -339,6 +345,45 @@ public class PullCommand extends TransportCommand<PullCommand, PullResult> { PullResult result; if (pullRebaseMode != BranchRebaseMode.NONE) { + try { + Ref head = repo.exactRef(Constants.HEAD); + if (head == null) { + throw new NoHeadException(JGitText + .get().commitOnRepoWithoutHEADCurrentlyNotSupported); + } + ObjectId headId = head.getObjectId(); + if (headId == null) { + // Pull on an unborn branch: checkout + try (RevWalk revWalk = new RevWalk(repo)) { + RevCommit srcCommit = revWalk + .parseCommit(commitToMerge); + DirCacheCheckout dco = new DirCacheCheckout(repo, + repo.lockDirCache(), srcCommit.getTree()); + dco.setFailOnConflict(true); + dco.setProgressMonitor(monitor); + dco.checkout(); + RefUpdate refUpdate = repo + .updateRef(head.getTarget().getName()); + refUpdate.setNewObjectId(commitToMerge); + refUpdate.setExpectedOldObjectId(null); + refUpdate.setRefLogMessage("initial pull", false); //$NON-NLS-1$ + if (refUpdate.update() != Result.NEW) { + throw new NoHeadException(JGitText + .get().commitOnRepoWithoutHEADCurrentlyNotSupported); + } + monitor.endTask(); + return new PullResult(fetchRes, remote, + RebaseResult.result( + RebaseResult.Status.FAST_FORWARD, + srcCommit)); + } + } + } catch (NoHeadException e) { + throw e; + } catch (IOException e) { + throw new JGitInternalException(JGitText + .get().exceptionCaughtDuringExecutionOfPullCommand, e); + } RebaseCommand rebase = new RebaseCommand(repo); RebaseResult rebaseRes = rebase.setUpstream(commitToMerge) .setUpstreamName(upstreamName).setProgressMonitor(monitor) 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 0e3d000d3a..0dacd4dfbf 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/api/RebaseCommand.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/api/RebaseCommand.java @@ -362,7 +362,7 @@ public class RebaseCommand extends GitCommand<RebaseResult> { List<RebaseTodoLine> steps = repo.readRebaseTodo( rebaseState.getPath(GIT_REBASE_TODO), false); - if (steps.size() == 0) { + if (steps.isEmpty()) { return finishRebase(walk.parseCommit(repo.resolve(Constants.HEAD)), false); } if (isInteractive()) { @@ -490,7 +490,7 @@ public class RebaseCommand extends GitCommand<RebaseResult> { resetSoftToParent(); List<RebaseTodoLine> steps = repo.readRebaseTodo( rebaseState.getPath(GIT_REBASE_TODO), false); - RebaseTodoLine nextStep = steps.size() > 0 ? steps.get(0) : null; + RebaseTodoLine nextStep = steps.isEmpty() ? null : steps.get(0); File messageFixupFile = rebaseState.getFile(MESSAGE_FIXUP); File messageSquashFile = rebaseState.getFile(MESSAGE_SQUASH); if (isSquash && messageFixupFile.exists()) @@ -575,7 +575,7 @@ public class RebaseCommand extends GitCommand<RebaseResult> { ObjectId headId = getHead().getObjectId(); // getHead() checks for null assert headId != null; - if (!AnyObjectId.equals(headId, newParents.get(0))) + if (!AnyObjectId.isEqual(headId, newParents.get(0))) checkoutCommit(headId.getName(), newParents.get(0)); // Use the cherry-pick strategy if all non-first parents did not @@ -1083,7 +1083,7 @@ public class RebaseCommand extends GitCommand<RebaseResult> { repo.writeRebaseTodoFile(rebaseState.getPath(GIT_REBASE_TODO), todoLines, false); - if (poppedLines.size() > 0) { + if (!poppedLines.isEmpty()) { repo.writeRebaseTodoFile(rebaseState.getPath(DONE), poppedLines, true); } @@ -1295,13 +1295,8 @@ public class RebaseCommand extends GitCommand<RebaseResult> { } } return newCommit; - } catch (RefAlreadyExistsException e) { - throw new JGitInternalException(e.getMessage(), e); - } catch (RefNotFoundException e) { - throw new JGitInternalException(e.getMessage(), e); - } catch (InvalidRefNameException e) { - throw new JGitInternalException(e.getMessage(), e); - } catch (CheckoutConflictException e) { + } catch (RefAlreadyExistsException | RefNotFoundException + | InvalidRefNameException | CheckoutConflictException e) { throw new JGitInternalException(e.getMessage(), e); } } diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/api/RevertCommand.java b/org.eclipse.jgit/src/org/eclipse/jgit/api/RevertCommand.java index 46e0df7263..ddd60b6fa2 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/api/RevertCommand.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/api/RevertCommand.java @@ -175,8 +175,8 @@ public class RevertCommand extends GitCommand<RevCommit> { + "This reverts commit " + srcCommit.getId().getName() //$NON-NLS-1$ + ".\n"; //$NON-NLS-1$ if (merger.merge(headCommit, srcParent)) { - if (AnyObjectId.equals(headCommit.getTree().getId(), merger - .getResultTreeId())) + if (AnyObjectId.isEqual(headCommit.getTree().getId(), + merger.getResultTreeId())) continue; DirCacheCheckout dco = new DirCacheCheckout(repo, headCommit.getTree(), repo.lockDirCache(), 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 f92455a96a..8908277725 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/api/SubmoduleAddCommand.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/api/SubmoduleAddCommand.java @@ -238,9 +238,7 @@ public class SubmoduleAddCommand extends modulesConfig.setString(ConfigConstants.CONFIG_SUBMODULE_SECTION, name, ConfigConstants.CONFIG_KEY_URL, uri); modulesConfig.save(); - } catch (IOException e) { - throw new JGitInternalException(e.getMessage(), e); - } catch (ConfigInvalidException e) { + } catch (IOException | ConfigInvalidException 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 5a0528b0f5..ebcea4b1dd 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/api/SubmoduleDeinitCommand.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/api/SubmoduleDeinitCommand.java @@ -173,8 +173,8 @@ public class SubmoduleDeinitCommand } final File[] ls = dir.listFiles(); if (ls != null) { - for (int i = 0; i < ls.length; i++) { - FileUtils.delete(ls[i], RECURSIVE); + for (File f : ls) { + FileUtils.delete(f, RECURSIVE); } } } diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/api/SubmoduleInitCommand.java b/org.eclipse.jgit/src/org/eclipse/jgit/api/SubmoduleInitCommand.java index 2db12b8e25..6fd94052a4 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/api/SubmoduleInitCommand.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/api/SubmoduleInitCommand.java @@ -128,9 +128,7 @@ public class SubmoduleInitCommand extends GitCommand<Collection<String>> { if (!initialized.isEmpty()) config.save(); return initialized; - } catch (IOException e) { - throw new JGitInternalException(e.getMessage(), e); - } catch (ConfigInvalidException e) { + } catch (IOException | ConfigInvalidException e) { throw new JGitInternalException(e.getMessage(), e); } } diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/api/SubmoduleStatusCommand.java b/org.eclipse.jgit/src/org/eclipse/jgit/api/SubmoduleStatusCommand.java index 0606c5b8d4..58e59598ed 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/api/SubmoduleStatusCommand.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/api/SubmoduleStatusCommand.java @@ -108,9 +108,7 @@ public class SubmoduleStatusCommand extends statuses.put(status.getPath(), status); } return statuses; - } catch (IOException e) { - throw new JGitInternalException(e.getMessage(), e); - } catch (ConfigInvalidException e) { + } catch (IOException | ConfigInvalidException e) { throw new JGitInternalException(e.getMessage(), e); } } diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/api/SubmoduleSyncCommand.java b/org.eclipse.jgit/src/org/eclipse/jgit/api/SubmoduleSyncCommand.java index 7cf4b73af0..52393695d9 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/api/SubmoduleSyncCommand.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/api/SubmoduleSyncCommand.java @@ -162,9 +162,7 @@ public class SubmoduleSyncCommand extends GitCommand<Map<String, String>> { if (!synced.isEmpty()) config.save(); return synced; - } catch (IOException e) { - throw new JGitInternalException(e.getMessage(), e); - } catch (ConfigInvalidException e) { + } catch (IOException | ConfigInvalidException e) { throw new JGitInternalException(e.getMessage(), e); } } 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 e7ad0bc40d..1cecff6fb0 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/diff/DiffFormatter.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/diff/DiffFormatter.java @@ -1063,7 +1063,7 @@ public class DiffFormatter implements AutoCloseable { entry.newId = id; break; } - } else if (ids.size() == 0) + } else if (ids.isEmpty()) throw new MissingObjectException(id, Constants.OBJ_BLOB); else throw new AmbiguousObjectException(id, ids); diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/dircache/DirCache.java b/org.eclipse.jgit/src/org/eclipse/jgit/dircache/DirCache.java index 0cfd16b58a..95e1d21434 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/dircache/DirCache.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/dircache/DirCache.java @@ -112,14 +112,12 @@ public class DirCache { private static final byte[] NO_CHECKSUM = {}; - static final Comparator<DirCacheEntry> ENT_CMP = new Comparator<DirCacheEntry>() { - @Override - public int compare(DirCacheEntry o1, DirCacheEntry o2) { - final int cr = cmp(o1, o2); - if (cr != 0) - return cr; - return o1.getStage() - o2.getStage(); - } + static final Comparator<DirCacheEntry> ENT_CMP = (DirCacheEntry o1, + DirCacheEntry o2) -> { + final int cr = cmp(o1, o2); + if (cr != 0) + return cr; + return o1.getStage() - o2.getStage(); }; static int cmp(DirCacheEntry a, DirCacheEntry b) { @@ -254,13 +252,7 @@ public class DirCache { try { c.read(); - } catch (IOException e) { - c.unlock(); - throw e; - } catch (RuntimeException e) { - c.unlock(); - throw e; - } catch (Error e) { + } catch (IOException | RuntimeException | Error e) { c.unlock(); throw e; } @@ -637,13 +629,7 @@ public class DirCache { try (OutputStream o = tmp.getOutputStream(); OutputStream bo = new BufferedOutputStream(o)) { writeTo(liveFile.getParentFile(), bo); - } catch (IOException err) { - tmp.unlock(); - throw err; - } catch (RuntimeException err) { - tmp.unlock(); - throw err; - } catch (Error err) { + } catch (IOException | RuntimeException | Error err) { tmp.unlock(); throw err; } 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 2d6228657a..22090f5b60 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/dircache/DirCacheCheckout.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/dircache/DirCacheCheckout.java @@ -635,7 +635,7 @@ public class DirCacheCheckout { if (!builder.commit()) throw new IndexWriteException(); } - return toBeDeleted.size() == 0; + return toBeDeleted.isEmpty(); } private void checkoutGitlink(String path, DirCacheEntry entry) diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/dircache/DirCacheEditor.java b/org.eclipse.jgit/src/org/eclipse/jgit/dircache/DirCacheEditor.java index 74ba97fb8d..5b8e11f330 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/dircache/DirCacheEditor.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/dircache/DirCacheEditor.java @@ -75,13 +75,11 @@ import org.eclipse.jgit.util.Paths; * @see DirCacheBuilder */ public class DirCacheEditor extends BaseDirCacheEditor { - private static final Comparator<PathEdit> EDIT_CMP = new Comparator<PathEdit>() { - @Override - public int compare(PathEdit o1, PathEdit o2) { - final byte[] a = o1.path; - final byte[] b = o2.path; - return cmp(a, a.length, b, b.length); - } + private static final Comparator<PathEdit> EDIT_CMP = (PathEdit o1, + PathEdit o2) -> { + final byte[] a = o1.path; + final byte[] b = o2.path; + return cmp(a, a.length, b, b.length); }; private final List<PathEdit> edits; 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 d2a59c1310..d4db15ce9b 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/dircache/DirCacheEntry.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/dircache/DirCacheEntry.java @@ -448,9 +448,9 @@ public class DirCacheEntry { */ public void setAssumeValid(boolean assume) { if (assume) - info[infoOffset + P_FLAGS] |= ASSUME_VALID; + info[infoOffset + P_FLAGS] |= (byte) ASSUME_VALID; else - info[infoOffset + P_FLAGS] &= ~ASSUME_VALID; + info[infoOffset + P_FLAGS] &= (byte) ~ASSUME_VALID; } /** @@ -470,9 +470,9 @@ public class DirCacheEntry { */ public void setUpdateNeeded(boolean updateNeeded) { if (updateNeeded) - inCoreFlags |= UPDATE_NEEDED; + inCoreFlags |= (byte) UPDATE_NEEDED; else - inCoreFlags &= ~UPDATE_NEEDED; + inCoreFlags &= (byte) ~UPDATE_NEEDED; } /** 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 11a3474a35..80e1084fe0 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/dircache/DirCacheTree.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/dircache/DirCacheTree.java @@ -81,25 +81,26 @@ public class DirCacheTree { private static final DirCacheTree[] NO_CHILDREN = {}; - private static final Comparator<DirCacheTree> TREE_CMP = new Comparator<DirCacheTree>() { - @Override - public int compare(DirCacheTree o1, DirCacheTree o2) { - final byte[] a = o1.encodedName; - final byte[] b = o2.encodedName; - final int aLen = a.length; - final int bLen = b.length; - int cPos; - for (cPos = 0; cPos < aLen && cPos < bLen; cPos++) { - final int cmp = (a[cPos] & 0xff) - (b[cPos] & 0xff); - if (cmp != 0) - return cmp; + private static final Comparator<DirCacheTree> TREE_CMP = (DirCacheTree o1, + DirCacheTree o2) -> { + final byte[] a = o1.encodedName; + final byte[] b = o2.encodedName; + final int aLen = a.length; + final int bLen = b.length; + int cPos; + for (cPos = 0; cPos < aLen && cPos < bLen; cPos++) { + final int cmp = (a[cPos] & 0xff) - (b[cPos] & 0xff); + if (cmp != 0) { + return cmp; } - if (aLen == bLen) - return 0; - if (aLen < bLen) - return '/' - (b[cPos] & 0xff); - return (a[cPos] & 0xff) - '/'; } + if (aLen == bLen) { + return 0; + } + if (aLen < bLen) { + return '/' - (b[cPos] & 0xff); + } + return (a[cPos] & 0xff) - '/'; }; /** Tree this tree resides in; null if we are the root. */ diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/errors/IncorrectObjectTypeException.java b/org.eclipse.jgit/src/org/eclipse/jgit/errors/IncorrectObjectTypeException.java index 5abd0c347b..15fd803d00 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/errors/IncorrectObjectTypeException.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/errors/IncorrectObjectTypeException.java @@ -63,7 +63,7 @@ public class IncorrectObjectTypeException extends IOException { private static final long serialVersionUID = 1L; /** - * Construct and IncorrectObjectTypeException for the specified object id. + * Construct an IncorrectObjectTypeException for the specified object id. * * Provide the type to make it easier to track down the problem. * @@ -75,7 +75,7 @@ public class IncorrectObjectTypeException extends IOException { } /** - * Construct and IncorrectObjectTypeException for the specified object id. + * Construct an IncorrectObjectTypeException for the specified object id. * * Provide the type to make it easier to track down the problem. * diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/ignore/internal/WildMatcher.java b/org.eclipse.jgit/src/org/eclipse/jgit/ignore/internal/WildMatcher.java index 2ad87dade6..239e2c81d3 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/ignore/internal/WildMatcher.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/ignore/internal/WildMatcher.java @@ -64,7 +64,7 @@ public final class WildMatcher extends AbstractMatcher { public final boolean matches(String path, boolean assumeDirectory, boolean pathMatch) { return !dirOnly || assumeDirectory - || !pathMatch && isSubdirectory(path); + || (!pathMatch && isSubdirectory(path)); } /** {@inheritDoc} */ 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 039a6b2b43..cd50e347ab 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/internal/JGitText.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/internal/JGitText.java @@ -202,6 +202,7 @@ public class JGitText extends TranslationBundle { /***/ public String configSubsectionContainsNullByte; /***/ public String configValueContainsNullByte; /***/ public String configHandleIsStale; + /***/ public String configHandleMayBeLocked; /***/ public String connectionFailed; /***/ public String connectionTimeOut; /***/ public String contextMustBeNonNegative; @@ -269,9 +270,13 @@ public class JGitText extends TranslationBundle { /***/ public String couldNotCheckOutBecauseOfConflicts; /***/ public String couldNotDeleteLockFileShouldNotHappen; /***/ public String couldNotDeleteTemporaryIndexFileShouldNotHappen; + /***/ public String couldNotFindTabInLine; + /***/ public String couldNotFindSixTabsInLine; /***/ public String couldNotGetAdvertisedRef; /***/ public String couldNotGetRepoStatistics; /***/ public String couldNotLockHEAD; + /***/ public String couldNotPersistCookies; + /***/ public String couldNotReadCookieFile; /***/ public String couldNotReadIndexInOneGo; /***/ public String couldNotReadObjectWhileParsingCommit; /***/ public String couldNotRenameDeleteOldIndex; @@ -394,6 +399,7 @@ public class JGitText extends TranslationBundle { /***/ public String gpgNoKeyInLegacySecring; /***/ public String gpgNoPublicKeyFound; /***/ public String gpgNoSecretKeyForPublicKey; + /***/ public String gpgNotASigningKey; /***/ public String gpgKeyInfo; /***/ public String gpgSigningCancelled; /***/ public String headRequiredToStash; @@ -520,6 +526,7 @@ public class JGitText extends TranslationBundle { /***/ public String mismatchCRC; /***/ public String missingAccesskey; /***/ public String missingConfigurationForKey; + /***/ public String missingCookieFile; /***/ public String missingCRC; /***/ public String missingDeltaBase; /***/ public String missingForwardImageInGITBinaryPatch; @@ -694,6 +701,7 @@ public class JGitText extends TranslationBundle { /***/ public String s3ActionReading; /***/ public String s3ActionWriting; /***/ public String saveFileStoreAttributesFailed; + /***/ public String searchForReachableBranches; /***/ public String searchForReuse; /***/ public String searchForSizes; /***/ public String secondsAgo; 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 fa32b267df..c0364acdd1 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 @@ -385,12 +385,7 @@ public abstract class KetchLeader { private void scheduleLeader() { idle = false; - system.getExecutor().execute(new Runnable() { - @Override - public void run() { - runLeader(); - } - }); + system.getExecutor().execute(this::runLeader); } private void runLeader() { diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/internal/ketch/KetchReplica.java b/org.eclipse.jgit/src/org/eclipse/jgit/internal/ketch/KetchReplica.java index a0176d7d2e..0e8377dd02 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/internal/ketch/KetchReplica.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/internal/ketch/KetchReplica.java @@ -345,7 +345,7 @@ public abstract class KetchReplica { } private static boolean equals(@Nullable ObjectId a, LogIndex b) { - return a != null && b != null && AnyObjectId.equals(a, b); + return a != null && b != null && AnyObjectId.isEqual(a, b); } /** @@ -749,7 +749,7 @@ public abstract class KetchReplica { Ref oldRef = remote.remove(name); ObjectId oldId = getId(oldRef); ObjectId newId = tw.getObjectId(0); - if (!AnyObjectId.equals(oldId, newId)) { + if (!AnyObjectId.isEqual(oldId, newId)) { delta.add(new ReceiveCommand(oldId, newId, name)); } } diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/internal/ketch/LagCheck.java b/org.eclipse.jgit/src/org/eclipse/jgit/internal/ketch/LagCheck.java index c09d872f0a..53fd198006 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/internal/ketch/LagCheck.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/internal/ketch/LagCheck.java @@ -106,7 +106,7 @@ class LagCheck implements AutoCloseable { return UNKNOWN; } - if (AnyObjectId.equals(remoteId, ObjectId.zeroId())) { + if (AnyObjectId.isEqual(remoteId, ObjectId.zeroId())) { // Replica does not have the txnAccepted reference. return LAGGING; } 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 6f1f5c5c2c..cd0ded5e38 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 @@ -123,21 +123,18 @@ public class LocalReplica extends KetchReplica { /** {@inheritDoc} */ @Override protected void startPush(ReplicaPushRequest req) { - getSystem().getExecutor().execute(new Runnable() { - @Override - public void run() { - MonotonicClock clk = getSystem().getClock(); - try (Repository git = getLeader().openRepository(); - ProposedTimestamp ts = clk.propose()) { - try { - update(git, req, ts); - req.done(git); - } catch (Throwable err) { - req.setException(git, err); - } - } catch (IOException err) { - req.setException(null, err); + getSystem().getExecutor().execute(() -> { + MonotonicClock clk = getSystem().getClock(); + try (Repository git = getLeader().openRepository(); + ProposedTimestamp ts = clk.propose()) { + try { + update(git, req, ts); + req.done(git); + } catch (Throwable err) { + req.setException(git, err); } + } catch (IOException err) { + req.setException(null, err); } }); } diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/internal/ketch/RemoteGitReplica.java b/org.eclipse.jgit/src/org/eclipse/jgit/internal/ketch/RemoteGitReplica.java index b61274ef4a..4bed575f26 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/internal/ketch/RemoteGitReplica.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/internal/ketch/RemoteGitReplica.java @@ -139,19 +139,16 @@ public class RemoteGitReplica extends KetchReplica { /** {@inheritDoc} */ @Override protected void startPush(ReplicaPushRequest req) { - getSystem().getExecutor().execute(new Runnable() { - @Override - public void run() { - try (Repository git = getLeader().openRepository()) { - try { - push(git, req); - req.done(git); - } catch (Throwable err) { - req.setException(git, err); - } - } catch (IOException err) { - req.setException(null, err); + getSystem().getExecutor().execute(() -> { + try (Repository git = getLeader().openRepository()) { + try { + push(git, req); + req.done(git); + } catch (Throwable err) { + req.setException(git, err); } + } catch (IOException err) { + req.setException(null, err); } }); } @@ -203,7 +200,7 @@ public class RemoteGitReplica extends KetchReplica { private static boolean isExpectedValue(Map<String, Ref> adv, RemoteRefUpdate u) { Ref r = adv.get(u.getRemoteName()); - if (!AnyObjectId.equals(getId(r), u.getExpectedOldObjectId())) { + if (!AnyObjectId.isEqual(getId(r), u.getExpectedOldObjectId())) { ((RemoteCommand) u).cmd.setResult(LOCK_FAILURE); return false; } diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/internal/ketch/StageBuilder.java b/org.eclipse.jgit/src/org/eclipse/jgit/internal/ketch/StageBuilder.java index ae82dced21..815984deb2 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/internal/ketch/StageBuilder.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/internal/ketch/StageBuilder.java @@ -138,7 +138,7 @@ public class StageBuilder { try (RevWalk rw = new RevWalk(git); TreeWalk tw = new TreeWalk(rw.getObjectReader()); ObjectInserter ins = git.newObjectInserter()) { - if (AnyObjectId.equals(oldTree, ObjectId.zeroId())) { + if (AnyObjectId.isEqual(oldTree, ObjectId.zeroId())) { tw.addTree(new EmptyTreeIterator()); } else { tw.addTree(rw.parseTree(oldTree)); diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/dfs/DeltaBaseCache.java b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/dfs/DeltaBaseCache.java index bd4b4d23f4..3b92deeaeb 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/dfs/DeltaBaseCache.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/dfs/DeltaBaseCache.java @@ -180,8 +180,8 @@ final class DeltaBaseCache { int getMemoryUsedByTableForTest() { int r = 0; - for (int i = 0; i < table.length; i++) { - for (Entry e = table[i]; e != null; e = e.tableNext) { + for (Entry t : table) { + for (Entry e = t; e != null; e = e.tableNext) { r += e.data.length; } } diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/dfs/DfsGarbageCollector.java b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/dfs/DfsGarbageCollector.java index ca11fb9265..f10a1d8127 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/dfs/DfsGarbageCollector.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/dfs/DfsGarbageCollector.java @@ -661,7 +661,7 @@ public class DfsGarbageCollector { private int objectsBefore() { int cnt = 0; for (DfsPackFile p : packsBefore) - cnt += p.getPackDescription().getObjectCount(); + cnt += (int) p.getPackDescription().getObjectCount(); return cnt; } 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 127ee6bf11..6f3f2bd8e7 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 @@ -469,12 +469,8 @@ public class DfsPackCompactor { continue SCAN; want.add(new ObjectIdWithOffset(id, ent.getOffset())); } - Collections.sort(want, new Comparator<ObjectIdWithOffset>() { - @Override - public int compare(ObjectIdWithOffset a, ObjectIdWithOffset b) { - return Long.signum(a.offset - b.offset); - } - }); + Collections.sort(want, (ObjectIdWithOffset a, + ObjectIdWithOffset b) -> Long.signum(a.offset - b.offset)); return want; } diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/dfs/DfsPackParser.java b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/dfs/DfsPackParser.java index 3a30d7daf5..e4c37cb4c2 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/dfs/DfsPackParser.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/dfs/DfsPackParser.java @@ -429,10 +429,10 @@ public class DfsPackParser extends PackParser { final byte[] buf = buffer(); int sz = data.length; int len = 0; - buf[len++] = (byte) ((typeCode << 4) | sz & 15); + buf[len++] = (byte) ((typeCode << 4) | (sz & 15)); sz >>>= 4; while (sz > 0) { - buf[len - 1] |= 0x80; + buf[len - 1] |= (byte) 0x80; buf[len++] = (byte) (sz & 0x7f); sz >>>= 7; } 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 d04709f6c2..c75b88f3bd 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 @@ -287,14 +287,12 @@ public class DfsReader extends ObjectReader implements ObjectReuseAsIs { return Collections.emptySet(); } - private static final Comparator<FoundObject<?>> FOUND_OBJECT_SORT = new Comparator<FoundObject<?>>() { - @Override - public int compare(FoundObject<?> a, FoundObject<?> b) { - int cmp = a.packIndex - b.packIndex; - if (cmp == 0) - cmp = Long.signum(a.offset - b.offset); - return cmp; - } + private static final Comparator<FoundObject<?>> FOUND_OBJECT_SORT = ( + FoundObject<?> a, FoundObject<?> b) -> { + int cmp = a.packIndex - b.packIndex; + if (cmp == 0) + cmp = Long.signum(a.offset - b.offset); + return cmp; }; private static class FoundObject<T extends ObjectId> { @@ -565,12 +563,9 @@ public class DfsReader extends ObjectReader implements ObjectReuseAsIs { return new DfsObjectToPack(objectId, type); } - private static final Comparator<DfsObjectToPack> OFFSET_SORT = new Comparator<DfsObjectToPack>() { - @Override - public int compare(DfsObjectToPack a, DfsObjectToPack b) { - return Long.signum(a.getOffset() - b.getOffset()); - } - }; + private static final Comparator<DfsObjectToPack> OFFSET_SORT = ( + DfsObjectToPack a, + DfsObjectToPack b) -> Long.signum(a.getOffset() - b.getOffset()); @Override public void selectObjectRepresentation(PackWriter packer, @@ -757,6 +752,7 @@ public class DfsReader extends ObjectReader implements ObjectReuseAsIs { */ int inflate(DfsPackFile pack, long position, byte[] dstbuf, boolean headerOnly) throws IOException, DataFormatException { + long start = System.nanoTime(); prepareInflater(); pin(pack, position); position += block.setInput(position, inf); @@ -765,6 +761,7 @@ public class DfsReader extends ObjectReader implements ObjectReuseAsIs { dstoff += n; if (inf.finished() || (headerOnly && dstoff == dstbuf.length)) { stats.inflatedBytes += dstoff; + stats.inflationMicros += BlockBasedFile.elapsedMicros(start); return dstoff; } else if (inf.needsInput()) { pin(pack, position); diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/dfs/DfsReaderIoStats.java b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/dfs/DfsReaderIoStats.java index c35801f3b0..d6401a1640 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/dfs/DfsReaderIoStats.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/dfs/DfsReaderIoStats.java @@ -85,6 +85,9 @@ public class DfsReaderIoStats { /** Total number of bytes decompressed. */ long inflatedBytes; + /** Total microseconds spent inflating compressed bytes. */ + long inflationMicros; + Accumulator() { } } @@ -186,4 +189,13 @@ public class DfsReaderIoStats { public long getInflatedBytes() { return stats.inflatedBytes; } + + /** + * Get total microseconds spent inflating compressed bytes. + * + * @return total microseconds inflating compressed bytes. + */ + public long getInflationMicros() { + return stats.inflationMicros; + } } diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/dfs/DfsRefDatabase.java b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/dfs/DfsRefDatabase.java index 8b2a03d4c5..732cd4d1c6 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/dfs/DfsRefDatabase.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/dfs/DfsRefDatabase.java @@ -43,6 +43,7 @@ package org.eclipse.jgit.internal.storage.dfs; +import static org.eclipse.jgit.lib.Ref.UNDEFINED_UPDATE_INDEX; import static org.eclipse.jgit.lib.Ref.Storage.NEW; import java.io.IOException; @@ -175,7 +176,7 @@ public abstract class DfsRefDatabase extends RefDatabase { cachePeeledState(oldLeaf, newLeaf); } - return recreate(ref, newLeaf); + return recreate(ref, newLeaf, hasVersioning()); } Ref doPeel(Ref leaf) throws MissingObjectException, @@ -187,20 +188,26 @@ public abstract class DfsRefDatabase extends RefDatabase { leaf.getStorage(), leaf.getName(), leaf.getObjectId(), - rw.peel(obj).copy()); + rw.peel(obj).copy(), + hasVersioning() ? leaf.getUpdateIndex() + : UNDEFINED_UPDATE_INDEX); } else { return new ObjectIdRef.PeeledNonTag( leaf.getStorage(), leaf.getName(), - leaf.getObjectId()); + leaf.getObjectId(), + hasVersioning() ? leaf.getUpdateIndex() + : UNDEFINED_UPDATE_INDEX); } } } - static Ref recreate(Ref old, Ref leaf) { + static Ref recreate(Ref old, Ref leaf, boolean hasVersioning) { if (old.isSymbolic()) { - Ref dst = recreate(old.getTarget(), leaf); - return new SymbolicRef(old.getName(), dst); + Ref dst = recreate(old.getTarget(), leaf, hasVersioning); + return new SymbolicRef(old.getName(), dst, + hasVersioning ? old.getUpdateIndex() + : UNDEFINED_UPDATE_INDEX); } return leaf; } 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 83394bb92c..6050c15992 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 @@ -47,8 +47,10 @@ import java.io.IOException; import java.util.Arrays; import java.util.ArrayList; import java.util.Collections; +import java.util.HashSet; import java.util.List; import java.util.Map; +import java.util.Set; import java.util.concurrent.locks.ReentrantLock; import org.eclipse.jgit.annotations.Nullable; @@ -277,12 +279,31 @@ public class DfsReftableDatabase extends DfsRefDatabase { /** {@inheritDoc} */ @Override + public Set<Ref> getTipsWithSha1(ObjectId id) throws IOException { + if (!getReftableConfig().isIndexObjects()) { + return super.getTipsWithSha1(id); + } + lock.lock(); + try { + RefCursor cursor = reader().byObjectId(id); + Set<Ref> refs = new HashSet<>(); + while (cursor.next()) { + refs.add(cursor.getRef()); + } + return refs; + } finally { + lock.unlock(); + } + } + + /** {@inheritDoc} */ + @Override public Ref peel(Ref ref) throws IOException { Ref oldLeaf = ref.getLeaf(); if (oldLeaf.isPeeled() || oldLeaf.getObjectId() == null) { return ref; } - return recreate(ref, doPeel(oldLeaf)); + return recreate(ref, doPeel(oldLeaf), hasVersioning()); } @Override @@ -315,6 +336,7 @@ public class DfsReftableDatabase extends DfsRefDatabase { throws IOException { ReceiveCommand cmd = toCommand(oldRef, newRef); try (RevWalk rw = new RevWalk(getRepository())) { + rw.setRetainBody(false); newBatchUpdate().setAllowNonFastForwards(true).addCommand(cmd) .execute(rw, NullProgressMonitor.INSTANCE); } diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/dfs/DfsRepository.java b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/dfs/DfsRepository.java index 5169e929e4..8e5c5a7f75 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/dfs/DfsRepository.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/dfs/DfsRepository.java @@ -126,6 +126,12 @@ public abstract class DfsRepository extends Repository { /** {@inheritDoc} */ @Override + public String getIdentifier() { + return getDescription().getRepositoryName(); + } + + /** {@inheritDoc} */ + @Override public void scanForRepoChanges() throws IOException { getRefDatabase().refresh(); getObjectDatabase().clearCache(); 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 47ac4ec72e..07fd00f149 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 @@ -252,7 +252,7 @@ public class ReftableBatchRefUpdate extends BatchRefUpdate { private static boolean matchOld(ReceiveCommand cmd, @Nullable Ref ref) { if (ref == null) { - return AnyObjectId.equals(ObjectId.zeroId(), cmd.getOldId()) + return AnyObjectId.isEqual(ObjectId.zeroId(), cmd.getOldId()) && cmd.getOldSymref() == null; } else if (ref.isSymbolic()) { return ref.getTarget().getName().equals(cmd.getOldSymref()); @@ -368,7 +368,7 @@ public class ReftableBatchRefUpdate extends BatchRefUpdate { String name = cmd.getRefName(); ObjectId newId = cmd.getNewId(); String newSymref = cmd.getNewSymref(); - if (AnyObjectId.equals(ObjectId.zeroId(), newId) + if (AnyObjectId.isEqual(ObjectId.zeroId(), newId) && newSymref == null) { refs.add(new ObjectIdRef.Unpeeled(NEW, name, null)); continue; 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 356d64b563..4f5f8a613e 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 @@ -62,8 +62,6 @@ import org.eclipse.jgit.api.errors.JGitInternalException; import org.eclipse.jgit.attributes.AttributesNode; import org.eclipse.jgit.attributes.AttributesNodeProvider; import org.eclipse.jgit.errors.ConfigInvalidException; -import org.eclipse.jgit.events.ConfigChangedEvent; -import org.eclipse.jgit.events.ConfigChangedListener; import org.eclipse.jgit.events.IndexChangedEvent; import org.eclipse.jgit.internal.JGitText; import org.eclipse.jgit.internal.storage.file.ObjectDirectory.AlternateHandle; @@ -192,12 +190,7 @@ public class FileRepository extends Repository { getFS()); loadRepoConfig(); - repoConfig.addChangeListener(new ConfigChangedListener() { - @Override - public void onConfigChanged(ConfigChangedEvent event) { - fireEvent(event); - } - }); + repoConfig.addChangeListener(this::fireEvent); final long repositoryFormatVersion = getConfig().getLong( ConfigConstants.CONFIG_CORE_SECTION, null, @@ -361,6 +354,17 @@ public class FileRepository extends Repository { /** {@inheritDoc} */ @Override + public String getIdentifier() { + File directory = getDirectory(); + if (directory != null) { + return directory.getPath(); + } else { + throw new IllegalStateException(); + } + } + + /** {@inheritDoc} */ + @Override public FileBasedConfig getConfig() { try { SystemReader.getInstance().getUserConfig(); diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/FileSnapshot.java b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/FileSnapshot.java index 976f946e5d..8650ebfe29 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/FileSnapshot.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/FileSnapshot.java @@ -413,6 +413,7 @@ public class FileSnapshot { * the other snapshot. * @return true if the two snapshots share the same information. */ + @SuppressWarnings("NonOverridingEquals") public boolean equals(FileSnapshot other) { boolean sizeEq = size == UNKNOWN_SIZE || other.size == UNKNOWN_SIZE || size == other.size; return lastModified.equals(other.lastModified) && sizeEq @@ -490,7 +491,7 @@ public class FileSnapshot { } /** {@inheritDoc} */ - @SuppressWarnings("nls") + @SuppressWarnings({ "nls", "ReferenceEquality" }) @Override public String toString() { if (this == DIRTY) { 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 7400308c86..08bb6cb7fa 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 @@ -244,7 +244,7 @@ public class GC { * If the configuration parameter "gc.pruneexpire" couldn't be * parsed */ - // TODO(ms): in 5.0 change signature and return Future<Collection<PackFile>> + // TODO(ms): change signature and return Future<Collection<PackFile>> @SuppressWarnings("FutureReturnValueIgnored") public Collection<PackFile> gc() throws IOException, ParseException { if (!background) { @@ -281,7 +281,7 @@ public class GC { } return Collections.emptyList(); }; - // TODO(ms): in 5.0 change signature and return the Future + // TODO(ms): change signature and return the Future executor().submit(gcTask); return Collections.emptyList(); } diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/LockFile.java b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/LockFile.java index f7e78b94f7..6af41256d6 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/LockFile.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/LockFile.java @@ -120,12 +120,8 @@ public class LockFile { } /** Filter to skip over active lock files when listing a directory. */ - static final FilenameFilter FILTER = new FilenameFilter() { - @Override - public boolean accept(File dir, String name) { - return !name.endsWith(LOCK_SUFFIX); - } - }; + static final FilenameFilter FILTER = (File dir, + String name) -> !name.endsWith(LOCK_SUFFIX); private final File ref; @@ -248,13 +244,7 @@ public class LockFile { // Don't worry about a file that doesn't exist yet, it // conceptually has no current content to copy. // - } catch (IOException ioe) { - unlock(); - throw ioe; - } catch (RuntimeException ioe) { - unlock(); - throw ioe; - } catch (Error ioe) { + } catch (IOException | RuntimeException | Error ioe) { unlock(); throw ioe; } @@ -308,13 +298,7 @@ public class LockFile { } os.close(); os = null; - } catch (IOException ioe) { - unlock(); - throw ioe; - } catch (RuntimeException ioe) { - unlock(); - throw ioe; - } catch (Error ioe) { + } catch (IOException | RuntimeException | Error ioe) { unlock(); throw ioe; } @@ -362,13 +346,7 @@ public class LockFile { os.getChannel().force(true); out.close(); os = null; - } catch (IOException ioe) { - unlock(); - throw ioe; - } catch (RuntimeException ioe) { - unlock(); - throw ioe; - } catch (Error ioe) { + } catch (IOException | RuntimeException | Error ioe) { unlock(); throw ioe; } diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/ObjectDirectoryPackParser.java b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/ObjectDirectoryPackParser.java index 6e8a15e86d..7d31673566 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/ObjectDirectoryPackParser.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/ObjectDirectoryPackParser.java @@ -353,10 +353,10 @@ public class ObjectDirectoryPackParser extends PackParser { final byte[] buf = buffer(); int sz = data.length; int len = 0; - buf[len++] = (byte) ((typeCode << 4) | sz & 15); + buf[len++] = (byte) ((typeCode << 4) | (sz & 15)); sz >>>= 4; while (sz > 0) { - buf[len - 1] |= 0x80; + buf[len - 1] |= (byte) 0x80; buf[len++] = (byte) (sz & 0x7f); sz >>>= 7; } 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 eff7958748..9941ff3740 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 @@ -45,7 +45,6 @@ package org.eclipse.jgit.internal.storage.file; import java.text.MessageFormat; import java.util.Collections; -import java.util.Comparator; import java.util.Iterator; import java.util.List; import java.util.NoSuchElementException; @@ -133,12 +132,8 @@ public class PackBitmapIndexBuilder extends BasePackBitmapIndex { for (int i = 0; i < entries.size(); i++) { positionEntries.add(new PositionEntry(entries.get(i), i)); } - Collections.sort(entries, new Comparator<ObjectToPack>() { - @Override - public int compare(ObjectToPack a, ObjectToPack b) { - return Long.signum(a.getOffset() - b.getOffset()); - } - }); + Collections.sort(entries, (ObjectToPack a, ObjectToPack b) -> Long + .signum(a.getOffset() - b.getOffset())); for (int i = 0; i < entries.size(); i++) { PositionEntry e = positionEntries.get(entries.get(i)); e.offsetPosition = i; @@ -310,57 +305,55 @@ public class PackBitmapIndexBuilder extends BasePackBitmapIndex { public Iterable<StoredEntry> getCompressedBitmaps() { // Add order is from oldest to newest. The reverse add order is the // output order. - return new Iterable<StoredEntry>() { + return () -> new Iterator<StoredEntry>() { + + private int index = byAddOrder.size() - 1; + @Override - public Iterator<StoredEntry> iterator() { - return new Iterator<StoredEntry>() { - private int index = byAddOrder.size() - 1; + public boolean hasNext() { + return index >= 0; + } - @Override - public boolean hasNext() { - return index >= 0; + @Override + public StoredEntry next() { + if (!hasNext()) { + throw new NoSuchElementException(); + } + StoredBitmap item = byAddOrder.get(index); + int bestXorOffset = 0; + EWAHCompressedBitmap bestBitmap = item.getBitmap(); + + // Attempt to compress the bitmap with an XOR of the + // previously written entries. + for (int i = 1; i <= MAX_XOR_OFFSET_SEARCH; i++) { + int curr = i + index; + if (curr >= byAddOrder.size()) { + break; } - @Override - public StoredEntry next() { - if (!hasNext()) - throw new NoSuchElementException(); - StoredBitmap item = byAddOrder.get(index); - int bestXorOffset = 0; - EWAHCompressedBitmap bestBitmap = item.getBitmap(); - - // Attempt to compress the bitmap with an XOR of the - // previously written entries. - for (int i = 1; i <= MAX_XOR_OFFSET_SEARCH; i++) { - int curr = i + index; - if (curr >= byAddOrder.size()) - break; - - StoredBitmap other = byAddOrder.get(curr); - EWAHCompressedBitmap bitmap = other.getBitmap() - .xor(item.getBitmap()); - - if (bitmap.sizeInBytes() - < bestBitmap.sizeInBytes()) { - bestBitmap = bitmap; - bestXorOffset = i; - } - } - index--; - - PositionEntry entry = positionEntries.get(item); - if (entry == null) - throw new IllegalStateException(); - bestBitmap.trim(); - return new StoredEntry(entry.namePosition, bestBitmap, - bestXorOffset, item.getFlags()); - } + StoredBitmap other = byAddOrder.get(curr); + EWAHCompressedBitmap bitmap = other.getBitmap() + .xor(item.getBitmap()); - @Override - public void remove() { - throw new UnsupportedOperationException(); + if (bitmap.sizeInBytes() < bestBitmap.sizeInBytes()) { + bestBitmap = bitmap; + bestXorOffset = i; } - }; + } + index--; + + PositionEntry entry = positionEntries.get(item); + if (entry == null) { + throw new IllegalStateException(); + } + bestBitmap.trim(); + return new StoredEntry(entry.namePosition, bestBitmap, + bestXorOffset, item.getFlags()); + } + + @Override + public void remove() { + throw new UnsupportedOperationException(); } }; } 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 a4729bba48..e5cea6c010 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 @@ -745,7 +745,7 @@ public class RefDirectory extends RefDatabase { for (LockFile ol : heldLocks.values()) { ol.requireLock(); } - if (refs.size() == 0) { + if (refs.isEmpty()) { return null; } FS fs = parent.getFS(); @@ -1128,9 +1128,11 @@ public class RefDirectory extends RefDatabase { // check whether the found new ref is the an additional ref. These refs // should not go into looseRefs - for (int i = 0; i < additionalRefsNames.length; i++) - if (name.equals(additionalRefsNames[i])) + for (String additionalRefsName : additionalRefsNames) { + if (name.equals(additionalRefsName)) { return n; + } + } if (looseRefs.compareAndSet(curList, curList.add(idx, n))) modCnt.incrementAndGet(); diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/UnpackedObject.java b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/UnpackedObject.java index cf474afbbe..79f1307578 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/UnpackedObject.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/UnpackedObject.java @@ -295,7 +295,7 @@ public class UnpackedObject { * can always correctly determine the buffer format. */ final int fb = hdr[0] & 0xff; - return (fb & 0x8f) == 0x08 && (((fb << 8) | hdr[1] & 0xff) % 31) == 0; + return (fb & 0x8f) == 0x08 && (((fb << 8) | (hdr[1] & 0xff)) % 31) == 0; } static InputStream inflate(final InputStream in, final long size, diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/UnpackedObjectCache.java b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/UnpackedObjectCache.java index 967754a627..ea0d269053 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/UnpackedObjectCache.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/UnpackedObjectCache.java @@ -112,7 +112,7 @@ class UnpackedObjectCache { if (obj == null) break; - if (AnyObjectId.equals(obj, toFind)) + if (AnyObjectId.isEqual(obj, toFind)) return true; if (++i == ids.length()) @@ -132,7 +132,7 @@ class UnpackedObjectCache { continue; } - if (AnyObjectId.equals(obj, toAdd)) + if (AnyObjectId.isEqual(obj, toAdd)) return true; if (++i == ids.length()) diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/WindowCache.java b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/WindowCache.java index e8fac514be..da7250d141 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/WindowCache.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/WindowCache.java @@ -298,13 +298,7 @@ public class WindowCache { if (mmap) return pack.mmap(offset, windowSize); return pack.read(offset, windowSize); - } catch (IOException e) { - close(pack); - throw e; - } catch (RuntimeException e) { - close(pack); - throw e; - } catch (Error e) { + } catch (IOException | RuntimeException | Error e) { close(pack); throw e; } diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/pack/BinaryDelta.java b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/pack/BinaryDelta.java index c7e5ad6232..5f69d0a884 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/pack/BinaryDelta.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/pack/BinaryDelta.java @@ -142,7 +142,7 @@ public class BinaryDelta { int c, shift = 0; do { c = delta[deltaPtr++] & 0xff; - baseLen |= ((long) (c & 0x7f)) << shift; + baseLen |= (c & 0x7f) << shift; shift += 7; } while ((c & 0x80) != 0); if (base.length != baseLen) @@ -155,7 +155,7 @@ public class BinaryDelta { shift = 0; do { c = delta[deltaPtr++] & 0xff; - resLen |= ((long) (c & 0x7f)) << shift; + resLen |= (c & 0x7f) << shift; shift += 7; } while ((c & 0x80) != 0); diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/pack/DeltaTask.java b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/pack/DeltaTask.java index 0347644324..a211d164c4 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/pack/DeltaTask.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/pack/DeltaTask.java @@ -46,7 +46,6 @@ package org.eclipse.jgit.internal.storage.pack; import java.io.IOException; import java.util.ArrayList; import java.util.Collections; -import java.util.Comparator; import java.util.Iterator; import java.util.LinkedList; import java.util.List; @@ -212,12 +211,8 @@ final class DeltaTask implements Callable<Object> { } // Sort by starting index to identify gaps later. - Collections.sort(topPaths, new Comparator<WeightedPath>() { - @Override - public int compare(WeightedPath a, WeightedPath b) { - return a.slice.beginIndex - b.slice.beginIndex; - } - }); + Collections.sort(topPaths, (WeightedPath a, + WeightedPath b) -> a.slice.beginIndex - b.slice.beginIndex); bytesPerUnit = 1; while (MAX_METER <= (totalWeight / bytesPerUnit)) { diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/pack/DeltaWindow.java b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/pack/DeltaWindow.java index a047534fbf..d152a392f0 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/pack/DeltaWindow.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/pack/DeltaWindow.java @@ -365,9 +365,7 @@ final class DeltaWindow { resObj.setCachedDelta(deltaCache.cache(zbuf, len, deltaLen)); resObj.setCachedSize(deltaLen); - } catch (IOException err) { - deltaCache.credit(deltaLen); - } catch (OutOfMemoryError err) { + } catch (IOException | OutOfMemoryError err) { deltaCache.credit(deltaLen); } } 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 1e3d74ab57..6506789218 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 @@ -44,6 +44,7 @@ package org.eclipse.jgit.internal.storage.pack; +import static java.util.Objects.requireNonNull; import static org.eclipse.jgit.internal.storage.pack.StoredObjectRepresentation.PACK_DELTA; import static org.eclipse.jgit.internal.storage.pack.StoredObjectRepresentation.PACK_WHOLE; import static org.eclipse.jgit.lib.Constants.OBJECT_ID_LENGTH; @@ -61,7 +62,7 @@ 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.Iterator; import java.util.List; @@ -119,6 +120,7 @@ import org.eclipse.jgit.revwalk.RevTag; import org.eclipse.jgit.revwalk.RevTree; import org.eclipse.jgit.storage.pack.PackConfig; import org.eclipse.jgit.storage.pack.PackStatistics; +import org.eclipse.jgit.transport.FilterSpec; import org.eclipse.jgit.transport.ObjectCountCallback; import org.eclipse.jgit.transport.WriteAbortedException; import org.eclipse.jgit.util.BlockList; @@ -303,7 +305,7 @@ public class PackWriter implements AutoCloseable { private ObjectCountCallback callback; - private long filterBlobLimit = -1; + private FilterSpec filterSpec = FilterSpec.NO_FILTER; /** * Create writer for specified repository. @@ -641,10 +643,11 @@ public class PackWriter implements AutoCloseable { } /** - * @param bytes exclude blobs of size greater than this + * @param filter the filter which indicates what and what not this writer + * should include */ - public void setFilterBlobLimit(long bytes) { - filterBlobLimit = bytes; + public void setFilterSpec(@NonNull FilterSpec filter) { + filterSpec = requireNonNull(filter); } /** @@ -870,6 +873,37 @@ public class PackWriter implements AutoCloseable { } /** + * A visitation policy which uses the depth at which the object is seen to + * decide if re-traversal is necessary. In particular, if the object has + * already been visited at this depth or shallower, it is not necessary to + * re-visit at this depth. + */ + private static class DepthAwareVisitationPolicy + implements ObjectWalk.VisitationPolicy { + private final Map<ObjectId, Integer> lowestDepthVisited = new HashMap<>(); + + private final ObjectWalk walk; + + DepthAwareVisitationPolicy(ObjectWalk walk) { + this.walk = requireNonNull(walk); + } + + @Override + public boolean shouldVisit(RevObject o) { + Integer lastDepth = lowestDepthVisited.get(o); + if (lastDepth == null) { + return true; + } + return walk.getTreeDepth() < lastDepth.intValue(); + } + + @Override + public void visited(RevObject o) { + lowestDepthVisited.put(o, Integer.valueOf(walk.getTreeDepth())); + } + } + + /** * Prepare the list of objects to be written to the pack stream. * <p> * Basing on these 2 sets, another set of objects to put in a pack file is @@ -910,6 +944,9 @@ public class PackWriter implements AutoCloseable { if (shallowPack && !(walk instanceof DepthWalk.ObjectWalk)) throw new IllegalArgumentException( JGitText.get().shallowPacksRequireDepthWalk); + if (filterSpec.getTreeDepthLimit() >= 0) { + walk.setVisitationPolicy(new DepthAwareVisitationPolicy(walk)); + } findObjectsToPack(countingMonitor, walk, interestingObjects, uninterestingObjects, noBitmaps); } @@ -1380,32 +1417,33 @@ public class PackWriter implements AutoCloseable { // applies "Linus' Law" which states that newer files tend to be the // bigger ones, because source files grow and hardly ever shrink. // - Arrays.sort(list, 0, cnt, new Comparator<ObjectToPack>() { - @Override - public int compare(ObjectToPack a, ObjectToPack b) { - int cmp = (a.isDoNotDelta() ? 1 : 0) - - (b.isDoNotDelta() ? 1 : 0); - if (cmp != 0) - return cmp; - - cmp = a.getType() - b.getType(); - if (cmp != 0) - return cmp; - - cmp = (a.getPathHash() >>> 1) - (b.getPathHash() >>> 1); - if (cmp != 0) - return cmp; - - cmp = (a.getPathHash() & 1) - (b.getPathHash() & 1); - if (cmp != 0) - return cmp; - - cmp = (a.isEdge() ? 0 : 1) - (b.isEdge() ? 0 : 1); - if (cmp != 0) - return cmp; - - return b.getWeight() - a.getWeight(); + Arrays.sort(list, 0, cnt, (ObjectToPack a, ObjectToPack b) -> { + int cmp = (a.isDoNotDelta() ? 1 : 0) - (b.isDoNotDelta() ? 1 : 0); + if (cmp != 0) { + return cmp; + } + + cmp = a.getType() - b.getType(); + if (cmp != 0) { + return cmp; } + + cmp = (a.getPathHash() >>> 1) - (b.getPathHash() >>> 1); + if (cmp != 0) { + return cmp; + } + + cmp = (a.getPathHash() & 1) - (b.getPathHash() & 1); + if (cmp != 0) { + return cmp; + } + + cmp = (a.isEdge() ? 0 : 1) - (b.isEdge() ? 0 : 1); + if (cmp != 0) { + return cmp; + } + + return b.getWeight() - a.getWeight(); }); // Above we stored the objects we cannot delta onto the end. @@ -1499,7 +1537,7 @@ public class PackWriter implements AutoCloseable { Executor executor = config.getExecutor(); final List<Throwable> errors = - Collections.synchronizedList(new ArrayList<Throwable>(threads)); + Collections.synchronizedList(new ArrayList<>(threads)); if (executor instanceof ExecutorService) { // Caller supplied us a service, use it directly. runTasks((ExecutorService) executor, pm, taskBlock, errors); @@ -1526,14 +1564,11 @@ public class PackWriter implements AutoCloseable { // asynchronous execution. Wrap everything and hope it // can schedule these for us. for (DeltaTask task : taskBlock.tasks) { - executor.execute(new Runnable() { - @Override - public void run() { - try { - task.call(); - } catch (Throwable failure) { - errors.add(failure); - } + executor.execute(() -> { + try { + task.call(); + } catch (Throwable failure) { + errors.add(failure); } }); } @@ -1969,7 +2004,9 @@ 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, want); + if (!depthSkip(o, walker)) { + filterAndAddObject(o, o.getType(), pathHash, want); + } countingMonitor.update(1); } } else { @@ -1979,7 +2016,10 @@ public class PackWriter implements AutoCloseable { continue; if (exclude(o)) continue; - filterAndAddObject(o, o.getType(), walker.getPathHashCode(), want); + if (!depthSkip(o, walker)) { + filterAndAddObject(o, o.getType(), walker.getPathHashCode(), + want); + } countingMonitor.update(1); } } @@ -2071,6 +2111,44 @@ public class PackWriter implements AutoCloseable { objectsMap.add(otp); } + /** + * Determines if the object should be omitted from the pack as a result of + * its depth (probably because of the tree:<depth> filter). + * <p> + * Causes {@code walker} to skip traversing the current tree, which ought to + * have just started traversal, assuming this method is called as soon as a + * new depth is reached. + * <p> + * This method increments the {@code treesTraversed} statistic. + * + * @param obj + * the object to check whether it should be omitted. + * @param walker + * the walker being used for traveresal. + * @return whether the given object should be skipped. + */ + private boolean depthSkip(@NonNull RevObject obj, ObjectWalk walker) { + long treeDepth = walker.getTreeDepth(); + + // Check if this object needs to be rejected because it is a tree or + // blob that is too deep from the root tree. + + // A blob is considered one level deeper than the tree that contains it. + if (obj.getType() == OBJ_BLOB) { + treeDepth++; + } else { + stats.treesTraversed++; + } + + if (filterSpec.getTreeDepthLimit() < 0 || + treeDepth <= filterSpec.getTreeDepthLimit()) { + return false; + } + + walker.skipTree(); + return true; + } + // 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, @@ -2079,10 +2157,10 @@ public class PackWriter implements AutoCloseable { // Check if this object needs to be rejected, doing the cheaper // checks first. - boolean reject = filterBlobLimit >= 0 && + boolean reject = filterSpec.getBlobLimit() >= 0 && type == OBJ_BLOB && !want.contains(src) && - reader.getObjectSize(src, OBJ_BLOB) > filterBlobLimit; + reader.getObjectSize(src, OBJ_BLOB) > filterSpec.getBlobLimit(); if (!reject) { addObject(src, type, pathHashCode); } @@ -2120,7 +2198,7 @@ public class PackWriter implements AutoCloseable { if (!cachedPacks.isEmpty()) { if (otp.isEdge()) return; - if ((nFmt == PACK_WHOLE) | (nFmt == PACK_DELTA)) { + if (nFmt == PACK_WHOLE || nFmt == PACK_DELTA) { for (CachedPack pack : cachedPacks) { if (pack.hasObject(otp, next)) { otp.setEdge(); @@ -2163,7 +2241,7 @@ public class PackWriter implements AutoCloseable { otp.clearReuseAsIs(); } - otp.setDeltaAttempted(reuseDeltas & next.wasDeltaAttempted()); + otp.setDeltaAttempted(reuseDeltas && next.wasDeltaAttempted()); otp.select(next); } 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 99db74956c..d3b5e128d1 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,12 +91,9 @@ class PackWriterBitmapPreparer { private static final int DAY_IN_SECONDS = 24 * 60 * 60; - private static final Comparator<RevCommit> ORDER_BY_REVERSE_TIMESTAMP = new Comparator<RevCommit>() { - @Override - public int compare(RevCommit a, RevCommit b) { - return Integer.signum(b.getCommitTime() - a.getCommitTime()); - } - }; + private static final Comparator<RevCommit> ORDER_BY_REVERSE_TIMESTAMP = ( + RevCommit a, RevCommit b) -> Integer + .signum(b.getCommitTime() - a.getCommitTime()); private final ObjectReader reader; private final ProgressMonitor pm; diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/internal/transport/http/NetscapeCookieFile.java b/org.eclipse.jgit/src/org/eclipse/jgit/internal/transport/http/NetscapeCookieFile.java new file mode 100644 index 0000000000..e16adb9bfb --- /dev/null +++ b/org.eclipse.jgit/src/org/eclipse/jgit/internal/transport/http/NetscapeCookieFile.java @@ -0,0 +1,488 @@ +/* + * Copyright (C) 2018, Konrad Windszus <konrad_w@gmx.de> + * 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.transport.http; + +import java.io.BufferedReader; +import java.io.ByteArrayOutputStream; +import java.io.File; +import java.io.FileNotFoundException; +import java.io.IOException; +import java.io.OutputStreamWriter; +import java.io.StringReader; +import java.io.Writer; +import java.net.HttpCookie; +import java.net.URL; +import java.nio.charset.StandardCharsets; +import java.nio.file.Path; +import java.text.MessageFormat; +import java.util.Arrays; +import java.util.Collection; +import java.util.Date; +import java.util.LinkedHashSet; +import java.util.Set; + +import org.eclipse.jgit.annotations.NonNull; +import org.eclipse.jgit.annotations.Nullable; +import org.eclipse.jgit.internal.JGitText; +import org.eclipse.jgit.internal.storage.file.FileSnapshot; +import org.eclipse.jgit.internal.storage.file.LockFile; +import org.eclipse.jgit.lib.Constants; +import org.eclipse.jgit.storage.file.FileBasedConfig; +import org.eclipse.jgit.util.FileUtils; +import org.eclipse.jgit.util.IO; +import org.eclipse.jgit.util.RawParseUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * Wraps all cookies persisted in a <strong>Netscape Cookie File Format</strong> + * being referenced via the git config <a href= + * "https://git-scm.com/docs/git-config#git-config-httpcookieFile">http.cookieFile</a>. + * <p> + * It will only load the cookies lazily, i.e. before calling + * {@link #getCookies(boolean)} the file is not evaluated. This class also + * allows persisting cookies in that file format. + * <p> + * In general this class is not thread-safe. So any consumer needs to take care + * of synchronization! + * + * @see <a href="http://www.cookiecentral.com/faq/#3.5">Netscape Cookie File + * Format</a> + * @see <a href= + * "https://unix.stackexchange.com/questions/36531/format-of-cookies-when-using-wget">Cookie + * format for wget</a> + * @see <a href= + * "https://github.com/curl/curl/blob/07ebaf837843124ee670e5b8c218b80b92e06e47/lib/cookie.c#L745">libcurl + * Cookie file parsing</a> + * @see <a href= + * "https://github.com/curl/curl/blob/07ebaf837843124ee670e5b8c218b80b92e06e47/lib/cookie.c#L1417">libcurl + * Cookie file writing</a> + * @see NetscapeCookieFileCache + */ +public final class NetscapeCookieFile { + + private static final String HTTP_ONLY_PREAMBLE = "#HttpOnly_"; //$NON-NLS-1$ + + private static final String COLUMN_SEPARATOR = "\t"; //$NON-NLS-1$ + + private static final String LINE_SEPARATOR = "\n"; //$NON-NLS-1$ + + /** + * Maximum number of retries to acquire the lock for writing to the + * underlying file. + */ + private static final int LOCK_ACQUIRE_MAX_RETRY_COUNT = 4; + + /** + * Sleep time in milliseconds between retries to acquire the lock for + * writing to the underlying file. + */ + private static final int LOCK_ACQUIRE_RETRY_SLEEP = 500; + + private final Path path; + + private FileSnapshot snapshot; + + private byte[] hash; + + final Date creationDate; + + private Set<HttpCookie> cookies = null; + + private static final Logger LOG = LoggerFactory + .getLogger(NetscapeCookieFile.class); + + /** + * @param path + * where to find the cookie file + */ + public NetscapeCookieFile(Path path) { + this(path, new Date()); + } + + NetscapeCookieFile(Path path, Date creationDate) { + this.path = path; + this.snapshot = FileSnapshot.DIRTY; + this.creationDate = creationDate; + } + + /** + * Path to the underlying cookie file. + * + * @return the path + */ + public Path getPath() { + return path; + } + + /** + * Return all cookies from the underlying cookie file. + * + * @param refresh + * if {@code true} updates the list from the underlying cookie + * file if it has been modified since the last read otherwise + * returns the current transient state. In case the cookie file + * has never been read before will always read from the + * underlying file disregarding the value of this parameter. + * @return all cookies (may contain session cookies as well). This does not + * return a copy of the list but rather the original one. Every + * addition to the returned list can afterwards be persisted via + * {@link #write(URL)}. Errors in the underlying file will not lead + * to exceptions but rather to an empty set being returned and the + * underlying error being logged. + */ + public Set<HttpCookie> getCookies(boolean refresh) { + if (cookies == null || refresh) { + try { + byte[] in = getFileContentIfModified(); + Set<HttpCookie> newCookies = parseCookieFile(in, creationDate); + if (cookies != null) { + cookies = mergeCookies(newCookies, cookies); + } else { + cookies = newCookies; + } + return cookies; + } catch (IOException | IllegalArgumentException e) { + LOG.warn( + MessageFormat.format( + JGitText.get().couldNotReadCookieFile, path), + e); + if (cookies == null) { + cookies = new LinkedHashSet<>(); + } + } + } + return cookies; + + } + + /** + * Parses the given file and extracts all cookie information from it. + * + * @param input + * the file content to parse + * @param creationDate + * the date for the creation of the cookies (used to calculate + * the maxAge based on the expiration date given within the file) + * @return the set of parsed cookies from the given file (even expired + * ones). If there is more than one cookie with the same name in + * this file the last one overwrites the first one! + * @throws IOException + * if the given file could not be read for some reason + * @throws IllegalArgumentException + * if the given file does not have a proper format + */ + private static Set<HttpCookie> parseCookieFile(@NonNull byte[] input, + @NonNull Date creationDate) + throws IOException, IllegalArgumentException { + + String decoded = RawParseUtils.decode(StandardCharsets.US_ASCII, input); + + Set<HttpCookie> cookies = new LinkedHashSet<>(); + try (BufferedReader reader = new BufferedReader( + new StringReader(decoded))) { + String line; + while ((line = reader.readLine()) != null) { + HttpCookie cookie = parseLine(line, creationDate); + if (cookie != null) { + cookies.add(cookie); + } + } + } + return cookies; + } + + private static HttpCookie parseLine(@NonNull String line, + @NonNull Date creationDate) { + if (line.isEmpty() || (line.startsWith("#") //$NON-NLS-1$ + && !line.startsWith(HTTP_ONLY_PREAMBLE))) { + return null; + } + String[] cookieLineParts = line.split(COLUMN_SEPARATOR, 7); + if (cookieLineParts == null) { + throw new IllegalArgumentException(MessageFormat + .format(JGitText.get().couldNotFindTabInLine, line)); + } + if (cookieLineParts.length < 7) { + throw new IllegalArgumentException(MessageFormat.format( + JGitText.get().couldNotFindSixTabsInLine, + Integer.valueOf(cookieLineParts.length), line)); + } + String name = cookieLineParts[5]; + String value = cookieLineParts[6]; + HttpCookie cookie = new HttpCookie(name, value); + + String domain = cookieLineParts[0]; + if (domain.startsWith(HTTP_ONLY_PREAMBLE)) { + cookie.setHttpOnly(true); + domain = domain.substring(HTTP_ONLY_PREAMBLE.length()); + } + // strip off leading "." + // (https://tools.ietf.org/html/rfc6265#section-5.2.3) + if (domain.startsWith(".")) { //$NON-NLS-1$ + domain = domain.substring(1); + } + cookie.setDomain(domain); + // domain evaluation as boolean flag not considered (i.e. always assumed + // to be true) + cookie.setPath(cookieLineParts[2]); + cookie.setSecure(Boolean.parseBoolean(cookieLineParts[3])); + + long expires = Long.parseLong(cookieLineParts[4]); + long maxAge = (expires - creationDate.getTime()) / 1000; + if (maxAge <= 0) { + return null; // skip expired cookies + } + cookie.setMaxAge(maxAge); + return cookie; + } + + /** + * Read the underying file and return its content but only in case it has + * been modified since the last access. + * <p> + * Internally calculates the hash and maintains {@link FileSnapshot}s to + * prevent issues described as <a href= + * "https://github.com/git/git/blob/master/Documentation/technical/racy-git.txt">"Racy + * Git problem"</a>. Inspired by {@link FileBasedConfig#load()}. + * + * @return the file contents in case the file has been modified since the + * last access, otherwise {@code null} + * @throws IOException + * if the file is not found or cannot be read + */ + private byte[] getFileContentIfModified() throws IOException { + final int maxStaleRetries = 5; + int retries = 0; + File file = getPath().toFile(); + if (!file.exists()) { + LOG.warn(MessageFormat.format(JGitText.get().missingCookieFile, + file.getAbsolutePath())); + return new byte[0]; + } + while (true) { + final FileSnapshot oldSnapshot = snapshot; + final FileSnapshot newSnapshot = FileSnapshot.save(file); + try { + final byte[] in = IO.readFully(file); + byte[] newHash = hash(in); + if (Arrays.equals(hash, newHash)) { + if (oldSnapshot.equals(newSnapshot)) { + oldSnapshot.setClean(newSnapshot); + } else { + snapshot = newSnapshot; + } + } else { + snapshot = newSnapshot; + hash = newHash; + } + return in; + } catch (FileNotFoundException e) { + throw e; + } catch (IOException e) { + if (FileUtils.isStaleFileHandle(e) + && retries < maxStaleRetries) { + if (LOG.isDebugEnabled()) { + LOG.debug(MessageFormat.format( + JGitText.get().configHandleIsStale, + Integer.valueOf(retries)), e); + } + retries++; + continue; + } + throw new IOException(MessageFormat + .format(JGitText.get().cannotReadFile, getPath()), e); + } + } + + } + + private static byte[] hash(final byte[] in) { + return Constants.newMessageDigest().digest(in); + } + + /** + * Writes all the cookies being maintained in the set being returned by + * {@link #getCookies(boolean)} to the underlying file. + * <p> + * Session-cookies will not be persisted. + * + * @param url + * url for which to write the cookies (important to derive + * default values for non-explicitly set attributes) + * @throws IOException + * if the underlying cookie file could not be read or written or + * a problem with the lock file + * @throws InterruptedException + * if the thread is interrupted while waiting for the lock + */ + public void write(URL url) throws IOException, InterruptedException { + try { + byte[] cookieFileContent = getFileContentIfModified(); + if (cookieFileContent != null) { + LOG.debug("Reading the underlying cookie file '{}' " //$NON-NLS-1$ + + "as it has been modified since " //$NON-NLS-1$ + + "the last access", //$NON-NLS-1$ + path); + // reread new changes if necessary + Set<HttpCookie> cookiesFromFile = NetscapeCookieFile + .parseCookieFile(cookieFileContent, creationDate); + this.cookies = mergeCookies(cookiesFromFile, cookies); + } + } catch (FileNotFoundException e) { + // ignore if file previously did not exist yet! + } + + ByteArrayOutputStream output = new ByteArrayOutputStream(); + try (Writer writer = new OutputStreamWriter(output, + StandardCharsets.US_ASCII)) { + write(writer, cookies, url, creationDate); + } + LockFile lockFile = new LockFile(path.toFile()); + for (int retryCount = 0; retryCount < LOCK_ACQUIRE_MAX_RETRY_COUNT; retryCount++) { + if (lockFile.lock()) { + try { + lockFile.setNeedSnapshot(true); + lockFile.write(output.toByteArray()); + if (!lockFile.commit()) { + throw new IOException(MessageFormat.format( + JGitText.get().cannotCommitWriteTo, path)); + } + } finally { + lockFile.unlock(); + } + return; + } + Thread.sleep(LOCK_ACQUIRE_RETRY_SLEEP); + } + throw new IOException( + MessageFormat.format(JGitText.get().cannotLock, lockFile)); + } + + /** + * Writes the given cookies to the file in the Netscape Cookie File Format + * (also used by curl). + * + * @param writer + * the writer to use to persist the cookies + * @param cookies + * the cookies to write into the file + * @param url + * the url for which to write the cookie (to derive the default + * values for certain cookie attributes) + * @param creationDate + * the date when the cookie has been created. Important for + * calculation the cookie expiration time (calculated from + * cookie's maxAge and this creation time) + * @throws IOException + * if an I/O error occurs + */ + static void write(@NonNull Writer writer, + @NonNull Collection<HttpCookie> cookies, @NonNull URL url, + @NonNull Date creationDate) throws IOException { + for (HttpCookie cookie : cookies) { + writeCookie(writer, cookie, url, creationDate); + } + } + + private static void writeCookie(@NonNull Writer writer, + @NonNull HttpCookie cookie, @NonNull URL url, + @NonNull Date creationDate) throws IOException { + if (cookie.getMaxAge() <= 0) { + return; // skip expired cookies + } + String domain = ""; //$NON-NLS-1$ + if (cookie.isHttpOnly()) { + domain = HTTP_ONLY_PREAMBLE; + } + if (cookie.getDomain() != null) { + domain += cookie.getDomain(); + } else { + domain += url.getHost(); + } + writer.write(domain); + writer.write(COLUMN_SEPARATOR); + writer.write("TRUE"); //$NON-NLS-1$ + writer.write(COLUMN_SEPARATOR); + String path = cookie.getPath(); + if (path == null) { + path = url.getPath(); + } + writer.write(path); + writer.write(COLUMN_SEPARATOR); + writer.write(Boolean.toString(cookie.getSecure()).toUpperCase()); + writer.write(COLUMN_SEPARATOR); + final String expirationDate; + // whenCreated field is not accessible in HttpCookie + expirationDate = String + .valueOf(creationDate.getTime() + (cookie.getMaxAge() * 1000)); + writer.write(expirationDate); + writer.write(COLUMN_SEPARATOR); + writer.write(cookie.getName()); + writer.write(COLUMN_SEPARATOR); + writer.write(cookie.getValue()); + writer.write(LINE_SEPARATOR); + } + + /** + * Merge the given sets in the following way. All cookies from + * {@code cookies1} and {@code cookies2} are contained in the resulting set + * which have unique names. If there is a duplicate entry for one name only + * the entry from set {@code cookies1} ends up in the resulting set. + * + * @param cookies1 + * first set of cookies + * @param cookies2 + * second set of cookies + * + * @return the merged cookies + */ + static Set<HttpCookie> mergeCookies(Set<HttpCookie> cookies1, + @Nullable Set<HttpCookie> cookies2) { + Set<HttpCookie> mergedCookies = new LinkedHashSet<>(cookies1); + if (cookies2 != null) { + mergedCookies.addAll(cookies2); + } + return mergedCookies; + } +} diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/internal/transport/http/NetscapeCookieFileCache.java b/org.eclipse.jgit/src/org/eclipse/jgit/internal/transport/http/NetscapeCookieFileCache.java new file mode 100644 index 0000000000..882b2d055b --- /dev/null +++ b/org.eclipse.jgit/src/org/eclipse/jgit/internal/transport/http/NetscapeCookieFileCache.java @@ -0,0 +1,106 @@ +/* + * Copyright (C) 2018, Konrad Windszus <konrad_w@gmx.de> + * 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.transport.http; + +import java.nio.file.Path; + +import org.eclipse.jgit.transport.HttpConfig; +import org.eclipse.jgit.util.LRUMap; + +/** + * A cache of all known cookie files ({@link NetscapeCookieFile}). May contain + * at most {@code n} entries, where the least-recently used one is evicted as + * soon as more entries are added. The maximum number of entries (={@code n}) + * can be set via the git config key {@code http.cookieFileCacheLimit}. By + * default it is set to 10. + * <p> + * The cache is global, i.e. it is shared among all consumers within the same + * Java process. + * + * @see NetscapeCookieFile + * + */ +public class NetscapeCookieFileCache { + + private final LRUMap<Path, NetscapeCookieFile> cookieFileMap; + + private static NetscapeCookieFileCache instance; + + private NetscapeCookieFileCache(HttpConfig config) { + cookieFileMap = new LRUMap<>(config.getCookieFileCacheLimit(), + config.getCookieFileCacheLimit()); + } + + /** + * @param config + * the config which defines the limit for this cache + * @return the singleton instance of the cookie file cache. If the cache has + * already been created the given config is ignored (even if it + * differs from the config, with which the cache has originally been + * created) + */ + public static NetscapeCookieFileCache getInstance(HttpConfig config) { + if (instance == null) { + return new NetscapeCookieFileCache(config); + } else { + return instance; + } + } + + /** + * @param path + * the path of the cookie file to retrieve + * @return the cache entry belonging to the requested file + */ + public NetscapeCookieFile getEntry(Path path) { + if (!cookieFileMap.containsKey(path)) { + synchronized (NetscapeCookieFileCache.class) { + if (!cookieFileMap.containsKey(path)) { + cookieFileMap.put(path, new NetscapeCookieFile(path)); + } + } + } + return cookieFileMap.get(path); + } + +} diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/lib/AbbreviatedObjectId.java b/org.eclipse.jgit/src/org/eclipse/jgit/lib/AbbreviatedObjectId.java index d105d0d200..b0339c677f 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/lib/AbbreviatedObjectId.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/lib/AbbreviatedObjectId.java @@ -162,7 +162,7 @@ public final class AbbreviatedObjectId implements Serializable { r |= RawParseUtils.parseHexInt4(bs[p++]); n++; } - return r << (8 - n) * 4; + return r << ((8 - n) * 4); } static int mask(int nibbles, int word, int v) { diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/lib/AnyObjectId.java b/org.eclipse.jgit/src/org/eclipse/jgit/lib/AnyObjectId.java index 978dd3a729..4f90e69008 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/lib/AnyObjectId.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/lib/AnyObjectId.java @@ -49,6 +49,7 @@ import java.io.Writer; import java.nio.ByteBuffer; import org.eclipse.jgit.util.NB; +import org.eclipse.jgit.util.References; /** * A (possibly mutable) SHA-1 abstraction. @@ -60,19 +61,37 @@ import org.eclipse.jgit.util.NB; public abstract class AnyObjectId implements Comparable<AnyObjectId> { /** - * Compare to object identifier byte sequences for equality. + * Compare two object identifier byte sequences for equality. * * @param firstObjectId * the first identifier to compare. Must not be null. * @param secondObjectId * the second identifier to compare. Must not be null. * @return true if the two identifiers are the same. + * @deprecated use {@link #isEqual(AnyObjectId, AnyObjectId)} instead */ + @Deprecated + @SuppressWarnings("AmbiguousMethodReference") public static boolean equals(final AnyObjectId firstObjectId, final AnyObjectId secondObjectId) { - if (firstObjectId == secondObjectId) - return true; + return isEqual(firstObjectId, secondObjectId); + } + /** + * Compare two object identifier byte sequences for equality. + * + * @param firstObjectId + * the first identifier to compare. Must not be null. + * @param secondObjectId + * the second identifier to compare. Must not be null. + * @return true if the two identifiers are the same. + * @since 5.4 + */ + public static boolean isEqual(final AnyObjectId firstObjectId, + final AnyObjectId secondObjectId) { + if (References.isSameObject(firstObjectId, secondObjectId)) { + return true; + } // We test word 3 first since the git file-based ODB // uses the first byte of w1, and we use w2 as the // hash code, one of those probably came up with these @@ -80,7 +99,6 @@ public abstract class AnyObjectId implements Comparable<AnyObjectId> { // Therefore the first two words are very likely to be // identical. We want to break away from collisions as // quickly as possible. - // return firstObjectId.w3 == secondObjectId.w3 && firstObjectId.w4 == secondObjectId.w4 && firstObjectId.w5 == secondObjectId.w5 @@ -276,8 +294,9 @@ public abstract class AnyObjectId implements Comparable<AnyObjectId> { * the other id to compare to. May be null. * @return true only if both ObjectIds have identical bits. */ + @SuppressWarnings({ "NonOverridingEquals", "AmbiguousMethodReference" }) public final boolean equals(AnyObjectId other) { - return other != null ? equals(this, other) : false; + return other != null ? isEqual(this, other) : false; } /** {@inheritDoc} */ 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 6cbddec543..13f71a7ff6 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/lib/CommitBuilder.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/lib/CommitBuilder.java @@ -57,6 +57,7 @@ import java.text.MessageFormat; import java.util.List; import org.eclipse.jgit.internal.JGitText; +import org.eclipse.jgit.util.References; /** * Mutable builder to construct a commit recording the state of a project. @@ -365,7 +366,7 @@ public class CommitBuilder { os.write('\n'); } - if (getEncoding() != UTF_8) { + if (!References.isSameObject(getEncoding(), UTF_8)) { os.write(hencoding); os.write(' '); os.write(Constants.encodeASCII(getEncoding().name())); @@ -474,7 +475,7 @@ public class CommitBuilder { r.append(gpgSignature != null ? gpgSignature.toString() : "NOT_SET"); r.append("\n"); - if (encoding != null && encoding != UTF_8) { + if (encoding != null && !References.isSameObject(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 4726975d07..71f863589d 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/lib/Config.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/lib/Config.java @@ -107,7 +107,7 @@ public class Config { * must ensure it is a special copy of the empty string. It also must * be treated like the empty string. */ - static final String MAGIC_EMPTY_VALUE = new String(); + private static final String MISSING_ENTRY = new String(); /** * Create a configuration with no default fallback. @@ -129,6 +129,18 @@ public class Config { } /** + * Check if a given string is the "missing" value. + * + * @param value string to be checked. + * @return true if the given string is the "missing" value. + * @since 5.4 + */ + @SuppressWarnings({ "ReferenceEquality", "StringEquality" }) + public static boolean isMissing(String value) { + return value == MISSING_ENTRY; + } + + /** * Globally sets a {@link org.eclipse.jgit.lib.TypedConfigGetter} that is * subsequently used to read typed values from all git configs. * @@ -1041,7 +1053,7 @@ public class Config { if (e.prefix == null || "".equals(e.prefix)) //$NON-NLS-1$ out.append('\t'); out.append(e.name); - if (MAGIC_EMPTY_VALUE != e.value) { + if (!isMissing(e.value)) { out.append(" ="); //$NON-NLS-1$ if (e.value != null) { out.append(' '); @@ -1132,7 +1144,7 @@ public class Config { e.name = readKeyName(in); if (e.name.endsWith("\n")) { //$NON-NLS-1$ e.name = e.name.substring(0, e.name.length() - 1); - e.value = MAGIC_EMPTY_VALUE; + e.value = MISSING_ENTRY; } else e.value = readValue(in); @@ -1165,7 +1177,7 @@ public class Config { private void addIncludedConfig(final List<ConfigLine> newEntries, ConfigLine line, int depth) throws ConfigInvalidException { if (!line.name.equalsIgnoreCase("path") || //$NON-NLS-1$ - line.value == null || line.value.equals(MAGIC_EMPTY_VALUE)) { + line.value == null || line.value.equals(MISSING_ENTRY)) { throw new ConfigInvalidException(MessageFormat.format( JGitText.get().invalidLineInConfigFileWithParam, line)); } @@ -1413,11 +1425,23 @@ public class Config { case '"': value.append('"'); continue; + case '\r': { + int next = in.read(); + if (next == '\n') { + continue; // CR-LF + } else if (next >= 0) { + in.reset(); + } + break; + } default: - throw new ConfigInvalidException(MessageFormat.format( - JGitText.get().badEscape, - Character.valueOf(((char) c)))); + break; } + throw new ConfigInvalidException( + MessageFormat.format(JGitText.get().badEscape, + Character.isAlphabetic(c) + ? Character.valueOf(((char) c)) + : toUnicodeLiteral(c))); } if ('"' == c) { @@ -1430,6 +1454,11 @@ public class Config { return value.length() > 0 ? value.toString() : null; } + private static String toUnicodeLiteral(int c) { + return String.format("\\u%04x", //$NON-NLS-1$ + Integer.valueOf(c)); + } + /** * Parses a section of the configuration into an application model object. * <p> 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 5ae9d41db2..8f40db626a 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/lib/ConfigConstants.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/lib/ConfigConstants.java @@ -365,50 +365,50 @@ public final class ConfigConstants { public static final String CONFIG_KEY_CHECKSTAT = "checkstat"; /** - * The "renamelimit" key in the "diff section" + * The "renamelimit" key in the "diff" section * @since 3.0 */ public static final String CONFIG_KEY_RENAMELIMIT = "renamelimit"; /** - * The "trustfolderstat" key in the "core section" + * The "trustfolderstat" key in the "core" section * @since 3.6 */ public static final String CONFIG_KEY_TRUSTFOLDERSTAT = "trustfolderstat"; /** - * The "supportsAtomicFileCreation" key in the "core section" + * The "supportsAtomicFileCreation" key in the "core" section * * @since 4.5 */ public static final String CONFIG_KEY_SUPPORTSATOMICFILECREATION = "supportsatomicfilecreation"; /** - * The "noprefix" key in the "diff section" + * The "noprefix" key in the "diff" section * @since 3.0 */ public static final String CONFIG_KEY_NOPREFIX = "noprefix"; /** - * A "renamelimit" value in the "diff section" + * A "renamelimit" value in the "diff" section * @since 3.0 */ public static final String CONFIG_RENAMELIMIT_COPY = "copy"; /** - * A "renamelimit" value in the "diff section" + * A "renamelimit" value in the "diff" section * @since 3.0 */ public static final String CONFIG_RENAMELIMIT_COPIES = "copies"; /** - * The "renames" key in the "diff section" + * The "renames" key in the "diff" section * @since 3.0 */ public static final String CONFIG_KEY_RENAMES = "renames"; /** - * The "inCoreLimit" key in the "merge section". It's a size limit (bytes) used to + * The "inCoreLimit" key in the "merge" section. It's a size limit (bytes) used to * control a file to be stored in {@code Heap} or {@code LocalFile} during the merge. * @since 4.9 */ 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 4c55196961..8f4468eef2 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/lib/Constants.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/lib/Constants.java @@ -58,7 +58,7 @@ import org.eclipse.jgit.internal.JGitText; import org.eclipse.jgit.util.MutableInteger; /** - * Misc. constants used throughout JGit. + * Misc. constants and helpers used throughout JGit. */ @SuppressWarnings("nls") public final class Constants { diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/lib/DefaultTypedConfigGetter.java b/org.eclipse.jgit/src/org/eclipse/jgit/lib/DefaultTypedConfigGetter.java index fb239399ed..e865da83b1 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/lib/DefaultTypedConfigGetter.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/lib/DefaultTypedConfigGetter.java @@ -72,7 +72,7 @@ public class DefaultTypedConfigGetter implements TypedConfigGetter { if (n == null) { return defaultValue; } - if (Config.MAGIC_EMPTY_VALUE == n) { + if (Config.isMissing(n)) { return true; } try { diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/lib/FileMode.java b/org.eclipse.jgit/src/org/eclipse/jgit/lib/FileMode.java index d4c4d5b40d..8fa8d5f7d5 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/lib/FileMode.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/lib/FileMode.java @@ -88,6 +88,7 @@ public abstract class FileMode { public static final FileMode TREE = new FileMode(TYPE_TREE, Constants.OBJ_TREE) { @Override + @SuppressWarnings("NonOverridingEquals") public boolean equals(int modeBits) { return (modeBits & TYPE_MASK) == TYPE_TREE; } @@ -97,6 +98,7 @@ public abstract class FileMode { public static final FileMode SYMLINK = new FileMode(TYPE_SYMLINK, Constants.OBJ_BLOB) { @Override + @SuppressWarnings("NonOverridingEquals") public boolean equals(int modeBits) { return (modeBits & TYPE_MASK) == TYPE_SYMLINK; } @@ -106,6 +108,7 @@ public abstract class FileMode { public static final FileMode REGULAR_FILE = new FileMode(0100644, Constants.OBJ_BLOB) { @Override + @SuppressWarnings("NonOverridingEquals") public boolean equals(int modeBits) { return (modeBits & TYPE_MASK) == TYPE_FILE && (modeBits & 0111) == 0; } @@ -115,6 +118,7 @@ public abstract class FileMode { public static final FileMode EXECUTABLE_FILE = new FileMode(0100755, Constants.OBJ_BLOB) { @Override + @SuppressWarnings("NonOverridingEquals") public boolean equals(int modeBits) { return (modeBits & TYPE_MASK) == TYPE_FILE && (modeBits & 0111) != 0; } @@ -124,6 +128,7 @@ public abstract class FileMode { public static final FileMode GITLINK = new FileMode(TYPE_GITLINK, Constants.OBJ_COMMIT) { @Override + @SuppressWarnings("NonOverridingEquals") public boolean equals(int modeBits) { return (modeBits & TYPE_MASK) == TYPE_GITLINK; } @@ -133,6 +138,7 @@ public abstract class FileMode { public static final FileMode MISSING = new FileMode(TYPE_MISSING, Constants.OBJ_BAD) { @Override + @SuppressWarnings("NonOverridingEquals") public boolean equals(int modeBits) { return modeBits == 0; } @@ -165,6 +171,7 @@ public abstract class FileMode { return new FileMode(bits, Constants.OBJ_BAD) { @Override + @SuppressWarnings("NonOverridingEquals") public boolean equals(int a) { return bits == a; } @@ -206,6 +213,7 @@ public abstract class FileMode { * a int. * @return true if the mode bits represent the same mode as this object */ + @SuppressWarnings("NonOverridingEquals") public abstract boolean equals(int modebits); /** diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/lib/IndexDiff.java b/org.eclipse.jgit/src/org/eclipse/jgit/lib/IndexDiff.java index f37c310752..ce1eb597fc 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/lib/IndexDiff.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/lib/IndexDiff.java @@ -352,12 +352,7 @@ public class IndexDiff { public WorkingTreeIterator getWorkingTreeIterator(Repository repo); } - private WorkingTreeIteratorFactory wTreeIt = new WorkingTreeIteratorFactory() { - @Override - public WorkingTreeIterator getWorkingTreeIterator(Repository repo) { - return new FileTreeIterator(repo); - } - }; + private WorkingTreeIteratorFactory wTreeIt = FileTreeIterator::new; /** * Allows higher layers to set the factory for WorkingTreeIterators. @@ -647,11 +642,12 @@ public class IndexDiff { private void addConflict(String path, int stage) { StageState existingStageStates = conflicts.get(path); byte stageMask = 0; - if (existingStageStates != null) - stageMask |= existingStageStates.getStageMask(); + if (existingStageStates != null) { + stageMask |= (byte) existingStageStates.getStageMask(); + } // stage 1 (base) should be shifted 0 times int shifts = stage - 1; - stageMask |= (1 << shifts); + stageMask |= (byte) (1 << shifts); StageState stageState = StageState.fromMask(stageMask); conflicts.put(path, stageState); } diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/lib/ObjectIdRef.java b/org.eclipse.jgit/src/org/eclipse/jgit/lib/ObjectIdRef.java index b791c64552..d65c1bdf1a 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/lib/ObjectIdRef.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/lib/ObjectIdRef.java @@ -67,7 +67,7 @@ public abstract class ObjectIdRef implements Ref { */ public Unpeeled(@NonNull Storage st, @NonNull String name, @Nullable ObjectId id) { - super(st, name, id, -1); + super(st, name, id, UNDEFINED_UPDATE_INDEX); } /** @@ -119,7 +119,7 @@ public abstract class ObjectIdRef implements Ref { */ public PeeledTag(@NonNull Storage st, @NonNull String name, @Nullable ObjectId id, @NonNull ObjectId p) { - super(st, name, id, -1); + super(st, name, id, UNDEFINED_UPDATE_INDEX); peeledObjectId = p; } @@ -172,7 +172,7 @@ public abstract class ObjectIdRef implements Ref { */ public PeeledNonTag(@NonNull Storage st, @NonNull String name, @Nullable ObjectId id) { - super(st, name, id, -1); + super(st, name, id, UNDEFINED_UPDATE_INDEX); } /** @@ -284,7 +284,7 @@ public abstract class ObjectIdRef implements Ref { */ @Override public long getUpdateIndex() { - if (updateIndex == -1) { + if (updateIndex == UNDEFINED_UPDATE_INDEX) { throw new UnsupportedOperationException(); } return updateIndex; diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/lib/ObjectIdSubclassMap.java b/org.eclipse.jgit/src/org/eclipse/jgit/lib/ObjectIdSubclassMap.java index cd57bda82e..470275beb1 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/lib/ObjectIdSubclassMap.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/lib/ObjectIdSubclassMap.java @@ -103,8 +103,9 @@ public class ObjectIdSubclassMap<V extends ObjectId> V obj; while ((obj = tbl[i]) != null) { - if (AnyObjectId.equals(obj, toFind)) + if (AnyObjectId.isEqual(obj, toFind)) { return obj; + } i = (i + 1) & msk; } return null; @@ -162,7 +163,7 @@ public class ObjectIdSubclassMap<V extends ObjectId> V obj; while ((obj = tbl[i]) != null) { - if (AnyObjectId.equals(obj, newValue)) + if (AnyObjectId.isEqual(obj, newValue)) return obj; i = (i + 1) & msk; } 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 0d31851836..ebbb3a4844 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/lib/RebaseTodoFile.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/lib/RebaseTodoFile.java @@ -181,7 +181,7 @@ public class RebaseTodoFile { int nextSpace = RawParseUtils.next(buf, tokenBegin, ' '); int tokenCount = 0; - while (tokenCount < 3 && nextSpace < lineEnd) { + while (tokenCount < 3 && nextSpace <= lineEnd) { switch (tokenCount) { case 0: String actionToken = new String(buf, tokenBegin, @@ -193,8 +193,14 @@ public class RebaseTodoFile { break; case 1: nextSpace = RawParseUtils.next(buf, tokenBegin, ' '); - String commitToken = new String(buf, tokenBegin, - nextSpace - tokenBegin - 1, UTF_8); + String commitToken; + if (nextSpace > lineEnd + 1) { + commitToken = new String(buf, tokenBegin, + lineEnd - tokenBegin + 1, UTF_8); + } else { + commitToken = new String(buf, tokenBegin, + nextSpace - tokenBegin - 1, UTF_8); + } tokenBegin = nextSpace; commit = AbbreviatedObjectId.fromString(commitToken); break; diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/lib/Ref.java b/org.eclipse.jgit/src/org/eclipse/jgit/lib/Ref.java index 32c8b06c91..4082d21c2e 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/lib/Ref.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/lib/Ref.java @@ -126,6 +126,13 @@ public interface Ref { } /** + * Update index value when a reference doesn't have one + * + * @since 5.4 + */ + long UNDEFINED_UPDATE_INDEX = -1L; + + /** * What this ref is called within the repository. * * @return name of this ref. diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/lib/RefDatabase.java b/org.eclipse.jgit/src/org/eclipse/jgit/lib/RefDatabase.java index 877792097c..4d9450e758 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/lib/RefDatabase.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/lib/RefDatabase.java @@ -44,6 +44,7 @@ package org.eclipse.jgit.lib; import static java.util.stream.Collectors.toList; +import static java.util.stream.Collectors.toSet; import java.io.IOException; import java.util.ArrayList; @@ -52,7 +53,7 @@ import java.util.Collections; import java.util.HashMap; import java.util.List; import java.util.Map; - +import java.util.Set; import org.eclipse.jgit.annotations.NonNull; import org.eclipse.jgit.annotations.Nullable; @@ -470,6 +471,31 @@ public abstract class RefDatabase { return Collections.unmodifiableList(result); } + + /** + * Returns all refs that resolve directly to the given {@link ObjectId}. + * Includes peeled {@linkObjectId}s. This is the inverse lookup of + * {@link #exactRef(String...)}. + * + * <p> + * The default implementation uses a linear scan. Implementors of + * {@link RefDatabase} should override this method directly if a better + * implementation is possible. + * + * @param id + * {@link ObjectId} to resolve + * @return a {@link Set} of {@link Ref}s whose tips point to the provided + * id. + * @throws java.io.IOException + * the reference space cannot be accessed. + * @since 5.4 + */ + @NonNull + public Set<Ref> getTipsWithSha1(ObjectId id) throws IOException { + return getRefs().stream().filter(r -> id.equals(r.getObjectId()) + || id.equals(r.getPeeledObjectId())).collect(toSet()); + } + /** * Check if any refs exist in the ref database. * <p> diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/lib/RefUpdate.java b/org.eclipse.jgit/src/org/eclipse/jgit/lib/RefUpdate.java index 1ce1528344..eca15c032a 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/lib/RefUpdate.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/lib/RefUpdate.java @@ -53,6 +53,7 @@ import org.eclipse.jgit.revwalk.RevCommit; import org.eclipse.jgit.revwalk.RevObject; import org.eclipse.jgit.revwalk.RevWalk; import org.eclipse.jgit.transport.PushCertificate; +import org.eclipse.jgit.util.References; /** * Creates, updates or deletes any reference. @@ -599,6 +600,7 @@ public abstract class RefUpdate { */ public Result update() throws IOException { try (RevWalk rw = new RevWalk(getRepository())) { + rw.setRetainBody(false); return update(rw); } } @@ -646,6 +648,7 @@ public abstract class RefUpdate { */ public Result delete() throws IOException { try (RevWalk rw = new RevWalk(getRepository())) { + rw.setRetainBody(false); return delete(rw); } } @@ -751,7 +754,7 @@ public abstract class RefUpdate { if (expValue != null) { final ObjectId o; o = oldValue != null ? oldValue : ObjectId.zeroId(); - if (!AnyObjectId.equals(expValue, o)) { + if (!AnyObjectId.isEqual(expValue, o)) { return Result.LOCK_FAILURE; } } @@ -766,7 +769,8 @@ public abstract class RefUpdate { } oldObj = safeParseOld(walk, oldValue); - if (newObj == oldObj && !detachingSymbolicRef) { + if (References.isSameObject(newObj, oldObj) + && !detachingSymbolicRef) { return store.execute(Result.NO_CHANGE); } 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 a61897a652..68866ea279 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/lib/Repository.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/lib/Repository.java @@ -240,6 +240,15 @@ public abstract class Repository implements AutoCloseable { } /** + * Get repository identifier. + * + * @return repository identifier. The returned identifier has to be unique + * within a given Git server. + * @since 5.4 + */ + public abstract String getIdentifier(); + + /** * Get the object database which stores this repository's data. * * @return the object database which stores this repository's data. @@ -489,6 +498,7 @@ public abstract class Repository implements AutoCloseable { throws AmbiguousObjectException, IncorrectObjectTypeException, RevisionSyntaxException, IOException { try (RevWalk rw = new RevWalk(this)) { + rw.setRetainBody(false); Object resolved = resolve(rw, revstr); if (resolved instanceof String) { final Ref ref = findRef((String) resolved); @@ -515,6 +525,7 @@ public abstract class Repository implements AutoCloseable { public String simplify(String revstr) throws AmbiguousObjectException, IOException { try (RevWalk rw = new RevWalk(this)) { + rw.setRetainBody(true); Object resolved = resolve(rw, revstr); if (resolved != null) if (resolved instanceof String) @@ -606,7 +617,7 @@ public abstract class Repository implements AutoCloseable { if (!(rev instanceof RevBlob)) throw new IncorrectObjectTypeException(rev, Constants.TYPE_BLOB); - } else if (item.equals("")) { //$NON-NLS-1$ + } else if (item.isEmpty()) { rev = rw.peel(rev); } else throw new RevisionSyntaxException(revstr); @@ -707,7 +718,7 @@ public abstract class Repository implements AutoCloseable { if (time.equals("upstream")) { //$NON-NLS-1$ if (name == null) name = new String(revChars, done, i); - if (name.equals("")) //$NON-NLS-1$ + if (name.isEmpty()) // Currently checked out branch, HEAD if // detached name = Constants.HEAD; @@ -762,7 +773,7 @@ public abstract class Repository implements AutoCloseable { } else { if (name == null) name = new String(revChars, done, i); - if (name.equals("")) //$NON-NLS-1$ + if (name.isEmpty()) name = Constants.HEAD; if (!Repository.isValidRefName("x/" + name)) //$NON-NLS-1$ throw new RevisionSyntaxException(MessageFormat @@ -788,7 +799,7 @@ public abstract class Repository implements AutoCloseable { if (rev == null) { if (name == null) name = new String(revChars, done, i); - if (name.equals("")) //$NON-NLS-1$ + if (name.isEmpty()) name = Constants.HEAD; rev = parseSimple(rw, name); name = null; @@ -921,7 +932,7 @@ public abstract class Repository implements AutoCloseable { AbbreviatedObjectId id = AbbreviatedObjectId.fromString(revstr); try (ObjectReader reader = newObjectReader()) { Collection<ObjectId> matches = reader.resolve(id); - if (matches.size() == 0) + if (matches.isEmpty()) return null; else if (matches.size() == 1) return matches.iterator().next(); @@ -1275,11 +1286,8 @@ public abstract class Repository implements AutoCloseable { CorruptObjectException, IOException { // we want DirCache to inform us so that we can inform registered // listeners about index changes - IndexChangedListener l = new IndexChangedListener() { - @Override - public void onIndexChanged(IndexChangedEvent event) { - notifyIndexChanged(true); - } + IndexChangedListener l = (IndexChangedEvent event) -> { + notifyIndexChanged(true); }; return DirCache.lock(this, l); } @@ -1528,19 +1536,22 @@ public abstract class Repository implements AutoCloseable { final String filePath = file.getPath(); final String workDirPath = workDir.getPath(); - if (filePath.length() <= workDirPath.length() || - filePath.charAt(workDirPath.length()) != File.separatorChar || - !filePath.startsWith(workDirPath)) { - File absWd = workDir.isAbsolute() ? workDir : workDir.getAbsoluteFile(); + if (filePath.length() <= workDirPath.length() + || filePath.charAt(workDirPath.length()) != File.separatorChar + || !filePath.startsWith(workDirPath)) { + File absWd = workDir.isAbsolute() ? workDir + : workDir.getAbsoluteFile(); File absFile = file.isAbsolute() ? file : file.getAbsoluteFile(); - if (absWd == workDir && absFile == file) + if (absWd.equals(workDir) && absFile.equals(file)) { return ""; //$NON-NLS-1$ + } return stripWorkDir(absWd, absFile); } String relName = filePath.substring(workDirPath.length() + 1); - if (File.separatorChar != '/') + if (File.separatorChar != '/') { relName = relName.replace(File.separatorChar, '/'); + } return relName; } diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/lib/RepositoryCache.java b/org.eclipse.jgit/src/org/eclipse/jgit/lib/RepositoryCache.java index 400342b1bd..27befba5a4 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/lib/RepositoryCache.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/lib/RepositoryCache.java @@ -255,14 +255,11 @@ public class RepositoryCache { if (delay == RepositoryCacheConfig.NO_CLEANUP) { return; } - cleanupTask = scheduler.scheduleWithFixedDelay(new Runnable() { - @Override - public void run() { - try { - cache.clearAllExpired(); - } catch (Throwable e) { - LOG.error(e.getMessage(), e); - } + cleanupTask = scheduler.scheduleWithFixedDelay(() -> { + try { + cache.clearAllExpired(); + } catch (Throwable e) { + LOG.error(e.getMessage(), e); } }, delay, delay, TimeUnit.MILLISECONDS); } diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/lib/SymbolicRef.java b/org.eclipse.jgit/src/org/eclipse/jgit/lib/SymbolicRef.java index 00fcf52037..9f0568f0c2 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/lib/SymbolicRef.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/lib/SymbolicRef.java @@ -71,7 +71,7 @@ public class SymbolicRef implements Ref { public SymbolicRef(@NonNull String refName, @NonNull Ref target) { this.name = refName; this.target = target; - this.updateIndex = -1; + this.updateIndex = UNDEFINED_UPDATE_INDEX; } /** @@ -155,7 +155,7 @@ public class SymbolicRef implements Ref { */ @Override public long getUpdateIndex() { - if (updateIndex == -1) { + if (updateIndex == UNDEFINED_UPDATE_INDEX) { throw new UnsupportedOperationException(); } return updateIndex; diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/lib/internal/BouncyCastleGpgKeyLocator.java b/org.eclipse.jgit/src/org/eclipse/jgit/lib/internal/BouncyCastleGpgKeyLocator.java index 091667db01..0d44317658 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/lib/internal/BouncyCastleGpgKeyLocator.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/lib/internal/BouncyCastleGpgKeyLocator.java @@ -54,6 +54,8 @@ import java.nio.file.Files; import java.nio.file.InvalidPathException; import java.nio.file.Path; import java.nio.file.Paths; +import java.security.NoSuchAlgorithmException; +import java.security.NoSuchProviderException; import java.text.MessageFormat; import java.util.Iterator; import java.util.Locale; @@ -67,6 +69,7 @@ import org.bouncycastle.gpg.keybox.KeyBox; import org.bouncycastle.gpg.keybox.KeyInformation; import org.bouncycastle.gpg.keybox.PublicKeyRingBlob; import org.bouncycastle.gpg.keybox.UserID; +import org.bouncycastle.gpg.keybox.jcajce.JcaKeyBoxBuilder; import org.bouncycastle.openpgp.PGPException; import org.bouncycastle.openpgp.PGPPublicKey; import org.bouncycastle.openpgp.PGPSecretKey; @@ -85,6 +88,8 @@ import org.eclipse.jgit.errors.UnsupportedCredentialItem; import org.eclipse.jgit.internal.JGitText; import org.eclipse.jgit.util.FS; import org.eclipse.jgit.util.SystemReader; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; /** * Locates GPG keys from either <code>~/.gnupg/private-keys-v1.d</code> or @@ -92,6 +97,9 @@ import org.eclipse.jgit.util.SystemReader; */ class BouncyCastleGpgKeyLocator { + private static final Logger log = LoggerFactory + .getLogger(BouncyCastleGpgKeyLocator.class); + private static final Path GPG_DIRECTORY = findGpgDirectory(); private static final Path USER_KEYBOX_PATH = GPG_DIRECTORY @@ -157,11 +165,14 @@ class BouncyCastleGpgKeyLocator { private PGPSecretKey attemptParseSecretKey(Path keyFile, PGPDigestCalculatorProvider calculatorProvider, PBEProtectionRemoverFactory passphraseProvider, - PGPPublicKey publicKey) throws IOException { + PGPPublicKey publicKey) { try (InputStream in = newInputStream(keyFile)) { return new SExprParser(calculatorProvider).parseSecretKey( new BufferedInputStream(in), passphraseProvider, publicKey); - } catch (PGPException | ClassCastException e) { + } catch (IOException | PGPException | ClassCastException e) { + if (log.isDebugEnabled()) + log.debug("Ignoring unreadable file '{}': {}", keyFile, //$NON-NLS-1$ + e.getMessage(), e); return null; } } @@ -173,10 +184,11 @@ class BouncyCastleGpgKeyLocator { private PGPPublicKey findPublicKeyByKeyId(KeyBlob keyBlob) throws IOException { + String keyId = signingKey.toLowerCase(Locale.ROOT); for (KeyInformation keyInfo : keyBlob.getKeyInformation()) { - if (signingKey.toLowerCase(Locale.ROOT) - .equals(Hex.toHexString(keyInfo.getKeyID()) - .toLowerCase(Locale.ROOT))) { + String fingerprint = Hex.toHexString(keyInfo.getFingerprint()) + .toLowerCase(Locale.ROOT); + if (fingerprint.endsWith(keyId)) { return getFirstPublicKey(keyBlob); } } @@ -201,9 +213,12 @@ class BouncyCastleGpgKeyLocator { * @return publicKey the public key (maybe <code>null</code>) * @throws IOException * in case of problems reading the file + * @throws NoSuchAlgorithmException + * @throws NoSuchProviderException */ private PGPPublicKey findPublicKeyInKeyBox(Path keyboxFile) - throws IOException { + throws IOException, NoSuchAlgorithmException, + NoSuchProviderException { KeyBox keyBox = readKeyBoxFile(keyboxFile); for (KeyBlob keyBlob : keyBox.getKeyBlobs()) { if (keyBlob.getType() == BlobType.OPEN_PGP_BLOB) { @@ -227,15 +242,17 @@ class BouncyCastleGpgKeyLocator { * @return the secret key * @throws IOException * in case of issues reading key files + * @throws NoSuchAlgorithmException + * @throws NoSuchProviderException * @throws PGPException * in case of issues finding a key * @throws CanceledException * @throws URISyntaxException * @throws UnsupportedCredentialItem */ - public BouncyCastleGpgKey findSecretKey() - throws IOException, PGPException, CanceledException, - UnsupportedCredentialItem, URISyntaxException { + public BouncyCastleGpgKey findSecretKey() throws IOException, + NoSuchAlgorithmException, NoSuchProviderException, PGPException, + CanceledException, UnsupportedCredentialItem, URISyntaxException { if (exists(USER_KEYBOX_PATH)) { PGPPublicKey publicKey = // findPublicKeyInKeyBox(USER_KEYBOX_PATH); @@ -252,6 +269,10 @@ class BouncyCastleGpgKeyLocator { USER_PGP_LEGACY_SECRING_FILE); if (secretKey != null) { + if (!secretKey.isSigningKey()) { + throw new PGPException(MessageFormat.format( + JGitText.get().gpgNotASigningKey, signingKey)); + } return new BouncyCastleGpgKey(secretKey, USER_PGP_LEGACY_SECRING_FILE); } @@ -285,6 +306,10 @@ class BouncyCastleGpgKeyLocator { PGPSecretKey secretKey = attemptParseSecretKey(keyFile, calculatorProvider, passphraseProvider, publicKey); if (secretKey != null) { + if (!secretKey.isSigningKey()) { + throw new PGPException(MessageFormat.format( + JGitText.get().gpgNotASigningKey, signingKey)); + } return new BouncyCastleGpgKey(secretKey, userKeyboxPath); } } @@ -326,6 +351,7 @@ class BouncyCastleGpgKeyLocator { PGPUtil.getDecoderStream(new BufferedInputStream(in)), new JcaKeyFingerprintCalculator()); + String keyId = signingkey.toLowerCase(Locale.ROOT); Iterator<PGPSecretKeyRing> keyrings = pgpSec.getKeyRings(); while (keyrings.hasNext()) { PGPSecretKeyRing keyRing = keyrings.next(); @@ -336,8 +362,7 @@ class BouncyCastleGpgKeyLocator { String fingerprint = Hex .toHexString(key.getPublicKey().getFingerprint()) .toLowerCase(Locale.ROOT); - if (fingerprint - .endsWith(signingkey.toLowerCase(Locale.ROOT))) { + if (fingerprint.endsWith(keyId)) { return key; } // try user id @@ -359,14 +384,12 @@ class BouncyCastleGpgKeyLocator { .getPublicKey(); } - private KeyBox readKeyBoxFile(Path keyboxFile) throws IOException { + private KeyBox readKeyBoxFile(Path keyboxFile) throws IOException, + NoSuchAlgorithmException, NoSuchProviderException { KeyBox keyBox; try (InputStream in = new BufferedInputStream( newInputStream(keyboxFile))) { - // note: KeyBox constructor reads in the whole InputStream at once - // this code will change in 1.61 to - // either 'new BcKeyBox(in)' or 'new JcaKeyBoxBuilder().build(in)' - keyBox = new KeyBox(in, new JcaKeyFingerprintCalculator()); + keyBox = new JcaKeyBoxBuilder().build(in); } return keyBox; } diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/lib/internal/BouncyCastleGpgSigner.java b/org.eclipse.jgit/src/org/eclipse/jgit/lib/internal/BouncyCastleGpgSigner.java index 4d696dd9e7..cfe0931b47 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/lib/internal/BouncyCastleGpgSigner.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/lib/internal/BouncyCastleGpgSigner.java @@ -45,6 +45,8 @@ package org.eclipse.jgit.lib.internal; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.net.URISyntaxException; +import java.security.NoSuchAlgorithmException; +import java.security.NoSuchProviderException; import java.security.Security; import org.bouncycastle.bcpg.ArmoredOutputStream; @@ -100,7 +102,8 @@ public class BouncyCastleGpgSigner extends GpgSigner { BouncyCastleGpgKey gpgKey = locateSigningKey(gpgSigningKey, committer, passphrasePrompt); return gpgKey != null; - } catch (PGPException | IOException | URISyntaxException e) { + } catch (PGPException | IOException | NoSuchAlgorithmException + | NoSuchProviderException | URISyntaxException e) { return false; } } @@ -109,7 +112,8 @@ public class BouncyCastleGpgSigner extends GpgSigner { PersonIdent committer, BouncyCastleGpgKeyPassphrasePrompt passphrasePrompt) throws CanceledException, UnsupportedCredentialItem, IOException, - PGPException, URISyntaxException { + NoSuchAlgorithmException, NoSuchProviderException, PGPException, + URISyntaxException { if (gpgSigningKey == null || gpgSigningKey.isEmpty()) { gpgSigningKey = committer.getEmailAddress(); } @@ -153,7 +157,8 @@ public class BouncyCastleGpgSigner extends GpgSigner { signatureGenerator.generate().encode(out); } commit.setGpgSignature(new GpgSignature(buffer.toByteArray())); - } catch (PGPException | IOException | URISyntaxException e) { + } catch (PGPException | IOException | NoSuchAlgorithmException + | NoSuchProviderException | URISyntaxException e) { throw new JGitInternalException(e.getMessage(), e); } } diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/merge/MergeAlgorithm.java b/org.eclipse.jgit/src/org/eclipse/jgit/merge/MergeAlgorithm.java index dd42e43841..a77cb4ffb9 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/merge/MergeAlgorithm.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/merge/MergeAlgorithm.java @@ -86,6 +86,11 @@ public final class MergeAlgorithm { private final static Edit END_EDIT = new Edit(Integer.MAX_VALUE, Integer.MAX_VALUE); + @SuppressWarnings("ReferenceEquality") + private static boolean isEndEdit(Edit edit) { + return edit == END_EDIT; + } + /** * Does the three way merge between a common base and two sequences. * @@ -145,7 +150,7 @@ public final class MergeAlgorithm { // iterate over all edits from base to ours and from base to theirs // leave the loop when there are no edits more for ours or for theirs // (or both) - while (theirsEdit != END_EDIT || oursEdit != END_EDIT) { + while (!isEndEdit(theirsEdit) || !isEndEdit(oursEdit)) { if (oursEdit.getEndA() < theirsEdit.getBeginA()) { // something was changed in ours not overlapping with any change // from theirs. First add the common part in front of the edit 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 75334ddb0c..0b423fb5d4 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/merge/ResolveMerger.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/merge/ResolveMerger.java @@ -1182,7 +1182,7 @@ public class ResolveMerger extends ThreeWayMerger { * fail. */ public Map<String, MergeFailureReason> getFailingPaths() { - return (failingPaths.size() == 0) ? null : failingPaths; + return failingPaths.isEmpty() ? null : failingPaths; } /** @@ -1193,7 +1193,7 @@ public class ResolveMerger extends ThreeWayMerger { * otherwise */ public boolean failed() { - return failingPaths.size() > 0; + return !failingPaths.isEmpty(); } /** diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/nls/GlobalBundleCache.java b/org.eclipse.jgit/src/org/eclipse/jgit/nls/GlobalBundleCache.java index fd425abf35..b437f635f5 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/nls/GlobalBundleCache.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/nls/GlobalBundleCache.java @@ -43,6 +43,7 @@ package org.eclipse.jgit.nls; +import java.lang.reflect.InvocationTargetException; import java.util.HashMap; import java.util.Locale; import java.util.Map; @@ -92,14 +93,13 @@ class GlobalBundleCache { } TranslationBundle bundle = bundles.get(type); if (bundle == null) { - bundle = type.newInstance(); + bundle = type.getDeclaredConstructor().newInstance(); bundle.load(locale); bundles.put(type, bundle); } return (T) bundle; - } catch (InstantiationException e) { - throw new Error(e); - } catch (IllegalAccessException e) { + } catch (InstantiationException | IllegalAccessException + | InvocationTargetException | NoSuchMethodException e) { throw new Error(e); } } diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/nls/TranslationBundle.java b/org.eclipse.jgit/src/org/eclipse/jgit/nls/TranslationBundle.java index cdd7be266f..c41fb416d5 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/nls/TranslationBundle.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/nls/TranslationBundle.java @@ -182,9 +182,7 @@ public abstract class TranslationBundle { field.set(this, translatedText); } catch (MissingResourceException e) { throw new TranslationStringMissingException(bundleClass, locale, field.getName(), e); - } catch (IllegalArgumentException e) { - throw new Error(e); - } catch (IllegalAccessException e) { + } catch (IllegalArgumentException | IllegalAccessException e) { throw new Error(e); } } diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/notes/NoteMapMerger.java b/org.eclipse.jgit/src/org/eclipse/jgit/notes/NoteMapMerger.java index 325ff4f268..ba7223b8f0 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/notes/NoteMapMerger.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/notes/NoteMapMerger.java @@ -295,14 +295,14 @@ public class NoteMapMerger { private static boolean sameNote(Note a, Note b) { if (a == null && b == null) return true; - return a != null && b != null && AnyObjectId.equals(a, b); + return a != null && b != null && AnyObjectId.isEqual(a, b); } private static boolean sameContent(Note a, Note b) { if (a == null && b == null) return true; return a != null && b != null - && AnyObjectId.equals(a.getData(), b.getData()); + && AnyObjectId.isEqual(a.getData(), b.getData()); } private static InMemoryNoteBucket addIfNotNull(InMemoryNoteBucket result, diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/patch/CombinedHunkHeader.java b/org.eclipse.jgit/src/org/eclipse/jgit/patch/CombinedHunkHeader.java index d278132c61..74eec81209 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/patch/CombinedHunkHeader.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/patch/CombinedHunkHeader.java @@ -109,12 +109,13 @@ public class CombinedHunkHeader extends HunkHeader { final MutableInteger ptr = new MutableInteger(); ptr.value = nextLF(buf, startOffset, ' '); - for (int n = 0; n < old.length; n++) { - old[n].startLine = -parseBase10(buf, ptr.value, ptr); - if (buf[ptr.value] == ',') - old[n].lineCount = parseBase10(buf, ptr.value + 1, ptr); - else - old[n].lineCount = 1; + for (CombinedOldImage o : old) { + o.startLine = -parseBase10(buf, ptr.value, ptr); + if (buf[ptr.value] == ',') { + o.lineCount = parseBase10(buf, ptr.value + 1, ptr); + } else { + o.lineCount = 1; + } } newStartLine = parseBase10(buf, ptr.value + 1, ptr); diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/revplot/AbstractPlotRenderer.java b/org.eclipse.jgit/src/org/eclipse/jgit/revplot/AbstractPlotRenderer.java index 58e2106fe2..b2f8d11921 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/revplot/AbstractPlotRenderer.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/revplot/AbstractPlotRenderer.java @@ -114,39 +114,39 @@ public abstract class AbstractPlotRenderer<TLane extends PlotLane, TColor> { drawLine(myColor, myLaneX, h, myLaneX, (h + dotSize) / 2, LINE_WIDTH); - for (int i = 0; i < commit.mergingLanes.length; i++) { - final TLane pLane = (TLane) commit.mergingLanes[i]; + for (PlotLane mergingLane : commit.mergingLanes) { + final TLane pLane = (TLane) mergingLane; final TColor pColor = laneColor(pLane); final int cx = laneC(pLane); - if (Math.abs(myLaneX - cx) > LANE_WIDTH) { final int ix; - if (myLaneX < cx) + if (myLaneX < cx) { ix = cx - LANE_WIDTH / 2; - else + } else { ix = cx + LANE_WIDTH / 2; + } drawLine(pColor, myLaneX, h / 2, ix, h / 2, LINE_WIDTH); drawLine(pColor, ix, h / 2, cx, h, LINE_WIDTH); } else drawLine(pColor, myLaneX, h / 2, cx, h, LINE_WIDTH); - maxCenter = Math.max(maxCenter, cx); } } if (commit.getChildCount() > 0) { - for (int i = 0; i < commit.forkingOffLanes.length; i++) { - final TLane childLane = (TLane) commit.forkingOffLanes[i]; + for (PlotLane forkingOffLane : commit.forkingOffLanes) { + final TLane childLane = (TLane) forkingOffLane; final TColor cColor = laneColor(childLane); final int cx = laneC(childLane); if (Math.abs(myLaneX - cx) > LANE_WIDTH) { final int ix; - if (myLaneX < cx) + if (myLaneX < cx) { ix = cx - LANE_WIDTH / 2; - else + } else { ix = cx + LANE_WIDTH / 2; + } drawLine(cColor, myLaneX, h / 2, ix, h / 2, LINE_WIDTH); drawLine(cColor, ix, h / 2, cx, 0, LINE_WIDTH); diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/BitmapCalculator.java b/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/BitmapCalculator.java new file mode 100644 index 0000000000..14e95670aa --- /dev/null +++ b/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/BitmapCalculator.java @@ -0,0 +1,136 @@ +/* + * Copyright (C) 2019, 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.revwalk; + +import static java.util.Objects.requireNonNull; + +import java.io.IOException; + +import org.eclipse.jgit.errors.IncorrectObjectTypeException; +import org.eclipse.jgit.errors.MissingObjectException; +import org.eclipse.jgit.internal.revwalk.AddToBitmapFilter; +import org.eclipse.jgit.lib.BitmapIndex; +import org.eclipse.jgit.lib.BitmapIndex.Bitmap; +import org.eclipse.jgit.lib.BitmapIndex.BitmapBuilder; +import org.eclipse.jgit.lib.ProgressMonitor; + +/** + * Calculate the bitmap indicating what other commits are reachable from certain + * commit. + * <p> + * This bitmap refers only to commits. For a bitmap with ALL objects reachable + * from certain object, see {@code BitmapWalker}. + */ +class BitmapCalculator { + + private final RevWalk walk; + private final BitmapIndex bitmapIndex; + + BitmapCalculator(RevWalk walk) throws IOException { + this.walk = walk; + this.bitmapIndex = requireNonNull( + walk.getObjectReader().getBitmapIndex()); + } + + /** + * Get the reachability bitmap from certain commit to other commits. + * <p> + * This will return a precalculated bitmap if available or walk building one + * until finding a precalculated bitmap (and returning the union). + * <p> + * Beware that the returned bitmap it is guaranteed to include ONLY the + * commits reachable from the initial commit. It COULD include other objects + * (because precalculated bitmaps have them) but caller shouldn't count on + * that. See {@link BitmapWalker} for a full reachability bitmap. + * + * @param start + * the commit. Use {@code walk.parseCommit(objectId)} to get this + * object from the id. + * @param pm + * progress monitor. Updated by one per commit browsed in the + * graph + * @return the bitmap of reachable commits (and maybe some extra objects) + * for the commit + * @throws MissingObjectException + * the supplied id doesn't exist + * @throws IncorrectObjectTypeException + * the supplied id doesn't refer to a commit or a tag + * @throws IOException + * if the walk cannot open a packfile or loose object + */ + BitmapBuilder getBitmap(RevCommit start, ProgressMonitor pm) + throws MissingObjectException, + IncorrectObjectTypeException, IOException { + Bitmap precalculatedBitmap = bitmapIndex.getBitmap(start); + if (precalculatedBitmap != null) { + return asBitmapBuilder(precalculatedBitmap); + } + + walk.reset(); + walk.sort(RevSort.TOPO); + walk.markStart(start); + // Unbounded walk. If the repo has bitmaps, it should bump into one at + // some point. + + BitmapBuilder bitmapResult = bitmapIndex.newBitmapBuilder(); + walk.setRevFilter(new AddToBitmapFilter(bitmapResult)); + while (walk.next() != null) { + // Iterate through all of the commits. The BitmapRevFilter does + // the work. + // + // filter.include returns true for commits that do not have + // a bitmap in bitmapIndex and are not reachable from a + // bitmap in bitmapIndex encountered earlier in the walk. + // Thus the number of commits returned by next() measures how + // much history was traversed without being able to make use + // of bitmaps. + pm.update(1); + } + + return bitmapResult; + } + + private BitmapBuilder asBitmapBuilder(Bitmap bitmap) { + return bitmapIndex.newBitmapBuilder().or(bitmap); + } +} diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/BitmappedReachabilityChecker.java b/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/BitmappedReachabilityChecker.java new file mode 100644 index 0000000000..6e510f677b --- /dev/null +++ b/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/BitmappedReachabilityChecker.java @@ -0,0 +1,120 @@ +/* + * Copyright (C) 2019, 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.revwalk; + +import java.io.IOException; +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; +import java.util.Optional; + +import org.eclipse.jgit.errors.IncorrectObjectTypeException; +import org.eclipse.jgit.errors.MissingObjectException; +import org.eclipse.jgit.lib.BitmapIndex.BitmapBuilder; +import org.eclipse.jgit.lib.NullProgressMonitor; + +/** + * Checks the reachability using bitmaps. + */ +class BitmappedReachabilityChecker implements ReachabilityChecker { + + private final RevWalk walk; + + /** + * @param walk + * walk on the repository to get or create the bitmaps for the + * commits. It must have bitmaps. + * @throws AssertionError + * runtime exception if walk is over a repository without + * bitmaps + * @throws IOException + * if the index or the object reader cannot be opened. + */ + public BitmappedReachabilityChecker(RevWalk walk) + throws IOException { + this.walk = walk; + if (walk.getObjectReader().getBitmapIndex() == null) { + throw new AssertionError( + "Trying to use bitmapped reachability check " //$NON-NLS-1$ + + "on a repository without bitmaps"); //$NON-NLS-1$ + } + } + + /** + * Check all targets are reachable from the starters. + * <p> + * In this implementation, it is recommended to put the most popular + * starters (e.g. refs/heads tips) at the beginning of the collection + */ + @Override + public Optional<RevCommit> areAllReachable(Collection<RevCommit> targets, + Collection<RevCommit> starters) throws MissingObjectException, + IncorrectObjectTypeException, IOException { + BitmapCalculator calculator = new BitmapCalculator(walk); + + /** + * Iterate over starters bitmaps and remove targets as they become + * reachable. + * + * Building the total starters bitmap has the same cost (iterating over + * all starters adding the bitmaps) and this gives us the chance to + * shorcut the loop. + * + * This is based on the assuption that most of the starters will have + * the reachability bitmap precalculated. If many require a walk, the + * walk.reset() could start to take too much time. + */ + List<RevCommit> remainingTargets = new ArrayList<>(targets); + for (RevCommit starter : starters) { + BitmapBuilder starterBitmap = calculator.getBitmap(starter, + NullProgressMonitor.INSTANCE); + remainingTargets.removeIf(starterBitmap::contains); + if (remainingTargets.isEmpty()) { + return Optional.empty(); + } + } + + return Optional.of(remainingTargets.get(0)); + } + +} diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/DepthGenerator.java b/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/DepthGenerator.java index 5154920393..5199a2927d 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/DepthGenerator.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/DepthGenerator.java @@ -108,12 +108,25 @@ class DepthGenerator extends Generator { // Begin by sucking out all of the source's commits, and // adding them to the pending queue + FIFORevQueue unshallowCommits = new FIFORevQueue(); for (;;) { RevCommit c = s.next(); if (c == null) break; - if (((DepthWalk.Commit) c).getDepth() == 0) + if (c.has(UNSHALLOW)) { + unshallowCommits.add(c); + } else if (((DepthWalk.Commit) c).getDepth() == 0) { pending.add(c); + } + } + // Move unshallow commits to the front so that the REINTERESTING flag + // carry over code is executed first. + for (;;) { + RevCommit c = unshallowCommits.next(); + if (c == null) { + break; + } + pending.unpop(c); } // Mark DEEPEN_NOT on all deepen-not commits and their ancestors. diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/FooterLine.java b/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/FooterLine.java index d6fed66702..84b6d2e481 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/FooterLine.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/FooterLine.java @@ -95,7 +95,7 @@ public final class FooterLine { for (int kPtr = 0; kPtr < len;) { byte b = buffer[bPtr++]; if ('A' <= b && b <= 'Z') - b += 'a' - 'A'; + b += (byte) ('a' - 'A'); if (b != kRaw[kPtr++]) return false; } diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/ObjectWalk.java b/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/ObjectWalk.java index fd578da333..b6c5810b32 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/ObjectWalk.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/ObjectWalk.java @@ -43,6 +43,7 @@ package org.eclipse.jgit.revwalk; +import static java.util.Objects.requireNonNull; import static org.eclipse.jgit.lib.Constants.OBJ_BLOB; import static org.eclipse.jgit.lib.Constants.OBJ_COMMIT; import static org.eclipse.jgit.lib.Constants.OBJ_TREE; @@ -97,6 +98,55 @@ public class ObjectWalk extends RevWalk { */ private static final int IN_PENDING = RevWalk.REWRITE; + /** + * When walking over a tree and blob graph, objects are usually marked as + * seen as they are visited and this "seen" status is checked upon the next + * visit. If they are already "seen" then they are not processed (returned + * by {@link ObjectWalk#nextObject()}) again. However, this behavior can be + * overridden by supplying a different implementation of this class. + * + * @since 5.4 + */ + public interface VisitationPolicy { + /** + * Whenever the rev or object walk reaches a Git object, if that object + * already exists as a RevObject, this method is called to determine if + * that object should be visited. + * + * @param o + * the object to check if it should be visited + * @return true if the object should be visited + */ + boolean shouldVisit(RevObject o); + + /** + * Called when an object is visited. + * + * @param o + * the object that was visited + */ + void visited(RevObject o); + } + + /** + * The default visitation policy: causes all objects to be visited exactly + * once. + * + * @since 5.4 + */ + public static final VisitationPolicy SIMPLE_VISITATION_POLICY = + new VisitationPolicy() { + @Override + public boolean shouldVisit(RevObject o) { + return (o.flags & SEEN) == 0; + } + + @Override + public void visited(RevObject o) { + o.flags |= SEEN; + } + }; + private List<RevObject> rootObjects; private BlockObjQueue pendingObjects; @@ -113,6 +163,8 @@ public class ObjectWalk extends RevWalk { private boolean boundary; + private VisitationPolicy visitationPolicy = SIMPLE_VISITATION_POLICY; + /** * Create a new revision and object walker for a given repository. * @@ -299,6 +351,18 @@ public class ObjectWalk extends RevWalk { objectFilter = newFilter != null ? newFilter : ObjectFilter.ALL; } + /** + * Sets the visitation policy to use during this walk. + * + * @param policy + * the {@code VisitationPolicy} to use + * @since 5.4 + */ + public void setVisitationPolicy(VisitationPolicy policy) { + assertNotStarted(); + visitationPolicy = requireNonNull(policy); + } + /** {@inheritDoc} */ @Override public RevCommit next() throws MissingObjectException, @@ -326,6 +390,17 @@ public class ObjectWalk extends RevWalk { } /** + * Skips the current tree such that {@link #nextObject()} does not return + * any objects inside it. This should be called right after + * {@link #nextObject()} returns the tree. + * + * @since 5.4 + */ + public void skipTree() { + currVisit.ptr = currVisit.buf.length; + } + + /** * Pop the next most recent object. * * @return next most recent object; null if traversal is over. @@ -357,24 +432,23 @@ public class ObjectWalk extends RevWalk { } RevObject obj = objects.get(idBuffer); - if (obj != null && (obj.flags & SEEN) != 0) + if (obj != null && !visitationPolicy.shouldVisit(obj)) continue; int mode = parseMode(buf, startPtr, ptr, tv); - int flags; switch (mode >>> TYPE_SHIFT) { case TYPE_FILE: case TYPE_SYMLINK: if (obj == null) { obj = new RevBlob(idBuffer); - obj.flags = SEEN; + visitationPolicy.visited(obj); objects.add(obj); return obj; } if (!(obj instanceof RevBlob)) throw new IncorrectObjectTypeException(obj, OBJ_BLOB); - obj.flags = flags = obj.flags | SEEN; - if ((flags & UNINTERESTING) == 0) + visitationPolicy.visited(obj); + if ((obj.flags & UNINTERESTING) == 0) return obj; if (boundary) return obj; @@ -383,17 +457,17 @@ public class ObjectWalk extends RevWalk { case TYPE_TREE: if (obj == null) { obj = new RevTree(idBuffer); - obj.flags = SEEN; + visitationPolicy.visited(obj); objects.add(obj); - return enterTree(obj); + return pushTree(obj); } if (!(obj instanceof RevTree)) throw new IncorrectObjectTypeException(obj, OBJ_TREE); - obj.flags = flags = obj.flags | SEEN; - if ((flags & UNINTERESTING) == 0) - return enterTree(obj); + visitationPolicy.visited(obj); + if ((obj.flags & UNINTERESTING) == 0) + return pushTree(obj); if (boundary) - return enterTree(obj); + return pushTree(obj); continue; case TYPE_GITLINK: @@ -419,30 +493,23 @@ public class ObjectWalk extends RevWalk { if (o == null) { return null; } - int flags = o.flags; - if ((flags & SEEN) != 0) + if (!visitationPolicy.shouldVisit(o)) { continue; - flags |= SEEN; - o.flags = flags; - if ((flags & UNINTERESTING) == 0 | boundary) { + } + visitationPolicy.visited(o); + if ((o.flags & UNINTERESTING) == 0 || boundary) { if (o instanceof RevTree) { - tv = newTreeVisit(o); - tv.parent = null; - currVisit = tv; + // The previous while loop should have exhausted the stack + // of trees. + assert currVisit == null; + + pushTree(o); } return o; } } } - private RevObject enterTree(RevObject obj) throws MissingObjectException, - IncorrectObjectTypeException, IOException { - TreeVisit tv = newTreeVisit(obj); - tv.parent = currVisit; - currVisit = tv; - return obj; - } - private static int findObjectId(byte[] buf, int ptr) { // Skip over the mode and name until the NUL before the ObjectId // can be located. Skip the NUL as the function returns. @@ -582,6 +649,17 @@ public class ObjectWalk extends RevWalk { } /** + * @return the current traversal depth from the root tree object + * @since 5.4 + */ + public int getTreeDepth() { + if (currVisit == null) { + return 0; + } + return currVisit.depth; + } + + /** * Get the current object's path hash code. * <p> * This method computes a hash code on the fly for this path, the hash is @@ -768,7 +846,7 @@ public class ObjectWalk extends RevWalk { } } - private TreeVisit newTreeVisit(RevObject obj) throws LargeObjectException, + private RevObject pushTree(RevObject obj) throws LargeObjectException, MissingObjectException, IncorrectObjectTypeException, IOException { TreeVisit tv = freeVisit; if (tv != null) { @@ -782,7 +860,15 @@ public class ObjectWalk extends RevWalk { } tv.obj = obj; tv.buf = reader.open(obj, OBJ_TREE).getCachedBytes(); - return tv; + tv.parent = currVisit; + currVisit = tv; + if (tv.parent == null) { + tv.depth = 1; + } else { + tv.depth = tv.parent.depth + 1; + } + + return obj; } private void releaseTreeVisit(TreeVisit tv) { @@ -812,5 +898,8 @@ public class ObjectWalk extends RevWalk { /** Number of bytes in the path leading up to this tree. */ int pathLen; + + /** Number of levels deep from the root tree. 0 for root tree. */ + int depth; } } diff --git a/org.eclipse.jgit.ssh.apache/src/org/eclipse/jgit/internal/transport/sshd/JGitPublicKeyAuthFactory.java b/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/PedestrianReachabilityChecker.java index 0b3de4ace3..bba3c5cff3 100644 --- a/org.eclipse.jgit.ssh.apache/src/org/eclipse/jgit/internal/transport/sshd/JGitPublicKeyAuthFactory.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/PedestrianReachabilityChecker.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2018, Thomas Wolf <thomas.wolf@paranor.ch> + * Copyright (C) 2019, Google LLC. * and other copyright owners as documented in the project's IP log. * * This program and the accompanying materials are made available @@ -40,44 +40,57 @@ * 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.transport.sshd; +package org.eclipse.jgit.revwalk; -import java.util.List; +import java.io.IOException; +import java.util.Collection; +import java.util.Optional; -import org.apache.sshd.client.auth.AbstractUserAuthFactory; -import org.apache.sshd.client.auth.UserAuth; -import org.apache.sshd.client.auth.pubkey.UserAuthPublicKeyFactory; -import org.apache.sshd.common.NamedFactory; -import org.apache.sshd.common.signature.Signature; -import org.apache.sshd.common.signature.SignatureFactoriesManager; +import org.eclipse.jgit.errors.IncorrectObjectTypeException; +import org.eclipse.jgit.errors.MissingObjectException; /** - * A customized authentication factory for public key user authentication. The - * default implementation {@link UserAuthPublicKeyFactory} ends up doing some - * crazy stream "magic" that loads too many keys too early. + * Checks the reachability walking the graph from the starters towards the + * target. */ -public class JGitPublicKeyAuthFactory extends AbstractUserAuthFactory - implements SignatureFactoriesManager { +class PedestrianReachabilityChecker implements ReachabilityChecker { - /** The singleton {@link JGitPublicKeyAuthFactory}. */ - public static final JGitPublicKeyAuthFactory INSTANCE = new JGitPublicKeyAuthFactory(); + private final boolean topoSort; - private JGitPublicKeyAuthFactory() { - super(UserAuthPublicKeyFactory.NAME); - } + private final RevWalk walk; - @Override - public UserAuth create() { - return new JGitPublicKeyAuthentication(getSignatureFactories()); + /** + * New instance of the reachability checker using a existing walk. + * + * @param topoSort + * walk commits in topological order + * @param walk + * RevWalk instance to reuse. Caller retains ownership. + */ + public PedestrianReachabilityChecker(boolean topoSort, + RevWalk walk) { + this.topoSort = topoSort; + this.walk = walk; } @Override - public List<NamedFactory<Signature>> getSignatureFactories() { - return null; - } + public Optional<RevCommit> areAllReachable(Collection<RevCommit> targets, + Collection<RevCommit> starters) + throws MissingObjectException, IncorrectObjectTypeException, + IOException { + walk.reset(); + if (topoSort) { + walk.sort(RevSort.TOPO); + } - @Override - public void setSignatureFactories(List<NamedFactory<Signature>> factories) { - throw new UnsupportedOperationException(); + for (RevCommit target: targets) { + walk.markStart(target); + } + + for (RevCommit starter : starters) { + walk.markUninteresting(starter); + } + + return Optional.ofNullable(walk.next()); } } diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/ReachabilityChecker.java b/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/ReachabilityChecker.java new file mode 100644 index 0000000000..2ed06d1769 --- /dev/null +++ b/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/ReachabilityChecker.java @@ -0,0 +1,90 @@ +/* + * Copyright (C) 2019, 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.revwalk; + +import java.io.IOException; +import java.util.Collection; +import java.util.Optional; + +import org.eclipse.jgit.errors.IncorrectObjectTypeException; +import org.eclipse.jgit.errors.MissingObjectException; + +/** + * Check if a commit is reachable from a collection of starting commits. + * <p> + * Note that this checks the reachability of commits (and tags). Trees, blobs or + * any other object will cause IncorrectObjectTypeException exceptions. + * + * @since 5.4 + */ +public interface ReachabilityChecker { + + /** + * Check if all targets are reachable from the {@code starter} commits. + * <p> + * Caller should parse the objectIds (preferably with + * {@code walk.parseCommit()} and handle missing/incorrect type objects + * before calling this method. + * + * @param targets + * commits to reach. + * @param starters + * known starting points. + * @return An unreachable target if at least one of the targets is + * unreachable. An empty optional if all targets are reachable from + * the starters. + * + * @throws MissingObjectException + * if any of the incoming objects doesn't exist in the + * repository. + * @throws IncorrectObjectTypeException + * if any of the incoming objects is not a commit or a tag. + * @throws IOException + * if any of the underlying indexes or readers can not be + * opened. + */ + Optional<RevCommit> areAllReachable(Collection<RevCommit> targets, + Collection<RevCommit> starters) + throws MissingObjectException, IncorrectObjectTypeException, + IOException; +} 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 0a43e8fb1a..f50d189ce5 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/RevWalk.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/RevWalk.java @@ -72,6 +72,7 @@ import org.eclipse.jgit.lib.ObjectReader; import org.eclipse.jgit.lib.Repository; import org.eclipse.jgit.revwalk.filter.RevFilter; import org.eclipse.jgit.treewalk.filter.TreeFilter; +import org.eclipse.jgit.util.References; /** * Walks a commit graph and produces the matching commits in order. @@ -250,6 +251,23 @@ public class RevWalk implements Iterable<RevCommit>, AutoCloseable { } /** + * Get a reachability checker for commits over this revwalk. + * + * @return the most efficient reachability checker for this repository. + * @throws IOException + * if it cannot open any of the underlying indices. + * + * @since 5.4 + */ + public ReachabilityChecker createReachabilityChecker() throws IOException { + if (reader.getBitmapIndex() != null) { + return new BitmappedReachabilityChecker(this); + } + + return new PedestrianReachabilityChecker(true, this); + } + + /** * {@inheritDoc} * <p> * Release any resources used by this walker's reader. @@ -416,9 +434,11 @@ public class RevWalk implements Iterable<RevCommit>, AutoCloseable { markStart(tip); markStart(base); RevCommit mergeBase; - while ((mergeBase = next()) != null) - if (mergeBase == base) + while ((mergeBase = next()) != null) { + if (References.isSameObject(mergeBase, base)) { return true; + } + } return false; } finally { filter = oldRF; @@ -506,7 +526,7 @@ public class RevWalk implements Iterable<RevCommit>, AutoCloseable { if (sorting.size() > 1) sorting.remove(RevSort.NONE); - else if (sorting.size() == 0) + else if (sorting.isEmpty()) sorting.add(RevSort.NONE); } diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/RevWalkUtils.java b/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/RevWalkUtils.java index f1252a4c4b..2b721b8877 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/RevWalkUtils.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/RevWalkUtils.java @@ -50,6 +50,9 @@ import java.util.List; import org.eclipse.jgit.errors.IncorrectObjectTypeException; import org.eclipse.jgit.errors.MissingObjectException; +import org.eclipse.jgit.internal.JGitText; +import org.eclipse.jgit.lib.NullProgressMonitor; +import org.eclipse.jgit.lib.ProgressMonitor; import org.eclipse.jgit.lib.Ref; /** @@ -130,7 +133,7 @@ public final class RevWalkUtils { /** * Find the list of branches a given commit is reachable from when following - * parent.s + * parents. * <p> * Note that this method calls * {@link org.eclipse.jgit.revwalk.RevWalk#reset()} at the beginning. @@ -153,15 +156,51 @@ public final class RevWalkUtils { RevWalk revWalk, Collection<Ref> refs) throws MissingObjectException, IncorrectObjectTypeException, IOException { + return findBranchesReachableFrom(commit, revWalk, refs, + NullProgressMonitor.INSTANCE); + } + + /** + * Find the list of branches a given commit is reachable from when following + * parents. + * <p> + * Note that this method calls + * {@link org.eclipse.jgit.revwalk.RevWalk#reset()} at the beginning. + * <p> + * In order to improve performance this method assumes clock skew among + * committers is never larger than 24 hours. + * + * @param commit + * the commit we are looking at + * @param revWalk + * The RevWalk to be used. + * @param refs + * the set of branches we want to see reachability from + * @param monitor + * the callback for progress and cancellation + * @return the list of branches a given commit is reachable from + * @throws org.eclipse.jgit.errors.MissingObjectException + * @throws org.eclipse.jgit.errors.IncorrectObjectTypeException + * @throws java.io.IOException + * @since 5.4 + */ + public static List<Ref> findBranchesReachableFrom(RevCommit commit, + RevWalk revWalk, Collection<Ref> refs, ProgressMonitor monitor) + throws MissingObjectException, IncorrectObjectTypeException, + IOException { // Make sure commit is from the same RevWalk commit = revWalk.parseCommit(commit.getId()); revWalk.reset(); List<Ref> result = new ArrayList<>(); - + monitor.beginTask(JGitText.get().searchForReachableBranches, + refs.size()); final int SKEW = 24*3600; // one day clock skew for (Ref ref : refs) { + if (monitor.isCancelled()) + return result; + monitor.update(1); RevObject maybehead = revWalk.parseAny(ref.getObjectId()); if (!(maybehead instanceof RevCommit)) continue; @@ -176,6 +215,7 @@ public final class RevWalkUtils { if (revWalk.isMergedInto(commit, headCommit)) result.add(ref); } + monitor.endTask(); return result; } diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/filter/RevFlagFilter.java b/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/filter/RevFlagFilter.java index c67c44b216..c3dc3dea66 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/filter/RevFlagFilter.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/filter/RevFlagFilter.java @@ -44,6 +44,7 @@ package org.eclipse.jgit.revwalk.filter; import java.io.IOException; +import java.util.Arrays; import org.eclipse.jgit.errors.IncorrectObjectTypeException; import org.eclipse.jgit.errors.MissingObjectException; @@ -78,8 +79,7 @@ public abstract class RevFlagFilter extends RevFilter { */ public static RevFilter hasAll(RevFlag... a) { final RevFlagSet set = new RevFlagSet(); - for (RevFlag flag : a) - set.add(flag); + set.addAll(Arrays.asList(a)); return new HasAll(set); } @@ -103,8 +103,7 @@ public abstract class RevFlagFilter extends RevFilter { */ public static RevFilter hasAny(RevFlag... a) { final RevFlagSet set = new RevFlagSet(); - for (RevFlag flag : a) - set.add(flag); + set.addAll(Arrays.asList(a)); return new HasAny(set); } 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 bdbd7c9072..5bb8153a58 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 @@ -148,7 +148,8 @@ public class FileBasedConfig extends StoredConfig { */ @Override public void load() throws IOException, ConfigInvalidException { - final int maxStaleRetries = 5; + final int maxRetries = 5; + int retryDelayMillis = 20; int retries = 0; while (true) { final FileSnapshot oldSnapshot = snapshot; @@ -179,6 +180,22 @@ public class FileBasedConfig extends StoredConfig { } return; } catch (FileNotFoundException noFile) { + // might be locked by another process (see exception Javadoc) + if (retries < maxRetries && configFile.exists()) { + if (LOG.isDebugEnabled()) { + LOG.debug(MessageFormat.format( + JGitText.get().configHandleMayBeLocked, + Integer.valueOf(retries)), noFile); + } + try { + Thread.sleep(retryDelayMillis); + } catch (InterruptedException e) { + Thread.currentThread().interrupt(); + } + retries++; + retryDelayMillis *= 2; // max wait 1260 ms + continue; + } if (configFile.exists()) { throw noFile; } @@ -187,7 +204,7 @@ public class FileBasedConfig extends StoredConfig { return; } catch (IOException e) { if (FileUtils.isStaleFileHandle(e) - && retries < maxStaleRetries) { + && retries < maxRetries) { if (LOG.isDebugEnabled()) { LOG.debug(MessageFormat.format( JGitText.get().configHandleIsStale, diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/storage/pack/PackStatistics.java b/org.eclipse.jgit/src/org/eclipse/jgit/storage/pack/PackStatistics.java index 68878e5a61..e6e3d4fb12 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/storage/pack/PackStatistics.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/storage/pack/PackStatistics.java @@ -266,6 +266,10 @@ public class PackStatistics { /** Time in ms spent writing the pack. */ public long timeWriting; + /** Number of trees traversed in the walk when writing the pack. + * @since 5.4*/ + public long treesTraversed; + /** * Statistics about each object type in the pack (commits, tags, trees * and blobs.) @@ -586,6 +590,14 @@ public class PackStatistics { } /** + * @return number of trees traversed in the walk when writing the pack. + * @since 5.4 + */ + public long getTreesTraversed() { + return statistics.treesTraversed; + } + + /** * Get total time spent processing this pack. * * @return total time spent processing this pack. diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/submodule/SubmoduleWalk.java b/org.eclipse.jgit/src/org/eclipse/jgit/submodule/SubmoduleWalk.java index ce8995ad8f..e5559dea09 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/submodule/SubmoduleWalk.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/submodule/SubmoduleWalk.java @@ -144,7 +144,8 @@ public class SubmoduleWalk implements AutoCloseable { * path and .gitmodules at the root. * @param path * a {@link java.lang.String} object. - * @return generator at given path, null if no submodule at given path + * @return generator at given path. The caller is responsible for calling + * {@link #close()}. Null if no submodule at given path. * @throws java.io.IOException */ public static SubmoduleWalk forPath(Repository repository, @@ -177,7 +178,8 @@ public class SubmoduleWalk implements AutoCloseable { * path and .gitmodules at the root. * @param path * a {@link java.lang.String} object. - * @return generator at given path, null if no submodule at given path + * @return generator at given path. The caller is responsible for calling + * {@link #close()}. Null if no submodule at given path. * @throws java.io.IOException */ public static SubmoduleWalk forPath(Repository repository, diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/transport/BasePackConnection.java b/org.eclipse.jgit/src/org/eclipse/jgit/transport/BasePackConnection.java index fcf78ac7b9..e8724b72db 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/transport/BasePackConnection.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/transport/BasePackConnection.java @@ -53,6 +53,7 @@ import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.text.MessageFormat; +import java.util.Arrays; import java.util.HashSet; import java.util.LinkedHashMap; import java.util.Set; @@ -182,10 +183,7 @@ abstract class BasePackConnection extends BaseConnection { } catch (TransportException err) { close(); throw err; - } catch (IOException err) { - close(); - throw new TransportException(err.getMessage(), err); - } catch (RuntimeException err) { + } catch (IOException | RuntimeException err) { close(); throw new TransportException(err.getMessage(), err); } @@ -203,7 +201,7 @@ abstract class BasePackConnection extends BaseConnection { throw noRepository(); throw eof; } - if (line == PacketLineIn.END) + if (PacketLineIn.isEnd(line)) break; if (line.startsWith("ERR ")) { //$NON-NLS-1$ @@ -217,8 +215,8 @@ abstract class BasePackConnection extends BaseConnection { if (nul >= 0) { // The first line (if any) may contain "hidden" // capability values after a NUL byte. - for (String c : line.substring(nul + 1).split(" ")) //$NON-NLS-1$ - remoteCapablities.add(c); + remoteCapablities.addAll( + Arrays.asList(line.substring(nul + 1).split(" "))); //$NON-NLS-1$ line = line.substring(0, nul); } } 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 ed7465c82a..57d6bc2466 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/transport/BasePackFetchConnection.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/transport/BasePackFetchConnection.java @@ -245,8 +245,12 @@ public abstract class BasePackFetchConnection extends BasePackConnection private PacketLineOut pckState; - /** If not -1, the maximum blob size to be sent to the server. */ - private final long filterBlobLimit; + /** + * Either FilterSpec.NO_FILTER for a filter that doesn't filter + * anything, or a filter that indicates what and what not to send to the + * server. + */ + private final FilterSpec filterSpec; /** * Create a new connection to fetch using the native git transport. @@ -268,10 +272,11 @@ public abstract class BasePackFetchConnection extends BasePackConnection includeTags = transport.getTagOpt() != TagOpt.NO_TAGS; thinPack = transport.isFetchThin(); - filterBlobLimit = transport.getFilterBlobLimit(); + filterSpec = transport.getFilterSpec(); if (local != null) { walk = new RevWalk(local); + walk.setRetainBody(false); reachableCommits = new RevCommitList<>(); REACHABLE = walk.newFlag("REACHABLE"); //$NON-NLS-1$ COMMON = walk.newFlag("COMMON"); //$NON-NLS-1$ @@ -395,10 +400,7 @@ public abstract class BasePackFetchConnection extends BasePackConnection } catch (CancelledException ce) { close(); return; // Caller should test (or just know) this themselves. - } catch (IOException err) { - close(); - throw new TransportException(err.getMessage(), err); - } catch (RuntimeException err) { + } catch (IOException | RuntimeException err) { close(); throw new TransportException(err.getMessage(), err); } @@ -520,10 +522,8 @@ public abstract class BasePackFetchConnection extends BasePackConnection if (first) { return false; } - if (filterBlobLimit == 0) { - p.writeString(OPTION_FILTER + " blob:none"); //$NON-NLS-1$ - } else if (filterBlobLimit > 0) { - p.writeString(OPTION_FILTER + " blob:limit=" + filterBlobLimit); //$NON-NLS-1$ + if (!filterSpec.isNoOp()) { + p.writeString(filterSpec.filterLine()); } p.end(); outNeedsEnd = false; @@ -565,7 +565,7 @@ public abstract class BasePackFetchConnection extends BasePackConnection OPTION_MULTI_ACK_DETAILED)); } - if (filterBlobLimit >= 0 && !wantCapability(line, OPTION_FILTER)) { + if (!filterSpec.isNoOp() && !wantCapability(line, OPTION_FILTER)) { throw new PackProtocolException(uri, JGitText.get().filterRequiresCapability); } @@ -670,14 +670,14 @@ public abstract class BasePackFetchConnection extends BasePackConnection } } - if (noDone & receivedReady) { + if (noDone && receivedReady) { break SEND_HAVES; } if (statelessRPC) { 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 diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/transport/BasePackPushConnection.java b/org.eclipse.jgit/src/org/eclipse/jgit/transport/BasePackPushConnection.java index 847e901980..35ea35ecb8 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/transport/BasePackPushConnection.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/transport/BasePackPushConnection.java @@ -383,8 +383,7 @@ public abstract class BasePackPushConnection extends BasePackConnection implemen JGitText.get().errorOccurredDuringUnpackingOnTheRemoteEnd, unpackStatus)); } - String refLine; - while ((refLine = pckIn.readString()) != PacketLineIn.END) { + for (String refLine : pckIn.readStrings()) { boolean ok = false; int refNameEnd = -1; if (refLine.startsWith("ok ")) { //$NON-NLS-1$ diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/transport/BaseReceivePack.java b/org.eclipse.jgit/src/org/eclipse/jgit/transport/BaseReceivePack.java index 6f17620d91..e402de0158 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/transport/BaseReceivePack.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/transport/BaseReceivePack.java @@ -314,6 +314,7 @@ public abstract class BaseReceivePack { protected BaseReceivePack(Repository into) { db = into; walk = new RevWalk(db); + walk.setRetainBody(false); TransferConfig tc = db.getConfig().get(TransferConfig.KEY); objectChecker = tc.newReceiveObjectChecker(); @@ -1240,7 +1241,7 @@ public abstract class BaseReceivePack { adv.advertiseCapability(CAPABILITY_PUSH_OPTIONS); } adv.advertiseCapability(OPTION_AGENT, UserAgent.get()); - adv.send(getAdvertisedOrDefaultRefs()); + adv.send(getAdvertisedOrDefaultRefs().values()); for (ObjectId obj : advertisedHaves) adv.advertiseHave(obj); if (adv.isEmpty()) @@ -1281,7 +1282,7 @@ public abstract class BaseReceivePack { return; throw eof; } - if (line == PacketLineIn.END) { + if (PacketLineIn.isEnd(line)) { break; } 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 84a0972723..6cf75031cd 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/transport/BundleFetchConnection.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/transport/BundleFetchConnection.java @@ -112,10 +112,7 @@ class BundleFetchConnection extends BaseFetchConnection { } catch (TransportException err) { close(); throw err; - } catch (IOException err) { - close(); - throw new TransportException(transport.uri, err.getMessage(), err); - } catch (RuntimeException err) { + } catch (IOException | RuntimeException err) { close(); throw new TransportException(transport.uri, err.getMessage(), err); } @@ -205,10 +202,7 @@ class BundleFetchConnection extends BaseFetchConnection { packLock = parser.parse(NullProgressMonitor.INSTANCE); ins.flush(); } - } catch (IOException err) { - close(); - throw new TransportException(transport.uri, err.getMessage(), err); - } catch (RuntimeException err) { + } catch (IOException | RuntimeException err) { close(); throw new TransportException(transport.uri, err.getMessage(), err); } 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 56aaede80d..d1db51eca6 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/transport/BundleWriter.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/transport/BundleWriter.java @@ -227,10 +227,11 @@ public class BundleWriter { exc.add(r.getId()); packWriter.setIndexDisabled(true); packWriter.setDeltaBaseAsOffset(true); - packWriter.setThin(exc.size() > 0); + packWriter.setThin(!exc.isEmpty()); packWriter.setReuseValidatingObjects(false); - if (exc.size() == 0) + if (exc.isEmpty()) { packWriter.setTagTargets(tagTargets); + } packWriter.preparePack(monitor, inc, exc); final Writer w = new OutputStreamWriter(os, UTF_8); diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/transport/Daemon.java b/org.eclipse.jgit/src/org/eclipse/jgit/transport/Daemon.java index 7289ce7b6c..2b27df2b84 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/transport/Daemon.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/transport/Daemon.java @@ -115,36 +115,26 @@ public class Daemon { repositoryResolver = (RepositoryResolver<DaemonClient>) RepositoryResolver.NONE; - uploadPackFactory = new UploadPackFactory<DaemonClient>() { - @Override - public UploadPack create(DaemonClient req, Repository db) - throws ServiceNotEnabledException, - ServiceNotAuthorizedException { - UploadPack up = new UploadPack(db); - up.setTimeout(getTimeout()); - up.setPackConfig(getPackConfig()); - return up; - } + uploadPackFactory = (DaemonClient req, Repository db) -> { + UploadPack up = new UploadPack(db); + up.setTimeout(getTimeout()); + up.setPackConfig(getPackConfig()); + return up; }; - receivePackFactory = new ReceivePackFactory<DaemonClient>() { - @Override - public ReceivePack create(DaemonClient req, Repository db) - throws ServiceNotEnabledException, - ServiceNotAuthorizedException { - ReceivePack rp = new ReceivePack(db); - - InetAddress peer = req.getRemoteAddress(); - String host = peer.getCanonicalHostName(); - if (host == null) - host = peer.getHostAddress(); - String name = "anonymous"; //$NON-NLS-1$ - String email = name + "@" + host; //$NON-NLS-1$ - rp.setRefLogIdent(new PersonIdent(name, email)); - rp.setTimeout(getTimeout()); - - return rp; - } + receivePackFactory = (DaemonClient req, Repository db) -> { + ReceivePack rp = new ReceivePack(db); + + InetAddress peer = req.getRemoteAddress(); + String host = peer.getCanonicalHostName(); + if (host == null) + host = peer.getHostAddress(); + String name = "anonymous"; //$NON-NLS-1$ + String email = name + "@" + host; //$NON-NLS-1$ + rp.setRefLogIdent(new PersonIdent(name, email)); + rp.setTimeout(getTimeout()); + + return rp; }; services = new DaemonService[] { diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/transport/FetchProcess.java b/org.eclipse.jgit/src/org/eclipse/jgit/transport/FetchProcess.java index 681ae125cb..e584440b3f 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/transport/FetchProcess.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/transport/FetchProcess.java @@ -200,6 +200,7 @@ class FetchProcess { .setAllowNonFastForwards(true) .setRefLogMessage("fetch", true); //$NON-NLS-1$ try (RevWalk walk = new RevWalk(transport.local)) { + walk.setRetainBody(false); if (monitor instanceof BatchingProgressMonitor) { ((BatchingProgressMonitor) monitor).setDelayStart( 250, TimeUnit.MILLISECONDS); diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/transport/FetchRequest.java b/org.eclipse.jgit/src/org/eclipse/jgit/transport/FetchRequest.java index 40ba3a3ad2..4dd7d6ed8b 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/transport/FetchRequest.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/transport/FetchRequest.java @@ -62,7 +62,7 @@ abstract class FetchRequest { final Set<ObjectId> clientShallowCommits; - final long filterBlobLimit; + final FilterSpec filterSpec; final Set<String> clientCapabilities; @@ -82,8 +82,8 @@ abstract class FetchRequest { * how deep to go in the tree * @param clientShallowCommits * commits the client has without history - * @param filterBlobLimit - * to exclude blobs on certain conditions + * @param filterSpec + * the filter spec * @param clientCapabilities * capabilities sent in the request * @param deepenNotRefs @@ -96,13 +96,14 @@ abstract class FetchRequest { * agent as reported by the client in the request body */ FetchRequest(@NonNull Set<ObjectId> wantIds, int depth, - @NonNull Set<ObjectId> clientShallowCommits, long filterBlobLimit, + @NonNull Set<ObjectId> clientShallowCommits, + @NonNull FilterSpec filterSpec, @NonNull Set<String> clientCapabilities, int deepenSince, @NonNull List<String> deepenNotRefs, @Nullable String agent) { this.wantIds = requireNonNull(wantIds); this.depth = depth; this.clientShallowCommits = requireNonNull(clientShallowCommits); - this.filterBlobLimit = filterBlobLimit; + this.filterSpec = requireNonNull(filterSpec); this.clientCapabilities = requireNonNull(clientCapabilities); this.deepenSince = deepenSince; this.deepenNotRefs = requireNonNull(deepenNotRefs); @@ -137,10 +138,11 @@ abstract class FetchRequest { } /** - * @return the blob limit set in a "filter" line (-1 if not set) + * @return the filter spec given in a "filter" line */ - long getFilterBlobLimit() { - return filterBlobLimit; + @NonNull + FilterSpec getFilterSpec() { + return filterSpec; } /** @@ -191,4 +193,4 @@ abstract class FetchRequest { String getAgent() { return agent; } -}
\ No newline at end of file +} diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/transport/FetchV0Request.java b/org.eclipse.jgit/src/org/eclipse/jgit/transport/FetchV0Request.java index 05f4a8155f..231ab9f2cc 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/transport/FetchV0Request.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/transport/FetchV0Request.java @@ -42,6 +42,8 @@ */ package org.eclipse.jgit.transport; +import static java.util.Objects.requireNonNull; + import java.util.Collection; import java.util.Collections; import java.util.HashSet; @@ -57,10 +59,11 @@ import org.eclipse.jgit.lib.ObjectId; final class FetchV0Request extends FetchRequest { FetchV0Request(@NonNull Set<ObjectId> wantIds, int depth, - @NonNull Set<ObjectId> clientShallowCommits, long filterBlobLimit, + @NonNull Set<ObjectId> clientShallowCommits, + @NonNull FilterSpec filterSpec, @NonNull Set<String> clientCapabilities, @Nullable String agent) { - super(wantIds, depth, clientShallowCommits, filterBlobLimit, - clientCapabilities, 0, Collections.emptyList(), agent); + super(wantIds, depth, clientShallowCommits, filterSpec, + clientCapabilities, 0, Collections.emptyList(), agent); } static final class Builder { @@ -71,7 +74,7 @@ final class FetchV0Request extends FetchRequest { final Set<ObjectId> clientShallowCommits = new HashSet<>(); - long filterBlobLimit = -1; + FilterSpec filterSpec = FilterSpec.NO_FILTER; final Set<String> clientCaps = new HashSet<>(); @@ -129,18 +132,18 @@ final class FetchV0Request extends FetchRequest { } /** - * @param filterBlobLim - * blob limit set in a "filter" line + * @param filter + * the filter set in a filter line * @return this builder */ - Builder setFilterBlobLimit(long filterBlobLim) { - filterBlobLimit = filterBlobLim; + Builder setFilterSpec(@NonNull FilterSpec filter) { + filterSpec = requireNonNull(filter); return this; } FetchV0Request build() { return new FetchV0Request(wantIds, depth, clientShallowCommits, - filterBlobLimit, clientCaps, agent); + filterSpec, clientCaps, agent); } } diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/transport/FetchV2Request.java b/org.eclipse.jgit/src/org/eclipse/jgit/transport/FetchV2Request.java index ac6361cdeb..6c24269095 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/transport/FetchV2Request.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/transport/FetchV2Request.java @@ -77,11 +77,12 @@ public final class FetchV2Request extends FetchRequest { @NonNull Set<ObjectId> wantIds, @NonNull Set<ObjectId> clientShallowCommits, int deepenSince, @NonNull List<String> deepenNotRefs, int depth, - long filterBlobLimit, + @NonNull FilterSpec filterSpec, boolean doneReceived, @NonNull Set<String> clientCapabilities, @Nullable String agent, @NonNull List<String> serverOptions) { - super(wantIds, depth, clientShallowCommits, filterBlobLimit, - clientCapabilities, deepenSince, deepenNotRefs, agent); + super(wantIds, depth, clientShallowCommits, filterSpec, + clientCapabilities, deepenSince, + deepenNotRefs, agent); this.peerHas = requireNonNull(peerHas); this.wantedRefs = requireNonNull(wantedRefs); this.doneReceived = doneReceived; @@ -98,9 +99,11 @@ public final class FetchV2Request extends FetchRequest { /** * @return list of references received in "want-ref" lines + * + * @since 5.4 */ @NonNull - List<String> getWantedRefs() { + public List<String> getWantedRefs() { return wantedRefs; } @@ -147,7 +150,7 @@ public final class FetchV2Request extends FetchRequest { int deepenSince; - long filterBlobLimit = -1; + FilterSpec filterSpec = FilterSpec.NO_FILTER; boolean doneReceived; @@ -266,12 +269,12 @@ public final class FetchV2Request extends FetchRequest { } /** - * @param filterBlobLim - * set in a "filter" line + * @param filter + * spec set in a "filter" line * @return this builder */ - Builder setFilterBlobLimit(long filterBlobLim) { - filterBlobLimit = filterBlobLim; + Builder setFilterSpec(@NonNull FilterSpec filter) { + filterSpec = requireNonNull(filter); return this; } @@ -320,7 +323,7 @@ public final class FetchV2Request extends FetchRequest { FetchV2Request build() { return new FetchV2Request(peerHas, wantedRefs, wantIds, clientShallowCommits, deepenSince, deepenNotRefs, - depth, filterBlobLimit, doneReceived, clientCapabilities, + depth, filterSpec, doneReceived, clientCapabilities, agent, Collections.unmodifiableList(serverOptions)); } } diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/transport/FilterSpec.java b/org.eclipse.jgit/src/org/eclipse/jgit/transport/FilterSpec.java new file mode 100644 index 0000000000..a663c9b470 --- /dev/null +++ b/org.eclipse.jgit/src/org/eclipse/jgit/transport/FilterSpec.java @@ -0,0 +1,192 @@ +/* + * Copyright (C) 2019, 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.text.MessageFormat; + +import org.eclipse.jgit.annotations.Nullable; +import org.eclipse.jgit.errors.PackProtocolException; +import org.eclipse.jgit.internal.JGitText; + +/** + * Represents either a filter specified in a protocol "filter" line, or a + * placeholder to indicate no filtering. + * + * @since 5.4 + */ +public final class FilterSpec { + + private final long blobLimit; + + private final long treeDepthLimit; + + private FilterSpec(long blobLimit, long treeDepthLimit) { + this.blobLimit = blobLimit; + this.treeDepthLimit = treeDepthLimit; + } + + /** + * Process the content of "filter" line from the protocol. It has a shape + * like: + * + * <ul> + * <li>"blob:none" + * <li>"blob:limit=N", with N >= 0 + * <li>"tree:DEPTH", with DEPTH >= 0 + * </ul> + * + * @param filterLine + * the content of the "filter" line in the protocol + * @return a FilterSpec representing the given filter + * @throws PackProtocolException + * invalid filter because due to unrecognized format or + * negative/non-numeric filter. + */ + public static FilterSpec fromFilterLine(String filterLine) + throws PackProtocolException { + if (filterLine.equals("blob:none")) { //$NON-NLS-1$ + return FilterSpec.withBlobLimit(0); + } else if (filterLine.startsWith("blob:limit=")) { //$NON-NLS-1$ + long blobLimit = -1; + try { + blobLimit = Long + .parseLong(filterLine.substring("blob:limit=".length())); //$NON-NLS-1$ + } catch (NumberFormatException e) { + // Do not change blobLimit so that we throw a + // PackProtocolException later. + } + if (blobLimit >= 0) { + return FilterSpec.withBlobLimit(blobLimit); + } + } else if (filterLine.startsWith("tree:")) { //$NON-NLS-1$ + long treeDepthLimit = -1; + try { + treeDepthLimit = Long + .parseLong(filterLine.substring("tree:".length())); //$NON-NLS-1$ + } catch (NumberFormatException e) { + // Do not change blobLimit so that we throw a + // PackProtocolException later. + } + if (treeDepthLimit >= 0) { + return FilterSpec.withTreeDepthLimit(treeDepthLimit); + } + } + + // Did not match any known filter format. + throw new PackProtocolException( + MessageFormat.format(JGitText.get().invalidFilter, filterLine)); + } + + /** + * @param blobLimit + * the blob limit in a "blob:[limit]" or "blob:none" filter line + * @return a filter spec which filters blobs above a certain size + */ + static FilterSpec withBlobLimit(long blobLimit) { + if (blobLimit < 0) { + throw new IllegalArgumentException( + "blobLimit cannot be negative: " + blobLimit); //$NON-NLS-1$ + } + return new FilterSpec(blobLimit, -1); + } + + /** + * @param treeDepthLimit + * the tree depth limit in a "tree:[depth]" filter line + * @return a filter spec which filters blobs and trees beyond a certain tree + * depth + */ + static FilterSpec withTreeDepthLimit(long treeDepthLimit) { + if (treeDepthLimit < 0) { + throw new IllegalArgumentException( + "treeDepthLimit cannot be negative: " + treeDepthLimit); //$NON-NLS-1$ + } + return new FilterSpec(-1, treeDepthLimit); + } + + /** + * A placeholder that indicates no filtering. + */ + public static final FilterSpec NO_FILTER = new FilterSpec(-1, -1); + + /** + * @return -1 if this filter does not filter blobs based on size, or a + * non-negative integer representing the max size of blobs to allow + */ + public long getBlobLimit() { + return blobLimit; + } + + /** + * @return -1 if this filter does not filter blobs and trees based on depth, + * or a non-negative integer representing the max tree depth of + * blobs and trees to fetch + */ + public long getTreeDepthLimit() { + return treeDepthLimit; + } + + /** + * @return true if this filter doesn't filter out anything + */ + public boolean isNoOp() { + return blobLimit == -1 && treeDepthLimit == -1; + } + + /** + * @return the filter line which describes this spec, e.g. "filter blob:limit=42" + */ + @Nullable + public String filterLine() { + if (blobLimit == 0) { + return GitProtocolConstants.OPTION_FILTER + " blob:none"; //$NON-NLS-1$ + } + + if (blobLimit > 0) { + return GitProtocolConstants.OPTION_FILTER + " blob:limit=" + blobLimit; //$NON-NLS-1$ + } + + return null; + } +} 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 6c26b7026a..01f6fec7e4 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/transport/HMACSHA1NonceGenerator.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/transport/HMACSHA1NonceGenerator.java @@ -45,14 +45,12 @@ package org.eclipse.jgit.transport; import static java.nio.charset.StandardCharsets.ISO_8859_1; import static java.nio.charset.StandardCharsets.UTF_8; -import java.io.File; import java.security.InvalidKeyException; import java.security.NoSuchAlgorithmException; import javax.crypto.Mac; import javax.crypto.spec.SecretKeySpec; -import org.eclipse.jgit.internal.storage.dfs.DfsRepository; import org.eclipse.jgit.lib.Repository; import org.eclipse.jgit.transport.PushCertificate.NonceStatus; @@ -78,9 +76,7 @@ public class HMACSHA1NonceGenerator implements NonceGenerator { SecretKeySpec signingKey = new SecretKeySpec(keyBytes, "HmacSHA1"); //$NON-NLS-1$ mac = Mac.getInstance("HmacSHA1"); //$NON-NLS-1$ mac.init(signingKey); - } catch (InvalidKeyException e) { - throw new IllegalStateException(e); - } catch (NoSuchAlgorithmException e) { + } catch (InvalidKeyException | NoSuchAlgorithmException e) { throw new IllegalStateException(e); } } @@ -89,19 +85,7 @@ public class HMACSHA1NonceGenerator implements NonceGenerator { @Override public synchronized String createNonce(Repository repo, long timestamp) throws IllegalStateException { - String path; - if (repo instanceof DfsRepository) { - path = ((DfsRepository) repo).getDescription().getRepositoryName(); - } else { - File directory = repo.getDirectory(); - if (directory != null) { - path = directory.getPath(); - } else { - throw new IllegalStateException(); - } - } - - String input = path + ":" + String.valueOf(timestamp); //$NON-NLS-1$ + String input = repo.getIdentifier() + ":" + String.valueOf(timestamp); //$NON-NLS-1$ 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/HttpConfig.java b/org.eclipse.jgit/src/org/eclipse/jgit/transport/HttpConfig.java index ce9e1b3def..be7111d904 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/transport/HttpConfig.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/transport/HttpConfig.java @@ -88,6 +88,30 @@ public class HttpConfig { /** git config key for the "sslVerify" setting. */ public static final String SSL_VERIFY_KEY = "sslVerify"; //$NON-NLS-1$ + /** + * git config key for the "cookieFile" setting. + * + * @since 5.4 + */ + public static final String COOKIE_FILE_KEY = "cookieFile"; //$NON-NLS-1$ + + /** + * git config key for the "saveCookies" setting. + * + * @since 5.4 + */ + public static final String SAVE_COOKIES_KEY = "saveCookies"; //$NON-NLS-1$ + + /** + * Custom JGit config key which holds the maximum number of cookie files to + * keep in the cache. + * + * @since 5.4 + */ + public static final String COOKIE_FILE_CACHE_LIMIT_KEY = "cookieFileCacheLimit"; //$NON-NLS-1$ + + private static final int DEFAULT_COOKIE_FILE_CACHE_LIMIT = 10; + private static final String MAX_REDIRECT_SYSTEM_PROPERTY = "http.maxRedirects"; //$NON-NLS-1$ private static final int DEFAULT_MAX_REDIRECTS = 5; @@ -152,6 +176,12 @@ public class HttpConfig { private int maxRedirects; + private String cookieFile; + + private boolean saveCookies; + + private int cookieFileCacheLimit; + /** * Get the "http.postBuffer" setting * @@ -189,6 +219,40 @@ public class HttpConfig { } /** + * Get the "http.cookieFile" setting + * + * @return the value of the "http.cookieFile" setting + * + * @since 5.4 + */ + public String getCookieFile() { + return cookieFile; + } + + /** + * Get the "http.saveCookies" setting + * + * @return the value of the "http.saveCookies" setting + * + * @since 5.4 + */ + public boolean getSaveCookies() { + return saveCookies; + } + + /** + * Get the "http.cookieFileCacheLimit" setting (gives the maximum number of + * cookie files to keep in the LRU cache) + * + * @return the value of the "http.cookieFileCacheLimit" setting + * + * @since 5.4 + */ + public int getCookieFileCacheLimit() { + return cookieFileCacheLimit; + } + + /** * Creates a new {@link org.eclipse.jgit.transport.HttpConfig} tailored to * the given {@link org.eclipse.jgit.transport.URIish}. * @@ -234,6 +298,10 @@ public class HttpConfig { if (redirectLimit < 0) { redirectLimit = MAX_REDIRECTS; } + cookieFile = config.getString(HTTP, null, COOKIE_FILE_KEY); + saveCookies = config.getBoolean(HTTP, SAVE_COOKIES_KEY, false); + cookieFileCacheLimit = config.getInt(HTTP, COOKIE_FILE_CACHE_LIMIT_KEY, + DEFAULT_COOKIE_FILE_CACHE_LIMIT); String match = findMatch(config.getSubsections(HTTP), uri); if (match != null) { // Override with more specific items @@ -248,6 +316,13 @@ public class HttpConfig { if (newMaxRedirects >= 0) { redirectLimit = newMaxRedirects; } + String urlSpecificCookieFile = config.getString(HTTP, match, + COOKIE_FILE_KEY); + if (urlSpecificCookieFile != null) { + cookieFile = urlSpecificCookieFile; + } + saveCookies = config.getBoolean(HTTP, match, SAVE_COOKIES_KEY, + saveCookies); } postBuffer = postBufferSize; sslVerify = sslVerifyFlag; @@ -319,8 +394,9 @@ public class HttpConfig { // A longer path match is always preferred even over a user // match. If the path matches are equal, a match with user wins // over a match without user. - if (matchLength > bestMatchLength || !withUser && hasUser - && matchLength >= 0 && matchLength == bestMatchLength) { + if (matchLength > bestMatchLength + || (!withUser && hasUser && matchLength >= 0 + && matchLength == bestMatchLength)) { bestMatch = s; bestMatchLength = matchLength; withUser = hasUser; @@ -366,7 +442,7 @@ public class HttpConfig { int uLength = uriPath.length(); int mLength = matchPath.length(); if (mLength == uLength || matchPath.charAt(mLength - 1) == '/' - || mLength < uLength && uriPath.charAt(mLength) == '/') { + || (mLength < uLength && uriPath.charAt(mLength) == '/')) { return mLength; } return -1; @@ -386,7 +462,7 @@ public class HttpConfig { if (slash < 0) { slash = length; } - if (slash == i || slash == i + 1 && path.charAt(i) == '.') { + if (slash == i || (slash == i + 1 && path.charAt(i) == '.')) { // Skip /. or also double slashes } else if (slash == i + 2 && path.charAt(i) == '.' && path.charAt(i + 1) == '.') { diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/transport/InternalFetchConnection.java b/org.eclipse.jgit/src/org/eclipse/jgit/transport/InternalFetchConnection.java index 9fb9062fbb..dc3dcbc545 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/transport/InternalFetchConnection.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/transport/InternalFetchConnection.java @@ -107,16 +107,12 @@ class InternalFetchConnection<C> extends BasePackFetchConnection { try { final UploadPack rp = uploadPackFactory.create(req, remote); rp.upload(out_r, in_w, null); - } catch (ServiceNotEnabledException e) { + } catch (ServiceNotEnabledException + | ServiceNotAuthorizedException e) { // Ignored. Client cannot use this repository. - } catch (ServiceNotAuthorizedException e) { - // Ignored. Client cannot use this repository. - } catch (IOException err) { + } catch (IOException | RuntimeException err) { // Client side of the pipes should report the problem. err.printStackTrace(); - } catch (RuntimeException err) { - // Client side will notice we went away, and report. - err.printStackTrace(); } finally { try { out_r.close(); diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/transport/InternalPushConnection.java b/org.eclipse.jgit/src/org/eclipse/jgit/transport/InternalPushConnection.java index f05e0b8c7d..9663de09f4 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/transport/InternalPushConnection.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/transport/InternalPushConnection.java @@ -100,16 +100,14 @@ class InternalPushConnection<C> extends BasePackPushConnection { try { final ReceivePack rp = receivePackFactory.create(req, remote); rp.receive(out_r, in_w, System.err); - } catch (ServiceNotEnabledException e) { - // Ignored. Client cannot use this repository. - } catch (ServiceNotAuthorizedException e) { + } catch (ServiceNotEnabledException + | ServiceNotAuthorizedException e) { // Ignored. Client cannot use this repository. } catch (IOException e) { - // Since the InternalPushConnection - // is used in tests, we want to avoid hiding exceptions - // because they can point to programming errors on the server - // side. By rethrowing, the default handler will dump it - // to stderr. + // Since the InternalPushConnection is used in tests, we + // want to avoid hiding exceptions because they can point to + // programming errors on the server side. By rethrowing, the + // default handler will dump it to stderr. throw new UncheckedIOException(e); } finally { try { 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 c6e19d5762..d73e1939a6 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/transport/PacketLineIn.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/transport/PacketLineIn.java @@ -49,7 +49,9 @@ import static java.nio.charset.StandardCharsets.UTF_8; import java.io.IOException; import java.io.InputStream; +import java.io.UncheckedIOException; import java.text.MessageFormat; +import java.util.Iterator; import org.eclipse.jgit.errors.PackProtocolException; import org.eclipse.jgit.internal.JGitText; @@ -72,14 +74,25 @@ import org.slf4j.LoggerFactory; public class PacketLineIn { private static final Logger log = LoggerFactory.getLogger(PacketLineIn.class); - /** Magic return from {@link #readString()} when a flush packet is found. */ + /** + * Magic return from {@link #readString()} when a flush packet is found. + * + * @deprecated Callers should use {@link #isEnd(String)} to check if a + * string is the end marker, or + * {@link PacketLineIn#readStrings()} to iterate over all + * strings in the input stream until the marker is reached. + */ + @Deprecated public static final String END = new StringBuilder(0).toString(); /* must not string pool */ /** * Magic return from {@link #readString()} when a delim packet is found. * * @since 5.0 + * @deprecated Callers should use {@link #isDelimiter(String)} to check if a + * string is the delimiter. */ + @Deprecated public static final String DELIM = new StringBuilder(0).toString(); /* must not string pool */ static enum AckNackResult { @@ -193,6 +206,20 @@ public class PacketLineIn { } /** + * Get an iterator to read strings from the input stream. + * + * @return an iterator that calls {@link #readString()} until {@link #END} + * is encountered. + * + * @throws IOException + * on failure to read the initial packet line. + * @since 5.4 + */ + public PacketLineInIterator readStrings() throws IOException { + return new PacketLineInIterator(this); + } + + /** * Read a single UTF-8 encoded string packet from the input stream. * <p> * Unlike {@link #readString()} a trailing LF will be retained. @@ -224,6 +251,54 @@ public class PacketLineIn { return s; } + /** + * Check if a string is the delimiter marker. + * + * @param s + * the string to check + * @return true if the given string is {@link #DELIM}, otherwise false. + * @since 5.4 + */ + @SuppressWarnings({ "ReferenceEquality", "StringEquality" }) + public static boolean isDelimiter(String s) { + return s == DELIM; + } + + /** + * Get the delimiter marker. + * <p> + * Intended for use only in tests. + * + * @return The delimiter marker. + */ + static String delimiter() { + return DELIM; + } + + /** + * Get the end marker. + * <p> + * Intended for use only in tests. + * + * @return The end marker. + */ + static String end() { + return END; + } + + /** + * Check if a string is the packet end marker. + * + * @param s + * the string to check + * @return true if the given string is {@link #END}, otherwise false. + * @since 5.4 + */ + @SuppressWarnings({ "ReferenceEquality", "StringEquality" }) + public static boolean isEnd(String s) { + return s == END; + } + void discardUntilEnd() throws IOException { for (;;) { int n = readLength(); @@ -282,4 +357,46 @@ public class PacketLineIn { public static class InputOverLimitIOException extends IOException { private static final long serialVersionUID = 1L; } + + /** + * Iterator over packet lines. + * <p> + * Calls {@link #readString()} on the {@link PacketLineIn} until + * {@link #END} is encountered. + * + * @since 5.4 + * + */ + public static class PacketLineInIterator implements Iterable<String> { + private PacketLineIn in; + + private String current; + + PacketLineInIterator(PacketLineIn in) throws IOException { + this.in = in; + current = in.readString(); + } + + @Override + public Iterator<String> iterator() { + return new Iterator<String>() { + @Override + public boolean hasNext() { + return !PacketLineIn.isEnd(current); + } + + @Override + public String next() { + String next = current; + try { + current = in.readString(); + } catch (IOException e) { + throw new UncheckedIOException(e); + } + return next; + } + }; + } + + } } diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/transport/PostReceiveHook.java b/org.eclipse.jgit/src/org/eclipse/jgit/transport/PostReceiveHook.java index ba5d2f3c8f..28a146dde5 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/transport/PostReceiveHook.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/transport/PostReceiveHook.java @@ -63,12 +63,9 @@ import java.util.Collection; */ public interface PostReceiveHook { /** A simple no-op hook. */ - PostReceiveHook NULL = new PostReceiveHook() { - @Override - public void onPostReceive(final ReceivePack rp, - final Collection<ReceiveCommand> commands) { - // Do nothing. - } + PostReceiveHook NULL = (final ReceivePack rp, + final Collection<ReceiveCommand> commands) -> { + // Do nothing. }; /** diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/transport/PostUploadHook.java b/org.eclipse.jgit/src/org/eclipse/jgit/transport/PostUploadHook.java index 3aa3b127e5..251bfe271a 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/transport/PostUploadHook.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/transport/PostUploadHook.java @@ -57,11 +57,8 @@ import org.eclipse.jgit.storage.pack.PackStatistics; */ public interface PostUploadHook { /** A simple no-op hook. */ - PostUploadHook NULL = new PostUploadHook() { - @Override - public void onPostUpload(PackStatistics stats) { - // Do nothing. - } + PostUploadHook NULL = (PackStatistics stats) -> { + // Do nothing. }; /** diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/transport/PreReceiveHook.java b/org.eclipse.jgit/src/org/eclipse/jgit/transport/PreReceiveHook.java index 30845d3b68..b91756bd5e 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/transport/PreReceiveHook.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/transport/PreReceiveHook.java @@ -79,12 +79,9 @@ import java.util.Collection; */ public interface PreReceiveHook { /** A simple no-op hook. */ - PreReceiveHook NULL = new PreReceiveHook() { - @Override - public void onPreReceive(final ReceivePack rp, - final Collection<ReceiveCommand> commands) { - // Do nothing. - } + PreReceiveHook NULL = (final ReceivePack rp, + final Collection<ReceiveCommand> commands) -> { + // Do nothing. }; /** diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/transport/ProtocolV0Parser.java b/org.eclipse.jgit/src/org/eclipse/jgit/transport/ProtocolV0Parser.java index 21498d6f5c..428a45c09d 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/transport/ProtocolV0Parser.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/transport/ProtocolV0Parser.java @@ -99,7 +99,7 @@ final class ProtocolV0Parser { throw eof; } - if (line == PacketLineIn.END) { + if (PacketLineIn.isEnd(line)) { break; } @@ -130,7 +130,7 @@ final class ProtocolV0Parser { } filterReceived = true; - reqBuilder.setFilterBlobLimit(ProtocolV2Parser.filterLine(arg)); + reqBuilder.setFilterSpec(FilterSpec.fromFilterLine(arg)); continue; } diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/transport/ProtocolV2Parser.java b/org.eclipse.jgit/src/org/eclipse/jgit/transport/ProtocolV2Parser.java index 8f4b86ee0a..caba15fc54 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/transport/ProtocolV2Parser.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/transport/ProtocolV2Parser.java @@ -92,7 +92,7 @@ final class ProtocolV2Parser { String agentPrefix = OPTION_AGENT + '='; String line = pckIn.readString(); - while (line != PacketLineIn.DELIM && line != PacketLineIn.END) { + while (!PacketLineIn.isDelimiter(line) && !PacketLineIn.isEnd(line)) { if (line.startsWith(serverOptionPrefix)) { serverOptionConsumer .accept(line.substring(serverOptionPrefix.length())); @@ -133,40 +133,41 @@ final class ProtocolV2Parser { serverOption -> reqBuilder.addServerOption(serverOption), agent -> reqBuilder.setAgent(agent)); - if (line == PacketLineIn.END) { + if (PacketLineIn.isEnd(line)) { return reqBuilder.build(); } - if (line != PacketLineIn.DELIM) { + if (!PacketLineIn.isDelimiter(line)) { 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.addWantId(ObjectId.fromString(line.substring(5))); + for (String line2 : pckIn.readStrings()) { + if (line2.startsWith("want ")) { //$NON-NLS-1$ + reqBuilder.addWantId(ObjectId.fromString(line2.substring(5))); } else if (transferConfig.isAllowRefInWant() - && line.startsWith(OPTION_WANT_REF + " ")) { //$NON-NLS-1$ - reqBuilder.addWantedRef(line.substring(OPTION_WANT_REF.length() + 1)); - } else if (line.startsWith("have ")) { //$NON-NLS-1$ - reqBuilder.addPeerHas(ObjectId.fromString(line.substring(5))); - } else if (line.equals("done")) { //$NON-NLS-1$ + && line2.startsWith(OPTION_WANT_REF + " ")) { //$NON-NLS-1$ + reqBuilder.addWantedRef( + line2.substring(OPTION_WANT_REF.length() + 1)); + } else if (line2.startsWith("have ")) { //$NON-NLS-1$ + reqBuilder.addPeerHas(ObjectId.fromString(line2.substring(5))); + } else if (line2.equals("done")) { //$NON-NLS-1$ reqBuilder.setDoneReceived(); - } else if (line.equals(OPTION_THIN_PACK)) { + } else if (line2.equals(OPTION_THIN_PACK)) { reqBuilder.addClientCapability(OPTION_THIN_PACK); - } else if (line.equals(OPTION_NO_PROGRESS)) { + } else if (line2.equals(OPTION_NO_PROGRESS)) { reqBuilder.addClientCapability(OPTION_NO_PROGRESS); - } else if (line.equals(OPTION_INCLUDE_TAG)) { + } else if (line2.equals(OPTION_INCLUDE_TAG)) { reqBuilder.addClientCapability(OPTION_INCLUDE_TAG); - } else if (line.equals(OPTION_OFS_DELTA)) { + } else if (line2.equals(OPTION_OFS_DELTA)) { reqBuilder.addClientCapability(OPTION_OFS_DELTA); - } else if (line.startsWith("shallow ")) { //$NON-NLS-1$ + } else if (line2.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)); + ObjectId.fromString(line2.substring(8))); + } else if (line2.startsWith("deepen ")) { //$NON-NLS-1$ + int parsedDepth = Integer.parseInt(line2.substring(7)); if (parsedDepth <= 0) { throw new PackProtocolException( MessageFormat.format(JGitText.get().invalidDepth, @@ -181,19 +182,19 @@ final class ProtocolV2Parser { JGitText.get().deepenNotWithDeepen); } reqBuilder.setDepth(parsedDepth); - } else if (line.startsWith("deepen-not ")) { //$NON-NLS-1$ - reqBuilder.addDeepenNotRef(line.substring(11)); + } else if (line2.startsWith("deepen-not ")) { //$NON-NLS-1$ + reqBuilder.addDeepenNotRef(line2.substring(11)); if (reqBuilder.getDepth() != 0) { throw new PackProtocolException( JGitText.get().deepenNotWithDeepen); } - } else if (line.equals(OPTION_DEEPEN_RELATIVE)) { + } else if (line2.equals(OPTION_DEEPEN_RELATIVE)) { reqBuilder.addClientCapability(OPTION_DEEPEN_RELATIVE); - } else if (line.startsWith("deepen-since ")) { //$NON-NLS-1$ - int ts = Integer.parseInt(line.substring(13)); + } else if (line2.startsWith("deepen-since ")) { //$NON-NLS-1$ + int ts = Integer.parseInt(line2.substring(13)); if (ts <= 0) { throw new PackProtocolException(MessageFormat - .format(JGitText.get().invalidTimestamp, line)); + .format(JGitText.get().invalidTimestamp, line2)); } if (reqBuilder.getDepth() != 0) { throw new PackProtocolException( @@ -201,17 +202,17 @@ final class ProtocolV2Parser { } reqBuilder.setDeepenSince(ts); } else if (transferConfig.isAllowFilter() - && line.startsWith(OPTION_FILTER + ' ')) { + && line2.startsWith(OPTION_FILTER + ' ')) { if (filterReceived) { throw new PackProtocolException( JGitText.get().tooManyFilters); } filterReceived = true; - reqBuilder.setFilterBlobLimit(filterLine( - line.substring(OPTION_FILTER.length() + 1))); + reqBuilder.setFilterSpec(FilterSpec.fromFilterLine( + line2.substring(OPTION_FILTER.length() + 1))); } else { throw new PackProtocolException(MessageFormat - .format(JGitText.get().unexpectedPacketLine, line)); + .format(JGitText.get().unexpectedPacketLine, line2)); } } @@ -244,67 +245,29 @@ final class ProtocolV2Parser { serverOption -> builder.addServerOption(serverOption), agent -> builder.setAgent(agent)); - if (line == PacketLineIn.END) { + if (PacketLineIn.isEnd(line)) { return builder.build(); } - if (line != PacketLineIn.DELIM) { + if (!PacketLineIn.isDelimiter(line)) { throw new PackProtocolException(MessageFormat .format(JGitText.get().unexpectedPacketLine, line)); } - while ((line = pckIn.readString()) != PacketLineIn.END) { - if (line.equals("peel")) { //$NON-NLS-1$ + for (String line2 : pckIn.readStrings()) { + if (line2.equals("peel")) { //$NON-NLS-1$ builder.setPeel(true); - } else if (line.equals("symrefs")) { //$NON-NLS-1$ + } else if (line2.equals("symrefs")) { //$NON-NLS-1$ builder.setSymrefs(true); - } else if (line.startsWith("ref-prefix ")) { //$NON-NLS-1$ - prefixes.add(line.substring("ref-prefix ".length())); //$NON-NLS-1$ + } else if (line2.startsWith("ref-prefix ")) { //$NON-NLS-1$ + prefixes.add(line2.substring("ref-prefix ".length())); //$NON-NLS-1$ } else { throw new PackProtocolException(MessageFormat - .format(JGitText.get().unexpectedPacketLine, line)); + .format(JGitText.get().unexpectedPacketLine, line2)); } } return builder.setRefPrefixes(prefixes).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/PushCertificateStore.java b/org.eclipse.jgit/src/org/eclipse/jgit/transport/PushCertificateStore.java index aeca63500a..14afc44eec 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/transport/PushCertificateStore.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/transport/PushCertificateStore.java @@ -57,7 +57,6 @@ import java.text.MessageFormat; import java.util.ArrayList; import java.util.Collection; import java.util.Collections; -import java.util.Comparator; import java.util.HashMap; import java.util.Iterator; import java.util.List; @@ -193,81 +192,78 @@ public class PushCertificateStore implements AutoCloseable { * close resources. */ public Iterable<PushCertificate> getAll(String refName) { - return new Iterable<PushCertificate>() { - @Override - public Iterator<PushCertificate> iterator() { - return new Iterator<PushCertificate>() { - private final String path = pathName(refName); - private PushCertificate next; + return () -> new Iterator<PushCertificate>() { + private final String path = pathName(refName); + + private PushCertificate next; + + private RevWalk rw; + { + try { + if (reader == null) { + load(); + } + if (commit != null) { + rw = new RevWalk(reader); + rw.setTreeFilter(AndTreeFilter.create( + PathFilterGroup.create(Collections + .singleton(PathFilter.create(path))), + TreeFilter.ANY_DIFF)); + rw.setRewriteParents(false); + rw.markStart(rw.parseCommit(commit)); + } else { + rw = null; + } + } catch (IOException e) { + throw new RuntimeException(e); + } + } - private RevWalk rw; - { + @Override + public boolean hasNext() { + try { + if (next == null) { + if (rw == null) { + return false; + } try { - if (reader == null) { - load(); - } - if (commit != null) { - rw = new RevWalk(reader); - rw.setTreeFilter(AndTreeFilter.create( - PathFilterGroup.create( - Collections.singleton(PathFilter.create(path))), - TreeFilter.ANY_DIFF)); - rw.setRewriteParents(false); - rw.markStart(rw.parseCommit(commit)); + RevCommit c = rw.next(); + if (c != null) { + try (TreeWalk tw = TreeWalk.forPath( + rw.getObjectReader(), path, + c.getTree())) { + next = read(tw); + } } else { - rw = null; + next = null; } } catch (IOException e) { throw new RuntimeException(e); } } - - @Override - public boolean hasNext() { - try { - if (next == null) { - if (rw == null) { - return false; - } - try { - RevCommit c = rw.next(); - if (c != null) { - try (TreeWalk tw = TreeWalk.forPath( - rw.getObjectReader(), path, c.getTree())) { - next = read(tw); - } - } else { - next = null; - } - } catch (IOException e) { - throw new RuntimeException(e); - } - } - return next != null; - } finally { - if (next == null && rw != null) { - rw.close(); - rw = null; - } - } + return next != null; + } finally { + if (next == null && rw != null) { + rw.close(); + rw = null; } + } + } - @Override - public PushCertificate next() { - hasNext(); - PushCertificate n = next; - if (n == null) { - throw new NoSuchElementException(); - } - next = null; - return n; - } + @Override + public PushCertificate next() { + hasNext(); + PushCertificate n = next; + if (n == null) { + throw new NoSuchElementException(); + } + next = null; + return n; + } - @Override - public void remove() { - throw new UnsupportedOperationException(); - } - }; + @Override + public void remove() { + throw new UnsupportedOperationException(); } }; } @@ -442,13 +438,8 @@ public class PushCertificateStore implements AutoCloseable { } private static void sortPending(List<PendingCert> pending) { - Collections.sort(pending, new Comparator<PendingCert>() { - @Override - public int compare(PendingCert a, PendingCert b) { - return Long.signum( - a.ident.getWhen().getTime() - b.ident.getWhen().getTime()); - } - }); + Collections.sort(pending, (PendingCert a, PendingCert b) -> Long.signum( + a.ident.getWhen().getTime() - b.ident.getWhen().getTime())); } private DirCache newDirCache() throws IOException { diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/transport/ReceiveCommand.java b/org.eclipse.jgit/src/org/eclipse/jgit/transport/ReceiveCommand.java index d61aeb04d2..a9a995cd3f 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/transport/ReceiveCommand.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/transport/ReceiveCommand.java @@ -429,7 +429,7 @@ public class ReceiveCommand { this.newId = ObjectId.zeroId(); this.newSymref = newSymref; this.name = name; - if (AnyObjectId.equals(ObjectId.zeroId(), oldId)) { + if (AnyObjectId.isEqual(ObjectId.zeroId(), oldId)) { type = Type.CREATE; } else if (newSymref != null) { type = Type.UPDATE; @@ -468,7 +468,7 @@ public class ReceiveCommand { this.name = name; if (oldSymref == null) { type = Type.CREATE; - } else if (!AnyObjectId.equals(ObjectId.zeroId(), newId)) { + } else if (!AnyObjectId.isEqual(ObjectId.zeroId(), newId)) { type = Type.UPDATE; } else { type = Type.DELETE; @@ -750,7 +750,7 @@ public class ReceiveCommand { public void updateType(RevWalk walk) throws IOException { if (typeIsCorrect) return; - if (type == Type.UPDATE && !AnyObjectId.equals(oldId, newId)) { + if (type == Type.UPDATE && !AnyObjectId.isEqual(oldId, newId)) { RevObject o = walk.parseAny(oldId); RevObject n = walk.parseAny(newId); if (!(o instanceof RevCommit) diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/transport/ReceivePack.java b/org.eclipse.jgit/src/org/eclipse/jgit/transport/ReceivePack.java index 4652c3fda8..d6adf1e0d8 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/transport/ReceivePack.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/transport/ReceivePack.java @@ -348,7 +348,7 @@ public class ReceivePack extends BaseReceivePack { pushOptions = new ArrayList<>(4); for (;;) { String option = in.readString(); - if (option == PacketLineIn.END) { + if (PacketLineIn.isEnd(option)) { break; } pushOptions.add(option); diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/transport/RefFilter.java b/org.eclipse.jgit/src/org/eclipse/jgit/transport/RefFilter.java index d6d6198f5b..d19c652c25 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/transport/RefFilter.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/transport/RefFilter.java @@ -61,12 +61,7 @@ public interface RefFilter { /** * The default filter, allows all refs to be shown. */ - RefFilter DEFAULT = new RefFilter() { - @Override - public Map<String, Ref> filter (Map<String, Ref> refs) { - return refs; - } - }; + RefFilter DEFAULT = (Map<String, Ref> refs) -> refs; /** * Filters a {@code Map} of refs before it is advertised to the client. diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/transport/RefSpec.java b/org.eclipse.jgit/src/org/eclipse/jgit/transport/RefSpec.java index afd3adaacc..16c6faf277 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/transport/RefSpec.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/transport/RefSpec.java @@ -49,6 +49,7 @@ import java.text.MessageFormat; import org.eclipse.jgit.internal.JGitText; import org.eclipse.jgit.lib.Constants; import org.eclipse.jgit.lib.Ref; +import org.eclipse.jgit.util.References; /** * Describes how refs in one repository copy into another repository. @@ -585,8 +586,9 @@ public class RefSpec implements Serializable { } private static boolean eq(String a, String b) { - if (a == b) + if (References.isSameObject(a, b)) { return true; + } if (a == null || b == null) return false; return a.equals(b); diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/transport/SshSessionFactory.java b/org.eclipse.jgit/src/org/eclipse/jgit/transport/SshSessionFactory.java index 005a0c2d0e..fdb19df91a 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/transport/SshSessionFactory.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/transport/SshSessionFactory.java @@ -100,13 +100,9 @@ public abstract class SshSessionFactory { * @since 5.2 */ public static String getLocalUserName() { - return AccessController.doPrivileged(new PrivilegedAction<String>() { - @Override - public String run() { - return SystemReader.getInstance() - .getProperty(Constants.OS_USER_NAME_KEY); - } - }); + return AccessController + .doPrivileged((PrivilegedAction<String>) () -> SystemReader + .getInstance().getProperty(Constants.OS_USER_NAME_KEY)); } /** diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/transport/TrackingRefUpdate.java b/org.eclipse.jgit/src/org/eclipse/jgit/transport/TrackingRefUpdate.java index ba2a673a18..550a9ef372 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/transport/TrackingRefUpdate.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/transport/TrackingRefUpdate.java @@ -175,7 +175,7 @@ public class TrackingRefUpdate { private RefUpdate.Result decode(ReceiveCommand.Result status) { switch (status) { case OK: - if (AnyObjectId.equals(oldObjectId, newObjectId)) + if (AnyObjectId.isEqual(oldObjectId, newObjectId)) return RefUpdate.Result.NO_CHANGE; switch (getType()) { case CREATE: 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 621c2ea56c..0b7907035e 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/transport/Transport.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/transport/Transport.java @@ -47,6 +47,7 @@ package org.eclipse.jgit.transport; import static java.nio.charset.StandardCharsets.UTF_8; +import static java.util.Objects.requireNonNull; import java.io.BufferedReader; import java.io.IOException; @@ -70,6 +71,7 @@ import java.util.Map; import java.util.Vector; import java.util.concurrent.CopyOnWriteArrayList; +import org.eclipse.jgit.annotations.NonNull; import org.eclipse.jgit.api.errors.AbortedByHookException; import org.eclipse.jgit.errors.NotSupportedException; import org.eclipse.jgit.errors.TransportException; @@ -178,10 +180,7 @@ public abstract class Transport implements AutoCloseable { TransportProtocol proto; try { proto = (TransportProtocol) f.get(null); - } catch (IllegalArgumentException e) { - // If we cannot access the field, don't. - continue; - } catch (IllegalAccessException e) { + } catch (IllegalArgumentException | IllegalAccessException e) { // If we cannot access the field, don't. continue; } @@ -790,7 +789,7 @@ public abstract class Transport implements AutoCloseable { /** Should refs no longer on the source be pruned from the destination? */ private boolean removeDeletedRefs; - private long filterBlobLimit = -1; + private FilterSpec filterSpec = FilterSpec.NO_FILTER; /** Timeout in seconds to wait before aborting an IO read or write. */ private int timeout; @@ -1067,20 +1066,42 @@ public abstract class Transport implements AutoCloseable { } /** - * @return the last value passed to {@link #setFilterBlobLimit}, or -1 if - * it was never invoked. + * @return the blob limit value set with {@link #setFilterBlobLimit} or + * {@link #setFilterSpec(FilterSpec)}, or -1 if no blob limit value + * was set * @since 5.0 + * @deprecated Use {@link #getFilterSpec()} instead */ - public long getFilterBlobLimit() { - return filterBlobLimit; + @Deprecated + public final long getFilterBlobLimit() { + return filterSpec.getBlobLimit(); } /** * @param bytes exclude blobs of size greater than this * @since 5.0 + * @deprecated Use {@link #setFilterSpec(FilterSpec)} instead + */ + @Deprecated + public final void setFilterBlobLimit(long bytes) { + setFilterSpec(FilterSpec.withBlobLimit(bytes)); + } + + /** + * @return the last filter spec set with {@link #setFilterSpec(FilterSpec)}, + * or {@link FilterSpec#NO_FILTER} if it was never invoked. + * @since 5.4 + */ + public final FilterSpec getFilterSpec() { + return filterSpec; + } + + /** + * @param filter a new filter to use for this transport + * @since 5.4 */ - public void setFilterBlobLimit(long bytes) { - filterBlobLimit = bytes; + public final void setFilterSpec(@NonNull FilterSpec filter) { + filterSpec = requireNonNull(filter); } /** 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 0df1b70cb7..a591dbae2a 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/transport/TransportHttp.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/transport/TransportHttp.java @@ -54,8 +54,11 @@ import static org.eclipse.jgit.util.HttpSupport.HDR_ACCEPT; import static org.eclipse.jgit.util.HttpSupport.HDR_ACCEPT_ENCODING; import static org.eclipse.jgit.util.HttpSupport.HDR_CONTENT_ENCODING; import static org.eclipse.jgit.util.HttpSupport.HDR_CONTENT_TYPE; +import static org.eclipse.jgit.util.HttpSupport.HDR_COOKIE; import static org.eclipse.jgit.util.HttpSupport.HDR_LOCATION; import static org.eclipse.jgit.util.HttpSupport.HDR_PRAGMA; +import static org.eclipse.jgit.util.HttpSupport.HDR_SET_COOKIE; +import static org.eclipse.jgit.util.HttpSupport.HDR_SET_COOKIE2; import static org.eclipse.jgit.util.HttpSupport.HDR_USER_AGENT; import static org.eclipse.jgit.util.HttpSupport.HDR_WWW_AUTHENTICATE; import static org.eclipse.jgit.util.HttpSupport.METHOD_GET; @@ -68,11 +71,15 @@ import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.io.OutputStream; +import java.net.HttpCookie; import java.net.MalformedURLException; import java.net.Proxy; import java.net.ProxySelector; import java.net.URISyntaxException; import java.net.URL; +import java.nio.file.InvalidPathException; +import java.nio.file.Path; +import java.nio.file.Paths; import java.security.cert.CertPathBuilderException; import java.security.cert.CertPathValidatorException; import java.security.cert.CertificateException; @@ -84,6 +91,8 @@ import java.util.Collections; import java.util.EnumSet; import java.util.HashSet; import java.util.LinkedHashSet; +import java.util.LinkedList; +import java.util.List; import java.util.Locale; import java.util.Map; import java.util.Set; @@ -100,6 +109,8 @@ 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.RefDirectory; +import org.eclipse.jgit.internal.transport.http.NetscapeCookieFile; +import org.eclipse.jgit.internal.transport.http.NetscapeCookieFileCache; import org.eclipse.jgit.lib.Constants; import org.eclipse.jgit.lib.ObjectId; import org.eclipse.jgit.lib.ObjectIdRef; @@ -114,6 +125,7 @@ import org.eclipse.jgit.transport.http.HttpConnection; import org.eclipse.jgit.util.HttpSupport; import org.eclipse.jgit.util.IO; import org.eclipse.jgit.util.RawParseUtils; +import org.eclipse.jgit.util.StringUtils; import org.eclipse.jgit.util.SystemReader; import org.eclipse.jgit.util.TemporaryBuffer; import org.eclipse.jgit.util.io.DisabledOutputStream; @@ -272,6 +284,19 @@ public class TransportHttp extends HttpTransport implements WalkTransport, private boolean sslFailure = false; + /** + * All stored cookies bound to this repo (independent of the baseUrl) + */ + private final NetscapeCookieFile cookieFile; + + /** + * The cookies to be sent with each request to the given {@link #baseUrl}. + * Filtered view on top of {@link #cookieFile} where only cookies which + * apply to the current url are left. This set needs to be filtered for + * expired entries each time prior to sending them. + */ + private final Set<HttpCookie> relevantCookies; + TransportHttp(Repository local, URIish uri) throws NotSupportedException { super(local, uri); @@ -279,6 +304,8 @@ public class TransportHttp extends HttpTransport implements WalkTransport, http = new HttpConfig(local.getConfig(), uri); proxySelector = ProxySelector.getDefault(); sslVerify = http.isSslVerify(); + cookieFile = getCookieFileFromConfig(http); + relevantCookies = filterCookies(cookieFile, baseUrl); } private URL toURL(URIish urish) throws MalformedURLException { @@ -319,6 +346,8 @@ public class TransportHttp extends HttpTransport implements WalkTransport, http = new HttpConfig(uri); proxySelector = ProxySelector.getDefault(); sslVerify = http.isSslVerify(); + cookieFile = getCookieFileFromConfig(http); + relevantCookies = filterCookies(cookieFile, baseUrl); } /** @@ -361,9 +390,7 @@ public class TransportHttp extends HttpTransport implements WalkTransport, try (InputStream in = openInputStream(c)) { return getConnection(c, in, service); } - } catch (NotSupportedException err) { - throw err; - } catch (TransportException err) { + } catch (NotSupportedException | TransportException err) { throw err; } catch (IOException err) { throw new TransportException(uri, JGitText.get().errorReadingInfoRefs, err); @@ -447,9 +474,7 @@ public class TransportHttp extends HttpTransport implements WalkTransport, throw new NotSupportedException(msg); } } - } catch (NotSupportedException err) { - throw err; - } catch (TransportException err) { + } catch (NotSupportedException | TransportException err) { throw err; } catch (IOException err) { throw new TransportException(uri, JGitText.get().errorReadingInfoRefs, err); @@ -510,6 +535,7 @@ public class TransportHttp extends HttpTransport implements WalkTransport, conn.setRequestProperty(HDR_ACCEPT, "*/*"); //$NON-NLS-1$ } final int status = HttpSupport.response(conn); + processResponseCookies(conn); switch (status) { case HttpConnection.HTTP_OK: // Check if HttpConnection did some authentication in the @@ -573,9 +599,7 @@ public class TransportHttp extends HttpTransport implements WalkTransport, String err = status + " " + conn.getResponseMessage(); //$NON-NLS-1$ throw new TransportException(uri, err); } - } catch (NotSupportedException e) { - throw e; - } catch (TransportException e) { + } catch (NotSupportedException | TransportException e) { throw e; } catch (SSLHandshakeException e) { handleSslFailure(e); @@ -600,6 +624,57 @@ public class TransportHttp extends HttpTransport implements WalkTransport, } } + void processResponseCookies(HttpConnection conn) { + if (cookieFile != null && http.getSaveCookies()) { + List<HttpCookie> foundCookies = new LinkedList<>(); + + List<String> cookieHeaderValues = conn + .getHeaderFields(HDR_SET_COOKIE); + if (!cookieHeaderValues.isEmpty()) { + foundCookies.addAll( + extractCookies(HDR_SET_COOKIE, cookieHeaderValues)); + } + cookieHeaderValues = conn.getHeaderFields(HDR_SET_COOKIE2); + if (!cookieHeaderValues.isEmpty()) { + foundCookies.addAll( + extractCookies(HDR_SET_COOKIE2, cookieHeaderValues)); + } + if (!foundCookies.isEmpty()) { + try { + // update cookie lists with the newly received cookies! + Set<HttpCookie> cookies = cookieFile.getCookies(false); + cookies.addAll(foundCookies); + cookieFile.write(baseUrl); + relevantCookies.addAll(foundCookies); + } catch (IOException | IllegalArgumentException + | InterruptedException e) { + LOG.warn(MessageFormat.format( + JGitText.get().couldNotPersistCookies, + cookieFile.getPath()), e); + } + } + } + } + + private List<HttpCookie> extractCookies(String headerKey, + List<String> headerValues) { + List<HttpCookie> foundCookies = new LinkedList<>(); + for (String headerValue : headerValues) { + foundCookies + .addAll(HttpCookie.parse(headerKey + ':' + headerValue)); + } + // HttpCookies.parse(...) is only compliant with RFC 2965. Make it RFC + // 6265 compliant by applying the logic from + // https://tools.ietf.org/html/rfc6265#section-5.2.3 + for (HttpCookie foundCookie : foundCookies) { + String domain = foundCookie.getDomain(); + if (domain != null && domain.startsWith(".")) { //$NON-NLS-1$ + foundCookie.setDomain(domain.substring(1)); + } + } + return foundCookies; + } + private static class CredentialItems { CredentialItem.InformationalMessage message; @@ -775,7 +850,7 @@ public class TransportHttp extends HttpTransport implements WalkTransport, } // git allows only rewriting the root, i.e., everything before INFO_REFS // or the service name - if (next.indexOf(checkFor) < 0) { + if (!next.contains(checkFor)) { return false; } // Basically we should test here that whatever follows INFO_REFS is @@ -849,14 +924,35 @@ public class TransportHttp extends HttpTransport implements WalkTransport, conn.setConnectTimeout(effTimeOut); conn.setReadTimeout(effTimeOut); } + // set cookie header if necessary + if (!relevantCookies.isEmpty()) { + setCookieHeader(conn); + } + if (this.headers != null && !this.headers.isEmpty()) { - for (Map.Entry<String, String> entry : this.headers.entrySet()) + for (Map.Entry<String, String> entry : this.headers.entrySet()) { conn.setRequestProperty(entry.getKey(), entry.getValue()); + } } authMethod.configureRequest(conn); return conn; } + private void setCookieHeader(HttpConnection conn) { + StringBuilder cookieHeaderValue = new StringBuilder(); + for (HttpCookie cookie : relevantCookies) { + if (!cookie.hasExpired()) { + if (cookieHeaderValue.length() > 0) { + cookieHeaderValue.append(';'); + } + cookieHeaderValue.append(cookie.toString()); + } + } + if (cookieHeaderValue.length() > 0) { + conn.setRequestProperty(HDR_COOKIE, cookieHeaderValue.toString()); + } + } + final InputStream openInputStream(HttpConnection conn) throws IOException { InputStream input = conn.getInputStream(); @@ -870,6 +966,150 @@ public class TransportHttp extends HttpTransport implements WalkTransport, return new TransportException(uri, why); } + private static NetscapeCookieFile getCookieFileFromConfig( + HttpConfig config) { + if (!StringUtils.isEmptyOrNull(config.getCookieFile())) { + try { + Path cookieFilePath = Paths.get(config.getCookieFile()); + return NetscapeCookieFileCache.getInstance(config) + .getEntry(cookieFilePath); + } catch (InvalidPathException e) { + LOG.warn(MessageFormat.format( + JGitText.get().couldNotReadCookieFile, + config.getCookieFile()), e); + } + } + return null; + } + + private static Set<HttpCookie> filterCookies(NetscapeCookieFile cookieFile, + URL url) { + if (cookieFile != null) { + return filterCookies(cookieFile.getCookies(true), url); + } + return Collections.emptySet(); + } + + /** + * + * @param allCookies + * a list of cookies. + * @param url + * the url for which to filter the list of cookies. + * @return only the cookies from {@code allCookies} which are relevant (i.e. + * are not expired, have a matching domain, have a matching path and + * have a matching secure attribute) + */ + private static Set<HttpCookie> filterCookies(Set<HttpCookie> allCookies, + URL url) { + Set<HttpCookie> filteredCookies = new HashSet<>(); + for (HttpCookie cookie : allCookies) { + if (cookie.hasExpired()) { + continue; + } + if (!matchesCookieDomain(url.getHost(), cookie.getDomain())) { + continue; + } + if (!matchesCookiePath(url.getPath(), cookie.getPath())) { + continue; + } + if (cookie.getSecure() && !"https".equals(url.getProtocol())) { //$NON-NLS-1$ + continue; + } + filteredCookies.add(cookie); + } + return filteredCookies; + } + + /** + * + * The utility method to check whether a host name is in a cookie's domain + * or not. Similar to {@link HttpCookie#domainMatches(String, String)} but + * implements domain matching rules according to + * <a href="https://tools.ietf.org/html/rfc6265#section-5.1.3">RFC 6265, + * section 5.1.3</a> instead of the rules from + * <a href="https://tools.ietf.org/html/rfc2965#section-3.3">RFC 2965, + * section 3.3.1</a>. + * <p> + * The former rules are also used by libcurl internally. + * <p> + * The rules are as follows + * + * A string matches another domain string if at least one of the following + * conditions holds: + * <ul> + * <li>The domain string and the string are identical. (Note that both the + * domain string and the string will have been canonicalized to lower case + * at this point.)</li> + * <li>All of the following conditions hold + * <ul> + * <li>The domain string is a suffix of the string.</li> + * <li>The last character of the string that is not included in the domain + * string is a %x2E (".") character.</li> + * <li>The string is a host name (i.e., not an IP address).</li> + * </ul> + * </li> + * </ul> + * + * @param host + * the host to compare against the cookieDomain + * @param cookieDomain + * the domain to compare against + * @return {@code true} if they domain-match; {@code false} if not + * + * @see <a href= "https://tools.ietf.org/html/rfc6265#section-5.1.3">RFC + * 6265, section 5.1.3 (Domain Matching)</a> + * @see <a href= + * "https://bugs.java.com/bugdatabase/view_bug.do?bug_id=8206092">JDK-8206092 + * : HttpCookie.domainMatches() does not match to sub-sub-domain</a> + */ + static boolean matchesCookieDomain(String host, String cookieDomain) { + cookieDomain = cookieDomain.toLowerCase(Locale.ROOT); + host = host.toLowerCase(Locale.ROOT); + if (host.equals(cookieDomain)) { + return true; + } else { + if (!host.endsWith(cookieDomain)) { + return false; + } + return host + .charAt(host.length() - cookieDomain.length() - 1) == '.'; + } + } + + /** + * The utility method to check whether a path is matching a cookie path + * domain or not. The rules are defined by + * <a href="https://tools.ietf.org/html/rfc6265#section-5.1.4">RFC 6265, + * section 5.1.4</a>: + * + * A request-path path-matches a given cookie-path if at least one of the + * following conditions holds: + * <ul> + * <li>The cookie-path and the request-path are identical.</li> + * <li>The cookie-path is a prefix of the request-path, and the last + * character of the cookie-path is %x2F ("/").</li> + * <li>The cookie-path is a prefix of the request-path, and the first + * character of the request-path that is not included in the cookie- path is + * a %x2F ("/") character.</li> + * </ul> + * @param path + * the path to check + * @param cookiePath + * the cookie's path + * + * @return {@code true} if they path-match; {@code false} if not + */ + static boolean matchesCookiePath(String path, String cookiePath) { + if (cookiePath.equals(path)) { + return true; + } + if (!cookiePath.endsWith("/")) { //$NON-NLS-1$ + cookiePath += "/"; //$NON-NLS-1$ + } + return path.startsWith(cookiePath); + } + private boolean isSmartHttp(HttpConnection c, String service) { final String expType = "application/x-" + service + "-advertisement"; //$NON-NLS-1$ //$NON-NLS-2$ final String actType = c.getContentType(); @@ -904,7 +1144,7 @@ public class TransportHttp extends HttpTransport implements WalkTransport, JGitText.get().expectedGot, exp, act)); } - while (pckIn.readString() != PacketLineIn.END) { + while (!PacketLineIn.isEnd(pckIn.readString())) { // for now, ignore the remaining header lines } } diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/transport/TransportLocal.java b/org.eclipse.jgit/src/org/eclipse/jgit/transport/TransportLocal.java index fbb2c44100..f2a2b0a1c2 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/transport/TransportLocal.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/transport/TransportLocal.java @@ -188,12 +188,8 @@ class TransportLocal extends Transport implements PackTransport { && !"git upload-pack".equals(up)) //$NON-NLS-1$ return new ForkLocalFetchConnection(); - UploadPackFactory<Void> upf = new UploadPackFactory<Void>() { - @Override - public UploadPack create(Void req, Repository db) { - return createUploadPack(db); - } - }; + UploadPackFactory<Void> upf = (Void req, + Repository db) -> createUploadPack(db); return new InternalFetchConnection<>(this, upf, null, openRepo()); } @@ -205,12 +201,8 @@ class TransportLocal extends Transport implements PackTransport { && !"git receive-pack".equals(rp)) //$NON-NLS-1$ return new ForkLocalPushConnection(); - ReceivePackFactory<Void> rpf = new ReceivePackFactory<Void>() { - @Override - public ReceivePack create(Void req, Repository db) { - return createReceivePack(db); - } - }; + ReceivePackFactory<Void> rpf = (Void req, + Repository db) -> createReceivePack(db); return new InternalPushConnection<>(this, rpf, null, openRepo()); } diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/transport/URIish.java b/org.eclipse.jgit/src/org/eclipse/jgit/transport/URIish.java index 70fb1f0e56..7ca9cc134c 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/transport/URIish.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/transport/URIish.java @@ -62,6 +62,7 @@ import java.util.regex.Pattern; import org.eclipse.jgit.internal.JGitText; import org.eclipse.jgit.lib.Constants; import org.eclipse.jgit.util.RawParseUtils; +import org.eclipse.jgit.util.References; import org.eclipse.jgit.util.StringUtils; /** @@ -362,8 +363,8 @@ public class URIish implements Serializable { if (p.length() >= 3 && p.charAt(0) == '/' && p.charAt(2) == ':' - && (p.charAt(1) >= 'A' && p.charAt(1) <= 'Z' || p.charAt(1) >= 'a' - && p.charAt(1) <= 'z')) + && ((p.charAt(1) >= 'A' && p.charAt(1) <= 'Z') + || (p.charAt(1) >= 'a' && p.charAt(1) <= 'z'))) return p.substring(1); else if (s != null && p.length() >= 2 && p.charAt(0) == '/' && p.charAt(1) == '~') @@ -624,8 +625,9 @@ public class URIish implements Serializable { } private static boolean eq(String a, String b) { - if (a == b) + if (References.isSameObject(a, b)) { return true; + } if (StringUtils.isEmptyOrNull(a) && StringUtils.isEmptyOrNull(b)) return true; if (a == null || b == null) 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 1d0f836619..9278f42adf 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/transport/UploadPack.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/transport/UploadPack.java @@ -44,13 +44,11 @@ package org.eclipse.jgit.transport; import static java.util.Collections.unmodifiableMap; -import static java.util.function.Function.identity; -import static java.util.stream.Collectors.toMap; import static org.eclipse.jgit.lib.Constants.R_TAGS; import static org.eclipse.jgit.transport.GitProtocolConstants.CAPABILITY_REF_IN_WANT; +import static org.eclipse.jgit.transport.GitProtocolConstants.CAPABILITY_SERVER_OPTION; 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.CAPABILITY_SERVER_OPTION; import static org.eclipse.jgit.transport.GitProtocolConstants.OPTION_AGENT; import static org.eclipse.jgit.transport.GitProtocolConstants.OPTION_ALLOW_REACHABLE_SHA1_IN_WANT; import static org.eclipse.jgit.transport.GitProtocolConstants.OPTION_ALLOW_TIP_SHA1_IN_WANT; @@ -66,6 +64,7 @@ import static org.eclipse.jgit.transport.GitProtocolConstants.OPTION_SHALLOW; import static org.eclipse.jgit.transport.GitProtocolConstants.OPTION_SIDE_BAND; import static org.eclipse.jgit.transport.GitProtocolConstants.OPTION_SIDE_BAND_64K; import static org.eclipse.jgit.transport.GitProtocolConstants.OPTION_THIN_PACK; +import static org.eclipse.jgit.util.RefMap.toRefMap; import java.io.ByteArrayOutputStream; import java.io.EOFException; @@ -81,8 +80,10 @@ import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Objects; +import java.util.Optional; import java.util.Set; import java.util.TreeMap; +import java.util.stream.Collectors; import org.eclipse.jgit.annotations.NonNull; import org.eclipse.jgit.annotations.Nullable; @@ -107,6 +108,7 @@ import org.eclipse.jgit.revwalk.AsyncRevObjectQueue; import org.eclipse.jgit.revwalk.BitmapWalker; import org.eclipse.jgit.revwalk.DepthWalk; import org.eclipse.jgit.revwalk.ObjectWalk; +import org.eclipse.jgit.revwalk.ReachabilityChecker; import org.eclipse.jgit.revwalk.RevCommit; import org.eclipse.jgit.revwalk.RevFlag; import org.eclipse.jgit.revwalk.RevFlagSet; @@ -817,7 +819,7 @@ public class UploadPack { // Fall back to all refs. setAdvertisedRefs( db.getRefDatabase().getRefs().stream() - .collect(toMap(Ref::getName, identity()))); + .collect(toRefMap((a, b) -> b))); } return refs; } @@ -836,7 +838,7 @@ public class UploadPack { String[] prefixes = refPrefixes.toArray(new String[0]); Map<String, Ref> rs = db.getRefDatabase().getRefsByPrefix(prefixes).stream() - .collect(toMap(Ref::getName, identity(), (a, b) -> b)); + .collect(toRefMap((a, b) -> b)); if (refFilter != RefFilter.DEFAULT) { return refFilter.filter(rs); } @@ -848,7 +850,7 @@ public class UploadPack { return refs.values().stream() .filter(ref -> refPrefixes.stream() .anyMatch(ref.getName()::startsWith)) - .collect(toMap(Ref::getName, identity())); + .collect(toRefMap((a, b) -> b)); } /** @@ -871,7 +873,7 @@ public class UploadPack { names.stream() .map(refs::get) .filter(Objects::nonNull) - .collect(toMap(Ref::getName, identity(), (a, b) -> b))); + .collect(toRefMap((a, b) -> b))); } /** @@ -1066,7 +1068,7 @@ public class UploadPack { findSymrefs(adv, refsToSend); } - adv.send(refsToSend); + adv.send(refsToSend.values()); adv.end(); } @@ -1227,7 +1229,7 @@ public class UploadPack { /* EOF when awaiting command is fine */ return true; } - if (command == PacketLineIn.END) { + if (PacketLineIn.isEnd(command)) { // A blank request is valid according // to the protocol; do nothing in this // case. @@ -1477,7 +1479,8 @@ public class UploadPack { } adv.setDerefTags(true); findSymrefs(adv, advertisedOrDefaultRefs); - advertised = adv.send(advertisedOrDefaultRefs); + advertised = adv.send(advertisedOrDefaultRefs.values()); + if (adv.isEmpty()) adv.advertiseId(ObjectId.zeroId(), "capabilities^{}"); //$NON-NLS-1$ adv.end(); @@ -1526,17 +1529,30 @@ public class UploadPack { } /** - * Returns the filter blob limit for the current request. Valid only after - * calling recvWants(). A limit -1 means no limit. + * Deprecated synonym for {@code getFilterSpec().getBlobLimit()}. * * @return filter blob limit requested by the client, or -1 if no limit * @since 5.3 + * @deprecated Use {@link #getFilterSpec()} instead */ - public long getFilterBlobLimit() { + @Deprecated + public final long getFilterBlobLimit() { + return getFilterSpec().getBlobLimit(); + } + + /** + * Returns the filter spec for the current request. Valid only after + * calling recvWants(). This may be a no-op filter spec, but it won't be + * null. + * + * @return filter requested by the client + * @since 5.4 + */ + public final FilterSpec getFilterSpec() { if (currentRequest == null) { throw new RequestNotYetReadException(); } - return currentRequest.getFilterBlobLimit(); + return currentRequest.getFilterSpec(); } /** @@ -1584,7 +1600,7 @@ public class UploadPack { throw eof; } - if (line == PacketLineIn.END) { + if (PacketLineIn.isEnd(line)) { last = processHaveLines(peerHas, last, pckOut); if (commonBase.isEmpty() || multiAck != MultiAck.OFF) pckOut.writeString("NAK\n"); //$NON-NLS-1$ @@ -1854,58 +1870,88 @@ public class UploadPack { private static void checkNotAdvertisedWants(UploadPack up, List<ObjectId> notAdvertisedWants, Set<ObjectId> reachableFrom) - throws MissingObjectException, IncorrectObjectTypeException, IOException { - // Walk the requested commits back to the provided set of commits. If any - // commit exists, a branch was deleted or rewound and the repository owner - // no longer exports that requested item. If the requested commit is merged - // into an advertised branch it will be marked UNINTERESTING and no commits - // return. + throws IOException { ObjectReader reader = up.getRevWalk().getObjectReader(); try (RevWalk walk = new RevWalk(reader)) { - AsyncRevObjectQueue q = walk.parseAny(notAdvertisedWants, true); - try { - RevObject obj; - while ((obj = q.next()) != null) { - if (!(obj instanceof RevCommit)) { - // If unadvertized non-commits are requested, use - // bitmaps. If there are no bitmaps, instead of - // incurring the expense of a manual walk, reject - // the request. - BitmapIndex bitmapIndex = reader.getBitmapIndex(); - if (bitmapIndex != null) { - checkNotAdvertisedWantsUsingBitmap( - reader, - bitmapIndex, - notAdvertisedWants, - reachableFrom); - return; - } - throw new WantNotValidException(obj); - } - walk.markStart((RevCommit) obj); + walk.setRetainBody(false); + // Missing "wants" throw exception here + List<RevObject> wantsAsObjs = objectIdsToRevObjects(walk, + notAdvertisedWants); + List<RevCommit> wantsAsCommits = wantsAsObjs.stream() + .filter(obj -> obj instanceof RevCommit) + .map(obj -> (RevCommit) obj) + .collect(Collectors.toList()); + boolean allWantsAreCommits = wantsAsObjs.size() == wantsAsCommits + .size(); + boolean repoHasBitmaps = reader.getBitmapIndex() != null; + + if (!allWantsAreCommits) { + if (!repoHasBitmaps) { + // If unadvertized non-commits are requested, use + // bitmaps. If there are no bitmaps, instead of + // incurring the expense of a manual walk, reject + // the request. + RevObject nonCommit = wantsAsObjs + .stream() + .filter(obj -> !(obj instanceof RevCommit)) + .limit(1) + .collect(Collectors.toList()).get(0); + throw new WantNotValidException(nonCommit); + } - } catch (MissingObjectException notFound) { - throw new WantNotValidException(notFound.getObjectId(), - notFound); - } finally { - q.release(); + checkNotAdvertisedWantsUsingBitmap(reader, + reader.getBitmapIndex(), notAdvertisedWants, + reachableFrom); + return; } - for (ObjectId id : reachableFrom) { - try { - walk.markUninteresting(walk.parseCommit(id)); - } catch (IncorrectObjectTypeException notCommit) { - continue; - } + + // All wants are commits, we can use ReachabilityChecker + ReachabilityChecker reachabilityChecker = walk + .createReachabilityChecker(); + + List<RevCommit> starters = objectIdsToRevCommits(walk, + reachableFrom); + Optional<RevCommit> unreachable = reachabilityChecker + .areAllReachable(wantsAsCommits, starters); + if (unreachable.isPresent()) { + throw new WantNotValidException(unreachable.get()); } - RevCommit bad = walk.next(); - if (bad != null) { - throw new WantNotValidException(bad); + } catch (MissingObjectException notFound) { + throw new WantNotValidException(notFound.getObjectId(), notFound); + } + } + + // Resolve the ObjectIds into RevObjects. Any missing object raises an + // exception + private static List<RevObject> objectIdsToRevObjects(RevWalk walk, + Iterable<ObjectId> objectIds) + throws MissingObjectException, IOException { + List<RevObject> result = new ArrayList<>(); + for (ObjectId objectId : objectIds) { + result.add(walk.parseAny(objectId)); + } + return result; + } + + // Get commits from object ids. If the id is not a commit, ignore it. If the + // id doesn't exist, report the missing object in a exception. + private static List<RevCommit> objectIdsToRevCommits(RevWalk walk, + Iterable<ObjectId> objectIds) + throws MissingObjectException, IOException { + List<RevCommit> result = new ArrayList<>(); + for (ObjectId objectId : objectIds) { + try { + result.add(walk.parseCommit(objectId)); + } catch (IncorrectObjectTypeException e) { + continue; } } + return result; } + private void addCommonBase(RevObject o) { if (!o.has(COMMON)) { o.add(COMMON); @@ -1988,21 +2034,12 @@ public class UploadPack { } catch (ServiceMayNotContinueException noPack) { // This was already reported on (below). throw noPack; - } catch (IOException err) { - if (reportInternalServerErrorOverSideband()) - throw new UploadPackInternalServerErrorException(err); - else - throw err; - } catch (RuntimeException err) { - if (reportInternalServerErrorOverSideband()) - throw new UploadPackInternalServerErrorException(err); - else - throw err; - } catch (Error err) { - if (reportInternalServerErrorOverSideband()) + } catch (IOException | RuntimeException | Error err) { + if (reportInternalServerErrorOverSideband()) { throw new UploadPackInternalServerErrorException(err); - else + } else { throw err; + } } } else { sendPack(false, req, accumulator, allTags, unshallowCommits, deepenNots); @@ -2097,15 +2134,16 @@ public class UploadPack { accumulator); try { pw.setIndexDisabled(true); - if (req.getFilterBlobLimit() >= 0) { - pw.setFilterBlobLimit(req.getFilterBlobLimit()); - pw.setUseCachedPacks(false); - } else { + if (req.getFilterSpec().isNoOp()) { pw.setUseCachedPacks(true); + } else { + pw.setFilterSpec(req.getFilterSpec()); + pw.setUseCachedPacks(false); } pw.setUseBitmaps( req.getDepth() == 0 - && req.getClientShallowCommits().isEmpty()); + && req.getClientShallowCommits().isEmpty() + && req.getFilterSpec().getTreeDepthLimit() == -1); pw.setClientShallowCommits(req.getClientShallowCommits()); pw.setReuseDeltaCommits(true); pw.setDeltaBaseAsOffset( diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/transport/WalkFetchConnection.java b/org.eclipse.jgit/src/org/eclipse/jgit/transport/WalkFetchConnection.java index 2bb58144ba..b289e42177 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/transport/WalkFetchConnection.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/transport/WalkFetchConnection.java @@ -657,7 +657,7 @@ class WalkFetchConnection extends BaseFetchConnection { } ObjectId act = inserter.insert(type, raw); - if (!AnyObjectId.equals(id, act)) { + if (!AnyObjectId.isEqual(id, act)) { throw new TransportException(MessageFormat.format( JGitText.get().incorrectHashFor, id.name(), act.name(), Constants.typeString(type), diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/transport/WalkPushConnection.java b/org.eclipse.jgit/src/org/eclipse/jgit/transport/WalkPushConnection.java index 4c754252a3..d9103f8b27 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/transport/WalkPushConnection.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/transport/WalkPushConnection.java @@ -165,7 +165,7 @@ class WalkPushConnection extends BaseConnection implements PushConnection { continue; } - if (AnyObjectId.equals(ObjectId.zeroId(), u.getNewObjectId())) + if (AnyObjectId.isEqual(ObjectId.zeroId(), u.getNewObjectId())) deleteCommand(u); else updates.add(u); diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/transport/resolver/FileResolver.java b/org.eclipse.jgit/src/org/eclipse/jgit/transport/resolver/FileResolver.java index 60acd2f8ae..b4a7af094d 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/transport/resolver/FileResolver.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/transport/resolver/FileResolver.java @@ -127,11 +127,7 @@ public class FileResolver<C> implements RepositoryResolver<C> { } else throw new ServiceNotEnabledException(); - } catch (RuntimeException e) { - db.close(); - throw new RepositoryNotFoundException(name, e); - - } catch (IOException e) { + } catch (RuntimeException | IOException e) { db.close(); throw new RepositoryNotFoundException(name, e); diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/transport/resolver/ReceivePackFactory.java b/org.eclipse.jgit/src/org/eclipse/jgit/transport/resolver/ReceivePackFactory.java index b850d1ef94..5d36e58c01 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/transport/resolver/ReceivePackFactory.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/transport/resolver/ReceivePackFactory.java @@ -57,12 +57,8 @@ public interface ReceivePackFactory<C> { /** * A factory disabling the ReceivePack service for all repositories */ - ReceivePackFactory<?> DISABLED = new ReceivePackFactory<Object>() { - @Override - public ReceivePack create(Object req, Repository db) - throws ServiceNotEnabledException { - throw new ServiceNotEnabledException(); - } + ReceivePackFactory<?> DISABLED = (Object req, Repository db) -> { + throw new ServiceNotEnabledException(); }; /** diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/transport/resolver/RepositoryResolver.java b/org.eclipse.jgit/src/org/eclipse/jgit/transport/resolver/RepositoryResolver.java index 4816f21bcc..dd24b7a0f2 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/transport/resolver/RepositoryResolver.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/transport/resolver/RepositoryResolver.java @@ -57,12 +57,8 @@ public interface RepositoryResolver<C> { /** * Resolver configured to open nothing. */ - RepositoryResolver<?> NONE = new RepositoryResolver<Object>() { - @Override - public Repository open(Object req, String name) - throws RepositoryNotFoundException { - throw new RepositoryNotFoundException(name); - } + RepositoryResolver<?> NONE = (Object req, String name) -> { + throw new RepositoryNotFoundException(name); }; /** diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/transport/resolver/UploadPackFactory.java b/org.eclipse.jgit/src/org/eclipse/jgit/transport/resolver/UploadPackFactory.java index bb43b136d8..b8673f5eb5 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/transport/resolver/UploadPackFactory.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/transport/resolver/UploadPackFactory.java @@ -57,12 +57,8 @@ public interface UploadPackFactory<C> { /** * A factory disabling the UploadPack service for all repositories. */ - UploadPackFactory<?> DISABLED = new UploadPackFactory<Object>() { - @Override - public UploadPack create(Object req, Repository db) - throws ServiceNotEnabledException { - throw new ServiceNotEnabledException(); - } + UploadPackFactory<?> DISABLED = (Object req, Repository db) -> { + throw new ServiceNotEnabledException(); }; /** diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/treewalk/NameConflictTreeWalk.java b/org.eclipse.jgit/src/org/eclipse/jgit/treewalk/NameConflictTreeWalk.java index 61b130f93f..2f8af78f82 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/treewalk/NameConflictTreeWalk.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/treewalk/NameConflictTreeWalk.java @@ -323,8 +323,7 @@ public class NameConflictTreeWalk extends TreeWalk { @Override void popEntriesEqual() throws CorruptObjectException { final AbstractTreeIterator ch = currentHead; - for (int i = 0; i < trees.length; i++) { - final AbstractTreeIterator t = trees[i]; + for (AbstractTreeIterator t : trees) { if (t.matches == ch) { if (t.matchShift == 0) t.next(1); @@ -343,8 +342,7 @@ public class NameConflictTreeWalk extends TreeWalk { @Override void skipEntriesEqual() throws CorruptObjectException { final AbstractTreeIterator ch = currentHead; - for (int i = 0; i < trees.length; i++) { - final AbstractTreeIterator t = trees[i]; + for (AbstractTreeIterator t : trees) { if (t.matches == ch) { if (t.matchShift == 0) t.skip(); 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 69303d6ee3..65d8512179 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/treewalk/TreeWalk.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/treewalk/TreeWalk.java @@ -1338,8 +1338,7 @@ public class TreeWalk implements AutoCloseable, AttributesProvider { void popEntriesEqual() throws CorruptObjectException { final AbstractTreeIterator ch = currentHead; - for (int i = 0; i < trees.length; i++) { - final AbstractTreeIterator t = trees[i]; + for (AbstractTreeIterator t : trees) { if (t.matches == ch) { t.next(1); t.matches = null; @@ -1349,8 +1348,7 @@ public class TreeWalk implements AutoCloseable, AttributesProvider { void skipEntriesEqual() throws CorruptObjectException { final AbstractTreeIterator ch = currentHead; - for (int i = 0; i < trees.length; i++) { - final AbstractTreeIterator t = trees[i]; + for (AbstractTreeIterator t : trees) { if (t.matches == ch) { t.skip(); t.matches = null; @@ -1398,10 +1396,8 @@ public class TreeWalk implements AutoCloseable, AttributesProvider { * @param <T> * a tree type. */ - public <T extends AbstractTreeIterator> T getTree( - Class<T> type) { - for (int i = 0; i < trees.length; i++) { - AbstractTreeIterator tree = trees[i]; + public <T extends AbstractTreeIterator> T getTree(Class<T> type) { + for (AbstractTreeIterator tree : trees) { if (type.isInstance(tree)) { return type.cast(tree); } 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 90524fedaf..f816ff370e 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/treewalk/WorkingTreeIterator.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/treewalk/WorkingTreeIterator.java @@ -787,14 +787,10 @@ public abstract class WorkingTreeIterator extends AbstractTreeIterator { return attributesNode; } - private static final Comparator<Entry> ENTRY_CMP = new Comparator<Entry>() { - @Override - public int compare(Entry a, Entry b) { - return Paths.compare( - a.encodedName, 0, a.encodedNameLen, a.getMode().getBits(), - b.encodedName, 0, b.encodedNameLen, b.getMode().getBits()); - } - }; + private static final Comparator<Entry> ENTRY_CMP = (Entry a, + Entry b) -> Paths.compare(a.encodedName, 0, a.encodedNameLen, + a.getMode().getBits(), b.encodedName, 0, b.encodedNameLen, + b.getMode().getBits()); /** * Constructor helper. @@ -1547,6 +1543,7 @@ public abstract class WorkingTreeIterator extends AbstractTreeIterator { ObjectId blobId = entry.getObjectId(); if (entry.getStage() > 0 && entry.getStage() != DirCacheEntry.STAGE_2) { + blobId = null; // Merge conflict: check ours (stage 2) byte[] name = entry.getRawPath(); int i = 0; @@ -1554,7 +1551,8 @@ public abstract class WorkingTreeIterator extends AbstractTreeIterator { dirCache.next(1); i++; entry = dirCache.getDirCacheEntry(); - if (!Arrays.equals(name, entry.getRawPath())) { + if (entry == null + || !Arrays.equals(name, entry.getRawPath())) { break; } if (entry.getStage() == DirCacheEntry.STAGE_2) { @@ -1564,17 +1562,20 @@ public abstract class WorkingTreeIterator extends AbstractTreeIterator { } dirCache.back(i); } - try (ObjectReader reader = repository.newObjectReader()) { - ObjectLoader loader = reader.open(blobId, Constants.OBJ_BLOB); - try { - return RawText.isCrLfText(loader.getCachedBytes()); - } catch (LargeObjectException e) { - try (InputStream in = loader.openStream()) { - return RawText.isCrLfText(in); + if (blobId != null) { + try (ObjectReader reader = repository.newObjectReader()) { + ObjectLoader loader = reader.open(blobId, + Constants.OBJ_BLOB); + try { + return RawText.isCrLfText(loader.getCachedBytes()); + } catch (LargeObjectException e) { + try (InputStream in = loader.openStream()) { + return RawText.isCrLfText(in); + } } + } catch (IOException e) { + // Ignore and return false below } - } catch (IOException e) { - // Ignore and return false below } } return false; diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/treewalk/filter/TreeFilterMarker.java b/org.eclipse.jgit/src/org/eclipse/jgit/treewalk/filter/TreeFilterMarker.java index 738ccbd8b7..c28f03534c 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/treewalk/filter/TreeFilterMarker.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/treewalk/filter/TreeFilterMarker.java @@ -113,7 +113,7 @@ public class TreeFilterMarker { try { boolean marked = filter.include(walk); if (marked) - marks |= (1L << index); + marks |= (1 << index); } catch (StopWalkException e) { // Don't check tree filter anymore, it will no longer // match 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 a9cef59636..90305013f5 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/util/FS.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/util/FS.java @@ -363,7 +363,7 @@ public abstract class FS { } return attributes; }); - f.exceptionally(e -> { + f = f.exceptionally(e -> { LOG.error(e.getLocalizedMessage(), e); return Optional.empty(); }); @@ -1042,13 +1042,9 @@ public abstract class FS { * @return the user's home directory; null if the user does not have one. */ protected File userHomeImpl() { - final String home = AccessController - .doPrivileged(new PrivilegedAction<String>() { - @Override - public String run() { - return System.getProperty("user.home"); //$NON-NLS-1$ - } - }); + final String home = AccessController.doPrivileged( + (PrivilegedAction<String>) () -> System.getProperty("user.home") //$NON-NLS-1$ + ); if (home == null || home.length() == 0) return null; return new File(home).getAbsoluteFile(); diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/util/FS_POSIX.java b/org.eclipse.jgit/src/org/eclipse/jgit/util/FS_POSIX.java index eda0fae247..a485389a9a 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/util/FS_POSIX.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/util/FS_POSIX.java @@ -51,8 +51,9 @@ import java.io.IOException; import java.io.InputStreamReader; import java.io.PrintStream; import java.nio.charset.Charset; -import java.nio.file.AccessDeniedException; import java.nio.file.FileAlreadyExistsException; +import java.nio.file.FileStore; +import java.nio.file.FileSystemException; import java.nio.file.Files; import java.nio.file.InvalidPathException; import java.nio.file.Path; @@ -62,9 +63,11 @@ import java.text.MessageFormat; import java.util.ArrayList; import java.util.Arrays; import java.util.List; +import java.util.Map; import java.util.Optional; import java.util.Set; import java.util.UUID; +import java.util.concurrent.ConcurrentHashMap; import org.eclipse.jgit.annotations.Nullable; import org.eclipse.jgit.api.errors.JGitInternalException; @@ -88,7 +91,7 @@ public class FS_POSIX extends FS { private static final int DEFAULT_UMASK = 0022; private volatile int umask = -1; - private volatile boolean supportsUnixNLink = true; + private static final Map<FileStore, Boolean> CAN_HARD_LINK = new ConcurrentHashMap<>(); private volatile AtomicFileCreation supportsAtomicFileCreation = AtomicFileCreation.UNDEFINED; @@ -375,12 +378,23 @@ public class FS_POSIX extends FS { if (!lock.createNewFile()) { return false; } - if (supportsAtomicCreateNewFile() || !supportsUnixNLink) { + if (supportsAtomicCreateNewFile()) { return true; } Path lockPath = lock.toPath(); Path link = null; + FileStore store = null; try { + store = Files.getFileStore(lockPath); + } catch (SecurityException e) { + return true; + } + try { + Boolean canLink = CAN_HARD_LINK.computeIfAbsent(store, + s -> Boolean.TRUE); + if (Boolean.FALSE.equals(canLink)) { + return true; + } link = Files.createLink( Paths.get(lock.getAbsolutePath() + ".lnk"), //$NON-NLS-1$ lockPath); @@ -392,11 +406,11 @@ public class FS_POSIX extends FS { nlink)); return false; } else if (nlink < 2) { - supportsUnixNLink = false; + CAN_HARD_LINK.put(store, Boolean.FALSE); } return true; } catch (UnsupportedOperationException | IllegalArgumentException e) { - supportsUnixNLink = false; + CAN_HARD_LINK.put(store, Boolean.FALSE); return true; } finally { if (link != null) { @@ -439,11 +453,22 @@ public class FS_POSIX extends FS { } catch (FileAlreadyExistsException | InvalidPathException e) { return token(false, null); } - if (supportsAtomicCreateNewFile() || !supportsUnixNLink) { + if (supportsAtomicCreateNewFile()) { return token(true, null); } Path link = null; + FileStore store = null; try { + store = Files.getFileStore(path); + } catch (SecurityException e) { + return token(true, null); + } + try { + Boolean canLink = CAN_HARD_LINK.computeIfAbsent(store, + s -> Boolean.TRUE); + if (Boolean.FALSE.equals(canLink)) { + return token(true, null); + } link = Files.createLink(Paths.get(uniqueLinkPath(file)), path); Integer nlink = (Integer) (Files.getAttribute(path, "unix:nlink")); //$NON-NLS-1$ @@ -452,12 +477,12 @@ public class FS_POSIX extends FS { JGitText.get().failedAtomicFileCreation, path, nlink)); return token(false, link); } else if (nlink.intValue() < 2) { - supportsUnixNLink = false; + CAN_HARD_LINK.put(store, Boolean.FALSE); } return token(true, link); } catch (UnsupportedOperationException | IllegalArgumentException - | AccessDeniedException | SecurityException e) { - supportsUnixNLink = false; + | FileSystemException | SecurityException e) { + CAN_HARD_LINK.put(store, Boolean.FALSE); return token(true, link); } } 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 7c07270363..7fe80bb21a 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 @@ -205,18 +205,21 @@ public class FS_Win32 extends FS { @Override protected File userHomeImpl() { String home = SystemReader.getInstance().getenv("HOME"); //$NON-NLS-1$ - if (home != null) + if (home != null) { return resolve(null, home); + } String homeDrive = SystemReader.getInstance().getenv("HOMEDRIVE"); //$NON-NLS-1$ if (homeDrive != null) { String homePath = SystemReader.getInstance().getenv("HOMEPATH"); //$NON-NLS-1$ - if (homePath != null) + if (homePath != null) { return new File(homeDrive, homePath); + } } String homeShare = SystemReader.getInstance().getenv("HOMESHARE"); //$NON-NLS-1$ - if (homeShare != null) + if (homeShare != null) { return new File(homeShare); + } return super.userHomeImpl(); } @@ -237,8 +240,9 @@ public class FS_Win32 extends FS { /** {@inheritDoc} */ @Override public boolean supportsSymlinks() { - if (supportSymlinks == null) + if (supportSymlinks == null) { detectSymlinkSupport(); + } return Boolean.TRUE.equals(supportSymlinks); } @@ -254,12 +258,13 @@ public class FS_Win32 extends FS { | InternalError e) { supportSymlinks = Boolean.FALSE; } finally { - if (tempFile != null) + if (tempFile != null) { try { FileUtils.delete(tempFile); } catch (IOException e) { throw new RuntimeException(e); // panic } + } } } 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 e5c8d9d398..9a163e8e38 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 @@ -80,12 +80,9 @@ public class FS_Win32_Cygwin extends FS_Win32 { */ public static boolean isCygwin() { final String path = AccessController - .doPrivileged(new PrivilegedAction<String>() { - @Override - public String run() { - return System.getProperty("java.library.path"); //$NON-NLS-1$ - } - }); + .doPrivileged((PrivilegedAction<String>) () -> System + .getProperty("java.library.path") //$NON-NLS-1$ + ); if (path == null) return false; File found = FS.searchPath(path, "cygpath.exe"); //$NON-NLS-1$ @@ -141,13 +138,9 @@ public class FS_Win32_Cygwin extends FS_Win32 { /** {@inheritDoc} */ @Override protected File userHomeImpl() { - final String home = AccessController - .doPrivileged(new PrivilegedAction<String>() { - @Override - public String run() { - return System.getenv("HOME"); //$NON-NLS-1$ - } - }); + final String home = AccessController.doPrivileged( + (PrivilegedAction<String>) () -> System.getenv("HOME") //$NON-NLS-1$ + ); if (home == null || home.length() == 0) return super.userHomeImpl(); return resolve(new File("."), home); //$NON-NLS-1$ 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 9f7d9a236e..4d791e470a 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/util/FileUtils.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/util/FileUtils.java @@ -48,6 +48,7 @@ package org.eclipse.jgit.util; import static java.nio.charset.StandardCharsets.UTF_8; import java.io.File; +import java.io.FileNotFoundException; import java.io.IOException; import java.nio.channels.FileChannel; import java.nio.file.AtomicMoveNotSupportedException; @@ -200,31 +201,50 @@ public class FileUtils { if ((options & EMPTY_DIRECTORIES_ONLY) != 0) { if (f.isDirectory()) { delete = true; - } else { - if ((options & IGNORE_ERRORS) == 0) - throw new IOException(MessageFormat.format( - JGitText.get().deleteFileFailed, - f.getAbsolutePath())); + } else if ((options & IGNORE_ERRORS) == 0) { + throw new IOException(MessageFormat.format( + JGitText.get().deleteFileFailed, f.getAbsolutePath())); } } else { delete = true; } - if (delete && !f.delete()) { - if ((options & RETRY) != 0 && fs.exists(f)) { + if (delete) { + Throwable t = null; + Path p = f.toPath(); + try { + Files.delete(p); + return; + } catch (FileNotFoundException e) { + if ((options & (SKIP_MISSING | IGNORE_ERRORS)) == 0) { + throw new IOException(MessageFormat.format( + JGitText.get().deleteFileFailed, + f.getAbsolutePath()), e); + } + return; + } catch (IOException e) { + t = e; + } + if ((options & RETRY) != 0) { for (int i = 1; i < 10; i++) { try { Thread.sleep(100); - } catch (InterruptedException e) { + } catch (InterruptedException ex) { // ignore } - if (f.delete()) + try { + Files.deleteIfExists(p); return; + } catch (IOException e) { + t = e; + } } } - if ((options & IGNORE_ERRORS) == 0) + if ((options & IGNORE_ERRORS) == 0) { throw new IOException(MessageFormat.format( - JGitText.get().deleteFileFailed, f.getAbsolutePath())); + JGitText.get().deleteFileFailed, f.getAbsolutePath()), + t); + } } } diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/util/GSSManagerFactory.java b/org.eclipse.jgit/src/org/eclipse/jgit/util/GSSManagerFactory.java index da57999e29..5927b33355 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/util/GSSManagerFactory.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/util/GSSManagerFactory.java @@ -145,13 +145,8 @@ public abstract class GSSManagerFactory { return (GSSManager) GSS_MANAGER_IMPL_CONSTRUCTOR .newInstance(httpCaller); - } catch (InstantiationException e) { - throw new Error(e); - } catch (IllegalAccessException e) { - throw new Error(e); - } catch (IllegalArgumentException e) { - throw new Error(e); - } catch (InvocationTargetException e) { + } catch (InstantiationException | IllegalAccessException + | IllegalArgumentException | InvocationTargetException e) { throw new Error(e); } } diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/util/GitDateParser.java b/org.eclipse.jgit/src/org/eclipse/jgit/util/GitDateParser.java index a339b9aba0..56a173163d 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/util/GitDateParser.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/util/GitDateParser.java @@ -126,7 +126,7 @@ public class GitDateParser { DEFAULT("EEE MMM dd HH:mm:ss yyyy Z"), // //$NON-NLS-1$ LOCAL("EEE MMM dd HH:mm:ss yyyy"); //$NON-NLS-1$ - String formatStr; + private final String formatStr; private ParseableSimpleDateFormat(String formatStr) { this.formatStr = formatStr; diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/util/HttpSupport.java b/org.eclipse.jgit/src/org/eclipse/jgit/util/HttpSupport.java index 9190a5915a..640670debc 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/util/HttpSupport.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/util/HttpSupport.java @@ -170,6 +170,27 @@ public class HttpSupport { public static final String HDR_WWW_AUTHENTICATE = "WWW-Authenticate"; //$NON-NLS-1$ /** + * The {@code Cookie} header. + * + * @since 5.4 + */ + public static final String HDR_COOKIE = "Cookie"; //$NON-NLS-1$ + + /** + * The {@code Set-Cookie} header. + * + * @since 5.4 + */ + public static final String HDR_SET_COOKIE = "Set-Cookie"; //$NON-NLS-1$ + + /** + * The {@code Set-Cookie2} header. + * + * @since 5.4 + */ + public static final String HDR_SET_COOKIE2 = "Set-Cookie2"; //$NON-NLS-1$ + + /** * URL encode a value string into an output buffer. * * @param urlstr @@ -303,9 +324,7 @@ public class HttpSupport { try { conn.configure(null, trustAllCerts, null); conn.setHostnameVerifier(new DummyHostnameVerifier()); - } catch (KeyManagementException e) { - throw new IOException(e.getMessage()); - } catch (NoSuchAlgorithmException e) { + } catch (KeyManagementException | NoSuchAlgorithmException e) { throw new IOException(e.getMessage()); } } diff --git a/org.eclipse.jgit.ssh.apache/src/org/eclipse/jgit/internal/transport/sshd/JGitPublicKeyAuthentication.java b/org.eclipse.jgit/src/org/eclipse/jgit/util/LRUMap.java index 63b3990b13..41c15363f8 100644 --- a/org.eclipse.jgit.ssh.apache/src/org/eclipse/jgit/internal/transport/sshd/JGitPublicKeyAuthentication.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/util/LRUMap.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2018, Thomas Wolf <thomas.wolf@paranor.ch> + * Copyright (C) 2018, Konrad Windszus <konrad_w@gmx.de> * and other copyright owners as documented in the project's IP log. * * This program and the accompanying materials are made available @@ -40,64 +40,44 @@ * 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.transport.sshd; +package org.eclipse.jgit.util; -import java.util.List; - -import org.apache.sshd.client.auth.pubkey.UserAuthPublicKey; -import org.apache.sshd.client.session.ClientSession; -import org.apache.sshd.common.NamedFactory; -import org.apache.sshd.common.signature.Signature; +import java.util.LinkedHashMap; /** - * A specialized public key authentication handler that uses our own - * {@link JGitPublicKeyIterator}. The super class creates in - * {@link #init(ClientSession, String)} a - * {@link org.apache.sshd.client.auth.pubkey.UserAuthPublicKeyIterator}, which - * in its constructor does some strange {@link java.util.stream.Stream} "magic" - * that ends up loading keys prematurely. + * Map with only up to n entries. If a new entry is added so that the map + * contains more than those n entries the least-recently used entry is removed + * from the map. + * + * @param <K> + * the type of keys maintained by this map + * @param <V> + * the type of mapped values + * + * @since 5.4 */ -public class JGitPublicKeyAuthentication extends UserAuthPublicKey { +public class LRUMap<K, V> extends LinkedHashMap<K, V> { - private ClientSession clientSession; + private static final long serialVersionUID = 4329609127403759486L; - private String serviceName; + private final int limit; /** - * Creates a new {@link JGitPublicKeyAuthentication}. + * Constructs an empty map which may contain at most the given amount of + * entries. * - * @param factories - * signature factories to use + * @param initialCapacity + * the initial capacity + * @param limit + * the number of entries the map should have at most */ - public JGitPublicKeyAuthentication( - List<NamedFactory<Signature>> factories) { - super(factories); - } - - @Override - public void init(ClientSession session, String service) throws Exception { - // Do *not* call super.init(); it'll create a UserAuthPublicKeyIterator - // and that's where things then go wrong. Instead, do the whole - // initialization directly here. - clientSession = session; - serviceName = service; - releaseKeys(); - // Use our own iterator! - keys = new JGitPublicKeyIterator(session, this); - } - - @Override - public ClientSession getClientSession() { - return clientSession; - } - - @Override - public ClientSession getSession() { - return clientSession; + public LRUMap(int initialCapacity, int limit) { + super(initialCapacity, 0.75f, true); + this.limit = limit; } @Override - public String getService() { - return serviceName; + protected boolean removeEldestEntry(java.util.Map.Entry<K, V> eldest) { + return size() > limit; } } diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/util/RefList.java b/org.eclipse.jgit/src/org/eclipse/jgit/util/RefList.java index 639c353621..60dead51b2 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/util/RefList.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/util/RefList.java @@ -48,7 +48,10 @@ import java.util.Collections; import java.util.Iterator; import java.util.List; import java.util.NoSuchElementException; +import java.util.function.BinaryOperator; +import java.util.stream.Collector; +import org.eclipse.jgit.annotations.Nullable; import org.eclipse.jgit.lib.Ref; import org.eclipse.jgit.lib.RefComparator; @@ -333,6 +336,32 @@ public class RefList<T extends Ref> implements Iterable<Ref> { } /** + * Create a {@link Collector} for {@link Ref}. + * + * @param mergeFunction + * if specified the result will be sorted and deduped. + * @return {@link Collector} for {@link Ref} + * @since 5.4 + */ + public static <T extends Ref> Collector<T, ?, RefList<T>> toRefList( + @Nullable BinaryOperator<T> mergeFunction) { + return Collector.of( + () -> new Builder<>(), + Builder<T>::add, (b1, b2) -> { + Builder<T> b = new Builder<>(); + b.addAll(b1); + b.addAll(b2); + return b; + }, (b) -> { + if (mergeFunction != null) { + b.sort(); + b.dedupe(mergeFunction); + } + return b.toRefList(); + }); + } + + /** * Builder to facilitate fast construction of an immutable RefList. * * @param <T> @@ -405,6 +434,16 @@ public class RefList<T extends Ref> implements Iterable<Ref> { } /** + * Add all items from another builder. + * + * @param other + * @since 5.4 + */ + public void addAll(Builder other) { + addAll(other.list, 0, other.size); + } + + /** * Add all items from a source array. * <p> * References must be added in sort order, or the array must be sorted @@ -444,6 +483,31 @@ public class RefList<T extends Ref> implements Iterable<Ref> { Arrays.sort(list, 0, size, RefComparator.INSTANCE); } + /** + * Dedupe the refs in place. Must be called after {@link #sort}. + * + * @param mergeFunction + */ + @SuppressWarnings("unchecked") + void dedupe(BinaryOperator<T> mergeFunction) { + if (size == 0) { + return; + } + int lastElement = 0; + for (int i = 1; i < size; i++) { + if (RefComparator.INSTANCE.compare(list[lastElement], + list[i]) == 0) { + list[lastElement] = mergeFunction + .apply((T) list[lastElement], (T) list[i]); + } else { + list[lastElement + 1] = list[i]; + lastElement++; + } + } + size = lastElement + 1; + Arrays.fill(list, size, list.length, null); + } + /** @return an unmodifiable list using this collection's backing array. */ public RefList<T> toRefList() { return new RefList<>(list, size); diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/util/RefMap.java b/org.eclipse.jgit/src/org/eclipse/jgit/util/RefMap.java index a3f9730f13..9663e3cef5 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/util/RefMap.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/util/RefMap.java @@ -49,6 +49,9 @@ import java.util.Iterator; import java.util.Map; import java.util.NoSuchElementException; import java.util.Set; +import java.util.function.BinaryOperator; +import java.util.stream.Collector; +import java.util.stream.Collectors; import org.eclipse.jgit.lib.AnyObjectId; import org.eclipse.jgit.lib.ObjectId; @@ -285,6 +288,21 @@ public class RefMap extends AbstractMap<String, Ref> { return r.toString(); } + /** + * Create a {@link Collector} for {@link Ref}. + * + * @param mergeFunction + * @return {@link Collector} for {@link Ref} + * @since 5.4 + */ + public static Collector<Ref, ?, RefMap> toRefMap( + BinaryOperator<Ref> mergeFunction) { + return Collectors.collectingAndThen(RefList.toRefList(mergeFunction), + (refs) -> new RefMap("", //$NON-NLS-1$ + refs, RefList.emptyList(), + RefList.emptyList())); + } + private String toRefName(String name) { if (0 < prefix.length()) name = prefix + name; @@ -425,8 +443,10 @@ public class RefMap extends AbstractMap<String, Ref> { if (r.getName().equals(ref.getName())) { final ObjectId a = r.getObjectId(); final ObjectId b = ref.getObjectId(); - if (a != null && b != null && AnyObjectId.equals(a, b)) + if (a != null && b != null + && AnyObjectId.isEqual(a, b)) { return true; + } } } } diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/util/References.java b/org.eclipse.jgit/src/org/eclipse/jgit/util/References.java new file mode 100644 index 0000000000..341fbfa943 --- /dev/null +++ b/org.eclipse.jgit/src/org/eclipse/jgit/util/References.java @@ -0,0 +1,67 @@ +/* + * Copyright (C) 2019, 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.util; + +/** + * Utility methods for object references + * + * @since 5.4 + */ +public interface References { + + /** + * Compare two references + * + * @param <T> + * type of the references + * @param ref1 + * first reference + * @param ref2 + * second reference + * @return {@code true} if both references refer to the same object + */ + @SuppressWarnings("ReferenceEquality") + public static <T> boolean isSameObject(T ref1, T ref2) { + return ref1 == ref2; + } +} diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/util/SimpleLruCache.java b/org.eclipse.jgit/src/org/eclipse/jgit/util/SimpleLruCache.java index 709d9ee73d..7235b15548 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/util/SimpleLruCache.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/util/SimpleLruCache.java @@ -159,6 +159,7 @@ public class SimpleLruCache<K, V> { * * @return value mapped for this key, or {@code null} if no value is mapped */ + @SuppressWarnings("NonAtomicVolatileUpdate") public V get(Object key) { Entry<K, V> entry = map.get(key); if (entry != null) { @@ -185,6 +186,7 @@ public class SimpleLruCache<K, V> { * @throws NullPointerException * if the specified key or value is null */ + @SuppressWarnings("NonAtomicVolatileUpdate") public V put(@NonNull K key, @NonNull V value) { map.put(key, new Entry<>(key, value, ++time)); if (map.size() > maximumSize) { diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/util/StringUtils.java b/org.eclipse.jgit/src/org/eclipse/jgit/util/StringUtils.java index 3868e56f50..f4b6f9d0df 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/util/StringUtils.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/util/StringUtils.java @@ -139,8 +139,9 @@ public final class StringUtils { * @return true if a equals b */ public static boolean equalsIgnoreCase(String a, String b) { - if (a == b) + if (References.isSameObject(a, b)) { return true; + } if (a.length() != b.length()) return false; for (int i = 0; i < a.length(); i++) { diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/util/SystemReader.java b/org.eclipse.jgit/src/org/eclipse/jgit/util/SystemReader.java index d554562a75..8431196cb5 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/util/SystemReader.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/util/SystemReader.java @@ -461,12 +461,9 @@ public abstract class SystemReader { } private String getOsName() { - return AccessController.doPrivileged(new PrivilegedAction<String>() { - @Override - public String run() { - return getProperty("os.name"); //$NON-NLS-1$ - } - }); + return AccessController.doPrivileged( + (PrivilegedAction<String>) () -> getProperty("os.name") //$NON-NLS-1$ + ); } /** diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/util/io/IsolatedOutputStream.java b/org.eclipse.jgit/src/org/eclipse/jgit/util/io/IsolatedOutputStream.java index 65470d4ef1..18de7052d9 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/util/io/IsolatedOutputStream.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/util/io/IsolatedOutputStream.java @@ -88,7 +88,7 @@ public class IsolatedOutputStream extends OutputStream { public IsolatedOutputStream(OutputStream out) { dst = out; copier = new ThreadPoolExecutor(1, 1, 0, TimeUnit.MILLISECONDS, - new ArrayBlockingQueue<Runnable>(1), new NamedThreadFactory()); + new ArrayBlockingQueue<>(1), new NamedThreadFactory()); } /** {@inheritDoc} */ @@ -102,12 +102,9 @@ public class IsolatedOutputStream extends OutputStream { public void write(byte[] buf, int pos, int cnt) throws IOException { checkClosed(); - execute(new Callable<Void>() { - @Override - public Void call() throws IOException { - dst.write(buf, pos, cnt); - return null; - } + execute(() -> { + dst.write(buf, pos, cnt); + return null; }); } @@ -115,12 +112,9 @@ public class IsolatedOutputStream extends OutputStream { @Override public void flush() throws IOException { checkClosed(); - execute(new Callable<Void>() { - @Override - public Void call() throws IOException { - dst.flush(); - return null; - } + execute(() -> { + dst.flush(); + return null; }); } @@ -159,12 +153,9 @@ public class IsolatedOutputStream extends OutputStream { } private void cleanClose() throws IOException { - execute(new Callable<Void>() { - @Override - public Void call() throws IOException { - dst.close(); - return null; - } + execute(() -> { + dst.close(); + return null; }); } @@ -178,12 +169,9 @@ public class IsolatedOutputStream extends OutputStream { Future<Void> close; try { - close = copier.submit(new Callable<Void>() { - @Override - public Void call() throws IOException { - dst.close(); - return null; - } + close = copier.submit(() -> { + dst.close(); + return null; }); } catch (RejectedExecutionException e) { throw new IOException(e); diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/util/io/ThrowingPrintWriter.java b/org.eclipse.jgit/src/org/eclipse/jgit/util/io/ThrowingPrintWriter.java index caabcef574..9431aafbde 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/util/io/ThrowingPrintWriter.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/util/io/ThrowingPrintWriter.java @@ -68,12 +68,10 @@ public class ThrowingPrintWriter extends Writer { */ public ThrowingPrintWriter(Writer out) { this.out = out; - LF = AccessController.doPrivileged(new PrivilegedAction<String>() { - @Override - public String run() { - return SystemReader.getInstance().getProperty("line.separator"); //$NON-NLS-1$ - } - }); + LF = AccessController + .doPrivileged((PrivilegedAction<String>) () -> SystemReader + .getInstance().getProperty("line.separator") //$NON-NLS-1$ + ); } /** {@inheritDoc} */ @@ -51,7 +51,7 @@ <groupId>org.eclipse.jgit</groupId> <artifactId>org.eclipse.jgit-parent</artifactId> <packaging>pom</packaging> - <version>5.3.3-SNAPSHOT</version> + <version>5.4.1-SNAPSHOT</version> <name>JGit - Parent</name> <url>${jgit-url}</url> @@ -182,8 +182,8 @@ <maven.build.timestamp.format>yyyyMMddHHmm</maven.build.timestamp.format> <bundle-manifest>${project.build.directory}/META-INF/MANIFEST.MF</bundle-manifest> - <jgit-last-release-version>5.2.0.201812061821-r</jgit-last-release-version> - <apache-sshd-version>2.0.0</apache-sshd-version> + <jgit-last-release-version>5.3.0.201903130848-r</jgit-last-release-version> + <apache-sshd-version>2.2.0</apache-sshd-version> <jsch-version>0.1.55</jsch-version> <jzlib-version>1.1.1</jzlib-version> <javaewah-version>1.1.6</javaewah-version> @@ -200,10 +200,10 @@ <slf4j-version>1.7.2</slf4j-version> <log4j-version>1.2.15</log4j-version> <maven-javadoc-plugin-version>3.1.0</maven-javadoc-plugin-version> - <tycho-extras-version>1.3.0</tycho-extras-version> + <tycho-extras-version>1.4.0</tycho-extras-version> <gson-version>2.8.2</gson-version> - <bouncycastle-version>1.60</bouncycastle-version> - <spotbugs-maven-plugin-version>3.1.11</spotbugs-maven-plugin-version> + <bouncycastle-version>1.61</bouncycastle-version> + <spotbugs-maven-plugin-version>3.1.12</spotbugs-maven-plugin-version> <maven-project-info-reports-plugin-version>3.0.0</maven-project-info-reports-plugin-version> <maven-jxr-plugin-version>3.0.0</maven-jxr-plugin-version> <spotbugs-maven-plugin-version>3.1.12</spotbugs-maven-plugin-version> diff --git a/tools/BUILD b/tools/BUILD index f0342ad75a..bfe0d6ef8b 100644 --- a/tools/BUILD +++ b/tools/BUILD @@ -26,13 +26,13 @@ java_package_configuration( "-Xep:ReferenceEquality:WARN", "-Xep:StringEquality:WARN", "-Xep:WildcardImport:ERROR", - "-Xep:AmbiguousMethodReference:WARN", + "-Xep:AmbiguousMethodReference:ERROR", "-Xep:BadAnnotationImplementation:ERROR", "-Xep:BadComparable:WARN", "-Xep:BoxedPrimitiveConstructor:ERROR", "-Xep:CannotMockFinalClass:ERROR", "-Xep:ClassCanBeStatic:ERROR", - "-Xep:ClassNewInstance:WARN", + "-Xep:ClassNewInstance:ERROR", "-Xep:DefaultCharset:ERROR", "-Xep:DoubleCheckedLocking:ERROR", "-Xep:ElementsCountedInLoop:ERROR", @@ -44,10 +44,10 @@ java_package_configuration( "-Xep:FragmentInjection:ERROR", "-Xep:FragmentNotInstantiable:ERROR", "-Xep:FunctionalInterfaceClash:ERROR", - "-Xep:FutureReturnValueIgnored:WARN", + "-Xep:FutureReturnValueIgnored:ERROR", "-Xep:GetClassOnEnum:ERROR", "-Xep:ImmutableAnnotationChecker:ERROR", - "-Xep:ImmutableEnumChecker:WARN", + "-Xep:ImmutableEnumChecker:ERROR", "-Xep:IncompatibleModifiers:ERROR", "-Xep:InjectOnConstructorOfAbstractClass:ERROR", "-Xep:InputStreamSlowMultibyteRead:ERROR", @@ -58,19 +58,19 @@ java_package_configuration( "-Xep:MissingFail:ERROR", "-Xep:MissingOverride:ERROR", "-Xep:MutableConstantField:ERROR", - "-Xep:NarrowingCompoundAssignment:WARN", + "-Xep:NarrowingCompoundAssignment:ERROR", "-Xep:NonAtomicVolatileUpdate:ERROR", - "-Xep:NonOverridingEquals:WARN", + "-Xep:NonOverridingEquals:ERROR", "-Xep:NullableConstructor:ERROR", "-Xep:NullablePrimitive:ERROR", "-Xep:NullableVoid:ERROR", - "-Xep:OperatorPrecedence:WARN", + "-Xep:OperatorPrecedence:ERROR", "-Xep:OverridesGuiceInjectableMethod:ERROR", "-Xep:PreconditionsInvalidPlaceholder:ERROR", "-Xep:ProtoFieldPreconditionsCheckNotNull:ERROR", "-Xep:ProtocolBufferOrdinal:ERROR", "-Xep:RequiredModifiers:ERROR", - "-Xep:ShortCircuitBoolean:WARN", + "-Xep:ShortCircuitBoolean:ERROR", "-Xep:SimpleDateFormatConstant:ERROR", "-Xep:StaticGuardedByInstance:ERROR", "-Xep:SynchronizeOnNonFinalField:ERROR", diff --git a/tools/version.sh b/tools/version.sh index 8b8095db42..80693cdbdb 100755 --- a/tools/version.sh +++ b/tools/version.sh @@ -131,7 +131,8 @@ perl -pi~ -e ' $seen_version = 1 if (!/<\?xml/ && s/(version=")[^"]*(")/${1}'"$OSGI_V"'${2}/); } - s/(import feature="org\.eclipse\.jgit.*" version=")[^"]*(")/${1}'"$API_V"'${2}/; + s/(import feature="org\.eclipse\.jgit[^"]*" version=")[^"]*(")/${1}'"$API_V"'${2}/; + s/(import plugin="org\.eclipse\.jgit[^"]*" version=")[^"]*(")/${1}'"$API_V"'${2}/; ' org.eclipse.jgit.packaging/org.*.feature/feature.xml perl -pi~ -e ' @@ -139,22 +140,11 @@ perl -pi~ -e ' $seen_version = 0; $old_argv = $ARGV; } - if (!$seen_version) { - $seen_version = 1 if - s{<(version)>.*</\1>}{<${1}>'"$POM_V"'</${1}>}; - } - ' org.eclipse.jgit.packaging/org.*.feature/pom.xml - -perl -pi~ -e ' - if ($ARGV ne $old_argv) { - $seen_version = 0; - $old_argv = $ARGV; - } - if (!$seen_version) { - $seen_version = 1 if + if ($seen_version < 2) { + $seen_version++ if s{<(version)>.*</\1>}{<${1}>'"$POM_V"'</${1}>}; } - ' org.eclipse.jgit.packaging/pom.xml + ' org.eclipse.jgit.packaging/org.*.source.feature/pom.xml perl -pi~ -e ' if ($ARGV ne $old_argv) { @@ -162,7 +152,7 @@ perl -pi~ -e ' $old_argv = $ARGV; } if ($seen_version < 18) { - $seen_version++ if + $seen_version++ if s{<(version)>.*</\1>}{<${1}>'"$POM_V"'</${1}>}; } ' org.eclipse.jgit.coverage/pom.xml |