Merge branch 'stable-5.4' into stable-5.5

* stable-5.4:
  Use FileSnapshot without using configs for FileBasedConfig

Change-Id: I84e11bdaa9306e23212dac9d8670557a18d40107
diff --git a/BUILD b/BUILD
index 5fea669..be6dd76 100644
--- a/BUILD
+++ b/BUILD
@@ -1,12 +1,5 @@
 package(default_visibility = ["//visibility:public"])
 
-config_setting(
-    name = "jdk9",
-    values = {
-        "java_toolchain": "@bazel_tools//tools/jdk:toolchain_jdk9",
-    },
-)
-
 genrule(
     name = "all",
     testonly = 1,
diff --git a/WORKSPACE b/WORKSPACE
index 4fa9968..e40dd40 100644
--- a/WORKSPACE
+++ b/WORKSPACE
@@ -198,48 +198,48 @@
     sha1 = "3edcfe49d2c6053a70a2a47e4e1c2f94998a49cf",
 )
 
-JETTY_VER = "9.4.14.v20181114"
+JETTY_VER = "9.4.20.v20190813"
 
 maven_jar(
     name = "jetty-servlet",
     artifact = "org.eclipse.jetty:jetty-servlet:" + JETTY_VER,
-    sha1 = "96f501462af425190ff7b63e387692c1aa3af2c8",
-    src_sha1 = "204b8a84adf3ce354138509c42638b5b2d223d1f",
+    sha1 = "d5d6610321bd173aead473e994f170989d633b25",
+    src_sha1 = "09aa4fce2579d0905e3bde0b3bc923a032394805",
 )
 
 maven_jar(
     name = "jetty-security",
     artifact = "org.eclipse.jetty:jetty-security:" + JETTY_VER,
-    sha1 = "6cbeb2fe9b3cc4f88a7ea040b8a0c4f703cd72ce",
-    src_sha1 = "33555125c5988fca12273f60a0aa545d848de54a",
+    sha1 = "300c2e6dd62291c512bdaf3ecfefc1e305e26088",
+    src_sha1 = "ec03ce3b6a8c0c3dd2bd8b32bc51419caa10ad62",
 )
 
 maven_jar(
     name = "jetty-server",
     artifact = "org.eclipse.jetty:jetty-server:" + JETTY_VER,
-    sha1 = "b36a3d52d78a1df6406f6fa236a6eeff48cbfef6",
-    src_sha1 = "55db20ea68c9c1b0ed264d80e7d75b4988da87a6",
+    sha1 = "d4ee11134bca83db85919a1710fce022c67df3b7",
+    src_sha1 = "0db81f86709a8184c793acd309c27dccdb5d439c",
 )
 
 maven_jar(
     name = "jetty-http",
     artifact = "org.eclipse.jetty:jetty-http:" + JETTY_VER,
-    sha1 = "6d0c8ac42e9894ae7b5032438eb4579c2a47f4fe",
-    src_sha1 = "3c4f8a942909cabe6d029f835c185207eb91af75",
+    sha1 = "edda2fd904a881114aba79e2f881c6f4004e8148",
+    src_sha1 = "3e187c60d578c529f4baa3bbfc727d4b7ca7b93c",
 )
 
 maven_jar(
     name = "jetty-io",
     artifact = "org.eclipse.jetty:jetty-io:" + JETTY_VER,
-    sha1 = "a8c6a705ddb9f83a75777d89b0be59fcef3f7637",
-    src_sha1 = "06132108ccabbe181707af911e5a68fd8e8806ff",
+    sha1 = "b246c5e350d0aa1b310c07ec362755c34a1cc8cb",
+    src_sha1 = "d12619b4df0d202847096a8429b0f96f123c7c77",
 )
 
 maven_jar(
     name = "jetty-util",
     artifact = "org.eclipse.jetty:jetty-util:" + JETTY_VER,
-    sha1 = "5bb3d7a38f7ea54138336591d89dd5867b806c02",
-    src_sha1 = "94e89a8c9f82e38555e95b9f7f58344a247e862c",
+    sha1 = "8ee753d673a124ba2880361871ab13f6863b2d40",
+    src_sha1 = "2827925d01d95f42d02adf177d2474fbc8a3d5e0",
 )
 
 BOUNCYCASTLE_VER = "1.61"
diff --git a/org.eclipse.jgit.ant.test/META-INF/MANIFEST.MF b/org.eclipse.jgit.ant.test/META-INF/MANIFEST.MF
index 3fd704f..74ed271 100644
--- a/org.eclipse.jgit.ant.test/META-INF/MANIFEST.MF
+++ b/org.eclipse.jgit.ant.test/META-INF/MANIFEST.MF
@@ -1,16 +1,17 @@
 Bundle-Localization: plugin
 Manifest-Version: 1.0
 Bundle-ManifestVersion: 2
-Bundle-Name: %plugin_name
+Bundle-Name: %Bundle-Name
 Automatic-Module-Name: org.eclipse.jgit.ant.test
 Bundle-SymbolicName: org.eclipse.jgit.ant.test
-Bundle-Version: 5.4.4.qualifier
+Bundle-Vendor: %Bundle-Vendor
+Bundle-Version: 5.5.2.qualifier
 Bundle-ActivationPolicy: lazy
 Bundle-RequiredExecutionEnvironment: JavaSE-1.8
 Import-Package: org.apache.tools.ant,
- org.eclipse.jgit.ant.tasks;version="[5.4.4,5.5.0)",
- org.eclipse.jgit.junit;version="[5.4.4,5.5.0)",
- org.eclipse.jgit.lib;version="[5.4.4,5.5.0)",
- org.eclipse.jgit.util;version="[5.4.4,5.5.0)",
+ org.eclipse.jgit.ant.tasks;version="[5.5.2,5.6.0)",
+ org.eclipse.jgit.junit;version="[5.5.2,5.6.0)",
+ org.eclipse.jgit.lib;version="[5.5.2,5.6.0)",
+ org.eclipse.jgit.util;version="[5.5.2,5.6.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/plugin.properties b/org.eclipse.jgit.ant.test/plugin.properties
index 4f849eb..412f392 100644
--- a/org.eclipse.jgit.ant.test/plugin.properties
+++ b/org.eclipse.jgit.ant.test/plugin.properties
@@ -1,2 +1,2 @@
-plugin_name=JGit Ant Tasks Tests
-provider_name=Eclipse JGit
+Bundle-Name=JGit Ant Tasks Tests
+Bundle-Vendor=Eclipse JGit
diff --git a/org.eclipse.jgit.ant.test/pom.xml b/org.eclipse.jgit.ant.test/pom.xml
index b0473e5..a5d6304 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.4.4-SNAPSHOT</version>
+    <version>5.5.2-SNAPSHOT</version>
   </parent>
 
   <artifactId>org.eclipse.jgit.ant.test</artifactId>
diff --git a/org.eclipse.jgit.ant/META-INF/MANIFEST.MF b/org.eclipse.jgit.ant/META-INF/MANIFEST.MF
index 0ab7ae5..fac3286 100644
--- a/org.eclipse.jgit.ant/META-INF/MANIFEST.MF
+++ b/org.eclipse.jgit.ant/META-INF/MANIFEST.MF
@@ -3,13 +3,13 @@
 Bundle-Name: %Bundle-Name
 Automatic-Module-Name: org.eclipse.jgit.ant
 Bundle-SymbolicName: org.eclipse.jgit.ant
-Bundle-Version: 5.4.4.qualifier
+Bundle-Version: 5.5.2.qualifier
 Bundle-RequiredExecutionEnvironment: JavaSE-1.8
 Import-Package: org.apache.tools.ant,
-  org.eclipse.jgit.storage.file;version="[5.4.4,5.5.0)"
+  org.eclipse.jgit.storage.file;version="[5.5.2,5.6.0)"
 Bundle-Localization: plugin
-Bundle-Vendor: %Provider-Name
-Export-Package: org.eclipse.jgit.ant;version="5.4.4",
- org.eclipse.jgit.ant.tasks;version="5.4.4";
+Bundle-Vendor: %Bundle-Vendor
+Export-Package: org.eclipse.jgit.ant;version="5.5.2",
+ org.eclipse.jgit.ant.tasks;version="5.5.2";
   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
index a720849..a1ba9ce 100644
--- a/org.eclipse.jgit.ant/META-INF/SOURCE-MANIFEST.MF
+++ b/org.eclipse.jgit.ant/META-INF/SOURCE-MANIFEST.MF
@@ -3,5 +3,5 @@
 Bundle-Name: org.eclipse.jgit.ant - Sources
 Bundle-SymbolicName: org.eclipse.jgit.ant.source
 Bundle-Vendor: Eclipse.org - JGit
-Bundle-Version: 5.4.4.qualifier
-Eclipse-SourceBundle: org.eclipse.jgit.ant;version="5.4.4.qualifier";roots="."
+Bundle-Version: 5.5.2.qualifier
+Eclipse-SourceBundle: org.eclipse.jgit.ant;version="5.5.2.qualifier";roots="."
diff --git a/org.eclipse.jgit.ant/plugin.properties b/org.eclipse.jgit.ant/plugin.properties
index 47725bc..7c9e5f0 100644
--- a/org.eclipse.jgit.ant/plugin.properties
+++ b/org.eclipse.jgit.ant/plugin.properties
@@ -1,3 +1,3 @@
 #Properties file for org.eclipse.jgit.ant
 Bundle-Name = JGit Ant Tasks
-Provider-Name = Eclipse JGit
\ No newline at end of file
+Bundle-Vendor = Eclipse JGit
\ No newline at end of file
diff --git a/org.eclipse.jgit.ant/pom.xml b/org.eclipse.jgit.ant/pom.xml
index 71be666..1c1c494 100644
--- a/org.eclipse.jgit.ant/pom.xml
+++ b/org.eclipse.jgit.ant/pom.xml
@@ -48,7 +48,7 @@
   <parent>
     <groupId>org.eclipse.jgit</groupId>
     <artifactId>org.eclipse.jgit-parent</artifactId>
-    <version>5.4.4-SNAPSHOT</version>
+    <version>5.5.2-SNAPSHOT</version>
   </parent>
 
   <artifactId>org.eclipse.jgit.ant</artifactId>
diff --git a/org.eclipse.jgit.archive/META-INF/MANIFEST.MF b/org.eclipse.jgit.archive/META-INF/MANIFEST.MF
index cac5489..14167a6 100644
--- a/org.eclipse.jgit.archive/META-INF/MANIFEST.MF
+++ b/org.eclipse.jgit.archive/META-INF/MANIFEST.MF
@@ -1,10 +1,10 @@
 Manifest-Version: 1.0
 Bundle-ManifestVersion: 2
-Bundle-Name: %plugin_name
+Bundle-Name: %Bundle-Name
 Automatic-Module-Name: org.eclipse.jgit.archive
 Bundle-SymbolicName: org.eclipse.jgit.archive
-Bundle-Version: 5.4.4.qualifier
-Bundle-Vendor: %provider_name
+Bundle-Version: 5.5.2.qualifier
+Bundle-Vendor: %Bundle-Vendor
 Bundle-Localization: plugin
 Bundle-RequiredExecutionEnvironment: JavaSE-1.8
 Import-Package: org.apache.commons.compress.archivers;version="[1.4,2.0)",
@@ -13,17 +13,17 @@
  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.4.4,5.5.0)",
- org.eclipse.jgit.lib;version="[5.4.4,5.5.0)",
- org.eclipse.jgit.nls;version="[5.4.4,5.5.0)",
- org.eclipse.jgit.revwalk;version="[5.4.4,5.5.0)",
- org.eclipse.jgit.util;version="[5.4.4,5.5.0)",
+ org.eclipse.jgit.api;version="[5.5.2,5.6.0)",
+ org.eclipse.jgit.lib;version="[5.5.2,5.6.0)",
+ org.eclipse.jgit.nls;version="[5.5.2,5.6.0)",
+ org.eclipse.jgit.revwalk;version="[5.5.2,5.6.0)",
+ org.eclipse.jgit.util;version="[5.5.2,5.6.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.4.4";
+Export-Package: org.eclipse.jgit.archive;version="5.5.2";
   uses:="org.eclipse.jgit.lib,
    org.eclipse.jgit.api,
    org.apache.commons.compress.archivers,
    org.osgi.framework",
- org.eclipse.jgit.archive.internal;version="5.4.4";x-internal:=true
+ org.eclipse.jgit.archive.internal;version="5.5.2";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 3fa9790..21facee 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-Name: org.eclipse.jgit.archive - Sources
 Bundle-SymbolicName: org.eclipse.jgit.archive.source
 Bundle-Vendor: Eclipse.org - JGit
-Bundle-Version: 5.4.4.qualifier
-Eclipse-SourceBundle: org.eclipse.jgit.archive;version="5.4.4.qualifier";roots="."
+Bundle-Version: 5.5.2.qualifier
+Eclipse-SourceBundle: org.eclipse.jgit.archive;version="5.5.2.qualifier";roots="."
diff --git a/org.eclipse.jgit.archive/plugin.properties b/org.eclipse.jgit.archive/plugin.properties
index f4269b7..fe22ce8 100644
--- a/org.eclipse.jgit.archive/plugin.properties
+++ b/org.eclipse.jgit.archive/plugin.properties
@@ -1,2 +1,2 @@
-plugin_name=JGit Archive Formats
-provider_name=Eclipse JGit
+Bundle-Name=JGit Archive Formats
+Bundle-Vendor=Eclipse JGit
diff --git a/org.eclipse.jgit.archive/pom.xml b/org.eclipse.jgit.archive/pom.xml
index 1cfbc3b..61d25a6 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.4.4-SNAPSHOT</version>
+    <version>5.5.2-SNAPSHOT</version>
   </parent>
 
   <artifactId>org.eclipse.jgit.archive</artifactId>
diff --git a/org.eclipse.jgit.benchmarks/pom.xml b/org.eclipse.jgit.benchmarks/pom.xml
index 2dd6a85..0aade52 100644
--- a/org.eclipse.jgit.benchmarks/pom.xml
+++ b/org.eclipse.jgit.benchmarks/pom.xml
@@ -47,7 +47,7 @@
   <modelVersion>4.0.0</modelVersion>
 
   <groupId>org.eclipse.jgit</groupId>
-  <version>5.4.4-SNAPSHOT</version>
+  <version>5.5.2-SNAPSHOT</version>
   <artifactId>org.eclipse.jgit.benchmarks</artifactId>
   <packaging>jar</packaging>
 
diff --git a/org.eclipse.jgit.coverage/pom.xml b/org.eclipse.jgit.coverage/pom.xml
index d4c140c..be76c03 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.4.4-SNAPSHOT</version>
+    <version>5.5.2-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.4.4-SNAPSHOT</version>
+      <version>5.5.2-SNAPSHOT</version>
     </dependency>
     <dependency>
       <groupId>org.eclipse.jgit</groupId>
       <artifactId>org.eclipse.jgit.ant</artifactId>
-      <version>5.4.4-SNAPSHOT</version>
+      <version>5.5.2-SNAPSHOT</version>
     </dependency>
     <dependency>
       <groupId>org.eclipse.jgit</groupId>
       <artifactId>org.eclipse.jgit.archive</artifactId>
-      <version>5.4.4-SNAPSHOT</version>
+      <version>5.5.2-SNAPSHOT</version>
     </dependency>
     <dependency>
       <groupId>org.eclipse.jgit</groupId>
       <artifactId>org.eclipse.jgit.http.apache</artifactId>
-      <version>5.4.4-SNAPSHOT</version>
+      <version>5.5.2-SNAPSHOT</version>
     </dependency>
     <dependency>
       <groupId>org.eclipse.jgit</groupId>
       <artifactId>org.eclipse.jgit.http.server</artifactId>
-      <version>5.4.4-SNAPSHOT</version>
+      <version>5.5.2-SNAPSHOT</version>
     </dependency>
     <dependency>
       <groupId>org.eclipse.jgit</groupId>
       <artifactId>org.eclipse.jgit.lfs</artifactId>
-      <version>5.4.4-SNAPSHOT</version>
+      <version>5.5.2-SNAPSHOT</version>
     </dependency>
     <dependency>
       <groupId>org.eclipse.jgit</groupId>
       <artifactId>org.eclipse.jgit.lfs.server</artifactId>
-      <version>5.4.4-SNAPSHOT</version>
+      <version>5.5.2-SNAPSHOT</version>
     </dependency>
     <dependency>
       <groupId>org.eclipse.jgit</groupId>
       <artifactId>org.eclipse.jgit.pgm</artifactId>
-      <version>5.4.4-SNAPSHOT</version>
+      <version>5.5.2-SNAPSHOT</version>
     </dependency>
     <dependency>
       <groupId>org.eclipse.jgit</groupId>
       <artifactId>org.eclipse.jgit.ui</artifactId>
-      <version>5.4.4-SNAPSHOT</version>
+      <version>5.5.2-SNAPSHOT</version>
     </dependency>
     <dependency>
       <groupId>org.eclipse.jgit</groupId>
       <artifactId>org.eclipse.jgit.ssh.apache</artifactId>
-      <version>5.4.4-SNAPSHOT</version>
+      <version>5.5.2-SNAPSHOT</version>
     </dependency>
 
     <dependency>
       <groupId>org.eclipse.jgit</groupId>
       <artifactId>org.eclipse.jgit.test</artifactId>
-      <version>5.4.4-SNAPSHOT</version>
+      <version>5.5.2-SNAPSHOT</version>
     </dependency>
     <dependency>
       <groupId>org.eclipse.jgit</groupId>
       <artifactId>org.eclipse.jgit.ant.test</artifactId>
-      <version>5.4.4-SNAPSHOT</version>
+      <version>5.5.2-SNAPSHOT</version>
     </dependency>
     <dependency>
       <groupId>org.eclipse.jgit</groupId>
       <artifactId>org.eclipse.jgit.http.test</artifactId>
-      <version>5.4.4-SNAPSHOT</version>
+      <version>5.5.2-SNAPSHOT</version>
     </dependency>
     <dependency>
       <groupId>org.eclipse.jgit</groupId>
       <artifactId>org.eclipse.jgit.pgm.test</artifactId>
-      <version>5.4.4-SNAPSHOT</version>
+      <version>5.5.2-SNAPSHOT</version>
     </dependency>
     <dependency>
       <groupId>org.eclipse.jgit</groupId>
       <artifactId>org.eclipse.jgit.lfs.test</artifactId>
-      <version>5.4.4-SNAPSHOT</version>
+      <version>5.5.2-SNAPSHOT</version>
     </dependency>
     <dependency>
       <groupId>org.eclipse.jgit</groupId>
       <artifactId>org.eclipse.jgit.lfs.server.test</artifactId>
-      <version>5.4.4-SNAPSHOT</version>
+      <version>5.5.2-SNAPSHOT</version>
     </dependency>
     <dependency>
       <groupId>org.eclipse.jgit</groupId>
       <artifactId>org.eclipse.jgit.ssh.apache.test</artifactId>
-      <version>5.4.4-SNAPSHOT</version>
+      <version>5.5.2-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 05c07d1..84da9f8 100644
--- a/org.eclipse.jgit.http.apache/META-INF/MANIFEST.MF
+++ b/org.eclipse.jgit.http.apache/META-INF/MANIFEST.MF
@@ -3,10 +3,10 @@
 Bundle-Name: %Bundle-Name
 Automatic-Module-Name: org.eclipse.jgit.http.apache
 Bundle-SymbolicName: org.eclipse.jgit.http.apache
-Bundle-Version: 5.4.4.qualifier
+Bundle-Version: 5.5.2.qualifier
 Bundle-RequiredExecutionEnvironment: JavaSE-1.8
 Bundle-Localization: plugin
-Bundle-Vendor: %Provider-Name
+Bundle-Vendor: %Bundle-Vendor
 Bundle-ActivationPolicy: lazy
 Import-Package: org.apache.http;version="[4.3.0,5.0.0)",
  org.apache.http.client;version="[4.3.0,5.0.0)",
@@ -23,11 +23,11 @@
  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.4.4,5.5.0)",
- org.eclipse.jgit.nls;version="[5.4.4,5.5.0)",
- org.eclipse.jgit.transport.http;version="[5.4.4,5.5.0)",
- org.eclipse.jgit.util;version="[5.4.4,5.5.0)"
-Export-Package: org.eclipse.jgit.transport.http.apache;version="5.4.4";
+ org.eclipse.jgit.annotations;version="[5.5.2,5.6.0)",
+ org.eclipse.jgit.nls;version="[5.5.2,5.6.0)",
+ org.eclipse.jgit.transport.http;version="[5.5.2,5.6.0)",
+ org.eclipse.jgit.util;version="[5.5.2,5.6.0)"
+Export-Package: org.eclipse.jgit.transport.http.apache;version="5.5.2";
   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
index 9c4b862..3666a28 100644
--- a/org.eclipse.jgit.http.apache/META-INF/SOURCE-MANIFEST.MF
+++ b/org.eclipse.jgit.http.apache/META-INF/SOURCE-MANIFEST.MF
@@ -3,5 +3,5 @@
 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.4.qualifier
-Eclipse-SourceBundle: org.eclipse.jgit.http.apache;version="5.4.4.qualifier";roots="."
+Bundle-Version: 5.5.2.qualifier
+Eclipse-SourceBundle: org.eclipse.jgit.http.apache;version="5.5.2.qualifier";roots="."
diff --git a/org.eclipse.jgit.http.apache/plugin.properties b/org.eclipse.jgit.http.apache/plugin.properties
index f87497a..e242829 100644
--- a/org.eclipse.jgit.http.apache/plugin.properties
+++ b/org.eclipse.jgit.http.apache/plugin.properties
@@ -1,3 +1,3 @@
 #Properties file for org.eclipse.jgit.http.apache
 Bundle-Name = JGit Apache httpclient based HTTP support
-Provider-Name = Eclipse JGit
\ No newline at end of file
+Bundle-Vendor = Eclipse JGit
\ No newline at end of file
diff --git a/org.eclipse.jgit.http.apache/pom.xml b/org.eclipse.jgit.http.apache/pom.xml
index 98b58e9..a8f5576 100644
--- a/org.eclipse.jgit.http.apache/pom.xml
+++ b/org.eclipse.jgit.http.apache/pom.xml
@@ -48,7 +48,7 @@
   <parent>
     <groupId>org.eclipse.jgit</groupId>
     <artifactId>org.eclipse.jgit-parent</artifactId>
-    <version>5.4.4-SNAPSHOT</version>
+    <version>5.5.2-SNAPSHOT</version>
   </parent>
 
   <artifactId>org.eclipse.jgit.http.apache</artifactId>
diff --git a/org.eclipse.jgit.http.apache/src/org/eclipse/jgit/transport/http/apache/HttpClientConnection.java b/org.eclipse.jgit.http.apache/src/org/eclipse/jgit/transport/http/apache/HttpClientConnection.java
index 4ac81a5..f92c5df 100644
--- a/org.eclipse.jgit.http.apache/src/org/eclipse/jgit/transport/http/apache/HttpClientConnection.java
+++ b/org.eclipse.jgit.http.apache/src/org/eclipse/jgit/transport/http/apache/HttpClientConnection.java
@@ -345,6 +345,7 @@
 	/** {@inheritDoc} */
 	@Override
 	public InputStream getInputStream() throws IOException {
+		execute();
 		return resp.getEntity().getContent();
 	}
 
diff --git a/org.eclipse.jgit.http.server/META-INF/MANIFEST.MF b/org.eclipse.jgit.http.server/META-INF/MANIFEST.MF
index aaed0f7..8d71a4d 100644
--- a/org.eclipse.jgit.http.server/META-INF/MANIFEST.MF
+++ b/org.eclipse.jgit.http.server/META-INF/MANIFEST.MF
@@ -1,15 +1,15 @@
 Manifest-Version: 1.0
 Bundle-ManifestVersion: 2
-Bundle-Name: %plugin_name
+Bundle-Name: %Bundle-Name
 Automatic-Module-Name: org.eclipse.jgit.http.server
 Bundle-SymbolicName: org.eclipse.jgit.http.server
-Bundle-Version: 5.4.4.qualifier
+Bundle-Version: 5.5.2.qualifier
 Bundle-Localization: plugin
-Bundle-Vendor: %provider_name
-Export-Package: org.eclipse.jgit.http.server;version="5.4.4",
- org.eclipse.jgit.http.server.glue;version="5.4.4";
+Bundle-Vendor: %Bundle-Vendor
+Export-Package: org.eclipse.jgit.http.server;version="5.5.2",
+ org.eclipse.jgit.http.server.glue;version="5.5.2";
   uses:="javax.servlet,javax.servlet.http",
- org.eclipse.jgit.http.server.resolver;version="5.4.4";
+ org.eclipse.jgit.http.server.resolver;version="5.5.2";
   uses:="org.eclipse.jgit.transport.resolver,
    org.eclipse.jgit.lib,
    org.eclipse.jgit.transport,
@@ -18,13 +18,13 @@
 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.4.4,5.5.0)",
- org.eclipse.jgit.internal.storage.dfs;version="[5.4.4,5.5.0)",
- org.eclipse.jgit.internal.storage.file;version="[5.4.4,5.5.0)",
- org.eclipse.jgit.internal.transport.parser;version="[5.4.4,5.5.0)",
- org.eclipse.jgit.lib;version="[5.4.4,5.5.0)",
- org.eclipse.jgit.nls;version="[5.4.4,5.5.0)",
- org.eclipse.jgit.revwalk;version="[5.4.4,5.5.0)",
- org.eclipse.jgit.transport;version="[5.4.4,5.5.0)",
- org.eclipse.jgit.transport.resolver;version="[5.4.4,5.5.0)",
- org.eclipse.jgit.util;version="[5.4.4,5.5.0)"
+ org.eclipse.jgit.errors;version="[5.5.2,5.6.0)",
+ org.eclipse.jgit.internal.storage.dfs;version="[5.5.2,5.6.0)",
+ org.eclipse.jgit.internal.storage.file;version="[5.5.2,5.6.0)",
+ org.eclipse.jgit.internal.transport.parser;version="[5.5.2,5.6.0)",
+ org.eclipse.jgit.lib;version="[5.5.2,5.6.0)",
+ org.eclipse.jgit.nls;version="[5.5.2,5.6.0)",
+ org.eclipse.jgit.revwalk;version="[5.5.2,5.6.0)",
+ org.eclipse.jgit.transport;version="[5.5.2,5.6.0)",
+ org.eclipse.jgit.transport.resolver;version="[5.5.2,5.6.0)",
+ org.eclipse.jgit.util;version="[5.5.2,5.6.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
index fea01da..39c8877 100644
--- a/org.eclipse.jgit.http.server/META-INF/SOURCE-MANIFEST.MF
+++ b/org.eclipse.jgit.http.server/META-INF/SOURCE-MANIFEST.MF
@@ -3,5 +3,5 @@
 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.4.qualifier
-Eclipse-SourceBundle: org.eclipse.jgit.http.server;version="5.4.4.qualifier";roots="."
+Bundle-Version: 5.5.2.qualifier
+Eclipse-SourceBundle: org.eclipse.jgit.http.server;version="5.5.2.qualifier";roots="."
diff --git a/org.eclipse.jgit.http.server/plugin.properties b/org.eclipse.jgit.http.server/plugin.properties
index d891b50..bcec310 100644
--- a/org.eclipse.jgit.http.server/plugin.properties
+++ b/org.eclipse.jgit.http.server/plugin.properties
@@ -1,2 +1,2 @@
-plugin_name=JGit HTTP Server
-provider_name=Eclipse JGit
+Bundle-Name=JGit HTTP Server
+Bundle-Vendor=Eclipse JGit
diff --git a/org.eclipse.jgit.http.server/pom.xml b/org.eclipse.jgit.http.server/pom.xml
index 0e1ea2a..2d4f758 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.4.4-SNAPSHOT</version>
+    <version>5.5.2-SNAPSHOT</version>
   </parent>
 
   <artifactId>org.eclipse.jgit.http.server</artifactId>
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 51de8ab..1c5e7ec 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
@@ -248,13 +248,13 @@
 					.through(enabled)//
 					.with(new TextFileServlet(Constants.HEAD));
 
-			final String info_alternates = "objects/info/alternates";
+			final String info_alternates = Constants.OBJECTS + "/" + Constants.INFO_ALTERNATES;
 			serve("*/" + info_alternates)//
 					.through(mustBeLocal)//
 					.through(enabled)//
 					.with(new TextFileServlet(info_alternates));
 
-			final String http_alternates = "objects/info/http-alternates";
+			final String http_alternates = Constants.OBJECTS + "/" + Constants.INFO_HTTP_ALTERNATES;
 			serve("*/" + http_alternates)//
 					.through(mustBeLocal)//
 					.through(enabled)//
diff --git a/org.eclipse.jgit.http.test/META-INF/MANIFEST.MF b/org.eclipse.jgit.http.test/META-INF/MANIFEST.MF
index ef21e8b..cec2a09 100644
--- a/org.eclipse.jgit.http.test/META-INF/MANIFEST.MF
+++ b/org.eclipse.jgit.http.test/META-INF/MANIFEST.MF
@@ -1,10 +1,10 @@
 Manifest-Version: 1.0
 Bundle-ManifestVersion: 2
-Bundle-Name: %plugin_name
+Bundle-Name: %Bundle-Name
 Automatic-Module-Name: org.eclipse.jgit.http.test
 Bundle-SymbolicName: org.eclipse.jgit.http.test
-Bundle-Version: 5.4.4.qualifier
-Bundle-Vendor: %provider_name
+Bundle-Version: 5.5.2.qualifier
+Bundle-Vendor: %Bundle-Vendor
 Bundle-Localization: plugin
 Bundle-RequiredExecutionEnvironment: JavaSE-1.8
 Import-Package: javax.servlet;version="[2.5.0,3.2.0)",
@@ -28,25 +28,25 @@
  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.4.4,5.5.0)",
- org.eclipse.jgit.http.server;version="[5.4.4,5.5.0)",
- org.eclipse.jgit.http.server.glue;version="[5.4.4,5.5.0)",
- org.eclipse.jgit.http.server.resolver;version="[5.4.4,5.5.0)",
- org.eclipse.jgit.internal;version="[5.4.4,5.5.0)",
- org.eclipse.jgit.internal.storage.dfs;version="[5.4.4,5.5.0)",
- org.eclipse.jgit.internal.storage.file;version="[5.4.4,5.5.0)",
- org.eclipse.jgit.internal.storage.reftable;version="[5.4.4,5.5.0)",
- org.eclipse.jgit.junit;version="[5.4.4,5.5.0)",
- org.eclipse.jgit.junit.http;version="[5.4.4,5.5.0)",
- org.eclipse.jgit.lib;version="[5.4.4,5.5.0)",
- org.eclipse.jgit.nls;version="[5.4.4,5.5.0)",
- org.eclipse.jgit.revwalk;version="[5.4.4,5.5.0)",
- org.eclipse.jgit.storage.file;version="[5.4.4,5.5.0)",
- org.eclipse.jgit.transport;version="[5.4.4,5.5.0)",
- org.eclipse.jgit.transport.http;version="[5.4.4,5.5.0)",
- org.eclipse.jgit.transport.http.apache;version="[5.4.4,5.5.0)",
- org.eclipse.jgit.transport.resolver;version="[5.4.4,5.5.0)",
- org.eclipse.jgit.util;version="[5.4.4,5.5.0)",
+ org.eclipse.jgit.errors;version="[5.5.2,5.6.0)",
+ org.eclipse.jgit.http.server;version="[5.5.2,5.6.0)",
+ org.eclipse.jgit.http.server.glue;version="[5.5.2,5.6.0)",
+ org.eclipse.jgit.http.server.resolver;version="[5.5.2,5.6.0)",
+ org.eclipse.jgit.internal;version="[5.5.2,5.6.0)",
+ org.eclipse.jgit.internal.storage.dfs;version="[5.5.2,5.6.0)",
+ org.eclipse.jgit.internal.storage.file;version="[5.5.2,5.6.0)",
+ org.eclipse.jgit.internal.storage.reftable;version="[5.5.2,5.6.0)",
+ org.eclipse.jgit.junit;version="[5.5.2,5.6.0)",
+ org.eclipse.jgit.junit.http;version="[5.5.2,5.6.0)",
+ org.eclipse.jgit.lib;version="[5.5.2,5.6.0)",
+ org.eclipse.jgit.nls;version="[5.5.2,5.6.0)",
+ org.eclipse.jgit.revwalk;version="[5.5.2,5.6.0)",
+ org.eclipse.jgit.storage.file;version="[5.5.2,5.6.0)",
+ org.eclipse.jgit.transport;version="[5.5.2,5.6.0)",
+ org.eclipse.jgit.transport.http;version="[5.5.2,5.6.0)",
+ org.eclipse.jgit.transport.http.apache;version="[5.5.2,5.6.0)",
+ org.eclipse.jgit.transport.resolver;version="[5.5.2,5.6.0)",
+ org.eclipse.jgit.util;version="[5.5.2,5.6.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/plugin.properties b/org.eclipse.jgit.http.test/plugin.properties
index 0a620aa..d574f0d 100644
--- a/org.eclipse.jgit.http.test/plugin.properties
+++ b/org.eclipse.jgit.http.test/plugin.properties
@@ -1,2 +1,2 @@
-plugin_name=JGit HTTP Tests
-provider_name=Eclipse JGit
+Bundle-Name=JGit HTTP Tests
+Bundle-Vendor=Eclipse JGit
diff --git a/org.eclipse.jgit.http.test/pom.xml b/org.eclipse.jgit.http.test/pom.xml
index 29e54cd..5ab6a7e 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.4.4-SNAPSHOT</version>
+    <version>5.5.2-SNAPSHOT</version>
   </parent>
 
   <artifactId>org.eclipse.jgit.http.test</artifactId>
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 ec9ced0..3f2b0e7 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
@@ -57,7 +57,6 @@
 import org.eclipse.jgit.http.server.GitServlet;
 import org.eclipse.jgit.http.server.resolver.DefaultReceivePackFactory;
 import org.eclipse.jgit.junit.TestRepository;
-import org.eclipse.jgit.junit.http.HttpTestCase;
 import org.eclipse.jgit.lib.Constants;
 import org.eclipse.jgit.lib.NullProgressMonitor;
 import org.eclipse.jgit.lib.ObjectId;
@@ -69,16 +68,22 @@
 import org.eclipse.jgit.transport.RemoteRefUpdate;
 import org.eclipse.jgit.transport.Transport;
 import org.eclipse.jgit.transport.URIish;
+import org.eclipse.jgit.transport.http.HttpConnectionFactory;
 import org.eclipse.jgit.transport.resolver.ServiceNotAuthorizedException;
 import org.eclipse.jgit.transport.resolver.ServiceNotEnabledException;
 import org.junit.Before;
 import org.junit.Test;
 
-public class AdvertiseErrorTest extends HttpTestCase {
+public class AdvertiseErrorTest extends AllFactoriesHttpTestCase {
+
 	private Repository remoteRepository;
 
 	private URIish remoteURI;
 
+	public AdvertiseErrorTest(HttpConnectionFactory cf) {
+		super(cf);
+	}
+
 	@Override
 	@Before
 	public void setUp() throws Exception {
diff --git a/org.eclipse.jgit.http.test/tst/org/eclipse/jgit/http/test/AllFactoriesHttpTestCase.java b/org.eclipse.jgit.http.test/tst/org/eclipse/jgit/http/test/AllFactoriesHttpTestCase.java
new file mode 100644
index 0000000..d292d79
--- /dev/null
+++ b/org.eclipse.jgit.http.test/tst/org/eclipse/jgit/http/test/AllFactoriesHttpTestCase.java
@@ -0,0 +1,101 @@
+/*
+ * 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.http.test;
+
+import java.util.Arrays;
+import java.util.Collection;
+
+import org.eclipse.jgit.junit.http.HttpTestCase;
+import org.eclipse.jgit.transport.HttpTransport;
+import org.eclipse.jgit.transport.http.HttpConnectionFactory;
+import org.eclipse.jgit.transport.http.JDKHttpConnectionFactory;
+import org.eclipse.jgit.transport.http.apache.HttpClientConnectionFactory;
+import org.junit.AfterClass;
+import org.junit.BeforeClass;
+import org.junit.Ignore;
+import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
+import org.junit.runners.Parameterized.Parameters;
+
+/**
+ * Abstract test base class for running HTTP-related tests with all connection
+ * factories provided in JGit: the JDK {@link JDKHttpConnectionFactory} and the
+ * Apache HTTP {@link HttpClientConnectionFactory}.
+ */
+@Ignore
+@RunWith(Parameterized.class)
+public abstract class AllFactoriesHttpTestCase extends HttpTestCase {
+
+	@Parameters(name = "{0}")
+	public static Collection<Object[]> data() {
+		// run all tests with both connection factories we have
+		return Arrays.asList(new Object[][] { { new JDKHttpConnectionFactory() {
+			@Override
+			public String toString() {
+				return this.getClass().getSuperclass().getName();
+			}
+		} }, { new HttpClientConnectionFactory() {
+			@Override
+			public String toString() {
+				return this.getClass().getSuperclass().getName();
+			}
+		} } });
+	}
+
+	protected AllFactoriesHttpTestCase(HttpConnectionFactory cf) {
+		HttpTransport.setConnectionFactory(cf);
+	}
+
+	private static HttpConnectionFactory originalFactory;
+
+	@BeforeClass
+	public static void saveConnectionFactory() {
+		originalFactory = HttpTransport.getConnectionFactory();
+	}
+
+	@AfterClass
+	public static void restoreConnectionFactory() {
+		HttpTransport.setConnectionFactory(originalFactory);
+	}
+
+}
diff --git a/org.eclipse.jgit.http.test/tst/org/eclipse/jgit/http/test/DumbClientDumbServerTest.java b/org.eclipse.jgit.http.test/tst/org/eclipse/jgit/http/test/DumbClientDumbServerTest.java
index c1e55cb..e8f84ae 100644
--- a/org.eclipse.jgit.http.test/tst/org/eclipse/jgit/http/test/DumbClientDumbServerTest.java
+++ b/org.eclipse.jgit.http.test/tst/org/eclipse/jgit/http/test/DumbClientDumbServerTest.java
@@ -55,8 +55,6 @@
 import java.io.File;
 import java.io.IOException;
 import java.net.URI;
-import java.util.Arrays;
-import java.util.Collection;
 import java.util.List;
 import java.util.Map;
 
@@ -66,7 +64,6 @@
 import org.eclipse.jgit.errors.NotSupportedException;
 import org.eclipse.jgit.junit.TestRepository;
 import org.eclipse.jgit.junit.http.AccessEvent;
-import org.eclipse.jgit.junit.http.HttpTestCase;
 import org.eclipse.jgit.lib.Constants;
 import org.eclipse.jgit.lib.NullProgressMonitor;
 import org.eclipse.jgit.lib.Ref;
@@ -79,16 +76,10 @@
 import org.eclipse.jgit.transport.TransportHttp;
 import org.eclipse.jgit.transport.URIish;
 import org.eclipse.jgit.transport.http.HttpConnectionFactory;
-import org.eclipse.jgit.transport.http.JDKHttpConnectionFactory;
-import org.eclipse.jgit.transport.http.apache.HttpClientConnectionFactory;
 import org.junit.Before;
 import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.junit.runners.Parameterized;
-import org.junit.runners.Parameterized.Parameters;
 
-@RunWith(Parameterized.class)
-public class DumbClientDumbServerTest extends HttpTestCase {
+public class DumbClientDumbServerTest extends AllFactoriesHttpTestCase {
 	private Repository remoteRepository;
 
 	private URIish remoteURI;
@@ -97,16 +88,8 @@
 
 	private RevCommit A, B;
 
-	@Parameters
-	public static Collection<Object[]> data() {
-		// run all tests with both connection factories we have
-		return Arrays.asList(new Object[][] {
-				{ new JDKHttpConnectionFactory() },
-				{ new HttpClientConnectionFactory() } });
-	}
-
 	public DumbClientDumbServerTest(HttpConnectionFactory cf) {
-		HttpTransport.setConnectionFactory(cf);
+		super(cf);
 	}
 
 	@Override
diff --git a/org.eclipse.jgit.http.test/tst/org/eclipse/jgit/http/test/DumbClientSmartServerTest.java b/org.eclipse.jgit.http.test/tst/org/eclipse/jgit/http/test/DumbClientSmartServerTest.java
index 2d22baf..5efc5a2 100644
--- a/org.eclipse.jgit.http.test/tst/org/eclipse/jgit/http/test/DumbClientSmartServerTest.java
+++ b/org.eclipse.jgit.http.test/tst/org/eclipse/jgit/http/test/DumbClientSmartServerTest.java
@@ -55,8 +55,6 @@
 import static org.junit.Assert.fail;
 
 import java.io.IOException;
-import java.util.Arrays;
-import java.util.Collection;
 import java.util.List;
 import java.util.Map;
 
@@ -66,7 +64,6 @@
 import org.eclipse.jgit.http.server.GitServlet;
 import org.eclipse.jgit.junit.TestRepository;
 import org.eclipse.jgit.junit.http.AccessEvent;
-import org.eclipse.jgit.junit.http.HttpTestCase;
 import org.eclipse.jgit.lib.Constants;
 import org.eclipse.jgit.lib.NullProgressMonitor;
 import org.eclipse.jgit.lib.Ref;
@@ -79,16 +76,10 @@
 import org.eclipse.jgit.transport.TransportHttp;
 import org.eclipse.jgit.transport.URIish;
 import org.eclipse.jgit.transport.http.HttpConnectionFactory;
-import org.eclipse.jgit.transport.http.JDKHttpConnectionFactory;
-import org.eclipse.jgit.transport.http.apache.HttpClientConnectionFactory;
 import org.junit.Before;
 import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.junit.runners.Parameterized;
-import org.junit.runners.Parameterized.Parameters;
 
-@RunWith(Parameterized.class)
-public class DumbClientSmartServerTest extends HttpTestCase {
+public class DumbClientSmartServerTest extends AllFactoriesHttpTestCase {
 	private Repository remoteRepository;
 
 	private URIish remoteURI;
@@ -97,16 +88,8 @@
 
 	private RevCommit A, B;
 
-	@Parameters
-	public static Collection<Object[]> data() {
-		// run all tests with both connection factories we have
-		return Arrays.asList(new Object[][] {
-				{ new JDKHttpConnectionFactory() },
-				{ new HttpClientConnectionFactory() } });
-	}
-
 	public DumbClientSmartServerTest(HttpConnectionFactory cf) {
-		HttpTransport.setConnectionFactory(cf);
+		super(cf);
 	}
 
 	@Override
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 49ff51a..5559c8c 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
@@ -62,7 +62,6 @@
 import org.eclipse.jgit.http.server.resolver.DefaultReceivePackFactory;
 import org.eclipse.jgit.junit.TestRepository;
 import org.eclipse.jgit.junit.http.AccessEvent;
-import org.eclipse.jgit.junit.http.HttpTestCase;
 import org.eclipse.jgit.lib.Constants;
 import org.eclipse.jgit.lib.NullProgressMonitor;
 import org.eclipse.jgit.lib.ObjectId;
@@ -76,16 +75,22 @@
 import org.eclipse.jgit.transport.RemoteRefUpdate;
 import org.eclipse.jgit.transport.Transport;
 import org.eclipse.jgit.transport.URIish;
+import org.eclipse.jgit.transport.http.HttpConnectionFactory;
 import org.eclipse.jgit.transport.resolver.ServiceNotAuthorizedException;
 import org.eclipse.jgit.transport.resolver.ServiceNotEnabledException;
 import org.junit.Before;
 import org.junit.Test;
 
-public class HookMessageTest extends HttpTestCase {
+public class HookMessageTest extends AllFactoriesHttpTestCase {
+
 	private Repository remoteRepository;
 
 	private URIish remoteURI;
 
+	public HookMessageTest(HttpConnectionFactory cf) {
+		super(cf);
+	}
+
 	@Override
 	@Before
 	public void setUp() throws Exception {
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 8ec2f51..7588a95 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
@@ -71,7 +71,6 @@
 import org.eclipse.jgit.junit.TestRepository;
 import org.eclipse.jgit.junit.http.AccessEvent;
 import org.eclipse.jgit.junit.http.AppServer;
-import org.eclipse.jgit.junit.http.HttpTestCase;
 import org.eclipse.jgit.lib.Constants;
 import org.eclipse.jgit.lib.Ref;
 import org.eclipse.jgit.lib.RefUpdate;
@@ -79,17 +78,19 @@
 import org.eclipse.jgit.lib.StoredConfig;
 import org.eclipse.jgit.revwalk.RevCommit;
 import org.eclipse.jgit.transport.FetchConnection;
+import org.eclipse.jgit.transport.HttpTransport;
 import org.eclipse.jgit.transport.PacketLineIn;
 import org.eclipse.jgit.transport.PacketLineOut;
 import org.eclipse.jgit.transport.Transport;
 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.http.HttpConnectionFactory;
 import org.junit.Before;
 import org.junit.Test;
 
-public class HttpClientTests extends HttpTestCase {
+public class HttpClientTests extends AllFactoriesHttpTestCase {
+
 	private TestRepository<Repository> remoteRepository;
 
 	private URIish dumbAuthNoneURI;
@@ -100,6 +101,10 @@
 
 	private URIish smartAuthBasicURI;
 
+	public HttpClientTests(HttpConnectionFactory cf) {
+		super(cf);
+	}
+
 	@Override
 	@Before
 	public void setUp() throws Exception {
@@ -353,12 +358,11 @@
 
 	@Test
 	public void testHttpClientWantsV2ButServerNotConfigured() throws Exception {
-		JDKHttpConnectionFactory f = new JDKHttpConnectionFactory();
 		String url = smartAuthNoneURI.toString() + "/info/refs?service=git-upload-pack";
-		HttpConnection c = f.create(new URL(url));
+		HttpConnection c = HttpTransport.getConnectionFactory()
+				.create(new URL(url));
 		c.setRequestMethod("GET");
 		c.setRequestProperty("Git-Protocol", "version=2");
-		c.connect();
 		assertEquals(200, c.getResponseCode());
 
 		PacketLineIn pckIn = new PacketLineIn(c.getInputStream());
@@ -374,12 +378,11 @@
 		remoteRepository.getRepository().getConfig().setInt(
 				"protocol", null, "version", 2);
 
-		JDKHttpConnectionFactory f = new JDKHttpConnectionFactory();
 		String url = smartAuthNoneURI.toString() + "/info/refs?service=git-upload-pack";
-		HttpConnection c = f.create(new URL(url));
+		HttpConnection c = HttpTransport.getConnectionFactory()
+				.create(new URL(url));
 		c.setRequestMethod("GET");
 		c.setRequestProperty("Git-Protocol", "version=2");
-		c.connect();
 		assertEquals(200, c.getResponseCode());
 
 		PacketLineIn pckIn = new PacketLineIn(c.getInputStream());
@@ -397,14 +400,13 @@
 		remoteRepository.getRepository().getConfig().setInt(
 				"protocol", null, "version", 2);
 
-		JDKHttpConnectionFactory f = new JDKHttpConnectionFactory();
 		String url = smartAuthNoneURI.toString() + "/git-upload-pack";
-		HttpConnection c = f.create(new URL(url));
+		HttpConnection c = HttpTransport.getConnectionFactory()
+				.create(new URL(url));
 		c.setRequestMethod("POST");
 		c.setRequestProperty("Content-Type", "application/x-git-upload-pack-request");
 		c.setRequestProperty("Git-Protocol", "version=2");
 		c.setDoOutput(true);
-		c.connect();
 
 		// Test ls-refs to verify that everything is connected
 		// properly. Tests for other commands go in
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 79df5a2..dd49e56 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
@@ -55,7 +55,6 @@
 import org.eclipse.jgit.http.server.GitServlet;
 import org.eclipse.jgit.http.server.resolver.DefaultReceivePackFactory;
 import org.eclipse.jgit.junit.TestRepository;
-import org.eclipse.jgit.junit.http.HttpTestCase;
 import org.eclipse.jgit.lib.Constants;
 import org.eclipse.jgit.lib.NullProgressMonitor;
 import org.eclipse.jgit.lib.ObjectId;
@@ -69,18 +68,24 @@
 import org.eclipse.jgit.transport.RemoteRefUpdate;
 import org.eclipse.jgit.transport.Transport;
 import org.eclipse.jgit.transport.URIish;
+import org.eclipse.jgit.transport.http.HttpConnectionFactory;
 import org.eclipse.jgit.transport.resolver.ServiceNotAuthorizedException;
 import org.eclipse.jgit.transport.resolver.ServiceNotEnabledException;
 import org.junit.Before;
 import org.junit.Test;
 
-public class MeasurePackSizeTest extends HttpTestCase {
+public class MeasurePackSizeTest extends AllFactoriesHttpTestCase {
+
 	private Repository remoteRepository;
 
 	private URIish remoteURI;
 
 	long packSize = -1;
 
+	public MeasurePackSizeTest(HttpConnectionFactory cf) {
+		super(cf);
+	}
+
 	@Override
 	@Before
 	public void setUp() throws Exception {
diff --git a/org.eclipse.jgit.http.test/tst/org/eclipse/jgit/http/test/SetAdditionalHeadersTest.java b/org.eclipse.jgit.http.test/tst/org/eclipse/jgit/http/test/SetAdditionalHeadersTest.java
index fbc54f3..f24768b 100644
--- a/org.eclipse.jgit.http.test/tst/org/eclipse/jgit/http/test/SetAdditionalHeadersTest.java
+++ b/org.eclipse.jgit.http.test/tst/org/eclipse/jgit/http/test/SetAdditionalHeadersTest.java
@@ -57,7 +57,6 @@
 import org.eclipse.jetty.servlet.ServletHolder;
 import org.eclipse.jgit.junit.TestRepository;
 import org.eclipse.jgit.junit.http.AccessEvent;
-import org.eclipse.jgit.junit.http.HttpTestCase;
 import org.eclipse.jgit.lib.Repository;
 import org.eclipse.jgit.revwalk.RevBlob;
 import org.eclipse.jgit.revwalk.RevCommit;
@@ -65,10 +64,11 @@
 import org.eclipse.jgit.transport.Transport;
 import org.eclipse.jgit.transport.TransportHttp;
 import org.eclipse.jgit.transport.URIish;
+import org.eclipse.jgit.transport.http.HttpConnectionFactory;
 import org.junit.Before;
 import org.junit.Test;
 
-public class SetAdditionalHeadersTest extends HttpTestCase {
+public class SetAdditionalHeadersTest extends AllFactoriesHttpTestCase {
 
 	private URIish remoteURI;
 
@@ -76,6 +76,9 @@
 
 	private RevCommit A, B;
 
+	public SetAdditionalHeadersTest(HttpConnectionFactory cf) {
+		super(cf);
+	}
 
 	@Override
 	@Before
diff --git a/org.eclipse.jgit.http.test/tst/org/eclipse/jgit/http/test/SmartClientSmartServerSslTest.java b/org.eclipse.jgit.http.test/tst/org/eclipse/jgit/http/test/SmartClientSmartServerSslTest.java
index 30501df..d6e9dbe 100644
--- a/org.eclipse.jgit.http.test/tst/org/eclipse/jgit/http/test/SmartClientSmartServerSslTest.java
+++ b/org.eclipse.jgit.http.test/tst/org/eclipse/jgit/http/test/SmartClientSmartServerSslTest.java
@@ -49,8 +49,6 @@
 import static org.junit.Assert.fail;
 
 import java.io.IOException;
-import java.util.Arrays;
-import java.util.Collection;
 import java.util.EnumSet;
 import java.util.List;
 
@@ -73,7 +71,6 @@
 import org.eclipse.jgit.junit.TestRepository;
 import org.eclipse.jgit.junit.http.AccessEvent;
 import org.eclipse.jgit.junit.http.AppServer;
-import org.eclipse.jgit.junit.http.HttpTestCase;
 import org.eclipse.jgit.lib.ConfigConstants;
 import org.eclipse.jgit.lib.NullProgressMonitor;
 import org.eclipse.jgit.lib.Repository;
@@ -81,22 +78,18 @@
 import org.eclipse.jgit.revwalk.RevCommit;
 import org.eclipse.jgit.transport.CredentialItem;
 import org.eclipse.jgit.transport.CredentialsProvider;
-import org.eclipse.jgit.transport.HttpTransport;
 import org.eclipse.jgit.transport.Transport;
 import org.eclipse.jgit.transport.URIish;
 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.util.HttpSupport;
 import org.junit.Before;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 import org.junit.runners.Parameterized;
-import org.junit.runners.Parameterized.Parameters;
 
 @RunWith(Parameterized.class)
-public class SmartClientSmartServerSslTest extends HttpTestCase {
+public class SmartClientSmartServerSslTest extends AllFactoriesHttpTestCase {
 
 	// We run these tests with a server on localhost with a self-signed
 	// certificate. We don't do authentication tests here, so there's no need
@@ -152,16 +145,8 @@
 
 	private RevCommit A, B;
 
-	@Parameters
-	public static Collection<Object[]> data() {
-		// run all tests with both connection factories we have
-		return Arrays.asList(new Object[][] {
-				{ new JDKHttpConnectionFactory() },
-				{ new HttpClientConnectionFactory() } });
-	}
-
 	public SmartClientSmartServerSslTest(HttpConnectionFactory cf) {
-		HttpTransport.setConnectionFactory(cf);
+		super(cf);
 	}
 
 	@Override
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 8b85bef..3401e26 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
@@ -56,10 +56,9 @@
 
 import java.io.IOException;
 import java.io.PrintWriter;
+import java.net.URI;
 import java.net.URISyntaxException;
 import java.text.MessageFormat;
-import java.util.Arrays;
-import java.util.Collection;
 import java.util.Collections;
 import java.util.EnumSet;
 import java.util.List;
@@ -92,7 +91,6 @@
 import org.eclipse.jgit.junit.TestRng;
 import org.eclipse.jgit.junit.http.AccessEvent;
 import org.eclipse.jgit.junit.http.AppServer;
-import org.eclipse.jgit.junit.http.HttpTestCase;
 import org.eclipse.jgit.lib.ConfigConstants;
 import org.eclipse.jgit.lib.Constants;
 import org.eclipse.jgit.lib.NullProgressMonitor;
@@ -121,8 +119,6 @@
 import org.eclipse.jgit.transport.UploadPack;
 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.util.HttpSupport;
 import org.eclipse.jgit.util.SystemReader;
 import org.hamcrest.Matchers;
@@ -130,12 +126,8 @@
 import org.junit.Rule;
 import org.junit.Test;
 import org.junit.rules.ExpectedException;
-import org.junit.runner.RunWith;
-import org.junit.runners.Parameterized;
-import org.junit.runners.Parameterized.Parameters;
 
-@RunWith(Parameterized.class)
-public class SmartClientSmartServerTest extends HttpTestCase {
+public class SmartClientSmartServerTest extends AllFactoriesHttpTestCase {
 	private static final String HDR_TRANSFER_ENCODING = "Transfer-Encoding";
 
 	@Rule
@@ -162,16 +154,8 @@
 
 	private RevCommit A, B, unreachableCommit;
 
-	@Parameters
-	public static Collection<Object[]> data() {
-		// run all tests with both connection factories we have
-		return Arrays.asList(new Object[][] {
-				{ new JDKHttpConnectionFactory() },
-				{ new HttpClientConnectionFactory() } });
-	}
-
 	public SmartClientSmartServerTest(HttpConnectionFactory cf) {
-		HttpTransport.setConnectionFactory(cf);
+		super(cf);
 	}
 
 	@Override
@@ -338,6 +322,23 @@
 				// empty
 			}
 
+			private String local(String url, boolean toLocal) {
+				if (!toLocal) {
+					return url;
+				}
+				try {
+					URI u = new URI(url);
+					String fragment = u.getRawFragment();
+					if (fragment != null) {
+						return u.getRawPath() + '#' + fragment;
+					} else {
+						return u.getRawPath();
+					}
+				} catch (URISyntaxException e) {
+					return url;
+				}
+			}
+
 			@Override
 			public void doFilter(ServletRequest request,
 					ServletResponse response, FilterChain chain)
@@ -350,6 +351,11 @@
 							.append(httpServletRequest.getQueryString());
 				}
 				String urlString = fullUrl.toString();
+				boolean localRedirect = false;
+				if (urlString.contains("/local")) {
+					urlString = urlString.replace("/local", "");
+					localRedirect = true;
+				}
 				if (urlString.contains("/loop/")) {
 					urlString = urlString.replace("/loop/", "/loop/x/");
 					if (urlString.contains("/loop/x/x/x/x/x/x/x/x/")) {
@@ -360,7 +366,7 @@
 					httpServletResponse.setStatus(
 							HttpServletResponse.SC_MOVED_TEMPORARILY);
 					httpServletResponse.setHeader(HttpSupport.HDR_LOCATION,
-							urlString);
+							local(urlString, localRedirect));
 					return;
 				}
 				int responseCode = HttpServletResponse.SC_MOVED_PERMANENTLY;
@@ -390,9 +396,10 @@
 						targetContext = matcher.group(1);
 					}
 					urlString = urlString.replace("/redirect", targetContext);
+
 				}
 				httpServletResponse.setHeader(HttpSupport.HDR_LOCATION,
-						urlString);
+						local(urlString, localRedirect));
 			}
 
 			@Override
@@ -559,7 +566,15 @@
 
 	private void initialClone_Redirect(int nofRedirects, int code)
 			throws Exception {
+		initialClone_Redirect(nofRedirects, code, false);
+	}
+
+	private void initialClone_Redirect(int nofRedirects, int code,
+			boolean localRedirect) throws Exception {
 		URIish cloneFrom = redirectURI;
+		if (localRedirect) {
+			cloneFrom = extendPath(cloneFrom, "/local");
+		}
 		if (code != 301 || nofRedirects > 1) {
 			cloneFrom = extendPath(cloneFrom,
 					"/response/" + nofRedirects + "/" + code);
@@ -613,6 +628,11 @@
 	}
 
 	@Test
+	public void testInitialClone_Redirect301Local() throws Exception {
+		initialClone_Redirect(1, 301, true);
+	}
+
+	@Test
 	public void testInitialClone_Redirect302Small() throws Exception {
 		initialClone_Redirect(1, 302);
 	}
diff --git a/org.eclipse.jgit.junit.http/META-INF/MANIFEST.MF b/org.eclipse.jgit.junit.http/META-INF/MANIFEST.MF
index d2b692b..a7254a3 100644
--- a/org.eclipse.jgit.junit.http/META-INF/MANIFEST.MF
+++ b/org.eclipse.jgit.junit.http/META-INF/MANIFEST.MF
@@ -1,11 +1,11 @@
 Manifest-Version: 1.0
 Bundle-ManifestVersion: 2
-Bundle-Name: %plugin_name
+Bundle-Name: %Bundle-Name
 Automatic-Module-Name: org.eclipse.jgit.junit.http
 Bundle-SymbolicName: org.eclipse.jgit.junit.http
-Bundle-Version: 5.4.4.qualifier
+Bundle-Version: 5.5.2.qualifier
 Bundle-Localization: plugin
-Bundle-Vendor: %provider_name
+Bundle-Vendor: %Bundle-Vendor
 Bundle-ActivationPolicy: lazy
 Bundle-RequiredExecutionEnvironment: JavaSE-1.8
 Import-Package: javax.servlet;version="[2.5.0,3.2.0)",
@@ -22,16 +22,16 @@
  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.4.4,5.5.0)",
- org.eclipse.jgit.http.server;version="[5.4.4,5.5.0)",
- org.eclipse.jgit.internal.storage.file;version="[5.4.4,5.5.0)",
- org.eclipse.jgit.junit;version="[5.4.4,5.5.0)",
- org.eclipse.jgit.lib;version="[5.4.4,5.5.0)",
- org.eclipse.jgit.revwalk;version="[5.4.4,5.5.0)",
- org.eclipse.jgit.transport;version="[5.4.4,5.5.0)",
- org.eclipse.jgit.transport.resolver;version="[5.4.4,5.5.0)",
+ org.eclipse.jgit.errors;version="[5.5.2,5.6.0)",
+ org.eclipse.jgit.http.server;version="[5.5.2,5.6.0)",
+ org.eclipse.jgit.internal.storage.file;version="[5.5.2,5.6.0)",
+ org.eclipse.jgit.junit;version="[5.5.2,5.6.0)",
+ org.eclipse.jgit.lib;version="[5.5.2,5.6.0)",
+ org.eclipse.jgit.revwalk;version="[5.5.2,5.6.0)",
+ org.eclipse.jgit.transport;version="[5.5.2,5.6.0)",
+ org.eclipse.jgit.transport.resolver;version="[5.5.2,5.6.0)",
  org.junit;version="[4.12,5.0.0)"
-Export-Package: org.eclipse.jgit.junit.http;version="5.4.4";
+Export-Package: org.eclipse.jgit.junit.http;version="5.5.2";
   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
index decfed1..6f5590b 100644
--- a/org.eclipse.jgit.junit.http/META-INF/SOURCE-MANIFEST.MF
+++ b/org.eclipse.jgit.junit.http/META-INF/SOURCE-MANIFEST.MF
@@ -3,5 +3,5 @@
 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.4.qualifier
-Eclipse-SourceBundle: org.eclipse.jgit.junit.http;version="5.4.4.qualifier";roots="."
+Bundle-Version: 5.5.2.qualifier
+Eclipse-SourceBundle: org.eclipse.jgit.junit.http;version="5.5.2.qualifier";roots="."
diff --git a/org.eclipse.jgit.junit.http/plugin.properties b/org.eclipse.jgit.junit.http/plugin.properties
index 7a96b09..2ec05e1 100644
--- a/org.eclipse.jgit.junit.http/plugin.properties
+++ b/org.eclipse.jgit.junit.http/plugin.properties
@@ -1,2 +1,2 @@
-plugin_name=JGit JUnit Http Utility Classes
-provider_name=Eclipse JGit
+Bundle-Name=JGit JUnit Http Utility Classes
+Bundle-Vendor=Eclipse JGit
diff --git a/org.eclipse.jgit.junit.http/pom.xml b/org.eclipse.jgit.junit.http/pom.xml
index e82c243..e4b2c6b 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.4.4-SNAPSHOT</version>
+    <version>5.5.2-SNAPSHOT</version>
   </parent>
 
   <artifactId>org.eclipse.jgit.junit.http</artifactId>
diff --git a/org.eclipse.jgit.junit.ssh/META-INF/MANIFEST.MF b/org.eclipse.jgit.junit.ssh/META-INF/MANIFEST.MF
index 0167b95..ff2edd3 100644
--- a/org.eclipse.jgit.junit.ssh/META-INF/MANIFEST.MF
+++ b/org.eclipse.jgit.junit.ssh/META-INF/MANIFEST.MF
@@ -1,11 +1,11 @@
 Manifest-Version: 1.0
 Bundle-ManifestVersion: 2
-Bundle-Name: %plugin_name
+Bundle-Name: %Bundle-Name
 Automatic-Module-Name: org.eclipse.jgit.junit.ssh
 Bundle-SymbolicName: org.eclipse.jgit.junit.ssh
-Bundle-Version: 5.4.4.qualifier
+Bundle-Version: 5.5.2.qualifier
 Bundle-Localization: plugin
-Bundle-Vendor: %provider_name
+Bundle-Vendor: %Bundle-Vendor
 Bundle-ActivationPolicy: lazy
 Bundle-RequiredExecutionEnvironment: JavaSE-1.8
 Import-Package: org.apache.sshd.common;version="[2.2.0,2.3.0)",
@@ -30,8 +30,8 @@
  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.4,5.5.0)",
- org.eclipse.jgit.lib;version="[5.4.4,5.5.0)",
- org.eclipse.jgit.transport;version="[5.4.4,5.5.0)",
+ org.eclipse.jgit.annotations;version="[5.5.2,5.6.0)",
+ org.eclipse.jgit.lib;version="[5.5.2,5.6.0)",
+ org.eclipse.jgit.transport;version="[5.5.2,5.6.0)",
  org.slf4j;version="[1.7.0,2.0.0)"
-Export-Package: org.eclipse.jgit.junit.ssh;version="5.4.4"
+Export-Package: org.eclipse.jgit.junit.ssh;version="5.5.2"
diff --git a/org.eclipse.jgit.junit.ssh/META-INF/SOURCE-MANIFEST.MF b/org.eclipse.jgit.junit.ssh/META-INF/SOURCE-MANIFEST.MF
index a0b8429..c828888 100644
--- a/org.eclipse.jgit.junit.ssh/META-INF/SOURCE-MANIFEST.MF
+++ b/org.eclipse.jgit.junit.ssh/META-INF/SOURCE-MANIFEST.MF
@@ -3,5 +3,5 @@
 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.4.qualifier
-Eclipse-SourceBundle: org.eclipse.jgit.junit.ssh;version="5.4.4.qualifier";roots="."
+Bundle-Version: 5.5.2.qualifier
+Eclipse-SourceBundle: org.eclipse.jgit.junit.ssh;version="5.5.2.qualifier";roots="."
diff --git a/org.eclipse.jgit.junit.ssh/plugin.properties b/org.eclipse.jgit.junit.ssh/plugin.properties
index 5689b94..3af91ed 100644
--- a/org.eclipse.jgit.junit.ssh/plugin.properties
+++ b/org.eclipse.jgit.junit.ssh/plugin.properties
@@ -1,2 +1,2 @@
-plugin_name=JGit JUnit Ssh Utility Classes
-provider_name=Eclipse JGit
+Bundle-Name=JGit JUnit Ssh Utility Classes
+Bundle-Vendor=Eclipse JGit
diff --git a/org.eclipse.jgit.junit.ssh/pom.xml b/org.eclipse.jgit.junit.ssh/pom.xml
index 9e91018..3b28c00 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.4.4-SNAPSHOT</version>
+    <version>5.5.2-SNAPSHOT</version>
   </parent>
 
   <artifactId>org.eclipse.jgit.junit.ssh</artifactId>
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 25d952f..f54c279 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
@@ -58,6 +58,7 @@
 
 import org.apache.sshd.common.NamedFactory;
 import org.apache.sshd.common.NamedResource;
+import org.apache.sshd.common.PropertyResolverUtils;
 import org.apache.sshd.common.SshConstants;
 import org.apache.sshd.common.config.keys.AuthorizedKeyEntry;
 import org.apache.sshd.common.config.keys.KeyUtils;
@@ -69,6 +70,7 @@
 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.ServerFactoryManager;
 import org.apache.sshd.server.SshServer;
 import org.apache.sshd.server.auth.UserAuth;
 import org.apache.sshd.server.auth.gss.GSSAuthenticator;
@@ -336,12 +338,38 @@
 		server.stop(true);
 	}
 
+	/**
+	 * Sets the test user's public key on the server.
+	 *
+	 * @param key
+	 *            to set
+	 * @throws IOException
+	 *             if the file cannot be read
+	 * @throws GeneralSecurityException
+	 *             if the public key cannot be extracted from the file
+	 */
 	public void setTestUserPublicKey(Path key)
 			throws IOException, GeneralSecurityException {
 		this.testKey = AuthorizedKeyEntry.readAuthorizedKeys(key).get(0)
 				.resolvePublicKey(null, PublicKeyEntryResolver.IGNORING);
 	}
 
+	/**
+	 * Sets the lines the server sends before its server identification in the
+	 * initial protocol version exchange.
+	 *
+	 * @param lines
+	 *            to send
+	 * @since 5.5
+	 */
+	public void setPreamble(String... lines) {
+		if (lines != null && lines.length > 0) {
+			PropertyResolverUtils.updateProperty(this.server,
+					ServerFactoryManager.SERVER_EXTRA_IDENTIFICATION_LINES,
+					String.join("|", lines));
+		}
+	}
+
 	private class GitUploadPackCommand extends AbstractCommandSupport {
 
 		protected GitUploadPackCommand(String command,
diff --git a/org.eclipse.jgit.junit/.settings/.api_filters b/org.eclipse.jgit.junit/.settings/.api_filters
index 05665a3..4a2da06 100644
--- a/org.eclipse.jgit.junit/.settings/.api_filters
+++ b/org.eclipse.jgit.junit/.settings/.api_filters
@@ -1,5 +1,31 @@
 <?xml version="1.0" encoding="UTF-8" standalone="no"?>
 <component id="org.eclipse.jgit.junit" version="2">
+    <resource path="src/org/eclipse/jgit/junit/MockSystemReader.java" type="org.eclipse.jgit.junit.MockSystemReader">
+        <filter id="1141899266">
+            <message_arguments>
+                <message_argument value="5.1"/>
+                <message_argument value="5.5"/>
+                <message_argument value="setSystemGitConfig(FileBasedConfig)"/>
+            </message_arguments>
+        </filter>
+        <filter id="1142947843">
+            <message_arguments>
+                <message_argument value="5.1.9"/>
+                <message_argument value="setSystemGitConfig(FileBasedConfig)"/>
+            </message_arguments>
+        </filter>
+        <filter id="1142947843">
+            <message_arguments>
+                <message_argument value="5.1.9"/>
+                <message_argument value="setUserGitConfig(FileBasedConfig)"/>
+            </message_arguments>
+        </filter>
+        <filter id="1143996420">
+            <message_arguments>
+                <message_argument value="getJGitConfig()"/>
+            </message_arguments>
+        </filter>
+    </resource>
     <resource path="src/org/eclipse/jgit/junit/Repeat.java" type="org.eclipse.jgit.junit.Repeat">
         <filter id="1092616195">
             <message_arguments>
@@ -8,4 +34,34 @@
             </message_arguments>
         </filter>
     </resource>
+    <resource path="src/org/eclipse/jgit/junit/RepeatRule.java" type="org.eclipse.jgit.junit.RepeatRule$RepeatedTestException">
+        <filter id="1142947843">
+            <message_arguments>
+                <message_argument value="5.1.9"/>
+                <message_argument value="RepeatedTestException(String)"/>
+            </message_arguments>
+        </filter>
+    </resource>
+    <resource path="src/org/eclipse/jgit/junit/RepositoryTestCase.java" type="org.eclipse.jgit.junit.RepositoryTestCase">
+        <filter id="338792546">
+            <message_arguments>
+                <message_argument value="org.eclipse.jgit.junit.RepositoryTestCase"/>
+                <message_argument value="fsTick(File)"/>
+            </message_arguments>
+        </filter>
+        <filter id="1142947843">
+            <message_arguments>
+                <message_argument value="5.1.9"/>
+                <message_argument value="fsTick(File)"/>
+            </message_arguments>
+        </filter>
+    </resource>
+    <resource path="src/org/eclipse/jgit/junit/time/TimeUtil.java" type="org.eclipse.jgit.junit.time.TimeUtil">
+        <filter id="1109393411">
+            <message_arguments>
+                <message_argument value="5.1.9"/>
+                <message_argument value="org.eclipse.jgit.junit.time.TimeUtil"/>
+            </message_arguments>
+        </filter>
+    </resource>
 </component>
diff --git a/org.eclipse.jgit.junit/META-INF/MANIFEST.MF b/org.eclipse.jgit.junit/META-INF/MANIFEST.MF
index 4b4f882..4de3e46 100644
--- a/org.eclipse.jgit.junit/META-INF/MANIFEST.MF
+++ b/org.eclipse.jgit.junit/META-INF/MANIFEST.MF
@@ -1,36 +1,37 @@
 Manifest-Version: 1.0
 Bundle-ManifestVersion: 2
-Bundle-Name: %plugin_name
+Bundle-Name: %Bundle-Name
 Automatic-Module-Name: org.eclipse.jgit.junit
 Bundle-SymbolicName: org.eclipse.jgit.junit
-Bundle-Version: 5.4.4.qualifier
+Bundle-Version: 5.5.2.qualifier
 Bundle-Localization: plugin
-Bundle-Vendor: %provider_name
+Bundle-Vendor: %Bundle-Vendor
 Bundle-ActivationPolicy: lazy
 Bundle-RequiredExecutionEnvironment: JavaSE-1.8
-Import-Package: org.eclipse.jgit.annotations;version="[5.4.4,5.5.0)",
- org.eclipse.jgit.api;version="[5.4.4,5.5.0)",
- org.eclipse.jgit.api.errors;version="[5.4.4,5.5.0)",
- org.eclipse.jgit.dircache;version="[5.4.4,5.5.0)",
- org.eclipse.jgit.errors;version="[5.4.4,5.5.0)",
- org.eclipse.jgit.internal.storage.file;version="[5.4.4,5.5.0)",
- org.eclipse.jgit.internal.storage.pack;version="[5.4.4,5.5.0)",
- org.eclipse.jgit.lib;version="[5.4.4,5.5.0)",
- org.eclipse.jgit.merge;version="[5.4.4,5.5.0)",
- org.eclipse.jgit.revwalk;version="[5.4.4,5.5.0)",
- org.eclipse.jgit.storage.file;version="[5.4.4,5.5.0)",
- org.eclipse.jgit.transport;version="5.4.4",
- org.eclipse.jgit.treewalk;version="[5.4.4,5.5.0)",
- org.eclipse.jgit.treewalk.filter;version="[5.4.4,5.5.0)",
- org.eclipse.jgit.util;version="[5.4.4,5.5.0)",
- org.eclipse.jgit.util.io;version="[5.4.4,5.5.0)",
- org.eclipse.jgit.util.time;version="[5.4.4,5.5.0)",
+Import-Package: org.eclipse.jgit.annotations;version="[5.5.2,5.6.0)",
+ org.eclipse.jgit.api;version="[5.5.2,5.6.0)",
+ org.eclipse.jgit.api.errors;version="[5.5.2,5.6.0)",
+ org.eclipse.jgit.dircache;version="[5.5.2,5.6.0)",
+ org.eclipse.jgit.errors;version="[5.5.2,5.6.0)",
+ org.eclipse.jgit.internal.storage.file;version="[5.5.2,5.6.0)",
+ org.eclipse.jgit.internal.storage.pack;version="[5.5.2,5.6.0)",
+ org.eclipse.jgit.lib;version="[5.5.2,5.6.0)",
+ org.eclipse.jgit.merge;version="[5.5.2,5.6.0)",
+ org.eclipse.jgit.revwalk;version="[5.5.2,5.6.0)",
+ org.eclipse.jgit.storage.file;version="[5.5.2,5.6.0)",
+ org.eclipse.jgit.transport;version="5.5.2",
+ org.eclipse.jgit.treewalk;version="[5.5.2,5.6.0)",
+ org.eclipse.jgit.treewalk.filter;version="[5.5.2,5.6.0)",
+ org.eclipse.jgit.util;version="[5.5.2,5.6.0)",
+ org.eclipse.jgit.util.io;version="[5.5.2,5.6.0)",
+ org.eclipse.jgit.util.time;version="[5.5.2,5.6.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;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.4.4";
+Export-Package: org.eclipse.jgit.junit;version="5.5.2";
   uses:="org.eclipse.jgit.dircache,
    org.eclipse.jgit.lib,
    org.eclipse.jgit.revwalk,
@@ -43,4 +44,4 @@
    org.junit.runners.model,
    org.junit.runner,
    org.eclipse.jgit.util.time",
- org.eclipse.jgit.junit.time;version="5.4.4";uses:="org.eclipse.jgit.util.time"
+ org.eclipse.jgit.junit.time;version="5.5.2";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
index 02bc82d..9568f93 100644
--- a/org.eclipse.jgit.junit/META-INF/SOURCE-MANIFEST.MF
+++ b/org.eclipse.jgit.junit/META-INF/SOURCE-MANIFEST.MF
@@ -3,5 +3,5 @@
 Bundle-Name: org.eclipse.jgit.junit - Sources
 Bundle-SymbolicName: org.eclipse.jgit.junit.source
 Bundle-Vendor: Eclipse.org - JGit
-Bundle-Version: 5.4.4.qualifier
-Eclipse-SourceBundle: org.eclipse.jgit.junit;version="5.4.4.qualifier";roots="."
+Bundle-Version: 5.5.2.qualifier
+Eclipse-SourceBundle: org.eclipse.jgit.junit;version="5.5.2.qualifier";roots="."
diff --git a/org.eclipse.jgit.junit/plugin.properties b/org.eclipse.jgit.junit/plugin.properties
index 9842967..f40f8e1 100644
--- a/org.eclipse.jgit.junit/plugin.properties
+++ b/org.eclipse.jgit.junit/plugin.properties
@@ -1,2 +1,2 @@
-plugin_name=JGit JUnit Utility Classes
-provider_name=Eclipse JGit
+Bundle-Name=JGit JUnit Utility Classes
+Bundle-Vendor=Eclipse JGit
diff --git a/org.eclipse.jgit.junit/pom.xml b/org.eclipse.jgit.junit/pom.xml
index ff4c0e7..1ccc220 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.4.4-SNAPSHOT</version>
+    <version>5.5.2-SNAPSHOT</version>
   </parent>
 
   <artifactId>org.eclipse.jgit.junit</artifactId>
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 5c2cd6a..eca8179 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
@@ -125,8 +125,9 @@
 	public void setUp() throws Exception {
 		tmp = File.createTempFile("jgit_test_", "_tmp");
 		CleanupThread.deleteOnShutdown(tmp);
-		if (!tmp.delete() || !tmp.mkdir())
+		if (!tmp.delete() || !tmp.mkdir()) {
 			throw new IOException("Cannot create " + tmp);
+		}
 
 		mockSystemReader = new MockSystemReader();
 		SystemReader.setInstance(mockSystemReader);
@@ -137,7 +138,11 @@
 		// the same one here
 		FS.getFileStoreAttributes(tmp.toPath().getParent());
 
-		FileBasedConfig userConfig = new FileBasedConfig(
+		FileBasedConfig jgitConfig = new FileBasedConfig(
+				new File(tmp, "jgitconfig"), FS.DETECTED);
+		FileBasedConfig systemConfig = new FileBasedConfig(jgitConfig,
+				new File(tmp, "systemgitconfig"), FS.DETECTED);
+		FileBasedConfig userConfig = new FileBasedConfig(systemConfig,
 				new File(tmp, "usergitconfig"), FS.DETECTED);
 		// We have to set autoDetach to false for tests, because tests expect to be able
 		// to clean up by recursively removing the repository, and background GC might be
@@ -145,7 +150,10 @@
 		userConfig.setBoolean(ConfigConstants.CONFIG_GC_SECTION,
 				null, ConfigConstants.CONFIG_KEY_AUTODETACH, false);
 		userConfig.save();
+		mockSystemReader.setJGitConfig(jgitConfig);
+		mockSystemReader.setSystemGitConfig(systemConfig);
 		mockSystemReader.setUserGitConfig(userConfig);
+
 		ceilTestDirectories(getCeilings());
 
 		author = new PersonIdent("J. Author", "jauthor@example.com");
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 13c2932..b9c83bc 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
@@ -103,6 +103,8 @@
 
 	private FileBasedConfig userGitConfig;
 
+	private FileBasedConfig jgitConfig;
+
 	FileBasedConfig systemGitConfig;
 
 	/**
@@ -111,6 +113,7 @@
 	 * @param userGitConfig
 	 *            set another user-level git config
 	 * @return the old user-level git config
+	 * @since 5.1.9
 	 */
 	public FileBasedConfig setUserGitConfig(FileBasedConfig userGitConfig) {
 		FileBasedConfig old = this.userGitConfig;
@@ -119,11 +122,23 @@
 	}
 
 	/**
+	 * Set the jgit config stored at $XDG_CONFIG_HOME/jgit/config
+	 *
+	 * @param jgitConfig
+	 *            set the jgit configuration
+	 * @since 5.5
+	 */
+	public void setJGitConfig(FileBasedConfig jgitConfig) {
+		this.jgitConfig = jgitConfig;
+	}
+
+	/**
 	 * Set the system-level git config
 	 *
 	 * @param systemGitConfig
 	 *            the new system-level git config
 	 * @return the old system-level config
+	 * @since 5.1.9
 	 */
 	public FileBasedConfig setSystemGitConfig(FileBasedConfig systemGitConfig) {
 		FileBasedConfig old = this.systemGitConfig;
@@ -142,6 +157,7 @@
 		init(Constants.GIT_COMMITTER_EMAIL_KEY);
 		setProperty(Constants.OS_USER_DIR, ".");
 		userGitConfig = new MockConfig(null, null);
+		jgitConfig = new MockConfig(null, null);
 		systemGitConfig = new MockConfig(null, null);
 		setCurrentPlatform();
 	}
@@ -200,6 +216,11 @@
 	}
 
 	@Override
+	public FileBasedConfig getJGitConfig() {
+		return jgitConfig;
+	}
+
+	@Override
 	public StoredConfig getSystemConfig()
 			throws IOException, ConfigInvalidException {
 		return systemGitConfig;
@@ -333,4 +354,9 @@
 		return "MockSystemReader";
 	}
 
+	@Override
+	public FileBasedConfig openJGitConfig(Config parent, FS fs) {
+		return jgitConfig;
+	}
+
 }
diff --git a/org.eclipse.jgit.junit/src/org/eclipse/jgit/junit/RepeatRule.java b/org.eclipse.jgit.junit/src/org/eclipse/jgit/junit/RepeatRule.java
index 8636f2a..5b58f0b 100644
--- a/org.eclipse.jgit.junit/src/org/eclipse/jgit/junit/RepeatRule.java
+++ b/org.eclipse.jgit.junit/src/org/eclipse/jgit/junit/RepeatRule.java
@@ -93,6 +93,7 @@
 		 *
 		 * @param message
 		 *            the error message
+		 * @since 5.1.9
 		 */
 		public RepeatedTestException(String message) {
 			super(message);
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 23f49a4..fe5d0aa 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
@@ -362,6 +362,7 @@
 	 *         greater than then the lastmodification time of lastfile.
 	 * @throws InterruptedException
 	 * @throws IOException
+	 * @since 5.1.9
 	 */
 	public static Instant fsTick(File lastFile)
 			throws InterruptedException,
diff --git a/org.eclipse.jgit.junit/src/org/eclipse/jgit/junit/SeparateClassloaderTestRunner.java b/org.eclipse.jgit.junit/src/org/eclipse/jgit/junit/SeparateClassloaderTestRunner.java
new file mode 100644
index 0000000..fbfdf8f
--- /dev/null
+++ b/org.eclipse.jgit.junit/src/org/eclipse/jgit/junit/SeparateClassloaderTestRunner.java
@@ -0,0 +1,96 @@
+/*
+ * Copyright (C) 2019 Nail Samatov <sanail@yandex.ru>
+ * 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.junit;
+
+import static java.lang.ClassLoader.getSystemClassLoader;
+
+import java.net.URL;
+import java.net.URLClassLoader;
+
+import org.junit.runners.BlockJUnit4ClassRunner;
+import org.junit.runners.model.InitializationError;
+
+/**
+ * This class is used when it's required to load jgit classes in separate
+ * classloader for each test class. It can be needed to isolate static field
+ * initialization between separate tests.
+ *
+ * @since 5.5
+ */
+public class SeparateClassloaderTestRunner extends BlockJUnit4ClassRunner {
+
+	/**
+	 * Creates a SeparateClassloaderTestRunner to run {@code klass}.
+	 *
+	 * @param klass
+	 *            test class to run.
+	 * @throws InitializationError
+	 *             if the test class is malformed or can't be found.
+	 */
+	public SeparateClassloaderTestRunner(Class<?> klass)
+			throws InitializationError {
+		super(loadNewClass(klass));
+	}
+
+	private static Class<?> loadNewClass(Class<?> klass)
+			throws InitializationError {
+		try {
+			URL[] urls = ((URLClassLoader) getSystemClassLoader()).getURLs();
+			ClassLoader testClassLoader = new URLClassLoader(urls) {
+
+				@Override
+				public Class<?> loadClass(String name)
+						throws ClassNotFoundException {
+					if (name.startsWith("org.eclipse.jgit.")) {
+						return super.findClass(name);
+					}
+
+					return super.loadClass(name);
+				}
+			};
+			return Class.forName(klass.getName(), true, testClassLoader);
+		} catch (ClassNotFoundException e) {
+			throw new InitializationError(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 e89cf0f..593b960 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
@@ -361,6 +361,22 @@
 	}
 
 	/**
+	 * Create a new, unparsed commit.
+	 * <p>
+	 * See {@link #unparsedCommit(int, RevTree, ObjectId...)}. The tree is the
+	 * empty tree (no files or subdirectories).
+	 *
+	 * @param parents
+	 *            zero or more IDs of the commit's parents.
+	 * @return the ID of the new commit.
+	 * @throws Exception
+	 * @since 5.5
+	 */
+	public ObjectId unparsedCommit(ObjectId... parents) throws Exception {
+		return unparsedCommit(1, tree(), parents);
+	}
+
+	/**
 	 * Create a new commit.
 	 * <p>
 	 * See {@link #commit(int, RevTree, RevCommit...)}. The tree is the empty
@@ -428,6 +444,29 @@
 	 */
 	public RevCommit commit(final int secDelta, final RevTree tree,
 			final RevCommit... parents) throws Exception {
+		ObjectId id = unparsedCommit(secDelta, tree, parents);
+		return pool.parseCommit(id);
+	}
+
+	/**
+	 * Create a new, unparsed commit.
+	 * <p>
+	 * The author and committer identities are stored using the current
+	 * timestamp, after being incremented by {@code secDelta}. The message body
+	 * is empty.
+	 *
+	 * @param secDelta
+	 *            number of seconds to advance {@link #tick(int)} by.
+	 * @param tree
+	 *            the root tree for the commit.
+	 * @param parents
+	 *            zero or more IDs of the commit's parents.
+	 * @return the ID of the new commit.
+	 * @throws Exception
+	 * @since 5.5
+	 */
+	public ObjectId unparsedCommit(final int secDelta, final RevTree tree,
+			final ObjectId... parents) throws Exception {
 		tick(secDelta);
 
 		final org.eclipse.jgit.lib.CommitBuilder c;
@@ -443,7 +482,7 @@
 			id = ins.insert(c);
 			ins.flush();
 		}
-		return pool.parseCommit(id);
+		return id;
 	}
 
 	/**
diff --git a/org.eclipse.jgit.junit/src/org/eclipse/jgit/junit/time/TimeUtil.java b/org.eclipse.jgit.junit/src/org/eclipse/jgit/junit/time/TimeUtil.java
index 1f8070d..a24f058 100644
--- a/org.eclipse.jgit.junit/src/org/eclipse/jgit/junit/time/TimeUtil.java
+++ b/org.eclipse.jgit.junit/src/org/eclipse/jgit/junit/time/TimeUtil.java
@@ -53,6 +53,8 @@
 
 /**
  * Utility methods for handling timestamps
+ *
+ * @since 5.1.9
  */
 public class TimeUtil {
 	/**
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 be2ff2e..bcd5cf0 100644
--- a/org.eclipse.jgit.lfs.server.test/META-INF/MANIFEST.MF
+++ b/org.eclipse.jgit.lfs.server.test/META-INF/MANIFEST.MF
@@ -1,10 +1,10 @@
 Manifest-Version: 1.0
 Bundle-ManifestVersion: 2
-Bundle-Name: %plugin_name
+Bundle-Name: %Bundle-Name
 Automatic-Module-Name: org.eclipse.jgit.lfs.server.test
 Bundle-SymbolicName: org.eclipse.jgit.lfs.server.test
-Bundle-Version: 5.4.4.qualifier
-Bundle-Vendor: %provider_name
+Bundle-Version: 5.5.2.qualifier
+Bundle-Vendor: %Bundle-Vendor
 Bundle-Localization: plugin
 Bundle-RequiredExecutionEnvironment: JavaSE-1.8
 Import-Package: javax.servlet;version="[3.1.0,4.0.0)",
@@ -28,24 +28,24 @@
  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.4.4,5.5.0)",
- org.eclipse.jgit.api.errors;version="[5.4.4,5.5.0)",
- org.eclipse.jgit.internal.storage.file;version="[5.4.4,5.5.0)",
- org.eclipse.jgit.junit;version="[5.4.4,5.5.0)",
- org.eclipse.jgit.junit.http;version="[5.4.4,5.5.0)",
- org.eclipse.jgit.lfs;version="[5.4.4,5.5.0)",
- org.eclipse.jgit.lfs.errors;version="[5.4.4,5.5.0)",
- org.eclipse.jgit.lfs.lib;version="[5.4.4,5.5.0)",
- org.eclipse.jgit.lfs.server;version="[5.4.4,5.5.0)",
- org.eclipse.jgit.lfs.server.fs;version="[5.4.4,5.5.0)",
- org.eclipse.jgit.lfs.test;version="[5.4.4,5.5.0)",
- org.eclipse.jgit.lib;version="[5.4.4,5.5.0)",
- org.eclipse.jgit.revwalk;version="[5.4.4,5.5.0)",
- org.eclipse.jgit.storage.file;version="[5.4.4,5.5.0)",
- org.eclipse.jgit.transport;version="[5.4.4,5.5.0)",
- org.eclipse.jgit.treewalk;version="[5.4.4,5.5.0)",
- org.eclipse.jgit.treewalk.filter;version="[5.4.4,5.5.0)",
- org.eclipse.jgit.util;version="[5.4.4,5.5.0)",
+ org.eclipse.jgit.api;version="[5.5.2,5.6.0)",
+ org.eclipse.jgit.api.errors;version="[5.5.2,5.6.0)",
+ org.eclipse.jgit.internal.storage.file;version="[5.5.2,5.6.0)",
+ org.eclipse.jgit.junit;version="[5.5.2,5.6.0)",
+ org.eclipse.jgit.junit.http;version="[5.5.2,5.6.0)",
+ org.eclipse.jgit.lfs;version="[5.5.2,5.6.0)",
+ org.eclipse.jgit.lfs.errors;version="[5.5.2,5.6.0)",
+ org.eclipse.jgit.lfs.lib;version="[5.5.2,5.6.0)",
+ org.eclipse.jgit.lfs.server;version="[5.5.2,5.6.0)",
+ org.eclipse.jgit.lfs.server.fs;version="[5.5.2,5.6.0)",
+ org.eclipse.jgit.lfs.test;version="[5.5.2,5.6.0)",
+ org.eclipse.jgit.lib;version="[5.5.2,5.6.0)",
+ org.eclipse.jgit.revwalk;version="[5.5.2,5.6.0)",
+ org.eclipse.jgit.storage.file;version="[5.5.2,5.6.0)",
+ org.eclipse.jgit.transport;version="[5.5.2,5.6.0)",
+ org.eclipse.jgit.treewalk;version="[5.5.2,5.6.0)",
+ org.eclipse.jgit.treewalk.filter;version="[5.5.2,5.6.0)",
+ org.eclipse.jgit.util;version="[5.5.2,5.6.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/plugin.properties b/org.eclipse.jgit.lfs.server.test/plugin.properties
index 4a8e642..b6dd7c0 100644
--- a/org.eclipse.jgit.lfs.server.test/plugin.properties
+++ b/org.eclipse.jgit.lfs.server.test/plugin.properties
@@ -1,2 +1,2 @@
-plugin_name=JGit LFS Server Tests
-provider_name=Eclipse JGit
+Bundle-Name=JGit LFS Server Tests
+Bundle-Vendor=Eclipse JGit
diff --git a/org.eclipse.jgit.lfs.server.test/pom.xml b/org.eclipse.jgit.lfs.server.test/pom.xml
index fdcf556..a116a6d 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.4.4-SNAPSHOT</version>
+    <version>5.5.2-SNAPSHOT</version>
   </parent>
 
   <artifactId>org.eclipse.jgit.lfs.server.test</artifactId>
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 6609c3d..0000000
--- a/org.eclipse.jgit.lfs.server/.settings/.api_filters
+++ /dev/null
@@ -1,19 +0,0 @@
-<?xml version="1.0" encoding="UTF-8" standalone="no"?>
-<component id="org.eclipse.jgit.lfs.server" version="2">
-    <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 a97e096..f519f26 100644
--- a/org.eclipse.jgit.lfs.server/META-INF/MANIFEST.MF
+++ b/org.eclipse.jgit.lfs.server/META-INF/MANIFEST.MF
@@ -1,21 +1,21 @@
 Manifest-Version: 1.0
 Bundle-ManifestVersion: 2
-Bundle-Name: %plugin_name
+Bundle-Name: %Bundle-Name
 Automatic-Module-Name: org.eclipse.jgit.lfs.server
 Bundle-SymbolicName: org.eclipse.jgit.lfs.server
-Bundle-Version: 5.4.4.qualifier
+Bundle-Version: 5.5.2.qualifier
 Bundle-Localization: plugin
-Bundle-Vendor: %provider_name
-Export-Package: org.eclipse.jgit.lfs.server;version="5.4.4";
+Bundle-Vendor: %Bundle-Vendor
+Export-Package: org.eclipse.jgit.lfs.server;version="5.5.2";
   uses:="javax.servlet.http,
    org.eclipse.jgit.lfs.lib",
- org.eclipse.jgit.lfs.server.fs;version="5.4.4";
+ org.eclipse.jgit.lfs.server.fs;version="5.5.2";
   uses:="javax.servlet,
    javax.servlet.http,
    org.eclipse.jgit.lfs.server,
    org.eclipse.jgit.lfs.lib",
- org.eclipse.jgit.lfs.server.internal;version="5.4.4";x-internal:=true,
- org.eclipse.jgit.lfs.server.s3;version="5.4.4";
+ org.eclipse.jgit.lfs.server.internal;version="5.5.2";x-internal:=true,
+ org.eclipse.jgit.lfs.server.s3;version="5.5.2";
   uses:="org.eclipse.jgit.lfs.server,
    org.eclipse.jgit.lfs.lib"
 Bundle-RequiredExecutionEnvironment: JavaSE-1.8
@@ -25,15 +25,15 @@
  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.4.4,5.5.0)",
- org.eclipse.jgit.internal;version="[5.4.4,5.5.0)",
- org.eclipse.jgit.internal.storage.file;version="[5.4.4,5.5.0)",
- org.eclipse.jgit.lfs.errors;version="[5.4.4,5.5.0)",
- org.eclipse.jgit.lfs.internal;version="[5.4.4,5.5.0)",
- org.eclipse.jgit.lfs.lib;version="[5.4.4,5.5.0)",
- org.eclipse.jgit.lib;version="[5.4.4,5.5.0)",
- org.eclipse.jgit.nls;version="[5.4.4,5.5.0)",
- org.eclipse.jgit.transport.http;version="[5.4.4,5.5.0)",
- org.eclipse.jgit.transport.http.apache;version="[5.4.4,5.5.0)",
- org.eclipse.jgit.util;version="[5.4.4,5.5.0)",
+ org.eclipse.jgit.annotations;version="[5.5.2,5.6.0)",
+ org.eclipse.jgit.internal;version="[5.5.2,5.6.0)",
+ org.eclipse.jgit.internal.storage.file;version="[5.5.2,5.6.0)",
+ org.eclipse.jgit.lfs.errors;version="[5.5.2,5.6.0)",
+ org.eclipse.jgit.lfs.internal;version="[5.5.2,5.6.0)",
+ org.eclipse.jgit.lfs.lib;version="[5.5.2,5.6.0)",
+ org.eclipse.jgit.lib;version="[5.5.2,5.6.0)",
+ org.eclipse.jgit.nls;version="[5.5.2,5.6.0)",
+ org.eclipse.jgit.transport.http;version="[5.5.2,5.6.0)",
+ org.eclipse.jgit.transport.http.apache;version="[5.5.2,5.6.0)",
+ org.eclipse.jgit.util;version="[5.5.2,5.6.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
index 41435df..55cdc0b 100644
--- a/org.eclipse.jgit.lfs.server/META-INF/SOURCE-MANIFEST.MF
+++ b/org.eclipse.jgit.lfs.server/META-INF/SOURCE-MANIFEST.MF
@@ -3,5 +3,5 @@
 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.4.qualifier
-Eclipse-SourceBundle: org.eclipse.jgit.lfs.server;version="5.4.4.qualifier";roots="."
+Bundle-Version: 5.5.2.qualifier
+Eclipse-SourceBundle: org.eclipse.jgit.lfs.server;version="5.5.2.qualifier";roots="."
diff --git a/org.eclipse.jgit.lfs.server/plugin.properties b/org.eclipse.jgit.lfs.server/plugin.properties
index 59f0139..4b9ee82 100644
--- a/org.eclipse.jgit.lfs.server/plugin.properties
+++ b/org.eclipse.jgit.lfs.server/plugin.properties
@@ -1,2 +1,2 @@
-plugin_name=JGit Large File Storage Server
-provider_name=Eclipse JGit
+Bundle-Name=JGit Large File Storage Server
+Bundle-Vendor=Eclipse JGit
diff --git a/org.eclipse.jgit.lfs.server/pom.xml b/org.eclipse.jgit.lfs.server/pom.xml
index 201a5f0..01a0b8d 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.4.4-SNAPSHOT</version>
+    <version>5.5.2-SNAPSHOT</version>
   </parent>
 
   <artifactId>org.eclipse.jgit.lfs.server</artifactId>
diff --git a/org.eclipse.jgit.lfs.test/META-INF/MANIFEST.MF b/org.eclipse.jgit.lfs.test/META-INF/MANIFEST.MF
index c44feb6..cf10aa6 100644
--- a/org.eclipse.jgit.lfs.test/META-INF/MANIFEST.MF
+++ b/org.eclipse.jgit.lfs.test/META-INF/MANIFEST.MF
@@ -1,24 +1,24 @@
 Manifest-Version: 1.0
 Bundle-ManifestVersion: 2
-Bundle-Name: %plugin_name
+Bundle-Name: %Bundle-Name
 Automatic-Module-Name: org.eclipse.jgit.lfs.test
 Bundle-SymbolicName: org.eclipse.jgit.lfs.test
-Bundle-Version: 5.4.4.qualifier
-Bundle-Vendor: %provider_name
+Bundle-Version: 5.5.2.qualifier
+Bundle-Vendor: %Bundle-Vendor
 Bundle-Localization: plugin
 Bundle-RequiredExecutionEnvironment: JavaSE-1.8
-Import-Package: org.eclipse.jgit.internal.storage.dfs;version="[5.4.4,5.5.0)",
- org.eclipse.jgit.junit;version="[5.4.4,5.5.0)",
- org.eclipse.jgit.lfs;version="[5.4.4,5.5.0)",
- org.eclipse.jgit.lfs.errors;version="[5.4.4,5.5.0)",
- org.eclipse.jgit.lfs.lib;version="[5.4.4,5.5.0)",
- org.eclipse.jgit.lib;version="[5.4.4,5.5.0)",
- org.eclipse.jgit.revwalk;version="[5.4.4,5.5.0)",
- org.eclipse.jgit.treewalk;version="[5.4.4,5.5.0)",
- org.eclipse.jgit.treewalk.filter;version="[5.4.4,5.5.0)",
- org.eclipse.jgit.util;version="[5.4.4,5.5.0)",
+Import-Package: org.eclipse.jgit.internal.storage.dfs;version="[5.5.2,5.6.0)",
+ org.eclipse.jgit.junit;version="[5.5.2,5.6.0)",
+ org.eclipse.jgit.lfs;version="[5.5.2,5.6.0)",
+ org.eclipse.jgit.lfs.errors;version="[5.5.2,5.6.0)",
+ org.eclipse.jgit.lfs.lib;version="[5.5.2,5.6.0)",
+ org.eclipse.jgit.lib;version="[5.5.2,5.6.0)",
+ org.eclipse.jgit.revwalk;version="[5.5.2,5.6.0)",
+ org.eclipse.jgit.treewalk;version="[5.5.2,5.6.0)",
+ org.eclipse.jgit.treewalk.filter;version="[5.5.2,5.6.0)",
+ org.eclipse.jgit.util;version="[5.5.2,5.6.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.4.4";x-friends:="org.eclipse.jgit.lfs.server.test"
+Export-Package: org.eclipse.jgit.lfs.test;version="5.5.2";x-friends:="org.eclipse.jgit.lfs.server.test"
diff --git a/org.eclipse.jgit.lfs.test/plugin.properties b/org.eclipse.jgit.lfs.test/plugin.properties
index f900780..ab78575 100644
--- a/org.eclipse.jgit.lfs.test/plugin.properties
+++ b/org.eclipse.jgit.lfs.test/plugin.properties
@@ -1,2 +1,2 @@
-plugin_name=JGit LFS Tests
-provider_name=Eclipse JGit
+Bundle-Name=JGit LFS Tests
+Bundle-Vendor=Eclipse JGit
diff --git a/org.eclipse.jgit.lfs.test/pom.xml b/org.eclipse.jgit.lfs.test/pom.xml
index 0494322..8166a07 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.4.4-SNAPSHOT</version>
+    <version>5.5.2-SNAPSHOT</version>
   </parent>
 
   <artifactId>org.eclipse.jgit.lfs.test</artifactId>
diff --git a/org.eclipse.jgit.lfs/.settings/.api_filters b/org.eclipse.jgit.lfs/.settings/.api_filters
new file mode 100644
index 0000000..9747df8
--- /dev/null
+++ b/org.eclipse.jgit.lfs/.settings/.api_filters
@@ -0,0 +1,12 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<component id="org.eclipse.jgit.lfs" version="2">
+    <resource path="src/org/eclipse/jgit/lfs/lib/AnyLongObjectId.java" type="org.eclipse.jgit.lfs.lib.AnyLongObjectId">
+        <filter id="1141899266">
+            <message_arguments>
+                <message_argument value="5.4"/>
+                <message_argument value="5.5"/>
+                <message_argument value="isEqual(AnyLongObjectId, AnyLongObjectId)"/>
+            </message_arguments>
+        </filter>
+    </resource>
+</component>
diff --git a/org.eclipse.jgit.lfs/META-INF/MANIFEST.MF b/org.eclipse.jgit.lfs/META-INF/MANIFEST.MF
index 097ec66..da1fbd7 100644
--- a/org.eclipse.jgit.lfs/META-INF/MANIFEST.MF
+++ b/org.eclipse.jgit.lfs/META-INF/MANIFEST.MF
@@ -1,35 +1,35 @@
 Manifest-Version: 1.0
 Bundle-ManifestVersion: 2
-Bundle-Name: %plugin_name
+Bundle-Name: %Bundle-Name
 Automatic-Module-Name: org.eclipse.jgit.lfs
 Bundle-SymbolicName: org.eclipse.jgit.lfs
-Bundle-Version: 5.4.4.qualifier
+Bundle-Version: 5.5.2.qualifier
 Bundle-Localization: plugin
-Bundle-Vendor: %provider_name
-Export-Package: org.eclipse.jgit.lfs;version="5.4.4",
- org.eclipse.jgit.lfs.errors;version="5.4.4",
- org.eclipse.jgit.lfs.internal;version="5.4.4";x-friends:="org.eclipse.jgit.lfs.test,org.eclipse.jgit.lfs.server.fs,org.eclipse.jgit.lfs.server",
- org.eclipse.jgit.lfs.lib;version="5.4.4"
+Bundle-Vendor: %Bundle-Vendor
+Export-Package: org.eclipse.jgit.lfs;version="5.5.2",
+ org.eclipse.jgit.lfs.errors;version="5.5.2",
+ org.eclipse.jgit.lfs.internal;version="5.5.2";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.5.2"
 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.4.4,5.5.0)";resolution:=optional,
- org.eclipse.jgit.api.errors;version="[5.4.4,5.5.0)",
- org.eclipse.jgit.attributes;version="[5.4.4,5.5.0)",
- org.eclipse.jgit.diff;version="[5.4.4,5.5.0)",
- org.eclipse.jgit.errors;version="[5.4.4,5.5.0)",
- org.eclipse.jgit.hooks;version="[5.4.4,5.5.0)",
- org.eclipse.jgit.internal.storage.file;version="[5.4.4,5.5.0)",
- org.eclipse.jgit.lib;version="[5.4.4,5.5.0)",
- org.eclipse.jgit.nls;version="[5.4.4,5.5.0)",
- org.eclipse.jgit.revwalk;version="[5.4.4,5.5.0)",
- org.eclipse.jgit.storage.file;version="[5.4.4,5.5.0)",
- org.eclipse.jgit.storage.pack;version="[5.4.4,5.5.0)",
- org.eclipse.jgit.transport;version="[5.4.4,5.5.0)",
- org.eclipse.jgit.transport.http;version="[5.4.4,5.5.0)",
- org.eclipse.jgit.treewalk;version="[5.4.4,5.5.0)",
- org.eclipse.jgit.treewalk.filter;version="[5.4.4,5.5.0)",
- org.eclipse.jgit.util;version="[5.4.4,5.5.0)",
- org.eclipse.jgit.util.io;version="[5.4.4,5.5.0)"
+ org.eclipse.jgit.annotations;version="[5.5.2,5.6.0)";resolution:=optional,
+ org.eclipse.jgit.api.errors;version="[5.5.2,5.6.0)",
+ org.eclipse.jgit.attributes;version="[5.5.2,5.6.0)",
+ org.eclipse.jgit.diff;version="[5.5.2,5.6.0)",
+ org.eclipse.jgit.errors;version="[5.5.2,5.6.0)",
+ org.eclipse.jgit.hooks;version="[5.5.2,5.6.0)",
+ org.eclipse.jgit.internal.storage.file;version="[5.5.2,5.6.0)",
+ org.eclipse.jgit.lib;version="[5.5.2,5.6.0)",
+ org.eclipse.jgit.nls;version="[5.5.2,5.6.0)",
+ org.eclipse.jgit.revwalk;version="[5.5.2,5.6.0)",
+ org.eclipse.jgit.storage.file;version="[5.5.2,5.6.0)",
+ org.eclipse.jgit.storage.pack;version="[5.5.2,5.6.0)",
+ org.eclipse.jgit.transport;version="[5.5.2,5.6.0)",
+ org.eclipse.jgit.transport.http;version="[5.5.2,5.6.0)",
+ org.eclipse.jgit.treewalk;version="[5.5.2,5.6.0)",
+ org.eclipse.jgit.treewalk.filter;version="[5.5.2,5.6.0)",
+ org.eclipse.jgit.util;version="[5.5.2,5.6.0)",
+ org.eclipse.jgit.util.io;version="[5.5.2,5.6.0)"
diff --git a/org.eclipse.jgit.lfs/META-INF/SOURCE-MANIFEST.MF b/org.eclipse.jgit.lfs/META-INF/SOURCE-MANIFEST.MF
index dda63a9..562747d 100644
--- a/org.eclipse.jgit.lfs/META-INF/SOURCE-MANIFEST.MF
+++ b/org.eclipse.jgit.lfs/META-INF/SOURCE-MANIFEST.MF
@@ -3,5 +3,5 @@
 Bundle-Name: org.eclipse.jgit.lfs - Sources
 Bundle-SymbolicName: org.eclipse.jgit.lfs.source
 Bundle-Vendor: Eclipse.org - JGit
-Bundle-Version: 5.4.4.qualifier
-Eclipse-SourceBundle: org.eclipse.jgit.lfs;version="5.4.4.qualifier";roots="."
+Bundle-Version: 5.5.2.qualifier
+Eclipse-SourceBundle: org.eclipse.jgit.lfs;version="5.5.2.qualifier";roots="."
diff --git a/org.eclipse.jgit.lfs/plugin.properties b/org.eclipse.jgit.lfs/plugin.properties
index 7c22ddb..76ead9b 100644
--- a/org.eclipse.jgit.lfs/plugin.properties
+++ b/org.eclipse.jgit.lfs/plugin.properties
@@ -1,2 +1,2 @@
-plugin_name=JGit Large File Storage
-provider_name=Eclipse JGit
+Bundle-Name=JGit Large File Storage
+Bundle-Vendor=Eclipse JGit
diff --git a/org.eclipse.jgit.lfs/pom.xml b/org.eclipse.jgit.lfs/pom.xml
index b66eb24..1f2afd9 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.4.4-SNAPSHOT</version>
+    <version>5.5.2-SNAPSHOT</version>
   </parent>
 
   <artifactId>org.eclipse.jgit.lfs</artifactId>
diff --git a/org.eclipse.jgit.lfs/src/org/eclipse/jgit/lfs/Lfs.java b/org.eclipse.jgit.lfs/src/org/eclipse/jgit/lfs/Lfs.java
index 4c46bbd..8dba09c 100644
--- a/org.eclipse.jgit.lfs/src/org/eclipse/jgit/lfs/Lfs.java
+++ b/org.eclipse.jgit.lfs/src/org/eclipse/jgit/lfs/Lfs.java
@@ -42,6 +42,8 @@
  */
 package org.eclipse.jgit.lfs;
 
+import static org.eclipse.jgit.lib.Constants.OBJECTS;
+
 import java.io.IOException;
 import java.nio.file.Files;
 import java.nio.file.Path;
@@ -104,7 +106,7 @@
 	 */
 	public Path getLfsObjDir() {
 		if (objDir == null) {
-			objDir = root.resolve("objects"); //$NON-NLS-1$
+			objDir = root.resolve(OBJECTS);
 		}
 		return objDir;
 	}
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 791f8c0..2a1a0b6 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.4.4.qualifier"
+      version="5.5.2.qualifier"
       provider-name="%providerName">
 
    <description url="http://www.eclipse.org/jgit/">
@@ -18,8 +18,8 @@
    </license>
 
    <url>
-      <update label="%updateSiteName" url="http://download.eclipse.org/egit/updates"/>
-      <discovery label="%updateSiteName" url="http://download.eclipse.org/egit/updates"/>
+      <update label="%updateSiteName" url="https://download.eclipse.org/egit/updates"/>
+      <discovery label="%updateSiteName" url="https://download.eclipse.org/egit/updates"/>
    </url>
 
    <plugin
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 3c759d4..9f2a30d 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.4.4-SNAPSHOT</version>
+    <version>5.5.2-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 7343dd6..4096f8d 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.4.4.qualifier"
+      version="5.5.2.qualifier"
       provider-name="%providerName">
 
    <description url="http://www.eclipse.org/jgit/">
@@ -18,12 +18,12 @@
    </license>
 
    <url>
-      <update label="%updateSiteName" url="http://download.eclipse.org/egit/updates"/>
-      <discovery label="%updateSiteName" url="http://download.eclipse.org/egit/updates"/>
+      <update label="%updateSiteName" url="https://download.eclipse.org/egit/updates"/>
+      <discovery label="%updateSiteName" url="https://download.eclipse.org/egit/updates"/>
    </url>
 
    <requires>
-      <import plugin="org.eclipse.jgit" version="5.4.4" match="equivalent"/>
+      <import plugin="org.eclipse.jgit" version="5.5.2" 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 5006993..200a1e5 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.4.4-SNAPSHOT</version>
+    <version>5.5.2-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 f8ed86a..aa43cef 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.4.4.qualifier"
+      version="5.5.2.qualifier"
       provider-name="%providerName">
 
    <description url="http://www.eclipse.org/jgit/">
@@ -18,13 +18,13 @@
    </license>
 
    <url>
-      <update label="%updateSiteName" url="http://download.eclipse.org/egit/updates"/>
-      <discovery label="%updateSiteName" url="http://download.eclipse.org/egit/updates"/>
+      <update label="%updateSiteName" url="https://download.eclipse.org/egit/updates"/>
+      <discovery label="%updateSiteName" url="https://download.eclipse.org/egit/updates"/>
    </url>
 
    <requires>
       <import plugin="com.jcraft.jsch"/>
-      <import plugin="org.eclipse.jgit" version="5.4.4" match="equivalent"/>
+      <import plugin="org.eclipse.jgit" version="5.5.2" match="equivalent"/>
    </requires>
 
    <plugin
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 0df1c8a..23d3450 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.4.4-SNAPSHOT</version>
+    <version>5.5.2-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 c99f82d..781e94a 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.4.4.qualifier"
+      version="5.5.2.qualifier"
       provider-name="%providerName">
 
    <description url="http://www.eclipse.org/jgit/">
@@ -18,12 +18,12 @@
    </license>
 
    <url>
-      <update label="%updateSiteName" url="http://download.eclipse.org/egit/updates"/>
-      <discovery label="%updateSiteName" url="http://download.eclipse.org/egit/updates"/>
+      <update label="%updateSiteName" url="https://download.eclipse.org/egit/updates"/>
+      <discovery label="%updateSiteName" url="https://download.eclipse.org/egit/updates"/>
    </url>
 
    <requires>
-      <import feature="org.eclipse.jgit" version="5.4.4" match="equivalent"/>
+      <import feature="org.eclipse.jgit" version="5.5.2" 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 2e2298c..b5fb886 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.4.4-SNAPSHOT</version>
+    <version>5.5.2-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 c00d360..8656890 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.4.4.qualifier"
+      version="5.5.2.qualifier"
       provider-name="%providerName">
 
    <description url="http://www.eclipse.org/jgit/">
@@ -18,8 +18,8 @@
    </license>
 
    <url>
-      <update label="%updateSiteName" url="http://download.eclipse.org/egit/updates"/>
-      <discovery label="%updateSiteName" url="http://download.eclipse.org/egit/updates"/>
+      <update label="%updateSiteName" url="https://download.eclipse.org/egit/updates"/>
+      <discovery label="%updateSiteName" url="https://download.eclipse.org/egit/updates"/>
    </url>
 
    <includes
@@ -35,9 +35,9 @@
          version="0.0.0"/>
 
    <requires>
-      <import feature="org.eclipse.jgit" version="5.4.4" match="equivalent"/>
-      <import feature="org.eclipse.jgit.lfs" version="5.4.4" match="equivalent"/>
-      <import feature="org.eclipse.jgit.ssh.apache" version="5.4.4" match="equivalent"/>
+      <import feature="org.eclipse.jgit" version="5.5.2" match="equivalent"/>
+      <import feature="org.eclipse.jgit.lfs" version="5.5.2" match="equivalent"/>
+      <import feature="org.eclipse.jgit.ssh.apache" version="5.5.2" 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 748ee58..b4fe972 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.4.4-SNAPSHOT</version>
+    <version>5.5.2-SNAPSHOT</version>
   </parent>
 
   <groupId>org.eclipse.jgit.feature</groupId>
diff --git a/org.eclipse.jgit.packaging/org.eclipse.jgit.repository/pom.xml b/org.eclipse.jgit.packaging/org.eclipse.jgit.repository/pom.xml
index 81859e4..63c76bf 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.4.4-SNAPSHOT</version>
+    <version>5.5.2-SNAPSHOT</version>
   </parent>
 
   <artifactId>org.eclipse.jgit.repository</artifactId>
diff --git a/org.eclipse.jgit.packaging/org.eclipse.jgit.source.feature/feature.xml b/org.eclipse.jgit.packaging/org.eclipse.jgit.source.feature/feature.xml
index efd90a1..8781c66 100644
--- a/org.eclipse.jgit.packaging/org.eclipse.jgit.source.feature/feature.xml
+++ b/org.eclipse.jgit.packaging/org.eclipse.jgit.source.feature/feature.xml
@@ -2,7 +2,7 @@
 <feature
       id="org.eclipse.jgit.source"
       label="%featureName"
-      version="5.4.4.qualifier"
+      version="5.5.2.qualifier"
       provider-name="%providerName">
 
    <description url="http://www.eclipse.org/jgit/">
@@ -18,12 +18,12 @@
    </license>
 
    <url>
-      <update label="%updateSiteName" url="http://download.eclipse.org/egit/updates"/>
-      <discovery label="%updateSiteName" url="http://download.eclipse.org/egit/updates"/>
+      <update label="%updateSiteName" url="https://download.eclipse.org/egit/updates"/>
+      <discovery label="%updateSiteName" url="https://download.eclipse.org/egit/updates"/>
    </url>
 
    <requires>
-      <import feature="org.eclipse.jgit" version="5.4.4" match="equivalent"/>
+      <import feature="org.eclipse.jgit" version="5.5.2" match="equivalent"/>
    </requires>
 
    <plugin
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 bb8fedd..9ce5ec4 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.4.4-SNAPSHOT</version>
+    <version>5.5.2-SNAPSHOT</version>
   </parent>
 
   <groupId>org.eclipse.jgit.feature</groupId>
@@ -63,7 +63,7 @@
     <dependency>
       <groupId>org.eclipse.jgit.feature</groupId>
       <artifactId>org.eclipse.jgit</artifactId>
-      <version>5.4.4-SNAPSHOT</version>
+      <version>5.5.2-SNAPSHOT</version>
     </dependency>
   </dependencies>
 
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 75cbdaf..a55f941 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.4.4.qualifier"
+      version="5.5.2.qualifier"
       provider-name="%providerName">
 
    <description url="http://www.eclipse.org/jgit/">
@@ -18,12 +18,12 @@
    </license>
 
    <url>
-      <update label="%updateSiteName" url="http://download.eclipse.org/egit/updates"/>
-      <discovery label="%updateSiteName" url="http://download.eclipse.org/egit/updates"/>
+      <update label="%updateSiteName" url="https://download.eclipse.org/egit/updates"/>
+      <discovery label="%updateSiteName" url="https://download.eclipse.org/egit/updates"/>
    </url>
 
    <requires>
-      <import feature="org.eclipse.jgit" version="5.4.4" match="equivalent"/>
+      <import feature="org.eclipse.jgit" version="5.5.2" match="equivalent"/>
    </requires>
 
    <plugin
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 888673a..9ebafca 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.4.4-SNAPSHOT</version>
+    <version>5.5.2-SNAPSHOT</version>
   </parent>
 
   <groupId>org.eclipse.jgit.feature</groupId>
diff --git a/org.eclipse.jgit.packaging/org.eclipse.jgit.target/META-INF/MANIFEST.MF b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/META-INF/MANIFEST.MF
index ae9a02a..5954a34 100644
--- a/org.eclipse.jgit.packaging/org.eclipse.jgit.target/META-INF/MANIFEST.MF
+++ b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/META-INF/MANIFEST.MF
@@ -2,4 +2,4 @@
 Bundle-ManifestVersion: 2
 Bundle-Name: JGit Target Platform Bundle
 Bundle-SymbolicName: org.eclipse.jgit.target
-Bundle-Version: 5.4.4.qualifier
+Bundle-Version: 5.5.2.qualifier
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 941d496..5d9a00a 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,28 +1,44 @@
 <?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="1638580694">
+<target name="jgit-4.10" sequenceNumber="1638608437">
   <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="https://archive.eclipse.org/jetty/updates/jetty-bundles-9.x/jetty-bundles-9.x/9.4.14.v20181114"/>
+      <unit id="org.eclipse.jetty.client" version="9.4.20.v20190813"/>
+      <unit id="org.eclipse.jetty.client.source" version="9.4.20.v20190813"/>
+      <unit id="org.eclipse.jetty.continuation" version="9.4.20.v20190813"/>
+      <unit id="org.eclipse.jetty.continuation.source" version="9.4.20.v20190813"/>
+      <unit id="org.eclipse.jetty.http" version="9.4.20.v20190813"/>
+      <unit id="org.eclipse.jetty.http.source" version="9.4.20.v20190813"/>
+      <unit id="org.eclipse.jetty.io" version="9.4.20.v20190813"/>
+      <unit id="org.eclipse.jetty.io.source" version="9.4.20.v20190813"/>
+      <unit id="org.eclipse.jetty.security" version="9.4.20.v20190813"/>
+      <unit id="org.eclipse.jetty.security.source" version="9.4.20.v20190813"/>
+      <unit id="org.eclipse.jetty.server" version="9.4.20.v20190813"/>
+      <unit id="org.eclipse.jetty.server.source" version="9.4.20.v20190813"/>
+      <unit id="org.eclipse.jetty.servlet" version="9.4.20.v20190813"/>
+      <unit id="org.eclipse.jetty.servlet.source" version="9.4.20.v20190813"/>
+      <unit id="org.eclipse.jetty.util" version="9.4.20.v20190813"/>
+      <unit id="org.eclipse.jetty.util.source" version="9.4.20.v20190813"/>
+      <repository id="jetty-9.4.20" location="https://archive.eclipse.org/jetty/updates/jetty-bundles-9.x/jetty-bundles-9.x/9.4.20.v20190813/"/>
     </location>
     <location includeMode="slicer" includeAllPlatforms="false" includeSource="true" includeConfigurePhase="true" type="InstallableUnit">
+      <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="com.jcraft.jzlib" version="1.1.1.v201205102305"/>
+      <unit id="com.jcraft.jzlib.source" version="1.1.1.v201205102305"/>
+      <unit id="javaewah" version="1.1.6.v20160919-1400"/>
+      <unit id="javaewah.source" version="1.1.6.v20160919-1400"/>
+      <unit id="javax.servlet" version="3.1.0.v201410161800"/>
+      <unit id="javax.servlet.source" version="3.1.0.v201410161800"/>
+      <unit id="net.bytebuddy.byte-buddy" 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="net.bytebuddy.byte-buddy.source" version="1.9.0.v20181107-1410"/>
+      <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.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"/>
@@ -37,52 +53,36 @@
       <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.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"/>
       <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.kohsuke.args4j" version="2.33.0.v20160323-2218"/>
+      <unit id="org.kohsuke.args4j.source" version="2.33.0.v20160323-2218"/>
+      <unit id="org.mockito" version="2.23.0.v20190527-1420"/>
+      <unit id="org.mockito.source" version="2.23.0.v20190527-1420"/>
+      <unit id="org.objenesis" version="2.6.0.v20180420-1519"/>
+      <unit id="org.objenesis.source" version="2.6.0.v20180420-1519"/>
       <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"/>
+      <unit id="org.tukaani.xz" version="1.8.0.v20180207-1613"/>
+      <unit id="org.tukaani.xz.source" version="1.8.0.v20180207-1613"/>
+      <repository location="https://download.eclipse.org/tools/orbit/downloads/drops/R20190827152740/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.10.tpd b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.10.tpd
index fad2e92..8d0df4f 100644
--- a/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.10.tpd
+++ b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.10.tpd
@@ -1,7 +1,7 @@
 target "jgit-4.10" with source configurePhase
 
-include "projects/jetty-9.4.14.tpd"
-include "orbit/R20190602212107-2019-06.tpd"
+include "projects/jetty-9.4.20.tpd"
+include "orbit/R20190827152740-2019-09.tpd"
 
 location "https://download.eclipse.org/releases/2018-12/" {
 	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
index 4be2f46..76fb1ef 100644
--- 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
@@ -1,28 +1,44 @@
 <?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="1638580694">
+<target name="jgit-4.11" sequenceNumber="1638608437">
   <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="https://archive.eclipse.org/jetty/updates/jetty-bundles-9.x/jetty-bundles-9.x/9.4.14.v20181114"/>
+      <unit id="org.eclipse.jetty.client" version="9.4.20.v20190813"/>
+      <unit id="org.eclipse.jetty.client.source" version="9.4.20.v20190813"/>
+      <unit id="org.eclipse.jetty.continuation" version="9.4.20.v20190813"/>
+      <unit id="org.eclipse.jetty.continuation.source" version="9.4.20.v20190813"/>
+      <unit id="org.eclipse.jetty.http" version="9.4.20.v20190813"/>
+      <unit id="org.eclipse.jetty.http.source" version="9.4.20.v20190813"/>
+      <unit id="org.eclipse.jetty.io" version="9.4.20.v20190813"/>
+      <unit id="org.eclipse.jetty.io.source" version="9.4.20.v20190813"/>
+      <unit id="org.eclipse.jetty.security" version="9.4.20.v20190813"/>
+      <unit id="org.eclipse.jetty.security.source" version="9.4.20.v20190813"/>
+      <unit id="org.eclipse.jetty.server" version="9.4.20.v20190813"/>
+      <unit id="org.eclipse.jetty.server.source" version="9.4.20.v20190813"/>
+      <unit id="org.eclipse.jetty.servlet" version="9.4.20.v20190813"/>
+      <unit id="org.eclipse.jetty.servlet.source" version="9.4.20.v20190813"/>
+      <unit id="org.eclipse.jetty.util" version="9.4.20.v20190813"/>
+      <unit id="org.eclipse.jetty.util.source" version="9.4.20.v20190813"/>
+      <repository id="jetty-9.4.20" location="https://archive.eclipse.org/jetty/updates/jetty-bundles-9.x/jetty-bundles-9.x/9.4.20.v20190813/"/>
     </location>
     <location includeMode="slicer" includeAllPlatforms="false" includeSource="true" includeConfigurePhase="true" type="InstallableUnit">
+      <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="com.jcraft.jzlib" version="1.1.1.v201205102305"/>
+      <unit id="com.jcraft.jzlib.source" version="1.1.1.v201205102305"/>
+      <unit id="javaewah" version="1.1.6.v20160919-1400"/>
+      <unit id="javaewah.source" version="1.1.6.v20160919-1400"/>
+      <unit id="javax.servlet" version="3.1.0.v201410161800"/>
+      <unit id="javax.servlet.source" version="3.1.0.v201410161800"/>
+      <unit id="net.bytebuddy.byte-buddy" 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="net.bytebuddy.byte-buddy.source" version="1.9.0.v20181107-1410"/>
+      <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.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"/>
@@ -37,52 +53,36 @@
       <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.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"/>
       <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.kohsuke.args4j" version="2.33.0.v20160323-2218"/>
+      <unit id="org.kohsuke.args4j.source" version="2.33.0.v20160323-2218"/>
+      <unit id="org.mockito" version="2.23.0.v20190527-1420"/>
+      <unit id="org.mockito.source" version="2.23.0.v20190527-1420"/>
+      <unit id="org.objenesis" version="2.6.0.v20180420-1519"/>
+      <unit id="org.objenesis.source" version="2.6.0.v20180420-1519"/>
       <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"/>
+      <unit id="org.tukaani.xz" version="1.8.0.v20180207-1613"/>
+      <unit id="org.tukaani.xz.source" version="1.8.0.v20180207-1613"/>
+      <repository location="https://download.eclipse.org/tools/orbit/downloads/drops/R20190827152740/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.tpd b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.11.tpd
index 0864e76..92eba15 100644
--- 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
@@ -1,7 +1,7 @@
 target "jgit-4.11" with source configurePhase
 
-include "projects/jetty-9.4.14.tpd"
-include "orbit/R20190602212107-2019-06.tpd"
+include "projects/jetty-9.4.20.tpd"
+include "orbit/R20190827152740-2019-09.tpd"
 
 location "https://download.eclipse.org/releases/2019-03/" {
 	org.eclipse.osgi lazy
diff --git a/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.12.target b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.12.target
index 34ffd45..8279a30 100644
--- a/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.12.target
+++ b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.12.target
@@ -1,28 +1,44 @@
 <?xml version="1.0" encoding="UTF-8" standalone="no"?>
 <?pde?>
 <!-- generated with https://github.com/eclipse-cbi/targetplatform-dsl -->
-<target name="jgit-4.12" sequenceNumber="1638580694">
+<target name="jgit-4.12" sequenceNumber="1638608437">
   <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="https://archive.eclipse.org/jetty/updates/jetty-bundles-9.x/jetty-bundles-9.x/9.4.14.v20181114"/>
+      <unit id="org.eclipse.jetty.client" version="9.4.20.v20190813"/>
+      <unit id="org.eclipse.jetty.client.source" version="9.4.20.v20190813"/>
+      <unit id="org.eclipse.jetty.continuation" version="9.4.20.v20190813"/>
+      <unit id="org.eclipse.jetty.continuation.source" version="9.4.20.v20190813"/>
+      <unit id="org.eclipse.jetty.http" version="9.4.20.v20190813"/>
+      <unit id="org.eclipse.jetty.http.source" version="9.4.20.v20190813"/>
+      <unit id="org.eclipse.jetty.io" version="9.4.20.v20190813"/>
+      <unit id="org.eclipse.jetty.io.source" version="9.4.20.v20190813"/>
+      <unit id="org.eclipse.jetty.security" version="9.4.20.v20190813"/>
+      <unit id="org.eclipse.jetty.security.source" version="9.4.20.v20190813"/>
+      <unit id="org.eclipse.jetty.server" version="9.4.20.v20190813"/>
+      <unit id="org.eclipse.jetty.server.source" version="9.4.20.v20190813"/>
+      <unit id="org.eclipse.jetty.servlet" version="9.4.20.v20190813"/>
+      <unit id="org.eclipse.jetty.servlet.source" version="9.4.20.v20190813"/>
+      <unit id="org.eclipse.jetty.util" version="9.4.20.v20190813"/>
+      <unit id="org.eclipse.jetty.util.source" version="9.4.20.v20190813"/>
+      <repository id="jetty-9.4.20" location="https://archive.eclipse.org/jetty/updates/jetty-bundles-9.x/jetty-bundles-9.x/9.4.20.v20190813/"/>
     </location>
     <location includeMode="slicer" includeAllPlatforms="false" includeSource="true" includeConfigurePhase="true" type="InstallableUnit">
+      <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="com.jcraft.jzlib" version="1.1.1.v201205102305"/>
+      <unit id="com.jcraft.jzlib.source" version="1.1.1.v201205102305"/>
+      <unit id="javaewah" version="1.1.6.v20160919-1400"/>
+      <unit id="javaewah.source" version="1.1.6.v20160919-1400"/>
+      <unit id="javax.servlet" version="3.1.0.v201410161800"/>
+      <unit id="javax.servlet.source" version="3.1.0.v201410161800"/>
+      <unit id="net.bytebuddy.byte-buddy" 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="net.bytebuddy.byte-buddy.source" version="1.9.0.v20181107-1410"/>
+      <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.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"/>
@@ -37,52 +53,36 @@
       <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.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"/>
       <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.kohsuke.args4j" version="2.33.0.v20160323-2218"/>
+      <unit id="org.kohsuke.args4j.source" version="2.33.0.v20160323-2218"/>
+      <unit id="org.mockito" version="2.23.0.v20190527-1420"/>
+      <unit id="org.mockito.source" version="2.23.0.v20190527-1420"/>
+      <unit id="org.objenesis" version="2.6.0.v20180420-1519"/>
+      <unit id="org.objenesis.source" version="2.6.0.v20180420-1519"/>
       <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"/>
+      <unit id="org.tukaani.xz" version="1.8.0.v20180207-1613"/>
+      <unit id="org.tukaani.xz.source" version="1.8.0.v20180207-1613"/>
+      <repository location="https://download.eclipse.org/tools/orbit/downloads/drops/R20190827152740/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.12.tpd b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.12.tpd
index cff6026..36d7110 100644
--- a/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.12.tpd
+++ b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.12.tpd
@@ -1,7 +1,7 @@
 target "jgit-4.12" with source configurePhase
 
-include "projects/jetty-9.4.14.tpd"
-include "orbit/R20190602212107-2019-06.tpd"
+include "projects/jetty-9.4.20.tpd"
+include "orbit/R20190827152740-2019-09.tpd"
 
 location "https://download.eclipse.org/releases/2019-06/" {
 	org.eclipse.osgi lazy
diff --git a/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.13.target b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.13.target
new file mode 100644
index 0000000..5c7c025
--- /dev/null
+++ b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.13.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.13" sequenceNumber="1638608439">
+  <locations>
+    <location includeMode="slicer" includeAllPlatforms="false" includeSource="true" includeConfigurePhase="true" type="InstallableUnit">
+      <unit id="org.eclipse.jetty.client" version="9.4.20.v20190813"/>
+      <unit id="org.eclipse.jetty.client.source" version="9.4.20.v20190813"/>
+      <unit id="org.eclipse.jetty.continuation" version="9.4.20.v20190813"/>
+      <unit id="org.eclipse.jetty.continuation.source" version="9.4.20.v20190813"/>
+      <unit id="org.eclipse.jetty.http" version="9.4.20.v20190813"/>
+      <unit id="org.eclipse.jetty.http.source" version="9.4.20.v20190813"/>
+      <unit id="org.eclipse.jetty.io" version="9.4.20.v20190813"/>
+      <unit id="org.eclipse.jetty.io.source" version="9.4.20.v20190813"/>
+      <unit id="org.eclipse.jetty.security" version="9.4.20.v20190813"/>
+      <unit id="org.eclipse.jetty.security.source" version="9.4.20.v20190813"/>
+      <unit id="org.eclipse.jetty.server" version="9.4.20.v20190813"/>
+      <unit id="org.eclipse.jetty.server.source" version="9.4.20.v20190813"/>
+      <unit id="org.eclipse.jetty.servlet" version="9.4.20.v20190813"/>
+      <unit id="org.eclipse.jetty.servlet.source" version="9.4.20.v20190813"/>
+      <unit id="org.eclipse.jetty.util" version="9.4.20.v20190813"/>
+      <unit id="org.eclipse.jetty.util.source" version="9.4.20.v20190813"/>
+      <repository id="jetty-9.4.20" location="https://archive.eclipse.org/jetty/updates/jetty-bundles-9.x/jetty-bundles-9.x/9.4.20.v20190813/"/>
+    </location>
+    <location includeMode="slicer" includeAllPlatforms="false" includeSource="true" includeConfigurePhase="true" type="InstallableUnit">
+      <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="com.jcraft.jzlib" version="1.1.1.v201205102305"/>
+      <unit id="com.jcraft.jzlib.source" version="1.1.1.v201205102305"/>
+      <unit id="javaewah" version="1.1.6.v20160919-1400"/>
+      <unit id="javaewah.source" version="1.1.6.v20160919-1400"/>
+      <unit id="javax.servlet" version="3.1.0.v201410161800"/>
+      <unit id="javax.servlet.source" version="3.1.0.v201410161800"/>
+      <unit id="net.bytebuddy.byte-buddy" 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="net.bytebuddy.byte-buddy.source" version="1.9.0.v20181107-1410"/>
+      <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.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.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"/>
+      <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.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="org.junit" version="4.12.0.v201504281640"/>
+      <unit id="org.junit.source" version="4.12.0.v201504281640"/>
+      <unit id="org.kohsuke.args4j" version="2.33.0.v20160323-2218"/>
+      <unit id="org.kohsuke.args4j.source" version="2.33.0.v20160323-2218"/>
+      <unit id="org.mockito" version="2.23.0.v20190527-1420"/>
+      <unit id="org.mockito.source" version="2.23.0.v20190527-1420"/>
+      <unit id="org.objenesis" version="2.6.0.v20180420-1519"/>
+      <unit id="org.objenesis.source" version="2.6.0.v20180420-1519"/>
+      <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="org.tukaani.xz" version="1.8.0.v20180207-1613"/>
+      <unit id="org.tukaani.xz.source" version="1.8.0.v20180207-1613"/>
+      <repository location="https://download.eclipse.org/tools/orbit/downloads/drops/R20190827152740/repository"/>
+    </location>
+    <location includeMode="slicer" includeAllPlatforms="false" includeSource="true" includeConfigurePhase="true" type="InstallableUnit">
+      <unit id="org.eclipse.osgi" version="0.0.0"/>
+      <repository location="https://download.eclipse.org/releases/2019-09/"/>
+    </location>
+  </locations>
+</target>
diff --git a/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.13.tpd b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.13.tpd
new file mode 100644
index 0000000..7eb4649
--- /dev/null
+++ b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.13.tpd
@@ -0,0 +1,8 @@
+target "jgit-4.13" with source configurePhase
+
+include "projects/jetty-9.4.20.tpd"
+include "orbit/R20190827152740-2019-09.tpd"
+
+location "https://download.eclipse.org/releases/2019-09/" {
+	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 489b01c..72a9c97 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,28 +1,44 @@
 <?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="1638580694">
+<target name="jgit-4.6" sequenceNumber="1638608437">
   <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="https://archive.eclipse.org/jetty/updates/jetty-bundles-9.x/jetty-bundles-9.x/9.4.14.v20181114"/>
+      <unit id="org.eclipse.jetty.client" version="9.4.20.v20190813"/>
+      <unit id="org.eclipse.jetty.client.source" version="9.4.20.v20190813"/>
+      <unit id="org.eclipse.jetty.continuation" version="9.4.20.v20190813"/>
+      <unit id="org.eclipse.jetty.continuation.source" version="9.4.20.v20190813"/>
+      <unit id="org.eclipse.jetty.http" version="9.4.20.v20190813"/>
+      <unit id="org.eclipse.jetty.http.source" version="9.4.20.v20190813"/>
+      <unit id="org.eclipse.jetty.io" version="9.4.20.v20190813"/>
+      <unit id="org.eclipse.jetty.io.source" version="9.4.20.v20190813"/>
+      <unit id="org.eclipse.jetty.security" version="9.4.20.v20190813"/>
+      <unit id="org.eclipse.jetty.security.source" version="9.4.20.v20190813"/>
+      <unit id="org.eclipse.jetty.server" version="9.4.20.v20190813"/>
+      <unit id="org.eclipse.jetty.server.source" version="9.4.20.v20190813"/>
+      <unit id="org.eclipse.jetty.servlet" version="9.4.20.v20190813"/>
+      <unit id="org.eclipse.jetty.servlet.source" version="9.4.20.v20190813"/>
+      <unit id="org.eclipse.jetty.util" version="9.4.20.v20190813"/>
+      <unit id="org.eclipse.jetty.util.source" version="9.4.20.v20190813"/>
+      <repository id="jetty-9.4.20" location="https://archive.eclipse.org/jetty/updates/jetty-bundles-9.x/jetty-bundles-9.x/9.4.20.v20190813/"/>
     </location>
     <location includeMode="slicer" includeAllPlatforms="false" includeSource="true" includeConfigurePhase="true" type="InstallableUnit">
+      <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="com.jcraft.jzlib" version="1.1.1.v201205102305"/>
+      <unit id="com.jcraft.jzlib.source" version="1.1.1.v201205102305"/>
+      <unit id="javaewah" version="1.1.6.v20160919-1400"/>
+      <unit id="javaewah.source" version="1.1.6.v20160919-1400"/>
+      <unit id="javax.servlet" version="3.1.0.v201410161800"/>
+      <unit id="javax.servlet.source" version="3.1.0.v201410161800"/>
+      <unit id="net.bytebuddy.byte-buddy" 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="net.bytebuddy.byte-buddy.source" version="1.9.0.v20181107-1410"/>
+      <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.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"/>
@@ -37,52 +53,36 @@
       <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.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"/>
       <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.kohsuke.args4j" version="2.33.0.v20160323-2218"/>
+      <unit id="org.kohsuke.args4j.source" version="2.33.0.v20160323-2218"/>
+      <unit id="org.mockito" version="2.23.0.v20190527-1420"/>
+      <unit id="org.mockito.source" version="2.23.0.v20190527-1420"/>
+      <unit id="org.objenesis" version="2.6.0.v20180420-1519"/>
+      <unit id="org.objenesis.source" version="2.6.0.v20180420-1519"/>
       <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"/>
+      <unit id="org.tukaani.xz" version="1.8.0.v20180207-1613"/>
+      <unit id="org.tukaani.xz.source" version="1.8.0.v20180207-1613"/>
+      <repository location="https://download.eclipse.org/tools/orbit/downloads/drops/R20190827152740/repository"/>
     </location>
     <location includeMode="slicer" includeAllPlatforms="false" includeSource="true" includeConfigurePhase="true" type="InstallableUnit">
       <unit id="org.eclipse.osgi" version="0.0.0"/>
diff --git a/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.6.tpd b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.6.tpd
index a43593f..a88a927 100644
--- a/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.6.tpd
+++ b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.6.tpd
@@ -1,7 +1,7 @@
 target "jgit-4.6" with source configurePhase
 
-include "projects/jetty-9.4.14.tpd"
-include "orbit/R20190602212107-2019-06.tpd"
+include "projects/jetty-9.4.20.tpd"
+include "orbit/R20190827152740-2019-09.tpd"
 
 location "https://download.eclipse.org/releases/neon/" {
 	org.eclipse.osgi lazy
diff --git a/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.7.target b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.7.target
index 627a83a..a43101a 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,28 +1,44 @@
 <?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="1638580694">
+<target name="jgit-4.7" sequenceNumber="1638608437">
   <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="https://archive.eclipse.org/jetty/updates/jetty-bundles-9.x/jetty-bundles-9.x/9.4.14.v20181114"/>
+      <unit id="org.eclipse.jetty.client" version="9.4.20.v20190813"/>
+      <unit id="org.eclipse.jetty.client.source" version="9.4.20.v20190813"/>
+      <unit id="org.eclipse.jetty.continuation" version="9.4.20.v20190813"/>
+      <unit id="org.eclipse.jetty.continuation.source" version="9.4.20.v20190813"/>
+      <unit id="org.eclipse.jetty.http" version="9.4.20.v20190813"/>
+      <unit id="org.eclipse.jetty.http.source" version="9.4.20.v20190813"/>
+      <unit id="org.eclipse.jetty.io" version="9.4.20.v20190813"/>
+      <unit id="org.eclipse.jetty.io.source" version="9.4.20.v20190813"/>
+      <unit id="org.eclipse.jetty.security" version="9.4.20.v20190813"/>
+      <unit id="org.eclipse.jetty.security.source" version="9.4.20.v20190813"/>
+      <unit id="org.eclipse.jetty.server" version="9.4.20.v20190813"/>
+      <unit id="org.eclipse.jetty.server.source" version="9.4.20.v20190813"/>
+      <unit id="org.eclipse.jetty.servlet" version="9.4.20.v20190813"/>
+      <unit id="org.eclipse.jetty.servlet.source" version="9.4.20.v20190813"/>
+      <unit id="org.eclipse.jetty.util" version="9.4.20.v20190813"/>
+      <unit id="org.eclipse.jetty.util.source" version="9.4.20.v20190813"/>
+      <repository id="jetty-9.4.20" location="https://archive.eclipse.org/jetty/updates/jetty-bundles-9.x/jetty-bundles-9.x/9.4.20.v20190813/"/>
     </location>
     <location includeMode="slicer" includeAllPlatforms="false" includeSource="true" includeConfigurePhase="true" type="InstallableUnit">
+      <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="com.jcraft.jzlib" version="1.1.1.v201205102305"/>
+      <unit id="com.jcraft.jzlib.source" version="1.1.1.v201205102305"/>
+      <unit id="javaewah" version="1.1.6.v20160919-1400"/>
+      <unit id="javaewah.source" version="1.1.6.v20160919-1400"/>
+      <unit id="javax.servlet" version="3.1.0.v201410161800"/>
+      <unit id="javax.servlet.source" version="3.1.0.v201410161800"/>
+      <unit id="net.bytebuddy.byte-buddy" 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="net.bytebuddy.byte-buddy.source" version="1.9.0.v20181107-1410"/>
+      <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.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"/>
@@ -37,52 +53,36 @@
       <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.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"/>
       <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.kohsuke.args4j" version="2.33.0.v20160323-2218"/>
+      <unit id="org.kohsuke.args4j.source" version="2.33.0.v20160323-2218"/>
+      <unit id="org.mockito" version="2.23.0.v20190527-1420"/>
+      <unit id="org.mockito.source" version="2.23.0.v20190527-1420"/>
+      <unit id="org.objenesis" version="2.6.0.v20180420-1519"/>
+      <unit id="org.objenesis.source" version="2.6.0.v20180420-1519"/>
       <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"/>
+      <unit id="org.tukaani.xz" version="1.8.0.v20180207-1613"/>
+      <unit id="org.tukaani.xz.source" version="1.8.0.v20180207-1613"/>
+      <repository location="https://download.eclipse.org/tools/orbit/downloads/drops/R20190827152740/repository"/>
     </location>
     <location includeMode="slicer" includeAllPlatforms="false" includeSource="true" includeConfigurePhase="true" type="InstallableUnit">
       <unit id="org.eclipse.osgi" version="0.0.0"/>
diff --git a/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.7.tpd b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.7.tpd
index 32835ca..38ae2b3 100644
--- a/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.7.tpd
+++ b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.7.tpd
@@ -1,7 +1,7 @@
 target "jgit-4.7" with source configurePhase
 
-include "projects/jetty-9.4.14.tpd"
-include "orbit/R20190602212107-2019-06.tpd"
+include "projects/jetty-9.4.20.tpd"
+include "orbit/R20190827152740-2019-09.tpd"
 
 location "https://download.eclipse.org/releases/oxygen/" {
 	org.eclipse.osgi lazy
diff --git a/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.8.target b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.8.target
index dc45c7d..cabc810 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,28 +1,44 @@
 <?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="1638580694">
+<target name="jgit-4.8" sequenceNumber="1638608437">
   <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="https://archive.eclipse.org/jetty/updates/jetty-bundles-9.x/jetty-bundles-9.x/9.4.14.v20181114"/>
+      <unit id="org.eclipse.jetty.client" version="9.4.20.v20190813"/>
+      <unit id="org.eclipse.jetty.client.source" version="9.4.20.v20190813"/>
+      <unit id="org.eclipse.jetty.continuation" version="9.4.20.v20190813"/>
+      <unit id="org.eclipse.jetty.continuation.source" version="9.4.20.v20190813"/>
+      <unit id="org.eclipse.jetty.http" version="9.4.20.v20190813"/>
+      <unit id="org.eclipse.jetty.http.source" version="9.4.20.v20190813"/>
+      <unit id="org.eclipse.jetty.io" version="9.4.20.v20190813"/>
+      <unit id="org.eclipse.jetty.io.source" version="9.4.20.v20190813"/>
+      <unit id="org.eclipse.jetty.security" version="9.4.20.v20190813"/>
+      <unit id="org.eclipse.jetty.security.source" version="9.4.20.v20190813"/>
+      <unit id="org.eclipse.jetty.server" version="9.4.20.v20190813"/>
+      <unit id="org.eclipse.jetty.server.source" version="9.4.20.v20190813"/>
+      <unit id="org.eclipse.jetty.servlet" version="9.4.20.v20190813"/>
+      <unit id="org.eclipse.jetty.servlet.source" version="9.4.20.v20190813"/>
+      <unit id="org.eclipse.jetty.util" version="9.4.20.v20190813"/>
+      <unit id="org.eclipse.jetty.util.source" version="9.4.20.v20190813"/>
+      <repository id="jetty-9.4.20" location="https://archive.eclipse.org/jetty/updates/jetty-bundles-9.x/jetty-bundles-9.x/9.4.20.v20190813/"/>
     </location>
     <location includeMode="slicer" includeAllPlatforms="false" includeSource="true" includeConfigurePhase="true" type="InstallableUnit">
+      <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="com.jcraft.jzlib" version="1.1.1.v201205102305"/>
+      <unit id="com.jcraft.jzlib.source" version="1.1.1.v201205102305"/>
+      <unit id="javaewah" version="1.1.6.v20160919-1400"/>
+      <unit id="javaewah.source" version="1.1.6.v20160919-1400"/>
+      <unit id="javax.servlet" version="3.1.0.v201410161800"/>
+      <unit id="javax.servlet.source" version="3.1.0.v201410161800"/>
+      <unit id="net.bytebuddy.byte-buddy" 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="net.bytebuddy.byte-buddy.source" version="1.9.0.v20181107-1410"/>
+      <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.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"/>
@@ -37,52 +53,36 @@
       <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.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"/>
       <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.kohsuke.args4j" version="2.33.0.v20160323-2218"/>
+      <unit id="org.kohsuke.args4j.source" version="2.33.0.v20160323-2218"/>
+      <unit id="org.mockito" version="2.23.0.v20190527-1420"/>
+      <unit id="org.mockito.source" version="2.23.0.v20190527-1420"/>
+      <unit id="org.objenesis" version="2.6.0.v20180420-1519"/>
+      <unit id="org.objenesis.source" version="2.6.0.v20180420-1519"/>
       <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"/>
+      <unit id="org.tukaani.xz" version="1.8.0.v20180207-1613"/>
+      <unit id="org.tukaani.xz.source" version="1.8.0.v20180207-1613"/>
+      <repository location="https://download.eclipse.org/tools/orbit/downloads/drops/R20190827152740/repository"/>
     </location>
     <location includeMode="slicer" includeAllPlatforms="false" includeSource="true" includeConfigurePhase="true" type="InstallableUnit">
       <unit id="org.eclipse.osgi" version="0.0.0"/>
diff --git a/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.8.tpd b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.8.tpd
index c11bc62..075525e 100644
--- a/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.8.tpd
+++ b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.8.tpd
@@ -1,7 +1,7 @@
 target "jgit-4.8" with source configurePhase
 
-include "projects/jetty-9.4.14.tpd"
-include "orbit/R20190602212107-2019-06.tpd"
+include "projects/jetty-9.4.20.tpd"
+include "orbit/R20190827152740-2019-09.tpd"
 
 location "https://download.eclipse.org/releases/photon/" {
 	org.eclipse.osgi lazy
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 040c1d1..3b2f005 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,28 +1,44 @@
 <?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="1638580694">
+<target name="jgit-4.9" sequenceNumber="1638608437">
   <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="https://archive.eclipse.org/jetty/updates/jetty-bundles-9.x/jetty-bundles-9.x/9.4.14.v20181114"/>
+      <unit id="org.eclipse.jetty.client" version="9.4.20.v20190813"/>
+      <unit id="org.eclipse.jetty.client.source" version="9.4.20.v20190813"/>
+      <unit id="org.eclipse.jetty.continuation" version="9.4.20.v20190813"/>
+      <unit id="org.eclipse.jetty.continuation.source" version="9.4.20.v20190813"/>
+      <unit id="org.eclipse.jetty.http" version="9.4.20.v20190813"/>
+      <unit id="org.eclipse.jetty.http.source" version="9.4.20.v20190813"/>
+      <unit id="org.eclipse.jetty.io" version="9.4.20.v20190813"/>
+      <unit id="org.eclipse.jetty.io.source" version="9.4.20.v20190813"/>
+      <unit id="org.eclipse.jetty.security" version="9.4.20.v20190813"/>
+      <unit id="org.eclipse.jetty.security.source" version="9.4.20.v20190813"/>
+      <unit id="org.eclipse.jetty.server" version="9.4.20.v20190813"/>
+      <unit id="org.eclipse.jetty.server.source" version="9.4.20.v20190813"/>
+      <unit id="org.eclipse.jetty.servlet" version="9.4.20.v20190813"/>
+      <unit id="org.eclipse.jetty.servlet.source" version="9.4.20.v20190813"/>
+      <unit id="org.eclipse.jetty.util" version="9.4.20.v20190813"/>
+      <unit id="org.eclipse.jetty.util.source" version="9.4.20.v20190813"/>
+      <repository id="jetty-9.4.20" location="https://archive.eclipse.org/jetty/updates/jetty-bundles-9.x/jetty-bundles-9.x/9.4.20.v20190813/"/>
     </location>
     <location includeMode="slicer" includeAllPlatforms="false" includeSource="true" includeConfigurePhase="true" type="InstallableUnit">
+      <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="com.jcraft.jzlib" version="1.1.1.v201205102305"/>
+      <unit id="com.jcraft.jzlib.source" version="1.1.1.v201205102305"/>
+      <unit id="javaewah" version="1.1.6.v20160919-1400"/>
+      <unit id="javaewah.source" version="1.1.6.v20160919-1400"/>
+      <unit id="javax.servlet" version="3.1.0.v201410161800"/>
+      <unit id="javax.servlet.source" version="3.1.0.v201410161800"/>
+      <unit id="net.bytebuddy.byte-buddy" 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="net.bytebuddy.byte-buddy.source" version="1.9.0.v20181107-1410"/>
+      <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.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"/>
@@ -37,52 +53,36 @@
       <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.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"/>
       <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.kohsuke.args4j" version="2.33.0.v20160323-2218"/>
+      <unit id="org.kohsuke.args4j.source" version="2.33.0.v20160323-2218"/>
+      <unit id="org.mockito" version="2.23.0.v20190527-1420"/>
+      <unit id="org.mockito.source" version="2.23.0.v20190527-1420"/>
+      <unit id="org.objenesis" version="2.6.0.v20180420-1519"/>
+      <unit id="org.objenesis.source" version="2.6.0.v20180420-1519"/>
       <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"/>
+      <unit id="org.tukaani.xz" version="1.8.0.v20180207-1613"/>
+      <unit id="org.tukaani.xz.source" version="1.8.0.v20180207-1613"/>
+      <repository location="https://download.eclipse.org/tools/orbit/downloads/drops/R20190827152740/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.tpd b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.9.tpd
index a2658b4..36894cf 100644
--- a/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.9.tpd
+++ b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.9.tpd
@@ -1,7 +1,7 @@
 target "jgit-4.9" with source configurePhase
 
-include "projects/jetty-9.4.14.tpd"
-include "orbit/R20190602212107-2019-06.tpd"
+include "projects/jetty-9.4.20.tpd"
+include "orbit/R20190827152740-2019-09.tpd"
 
 location "https://download.eclipse.org/releases/2018-09/" {
 	org.eclipse.osgi lazy
diff --git a/org.eclipse.jgit.packaging/org.eclipse.jgit.target/orbit/R20180206163158-Oxygen.tpd b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/orbit/R20180206163158-Oxygen.tpd
deleted file mode 100644
index 91c66db..0000000
--- a/org.eclipse.jgit.packaging/org.eclipse.jgit.target/orbit/R20180206163158-Oxygen.tpd
+++ /dev/null
@@ -1,46 +0,0 @@
-target "R20180206163158-Oxygen" with source configurePhase
-// see http://download.eclipse.org/tools/orbit/downloads/
-
-location "http://download.eclipse.org/tools/orbit/downloads/drops/R20180206163158/repository" {
-	org.apache.ant [1.9.6.v201510161327,1.9.6.v201510161327]
-	org.apache.ant.source [1.9.6.v201510161327,1.9.6.v201510161327]
-	org.apache.commons.codec [1.9.0.v20170208-1614,1.9.0.v20170208-1614]
-	org.apache.commons.codec.source [1.9.0.v20170208-1614,1.9.0.v20170208-1614]
-	org.apache.commons.compress [1.6.0.v201310281400,1.6.0.v201310281400]
-	org.apache.commons.compress.source [1.6.0.v201310281400,1.6.0.v201310281400]
-	org.apache.commons.logging [1.1.1.v201101211721,1.1.1.v201101211721]
-	org.apache.commons.logging.source [1.1.1.v201101211721,1.1.1.v201101211721]
-	org.apache.httpcomponents.httpcore [4.4.6.v20170210-0925,4.4.6.v20170210-0925]
-	org.apache.httpcomponents.httpcore.source [4.4.6.v20170210-0925,4.4.6.v20170210-0925]
-	org.apache.httpcomponents.httpclient [4.5.2.v20170210-0925,4.5.2.v20170210-0925]
-	org.apache.httpcomponents.httpclient.source [4.5.2.v20170210-0925,4.5.2.v20170210-0925]
-	org.apache.log4j [1.2.15.v201012070815,1.2.15.v201012070815]
-	org.apache.log4j.source [1.2.15.v201012070815,1.2.15.v201012070815]
-	org.kohsuke.args4j [2.33.0.v20160323-2218,2.33.0.v20160323-2218]
-	org.kohsuke.args4j.source [2.33.0.v20160323-2218,2.33.0.v20160323-2218]
-	org.hamcrest.core [1.3.0.v201303031735,1.3.0.v201303031735]
-	org.hamcrest.core.source [1.3.0.v201303031735,1.3.0.v201303031735]
-	org.hamcrest.library [1.3.0.v201505072020,1.3.0.v201505072020]
-	org.hamcrest.library.source [1.3.0.v201505072020,1.3.0.v201505072020]
-	javaewah [1.1.6.v20160919-1400,1.1.6.v20160919-1400]
-	javaewah.source [1.1.6.v20160919-1400,1.1.6.v20160919-1400]
-	org.objenesis [1.0.0.v201505121915,1.0.0.v201505121915]
-	org.objenesis.source [1.0.0.v201505121915,1.0.0.v201505121915]
-	org.mockito [1.8.4.v201303031500,1.8.4.v201303031500]
-	org.mockito.source [1.8.4.v201303031500,1.8.4.v201303031500]
-	com.google.gson [2.2.4.v201311231704,2.2.4.v201311231704]
-	com.jcraft.jsch [0.1.54.v20170116-1932,0.1.54.v20170116-1932]
-	com.jcraft.jsch.source [0.1.54.v20170116-1932,0.1.54.v20170116-1932]
-	org.junit [4.12.0.v201504281640,4.12.0.v201504281640]
-	org.junit.source [4.12.0.v201504281640,4.12.0.v201504281640]
-	javax.servlet [3.1.0.v201410161800,3.1.0.v201410161800]
-	javax.servlet.source [3.1.0.v201410161800,3.1.0.v201410161800]
-	org.tukaani.xz [1.3.0.v201308270617,1.3.0.v201308270617]
-	org.tukaani.xz.source [1.3.0.v201308270617,1.3.0.v201308270617]
-	org.slf4j.api [1.7.2.v20121108-1250,1.7.2.v20121108-1250]
-	org.slf4j.api.source [1.7.2.v20121108-1250,1.7.2.v20121108-1250]
-	org.slf4j.impl.log4j12 [1.7.2.v20131105-2200,1.7.2.v20131105-2200]
-	org.slf4j.impl.log4j12.source [1.7.2.v20131105-2200,1.7.2.v20131105-2200]
-	com.jcraft.jzlib [1.1.1.v201205102305,1.1.1.v201205102305]
-	com.jcraft.jzlib.source [1.1.1.v201205102305,1.1.1.v201205102305]
-}
\ No newline at end of file
diff --git a/org.eclipse.jgit.packaging/org.eclipse.jgit.target/orbit/R20180606145124-Photon.tpd b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/orbit/R20180606145124-Photon.tpd
deleted file mode 100644
index ecec41d..0000000
--- a/org.eclipse.jgit.packaging/org.eclipse.jgit.target/orbit/R20180606145124-Photon.tpd
+++ /dev/null
@@ -1,48 +0,0 @@
-target "R20180606145124-Photon" with source configurePhase
-// see http://download.eclipse.org/tools/orbit/downloads/
-
-location "http://download.eclipse.org/tools/orbit/downloads/drops/R20180606145124/repository" {
-	org.apache.ant [1.9.6.v201510161327,1.9.6.v201510161327]
-	org.apache.ant.source [1.9.6.v201510161327,1.9.6.v201510161327]
-	org.apache.commons.codec [1.9.0.v20170208-1614,1.9.0.v20170208-1614]
-	org.apache.commons.codec.source [1.9.0.v20170208-1614,1.9.0.v20170208-1614]
-	org.apache.commons.compress [1.15.0.v20180119-1613,1.15.0.v20180119-1613]
-	org.apache.commons.compress.source [1.15.0.v20180119-1613,1.15.0.v20180119-1613s]
-	org.apache.commons.logging [1.1.1.v201101211721,1.1.1.v201101211721]
-	org.apache.commons.logging.source [1.1.1.v201101211721,1.1.1.v201101211721]
-	org.apache.httpcomponents.httpcore [4.4.6.v20170210-0925,4.4.6.v20170210-0925]
-	org.apache.httpcomponents.httpcore.source [4.4.6.v20170210-0925,4.4.6.v20170210-0925]
-	org.apache.httpcomponents.httpclient [4.5.2.v20180410-1551,4.5.2.v20180410-1551]
-	org.apache.httpcomponents.httpclient.source [4.5.2.v20180410-1551,4.5.2.v20180410-1551]
-	org.apache.log4j [1.2.15.v201012070815,1.2.15.v201012070815]
-	org.apache.log4j.source [1.2.15.v201012070815,1.2.15.v201012070815]
-	org.kohsuke.args4j [2.33.0.v20160323-2218,2.33.0.v20160323-2218]
-	org.kohsuke.args4j.source [2.33.0.v20160323-2218,2.33.0.v20160323-2218]
-	org.hamcrest [1.1.0.v20090501071000,1.1.0.v20090501071000]
-	org.hamcrest.core [1.3.0.v20180420-1519,1.3.0.v20180420-1519]
-	org.hamcrest.core.source [1.3.0.v20180420-1519,1.3.0.v20180420-1519]
-	org.hamcrest.library [1.3.0.v20180524-2246,1.3.0.v20180524-2246]
-	org.hamcrest.library.source [1.3.0.v20180524-2246,1.3.0.v20180524-2246]
-	javaewah [1.1.6.v20160919-1400,1.1.6.v20160919-1400]
-	javaewah.source [1.1.6.v20160919-1400,1.1.6.v20160919-1400]
-	org.objenesis [1.0.0.v201505121915,1.0.0.v201505121915]
-	org.objenesis.source [1.0.0.v201505121915,1.0.0.v201505121915]
-	org.mockito [1.8.4.v201303031500,1.8.4.v201303031500]
-	org.mockito.source [1.8.4.v201303031500,1.8.4.v201303031500]
-	com.google.gson [2.8.2.v20180104-1110,2.8.2.v20180104-1110]
-	com.google.gson.source [2.8.2.v20180104-1110,2.8.2.v20180104-1110]
-	com.jcraft.jsch [0.1.54.v20170116-1932,0.1.54.v20170116-1932]
-	com.jcraft.jsch.source [0.1.54.v20170116-1932,0.1.54.v20170116-1932]
-	org.junit [4.12.0.v201504281640,4.12.0.v201504281640]
-	org.junit.source [4.12.0.v201504281640,4.12.0.v201504281640]
-	javax.servlet [3.1.0.v201410161800,3.1.0.v201410161800]
-	javax.servlet.source [3.1.0.v201410161800,3.1.0.v201410161800]
-	org.tukaani.xz [1.6.0.v20170629-1752,1.6.0.v20170629-1752]
-	org.tukaani.xz.source [1.6.0.v20170629-1752,1.6.0.v20170629-1752]
-	org.slf4j.api [1.7.2.v20121108-1250,1.7.2.v20121108-1250]
-	org.slf4j.api.source [1.7.2.v20121108-1250,1.7.2.v20121108-1250]
-	org.slf4j.impl.log4j12 [1.7.2.v20131105-2200,1.7.2.v20131105-2200]
-	org.slf4j.impl.log4j12.source [1.7.2.v20131105-2200,1.7.2.v20131105-2200]
-	com.jcraft.jzlib [1.1.1.v201205102305,1.1.1.v201205102305]
-	com.jcraft.jzlib.source [1.1.1.v201205102305,1.1.1.v201205102305]
-}
diff --git a/org.eclipse.jgit.packaging/org.eclipse.jgit.target/orbit/R20180905201904-2018-09.tpd b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/orbit/R20180905201904-2018-09.tpd
deleted file mode 100644
index eaae99c..0000000
--- a/org.eclipse.jgit.packaging/org.eclipse.jgit.target/orbit/R20180905201904-2018-09.tpd
+++ /dev/null
@@ -1,48 +0,0 @@
-target "R20180905201904-2018-09" with source configurePhase
-// see http://download.eclipse.org/tools/orbit/downloads/
-
-location "http://download.eclipse.org/tools/orbit/downloads/drops/R20180905201904/repository" {
-	org.apache.ant [1.9.6.v201510161327,1.9.6.v201510161327]
-	org.apache.ant.source [1.9.6.v201510161327,1.9.6.v201510161327]
-	org.apache.commons.codec [1.10.0.v20180409-1845,1.10.0.v20180409-1845]
-	org.apache.commons.codec.source [1.10.0.v20180409-1845,1.10.0.v20180409-1845]
-	org.apache.commons.compress [1.15.0.v20180119-1613,1.15.0.v20180119-1613]
-	org.apache.commons.compress.source [1.15.0.v20180119-1613,1.15.0.v20180119-1613s]
-	org.apache.commons.logging [1.2.0.v20180409-1502,1.2.0.v20180409-1502]
-	org.apache.commons.logging.source [1.2.0.v20180409-1502,1.2.0.v20180409-1502]
-	org.apache.httpcomponents.httpclient [4.5.5.v20180409-1525,4.5.5.v20180409-1525]
-	org.apache.httpcomponents.httpclient.source [4.5.5.v20180409-1525,4.5.5.v20180409-1525]
-	org.apache.httpcomponents.httpcore [4.4.9.v20180409-1525,4.4.9.v20180409-1525]
-	org.apache.httpcomponents.httpcore.source [4.4.9.v20180409-1525,4.4.9.v20180409-1525]
-	org.apache.log4j [1.2.15.v201012070815,1.2.15.v201012070815]
-	org.apache.log4j.source [1.2.15.v201012070815,1.2.15.v201012070815]
-	org.kohsuke.args4j [2.33.0.v20160323-2218,2.33.0.v20160323-2218]
-	org.kohsuke.args4j.source [2.33.0.v20160323-2218,2.33.0.v20160323-2218]
-	org.hamcrest [1.1.0.v20090501071000,1.1.0.v20090501071000]
-	org.hamcrest.core [1.3.0.v20180420-1519,1.3.0.v20180420-1519]
-	org.hamcrest.core.source [1.3.0.v20180420-1519,1.3.0.v20180420-1519]
-	org.hamcrest.library [1.3.0.v20180524-2246,1.3.0.v20180524-2246]
-	org.hamcrest.library.source [1.3.0.v20180524-2246,1.3.0.v20180524-2246]
-	javaewah [1.1.6.v20160919-1400,1.1.6.v20160919-1400]
-	javaewah.source [1.1.6.v20160919-1400,1.1.6.v20160919-1400]
-	org.objenesis [1.0.0.v201505121915,1.0.0.v201505121915]
-	org.objenesis.source [1.0.0.v201505121915,1.0.0.v201505121915]
-	org.mockito [1.8.4.v201303031500,1.8.4.v201303031500]
-	org.mockito.source [1.8.4.v201303031500,1.8.4.v201303031500]
-	com.google.gson [2.8.2.v20180104-1110,2.8.2.v20180104-1110]
-	com.google.gson.source [2.8.2.v20180104-1110,2.8.2.v20180104-1110]
-	com.jcraft.jsch [0.1.54.v20170116-1932,0.1.54.v20170116-1932]
-	com.jcraft.jsch.source [0.1.54.v20170116-1932,0.1.54.v20170116-1932]
-	org.junit [4.12.0.v201504281640,4.12.0.v201504281640]
-	org.junit.source [4.12.0.v201504281640,4.12.0.v201504281640]
-	javax.servlet [3.1.0.v201410161800,3.1.0.v201410161800]
-	javax.servlet.source [3.1.0.v201410161800,3.1.0.v201410161800]
-	org.tukaani.xz [1.6.0.v20170629-1752,1.6.0.v20170629-1752]
-	org.tukaani.xz.source [1.6.0.v20170629-1752,1.6.0.v20170629-1752]
-	org.slf4j.api [1.7.2.v20121108-1250,1.7.2.v20121108-1250]
-	org.slf4j.api.source [1.7.2.v20121108-1250,1.7.2.v20121108-1250]
-	org.slf4j.impl.log4j12 [1.7.2.v20131105-2200,1.7.2.v20131105-2200]
-	org.slf4j.impl.log4j12.source [1.7.2.v20131105-2200,1.7.2.v20131105-2200]
-	com.jcraft.jzlib [1.1.1.v201205102305,1.1.1.v201205102305]
-	com.jcraft.jzlib.source [1.1.1.v201205102305,1.1.1.v201205102305]
-}
diff --git a/org.eclipse.jgit.packaging/org.eclipse.jgit.target/orbit/R20181128170323-2018-12.tpd b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/orbit/R20181128170323-2018-12.tpd
deleted file mode 100644
index fd69da2..0000000
--- a/org.eclipse.jgit.packaging/org.eclipse.jgit.target/orbit/R20181128170323-2018-12.tpd
+++ /dev/null
@@ -1,64 +0,0 @@
-target "R20181128170323-2018-12" with source configurePhase
-// see http://download.eclipse.org/tools/orbit/downloads/
-
-location "http://download.eclipse.org/tools/orbit/downloads/drops/R20181128170323/repository" {
-	org.apache.ant [1.10.5.v20180808-0324,1.10.5.v20180808-0324]
-	org.apache.ant.source [1.10.5.v20180808-0324,1.10.5.v20180808-0324]
-	org.apache.commons.codec [1.10.0.v20180409-1845,1.10.0.v20180409-1845]
-	org.apache.commons.codec.source [1.10.0.v20180409-1845,1.10.0.v20180409-1845]
-	org.apache.commons.compress [1.18.0.v20181121-2221,1.18.0.v20181121-2221]
-	org.apache.commons.compress.source [1.18.0.v20181121-2221,1.18.0.v20181121-2221]
-	org.apache.commons.logging [1.2.0.v20180409-1502,1.2.0.v20180409-1502]
-	org.apache.commons.logging.source [1.2.0.v20180409-1502,1.2.0.v20180409-1502]
-	org.apache.httpcomponents.httpclient [4.5.5.v20180409-1525,4.5.5.v20180409-1525]
-	org.apache.httpcomponents.httpclient.source [4.5.5.v20180409-1525,4.5.5.v20180409-1525]
-	org.apache.httpcomponents.httpcore [4.4.9.v20180409-1525,4.4.9.v20180409-1525]
-	org.apache.httpcomponents.httpcore.source [4.4.9.v20180409-1525,4.4.9.v20180409-1525]
-	org.apache.log4j [1.2.15.v201012070815,1.2.15.v201012070815]
-	org.apache.log4j.source [1.2.15.v201012070815,1.2.15.v201012070815]
-	org.bouncycastle.bcpg [1.60.0.v20181107-1520,1.60.0.v20181107-1520]
-	org.bouncycastle.bcpg.source [1.60.0.v20181107-1520,1.60.0.v20181107-1520]
-	org.bouncycastle.bcpkix [1.60.0.v20181107-1520,1.60.0.v20181107-1520]
-	org.bouncycastle.bcpkix.source [1.60.0.v20181107-1520,1.60.0.v20181107-1520]
-	org.bouncycastle.bcprov [1.60.0.v20181107-1520,1.60.0.v20181107-1520]
-	org.bouncycastle.bcprov.source [1.60.0.v20181107-1520,1.60.0.v20181107-1520]
-	org.kohsuke.args4j [2.33.0.v20160323-2218,2.33.0.v20160323-2218]
-	org.kohsuke.args4j.source [2.33.0.v20160323-2218,2.33.0.v20160323-2218]
-	org.hamcrest [1.1.0.v20090501071000,1.1.0.v20090501071000]
-	org.hamcrest.core [1.3.0.v20180420-1519,1.3.0.v20180420-1519]
-	org.hamcrest.core.source [1.3.0.v20180420-1519,1.3.0.v20180420-1519]
-	org.hamcrest.library [1.3.0.v20180524-2246,1.3.0.v20180524-2246]
-	org.hamcrest.library.source [1.3.0.v20180524-2246,1.3.0.v20180524-2246]
-	javaewah [1.1.6.v20160919-1400,1.1.6.v20160919-1400]
-	javaewah.source [1.1.6.v20160919-1400,1.1.6.v20160919-1400]
-	org.objenesis [2.6.0.v20180420-1519,2.6.0.v20180420-1519]
-	org.objenesis.source [2.6.0.v20180420-1519,2.6.0.v20180420-1519]
-	org.mockito [2.13.0.v20180426-1843,2.13.0.v20180426-1843]
-	org.mockito.source [2.13.0.v20180426-1843,2.13.0.v20180426-1843]
-	net.bytebuddy.byte-buddy [1.7.9.v20180420-1519,1.7.9.v20180420-1519]
-	net.bytebuddy.byte-buddy.source [1.7.9.v20180420-1519,1.7.9.v20180420-1519]
-	net.bytebuddy.byte-buddy-agent [1.7.9.v20180420-1519,1.7.9.v20180420-1519]
-	net.bytebuddy.byte-buddy-agent.source [1.7.9.v20180420-1519,1.7.9.v20180420-1519]
-	com.google.gson [2.8.2.v20180104-1110,2.8.2.v20180104-1110]
-	com.google.gson.source [2.8.2.v20180104-1110,2.8.2.v20180104-1110]
-	com.jcraft.jsch [0.1.54.v20170116-1932,0.1.54.v20170116-1932]
-	com.jcraft.jsch.source [0.1.54.v20170116-1932,0.1.54.v20170116-1932]
-	org.junit [4.12.0.v201504281640,4.12.0.v201504281640]
-	org.junit.source [4.12.0.v201504281640,4.12.0.v201504281640]
-	javax.servlet [3.1.0.v201410161800,3.1.0.v201410161800]
-	javax.servlet.source [3.1.0.v201410161800,3.1.0.v201410161800]
-	org.tukaani.xz [1.8.0.v20180207-1613,1.8.0.v20180207-1613]
-	org.tukaani.xz.source [1.8.0.v20180207-1613,1.8.0.v20180207-1613]
-	org.slf4j.api [1.7.2.v20121108-1250,1.7.2.v20121108-1250]
-	org.slf4j.api.source [1.7.2.v20121108-1250,1.7.2.v20121108-1250]
-	org.slf4j.impl.log4j12 [1.7.2.v20131105-2200,1.7.2.v20131105-2200]
-	org.slf4j.impl.log4j12.source [1.7.2.v20131105-2200,1.7.2.v20131105-2200]
-	com.jcraft.jzlib [1.1.1.v201205102305,1.1.1.v201205102305]
-	com.jcraft.jzlib.source [1.1.1.v201205102305,1.1.1.v201205102305]
-	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]
-}
diff --git a/org.eclipse.jgit.packaging/org.eclipse.jgit.target/orbit/R20190226160451-2019-03.tpd b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/orbit/R20190226160451-2019-03.tpd
deleted file mode 100644
index 32aba68..0000000
--- a/org.eclipse.jgit.packaging/org.eclipse.jgit.target/orbit/R20190226160451-2019-03.tpd
+++ /dev/null
@@ -1,64 +0,0 @@
-target "R20190226160451-2019-03" with source configurePhase
-// see http://download.eclipse.org/tools/orbit/downloads/
-
-location "http://download.eclipse.org/tools/orbit/downloads/drops/R20190226160451/repository" {
-	org.apache.ant [1.10.5.v20180808-0324,1.10.5.v20180808-0324]
-	org.apache.ant.source [1.10.5.v20180808-0324,1.10.5.v20180808-0324]
-	org.apache.commons.codec [1.10.0.v20180409-1845,1.10.0.v20180409-1845]
-	org.apache.commons.codec.source [1.10.0.v20180409-1845,1.10.0.v20180409-1845]
-	org.apache.commons.compress [1.18.0.v20181121-2221,1.18.0.v20181121-2221]
-	org.apache.commons.compress.source [1.18.0.v20181121-2221,1.18.0.v20181121-2221]
-	org.apache.commons.logging [1.2.0.v20180409-1502,1.2.0.v20180409-1502]
-	org.apache.commons.logging.source [1.2.0.v20180409-1502,1.2.0.v20180409-1502]
-	org.apache.httpcomponents.httpclient [4.5.6.v20190213-1430,4.5.6.v20190213-1430]
-	org.apache.httpcomponents.httpclient.source [4.5.6.v20190213-1430,4.5.6.v20190213-1430]
-	org.apache.httpcomponents.httpcore [4.4.10.v20190123-2214,4.4.10.v20190123-2214]
-	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.kohsuke.args4j [2.33.0.v20160323-2218,2.33.0.v20160323-2218]
-	org.kohsuke.args4j.source [2.33.0.v20160323-2218,2.33.0.v20160323-2218]
-	org.hamcrest [1.1.0.v20090501071000,1.1.0.v20090501071000]
-	org.hamcrest.core [1.3.0.v20180420-1519,1.3.0.v20180420-1519]
-	org.hamcrest.core.source [1.3.0.v20180420-1519,1.3.0.v20180420-1519]
-	org.hamcrest.library [1.3.0.v20180524-2246,1.3.0.v20180524-2246]
-	org.hamcrest.library.source [1.3.0.v20180524-2246,1.3.0.v20180524-2246]
-	javaewah [1.1.6.v20160919-1400,1.1.6.v20160919-1400]
-	javaewah.source [1.1.6.v20160919-1400,1.1.6.v20160919-1400]
-	org.objenesis [2.6.0.v20180420-1519,2.6.0.v20180420-1519]
-	org.objenesis.source [2.6.0.v20180420-1519,2.6.0.v20180420-1519]
-	org.mockito [2.13.0.v20180426-1843,2.13.0.v20180426-1843]
-	org.mockito.source [2.13.0.v20180426-1843,2.13.0.v20180426-1843]
-	net.bytebuddy.byte-buddy [1.7.9.v20180420-1519,1.7.9.v20180420-1519]
-	net.bytebuddy.byte-buddy.source [1.7.9.v20180420-1519,1.7.9.v20180420-1519]
-	net.bytebuddy.byte-buddy-agent [1.7.9.v20180420-1519,1.7.9.v20180420-1519]
-	net.bytebuddy.byte-buddy-agent.source [1.7.9.v20180420-1519,1.7.9.v20180420-1519]
-	com.google.gson [2.8.2.v20180104-1110,2.8.2.v20180104-1110]
-	com.google.gson.source [2.8.2.v20180104-1110,2.8.2.v20180104-1110]
-	com.jcraft.jsch [0.1.54.v20170116-1932,0.1.54.v20170116-1932]
-	com.jcraft.jsch.source [0.1.54.v20170116-1932,0.1.54.v20170116-1932]
-	org.junit [4.12.0.v201504281640,4.12.0.v201504281640]
-	org.junit.source [4.12.0.v201504281640,4.12.0.v201504281640]
-	javax.servlet [3.1.0.v201410161800,3.1.0.v201410161800]
-	javax.servlet.source [3.1.0.v201410161800,3.1.0.v201410161800]
-	org.tukaani.xz [1.8.0.v20180207-1613,1.8.0.v20180207-1613]
-	org.tukaani.xz.source [1.8.0.v20180207-1613,1.8.0.v20180207-1613]
-	org.slf4j.api [1.7.2.v20121108-1250,1.7.2.v20121108-1250]
-	org.slf4j.api.source [1.7.2.v20121108-1250,1.7.2.v20121108-1250]
-	org.slf4j.impl.log4j12 [1.7.2.v20131105-2200,1.7.2.v20131105-2200]
-	org.slf4j.impl.log4j12.source [1.7.2.v20131105-2200,1.7.2.v20131105-2200]
-	com.jcraft.jzlib [1.1.1.v201205102305,1.1.1.v201205102305]
-	com.jcraft.jzlib.source [1.1.1.v201205102305,1.1.1.v201205102305]
-	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]
-}
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 db67449..e278bb1 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
@@ -2,6 +2,22 @@
 // see http://download.eclipse.org/tools/orbit/downloads/
 
 location "https://download.eclipse.org/tools/orbit/downloads/drops/R20190602212107/repository" {
+	com.google.gson [2.8.2.v20180104-1110,2.8.2.v20180104-1110]
+	com.google.gson.source [2.8.2.v20180104-1110,2.8.2.v20180104-1110]
+	com.jcraft.jsch [0.1.55.v20190404-1902,0.1.55.v20190404-1902]
+	com.jcraft.jsch.source [0.1.55.v20190404-1902,0.1.55.v20190404-1902]
+	com.jcraft.jzlib [1.1.1.v201205102305,1.1.1.v201205102305]
+	com.jcraft.jzlib.source [1.1.1.v201205102305,1.1.1.v201205102305]
+	javaewah [1.1.6.v20160919-1400,1.1.6.v20160919-1400]
+	javaewah.source [1.1.6.v20160919-1400,1.1.6.v20160919-1400]
+	javax.servlet [3.1.0.v201410161800,3.1.0.v201410161800]
+	javax.servlet.source [3.1.0.v201410161800,3.1.0.v201410161800]
+	net.bytebuddy.byte-buddy [1.9.0.v20181107-1410,1.9.0.v20181107-1410]
+	net.bytebuddy.byte-buddy-agent [1.9.0.v20181106-1534,1.9.0.v20181106-1534]
+	net.bytebuddy.byte-buddy-agent.source [1.9.0.v20181106-1534,1.9.0.v20181106-1534]
+	net.bytebuddy.byte-buddy.source [1.9.0.v20181107-1410,1.9.0.v20181107-1410]
+	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.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,50 +32,34 @@
 	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.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]
 	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]
 	org.hamcrest.core [1.3.0.v20180420-1519,1.3.0.v20180420-1519]
 	org.hamcrest.core.source [1.3.0.v20180420-1519,1.3.0.v20180420-1519]
 	org.hamcrest.library [1.3.0.v20180524-2246,1.3.0.v20180524-2246]
 	org.hamcrest.library.source [1.3.0.v20180524-2246,1.3.0.v20180524-2246]
-	javaewah [1.1.6.v20160919-1400,1.1.6.v20160919-1400]
-	javaewah.source [1.1.6.v20160919-1400,1.1.6.v20160919-1400]
-	org.objenesis [2.6.0.v20180420-1519,2.6.0.v20180420-1519]
-	org.objenesis.source [2.6.0.v20180420-1519,2.6.0.v20180420-1519]
-	org.mockito [2.23.0.v20190527-1420,2.23.0.v20190527-1420]
-	org.mockito.source [2.23.0.v20190527-1420,2.23.0.v20190527-1420]
-	net.bytebuddy.byte-buddy [1.9.0.v20181107-1410,1.9.0.v20181107-1410]
-	net.bytebuddy.byte-buddy.source [1.9.0.v20181107-1410,1.9.0.v20181107-1410]
-	net.bytebuddy.byte-buddy-agent [1.9.0.v20181106-1534,1.9.0.v20181106-1534]
-	net.bytebuddy.byte-buddy-agent.source [1.9.0.v20181106-1534,1.9.0.v20181106-1534]
-	com.google.gson [2.8.2.v20180104-1110,2.8.2.v20180104-1110]
-	com.google.gson.source [2.8.2.v20180104-1110,2.8.2.v20180104-1110]
-	com.jcraft.jsch [0.1.55.v20190404-1902,0.1.55.v20190404-1902]
-	com.jcraft.jsch.source [0.1.55.v20190404-1902,0.1.55.v20190404-1902]
 	org.junit [4.12.0.v201504281640,4.12.0.v201504281640]
 	org.junit.source [4.12.0.v201504281640,4.12.0.v201504281640]
-	javax.servlet [3.1.0.v201410161800,3.1.0.v201410161800]
-	javax.servlet.source [3.1.0.v201410161800,3.1.0.v201410161800]
-	org.tukaani.xz [1.8.0.v20180207-1613,1.8.0.v20180207-1613]
-	org.tukaani.xz.source [1.8.0.v20180207-1613,1.8.0.v20180207-1613]
+	org.kohsuke.args4j [2.33.0.v20160323-2218,2.33.0.v20160323-2218]
+	org.kohsuke.args4j.source [2.33.0.v20160323-2218,2.33.0.v20160323-2218]
+	org.mockito [2.23.0.v20190527-1420,2.23.0.v20190527-1420]
+	org.mockito.source [2.23.0.v20190527-1420,2.23.0.v20190527-1420]
+	org.objenesis [2.6.0.v20180420-1519,2.6.0.v20180420-1519]
+	org.objenesis.source [2.6.0.v20180420-1519,2.6.0.v20180420-1519]
 	org.slf4j.api [1.7.2.v20121108-1250,1.7.2.v20121108-1250]
 	org.slf4j.api.source [1.7.2.v20121108-1250,1.7.2.v20121108-1250]
 	org.slf4j.impl.log4j12 [1.7.2.v20131105-2200,1.7.2.v20131105-2200]
 	org.slf4j.impl.log4j12.source [1.7.2.v20131105-2200,1.7.2.v20131105-2200]
-	com.jcraft.jzlib [1.1.1.v201205102305,1.1.1.v201205102305]
-	com.jcraft.jzlib.source [1.1.1.v201205102305,1.1.1.v201205102305]
-	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.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]
+	org.tukaani.xz [1.8.0.v20180207-1613,1.8.0.v20180207-1613]
+	org.tukaani.xz.source [1.8.0.v20180207-1613,1.8.0.v20180207-1613]
 }
 
diff --git a/org.eclipse.jgit.packaging/org.eclipse.jgit.target/orbit/R20190827152740-2019-09.tpd b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/orbit/R20190827152740-2019-09.tpd
new file mode 100644
index 0000000..63642f5
--- /dev/null
+++ b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/orbit/R20190827152740-2019-09.tpd
@@ -0,0 +1,65 @@
+target "R20190827152740-2019-09" with source configurePhase
+// see http://download.eclipse.org/tools/orbit/downloads/
+
+location "https://download.eclipse.org/tools/orbit/downloads/drops/R20190827152740/repository" {
+	com.google.gson [2.8.2.v20180104-1110,2.8.2.v20180104-1110]
+	com.google.gson.source [2.8.2.v20180104-1110,2.8.2.v20180104-1110]
+	com.jcraft.jsch [0.1.55.v20190404-1902,0.1.55.v20190404-1902]
+	com.jcraft.jsch.source [0.1.55.v20190404-1902,0.1.55.v20190404-1902]
+	com.jcraft.jzlib [1.1.1.v201205102305,1.1.1.v201205102305]
+	com.jcraft.jzlib.source [1.1.1.v201205102305,1.1.1.v201205102305]
+	javaewah [1.1.6.v20160919-1400,1.1.6.v20160919-1400]
+	javaewah.source [1.1.6.v20160919-1400,1.1.6.v20160919-1400]
+	javax.servlet [3.1.0.v201410161800,3.1.0.v201410161800]
+	javax.servlet.source [3.1.0.v201410161800,3.1.0.v201410161800]
+	net.bytebuddy.byte-buddy [1.9.0.v20181107-1410,1.9.0.v20181107-1410]
+	net.bytebuddy.byte-buddy-agent [1.9.0.v20181106-1534,1.9.0.v20181106-1534]
+	net.bytebuddy.byte-buddy-agent.source [1.9.0.v20181106-1534,1.9.0.v20181106-1534]
+	net.bytebuddy.byte-buddy.source [1.9.0.v20181107-1410,1.9.0.v20181107-1410]
+	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.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]
+	org.apache.commons.codec.source [1.10.0.v20180409-1845,1.10.0.v20180409-1845]
+	org.apache.commons.compress [1.18.0.v20181121-2221,1.18.0.v20181121-2221]
+	org.apache.commons.compress.source [1.18.0.v20181121-2221,1.18.0.v20181121-2221]
+	org.apache.commons.logging [1.2.0.v20180409-1502,1.2.0.v20180409-1502]
+	org.apache.commons.logging.source [1.2.0.v20180409-1502,1.2.0.v20180409-1502]
+	org.apache.httpcomponents.httpclient [4.5.6.v20190503-0009,4.5.6.v20190503-0009]
+	org.apache.httpcomponents.httpclient.source [4.5.6.v20190503-0009,4.5.6.v20190503-0009]
+	org.apache.httpcomponents.httpcore [4.4.10.v20190123-2214,4.4.10.v20190123-2214]
+	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.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]
+	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.hamcrest [1.1.0.v20090501071000,1.1.0.v20090501071000]
+	org.hamcrest.core [1.3.0.v20180420-1519,1.3.0.v20180420-1519]
+	org.hamcrest.core.source [1.3.0.v20180420-1519,1.3.0.v20180420-1519]
+	org.hamcrest.library [1.3.0.v20180524-2246,1.3.0.v20180524-2246]
+	org.hamcrest.library.source [1.3.0.v20180524-2246,1.3.0.v20180524-2246]
+	org.junit [4.12.0.v201504281640,4.12.0.v201504281640]
+	org.junit.source [4.12.0.v201504281640,4.12.0.v201504281640]
+	org.kohsuke.args4j [2.33.0.v20160323-2218,2.33.0.v20160323-2218]
+	org.kohsuke.args4j.source [2.33.0.v20160323-2218,2.33.0.v20160323-2218]
+	org.mockito [2.23.0.v20190527-1420,2.23.0.v20190527-1420]
+	org.mockito.source [2.23.0.v20190527-1420,2.23.0.v20190527-1420]
+	org.objenesis [2.6.0.v20180420-1519,2.6.0.v20180420-1519]
+	org.objenesis.source [2.6.0.v20180420-1519,2.6.0.v20180420-1519]
+	org.slf4j.api [1.7.2.v20121108-1250,1.7.2.v20121108-1250]
+	org.slf4j.api.source [1.7.2.v20121108-1250,1.7.2.v20121108-1250]
+	org.slf4j.impl.log4j12 [1.7.2.v20131105-2200,1.7.2.v20131105-2200]
+	org.slf4j.impl.log4j12.source [1.7.2.v20131105-2200,1.7.2.v20131105-2200]
+	org.tukaani.xz [1.8.0.v20180207-1613,1.8.0.v20180207-1613]
+	org.tukaani.xz.source [1.8.0.v20180207-1613,1.8.0.v20180207-1613]
+}
+
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 b278457..c0cf064 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.4.4-SNAPSHOT</version>
+    <version>5.5.2-SNAPSHOT</version>
   </parent>
 
   <artifactId>org.eclipse.jgit.target</artifactId>
diff --git a/org.eclipse.jgit.packaging/org.eclipse.jgit.target/projects/jetty-9.4.14.tpd b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/projects/jetty-9.4.14.tpd
deleted file mode 100644
index fb0963e..0000000
--- a/org.eclipse.jgit.packaging/org.eclipse.jgit.target/projects/jetty-9.4.14.tpd
+++ /dev/null
@@ -1,20 +0,0 @@
-target "jetty-9.4.14" with source configurePhase
-
-location jetty-9.4.14 "https://archive.eclipse.org/jetty/updates/jetty-bundles-9.x/jetty-bundles-9.x/9.4.14.v20181114" {
-	org.eclipse.jetty.client [9.4.14.v20181114,9.4.14.v20181114]
-	org.eclipse.jetty.client.source [9.4.14.v20181114,9.4.14.v20181114]
-	org.eclipse.jetty.continuation [9.4.14.v20181114,9.4.14.v20181114]
-	org.eclipse.jetty.continuation.source [9.4.14.v20181114,9.4.14.v20181114]
-	org.eclipse.jetty.http [9.4.14.v20181114,9.4.14.v20181114]
-	org.eclipse.jetty.http.source [9.4.14.v20181114,9.4.14.v20181114]
-	org.eclipse.jetty.io [9.4.14.v20181114,9.4.14.v20181114]
-	org.eclipse.jetty.io.source [9.4.14.v20181114,9.4.14.v20181114]
-	org.eclipse.jetty.security [9.4.14.v20181114,9.4.14.v20181114]
-	org.eclipse.jetty.security.source [9.4.14.v20181114,9.4.14.v20181114]
-	org.eclipse.jetty.server [9.4.14.v20181114,9.4.14.v20181114]
-	org.eclipse.jetty.server.source [9.4.14.v20181114,9.4.14.v20181114]
-	org.eclipse.jetty.servlet [9.4.14.v20181114,9.4.14.v20181114]
-	org.eclipse.jetty.servlet.source [9.4.14.v20181114,9.4.14.v20181114]
-	org.eclipse.jetty.util [9.4.14.v20181114,9.4.14.v20181114]
-	org.eclipse.jetty.util.source [9.4.14.v20181114,9.4.14.v20181114]
-}
diff --git a/org.eclipse.jgit.packaging/org.eclipse.jgit.target/projects/jetty-9.4.20.tpd b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/projects/jetty-9.4.20.tpd
new file mode 100644
index 0000000..0e4d189
--- /dev/null
+++ b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/projects/jetty-9.4.20.tpd
@@ -0,0 +1,20 @@
+target "jetty-9.4.20" with source configurePhase
+
+location jetty-9.4.20 "https://archive.eclipse.org/jetty/updates/jetty-bundles-9.x/jetty-bundles-9.x/9.4.20.v20190813/" {
+	org.eclipse.jetty.client [9.4.20.v20190813,9.4.20.v20190813]
+	org.eclipse.jetty.client.source [9.4.20.v20190813,9.4.20.v20190813]
+	org.eclipse.jetty.continuation [9.4.20.v20190813,9.4.20.v20190813]
+	org.eclipse.jetty.continuation.source [9.4.20.v20190813,9.4.20.v20190813]
+	org.eclipse.jetty.http [9.4.20.v20190813,9.4.20.v20190813]
+	org.eclipse.jetty.http.source [9.4.20.v20190813,9.4.20.v20190813]
+	org.eclipse.jetty.io [9.4.20.v20190813,9.4.20.v20190813]
+	org.eclipse.jetty.io.source [9.4.20.v20190813,9.4.20.v20190813]
+	org.eclipse.jetty.security [9.4.20.v20190813,9.4.20.v20190813]
+	org.eclipse.jetty.security.source [9.4.20.v20190813,9.4.20.v20190813]
+	org.eclipse.jetty.server [9.4.20.v20190813,9.4.20.v20190813]
+	org.eclipse.jetty.server.source [9.4.20.v20190813,9.4.20.v20190813]
+	org.eclipse.jetty.servlet [9.4.20.v20190813,9.4.20.v20190813]
+	org.eclipse.jetty.servlet.source [9.4.20.v20190813,9.4.20.v20190813]
+	org.eclipse.jetty.util [9.4.20.v20190813,9.4.20.v20190813]
+	org.eclipse.jetty.util.source [9.4.20.v20190813,9.4.20.v20190813]
+}
diff --git a/org.eclipse.jgit.packaging/pom.xml b/org.eclipse.jgit.packaging/pom.xml
index 5a90df0..9c3b926 100644
--- a/org.eclipse.jgit.packaging/pom.xml
+++ b/org.eclipse.jgit.packaging/pom.xml
@@ -49,7 +49,7 @@
 
   <groupId>org.eclipse.jgit</groupId>
   <artifactId>jgit.tycho.parent</artifactId>
-  <version>5.4.4-SNAPSHOT</version>
+  <version>5.5.2-SNAPSHOT</version>
   <packaging>pom</packaging>
 
   <name>JGit Tycho Parent</name>
diff --git a/org.eclipse.jgit.pgm.test/META-INF/MANIFEST.MF b/org.eclipse.jgit.pgm.test/META-INF/MANIFEST.MF
index b3d615c..2cb36e1 100644
--- a/org.eclipse.jgit.pgm.test/META-INF/MANIFEST.MF
+++ b/org.eclipse.jgit.pgm.test/META-INF/MANIFEST.MF
@@ -1,30 +1,30 @@
 Manifest-Version: 1.0
 Bundle-ManifestVersion: 2
-Bundle-Name: %plugin_name
+Bundle-Name: %Bundle-Name
 Automatic-Module-Name: org.eclipse.jgit.pgm.test
 Bundle-SymbolicName: org.eclipse.jgit.pgm.test
-Bundle-Version: 5.4.4.qualifier
-Bundle-Vendor: %provider_name
+Bundle-Version: 5.5.2.qualifier
+Bundle-Vendor: %Bundle-Vendor
 Bundle-Localization: plugin
 Bundle-ActivationPolicy: lazy
 Bundle-RequiredExecutionEnvironment: JavaSE-1.8
-Import-Package: org.eclipse.jgit.api;version="[5.4.4,5.5.0)",
- org.eclipse.jgit.api.errors;version="[5.4.4,5.5.0)",
- org.eclipse.jgit.diff;version="[5.4.4,5.5.0)",
- org.eclipse.jgit.dircache;version="[5.4.4,5.5.0)",
- org.eclipse.jgit.internal.storage.file;version="5.4.4",
- org.eclipse.jgit.junit;version="[5.4.4,5.5.0)",
- org.eclipse.jgit.lib;version="[5.4.4,5.5.0)",
- org.eclipse.jgit.merge;version="[5.4.4,5.5.0)",
- org.eclipse.jgit.pgm;version="[5.4.4,5.5.0)",
- org.eclipse.jgit.pgm.internal;version="[5.4.4,5.5.0)",
- org.eclipse.jgit.pgm.opt;version="[5.4.4,5.5.0)",
- org.eclipse.jgit.revwalk;version="[5.4.4,5.5.0)",
- org.eclipse.jgit.storage.file;version="[5.4.4,5.5.0)",
- org.eclipse.jgit.transport;version="[5.4.4,5.5.0)",
- org.eclipse.jgit.treewalk;version="[5.4.4,5.5.0)",
- org.eclipse.jgit.util;version="[5.4.4,5.5.0)",
- org.eclipse.jgit.util.io;version="[5.4.4,5.5.0)",
+Import-Package: org.eclipse.jgit.api;version="[5.5.2,5.6.0)",
+ org.eclipse.jgit.api.errors;version="[5.5.2,5.6.0)",
+ org.eclipse.jgit.diff;version="[5.5.2,5.6.0)",
+ org.eclipse.jgit.dircache;version="[5.5.2,5.6.0)",
+ org.eclipse.jgit.internal.storage.file;version="5.5.2",
+ org.eclipse.jgit.junit;version="[5.5.2,5.6.0)",
+ org.eclipse.jgit.lib;version="[5.5.2,5.6.0)",
+ org.eclipse.jgit.merge;version="[5.5.2,5.6.0)",
+ org.eclipse.jgit.pgm;version="[5.5.2,5.6.0)",
+ org.eclipse.jgit.pgm.internal;version="[5.5.2,5.6.0)",
+ org.eclipse.jgit.pgm.opt;version="[5.5.2,5.6.0)",
+ org.eclipse.jgit.revwalk;version="[5.5.2,5.6.0)",
+ org.eclipse.jgit.storage.file;version="[5.5.2,5.6.0)",
+ org.eclipse.jgit.transport;version="[5.5.2,5.6.0)",
+ org.eclipse.jgit.treewalk;version="[5.5.2,5.6.0)",
+ org.eclipse.jgit.util;version="[5.5.2,5.6.0)",
+ org.eclipse.jgit.util.io;version="[5.5.2,5.6.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/plugin.properties b/org.eclipse.jgit.pgm.test/plugin.properties
index e131c69..61cae8e 100644
--- a/org.eclipse.jgit.pgm.test/plugin.properties
+++ b/org.eclipse.jgit.pgm.test/plugin.properties
@@ -1,2 +1,2 @@
-plugin_name=JGit Command Line Interface Tests
-provider_name=Eclipse JGit
+Bundle-Name=JGit Command Line Interface Tests
+Bundle-Vendor=Eclipse JGit
diff --git a/org.eclipse.jgit.pgm.test/pom.xml b/org.eclipse.jgit.pgm.test/pom.xml
index ecf3d70..49535d6 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.4.4-SNAPSHOT</version>
+    <version>5.5.2-SNAPSHOT</version>
   </parent>
 
   <artifactId>org.eclipse.jgit.pgm.test</artifactId>
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 a830ff2..befb7f6 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
@@ -211,6 +211,14 @@
 				.replaceAll("\t", "\\\\t");
 	}
 
+	protected String shellQuote(String s) {
+		return "'" + s.replace("'", "'\\''") + "'";
+	}
+
+	protected String shellQuote(File f) {
+		return "'" + f.getPath().replace("'", "'\\''") + "'";
+	}
+
 	protected void assertStringArrayEquals(String expected, String[] actual) {
 		// if there is more than one line, ignore last one if empty
 		assertEquals(1,
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 e07fdd5..03aa469 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
@@ -139,10 +139,6 @@
 				listTarEntries(result));
 	}
 
-	private static String shellQuote(String s) {
-		return "'" + s.replace("'", "'\\''") + "'";
-	}
-
 	@Test
 	public void testFormatOverridesFilename() throws Exception {
 		File archive = new File(db.getWorkTree(), "format-overrides-name.tar");
diff --git a/org.eclipse.jgit.pgm.test/tst/org/eclipse/jgit/pgm/BlameTest.java b/org.eclipse.jgit.pgm.test/tst/org/eclipse/jgit/pgm/BlameTest.java
new file mode 100644
index 0000000..e806872
--- /dev/null
+++ b/org.eclipse.jgit.pgm.test/tst/org/eclipse/jgit/pgm/BlameTest.java
@@ -0,0 +1,122 @@
+/*
+ * 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.pgm;
+
+import org.eclipse.jgit.api.Git;
+import org.eclipse.jgit.lib.CLIRepositoryTestCase;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.rules.ExpectedException;
+
+public class BlameTest extends CLIRepositoryTestCase {
+
+	@Rule
+	public ExpectedException thrown = ExpectedException.none();
+
+	@Test
+	public void testBlameNoHead() throws Exception {
+		try (Git git = new Git(db)) {
+			writeTrashFile("inIndex.txt", "index");
+			git.add().addFilepattern("inIndex.txt").call();
+		}
+		thrown.expect(Die.class);
+		thrown.expectMessage("no such ref: HEAD");
+		execute("git blame inIndex.txt");
+	}
+
+	@Test
+	public void testBlameCommitted() throws Exception {
+		try (Git git = new Git(db)) {
+			git.commit().setMessage("initial commit").call();
+			writeTrashFile("committed.txt", "committed");
+			git.add().addFilepattern("committed.txt").call();
+			git.commit().setMessage("commit").call();
+		}
+		assertStringArrayEquals(
+				"1ad3399c (GIT_COMMITTER_NAME 2009-08-15 20:12:58 -0330 1) committed",
+				execute("git blame committed.txt"));
+	}
+
+	@Test
+	public void testBlameStaged() throws Exception {
+		try (Git git = new Git(db)) {
+			git.commit().setMessage("initial commit").call();
+			writeTrashFile("inIndex.txt", "index");
+			git.add().addFilepattern("inIndex.txt").call();
+		}
+		assertStringArrayEquals(
+				"         (Not Committed Yet          1) index",
+				execute("git blame inIndex.txt"));
+	}
+
+	@Test
+	public void testBlameUnstaged() throws Exception {
+		try (Git git = new Git(db)) {
+			git.commit().setMessage("initial commit").call();
+		}
+		writeTrashFile("onlyInWorkingTree.txt", "not in repo");
+		thrown.expect(Die.class);
+		thrown.expectMessage("no such path 'onlyInWorkingTree.txt' in HEAD");
+		execute("git blame onlyInWorkingTree.txt");
+	}
+
+	@Test
+	public void testBlameNonExisting() throws Exception {
+		try (Git git = new Git(db)) {
+			git.commit().setMessage("initial commit").call();
+		}
+		thrown.expect(Die.class);
+		thrown.expectMessage("no such path 'does_not_exist.txt' in HEAD");
+		execute("git blame does_not_exist.txt");
+	}
+
+	@Test
+	public void testBlameNonExistingInSubdir() throws Exception {
+		try (Git git = new Git(db)) {
+			git.commit().setMessage("initial commit").call();
+		}
+		thrown.expect(Die.class);
+		thrown.expectMessage("no such path 'sub/does_not_exist.txt' in HEAD");
+		execute("git blame sub/does_not_exist.txt");
+	}
+}
diff --git a/org.eclipse.jgit.pgm.test/tst/org/eclipse/jgit/pgm/CloneTest.java b/org.eclipse.jgit.pgm.test/tst/org/eclipse/jgit/pgm/CloneTest.java
index 2c0abd7..c31f28c 100644
--- a/org.eclipse.jgit.pgm.test/tst/org/eclipse/jgit/pgm/CloneTest.java
+++ b/org.eclipse.jgit.pgm.test/tst/org/eclipse/jgit/pgm/CloneTest.java
@@ -78,9 +78,9 @@
 		File gitDir = db.getDirectory();
 		String sourceURI = gitDir.toURI().toString();
 		File target = createTempDirectory("target");
-		StringBuilder cmd = new StringBuilder("git clone ").append(sourceURI
-				+ " " + target.getPath());
-		String[] result = execute(cmd.toString());
+		String cmd = "git clone " + sourceURI + " "
+				+ shellQuote(target.getPath());
+		String[] result = execute(cmd);
 		assertArrayEquals(new String[] {
 				"Cloning into '" + target.getPath() + "'...",
 						"", "" }, result);
@@ -101,9 +101,9 @@
 		File gitDir = db.getDirectory();
 		String sourceURI = gitDir.toURI().toString();
 		File target = createTempDirectory("target");
-		StringBuilder cmd = new StringBuilder("git clone ").append(sourceURI
-				+ " " + target.getPath());
-		String[] result = execute(cmd.toString());
+		String cmd = "git clone " + sourceURI + " "
+				+ shellQuote(target.getPath());
+		String[] result = execute(cmd);
 		assertArrayEquals(new String[] {
 				"Cloning into '" + target.getPath() + "'...",
 				"warning: You appear to have cloned an empty repository.", "",
@@ -125,8 +125,8 @@
 		File gitDir = db.getDirectory();
 		String sourceURI = gitDir.toURI().toString();
 		String name = new URIish(sourceURI).getHumanishName();
-		StringBuilder cmd = new StringBuilder("git clone ").append(sourceURI);
-		String[] result = execute(cmd.toString());
+		String cmd = "git clone " + sourceURI;
+		String[] result = execute(cmd);
 		assertArrayEquals(new String[] {
 				"Cloning into '" + new File(target, name).getName() + "'...",
 				"", "" }, result);
@@ -143,10 +143,10 @@
 		String sourcePath = gitDir.getAbsolutePath();
 		String targetPath = (new File(sourcePath)).getParentFile()
 				.getParentFile().getAbsolutePath()
-				+ "/target.git";
-		StringBuilder cmd = new StringBuilder("git clone --bare ")
-				.append(sourcePath + " " + targetPath);
-		String[] result = execute(cmd.toString());
+				+ File.separator + "target.git";
+		String cmd = "git clone --bare " + shellQuote(sourcePath) + " "
+				+ shellQuote(targetPath);
+		String[] result = execute(cmd);
 		assertArrayEquals(new String[] {
 				"Cloning into '" + targetPath + "'...", "", "" }, result);
 		Git git2 = Git.open(new File(targetPath));
diff --git a/org.eclipse.jgit.pgm.test/tst/org/eclipse/jgit/pgm/LsRemoteTest.java b/org.eclipse.jgit.pgm.test/tst/org/eclipse/jgit/pgm/LsRemoteTest.java
index ba6b771..fd3c383 100644
--- a/org.eclipse.jgit.pgm.test/tst/org/eclipse/jgit/pgm/LsRemoteTest.java
+++ b/org.eclipse.jgit.pgm.test/tst/org/eclipse/jgit/pgm/LsRemoteTest.java
@@ -80,7 +80,7 @@
 	@Test
 	public void testLsRemote() throws Exception {
 		final List<String> result = CLIGitCommand.execute(
-				"git ls-remote " + db.getDirectory(), db);
+				"git ls-remote " + shellQuote(db.getDirectory()), db);
 		assertArrayEquals(new String[] {
 				"d0b1ef2b3dea02bb2ca824445c04e6def012c32c	HEAD",
 				"d0b1ef2b3dea02bb2ca824445c04e6def012c32c	refs/heads/master",
@@ -98,7 +98,8 @@
 	public void testLsRemoteHeads() throws Exception {
 		final List<String> result = CLIGitCommand.execute(
 				"git ls-remote --heads "
-				+ db.getDirectory(), db);
+						+ shellQuote(db.getDirectory()),
+				db);
 		assertArrayEquals(new String[] {
 				"d0b1ef2b3dea02bb2ca824445c04e6def012c32c	refs/heads/master",
 				"d0b1ef2b3dea02bb2ca824445c04e6def012c32c	refs/heads/test",
@@ -108,7 +109,7 @@
 	@Test
 	public void testLsRemoteTags() throws Exception {
 		final List<String> result = CLIGitCommand.execute(
-				"git ls-remote --tags " + db.getDirectory(), db);
+				"git ls-remote --tags " + shellQuote(db.getDirectory()), db);
 		assertArrayEquals(new String[] {
 				"efc02078d83a5226986ae917323acec7e1e8b7cb	refs/tags/tag1",
 				"d0b1ef2b3dea02bb2ca824445c04e6def012c32c	refs/tags/tag1^{}",
@@ -122,7 +123,8 @@
 	@Test
 	public void testLsRemoteHeadsTags() throws Exception {
 		final List<String> result = CLIGitCommand.execute(
-				"git ls-remote --heads --tags " + db.getDirectory(), db);
+				"git ls-remote --heads --tags " + shellQuote(db.getDirectory()),
+				db);
 		assertArrayEquals(new String[] {
 				"d0b1ef2b3dea02bb2ca824445c04e6def012c32c	refs/heads/master",
 				"d0b1ef2b3dea02bb2ca824445c04e6def012c32c	refs/heads/test",
diff --git a/org.eclipse.jgit.pgm/META-INF/MANIFEST.MF b/org.eclipse.jgit.pgm/META-INF/MANIFEST.MF
index d928303..0a9074a 100644
--- a/org.eclipse.jgit.pgm/META-INF/MANIFEST.MF
+++ b/org.eclipse.jgit.pgm/META-INF/MANIFEST.MF
@@ -1,10 +1,10 @@
 Manifest-Version: 1.0
 Bundle-ManifestVersion: 2
-Bundle-Name: %plugin_name
+Bundle-Name: %Bundle-Name
 Automatic-Module-Name: org.eclipse.jgit.pgm
 Bundle-SymbolicName: org.eclipse.jgit.pgm
-Bundle-Version: 5.4.4.qualifier
-Bundle-Vendor: %provider_name
+Bundle-Version: 5.5.2.qualifier
+Bundle-Vendor: %Bundle-Vendor
 Bundle-ActivationPolicy: lazy
 Bundle-Localization: plugin
 Bundle-RequiredExecutionEnvironment: JavaSE-1.8
@@ -28,50 +28,50 @@
  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.4.4,5.5.0)",
- org.eclipse.jgit.api.errors;version="[5.4.4,5.5.0)",
- org.eclipse.jgit.archive;version="[5.4.4,5.5.0)",
- org.eclipse.jgit.awtui;version="[5.4.4,5.5.0)",
- org.eclipse.jgit.blame;version="[5.4.4,5.5.0)",
- org.eclipse.jgit.diff;version="[5.4.4,5.5.0)",
- org.eclipse.jgit.dircache;version="[5.4.4,5.5.0)",
- org.eclipse.jgit.errors;version="[5.4.4,5.5.0)",
- org.eclipse.jgit.gitrepo;version="[5.4.4,5.5.0)",
- org.eclipse.jgit.internal.ketch;version="[5.4.4,5.5.0)",
- org.eclipse.jgit.internal.storage.dfs;version="[5.4.4,5.5.0)",
- org.eclipse.jgit.internal.storage.file;version="[5.4.4,5.5.0)",
- org.eclipse.jgit.internal.storage.io;version="[5.4.4,5.5.0)",
- org.eclipse.jgit.internal.storage.pack;version="[5.4.4,5.5.0)",
- org.eclipse.jgit.internal.storage.reftable;version="[5.4.4,5.5.0)",
- org.eclipse.jgit.internal.storage.reftree;version="[5.4.4,5.5.0)",
- org.eclipse.jgit.lfs;version="[5.4.4,5.5.0)",
- org.eclipse.jgit.lfs.lib;version="[5.4.4,5.5.0)",
- org.eclipse.jgit.lfs.server;version="[5.4.4,5.5.0)",
- org.eclipse.jgit.lfs.server.fs;version="[5.4.4,5.5.0)",
- org.eclipse.jgit.lfs.server.s3;version="[5.4.4,5.5.0)",
- org.eclipse.jgit.lib;version="[5.4.4,5.5.0)",
- org.eclipse.jgit.merge;version="[5.4.4,5.5.0)",
- org.eclipse.jgit.nls;version="[5.4.4,5.5.0)",
- org.eclipse.jgit.notes;version="[5.4.4,5.5.0)",
- org.eclipse.jgit.revplot;version="[5.4.4,5.5.0)",
- org.eclipse.jgit.revwalk;version="[5.4.4,5.5.0)",
- org.eclipse.jgit.revwalk.filter;version="[5.4.4,5.5.0)",
- org.eclipse.jgit.storage.file;version="[5.4.4,5.5.0)",
- org.eclipse.jgit.storage.pack;version="[5.4.4,5.5.0)",
- org.eclipse.jgit.transport;version="[5.4.4,5.5.0)",
- org.eclipse.jgit.transport.http.apache;version="[5.4.4,5.5.0)",
- org.eclipse.jgit.transport.resolver;version="[5.4.4,5.5.0)",
- org.eclipse.jgit.transport.sshd;version="[5.4.4,5.5.0)",
- org.eclipse.jgit.treewalk;version="[5.4.4,5.5.0)",
- org.eclipse.jgit.treewalk.filter;version="[5.4.4,5.5.0)",
- org.eclipse.jgit.util;version="[5.4.4,5.5.0)",
- org.eclipse.jgit.util.io;version="[5.4.4,5.5.0)",
+ org.eclipse.jgit.api;version="[5.5.2,5.6.0)",
+ org.eclipse.jgit.api.errors;version="[5.5.2,5.6.0)",
+ org.eclipse.jgit.archive;version="[5.5.2,5.6.0)",
+ org.eclipse.jgit.awtui;version="[5.5.2,5.6.0)",
+ org.eclipse.jgit.blame;version="[5.5.2,5.6.0)",
+ org.eclipse.jgit.diff;version="[5.5.2,5.6.0)",
+ org.eclipse.jgit.dircache;version="[5.5.2,5.6.0)",
+ org.eclipse.jgit.errors;version="[5.5.2,5.6.0)",
+ org.eclipse.jgit.gitrepo;version="[5.5.2,5.6.0)",
+ org.eclipse.jgit.internal.ketch;version="[5.5.2,5.6.0)",
+ org.eclipse.jgit.internal.storage.dfs;version="[5.5.2,5.6.0)",
+ org.eclipse.jgit.internal.storage.file;version="[5.5.2,5.6.0)",
+ org.eclipse.jgit.internal.storage.io;version="[5.5.2,5.6.0)",
+ org.eclipse.jgit.internal.storage.pack;version="[5.5.2,5.6.0)",
+ org.eclipse.jgit.internal.storage.reftable;version="[5.5.2,5.6.0)",
+ org.eclipse.jgit.internal.storage.reftree;version="[5.5.2,5.6.0)",
+ org.eclipse.jgit.lfs;version="[5.5.2,5.6.0)",
+ org.eclipse.jgit.lfs.lib;version="[5.5.2,5.6.0)",
+ org.eclipse.jgit.lfs.server;version="[5.5.2,5.6.0)",
+ org.eclipse.jgit.lfs.server.fs;version="[5.5.2,5.6.0)",
+ org.eclipse.jgit.lfs.server.s3;version="[5.5.2,5.6.0)",
+ org.eclipse.jgit.lib;version="[5.5.2,5.6.0)",
+ org.eclipse.jgit.merge;version="[5.5.2,5.6.0)",
+ org.eclipse.jgit.nls;version="[5.5.2,5.6.0)",
+ org.eclipse.jgit.notes;version="[5.5.2,5.6.0)",
+ org.eclipse.jgit.revplot;version="[5.5.2,5.6.0)",
+ org.eclipse.jgit.revwalk;version="[5.5.2,5.6.0)",
+ org.eclipse.jgit.revwalk.filter;version="[5.5.2,5.6.0)",
+ org.eclipse.jgit.storage.file;version="[5.5.2,5.6.0)",
+ org.eclipse.jgit.storage.pack;version="[5.5.2,5.6.0)",
+ org.eclipse.jgit.transport;version="[5.5.2,5.6.0)",
+ org.eclipse.jgit.transport.http.apache;version="[5.5.2,5.6.0)",
+ org.eclipse.jgit.transport.resolver;version="[5.5.2,5.6.0)",
+ org.eclipse.jgit.transport.sshd;version="[5.5.2,5.6.0)",
+ org.eclipse.jgit.treewalk;version="[5.5.2,5.6.0)",
+ org.eclipse.jgit.treewalk.filter;version="[5.5.2,5.6.0)",
+ org.eclipse.jgit.util;version="[5.5.2,5.6.0)",
+ org.eclipse.jgit.util.io;version="[5.5.2,5.6.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.4.4";
+Export-Package: org.eclipse.jgit.console;version="5.5.2";
   uses:="org.eclipse.jgit.transport,
    org.eclipse.jgit.util",
- org.eclipse.jgit.pgm;version="5.4.4";
+ org.eclipse.jgit.pgm;version="5.5.2";
   uses:="org.eclipse.jgit.revwalk,
    org.eclipse.jgit.treewalk.filter,
    org.eclipse.jgit.pgm.opt,
@@ -82,11 +82,11 @@
    org.eclipse.jgit.treewalk,
    javax.swing,
    org.eclipse.jgit.transport",
- org.eclipse.jgit.pgm.debug;version="5.4.4";
+ org.eclipse.jgit.pgm.debug;version="5.5.2";
   uses:="org.eclipse.jgit.util.io,
    org.eclipse.jgit.pgm",
- org.eclipse.jgit.pgm.internal;version="5.4.4";x-friends:="org.eclipse.jgit.pgm.test,org.eclipse.jgit.test",
- org.eclipse.jgit.pgm.opt;version="5.4.4";
+ org.eclipse.jgit.pgm.internal;version="5.5.2";x-friends:="org.eclipse.jgit.pgm.test,org.eclipse.jgit.test",
+ org.eclipse.jgit.pgm.opt;version="5.5.2";
   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 750676b..1ce53a5 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-Name: org.eclipse.jgit.pgm - Sources
 Bundle-SymbolicName: org.eclipse.jgit.pgm.source
 Bundle-Vendor: Eclipse.org - JGit
-Bundle-Version: 5.4.4.qualifier
-Eclipse-SourceBundle: org.eclipse.jgit.pgm;version="5.4.4.qualifier";roots="."
+Bundle-Version: 5.5.2.qualifier
+Eclipse-SourceBundle: org.eclipse.jgit.pgm;version="5.5.2.qualifier";roots="."
diff --git a/org.eclipse.jgit.pgm/plugin.properties b/org.eclipse.jgit.pgm/plugin.properties
index 118fe47..bfa216c 100644
--- a/org.eclipse.jgit.pgm/plugin.properties
+++ b/org.eclipse.jgit.pgm/plugin.properties
@@ -1,2 +1,2 @@
-plugin_name=JGit Command Line Interface
-provider_name=Eclipse JGit
+Bundle-Name=JGit Command Line Interface
+Bundle-Vendor=Eclipse JGit
diff --git a/org.eclipse.jgit.pgm/pom.xml b/org.eclipse.jgit.pgm/pom.xml
index f7e8407..c7bcaf1 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.4.4-SNAPSHOT</version>
+    <version>5.5.2-SNAPSHOT</version>
   </parent>
 
   <artifactId>org.eclipse.jgit.pgm</artifactId>
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 124bb44..f029442 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
@@ -153,6 +153,8 @@
 noGitRepositoryConfigured=No Git repository configured.
 noNamesFound=No names found, cannot describe anything.
 noSuchFile=no such file: {0}
+noSuchPathInRef=no such path ''{0}'' in {1}
+noSuchRef=no such ref: {0}
 noSystemConsoleAvailable=No System.console available
 noTREESectionInIndex=no 'TREE' section in index
 nonFastForward=non-fast forward
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 e38cb46..b67b04c 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
@@ -67,6 +67,7 @@
 import org.eclipse.jgit.dircache.DirCache;
 import org.eclipse.jgit.errors.NoWorkTreeException;
 import org.eclipse.jgit.lib.Constants;
+import org.eclipse.jgit.lib.ObjectId;
 import org.eclipse.jgit.lib.ObjectReader;
 import org.eclipse.jgit.lib.PersonIdent;
 import org.eclipse.jgit.pgm.internal.CLIText;
@@ -178,14 +179,28 @@
 				}
 				generator.reverse(rangeStart, rangeEnd);
 			} else if (revision != null) {
-				generator.push(null, db.resolve(revision + "^{commit}")); //$NON-NLS-1$
+				ObjectId rev = db.resolve(revision + "^{commit}"); //$NON-NLS-1$
+				if (rev == null) {
+					throw die(MessageFormat.format(CLIText.get().noSuchRef,
+							revision));
+				}
+				generator.push(null, rev);
 			} else {
-				generator.push(null, db.resolve(Constants.HEAD));
+				ObjectId head = db.resolve(Constants.HEAD);
+				if (head == null) {
+					throw die(MessageFormat.format(CLIText.get().noSuchRef,
+							Constants.HEAD));
+				}
+				generator.push(null, head);
 				if (!db.isBare()) {
 					DirCache dc = db.readDirCache();
 					int entry = dc.findEntry(file);
 					if (0 <= entry) {
 						generator.push(null, dc.getEntry(entry).getObjectId());
+					} else {
+						throw die(MessageFormat.format(
+								CLIText.get().noSuchPathInRef, file,
+								Constants.HEAD));
 					}
 
 					File inTree = new File(db.getWorkTree(), file);
@@ -196,6 +211,10 @@
 			}
 
 			blame = BlameResult.create(generator);
+			if (blame == null) {
+				throw die(MessageFormat.format(CLIText.get().noSuchPathInRef,
+						file, revision != null ? revision : Constants.HEAD));
+			}
 			begin = 0;
 			end = blame.getResultContents().size();
 			if (rangeString != null) {
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 8a3e43e..3d81e7c 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
@@ -255,6 +255,8 @@
 	/***/ public String noGitRepositoryConfigured;
 	/***/ public String noNamesFound;
 	/***/ public String noSuchFile;
+	/***/ public String noSuchPathInRef;
+	/***/ public String noSuchRef;
 	/***/ public String noTREESectionInIndex;
 	/***/ public String nonFastForward;
 	/***/ public String noSystemConsoleAvailable;
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 e6debfe..81969e7 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,27 @@
 Bundle-Name: %Bundle-Name
 Automatic-Module-Name: org.eclipse.jgit.ssh.apache.test
 Bundle-SymbolicName: org.eclipse.jgit.ssh.apache.test
-Bundle-Version: 5.4.4.qualifier
-Bundle-Vendor: %Provider-Name
+Bundle-Version: 5.5.2.qualifier
+Bundle-Vendor: %Bundle-Vendor
+Bundle-Localization: plugin
 Bundle-RequiredExecutionEnvironment: JavaSE-1.8
-Import-Package: org.eclipse.jgit.internal.transport.sshd.proxy;version="[5.4.4,5.5.0)",
- org.eclipse.jgit.junit;version="[5.4.4,5.5.0)",
- org.eclipse.jgit.junit.ssh;version="[5.4.4,5.5.0)",
- org.eclipse.jgit.lib;version="[5.4.4,5.5.0)",
- org.eclipse.jgit.transport;version="[5.4.4,5.5.0)",
- org.eclipse.jgit.transport.ssh;version="[5.4.4,5.5.0)",
- org.eclipse.jgit.transport.sshd;version="[5.4.4,5.5.0)",
- org.eclipse.jgit.util;version="[5.4.4,5.5.0)",
+Import-Package: org.apache.sshd.client.config.hosts;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.config.keys;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.net;version="[2.2.0,2.3.0)",
+ org.apache.sshd.common.util.security;version="[2.2.0,2.3.0)",
+ org.eclipse.jgit.api.errors;version="[5.5.2,5.6.0)",
+ org.eclipse.jgit.internal.transport.sshd.proxy;version="[5.5.2,5.6.0)",
+ org.eclipse.jgit.junit;version="[5.5.2,5.6.0)",
+ org.eclipse.jgit.junit.ssh;version="[5.5.2,5.6.0)",
+ org.eclipse.jgit.lib;version="[5.5.2,5.6.0)",
+ org.eclipse.jgit.transport;version="[5.5.2,5.6.0)",
+ org.eclipse.jgit.transport.ssh;version="[5.5.2,5.6.0)",
+ org.eclipse.jgit.transport.sshd;version="[5.5.2,5.6.0)",
+ org.eclipse.jgit.util;version="[5.5.2,5.6.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/plugin.properties b/org.eclipse.jgit.ssh.apache.test/plugin.properties
index 67c296d..b279c8f 100644
--- a/org.eclipse.jgit.ssh.apache.test/plugin.properties
+++ b/org.eclipse.jgit.ssh.apache.test/plugin.properties
@@ -1,2 +1,2 @@
-plugin_name=JGit Tests for SSH with Apache MINA sshd
-provider_name=Eclipse JGit
+Bundle-Name=JGit Tests for SSH with Apache MINA sshd
+Bundle-Vendor=Eclipse JGit
diff --git a/org.eclipse.jgit.ssh.apache.test/pom.xml b/org.eclipse.jgit.ssh.apache.test/pom.xml
index 367a3d4..0f2504c 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.4.4-SNAPSHOT</version>
+    <version>5.5.2-SNAPSHOT</version>
   </parent>
 
   <artifactId>org.eclipse.jgit.ssh.apache.test</artifactId>
diff --git a/org.eclipse.jgit.ssh.apache.test/tst/org/eclipse/jgit/transport/sshd/ApacheSshTest.java b/org.eclipse.jgit.ssh.apache.test/tst/org/eclipse/jgit/transport/sshd/ApacheSshTest.java
index 98a38ff..b9b7353 100644
--- a/org.eclipse.jgit.ssh.apache.test/tst/org/eclipse/jgit/transport/sshd/ApacheSshTest.java
+++ b/org.eclipse.jgit.ssh.apache.test/tst/org/eclipse/jgit/transport/sshd/ApacheSshTest.java
@@ -42,12 +42,19 @@
  */
 package org.eclipse.jgit.transport.sshd;
 
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+
 import java.io.File;
 import java.io.IOException;
 import java.io.UncheckedIOException;
 import java.nio.file.Files;
 import java.util.Arrays;
-
+import java.util.List;
+import java.util.stream.Collectors;
+import org.apache.sshd.client.config.hosts.KnownHostEntry;
+import org.eclipse.jgit.api.errors.TransportException;
 import org.eclipse.jgit.lib.Constants;
 import org.eclipse.jgit.transport.SshSessionFactory;
 import org.eclipse.jgit.transport.ssh.SshTestBase;
@@ -81,11 +88,10 @@
 		}
 	}
 
-	// Using an ed25519 (unencrypted) user key is tested in the super class in
-	// testSshKeys(). sshd 2.0.0 cannot yet read encrypted ed25519 keys.
-
 	@Test
 	public void testEd25519HostKey() throws Exception {
+		// Using ed25519 user identities is tested in the super class in
+		// testSshKeys().
 		File newHostKey = new File(getTemporaryDirectory(), "newhostkey");
 		copyTestResource("id_ed25519", newHostKey);
 		server.addHostKey(newHostKey.toPath(), true);
@@ -101,4 +107,105 @@
 				"IdentityFile " + privateKey1.getAbsolutePath());
 	}
 
+	@Test
+	public void testHashedKnownHosts() throws Exception {
+		assertTrue("Failed to delete known_hosts", knownHosts.delete());
+		// The provider will answer "yes" to all questions, so we should be able
+		// to connect and end up with a new known_hosts file with the host key.
+		TestCredentialsProvider provider = new TestCredentialsProvider();
+		cloneWith("ssh://localhost/doesntmatter", defaultCloneDir, provider, //
+				"HashKnownHosts yes", //
+				"Host localhost", //
+				"HostName localhost", //
+				"Port " + testPort, //
+				"User " + TEST_USER, //
+				"IdentityFile " + privateKey1.getAbsolutePath());
+		List<LogEntry> messages = provider.getLog();
+		assertFalse("Expected user interaction", messages.isEmpty());
+		assertEquals(
+				"Expected to be asked about the key, and the file creation", 2,
+				messages.size());
+		assertTrue("~/.ssh/known_hosts should exist now", knownHosts.exists());
+		// Let's clone again without provider. If it works, the server host key
+		// was written correctly.
+		File clonedAgain = new File(getTemporaryDirectory(), "cloned2");
+		cloneWith("ssh://localhost/doesntmatter", clonedAgain, null, //
+				"Host localhost", //
+				"HostName localhost", //
+				"Port " + testPort, //
+				"User " + TEST_USER, //
+				"IdentityFile " + privateKey1.getAbsolutePath());
+		// Check that the first line contains neither "localhost" nor
+		// "127.0.0.1", but does contain the expected hash.
+		List<String> lines = Files.readAllLines(knownHosts.toPath()).stream()
+				.filter(s -> s != null && s.length() >= 1 && s.charAt(0) != '#'
+						&& !s.trim().isEmpty())
+				.collect(Collectors.toList());
+		assertEquals("Unexpected number of known_hosts lines", 1, lines.size());
+		String line = lines.get(0);
+		assertFalse("Found host in line", line.contains("localhost"));
+		assertFalse("Found IP in line", line.contains("127.0.0.1"));
+		assertTrue("Hash not found", line.contains("|"));
+		KnownHostEntry entry = KnownHostEntry.parseKnownHostEntry(line);
+		assertTrue("Hash doesn't match localhost",
+				entry.isHostMatch("localhost", testPort)
+						|| entry.isHostMatch("127.0.0.1", testPort));
+	}
+
+	@Test
+	public void testPreamble() throws Exception {
+		// Test that the client can deal with strange lines being sent before
+		// the server identification string.
+		StringBuilder b = new StringBuilder();
+		for (int i = 0; i < 257; i++) {
+			b.append('a');
+		}
+		server.setPreamble("A line with a \000 NUL",
+				"A long line: " + b.toString());
+		cloneWith(
+				"ssh://" + TEST_USER + "@localhost:" + testPort
+						+ "/doesntmatter",
+				defaultCloneDir, null,
+				"IdentityFile " + privateKey1.getAbsolutePath());
+	}
+
+	@Test
+	public void testLongPreamble() throws Exception {
+		// Test that the client can deal with a long (about 60k) preamble.
+		StringBuilder b = new StringBuilder();
+		for (int i = 0; i < 1024; i++) {
+			b.append('a');
+		}
+		String line = b.toString();
+		String[] lines = new String[60];
+		for (int i = 0; i < lines.length; i++) {
+			lines[i] = line;
+		}
+		server.setPreamble(lines);
+		cloneWith(
+				"ssh://" + TEST_USER + "@localhost:" + testPort
+						+ "/doesntmatter",
+				defaultCloneDir, null,
+				"IdentityFile " + privateKey1.getAbsolutePath());
+	}
+
+	@Test (expected = TransportException.class)
+	public void testHugePreamble() throws Exception {
+		// Test that the connection fails when the preamble is longer than 64k.
+		StringBuilder b = new StringBuilder();
+		for (int i = 0; i < 1024; i++) {
+			b.append('a');
+		}
+		String line = b.toString();
+		String[] lines = new String[70];
+		for (int i = 0; i < lines.length; i++) {
+			lines[i] = line;
+		}
+		server.setPreamble(lines);
+		cloneWith(
+				"ssh://" + TEST_USER + "@localhost:" + testPort
+						+ "/doesntmatter",
+				defaultCloneDir, null,
+				"IdentityFile " + privateKey1.getAbsolutePath());
+	}
 }
diff --git a/org.eclipse.jgit.ssh.apache.test/tst/org/eclipse/jgit/transport/sshd/NoFilesSshTest.java b/org.eclipse.jgit.ssh.apache.test/tst/org/eclipse/jgit/transport/sshd/NoFilesSshTest.java
new file mode 100644
index 0000000..c0dc2cf
--- /dev/null
+++ b/org.eclipse.jgit.ssh.apache.test/tst/org/eclipse/jgit/transport/sshd/NoFilesSshTest.java
@@ -0,0 +1,221 @@
+/*
+ * 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.transport.sshd;
+
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.UncheckedIOException;
+import java.net.InetSocketAddress;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.security.GeneralSecurityException;
+import java.security.KeyPair;
+import java.security.PublicKey;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.Iterator;
+import java.util.List;
+
+import org.apache.sshd.common.NamedResource;
+import org.apache.sshd.common.config.keys.KeyUtils;
+import org.apache.sshd.common.keyprovider.KeyIdentityProvider;
+import org.apache.sshd.common.session.SessionContext;
+import org.apache.sshd.common.util.net.SshdSocketAddress;
+import org.apache.sshd.common.util.security.SecurityUtils;
+import org.eclipse.jgit.lib.Constants;
+import org.eclipse.jgit.transport.CredentialsProvider;
+import org.eclipse.jgit.transport.SshSessionFactory;
+import org.eclipse.jgit.transport.ssh.SshTestHarness;
+import org.eclipse.jgit.util.FS;
+import org.junit.After;
+import org.junit.Test;
+
+/**
+ * Test for using the SshdSessionFactory without files in ~/.ssh but with an
+ * in-memory setup.
+ */
+public class NoFilesSshTest extends SshTestHarness {
+
+
+	private PublicKey testServerKey;
+
+	private KeyPair testUserKey;
+
+	@Override
+	protected SshSessionFactory createSessionFactory() {
+		SshdSessionFactory result = new SshdSessionFactory(new JGitKeyCache(),
+				null) {
+
+			@Override
+			protected File getSshConfig(File dir) {
+				return null;
+			}
+
+			@Override
+			protected ServerKeyDatabase getServerKeyDatabase(File homeDir,
+					File dir) {
+				return new ServerKeyDatabase() {
+
+					@Override
+					public List<PublicKey> lookup(String connectAddress,
+							InetSocketAddress remoteAddress,
+							Configuration config) {
+						return Collections.singletonList(testServerKey);
+					}
+
+					@Override
+					public boolean accept(String connectAddress,
+							InetSocketAddress remoteAddress,
+							PublicKey serverKey, Configuration config,
+							CredentialsProvider provider) {
+						return KeyUtils.compareKeys(serverKey, testServerKey);
+					}
+
+				};
+			}
+
+			@Override
+			protected Iterable<KeyPair> getDefaultKeys(File dir) {
+				// This would work for this simple test case:
+				// return Collections.singletonList(testUserKey);
+				// But let's see if we can check the host and username that's used.
+				// For that, we need access to the sshd SessionContext:
+				return new KeyAuthenticator();
+			}
+
+			@Override
+			protected String getDefaultPreferredAuthentications() {
+				return "publickey";
+			}
+		};
+
+		// The home directory is mocked at this point!
+		result.setHomeDirectory(FS.DETECTED.userHome());
+		result.setSshDirectory(sshDir);
+		return result;
+	}
+
+	private class KeyAuthenticator implements KeyIdentityProvider, Iterable<KeyPair> {
+
+		@Override
+		public Iterator<KeyPair> iterator() {
+			// Should not be called. The use of the Iterable interface in
+			// SshdSessionFactory.getDefaultKeys() made sense in sshd 2.0.0,
+			// but sshd 2.2.0 added the SessionContext, which although good
+			// (without it we couldn't check here) breaks the Iterable analogy.
+			// But we're stuck now with that interface for getDefaultKeys, and
+			// so this override throwing an exception is unfortunately needed.
+			throw new UnsupportedOperationException();
+		}
+
+		@Override
+		public Iterable<KeyPair> loadKeys(SessionContext session)
+				throws IOException, GeneralSecurityException {
+			if (!TEST_USER.equals(session.getUsername())) {
+				return Collections.emptyList();
+			}
+			SshdSocketAddress remoteAddress = SshdSocketAddress
+					.toSshdSocketAddress(session.getRemoteAddress());
+			switch (remoteAddress.getHostName()) {
+			case "localhost":
+			case "127.0.0.1":
+				return Collections.singletonList(testUserKey);
+			default:
+				return Collections.emptyList();
+			}
+		}
+	}
+
+	@After
+	public void cleanUp() {
+		testServerKey = null;
+		testUserKey = null;
+	}
+
+	@Override
+	protected void installConfig(String... config) {
+		File configFile = new File(sshDir, Constants.CONFIG);
+		if (config != null) {
+			try {
+				Files.write(configFile.toPath(), Arrays.asList(config));
+			} catch (IOException e) {
+				throw new UncheckedIOException(e);
+			}
+		}
+	}
+
+	private KeyPair load(Path path) throws Exception {
+		try (InputStream in = Files.newInputStream(path)) {
+			return SecurityUtils
+					.loadKeyPairIdentities(null,
+							NamedResource.ofName(path.toString()), in, null)
+					.iterator().next();
+		}
+	}
+
+	@Test
+	public void testCloneWithBuiltInKeys() throws Exception {
+		// This test should fail unless our in-memory setup is taken: no
+		// known_hosts file, and a config that specifies a non-existing key.
+		File newHostKey = new File(getTemporaryDirectory(), "newhostkey");
+		copyTestResource("id_ed25519", newHostKey);
+		server.addHostKey(newHostKey.toPath(), true);
+		testServerKey = load(newHostKey.toPath()).getPublic();
+		assertTrue(newHostKey.delete());
+		testUserKey = load(privateKey1.getAbsoluteFile().toPath());
+		assertNotNull(testServerKey);
+		assertNotNull(testUserKey);
+		cloneWith(
+				"ssh://" + TEST_USER + "@localhost:" + testPort
+						+ "/doesntmatter",
+				new File(getTemporaryDirectory(), "cloned"), null, //
+				"Host localhost", //
+				"IdentityFile "
+						+ new File(sshDir, "does_not_exist").getAbsolutePath());
+	}
+
+}
diff --git a/org.eclipse.jgit.ssh.apache/META-INF/MANIFEST.MF b/org.eclipse.jgit.ssh.apache/META-INF/MANIFEST.MF
index 1054cec..6a11b18 100644
--- a/org.eclipse.jgit.ssh.apache/META-INF/MANIFEST.MF
+++ b/org.eclipse.jgit.ssh.apache/META-INF/MANIFEST.MF
@@ -3,11 +3,12 @@
 Bundle-Name: %Bundle-Name
 Automatic-Module-Name: org.eclipse.jgit.ssh.apache
 Bundle-SymbolicName: org.eclipse.jgit.ssh.apache
-Bundle-Vendor: %Provider-Name
+Bundle-Vendor: %Bundle-Vendor
+Bundle-Localization: plugin
 Bundle-ActivationPolicy: lazy
-Bundle-Version: 5.4.4.qualifier
+Bundle-Version: 5.5.2.qualifier
 Bundle-RequiredExecutionEnvironment: JavaSE-1.8
-Export-Package: org.eclipse.jgit.internal.transport.sshd;version="5.4.4";x-internal:=true;
+Export-Package: org.eclipse.jgit.internal.transport.sshd;version="5.5.2";x-internal:=true;
   uses:="org.apache.sshd.client,
    org.apache.sshd.client.auth,
    org.apache.sshd.client.auth.keyboard,
@@ -22,9 +23,9 @@
    org.apache.sshd.common.signature,
    org.apache.sshd.common.util.buffer,
    org.eclipse.jgit.transport",
- org.eclipse.jgit.internal.transport.sshd.auth;version="5.4.4";x-internal:=true,
- org.eclipse.jgit.internal.transport.sshd.proxy;version="5.4.4";x-friends:="org.eclipse.jgit.ssh.apache.test",
- org.eclipse.jgit.transport.sshd;version="5.4.4";
+ org.eclipse.jgit.internal.transport.sshd.auth;version="5.5.2";x-internal:=true,
+ org.eclipse.jgit.internal.transport.sshd.proxy;version="5.5.2";x-friends:="org.eclipse.jgit.ssh.apache.test",
+ org.eclipse.jgit.transport.sshd;version="5.5.2";
   uses:="org.eclipse.jgit.transport,
    org.apache.sshd.client.config.hosts,
    org.apache.sshd.common.keyprovider,
@@ -74,12 +75,12 @@
  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.4,5.5.0)",
- org.eclipse.jgit.errors;version="[5.4.4,5.5.0)",
- org.eclipse.jgit.fnmatch;version="[5.4.4,5.5.0)",
- org.eclipse.jgit.internal.storage.file;version="[5.4.4,5.5.0)",
- org.eclipse.jgit.internal.transport.ssh;version="[5.4.4,5.5.0)",
- org.eclipse.jgit.nls;version="[5.4.4,5.5.0)",
- org.eclipse.jgit.transport;version="[5.4.4,5.5.0)",
- org.eclipse.jgit.util;version="[5.4.4,5.5.0)",
+ org.eclipse.jgit.annotations;version="[5.5.2,5.6.0)",
+ org.eclipse.jgit.errors;version="[5.5.2,5.6.0)",
+ org.eclipse.jgit.fnmatch;version="[5.5.2,5.6.0)",
+ org.eclipse.jgit.internal.storage.file;version="[5.5.2,5.6.0)",
+ org.eclipse.jgit.internal.transport.ssh;version="[5.5.2,5.6.0)",
+ org.eclipse.jgit.nls;version="[5.5.2,5.6.0)",
+ org.eclipse.jgit.transport;version="[5.5.2,5.6.0)",
+ org.eclipse.jgit.util;version="[5.5.2,5.6.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 3df5ff0..8991b5b 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-Name: org.eclipse.jgit.ssh.apache - Sources
 Bundle-SymbolicName: org.eclipse.jgit.ssh.apache.source
 Bundle-Vendor: Eclipse.org - JGit
-Bundle-Version: 5.4.4.qualifier
-Eclipse-SourceBundle: org.eclipse.jgit.ssh.apache;version="5.4.4.qualifier";roots="."
+Bundle-Version: 5.5.2.qualifier
+Eclipse-SourceBundle: org.eclipse.jgit.ssh.apache;version="5.5.2.qualifier";roots="."
diff --git a/org.eclipse.jgit.ssh.apache/plugin.properties b/org.eclipse.jgit.ssh.apache/plugin.properties
index 8f3540c..8358cc1 100644
--- a/org.eclipse.jgit.ssh.apache/plugin.properties
+++ b/org.eclipse.jgit.ssh.apache/plugin.properties
@@ -1,2 +1,2 @@
-plugin_name=JGit SSH support based on Apache MINA sshd
-provider_name=Eclipse JGit
+Bundle-Name=JGit SSH support based on Apache MINA sshd
+Bundle-Vendor=Eclipse JGit
diff --git a/org.eclipse.jgit.ssh.apache/pom.xml b/org.eclipse.jgit.ssh.apache/pom.xml
index bb21214..f412d63 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.4.4-SNAPSHOT</version>
+    <version>5.5.2-SNAPSHOT</version>
   </parent>
 
   <artifactId>org.eclipse.jgit.ssh.apache</artifactId>
diff --git a/org.eclipse.jgit.ssh.apache/resources/org/eclipse/jgit/internal/transport/sshd/SshdText.properties b/org.eclipse.jgit.ssh.apache/resources/org/eclipse/jgit/internal/transport/sshd/SshdText.properties
index bdb4a7d..4f85ebe 100644
--- a/org.eclipse.jgit.ssh.apache/resources/org/eclipse/jgit/internal/transport/sshd/SshdText.properties
+++ b/org.eclipse.jgit.ssh.apache/resources/org/eclipse/jgit/internal/transport/sshd/SshdText.properties
@@ -71,6 +71,9 @@
 proxySocksUnexpectedMessage=Unexpected message received from SOCKS5 proxy {0}; client state {1}: {2}
 proxySocksUnexpectedVersion=Expected SOCKS version 5, got {0}
 proxySocksUsernameTooLong=User name for proxy {0} must be at most 255 bytes long, is {1} bytes: {2}
+serverIdNotReceived=No server identification received within {0} bytes
+serverIdTooLong=Server identification is longer than 255 characters (including line ending): {0}
+serverIdWithNul=Server identification contains a NUL character: {0}
 sessionCloseFailed=Closing the session failed
 sshClosingDown=Apache MINA sshd session factory is closing down; cannot create new ssh sessions on this factory
 sshCommandTimeout={0} timed out after {1} seconds while opening the channel
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 56f8ade..1954abc 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
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2018, Thomas Wolf <thomas.wolf@paranor.ch>
+ * Copyright (C) 2018, 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
@@ -46,6 +46,7 @@
 
 import java.io.IOException;
 import java.net.SocketAddress;
+import java.nio.charset.StandardCharsets;
 import java.security.GeneralSecurityException;
 import java.security.PublicKey;
 import java.util.ArrayList;
@@ -56,15 +57,16 @@
 
 import org.apache.sshd.client.ClientFactoryManager;
 import org.apache.sshd.client.config.hosts.HostConfigEntry;
-import org.apache.sshd.client.keyverifier.KnownHostsServerKeyVerifier.HostEntryPair;
 import org.apache.sshd.client.keyverifier.ServerKeyVerifier;
 import org.apache.sshd.client.session.ClientSessionImpl;
 import org.apache.sshd.common.FactoryManager;
+import org.apache.sshd.common.PropertyResolverUtils;
 import org.apache.sshd.common.SshException;
 import org.apache.sshd.common.config.keys.KeyUtils;
 import org.apache.sshd.common.io.IoSession;
 import org.apache.sshd.common.io.IoWriteFuture;
 import org.apache.sshd.common.util.Readable;
+import org.apache.sshd.common.util.buffer.Buffer;
 import org.eclipse.jgit.errors.InvalidPatternException;
 import org.eclipse.jgit.fnmatch.FileNameMatcher;
 import org.eclipse.jgit.internal.transport.sshd.proxy.StatefulProxyConnector;
@@ -82,11 +84,20 @@
  */
 public class JGitClientSession extends ClientSessionImpl {
 
+	/**
+	 * Default setting for the maximum number of bytes to read in the initial
+	 * protocol version exchange. 64kb is what OpenSSH < 8.0 read; OpenSSH 8.0
+	 * changed it to 8Mb, but that seems excessive for the purpose stated in RFC
+	 * 4253. The Apache MINA sshd default in
+	 * {@link FactoryManager#DEFAULT_MAX_IDENTIFICATION_SIZE} is 16kb.
+	 */
+	private static final int DEFAULT_MAX_IDENTIFICATION_SIZE = 64 * 1024;
+
 	private HostConfigEntry hostConfig;
 
 	private CredentialsProvider credentialsProvider;
 
-	private StatefulProxyConnector proxyHandler;
+	private volatile StatefulProxyConnector proxyHandler;
 
 	/**
 	 * @param manager
@@ -281,11 +292,10 @@
 		if (verifier instanceof ServerKeyLookup) {
 			SocketAddress remoteAddress = resolvePeerAddress(
 					resolveAttribute(JGitSshClient.ORIGINAL_REMOTE_ADDRESS));
-			List<HostEntryPair> allKnownKeys = ((ServerKeyLookup) verifier)
+			List<PublicKey> allKnownKeys = ((ServerKeyLookup) verifier)
 					.lookup(this, remoteAddress);
 			Set<String> reordered = new LinkedHashSet<>();
-			for (HostEntryPair h : allKnownKeys) {
-				PublicKey key = h.getServerKey();
+			for (PublicKey key : allKnownKeys) {
 				if (key != null) {
 					String keyType = KeyUtils.getKeyType(key);
 					if (keyType != null) {
@@ -332,4 +342,123 @@
 		return newNames;
 	}
 
+	@Override
+	protected boolean readIdentification(Buffer buffer) throws IOException {
+		// Propagate a failure from doReadIdentification.
+		// TODO: remove for sshd > 2.3.0; its doReadIdentification throws
+		// StreamCorruptedException instead of IllegalStateException.
+		try {
+			return super.readIdentification(buffer);
+		} catch (IllegalStateException e) {
+			throw new IOException(e.getLocalizedMessage(), e);
+		}
+	}
+
+	/**
+	 * Reads the RFC 4253, section 4.2 protocol version identification. The
+	 * Apache MINA sshd default implementation checks for NUL bytes also in any
+	 * preceding lines, whereas RFC 4253 requires such a check only for the
+	 * actual identification string starting with "SSH-". Likewise, the 255
+	 * character limit exists only for the identification string, not for the
+	 * preceding lines. CR-LF handling is also relaxed.
+	 *
+	 * @param buffer
+	 *            to read from
+	 * @param server
+	 *            whether we're an SSH server (should always be {@code false})
+	 * @return the lines read, with the server identification line last, or
+	 *         {@code null} if no identification line was found and more bytes
+	 *         are needed
+	 *
+	 * @see <a href="https://tools.ietf.org/html/rfc4253#section-4.2">RFC 4253,
+	 *      section 4.2</a>
+	 */
+	@Override
+	protected List<String> doReadIdentification(Buffer buffer, boolean server) {
+		if (server) {
+			// Should never happen. No translation; internal bug.
+			throw new IllegalStateException(
+					"doReadIdentification of client called with server=true"); //$NON-NLS-1$
+		}
+		int maxIdentSize = PropertyResolverUtils.getIntProperty(this,
+				FactoryManager.MAX_IDENTIFICATION_SIZE,
+				DEFAULT_MAX_IDENTIFICATION_SIZE);
+		int current = buffer.rpos();
+		int end = current + buffer.available();
+		if (current >= end) {
+			return null;
+		}
+		byte[] raw = buffer.array();
+		List<String> ident = new ArrayList<>();
+		int start = current;
+		boolean hasNul = false;
+		for (int i = current; i < end; i++) {
+			switch (raw[i]) {
+			case 0:
+				hasNul = true;
+				break;
+			case '\n':
+				int eol = 1;
+				if (i > start && raw[i - 1] == '\r') {
+					eol++;
+				}
+				String line = new String(raw, start, i + 1 - eol - start,
+						StandardCharsets.UTF_8);
+				start = i + 1;
+				if (log.isDebugEnabled()) {
+					log.debug(format("doReadIdentification({0}) line: ", this) + //$NON-NLS-1$
+							escapeControls(line));
+				}
+				ident.add(line);
+				if (line.startsWith("SSH-")) { //$NON-NLS-1$
+					if (hasNul) {
+						throw new IllegalStateException(
+								format(SshdText.get().serverIdWithNul,
+										escapeControls(line)));
+					}
+					if (line.length() + eol > 255) {
+						throw new IllegalStateException(
+								format(SshdText.get().serverIdTooLong,
+										escapeControls(line)));
+					}
+					buffer.rpos(start);
+					return ident;
+				}
+				// If this were a server, we could throw an exception here: a
+				// client is not supposed to send any extra lines before its
+				// identification string.
+				hasNul = false;
+				break;
+			default:
+				break;
+			}
+			if (i - current + 1 >= maxIdentSize) {
+				String msg = format(SshdText.get().serverIdNotReceived,
+						Integer.toString(maxIdentSize));
+				if (log.isDebugEnabled()) {
+					log.debug(msg);
+					log.debug(buffer.toHex());
+				}
+				throw new IllegalStateException(msg);
+			}
+		}
+		// Need more data
+		return null;
+	}
+
+	private static String escapeControls(String s) {
+		StringBuilder b = new StringBuilder();
+		int l = s.length();
+		for (int i = 0; i < l; i++) {
+			char ch = s.charAt(i);
+			if (Character.isISOControl(ch)) {
+				b.append(ch <= 0xF ? "\\u000" : "\\u00") //$NON-NLS-1$ //$NON-NLS-2$
+						.append(Integer.toHexString(ch));
+			} else {
+				b.append(ch);
+			}
+		}
+		return b.toString();
+	}
+
 }
diff --git a/org.eclipse.jgit.ssh.apache/src/org/eclipse/jgit/internal/transport/sshd/JGitServerKeyVerifier.java b/org.eclipse.jgit.ssh.apache/src/org/eclipse/jgit/internal/transport/sshd/JGitServerKeyVerifier.java
new file mode 100644
index 0000000..b94515c
--- /dev/null
+++ b/org.eclipse.jgit.ssh.apache/src/org/eclipse/jgit/internal/transport/sshd/JGitServerKeyVerifier.java
@@ -0,0 +1,190 @@
+/*
+ * 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.internal.transport.sshd;
+
+import static org.eclipse.jgit.internal.transport.ssh.OpenSshConfigFile.flag;
+
+import java.net.InetSocketAddress;
+import java.net.SocketAddress;
+import java.security.PublicKey;
+import java.util.Collections;
+import java.util.List;
+import java.util.Locale;
+
+import org.apache.sshd.client.config.hosts.HostConfigEntry;
+import org.apache.sshd.client.config.hosts.KnownHostHashValue;
+import org.apache.sshd.client.keyverifier.ServerKeyVerifier;
+import org.apache.sshd.client.session.ClientSession;
+import org.apache.sshd.common.util.net.SshdSocketAddress;
+import org.eclipse.jgit.annotations.NonNull;
+import org.eclipse.jgit.transport.CredentialsProvider;
+import org.eclipse.jgit.transport.SshConstants;
+import org.eclipse.jgit.transport.sshd.ServerKeyDatabase;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * A bridge between the {@link ServerKeyVerifier} from Apache MINA sshd and our
+ * {@link ServerKeyDatabase}.
+ */
+public class JGitServerKeyVerifier
+		implements ServerKeyVerifier, ServerKeyLookup {
+
+	private static final Logger LOG = LoggerFactory
+			.getLogger(JGitServerKeyVerifier.class);
+
+	private final @NonNull ServerKeyDatabase database;
+
+	/**
+	 * Creates a new {@link JGitServerKeyVerifier} using the given
+	 * {@link ServerKeyDatabase}.
+	 *
+	 * @param database
+	 *            to use
+	 */
+	public JGitServerKeyVerifier(@NonNull ServerKeyDatabase database) {
+		this.database = database;
+	}
+
+	@Override
+	public List<PublicKey> lookup(ClientSession session,
+			SocketAddress remoteAddress) {
+		if (!(session instanceof JGitClientSession)) {
+			LOG.warn("Internal error: wrong session kind: " //$NON-NLS-1$
+					+ session.getClass().getName());
+			return Collections.emptyList();
+		}
+		if (!(remoteAddress instanceof InetSocketAddress)) {
+			return Collections.emptyList();
+		}
+		SessionConfig config = new SessionConfig((JGitClientSession) session);
+		SshdSocketAddress connectAddress = SshdSocketAddress
+				.toSshdSocketAddress(session.getConnectAddress());
+		String connect = KnownHostHashValue.createHostPattern(
+				connectAddress.getHostName(), connectAddress.getPort());
+		return database.lookup(connect, (InetSocketAddress) remoteAddress,
+				config);
+	}
+
+	@Override
+	public boolean verifyServerKey(ClientSession session,
+			SocketAddress remoteAddress, PublicKey serverKey) {
+		if (!(session instanceof JGitClientSession)) {
+			LOG.warn("Internal error: wrong session kind: " //$NON-NLS-1$
+					+ session.getClass().getName());
+			return false;
+		}
+		if (!(remoteAddress instanceof InetSocketAddress)) {
+			return false;
+		}
+		SessionConfig config = new SessionConfig((JGitClientSession) session);
+		SshdSocketAddress connectAddress = SshdSocketAddress
+				.toSshdSocketAddress(session.getConnectAddress());
+		String connect = KnownHostHashValue.createHostPattern(
+				connectAddress.getHostName(), connectAddress.getPort());
+		CredentialsProvider provider = ((JGitClientSession) session)
+				.getCredentialsProvider();
+		return database.accept(connect, (InetSocketAddress) remoteAddress,
+				serverKey, config, provider);
+	}
+
+	private static class SessionConfig
+			implements ServerKeyDatabase.Configuration {
+
+		private final JGitClientSession session;
+
+		public SessionConfig(JGitClientSession session) {
+			this.session = session;
+		}
+
+		private List<String> get(String key) {
+			HostConfigEntry entry = session.getHostConfigEntry();
+			if (entry instanceof JGitHostConfigEntry) {
+				// Always true!
+				return ((JGitHostConfigEntry) entry).getMultiValuedOptions()
+						.get(key);
+			}
+			return Collections.emptyList();
+		}
+
+		@Override
+		public List<String> getUserKnownHostsFiles() {
+			return get(SshConstants.USER_KNOWN_HOSTS_FILE);
+		}
+
+		@Override
+		public List<String> getGlobalKnownHostsFiles() {
+			return get(SshConstants.GLOBAL_KNOWN_HOSTS_FILE);
+		}
+
+		@Override
+		public StrictHostKeyChecking getStrictHostKeyChecking() {
+			HostConfigEntry entry = session.getHostConfigEntry();
+			String value = entry
+					.getProperty(SshConstants.STRICT_HOST_KEY_CHECKING, "ask"); //$NON-NLS-1$
+			switch (value.toLowerCase(Locale.ROOT)) {
+			case SshConstants.YES:
+			case SshConstants.ON:
+				return StrictHostKeyChecking.REQUIRE_MATCH;
+			case SshConstants.NO:
+			case SshConstants.OFF:
+				return StrictHostKeyChecking.ACCEPT_ANY;
+			case "accept-new": //$NON-NLS-1$
+				return StrictHostKeyChecking.ACCEPT_NEW;
+			default:
+				return StrictHostKeyChecking.ASK;
+			}
+		}
+
+		@Override
+		public boolean getHashKnownHosts() {
+			HostConfigEntry entry = session.getHostConfigEntry();
+			return flag(entry.getProperty(SshConstants.HASH_KNOWN_HOSTS));
+		}
+
+		@Override
+		public String getUsername() {
+			return session.getUsername();
+		}
+	}
+}
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 98e71df..377eabb 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
@@ -177,6 +177,10 @@
 			return remoteAddress;
 		}
 		InetSocketAddress address = (InetSocketAddress) proxy.address();
+		if (address.isUnresolved()) {
+			address = new InetSocketAddress(address.getHostName(),
+					address.getPort());
+		}
 		switch (proxy.type()) {
 		case HTTP:
 			setClientProxyConnector(
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 6468b3e..54a2a05 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
@@ -83,7 +83,9 @@
  */
 public class JGitSshConfig implements HostConfigEntryResolver {
 
-	private OpenSshConfigFile configFile;
+	private final OpenSshConfigFile configFile;
+
+	private final String localUserName;
 
 	/**
 	 * Creates a new {@link OpenSshConfigFile} that will read the config from
@@ -92,20 +94,22 @@
 	 * @param home
 	 *            user's home directory for the purpose of ~ replacement
 	 * @param config
-	 *            file to load.
+	 *            file to load; may be {@code null} if no ssh config file
+	 *            handling is desired
 	 * @param localUserName
 	 *            user name of the current user on the local host OS
 	 */
-	public JGitSshConfig(@NonNull File home, @NonNull File config,
+	public JGitSshConfig(@NonNull File home, File config,
 			@NonNull String localUserName) {
-		configFile = new OpenSshConfigFile(home, config, localUserName);
+		this.localUserName = localUserName;
+		configFile = config == null ?  null : new OpenSshConfigFile(home, config, localUserName);
 	}
 
 	@Override
 	public HostConfigEntry resolveEffectiveHost(String host, int port,
 			SocketAddress localAddress, String username,
 			AttributeRepository attributes) throws IOException {
-		HostEntry entry = configFile.lookup(host, port, username);
+		HostEntry entry = configFile == null ? new HostEntry() : configFile.lookup(host, port, username);
 		JGitHostConfigEntry config = new JGitHostConfigEntry();
 		// Apache MINA conflates all keys, even multi-valued ones, in one map
 		// and puts multiple values separated by commas in one string. See
@@ -131,7 +135,7 @@
 		String user = username != null && !username.isEmpty() ? username
 				: entry.getValue(SshConstants.USER);
 		if (user == null || user.isEmpty()) {
-			user = configFile.getLocalUserName();
+			user = localUserName;
 		}
 		config.setUsername(user);
 		config.setProperty(SshConstants.USER, user);
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/OpenSshServerKeyDatabase.java
similarity index 67%
rename from org.eclipse.jgit.ssh.apache/src/org/eclipse/jgit/internal/transport/sshd/OpenSshServerKeyVerifier.java
rename to org.eclipse.jgit.ssh.apache/src/org/eclipse/jgit/internal/transport/sshd/OpenSshServerKeyDatabase.java
index 381f7cf..f4849ce 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/OpenSshServerKeyDatabase.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2018, Thomas Wolf <thomas.wolf@paranor.ch>
+ * Copyright (C) 2018, 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
@@ -47,7 +47,6 @@
 
 import java.io.BufferedReader;
 import java.io.BufferedWriter;
-import java.io.File;
 import java.io.FileNotFoundException;
 import java.io.IOException;
 import java.io.OutputStreamWriter;
@@ -59,34 +58,39 @@
 import java.nio.file.Paths;
 import java.security.GeneralSecurityException;
 import java.security.PublicKey;
+import java.security.SecureRandom;
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.Collection;
 import java.util.Collections;
 import java.util.LinkedList;
 import java.util.List;
-import java.util.Locale;
 import java.util.Map;
+import java.util.TreeSet;
 import java.util.concurrent.ConcurrentHashMap;
 import java.util.function.Supplier;
 
-import org.apache.sshd.client.config.hosts.HostConfigEntry;
+import org.apache.sshd.client.config.hosts.HostPatternsHolder;
+import org.apache.sshd.client.config.hosts.KnownHostDigest;
 import org.apache.sshd.client.config.hosts.KnownHostEntry;
-import org.apache.sshd.client.keyverifier.KnownHostsServerKeyVerifier;
+import org.apache.sshd.client.config.hosts.KnownHostHashValue;
 import org.apache.sshd.client.keyverifier.KnownHostsServerKeyVerifier.HostEntryPair;
-import org.apache.sshd.client.keyverifier.ServerKeyVerifier;
 import org.apache.sshd.client.session.ClientSession;
+import org.apache.sshd.common.NamedFactory;
 import org.apache.sshd.common.config.keys.AuthorizedKeyEntry;
 import org.apache.sshd.common.config.keys.KeyUtils;
+import org.apache.sshd.common.config.keys.PublicKeyEntry;
 import org.apache.sshd.common.config.keys.PublicKeyEntryResolver;
 import org.apache.sshd.common.digest.BuiltinDigests;
+import org.apache.sshd.common.mac.Mac;
 import org.apache.sshd.common.util.io.ModifiableFileWatcher;
 import org.apache.sshd.common.util.net.SshdSocketAddress;
+import org.eclipse.jgit.annotations.NonNull;
 import org.eclipse.jgit.internal.storage.file.LockFile;
 import org.eclipse.jgit.transport.CredentialItem;
 import org.eclipse.jgit.transport.CredentialsProvider;
-import org.eclipse.jgit.transport.SshConstants;
 import org.eclipse.jgit.transport.URIish;
+import org.eclipse.jgit.transport.sshd.ServerKeyDatabase;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -148,14 +152,14 @@
  * @see <a href="http://man.openbsd.org/OpenBSD-current/man5/ssh_config.5">man
  *      ssh-config</a>
  */
-public class OpenSshServerKeyVerifier
-		implements ServerKeyVerifier, ServerKeyLookup {
+public class OpenSshServerKeyDatabase
+		implements ServerKeyDatabase {
 
 	// TODO: GlobalKnownHostsFile? May need some kind of LRU caching; these
 	// files may be large!
 
 	private static final Logger LOG = LoggerFactory
-			.getLogger(OpenSshServerKeyVerifier.class);
+			.getLogger(OpenSshServerKeyDatabase.class);
 
 	/** Can be used to mark revoked known host lines. */
 	private static final String MARKER_REVOKED = "revoked"; //$NON-NLS-1$
@@ -166,12 +170,8 @@
 
 	private final List<HostKeyFile> defaultFiles = new ArrayList<>();
 
-	private enum ModifiedKeyHandling {
-		DENY, ALLOW, ALLOW_AND_STORE
-	}
-
 	/**
-	 * Creates a new {@link OpenSshServerKeyVerifier}.
+	 * Creates a new {@link OpenSshServerKeyDatabase}.
 	 *
 	 * @param askAboutNewFile
 	 *            whether to ask the user, if possible, about creating a new
@@ -181,7 +181,7 @@
 	 *            empty or {@code null}, in which case no default files are
 	 *            installed. The files need not exist.
 	 */
-	public OpenSshServerKeyVerifier(boolean askAboutNewFile,
+	public OpenSshServerKeyDatabase(boolean askAboutNewFile,
 			List<Path> defaultFiles) {
 		if (defaultFiles != null) {
 			for (Path file : defaultFiles) {
@@ -193,38 +193,30 @@
 		this.askAboutNewFile = askAboutNewFile;
 	}
 
-	private List<HostKeyFile> getFilesToUse(ClientSession session) {
+	private List<HostKeyFile> getFilesToUse(@NonNull Configuration config) {
 		List<HostKeyFile> filesToUse = defaultFiles;
-		if (session instanceof JGitClientSession) {
-			HostConfigEntry entry = ((JGitClientSession) session)
-					.getHostConfigEntry();
-			if (entry instanceof JGitHostConfigEntry) {
-				// Always true!
-				List<HostKeyFile> userFiles = addUserHostKeyFiles(
-						((JGitHostConfigEntry) entry).getMultiValuedOptions()
-								.get(SshConstants.USER_KNOWN_HOSTS_FILE));
-				if (!userFiles.isEmpty()) {
-					filesToUse = userFiles;
-				}
-			}
+		List<HostKeyFile> userFiles = addUserHostKeyFiles(
+				config.getUserKnownHostsFiles());
+		if (!userFiles.isEmpty()) {
+			filesToUse = userFiles;
 		}
 		return filesToUse;
 	}
 
 	@Override
-	public List<HostEntryPair> lookup(ClientSession session,
-			SocketAddress remote) {
-		List<HostKeyFile> filesToUse = getFilesToUse(session);
-		HostKeyHelper helper = new HostKeyHelper();
-		List<HostEntryPair> result = new ArrayList<>();
-		Collection<SshdSocketAddress> candidates = helper
-				.resolveHostNetworkIdentities(session, remote);
+	public List<PublicKey> lookup(@NonNull String connectAddress,
+			@NonNull InetSocketAddress remoteAddress,
+			@NonNull Configuration config) {
+		List<HostKeyFile> filesToUse = getFilesToUse(config);
+		List<PublicKey> result = new ArrayList<>();
+		Collection<SshdSocketAddress> candidates = getCandidates(
+				connectAddress, remoteAddress);
 		for (HostKeyFile file : filesToUse) {
 			for (HostEntryPair current : file.get()) {
 				KnownHostEntry entry = current.getHostEntry();
 				for (SshdSocketAddress host : candidates) {
 					if (entry.isHostMatch(host.getHostName(), host.getPort())) {
-						result.add(current);
+						result.add(current.getServerKey());
 						break;
 					}
 				}
@@ -234,22 +226,23 @@
 	}
 
 	@Override
-	public boolean verifyServerKey(ClientSession clientSession,
-			SocketAddress remoteAddress, PublicKey serverKey) {
-		List<HostKeyFile> filesToUse = getFilesToUse(clientSession);
-		AskUser ask = new AskUser();
+	public boolean accept(@NonNull String connectAddress,
+			@NonNull InetSocketAddress remoteAddress,
+			@NonNull PublicKey serverKey,
+			@NonNull Configuration config, CredentialsProvider provider) {
+		List<HostKeyFile> filesToUse = getFilesToUse(config);
+		AskUser ask = new AskUser(config, provider);
 		HostEntryPair[] modified = { null };
 		Path path = null;
-		HostKeyHelper helper = new HostKeyHelper();
+		Collection<SshdSocketAddress> candidates = getCandidates(connectAddress,
+				remoteAddress);
 		for (HostKeyFile file : filesToUse) {
 			try {
-				if (find(clientSession, remoteAddress, serverKey, file.get(),
-						modified, helper)) {
+				if (find(candidates, serverKey, file.get(), modified)) {
 					return true;
 				}
 			} catch (RevokedKeyException e) {
-				ask.revokedKey(clientSession, remoteAddress, serverKey,
-						file.getPath());
+				ask.revokedKey(remoteAddress, serverKey, file.getPath());
 				return false;
 			}
 			if (path == null && modified[0] != null) {
@@ -260,20 +253,19 @@
 		}
 		if (modified[0] != null) {
 			// We found an entry, but with a different key
-			ModifiedKeyHandling toDo = ask.acceptModifiedServerKey(
-					clientSession, remoteAddress, modified[0].getServerKey(),
+			AskUser.ModifiedKeyHandling toDo = ask.acceptModifiedServerKey(
+					remoteAddress, modified[0].getServerKey(),
 					serverKey, path);
-			if (toDo == ModifiedKeyHandling.ALLOW_AND_STORE) {
+			if (toDo == AskUser.ModifiedKeyHandling.ALLOW_AND_STORE) {
 				try {
-					updateModifiedServerKey(clientSession, remoteAddress,
-							serverKey, modified[0], path, helper);
+					updateModifiedServerKey(serverKey, modified[0], path);
 					knownHostsFiles.get(path).resetReloadAttributes();
 				} catch (IOException e) {
 					LOG.warn(format(SshdText.get().knownHostsCouldNotUpdate,
 							path));
 				}
 			}
-			if (toDo == ModifiedKeyHandling.DENY) {
+			if (toDo == AskUser.ModifiedKeyHandling.DENY) {
 				return false;
 			}
 			// TODO: OpenSsh disables password and keyboard-interactive
@@ -281,18 +273,20 @@
 			// are switched off. (Plus a few other things such as X11 forwarding
 			// that are of no interest to a git client.)
 			return true;
-		} else if (ask.acceptUnknownKey(clientSession, remoteAddress,
-				serverKey)) {
+		} else if (ask.acceptUnknownKey(remoteAddress, serverKey)) {
 			if (!filesToUse.isEmpty()) {
 				HostKeyFile toUpdate = filesToUse.get(0);
 				path = toUpdate.getPath();
 				try {
-					updateKnownHostsFile(clientSession, remoteAddress,
-							serverKey, path, helper);
-					toUpdate.resetReloadAttributes();
-				} catch (IOException e) {
+					if (Files.exists(path) || !askAboutNewFile
+							|| ask.createNewFile(path)) {
+						updateKnownHostsFile(candidates, serverKey, path,
+								config);
+						toUpdate.resetReloadAttributes();
+					}
+				} catch (Exception e) {
 					LOG.warn(format(SshdText.get().knownHostsCouldNotUpdate,
-							path));
+							path), e);
 				}
 			}
 			return true;
@@ -304,12 +298,9 @@
 		private static final long serialVersionUID = 1L;
 	}
 
-	private boolean find(ClientSession clientSession,
-			SocketAddress remoteAddress, PublicKey serverKey,
-			List<HostEntryPair> entries, HostEntryPair[] modified,
-			HostKeyHelper helper) throws RevokedKeyException {
-		Collection<SshdSocketAddress> candidates = helper
-				.resolveHostNetworkIdentities(clientSession, remoteAddress);
+	private boolean find(Collection<SshdSocketAddress> candidates,
+			PublicKey serverKey, List<HostEntryPair> entries,
+			HostEntryPair[] modified) throws RevokedKeyException {
 		for (HostEntryPair current : entries) {
 			KnownHostEntry entry = current.getHostEntry();
 			for (SshdSocketAddress host : candidates) {
@@ -355,33 +346,13 @@
 		return userFiles;
 	}
 
-	private void updateKnownHostsFile(ClientSession clientSession,
-			SocketAddress remoteAddress, PublicKey serverKey, Path path,
-			HostKeyHelper updater)
-			throws IOException {
-		KnownHostEntry entry = updater.prepareKnownHostEntry(clientSession,
-				remoteAddress, serverKey);
-		if (entry == null) {
+	private void updateKnownHostsFile(Collection<SshdSocketAddress> candidates,
+			PublicKey serverKey, Path path, Configuration config)
+			throws Exception {
+		String newEntry = createHostKeyLine(candidates, serverKey, config);
+		if (newEntry == null) {
 			return;
 		}
-		if (!Files.exists(path)) {
-			if (askAboutNewFile) {
-				CredentialsProvider provider = getCredentialsProvider(
-						clientSession);
-				if (provider == null) {
-					// We can't ask, so don't create the file
-					return;
-				}
-				URIish uri = new URIish().setPath(path.toString());
-				if (!askUser(provider, uri, //
-						format(SshdText.get().knownHostsUserAskCreationPrompt,
-								path), //
-						format(SshdText.get().knownHostsUserAskCreationMsg,
-								path))) {
-					return;
-				}
-			}
-		}
 		LockFile lock = new LockFile(path.toFile());
 		if (lock.lockForAppend()) {
 			try {
@@ -389,7 +360,7 @@
 						new OutputStreamWriter(lock.getOutputStream(),
 								UTF_8))) {
 					writer.newLine();
-					writer.write(entry.getConfigLine());
+					writer.write(newEntry);
 					writer.newLine();
 				}
 				lock.commit();
@@ -403,15 +374,12 @@
 		}
 	}
 
-	private void updateModifiedServerKey(ClientSession clientSession,
-			SocketAddress remoteAddress, PublicKey serverKey,
-			HostEntryPair entry, Path path, HostKeyHelper helper)
+	private void updateModifiedServerKey(PublicKey serverKey,
+			HostEntryPair entry, Path path)
 			throws IOException {
 		KnownHostEntry hostEntry = entry.getHostEntry();
 		String oldLine = hostEntry.getConfigLine();
-		String newLine = helper.prepareModifiedServerKeyLine(clientSession,
-				remoteAddress, hostEntry, oldLine, entry.getServerKey(),
-				serverKey);
+		String newLine = updateHostKeyLine(oldLine, serverKey);
 		if (newLine == null || newLine.isEmpty()) {
 			return;
 		}
@@ -454,78 +422,65 @@
 		}
 	}
 
-	private static CredentialsProvider getCredentialsProvider(
-			ClientSession session) {
-		if (session instanceof JGitClientSession) {
-			return ((JGitClientSession) session).getCredentialsProvider();
-		}
-		return null;
-	}
-
-	private static boolean askUser(CredentialsProvider provider, URIish uri,
-			String prompt, String... messages) {
-		List<CredentialItem> items = new ArrayList<>(messages.length + 1);
-		for (String message : messages) {
-			items.add(new CredentialItem.InformationalMessage(message));
-		}
-		if (prompt != null) {
-			CredentialItem.YesNoType answer = new CredentialItem.YesNoType(
-					prompt);
-			items.add(answer);
-			return provider.get(uri, items) && answer.getValue();
-		} else {
-			return provider.get(uri, items);
-		}
-	}
-
 	private static class AskUser {
 
+		public enum ModifiedKeyHandling {
+			DENY, ALLOW, ALLOW_AND_STORE
+		}
+
 		private enum Check {
 			ASK, DENY, ALLOW;
 		}
 
-		@SuppressWarnings("nls")
-		private Check checkMode(ClientSession session,
-				SocketAddress remoteAddress, boolean changed) {
+		private final @NonNull Configuration config;
+
+		private final CredentialsProvider provider;
+
+		public AskUser(@NonNull Configuration config,
+				CredentialsProvider provider) {
+			this.config = config;
+			this.provider = provider;
+		}
+
+		private static boolean askUser(CredentialsProvider provider, URIish uri,
+				String prompt, String... messages) {
+			List<CredentialItem> items = new ArrayList<>(messages.length + 1);
+			for (String message : messages) {
+				items.add(new CredentialItem.InformationalMessage(message));
+			}
+			if (prompt != null) {
+				CredentialItem.YesNoType answer = new CredentialItem.YesNoType(
+						prompt);
+				items.add(answer);
+				return provider.get(uri, items) && answer.getValue();
+			} else {
+				return provider.get(uri, items);
+			}
+		}
+
+		private Check checkMode(SocketAddress remoteAddress, boolean changed) {
 			if (!(remoteAddress instanceof InetSocketAddress)) {
 				return Check.DENY;
 			}
-			if (session instanceof JGitClientSession) {
-				HostConfigEntry entry = ((JGitClientSession) session)
-						.getHostConfigEntry();
-				String value = entry.getProperty(
-						SshConstants.STRICT_HOST_KEY_CHECKING, "ask");
-				switch (value.toLowerCase(Locale.ROOT)) {
-				case SshConstants.YES:
-				case SshConstants.ON:
-					return Check.DENY;
-				case SshConstants.NO:
-				case SshConstants.OFF:
-					return Check.ALLOW;
-				case "accept-new":
-					return changed ? Check.DENY : Check.ALLOW;
-				default:
-					break;
-				}
-			}
-			if (getCredentialsProvider(session) == null) {
-				// This is called only for new, unknown hosts. If we have no way
-				// to interact with the user, the fallback mode is to deny the
-				// key.
+			switch (config.getStrictHostKeyChecking()) {
+			case REQUIRE_MATCH:
 				return Check.DENY;
+			case ACCEPT_ANY:
+				return Check.ALLOW;
+			case ACCEPT_NEW:
+				return changed ? Check.DENY : Check.ALLOW;
+			default:
+				return provider == null ? Check.DENY : Check.ASK;
 			}
-			return Check.ASK;
 		}
 
-		public void revokedKey(ClientSession clientSession,
-				SocketAddress remoteAddress, PublicKey serverKey, Path path) {
-			CredentialsProvider provider = getCredentialsProvider(
-					clientSession);
+		public void revokedKey(SocketAddress remoteAddress, PublicKey serverKey,
+				Path path) {
 			if (provider == null) {
 				return;
 			}
 			InetSocketAddress remote = (InetSocketAddress) remoteAddress;
-			URIish uri = JGitUserInteraction.toURI(clientSession.getUsername(),
+			URIish uri = JGitUserInteraction.toURI(config.getUsername(),
 					remote);
 			String sha256 = KeyUtils.getFingerPrint(BuiltinDigests.sha256,
 					serverKey);
@@ -539,14 +494,12 @@
 					md5, sha256);
 		}
 
-		public boolean acceptUnknownKey(ClientSession clientSession,
-				SocketAddress remoteAddress, PublicKey serverKey) {
-			Check check = checkMode(clientSession, remoteAddress, false);
+		public boolean acceptUnknownKey(SocketAddress remoteAddress,
+				PublicKey serverKey) {
+			Check check = checkMode(remoteAddress, false);
 			if (check != Check.ASK) {
 				return check == Check.ALLOW;
 			}
-			CredentialsProvider provider = getCredentialsProvider(
-					clientSession);
 			InetSocketAddress remote = (InetSocketAddress) remoteAddress;
 			// Ask the user
 			String sha256 = KeyUtils.getFingerPrint(BuiltinDigests.sha256,
@@ -554,7 +507,7 @@
 			String md5 = KeyUtils.getFingerPrint(BuiltinDigests.md5, serverKey);
 			String keyAlgorithm = serverKey.getAlgorithm();
 			String remoteHost = remote.getHostString();
-			URIish uri = JGitUserInteraction.toURI(clientSession.getUsername(),
+			URIish uri = JGitUserInteraction.toURI(config.getUsername(),
 					remote);
 			String prompt = SshdText.get().knownHostsUnknownKeyPrompt;
 			return askUser(provider, uri, prompt, //
@@ -566,19 +519,17 @@
 		}
 
 		public ModifiedKeyHandling acceptModifiedServerKey(
-				ClientSession clientSession,
-				SocketAddress remoteAddress, PublicKey expected,
+				InetSocketAddress remoteAddress, PublicKey expected,
 				PublicKey actual, Path path) {
-			Check check = checkMode(clientSession, remoteAddress, true);
+			Check check = checkMode(remoteAddress, true);
 			if (check == Check.ALLOW) {
 				// Never auto-store on CHECK.ALLOW
 				return ModifiedKeyHandling.ALLOW;
 			}
-			InetSocketAddress remote = (InetSocketAddress) remoteAddress;
 			String keyAlgorithm = actual.getAlgorithm();
-			String remoteHost = remote.getHostString();
-			URIish uri = JGitUserInteraction.toURI(clientSession.getUsername(),
-					remote);
+			String remoteHost = remoteAddress.getHostString();
+			URIish uri = JGitUserInteraction.toURI(config.getUsername(),
+					remoteAddress);
 			List<String> messages = new ArrayList<>();
 			String warning = format(
 					SshdText.get().knownHostsModifiedKeyWarning,
@@ -589,8 +540,6 @@
 					KeyUtils.getFingerPrint(BuiltinDigests.sha256, actual));
 			messages.addAll(Arrays.asList(warning.split("\n"))); //$NON-NLS-1$
 
-			CredentialsProvider provider = getCredentialsProvider(
-					clientSession);
 			if (check == Check.DENY) {
 				if (provider != null) {
 					messages.add(format(
@@ -618,6 +567,17 @@
 			return ModifiedKeyHandling.DENY;
 		}
 
+		public boolean createNewFile(Path path) {
+			if (provider == null) {
+				// We can't ask, so don't create the file
+				return false;
+			}
+			URIish uri = new URIish().setPath(path.toString());
+			return askUser(provider, uri, //
+					format(SshdText.get().knownHostsUserAskCreationPrompt,
+							path), //
+					format(SshdText.get().knownHostsUserAskCreationMsg, path));
+		}
 	}
 
 	private static class HostKeyFile extends ModifiableFileWatcher
@@ -694,50 +654,108 @@
 		}
 	}
 
-	// The stuff below is just a hack to avoid having to copy a lot of code from
-	// KnownHostsServerKeyVerifier
-
-	private static class HostKeyHelper extends KnownHostsServerKeyVerifier {
-
-		public HostKeyHelper() {
-			// These two arguments will never be used in any way.
-			super((c, r, s) -> false, new File(".").toPath()); //$NON-NLS-1$
+	private int parsePort(String s) {
+		try {
+			return Integer.parseInt(s);
+		} catch (NumberFormatException e) {
+			return -1;
 		}
+	}
 
-		@Override
-		protected KnownHostEntry prepareKnownHostEntry(
-				ClientSession clientSession, SocketAddress remoteAddress,
-				PublicKey serverKey) throws IOException {
-			// Make this method accessible
-			try {
-				return super.prepareKnownHostEntry(clientSession, remoteAddress,
-						serverKey);
-			} catch (Exception e) {
-				throw new IOException(e.getMessage(), e);
+	private SshdSocketAddress toSshdSocketAddress(@NonNull String address) {
+		String host = null;
+		int port = 0;
+		if (HostPatternsHolder.NON_STANDARD_PORT_PATTERN_ENCLOSURE_START_DELIM == address
+				.charAt(0)) {
+			int end = address.indexOf(
+					HostPatternsHolder.NON_STANDARD_PORT_PATTERN_ENCLOSURE_END_DELIM);
+			if (end <= 1) {
+				return null; // Invalid
+			}
+			host = address.substring(1, end);
+			if (end < address.length() - 1
+					&& HostPatternsHolder.PORT_VALUE_DELIMITER == address
+							.charAt(end + 1)) {
+				port = parsePort(address.substring(end + 2));
+			}
+		} else {
+			int i = address
+					.lastIndexOf(HostPatternsHolder.PORT_VALUE_DELIMITER);
+			if (i > 0) {
+				port = parsePort(address.substring(i + 1));
+				host = address.substring(0, i);
+			} else {
+				host = address;
 			}
 		}
+		if (port < 0 || port > 65535) {
+			return null;
+		}
+		return new SshdSocketAddress(host, port);
+	}
 
-		@Override
-		protected String prepareModifiedServerKeyLine(
-				ClientSession clientSession, SocketAddress remoteAddress,
-				KnownHostEntry entry, String curLine, PublicKey expected,
-				PublicKey actual) throws IOException {
-			// Make this method accessible
-			try {
-				return super.prepareModifiedServerKeyLine(clientSession,
-						remoteAddress, entry, curLine, expected, actual);
-			} catch (Exception e) {
-				throw new IOException(e.getMessage(), e);
+	private Collection<SshdSocketAddress> getCandidates(
+			@NonNull String connectAddress,
+			@NonNull InetSocketAddress remoteAddress) {
+		Collection<SshdSocketAddress> candidates = new TreeSet<>(
+				SshdSocketAddress.BY_HOST_AND_PORT);
+		candidates.add(SshdSocketAddress.toSshdSocketAddress(remoteAddress));
+		SshdSocketAddress address = toSshdSocketAddress(connectAddress);
+		if (address != null) {
+			candidates.add(address);
+		}
+		return candidates;
+	}
+
+	private String createHostKeyLine(Collection<SshdSocketAddress> patterns,
+			PublicKey key, Configuration config) throws Exception {
+		StringBuilder result = new StringBuilder();
+		if (config.getHashKnownHosts()) {
+			// SHA1 is the only algorithm for host name hashing known to OpenSSH
+			// or to Apache MINA sshd.
+			NamedFactory<Mac> digester = KnownHostDigest.SHA1;
+			Mac mac = digester.create();
+			SecureRandom prng = new SecureRandom();
+			byte[] salt = new byte[mac.getDefaultBlockSize()];
+			for (SshdSocketAddress address : patterns) {
+				if (result.length() > 0) {
+					result.append(',');
+				}
+				prng.nextBytes(salt);
+				KnownHostHashValue.append(result, digester, salt,
+						KnownHostHashValue.calculateHashValue(
+								address.getHostName(), address.getPort(), mac,
+								salt));
+			}
+		} else {
+			for (SshdSocketAddress address : patterns) {
+				if (result.length() > 0) {
+					result.append(',');
+				}
+				KnownHostHashValue.appendHostPattern(result,
+						address.getHostName(), address.getPort());
 			}
 		}
+		result.append(' ');
+		PublicKeyEntry.appendPublicKeyEntry(result, key);
+		return result.toString();
+	}
 
-		@Override
-		protected Collection<SshdSocketAddress> resolveHostNetworkIdentities(
-				ClientSession clientSession, SocketAddress remoteAddress) {
-			// Make this method accessible
-			return super.resolveHostNetworkIdentities(clientSession,
-					remoteAddress);
+	private String updateHostKeyLine(String line, PublicKey newKey)
+			throws IOException {
+		// Replaces an existing public key by the new key
+		int pos = line.indexOf(' ');
+		if (pos > 0 && line.charAt(0) == KnownHostEntry.MARKER_INDICATOR) {
+			// We're at the end of the marker. Skip ahead to the next blank.
+			pos = line.indexOf(' ', pos + 1);
 		}
+		if (pos < 0) {
+			// Don't update if bogus format
+			return null;
+		}
+		StringBuilder result = new StringBuilder(line.substring(0, pos + 1));
+		PublicKeyEntry.appendPublicKeyEntry(result, newKey);
+		return result.toString();
 	}
 
 }
diff --git a/org.eclipse.jgit.ssh.apache/src/org/eclipse/jgit/internal/transport/sshd/ServerKeyLookup.java b/org.eclipse.jgit.ssh.apache/src/org/eclipse/jgit/internal/transport/sshd/ServerKeyLookup.java
index 4f5f497..2baeb28 100644
--- a/org.eclipse.jgit.ssh.apache/src/org/eclipse/jgit/internal/transport/sshd/ServerKeyLookup.java
+++ b/org.eclipse.jgit.ssh.apache/src/org/eclipse/jgit/internal/transport/sshd/ServerKeyLookup.java
@@ -43,9 +43,9 @@
 package org.eclipse.jgit.internal.transport.sshd;
 
 import java.net.SocketAddress;
+import java.security.PublicKey;
 import java.util.List;
 
-import org.apache.sshd.client.keyverifier.KnownHostsServerKeyVerifier.HostEntryPair;
 import org.apache.sshd.client.session.ClientSession;
 import org.eclipse.jgit.annotations.NonNull;
 
@@ -55,7 +55,7 @@
 public interface ServerKeyLookup {
 
 	/**
-	 * Retrieves all entries for a given remote address.
+	 * Retrieves all public keys known for a given remote.
 	 *
 	 * @param session
 	 *            needed to determine the config files if specified in the ssh
@@ -65,5 +65,5 @@
 	 * @return a possibly empty list of entries found, including revoked ones
 	 */
 	@NonNull
-	List<HostEntryPair> lookup(ClientSession session, SocketAddress remote);
+	List<PublicKey> lookup(ClientSession session, SocketAddress remote);
 }
diff --git a/org.eclipse.jgit.ssh.apache/src/org/eclipse/jgit/internal/transport/sshd/SshdText.java b/org.eclipse.jgit.ssh.apache/src/org/eclipse/jgit/internal/transport/sshd/SshdText.java
index bf432be..f67170e 100644
--- a/org.eclipse.jgit.ssh.apache/src/org/eclipse/jgit/internal/transport/sshd/SshdText.java
+++ b/org.eclipse.jgit.ssh.apache/src/org/eclipse/jgit/internal/transport/sshd/SshdText.java
@@ -83,6 +83,9 @@
 	/***/ public String proxySocksUnexpectedMessage;
 	/***/ public String proxySocksUnexpectedVersion;
 	/***/ public String proxySocksUsernameTooLong;
+	/***/ public String serverIdNotReceived;
+	/***/ public String serverIdTooLong;
+	/***/ public String serverIdWithNul;
 	/***/ public String sessionCloseFailed;
 	/***/ public String sshClosingDown;
 	/***/ public String sshCommandTimeout;
diff --git a/org.eclipse.jgit.ssh.apache/src/org/eclipse/jgit/transport/sshd/DefaultProxyDataFactory.java b/org.eclipse.jgit.ssh.apache/src/org/eclipse/jgit/transport/sshd/DefaultProxyDataFactory.java
index 97e0da0..66e595c 100644
--- a/org.eclipse.jgit.ssh.apache/src/org/eclipse/jgit/transport/sshd/DefaultProxyDataFactory.java
+++ b/org.eclipse.jgit.ssh.apache/src/org/eclipse/jgit/transport/sshd/DefaultProxyDataFactory.java
@@ -62,8 +62,8 @@
 	public ProxyData get(InetSocketAddress remoteAddress) {
 		try {
 			List<Proxy> proxies = ProxySelector.getDefault()
-					.select(new URI(Proxy.Type.SOCKS.name(),
-							"//" + remoteAddress.getHostString(), null)); //$NON-NLS-1$
+					.select(new URI(
+							"socket://" + remoteAddress.getHostString())); //$NON-NLS-1$
 			ProxyData data = getData(proxies, Proxy.Type.SOCKS);
 			if (data == null) {
 				proxies = ProxySelector.getDefault()
diff --git a/org.eclipse.jgit.ssh.apache/src/org/eclipse/jgit/transport/sshd/ServerKeyDatabase.java b/org.eclipse.jgit.ssh.apache/src/org/eclipse/jgit/transport/sshd/ServerKeyDatabase.java
new file mode 100644
index 0000000..bdfb96d
--- /dev/null
+++ b/org.eclipse.jgit.ssh.apache/src/org/eclipse/jgit/transport/sshd/ServerKeyDatabase.java
@@ -0,0 +1,177 @@
+/*
+ * 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.transport.sshd;
+
+import java.net.InetSocketAddress;
+import java.security.PublicKey;
+import java.util.List;
+
+import org.eclipse.jgit.annotations.NonNull;
+import org.eclipse.jgit.transport.CredentialsProvider;
+
+/**
+ * An interface for a database of known server keys, supporting finding all
+ * known keys and also deciding whether a server key is to be accepted.
+ * <p>
+ * Connection addresses are given as strings of the format
+ * {@code [hostName]:port} if using a non-standard port (i.e., not port 22),
+ * otherwise just {@code hostname}.
+ * </p>
+ *
+ * @since 5.5
+ */
+public interface ServerKeyDatabase {
+
+	/**
+	 * Retrieves all known host keys for the given addresses.
+	 *
+	 * @param connectAddress
+	 *            IP address the session tried to connect to
+	 * @param remoteAddress
+	 *            IP address as reported for the remote end point
+	 * @param config
+	 *            giving access to potentially interesting configuration
+	 *            settings
+	 * @return the list of known keys for the given addresses
+	 */
+	@NonNull
+	List<PublicKey> lookup(@NonNull String connectAddress,
+			@NonNull InetSocketAddress remoteAddress,
+			@NonNull Configuration config);
+
+	/**
+	 * Determines whether to accept a received server host key.
+	 *
+	 * @param connectAddress
+	 *            IP address the session tried to connect to
+	 * @param remoteAddress
+	 *            IP address as reported for the remote end point
+	 * @param serverKey
+	 *            received from the remote end
+	 * @param config
+	 *            giving access to potentially interesting configuration
+	 *            settings
+	 * @param provider
+	 *            for interacting with the user, if required; may be
+	 *            {@code null}
+	 * @return {@code true} if the serverKey is accepted, {@code false}
+	 *         otherwise
+	 */
+	boolean accept(@NonNull String connectAddress,
+			@NonNull InetSocketAddress remoteAddress,
+			@NonNull PublicKey serverKey,
+			@NonNull Configuration config, CredentialsProvider provider);
+
+	/**
+	 * A simple provider for ssh config settings related to host key checking.
+	 * An instance is created by the JGit sshd framework and passed into
+	 * {@link ServerKeyDatabase#lookup(String, InetSocketAddress, Configuration)}
+	 * and
+	 * {@link ServerKeyDatabase#accept(String, InetSocketAddress, PublicKey, Configuration, CredentialsProvider)}.
+	 */
+	interface Configuration {
+
+		/**
+		 * Retrieves the list of file names from the "UserKnownHostsFile" ssh
+		 * config.
+		 *
+		 * @return the list as configured, with ~ already replaced
+		 */
+		List<String> getUserKnownHostsFiles();
+
+		/**
+		 * Retrieves the list of file names from the "GlobalKnownHostsFile" ssh
+		 * config.
+		 *
+		 * @return the list as configured, with ~ already replaced
+		 */
+		List<String> getGlobalKnownHostsFiles();
+
+		/**
+		 * The possible values for the "StrictHostKeyChecking" ssh config.
+		 */
+		enum StrictHostKeyChecking {
+			/**
+			 * "ask"; default: ask the user whether to accept (and store) a new
+			 * or mismatched key.
+			 */
+			ASK,
+			/**
+			 * "yes", "on": never accept new or mismatched keys.
+			 */
+			REQUIRE_MATCH,
+			/**
+			 * "no", "off": always accept new or mismatched keys.
+			 */
+			ACCEPT_ANY,
+			/**
+			 * "accept-new": accept new keys, but never accept modified keys.
+			 */
+			ACCEPT_NEW
+		}
+
+		/**
+		 * Obtains the value of the "StrictHostKeyChecking" ssh config.
+		 *
+		 * @return the {@link StrictHostKeyChecking}
+		 */
+		@NonNull
+		StrictHostKeyChecking getStrictHostKeyChecking();
+
+		/**
+		 * Obtains the value of the "HashKnownHosts" ssh config.
+		 *
+		 * @return {@code true} if new entries should be stored with hashed host
+		 *         information, {@code false} otherwise
+		 */
+		boolean getHashKnownHosts();
+
+		/**
+		 * Obtains the user name used in the connection attempt.
+		 *
+		 * @return the user name
+		 */
+		@NonNull
+		String getUsername();
+	}
+}
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 90dc8ca..3460185 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
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2018, Thomas Wolf <thomas.wolf@paranor.ch>
+ * Copyright (C) 2018, 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
@@ -66,7 +66,6 @@
 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;
@@ -77,10 +76,11 @@
 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.JGitServerKeyVerifier;
 import org.eclipse.jgit.internal.transport.sshd.JGitSshClient;
 import org.eclipse.jgit.internal.transport.sshd.JGitSshConfig;
 import org.eclipse.jgit.internal.transport.sshd.JGitUserInteraction;
-import org.eclipse.jgit.internal.transport.sshd.OpenSshServerKeyVerifier;
+import org.eclipse.jgit.internal.transport.sshd.OpenSshServerKeyDatabase;
 import org.eclipse.jgit.internal.transport.sshd.PasswordProviderWrapper;
 import org.eclipse.jgit.internal.transport.sshd.SshdText;
 import org.eclipse.jgit.transport.CredentialsProvider;
@@ -104,7 +104,7 @@
 
 	private final Map<Tuple, HostConfigEntryResolver> defaultHostConfigEntryResolver = new ConcurrentHashMap<>();
 
-	private final Map<Tuple, ServerKeyVerifier> defaultServerKeyVerifier = new ConcurrentHashMap<>();
+	private final Map<Tuple, ServerKeyDatabase> defaultServerKeyDatabase = new ConcurrentHashMap<>();
 
 	private final Map<Tuple, Iterable<KeyPair>> defaultKeys = new ConcurrentHashMap<>();
 
@@ -226,7 +226,8 @@
 						.filePasswordProvider(
 								createFilePasswordProvider(passphrases))
 						.hostConfigEntryResolver(configFile)
-						.serverKeyVerifier(getServerKeyVerifier(home, sshDir))
+						.serverKeyVerifier(new JGitServerKeyVerifier(
+								getServerKeyDatabase(home, sshDir)))
 						.compressionFactories(
 								new ArrayList<>(BuiltinCompressions.VALUES))
 						.build();
@@ -360,34 +361,48 @@
 			@NonNull File homeDir, @NonNull File sshDir) {
 		return defaultHostConfigEntryResolver.computeIfAbsent(
 				new Tuple(new Object[] { homeDir, sshDir }),
-				t -> new JGitSshConfig(homeDir,
-						new File(sshDir, SshConstants.CONFIG),
+				t -> new JGitSshConfig(homeDir, getSshConfig(sshDir),
 						getLocalUserName()));
 	}
 
 	/**
-	 * Obtain a {@link ServerKeyVerifier} to read known_hosts files and to
-	 * verify server host keys. The default implementation returns a
-	 * {@link ServerKeyVerifier} that recognizes the two openssh standard files
-	 * {@code ~/.ssh/known_hosts} and {@code ~/.ssh/known_hosts2} as well as any
-	 * files configured via the {@code UserKnownHostsFile} option in the ssh
-	 * config file.
+	 * Determines the ssh config file. The default implementation returns
+	 * ~/.ssh/config. If the file does not exist and is created later it will be
+	 * picked up. To not use a config file at all, return {@code null}.
+	 *
+	 * @param sshDir
+	 *            representing ~/.ssh/
+	 * @return the file (need not exist), or {@code null} if no config file
+	 *         shall be used
+	 * @since 5.5
+	 */
+	protected File getSshConfig(@NonNull File sshDir) {
+		return new File(sshDir, SshConstants.CONFIG);
+	}
+
+	/**
+	 * Obtain a {@link ServerKeyDatabase} to verify server host keys. The
+	 * default implementation returns a {@link ServerKeyDatabase} that
+	 * recognizes the two openssh standard files {@code ~/.ssh/known_hosts} and
+	 * {@code ~/.ssh/known_hosts2} as well as any files configured via the
+	 * {@code UserKnownHostsFile} option in the ssh config file.
 	 *
 	 * @param homeDir
 	 *            home directory to use for ~ replacement
 	 * @param sshDir
 	 *            representing ~/.ssh/
-	 * @return the resolver
+	 * @return the {@link ServerKeyDatabase}
+	 * @since 5.5
 	 */
 	@NonNull
-	private ServerKeyVerifier getServerKeyVerifier(@NonNull File homeDir,
+	protected ServerKeyDatabase getServerKeyDatabase(@NonNull File homeDir,
 			@NonNull File sshDir) {
-		return defaultServerKeyVerifier.computeIfAbsent(
+		return defaultServerKeyDatabase.computeIfAbsent(
 				new Tuple(new Object[] { homeDir, sshDir }),
-				t -> new OpenSshServerKeyVerifier(true,
+				t -> new OpenSshServerKeyDatabase(true,
 						getDefaultKnownHostsFiles(sshDir)));
-	}
 
+	}
 	/**
 	 * Gets the list of default user known hosts files. The default returns
 	 * ~/.ssh/known_hosts and ~/.ssh/known_hosts2. The ssh config
@@ -540,7 +555,7 @@
 	 * the ssh config defines {@code PreferredAuthentications} the value from
 	 * the ssh config takes precedence.
 	 *
-	 * @return a comma-separated list of algorithm names, or {@code null} if
+	 * @return a comma-separated list of mechanism names, or {@code null} if
 	 *         none
 	 */
 	protected String getDefaultPreferredAuthentications() {
diff --git a/org.eclipse.jgit.test/BUILD b/org.eclipse.jgit.test/BUILD
index 9c8cc89..3f664f9 100644
--- a/org.eclipse.jgit.test/BUILD
+++ b/org.eclipse.jgit.test/BUILD
@@ -37,11 +37,15 @@
     PKG + "lib/sorttest.gitindex.dat",
 ]
 
+EXCLUDED = [
+    PKG + "api/SecurityManagerTest.java",
+]
+
 RESOURCES = glob(["resources/**"])
 
 tests(tests = glob(
     ["tst/**/*.java"],
-    exclude = HELPERS + DATA,
+    exclude = HELPERS + DATA + EXCLUDED,
 ))
 
 java_library(
diff --git a/org.eclipse.jgit.test/META-INF/MANIFEST.MF b/org.eclipse.jgit.test/META-INF/MANIFEST.MF
index 94a3a20..42c9c57 100644
--- a/org.eclipse.jgit.test/META-INF/MANIFEST.MF
+++ b/org.eclipse.jgit.test/META-INF/MANIFEST.MF
@@ -1,11 +1,11 @@
 Manifest-Version: 1.0
 Bundle-ManifestVersion: 2
-Bundle-Name: %plugin_name
+Bundle-Name: %Bundle-Name
 Automatic-Module-Name: org.eclipse.jgit.test
 Bundle-SymbolicName: org.eclipse.jgit.test
-Bundle-Version: 5.4.4.qualifier
+Bundle-Version: 5.5.2.qualifier
 Bundle-Localization: plugin
-Bundle-Vendor: %provider_name
+Bundle-Vendor: %Bundle-Vendor
 Bundle-ActivationPolicy: lazy
 Bundle-RequiredExecutionEnvironment: JavaSE-1.8
 Import-Package: com.googlecode.javaewah;version="[1.1.6,2.0.0)",
@@ -18,57 +18,57 @@
  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.61.0,2.0.0)",
- org.eclipse.jgit.annotations;version="[5.4.4,5.5.0)",
- org.eclipse.jgit.api;version="[5.4.4,5.5.0)",
- org.eclipse.jgit.api.errors;version="[5.4.4,5.5.0)",
- org.eclipse.jgit.archive;version="[5.4.4,5.5.0)",
- org.eclipse.jgit.attributes;version="[5.4.4,5.5.0)",
- org.eclipse.jgit.awtui;version="[5.4.4,5.5.0)",
- org.eclipse.jgit.blame;version="[5.4.4,5.5.0)",
- org.eclipse.jgit.diff;version="[5.4.4,5.5.0)",
- org.eclipse.jgit.dircache;version="[5.4.4,5.5.0)",
- org.eclipse.jgit.errors;version="[5.4.4,5.5.0)",
- org.eclipse.jgit.events;version="[5.4.4,5.5.0)",
- org.eclipse.jgit.fnmatch;version="[5.4.4,5.5.0)",
- org.eclipse.jgit.gitrepo;version="[5.4.4,5.5.0)",
- org.eclipse.jgit.hooks;version="[5.4.4,5.5.0)",
- org.eclipse.jgit.ignore;version="[5.4.4,5.5.0)",
- org.eclipse.jgit.ignore.internal;version="[5.4.4,5.5.0)",
- org.eclipse.jgit.internal;version="[5.4.4,5.5.0)",
- org.eclipse.jgit.internal.fsck;version="[5.4.4,5.5.0)",
- org.eclipse.jgit.internal.storage.dfs;version="[5.4.4,5.5.0)",
- org.eclipse.jgit.internal.storage.file;version="[5.4.4,5.5.0)",
- org.eclipse.jgit.internal.storage.io;version="[5.4.4,5.5.0)",
- org.eclipse.jgit.internal.storage.pack;version="[5.4.4,5.5.0)",
- org.eclipse.jgit.internal.storage.reftable;version="[5.4.4,5.5.0)",
- org.eclipse.jgit.internal.storage.reftree;version="[5.4.4,5.5.0)",
- org.eclipse.jgit.internal.transport.http;version="[5.4.4,5.5.0)",
- org.eclipse.jgit.internal.transport.parser;version="[5.4.4,5.5.0)",
- org.eclipse.jgit.junit;version="[5.4.4,5.5.0)",
- org.eclipse.jgit.junit.ssh;version="[5.4.4,5.5.0)",
- org.eclipse.jgit.junit.time;version="[5.4.4,5.5.0)",
- org.eclipse.jgit.lfs;version="[5.4.4,5.5.0)",
- org.eclipse.jgit.lib;version="[5.4.4,5.5.0)",
- org.eclipse.jgit.merge;version="[5.4.4,5.5.0)",
- org.eclipse.jgit.nls;version="[5.4.4,5.5.0)",
- org.eclipse.jgit.notes;version="[5.4.4,5.5.0)",
- org.eclipse.jgit.patch;version="[5.4.4,5.5.0)",
- org.eclipse.jgit.pgm;version="[5.4.4,5.5.0)",
- org.eclipse.jgit.pgm.internal;version="[5.4.4,5.5.0)",
- org.eclipse.jgit.revplot;version="[5.4.4,5.5.0)",
- org.eclipse.jgit.revwalk;version="[5.4.4,5.5.0)",
- org.eclipse.jgit.revwalk.filter;version="[5.4.4,5.5.0)",
- org.eclipse.jgit.storage.file;version="[5.4.4,5.5.0)",
- org.eclipse.jgit.storage.pack;version="[5.4.4,5.5.0)",
- org.eclipse.jgit.submodule;version="[5.4.4,5.5.0)",
- org.eclipse.jgit.transport;version="[5.4.4,5.5.0)",
- org.eclipse.jgit.transport.http;version="[5.4.4,5.5.0)",
- org.eclipse.jgit.transport.resolver;version="[5.4.4,5.5.0)",
- org.eclipse.jgit.treewalk;version="[5.4.4,5.5.0)",
- org.eclipse.jgit.treewalk.filter;version="[5.4.4,5.5.0)",
- org.eclipse.jgit.util;version="[5.4.4,5.5.0)",
- org.eclipse.jgit.util.io;version="[5.4.4,5.5.0)",
- org.eclipse.jgit.util.sha1;version="[5.4.4,5.5.0)",
+ org.eclipse.jgit.annotations;version="[5.5.2,5.6.0)",
+ org.eclipse.jgit.api;version="[5.5.2,5.6.0)",
+ org.eclipse.jgit.api.errors;version="[5.5.2,5.6.0)",
+ org.eclipse.jgit.archive;version="[5.5.2,5.6.0)",
+ org.eclipse.jgit.attributes;version="[5.5.2,5.6.0)",
+ org.eclipse.jgit.awtui;version="[5.5.2,5.6.0)",
+ org.eclipse.jgit.blame;version="[5.5.2,5.6.0)",
+ org.eclipse.jgit.diff;version="[5.5.2,5.6.0)",
+ org.eclipse.jgit.dircache;version="[5.5.2,5.6.0)",
+ org.eclipse.jgit.errors;version="[5.5.2,5.6.0)",
+ org.eclipse.jgit.events;version="[5.5.2,5.6.0)",
+ org.eclipse.jgit.fnmatch;version="[5.5.2,5.6.0)",
+ org.eclipse.jgit.gitrepo;version="[5.5.2,5.6.0)",
+ org.eclipse.jgit.hooks;version="[5.5.2,5.6.0)",
+ org.eclipse.jgit.ignore;version="[5.5.2,5.6.0)",
+ org.eclipse.jgit.ignore.internal;version="[5.5.2,5.6.0)",
+ org.eclipse.jgit.internal;version="[5.5.2,5.6.0)",
+ org.eclipse.jgit.internal.fsck;version="[5.5.2,5.6.0)",
+ org.eclipse.jgit.internal.storage.dfs;version="[5.5.2,5.6.0)",
+ org.eclipse.jgit.internal.storage.file;version="[5.5.2,5.6.0)",
+ org.eclipse.jgit.internal.storage.io;version="[5.5.2,5.6.0)",
+ org.eclipse.jgit.internal.storage.pack;version="[5.5.2,5.6.0)",
+ org.eclipse.jgit.internal.storage.reftable;version="[5.5.2,5.6.0)",
+ org.eclipse.jgit.internal.storage.reftree;version="[5.5.2,5.6.0)",
+ org.eclipse.jgit.internal.transport.http;version="[5.5.2,5.6.0)",
+ org.eclipse.jgit.internal.transport.parser;version="[5.5.2,5.6.0)",
+ org.eclipse.jgit.junit;version="[5.5.2,5.6.0)",
+ org.eclipse.jgit.junit.ssh;version="[5.5.2,5.6.0)",
+ org.eclipse.jgit.junit.time;version="[5.5.2,5.6.0)",
+ org.eclipse.jgit.lfs;version="[5.5.2,5.6.0)",
+ org.eclipse.jgit.lib;version="[5.5.2,5.6.0)",
+ org.eclipse.jgit.merge;version="[5.5.2,5.6.0)",
+ org.eclipse.jgit.nls;version="[5.5.2,5.6.0)",
+ org.eclipse.jgit.notes;version="[5.5.2,5.6.0)",
+ org.eclipse.jgit.patch;version="[5.5.2,5.6.0)",
+ org.eclipse.jgit.pgm;version="[5.5.2,5.6.0)",
+ org.eclipse.jgit.pgm.internal;version="[5.5.2,5.6.0)",
+ org.eclipse.jgit.revplot;version="[5.5.2,5.6.0)",
+ org.eclipse.jgit.revwalk;version="[5.5.2,5.6.0)",
+ org.eclipse.jgit.revwalk.filter;version="[5.5.2,5.6.0)",
+ org.eclipse.jgit.storage.file;version="[5.5.2,5.6.0)",
+ org.eclipse.jgit.storage.pack;version="[5.5.2,5.6.0)",
+ org.eclipse.jgit.submodule;version="[5.5.2,5.6.0)",
+ org.eclipse.jgit.transport;version="[5.5.2,5.6.0)",
+ org.eclipse.jgit.transport.http;version="[5.5.2,5.6.0)",
+ org.eclipse.jgit.transport.resolver;version="[5.5.2,5.6.0)",
+ org.eclipse.jgit.treewalk;version="[5.5.2,5.6.0)",
+ org.eclipse.jgit.treewalk.filter;version="[5.5.2,5.6.0)",
+ org.eclipse.jgit.util;version="[5.5.2,5.6.0)",
+ org.eclipse.jgit.util.io;version="[5.5.2,5.6.0)",
+ org.eclipse.jgit.util.sha1;version="[5.5.2,5.6.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)",
@@ -83,4 +83,4 @@
  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.4.4";x-friends:="org.eclipse.jgit.ssh.apache.test"
+Export-Package: org.eclipse.jgit.transport.ssh;version="5.5.2";x-friends:="org.eclipse.jgit.ssh.apache.test"
diff --git a/org.eclipse.jgit.test/plugin.properties b/org.eclipse.jgit.test/plugin.properties
index 1d32644..4e353cd 100644
--- a/org.eclipse.jgit.test/plugin.properties
+++ b/org.eclipse.jgit.test/plugin.properties
@@ -1,2 +1,2 @@
-plugin_name=JGit Core Tests
-provider_name=Eclipse JGit
+Bundle-Name=JGit Core Tests
+Bundle-Vendor=Eclipse JGit
diff --git a/org.eclipse.jgit.test/pom.xml b/org.eclipse.jgit.test/pom.xml
index 720fa8c..91c3418 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.4.4-SNAPSHOT</version>
+    <version>5.5.2-SNAPSHOT</version>
   </parent>
 
   <artifactId>org.eclipse.jgit.test</artifactId>
diff --git a/org.eclipse.jgit.test/src/org/eclipse/jgit/lib/MoreAsserts.java b/org.eclipse.jgit.test/src/org/eclipse/jgit/lib/MoreAsserts.java
new file mode 100644
index 0000000..5945e7e
--- /dev/null
+++ b/org.eclipse.jgit.test/src/org/eclipse/jgit/lib/MoreAsserts.java
@@ -0,0 +1,79 @@
+/*
+ * 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.lib;
+
+/** Assertion methods. */
+public class MoreAsserts {
+	/**
+	 * Simple version of assertThrows that will be introduced in JUnit 4.13.
+	 *
+	 * @param expected
+	 *            Expected throwable class
+	 * @param r
+	 *            Runnable that is expected to throw an exception.
+	 * @return The thrown exception.
+	 */
+	public static <T extends Throwable> T assertThrows(Class<T> expected,
+			ThrowingRunnable r) {
+		try {
+			r.run();
+		} catch (Throwable actual) {
+			if (expected.isAssignableFrom(actual.getClass())) {
+				@SuppressWarnings("unchecked")
+				T toReturn = (T) actual;
+				return toReturn;
+			}
+			throw new AssertionError("Expected " + expected.getSimpleName()
+					+ ", but got " + actual.getClass().getSimpleName(), actual);
+		}
+		throw new AssertionError(
+				"Expected " + expected.getSimpleName() + " to be thrown");
+	}
+
+	public interface ThrowingRunnable {
+		void run() throws Throwable;
+	}
+
+	private MoreAsserts() {
+	}
+}
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 b8c90b2..dab93fd 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
@@ -305,7 +305,7 @@
 		// without provider. If it works, the server host key was written
 		// correctly.
 		File clonedAgain = new File(getTemporaryDirectory(), "cloned2");
-		cloneWith("ssh://localhost/doesntmatter", clonedAgain, provider, //
+		cloneWith("ssh://localhost/doesntmatter", clonedAgain, null, //
 				"Host localhost", //
 				"HostName localhost", //
 				"Port " + testPort, //
diff --git a/org.eclipse.jgit.test/tst-rsrc/org/eclipse/jgit/diff/A3.patch b/org.eclipse.jgit.test/tst-rsrc/org/eclipse/jgit/diff/A3.patch
new file mode 100644
index 0000000..ac63d91
--- /dev/null
+++ b/org.eclipse.jgit.test/tst-rsrc/org/eclipse/jgit/diff/A3.patch
@@ -0,0 +1,3 @@
+diff --git a/A3 b/A3
+new file mode 100644
+index 0000000..de98044
\ No newline at end of file
diff --git a/org.eclipse.jgit.test/tst-rsrc/org/eclipse/jgit/diff/A3_PostImage b/org.eclipse.jgit.test/tst-rsrc/org/eclipse/jgit/diff/A3_PostImage
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/org.eclipse.jgit.test/tst-rsrc/org/eclipse/jgit/diff/A3_PostImage
diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/ApplyCommandTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/ApplyCommandTest.java
index 1dd329a..714a54c 100644
--- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/ApplyCommandTest.java
+++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/ApplyCommandTest.java
@@ -111,6 +111,16 @@
 	}
 
 	@Test
+	public void testAddA3() throws Exception {
+		ApplyResult result = init("A3", false, true);
+		assertEquals(1, result.getUpdatedFiles().size());
+		assertEquals(new File(db.getWorkTree(), "A3"),
+				result.getUpdatedFiles().get(0));
+		checkFile(new File(db.getWorkTree(), "A3"),
+				b.getString(0, b.size(), false));
+	}
+
+	@Test
 	public void testAddA1Sub() throws Exception {
 		ApplyResult result = init("A1_sub", false, false);
 		assertEquals(1, result.getUpdatedFiles().size());
diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/ResetCommandTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/ResetCommandTest.java
index dd7230b..563b32d 100644
--- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/ResetCommandTest.java
+++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/ResetCommandTest.java
@@ -194,6 +194,42 @@
 	}
 
 	@Test
+	public void testHardResetWithConflicts_CreateFolder_UnstagedChanges() throws Exception {
+		setupRepository();
+
+		writeTrashFile("dir-or-file/c.txt", "content");
+		git.add().addFilepattern("dir-or-file/c.txt").call();
+		git.commit().setMessage("adding dir-or-file/c.txt").call();
+
+		FileUtils.delete(new File(db.getWorkTree(), "dir-or-file"), FileUtils.RECURSIVE);
+		writeTrashFile("dir-or-file", "content");
+
+		// bug 479266: cannot create folder "dir-or-file"
+		git.reset().setMode(ResetType.HARD).setRef(Constants.HEAD).call();
+		assertTrue(new File(db.getWorkTree(), "dir-or-file/c.txt").exists());
+	}
+
+	@Test
+	public void testHardResetWithConflicts_DeleteFolder_UnstagedChanges() throws Exception {
+		setupRepository();
+		ObjectId prevHead = db.resolve(Constants.HEAD);
+
+		writeTrashFile("dir-or-file/c.txt", "content");
+		git.add().addFilepattern("dir-or-file/c.txt").call();
+		git.commit().setMessage("adding dir-or-file/c.txt").call();
+
+		writeTrashFile("dir-or-file-2/d.txt", "content");
+		git.add().addFilepattern("dir-or-file-2/d.txt").call();
+		FileUtils.delete(new File(db.getWorkTree(), "dir-or-file-2"), FileUtils.RECURSIVE);
+		writeTrashFile("dir-or-file-2", "content");
+
+		// bug 479266: cannot delete folder "dir-or-file"
+		git.reset().setMode(ResetType.HARD).setRef(prevHead.getName()).call();
+		assertFalse(new File(db.getWorkTree(), "dir-or-file").exists());
+		assertFalse(new File(db.getWorkTree(), "dir-or-file-2").exists());
+	}
+
+	@Test
 	public void testResetToNonexistingHEAD() throws JGitInternalException,
 			AmbiguousObjectException, IOException, GitAPIException {
 
diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/SecurityManagerTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/SecurityManagerTest.java
new file mode 100644
index 0000000..62d3530
--- /dev/null
+++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/SecurityManagerTest.java
@@ -0,0 +1,206 @@
+/*
+ * Copyright (C) 2019 Nail Samatov <sanail@yandex.ru>
+ * 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.api;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+
+import java.io.File;
+import java.io.FilePermission;
+import java.io.IOException;
+import java.lang.reflect.ReflectPermission;
+import java.nio.file.Files;
+import java.security.Permission;
+import java.security.SecurityPermission;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.PropertyPermission;
+import java.util.logging.LoggingPermission;
+
+import javax.security.auth.AuthPermission;
+
+import org.eclipse.jgit.api.errors.GitAPIException;
+import org.eclipse.jgit.junit.JGitTestUtil;
+import org.eclipse.jgit.junit.MockSystemReader;
+import org.eclipse.jgit.junit.SeparateClassloaderTestRunner;
+import org.eclipse.jgit.revwalk.RevCommit;
+import org.eclipse.jgit.treewalk.TreeWalk;
+import org.eclipse.jgit.util.FileUtils;
+import org.eclipse.jgit.util.SystemReader;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+/**
+ * <p>
+ * Tests if jgit works if SecurityManager is enabled.
+ * </p>
+ *
+ * <p>
+ * Note: JGit's classes shouldn't be used before SecurityManager is configured.
+ * If you use some JGit's class before SecurityManager is replaced then part of
+ * the code can be invoked outside of our custom SecurityManager and this test
+ * becomes useless.
+ * </p>
+ *
+ * <p>
+ * For example the class {@link org.eclipse.jgit.util.FS} is used widely in jgit
+ * sources. It contains DETECTED static field. At the first usage of the class
+ * FS the field DETECTED is initialized and during initialization many system
+ * operations that SecurityManager can forbid are invoked.
+ * </p>
+ *
+ * <p>
+ * For this reason this test doesn't extend LocalDiskRepositoryTestCase (it uses
+ * JGit's classes in setUp() method) and other JGit's utility classes. It's done
+ * to affect SecurityManager as less as possible.
+ * </p>
+ *
+ * <p>
+ * We use SeparateClassloaderTestRunner to isolate FS.DETECTED field
+ * initialization between different tests run.
+ * </p>
+ */
+@RunWith(SeparateClassloaderTestRunner.class)
+public class SecurityManagerTest {
+	private File root;
+
+	private SecurityManager originalSecurityManager;
+
+	private List<Permission> permissions = new ArrayList<>();
+
+	@Before
+	public void setUp() throws Exception {
+		// Create working directory
+		SystemReader.setInstance(new MockSystemReader());
+		root = Files.createTempDirectory("jgit-security").toFile();
+
+		// Add system permissions
+		permissions.add(new RuntimePermission("*"));
+		permissions.add(new SecurityPermission("*"));
+		permissions.add(new AuthPermission("*"));
+		permissions.add(new ReflectPermission("*"));
+		permissions.add(new PropertyPermission("*", "read,write"));
+		permissions.add(new LoggingPermission("control", null));
+
+		permissions.add(new FilePermission(
+				System.getProperty("java.home") + "/-", "read"));
+
+		String tempDir = System.getProperty("java.io.tmpdir");
+		permissions.add(new FilePermission(tempDir, "read,write,delete"));
+		permissions
+				.add(new FilePermission(tempDir + "/-", "read,write,delete"));
+
+		// Add permissions to dependent jar files.
+		String classPath = System.getProperty("java.class.path");
+		if (classPath != null) {
+			for (String path : classPath.split(File.pathSeparator)) {
+				permissions.add(new FilePermission(path, "read"));
+			}
+		}
+		// Add permissions to jgit class files.
+		String jgitSourcesRoot = new File(System.getProperty("user.dir"))
+				.getParent();
+		permissions.add(new FilePermission(jgitSourcesRoot + "/-", "read"));
+
+		// Add permissions to working dir for jgit. Our git repositories will be
+		// initialized and cloned here.
+		permissions.add(new FilePermission(root.getPath() + "/-",
+				"read,write,delete,execute"));
+
+		// Replace Security Manager
+		originalSecurityManager = System.getSecurityManager();
+		System.setSecurityManager(new SecurityManager() {
+
+			@Override
+			public void checkPermission(Permission requested) {
+				for (Permission permission : permissions) {
+					if (permission.implies(requested)) {
+						return;
+					}
+				}
+
+				super.checkPermission(requested);
+			}
+		});
+	}
+
+	@After
+	public void tearDown() throws Exception {
+		System.setSecurityManager(originalSecurityManager);
+
+		// Note: don't use this method before security manager is replaced in
+		// setUp() method. The method uses FS.DETECTED internally and can affect
+		// the test.
+		FileUtils.delete(root, FileUtils.RECURSIVE | FileUtils.RETRY);
+	}
+
+	@Test
+	public void testInitAndClone() throws IOException, GitAPIException {
+		File remote = new File(root, "remote");
+		File local = new File(root, "local");
+
+		try (Git git = Git.init().setDirectory(remote).call()) {
+			JGitTestUtil.write(new File(remote, "hello.txt"), "Hello world!");
+			git.add().addFilepattern(".").call();
+			git.commit().setMessage("Initial commit").call();
+		}
+
+		try (Git git = Git.cloneRepository().setURI(remote.toURI().toString())
+				.setDirectory(local).call()) {
+			assertTrue(new File(local, ".git").exists());
+
+			JGitTestUtil.write(new File(local, "hi.txt"), "Hi!");
+			git.add().addFilepattern(".").call();
+			RevCommit commit1 = git.commit().setMessage("Commit on local repo")
+					.call();
+			assertEquals("Commit on local repo", commit1.getFullMessage());
+			assertNotNull(TreeWalk.forPath(git.getRepository(), "hello.txt",
+					commit1.getTree()));
+		}
+
+	}
+
+}
diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/file/AlternatesTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/file/AlternatesTest.java
index b09db03..2306e0b 100644
--- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/file/AlternatesTest.java
+++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/file/AlternatesTest.java
@@ -42,6 +42,7 @@
  */
 package org.eclipse.jgit.internal.storage.file;
 
+import static org.eclipse.jgit.lib.Constants.INFO_ALTERNATES;
 import static org.junit.Assert.assertTrue;
 
 import java.io.File;
@@ -76,7 +77,7 @@
 	private void setAlternate(FileRepository from, FileRepository to)
 			throws IOException {
 		File alt = new File(from.getObjectDatabase().getDirectory(),
-				"info/alternates");
+				INFO_ALTERNATES);
 		alt.getParentFile().mkdirs();
 		File fromDir = from.getObjectDatabase().getDirectory();
 		File toDir = to.getObjectDatabase().getDirectory();
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 5d0a7e2..1e2341b 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
@@ -44,6 +44,7 @@
 package org.eclipse.jgit.internal.storage.file;
 
 import static org.eclipse.jgit.internal.storage.pack.PackWriter.NONE;
+import static org.eclipse.jgit.lib.Constants.INFO_ALTERNATES;
 import static org.eclipse.jgit.lib.Constants.OBJ_BLOB;
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertFalse;
@@ -138,7 +139,7 @@
 		config = new PackConfig(db);
 
 		dst = createBareRepository();
-		File alt = new File(dst.getObjectDatabase().getDirectory(), "info/alternates");
+		File alt = new File(dst.getObjectDatabase().getDirectory(), INFO_ALTERNATES);
 		alt.getParentFile().mkdirs();
 		write(alt, db.getObjectDatabase().getDirectory().getAbsolutePath() + "\n");
 	}
diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/file/T0003_BasicTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/file/T0003_BasicTest.java
index e2887d9..43f30d8 100644
--- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/file/T0003_BasicTest.java
+++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/file/T0003_BasicTest.java
@@ -98,7 +98,7 @@
 	public void test001_Initalize() {
 		final File gitdir = new File(trash, Constants.DOT_GIT);
 		final File hooks = new File(gitdir, "hooks");
-		final File objects = new File(gitdir, "objects");
+		final File objects = new File(gitdir, Constants.OBJECTS);
 		final File objects_pack = new File(objects, "pack");
 		final File objects_info = new File(objects, "info");
 		final File refs = new File(gitdir, "refs");
@@ -150,7 +150,7 @@
 		assertEqualsPath(theDir, r.getDirectory());
 		assertEqualsPath(repo1Parent, r.getWorkTree());
 		assertEqualsPath(new File(theDir, "index"), r.getIndexFile());
-		assertEqualsPath(new File(theDir, "objects"), r.getObjectDatabase()
+		assertEqualsPath(new File(theDir, Constants.OBJECTS), r.getObjectDatabase()
 				.getDirectory());
 	}
 
@@ -176,7 +176,7 @@
 		assertEqualsPath(theDir, r.getDirectory());
 		assertEqualsPath(repo1Parent.getParentFile(), r.getWorkTree());
 		assertEqualsPath(new File(theDir, "index"), r.getIndexFile());
-		assertEqualsPath(new File(theDir, "objects"), r.getObjectDatabase()
+		assertEqualsPath(new File(theDir, Constants.OBJECTS), r.getObjectDatabase()
 				.getDirectory());
 	}
 
@@ -200,7 +200,7 @@
 		assertEqualsPath(theDir, r.getDirectory());
 		assertEqualsPath(repo1Parent, r.getWorkTree());
 		assertEqualsPath(new File(theDir, "index"), r.getIndexFile());
-		assertEqualsPath(new File(theDir, "objects"), r.getObjectDatabase()
+		assertEqualsPath(new File(theDir, Constants.OBJECTS), r.getObjectDatabase()
 				.getDirectory());
 	}
 
@@ -229,7 +229,7 @@
 		assertEqualsPath(theDir, r.getDirectory());
 		assertEqualsPath(workdir, r.getWorkTree());
 		assertEqualsPath(new File(theDir, "index"), r.getIndexFile());
-		assertEqualsPath(new File(theDir, "objects"), r.getObjectDatabase()
+		assertEqualsPath(new File(theDir, Constants.OBJECTS), r.getObjectDatabase()
 				.getDirectory());
 	}
 
@@ -258,7 +258,7 @@
 		assertEqualsPath(theDir, r.getDirectory());
 		assertEqualsPath(workdir, r.getWorkTree());
 		assertEqualsPath(new File(theDir, "index"), r.getIndexFile());
-		assertEqualsPath(new File(theDir, "objects"), r.getObjectDatabase()
+		assertEqualsPath(new File(theDir, Constants.OBJECTS), r.getObjectDatabase()
 				.getDirectory());
 	}
 
@@ -314,7 +314,7 @@
 		}
 
 		final File o = new File(new File(new File(newdb.getDirectory(),
-				"objects"), "4b"), "825dc642cb6eb9a060e54bf8d69288fbee4904");
+				Constants.OBJECTS), "4b"), "825dc642cb6eb9a060e54bf8d69288fbee4904");
 		assertTrue("Exists " + o, o.isFile());
 		assertTrue("Read-only " + o, !o.canWrite());
 	}
@@ -326,7 +326,7 @@
 		final ObjectId treeId = insertTree(new TreeFormatter());
 		assertEquals("4b825dc642cb6eb9a060e54bf8d69288fbee4904", treeId.name());
 		final File o = new File(new File(
-				new File(db.getDirectory(), "objects"), "4b"),
+				new File(db.getDirectory(), Constants.OBJECTS), "4b"),
 				"825dc642cb6eb9a060e54bf8d69288fbee4904");
 		assertFalse("Exists " + o, o.isFile());
 	}
diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/reftable/ReftableTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/reftable/ReftableTest.java
index a142166..0e33fa6 100644
--- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/reftable/ReftableTest.java
+++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/reftable/ReftableTest.java
@@ -46,13 +46,16 @@
 import static org.eclipse.jgit.lib.Constants.HEAD;
 import static org.eclipse.jgit.lib.Constants.OBJECT_ID_LENGTH;
 import static org.eclipse.jgit.lib.Constants.R_HEADS;
+import static org.eclipse.jgit.lib.MoreAsserts.assertThrows;
 import static org.eclipse.jgit.lib.Ref.Storage.NEW;
 import static org.eclipse.jgit.lib.Ref.Storage.PACKED;
+import static org.hamcrest.CoreMatchers.containsString;
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertFalse;
 import static org.junit.Assert.assertNotNull;
 import static org.junit.Assert.assertNull;
 import static org.junit.Assert.assertSame;
+import static org.junit.Assert.assertThat;
 import static org.junit.Assert.assertTrue;
 import static org.junit.Assert.fail;
 
@@ -415,6 +418,54 @@
 	}
 
 	@Test
+	public void invalidRefWriteOrder() throws IOException {
+		Ref master = ref(MASTER, 1);
+		Ref next = ref(NEXT, 2);
+		ReftableWriter writer = new ReftableWriter()
+			.setMinUpdateIndex(1)
+			.setMaxUpdateIndex(1)
+			.begin(new ByteArrayOutputStream());
+
+		writer.writeRef(next);
+		IllegalArgumentException e  = assertThrows(
+			IllegalArgumentException.class,
+			() -> writer.writeRef(master));
+		assertThat(e.getMessage(), containsString("records must be increasing"));
+	}
+
+	@Test
+	public void invalidReflogWriteOrderUpdateIndex() throws IOException {
+		ReftableWriter writer = new ReftableWriter()
+			.setMinUpdateIndex(1)
+			.setMaxUpdateIndex(2)
+			.begin(new ByteArrayOutputStream());
+		PersonIdent who = new PersonIdent("Log", "Ger", 1500079709, -8 * 60);
+		String msg = "test";
+
+		writer.writeLog(MASTER, 1, who, ObjectId.zeroId(), id(1), msg);
+		IllegalArgumentException e  = assertThrows(IllegalArgumentException.class,
+			() -> writer.writeLog(
+				MASTER, 2, who, ObjectId.zeroId(), id(2), msg));
+		assertThat(e.getMessage(), containsString("records must be increasing"));
+	}
+
+	@Test
+	public void invalidReflogWriteOrderName() throws IOException {
+		ReftableWriter writer = new ReftableWriter()
+			.setMinUpdateIndex(1)
+			.setMaxUpdateIndex(1)
+			.begin(new ByteArrayOutputStream());
+		PersonIdent who = new PersonIdent("Log", "Ger", 1500079709, -8 * 60);
+		String msg = "test";
+
+		writer.writeLog(NEXT, 1, who, ObjectId.zeroId(), id(1), msg);
+		IllegalArgumentException e = assertThrows(IllegalArgumentException.class,
+			() -> writer.writeLog(
+				MASTER, 1, who, ObjectId.zeroId(), id(2), msg));
+		assertThat(e.getMessage(), containsString("records must be increasing"));
+	}
+
+	@Test
 	public void withReflog() throws IOException {
 		Ref master = ref(MASTER, 1);
 		Ref next = ref(NEXT, 2);
@@ -472,6 +523,74 @@
 	}
 
 	@Test
+	public void reflogSeek() throws IOException {
+		PersonIdent who = new PersonIdent("Log", "Ger", 1500079709, -8 * 60);
+		String msg = "test";
+		String msgNext = "test next";
+
+		ByteArrayOutputStream buffer = new ByteArrayOutputStream();
+		ReftableWriter writer = new ReftableWriter()
+				.setMinUpdateIndex(1)
+				.setMaxUpdateIndex(1)
+				.begin(buffer);
+
+		writer.writeLog(MASTER, 1, who, ObjectId.zeroId(), id(1), msg);
+		writer.writeLog(NEXT, 1, who, ObjectId.zeroId(), id(2), msgNext);
+
+		writer.finish();
+		byte[] table = buffer.toByteArray();
+
+		ReftableReader t = read(table);
+		try (LogCursor c = t.seekLog(MASTER, Long.MAX_VALUE)) {
+			assertTrue(c.next());
+			assertEquals(c.getReflogEntry().getComment(), msg);
+		}
+		try (LogCursor c = t.seekLog(MASTER, 0)) {
+			assertFalse(c.next());
+		}
+		try (LogCursor c = t.seekLog(MASTER, 1)) {
+			assertTrue(c.next());
+			assertEquals(c.getUpdateIndex(), 1);
+			assertEquals(c.getReflogEntry().getComment(), msg);
+		}
+		try (LogCursor c = t.seekLog(NEXT, Long.MAX_VALUE)) {
+			assertTrue(c.next());
+			assertEquals(c.getReflogEntry().getComment(), msgNext);
+		}
+		try (LogCursor c = t.seekLog(NEXT, 0)) {
+			assertFalse(c.next());
+		}
+		try (LogCursor c = t.seekLog(NEXT, 1)) {
+			assertTrue(c.next());
+			assertEquals(c.getUpdateIndex(), 1);
+			assertEquals(c.getReflogEntry().getComment(), msgNext);
+		}
+	}
+
+	@Test
+	public void reflogSeekPrefix() throws IOException {
+		PersonIdent who = new PersonIdent("Log", "Ger", 1500079709, -8 * 60);
+
+		ByteArrayOutputStream buffer = new ByteArrayOutputStream();
+		ReftableWriter writer = new ReftableWriter()
+			.setMinUpdateIndex(1)
+			.setMaxUpdateIndex(1)
+			.begin(buffer);
+
+		writer.writeLog("branchname", 1, who, ObjectId.zeroId(), id(1), "branchname");
+
+		writer.finish();
+		byte[] table = buffer.toByteArray();
+
+		ReftableReader t = read(table);
+		try (LogCursor c = t.seekLog("branch", Long.MAX_VALUE)) {
+			// We find a reflog block, but the iteration won't confuse branchname
+			// and branch.
+			assertFalse(c.next());
+		}
+	}
+
+	@Test
 	public void onlyReflog() throws IOException {
 		PersonIdent who = new PersonIdent("Log", "Ger", 1500079709, -8 * 60);
 		String msg = "test";
@@ -505,6 +624,8 @@
 			assertEquals(ObjectId.zeroId(), lc.getReflogEntry().getOldId());
 			assertEquals(id(1), lc.getReflogEntry().getNewId());
 			assertEquals(who, lc.getReflogEntry().getWho());
+			// compare string too, to catch tz differences.
+			assertEquals(who.toExternalString(), lc.getReflogEntry().getWho().toExternalString());
 			assertEquals(msg, lc.getReflogEntry().getComment());
 
 			assertTrue(lc.next());
@@ -532,7 +653,7 @@
 
 		List<Ref> refs = new ArrayList<>();
 		for (int i = 1; i <= 5670; i++) {
-			Ref ref = ref(String.format("refs/heads/%03d", i), i);
+			Ref ref = ref(String.format("refs/heads/%04d", i), i);
 			refs.add(ref);
 			writer.writeRef(ref);
 		}
diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/lib/DirCacheCheckoutTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/lib/DirCacheCheckoutTest.java
index 483051c..8092c31 100644
--- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/lib/DirCacheCheckoutTest.java
+++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/lib/DirCacheCheckoutTest.java
@@ -1977,6 +1977,29 @@
 		}
 	}
 
+	@Test
+	public void testCheckoutWithEmptyIndexDoesntOverwrite() throws Exception {
+		try (Git git = new Git(db);
+				TestRepository<Repository> db_t = new TestRepository<>(db)) {
+			// prepare the commits
+			BranchBuilder master = db_t.branch("master");
+			RevCommit mergeCommit = master.commit()
+					.add("p/x", "headContent")
+					.message("m0").create();
+			master.commit().add("p/x", "headContent").message("m1").create();
+			git.checkout().setName("master").call();
+
+			// empty index and write unsaved data in 'p'
+			git.rm().addFilepattern("p").call();
+			writeTrashFile("p", "important data");
+
+			git.checkout().setName(mergeCommit.getName()).call();
+
+			assertEquals("", indexState(CONTENT));
+			assertEquals("important data", read("p"));
+		}
+	}
+
 	private static class TestFileTreeIterator extends FileTreeIterator {
 
 		// For assertions only
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
index 5cfc75c..3d3c697 100644
--- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/lib/RebaseTodoFileTest.java
+++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/lib/RebaseTodoFileTest.java
@@ -68,7 +68,7 @@
 	@Test
 	public void testReadTodoFile() throws Exception {
 		String[] expected = { "reword " + ObjectId.zeroId().name() + " Foo",
-				"# A comment in the the todo list",
+				"# A comment in the todo list",
 				"pick " + ObjectId.zeroId().name() + " Foo fie",
 				"squash " + ObjectId.zeroId().name() + " F",
 				"fixup " + ObjectId.zeroId().name(),
@@ -93,7 +93,7 @@
 				assertEquals("Expected COMMENT", RebaseTodoLine.Action.COMMENT,
 						line.getAction());
 				assertEquals("Unexpected Message",
-						"# A comment in the the todo list",
+						"# A comment in the todo list",
 						line.getComment());
 				break;
 			case 2:
diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/revwalk/FirstParentRevWalkTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/revwalk/FirstParentRevWalkTest.java
new file mode 100644
index 0000000..1fc7a55
--- /dev/null
+++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/revwalk/FirstParentRevWalkTest.java
@@ -0,0 +1,428 @@
+/*
+ * 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.assertNull;
+
+import org.eclipse.jgit.lib.ObjectId;
+import org.eclipse.jgit.revwalk.filter.MessageRevFilter;
+import org.eclipse.jgit.revwalk.filter.RevFilter;
+import org.junit.Test;
+
+public class FirstParentRevWalkTest extends RevWalkTestCase {
+	@Test
+	public void testStringOfPearls() throws Exception {
+		RevCommit a = commit();
+		RevCommit b = commit(a);
+		RevCommit c = commit(b);
+
+		rw.reset();
+		rw.setFirstParent(true);
+		markStart(c);
+		assertCommit(c, rw.next());
+		assertCommit(b, rw.next());
+		assertCommit(a, rw.next());
+		assertNull(rw.next());
+	}
+
+	@Test
+	public void testSideBranch() throws Exception {
+		RevCommit a = commit();
+		RevCommit b1 = commit(a);
+		RevCommit b2 = commit(a);
+		RevCommit c1 = commit(b1);
+		RevCommit c2 = commit(b2);
+		RevCommit d = commit(c1, c2);
+
+		rw.reset();
+		rw.setFirstParent(true);
+		markStart(d);
+		assertCommit(d, rw.next());
+		assertCommit(c1, rw.next());
+		assertCommit(b1, rw.next());
+		assertCommit(a, rw.next());
+		assertNull(rw.next());
+	}
+
+	@Test
+	public void testSecondParentAncestorOfFirstParent() throws Exception {
+		RevCommit a = commit();
+		RevCommit b = commit(a);
+		RevCommit c = commit(b, a);
+
+		rw.reset();
+		rw.setFirstParent(true);
+		markStart(c);
+		assertCommit(c, rw.next());
+		assertCommit(b, rw.next());
+		assertCommit(a, rw.next());
+		assertNull(rw.next());
+	}
+
+	@Test
+	public void testFirstParentMultipleOccurrences() throws Exception {
+		RevCommit a = commit();
+		RevCommit b = commit(a);
+		RevCommit c = commit(b);
+		RevCommit d = commit(b);
+
+		rw.reset();
+		rw.setFirstParent(true);
+		markStart(c);
+		markStart(d);
+		assertCommit(d, rw.next());
+		assertCommit(c, rw.next());
+		assertCommit(b, rw.next());
+		assertCommit(a, rw.next());
+		assertNull(rw.next());
+	}
+
+	@Test
+	public void testReachableAlongFirstAndLaterParents() throws Exception {
+		RevCommit a = commit();
+		RevCommit b1 = commit(a);
+		RevCommit b2 = commit(a);
+		RevCommit b3 = commit(a);
+		RevCommit c = commit(b1, b2);
+		RevCommit d = commit(b2, b3);
+
+		rw.reset();
+		rw.setFirstParent(true);
+		markStart(c);
+		markStart(d);
+		assertCommit(d, rw.next());
+		assertCommit(c, rw.next());
+		// b3 is only reachable from c's second parent.
+		// b2 is reachable from c's second parent but d's first parent.
+		assertCommit(b2, rw.next());
+		assertCommit(b1, rw.next());
+		assertCommit(a, rw.next());
+		assertNull(rw.next());
+	}
+
+	@Test
+	public void testStartCommitReachableOnlyFromLaterParents()
+			throws Exception {
+		RevCommit a = commit();
+		RevCommit b1 = commit(a);
+		RevCommit b2 = commit(a);
+		RevCommit c = commit(b1, b2);
+
+		rw.reset();
+		rw.setFirstParent(true);
+		markStart(c);
+		markStart(b2);
+		assertCommit(c, rw.next());
+		// b2 is only reachable from second parent, but is itself a start
+		// commit.
+		assertCommit(b2, rw.next());
+		assertCommit(b1, rw.next());
+		assertCommit(a, rw.next());
+		assertNull(rw.next());
+	}
+
+	@Test
+	public void testRevFilter() throws Exception {
+		RevCommit a = commit();
+		RevCommit b1 = commitBuilder().parent(a).message("commit b1").create();
+		RevCommit b2 = commitBuilder().parent(a).message("commit b2").create();
+		RevCommit c = commit(b1, b2);
+
+		rw.reset();
+		rw.setFirstParent(true);
+		rw.setRevFilter(MessageRevFilter.create("commit b"));
+		rw.markStart(c);
+		assertCommit(b1, rw.next());
+		assertNull(rw.next());
+	}
+
+	@Test
+	public void testTopoSort() throws Exception {
+		RevCommit a = commit();
+		RevCommit b1 = commit(a);
+		RevCommit b2 = commit(a);
+		RevCommit c = commit(b1, b2);
+
+		rw.reset();
+		rw.sort(RevSort.TOPO);
+		rw.setFirstParent(true);
+		markStart(c);
+		assertCommit(c, rw.next());
+		assertCommit(b1, rw.next());
+		assertCommit(a, rw.next());
+		assertNull(rw.next());
+	}
+
+	@Test
+	public void testCommitTimeSort() throws Exception {
+		RevCommit a = commit();
+		RevCommit b1 = commit(a);
+		RevCommit b2 = commit(a);
+		RevCommit c = commit(b1, b2);
+
+		rw.reset();
+		rw.sort(RevSort.COMMIT_TIME_DESC);
+		rw.setFirstParent(true);
+		markStart(c);
+		assertCommit(c, rw.next());
+		assertCommit(b1, rw.next());
+		assertCommit(a, rw.next());
+		assertNull(rw.next());
+	}
+
+	@Test
+	public void testReverseSort() throws Exception {
+		RevCommit a = commit();
+		RevCommit b1 = commit(a);
+		RevCommit b2 = commit(a);
+		RevCommit c = commit(b1, b2);
+
+		rw.reset();
+		rw.sort(RevSort.REVERSE);
+		rw.setFirstParent(true);
+		markStart(c);
+		assertCommit(a, rw.next());
+		assertCommit(b1, rw.next());
+		assertCommit(c, rw.next());
+		assertNull(rw.next());
+	}
+
+	@Test
+	public void testBoundarySort() throws Exception {
+		RevCommit a = commit();
+		RevCommit b = commit(a);
+		RevCommit c1 = commit(b);
+		RevCommit c2 = commit(b);
+		RevCommit d = commit(c1, c2);
+
+		rw.reset();
+		rw.sort(RevSort.BOUNDARY);
+		rw.setFirstParent(true);
+		markStart(d);
+		markUninteresting(a);
+		assertCommit(d, rw.next());
+		assertCommit(c1, rw.next());
+		assertCommit(b, rw.next());
+		assertCommit(a, rw.next());
+		assertNull(rw.next());
+	}
+
+	@Test
+	public void testFirstParentOfFirstParentMarkedUninteresting()
+			throws Exception {
+		RevCommit a = commit();
+		RevCommit b1 = commit(a);
+		RevCommit b2 = commit(a);
+		RevCommit c1 = commit(b1);
+		RevCommit c2 = commit(b2);
+		RevCommit d = commit(c1, c2);
+
+		rw.reset();
+		rw.setFirstParent(true);
+		markStart(d);
+		markUninteresting(b1);
+		assertCommit(d, rw.next());
+		assertCommit(c1, rw.next());
+		assertNull(rw.next());
+	}
+
+	@Test
+	public void testUnparsedFirstParentOfFirstParentMarkedUninteresting()
+			throws Exception {
+		ObjectId a = unparsedCommit();
+		ObjectId b1 = unparsedCommit(a);
+		ObjectId b2 = unparsedCommit(a);
+		ObjectId c1 = unparsedCommit(b1);
+		ObjectId c2 = unparsedCommit(b2);
+		ObjectId d = unparsedCommit(c1, c2);
+
+		rw.reset();
+		rw.setFirstParent(true);
+		RevCommit parsedD = rw.parseCommit(d);
+		markStart(parsedD);
+		markUninteresting(rw.parseCommit(b1));
+		assertCommit(parsedD, rw.next());
+		assertCommit(rw.parseCommit(c1), rw.next());
+		assertNull(rw.next());
+	}
+
+	@Test
+	public void testFirstParentMarkedUninteresting() throws Exception {
+		RevCommit a = commit();
+		RevCommit b1 = commit(a);
+		RevCommit b2 = commit(a);
+		RevCommit c = commit(b1, b2);
+
+		rw.reset();
+		rw.setFirstParent(true);
+		markStart(c);
+		markUninteresting(b1);
+		assertCommit(c, rw.next());
+		assertNull(rw.next());
+	}
+
+	@Test
+	public void testUnparsedFirstParentMarkedUninteresting() throws Exception {
+		ObjectId a = unparsedCommit();
+		ObjectId b1 = unparsedCommit(a);
+		ObjectId b2 = unparsedCommit(a);
+		ObjectId c = unparsedCommit(b1, b2);
+
+		rw.reset();
+		rw.setFirstParent(true);
+		RevCommit parsedC = rw.parseCommit(c);
+		markStart(parsedC);
+		markUninteresting(rw.parseCommit(b1));
+		assertCommit(parsedC, rw.next());
+		assertNull(rw.next());
+	}
+
+	@Test
+	public void testUninterestingCommitWithTwoParents() throws Exception {
+		RevCommit a = commit();
+		RevCommit b = commit(a);
+		RevCommit c1 = commit(b);
+		RevCommit c2 = commit(b);
+		RevCommit d = commit(c1);
+		RevCommit e = commit(c1, c2);
+
+		RevCommit uA = commit(a, b);
+		RevCommit uB1 = commit(uA, c2);
+		RevCommit uB2 = commit(uA, d);
+		RevCommit uninteresting = commit(uB1, uB2);
+
+		rw.reset();
+		rw.setFirstParent(true);
+		markStart(e);
+		markUninteresting(uninteresting);
+
+		assertCommit(e, rw.next());
+		assertNull(rw.next());
+	}
+
+	/**
+	 * This fails if we try to propagate flags before parsing commits.
+	 *
+	 * @throws Exception
+	 */
+	@Test
+	public void testUnparsedUninterestingCommitWithTwoParents()
+			throws Exception {
+		ObjectId a = unparsedCommit();
+		ObjectId b = unparsedCommit(a);
+		ObjectId c1 = unparsedCommit(b);
+		ObjectId c2 = unparsedCommit(b);
+		ObjectId d = unparsedCommit(c1);
+		ObjectId e = unparsedCommit(c1, c2);
+
+		ObjectId uA = unparsedCommit(a, b);
+		ObjectId uB1 = unparsedCommit(uA, c2);
+		ObjectId uB2 = unparsedCommit(uA, d);
+		ObjectId uninteresting = unparsedCommit(uB1, uB2);
+
+		rw.reset();
+		rw.setFirstParent(true);
+		RevCommit parsedE = rw.parseCommit(e);
+		markStart(parsedE);
+		markUninteresting(rw.parseCommit(uninteresting));
+
+		assertCommit(parsedE, rw.next());
+		assertNull(rw.next());
+	}
+
+	@Test
+	public void testDepthWalk() throws Exception {
+		RevCommit a = commit();
+		RevCommit b1 = commit(a);
+		RevCommit b2 = commit(a);
+		RevCommit c = commit(b1, b2);
+
+		try (DepthWalk.RevWalk dw = new DepthWalk.RevWalk(db, 1)) {
+			dw.setFirstParent(true);
+			dw.markRoot(dw.parseCommit(c));
+			dw.markStart(dw.parseCommit(c));
+			assertEquals(c, dw.next());
+			assertEquals(b1, dw.next());
+			assertNull(dw.next());
+		}
+	}
+
+	@Test
+	public void testDoNotRewriteParents() throws Exception {
+		RevCommit a = commit();
+		RevCommit b1 = commit(a);
+		RevCommit b2 = commit(a);
+		RevCommit c = commit(b1, b2);
+
+		rw.reset();
+		rw.setFirstParent(true);
+		rw.setRewriteParents(false);
+		markStart(c);
+		assertCommit(c, rw.next());
+		assertCommit(b1, rw.next());
+		assertCommit(a, rw.next());
+		assertNull(rw.next());
+	}
+
+	@Test(expected = IllegalStateException.class)
+	public void testMarkStartBeforeSetFirstParent() throws Exception {
+		RevCommit a = commit();
+
+		rw.reset();
+		markStart(a);
+		rw.setFirstParent(true);
+	}
+
+	@Test(expected = IllegalStateException.class)
+	public void testMergeBaseWithFirstParentNotAllowed() throws Exception {
+		RevCommit a = commit();
+
+		rw.reset();
+		rw.setFirstParent(true);
+		rw.setRevFilter(RevFilter.MERGE_BASE);
+		markStart(a);
+		assertNull(rw.next());
+	}
+}
diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/revwalk/RevWalkTestCase.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/revwalk/RevWalkTestCase.java
index 5443982..a0056ae 100644
--- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/revwalk/RevWalkTestCase.java
+++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/revwalk/RevWalkTestCase.java
@@ -51,6 +51,7 @@
 import org.eclipse.jgit.junit.RepositoryTestCase;
 import org.eclipse.jgit.junit.TestRepository;
 import org.eclipse.jgit.junit.TestRepository.CommitBuilder;
+import org.eclipse.jgit.lib.ObjectId;
 import org.eclipse.jgit.lib.Repository;
 
 /** Support for tests of the {@link RevWalk} class. */
@@ -96,6 +97,10 @@
 		return util.get(tree, path);
 	}
 
+	protected ObjectId unparsedCommit(ObjectId... parents) throws Exception {
+		return util.unparsedCommit(parents);
+	}
+
 	protected RevCommit commit(RevCommit... parents) throws Exception {
 		return util.commit(parents);
 	}
diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/transport/PostUploadHookChainTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/transport/PostUploadHookChainTest.java
new file mode 100644
index 0000000..ea7e8ed
--- /dev/null
+++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/transport/PostUploadHookChainTest.java
@@ -0,0 +1,99 @@
+/*
+ * 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 static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+
+import java.util.Arrays;
+
+import org.eclipse.jgit.storage.pack.PackStatistics;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
+
+@RunWith(JUnit4.class)
+public class PostUploadHookChainTest {
+
+	@Test
+	public void testDefaultIfEmpty() {
+		PostUploadHook[] noHooks = {};
+		PostUploadHook newChain = PostUploadHookChain
+				.newChain(Arrays.asList(noHooks));
+		assertEquals(newChain, PostUploadHook.NULL);
+	}
+
+	@Test
+	public void testFlattenChainIfOnlyOne() {
+		FakePostUploadHook hook1 = new FakePostUploadHook();
+		PostUploadHook newChain = PostUploadHookChain
+				.newChain(Arrays.asList(PostUploadHook.NULL, hook1));
+		assertEquals(newChain, hook1);
+	}
+
+	@Test
+	public void testMultipleHooks() {
+		FakePostUploadHook hook1 = new FakePostUploadHook();
+		FakePostUploadHook hook2 = new FakePostUploadHook();
+
+		PostUploadHook chained = PostUploadHookChain
+				.newChain(Arrays.asList(hook1, hook2));
+		chained.onPostUpload(null);
+
+		assertTrue(hook1.wasInvoked());
+		assertTrue(hook2.wasInvoked());
+	}
+
+	private static final class FakePostUploadHook implements PostUploadHook {
+		boolean invoked;
+
+		public boolean wasInvoked() {
+			return invoked;
+		}
+
+		@Override
+		public void onPostUpload(PackStatistics stats) {
+			invoked = true;
+		}
+	}
+}
\ No newline at end of file
diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/transport/PreUploadHookChainTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/transport/PreUploadHookChainTest.java
new file mode 100644
index 0000000..2a36d8a
--- /dev/null
+++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/transport/PreUploadHookChainTest.java
@@ -0,0 +1,118 @@
+/*
+ * 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 static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+
+import java.util.Arrays;
+import java.util.Collection;
+
+import org.eclipse.jgit.lib.ObjectId;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
+
+@RunWith(JUnit4.class)
+public class PreUploadHookChainTest {
+
+	@Test
+	public void testDefaultIfEmpty() {
+		PreUploadHook[] noHooks = {};
+		PreUploadHook newChain = PreUploadHookChain
+				.newChain(Arrays.asList(noHooks));
+		assertEquals(newChain, PreUploadHook.NULL);
+	}
+
+	@Test
+	public void testFlattenChainIfOnlyOne() {
+		FakePreUploadHook hook1 = new FakePreUploadHook();
+		PreUploadHook newChain = PreUploadHookChain
+				.newChain(Arrays.asList(PreUploadHook.NULL, hook1));
+		assertEquals(newChain, hook1);
+	}
+
+	@Test
+	public void testMultipleHooks() throws ServiceMayNotContinueException {
+		FakePreUploadHook hook1 = new FakePreUploadHook();
+		FakePreUploadHook hook2 = new FakePreUploadHook();
+
+		PreUploadHook chained = PreUploadHookChain
+				.newChain(Arrays.asList(hook1, hook2));
+		chained.onBeginNegotiateRound(null, null, 0);
+
+		assertTrue(hook1.wasInvoked());
+		assertTrue(hook2.wasInvoked());
+	}
+
+	private static final class FakePreUploadHook implements PreUploadHook {
+		boolean invoked;
+
+		@Override
+		public void onBeginNegotiateRound(UploadPack up,
+				Collection<? extends ObjectId> wants, int cntOffered)
+				throws ServiceMayNotContinueException {
+			invoked = true;
+		}
+
+		@Override
+		public void onEndNegotiateRound(UploadPack up,
+				Collection<? extends ObjectId> wants, int cntCommon,
+				int cntNotFound, boolean ready)
+				throws ServiceMayNotContinueException {
+			throw new UnsupportedOperationException();
+		}
+
+		@Override
+		public void onSendPack(UploadPack up,
+				Collection<? extends ObjectId> wants,
+				Collection<? extends ObjectId> haves)
+				throws ServiceMayNotContinueException {
+			throw new UnsupportedOperationException();
+		}
+
+		public boolean wasInvoked() {
+			return invoked;
+		}
+	}
+}
\ No newline at end of file
diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/transport/ProtocolV2HookChainTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/transport/ProtocolV2HookChainTest.java
new file mode 100644
index 0000000..8fb1ca8
--- /dev/null
+++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/transport/ProtocolV2HookChainTest.java
@@ -0,0 +1,111 @@
+/*
+ * 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 static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+
+import java.util.Arrays;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
+
+@RunWith(JUnit4.class)
+public class ProtocolV2HookChainTest {
+
+	@Test
+	public void testDefaultIfEmpty() {
+		ProtocolV2Hook[] noHooks = {};
+		ProtocolV2Hook newChain = ProtocolV2HookChain
+				.newChain(Arrays.asList(noHooks));
+		assertEquals(newChain, ProtocolV2Hook.DEFAULT);
+	}
+
+	@Test
+	public void testFlattenChainIfOnlyOne() {
+		FakeProtocolV2Hook hook1 = new FakeProtocolV2Hook();
+		ProtocolV2Hook newChain = ProtocolV2HookChain
+				.newChain(Arrays.asList(ProtocolV2Hook.DEFAULT, hook1));
+		assertEquals(newChain, hook1);
+	}
+
+	@Test
+	public void testMultipleHooks() throws ServiceMayNotContinueException {
+		FakeProtocolV2Hook hook1 = new FakeProtocolV2Hook();
+		FakeProtocolV2Hook hook2 = new FakeProtocolV2Hook();
+
+		ProtocolV2Hook chained = ProtocolV2HookChain
+				.newChain(Arrays.asList(hook1, hook2));
+		chained.onLsRefs(LsRefsV2Request.builder().build());
+
+		assertTrue(hook1.wasInvoked());
+		assertTrue(hook2.wasInvoked());
+	}
+
+	private static final class FakeProtocolV2Hook implements ProtocolV2Hook {
+		boolean invoked;
+
+		@Override
+		public void onLsRefs(LsRefsV2Request req)
+				throws ServiceMayNotContinueException {
+			invoked = true;
+		}
+
+		@Override
+		public void onCapabilities(CapabilitiesV2Request req)
+				throws ServiceMayNotContinueException {
+			throw new UnsupportedOperationException();
+		}
+
+		@Override
+		public void onFetch(FetchV2Request req)
+				throws ServiceMayNotContinueException {
+			throw new UnsupportedOperationException();
+		}
+
+		public boolean wasInvoked() {
+			return invoked;
+		}
+	}
+}
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 260130b..528a63f 100644
--- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/transport/UploadPackTest.java
+++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/transport/UploadPackTest.java
@@ -1,5 +1,7 @@
 package org.eclipse.jgit.transport;
 
+import static org.eclipse.jgit.lib.MoreAsserts.assertThrows;
+import static org.hamcrest.Matchers.containsInAnyOrder;
 import static org.hamcrest.Matchers.containsString;
 import static org.hamcrest.Matchers.hasItems;
 import static org.hamcrest.Matchers.is;
@@ -9,27 +11,32 @@
 import static org.junit.Assert.assertNotNull;
 import static org.junit.Assert.assertThat;
 import static org.junit.Assert.assertTrue;
-import static org.junit.Assert.fail;
 
 import java.io.ByteArrayInputStream;
 import java.io.ByteArrayOutputStream;
 import java.io.IOException;
+import java.io.InputStream;
 import java.io.StringWriter;
 import java.util.ArrayList;
 import java.util.Arrays;
+import java.util.Collection;
 import java.util.Collections;
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
+import java.util.Objects;
+import java.util.function.Consumer;
 
 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;
 import org.eclipse.jgit.internal.storage.dfs.DfsRepositoryDescription;
 import org.eclipse.jgit.internal.storage.dfs.InMemoryRepository;
+import org.eclipse.jgit.internal.storage.file.PackLock;
+import org.eclipse.jgit.internal.storage.pack.CachedPack;
+import org.eclipse.jgit.internal.storage.pack.CachedPackUriProvider;
 import org.eclipse.jgit.junit.TestRepository;
 import org.eclipse.jgit.lib.NullProgressMonitor;
 import org.eclipse.jgit.lib.ObjectId;
@@ -47,25 +54,19 @@
 import org.eclipse.jgit.storage.pack.PackStatistics;
 import org.eclipse.jgit.transport.UploadPack.RequestPolicy;
 import org.eclipse.jgit.util.io.NullOutputStream;
-import org.hamcrest.Matchers;
 import org.junit.After;
 import org.junit.Before;
-import org.junit.Rule;
 import org.junit.Test;
-import org.junit.rules.ExpectedException;
 
 /**
  * Tests for server upload-pack utilities.
  */
 public class UploadPackTest {
-	@Rule
-	public ExpectedException thrown = ExpectedException.none();
-
 	private URIish uri;
 
 	private TestProtocol<Object> testProtocol;
 
-	private Object ctx = new Object();
+	private final Object ctx = new Object();
 
 	private InMemoryRepository server;
 
@@ -144,11 +145,11 @@
 		assertFalse(client.getObjectDatabase().has(blob.toObjectId()));
 
 		try (Transport tn = testProtocol.open(uri, client, "server")) {
-			thrown.expect(TransportException.class);
-			thrown.expectMessage(Matchers.containsString(
-						"want " + blob.name() + " not valid"));
-			tn.fetch(NullProgressMonitor.INSTANCE,
-					Collections.singletonList(new RefSpec(blob.name())));
+			TransportException e = assertThrows(TransportException.class,
+					() -> tn.fetch(NullProgressMonitor.INSTANCE, Collections
+							.singletonList(new RefSpec(blob.name()))));
+			assertThat(e.getMessage(),
+					containsString("want " + blob.name() + " not valid"));
 		}
 	}
 
@@ -183,11 +184,41 @@
 		assertFalse(client.getObjectDatabase().has(blob.toObjectId()));
 
 		try (Transport tn = testProtocol.open(uri, client, "server")) {
-			thrown.expect(TransportException.class);
-			thrown.expectMessage(Matchers.containsString(
+			TransportException e = assertThrows(TransportException.class,
+					() -> tn.fetch(NullProgressMonitor.INSTANCE, Collections
+							.singletonList(new RefSpec(blob.name()))));
+			assertThat(e.getMessage(),
+					containsString(
 						"want " + blob.name() + " not valid"));
-			tn.fetch(NullProgressMonitor.INSTANCE,
-					Collections.singletonList(new RefSpec(blob.name())));
+		}
+	}
+
+	@Test
+	public void testFetchReachableBlobWithoutBitmapButFilterAllowed() throws Exception {
+		InMemoryRepository server2 = newRepo("server2");
+		try (TestRepository<InMemoryRepository> remote2 = new TestRepository<>(
+				server2)) {
+			RevBlob blob = remote2.blob("foo");
+			RevCommit commit = remote2.commit(remote2.tree(remote2.file("foo", blob)));
+			remote2.update("master", commit);
+
+			server2.getConfig().setBoolean("uploadpack", null, "allowfilter",
+					true);
+
+			testProtocol = new TestProtocol<>((Object req, Repository db) -> {
+				UploadPack up = new UploadPack(db);
+				up.setRequestPolicy(RequestPolicy.REACHABLE_COMMIT);
+				return up;
+			}, null);
+			uri = testProtocol.register(ctx, server2);
+
+			assertFalse(client.getObjectDatabase().has(blob.toObjectId()));
+
+			try (Transport tn = testProtocol.open(uri, client, "server2")) {
+				tn.fetch(NullProgressMonitor.INSTANCE,
+						Collections.singletonList(new RefSpec(blob.name())));
+				assertTrue(client.getObjectDatabase().has(blob.toObjectId()));
+			}
 		}
 	}
 
@@ -384,12 +415,11 @@
 			try (Transport tn = testProtocol.open(uri, client, "server2")) {
 				tn.setFilterSpec(FilterSpec.withBlobLimit(0));
 
-				thrown.expect(TransportException.class);
-				thrown.expectMessage(
-						"filter requires server to advertise that capability");
-
-				tn.fetch(NullProgressMonitor.INSTANCE,
-						Collections.singletonList(new RefSpec(commit.name())));
+				TransportException e = assertThrows(TransportException.class,
+						() -> tn.fetch(NullProgressMonitor.INSTANCE, Collections
+								.singletonList(new RefSpec(commit.name()))));
+				assertThat(e.getMessage(), containsString(
+						"filter requires server to advertise that capability"));
 			}
 		}
 	}
@@ -398,22 +428,18 @@
 	 * Invokes UploadPack with protocol v2 and sends it the given lines,
 	 * and returns UploadPack's output stream.
 	 */
-	private ByteArrayInputStream uploadPackV2Setup(RequestPolicy requestPolicy,
-			RefFilter refFilter, ProtocolV2Hook hook, String... inputLines)
+	private ByteArrayInputStream uploadPackV2Setup(
+			Consumer<UploadPack> postConstructionSetup, String... inputLines)
 			throws Exception {
 
 		ByteArrayInputStream send = linesAsInputStream(inputLines);
 
 		server.getConfig().setString("protocol", null, "version", "2");
 		UploadPack up = new UploadPack(server);
-		if (requestPolicy != null)
-			up.setRequestPolicy(requestPolicy);
-		if (refFilter != null)
-			up.setRefFilter(refFilter);
-		up.setExtraParameters(Sets.of("version=2"));
-		if (hook != null) {
-			up.setProtocolV2Hook(hook);
+		if (postConstructionSetup != null) {
+			postConstructionSetup.accept(up);
 		}
+		up.setExtraParameters(Sets.of("version=2"));
 
 		ByteArrayOutputStream recv = new ByteArrayOutputStream();
 		up.upload(send, recv, null);
@@ -427,6 +453,7 @@
 		try (ByteArrayOutputStream send = new ByteArrayOutputStream()) {
 			PacketLineOut pckOut = new PacketLineOut(send);
 			for (String line : inputLines) {
+				Objects.requireNonNull(line);
 				if (PacketLineIn.isEnd(line)) {
 					pckOut.end();
 				} else if (PacketLineIn.isDelimiter(line)) {
@@ -444,11 +471,12 @@
 	 * Returns UploadPack's output stream, not including the capability
 	 * advertisement by the server.
 	 */
-	private ByteArrayInputStream uploadPackV2(RequestPolicy requestPolicy,
-			RefFilter refFilter, ProtocolV2Hook hook, String... inputLines)
+	private ByteArrayInputStream uploadPackV2(
+			Consumer<UploadPack> postConstructionSetup,
+			String... inputLines)
 			throws Exception {
 		ByteArrayInputStream recvStream =
-				uploadPackV2Setup(requestPolicy, refFilter, hook, inputLines);
+				uploadPackV2Setup(postConstructionSetup, inputLines);
 		PacketLineIn pckIn = new PacketLineIn(recvStream);
 
 		// drain capabilities
@@ -459,7 +487,7 @@
 	}
 
 	private ByteArrayInputStream uploadPackV2(String... inputLines) throws Exception {
-		return uploadPackV2(null, null, null, inputLines);
+		return uploadPackV2(null, inputLines);
 	}
 
 	private static class TestV2Hook implements ProtocolV2Hook {
@@ -488,8 +516,9 @@
 	@Test
 	public void testV2Capabilities() throws Exception {
 		TestV2Hook hook = new TestV2Hook();
-		ByteArrayInputStream recvStream =
-				uploadPackV2Setup(null, null, hook, PacketLineIn.end());
+		ByteArrayInputStream recvStream = uploadPackV2Setup(
+				(UploadPack up) -> {up.setProtocolV2Hook(hook);},
+				PacketLineIn.end());
 		PacketLineIn pckIn = new PacketLineIn(recvStream);
 		assertThat(hook.capabilitiesRequest, notNullValue());
 		assertThat(pckIn.readString(), is("version 2"));
@@ -506,54 +535,72 @@
 		assertTrue(PacketLineIn.isEnd(pckIn.readString()));
 	}
 
-	@Test
-	public void testV2CapabilitiesAllowFilter() throws Exception {
-		server.getConfig().setBoolean("uploadpack", null, "allowfilter", true);
+	private void checkAdvertisedIfAllowed(String configSection, String configName,
+			String fetchCapability) throws Exception {
+		server.getConfig().setBoolean(configSection, null, configName, true);
 		ByteArrayInputStream recvStream =
-				uploadPackV2Setup(null, null, null, PacketLineIn.end());
+				uploadPackV2Setup(null, PacketLineIn.end());
 		PacketLineIn pckIn = new PacketLineIn(recvStream);
 
 		assertThat(pckIn.readString(), is("version 2"));
-		assertThat(
-				Arrays.asList(pckIn.readString(), pckIn.readString(),
-						pckIn.readString()),
-				// TODO(jonathantanmy) This check overspecifies the
-				// order of the capabilities of "fetch".
-				hasItems("ls-refs", "fetch=filter shallow", "server-option"));
-		assertTrue(PacketLineIn.isEnd(pckIn.readString()));
+
+		ArrayList<String> lines = new ArrayList<>();
+		String line;
+		while (!PacketLineIn.isEnd((line = pckIn.readString()))) {
+			if (line.startsWith("fetch=")) {
+				assertThat(
+					Arrays.asList(line.substring(6).split(" ")),
+					containsInAnyOrder(fetchCapability, "shallow"));
+				lines.add("fetch");
+			} else {
+				lines.add(line);
+			}
+		}
+		assertThat(lines, containsInAnyOrder("ls-refs", "fetch", "server-option"));
+	}
+
+	private void checkUnadvertisedIfUnallowed(String fetchCapability) throws Exception {
+		ByteArrayInputStream recvStream =
+				uploadPackV2Setup(null, PacketLineIn.end());
+		PacketLineIn pckIn = new PacketLineIn(recvStream);
+
+		assertThat(pckIn.readString(), is("version 2"));
+
+		ArrayList<String> lines = new ArrayList<>();
+		String line;
+		while (!PacketLineIn.isEnd((line = pckIn.readString()))) {
+			if (line.startsWith("fetch=")) {
+				assertThat(
+					Arrays.asList(line.substring(6).split(" ")),
+					hasItems("shallow"));
+				lines.add("fetch");
+			} else {
+				lines.add(line);
+			}
+		}
+		assertThat(lines, hasItems("ls-refs", "fetch", "server-option"));
+	}
+
+	@Test
+	public void testV2CapabilitiesAllowFilter() throws Exception {
+		checkAdvertisedIfAllowed("uploadpack", "allowfilter", "filter");
+		checkUnadvertisedIfUnallowed("filter");
 	}
 
 	@Test
 	public void testV2CapabilitiesRefInWant() throws Exception {
-		server.getConfig().setBoolean("uploadpack", null, "allowrefinwant", true);
-		ByteArrayInputStream recvStream =
-				uploadPackV2Setup(null, null, null, PacketLineIn.end());
-		PacketLineIn pckIn = new PacketLineIn(recvStream);
-
-		assertThat(pckIn.readString(), is("version 2"));
-		assertThat(
-				Arrays.asList(pckIn.readString(), pckIn.readString(),
-						pckIn.readString()),
-				// TODO(jonathantanmy) This check overspecifies the
-				// order of the capabilities of "fetch".
-				hasItems("ls-refs", "fetch=ref-in-want shallow",
-						"server-option"));
-		assertTrue(PacketLineIn.isEnd(pckIn.readString()));
+		checkAdvertisedIfAllowed("uploadpack", "allowrefinwant", "ref-in-want");
 	}
 
 	@Test
 	public void testV2CapabilitiesRefInWantNotAdvertisedIfUnallowed() throws Exception {
-		server.getConfig().setBoolean("uploadpack", null, "allowrefinwant", false);
-		ByteArrayInputStream recvStream =
-				uploadPackV2Setup(null, null, null, PacketLineIn.end());
-		PacketLineIn pckIn = new PacketLineIn(recvStream);
+		checkUnadvertisedIfUnallowed("ref-in-want");
+	}
 
-		assertThat(pckIn.readString(), is("version 2"));
-		assertThat(
-				Arrays.asList(pckIn.readString(), pckIn.readString(),
-						pckIn.readString()),
-				hasItems("ls-refs", "fetch=shallow", "server-option"));
-		assertTrue(PacketLineIn.isEnd(pckIn.readString()));
+	@Test
+	public void testV2CapabilitiesAllowSidebandAll() throws Exception {
+		checkAdvertisedIfAllowed("uploadpack", "allowsidebandall", "sideband-all");
+		checkUnadvertisedIfUnallowed("sideband-all");
 	}
 
 	@Test
@@ -561,7 +608,7 @@
 		server.getConfig().setBoolean("uploadpack", null, "allowrefinwant", true);
 		server.getConfig().setBoolean("uploadpack", null, "advertiserefinwant", false);
 		ByteArrayInputStream recvStream =
-				uploadPackV2Setup(null, null, null, PacketLineIn.end());
+				uploadPackV2Setup(null, PacketLineIn.end());
 		PacketLineIn pckIn = new PacketLineIn(recvStream);
 
 		assertThat(pckIn.readString(), is("version 2"));
@@ -589,7 +636,8 @@
 		remote.update("refs/tags/tag", tag);
 
 		TestV2Hook hook = new TestV2Hook();
-		ByteArrayInputStream recvStream = uploadPackV2(null, null, hook,
+		ByteArrayInputStream recvStream = uploadPackV2(
+				(UploadPack up) -> {up.setProtocolV2Hook(hook);},
 				"command=ls-refs\n", PacketLineIn.end());
 		PacketLineIn pckIn = new PacketLineIn(recvStream);
 
@@ -707,13 +755,13 @@
 
 	@Test
 	public void testV2LsRefsUnrecognizedArgument() throws Exception {
-		thrown.expect(PackProtocolException.class);
-		thrown.expectMessage("unexpected invalid-argument");
-		uploadPackV2(
-			"command=ls-refs\n",
-			PacketLineIn.delimiter(),
-			"invalid-argument\n",
-				PacketLineIn.end());
+		UploadPackInternalServerErrorException e = assertThrows(
+				UploadPackInternalServerErrorException.class,
+				() -> uploadPackV2("command=ls-refs\n",
+						PacketLineIn.delimiter(), "invalid-argument\n",
+						PacketLineIn.end()));
+		assertThat(e.getCause().getMessage(),
+				containsString("unexpected invalid-argument"));
 	}
 
 	@Test
@@ -724,7 +772,7 @@
 				PacketLineIn.end() };
 
 		TestV2Hook testHook = new TestV2Hook();
-		uploadPackV2Setup(null, null, testHook, lines);
+		uploadPackV2Setup((UploadPack up) -> {up.setProtocolV2Hook(testHook);}, lines);
 
 		LsRefsV2Request req = testHook.lsRefsRequest;
 		assertEquals(2, req.getServerOptions().size());
@@ -761,118 +809,117 @@
 
 		// This works
 		uploadPackV2(
-			RequestPolicy.ADVERTISED,
-			null,
-			null,
+			(UploadPack up) -> {up.setRequestPolicy(RequestPolicy.ADVERTISED);},
 			"command=fetch\n",
 			PacketLineIn.delimiter(),
 			"want " + advertized.name() + "\n",
-				PacketLineIn.end());
+			PacketLineIn.end());
 
 		// This doesn't
-		thrown.expect(TransportException.class);
-		thrown.expectMessage(Matchers.containsString(
-					"want " + unadvertized.name() + " not valid"));
-		uploadPackV2(
-			RequestPolicy.ADVERTISED,
-			null,
-			null,
-			"command=fetch\n",
-			PacketLineIn.delimiter(),
-			"want " + unadvertized.name() + "\n",
-				PacketLineIn.end());
+		UploadPackInternalServerErrorException e = assertThrows(
+				UploadPackInternalServerErrorException.class,
+				() -> uploadPackV2(
+						(UploadPack up) -> {up.setRequestPolicy(RequestPolicy.ADVERTISED);},
+						"command=fetch\n", PacketLineIn.delimiter(),
+						"want " + unadvertized.name() + "\n",
+						PacketLineIn.end()));
+		assertThat(e.getCause().getMessage(),
+				containsString("want " + unadvertized.name() + " not valid"));
 	}
 
 	@Test
 	public void testV2FetchRequestPolicyReachableCommit() throws Exception {
 		RevCommit reachable = remote.commit().message("x").create();
-		RevCommit advertized = remote.commit().message("x").parent(reachable).create();
+		RevCommit advertized = remote.commit().message("x").parent(reachable)
+				.create();
 		RevCommit unreachable = remote.commit().message("y").create();
 		remote.update("branch1", advertized);
 
 		// This works
 		uploadPackV2(
-			RequestPolicy.REACHABLE_COMMIT,
-			null,
-			null,
+			(UploadPack up) -> {up.setRequestPolicy(RequestPolicy.REACHABLE_COMMIT);},
 			"command=fetch\n",
 			PacketLineIn.delimiter(),
 			"want " + reachable.name() + "\n",
 				PacketLineIn.end());
 
 		// This doesn't
-		thrown.expect(TransportException.class);
-		thrown.expectMessage(Matchers.containsString(
-					"want " + unreachable.name() + " not valid"));
-		uploadPackV2(
-			RequestPolicy.REACHABLE_COMMIT,
-			null,
-			null,
-			"command=fetch\n",
-			PacketLineIn.delimiter(),
-			"want " + unreachable.name() + "\n",
-				PacketLineIn.end());
+		UploadPackInternalServerErrorException e = assertThrows(
+				UploadPackInternalServerErrorException.class,
+				() -> uploadPackV2(
+						(UploadPack up) -> {up.setRequestPolicy(RequestPolicy.REACHABLE_COMMIT);},
+						"command=fetch\n", PacketLineIn.delimiter(),
+						"want " + unreachable.name() + "\n",
+						PacketLineIn.end()));
+		assertThat(e.getCause().getMessage(),
+				containsString("want " + unreachable.name() + " not valid"));
 	}
 
 	@Test
 	public void testV2FetchRequestPolicyTip() throws Exception {
 		RevCommit parentOfTip = remote.commit().message("x").create();
-		RevCommit tip = remote.commit().message("y").parent(parentOfTip).create();
+		RevCommit tip = remote.commit().message("y").parent(parentOfTip)
+				.create();
 		remote.update("secret", tip);
 
 		// This works
 		uploadPackV2(
-			RequestPolicy.TIP,
-			new RejectAllRefFilter(),
-			null,
+			(UploadPack up) -> {
+				up.setRequestPolicy(RequestPolicy.TIP);
+				up.setRefFilter(new RejectAllRefFilter());
+			},
 			"command=fetch\n",
 			PacketLineIn.delimiter(),
 			"want " + tip.name() + "\n",
 				PacketLineIn.end());
 
 		// This doesn't
-		thrown.expect(TransportException.class);
-		thrown.expectMessage(Matchers.containsString(
-					"want " + parentOfTip.name() + " not valid"));
-		uploadPackV2(
-			RequestPolicy.TIP,
-			new RejectAllRefFilter(),
-			null,
-			"command=fetch\n",
-			PacketLineIn.delimiter(),
-			"want " + parentOfTip.name() + "\n",
-				PacketLineIn.end());
+		UploadPackInternalServerErrorException e = assertThrows(
+				UploadPackInternalServerErrorException.class,
+				() -> uploadPackV2(
+						(UploadPack up) -> {
+							up.setRequestPolicy(RequestPolicy.TIP);
+							up.setRefFilter(new RejectAllRefFilter());
+						},
+						"command=fetch\n", PacketLineIn.delimiter(),
+						"want " + parentOfTip.name() + "\n",
+						PacketLineIn.end()));
+		assertThat(e.getCause().getMessage(),
+				containsString("want " + parentOfTip.name() + " not valid"));
 	}
 
 	@Test
 	public void testV2FetchRequestPolicyReachableCommitTip() throws Exception {
 		RevCommit parentOfTip = remote.commit().message("x").create();
-		RevCommit tip = remote.commit().message("y").parent(parentOfTip).create();
+		RevCommit tip = remote.commit().message("y").parent(parentOfTip)
+				.create();
 		RevCommit unreachable = remote.commit().message("y").create();
 		remote.update("secret", tip);
 
 		// This works
 		uploadPackV2(
-			RequestPolicy.REACHABLE_COMMIT_TIP,
-			new RejectAllRefFilter(),
-			null,
-			"command=fetch\n",
-			PacketLineIn.delimiter(),
-			"want " + parentOfTip.name() + "\n",
+				(UploadPack up) -> {
+					up.setRequestPolicy(RequestPolicy.REACHABLE_COMMIT_TIP);
+					up.setRefFilter(new RejectAllRefFilter());
+				},
+				"command=fetch\n",
+				PacketLineIn.delimiter(), "want " + parentOfTip.name() + "\n",
 				PacketLineIn.end());
 
 		// This doesn't
-		thrown.expect(TransportException.class);
-		thrown.expectMessage(Matchers.containsString(
-					"want " + unreachable.name() + " not valid"));
-		uploadPackV2(
-			RequestPolicy.REACHABLE_COMMIT_TIP,
-			new RejectAllRefFilter(),
-			null,
-			"command=fetch\n",
-			PacketLineIn.delimiter(),
-			"want " + unreachable.name() + "\n",
-				PacketLineIn.end());
+		UploadPackInternalServerErrorException e = assertThrows(
+				UploadPackInternalServerErrorException.class,
+				() -> uploadPackV2(
+						(UploadPack up) -> {
+							up.setRequestPolicy(RequestPolicy.REACHABLE_COMMIT_TIP);
+							up.setRefFilter(new RejectAllRefFilter());
+						},
+						"command=fetch\n",
+						PacketLineIn.delimiter(),
+						"want " + unreachable.name() + "\n",
+						PacketLineIn.end()));
+		assertThat(e.getCause().getMessage(),
+				containsString("want " + unreachable.name() + " not valid"));
 	}
 
 	@Test
@@ -881,9 +928,7 @@
 
 		// Exercise to make sure that even unreachable commits can be fetched
 		uploadPackV2(
-			RequestPolicy.ANY,
-			null,
-			null,
+			(UploadPack up) -> {up.setRequestPolicy(RequestPolicy.ANY);},
 			"command=fetch\n",
 			PacketLineIn.delimiter(),
 			"want " + unreachable.name() + "\n",
@@ -980,29 +1025,29 @@
 		String commonInBlob = "abcdefghijklmnopqrstuvwxyz";
 
 		RevBlob parentBlob = remote.blob(commonInBlob + "a");
-		RevCommit parent = remote.commit(remote.tree(remote.file("foo", parentBlob)));
+		RevCommit parent = remote
+				.commit(remote.tree(remote.file("foo", parentBlob)));
 		RevBlob childBlob = remote.blob(commonInBlob + "b");
-		RevCommit child = remote.commit(remote.tree(remote.file("foo", childBlob)), parent);
+		RevCommit child = remote
+				.commit(remote.tree(remote.file("foo", childBlob)), parent);
 		remote.update("branch1", child);
 
 		// Pretend that we have parent to get a thin pack based on it.
-		ByteArrayInputStream recvStream = uploadPackV2(
-			"command=fetch\n",
-			PacketLineIn.delimiter(),
-			"want " + child.toObjectId().getName() + "\n",
-			"have " + parent.toObjectId().getName() + "\n",
-			"thin-pack\n",
-			"done\n",
-				PacketLineIn.end());
+		ByteArrayInputStream recvStream = uploadPackV2("command=fetch\n",
+				PacketLineIn.delimiter(),
+				"want " + child.toObjectId().getName() + "\n",
+				"have " + parent.toObjectId().getName() + "\n", "thin-pack\n",
+				"done\n", PacketLineIn.end());
 		PacketLineIn pckIn = new PacketLineIn(recvStream);
 
 		assertThat(pckIn.readString(), is("packfile"));
 
 		// Verify that we received a thin pack by trying to apply it
 		// against the client repo, which does not have parent.
-		thrown.expect(IOException.class);
-		thrown.expectMessage("pack has unresolved deltas");
-		parsePack(recvStream);
+		IOException e = assertThrows(IOException.class,
+				() -> parsePack(recvStream));
+		assertThat(e.getMessage(),
+				containsString("pack has unresolved deltas"));
 	}
 
 	@Test
@@ -1303,19 +1348,18 @@
 		PersonIdent person = new PersonIdent(remote.getRepository());
 
 		RevCommit tooOld = remote.commit()
-			.committer(new PersonIdent(person, 1500000000, 0)).create();
+				.committer(new PersonIdent(person, 1500000000, 0)).create();
 
 		remote.update("branch1", tooOld);
 
-		thrown.expect(PackProtocolException.class);
-		thrown.expectMessage("No commits selected for shallow request");
-		uploadPackV2(
-			"command=fetch\n",
-			PacketLineIn.delimiter(),
-			"deepen-since 1510000\n",
-			"want " + tooOld.toObjectId().getName() + "\n",
-			"done\n",
-				PacketLineIn.end());
+		UploadPackInternalServerErrorException e = assertThrows(
+				UploadPackInternalServerErrorException.class,
+				() -> uploadPackV2("command=fetch\n", PacketLineIn.delimiter(),
+						"deepen-since 1510000\n",
+						"want " + tooOld.toObjectId().getName() + "\n",
+						"done\n", PacketLineIn.end()));
+		assertThat(e.getCause().getMessage(),
+				containsString("No commits selected for shallow request"));
 	}
 
 	@Test
@@ -1374,7 +1418,8 @@
 	}
 
 	@Test
-	public void testV2FetchDeepenNot_excludeDescendantOfWant() throws Exception {
+	public void testV2FetchDeepenNot_excludeDescendantOfWant()
+			throws Exception {
 		RevCommit one = remote.commit().message("one").create();
 		RevCommit two = remote.commit().message("two").parent(one).create();
 		RevCommit three = remote.commit().message("three").parent(two).create();
@@ -1383,15 +1428,14 @@
 		remote.update("two", two);
 		remote.update("four", four);
 
-		thrown.expect(PackProtocolException.class);
-		thrown.expectMessage("No commits selected for shallow request");
-		uploadPackV2(
-			"command=fetch\n",
-			PacketLineIn.delimiter(),
-			"deepen-not four\n",
-			"want " + two.toObjectId().getName() + "\n",
-			"done\n",
-				PacketLineIn.end());
+		UploadPackInternalServerErrorException e = assertThrows(
+				UploadPackInternalServerErrorException.class,
+				() -> uploadPackV2("command=fetch\n", PacketLineIn.delimiter(),
+						"deepen-not four\n",
+						"want " + two.toObjectId().getName() + "\n", "done\n",
+						PacketLineIn.end()));
+		assertThat(e.getCause().getMessage(),
+				containsString("No commits selected for shallow request"));
 	}
 
 	@Test
@@ -1469,13 +1513,12 @@
 
 	@Test
 	public void testV2FetchUnrecognizedArgument() throws Exception {
-		thrown.expect(PackProtocolException.class);
-		thrown.expectMessage("unexpected invalid-argument");
-		uploadPackV2(
-			"command=fetch\n",
-			PacketLineIn.delimiter(),
-			"invalid-argument\n",
-				PacketLineIn.end());
+		UploadPackInternalServerErrorException e = assertThrows(
+				UploadPackInternalServerErrorException.class,
+				() -> uploadPackV2("command=fetch\n", PacketLineIn.delimiter(),
+						"invalid-argument\n", PacketLineIn.end()));
+		assertThat(e.getCause().getMessage(),
+				containsString("unexpected invalid-argument"));
 	}
 
 	@Test
@@ -1485,7 +1528,7 @@
 				PacketLineIn.end() };
 
 		TestV2Hook testHook = new TestV2Hook();
-		uploadPackV2Setup(null, null, testHook, lines);
+		uploadPackV2Setup((UploadPack up) -> {up.setProtocolV2Hook(testHook);}, lines);
 
 		FetchV2Request req = testHook.fetchRequest;
 		assertNotNull(req);
@@ -1569,8 +1612,9 @@
 		input.add("done\n");
 		input.add(PacketLineIn.end());
 		ByteArrayInputStream recvStream =
-				uploadPackV2(RequestPolicy.ANY, /*refFilter=*/null,
-							 /*hook=*/null, input.toArray(new String[0]));
+				uploadPackV2(
+						(UploadPack up) -> {up.setRequestPolicy(RequestPolicy.ANY);},
+						input.toArray(new String[0]));
 		PacketLineIn pckIn = new PacketLineIn(recvStream);
 		assertThat(pckIn.readString(), is("packfile"));
 		parsePack(recvStream);
@@ -1837,43 +1881,39 @@
 				.has(preparator.subtree3.toObjectId()));
 	}
 
-	@Test
-	public void testV2FetchFilterWhenNotAllowed() throws Exception {
+	private void checkV2FetchWhenNotAllowed(String fetchLine, String expectedMessage)
+			throws Exception {
 		RevCommit commit = remote.commit().message("0").create();
 		remote.update("master", commit);
 
-		server.getConfig().setBoolean("uploadpack", null, "allowfilter", false);
+		UploadPackInternalServerErrorException e = assertThrows(
+				UploadPackInternalServerErrorException.class,
+				() -> uploadPackV2("command=fetch\n", PacketLineIn.delimiter(),
+						"want " + commit.toObjectId().getName() + "\n",
+						fetchLine, "done\n", PacketLineIn.end()));
+		assertThat(e.getCause().getMessage(),
+				containsString(expectedMessage));
+	}
 
-		thrown.expect(PackProtocolException.class);
-		thrown.expectMessage("unexpected filter blob:limit=5");
-		uploadPackV2(
-			"command=fetch\n",
-			PacketLineIn.delimiter(),
-			"want " + commit.toObjectId().getName() + "\n",
+	@Test
+	public void testV2FetchFilterWhenNotAllowed() throws Exception {
+		checkV2FetchWhenNotAllowed(
 			"filter blob:limit=5\n",
-			"done\n",
-				PacketLineIn.end());
+			"unexpected filter blob:limit=5");
 	}
 
 	@Test
 	public void testV2FetchWantRefIfNotAllowed() throws Exception {
-		RevCommit one = remote.commit().message("1").create();
-		remote.update("one", one);
+		checkV2FetchWhenNotAllowed(
+			"want-ref refs/heads/one\n",
+			"unexpected want-ref refs/heads/one");
+	}
 
-		try {
-			uploadPackV2(
-				"command=fetch\n",
-				PacketLineIn.delimiter(),
-				"want-ref refs/heads/one\n",
-				"done\n",
-					PacketLineIn.end());
-		} catch (PackProtocolException e) {
-			assertThat(
-				e.getMessage(),
-				containsString("unexpected want-ref refs/heads/one"));
-			return;
-		}
-		fail("expected PackProtocolException");
+	@Test
+	public void testV2FetchSidebandAllIfNotAllowed() throws Exception {
+		checkV2FetchWhenNotAllowed(
+			"sideband-all\n",
+			"unexpected sideband-all");
 	}
 
 	@Test
@@ -1915,23 +1955,17 @@
 		RevCommit one = remote.commit().message("1").create();
 		remote.update("one", one);
 
-		server.getConfig().setBoolean("uploadpack", null, "allowrefinwant", true);
+		server.getConfig().setBoolean("uploadpack", null, "allowrefinwant",
+				true);
 
-		try {
-			uploadPackV2(
-				"command=fetch\n",
-				PacketLineIn.delimiter(),
-				"want-ref refs/heads/one\n",
-				"want-ref refs/heads/nonExistentRef\n",
-				"done\n",
-					PacketLineIn.end());
-		} catch (PackProtocolException e) {
-			assertThat(
-				e.getMessage(),
+		UploadPackInternalServerErrorException e = assertThrows(
+				UploadPackInternalServerErrorException.class,
+				() -> uploadPackV2("command=fetch\n", PacketLineIn.delimiter(),
+						"want-ref refs/heads/one\n",
+						"want-ref refs/heads/nonExistentRef\n", "done\n",
+						PacketLineIn.end()));
+		assertThat(e.getCause().getMessage(),
 				containsString("Invalid ref name: refs/heads/nonExistentRef"));
-			return;
-		}
-		fail("expected PackProtocolException");
 	}
 
 	@Test
@@ -2066,6 +2100,110 @@
 	}
 
 	@Test
+	public void testV2FetchSidebandAllNoPackfile() throws Exception {
+		RevCommit fooParent = remote.commit().message("x").create();
+		RevCommit fooChild = remote.commit().message("x").parent(fooParent).create();
+		RevCommit barParent = remote.commit().message("y").create();
+		RevCommit barChild = remote.commit().message("y").parent(barParent).create();
+		remote.update("branch1", fooChild);
+		remote.update("branch2", barChild);
+
+		server.getConfig().setBoolean("uploadpack", null, "allowsidebandall", true);
+
+		ByteArrayInputStream recvStream = uploadPackV2(
+			"command=fetch\n",
+			PacketLineIn.DELIM,
+			"sideband-all\n",
+			"want " + fooChild.toObjectId().getName() + "\n",
+			"want " + barChild.toObjectId().getName() + "\n",
+			"have " + fooParent.toObjectId().getName() + "\n",
+			PacketLineIn.END);
+		PacketLineIn pckIn = new PacketLineIn(recvStream);
+
+		assertThat(pckIn.readString(), is("\001acknowledgments"));
+		assertThat(pckIn.readString(), is("\001ACK " + fooParent.getName()));
+		assertTrue(PacketLineIn.isEnd(pckIn.readString()));
+	}
+
+	@Test
+	public void testV2FetchSidebandAllPackfile() throws Exception {
+		RevCommit commit = remote.commit().message("x").create();
+		remote.update("master", commit);
+
+		server.getConfig().setBoolean("uploadpack", null, "allowsidebandall", true);
+
+		ByteArrayInputStream recvStream = uploadPackV2("command=fetch\n",
+				PacketLineIn.DELIM,
+				"want " + commit.getName() + "\n",
+				"sideband-all\n",
+				"done\n",
+				PacketLineIn.END);
+		PacketLineIn pckIn = new PacketLineIn(recvStream);
+
+		String s;
+		// When sideband-all is used, object counting happens before
+		// "packfile" is written, and object counting outputs progress
+		// in sideband 2. Skip all these lines.
+		for (s = pckIn.readString(); s.startsWith("\002"); s = pckIn.readString()) {
+			// do nothing
+		}
+		assertThat(s, is("\001packfile"));
+		parsePack(recvStream);
+	}
+
+	@Test
+	public void testV2FetchPackfileUris() throws Exception {
+		// Inside the pack
+		RevCommit commit = remote.commit().message("x").create();
+		remote.update("master", commit);
+		generateBitmaps(server);
+
+		// Outside the pack
+		RevCommit commit2 = remote.commit().message("x").parent(commit).create();
+		remote.update("master", commit2);
+
+		server.getConfig().setBoolean("uploadpack", null, "allowsidebandall", true);
+
+		ByteArrayInputStream recvStream = uploadPackV2(
+			(UploadPack up) -> {
+				up.setCachedPackUriProvider(new CachedPackUriProvider() {
+					@Override
+					public PackInfo getInfo(CachedPack pack,
+							Collection<String> protocolsSupported)
+							throws IOException {
+						assertThat(protocolsSupported, hasItems("https"));
+						if (!protocolsSupported.contains("https"))
+							return null;
+						return new PackInfo("myhash", "myuri");
+					}
+
+				});
+			},
+			"command=fetch\n",
+			PacketLineIn.DELIM,
+			"want " + commit2.getName() + "\n",
+			"sideband-all\n",
+			"packfile-uris https\n",
+			"done\n",
+			PacketLineIn.END);
+		PacketLineIn pckIn = new PacketLineIn(recvStream);
+
+		String s;
+		// skip all \002 strings
+		for (s = pckIn.readString(); s.startsWith("\002"); s = pckIn.readString()) {
+			// do nothing
+		}
+		assertThat(s, is("\001packfile-uris"));
+		assertThat(pckIn.readString(), is("\001myhash myuri"));
+		assertTrue(PacketLineIn.isDelimiter(pckIn.readString()));
+		assertThat(pckIn.readString(), is("\001packfile"));
+		parsePack(recvStream);
+
+		assertFalse(client.getObjectDatabase().has(commit.toObjectId()));
+		assertTrue(client.getObjectDatabase().has(commit2.toObjectId()));
+	}
+
+	@Test
 	public void testGetPeerAgentProtocolV0() throws Exception {
 		RevCommit one = remote.commit().message("1").create();
 		remote.update("one", one);
@@ -2110,4 +2248,84 @@
 			return new HashMap<>();
 		}
 	}
+
+	@Test
+	public void testSingleBranchCloneTagChain() throws Exception {
+		RevBlob blob0 = remote.blob("Initial content of first file");
+		RevBlob blob1 = remote.blob("Second file content");
+		RevCommit commit0 = remote
+				.commit(remote.tree(remote.file("prvni.txt", blob0)));
+		RevCommit commit1 = remote
+				.commit(remote.tree(remote.file("druhy.txt", blob1)), commit0);
+		remote.update("master", commit1);
+
+		RevTag heavyTag1 = remote.tag("commitTagRing", commit0);
+		remote.getRevWalk().parseHeaders(heavyTag1);
+		RevTag heavyTag2 = remote.tag("middleTagRing", heavyTag1);
+		remote.lightweightTag("refTagRing", heavyTag2);
+
+		UploadPack uploadPack = new UploadPack(remote.getRepository());
+
+		ByteArrayOutputStream cli = new ByteArrayOutputStream();
+		PacketLineOut clientWant = new PacketLineOut(cli);
+		clientWant.writeString("want " + commit1.name()
+				+ " multi_ack_detailed include-tag thin-pack ofs-delta agent=tempo/pflaska");
+		clientWant.end();
+		clientWant.writeString("done\n");
+
+		try (ByteArrayOutputStream serverResponse = new ByteArrayOutputStream()) {
+
+			uploadPack.setPreUploadHook(new PreUploadHook() {
+				@Override
+				public void onBeginNegotiateRound(UploadPack up,
+						Collection<? extends ObjectId> wants, int cntOffered)
+						throws ServiceMayNotContinueException {
+					// Do nothing.
+				}
+
+				@Override
+				public void onEndNegotiateRound(UploadPack up,
+						Collection<? extends ObjectId> wants, int cntCommon,
+						int cntNotFound, boolean ready)
+						throws ServiceMayNotContinueException {
+					// Do nothing.
+				}
+
+				@Override
+				public void onSendPack(UploadPack up,
+						Collection<? extends ObjectId> wants,
+						Collection<? extends ObjectId> haves)
+						throws ServiceMayNotContinueException {
+					// collect pack data
+					serverResponse.reset();
+				}
+			});
+			uploadPack.upload(new ByteArrayInputStream(cli.toByteArray()),
+					serverResponse, System.err);
+			InputStream packReceived = new ByteArrayInputStream(
+					serverResponse.toByteArray());
+			PackLock lock = null;
+			try (ObjectInserter ins = client.newObjectInserter()) {
+				PackParser parser = ins.newPackParser(packReceived);
+				parser.setAllowThin(true);
+				parser.setLockMessage("receive-tag-chain");
+				ProgressMonitor mlc = NullProgressMonitor.INSTANCE;
+				lock = parser.parse(mlc, mlc);
+				ins.flush();
+			} finally {
+				if (lock != null) {
+					lock.unlock();
+				}
+			}
+			InMemoryRepository.MemObjDatabase objDb = client
+					.getObjectDatabase();
+			assertTrue(objDb.has(blob0.toObjectId()));
+			assertTrue(objDb.has(blob1.toObjectId()));
+			assertTrue(objDb.has(commit0.toObjectId()));
+			assertTrue(objDb.has(commit1.toObjectId()));
+			assertTrue(objDb.has(heavyTag1.toObjectId()));
+			assertTrue(objDb.has(heavyTag2.toObjectId()));
+		}
+	}
+
 }
diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/util/FS_POSIXTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/util/FS_POSIXTest.java
index 87349a2..d7a7d86 100644
--- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/util/FS_POSIXTest.java
+++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/util/FS_POSIXTest.java
@@ -59,7 +59,7 @@
 import org.junit.Test;
 
 public class FS_POSIXTest {
-	private SystemReader originalSystemReaderInstance;
+	private FileBasedConfig jgitConfig;
 
 	private FileBasedConfig systemConfig;
 
@@ -70,6 +70,7 @@
 	@Before
 	public void setUp() throws Exception {
 		tmp = Files.createTempDirectory("jgit_test_");
+
 		MockSystemReader mockSystemReader = new MockSystemReader();
 		SystemReader.setInstance(mockSystemReader);
 
@@ -78,7 +79,10 @@
 		// The MockSystemReader must be configured first since we need to use
 		// the same one here
 		FS.getFileStoreAttributes(tmp.getParent());
-		systemConfig = new FileBasedConfig(
+
+		jgitConfig = new FileBasedConfig(new File(tmp.toFile(), "jgitconfig"),
+				FS.DETECTED);
+		systemConfig = new FileBasedConfig(jgitConfig,
 				new File(tmp.toFile(), "systemgitconfig"), FS.DETECTED);
 		userConfig = new FileBasedConfig(systemConfig,
 				new File(tmp.toFile(), "usergitconfig"), FS.DETECTED);
@@ -89,16 +93,14 @@
 		userConfig.setBoolean(ConfigConstants.CONFIG_GC_SECTION, null,
 				ConfigConstants.CONFIG_KEY_AUTODETACH, false);
 		userConfig.save();
+		mockSystemReader.setJGitConfig(jgitConfig);
 		mockSystemReader.setSystemGitConfig(systemConfig);
 		mockSystemReader.setUserGitConfig(userConfig);
-
-		originalSystemReaderInstance = SystemReader.getInstance();
-		SystemReader.setInstance(mockSystemReader);
 	}
 
 	@After
 	public void tearDown() throws IOException {
-		SystemReader.setInstance(originalSystemReaderInstance);
+		SystemReader.setInstance(null);
 		FileUtils.delete(tmp.toFile(), FileUtils.RECURSIVE | FileUtils.RETRY);
 	}
 
diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/util/GitDateFormatterTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/util/GitDateFormatterTest.java
index d52166f..59ff2ad 100644
--- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/util/GitDateFormatterTest.java
+++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/util/GitDateFormatterTest.java
@@ -44,6 +44,7 @@
 package org.eclipse.jgit.util;
 
 import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
 
 import org.eclipse.jgit.junit.MockSystemReader;
 import org.eclipse.jgit.lib.PersonIdent;
@@ -120,13 +121,16 @@
 
 	@Test
 	public void LOCALE() {
-		assertEquals("Sep 20, 2011 7:09:25 PM -0400", new GitDateFormatter(
-				Format.LOCALE).formatDate(ident));
+		String date = new GitDateFormatter(Format.LOCALE).formatDate(ident);
+		assertTrue("Sep 20, 2011 7:09:25 PM -0400".equals(date)
+				|| "Sep 20, 2011, 7:09:25 PM -0400".equals(date)); // JDK-8206961
 	}
 
 	@Test
 	public void LOCALELOCAL() {
-		assertEquals("Sep 20, 2011 7:39:25 PM", new GitDateFormatter(
-				Format.LOCALELOCAL).formatDate(ident));
+		String date = new GitDateFormatter(Format.LOCALELOCAL)
+				.formatDate(ident);
+		assertTrue("Sep 20, 2011 7:39:25 PM".equals(date)
+				|| "Sep 20, 2011, 7:39:25 PM".equals(date)); // JDK-8206961
 	}
 }
diff --git a/org.eclipse.jgit.ui/META-INF/MANIFEST.MF b/org.eclipse.jgit.ui/META-INF/MANIFEST.MF
index 8103933..b143d51 100644
--- a/org.eclipse.jgit.ui/META-INF/MANIFEST.MF
+++ b/org.eclipse.jgit.ui/META-INF/MANIFEST.MF
@@ -1,17 +1,17 @@
 Bundle-Localization: plugin
 Manifest-Version: 1.0
 Bundle-ManifestVersion: 2
-Bundle-Name: %plugin_name
+Bundle-Name: %Bundle-Name
 Automatic-Module-Name: org.eclipse.jgit.ui
 Bundle-SymbolicName: org.eclipse.jgit.ui
-Bundle-Version: 5.4.4.qualifier
-Bundle-Vendor: %provider_name
+Bundle-Version: 5.5.2.qualifier
+Bundle-Vendor: %Bundle-Vendor
 Bundle-RequiredExecutionEnvironment: JavaSE-1.8
-Export-Package: org.eclipse.jgit.awtui;version="5.4.4"
-Import-Package: org.eclipse.jgit.errors;version="[5.4.4,5.5.0)",
- org.eclipse.jgit.lib;version="[5.4.4,5.5.0)",
- org.eclipse.jgit.nls;version="[5.4.4,5.5.0)",
- org.eclipse.jgit.revplot;version="[5.4.4,5.5.0)",
- org.eclipse.jgit.revwalk;version="[5.4.4,5.5.0)",
- org.eclipse.jgit.transport;version="[5.4.4,5.5.0)",
- org.eclipse.jgit.util;version="[5.4.4,5.5.0)"
+Export-Package: org.eclipse.jgit.awtui;version="5.5.2"
+Import-Package: org.eclipse.jgit.errors;version="[5.5.2,5.6.0)",
+ org.eclipse.jgit.lib;version="[5.5.2,5.6.0)",
+ org.eclipse.jgit.nls;version="[5.5.2,5.6.0)",
+ org.eclipse.jgit.revplot;version="[5.5.2,5.6.0)",
+ org.eclipse.jgit.revwalk;version="[5.5.2,5.6.0)",
+ org.eclipse.jgit.transport;version="[5.5.2,5.6.0)",
+ org.eclipse.jgit.util;version="[5.5.2,5.6.0)"
diff --git a/org.eclipse.jgit.ui/META-INF/SOURCE-MANIFEST.MF b/org.eclipse.jgit.ui/META-INF/SOURCE-MANIFEST.MF
index e36062d..5e75347 100644
--- a/org.eclipse.jgit.ui/META-INF/SOURCE-MANIFEST.MF
+++ b/org.eclipse.jgit.ui/META-INF/SOURCE-MANIFEST.MF
@@ -3,5 +3,5 @@
 Bundle-Name: org.eclipse.jgit.ui - Sources
 Bundle-SymbolicName: org.eclipse.jgit.ui.source
 Bundle-Vendor: Eclipse.org - JGit
-Bundle-Version: 5.4.4.qualifier
-Eclipse-SourceBundle: org.eclipse.jgit.ui;version="5.4.4.qualifier";roots="."
+Bundle-Version: 5.5.2.qualifier
+Eclipse-SourceBundle: org.eclipse.jgit.ui;version="5.5.2.qualifier";roots="."
diff --git a/org.eclipse.jgit.ui/plugin.properties b/org.eclipse.jgit.ui/plugin.properties
index 006c8c2..ce004ac 100644
--- a/org.eclipse.jgit.ui/plugin.properties
+++ b/org.eclipse.jgit.ui/plugin.properties
@@ -1,2 +1,2 @@
-plugin_name=JGit AWT User Interface
-provider_name=Eclipse JGit
+Bundle-Name=JGit AWT User Interface
+Bundle-Vendor=Eclipse JGit
diff --git a/org.eclipse.jgit.ui/pom.xml b/org.eclipse.jgit.ui/pom.xml
index a4200fd..fe7af76 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.4.4-SNAPSHOT</version>
+    <version>5.5.2-SNAPSHOT</version>
   </parent>
 
   <artifactId>org.eclipse.jgit.ui</artifactId>
diff --git a/org.eclipse.jgit/.settings/.api_filters b/org.eclipse.jgit/.settings/.api_filters
index 574ed4d..a2066ec 100644
--- a/org.eclipse.jgit/.settings/.api_filters
+++ b/org.eclipse.jgit/.settings/.api_filters
@@ -20,17 +20,20 @@
             </message_arguments>
         </filter>
     </resource>
-    <resource path="src/org/eclipse/jgit/errors/PackInvalidException.java" type="org.eclipse.jgit.errors.PackInvalidException">
-        <filter id="1142947843">
+    <resource path="src/org/eclipse/jgit/lib/AnyObjectId.java" type="org.eclipse.jgit.lib.AnyObjectId">
+        <filter id="1141899266">
             <message_arguments>
-                <message_argument value="4.5.7"/>
-                <message_argument value="PackInvalidException(File, Throwable)"/>
+                <message_argument value="5.4"/>
+                <message_argument value="5.5"/>
+                <message_argument value="isEqual(AnyObjectId, AnyObjectId)"/>
             </message_arguments>
         </filter>
+    </resource>
+    <resource path="src/org/eclipse/jgit/lib/Config.java" type="org.eclipse.jgit.lib.Config">
         <filter id="1142947843">
             <message_arguments>
-                <message_argument value="4.5.7"/>
-                <message_argument value="PackInvalidException(String, Throwable)"/>
+                <message_argument value="5.5.2"/>
+                <message_argument value="getBaseConfig()"/>
             </message_arguments>
         </filter>
     </resource>
@@ -90,27 +93,11 @@
             </message_arguments>
         </filter>
     </resource>
-    <resource path="src/org/eclipse/jgit/lib/Ref.java" type="org.eclipse.jgit.lib.Ref">
-        <filter id="403767336">
+    <resource path="src/org/eclipse/jgit/lib/Constants.java" type="org.eclipse.jgit.lib.Constants">
+        <filter id="1142947843">
             <message_arguments>
-                <message_argument value="org.eclipse.jgit.lib.Ref"/>
-                <message_argument value="UNDEFINED_UPDATE_INDEX"/>
-            </message_arguments>
-        </filter>
-    </resource>
-    <resource path="src/org/eclipse/jgit/lib/Repository.java" type="org.eclipse.jgit.lib.Repository">
-        <filter id="336695337">
-            <message_arguments>
-                <message_argument value="org.eclipse.jgit.lib.Repository"/>
-                <message_argument value="getIdentifier()"/>
-            </message_arguments>
-        </filter>
-    </resource>
-    <resource path="src/org/eclipse/jgit/revwalk/ObjectWalk.java" type="org.eclipse.jgit.revwalk.ObjectWalk">
-        <filter id="336658481">
-            <message_arguments>
-                <message_argument value="org.eclipse.jgit.revwalk.ObjectWalk"/>
-                <message_argument value="SIMPLE_VISITATION_POLICY"/>
+                <message_argument value="5.5.2"/>
+                <message_argument value="XDG_CONFIG_HOME"/>
             </message_arguments>
         </filter>
     </resource>
@@ -137,120 +124,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/storage/pack/PackStatistics.java" type="org.eclipse.jgit.storage.pack.PackStatistics$Accumulator">
-        <filter id="336658481">
-            <message_arguments>
-                <message_argument value="org.eclipse.jgit.storage.pack.PackStatistics.Accumulator"/>
-                <message_argument value="treesTraversed"/>
-            </message_arguments>
-        </filter>
-    </resource>
-    <resource path="src/org/eclipse/jgit/transport/HttpConfig.java" type="org.eclipse.jgit.transport.HttpConfig">
-        <filter id="336658481">
-            <message_arguments>
-                <message_argument value="org.eclipse.jgit.transport.HttpConfig"/>
-                <message_argument value="COOKIE_FILE_CACHE_LIMIT_KEY"/>
-            </message_arguments>
-        </filter>
-        <filter id="336658481">
-            <message_arguments>
-                <message_argument value="org.eclipse.jgit.transport.HttpConfig"/>
-                <message_argument value="COOKIE_FILE_KEY"/>
-            </message_arguments>
-        </filter>
-        <filter id="336658481">
-            <message_arguments>
-                <message_argument value="org.eclipse.jgit.transport.HttpConfig"/>
-                <message_argument value="SAVE_COOKIES_KEY"/>
-            </message_arguments>
-        </filter>
-    </resource>
-    <resource path="src/org/eclipse/jgit/transport/Transport.java" type="org.eclipse.jgit.transport.Transport">
-        <filter id="421654647">
-            <message_arguments>
-                <message_argument value="org.eclipse.jgit.transport.Transport"/>
-                <message_argument value="getFilterBlobLimit()"/>
-            </message_arguments>
-        </filter>
-        <filter id="421654647">
-            <message_arguments>
-                <message_argument value="org.eclipse.jgit.transport.Transport"/>
-                <message_argument value="setFilterBlobLimit(long)"/>
-            </message_arguments>
-        </filter>
-    </resource>
-    <resource path="src/org/eclipse/jgit/transport/UploadPack.java" type="org.eclipse.jgit.transport.UploadPack">
-        <filter id="421654647">
-            <message_arguments>
-                <message_argument value="org.eclipse.jgit.transport.UploadPack"/>
-                <message_argument value="getFilterBlobLimit()"/>
-            </message_arguments>
-        </filter>
-    </resource>
-    <resource path="src/org/eclipse/jgit/treewalk/FileTreeIterator.java" type="org.eclipse.jgit.treewalk.FileTreeIterator$FileEntry">
-        <filter id="1142947843">
-            <message_arguments>
-                <message_argument value="5.1.9"/>
-                <message_argument value="getLastModifiedInstant()"/>
-            </message_arguments>
-        </filter>
-    </resource>
     <resource path="src/org/eclipse/jgit/treewalk/WorkingTreeIterator.java" type="org.eclipse.jgit.treewalk.WorkingTreeIterator">
         <filter id="1142947843">
             <message_arguments>
@@ -274,6 +147,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"/>
@@ -321,34 +200,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/HttpSupport.java" type="org.eclipse.jgit.util.HttpSupport">
-        <filter id="336658481">
-            <message_arguments>
-                <message_argument value="org.eclipse.jgit.util.HttpSupport"/>
-                <message_argument value="HDR_COOKIE"/>
-            </message_arguments>
-        </filter>
-        <filter id="336658481">
-            <message_arguments>
-                <message_argument value="org.eclipse.jgit.util.HttpSupport"/>
-                <message_argument value="HDR_SET_COOKIE"/>
-            </message_arguments>
-        </filter>
-        <filter id="336658481">
-            <message_arguments>
-                <message_argument value="org.eclipse.jgit.util.HttpSupport"/>
-                <message_argument value="HDR_SET_COOKIE2"/>
-            </message_arguments>
-        </filter>
-    </resource>
     <resource path="src/org/eclipse/jgit/util/Monitoring.java" type="org.eclipse.jgit.util.Monitoring">
         <filter id="1109393411">
             <message_arguments>
@@ -357,6 +208,15 @@
             </message_arguments>
         </filter>
     </resource>
+    <resource path="src/org/eclipse/jgit/util/References.java" type="org.eclipse.jgit.util.References">
+        <filter id="1108344834">
+            <message_arguments>
+                <message_argument value="5.4"/>
+                <message_argument value="5.5"/>
+                <message_argument value="org.eclipse.jgit.util.References"/>
+            </message_arguments>
+        </filter>
+    </resource>
     <resource path="src/org/eclipse/jgit/util/SimpleLruCache.java" type="org.eclipse.jgit.util.SimpleLruCache">
         <filter id="1109393411">
             <message_arguments>
@@ -374,6 +234,12 @@
         </filter>
     </resource>
     <resource path="src/org/eclipse/jgit/util/SystemReader.java" type="org.eclipse.jgit.util.SystemReader">
+        <filter id="336695337">
+            <message_arguments>
+                <message_argument value="org.eclipse.jgit.util.SystemReader"/>
+                <message_argument value="openJGitConfig(Config, FS)"/>
+            </message_arguments>
+        </filter>
         <filter id="1142947843">
             <message_arguments>
                 <message_argument value="5.1.9"/>
@@ -386,5 +252,17 @@
                 <message_argument value="getUserConfig()"/>
             </message_arguments>
         </filter>
+        <filter id="1142947843">
+            <message_arguments>
+                <message_argument value="5.5.2"/>
+                <message_argument value="getJGitConfig()"/>
+            </message_arguments>
+        </filter>
+        <filter id="1142947843">
+            <message_arguments>
+                <message_argument value="5.5.2"/>
+                <message_argument value="openJGitConfig(Config, FS)"/>
+            </message_arguments>
+        </filter>
     </resource>
 </component>
diff --git a/org.eclipse.jgit/BUILD b/org.eclipse.jgit/BUILD
index c7d9fde..dcfeb17 100644
--- a/org.eclipse.jgit/BUILD
+++ b/org.eclipse.jgit/BUILD
@@ -16,10 +16,6 @@
 java_library(
     name = "jgit",
     srcs = SRCS,
-    javacopts = select({
-        "//:jdk9": ["--add-modules=java.xml.bind"],
-        "//conditions:default": [],
-    }),
     resource_strip_prefix = "org.eclipse.jgit/resources",
     resources = RESOURCES,
     deps = [
diff --git a/org.eclipse.jgit/META-INF/MANIFEST.MF b/org.eclipse.jgit/META-INF/MANIFEST.MF
index 5bfa344..69cdf30 100644
--- a/org.eclipse.jgit/META-INF/MANIFEST.MF
+++ b/org.eclipse.jgit/META-INF/MANIFEST.MF
@@ -1,14 +1,14 @@
 Manifest-Version: 1.0
 Bundle-ManifestVersion: 2
-Bundle-Name: %plugin_name
+Bundle-Name: %Bundle-Name
 Automatic-Module-Name: org.eclipse.jgit
 Bundle-SymbolicName: org.eclipse.jgit
-Bundle-Version: 5.4.4.qualifier
+Bundle-Version: 5.5.2.qualifier
 Bundle-Localization: plugin
-Bundle-Vendor: %provider_name
+Bundle-Vendor: %Bundle-Vendor
 Bundle-ActivationPolicy: lazy
-Export-Package: org.eclipse.jgit.annotations;version="5.4.4",
- org.eclipse.jgit.api;version="5.4.4";
+Export-Package: org.eclipse.jgit.annotations;version="5.5.2",
+ org.eclipse.jgit.api;version="5.5.2";
   uses:="org.eclipse.jgit.revwalk,
    org.eclipse.jgit.treewalk.filter,
    org.eclipse.jgit.diff,
@@ -22,53 +22,53 @@
    org.eclipse.jgit.submodule,
    org.eclipse.jgit.transport,
    org.eclipse.jgit.merge",
- org.eclipse.jgit.api.errors;version="5.4.4";uses:="org.eclipse.jgit.lib,org.eclipse.jgit.errors",
- org.eclipse.jgit.attributes;version="5.4.4",
- org.eclipse.jgit.blame;version="5.4.4";
+ org.eclipse.jgit.api.errors;version="5.5.2";uses:="org.eclipse.jgit.lib,org.eclipse.jgit.errors",
+ org.eclipse.jgit.attributes;version="5.5.2",
+ org.eclipse.jgit.blame;version="5.5.2";
   uses:="org.eclipse.jgit.lib,
    org.eclipse.jgit.revwalk,
    org.eclipse.jgit.treewalk.filter,
    org.eclipse.jgit.diff",
- org.eclipse.jgit.diff;version="5.4.4";
+ org.eclipse.jgit.diff;version="5.5.2";
   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.4.4";
+ org.eclipse.jgit.dircache;version="5.5.2";
   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.4.4";
+ org.eclipse.jgit.errors;version="5.5.2";
   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.4.4";uses:="org.eclipse.jgit.lib",
- org.eclipse.jgit.fnmatch;version="5.4.4",
- org.eclipse.jgit.gitrepo;version="5.4.4";
+ org.eclipse.jgit.events;version="5.5.2";uses:="org.eclipse.jgit.lib",
+ org.eclipse.jgit.fnmatch;version="5.5.2",
+ org.eclipse.jgit.gitrepo;version="5.5.2";
   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.4.4";x-internal:=true,
- org.eclipse.jgit.hooks;version="5.4.4";uses:="org.eclipse.jgit.lib",
- org.eclipse.jgit.ignore;version="5.4.4",
- org.eclipse.jgit.ignore.internal;version="5.4.4";x-friends:="org.eclipse.jgit.test",
- org.eclipse.jgit.internal;version="5.4.4";x-friends:="org.eclipse.jgit.test,org.eclipse.jgit.http.test",
- org.eclipse.jgit.internal.fsck;version="5.4.4";x-friends:="org.eclipse.jgit.test",
- org.eclipse.jgit.internal.ketch;version="5.4.4";x-friends:="org.eclipse.jgit.junit,org.eclipse.jgit.test,org.eclipse.jgit.pgm",
- org.eclipse.jgit.internal.revwalk;version="5.4.4";x-internal:=true,
- org.eclipse.jgit.internal.storage.dfs;version="5.4.4";
+ org.eclipse.jgit.gitrepo.internal;version="5.5.2";x-internal:=true,
+ org.eclipse.jgit.hooks;version="5.5.2";uses:="org.eclipse.jgit.lib",
+ org.eclipse.jgit.ignore;version="5.5.2",
+ org.eclipse.jgit.ignore.internal;version="5.5.2";x-friends:="org.eclipse.jgit.test",
+ org.eclipse.jgit.internal;version="5.5.2";x-friends:="org.eclipse.jgit.test,org.eclipse.jgit.http.test",
+ org.eclipse.jgit.internal.fsck;version="5.5.2";x-friends:="org.eclipse.jgit.test",
+ org.eclipse.jgit.internal.ketch;version="5.5.2";x-friends:="org.eclipse.jgit.junit,org.eclipse.jgit.test,org.eclipse.jgit.pgm",
+ org.eclipse.jgit.internal.revwalk;version="5.5.2";x-internal:=true,
+ org.eclipse.jgit.internal.storage.dfs;version="5.5.2";
   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.4.4";
+ org.eclipse.jgit.internal.storage.file;version="5.5.2";
   x-friends:="org.eclipse.jgit.test,
    org.eclipse.jgit.junit,
    org.eclipse.jgit.junit.http,
@@ -77,19 +77,19 @@
    org.eclipse.jgit.pgm,
    org.eclipse.jgit.pgm.test,
    org.eclipse.jgit.ssh.apache",
- org.eclipse.jgit.internal.storage.io;version="5.4.4";x-friends:="org.eclipse.jgit.junit,org.eclipse.jgit.test,org.eclipse.jgit.pgm",
- org.eclipse.jgit.internal.storage.pack;version="5.4.4";x-friends:="org.eclipse.jgit.junit,org.eclipse.jgit.test,org.eclipse.jgit.pgm",
- org.eclipse.jgit.internal.storage.reftable;version="5.4.4";
+ org.eclipse.jgit.internal.storage.io;version="5.5.2";x-friends:="org.eclipse.jgit.junit,org.eclipse.jgit.test,org.eclipse.jgit.pgm",
+ org.eclipse.jgit.internal.storage.pack;version="5.5.2";x-friends:="org.eclipse.jgit.junit,org.eclipse.jgit.test,org.eclipse.jgit.pgm",
+ org.eclipse.jgit.internal.storage.reftable;version="5.5.2";
   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.4.4";x-friends:="org.eclipse.jgit.junit,org.eclipse.jgit.test,org.eclipse.jgit.pgm",
- org.eclipse.jgit.internal.submodule;version="5.4.4";x-internal:=true,
- org.eclipse.jgit.internal.transport.http;version="5.4.4";x-friends:="org.eclipse.jgit.test",
- org.eclipse.jgit.internal.transport.parser;version="5.4.4";x-friends:="org.eclipse.jgit.http.server,org.eclipse.jgit.test",
- org.eclipse.jgit.internal.transport.ssh;version="5.4.4";x-friends:="org.eclipse.jgit.ssh.apache",
- org.eclipse.jgit.lib;version="5.4.4";
+ org.eclipse.jgit.internal.storage.reftree;version="5.5.2";x-friends:="org.eclipse.jgit.junit,org.eclipse.jgit.test,org.eclipse.jgit.pgm",
+ org.eclipse.jgit.internal.submodule;version="5.5.2";x-internal:=true,
+ org.eclipse.jgit.internal.transport.http;version="5.5.2";x-friends:="org.eclipse.jgit.test",
+ org.eclipse.jgit.internal.transport.parser;version="5.5.2";x-friends:="org.eclipse.jgit.http.server,org.eclipse.jgit.test",
+ org.eclipse.jgit.internal.transport.ssh;version="5.5.2";x-friends:="org.eclipse.jgit.ssh.apache",
+ org.eclipse.jgit.lib;version="5.5.2";
   uses:="org.eclipse.jgit.revwalk,
    org.eclipse.jgit.treewalk.filter,
    org.eclipse.jgit.util,
@@ -99,33 +99,33 @@
    org.eclipse.jgit.treewalk,
    org.eclipse.jgit.transport,
    org.eclipse.jgit.submodule",
- org.eclipse.jgit.lib.internal;version="5.4.4";x-internal:=true,
- org.eclipse.jgit.merge;version="5.4.4";
+ org.eclipse.jgit.lib.internal;version="5.5.2";x-internal:=true,
+ org.eclipse.jgit.merge;version="5.5.2";
   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.4.4",
- org.eclipse.jgit.notes;version="5.4.4";
+ org.eclipse.jgit.nls;version="5.5.2",
+ org.eclipse.jgit.notes;version="5.5.2";
   uses:="org.eclipse.jgit.lib,
    org.eclipse.jgit.treewalk,
    org.eclipse.jgit.revwalk,
    org.eclipse.jgit.merge",
- org.eclipse.jgit.patch;version="5.4.4";uses:="org.eclipse.jgit.lib,org.eclipse.jgit.diff",
- org.eclipse.jgit.revplot;version="5.4.4";uses:="org.eclipse.jgit.lib,org.eclipse.jgit.revwalk",
- org.eclipse.jgit.revwalk;version="5.4.4";
+ org.eclipse.jgit.patch;version="5.5.2";uses:="org.eclipse.jgit.lib,org.eclipse.jgit.diff",
+ org.eclipse.jgit.revplot;version="5.5.2";uses:="org.eclipse.jgit.lib,org.eclipse.jgit.revwalk",
+ org.eclipse.jgit.revwalk;version="5.5.2";
   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.4.4";uses:="org.eclipse.jgit.revwalk,org.eclipse.jgit.lib,org.eclipse.jgit.util",
- org.eclipse.jgit.storage.file;version="5.4.4";uses:="org.eclipse.jgit.lib,org.eclipse.jgit.util",
- org.eclipse.jgit.storage.pack;version="5.4.4";uses:="org.eclipse.jgit.lib",
- org.eclipse.jgit.submodule;version="5.4.4";uses:="org.eclipse.jgit.lib,org.eclipse.jgit.treewalk.filter,org.eclipse.jgit.treewalk",
- org.eclipse.jgit.transport;version="5.4.4";
+ org.eclipse.jgit.revwalk.filter;version="5.5.2";uses:="org.eclipse.jgit.revwalk,org.eclipse.jgit.lib,org.eclipse.jgit.util",
+ org.eclipse.jgit.storage.file;version="5.5.2";uses:="org.eclipse.jgit.lib,org.eclipse.jgit.util",
+ org.eclipse.jgit.storage.pack;version="5.5.2";uses:="org.eclipse.jgit.lib",
+ org.eclipse.jgit.submodule;version="5.5.2";uses:="org.eclipse.jgit.lib,org.eclipse.jgit.treewalk.filter,org.eclipse.jgit.treewalk",
+ org.eclipse.jgit.transport;version="5.5.2";
   uses:="org.eclipse.jgit.transport.resolver,
    org.eclipse.jgit.revwalk,
    org.eclipse.jgit.internal.storage.pack,
@@ -138,24 +138,24 @@
    org.eclipse.jgit.transport.http,
    org.eclipse.jgit.errors,
    org.eclipse.jgit.storage.pack",
- org.eclipse.jgit.transport.http;version="5.4.4";uses:="javax.net.ssl",
- org.eclipse.jgit.transport.resolver;version="5.4.4";uses:="org.eclipse.jgit.lib,org.eclipse.jgit.transport",
- org.eclipse.jgit.treewalk;version="5.4.4";
+ org.eclipse.jgit.transport.http;version="5.5.2";uses:="javax.net.ssl",
+ org.eclipse.jgit.transport.resolver;version="5.5.2";uses:="org.eclipse.jgit.lib,org.eclipse.jgit.transport",
+ org.eclipse.jgit.treewalk;version="5.5.2";
   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.4.4";uses:="org.eclipse.jgit.treewalk",
- org.eclipse.jgit.util;version="5.4.4";
+ org.eclipse.jgit.treewalk.filter;version="5.5.2";uses:="org.eclipse.jgit.treewalk",
+ org.eclipse.jgit.util;version="5.5.2";
   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.4.4",
- org.eclipse.jgit.util.sha1;version="5.4.4",
- org.eclipse.jgit.util.time;version="5.4.4"
+ org.eclipse.jgit.util.io;version="5.5.2",
+ org.eclipse.jgit.util.sha1;version="5.5.2",
+ org.eclipse.jgit.util.time;version="5.5.2"
 Bundle-RequiredExecutionEnvironment: JavaSE-1.8
 Import-Package: com.googlecode.javaewah;version="[1.1.6,2.0.0)",
  com.jcraft.jsch;version="[0.1.37,0.2.0)",
diff --git a/org.eclipse.jgit/META-INF/SOURCE-MANIFEST.MF b/org.eclipse.jgit/META-INF/SOURCE-MANIFEST.MF
index c3d5224..29db604 100644
--- a/org.eclipse.jgit/META-INF/SOURCE-MANIFEST.MF
+++ b/org.eclipse.jgit/META-INF/SOURCE-MANIFEST.MF
@@ -3,5 +3,5 @@
 Bundle-Name: org.eclipse.jgit - Sources
 Bundle-SymbolicName: org.eclipse.jgit.source
 Bundle-Vendor: Eclipse.org - JGit
-Bundle-Version: 5.4.4.qualifier
-Eclipse-SourceBundle: org.eclipse.jgit;version="5.4.4.qualifier";roots="."
+Bundle-Version: 5.5.2.qualifier
+Eclipse-SourceBundle: org.eclipse.jgit;version="5.5.2.qualifier";roots="."
diff --git a/org.eclipse.jgit/plugin.properties b/org.eclipse.jgit/plugin.properties
index 3ce6709..3e132b0 100644
--- a/org.eclipse.jgit/plugin.properties
+++ b/org.eclipse.jgit/plugin.properties
@@ -1,2 +1,2 @@
-plugin_name=JGit Core
-provider_name=Eclipse JGit
+Bundle-Name=JGit Core
+Bundle-Vendor=Eclipse JGit
diff --git a/org.eclipse.jgit/pom.xml b/org.eclipse.jgit/pom.xml
index 7576f37..656d4ff 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.4.4-SNAPSHOT</version>
+    <version>5.5.2-SNAPSHOT</version>
   </parent>
 
   <artifactId>org.eclipse.jgit</artifactId>
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 8890c9f..14ab51c 100644
--- a/org.eclipse.jgit/resources/org/eclipse/jgit/internal/JGitText.properties
+++ b/org.eclipse.jgit/resources/org/eclipse/jgit/internal/JGitText.properties
@@ -72,6 +72,7 @@
 cannotEnterObjectsPath=Cannot enter {0}/objects: {1}
 cannotEnterPathFromParent=Cannot enter {0} from {1}: {2}
 cannotExecute=cannot execute: {0}
+cannotFindMergeBaseUsingFirstParent=Cannot find merge bases using a first-parent walk.
 cannotGet=Cannot get {0}
 cannotGetObjectsPath=Cannot get {0}/{1}: {2}
 cannotListObjectsPath=Cannot ls {0}/{1}: {2}
@@ -125,6 +126,7 @@
 commitMessageNotSpecified=commit message not specified
 commitOnRepoWithoutHEADCurrentlyNotSupported=Commit on repo without HEAD currently not supported
 commitAmendOnInitialNotPossible=Amending is not possible on initial commit.
+commitsHaveAlreadyBeenMarkedAsStart=Commits have already been marked as walk starts.
 compressingObjects=Compressing objects
 configSubsectionContainsNewline=config subsection name contains newline
 configSubsectionContainsNullByte=config subsection name contains byte 0x00
@@ -199,8 +201,10 @@
 corruptPack=Pack file {0} is corrupt, removing it from pack list
 createBranchFailedUnknownReason=Create branch failed for unknown reason
 createBranchUnexpectedResult=Create branch returned unexpected result {0}
+createJGitConfigFailed=Creating JGit config directory {} failed
 createNewFileFailed=Could not create new file {0}
 createRequiresZeroOldId=Create requires old ID to be zero
+createXDGConfigHomeFailed=Creating XDG_CONFIG_HOME directory {} failed
 credentialPassword=Password
 credentialPassphrase=Passphrase
 credentialUsername=Username
@@ -530,6 +534,8 @@
 readerIsRequired=Reader is required
 readingObjectsFromLocalRepositoryFailed=reading objects from local repository failed: {0}
 readLastModifiedFailed=Reading lastModified of {0} failed
+readPipeIsNotAllowed=FS.readPipe() isn't allowed for command ''{0}''. Working directory: ''{1}''.
+readPipeIsNotAllowedRequiredPermission=FS.readPipe() isn't allowed for command ''{0}''. Working directory: ''{1}''. Required permission: {2}.
 readTimedOut=Read timed out after {0} ms
 receivePackObjectTooLarge1=Object too large, rejecting the pack. Max object size limit is {0} bytes.
 receivePackObjectTooLarge2=Object too large ({0} bytes), rejecting the pack. Max object size limit is {1} bytes.
@@ -545,6 +551,7 @@
 refAlreadyExists1=Ref {0} already exists
 reflogEntryNotFound=Entry {0} not found  in reflog for ''{1}''
 refNotResolved=Ref {0} cannot be resolved
+refTableRecordsMustIncrease=records must be increasing: last {0}, this {1}
 refUpdateReturnCodeWas=RefUpdate return code was: {0}
 remoteConfigHasNoURIAssociated=Remote config "{0}" has no URIs associated
 remoteDoesNotHaveSpec=Remote does not have {0} available for fetch.
@@ -603,6 +610,7 @@
 signingNotSupportedOnTag=Signing isn't supported on tag operations yet.
 similarityScoreMustBeWithinBounds=Similarity score must be between 0 and 100.
 skipMustBeNonNegative=skip must be >= 0
+skipNotAccessiblePath=The path ''{0}'' isn't accessible. Skip it.
 smartHTTPPushDisabled=smart HTTP push disabled
 sourceDestinationMustMatch=Source/Destination must match.
 sourceIsNotAWildcard=Source is not a wildcard.
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/api/ApplyCommand.java b/org.eclipse.jgit/src/org/eclipse/jgit/api/ApplyCommand.java
index c6f3c67..38e5444 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/api/ApplyCommand.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/api/ApplyCommand.java
@@ -279,9 +279,13 @@
 	}
 
 	private boolean isNoNewlineAtEndOfFile(FileHeader fh) {
-		HunkHeader lastHunk = fh.getHunks().get(fh.getHunks().size() - 1);
+		List<? extends HunkHeader> hunks = fh.getHunks();
+		if (hunks == null || hunks.isEmpty()) {
+			return false;
+		}
+		HunkHeader lastHunk = hunks.get(hunks.size() - 1);
 		RawText lhrt = new RawText(lastHunk.getBuffer());
-		return lhrt.getString(lhrt.size() - 1).equals(
-				"\\ No newline at end of file"); //$NON-NLS-1$
+		return lhrt.getString(lhrt.size() - 1)
+				.equals("\\ No newline at end of file"); //$NON-NLS-1$
 	}
 }
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/api/MergeCommand.java b/org.eclipse.jgit/src/org/eclipse/jgit/api/MergeCommand.java
index b8fa74d..f9a9baf 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/api/MergeCommand.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/api/MergeCommand.java
@@ -459,8 +459,8 @@
 	}
 
 	/**
-	 * Use values from the configuation if they have not been explicitly defined
-	 * via the setters
+	 * Use values from the configuration if they have not been explicitly
+	 * defined via the setters
 	 */
 	private void fallBackToConfiguration() {
 		MergeConfig config = MergeConfig.getConfigForCurrentBranch(repo);
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 22090f5..6bc2946 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/dircache/DirCacheCheckout.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/dircache/DirCacheCheckout.java
@@ -1301,14 +1301,6 @@
 						JGitText.get().cannotDeleteFile, c));
 			removeEmptyParents(conflict);
 		}
-		for (String r : removed) {
-			File file = new File(repo.getWorkTree(), r);
-			if (!file.delete())
-				throw new CheckoutConflictException(
-						MessageFormat.format(JGitText.get().cannotDeleteFile,
-								file.getAbsolutePath()));
-			removeEmptyParents(file);
-		}
 	}
 
 	/**
@@ -1473,6 +1465,9 @@
 		ObjectLoader ol = or.open(entry.getObjectId());
 		File f = new File(repo.getWorkTree(), entry.getPathString());
 		File parentDir = f.getParentFile();
+		if (parentDir.isFile()) {
+			FileUtils.delete(parentDir);
+		}
 		FileUtils.mkdirs(parentDir, true);
 		FS fs = repo.getFS();
 		WorkingTreeOptions opt = repo.getConfig().get(WorkingTreeOptions.KEY);
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 01c8b37..cd7d1e5 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/internal/JGitText.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/internal/JGitText.java
@@ -133,6 +133,7 @@
 	/***/ public String cannotEnterObjectsPath;
 	/***/ public String cannotEnterPathFromParent;
 	/***/ public String cannotExecute;
+	/***/ public String cannotFindMergeBaseUsingFirstParent;
 	/***/ public String cannotGet;
 	/***/ public String cannotGetObjectsPath;
 	/***/ public String cannotListObjectsPath;
@@ -186,6 +187,7 @@
 	/***/ public String commitMessageNotSpecified;
 	/***/ public String commitOnRepoWithoutHEADCurrentlyNotSupported;
 	/***/ public String commitAmendOnInitialNotPossible;
+	/***/ public String commitsHaveAlreadyBeenMarkedAsStart;
 	/***/ public String compressingObjects;
 	/***/ public String configSubsectionContainsNewline;
 	/***/ public String configSubsectionContainsNullByte;
@@ -260,8 +262,10 @@
 	/***/ public String countingObjects;
 	/***/ public String createBranchFailedUnknownReason;
 	/***/ public String createBranchUnexpectedResult;
+	/***/ public String createJGitConfigFailed;
 	/***/ public String createNewFileFailed;
 	/***/ public String createRequiresZeroOldId;
+	/***/ public String createXDGConfigHomeFailed;
 	/***/ public String credentialPassword;
 	/***/ public String credentialPassphrase;
 	/***/ public String credentialUsername;
@@ -591,6 +595,8 @@
 	/***/ public String readerIsRequired;
 	/***/ public String readingObjectsFromLocalRepositoryFailed;
 	/***/ public String readLastModifiedFailed;
+	/***/ public String readPipeIsNotAllowed;
+	/***/ public String readPipeIsNotAllowedRequiredPermission;
 	/***/ public String readTimedOut;
 	/***/ public String receivePackObjectTooLarge1;
 	/***/ public String receivePackObjectTooLarge2;
@@ -606,6 +612,7 @@
 	/***/ public String refAlreadyExists1;
 	/***/ public String reflogEntryNotFound;
 	/***/ public String refNotResolved;
+	/***/ public String refTableRecordsMustIncrease;
 	/***/ public String refUpdateReturnCodeWas;
 	/***/ public String remoteConfigHasNoURIAssociated;
 	/***/ public String remoteDoesNotHaveSpec;
@@ -664,6 +671,7 @@
 	/***/ public String signingNotSupportedOnTag;
 	/***/ public String similarityScoreMustBeWithinBounds;
 	/***/ public String skipMustBeNonNegative;
+	/***/ public String skipNotAccessiblePath;
 	/***/ public String smartHTTPPushDisabled;
 	/***/ public String sourceDestinationMustMatch;
 	/***/ public String sourceIsNotAWildcard;
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/ObjectDirectory.java b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/ObjectDirectory.java
index 258ccee..968ade6 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/ObjectDirectory.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/ObjectDirectory.java
@@ -171,7 +171,7 @@
 		infoDirectory = new File(objects, "info"); //$NON-NLS-1$
 		packDirectory = new File(objects, "pack"); //$NON-NLS-1$
 		preservedDirectory = new File(packDirectory, "preserved"); //$NON-NLS-1$
-		alternatesFile = new File(infoDirectory, "alternates"); //$NON-NLS-1$
+		alternatesFile = new File(objects, Constants.INFO_ALTERNATES);
 		packList = new AtomicReference<>(NO_PACKS);
 		unpackedObjectCache = new UnpackedObjectCache();
 		this.fs = fs;
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/PackIndex.java b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/PackIndex.java
index 72699b0..43bd9d4 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/PackIndex.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/PackIndex.java
@@ -313,6 +313,14 @@
 			int matchLimit) throws IOException;
 
 	/**
+	 * @return the checksum of the pack; caller must not modify it
+	 * @since 5.5
+	 */
+	public byte[] getChecksum() {
+		return packChecksum;
+	}
+
+	/**
 	 * Represent mutable entry of pack index consisting of object id and offset
 	 * in pack (both mutable).
 	 *
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/pack/CachedPackUriProvider.java b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/pack/CachedPackUriProvider.java
new file mode 100644
index 0000000..5cbc2ba
--- /dev/null
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/pack/CachedPackUriProvider.java
@@ -0,0 +1,103 @@
+/*
+ * 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.pack;
+
+import java.io.IOException;
+import java.util.Collection;
+import org.eclipse.jgit.annotations.Nullable;
+
+/**
+ * Provider of URIs corresponding to cached packs. For use with the
+ * "packfile-uris" feature.
+ * @since 5.5
+ */
+public interface CachedPackUriProvider {
+
+	/**
+	 * @param pack the cached pack for which to check if a corresponding URI
+	 *	exists
+	 * @param protocolsSupported the protocols that the client has declared
+	 *	support for; if a URI is returned, it must be of one of these
+	 *	protocols
+	 * @throws IOException implementations may throw this
+	 * @return if a URI corresponds to the cached pack, an object
+	 *	containing the URI and some other information; null otherwise
+	 * @since 5.5
+	 */
+	@Nullable
+	PackInfo getInfo(CachedPack pack, Collection<String> protocolsSupported)
+		throws IOException;
+
+	/**
+	 * Information about a packfile.
+	 * @since 5.5
+	 */
+	public static class PackInfo {
+		private final String hash;
+		private final String uri;
+
+		/**
+		 * Constructs an object containing information about a packfile.
+		 * @param hash the hash of the packfile as a hexadecimal string
+		 * @param uri the URI corresponding to the packfile
+		 */
+		public PackInfo(String hash, String uri) {
+			this.hash = hash;
+			this.uri = uri;
+		}
+
+		/**
+		 * @return the hash of the packfile as a hexadecimal string
+		 */
+		public String getHash() {
+			return hash;
+		}
+
+		/**
+		 * @return the URI corresponding to the packfile
+		 */
+		public String getUri() {
+			return uri;
+		}
+	}
+}
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 6506789..43067d3 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
@@ -122,6 +122,7 @@
 import org.eclipse.jgit.storage.pack.PackStatistics;
 import org.eclipse.jgit.transport.FilterSpec;
 import org.eclipse.jgit.transport.ObjectCountCallback;
+import org.eclipse.jgit.transport.PacketLineOut;
 import org.eclipse.jgit.transport.WriteAbortedException;
 import org.eclipse.jgit.util.BlockList;
 import org.eclipse.jgit.util.TemporaryBuffer;
@@ -307,6 +308,8 @@
 
 	private FilterSpec filterSpec = FilterSpec.NO_FILTER;
 
+	private PackfileUriConfig packfileUriConfig;
+
 	/**
 	 * Create writer for specified repository.
 	 * <p>
@@ -651,6 +654,14 @@
 	}
 
 	/**
+	 * @param config configuration related to packfile URIs
+	 * @since 5.5
+	 */
+	public void setPackfileUriConfig(PackfileUriConfig config) {
+		packfileUriConfig = config;
+	}
+
+	/**
 	 * Returns objects number in a pack file that was created by this writer.
 	 *
 	 * @return number of objects in pack.
@@ -673,6 +684,26 @@
 		return stats.totalObjects;
 	}
 
+	private long getUnoffloadedObjectCount() throws IOException {
+		long objCnt = 0;
+
+		objCnt += objectsLists[OBJ_COMMIT].size();
+		objCnt += objectsLists[OBJ_TREE].size();
+		objCnt += objectsLists[OBJ_BLOB].size();
+		objCnt += objectsLists[OBJ_TAG].size();
+
+		for (CachedPack pack : cachedPacks) {
+			CachedPackUriProvider.PackInfo packInfo =
+				packfileUriConfig.cachedPackUriProvider.getInfo(
+					pack, packfileUriConfig.protocolsSupported);
+			if (packInfo == null) {
+				objCnt += pack.getObjectCount();
+			}
+		}
+
+		return objCnt;
+	}
+
 	/**
 	 * Returns the object ids in the pack file that was created by this writer.
 	 * <p>
@@ -1177,13 +1208,38 @@
 				: new CheckedOutputStream(packStream, crc32),
 			this);
 
-		long objCnt = getObjectCount();
+		long objCnt = packfileUriConfig == null ? getObjectCount() :
+			getUnoffloadedObjectCount();
 		stats.totalObjects = objCnt;
 		if (callback != null)
 			callback.setObjectCount(objCnt);
 		beginPhase(PackingPhase.WRITING, writeMonitor, objCnt);
 		long writeStart = System.currentTimeMillis();
 		try {
+			List<CachedPack> unwrittenCachedPacks;
+
+			if (packfileUriConfig != null) {
+				unwrittenCachedPacks = new ArrayList<>();
+				CachedPackUriProvider p = packfileUriConfig.cachedPackUriProvider;
+				PacketLineOut o = packfileUriConfig.pckOut;
+
+				o.writeString("packfile-uris\n"); //$NON-NLS-1$
+				for (CachedPack pack : cachedPacks) {
+					CachedPackUriProvider.PackInfo packInfo = p.getInfo(
+							pack, packfileUriConfig.protocolsSupported);
+					if (packInfo != null) {
+						o.writeString(packInfo.getHash() + ' ' +
+								packInfo.getUri() + '\n');
+					} else {
+						unwrittenCachedPacks.add(pack);
+					}
+				}
+				packfileUriConfig.pckOut.writeDelim();
+				packfileUriConfig.pckOut.writeString("packfile\n"); //$NON-NLS-1$
+			} else {
+				unwrittenCachedPacks = cachedPacks;
+			}
+
 			out.writeFileHeader(PACK_VERSION_GENERATED, objCnt);
 			out.flush();
 
@@ -1197,7 +1253,7 @@
 			}
 
 			stats.reusedPacks = Collections.unmodifiableList(cachedPacks);
-			for (CachedPack pack : cachedPacks) {
+			for (CachedPack pack : unwrittenCachedPacks) {
 				long deltaCnt = pack.getDeltaCount();
 				stats.reusedObjects += pack.getObjectCount();
 				stats.reusedDeltas += deltaCnt;
@@ -2426,4 +2482,37 @@
 			return "PackWriter.State[" + phase + ", memory=" + bytesUsed + "]";
 		}
 	}
+
+	/**
+	 * Configuration related to the packfile URI feature.
+	 *
+	 * @since 5.5
+	 */
+	public static class PackfileUriConfig {
+		@NonNull
+		private final PacketLineOut pckOut;
+
+		@NonNull
+		private final Collection<String> protocolsSupported;
+
+		@NonNull
+		private final CachedPackUriProvider cachedPackUriProvider;
+
+		/**
+		 * @param pckOut where to write "packfile-uri" lines to (should
+		 *     output to the same stream as the one passed to
+		 *     PackWriter#writePack)
+		 * @param protocolsSupported list of protocols supported (e.g. "https")
+		 * @param cachedPackUriProvider provider of URIs corresponding
+		 *     to cached packs
+		 * @since 5.5
+		 */
+		public PackfileUriConfig(@NonNull PacketLineOut pckOut,
+				@NonNull Collection<String> protocolsSupported,
+				@NonNull CachedPackUriProvider cachedPackUriProvider) {
+			this.pckOut = pckOut;
+			this.protocolsSupported = protocolsSupported;
+			this.cachedPackUriProvider = cachedPackUriProvider;
+		}
+	}
 }
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/reftable/BlockReader.java b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/reftable/BlockReader.java
index 44529bf..b66751b 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/reftable/BlockReader.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/reftable/BlockReader.java
@@ -84,7 +84,11 @@
 import org.eclipse.jgit.util.NB;
 import org.eclipse.jgit.util.RawParseUtils;
 
-/** Reads a single block for {@link ReftableReader}. */
+/**
+ * Reads a single block for {@link ReftableReader}. Instances are tied to a
+ * specific block in the file so are not reused for other blocks. Instances hold
+ * an offset into the block.
+ */
 class BlockReader {
 	private byte blockType;
 	private long endPosition;
@@ -141,6 +145,8 @@
 		return RawParseUtils.decode(UTF_8, nameBuf, 0, len);
 	}
 
+	// Matches the key against a name or a prefix. For reflogs, only the
+	// refname is matched, and the updateIndex suffix is ignored.
 	boolean match(byte[] match, boolean matchIsPrefix) {
 		int len = nameLen;
 		if (blockType == LOG_BLOCK_TYPE) {
@@ -551,7 +557,9 @@
 	}
 
 	private short readInt16() {
-		return (short) NB.decodeUInt16(buf, ptr += 2);
+		short result =(short) NB.decodeUInt16(buf, ptr);
+		ptr += 2;
+		return result;
 	}
 
 	private int readVarint32() {
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/reftable/ReftableReader.java b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/reftable/ReftableReader.java
index bf3a9ae..4f0ff2d 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/reftable/ReftableReader.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/reftable/ReftableReader.java
@@ -255,6 +255,32 @@
 			block.seekKey(key);
 			return block;
 		}
+		if (blockType == LOG_BLOCK_TYPE) {
+			// No index. Log blocks are irregularly sized, so we can't do binary
+			// search between blocks. Scan over blocks instead.
+			BlockReader block = readBlock(startPos, endPos);
+
+			for (;;) {
+				if (block == null || block.type() != LOG_BLOCK_TYPE) {
+					return null;
+				}
+
+				int result = block.seekKey(key);
+				if (result <= 0) {
+					// == 0 : we found the key.
+					// < 0 : the key is before this block. Either the ref name is there
+					// but only at a newer updateIndex, or it is absent. We leave it to
+					// logcursor to distinguish between both cases.
+					return block;
+				}
+
+				long pos = block.endPosition();
+				if (pos >= endPos) {
+					return null;
+				}
+				block = readBlock(pos, endPos);
+			}
+		}
 		return binarySearch(blockType, key, startPos, endPos);
 	}
 
@@ -529,12 +555,20 @@
 	private class LogCursorImpl extends LogCursor {
 		private final long scanEnd;
 		private final byte[] match;
-
+	    
 		private String refName;
 		private long updateIndex;
 		private ReflogEntry entry;
 		BlockReader block;
 
+		/**
+		 * Scans logs from this table until scanEnd position.
+		 *
+		 * @param scanEnd
+		 *            end of the log data in the reftable.
+		 * @param match
+		 *            if non-null, limits the scan to precisely that refname.
+		 */
 		LogCursorImpl(long scanEnd, byte[] match) {
 			this.scanEnd = scanEnd;
 			this.match = match;
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/reftable/ReftableWriter.java b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/reftable/ReftableWriter.java
index f8b9ffd..6459c27 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/reftable/ReftableWriter.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/reftable/ReftableWriter.java
@@ -44,6 +44,7 @@
 package org.eclipse.jgit.internal.storage.reftable;
 
 import static java.lang.Math.log;
+import static java.nio.charset.StandardCharsets.UTF_8;
 import static org.eclipse.jgit.internal.storage.reftable.BlockWriter.padBetweenBlocks;
 import static org.eclipse.jgit.internal.storage.reftable.ReftableConstants.FILE_FOOTER_LEN;
 import static org.eclipse.jgit.internal.storage.reftable.ReftableConstants.FILE_HEADER_LEN;
@@ -59,6 +60,7 @@
 
 import java.io.IOException;
 import java.io.OutputStream;
+import java.text.MessageFormat;
 import java.util.ArrayList;
 import java.util.Collection;
 import java.util.Collections;
@@ -69,6 +71,7 @@
 import java.util.zip.CRC32;
 
 import org.eclipse.jgit.annotations.Nullable;
+import org.eclipse.jgit.internal.JGitText;
 import org.eclipse.jgit.internal.storage.reftable.BlockWriter.DeleteLogEntry;
 import org.eclipse.jgit.internal.storage.reftable.BlockWriter.Entry;
 import org.eclipse.jgit.internal.storage.reftable.BlockWriter.IndexEntry;
@@ -108,6 +111,8 @@
 	private ReftableOutputStream out;
 	private ObjectIdSubclassMap<RefList> obj2ref;
 
+	private BlockWriter.Entry lastRef;
+	private BlockWriter.Entry lastLog;
 	private BlockWriter cur;
 	private Section refs;
 	private Section objs;
@@ -120,6 +125,8 @@
 	 */
 	public ReftableWriter() {
 		this(new ReftableConfig());
+		lastRef = null;
+		lastLog = null;
 	}
 
 	/**
@@ -269,10 +276,22 @@
 			throw new IllegalArgumentException();
 		}
 		long d = updateIndex - minUpdateIndex;
-		long blockPos = refs.write(new RefEntry(ref, d));
+		RefEntry entry = new RefEntry(ref, d);
+		if (lastRef != null && Entry.compare(lastRef, entry) >= 0) {
+			throwIllegalEntry(lastRef, entry);
+		}
+		lastRef = entry;
+
+		long blockPos = refs.write(entry);
 		indexRef(ref, blockPos);
 	}
 
+	private void throwIllegalEntry(Entry last, Entry now) {
+		throw new IllegalArgumentException(MessageFormat.format(
+				JGitText.get().refTableRecordsMustIncrease,
+				new String(last.key, UTF_8), new String(now.key, UTF_8)));
+	}
+
 	private void indexRef(Ref ref, long blockPos) {
 		if (indexObjects && !ref.isSymbolic()) {
 			indexId(ref.getObjectId(), blockPos);
@@ -322,7 +341,12 @@
 					throws IOException {
 		String msg = message != null ? message : ""; //$NON-NLS-1$
 		beginLog();
-		logs.write(new LogEntry(ref, updateIndex, who, oldId, newId, msg));
+		LogEntry entry = new LogEntry(ref, updateIndex, who, oldId, newId, msg);
+		if (lastLog != null && Entry.compare(lastLog, entry) >= 0) {
+			throwIllegalEntry(lastLog, entry);
+		}
+		lastLog = entry;
+		logs.write(entry);
 	}
 
 	/**
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/lib/BaseRepositoryBuilder.java b/org.eclipse.jgit/src/org/eclipse/jgit/lib/BaseRepositoryBuilder.java
index d1cf1cd..96e5066 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/lib/BaseRepositoryBuilder.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/lib/BaseRepositoryBuilder.java
@@ -681,7 +681,7 @@
 	 */
 	protected void setupInternals() throws IOException {
 		if (getObjectDirectory() == null && getGitDir() != null)
-			setObjectDirectory(safeFS().resolve(getGitDir(), "objects")); //$NON-NLS-1$
+			setObjectDirectory(safeFS().resolve(getGitDir(), Constants.OBJECTS));
 	}
 
 	/**
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 16db717..d26b7fd 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/lib/Config.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/lib/Config.java
@@ -129,9 +129,21 @@
 	}
 
 	/**
+	 * Retrieves this config's base config.
+	 *
+	 * @return the base configuration of this config.
+	 *
+	 * @since 5.5.2
+	 */
+	public Config getBaseConfig() {
+		return baseConfig;
+	}
+
+	/**
 	 * Check if a given string is the "missing" value.
 	 *
-	 * @param value string to be checked.
+	 * @param value
+	 *            string to be checked.
 	 * @return true if the given string is the "missing" value.
 	 * @since 5.4
 	 */
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 8f4468e..9274fc6 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/lib/Constants.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/lib/Constants.java
@@ -275,9 +275,27 @@
 	/** Logs folder name */
 	public static final String LOGS = "logs";
 
+	/**
+	 * Objects folder name
+	 * @since 5.5
+	 */
+	public static final String OBJECTS = "objects";
+
 	/** Info refs folder */
 	public static final String INFO_REFS = "info/refs";
 
+	/**
+	 * Info alternates file (goes under OBJECTS)
+	 * @since 5.5
+	 */
+	public static final String INFO_ALTERNATES = "info/alternates";
+
+	/**
+	 * HTTP alternates file (goes under OBJECTS)
+	 * @since 5.5
+	 */
+	public static final String INFO_HTTP_ALTERNATES = "info/http-alternates";
+
 	/** Packed refs file */
 	public static final String PACKED_REFS = "packed-refs";
 
@@ -325,6 +343,15 @@
 	public static final String GIT_CONFIG_NOSYSTEM_KEY = "GIT_CONFIG_NOSYSTEM";
 
 	/**
+	 * The key of the XDG_CONFIG_HOME directory defined in the XDG base
+	 * directory specification, see
+	 * {@link "https://wiki.archlinux.org/index.php/XDG_Base_Directory"}
+	 *
+	 * @since 5.5.2
+	 */
+	public static final String XDG_CONFIG_HOME = "XDG_CONFIG_HOME";
+
+	/**
 	 * The environment variable that limits how close to the root of the file
 	 * systems JGit will traverse when looking for a repository root.
 	 */
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 27befba..fa113bf 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/lib/RepositoryCache.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/lib/RepositoryCache.java
@@ -474,7 +474,7 @@
 		 *         Git directory.
 		 */
 		public static boolean isGitRepository(File dir, FS fs) {
-			return fs.resolve(dir, "objects").exists() //$NON-NLS-1$
+			return fs.resolve(dir, Constants.OBJECTS).exists()
 					&& fs.resolve(dir, "refs").exists() //$NON-NLS-1$
 					&& isValidHead(new File(dir, Constants.HEAD));
 		}
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 0d44317..11db7c5 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
@@ -50,6 +50,7 @@
 import java.io.IOException;
 import java.io.InputStream;
 import java.net.URISyntaxException;
+import java.nio.file.DirectoryStream;
 import java.nio.file.Files;
 import java.nio.file.InvalidPathException;
 import java.nio.file.Path;
@@ -72,6 +73,8 @@
 import org.bouncycastle.gpg.keybox.jcajce.JcaKeyBoxBuilder;
 import org.bouncycastle.openpgp.PGPException;
 import org.bouncycastle.openpgp.PGPPublicKey;
+import org.bouncycastle.openpgp.PGPPublicKeyRing;
+import org.bouncycastle.openpgp.PGPPublicKeyRingCollection;
 import org.bouncycastle.openpgp.PGPSecretKey;
 import org.bouncycastle.openpgp.PGPSecretKeyRing;
 import org.bouncycastle.openpgp.PGPSecretKeyRingCollection;
@@ -97,6 +100,13 @@
  */
 class BouncyCastleGpgKeyLocator {
 
+	/** Thrown if a keybox file exists but doesn't contain an OpenPGP key. */
+	private static class NoOpenPgpKeyException extends Exception {
+
+		private static final long serialVersionUID = 1L;
+
+	}
+
 	private static final Logger log = LoggerFactory
 			.getLogger(BouncyCastleGpgKeyLocator.class);
 
@@ -108,6 +118,9 @@
 	private static final Path USER_SECRET_KEY_DIR = GPG_DIRECTORY
 			.resolve("private-keys-v1.d"); //$NON-NLS-1$
 
+	private static final Path USER_PGP_PUBRING_FILE = GPG_DIRECTORY
+			.resolve("pubring.gpg"); //$NON-NLS-1$
+
 	private static final Path USER_PGP_LEGACY_SECRING_FILE = GPG_DIRECTORY
 			.resolve("secring.gpg"); //$NON-NLS-1$
 
@@ -215,13 +228,17 @@
 	 *             in case of problems reading the file
 	 * @throws NoSuchAlgorithmException
 	 * @throws NoSuchProviderException
+	 * @throws NoOpenPgpKeyException
+	 *             if the file does not contain any OpenPGP key
 	 */
 	private PGPPublicKey findPublicKeyInKeyBox(Path keyboxFile)
 			throws IOException, NoSuchAlgorithmException,
-			NoSuchProviderException {
+			NoSuchProviderException, NoOpenPgpKeyException {
 		KeyBox keyBox = readKeyBoxFile(keyboxFile);
+		boolean hasOpenPgpKey = false;
 		for (KeyBlob keyBlob : keyBox.getKeyBlobs()) {
 			if (keyBlob.getType() == BlobType.OPEN_PGP_BLOB) {
+				hasOpenPgpKey = true;
 				PGPPublicKey key = findPublicKeyByKeyId(keyBlob);
 				if (key != null) {
 					return key;
@@ -232,12 +249,20 @@
 				}
 			}
 		}
+		if (!hasOpenPgpKey) {
+			throw new NoOpenPgpKeyException();
+		}
 		return null;
 	}
 
 	/**
-	 * Use pubring.kbx when available, if not fallback to secring.gpg or secret
-	 * key path provided to parse and return secret key
+	 * If there is a private key directory containing keys, use pubring.kbx or
+	 * pubring.gpg to find the public key; then try to find the secret key in
+	 * the directory.
+	 * <p>
+	 * If there is no private key directory (or it doesn't contain any keys),
+	 * try to find the key in secring.gpg directly.
+	 * </p>
 	 *
 	 * @return the secret key
 	 * @throws IOException
@@ -245,42 +270,112 @@
 	 * @throws NoSuchAlgorithmException
 	 * @throws NoSuchProviderException
 	 * @throws PGPException
-	 *             in case of issues finding a key
+	 *             in case of issues finding a key, including no key found
 	 * @throws CanceledException
 	 * @throws URISyntaxException
 	 * @throws UnsupportedCredentialItem
 	 */
+	@NonNull
 	public BouncyCastleGpgKey findSecretKey() throws IOException,
 			NoSuchAlgorithmException, NoSuchProviderException, PGPException,
 			CanceledException, UnsupportedCredentialItem, URISyntaxException {
-		if (exists(USER_KEYBOX_PATH)) {
-			PGPPublicKey publicKey = //
-					findPublicKeyInKeyBox(USER_KEYBOX_PATH);
-
-			if (publicKey != null) {
-				return findSecretKeyForKeyBoxPublicKey(publicKey,
-						USER_KEYBOX_PATH);
-			}
-
-			throw new PGPException(MessageFormat
-					.format(JGitText.get().gpgNoPublicKeyFound, signingKey));
-		} else if (exists(USER_PGP_LEGACY_SECRING_FILE)) {
-			PGPSecretKey secretKey = findSecretKeyInLegacySecring(signingKey,
-					USER_PGP_LEGACY_SECRING_FILE);
-
-			if (secretKey != null) {
-				if (!secretKey.isSigningKey()) {
+		BouncyCastleGpgKey key;
+		PGPPublicKey publicKey = null;
+		if (hasKeyFiles(USER_SECRET_KEY_DIR)) {
+			// Use pubring.kbx or pubring.gpg to find the public key, then try
+			// the key files in the directory. If the public key was found in
+			// pubring.gpg also try secring.gpg to find the secret key.
+			if (exists(USER_KEYBOX_PATH)) {
+				try {
+					publicKey = findPublicKeyInKeyBox(USER_KEYBOX_PATH);
+					if (publicKey != null) {
+						key = findSecretKeyForKeyBoxPublicKey(publicKey,
+								USER_KEYBOX_PATH);
+						if (key != null) {
+							return key;
+						}
+						throw new PGPException(MessageFormat.format(
+								JGitText.get().gpgNoSecretKeyForPublicKey,
+								Long.toHexString(publicKey.getKeyID())));
+					}
 					throw new PGPException(MessageFormat.format(
-							JGitText.get().gpgNotASigningKey, signingKey));
+							JGitText.get().gpgNoPublicKeyFound, signingKey));
+				} catch (NoOpenPgpKeyException e) {
+					// There are no OpenPGP keys in the keybox at all: try the
+					// pubring.gpg, if it exists.
+					if (log.isDebugEnabled()) {
+						log.debug("{} does not contain any OpenPGP keys", //$NON-NLS-1$
+								USER_KEYBOX_PATH);
+					}
 				}
-				return new BouncyCastleGpgKey(secretKey, USER_PGP_LEGACY_SECRING_FILE);
 			}
-
+			if (exists(USER_PGP_PUBRING_FILE)) {
+				publicKey = findPublicKeyInPubring(USER_PGP_PUBRING_FILE);
+				if (publicKey != null) {
+					// GPG < 2.1 may have both; the agent using the directory
+					// and gpg using secring.gpg. GPG >= 2.1 delegates all
+					// secret key handling to the agent and doesn't use
+					// secring.gpg at all, even if it exists. Which means for us
+					// we have to try both since we don't know which GPG version
+					// the user has.
+					key = findSecretKeyForKeyBoxPublicKey(publicKey,
+							USER_PGP_PUBRING_FILE);
+					if (key != null) {
+						return key;
+					}
+				}
+			}
+			if (publicKey == null) {
+				throw new PGPException(MessageFormat.format(
+						JGitText.get().gpgNoPublicKeyFound, signingKey));
+			}
+			// We found a public key, but didn't find the secret key in the
+			// private key directory. Go try the secring.gpg.
+		}
+		boolean hasSecring = false;
+		if (exists(USER_PGP_LEGACY_SECRING_FILE)) {
+			hasSecring = true;
+			key = loadKeyFromSecring(USER_PGP_LEGACY_SECRING_FILE);
+			if (key != null) {
+				return key;
+			}
+		}
+		if (publicKey != null) {
+			throw new PGPException(MessageFormat.format(
+					JGitText.get().gpgNoSecretKeyForPublicKey,
+					Long.toHexString(publicKey.getKeyID())));
+		} else if (hasSecring) {
+			// publicKey == null: user has _only_ pubring.gpg/secring.gpg.
 			throw new PGPException(MessageFormat.format(
 					JGitText.get().gpgNoKeyInLegacySecring, signingKey));
+		} else {
+			throw new PGPException(JGitText.get().gpgNoKeyring);
 		}
+	}
 
-		throw new PGPException(JGitText.get().gpgNoKeyring);
+	private boolean hasKeyFiles(Path dir) {
+		try (DirectoryStream<Path> contents = Files.newDirectoryStream(dir,
+				"*.key")) { //$NON-NLS-1$
+			return contents.iterator().hasNext();
+		} catch (IOException e) {
+			// Not a directory, or something else
+			return false;
+		}
+	}
+
+	private BouncyCastleGpgKey loadKeyFromSecring(Path secring)
+			throws IOException, PGPException {
+		PGPSecretKey secretKey = findSecretKeyInLegacySecring(signingKey,
+				secring);
+
+		if (secretKey != null) {
+			if (!secretKey.isSigningKey()) {
+				throw new PGPException(MessageFormat
+						.format(JGitText.get().gpgNotASigningKey, signingKey));
+			}
+			return new BouncyCastleGpgKey(secretKey, secring);
+		}
+		return null;
 	}
 
 	private BouncyCastleGpgKey findSecretKeyForKeyBoxPublicKey(
@@ -315,9 +410,7 @@
 			}
 
 			passphrasePrompt.clear();
-			throw new PGPException(MessageFormat.format(
-					JGitText.get().gpgNoSecretKeyForPublicKey,
-					Long.toHexString(publicKey.getKeyID())));
+			return null;
 		} catch (RuntimeException e) {
 			passphrasePrompt.clear();
 			throw e;
@@ -379,13 +472,62 @@
 		return null;
 	}
 
+	/**
+	 * Return the first public key matching the key id ({@link #signingKey}.
+	 *
+	 * @param pubringFile
+	 *
+	 * @return the PGP public key, or {@code null} if none found
+	 * @throws IOException
+	 *             on I/O related errors
+	 * @throws PGPException
+	 *             on BouncyCastle errors
+	 */
+	private PGPPublicKey findPublicKeyInPubring(Path pubringFile)
+			throws IOException, PGPException {
+		try (InputStream in = newInputStream(pubringFile)) {
+			PGPPublicKeyRingCollection pgpPub = new PGPPublicKeyRingCollection(
+					new BufferedInputStream(in),
+					new JcaKeyFingerprintCalculator());
+
+			String keyId = signingKey.toLowerCase(Locale.ROOT);
+			Iterator<PGPPublicKeyRing> keyrings = pgpPub.getKeyRings();
+			while (keyrings.hasNext()) {
+				PGPPublicKeyRing keyRing = keyrings.next();
+				Iterator<PGPPublicKey> keys = keyRing.getPublicKeys();
+				while (keys.hasNext()) {
+					PGPPublicKey key = keys.next();
+					// try key id
+					String fingerprint = Hex.toHexString(key.getFingerprint())
+							.toLowerCase(Locale.ROOT);
+					if (fingerprint.endsWith(keyId)) {
+						return key;
+					}
+					// try user id
+					Iterator<String> userIDs = key.getUserIDs();
+					while (userIDs.hasNext()) {
+						String userId = userIDs.next();
+						if (containsSigningKey(userId)) {
+							return key;
+						}
+					}
+				}
+			}
+		}
+		return null;
+	}
+
 	private PGPPublicKey getFirstPublicKey(KeyBlob keyBlob) throws IOException {
 		return ((PublicKeyRingBlob) keyBlob).getPGPPublicKeyRing()
 				.getPublicKey();
 	}
 
 	private KeyBox readKeyBoxFile(Path keyboxFile) throws IOException,
-			NoSuchAlgorithmException, NoSuchProviderException {
+			NoSuchAlgorithmException, NoSuchProviderException,
+			NoOpenPgpKeyException {
+		if (keyboxFile.toFile().length() == 0) {
+			throw new NoOpenPgpKeyException();
+		}
 		KeyBox keyBox;
 		try (InputStream in = new BufferedInputStream(
 				newInputStream(keyboxFile))) {
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/AbstractRevQueue.java b/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/AbstractRevQueue.java
index 247a3bd..7b5e6fa 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/AbstractRevQueue.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/AbstractRevQueue.java
@@ -49,6 +49,10 @@
 	/** Current output flags set for this generator instance. */
 	int outputType;
 
+	AbstractRevQueue(boolean firstParent) {
+		super(firstParent);
+	}
+
 	/**
 	 * Add a commit to the queue.
 	 * <p>
@@ -96,10 +100,15 @@
 	 */
 	public final void addParents(RevCommit c, RevFlag queueControl) {
 		final RevCommit[] pList = c.parents;
-		if (pList == null)
+		if (pList == null) {
 			return;
-		for (RevCommit p : pList)
-			add(p, queueControl);
+		}
+		for (int i = 0; i < pList.length; i++) {
+			if (firstParent && i > 0) {
+				break;
+			}
+			add(pList[i], queueControl);
+		}
 	}
 
 	/**
@@ -138,6 +147,10 @@
 	}
 
 	private static class AlwaysEmptyQueue extends AbstractRevQueue {
+		private AlwaysEmptyQueue() {
+			super(false);
+		}
+
 		@Override
 		public void add(RevCommit c) {
 			throw new UnsupportedOperationException();
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/BlockRevQueue.java b/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/BlockRevQueue.java
index 79307b5..64e9e03 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/BlockRevQueue.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/BlockRevQueue.java
@@ -53,13 +53,19 @@
 
 	/**
 	 * Create an empty revision queue.
+	 *
+	 * @param firstParent
+	 *            whether only first-parent links should be followed when
+	 *            walking
 	 */
-	protected BlockRevQueue() {
+	protected BlockRevQueue(boolean firstParent) {
+		super(firstParent);
 		free = new BlockFreeList();
 	}
 
 	BlockRevQueue(Generator s) throws MissingObjectException,
 			IncorrectObjectTypeException, IOException {
+		super(s.firstParent);
 		free = new BlockFreeList();
 		outputType = s.outputType();
 		s.shareFreeList(this);
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/BoundaryGenerator.java b/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/BoundaryGenerator.java
index 0fd6621..98c99e8 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/BoundaryGenerator.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/BoundaryGenerator.java
@@ -55,6 +55,7 @@
 	Generator g;
 
 	BoundaryGenerator(RevWalk w, Generator s) {
+		super(s.firstParent);
 		g = new InitialGenerator(w, s);
 	}
 
@@ -86,8 +87,9 @@
 		private final Generator source;
 
 		InitialGenerator(RevWalk w, Generator s) {
+			super(s.firstParent);
 			walk = w;
-			held = new FIFORevQueue();
+			held = new FIFORevQueue(firstParent);
 			source = s;
 			source.shareFreeList(held);
 		}
@@ -107,13 +109,19 @@
 				IncorrectObjectTypeException, IOException {
 			RevCommit c = source.next();
 			if (c != null) {
-				for (RevCommit p : c.parents)
-					if ((p.flags & UNINTERESTING) != 0)
+				for (int i = 0; i < c.parents.length; i++) {
+					if (firstParent && i > 0) {
+						break;
+					}
+					RevCommit p = c.parents[i];
+					if ((p.flags & UNINTERESTING) != 0) {
 						held.add(p);
+					}
+				}
 				return c;
 			}
 
-			final FIFORevQueue boundary = new FIFORevQueue();
+			final FIFORevQueue boundary = new FIFORevQueue(firstParent);
 			boundary.shareFreeList(held);
 			for (;;) {
 				c = held.next();
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/DateRevQueue.java b/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/DateRevQueue.java
index b86e876..d77b055 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/DateRevQueue.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/DateRevQueue.java
@@ -69,15 +69,18 @@
 
 	private int last = -1;
 
-	/**
-	 * Create an empty date queue.
-	 */
+	/** Create an empty date queue. */
 	public DateRevQueue() {
-		super();
+		super(false);
+	}
+
+	DateRevQueue(boolean firstParent) {
+		super(firstParent);
 	}
 
 	DateRevQueue(Generator s) throws MissingObjectException,
 			IncorrectObjectTypeException, IOException {
+		super(s.firstParent);
 		for (;;) {
 			final RevCommit c = s.next();
 			if (c == null)
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/DelayRevQueue.java b/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/DelayRevQueue.java
index c397a01..9134e08 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/DelayRevQueue.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/DelayRevQueue.java
@@ -70,6 +70,7 @@
 	private int size;
 
 	DelayRevQueue(Generator g) {
+		super(g.firstParent);
 		pending = g;
 		delay = new FIFORevQueue();
 	}
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 5199a29..0b04d5d 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/DepthGenerator.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/DepthGenerator.java
@@ -95,7 +95,8 @@
 	 */
 	DepthGenerator(DepthWalk w, Generator s) throws MissingObjectException,
 			IncorrectObjectTypeException, IOException {
-		pending = new FIFORevQueue();
+		super(s.firstParent);
+		pending = new FIFORevQueue(firstParent);
 		walk = (RevWalk)w;
 
 		this.depth = w.getDepth();
@@ -196,7 +197,11 @@
 
 			int newDepth = c.depth + 1;
 
-			for (RevCommit p : c.parents) {
+			for (int i = 0; i < c.parents.length; i++) {
+				if (firstParent && i > 0) {
+					break;
+				}
+				RevCommit p = c.parents[i];
 				DepthWalk.Commit dp = (DepthWalk.Commit) p;
 
 				// If no depth has been assigned to this commit, assign
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/EndGenerator.java b/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/EndGenerator.java
index 627e1c7..03916c8 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/EndGenerator.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/EndGenerator.java
@@ -47,7 +47,7 @@
 	static final EndGenerator INSTANCE = new EndGenerator();
 
 	private EndGenerator() {
-		// We have nothing to initialize.
+		super(false);
 	}
 
 	@Override
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/FIFORevQueue.java b/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/FIFORevQueue.java
index cdb084c..40ee55c 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/FIFORevQueue.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/FIFORevQueue.java
@@ -56,11 +56,13 @@
 
 	private Block tail;
 
-	/**
-	 * Create an empty FIFO queue.
-	 */
+	/** Create an empty FIFO queue. */
 	public FIFORevQueue() {
-		super();
+		super(false);
+	}
+
+	FIFORevQueue(boolean firstParent) {
+		super(firstParent);
 	}
 
 	FIFORevQueue(Generator s) throws MissingObjectException,
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/FixUninterestingGenerator.java b/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/FixUninterestingGenerator.java
index 4e6d7e6..289842a 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/FixUninterestingGenerator.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/FixUninterestingGenerator.java
@@ -62,6 +62,7 @@
 	private final Generator pending;
 
 	FixUninterestingGenerator(Generator g) {
+		super(g.firstParent);
 		pending = g;
 	}
 
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/Generator.java b/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/Generator.java
index b2c92ea..59c5cce 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/Generator.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/Generator.java
@@ -75,6 +75,12 @@
 	/** Output may have {@link RevWalk#UNINTERESTING} marked on it. */
 	static final int HAS_UNINTERESTING = 1 << 4;
 
+	protected final boolean firstParent;
+
+	protected Generator(boolean firstParent) {
+		this.firstParent = firstParent;
+	}
+
 	/**
 	 * Connect the supplied queue to this generator's own free list (if any).
 	 *
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/LIFORevQueue.java b/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/LIFORevQueue.java
index 846b8d9..5628d35 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/LIFORevQueue.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/LIFORevQueue.java
@@ -59,7 +59,7 @@
 	 * Create an empty LIFO queue.
 	 */
 	public LIFORevQueue() {
-		super();
+		super(false);
 	}
 
 	LIFORevQueue(Generator s) throws MissingObjectException,
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/MergeBaseGenerator.java b/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/MergeBaseGenerator.java
index 2fe9531..4ea57cb 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/MergeBaseGenerator.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/MergeBaseGenerator.java
@@ -85,8 +85,9 @@
 	private CarryStack stack;
 
 	MergeBaseGenerator(RevWalk w) {
+		super(w.isFirstParent());
 		walker = w;
-		pending = new DateRevQueue();
+		pending = new DateRevQueue(firstParent);
 	}
 
 	void init(AbstractRevQueue p) throws IOException {
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/PendingGenerator.java b/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/PendingGenerator.java
index e607b7d..3990dd6 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/PendingGenerator.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/PendingGenerator.java
@@ -109,6 +109,7 @@
 
 	PendingGenerator(final RevWalk w, final DateRevQueue p,
 			final RevFilter f, final int out) {
+		super(w.isFirstParent());
 		walker = w;
 		pending = p;
 		filter = f;
@@ -140,7 +141,13 @@
 					produce = filter.include(walker, c);
 				}
 
-				for (RevCommit p : c.parents) {
+				for (int i = 0; i < c.parents.length; i++) {
+					RevCommit p = c.parents[i];
+					// If the commit is uninteresting, don't try to prune
+					// parents because we want the maximal uninteresting set.
+					if (firstParent && i > 0 && (c.flags & UNINTERESTING) == 0) {
+						continue;
+					}
 					if ((p.flags & SEEN) != 0)
 						continue;
 					if ((p.flags & PARSED) == 0)
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 f50d189..4aa8325 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/RevWalk.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/RevWalk.java
@@ -201,6 +201,8 @@
 
 	private boolean rewriteParents = true;
 
+	private boolean firstParent;
+
 	boolean shallowCommitsInitialized;
 
 	/**
@@ -233,7 +235,7 @@
 		idBuffer = new MutableObjectId();
 		objects = new ObjectIdOwnerMap<>();
 		roots = new ArrayList<>();
-		queue = new DateRevQueue();
+		queue = new DateRevQueue(false);
 		pending = new StartGenerator(this);
 		sorting = EnumSet.of(RevSort.NONE);
 		filter = RevFilter.ALL;
@@ -664,6 +666,35 @@
 	}
 
 	/**
+	 * @return whether only first-parent links should be followed when walking.
+	 *
+	 * @since 5.5
+	 */
+	public boolean isFirstParent() {
+		return firstParent;
+	}
+
+	/**
+	 * Set whether or not only first parent links should be followed.
+	 * <p>
+	 * If set, second- and higher-parent links are not traversed at all.
+	 * <p>
+	 * This must be called prior to {@link #markStart(RevCommit)}.
+	 *
+	 * @param enable
+	 *            true to walk only first-parent links.
+	 *
+	 * @since 5.5
+	 */
+	public void setFirstParent(boolean enable) {
+		assertNotStarted();
+		assertNoCommitsMarkedStart();
+		firstParent = enable;
+		queue = new DateRevQueue(firstParent);
+		pending = new StartGenerator(this);
+	}
+
+	/**
 	 * Locate a reference to a blob without loading it.
 	 * <p>
 	 * The blob may or may not exist in the repository. It is impossible to tell
@@ -1295,7 +1326,8 @@
 	 * <p>
 	 * Unlike {@link #dispose()} previously acquired RevObject (and RevCommit)
 	 * instances are not invalidated. RevFlag instances are not invalidated, but
-	 * are removed from all RevObjects.
+	 * are removed from all RevObjects. The value of {@code firstParent} is
+	 * retained.
 	 *
 	 * @param retainFlags
 	 *            application flags that should <b>not</b> be cleared from
@@ -1331,7 +1363,7 @@
 		}
 
 		roots.clear();
-		queue = new DateRevQueue();
+		queue = new DateRevQueue(firstParent);
 		pending = new StartGenerator(this);
 	}
 
@@ -1349,9 +1381,10 @@
 		delayFreeFlags = 0;
 		retainOnReset = 0;
 		carryFlags = UNINTERESTING;
+		firstParent = false;
 		objects.clear();
 		roots.clear();
-		queue = new DateRevQueue();
+		queue = new DateRevQueue(firstParent);
 		pending = new StartGenerator(this);
 		shallowCommitsInitialized = false;
 	}
@@ -1423,6 +1456,21 @@
 		throw new IllegalStateException(JGitText.get().outputHasAlreadyBeenStarted);
 	}
 
+	/**
+	 * Throws an exception if any commits have been marked as start.
+	 * <p>
+	 * If {@link #markStart(RevCommit)} has already been called,
+	 * {@link #reset()} can be called to satisfy this condition.
+	 *
+	 * @since 5.5
+	 */
+	protected void assertNoCommitsMarkedStart() {
+		if (roots.isEmpty())
+			return;
+		throw new IllegalStateException(
+				JGitText.get().commitsHaveAlreadyBeenMarkedAsStart);
+	}
+
 	private boolean isNotStarted() {
 		return pending instanceof StartGenerator;
 	}
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/RewriteGenerator.java b/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/RewriteGenerator.java
index 1c868ff..2e26641 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/RewriteGenerator.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/RewriteGenerator.java
@@ -77,6 +77,7 @@
 	private final Generator source;
 
 	RewriteGenerator(Generator s) {
+		super(s.firstParent);
 		source = s;
 	}
 
@@ -102,6 +103,10 @@
 		final int nParents = pList.length;
 		for (int i = 0; i < nParents; i++) {
 			final RevCommit oldp = pList[i];
+			if (firstParent && i > 0) {
+				c.parents = new RevCommit[] { rewrite(oldp) };
+				return c;
+			}
 			final RevCommit newp = rewrite(oldp);
 			if (oldp != newp) {
 				pList[i] = newp;
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/StartGenerator.java b/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/StartGenerator.java
index eb129a2..b309d6f 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/StartGenerator.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/StartGenerator.java
@@ -67,6 +67,7 @@
 	private final RevWalk walker;
 
 	StartGenerator(RevWalk w) {
+		super(w.isFirstParent());
 		walker = w;
 	}
 
@@ -89,9 +90,14 @@
 			// Computing for merge bases is a special case and does not
 			// use the bulk of the generator pipeline.
 			//
-			if (tf != TreeFilter.ALL)
+			if (tf != TreeFilter.ALL) {
 				throw new IllegalStateException(MessageFormat.format(
 						JGitText.get().cannotCombineTreeFilterWithRevFilter, tf, rf));
+			}
+			if (w.isFirstParent()) {
+				throw new IllegalStateException(
+						JGitText.get().cannotFindMergeBaseUsingFirstParent);
+			}
 
 			final MergeBaseGenerator mbg = new MergeBaseGenerator(w);
 			walker.pending = mbg;
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/TopoSortGenerator.java b/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/TopoSortGenerator.java
index 6450343..a2c9ef6 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/TopoSortGenerator.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/TopoSortGenerator.java
@@ -71,15 +71,21 @@
 	 */
 	TopoSortGenerator(Generator s) throws MissingObjectException,
 			IncorrectObjectTypeException, IOException {
-		pending = new FIFORevQueue();
+		super(s.firstParent);
+		pending = new FIFORevQueue(firstParent);
 		outputType = s.outputType() | SORT_TOPO;
 		s.shareFreeList(pending);
 		for (;;) {
 			final RevCommit c = s.next();
-			if (c == null)
+			if (c == null) {
 				break;
-			for (RevCommit p : c.parents)
-				p.inDegree++;
+			}
+			for (int i = 0; i < c.parents.length; i++) {
+				if (firstParent && i > 0) {
+					break;
+				}
+				c.parents[i].inDegree++;
+			}
 			pending.add(c);
 		}
 	}
@@ -113,7 +119,11 @@
 			// All of our children have already produced,
 			// so it is OK for us to produce now as well.
 			//
-			for (RevCommit p : c.parents) {
+			for (int i = 0; i < c.parents.length; i++) {
+				if (firstParent && i > 0) {
+					break;
+				}
+				RevCommit p = c.parents[i];
 				if (--p.inDegree == 0 && (p.flags & TOPO_DELAY) != 0) {
 					// This parent tried to come before us, but we are
 					// his last child. unpop the parent so it goes right
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/TreeRevFilter.java b/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/TreeRevFilter.java
index 1130153..f7c3218 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/TreeRevFilter.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/TreeRevFilter.java
@@ -116,8 +116,7 @@
 	 * @param rewriteFlag
 	 *            flag to color commits to be removed from the simplified DAT.
 	 */
-	TreeRevFilter(final RevWalk walker, final TreeFilter t,
-			final int rewriteFlag) {
+	TreeRevFilter(RevWalk walker, TreeFilter t, int rewriteFlag) {
 		pathFilter = new TreeWalk(walker.reader);
 		pathFilter.setFilter(t);
 		pathFilter.setRecursive(t.shouldBeRecursive());
@@ -137,14 +136,15 @@
 			IncorrectObjectTypeException, IOException {
 		// Reset the tree filter to scan this commit and parents.
 		//
-		final RevCommit[] pList = c.parents;
-		final int nParents = pList.length;
-		final TreeWalk tw = pathFilter;
-		final ObjectId[] trees = new ObjectId[nParents + 1];
+		RevCommit[] pList = c.parents;
+		int nParents = pList.length;
+		TreeWalk tw = pathFilter;
+		ObjectId[] trees = new ObjectId[nParents + 1];
 		for (int i = 0; i < nParents; i++) {
-			final RevCommit p = c.parents[i];
-			if ((p.flags & PARSED) == 0)
+			RevCommit p = c.parents[i];
+			if ((p.flags & PARSED) == 0) {
 				p.parseHeaders(walker);
+			}
 			trees[i] = p.getTree();
 		}
 		trees[nParents] = c.getTree();
@@ -156,10 +156,11 @@
 			int chgs = 0, adds = 0;
 			while (tw.next()) {
 				chgs++;
-				if (tw.getRawMode(0) == 0 && tw.getRawMode(1) != 0)
+				if (tw.getRawMode(0) == 0 && tw.getRawMode(1) != 0) {
 					adds++;
-				else
+				} else {
 					break; // no point in looking at this further.
+				}
 			}
 
 			if (chgs == 0) {
@@ -185,8 +186,9 @@
 			// We have no parents to compare against. Consider us to be
 			// REWRITE only if we have no paths matching our filter.
 			//
-			if (tw.next())
+			if (tw.next()) {
 				return true;
+			}
 			c.flags |= rewriteFlag;
 			return false;
 		}
@@ -196,18 +198,19 @@
 		// it does not contribute changes to us. Such a parent may be an
 		// uninteresting side branch.
 		//
-		final int[] chgs = new int[nParents];
-		final int[] adds = new int[nParents];
+		int[] chgs = new int[nParents];
+		int[] adds = new int[nParents];
 		while (tw.next()) {
-			final int myMode = tw.getRawMode(nParents);
+			int myMode = tw.getRawMode(nParents);
 			for (int i = 0; i < nParents; i++) {
-				final int pMode = tw.getRawMode(i);
-				if (myMode == pMode && tw.idEqual(i, nParents))
+				int pMode = tw.getRawMode(i);
+				if (myMode == pMode && tw.idEqual(i, nParents)) {
 					continue;
-
+				}
 				chgs[i]++;
-				if (pMode == 0 && myMode != 0)
+				if (pMode == 0 && myMode != 0) {
 					adds[i]++;
+				}
 			}
 		}
 
@@ -220,7 +223,7 @@
 				// parent commit.
 				//
 
-				final RevCommit p = pList[i];
+				RevCommit p = pList[i];
 				if ((p.flags & UNINTERESTING) != 0) {
 					// This parent was marked as not interesting by the
 					// application. We should look for another parent
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 57d6bc2..27cc205 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/transport/BasePackFetchConnection.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/transport/BasePackFetchConnection.java
@@ -129,13 +129,13 @@
 	public static final String OPTION_INCLUDE_TAG = GitProtocolConstants.OPTION_INCLUDE_TAG;
 
 	/**
-	 * Mutli-ACK support for improved negotiation.
+	 * Multi-ACK support for improved negotiation.
 	 * @since 2.0
 	 */
 	public static final String OPTION_MULTI_ACK = GitProtocolConstants.OPTION_MULTI_ACK;
 
 	/**
-	 * Mutli-ACK detailed support for improved negotiation.
+	 * Multi-ACK detailed support for improved negotiation.
 	 * @since 2.0
 	 */
 	public static final String OPTION_MULTI_ACK_DETAILED = GitProtocolConstants.OPTION_MULTI_ACK_DETAILED;
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 e402de0..36a10cc 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/transport/BaseReceivePack.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/transport/BaseReceivePack.java
@@ -1361,7 +1361,7 @@
 	}
 
 	static ReceiveCommand parseCommand(String line) throws PackProtocolException {
-          if (line == null || line.length() < 83) {
+		if (line == null || line.length() < 83) {
 			throw new PackProtocolException(
 					JGitText.get().errorInvalidProtocolWantedOldNewRef);
 		}
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 6c24269..fe1b697 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/transport/FetchV2Request.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/transport/FetchV2Request.java
@@ -72,6 +72,11 @@
 	@NonNull
 	private final List<String> serverOptions;
 
+	private final boolean sidebandAll;
+
+	@NonNull
+	private final List<String> packfileUriProtocols;
+
 	FetchV2Request(@NonNull List<ObjectId> peerHas,
 			@NonNull List<String> wantedRefs,
 			@NonNull Set<ObjectId> wantIds,
@@ -79,7 +84,8 @@
 			@NonNull List<String> deepenNotRefs, int depth,
 			@NonNull FilterSpec filterSpec,
 			boolean doneReceived, @NonNull Set<String> clientCapabilities,
-			@Nullable String agent, @NonNull List<String> serverOptions) {
+			@Nullable String agent, @NonNull List<String> serverOptions,
+			boolean sidebandAll, @NonNull List<String> packfileUriProtocols) {
 		super(wantIds, depth, clientShallowCommits, filterSpec,
 				clientCapabilities, deepenSince,
 				deepenNotRefs, agent);
@@ -87,6 +93,8 @@
 		this.wantedRefs = requireNonNull(wantedRefs);
 		this.doneReceived = doneReceived;
 		this.serverOptions = requireNonNull(serverOptions);
+		this.sidebandAll = sidebandAll;
+		this.packfileUriProtocols = packfileUriProtocols;
 	}
 
 	/**
@@ -127,6 +135,18 @@
 		return serverOptions;
 	}
 
+	/**
+	 * @return true if "sideband-all" was received
+	 */
+	boolean getSidebandAll() {
+		return sidebandAll;
+	}
+
+	@NonNull
+	List<String> getPackfileUriProtocols() {
+		return packfileUriProtocols;
+	}
+
 	/** @return A builder of {@link FetchV2Request}. */
 	static Builder builder() {
 		return new Builder();
@@ -159,6 +179,10 @@
 
 		final List<String> serverOptions = new ArrayList<>();
 
+		boolean sidebandAll;
+
+		final List<String> packfileUriProtocols = new ArrayList<>();
+
 		private Builder() {
 		}
 
@@ -318,13 +342,29 @@
 		}
 
 		/**
+		 * @param value true if client sent "sideband-all"
+		 * @return this builder
+		 */
+		Builder setSidebandAll(boolean value) {
+			sidebandAll = value;
+			return this;
+		}
+
+		Builder addPackfileUriProtocol(@NonNull String value) {
+			packfileUriProtocols.add(value);
+			return this;
+		}
+
+		/**
 		 * @return Initialized fetch request
 		 */
 		FetchV2Request build() {
 			return new FetchV2Request(peerHas, wantedRefs, wantIds,
 					clientShallowCommits, deepenSince, deepenNotRefs,
 					depth, filterSpec, doneReceived, clientCapabilities,
-					agent, Collections.unmodifiableList(serverOptions));
+					agent, Collections.unmodifiableList(serverOptions),
+					sidebandAll,
+					Collections.unmodifiableList(packfileUriProtocols));
 		}
 	}
 }
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/transport/GitProtocolConstants.java b/org.eclipse.jgit/src/org/eclipse/jgit/transport/GitProtocolConstants.java
index 1561c93..e3c0bc6 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/transport/GitProtocolConstants.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/transport/GitProtocolConstants.java
@@ -59,14 +59,14 @@
 	public static final String OPTION_INCLUDE_TAG = "include-tag"; //$NON-NLS-1$
 
 	/**
-	 * Mutli-ACK support for improved negotiation.
+	 * Multi-ACK support for improved negotiation.
 	 *
 	 * @since 3.2
 	 */
 	public static final String OPTION_MULTI_ACK = "multi_ack"; //$NON-NLS-1$
 
 	/**
-	 * Mutli-ACK detailed support for improved negotiation.
+	 * Multi-ACK detailed support for improved negotiation.
 	 *
 	 * @since 3.2
 	 */
@@ -174,6 +174,14 @@
 	public static final String OPTION_WANT_REF = "want-ref"; //$NON-NLS-1$
 
 	/**
+	 * The client requested that the whole response be multiplexed, with
+	 * each non-flush and non-delim pkt prefixed by a sideband designator.
+	 *
+	 * @since 5.5
+	 */
+	public static final String OPTION_SIDEBAND_ALL = "sideband-all"; //$NON-NLS-1$
+
+	/**
 	 * The client supports atomic pushes. If this option is used, the server
 	 * will update all refs within one atomic transaction.
 	 *
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/transport/JschConfigSessionFactory.java b/org.eclipse.jgit/src/org/eclipse/jgit/transport/JschConfigSessionFactory.java
index 0bdd6ba..79af1eb 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/transport/JschConfigSessionFactory.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/transport/JschConfigSessionFactory.java
@@ -551,7 +551,7 @@
 	 * @param config
 	 *            to use
 	 */
-	void setConfig(OpenSshConfig config) {
+	synchronized void setConfig(OpenSshConfig config) {
 		this.config = config;
 	}
 }
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/transport/PacketLineOut.java b/org.eclipse.jgit/src/org/eclipse/jgit/transport/PacketLineOut.java
index e940091..7f837bb 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/transport/PacketLineOut.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/transport/PacketLineOut.java
@@ -74,6 +74,8 @@
 
 	private boolean flushOnEnd;
 
+	private boolean usingSideband;
+
 	/**
 	 * Create a new packet line writer.
 	 *
@@ -98,6 +100,28 @@
 	}
 
 	/**
+	 * @return whether to add a sideband designator to each non-flush and
+	 *     non-delim packet
+	 * @see #setUsingSideband
+	 * @since 5.5
+	 */
+	public boolean isUsingSideband() {
+		return usingSideband;
+	}
+
+	/**
+	 * @param value If true, when writing packet lines, add, as the first
+	 *     byte, a sideband designator to each non-flush and non-delim
+	 *     packet. See pack-protocol.txt and protocol-v2.txt from the Git
+	 *     project for more information, specifically the "side-band" and
+	 *     "sideband-all" sections.
+	 * @since 5.5
+	 */
+	public void setUsingSideband(boolean value) {
+		this.usingSideband = value;
+	}
+
+	/**
 	 * Write a UTF-8 encoded string as a single length-delimited packet.
 	 *
 	 * @param s
@@ -139,8 +163,14 @@
 	 * @since 4.5
 	 */
 	public void writePacket(byte[] buf, int pos, int len) throws IOException {
-		formatLength(len + 4);
-		out.write(lenbuffer, 0, 4);
+		if (usingSideband) {
+			formatLength(len + 5);
+			out.write(lenbuffer, 0, 4);
+			out.write(1);
+		} else {
+			formatLength(len + 4);
+			out.write(lenbuffer, 0, 4);
+		}
 		out.write(buf, pos, len);
 		if (log.isDebugEnabled()) {
 			String s = RawParseUtils.decode(UTF_8, buf, pos, len);
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/transport/PostUploadHookChain.java b/org.eclipse.jgit/src/org/eclipse/jgit/transport/PostUploadHookChain.java
index 542abe7..4334888 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/transport/PostUploadHookChain.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/transport/PostUploadHookChain.java
@@ -42,7 +42,9 @@
 
 package org.eclipse.jgit.transport;
 
+import java.util.Collections;
 import java.util.List;
+import java.util.stream.Collectors;
 
 import org.eclipse.jgit.storage.pack.PackStatistics;
 
@@ -55,8 +57,7 @@
  * @since 4.1
  */
 public class PostUploadHookChain implements PostUploadHook {
-	private final PostUploadHook[] hooks;
-	private final int count;
+	private final List<PostUploadHook> hooks;
 
 	/**
 	 * Create a new hook chaining the given hooks together.
@@ -65,29 +66,29 @@
 	 *            hooks to execute, in order.
 	 * @return a new chain of the given hooks.
 	 */
-	public static PostUploadHook newChain(List<? extends PostUploadHook> hooks) {
-		PostUploadHook[] newHooks = new PostUploadHook[hooks.size()];
-		int i = 0;
-		for (PostUploadHook hook : hooks)
-			if (hook != PostUploadHook.NULL)
-				newHooks[i++] = hook;
-		if (i == 0)
+	public static PostUploadHook newChain(List<PostUploadHook> hooks) {
+		List<PostUploadHook> newHooks = hooks.stream()
+				.filter(hook -> !hook.equals(PostUploadHook.NULL))
+				.collect(Collectors.toList());
+
+		if (newHooks.isEmpty()) {
 			return PostUploadHook.NULL;
-		else if (i == 1)
-			return newHooks[0];
-		else
-			return new PostUploadHookChain(newHooks, i);
+		} else if (newHooks.size() == 1) {
+			return newHooks.get(0);
+		} else {
+			return new PostUploadHookChain(newHooks);
+		}
 	}
 
 	/** {@inheritDoc} */
 	@Override
 	public void onPostUpload(PackStatistics stats) {
-		for (int i = 0; i < count; i++)
-			hooks[i].onPostUpload(stats);
+		for (PostUploadHook hook : hooks) {
+			hook.onPostUpload(stats);
+		}
 	}
 
-	private PostUploadHookChain(PostUploadHook[] hooks, int count) {
-		this.hooks = hooks;
-		this.count = count;
+	private PostUploadHookChain(List<PostUploadHook> hooks) {
+		this.hooks = Collections.unmodifiableList(hooks);
 	}
 }
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/transport/PreUploadHookChain.java b/org.eclipse.jgit/src/org/eclipse/jgit/transport/PreUploadHookChain.java
index bfd52af..2192654 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/transport/PreUploadHookChain.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/transport/PreUploadHookChain.java
@@ -44,7 +44,9 @@
 package org.eclipse.jgit.transport;
 
 import java.util.Collection;
+import java.util.Collections;
 import java.util.List;
+import java.util.stream.Collectors;
 
 import org.eclipse.jgit.lib.ObjectId;
 
@@ -56,8 +58,7 @@
  * one hook throws an exception, execution of remaining hook methods is aborted.
  */
 public class PreUploadHookChain implements PreUploadHook {
-	private final PreUploadHook[] hooks;
-	private final int count;
+	private final List<PreUploadHook> hooks;
 
 	/**
 	 * Create a new hook chaining the given hooks together.
@@ -66,18 +67,18 @@
 	 *            hooks to execute, in order.
 	 * @return a new hook chain of the given hooks.
 	 */
-	public static PreUploadHook newChain(List<? extends PreUploadHook> hooks) {
-		PreUploadHook[] newHooks = new PreUploadHook[hooks.size()];
-		int i = 0;
-		for (PreUploadHook hook : hooks)
-			if (hook != PreUploadHook.NULL)
-				newHooks[i++] = hook;
-		if (i == 0)
+	public static PreUploadHook newChain(List<PreUploadHook> hooks) {
+		List<PreUploadHook> newHooks = hooks.stream()
+				.filter(hook -> !hook.equals(PreUploadHook.NULL))
+				.collect(Collectors.toList());
+
+		if (newHooks.isEmpty()) {
 			return PreUploadHook.NULL;
-		else if (i == 1)
-			return newHooks[0];
-		else
-			return new PreUploadHookChain(newHooks, i);
+		} else if (newHooks.size() == 1) {
+			return newHooks.get(0);
+		} else {
+			return new PreUploadHookChain(newHooks);
+		}
 	}
 
 	/** {@inheritDoc} */
@@ -85,8 +86,9 @@
 	public void onBeginNegotiateRound(UploadPack up,
 			Collection<? extends ObjectId> wants, int cntOffered)
 			throws ServiceMayNotContinueException {
-		for (int i = 0; i < count; i++)
-			hooks[i].onBeginNegotiateRound(up, wants, cntOffered);
+		for (PreUploadHook hook : hooks) {
+			hook.onBeginNegotiateRound(up, wants, cntOffered);
+		}
 	}
 
 	/** {@inheritDoc} */
@@ -95,8 +97,9 @@
 			Collection<? extends ObjectId> wants, int cntCommon,
 			int cntNotFound, boolean ready)
 			throws ServiceMayNotContinueException {
-		for (int i = 0; i < count; i++)
-			hooks[i].onEndNegotiateRound(up, wants, cntCommon, cntNotFound, ready);
+		for (PreUploadHook hook : hooks) {
+			hook.onEndNegotiateRound(up, wants, cntCommon, cntNotFound, ready);
+		}
 	}
 
 	/** {@inheritDoc} */
@@ -105,12 +108,12 @@
 			Collection<? extends ObjectId> wants,
 			Collection<? extends ObjectId> haves)
 			throws ServiceMayNotContinueException {
-		for (int i = 0; i < count; i++)
-			hooks[i].onSendPack(up, wants, haves);
+		for (PreUploadHook hook : hooks) {
+			hook.onSendPack(up, wants, haves);
+		}
 	}
 
-	private PreUploadHookChain(PreUploadHook[] hooks, int count) {
-		this.hooks = hooks;
-		this.count = count;
+	private PreUploadHookChain(List<PreUploadHook> hooks) {
+		this.hooks = Collections.unmodifiableList(hooks);
 	}
 }
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/transport/ProtocolV2HookChain.java b/org.eclipse.jgit/src/org/eclipse/jgit/transport/ProtocolV2HookChain.java
new file mode 100644
index 0000000..cc36473
--- /dev/null
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/transport/ProtocolV2HookChain.java
@@ -0,0 +1,110 @@
+/*
+ * 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.util.Collections;
+import java.util.List;
+import java.util.stream.Collectors;
+
+/**
+ * {@link org.eclipse.jgit.transport.ProtocolV2Hook} that delegates to a list of
+ * other hooks.
+ * <p>
+ * Hooks are run in the order passed to the constructor. If running a method on
+ * one hook throws an exception, execution of remaining hook methods is aborted.
+ *
+ * @since 5.5
+ */
+public class ProtocolV2HookChain implements ProtocolV2Hook {
+	private final List<? extends ProtocolV2Hook> hooks;
+
+	/**
+	 * Create a new hook chaining the given hooks together.
+	 *
+	 * @param hooks
+	 *            hooks to execute, in order.
+	 * @return a new hook chain of the given hooks.
+	 */
+	public static ProtocolV2Hook newChain(
+			List<? extends ProtocolV2Hook> hooks) {
+		List<? extends ProtocolV2Hook> newHooks = hooks.stream()
+				.filter(hook -> !hook.equals(ProtocolV2Hook.DEFAULT))
+				.collect(Collectors.toList());
+
+		if (newHooks.isEmpty()) {
+			return ProtocolV2Hook.DEFAULT;
+		} else if (newHooks.size() == 1) {
+			return newHooks.get(0);
+		} else {
+			return new ProtocolV2HookChain(newHooks);
+		}
+	}
+
+	@Override
+	public void onCapabilities(CapabilitiesV2Request req)
+			throws ServiceMayNotContinueException {
+		for (ProtocolV2Hook hook : hooks) {
+			hook.onCapabilities(req);
+		}
+	}
+
+	@Override
+	public void onLsRefs(LsRefsV2Request req)
+			throws ServiceMayNotContinueException {
+		for (ProtocolV2Hook hook : hooks) {
+			hook.onLsRefs(req);
+		}
+	}
+
+	@Override
+	public void onFetch(FetchV2Request req)
+			throws ServiceMayNotContinueException {
+		for (ProtocolV2Hook hook : hooks) {
+			hook.onFetch(req);
+		}
+	}
+
+	private ProtocolV2HookChain(List<? extends ProtocolV2Hook> hooks) {
+		this.hooks = Collections.unmodifiableList(hooks);
+	}
+}
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 caba15f..14ccddf 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/transport/ProtocolV2Parser.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/transport/ProtocolV2Parser.java
@@ -49,6 +49,7 @@
 import static org.eclipse.jgit.transport.GitProtocolConstants.OPTION_NO_PROGRESS;
 import static org.eclipse.jgit.transport.GitProtocolConstants.OPTION_OFS_DELTA;
 import static org.eclipse.jgit.transport.GitProtocolConstants.OPTION_SERVER_OPTION;
+import static org.eclipse.jgit.transport.GitProtocolConstants.OPTION_SIDEBAND_ALL;
 import static org.eclipse.jgit.transport.GitProtocolConstants.OPTION_SIDE_BAND_64K;
 import static org.eclipse.jgit.transport.GitProtocolConstants.OPTION_THIN_PACK;
 import static org.eclipse.jgit.transport.GitProtocolConstants.OPTION_WANT_REF;
@@ -210,6 +211,13 @@
 				filterReceived = true;
 				reqBuilder.setFilterSpec(FilterSpec.fromFilterLine(
 						line2.substring(OPTION_FILTER.length() + 1)));
+			} else if (transferConfig.isAllowSidebandAll()
+					&& line2.equals(OPTION_SIDEBAND_ALL)) {
+				reqBuilder.setSidebandAll(true);
+			} else if (line2.startsWith("packfile-uris ")) { //$NON-NLS-1$
+				for (String s : line2.substring(14).split(",")) {
+					reqBuilder.addPackfileUriProtocol(s);
+				}
 			} else {
 				throw new PackProtocolException(MessageFormat
 						.format(JGitText.get().unexpectedPacketLine, line2));
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/transport/SshConstants.java b/org.eclipse.jgit/src/org/eclipse/jgit/transport/SshConstants.java
index 2b79d71..efbe777 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/transport/SshConstants.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/transport/SshConstants.java
@@ -101,6 +101,13 @@
 	/** Key in an ssh config file. */
 	public static final String GLOBAL_KNOWN_HOSTS_FILE = "GlobalKnownHostsFile";
 
+	/**
+	 * Key in an ssh config file.
+	 *
+	 * @since 5.5
+	 */
+	public static final String HASH_KNOWN_HOSTS = "HashKnownHosts";
+
 	/** Key in an ssh config file. */
 	public static final String HOST = "Host";
 
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/transport/TransferConfig.java b/org.eclipse.jgit/src/org/eclipse/jgit/transport/TransferConfig.java
index a3e655c..758d74c 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/transport/TransferConfig.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/transport/TransferConfig.java
@@ -131,6 +131,7 @@
 	private final boolean allowTipSha1InWant;
 	private final boolean allowReachableSha1InWant;
 	private final boolean allowFilter;
+	private final boolean allowSidebandAll;
 	final @Nullable ProtocolVersion protocolVersion;
 	final String[] hideRefs;
 
@@ -210,6 +211,8 @@
 				"uploadpack", "allowfilter", false);
 		protocolVersion = ProtocolVersion.parse(rc.getString("protocol", null, "version"));
 		hideRefs = rc.getStringList("uploadpack", null, "hiderefs");
+		allowSidebandAll = rc.getBoolean(
+				"uploadpack", "allowsidebandall", false);
 	}
 
 	/**
@@ -292,6 +295,14 @@
 	}
 
 	/**
+	 * @return true if clients are allowed to specify a "sideband-all" line
+	 * @since 5.5
+	 */
+	public boolean isAllowSidebandAll() {
+		return allowSidebandAll;
+	}
+
+	/**
 	 * Get {@link org.eclipse.jgit.transport.RefFilter} respecting configured
 	 * hidden refs.
 	 *
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/transport/TransportAmazonS3.java b/org.eclipse.jgit/src/org/eclipse/jgit/transport/TransportAmazonS3.java
index 6118cb8..c0a70bc 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/transport/TransportAmazonS3.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/transport/TransportAmazonS3.java
@@ -259,7 +259,7 @@
 		@Override
 		Collection<WalkRemoteObjectDatabase> getAlternates() throws IOException {
 			try {
-				return readAlternates(INFO_ALTERNATES);
+				return readAlternates(Constants.INFO_ALTERNATES);
 			} catch (FileNotFoundException err) {
 				// Fall through.
 			}
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 a591dba..3029327 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/transport/TransportHttp.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/transport/TransportHttp.java
@@ -48,6 +48,8 @@
 
 import static java.nio.charset.StandardCharsets.UTF_8;
 import static org.eclipse.jgit.lib.Constants.HEAD;
+import static org.eclipse.jgit.lib.Constants.INFO_ALTERNATES;
+import static org.eclipse.jgit.lib.Constants.INFO_HTTP_ALTERNATES;
 import static org.eclipse.jgit.util.HttpSupport.ENCODING_GZIP;
 import static org.eclipse.jgit.util.HttpSupport.ENCODING_X_GZIP;
 import static org.eclipse.jgit.util.HttpSupport.HDR_ACCEPT;
@@ -75,6 +77,7 @@
 import java.net.MalformedURLException;
 import java.net.Proxy;
 import java.net.ProxySelector;
+import java.net.URI;
 import java.net.URISyntaxException;
 import java.net.URL;
 import java.nio.file.InvalidPathException;
@@ -589,7 +592,8 @@
 										JGitText.get().redirectsOff,
 										Integer.valueOf(status)));
 					}
-					URIish newUri = redirect(conn.getHeaderField(HDR_LOCATION),
+					URIish newUri = redirect(u,
+							conn.getHeaderField(HDR_LOCATION),
 							Constants.INFO_REFS, redirects++);
 					setURI(newUri);
 					u = getServiceURL(service);
@@ -798,7 +802,8 @@
 		}
 	}
 
-	private URIish redirect(String location, String checkFor, int redirects)
+	private URIish redirect(URL currentUrl, String location, String checkFor,
+			int redirects)
 			throws TransportException {
 		if (location == null || location.isEmpty()) {
 			throw new TransportException(uri,
@@ -812,13 +817,16 @@
 							location));
 		}
 		try {
-			if (!isValidRedirect(baseUrl, location, checkFor)) {
+			URI redirectTo = new URI(location);
+			redirectTo = currentUrl.toURI().resolve(redirectTo);
+			String redirected = redirectTo.toASCIIString();
+			if (!isValidRedirect(baseUrl, redirected, checkFor)) {
 				throw new TransportException(uri,
 						MessageFormat.format(JGitText.get().redirectBlocked,
-								baseUrl, location));
+								baseUrl, redirected));
 			}
-			location = location.substring(0, location.indexOf(checkFor));
-			URIish result = new URIish(location);
+			redirected = redirected.substring(0, redirected.indexOf(checkFor));
+			URIish result = new URIish(redirected);
 			if (LOG.isInfoEnabled()) {
 				LOG.info(MessageFormat.format(JGitText.get().redirectHttp,
 						uri.setPass(null),
@@ -1448,7 +1456,8 @@
 							// Let openResponse() issue an error
 							return;
 						}
-						currentUri = redirect(conn.getHeaderField(HDR_LOCATION),
+						currentUri = redirect(conn.getURL(),
+								conn.getHeaderField(HDR_LOCATION),
 								'/' + serviceName, redirects++);
 						try {
 							baseUrl = toURL(currentUri);
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/transport/TransportSftp.java b/org.eclipse.jgit/src/org/eclipse/jgit/transport/TransportSftp.java
index 5c68308..8d91c60 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/transport/TransportSftp.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/transport/TransportSftp.java
@@ -43,7 +43,9 @@
 
 package org.eclipse.jgit.transport;
 
+import static org.eclipse.jgit.lib.Constants.INFO_ALTERNATES;
 import static org.eclipse.jgit.lib.Constants.LOCK_SUFFIX;
+import static org.eclipse.jgit.lib.Constants.OBJECTS;
 
 import java.io.BufferedReader;
 import java.io.FileNotFoundException;
@@ -172,7 +174,7 @@
 			try {
 				ftp = newSftp();
 				ftp.cd(path);
-				ftp.cd("objects"); //$NON-NLS-1$
+				ftp.cd(OBJECTS);
 				objectsPath = ftp.pwd();
 			} catch (FtpChannel.FtpException f) {
 				throw new TransportException(MessageFormat.format(
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 9278f42..20b4588 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/transport/UploadPack.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/transport/UploadPack.java
@@ -61,6 +61,7 @@
 import static org.eclipse.jgit.transport.GitProtocolConstants.OPTION_NO_PROGRESS;
 import static org.eclipse.jgit.transport.GitProtocolConstants.OPTION_OFS_DELTA;
 import static org.eclipse.jgit.transport.GitProtocolConstants.OPTION_SHALLOW;
+import static org.eclipse.jgit.transport.GitProtocolConstants.OPTION_SIDEBAND_ALL;
 import static org.eclipse.jgit.transport.GitProtocolConstants.OPTION_SIDE_BAND;
 import static org.eclipse.jgit.transport.GitProtocolConstants.OPTION_SIDE_BAND_64K;
 import static org.eclipse.jgit.transport.GitProtocolConstants.OPTION_THIN_PACK;
@@ -92,6 +93,7 @@
 import org.eclipse.jgit.errors.MissingObjectException;
 import org.eclipse.jgit.errors.PackProtocolException;
 import org.eclipse.jgit.internal.JGitText;
+import org.eclipse.jgit.internal.storage.pack.CachedPackUriProvider;
 import org.eclipse.jgit.internal.storage.pack.PackWriter;
 import org.eclipse.jgit.internal.transport.parser.FirstWant;
 import org.eclipse.jgit.lib.BitmapIndex;
@@ -113,6 +115,7 @@
 import org.eclipse.jgit.revwalk.RevFlag;
 import org.eclipse.jgit.revwalk.RevFlagSet;
 import org.eclipse.jgit.revwalk.RevObject;
+import org.eclipse.jgit.revwalk.RevSort;
 import org.eclipse.jgit.revwalk.RevTag;
 import org.eclipse.jgit.revwalk.RevWalk;
 import org.eclipse.jgit.revwalk.filter.CommitTimeRevFilter;
@@ -277,8 +280,6 @@
 
 	private PacketLineIn pckIn;
 
-	private PacketLineOut pckOut;
-
 	private OutputStream msgOut = NullOutputStream.INSTANCE;
 
 	/**
@@ -359,6 +360,8 @@
 	 */
 	private FetchRequest currentRequest;
 
+	private CachedPackUriProvider cachedPackUriProvider;
+
 	/**
 	 * Create a new pack upload for an open repository.
 	 *
@@ -602,6 +605,18 @@
 	}
 
 	/**
+	 * Get the currently installed protocol v2 hook.
+	 *
+	 * @return the hook or a default implementation if none installed.
+	 *
+	 * @since 5.5
+	 */
+	public ProtocolV2Hook getProtocolV2Hook() {
+		return this.protocolV2Hook != null ? this.protocolV2Hook
+				: ProtocolV2Hook.DEFAULT;
+	}
+
+	/**
 	 * Set the filter used while advertising the refs to the client.
 	 * <p>
 	 * Only refs allowed by this filter will be sent to the client. The filter
@@ -724,6 +739,15 @@
 		this.clientRequestedV2 = params.contains("version=2"); //$NON-NLS-1$
 	}
 
+	/**
+	 * @param p provider of URIs corresponding to cached packs (to support
+	 *     the packfile URIs feature)
+	 * @since 5.5
+	 */
+	public void setCachedPackUriProvider(@Nullable CachedPackUriProvider p) {
+		cachedPackUriProvider = p;
+	}
+
 	private boolean useProtocolV2() {
 		return ProtocolVersion.V2.equals(transferConfig.protocolVersion)
 				&& clientRequestedV2;
@@ -750,8 +774,9 @@
 	 *            other network connections this should be null.
 	 * @throws java.io.IOException
 	 */
-	public void upload(final InputStream input, OutputStream output,
-			final OutputStream messages) throws IOException {
+	public void upload(InputStream input, OutputStream output,
+			@Nullable OutputStream messages) throws IOException {
+		PacketLineOut pckOut = null;
 		try {
 			rawIn = input;
 			if (messages != null)
@@ -777,10 +802,40 @@
 			pckIn = new PacketLineIn(rawIn);
 			pckOut = new PacketLineOut(rawOut);
 			if (useProtocolV2()) {
-				serviceV2();
+				serviceV2(pckOut);
 			} else {
-				service();
+				service(pckOut);
 			}
+		} catch (UploadPackInternalServerErrorException err) {
+			// UploadPackInternalServerErrorException is a special exception
+			// that indicates an error is already written to the client. Do
+			// nothing.
+			throw err;
+		} catch (ServiceMayNotContinueException err) {
+			if (!err.isOutput() && err.getMessage() != null && pckOut != null) {
+				try {
+					pckOut.writeString("ERR " + err.getMessage() + "\n"); //$NON-NLS-1$ //$NON-NLS-2$
+				} catch (IOException e) {
+					err.addSuppressed(e);
+					throw err;
+				}
+				err.setOutput();
+			}
+			throw err;
+		} catch (IOException | RuntimeException | Error err) {
+			if (pckOut != null) {
+				String msg = err instanceof PackProtocolException
+						? err.getMessage()
+						: JGitText.get().internalServerError;
+				try {
+					pckOut.writeString("ERR " + msg + "\n"); //$NON-NLS-1$ //$NON-NLS-2$
+				} catch (IOException e) {
+					err.addSuppressed(e);
+					throw err;
+				}
+				throw new UploadPackInternalServerErrorException(err);
+			}
+			throw err;
 		} finally {
 			msgOut = NullOutputStream.INSTANCE;
 			walk.close();
@@ -941,7 +996,7 @@
 		return RefDatabase.findRef(getAdvertisedOrDefaultRefs(), name);
 	}
 
-	private void service() throws IOException {
+	private void service(PacketLineOut pckOut) throws IOException {
 		boolean sendPack = false;
 		// If it's a non-bidi request, we need to read the entire request before
 		// writing a response. Buffer the response until then.
@@ -997,7 +1052,7 @@
 
 			if (!req.getClientShallowCommits().isEmpty())
 				walk.assumeShallow(req.getClientShallowCommits());
-			sendPack = negotiate(req, accumulator);
+			sendPack = negotiate(req, accumulator, pckOut);
 			accumulator.timeNegotiating += System.currentTimeMillis()
 					- negotiateStart;
 
@@ -1012,31 +1067,6 @@
 							"\\x" + Integer.toHexString(eof))); //$NON-NLS-1$
 				}
 			}
-		} catch (ServiceMayNotContinueException err) {
-			if (!err.isOutput() && err.getMessage() != null) {
-				try {
-					pckOut.writeString("ERR " + err.getMessage() + "\n"); //$NON-NLS-1$ //$NON-NLS-2$
-					err.setOutput();
-				} catch (Throwable err2) {
-					// Ignore this secondary failure (and not mark output).
-				}
-			}
-			throw err;
-		} catch (IOException | RuntimeException | Error err) {
-			boolean output = false;
-			try {
-				String msg = err instanceof PackProtocolException
-						? err.getMessage()
-						: JGitText.get().internalServerError;
-				pckOut.writeString("ERR " + msg + "\n"); //$NON-NLS-1$ //$NON-NLS-2$
-				output = true;
-			} catch (Throwable err2) {
-				// Ignore this secondary failure, leave output false.
-			}
-			if (output) {
-				throw new UploadPackInternalServerErrorException(err);
-			}
-			throw err;
 		} finally {
 			if (!sendPack && !biDirectionalPipe) {
 				while (0 < rawIn.skip(2048) || 0 <= rawIn.read()) {
@@ -1048,11 +1078,11 @@
 
 		if (sendPack) {
 			sendPack(accumulator, req, refs == null ? null : refs.values(),
-					unshallowCommits, Collections.emptyList());
+					unshallowCommits, Collections.emptyList(), pckOut);
 		}
 	}
 
-	private void lsRefsV2() throws IOException {
+	private void lsRefsV2(PacketLineOut pckOut) throws IOException {
 		ProtocolV2Parser parser = new ProtocolV2Parser(transferConfig);
 		LsRefsV2Request req = parser.parseLsRefsRequest(pckIn);
 		protocolV2Hook.onLsRefs(req);
@@ -1097,7 +1127,7 @@
 		return result;
 	}
 
-	private void fetchV2() throws IOException {
+	private void fetchV2(PacketLineOut pckOut) throws IOException {
 		// Depending on the requestValidator, #processHaveLines may
 		// require that advertised be set. Set it only in the required
 		// circumstances (to avoid a full ref lookup in the case that
@@ -1117,6 +1147,10 @@
 
 		protocolV2Hook.onFetch(req);
 
+		if (req.getSidebandAll()) {
+			pckOut.setUsingSideband(true);
+		}
+
 		// TODO(ifrade): Refactor to pass around the Request object, instead of
 		// copying data back to class fields
 		List<ObjectId> deepenNots = new ArrayList<>();
@@ -1202,13 +1236,17 @@
 
 			if (sectionSent)
 				pckOut.writeDelim();
-			pckOut.writeString("packfile\n"); //$NON-NLS-1$
+			if (!pckOut.isUsingSideband()) {
+				// sendPack will write "packfile\n" for us if sideband-all is used.
+				// But sideband-all is not used, so we have to write it ourselves.
+				pckOut.writeString("packfile\n"); //$NON-NLS-1$
+			}
 			sendPack(new PackStatistics.Accumulator(),
 					req,
 					req.getClientCapabilities().contains(OPTION_INCLUDE_TAG)
 						? db.getRefDatabase().getRefsByPrefix(R_TAGS)
 						: null,
-					unshallowCommits, deepenNots);
+					unshallowCommits, deepenNots, pckOut);
 			// sendPack invokes pckOut.end() for us, so we do not
 			// need to invoke it here.
 		} else {
@@ -1221,7 +1259,7 @@
 	 * Returns true if this is the last command and we should tear down the
 	 * connection.
 	 */
-	private boolean serveOneCommandV2() throws IOException {
+	private boolean serveOneCommandV2(PacketLineOut pckOut) throws IOException {
 		String command;
 		try {
 			command = pckIn.readString();
@@ -1236,34 +1274,38 @@
 			return true;
 		}
 		if (command.equals("command=" + COMMAND_LS_REFS)) { //$NON-NLS-1$
-			lsRefsV2();
+			lsRefsV2(pckOut);
 			return false;
 		}
 		if (command.equals("command=" + COMMAND_FETCH)) { //$NON-NLS-1$
-			fetchV2();
+			fetchV2(pckOut);
 			return false;
 		}
 		throw new PackProtocolException(MessageFormat
 				.format(JGitText.get().unknownTransportCommand, command));
 	}
 
+	@SuppressWarnings("nls")
 	private List<String> getV2CapabilityAdvertisement() {
 		ArrayList<String> caps = new ArrayList<>();
-		caps.add("version 2"); //$NON-NLS-1$
+		caps.add("version 2");
 		caps.add(COMMAND_LS_REFS);
-		boolean advertiseRefInWant = transferConfig.isAllowRefInWant() &&
-				db.getConfig().getBoolean("uploadpack", null, //$NON-NLS-1$
-						"advertiserefinwant", true); //$NON-NLS-1$
-		caps.add(
-				COMMAND_FETCH + '=' +
-				(transferConfig.isAllowFilter() ? OPTION_FILTER + ' ' : "") + //$NON-NLS-1$
-				(advertiseRefInWant ? CAPABILITY_REF_IN_WANT + ' ' : "") + //$NON-NLS-1$
-				OPTION_SHALLOW);
+		boolean advertiseRefInWant = transferConfig.isAllowRefInWant()
+				&& db.getConfig().getBoolean("uploadpack", null,
+						"advertiserefinwant", true);
+		caps.add(COMMAND_FETCH + '='
+				+ (transferConfig.isAllowFilter() ? OPTION_FILTER + ' ' : "")
+				+ (advertiseRefInWant ? CAPABILITY_REF_IN_WANT + ' ' : "")
+				+ (transferConfig.isAllowSidebandAll()
+						? OPTION_SIDEBAND_ALL + ' '
+						: "")
+				+ (cachedPackUriProvider != null ? "packfile-uris " : "")
+				+ OPTION_SHALLOW);
 		caps.add(CAPABILITY_SERVER_OPTION);
 		return caps;
 	}
 
-	private void serviceV2() throws IOException {
+	private void serviceV2(PacketLineOut pckOut) throws IOException {
 		if (biDirectionalPipe) {
 			// Just like in service(), the capability advertisement
 			// is sent only if this is a bidirectional pipe. (If
@@ -1276,14 +1318,14 @@
 			}
 			pckOut.end();
 
-			while (!serveOneCommandV2()) {
+			while (!serveOneCommandV2(pckOut)) {
 				// Repeat until an empty command or EOF.
 			}
 			return;
 		}
 
 		try {
-			serveOneCommandV2();
+			serveOneCommandV2(pckOut);
 		} finally {
 			while (0 < rawIn.skip(2048) || 0 <= rawIn.read()) {
 				// Discard until EOF.
@@ -1579,7 +1621,8 @@
 	}
 
 	private boolean negotiate(FetchRequest req,
-			PackStatistics.Accumulator accumulator)
+			PackStatistics.Accumulator accumulator,
+			PacketLineOut pckOut)
 			throws IOException {
 		okToGiveUp = Boolean.FALSE;
 
@@ -1868,6 +1911,36 @@
 		}
 	}
 
+	private static void checkReachabilityByWalkingObjects(ObjectWalk walk,
+			List<RevObject> wants, Set<ObjectId> reachableFrom) throws IOException {
+
+		walk.sort(RevSort.TOPO);
+		for (RevObject want : wants) {
+			walk.markStart(want);
+		}
+		for (ObjectId have : reachableFrom) {
+			RevObject o = walk.parseAny(have);
+			walk.markUninteresting(o);
+
+			RevObject peeled = walk.peel(o);
+			if (peeled instanceof RevCommit) {
+				// By default, for performance reasons, ObjectWalk does not mark a
+				// tree as uninteresting when we mark a commit. Mark it ourselves so
+				// that we can determine reachability exactly.
+				walk.markUninteresting(((RevCommit) peeled).getTree());
+			}
+		}
+
+		RevCommit commit = walk.next();
+		if (commit != null) {
+			throw new WantNotValidException(commit);
+		}
+		RevObject object = walk.nextObject();
+		if (object != null) {
+			throw new WantNotValidException(object);
+		}
+	}
+
 	private static void checkNotAdvertisedWants(UploadPack up,
 			List<ObjectId> notAdvertisedWants, Set<ObjectId> reachableFrom)
 			throws IOException {
@@ -1888,6 +1961,17 @@
 
 			if (!allWantsAreCommits) {
 				if (!repoHasBitmaps) {
+					if (up.transferConfig.isAllowFilter()) {
+						// Use allowFilter as an indication that the server
+						// operator is willing to pay the cost of these
+						// reachability checks.
+						try (ObjectWalk objWalk = walk.toObjectWalkWithSameObjects()) {
+							checkReachabilityByWalkingObjects(objWalk,
+									wantsAsObjs, reachableFrom);
+						}
+						return;
+					}
+
 					// If unadvertized non-commits are requested, use
 					// bitmaps. If there are no bitmaps, instead of
 					// incurring the expense of a manual walk, reject
@@ -2016,6 +2100,8 @@
 	 *            shallow commits on the client that are now becoming unshallow
 	 * @param deepenNots
 	 *            objects that the client specified using --shallow-exclude
+	 * @param pckOut
+	 *            output writer
 	 * @throws IOException
 	 *             if an error occurred while generating or writing the pack.
 	 */
@@ -2023,43 +2109,51 @@
 			FetchRequest req,
 			@Nullable Collection<Ref> allTags,
 			List<ObjectId> unshallowCommits,
-			List<ObjectId> deepenNots) throws IOException {
+			List<ObjectId> deepenNots,
+			PacketLineOut pckOut) throws IOException {
 		Set<String> caps = req.getClientCapabilities();
 		boolean sideband = caps.contains(OPTION_SIDE_BAND)
 				|| caps.contains(OPTION_SIDE_BAND_64K);
 		if (sideband) {
 			try {
 				sendPack(true, req, accumulator, allTags, unshallowCommits,
-						deepenNots);
-			} catch (ServiceMayNotContinueException noPack) {
-				// This was already reported on (below).
-				throw noPack;
-			} catch (IOException | RuntimeException | Error err) {
-				if (reportInternalServerErrorOverSideband()) {
-					throw new UploadPackInternalServerErrorException(err);
-				} else {
+						deepenNots, pckOut);
+			} catch (ServiceMayNotContinueException err) {
+				String message = err.getMessage();
+				if (message == null) {
+					message = JGitText.get().internalServerError;
+				}
+				try {
+					reportInternalServerErrorOverSideband(message);
+				} catch (IOException e) {
+					err.addSuppressed(e);
 					throw err;
 				}
+				throw new UploadPackInternalServerErrorException(err);
+			} catch (IOException | RuntimeException | Error err) {
+				try {
+					reportInternalServerErrorOverSideband(
+							JGitText.get().internalServerError);
+				} catch (IOException e) {
+					err.addSuppressed(e);
+					throw err;
+				}
+				throw new UploadPackInternalServerErrorException(err);
 			}
 		} else {
-			sendPack(false, req, accumulator, allTags, unshallowCommits, deepenNots);
+			sendPack(false, req, accumulator, allTags, unshallowCommits, deepenNots,
+					pckOut);
 		}
 	}
 
-	private boolean reportInternalServerErrorOverSideband() {
-		try {
-			@SuppressWarnings("resource" /* java 7 */)
-			SideBandOutputStream err = new SideBandOutputStream(
-					SideBandOutputStream.CH_ERROR,
-					SideBandOutputStream.SMALL_BUF,
-					rawOut);
-			err.write(Constants.encode(JGitText.get().internalServerError));
-			err.flush();
-			return true;
-		} catch (Throwable cannotReport) {
-			// Ignore the reason. This is a secondary failure.
-			return false;
-		}
+	private void reportInternalServerErrorOverSideband(String message)
+			throws IOException {
+		@SuppressWarnings("resource" /* java 7 */)
+		SideBandOutputStream err = new SideBandOutputStream(
+				SideBandOutputStream.CH_ERROR, SideBandOutputStream.SMALL_BUF,
+				rawOut);
+		err.write(Constants.encode(message));
+		err.flush();
 	}
 
 	/**
@@ -2079,6 +2173,8 @@
 	 *            shallow commits on the client that are now becoming unshallow
 	 * @param deepenNots
 	 *            objects that the client specified using --shallow-exclude
+	 * @param pckOut
+	 *            output writer
 	 * @throws IOException
 	 *             if an error occurred while generating or writing the pack.
 	 */
@@ -2087,7 +2183,8 @@
 			PackStatistics.Accumulator accumulator,
 			@Nullable Collection<Ref> allTags,
 			List<ObjectId> unshallowCommits,
-			List<ObjectId> deepenNots) throws IOException {
+			List<ObjectId> deepenNots,
+			PacketLineOut pckOut) throws IOException {
 		ProgressMonitor pm = NullProgressMonitor.INSTANCE;
 		OutputStream packOut = rawOut;
 
@@ -2105,25 +2202,12 @@
 			}
 		}
 
-		try {
-			if (wantAll.isEmpty()) {
-				preUploadHook.onSendPack(this, wantIds, commonBase);
-			} else {
-				preUploadHook.onSendPack(this, wantAll, commonBase);
-			}
-			msgOut.flush();
-		} catch (ServiceMayNotContinueException noPack) {
-			if (sideband && noPack.getMessage() != null) {
-				noPack.setOutput();
-				@SuppressWarnings("resource" /* java 7 */)
-				SideBandOutputStream err = new SideBandOutputStream(
-						SideBandOutputStream.CH_ERROR,
-						SideBandOutputStream.SMALL_BUF, rawOut);
-				err.write(Constants.encode(noPack.getMessage()));
-				err.flush();
-			}
-			throw noPack;
+		if (wantAll.isEmpty()) {
+			preUploadHook.onSendPack(this, wantIds, commonBase);
+		} else {
+			preUploadHook.onSendPack(this, wantAll, commonBase);
 		}
+		msgOut.flush();
 
 		PackConfig cfg = packConfig;
 		if (cfg == null)
@@ -2219,12 +2303,32 @@
 					if (peeledId == null || objectId == null)
 						continue;
 
+					objectId = ref.getObjectId();
 					if (pw.willInclude(peeledId) && !pw.willInclude(objectId)) {
-						pw.addObject(rw.parseAny(objectId));
+						RevObject o = rw.parseAny(objectId);
+						addTagChain(o, pw);
+						pw.addObject(o);
 					}
 				}
 			}
 
+			if (pckOut.isUsingSideband()) {
+				if (req instanceof FetchV2Request &&
+						cachedPackUriProvider != null &&
+						!((FetchV2Request) req).getPackfileUriProtocols().isEmpty()) {
+					FetchV2Request reqV2 = (FetchV2Request) req;
+					pw.setPackfileUriConfig(new PackWriter.PackfileUriConfig(
+							pckOut,
+							reqV2.getPackfileUriProtocols(),
+							cachedPackUriProvider));
+				} else {
+					// PackWriter will write "packfile-uris\n" and "packfile\n"
+					// for us if provided a PackfileUriConfig. In this case, we
+					// are not providing a PackfileUriConfig, so we have to
+					// write this line ourselves.
+					pckOut.writeString("packfile\n"); //$NON-NLS-1$
+				}
+			}
 			pw.writePack(pm, NullProgressMonitor.INSTANCE, packOut);
 
 			if (msgOut != NullOutputStream.INSTANCE) {
@@ -2253,6 +2357,18 @@
 		}
 	}
 
+	private void addTagChain(
+			RevObject o, PackWriter pw) throws IOException {
+		while (Constants.OBJ_TAG == o.getType()) {
+			RevTag t = (RevTag) o;
+			o = t.getObject();
+			if (o.getType() == Constants.OBJ_TAG && !pw.willInclude(o.getId())) {
+				walk.parseBody(o);
+				pw.addObject(o);
+			}
+		}
+	}
+
 	private static class ResponseBufferedOutputStream extends OutputStream {
 		private final OutputStream rawOut;
 
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/transport/WalkEncryption.java b/org.eclipse.jgit/src/org/eclipse/jgit/transport/WalkEncryption.java
index b4248ee..7a973af 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/transport/WalkEncryption.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/transport/WalkEncryption.java
@@ -66,8 +66,8 @@
 import javax.crypto.spec.PBEKeySpec;
 import javax.crypto.spec.PBEParameterSpec;
 import javax.crypto.spec.SecretKeySpec;
-import javax.xml.bind.DatatypeConverter;
 
+import org.bouncycastle.util.encoders.Hex;
 import org.eclipse.jgit.internal.JGitText;
 import org.eclipse.jgit.util.Base64;
 
@@ -301,7 +301,7 @@
 		String DEFAULT_KEY_ALGO = JetS3tV2.ALGORITHM;
 		String DEFAULT_KEY_SIZE = Integer.toString(JetS3tV2.KEY_SIZE);
 		String DEFAULT_KEY_ITER = Integer.toString(JetS3tV2.ITERATIONS);
-		String DEFAULT_KEY_SALT = DatatypeConverter.printHexBinary(JetS3tV2.SALT);
+		String DEFAULT_KEY_SALT = Hex.toHexString(JetS3tV2.SALT);
 
 		String EMPTY = ""; //$NON-NLS-1$
 
@@ -377,8 +377,7 @@
 
 			final byte[] salt;
 			try {
-				salt = DatatypeConverter
-						.parseHexBinary(keySalt.replaceAll(REGEX_WS, EMPTY));
+				salt = Hex.decode(keySalt.replaceAll(REGEX_WS, EMPTY));
 			} catch (Exception e) {
 				throw securityError(X_KEY_SALT + EMPTY + keySalt);
 			}
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/transport/WalkRemoteObjectDatabase.java b/org.eclipse.jgit/src/org/eclipse/jgit/transport/WalkRemoteObjectDatabase.java
index 5c67253..4862d67 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/transport/WalkRemoteObjectDatabase.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/transport/WalkRemoteObjectDatabase.java
@@ -82,10 +82,6 @@
 
 	static final String INFO_PACKS = "info/packs"; //$NON-NLS-1$
 
-	static final String INFO_ALTERNATES = "info/alternates"; //$NON-NLS-1$
-
-	static final String INFO_HTTP_ALTERNATES = "info/http-alternates"; //$NON-NLS-1$
-
 	static final String INFO_REFS = ROOT_DIR + Constants.INFO_REFS;
 
 	abstract URIish getURI();
@@ -107,8 +103,10 @@
 	/**
 	 * Obtain alternate connections to alternate object databases (if any).
 	 * <p>
-	 * Alternates are typically read from the file {@link #INFO_ALTERNATES} or
-	 * {@link #INFO_HTTP_ALTERNATES}. The content of each line must be resolved
+         * Alternates are typically read from the file
+         * {@link org.eclipse.jgit.lib.Constants#INFO_ALTERNATES} or
+         * {@link org.eclipse.jgit.lib.Constants#INFO_HTTP_ALTERNATES}.
+         * The content of each line must be resolved
 	 * by the implementation and a new database reference should be returned to
 	 * represent the additional location.
 	 * <p>
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 9030501..0aa0e36 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/util/FS.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/util/FS.java
@@ -64,6 +64,7 @@
 import java.nio.file.Path;
 import java.nio.file.attribute.BasicFileAttributes;
 import java.nio.file.attribute.FileTime;
+import java.security.AccessControlException;
 import java.security.AccessController;
 import java.security.PrivilegedAction;
 import java.text.MessageFormat;
@@ -122,6 +123,8 @@
 	 */
 	protected static final Entry[] NO_ENTRIES = {};
 
+	private volatile Boolean supportSymlinks;
+
 	/**
 	 * This class creates FS instances. It will be overridden by a Java7 variant
 	 * if such can be detected in {@link #detect(Boolean)}.
@@ -241,8 +244,9 @@
 			background.set(async);
 		}
 
-		private static final String javaVersionPrefix = System
-				.getProperty("java.vendor") + '|' //$NON-NLS-1$
+		private static final String javaVersionPrefix = SystemReader
+				.getInstance().getHostname() + '|'
+				+ System.getProperty("java.vendor") + '|' //$NON-NLS-1$
 				+ System.getProperty("java.version") + '|'; //$NON-NLS-1$
 
 		private static final Duration FALLBACK_MIN_RACY_INTERVAL = Duration
@@ -276,15 +280,19 @@
 		 * @return FileStoreAttributes for the given path.
 		 */
 		public static FileStoreAttributes get(Path path) {
-			path = path.toAbsolutePath();
-			Path dir = Files.isDirectory(path) ? path : path.getParent();
-			FileStoreAttributes cached = attrCacheByPath.get(dir);
-			if (cached != null) {
-				return cached;
+			try {
+				path = path.toAbsolutePath();
+				Path dir = Files.isDirectory(path) ? path : path.getParent();
+				FileStoreAttributes cached = attrCacheByPath.get(dir);
+				if (cached != null) {
+					return cached;
+				}
+				FileStoreAttributes attrs = getFileStoreAttributes(dir);
+				attrCacheByPath.put(dir, attrs);
+				return attrs;
+			} catch (SecurityException e) {
+				return FALLBACK_FILESTORE_ATTRIBUTES;
 			}
-			FileStoreAttributes attrs = getFileStoreAttributes(dir);
-			attrCacheByPath.put(dir, attrs);
-			return attrs;
 		}
 
 		private static FileStoreAttributes getFileStoreAttributes(Path dir) {
@@ -538,9 +546,9 @@
 
 		private static void saveToConfig(FileStore s,
 				FileStoreAttributes c) {
-			StoredConfig userConfig;
+			StoredConfig jgitConfig;
 			try {
-				userConfig = SystemReader.getInstance().getUserConfig();
+				jgitConfig = SystemReader.getInstance().getJGitConfig();
 			} catch (IOException | ConfigInvalidException e) {
 				LOG.error(JGitText.get().saveFileStoreAttributesFailed, e);
 				return;
@@ -561,20 +569,19 @@
 			String key = getConfigKey(s);
 			while (!succeeded && retries < max_retries) {
 				try {
-					userConfig.load();
-					userConfig.setString(
+					jgitConfig.setString(
 							ConfigConstants.CONFIG_FILESYSTEM_SECTION, key,
 							ConfigConstants.CONFIG_KEY_TIMESTAMP_RESOLUTION,
 							String.format("%d %s", //$NON-NLS-1$
 									Long.valueOf(resolutionValue),
 									resolutionUnit.name().toLowerCase()));
-					userConfig.setString(
+					jgitConfig.setString(
 							ConfigConstants.CONFIG_FILESYSTEM_SECTION, key,
 							ConfigConstants.CONFIG_KEY_MIN_RACY_THRESHOLD,
 							String.format("%d %s", //$NON-NLS-1$
 									Long.valueOf(minRacyThresholdValue),
 									minRacyThresholdUnit.name().toLowerCase()));
-					userConfig.save();
+					jgitConfig.save();
 					succeeded = true;
 				} catch (LockFailedException e) {
 					// race with another thread, wait a bit and try again
@@ -583,11 +590,11 @@
 						if (retries < max_retries) {
 							Thread.sleep(100);
 							LOG.debug("locking {} failed, retries {}/{}", //$NON-NLS-1$
-									userConfig, Integer.valueOf(retries),
+									jgitConfig, Integer.valueOf(retries),
 									Integer.valueOf(max_retries));
 						} else {
 							LOG.warn(MessageFormat.format(
-									JGitText.get().lockFailedRetry, userConfig,
+									JGitText.get().lockFailedRetry, jgitConfig,
 									Integer.valueOf(retries)));
 						}
 					} catch (InterruptedException e1) {
@@ -596,12 +603,7 @@
 					}
 				} catch (IOException e) {
 					LOG.error(MessageFormat.format(
-							JGitText.get().cannotSaveConfig, userConfig), e);
-					break;
-				} catch (ConfigInvalidException e) {
-					LOG.error(MessageFormat.format(
-							JGitText.get().repositoryConfigFileInvalid,
-							userConfig, e.getMessage()));
+							JGitText.get().cannotSaveConfig, jgitConfig), e);
 					break;
 				}
 			}
@@ -813,7 +815,32 @@
 	 * @since 3.0
 	 */
 	public boolean supportsSymlinks() {
-		return false;
+		if (supportSymlinks == null) {
+			detectSymlinkSupport();
+		}
+		return Boolean.TRUE.equals(supportSymlinks);
+	}
+
+	private void detectSymlinkSupport() {
+		File tempFile = null;
+		try {
+			tempFile = File.createTempFile("tempsymlinktarget", ""); //$NON-NLS-1$ //$NON-NLS-2$
+			File linkName = new File(tempFile.getParentFile(), "tempsymlink"); //$NON-NLS-1$
+			createSymLink(linkName, tempFile.getPath());
+			supportSymlinks = Boolean.TRUE;
+			linkName.delete();
+		} catch (IOException | UnsupportedOperationException | SecurityException
+				| InternalError e) {
+			supportSymlinks = Boolean.FALSE;
+		} finally {
+			if (tempFile != null) {
+				try {
+					FileUtils.delete(tempFile);
+				} catch (IOException e) {
+					throw new RuntimeException(e); // panic
+				}
+			}
+		}
 	}
 
 	/**
@@ -1067,9 +1094,16 @@
 
 		for (String p : path.split(File.pathSeparator)) {
 			for (String command : lookFor) {
-				final File e = new File(p, command);
-				if (e.isFile())
-					return e.getAbsoluteFile();
+				final File file = new File(p, command);
+				try {
+					if (file.isFile()) {
+						return file.getAbsoluteFile();
+					}
+				} catch (SecurityException e) {
+					LOG.warn(MessageFormat.format(
+							JGitText.get().skipNotAccessiblePath,
+							file.getPath()));
+				}
 			}
 		}
 		return null;
@@ -1172,6 +1206,13 @@
 			}
 		} catch (IOException e) {
 			LOG.error("Caught exception in FS.readPipe()", e); //$NON-NLS-1$
+		} catch (AccessControlException e) {
+			LOG.warn(MessageFormat.format(
+					JGitText.get().readPipeIsNotAllowedRequiredPermission,
+					command, dir, e.getPermission()));
+		} catch (SecurityException e) {
+			LOG.warn(MessageFormat.format(JGitText.get().readPipeIsNotAllowed,
+					command, dir));
 		}
 		if (debug) {
 			LOG.debug("readpipe returns null"); //$NON-NLS-1$
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 a485389..6a1eef2 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
@@ -287,12 +287,6 @@
 
 	/** {@inheritDoc} */
 	@Override
-	public boolean supportsSymlinks() {
-		return true;
-	}
-
-	/** {@inheritDoc} */
-	@Override
 	public void setHidden(File path, boolean hidden) throws IOException {
 		// no action on POSIX
 	}
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 7fe80bb..1e64a38 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
@@ -74,8 +74,6 @@
 public class FS_Win32 extends FS {
 	private final static Logger LOG = LoggerFactory.getLogger(FS_Win32.class);
 
-	private volatile Boolean supportSymlinks;
-
 	/**
 	 * Constructor
 	 */
@@ -239,37 +237,6 @@
 
 	/** {@inheritDoc} */
 	@Override
-	public boolean supportsSymlinks() {
-		if (supportSymlinks == null) {
-			detectSymlinkSupport();
-		}
-		return Boolean.TRUE.equals(supportSymlinks);
-	}
-
-	private void detectSymlinkSupport() {
-		File tempFile = null;
-		try {
-			tempFile = File.createTempFile("tempsymlinktarget", ""); //$NON-NLS-1$ //$NON-NLS-2$
-			File linkName = new File(tempFile.getParentFile(), "tempsymlink"); //$NON-NLS-1$
-			createSymLink(linkName, tempFile.getPath());
-			supportSymlinks = Boolean.TRUE;
-			linkName.delete();
-		} catch (IOException | UnsupportedOperationException
-				| InternalError e) {
-			supportSymlinks = Boolean.FALSE;
-		} finally {
-			if (tempFile != null) {
-				try {
-					FileUtils.delete(tempFile);
-				} catch (IOException e) {
-					throw new RuntimeException(e); // panic
-				}
-			}
-		}
-	}
-
-	/** {@inheritDoc} */
-	@Override
 	public Attributes getAttributes(File path) {
 		return FileUtils.getFileAttributesBasic(this, path);
 	}
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 b80ffb5..e16a886 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/util/SystemReader.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/util/SystemReader.java
@@ -50,6 +50,10 @@
 import java.io.IOException;
 import java.net.InetAddress;
 import java.net.UnknownHostException;
+import java.nio.file.Files;
+import java.nio.file.InvalidPathException;
+import java.nio.file.Path;
+import java.nio.file.Paths;
 import java.security.AccessController;
 import java.security.PrivilegedAction;
 import java.text.DateFormat;
@@ -60,6 +64,7 @@
 
 import org.eclipse.jgit.errors.ConfigInvalidException;
 import org.eclipse.jgit.errors.CorruptObjectException;
+import org.eclipse.jgit.internal.JGitText;
 import org.eclipse.jgit.lib.Config;
 import org.eclipse.jgit.lib.Constants;
 import org.eclipse.jgit.lib.ObjectChecker;
@@ -137,6 +142,42 @@
 					fs);
 		}
 
+		private Path getXDGConfigHome(FS fs) {
+			String configHomePath = getenv(Constants.XDG_CONFIG_HOME);
+			if (StringUtils.isEmptyOrNull(configHomePath)) {
+				configHomePath = new File(fs.userHome(), ".config") //$NON-NLS-1$
+						.getAbsolutePath();
+			}
+			try {
+				Path xdgHomePath = Paths.get(configHomePath);
+				Files.createDirectories(xdgHomePath);
+				return xdgHomePath;
+			} catch (IOException | InvalidPathException e) {
+				LOG.error(JGitText.get().createXDGConfigHomeFailed,
+						configHomePath, e);
+			}
+			return null;
+		}
+
+		@Override
+		public FileBasedConfig openJGitConfig(Config parent, FS fs) {
+			Path xdgPath = getXDGConfigHome(fs);
+			if (xdgPath != null) {
+				Path configPath = null;
+				try {
+					configPath = xdgPath.resolve("jgit"); //$NON-NLS-1$
+					Files.createDirectories(configPath);
+					configPath = configPath.resolve(Constants.CONFIG);
+					return new FileBasedConfig(parent, configPath.toFile(), fs);
+				} catch (IOException e) {
+					LOG.error(JGitText.get().createJGitConfigFailed, configPath,
+							e);
+				}
+			}
+			return new FileBasedConfig(parent,
+					new File(fs.userHome(), ".jgitconfig"), fs); //$NON-NLS-1$
+		}
+
 		@Override
 		public String getHostname() {
 			if (hostname == null) {
@@ -198,6 +239,8 @@
 
 	private AtomicReference<FileBasedConfig> userConfig = new AtomicReference<>();
 
+	private AtomicReference<FileBasedConfig> jgitConfig = new AtomicReference<>();
+
 	private void init() {
 		// Creating ObjectChecker must be deferred. Unit tests change
 		// behavior of is{Windows,MacOS} in constructor of subclass.
@@ -275,6 +318,22 @@
 	public abstract FileBasedConfig openSystemConfig(Config parent, FS fs);
 
 	/**
+	 * Open the jgit configuration located at $XDG_CONFIG_HOME/jgit/config. Use
+	 * {@link #getJGitConfig()} to get the current jgit configuration in the
+	 * user home since it manages automatic reloading when the jgit config file
+	 * was modified and avoids unnecessary reloads.
+	 *
+	 * @param parent
+	 *            a config with values not found directly in the returned config
+	 * @param fs
+	 *            the file system abstraction which will be necessary to perform
+	 *            certain file system operations.
+	 * @return the jgit configuration located at $XDG_CONFIG_HOME/jgit/config
+	 * @since 5.5.2
+	 */
+	public abstract FileBasedConfig openJGitConfig(Config parent, FS fs);
+
+	/**
 	 * Get the git configuration found in the user home. The configuration will
 	 * be reloaded automatically if the configuration file was modified. Also
 	 * reloads the system config if the system config file was modified. If the
@@ -288,20 +347,41 @@
 	 * @since 5.1.9
 	 */
 	public StoredConfig getUserConfig()
-			throws IOException, ConfigInvalidException {
+			throws ConfigInvalidException, IOException {
 		FileBasedConfig c = userConfig.get();
 		if (c == null) {
 			userConfig.compareAndSet(null,
 					openUserConfig(getSystemConfig(), FS.DETECTED));
 			c = userConfig.get();
-		} else {
-			// Ensure the parent is up to date
-			getSystemConfig();
 		}
-		if (c.isOutdated()) {
-			LOG.debug("loading user config {}", userConfig); //$NON-NLS-1$
-			c.load();
+		// on the very first call this will check a second time if the system
+		// config is outdated
+		updateAll(c);
+		return c;
+	}
+
+	/**
+	 * Get the jgit configuration located at $XDG_CONFIG_HOME/jgit/config. The
+	 * configuration will be reloaded automatically if the configuration file
+	 * was modified. If the configuration file wasn't modified returns the
+	 * cached configuration.
+	 *
+	 * @return the jgit configuration located at $XDG_CONFIG_HOME/jgit/config
+	 * @throws ConfigInvalidException
+	 *             if configuration is invalid
+	 * @throws IOException
+	 *             if something went wrong when reading files
+	 * @since 5.5.2
+	 */
+	public StoredConfig getJGitConfig()
+			throws ConfigInvalidException, IOException {
+		FileBasedConfig c = jgitConfig.get();
+		if (c == null) {
+			jgitConfig.compareAndSet(null,
+					openJGitConfig(null, FS.DETECTED));
+			c = jgitConfig.get();
 		}
+		updateAll(c);
 		return c;
 	}
 
@@ -319,21 +399,43 @@
 	 * @since 5.1.9
 	 */
 	public StoredConfig getSystemConfig()
-			throws IOException, ConfigInvalidException {
+			throws ConfigInvalidException, IOException {
 		FileBasedConfig c = systemConfig.get();
 		if (c == null) {
 			systemConfig.compareAndSet(null,
-					openSystemConfig(null, FS.DETECTED));
+					openSystemConfig(getJGitConfig(), FS.DETECTED));
 			c = systemConfig.get();
 		}
-		if (c.isOutdated()) {
-			LOG.debug("loading system config {}", systemConfig); //$NON-NLS-1$
-			c.load();
-		}
+		updateAll(c);
 		return c;
 	}
 
 	/**
+	 * Update config and its parents if they seem modified
+	 *
+	 * @param config
+	 *            configuration to reload if outdated
+	 * @throws ConfigInvalidException
+	 *             if configuration is invalid
+	 * @throws IOException
+	 *             if something went wrong when reading files
+	 */
+	private void updateAll(Config config)
+			throws ConfigInvalidException, IOException {
+		if (config == null) {
+			return;
+		}
+		updateAll(config.getBaseConfig());
+		if (config instanceof FileBasedConfig) {
+			FileBasedConfig cfg = (FileBasedConfig) config;
+			if (cfg.isOutdated()) {
+				LOG.debug("loading config {}", cfg); //$NON-NLS-1$
+				cfg.load();
+			}
+		}
+	}
+
+	/**
 	 * Get the current system time
 	 *
 	 * @return the current system time
diff --git a/pom.xml b/pom.xml
index 26b1c1a..d0335b0 100644
--- a/pom.xml
+++ b/pom.xml
@@ -51,7 +51,7 @@
   <groupId>org.eclipse.jgit</groupId>
   <artifactId>org.eclipse.jgit-parent</artifactId>
   <packaging>pom</packaging>
-  <version>5.4.4-SNAPSHOT</version>
+  <version>5.5.2-SNAPSHOT</version>
 
   <name>JGit - Parent</name>
   <url>${jgit-url}</url>
@@ -182,7 +182,7 @@
     <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.3.0.201903130848-r</jgit-last-release-version>
+    <jgit-last-release-version>5.4.0.201906121030-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>
@@ -193,7 +193,7 @@
     <commons-compress-version>1.18</commons-compress-version>
     <osgi-core-version>4.3.1</osgi-core-version>
     <servlet-api-version>3.1.0</servlet-api-version>
-    <jetty-version>9.4.14.v20181114</jetty-version>
+    <jetty-version>9.4.20.v20190813</jetty-version>
     <japicmp-version>0.14.1</japicmp-version>
     <httpclient-version>4.5.6</httpclient-version>
     <httpcore-version>4.4.10</httpcore-version>
@@ -204,6 +204,7 @@
     <gson-version>2.8.2</gson-version>
     <bouncycastle-version>1.61</bouncycastle-version>
     <maven-project-info-reports-plugin-version>3.1.2</maven-project-info-reports-plugin-version>
+    <maven-jxr-plugin-version>3.1.1</maven-jxr-plugin-version>
     <maven-surefire-plugin-version>3.0.0-M5</maven-surefire-plugin-version>
     <spotbugs-maven-plugin-version>4.3.0</spotbugs-maven-plugin-version>
     <maven-surefire-plugin-version>3.0.0-M5</maven-surefire-plugin-version>
@@ -377,7 +378,7 @@
             <dependency><!-- add support for ssh/scp -->
               <groupId>org.apache.maven.wagon</groupId>
               <artifactId>wagon-ssh</artifactId>
-              <version>3.3.2</version>
+              <version>3.3.3</version>
             </dependency>
           </dependencies>
         </plugin>
@@ -924,7 +925,7 @@
               <dependency>
                 <groupId>org.eclipse.jdt</groupId>
                 <artifactId>ecj</artifactId>
-                <version>3.17.0</version>
+                <version>3.18.0</version>
               </dependency>
             </dependencies>
           </plugin>