Merge branch 'stable-5.8' into stable-5.9

* stable-5.8:
  [test] Create keystore with the keytool of the running JDK
  ReachabilityCheckerTestCase: fix reachable from self test case

Change-Id: If09cbb877c674f15261715cecef7a2393bf66fa3
Signed-off-by: Thomas Wolf <thomas.wolf@paranor.ch>
diff --git a/.bazelrc b/.bazelrc
index 3a61f8c..e24be88 100644
--- a/.bazelrc
+++ b/.bazelrc
@@ -1,3 +1,4 @@
+build --workspace_status_command="python ./tools/workspace_status.py"
 build --repository_cache=~/.gerritcodereview/bazel-cache/repository
 build --experimental_strict_action_env
 build --action_env=PATH
diff --git a/.bazelversion b/.bazelversion
index fd2a018..1545d96 100644
--- a/.bazelversion
+++ b/.bazelversion
@@ -1 +1 @@
-3.1.0
+3.5.0
diff --git a/WORKSPACE b/WORKSPACE
index 509cf6d..9cd666f 100644
--- a/WORKSPACE
+++ b/WORKSPACE
@@ -107,8 +107,8 @@
 
 maven_jar(
     name = "commons-codec",
-    artifact = "commons-codec:commons-codec:1.13",
-    sha1 = "3f18e1aa31031d89db6f01ba05d501258ce69d2c",
+    artifact = "commons-codec:commons-codec:1.14",
+    sha1 = "3cb1181b2141a7e752f5bdc998b7ef1849f726cf",
 )
 
 maven_jar(
@@ -209,48 +209,48 @@
     sha1 = "3edcfe49d2c6053a70a2a47e4e1c2f94998a49cf",
 )
 
-JETTY_VER = "9.4.28.v20200408"
+JETTY_VER = "9.4.30.v20200611"
 
 maven_jar(
     name = "jetty-servlet",
     artifact = "org.eclipse.jetty:jetty-servlet:" + JETTY_VER,
-    sha1 = "7df27a6d73e3094ad94ea4f32e3e6597cecbdf38",
-    src_sha1 = "49da8455dd5760b7c5961df3b1e7d1490ff9723e",
+    sha1 = "ca3dea2cd34ee88cec017001603af0c9e74781d6",
+    src_sha1 = "6908f24428060bd542bddfa3e89e03d0dbbc2a6d",
 )
 
 maven_jar(
     name = "jetty-security",
     artifact = "org.eclipse.jetty:jetty-security:" + JETTY_VER,
-    sha1 = "d5fe6851f14d1375e4b4ab1818475bfd929cf517",
-    src_sha1 = "204f19ac7e4df9f6f68df1910154d7667ecd78e8",
+    sha1 = "1a5261f6ad4081ad9e9bb01416d639931d391273",
+    src_sha1 = "6ca41b34aa4f84c267603edd4b069122bd5f17d3",
 )
 
 maven_jar(
     name = "jetty-server",
     artifact = "org.eclipse.jetty:jetty-server:" + JETTY_VER,
-    sha1 = "9c2cbd96426be38b1273ec87ae21e2696688a737",
-    src_sha1 = "83454098deb880ecc7168252578f712c06a5504b",
+    sha1 = "e5ede3724d062717d0c04e4c77f74fe8115c2a6f",
+    src_sha1 = "c8b02a47a35c1f083b310cbd202738cf08bc1d55",
 )
 
 maven_jar(
     name = "jetty-http",
     artifact = "org.eclipse.jetty:jetty-http:" + JETTY_VER,
-    sha1 = "dd56750ea7410c925f1fbae973c0a19cce5a0a68",
-    src_sha1 = "1ef8d10cb5ce5694f12650cbb49b31008c673182",
+    sha1 = "cd6223382e4f82b9ea807d8cdb04a23e5d629f1c",
+    src_sha1 = "00520c04b10609b981159b5ca284b5a158c077a9",
 )
 
 maven_jar(
     name = "jetty-io",
     artifact = "org.eclipse.jetty:jetty-io:" + JETTY_VER,
-    sha1 = "adda6786588a922f834e9c33c7db5f1484310f44",
-    src_sha1 = "4e7756e00b97b439d404e6a682bb1cdeb36fc887",
+    sha1 = "9c360d08e903b2dbd5d1f8e889a32046948628ce",
+    src_sha1 = "dac8f8a3f84afdd3686d36f58b5ccb276961b8ce",
 )
 
 maven_jar(
     name = "jetty-util",
     artifact = "org.eclipse.jetty:jetty-util:" + JETTY_VER,
-    sha1 = "118d2a44721885a04238aee21a5055dc1ab3818a",
-    src_sha1 = "e2e6d7c90e4126645d2667014d02f0732c08c948",
+    sha1 = "39ec6aa4745952077f5407cb1394d8ba2db88b13",
+    src_sha1 = "f41f9391f91884a79350f3ad9b09b8e46c9be0ec",
 )
 
 BOUNCYCASTLE_VER = "1.65"
diff --git a/org.eclipse.jgit.ant.test/.settings/org.eclipse.jdt.core.prefs b/org.eclipse.jgit.ant.test/.settings/org.eclipse.jdt.core.prefs
index 3dd5840..4c4634a 100644
--- a/org.eclipse.jgit.ant.test/.settings/org.eclipse.jdt.core.prefs
+++ b/org.eclipse.jgit.ant.test/.settings/org.eclipse.jdt.core.prefs
@@ -52,7 +52,7 @@
 org.eclipse.jdt.core.compiler.problem.missingJavadocCommentsOverriding=disabled
 org.eclipse.jdt.core.compiler.problem.missingJavadocCommentsVisibility=protected
 org.eclipse.jdt.core.compiler.problem.missingJavadocTagDescription=return_tag
-org.eclipse.jdt.core.compiler.problem.missingJavadocTags=error
+org.eclipse.jdt.core.compiler.problem.missingJavadocTags=ignore
 org.eclipse.jdt.core.compiler.problem.missingJavadocTagsMethodTypeParameters=disabled
 org.eclipse.jdt.core.compiler.problem.missingJavadocTagsOverriding=disabled
 org.eclipse.jdt.core.compiler.problem.missingJavadocTagsVisibility=private
diff --git a/org.eclipse.jgit.ant.test/META-INF/MANIFEST.MF b/org.eclipse.jgit.ant.test/META-INF/MANIFEST.MF
index 78b47c1..d660518 100644
--- a/org.eclipse.jgit.ant.test/META-INF/MANIFEST.MF
+++ b/org.eclipse.jgit.ant.test/META-INF/MANIFEST.MF
@@ -5,13 +5,13 @@
 Automatic-Module-Name: org.eclipse.jgit.ant.test
 Bundle-SymbolicName: org.eclipse.jgit.ant.test
 Bundle-Vendor: %Bundle-Vendor
-Bundle-Version: 5.8.2.qualifier
+Bundle-Version: 5.9.1.qualifier
 Bundle-ActivationPolicy: lazy
 Bundle-RequiredExecutionEnvironment: JavaSE-1.8
 Import-Package: org.apache.tools.ant,
- org.eclipse.jgit.ant.tasks;version="[5.8.2,5.9.0)",
- org.eclipse.jgit.junit;version="[5.8.2,5.9.0)",
- org.eclipse.jgit.lib;version="[5.8.2,5.9.0)",
- org.eclipse.jgit.util;version="[5.8.2,5.9.0)",
+ org.eclipse.jgit.ant.tasks;version="[5.9.1,5.10.0)",
+ org.eclipse.jgit.junit;version="[5.9.1,5.10.0)",
+ org.eclipse.jgit.lib;version="[5.9.1,5.10.0)",
+ org.eclipse.jgit.util;version="[5.9.1,5.10.0)",
  org.hamcrest.core;version="[1.1.0,2.0.0)",
  org.junit;version="[4.13,5.0.0)"
diff --git a/org.eclipse.jgit.ant.test/pom.xml b/org.eclipse.jgit.ant.test/pom.xml
index 230c077..d2dd5a1 100644
--- a/org.eclipse.jgit.ant.test/pom.xml
+++ b/org.eclipse.jgit.ant.test/pom.xml
@@ -17,7 +17,7 @@
   <parent>
     <groupId>org.eclipse.jgit</groupId>
     <artifactId>org.eclipse.jgit-parent</artifactId>
-    <version>5.8.2-SNAPSHOT</version>
+    <version>5.9.1-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 8e158fd..bd021e9 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.8.2.qualifier
+Bundle-Version: 5.9.1.qualifier
 Bundle-RequiredExecutionEnvironment: JavaSE-1.8
 Import-Package: org.apache.tools.ant,
-  org.eclipse.jgit.storage.file;version="[5.8.2,5.9.0)"
+  org.eclipse.jgit.storage.file;version="[5.9.1,5.10.0)"
 Bundle-Localization: plugin
 Bundle-Vendor: %Bundle-Vendor
-Export-Package: org.eclipse.jgit.ant;version="5.8.2",
- org.eclipse.jgit.ant.tasks;version="5.8.2";
+Export-Package: org.eclipse.jgit.ant;version="5.9.1",
+ org.eclipse.jgit.ant.tasks;version="5.9.1";
   uses:="org.apache.tools.ant,
    org.apache.tools.ant.types"
diff --git a/org.eclipse.jgit.ant/META-INF/SOURCE-MANIFEST.MF b/org.eclipse.jgit.ant/META-INF/SOURCE-MANIFEST.MF
index 2e6fae5..d10feaa 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.8.2.qualifier
-Eclipse-SourceBundle: org.eclipse.jgit.ant;version="5.8.2.qualifier";roots="."
+Bundle-Version: 5.9.1.qualifier
+Eclipse-SourceBundle: org.eclipse.jgit.ant;version="5.9.1.qualifier";roots="."
diff --git a/org.eclipse.jgit.ant/pom.xml b/org.eclipse.jgit.ant/pom.xml
index 62a5d24..342e84d 100644
--- a/org.eclipse.jgit.ant/pom.xml
+++ b/org.eclipse.jgit.ant/pom.xml
@@ -15,7 +15,7 @@
   <parent>
     <groupId>org.eclipse.jgit</groupId>
     <artifactId>org.eclipse.jgit-parent</artifactId>
-    <version>5.8.2-SNAPSHOT</version>
+    <version>5.9.1-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 6d384a6..96be945 100644
--- a/org.eclipse.jgit.archive/META-INF/MANIFEST.MF
+++ b/org.eclipse.jgit.archive/META-INF/MANIFEST.MF
@@ -3,7 +3,7 @@
 Bundle-Name: %Bundle-Name
 Automatic-Module-Name: org.eclipse.jgit.archive
 Bundle-SymbolicName: org.eclipse.jgit.archive
-Bundle-Version: 5.8.2.qualifier
+Bundle-Version: 5.9.1.qualifier
 Bundle-Vendor: %Bundle-Vendor
 Bundle-Localization: plugin
 Bundle-RequiredExecutionEnvironment: JavaSE-1.8
@@ -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.8.2,5.9.0)",
- org.eclipse.jgit.lib;version="[5.8.2,5.9.0)",
- org.eclipse.jgit.nls;version="[5.8.2,5.9.0)",
- org.eclipse.jgit.revwalk;version="[5.8.2,5.9.0)",
- org.eclipse.jgit.util;version="[5.8.2,5.9.0)",
+ org.eclipse.jgit.api;version="[5.9.1,5.10.0)",
+ org.eclipse.jgit.lib;version="[5.9.1,5.10.0)",
+ org.eclipse.jgit.nls;version="[5.9.1,5.10.0)",
+ org.eclipse.jgit.revwalk;version="[5.9.1,5.10.0)",
+ org.eclipse.jgit.util;version="[5.9.1,5.10.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.8.2";
+Export-Package: org.eclipse.jgit.archive;version="5.9.1";
   uses:="org.eclipse.jgit.lib,
    org.eclipse.jgit.api,
    org.apache.commons.compress.archivers,
    org.osgi.framework",
- org.eclipse.jgit.archive.internal;version="5.8.2";x-internal:=true
+ org.eclipse.jgit.archive.internal;version="5.9.1";x-internal:=true
diff --git a/org.eclipse.jgit.archive/META-INF/SOURCE-MANIFEST.MF b/org.eclipse.jgit.archive/META-INF/SOURCE-MANIFEST.MF
index 200f476..aa31f32 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.8.2.qualifier
-Eclipse-SourceBundle: org.eclipse.jgit.archive;version="5.8.2.qualifier";roots="."
+Bundle-Version: 5.9.1.qualifier
+Eclipse-SourceBundle: org.eclipse.jgit.archive;version="5.9.1.qualifier";roots="."
diff --git a/org.eclipse.jgit.archive/pom.xml b/org.eclipse.jgit.archive/pom.xml
index 512e6c5..1277f45 100644
--- a/org.eclipse.jgit.archive/pom.xml
+++ b/org.eclipse.jgit.archive/pom.xml
@@ -17,7 +17,7 @@
   <parent>
     <groupId>org.eclipse.jgit</groupId>
     <artifactId>org.eclipse.jgit-parent</artifactId>
-    <version>5.8.2-SNAPSHOT</version>
+    <version>5.9.1-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 f1e594b..e4d8703 100644
--- a/org.eclipse.jgit.benchmarks/pom.xml
+++ b/org.eclipse.jgit.benchmarks/pom.xml
@@ -14,7 +14,7 @@
   <modelVersion>4.0.0</modelVersion>
 
   <groupId>org.eclipse.jgit</groupId>
-  <version>5.8.2-SNAPSHOT</version>
+  <version>5.9.1-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 f08385f..14a22f5 100644
--- a/org.eclipse.jgit.coverage/pom.xml
+++ b/org.eclipse.jgit.coverage/pom.xml
@@ -14,7 +14,7 @@
   <parent>
     <groupId>org.eclipse.jgit</groupId>
     <artifactId>org.eclipse.jgit-parent</artifactId>
-    <version>5.8.2-SNAPSHOT</version>
+    <version>5.9.1-SNAPSHOT</version>
   </parent>
   <modelVersion>4.0.0</modelVersion>
 
@@ -27,88 +27,88 @@
     <dependency>
       <groupId>org.eclipse.jgit</groupId>
       <artifactId>org.eclipse.jgit</artifactId>
-      <version>5.8.2-SNAPSHOT</version>
+      <version>5.9.1-SNAPSHOT</version>
     </dependency>
     <dependency>
       <groupId>org.eclipse.jgit</groupId>
       <artifactId>org.eclipse.jgit.ant</artifactId>
-      <version>5.8.2-SNAPSHOT</version>
+      <version>5.9.1-SNAPSHOT</version>
     </dependency>
     <dependency>
       <groupId>org.eclipse.jgit</groupId>
       <artifactId>org.eclipse.jgit.archive</artifactId>
-      <version>5.8.2-SNAPSHOT</version>
+      <version>5.9.1-SNAPSHOT</version>
     </dependency>
     <dependency>
       <groupId>org.eclipse.jgit</groupId>
       <artifactId>org.eclipse.jgit.http.apache</artifactId>
-      <version>5.8.2-SNAPSHOT</version>
+      <version>5.9.1-SNAPSHOT</version>
     </dependency>
     <dependency>
       <groupId>org.eclipse.jgit</groupId>
       <artifactId>org.eclipse.jgit.http.server</artifactId>
-      <version>5.8.2-SNAPSHOT</version>
+      <version>5.9.1-SNAPSHOT</version>
     </dependency>
     <dependency>
       <groupId>org.eclipse.jgit</groupId>
       <artifactId>org.eclipse.jgit.lfs</artifactId>
-      <version>5.8.2-SNAPSHOT</version>
+      <version>5.9.1-SNAPSHOT</version>
     </dependency>
     <dependency>
       <groupId>org.eclipse.jgit</groupId>
       <artifactId>org.eclipse.jgit.lfs.server</artifactId>
-      <version>5.8.2-SNAPSHOT</version>
+      <version>5.9.1-SNAPSHOT</version>
     </dependency>
     <dependency>
       <groupId>org.eclipse.jgit</groupId>
       <artifactId>org.eclipse.jgit.pgm</artifactId>
-      <version>5.8.2-SNAPSHOT</version>
+      <version>5.9.1-SNAPSHOT</version>
     </dependency>
     <dependency>
       <groupId>org.eclipse.jgit</groupId>
       <artifactId>org.eclipse.jgit.ui</artifactId>
-      <version>5.8.2-SNAPSHOT</version>
+      <version>5.9.1-SNAPSHOT</version>
     </dependency>
     <dependency>
       <groupId>org.eclipse.jgit</groupId>
       <artifactId>org.eclipse.jgit.ssh.apache</artifactId>
-      <version>5.8.2-SNAPSHOT</version>
+      <version>5.9.1-SNAPSHOT</version>
     </dependency>
 
     <dependency>
       <groupId>org.eclipse.jgit</groupId>
       <artifactId>org.eclipse.jgit.test</artifactId>
-      <version>5.8.2-SNAPSHOT</version>
+      <version>5.9.1-SNAPSHOT</version>
     </dependency>
     <dependency>
       <groupId>org.eclipse.jgit</groupId>
       <artifactId>org.eclipse.jgit.ant.test</artifactId>
-      <version>5.8.2-SNAPSHOT</version>
+      <version>5.9.1-SNAPSHOT</version>
     </dependency>
     <dependency>
       <groupId>org.eclipse.jgit</groupId>
       <artifactId>org.eclipse.jgit.http.test</artifactId>
-      <version>5.8.2-SNAPSHOT</version>
+      <version>5.9.1-SNAPSHOT</version>
     </dependency>
     <dependency>
       <groupId>org.eclipse.jgit</groupId>
       <artifactId>org.eclipse.jgit.pgm.test</artifactId>
-      <version>5.8.2-SNAPSHOT</version>
+      <version>5.9.1-SNAPSHOT</version>
     </dependency>
     <dependency>
       <groupId>org.eclipse.jgit</groupId>
       <artifactId>org.eclipse.jgit.lfs.test</artifactId>
-      <version>5.8.2-SNAPSHOT</version>
+      <version>5.9.1-SNAPSHOT</version>
     </dependency>
     <dependency>
       <groupId>org.eclipse.jgit</groupId>
       <artifactId>org.eclipse.jgit.lfs.server.test</artifactId>
-      <version>5.8.2-SNAPSHOT</version>
+      <version>5.9.1-SNAPSHOT</version>
     </dependency>
     <dependency>
       <groupId>org.eclipse.jgit</groupId>
       <artifactId>org.eclipse.jgit.ssh.apache.test</artifactId>
-      <version>5.8.2-SNAPSHOT</version>
+      <version>5.9.1-SNAPSHOT</version>
     </dependency>
   </dependencies>
 
diff --git a/org.eclipse.jgit.gpg.bc.test/.settings/org.eclipse.jdt.core.prefs b/org.eclipse.jgit.gpg.bc.test/.settings/org.eclipse.jdt.core.prefs
index 822846c..d483c77 100644
--- a/org.eclipse.jgit.gpg.bc.test/.settings/org.eclipse.jdt.core.prefs
+++ b/org.eclipse.jgit.gpg.bc.test/.settings/org.eclipse.jdt.core.prefs
@@ -52,7 +52,7 @@
 org.eclipse.jdt.core.compiler.problem.missingJavadocCommentsOverriding=disabled
 org.eclipse.jdt.core.compiler.problem.missingJavadocCommentsVisibility=protected
 org.eclipse.jdt.core.compiler.problem.missingJavadocTagDescription=return_tag
-org.eclipse.jdt.core.compiler.problem.missingJavadocTags=error
+org.eclipse.jdt.core.compiler.problem.missingJavadocTags=ignore
 org.eclipse.jdt.core.compiler.problem.missingJavadocTagsMethodTypeParameters=disabled
 org.eclipse.jdt.core.compiler.problem.missingJavadocTagsOverriding=disabled
 org.eclipse.jdt.core.compiler.problem.missingJavadocTagsVisibility=private
diff --git a/org.eclipse.jgit.gpg.bc.test/META-INF/MANIFEST.MF b/org.eclipse.jgit.gpg.bc.test/META-INF/MANIFEST.MF
index 22ddf12..22ff017 100644
--- a/org.eclipse.jgit.gpg.bc.test/META-INF/MANIFEST.MF
+++ b/org.eclipse.jgit.gpg.bc.test/META-INF/MANIFEST.MF
@@ -3,11 +3,11 @@
 Bundle-Name: %Bundle-Name
 Automatic-Module-Name: org.eclipse.jgit.gpg.bc.test
 Bundle-SymbolicName: org.eclipse.jgit.gpg.bc.test
-Bundle-Version: 5.8.2.qualifier
+Bundle-Version: 5.9.1.qualifier
 Bundle-Vendor: %Bundle-Vendor
 Bundle-Localization: plugin
 Bundle-RequiredExecutionEnvironment: JavaSE-1.8
-Import-Package: org.eclipse.jgit.gpg.bc.internal;version="[5.8.2,5.9.0)",
+Import-Package: org.eclipse.jgit.gpg.bc.internal;version="[5.9.1,5.10.0)",
  org.junit;version="[4.13,5.0.0)"
 Export-Package: org.eclipse.jgit.gpg.bc.internal;x-internal:=true
 Require-Bundle: org.hamcrest.core;bundle-version="[1.1.0,2.0.0)",
diff --git a/org.eclipse.jgit.gpg.bc.test/pom.xml b/org.eclipse.jgit.gpg.bc.test/pom.xml
index 5c72775..780a273 100644
--- a/org.eclipse.jgit.gpg.bc.test/pom.xml
+++ b/org.eclipse.jgit.gpg.bc.test/pom.xml
@@ -17,7 +17,7 @@
   <parent>
     <groupId>org.eclipse.jgit</groupId>
     <artifactId>org.eclipse.jgit-parent</artifactId>
-    <version>5.8.2-SNAPSHOT</version>
+    <version>5.9.1-SNAPSHOT</version>
   </parent>
 
   <artifactId>org.eclipse.jgit.gpg.bc.test</artifactId>
diff --git a/org.eclipse.jgit.gpg.bc/META-INF/MANIFEST.MF b/org.eclipse.jgit.gpg.bc/META-INF/MANIFEST.MF
index 0e52068..544cf6f 100644
--- a/org.eclipse.jgit.gpg.bc/META-INF/MANIFEST.MF
+++ b/org.eclipse.jgit.gpg.bc/META-INF/MANIFEST.MF
@@ -3,10 +3,10 @@
 Bundle-Name: %Bundle-Name
 Automatic-Module-Name: org.eclipse.jgit.gpg.bc
 Bundle-SymbolicName: org.eclipse.jgit.gpg.bc;singleton:=true
-Fragment-Host: org.eclipse.jgit;bundle-version="[5.8.2,5.9.0)"
+Fragment-Host: org.eclipse.jgit;bundle-version="[5.9.1,5.10.0)"
 Bundle-Vendor: %Bundle-Vendor
 Bundle-Localization: plugin
-Bundle-Version: 5.8.2.qualifier
+Bundle-Version: 5.9.1.qualifier
 Bundle-RequiredExecutionEnvironment: JavaSE-1.8
 Import-Package: org.bouncycastle.bcpg;version="[1.65.0,2.0.0)",
  org.bouncycastle.gpg;version="[1.65.0,2.0.0)",
@@ -17,13 +17,13 @@
  org.bouncycastle.openpgp.operator;version="[1.65.0,2.0.0)",
  org.bouncycastle.openpgp.operator.jcajce;version="[1.65.0,2.0.0)",
  org.bouncycastle.util.encoders;version="[1.65.0,2.0.0)",
- org.eclipse.jgit.annotations;version="[5.8.2,5.9.0)",
- org.eclipse.jgit.api.errors;version="[5.8.2,5.9.0)",
- org.eclipse.jgit.errors;version="[5.8.2,5.9.0)",
- org.eclipse.jgit.lib;version="[5.8.2,5.9.0)",
- org.eclipse.jgit.nls;version="[5.8.2,5.9.0)",
- org.eclipse.jgit.transport;version="[5.8.2,5.9.0)",
- org.eclipse.jgit.util;version="[5.8.2,5.9.0)",
+ org.eclipse.jgit.annotations;version="[5.9.1,5.10.0)",
+ org.eclipse.jgit.api.errors;version="[5.9.1,5.10.0)",
+ org.eclipse.jgit.errors;version="[5.9.1,5.10.0)",
+ org.eclipse.jgit.lib;version="[5.9.1,5.10.0)",
+ org.eclipse.jgit.nls;version="[5.9.1,5.10.0)",
+ org.eclipse.jgit.transport;version="[5.9.1,5.10.0)",
+ org.eclipse.jgit.util;version="[5.9.1,5.10.0)",
  org.slf4j;version="[1.7.0,2.0.0)"
-Export-Package: org.eclipse.jgit.gpg.bc.internal;version="5.8.2";
+Export-Package: org.eclipse.jgit.gpg.bc.internal;version="5.9.1";
   x-friends:="org.eclipse.jgit.gpg.bc.test"
diff --git a/org.eclipse.jgit.gpg.bc/META-INF/SOURCE-MANIFEST.MF b/org.eclipse.jgit.gpg.bc/META-INF/SOURCE-MANIFEST.MF
index cbdd793..5a44e2a 100644
--- a/org.eclipse.jgit.gpg.bc/META-INF/SOURCE-MANIFEST.MF
+++ b/org.eclipse.jgit.gpg.bc/META-INF/SOURCE-MANIFEST.MF
@@ -3,5 +3,5 @@
 Bundle-Name: org.eclipse.jgit.gpg.bc - Sources
 Bundle-SymbolicName: org.eclipse.jgit.gpg.bc.source
 Bundle-Vendor: Eclipse.org - JGit
-Bundle-Version: 5.8.2.qualifier
-Eclipse-SourceBundle: org.eclipse.jgit.gpg.bc;version="5.8.2.qualifier";roots="."
+Bundle-Version: 5.9.1.qualifier
+Eclipse-SourceBundle: org.eclipse.jgit.gpg.bc;version="5.9.1.qualifier";roots="."
diff --git a/org.eclipse.jgit.gpg.bc/pom.xml b/org.eclipse.jgit.gpg.bc/pom.xml
index 1b443b8..9b09db5 100644
--- a/org.eclipse.jgit.gpg.bc/pom.xml
+++ b/org.eclipse.jgit.gpg.bc/pom.xml
@@ -17,7 +17,7 @@
   <parent>
     <groupId>org.eclipse.jgit</groupId>
     <artifactId>org.eclipse.jgit-parent</artifactId>
-    <version>5.8.2-SNAPSHOT</version>
+    <version>5.9.1-SNAPSHOT</version>
   </parent>
 
   <artifactId>org.eclipse.jgit.gpg.bc</artifactId>
@@ -128,7 +128,6 @@
         </configuration>
       </plugin>
 
-      <!-- No previous version to compare to
       <plugin>
           <groupId>com.github.siom79.japicmp</groupId>
           <artifactId>japicmp-maven-plugin</artifactId>
@@ -170,13 +169,11 @@
           </execution>
         </executions>
       </plugin>
-      -->
     </plugins>
   </build>
 
   <reporting>
     <plugins>
-      <!-- No previous version to compare to
       <plugin>
           <groupId>com.github.siom79.japicmp</groupId>
           <artifactId>japicmp-maven-plugin</artifactId>
@@ -217,7 +214,6 @@
               <skip>false</skip>
           </configuration>
       </plugin>
-      -->
     </plugins>
   </reporting>
 </project>
diff --git a/org.eclipse.jgit.gpg.bc/src/org/eclipse/jgit/gpg/bc/internal/BouncyCastleGpgSigner.java b/org.eclipse.jgit.gpg.bc/src/org/eclipse/jgit/gpg/bc/internal/BouncyCastleGpgSigner.java
index c6ecdbe..ea159c5 100644
--- a/org.eclipse.jgit.gpg.bc/src/org/eclipse/jgit/gpg/bc/internal/BouncyCastleGpgSigner.java
+++ b/org.eclipse.jgit.gpg.bc/src/org/eclipse/jgit/gpg/bc/internal/BouncyCastleGpgSigner.java
@@ -15,6 +15,7 @@
 import java.security.NoSuchAlgorithmException;
 import java.security.NoSuchProviderException;
 import java.security.Security;
+import java.util.Iterator;
 
 import org.bouncycastle.bcpg.ArmoredOutputStream;
 import org.bouncycastle.bcpg.BCPGOutputStream;
@@ -22,6 +23,7 @@
 import org.bouncycastle.jce.provider.BouncyCastleProvider;
 import org.bouncycastle.openpgp.PGPException;
 import org.bouncycastle.openpgp.PGPPrivateKey;
+import org.bouncycastle.openpgp.PGPPublicKey;
 import org.bouncycastle.openpgp.PGPSecretKey;
 import org.bouncycastle.openpgp.PGPSignature;
 import org.bouncycastle.openpgp.PGPSignatureGenerator;
@@ -38,6 +40,7 @@
 import org.eclipse.jgit.lib.GpgSigner;
 import org.eclipse.jgit.lib.PersonIdent;
 import org.eclipse.jgit.transport.CredentialsProvider;
+import org.eclipse.jgit.util.StringUtils;
 
 /**
  * GPG Signer using BouncyCastle library
@@ -126,17 +129,32 @@
 				privateKey = secretKey
 						.extractPrivateKey(decryptorBuilder.build(passphrase));
 			}
+			PGPPublicKey publicKey = secretKey.getPublicKey();
 			PGPSignatureGenerator signatureGenerator = new PGPSignatureGenerator(
 					new JcaPGPContentSignerBuilder(
-							secretKey.getPublicKey().getAlgorithm(),
+							publicKey.getAlgorithm(),
 							HashAlgorithmTags.SHA256).setProvider(
 									BouncyCastleProvider.PROVIDER_NAME));
 			signatureGenerator.init(PGPSignature.BINARY_DOCUMENT, privateKey);
-			PGPSignatureSubpacketGenerator subpacketGenerator = new PGPSignatureSubpacketGenerator();
-			subpacketGenerator.setIssuerFingerprint(false,
-					secretKey.getPublicKey());
+			PGPSignatureSubpacketGenerator subpackets = new PGPSignatureSubpacketGenerator();
+			subpackets.setIssuerFingerprint(false, publicKey);
+			// Also add the signer's user ID. Note that GPG uses only the e-mail
+			// address part.
+			String userId = committer.getEmailAddress();
+			Iterator<String> userIds = publicKey.getUserIDs();
+			if (userIds.hasNext()) {
+				String keyUserId = userIds.next();
+				if (!StringUtils.isEmptyOrNull(keyUserId)
+						&& (userId == null || !keyUserId.contains(userId))) {
+					// Not the committer's key?
+					userId = extractSignerId(keyUserId);
+				}
+			}
+			if (userId != null) {
+				subpackets.setSignerUserID(false, userId);
+			}
 			signatureGenerator
-					.setHashedSubpackets(subpacketGenerator.generate());
+					.setHashedSubpackets(subpackets.generate());
 			ByteArrayOutputStream buffer = new ByteArrayOutputStream();
 			try (BCPGOutputStream out = new BCPGOutputStream(
 					new ArmoredOutputStream(buffer))) {
@@ -149,4 +167,15 @@
 			throw new JGitInternalException(e.getMessage(), e);
 		}
 	}
+
+	private String extractSignerId(String pgpUserId) {
+		int from = pgpUserId.indexOf('<');
+		if (from >= 0) {
+			int to = pgpUserId.indexOf('>', from + 1);
+			if (to > from + 1) {
+				return pgpUserId.substring(from + 1, to);
+			}
+		}
+		return pgpUserId;
+	}
 }
diff --git a/org.eclipse.jgit.http.apache/META-INF/MANIFEST.MF b/org.eclipse.jgit.http.apache/META-INF/MANIFEST.MF
index 840168b..944d27a 100644
--- a/org.eclipse.jgit.http.apache/META-INF/MANIFEST.MF
+++ b/org.eclipse.jgit.http.apache/META-INF/MANIFEST.MF
@@ -3,7 +3,7 @@
 Bundle-Name: %Bundle-Name
 Automatic-Module-Name: org.eclipse.jgit.http.apache
 Bundle-SymbolicName: org.eclipse.jgit.http.apache
-Bundle-Version: 5.8.2.qualifier
+Bundle-Version: 5.9.1.qualifier
 Bundle-RequiredExecutionEnvironment: JavaSE-1.8
 Bundle-Localization: plugin
 Bundle-Vendor: %Bundle-Vendor
@@ -25,11 +25,11 @@
  org.apache.http.impl.conn;version="[4.3.0,5.0.0)",
  org.apache.http.params;version="[4.3.0,5.0.0)",
  org.apache.http.ssl;version="[4.3.0,5.0.0)",
- org.eclipse.jgit.annotations;version="[5.8.2,5.9.0)",
- org.eclipse.jgit.nls;version="[5.8.2,5.9.0)",
- org.eclipse.jgit.transport.http;version="[5.8.2,5.9.0)",
- org.eclipse.jgit.util;version="[5.8.2,5.9.0)"
-Export-Package: org.eclipse.jgit.transport.http.apache;version="5.8.2";
+ org.eclipse.jgit.annotations;version="[5.9.1,5.10.0)",
+ org.eclipse.jgit.nls;version="[5.9.1,5.10.0)",
+ org.eclipse.jgit.transport.http;version="[5.9.1,5.10.0)",
+ org.eclipse.jgit.util;version="[5.9.1,5.10.0)"
+Export-Package: org.eclipse.jgit.transport.http.apache;version="5.9.1";
   uses:="org.apache.http.client,
    org.eclipse.jgit.transport.http,
    org.apache.http.entity,
diff --git a/org.eclipse.jgit.http.apache/META-INF/SOURCE-MANIFEST.MF b/org.eclipse.jgit.http.apache/META-INF/SOURCE-MANIFEST.MF
index 81036a7..1569ae7 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.8.2.qualifier
-Eclipse-SourceBundle: org.eclipse.jgit.http.apache;version="5.8.2.qualifier";roots="."
+Bundle-Version: 5.9.1.qualifier
+Eclipse-SourceBundle: org.eclipse.jgit.http.apache;version="5.9.1.qualifier";roots="."
diff --git a/org.eclipse.jgit.http.apache/pom.xml b/org.eclipse.jgit.http.apache/pom.xml
index 633fd85..26d0eae 100644
--- a/org.eclipse.jgit.http.apache/pom.xml
+++ b/org.eclipse.jgit.http.apache/pom.xml
@@ -15,7 +15,7 @@
   <parent>
     <groupId>org.eclipse.jgit</groupId>
     <artifactId>org.eclipse.jgit-parent</artifactId>
-    <version>5.8.2-SNAPSHOT</version>
+    <version>5.9.1-SNAPSHOT</version>
   </parent>
 
   <artifactId>org.eclipse.jgit.http.apache</artifactId>
diff --git a/org.eclipse.jgit.http.server/META-INF/MANIFEST.MF b/org.eclipse.jgit.http.server/META-INF/MANIFEST.MF
index b3d519e..c966c45 100644
--- a/org.eclipse.jgit.http.server/META-INF/MANIFEST.MF
+++ b/org.eclipse.jgit.http.server/META-INF/MANIFEST.MF
@@ -3,13 +3,13 @@
 Bundle-Name: %Bundle-Name
 Automatic-Module-Name: org.eclipse.jgit.http.server
 Bundle-SymbolicName: org.eclipse.jgit.http.server
-Bundle-Version: 5.8.2.qualifier
+Bundle-Version: 5.9.1.qualifier
 Bundle-Localization: plugin
 Bundle-Vendor: %Bundle-Vendor
-Export-Package: org.eclipse.jgit.http.server;version="5.8.2",
- org.eclipse.jgit.http.server.glue;version="5.8.2";
+Export-Package: org.eclipse.jgit.http.server;version="5.9.1",
+ org.eclipse.jgit.http.server.glue;version="5.9.1";
   uses:="javax.servlet,javax.servlet.http",
- org.eclipse.jgit.http.server.resolver;version="5.8.2";
+ org.eclipse.jgit.http.server.resolver;version="5.9.1";
   uses:="org.eclipse.jgit.transport.resolver,
    org.eclipse.jgit.lib,
    org.eclipse.jgit.transport,
@@ -18,14 +18,14 @@
 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.annotations;version="[5.8.2,5.9.0)",
- org.eclipse.jgit.errors;version="[5.8.2,5.9.0)",
- org.eclipse.jgit.internal.storage.dfs;version="[5.8.2,5.9.0)",
- org.eclipse.jgit.internal.storage.file;version="[5.8.2,5.9.0)",
- org.eclipse.jgit.internal.transport.parser;version="[5.8.2,5.9.0)",
- org.eclipse.jgit.lib;version="[5.8.2,5.9.0)",
- org.eclipse.jgit.nls;version="[5.8.2,5.9.0)",
- org.eclipse.jgit.revwalk;version="[5.8.2,5.9.0)",
- org.eclipse.jgit.transport;version="[5.8.2,5.9.0)",
- org.eclipse.jgit.transport.resolver;version="[5.8.2,5.9.0)",
- org.eclipse.jgit.util;version="[5.8.2,5.9.0)"
+ org.eclipse.jgit.annotations;version="[5.9.1,5.10.0)",
+ org.eclipse.jgit.errors;version="[5.9.1,5.10.0)",
+ org.eclipse.jgit.internal.storage.dfs;version="[5.9.1,5.10.0)",
+ org.eclipse.jgit.internal.storage.file;version="[5.9.1,5.10.0)",
+ org.eclipse.jgit.internal.transport.parser;version="[5.9.1,5.10.0)",
+ org.eclipse.jgit.lib;version="[5.9.1,5.10.0)",
+ org.eclipse.jgit.nls;version="[5.9.1,5.10.0)",
+ org.eclipse.jgit.revwalk;version="[5.9.1,5.10.0)",
+ org.eclipse.jgit.transport;version="[5.9.1,5.10.0)",
+ org.eclipse.jgit.transport.resolver;version="[5.9.1,5.10.0)",
+ org.eclipse.jgit.util;version="[5.9.1,5.10.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 f49fa58..bdbbf89 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.8.2.qualifier
-Eclipse-SourceBundle: org.eclipse.jgit.http.server;version="5.8.2.qualifier";roots="."
+Bundle-Version: 5.9.1.qualifier
+Eclipse-SourceBundle: org.eclipse.jgit.http.server;version="5.9.1.qualifier";roots="."
diff --git a/org.eclipse.jgit.http.server/pom.xml b/org.eclipse.jgit.http.server/pom.xml
index 26fac62..572fd4b 100644
--- a/org.eclipse.jgit.http.server/pom.xml
+++ b/org.eclipse.jgit.http.server/pom.xml
@@ -19,7 +19,7 @@
   <parent>
     <groupId>org.eclipse.jgit</groupId>
     <artifactId>org.eclipse.jgit-parent</artifactId>
-    <version>5.8.2-SNAPSHOT</version>
+    <version>5.9.1-SNAPSHOT</version>
   </parent>
 
   <artifactId>org.eclipse.jgit.http.server</artifactId>
diff --git a/org.eclipse.jgit.http.test/.settings/org.eclipse.jdt.core.prefs b/org.eclipse.jgit.http.test/.settings/org.eclipse.jdt.core.prefs
index 3dd5840..4c4634a 100644
--- a/org.eclipse.jgit.http.test/.settings/org.eclipse.jdt.core.prefs
+++ b/org.eclipse.jgit.http.test/.settings/org.eclipse.jdt.core.prefs
@@ -52,7 +52,7 @@
 org.eclipse.jdt.core.compiler.problem.missingJavadocCommentsOverriding=disabled
 org.eclipse.jdt.core.compiler.problem.missingJavadocCommentsVisibility=protected
 org.eclipse.jdt.core.compiler.problem.missingJavadocTagDescription=return_tag
-org.eclipse.jdt.core.compiler.problem.missingJavadocTags=error
+org.eclipse.jdt.core.compiler.problem.missingJavadocTags=ignore
 org.eclipse.jdt.core.compiler.problem.missingJavadocTagsMethodTypeParameters=disabled
 org.eclipse.jdt.core.compiler.problem.missingJavadocTagsOverriding=disabled
 org.eclipse.jdt.core.compiler.problem.missingJavadocTagsVisibility=private
diff --git a/org.eclipse.jgit.http.test/META-INF/MANIFEST.MF b/org.eclipse.jgit.http.test/META-INF/MANIFEST.MF
index 8037a80..52e4bed 100644
--- a/org.eclipse.jgit.http.test/META-INF/MANIFEST.MF
+++ b/org.eclipse.jgit.http.test/META-INF/MANIFEST.MF
@@ -3,7 +3,7 @@
 Bundle-Name: %Bundle-Name
 Automatic-Module-Name: org.eclipse.jgit.http.test
 Bundle-SymbolicName: org.eclipse.jgit.http.test
-Bundle-Version: 5.8.2.qualifier
+Bundle-Version: 5.9.1.qualifier
 Bundle-Vendor: %Bundle-Vendor
 Bundle-Localization: plugin
 Bundle-RequiredExecutionEnvironment: JavaSE-1.8
@@ -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.8.2,5.9.0)",
- org.eclipse.jgit.http.server;version="[5.8.2,5.9.0)",
- org.eclipse.jgit.http.server.glue;version="[5.8.2,5.9.0)",
- org.eclipse.jgit.http.server.resolver;version="[5.8.2,5.9.0)",
- org.eclipse.jgit.internal;version="[5.8.2,5.9.0)",
- org.eclipse.jgit.internal.storage.dfs;version="[5.8.2,5.9.0)",
- org.eclipse.jgit.internal.storage.file;version="[5.8.2,5.9.0)",
- org.eclipse.jgit.internal.storage.reftable;version="[5.8.2,5.9.0)",
- org.eclipse.jgit.junit;version="[5.8.2,5.9.0)",
- org.eclipse.jgit.junit.http;version="[5.8.2,5.9.0)",
- org.eclipse.jgit.lib;version="[5.8.2,5.9.0)",
- org.eclipse.jgit.nls;version="[5.8.2,5.9.0)",
- org.eclipse.jgit.revwalk;version="[5.8.2,5.9.0)",
- org.eclipse.jgit.storage.file;version="[5.8.2,5.9.0)",
- org.eclipse.jgit.transport;version="[5.8.2,5.9.0)",
- org.eclipse.jgit.transport.http;version="[5.8.2,5.9.0)",
- org.eclipse.jgit.transport.http.apache;version="[5.8.2,5.9.0)",
- org.eclipse.jgit.transport.resolver;version="[5.8.2,5.9.0)",
- org.eclipse.jgit.util;version="[5.8.2,5.9.0)",
+ org.eclipse.jgit.errors;version="[5.9.1,5.10.0)",
+ org.eclipse.jgit.http.server;version="[5.9.1,5.10.0)",
+ org.eclipse.jgit.http.server.glue;version="[5.9.1,5.10.0)",
+ org.eclipse.jgit.http.server.resolver;version="[5.9.1,5.10.0)",
+ org.eclipse.jgit.internal;version="[5.9.1,5.10.0)",
+ org.eclipse.jgit.internal.storage.dfs;version="[5.9.1,5.10.0)",
+ org.eclipse.jgit.internal.storage.file;version="[5.9.1,5.10.0)",
+ org.eclipse.jgit.internal.storage.reftable;version="[5.9.1,5.10.0)",
+ org.eclipse.jgit.junit;version="[5.9.1,5.10.0)",
+ org.eclipse.jgit.junit.http;version="[5.9.1,5.10.0)",
+ org.eclipse.jgit.lib;version="[5.9.1,5.10.0)",
+ org.eclipse.jgit.nls;version="[5.9.1,5.10.0)",
+ org.eclipse.jgit.revwalk;version="[5.9.1,5.10.0)",
+ org.eclipse.jgit.storage.file;version="[5.9.1,5.10.0)",
+ org.eclipse.jgit.transport;version="[5.9.1,5.10.0)",
+ org.eclipse.jgit.transport.http;version="[5.9.1,5.10.0)",
+ org.eclipse.jgit.transport.http.apache;version="[5.9.1,5.10.0)",
+ org.eclipse.jgit.transport.resolver;version="[5.9.1,5.10.0)",
+ org.eclipse.jgit.util;version="[5.9.1,5.10.0)",
  org.hamcrest;version="[1.1.0,2.0.0)",
  org.hamcrest.core;version="[1.1.0,2.0.0)",
  org.junit;version="[4.13,5.0.0)",
diff --git a/org.eclipse.jgit.http.test/pom.xml b/org.eclipse.jgit.http.test/pom.xml
index fdb3ada..6c259e6 100644
--- a/org.eclipse.jgit.http.test/pom.xml
+++ b/org.eclipse.jgit.http.test/pom.xml
@@ -18,7 +18,7 @@
   <parent>
     <groupId>org.eclipse.jgit</groupId>
     <artifactId>org.eclipse.jgit-parent</artifactId>
-    <version>5.8.2-SNAPSHOT</version>
+    <version>5.9.1-SNAPSHOT</version>
   </parent>
 
   <artifactId>org.eclipse.jgit.http.test</artifactId>
diff --git a/org.eclipse.jgit.http.test/tst/org/eclipse/jgit/http/test/HttpClientTests.java b/org.eclipse.jgit.http.test/tst/org/eclipse/jgit/http/test/HttpClientTests.java
index 9665776..26a453b 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
@@ -38,6 +38,7 @@
 import org.eclipse.jgit.junit.TestRepository;
 import org.eclipse.jgit.junit.http.AccessEvent;
 import org.eclipse.jgit.junit.http.AppServer;
+import org.eclipse.jgit.lib.ConfigConstants;
 import org.eclipse.jgit.lib.Constants;
 import org.eclipse.jgit.lib.Ref;
 import org.eclipse.jgit.lib.RefUpdate;
@@ -49,6 +50,7 @@
 import org.eclipse.jgit.transport.PacketLineIn;
 import org.eclipse.jgit.transport.PacketLineOut;
 import org.eclipse.jgit.transport.Transport;
+import org.eclipse.jgit.transport.TransferConfig;
 import org.eclipse.jgit.transport.URIish;
 import org.eclipse.jgit.transport.UsernamePasswordCredentialsProvider;
 import org.eclipse.jgit.transport.http.HttpConnection;
@@ -342,8 +344,10 @@
 
 	@Test
 	public void testV2HttpFirstResponse() throws Exception {
-		remoteRepository.getRepository().getConfig().setInt(
-				"protocol", null, "version", 2);
+		remoteRepository.getRepository().getConfig().setString(
+				ConfigConstants.CONFIG_PROTOCOL_SECTION, null,
+				ConfigConstants.CONFIG_KEY_VERSION,
+				TransferConfig.ProtocolVersion.V2.version());
 
 		String url = smartAuthNoneURI.toString() + "/info/refs?service=git-upload-pack";
 		HttpConnection c = HttpTransport.getConnectionFactory()
@@ -364,8 +368,10 @@
 
 	@Test
 	public void testV2HttpSubsequentResponse() throws Exception {
-		remoteRepository.getRepository().getConfig().setInt(
-				"protocol", null, "version", 2);
+		remoteRepository.getRepository().getConfig().setString(
+				ConfigConstants.CONFIG_PROTOCOL_SECTION, null,
+				ConfigConstants.CONFIG_KEY_VERSION,
+				TransferConfig.ProtocolVersion.V2.version());
 
 		String url = smartAuthNoneURI.toString() + "/git-upload-pack";
 		HttpConnection c = HttpTransport.getConnectionFactory()
diff --git a/org.eclipse.jgit.junit.http/META-INF/MANIFEST.MF b/org.eclipse.jgit.junit.http/META-INF/MANIFEST.MF
index 00272e5..9654c91 100644
--- a/org.eclipse.jgit.junit.http/META-INF/MANIFEST.MF
+++ b/org.eclipse.jgit.junit.http/META-INF/MANIFEST.MF
@@ -3,7 +3,7 @@
 Bundle-Name: %Bundle-Name
 Automatic-Module-Name: org.eclipse.jgit.junit.http
 Bundle-SymbolicName: org.eclipse.jgit.junit.http
-Bundle-Version: 5.8.2.qualifier
+Bundle-Version: 5.9.1.qualifier
 Bundle-Localization: plugin
 Bundle-Vendor: %Bundle-Vendor
 Bundle-ActivationPolicy: lazy
@@ -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.8.2,5.9.0)",
- org.eclipse.jgit.http.server;version="[5.8.2,5.9.0)",
- org.eclipse.jgit.internal.storage.file;version="[5.8.2,5.9.0)",
- org.eclipse.jgit.junit;version="[5.8.2,5.9.0)",
- org.eclipse.jgit.lib;version="[5.8.2,5.9.0)",
- org.eclipse.jgit.revwalk;version="[5.8.2,5.9.0)",
- org.eclipse.jgit.transport;version="[5.8.2,5.9.0)",
- org.eclipse.jgit.transport.resolver;version="[5.8.2,5.9.0)",
+ org.eclipse.jgit.errors;version="[5.9.1,5.10.0)",
+ org.eclipse.jgit.http.server;version="[5.9.1,5.10.0)",
+ org.eclipse.jgit.internal.storage.file;version="[5.9.1,5.10.0)",
+ org.eclipse.jgit.junit;version="[5.9.1,5.10.0)",
+ org.eclipse.jgit.lib;version="[5.9.1,5.10.0)",
+ org.eclipse.jgit.revwalk;version="[5.9.1,5.10.0)",
+ org.eclipse.jgit.transport;version="[5.9.1,5.10.0)",
+ org.eclipse.jgit.transport.resolver;version="[5.9.1,5.10.0)",
  org.junit;version="[4.13,5.0.0)"
-Export-Package: org.eclipse.jgit.junit.http;version="5.8.2";
+Export-Package: org.eclipse.jgit.junit.http;version="5.9.1";
   uses:="org.eclipse.jgit.transport,
    org.eclipse.jgit.junit,
    javax.servlet.http,
diff --git a/org.eclipse.jgit.junit.http/META-INF/SOURCE-MANIFEST.MF b/org.eclipse.jgit.junit.http/META-INF/SOURCE-MANIFEST.MF
index 317623b..8732283 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.8.2.qualifier
-Eclipse-SourceBundle: org.eclipse.jgit.junit.http;version="5.8.2.qualifier";roots="."
+Bundle-Version: 5.9.1.qualifier
+Eclipse-SourceBundle: org.eclipse.jgit.junit.http;version="5.9.1.qualifier";roots="."
diff --git a/org.eclipse.jgit.junit.http/pom.xml b/org.eclipse.jgit.junit.http/pom.xml
index 04fd751..e7193e6 100644
--- a/org.eclipse.jgit.junit.http/pom.xml
+++ b/org.eclipse.jgit.junit.http/pom.xml
@@ -17,7 +17,7 @@
   <parent>
     <groupId>org.eclipse.jgit</groupId>
     <artifactId>org.eclipse.jgit-parent</artifactId>
-    <version>5.8.2-SNAPSHOT</version>
+    <version>5.9.1-SNAPSHOT</version>
   </parent>
 
   <artifactId>org.eclipse.jgit.junit.http</artifactId>
diff --git a/org.eclipse.jgit.junit.ssh/BUILD b/org.eclipse.jgit.junit.ssh/BUILD
index 61b5ce7..f7856b5 100644
--- a/org.eclipse.jgit.junit.ssh/BUILD
+++ b/org.eclipse.jgit.junit.ssh/BUILD
@@ -13,8 +13,8 @@
         "//org.eclipse.jgit.ssh.jsch.test:__pkg__",
     ],
     deps = [
-        "//lib:jsch",
         "//lib:junit",
+        "//lib:slf4j-api",
         "//lib:sshd-osgi",
         "//lib:sshd-sftp",
         # We want these deps to be provided_deps
diff --git a/org.eclipse.jgit.junit.ssh/META-INF/MANIFEST.MF b/org.eclipse.jgit.junit.ssh/META-INF/MANIFEST.MF
index 4b99dba..4e78d61 100644
--- a/org.eclipse.jgit.junit.ssh/META-INF/MANIFEST.MF
+++ b/org.eclipse.jgit.junit.ssh/META-INF/MANIFEST.MF
@@ -3,13 +3,12 @@
 Bundle-Name: %Bundle-Name
 Automatic-Module-Name: org.eclipse.jgit.junit.ssh
 Bundle-SymbolicName: org.eclipse.jgit.junit.ssh
-Bundle-Version: 5.8.2.qualifier
+Bundle-Version: 5.9.1.qualifier
 Bundle-Localization: plugin
 Bundle-Vendor: %Bundle-Vendor
 Bundle-ActivationPolicy: lazy
 Bundle-RequiredExecutionEnvironment: JavaSE-1.8
-Import-Package: com.jcraft.jsch;version="0.1.55",
- org.apache.sshd.common;version="[2.4.0,2.5.0)",
+Import-Package: org.apache.sshd.common;version="[2.4.0,2.5.0)",
  org.apache.sshd.common.config.keys;version="[2.4.0,2.5.0)",
  org.apache.sshd.common.file.virtualfs;version="[2.4.0,2.5.0)",
  org.apache.sshd.common.helpers;version="[2.4.0,2.5.0)",
@@ -31,16 +30,16 @@
  org.apache.sshd.server.shell;version="[2.4.0,2.5.0)",
  org.apache.sshd.server.subsystem;version="[2.4.0,2.5.0)",
  org.apache.sshd.server.subsystem.sftp;version="[2.4.0,2.5.0)",
- org.eclipse.jgit.annotations;version="[5.8.2,5.9.0)",
- org.eclipse.jgit.api;version="[5.8.2,5.9.0)",
- org.eclipse.jgit.api.errors;version="[5.8.2,5.9.0)",
- org.eclipse.jgit.errors;version="[5.8.2,5.9.0)",
- org.eclipse.jgit.junit;version="[5.8.2,5.9.0)",
- org.eclipse.jgit.lib;version="[5.8.2,5.9.0)",
- org.eclipse.jgit.revwalk;version="[5.8.2,5.9.0)",
- org.eclipse.jgit.transport;version="[5.8.2,5.9.0)",
- org.eclipse.jgit.util;version="[5.8.2,5.9.0)",
+ org.eclipse.jgit.annotations;version="[5.9.1,5.10.0)",
+ org.eclipse.jgit.api;version="[5.9.1,5.10.0)",
+ org.eclipse.jgit.api.errors;version="[5.9.1,5.10.0)",
+ org.eclipse.jgit.errors;version="[5.9.1,5.10.0)",
+ org.eclipse.jgit.junit;version="[5.9.1,5.10.0)",
+ org.eclipse.jgit.lib;version="[5.9.1,5.10.0)",
+ org.eclipse.jgit.revwalk;version="[5.9.1,5.10.0)",
+ org.eclipse.jgit.transport;version="[5.9.1,5.10.0)",
+ org.eclipse.jgit.util;version="[5.9.1,5.10.0)",
  org.junit;version="[4.13,5.0.0)",
  org.junit.experimental.theories;version="[4.13,5.0.0)",
  org.slf4j;version="[1.7.0,2.0.0)"
-Export-Package: org.eclipse.jgit.junit.ssh;version="5.8.2"
+Export-Package: org.eclipse.jgit.junit.ssh;version="5.9.1"
diff --git a/org.eclipse.jgit.junit.ssh/META-INF/SOURCE-MANIFEST.MF b/org.eclipse.jgit.junit.ssh/META-INF/SOURCE-MANIFEST.MF
index 9f099bc..7ec99eb 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.8.2.qualifier
-Eclipse-SourceBundle: org.eclipse.jgit.junit.ssh;version="5.8.2.qualifier";roots="."
+Bundle-Version: 5.9.1.qualifier
+Eclipse-SourceBundle: org.eclipse.jgit.junit.ssh;version="5.9.1.qualifier";roots="."
diff --git a/org.eclipse.jgit.junit.ssh/pom.xml b/org.eclipse.jgit.junit.ssh/pom.xml
index 15fc1b0..a1e635b 100644
--- a/org.eclipse.jgit.junit.ssh/pom.xml
+++ b/org.eclipse.jgit.junit.ssh/pom.xml
@@ -17,7 +17,7 @@
   <parent>
     <groupId>org.eclipse.jgit</groupId>
     <artifactId>org.eclipse.jgit-parent</artifactId>
-    <version>5.8.2-SNAPSHOT</version>
+    <version>5.9.1-SNAPSHOT</version>
   </parent>
 
   <artifactId>org.eclipse.jgit.junit.ssh</artifactId>
@@ -58,16 +58,6 @@
     </dependency>
 
     <dependency>
-      <groupId>com.jcraft</groupId>
-      <artifactId>jsch</artifactId>
-    </dependency>
-
-    <dependency>
-      <groupId>com.jcraft</groupId>
-      <artifactId>jzlib</artifactId>
-    </dependency>
-
-    <dependency>
       <groupId>junit</groupId>
       <artifactId>junit</artifactId>
       <scope>provided</scope>
diff --git a/org.eclipse.jgit.junit.ssh/src/org/eclipse/jgit/junit/ssh/SshTestBase.java b/org.eclipse.jgit.junit.ssh/src/org/eclipse/jgit/junit/ssh/SshTestBase.java
index 2d284cf..3784741 100644
--- a/org.eclipse.jgit.junit.ssh/src/org/eclipse/jgit/junit/ssh/SshTestBase.java
+++ b/org.eclipse.jgit.junit.ssh/src/org/eclipse/jgit/junit/ssh/SshTestBase.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2018, Thomas Wolf <thomas.wolf@paranor.ch> and others
+ * Copyright (C) 2018, 2020 Thomas Wolf <thomas.wolf@paranor.ch> and others
  *
  * This program and the accompanying materials are made available under the
  * terms of the Eclipse Distribution License v. 1.0 which is available at
@@ -14,6 +14,7 @@
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertFalse;
 import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertThrows;
 import static org.junit.Assert.assertTrue;
 import static org.junit.Assume.assumeTrue;
 
@@ -22,9 +23,14 @@
 import java.nio.file.Files;
 import java.util.List;
 import java.util.Locale;
+import java.util.concurrent.TimeUnit;
 
 import org.eclipse.jgit.api.errors.TransportException;
+import org.eclipse.jgit.errors.CommandFailedException;
 import org.eclipse.jgit.transport.CredentialItem;
+import org.eclipse.jgit.transport.URIish;
+import org.eclipse.jgit.util.FS;
+import org.eclipse.jgit.util.SshSupport;
 import org.junit.Test;
 import org.junit.experimental.theories.DataPoints;
 import org.junit.experimental.theories.Theory;
@@ -67,10 +73,45 @@
 		defaultCloneDir = new File(getTemporaryDirectory(), "cloned");
 	}
 
-	@Test(expected = TransportException.class)
+	@Test
 	public void testSshWithoutConfig() throws Exception {
-		cloneWith("ssh://" + TEST_USER + "@localhost:" + testPort
-				+ "/doesntmatter", defaultCloneDir, null);
+		assertThrows(TransportException.class,
+				() -> cloneWith("ssh://" + TEST_USER + "@localhost:" + testPort
+						+ "/doesntmatter", defaultCloneDir, null));
+	}
+
+	@Test
+	public void testSingleCommand() throws Exception {
+		installConfig("IdentityFile " + privateKey1.getAbsolutePath());
+		String command = SshTestGitServer.ECHO_COMMAND + " 1 without timeout";
+		long start = System.nanoTime();
+		String reply = SshSupport.runSshCommand(
+				new URIish("ssh://" + TEST_USER + "@localhost:" + testPort),
+				null, FS.DETECTED, command, 0); // 0 == no timeout
+		long elapsed = System.nanoTime() - start;
+		assertEquals(command, reply);
+		// Now that we have an idea how long this takes on the test
+		// infrastructure, try again with a timeout.
+		command = SshTestGitServer.ECHO_COMMAND + " 1 expecting no timeout";
+		// Still use a generous timeout.
+		int timeout = 10 * ((int) TimeUnit.NANOSECONDS.toSeconds(elapsed) + 1);
+		reply = SshSupport.runSshCommand(
+				new URIish("ssh://" + TEST_USER + "@localhost:" + testPort),
+				null, FS.DETECTED, command, timeout);
+		assertEquals(command, reply);
+	}
+
+	@Test
+	public void testSingleCommandWithTimeoutExpired() throws Exception {
+		installConfig("IdentityFile " + privateKey1.getAbsolutePath());
+		String command = SshTestGitServer.ECHO_COMMAND + " 2 EXPECTING TIMEOUT";
+
+		CommandFailedException e = assertThrows(CommandFailedException.class,
+				() -> SshSupport.runSshCommand(new URIish(
+						"ssh://" + TEST_USER + "@localhost:" + testPort), null,
+						FS.DETECTED, command, 1));
+		assertTrue(e.getMessage().contains(command));
+		assertTrue(e.getMessage().contains("time"));
 	}
 
 	@Test
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 03e2855..ab8e0c1 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
@@ -12,6 +12,8 @@
 import java.io.ByteArrayInputStream;
 import java.io.IOException;
 import java.io.InputStream;
+import java.io.OutputStream;
+import java.nio.charset.StandardCharsets;
 import java.nio.file.Files;
 import java.nio.file.Path;
 import java.security.GeneralSecurityException;
@@ -22,8 +24,10 @@
 import java.util.Collections;
 import java.util.List;
 import java.util.Locale;
+import java.util.concurrent.TimeUnit;
 
 import org.apache.sshd.common.NamedResource;
+import org.apache.sshd.common.PropertyResolver;
 import org.apache.sshd.common.PropertyResolverUtils;
 import org.apache.sshd.common.SshConstants;
 import org.apache.sshd.common.config.keys.AuthorizedKeyEntry;
@@ -66,6 +70,16 @@
  */
 public class SshTestGitServer {
 
+	/**
+	 * Simple echo test command. Replies with the command string as passed. If
+	 * of the form "echo [int] anything", takes the integer value as a delay in
+	 * seconds before replying, which may be useful to test various
+	 * timeout-related things.
+	 *
+	 * @since 5.9
+	 */
+	public static final String ECHO_COMMAND = "echo";
+
 	@NonNull
 	protected final String testUser;
 
@@ -90,8 +104,7 @@
 	 * @param testUser
 	 *            user name of the test user
 	 * @param testKey
-	 *            <em>private</em> key file of the test user; the server will
-	 *            only user the public key from it
+	 *            public key file of the test user
 	 * @param repository
 	 *            to serve
 	 * @param hostKey
@@ -102,17 +115,54 @@
 	public SshTestGitServer(@NonNull String testUser, @NonNull Path testKey,
 			@NonNull Repository repository, @NonNull byte[] hostKey)
 			throws IOException, GeneralSecurityException {
+		this(testUser, readPublicKey(testKey), repository,
+				readKeyPair(hostKey));
+	}
+
+	/**
+	 * Creates a ssh git <em>test</em> server. It serves one single repository,
+	 * and accepts public-key authentication for exactly one test user.
+	 *
+	 * @param testUser
+	 *            user name of the test user
+	 * @param testKey
+	 *            public key file of the test user
+	 * @param repository
+	 *            to serve
+	 * @param hostKey
+	 *            the unencrypted private key to use as host key
+	 * @throws IOException
+	 * @throws GeneralSecurityException
+	 * @since 5.9
+	 */
+	public SshTestGitServer(@NonNull String testUser, @NonNull Path testKey,
+			@NonNull Repository repository, @NonNull KeyPair hostKey)
+			throws IOException, GeneralSecurityException {
+		this(testUser, readPublicKey(testKey), repository, hostKey);
+	}
+
+	/**
+	 * Creates a ssh git <em>test</em> server. It serves one single repository,
+	 * and accepts public-key authentication for exactly one test user.
+	 *
+	 * @param testUser
+	 *            user name of the test user
+	 * @param testKey
+	 *            the {@link PublicKey} of the test user
+	 * @param repository
+	 *            to serve
+	 * @param hostKey
+	 *            the {@link KeyPair} to use as host key
+	 * @since 5.9
+	 */
+	public SshTestGitServer(@NonNull String testUser,
+			@NonNull PublicKey testKey, @NonNull Repository repository,
+			@NonNull KeyPair hostKey) {
 		this.testUser = testUser;
 		setTestUserPublicKey(testKey);
 		this.repository = repository;
 		server = SshServer.setUpDefaultServer();
-		// Set host key
-		try (ByteArrayInputStream in = new ByteArrayInputStream(hostKey)) {
-			SecurityUtils.loadKeyPairIdentities(null, null, in, null)
-					.forEach((k) -> hostKeys.add(k));
-		} catch (IOException | GeneralSecurityException e) {
-			// Ignore.
-		}
+		hostKeys.add(hostKey);
 		server.setKeyPairProvider((session) -> hostKeys);
 
 		configureAuthentication();
@@ -129,11 +179,27 @@
 				return new GitUploadPackCommand(command, executorService);
 			} else if (command.startsWith(RemoteConfig.DEFAULT_RECEIVE_PACK)) {
 				return new GitReceivePackCommand(command, executorService);
+			} else if (command.startsWith(ECHO_COMMAND)) {
+				return new EchoCommand(command, executorService);
 			}
 			return new UnknownCommand(command);
 		});
 	}
 
+	private static PublicKey readPublicKey(Path key)
+			throws IOException, GeneralSecurityException {
+		return AuthorizedKeyEntry.readAuthorizedKeys(key).get(0)
+				.resolvePublicKey(null, PublicKeyEntryResolver.IGNORING);
+	}
+
+	private static KeyPair readKeyPair(byte[] keyMaterial)
+			throws IOException, GeneralSecurityException {
+		try (ByteArrayInputStream in = new ByteArrayInputStream(keyMaterial)) {
+			return SecurityUtils.loadKeyPairIdentities(null, null, in, null)
+					.iterator().next();
+		}
+	}
+
 	private static class FakeUserAuthGSS extends UserAuthGSS {
 		@Override
 		protected Boolean doAuth(Buffer buffer, boolean initial)
@@ -298,6 +364,17 @@
 	}
 
 	/**
+	 * Retrieves the server's {@link PropertyResolver}, giving access to server
+	 * properties.
+	 *
+	 * @return the {@link PropertyResolver}
+	 * @since 5.9
+	 */
+	public PropertyResolver getPropertyResolver() {
+		return server;
+	}
+
+	/**
 	 * Starts the test server, listening on a random port.
 	 *
 	 * @return the port the server listens on; test clients should connect to
@@ -331,8 +408,7 @@
 	 */
 	public void setTestUserPublicKey(Path key)
 			throws IOException, GeneralSecurityException {
-		this.testKey = AuthorizedKeyEntry.readAuthorizedKeys(key).get(0)
-				.resolvePublicKey(null, PublicKeyEntryResolver.IGNORING);
+		this.testKey = readPublicKey(key);
 	}
 
 	/**
@@ -414,4 +490,52 @@
 		}
 
 	}
+
+	/**
+	 * Simple echo command that echoes back the command string. If the first
+	 * argument is a positive integer, it's taken as a delay (in seconds) before
+	 * replying. Assumes UTF-8 character encoding.
+	 */
+	private static class EchoCommand extends AbstractCommandSupport {
+
+		protected EchoCommand(String command,
+				CloseableExecutorService executorService) {
+			super(command, ThreadUtils.noClose(executorService));
+		}
+
+		@Override
+		public void run() {
+			String[] parts = getCommand().split(" ");
+			int timeout = 0;
+			if (parts.length >= 2) {
+				try {
+					timeout = Integer.parseInt(parts[1]);
+				} catch (NumberFormatException e) {
+					// No timeout.
+				}
+				if (timeout > 0) {
+					try {
+						Thread.sleep(TimeUnit.SECONDS.toMillis(timeout));
+					} catch (InterruptedException e) {
+						// Ignore.
+					}
+				}
+			}
+			try {
+				doEcho(getCommand(), getOutputStream());
+				onExit(0);
+			} catch (IOException e) {
+				log.warn(
+						MessageFormat.format("Could not run {0}", getCommand()),
+						e);
+				onExit(-1, e.toString());
+			}
+		}
+
+		private void doEcho(String text, OutputStream stream)
+				throws IOException {
+			stream.write(text.getBytes(StandardCharsets.UTF_8));
+			stream.flush();
+		}
+	}
 }
diff --git a/org.eclipse.jgit.junit.ssh/src/org/eclipse/jgit/junit/ssh/SshTestHarness.java b/org.eclipse.jgit.junit.ssh/src/org/eclipse/jgit/junit/ssh/SshTestHarness.java
index 43f9dc4..7970685 100644
--- a/org.eclipse.jgit.junit.ssh/src/org/eclipse/jgit/junit/ssh/SshTestHarness.java
+++ b/org.eclipse.jgit.junit.ssh/src/org/eclipse/jgit/junit/ssh/SshTestHarness.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2018, Thomas Wolf <thomas.wolf@paranor.ch> and others
+ * Copyright (C) 2018, 2020 Thomas Wolf <thomas.wolf@paranor.ch> and others
  *
  * This program and the accompanying materials are made available under the
  * terms of the Eclipse Distribution License v. 1.0 which is available at
@@ -9,27 +9,31 @@
  */
 package org.eclipse.jgit.junit.ssh;
 
-import static java.nio.charset.StandardCharsets.US_ASCII;
-import static java.nio.charset.StandardCharsets.UTF_8;
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertFalse;
 import static org.junit.Assert.assertNotEquals;
 import static org.junit.Assert.assertNotNull;
 import static org.junit.Assert.assertTrue;
 
-import java.io.ByteArrayOutputStream;
+import java.io.BufferedWriter;
 import java.io.File;
 import java.io.FileOutputStream;
 import java.io.IOException;
 import java.io.InputStream;
 import java.io.OutputStream;
+import java.nio.charset.StandardCharsets;
 import java.nio.file.Files;
+import java.security.KeyPair;
+import java.security.KeyPairGenerator;
+import java.security.PrivateKey;
 import java.util.ArrayList;
 import java.util.Arrays;
+import java.util.Base64;
 import java.util.Collections;
 import java.util.Iterator;
 import java.util.List;
 
+import org.apache.sshd.common.config.keys.PublicKeyEntry;
 import org.eclipse.jgit.api.CloneCommand;
 import org.eclipse.jgit.api.Git;
 import org.eclipse.jgit.api.PushCommand;
@@ -48,9 +52,6 @@
 import org.eclipse.jgit.util.FS;
 import org.junit.After;
 
-import com.jcraft.jsch.JSch;
-import com.jcraft.jsch.KeyPair;
-
 /**
  * Root class for ssh tests. Sets up the ssh test server. A set of pre-computed
  * keys for testing is provided in the bundle and can be used in test cases via
@@ -104,50 +105,71 @@
 		File serverDir = new File(getTemporaryDirectory(), "srv");
 		assertTrue(serverDir.mkdir());
 		// Create two key pairs. Let's not call them "id_rsa".
+		KeyPairGenerator generator = KeyPairGenerator.getInstance("RSA");
+		generator.initialize(2048);
 		privateKey1 = new File(sshDir, "first_key");
 		privateKey2 = new File(sshDir, "second_key");
-		publicKey1 = createKeyPair(privateKey1);
-		createKeyPair(privateKey2);
-		ByteArrayOutputStream publicHostKey = new ByteArrayOutputStream();
+		publicKey1 = createKeyPair(generator.generateKeyPair(), privateKey1);
+		createKeyPair(generator.generateKeyPair(), privateKey2);
+		// Create a host key
+		KeyPair hostKey = generator.generateKeyPair();
 		// Start a server with our test user and the first key.
 		server = new SshTestGitServer(TEST_USER, publicKey1.toPath(), db,
-				createHostKey(publicHostKey));
+				hostKey);
 		testPort = server.start();
 		assertTrue(testPort > 0);
 		knownHosts = new File(sshDir, "known_hosts");
-		Files.write(knownHosts.toPath(), Collections.singleton("[localhost]:"
-				+ testPort + ' '
-				+ publicHostKey.toString(US_ASCII.name())));
+		StringBuilder knownHostsLine = new StringBuilder();
+		knownHostsLine.append("[localhost]:").append(testPort).append(' ');
+		PublicKeyEntry.appendPublicKeyEntry(knownHostsLine,
+				hostKey.getPublic());
+		Files.write(knownHosts.toPath(),
+				Collections.singleton(knownHostsLine.toString()));
 		factory = createSessionFactory();
 		SshSessionFactory.setInstance(factory);
 	}
 
-	private static File createKeyPair(File privateKeyFile) throws Exception {
-		// Found no way to do this with MINA sshd except rolling it all
-		// ourselves...
-		JSch jsch = new JSch();
-		KeyPair pair = KeyPair.genKeyPair(jsch, KeyPair.RSA, 2048);
-		try (OutputStream out = new FileOutputStream(privateKeyFile)) {
-			pair.writePrivateKey(out);
+	private static File createKeyPair(KeyPair newKey, File privateKeyFile)
+			throws Exception {
+		// Write PKCS#8 PEM unencrypted. Both JSch and sshd can read that.
+		PrivateKey privateKey = newKey.getPrivate();
+		String format = privateKey.getFormat();
+		if (!"PKCS#8".equalsIgnoreCase(format)) {
+			throw new IOException("Cannot write " + privateKey.getAlgorithm()
+					+ " key in " + format + " format");
+		}
+		try (BufferedWriter writer = Files.newBufferedWriter(
+				privateKeyFile.toPath(), StandardCharsets.US_ASCII)) {
+			writer.write("-----BEGIN PRIVATE KEY-----");
+			writer.newLine();
+			write(writer, privateKey.getEncoded(), 64);
+			writer.write("-----END PRIVATE KEY-----");
+			writer.newLine();
 		}
 		File publicKeyFile = new File(privateKeyFile.getParentFile(),
 				privateKeyFile.getName() + ".pub");
+		StringBuilder builder = new StringBuilder();
+		PublicKeyEntry.appendPublicKeyEntry(builder, newKey.getPublic());
+		builder.append(' ').append(TEST_USER);
 		try (OutputStream out = new FileOutputStream(publicKeyFile)) {
-			pair.writePublicKey(out, TEST_USER);
+			out.write(builder.toString().getBytes(StandardCharsets.US_ASCII));
 		}
 		return publicKeyFile;
 	}
 
-	private static byte[] createHostKey(OutputStream publicKey)
-			throws Exception {
-		JSch jsch = new JSch();
-		KeyPair pair = KeyPair.genKeyPair(jsch, KeyPair.RSA, 2048);
-		pair.writePublicKey(publicKey, "");
-		try (ByteArrayOutputStream out = new ByteArrayOutputStream()) {
-			pair.writePrivateKey(out);
-			out.flush();
-			return out.toByteArray();
+	private static void write(BufferedWriter out, byte[] bytes, int lineLength)
+			throws IOException {
+		String data = Base64.getEncoder().encodeToString(bytes);
+		int last = data.length();
+		for (int i = 0; i < last; i += lineLength) {
+			if (i + lineLength <= last) {
+				out.write(data.substring(i, i + lineLength));
+			} else {
+				out.write(data.substring(i));
+			}
+			out.newLine();
 		}
+		Arrays.fill(bytes, (byte) 0);
 	}
 
 	/**
@@ -167,7 +189,8 @@
 	 */
 	protected static String createKnownHostsFile(File file, String host,
 			int port, File publicKey) throws IOException {
-		List<String> lines = Files.readAllLines(publicKey.toPath(), UTF_8);
+		List<String> lines = Files.readAllLines(publicKey.toPath(),
+				StandardCharsets.UTF_8);
 		assertEquals("Public key has too many lines", 1, lines.size());
 		String pubKey = lines.get(0);
 		// Strip off the comment.
diff --git a/org.eclipse.jgit.junit/META-INF/MANIFEST.MF b/org.eclipse.jgit.junit/META-INF/MANIFEST.MF
index ba44d61..993dc72 100644
--- a/org.eclipse.jgit.junit/META-INF/MANIFEST.MF
+++ b/org.eclipse.jgit.junit/META-INF/MANIFEST.MF
@@ -3,35 +3,35 @@
 Bundle-Name: %Bundle-Name
 Automatic-Module-Name: org.eclipse.jgit.junit
 Bundle-SymbolicName: org.eclipse.jgit.junit
-Bundle-Version: 5.8.2.qualifier
+Bundle-Version: 5.9.1.qualifier
 Bundle-Localization: plugin
 Bundle-Vendor: %Bundle-Vendor
 Bundle-ActivationPolicy: lazy
 Bundle-RequiredExecutionEnvironment: JavaSE-1.8
-Import-Package: org.eclipse.jgit.annotations;version="[5.8.2,5.9.0)",
- org.eclipse.jgit.api;version="[5.8.2,5.9.0)",
- org.eclipse.jgit.api.errors;version="[5.8.2,5.9.0)",
- org.eclipse.jgit.dircache;version="[5.8.2,5.9.0)",
- org.eclipse.jgit.errors;version="[5.8.2,5.9.0)",
- org.eclipse.jgit.internal.storage.file;version="[5.8.2,5.9.0)",
- org.eclipse.jgit.internal.storage.pack;version="[5.8.2,5.9.0)",
- org.eclipse.jgit.lib;version="[5.8.2,5.9.0)",
- org.eclipse.jgit.merge;version="[5.8.2,5.9.0)",
- org.eclipse.jgit.revwalk;version="[5.8.2,5.9.0)",
- org.eclipse.jgit.storage.file;version="[5.8.2,5.9.0)",
- org.eclipse.jgit.transport;version="5.8.2",
- org.eclipse.jgit.treewalk;version="[5.8.2,5.9.0)",
- org.eclipse.jgit.treewalk.filter;version="[5.8.2,5.9.0)",
- org.eclipse.jgit.util;version="[5.8.2,5.9.0)",
- org.eclipse.jgit.util.io;version="[5.8.2,5.9.0)",
- org.eclipse.jgit.util.time;version="[5.8.2,5.9.0)",
+Import-Package: org.eclipse.jgit.annotations;version="[5.9.1,5.10.0)",
+ org.eclipse.jgit.api;version="[5.9.1,5.10.0)",
+ org.eclipse.jgit.api.errors;version="[5.9.1,5.10.0)",
+ org.eclipse.jgit.dircache;version="[5.9.1,5.10.0)",
+ org.eclipse.jgit.errors;version="[5.9.1,5.10.0)",
+ org.eclipse.jgit.internal.storage.file;version="[5.9.1,5.10.0)",
+ org.eclipse.jgit.internal.storage.pack;version="[5.9.1,5.10.0)",
+ org.eclipse.jgit.lib;version="[5.9.1,5.10.0)",
+ org.eclipse.jgit.merge;version="[5.9.1,5.10.0)",
+ org.eclipse.jgit.revwalk;version="[5.9.1,5.10.0)",
+ org.eclipse.jgit.storage.file;version="[5.9.1,5.10.0)",
+ org.eclipse.jgit.transport;version="5.9.1",
+ org.eclipse.jgit.treewalk;version="[5.9.1,5.10.0)",
+ org.eclipse.jgit.treewalk.filter;version="[5.9.1,5.10.0)",
+ org.eclipse.jgit.util;version="[5.9.1,5.10.0)",
+ org.eclipse.jgit.util.io;version="[5.9.1,5.10.0)",
+ org.eclipse.jgit.util.time;version="[5.9.1,5.10.0)",
  org.junit;version="[4.13,5.0.0)",
  org.junit.rules;version="[4.13,5.0.0)",
  org.junit.runner;version="[4.13,5.0.0)",
  org.junit.runners;version="[4.13,5.0.0)",
  org.junit.runners.model;version="[4.13,5.0.0)",
  org.slf4j;version="[1.7.0,2.0.0)"
-Export-Package: org.eclipse.jgit.junit;version="5.8.2";
+Export-Package: org.eclipse.jgit.junit;version="5.9.1";
   uses:="org.eclipse.jgit.dircache,
    org.eclipse.jgit.lib,
    org.eclipse.jgit.revwalk,
@@ -44,4 +44,4 @@
    org.junit.runners.model,
    org.junit.runner,
    org.eclipse.jgit.util.time",
- org.eclipse.jgit.junit.time;version="5.8.2";uses:="org.eclipse.jgit.util.time"
+ org.eclipse.jgit.junit.time;version="5.9.1";uses:="org.eclipse.jgit.util.time"
diff --git a/org.eclipse.jgit.junit/META-INF/SOURCE-MANIFEST.MF b/org.eclipse.jgit.junit/META-INF/SOURCE-MANIFEST.MF
index 450be70..0f204a3 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.8.2.qualifier
-Eclipse-SourceBundle: org.eclipse.jgit.junit;version="5.8.2.qualifier";roots="."
+Bundle-Version: 5.9.1.qualifier
+Eclipse-SourceBundle: org.eclipse.jgit.junit;version="5.9.1.qualifier";roots="."
diff --git a/org.eclipse.jgit.junit/pom.xml b/org.eclipse.jgit.junit/pom.xml
index 188d695..c6c7c4f 100644
--- a/org.eclipse.jgit.junit/pom.xml
+++ b/org.eclipse.jgit.junit/pom.xml
@@ -19,7 +19,7 @@
   <parent>
     <groupId>org.eclipse.jgit</groupId>
     <artifactId>org.eclipse.jgit-parent</artifactId>
-    <version>5.8.2-SNAPSHOT</version>
+    <version>5.9.1-SNAPSHOT</version>
   </parent>
 
   <artifactId>org.eclipse.jgit.junit</artifactId>
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 de11e2c..cc84f19 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
@@ -34,6 +34,7 @@
 import org.eclipse.jgit.dircache.DirCacheCheckout;
 import org.eclipse.jgit.dircache.DirCacheEntry;
 import org.eclipse.jgit.internal.storage.file.FileRepository;
+import org.eclipse.jgit.lib.AnyObjectId;
 import org.eclipse.jgit.lib.Constants;
 import org.eclipse.jgit.lib.FileMode;
 import org.eclipse.jgit.lib.ObjectId;
@@ -513,6 +514,21 @@
 	}
 
 	/**
+	 * Create <code>DirCacheEntry</code>
+	 *
+	 * @param path
+	 * @param objectId
+	 * @return the DirCacheEntry
+	 */
+	protected DirCacheEntry createGitLink(String path, AnyObjectId objectId) {
+		final DirCacheEntry entry = new DirCacheEntry(path,
+				DirCacheEntry.STAGE_0);
+		entry.setFileMode(FileMode.GITLINK);
+		entry.setObjectId(objectId);
+		return entry;
+	}
+
+	/**
 	 * Assert files are equal
 	 *
 	 * @param expected
diff --git a/org.eclipse.jgit.lfs.server.test/.settings/org.eclipse.jdt.core.prefs b/org.eclipse.jgit.lfs.server.test/.settings/org.eclipse.jdt.core.prefs
index 3dd5840..4c4634a 100644
--- a/org.eclipse.jgit.lfs.server.test/.settings/org.eclipse.jdt.core.prefs
+++ b/org.eclipse.jgit.lfs.server.test/.settings/org.eclipse.jdt.core.prefs
@@ -52,7 +52,7 @@
 org.eclipse.jdt.core.compiler.problem.missingJavadocCommentsOverriding=disabled
 org.eclipse.jdt.core.compiler.problem.missingJavadocCommentsVisibility=protected
 org.eclipse.jdt.core.compiler.problem.missingJavadocTagDescription=return_tag
-org.eclipse.jdt.core.compiler.problem.missingJavadocTags=error
+org.eclipse.jdt.core.compiler.problem.missingJavadocTags=ignore
 org.eclipse.jdt.core.compiler.problem.missingJavadocTagsMethodTypeParameters=disabled
 org.eclipse.jdt.core.compiler.problem.missingJavadocTagsOverriding=disabled
 org.eclipse.jdt.core.compiler.problem.missingJavadocTagsVisibility=private
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 dfac6ee..2f398a0 100644
--- a/org.eclipse.jgit.lfs.server.test/META-INF/MANIFEST.MF
+++ b/org.eclipse.jgit.lfs.server.test/META-INF/MANIFEST.MF
@@ -3,7 +3,7 @@
 Bundle-Name: %Bundle-Name
 Automatic-Module-Name: org.eclipse.jgit.lfs.server.test
 Bundle-SymbolicName: org.eclipse.jgit.lfs.server.test
-Bundle-Version: 5.8.2.qualifier
+Bundle-Version: 5.9.1.qualifier
 Bundle-Vendor: %Bundle-Vendor
 Bundle-Localization: plugin
 Bundle-RequiredExecutionEnvironment: JavaSE-1.8
@@ -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.8.2,5.9.0)",
- org.eclipse.jgit.api.errors;version="[5.8.2,5.9.0)",
- org.eclipse.jgit.internal.storage.file;version="[5.8.2,5.9.0)",
- org.eclipse.jgit.junit;version="[5.8.2,5.9.0)",
- org.eclipse.jgit.junit.http;version="[5.8.2,5.9.0)",
- org.eclipse.jgit.lfs;version="[5.8.2,5.9.0)",
- org.eclipse.jgit.lfs.errors;version="[5.8.2,5.9.0)",
- org.eclipse.jgit.lfs.lib;version="[5.8.2,5.9.0)",
- org.eclipse.jgit.lfs.server;version="[5.8.2,5.9.0)",
- org.eclipse.jgit.lfs.server.fs;version="[5.8.2,5.9.0)",
- org.eclipse.jgit.lfs.test;version="[5.8.2,5.9.0)",
- org.eclipse.jgit.lib;version="[5.8.2,5.9.0)",
- org.eclipse.jgit.revwalk;version="[5.8.2,5.9.0)",
- org.eclipse.jgit.storage.file;version="[5.8.2,5.9.0)",
- org.eclipse.jgit.transport;version="[5.8.2,5.9.0)",
- org.eclipse.jgit.treewalk;version="[5.8.2,5.9.0)",
- org.eclipse.jgit.treewalk.filter;version="[5.8.2,5.9.0)",
- org.eclipse.jgit.util;version="[5.8.2,5.9.0)",
+ org.eclipse.jgit.api;version="[5.9.1,5.10.0)",
+ org.eclipse.jgit.api.errors;version="[5.9.1,5.10.0)",
+ org.eclipse.jgit.internal.storage.file;version="[5.9.1,5.10.0)",
+ org.eclipse.jgit.junit;version="[5.9.1,5.10.0)",
+ org.eclipse.jgit.junit.http;version="[5.9.1,5.10.0)",
+ org.eclipse.jgit.lfs;version="[5.9.1,5.10.0)",
+ org.eclipse.jgit.lfs.errors;version="[5.9.1,5.10.0)",
+ org.eclipse.jgit.lfs.lib;version="[5.9.1,5.10.0)",
+ org.eclipse.jgit.lfs.server;version="[5.9.1,5.10.0)",
+ org.eclipse.jgit.lfs.server.fs;version="[5.9.1,5.10.0)",
+ org.eclipse.jgit.lfs.test;version="[5.9.1,5.10.0)",
+ org.eclipse.jgit.lib;version="[5.9.1,5.10.0)",
+ org.eclipse.jgit.revwalk;version="[5.9.1,5.10.0)",
+ org.eclipse.jgit.storage.file;version="[5.9.1,5.10.0)",
+ org.eclipse.jgit.transport;version="[5.9.1,5.10.0)",
+ org.eclipse.jgit.treewalk;version="[5.9.1,5.10.0)",
+ org.eclipse.jgit.treewalk.filter;version="[5.9.1,5.10.0)",
+ org.eclipse.jgit.util;version="[5.9.1,5.10.0)",
  org.hamcrest.core;version="[1.1.0,2.0.0)",
  org.junit;version="[4.13,5.0.0)",
  org.junit.rules;version="[4.13,5.0.0)",
diff --git a/org.eclipse.jgit.lfs.server.test/pom.xml b/org.eclipse.jgit.lfs.server.test/pom.xml
index 0fc65e4..a4f7bd1 100644
--- a/org.eclipse.jgit.lfs.server.test/pom.xml
+++ b/org.eclipse.jgit.lfs.server.test/pom.xml
@@ -17,7 +17,7 @@
   <parent>
     <groupId>org.eclipse.jgit</groupId>
     <artifactId>org.eclipse.jgit-parent</artifactId>
-    <version>5.8.2-SNAPSHOT</version>
+    <version>5.9.1-SNAPSHOT</version>
   </parent>
 
   <artifactId>org.eclipse.jgit.lfs.server.test</artifactId>
diff --git a/org.eclipse.jgit.lfs.server/META-INF/MANIFEST.MF b/org.eclipse.jgit.lfs.server/META-INF/MANIFEST.MF
index 205a22f..cfb413c 100644
--- a/org.eclipse.jgit.lfs.server/META-INF/MANIFEST.MF
+++ b/org.eclipse.jgit.lfs.server/META-INF/MANIFEST.MF
@@ -3,19 +3,19 @@
 Bundle-Name: %Bundle-Name
 Automatic-Module-Name: org.eclipse.jgit.lfs.server
 Bundle-SymbolicName: org.eclipse.jgit.lfs.server
-Bundle-Version: 5.8.2.qualifier
+Bundle-Version: 5.9.1.qualifier
 Bundle-Localization: plugin
 Bundle-Vendor: %Bundle-Vendor
-Export-Package: org.eclipse.jgit.lfs.server;version="5.8.2";
+Export-Package: org.eclipse.jgit.lfs.server;version="5.9.1";
   uses:="javax.servlet.http,
    org.eclipse.jgit.lfs.lib",
- org.eclipse.jgit.lfs.server.fs;version="5.8.2";
+ org.eclipse.jgit.lfs.server.fs;version="5.9.1";
   uses:="javax.servlet,
    javax.servlet.http,
    org.eclipse.jgit.lfs.server,
    org.eclipse.jgit.lfs.lib",
- org.eclipse.jgit.lfs.server.internal;version="5.8.2";x-internal:=true,
- org.eclipse.jgit.lfs.server.s3;version="5.8.2";
+ org.eclipse.jgit.lfs.server.internal;version="5.9.1";x-internal:=true,
+ org.eclipse.jgit.lfs.server.s3;version="5.9.1";
   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.8.2,5.9.0)",
- org.eclipse.jgit.internal;version="[5.8.2,5.9.0)",
- org.eclipse.jgit.internal.storage.file;version="[5.8.2,5.9.0)",
- org.eclipse.jgit.lfs.errors;version="[5.8.2,5.9.0)",
- org.eclipse.jgit.lfs.internal;version="[5.8.2,5.9.0)",
- org.eclipse.jgit.lfs.lib;version="[5.8.2,5.9.0)",
- org.eclipse.jgit.lib;version="[5.8.2,5.9.0)",
- org.eclipse.jgit.nls;version="[5.8.2,5.9.0)",
- org.eclipse.jgit.transport.http;version="[5.8.2,5.9.0)",
- org.eclipse.jgit.transport.http.apache;version="[5.8.2,5.9.0)",
- org.eclipse.jgit.util;version="[5.8.2,5.9.0)",
+ org.eclipse.jgit.annotations;version="[5.9.1,5.10.0)",
+ org.eclipse.jgit.internal;version="[5.9.1,5.10.0)",
+ org.eclipse.jgit.internal.storage.file;version="[5.9.1,5.10.0)",
+ org.eclipse.jgit.lfs.errors;version="[5.9.1,5.10.0)",
+ org.eclipse.jgit.lfs.internal;version="[5.9.1,5.10.0)",
+ org.eclipse.jgit.lfs.lib;version="[5.9.1,5.10.0)",
+ org.eclipse.jgit.lib;version="[5.9.1,5.10.0)",
+ org.eclipse.jgit.nls;version="[5.9.1,5.10.0)",
+ org.eclipse.jgit.transport.http;version="[5.9.1,5.10.0)",
+ org.eclipse.jgit.transport.http.apache;version="[5.9.1,5.10.0)",
+ org.eclipse.jgit.util;version="[5.9.1,5.10.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 1b05aa0..708a62d 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.8.2.qualifier
-Eclipse-SourceBundle: org.eclipse.jgit.lfs.server;version="5.8.2.qualifier";roots="."
+Bundle-Version: 5.9.1.qualifier
+Eclipse-SourceBundle: org.eclipse.jgit.lfs.server;version="5.9.1.qualifier";roots="."
diff --git a/org.eclipse.jgit.lfs.server/pom.xml b/org.eclipse.jgit.lfs.server/pom.xml
index c5b9af2..abb2891 100644
--- a/org.eclipse.jgit.lfs.server/pom.xml
+++ b/org.eclipse.jgit.lfs.server/pom.xml
@@ -17,7 +17,7 @@
   <parent>
     <groupId>org.eclipse.jgit</groupId>
     <artifactId>org.eclipse.jgit-parent</artifactId>
-    <version>5.8.2-SNAPSHOT</version>
+    <version>5.9.1-SNAPSHOT</version>
   </parent>
 
   <artifactId>org.eclipse.jgit.lfs.server</artifactId>
diff --git a/org.eclipse.jgit.lfs.test/.settings/org.eclipse.jdt.core.prefs b/org.eclipse.jgit.lfs.test/.settings/org.eclipse.jdt.core.prefs
index 3dd5840..4c4634a 100644
--- a/org.eclipse.jgit.lfs.test/.settings/org.eclipse.jdt.core.prefs
+++ b/org.eclipse.jgit.lfs.test/.settings/org.eclipse.jdt.core.prefs
@@ -52,7 +52,7 @@
 org.eclipse.jdt.core.compiler.problem.missingJavadocCommentsOverriding=disabled
 org.eclipse.jdt.core.compiler.problem.missingJavadocCommentsVisibility=protected
 org.eclipse.jdt.core.compiler.problem.missingJavadocTagDescription=return_tag
-org.eclipse.jdt.core.compiler.problem.missingJavadocTags=error
+org.eclipse.jdt.core.compiler.problem.missingJavadocTags=ignore
 org.eclipse.jdt.core.compiler.problem.missingJavadocTagsMethodTypeParameters=disabled
 org.eclipse.jdt.core.compiler.problem.missingJavadocTagsOverriding=disabled
 org.eclipse.jdt.core.compiler.problem.missingJavadocTagsVisibility=private
diff --git a/org.eclipse.jgit.lfs.test/BUILD b/org.eclipse.jgit.lfs.test/BUILD
index 061ecd7..4665f67 100644
--- a/org.eclipse.jgit.lfs.test/BUILD
+++ b/org.eclipse.jgit.lfs.test/BUILD
@@ -13,6 +13,7 @@
     deps = [
         ":helpers",
         "//lib:junit",
+        "//lib:slf4j-api",
         "//org.eclipse.jgit:jgit",
         "//org.eclipse.jgit.junit:junit",
         "//org.eclipse.jgit.lfs:jgit-lfs",
diff --git a/org.eclipse.jgit.lfs.test/META-INF/MANIFEST.MF b/org.eclipse.jgit.lfs.test/META-INF/MANIFEST.MF
index cdb0d2a..0d02971 100644
--- a/org.eclipse.jgit.lfs.test/META-INF/MANIFEST.MF
+++ b/org.eclipse.jgit.lfs.test/META-INF/MANIFEST.MF
@@ -3,22 +3,22 @@
 Bundle-Name: %Bundle-Name
 Automatic-Module-Name: org.eclipse.jgit.lfs.test
 Bundle-SymbolicName: org.eclipse.jgit.lfs.test
-Bundle-Version: 5.8.2.qualifier
+Bundle-Version: 5.9.1.qualifier
 Bundle-Vendor: %Bundle-Vendor
 Bundle-Localization: plugin
 Bundle-RequiredExecutionEnvironment: JavaSE-1.8
-Import-Package: org.eclipse.jgit.internal.storage.dfs;version="[5.8.2,5.9.0)",
- org.eclipse.jgit.junit;version="[5.8.2,5.9.0)",
- org.eclipse.jgit.lfs;version="[5.8.2,5.9.0)",
- org.eclipse.jgit.lfs.errors;version="[5.8.2,5.9.0)",
- org.eclipse.jgit.lfs.lib;version="[5.8.2,5.9.0)",
- org.eclipse.jgit.lib;version="[5.8.2,5.9.0)",
- org.eclipse.jgit.revwalk;version="[5.8.2,5.9.0)",
- org.eclipse.jgit.treewalk;version="[5.8.2,5.9.0)",
- org.eclipse.jgit.treewalk.filter;version="[5.8.2,5.9.0)",
- org.eclipse.jgit.util;version="[5.8.2,5.9.0)",
+Import-Package: org.eclipse.jgit.internal.storage.dfs;version="[5.9.1,5.10.0)",
+ org.eclipse.jgit.junit;version="[5.9.1,5.10.0)",
+ org.eclipse.jgit.lfs;version="[5.9.1,5.10.0)",
+ org.eclipse.jgit.lfs.errors;version="[5.9.1,5.10.0)",
+ org.eclipse.jgit.lfs.lib;version="[5.9.1,5.10.0)",
+ org.eclipse.jgit.lib;version="[5.9.1,5.10.0)",
+ org.eclipse.jgit.revwalk;version="[5.9.1,5.10.0)",
+ org.eclipse.jgit.treewalk;version="[5.9.1,5.10.0)",
+ org.eclipse.jgit.treewalk.filter;version="[5.9.1,5.10.0)",
+ org.eclipse.jgit.util;version="[5.9.1,5.10.0)",
  org.hamcrest.core;version="[1.1.0,2.0.0)",
  org.junit;version="[4.13,5.0.0)",
  org.junit.runner;version="[4.13,5.0.0)",
  org.junit.runners;version="[4.13,5.0.0)"
-Export-Package: org.eclipse.jgit.lfs.test;version="5.8.2";x-friends:="org.eclipse.jgit.lfs.server.test"
+Export-Package: org.eclipse.jgit.lfs.test;version="5.9.1";x-friends:="org.eclipse.jgit.lfs.server.test"
diff --git a/org.eclipse.jgit.lfs.test/pom.xml b/org.eclipse.jgit.lfs.test/pom.xml
index b0029e9..22fd3a7 100644
--- a/org.eclipse.jgit.lfs.test/pom.xml
+++ b/org.eclipse.jgit.lfs.test/pom.xml
@@ -17,7 +17,7 @@
   <parent>
     <groupId>org.eclipse.jgit</groupId>
     <artifactId>org.eclipse.jgit-parent</artifactId>
-    <version>5.8.2-SNAPSHOT</version>
+    <version>5.9.1-SNAPSHOT</version>
   </parent>
 
   <artifactId>org.eclipse.jgit.lfs.test</artifactId>
diff --git a/org.eclipse.jgit.lfs/META-INF/MANIFEST.MF b/org.eclipse.jgit.lfs/META-INF/MANIFEST.MF
index 903641d..c7a3b84 100644
--- a/org.eclipse.jgit.lfs/META-INF/MANIFEST.MF
+++ b/org.eclipse.jgit.lfs/META-INF/MANIFEST.MF
@@ -3,33 +3,33 @@
 Bundle-Name: %Bundle-Name
 Automatic-Module-Name: org.eclipse.jgit.lfs
 Bundle-SymbolicName: org.eclipse.jgit.lfs
-Bundle-Version: 5.8.2.qualifier
+Bundle-Version: 5.9.1.qualifier
 Bundle-Localization: plugin
 Bundle-Vendor: %Bundle-Vendor
-Export-Package: org.eclipse.jgit.lfs;version="5.8.2",
- org.eclipse.jgit.lfs.errors;version="5.8.2",
- org.eclipse.jgit.lfs.internal;version="5.8.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.8.2"
+Export-Package: org.eclipse.jgit.lfs;version="5.9.1",
+ org.eclipse.jgit.lfs.errors;version="5.9.1",
+ org.eclipse.jgit.lfs.internal;version="5.9.1";x-friends:="org.eclipse.jgit.lfs.test,org.eclipse.jgit.lfs.server.fs,org.eclipse.jgit.lfs.server",
+ org.eclipse.jgit.lfs.lib;version="5.9.1"
 Bundle-RequiredExecutionEnvironment: JavaSE-1.8
 Import-Package: com.google.gson;version="[2.8.2,3.0.0)",
  com.google.gson.stream;version="[2.8.2,3.0.0)",
  org.apache.http.impl.client;version="[4.2.6,5.0.0)",
  org.apache.http.impl.conn;version="[4.2.6,5.0.0)",
- org.eclipse.jgit.annotations;version="[5.8.2,5.9.0)";resolution:=optional,
- org.eclipse.jgit.api.errors;version="[5.8.2,5.9.0)",
- org.eclipse.jgit.attributes;version="[5.8.2,5.9.0)",
- org.eclipse.jgit.diff;version="[5.8.2,5.9.0)",
- org.eclipse.jgit.errors;version="[5.8.2,5.9.0)",
- org.eclipse.jgit.hooks;version="[5.8.2,5.9.0)",
- org.eclipse.jgit.internal.storage.file;version="[5.8.2,5.9.0)",
- org.eclipse.jgit.lib;version="[5.8.2,5.9.0)",
- org.eclipse.jgit.nls;version="[5.8.2,5.9.0)",
- org.eclipse.jgit.revwalk;version="[5.8.2,5.9.0)",
- org.eclipse.jgit.storage.file;version="[5.8.2,5.9.0)",
- org.eclipse.jgit.storage.pack;version="[5.8.2,5.9.0)",
- org.eclipse.jgit.transport;version="[5.8.2,5.9.0)",
- org.eclipse.jgit.transport.http;version="[5.8.2,5.9.0)",
- org.eclipse.jgit.treewalk;version="[5.8.2,5.9.0)",
- org.eclipse.jgit.treewalk.filter;version="[5.8.2,5.9.0)",
- org.eclipse.jgit.util;version="[5.8.2,5.9.0)",
- org.eclipse.jgit.util.io;version="[5.8.2,5.9.0)"
+ org.eclipse.jgit.annotations;version="[5.9.1,5.10.0)";resolution:=optional,
+ org.eclipse.jgit.api.errors;version="[5.9.1,5.10.0)",
+ org.eclipse.jgit.attributes;version="[5.9.1,5.10.0)",
+ org.eclipse.jgit.diff;version="[5.9.1,5.10.0)",
+ org.eclipse.jgit.errors;version="[5.9.1,5.10.0)",
+ org.eclipse.jgit.hooks;version="[5.9.1,5.10.0)",
+ org.eclipse.jgit.internal.storage.file;version="[5.9.1,5.10.0)",
+ org.eclipse.jgit.lib;version="[5.9.1,5.10.0)",
+ org.eclipse.jgit.nls;version="[5.9.1,5.10.0)",
+ org.eclipse.jgit.revwalk;version="[5.9.1,5.10.0)",
+ org.eclipse.jgit.storage.file;version="[5.9.1,5.10.0)",
+ org.eclipse.jgit.storage.pack;version="[5.9.1,5.10.0)",
+ org.eclipse.jgit.transport;version="[5.9.1,5.10.0)",
+ org.eclipse.jgit.transport.http;version="[5.9.1,5.10.0)",
+ org.eclipse.jgit.treewalk;version="[5.9.1,5.10.0)",
+ org.eclipse.jgit.treewalk.filter;version="[5.9.1,5.10.0)",
+ org.eclipse.jgit.util;version="[5.9.1,5.10.0)",
+ org.eclipse.jgit.util.io;version="[5.9.1,5.10.0)"
diff --git a/org.eclipse.jgit.lfs/META-INF/SOURCE-MANIFEST.MF b/org.eclipse.jgit.lfs/META-INF/SOURCE-MANIFEST.MF
index edfcc42..59d2b7f 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.8.2.qualifier
-Eclipse-SourceBundle: org.eclipse.jgit.lfs;version="5.8.2.qualifier";roots="."
+Bundle-Version: 5.9.1.qualifier
+Eclipse-SourceBundle: org.eclipse.jgit.lfs;version="5.9.1.qualifier";roots="."
diff --git a/org.eclipse.jgit.lfs/pom.xml b/org.eclipse.jgit.lfs/pom.xml
index def4e23..2ee2f34 100644
--- a/org.eclipse.jgit.lfs/pom.xml
+++ b/org.eclipse.jgit.lfs/pom.xml
@@ -17,7 +17,7 @@
   <parent>
     <groupId>org.eclipse.jgit</groupId>
     <artifactId>org.eclipse.jgit-parent</artifactId>
-    <version>5.8.2-SNAPSHOT</version>
+    <version>5.9.1-SNAPSHOT</version>
   </parent>
 
   <artifactId>org.eclipse.jgit.lfs</artifactId>
diff --git a/org.eclipse.jgit.lfs/src/org/eclipse/jgit/lfs/internal/LfsConnectionFactory.java b/org.eclipse.jgit.lfs/src/org/eclipse/jgit/lfs/internal/LfsConnectionFactory.java
index cbad1b6..7a0ed45 100644
--- a/org.eclipse.jgit.lfs/src/org/eclipse/jgit/lfs/internal/LfsConnectionFactory.java
+++ b/org.eclipse.jgit.lfs/src/org/eclipse/jgit/lfs/internal/LfsConnectionFactory.java
@@ -112,8 +112,8 @@
 					remoteUrl = config.getString(
 							ConfigConstants.CONFIG_KEY_REMOTE, remote,
 							ConfigConstants.CONFIG_KEY_URL);
+					break;
 				}
-				break;
 			}
 			if (lfsUrl == null && remoteUrl != null) {
 				try {
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 f85b773..040e564 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.8.2.qualifier"
+      version="5.9.1.qualifier"
       provider-name="%providerName">
 
    <description url="http://www.eclipse.org/jgit/">
diff --git a/org.eclipse.jgit.packaging/org.eclipse.jgit.feature/pom.xml b/org.eclipse.jgit.packaging/org.eclipse.jgit.feature/pom.xml
index 93d9f54..3959f9e 100644
--- a/org.eclipse.jgit.packaging/org.eclipse.jgit.feature/pom.xml
+++ b/org.eclipse.jgit.packaging/org.eclipse.jgit.feature/pom.xml
@@ -17,7 +17,7 @@
   <parent>
     <groupId>org.eclipse.jgit</groupId>
     <artifactId>jgit.tycho.parent</artifactId>
-    <version>5.8.2-SNAPSHOT</version>
+    <version>5.9.1-SNAPSHOT</version>
   </parent>
 
   <groupId>org.eclipse.jgit.feature</groupId>
diff --git a/org.eclipse.jgit.packaging/org.eclipse.jgit.gpg.bc.feature/feature.xml b/org.eclipse.jgit.packaging/org.eclipse.jgit.gpg.bc.feature/feature.xml
index dc0e3dd..19f9c44 100644
--- a/org.eclipse.jgit.packaging/org.eclipse.jgit.gpg.bc.feature/feature.xml
+++ b/org.eclipse.jgit.packaging/org.eclipse.jgit.gpg.bc.feature/feature.xml
@@ -2,7 +2,7 @@
 <feature
       id="org.eclipse.jgit.gpg.bc"
       label="%featureName"
-      version="5.8.2.qualifier"
+      version="5.9.1.qualifier"
       provider-name="%providerName">
 
    <description url="http://www.eclipse.org/jgit/">
@@ -23,7 +23,7 @@
    </url>
 
    <requires>
-      <import plugin="org.eclipse.jgit" version="5.8.2" match="equivalent"/>
+      <import plugin="org.eclipse.jgit" version="5.9.1" match="equivalent"/>
    </requires>
 
    <plugin
diff --git a/org.eclipse.jgit.packaging/org.eclipse.jgit.gpg.bc.feature/pom.xml b/org.eclipse.jgit.packaging/org.eclipse.jgit.gpg.bc.feature/pom.xml
index 55c9266..0e48821 100644
--- a/org.eclipse.jgit.packaging/org.eclipse.jgit.gpg.bc.feature/pom.xml
+++ b/org.eclipse.jgit.packaging/org.eclipse.jgit.gpg.bc.feature/pom.xml
@@ -17,7 +17,7 @@
   <parent>
     <groupId>org.eclipse.jgit</groupId>
     <artifactId>jgit.tycho.parent</artifactId>
-    <version>5.8.2-SNAPSHOT</version>
+    <version>5.9.1-SNAPSHOT</version>
   </parent>
 
   <groupId>org.eclipse.jgit.feature</groupId>
diff --git a/org.eclipse.jgit.packaging/org.eclipse.jgit.http.apache.feature/feature.xml b/org.eclipse.jgit.packaging/org.eclipse.jgit.http.apache.feature/feature.xml
index a3df102..cb41fc5 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.8.2.qualifier"
+      version="5.9.1.qualifier"
       provider-name="%providerName">
 
    <description url="http://www.eclipse.org/jgit/">
@@ -23,7 +23,7 @@
    </url>
 
    <requires>
-      <import plugin="org.eclipse.jgit" version="5.8.2" match="equivalent"/>
+      <import plugin="org.eclipse.jgit" version="5.9.1" match="equivalent"/>
    </requires>
 
    <plugin
diff --git a/org.eclipse.jgit.packaging/org.eclipse.jgit.http.apache.feature/pom.xml b/org.eclipse.jgit.packaging/org.eclipse.jgit.http.apache.feature/pom.xml
index 06b8e5d..277e1f5 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
@@ -17,7 +17,7 @@
   <parent>
     <groupId>org.eclipse.jgit</groupId>
     <artifactId>jgit.tycho.parent</artifactId>
-    <version>5.8.2-SNAPSHOT</version>
+    <version>5.9.1-SNAPSHOT</version>
   </parent>
 
   <groupId>org.eclipse.jgit.feature</groupId>
diff --git a/org.eclipse.jgit.packaging/org.eclipse.jgit.junit.feature/feature.xml b/org.eclipse.jgit.packaging/org.eclipse.jgit.junit.feature/feature.xml
index b3233db..7ccc894 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.8.2.qualifier"
+      version="5.9.1.qualifier"
       provider-name="%providerName">
 
    <description url="http://www.eclipse.org/jgit/">
@@ -24,7 +24,7 @@
 
    <requires>
       <import plugin="com.jcraft.jsch"/>
-      <import plugin="org.eclipse.jgit" version="5.8.2" match="equivalent"/>
+      <import plugin="org.eclipse.jgit" version="5.9.1" 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 2b3c8a4..21bb3c8 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
@@ -17,7 +17,7 @@
   <parent>
     <groupId>org.eclipse.jgit</groupId>
     <artifactId>jgit.tycho.parent</artifactId>
-    <version>5.8.2-SNAPSHOT</version>
+    <version>5.9.1-SNAPSHOT</version>
   </parent>
 
   <groupId>org.eclipse.jgit.feature</groupId>
diff --git a/org.eclipse.jgit.packaging/org.eclipse.jgit.lfs.feature/feature.xml b/org.eclipse.jgit.packaging/org.eclipse.jgit.lfs.feature/feature.xml
index 5d1de45..8077793 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.8.2.qualifier"
+      version="5.9.1.qualifier"
       provider-name="%providerName">
 
    <description url="http://www.eclipse.org/jgit/">
@@ -23,7 +23,7 @@
    </url>
 
    <requires>
-      <import feature="org.eclipse.jgit" version="5.8.2" match="equivalent"/>
+      <import feature="org.eclipse.jgit" version="5.9.1" match="equivalent"/>
    </requires>
 
    <plugin
diff --git a/org.eclipse.jgit.packaging/org.eclipse.jgit.lfs.feature/pom.xml b/org.eclipse.jgit.packaging/org.eclipse.jgit.lfs.feature/pom.xml
index c89a889..a104305 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
@@ -17,7 +17,7 @@
   <parent>
     <groupId>org.eclipse.jgit</groupId>
     <artifactId>jgit.tycho.parent</artifactId>
-    <version>5.8.2-SNAPSHOT</version>
+    <version>5.9.1-SNAPSHOT</version>
   </parent>
 
   <groupId>org.eclipse.jgit.feature</groupId>
diff --git a/org.eclipse.jgit.packaging/org.eclipse.jgit.pgm.feature/feature.xml b/org.eclipse.jgit.packaging/org.eclipse.jgit.pgm.feature/feature.xml
index ed53ee0..fa24b82 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.8.2.qualifier"
+      version="5.9.1.qualifier"
       provider-name="%providerName">
 
    <description url="http://www.eclipse.org/jgit/">
@@ -35,9 +35,9 @@
          version="0.0.0"/>
 
    <requires>
-      <import feature="org.eclipse.jgit" version="5.8.2" match="equivalent"/>
-      <import feature="org.eclipse.jgit.lfs" version="5.8.2" match="equivalent"/>
-      <import feature="org.eclipse.jgit.ssh.apache" version="5.8.2" match="equivalent"/>
+      <import feature="org.eclipse.jgit" version="5.9.1" match="equivalent"/>
+      <import feature="org.eclipse.jgit.lfs" version="5.9.1" match="equivalent"/>
+      <import feature="org.eclipse.jgit.ssh.apache" version="5.9.1" match="equivalent"/>
    </requires>
 
    <plugin
diff --git a/org.eclipse.jgit.packaging/org.eclipse.jgit.pgm.feature/pom.xml b/org.eclipse.jgit.packaging/org.eclipse.jgit.pgm.feature/pom.xml
index 3967e2c..804057e 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
@@ -17,7 +17,7 @@
   <parent>
     <groupId>org.eclipse.jgit</groupId>
     <artifactId>jgit.tycho.parent</artifactId>
-    <version>5.8.2-SNAPSHOT</version>
+    <version>5.9.1-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 75ec8a1..7cb65b3 100644
--- a/org.eclipse.jgit.packaging/org.eclipse.jgit.repository/pom.xml
+++ b/org.eclipse.jgit.packaging/org.eclipse.jgit.repository/pom.xml
@@ -17,7 +17,7 @@
   <parent>
     <groupId>org.eclipse.jgit</groupId>
     <artifactId>jgit.tycho.parent</artifactId>
-    <version>5.8.2-SNAPSHOT</version>
+    <version>5.9.1-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 4610583..1cf7eef 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.8.2.qualifier"
+      version="5.9.1.qualifier"
       provider-name="%providerName">
 
    <description url="http://www.eclipse.org/jgit/">
@@ -23,7 +23,7 @@
    </url>
 
    <requires>
-      <import feature="org.eclipse.jgit" version="5.8.2" match="equivalent"/>
+      <import feature="org.eclipse.jgit" version="5.9.1" 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 c0dbcda..4f63e6a 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
@@ -17,7 +17,7 @@
   <parent>
     <groupId>org.eclipse.jgit</groupId>
     <artifactId>jgit.tycho.parent</artifactId>
-    <version>5.8.2-SNAPSHOT</version>
+    <version>5.9.1-SNAPSHOT</version>
   </parent>
 
   <groupId>org.eclipse.jgit.feature</groupId>
@@ -30,7 +30,7 @@
     <dependency>
       <groupId>org.eclipse.jgit.feature</groupId>
       <artifactId>org.eclipse.jgit</artifactId>
-      <version>5.8.2-SNAPSHOT</version>
+      <version>5.9.1-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 664af3d..4bd9e96 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.8.2.qualifier"
+      version="5.9.1.qualifier"
       provider-name="%providerName">
 
    <description url="http://www.eclipse.org/jgit/">
@@ -23,7 +23,7 @@
    </url>
 
    <requires>
-      <import feature="org.eclipse.jgit" version="5.8.2" match="equivalent"/>
+      <import feature="org.eclipse.jgit" version="5.9.1" 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 2571b55..0d1e81a 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
@@ -17,7 +17,7 @@
   <parent>
     <groupId>org.eclipse.jgit</groupId>
     <artifactId>jgit.tycho.parent</artifactId>
-    <version>5.8.2-SNAPSHOT</version>
+    <version>5.9.1-SNAPSHOT</version>
   </parent>
 
   <groupId>org.eclipse.jgit.feature</groupId>
diff --git a/org.eclipse.jgit.packaging/org.eclipse.jgit.ssh.jsch.feature/feature.xml b/org.eclipse.jgit.packaging/org.eclipse.jgit.ssh.jsch.feature/feature.xml
index 0e195b3..ed5c6a7 100644
--- a/org.eclipse.jgit.packaging/org.eclipse.jgit.ssh.jsch.feature/feature.xml
+++ b/org.eclipse.jgit.packaging/org.eclipse.jgit.ssh.jsch.feature/feature.xml
@@ -2,7 +2,7 @@
 <feature
       id="org.eclipse.jgit.ssh.jsch"
       label="%featureName"
-      version="5.8.2.qualifier"
+      version="5.9.1.qualifier"
       provider-name="%providerName">
 
    <description url="http://www.eclipse.org/jgit/">
@@ -23,7 +23,7 @@
    </url>
 
    <requires>
-      <import plugin="org.eclipse.jgit" version="5.8.2" match="equivalent"/>
+      <import plugin="org.eclipse.jgit" version="5.9.1" match="equivalent"/>
    </requires>
 
    <plugin
diff --git a/org.eclipse.jgit.packaging/org.eclipse.jgit.ssh.jsch.feature/pom.xml b/org.eclipse.jgit.packaging/org.eclipse.jgit.ssh.jsch.feature/pom.xml
index 378c2a5..3b2a45d 100644
--- a/org.eclipse.jgit.packaging/org.eclipse.jgit.ssh.jsch.feature/pom.xml
+++ b/org.eclipse.jgit.packaging/org.eclipse.jgit.ssh.jsch.feature/pom.xml
@@ -17,7 +17,7 @@
   <parent>
     <groupId>org.eclipse.jgit</groupId>
     <artifactId>jgit.tycho.parent</artifactId>
-    <version>5.8.2-SNAPSHOT</version>
+    <version>5.9.1-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 689bb73..fd90f99 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.8.2.qualifier
+Bundle-Version: 5.9.1.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 452503a..ad0816c 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,26 +1,26 @@
 <?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="1590935844">
+<target name="jgit-4.10" sequenceNumber="1598915260">
   <locations>
     <location includeMode="slicer" includeAllPlatforms="false" includeSource="true" includeConfigurePhase="true" type="InstallableUnit">
-      <unit id="org.eclipse.jetty.client" version="9.4.28.v20200408"/>
-      <unit id="org.eclipse.jetty.client.source" version="9.4.28.v20200408"/>
-      <unit id="org.eclipse.jetty.continuation" version="9.4.28.v20200408"/>
-      <unit id="org.eclipse.jetty.continuation.source" version="9.4.28.v20200408"/>
-      <unit id="org.eclipse.jetty.http" version="9.4.28.v20200408"/>
-      <unit id="org.eclipse.jetty.http.source" version="9.4.28.v20200408"/>
-      <unit id="org.eclipse.jetty.io" version="9.4.28.v20200408"/>
-      <unit id="org.eclipse.jetty.io.source" version="9.4.28.v20200408"/>
-      <unit id="org.eclipse.jetty.security" version="9.4.28.v20200408"/>
-      <unit id="org.eclipse.jetty.security.source" version="9.4.28.v20200408"/>
-      <unit id="org.eclipse.jetty.server" version="9.4.28.v20200408"/>
-      <unit id="org.eclipse.jetty.server.source" version="9.4.28.v20200408"/>
-      <unit id="org.eclipse.jetty.servlet" version="9.4.28.v20200408"/>
-      <unit id="org.eclipse.jetty.servlet.source" version="9.4.28.v20200408"/>
-      <unit id="org.eclipse.jetty.util" version="9.4.28.v20200408"/>
-      <unit id="org.eclipse.jetty.util.source" version="9.4.28.v20200408"/>
-      <repository id="jetty-9.4.25" location="https://download.eclipse.org/jetty/updates/jetty-bundles-9.x/9.4.28.v20200408/"/>
+      <unit id="org.eclipse.jetty.client" version="9.4.30.v20200611"/>
+      <unit id="org.eclipse.jetty.client.source" version="9.4.30.v20200611"/>
+      <unit id="org.eclipse.jetty.continuation" version="9.4.30.v20200611"/>
+      <unit id="org.eclipse.jetty.continuation.source" version="9.4.30.v20200611"/>
+      <unit id="org.eclipse.jetty.http" version="9.4.30.v20200611"/>
+      <unit id="org.eclipse.jetty.http.source" version="9.4.30.v20200611"/>
+      <unit id="org.eclipse.jetty.io" version="9.4.30.v20200611"/>
+      <unit id="org.eclipse.jetty.io.source" version="9.4.30.v20200611"/>
+      <unit id="org.eclipse.jetty.security" version="9.4.30.v20200611"/>
+      <unit id="org.eclipse.jetty.security.source" version="9.4.30.v20200611"/>
+      <unit id="org.eclipse.jetty.server" version="9.4.30.v20200611"/>
+      <unit id="org.eclipse.jetty.server.source" version="9.4.30.v20200611"/>
+      <unit id="org.eclipse.jetty.servlet" version="9.4.30.v20200611"/>
+      <unit id="org.eclipse.jetty.servlet.source" version="9.4.30.v20200611"/>
+      <unit id="org.eclipse.jetty.util" version="9.4.30.v20200611"/>
+      <unit id="org.eclipse.jetty.util.source" version="9.4.30.v20200611"/>
+      <repository id="jetty-9.4.30" location="https://download.eclipse.org/jetty/updates/jetty-bundles-9.x/9.4.30.v20200611/"/>
     </location>
     <location includeMode="slicer" includeAllPlatforms="false" includeSource="true" includeConfigurePhase="true" type="InstallableUnit">
       <unit id="com.google.gson" version="2.8.2.v20180104-1110"/>
@@ -41,14 +41,14 @@
       <unit id="net.i2p.crypto.eddsa.source" version="0.3.0.v20181102-1323"/>
       <unit id="org.apache.ant" version="1.10.8.v20200515-1239"/>
       <unit id="org.apache.ant.source" version="1.10.8.v20200515-1239"/>
-      <unit id="org.apache.commons.codec" version="1.13.0.v20200108-0001"/>
-      <unit id="org.apache.commons.codec.source" version="1.13.0.v20200108-0001"/>
+      <unit id="org.apache.commons.codec" version="1.14.0.v20200818-1422"/>
+      <unit id="org.apache.commons.codec.source" version="1.14.0.v20200818-1422"/>
       <unit id="org.apache.commons.compress" version="1.19.0.v20200106-2343"/>
       <unit id="org.apache.commons.compress.source" version="1.19.0.v20200106-2343"/>
       <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.10.v20200114-1512"/>
-      <unit id="org.apache.httpcomponents.httpclient.source" version="4.5.10.v20200114-1512"/>
+      <unit id="org.apache.httpcomponents.httpclient" version="4.5.10.v20200830-2311"/>
+      <unit id="org.apache.httpcomponents.httpclient.source" version="4.5.10.v20200830-2311"/>
       <unit id="org.apache.httpcomponents.httpcore" version="4.4.12.v20200108-1212"/>
       <unit id="org.apache.httpcomponents.httpcore.source" version="4.4.12.v20200108-1212"/>
       <unit id="org.apache.log4j" version="1.2.15.v201012070815"/>
@@ -84,7 +84,7 @@
       <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/R20200529191137/repository"/>
+      <repository location="https://download.eclipse.org/tools/orbit/downloads/drops/R20200831200620/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 717bc0a..c0a2db8 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.x.tpd"
-include "orbit/R20200529191137-2020-06.tpd"
+include "orbit/R20200831200620-2020-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 03e3641..75f893f 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,26 +1,26 @@
 <?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="1590935852">
+<target name="jgit-4.11" sequenceNumber="1598915260">
   <locations>
     <location includeMode="slicer" includeAllPlatforms="false" includeSource="true" includeConfigurePhase="true" type="InstallableUnit">
-      <unit id="org.eclipse.jetty.client" version="9.4.28.v20200408"/>
-      <unit id="org.eclipse.jetty.client.source" version="9.4.28.v20200408"/>
-      <unit id="org.eclipse.jetty.continuation" version="9.4.28.v20200408"/>
-      <unit id="org.eclipse.jetty.continuation.source" version="9.4.28.v20200408"/>
-      <unit id="org.eclipse.jetty.http" version="9.4.28.v20200408"/>
-      <unit id="org.eclipse.jetty.http.source" version="9.4.28.v20200408"/>
-      <unit id="org.eclipse.jetty.io" version="9.4.28.v20200408"/>
-      <unit id="org.eclipse.jetty.io.source" version="9.4.28.v20200408"/>
-      <unit id="org.eclipse.jetty.security" version="9.4.28.v20200408"/>
-      <unit id="org.eclipse.jetty.security.source" version="9.4.28.v20200408"/>
-      <unit id="org.eclipse.jetty.server" version="9.4.28.v20200408"/>
-      <unit id="org.eclipse.jetty.server.source" version="9.4.28.v20200408"/>
-      <unit id="org.eclipse.jetty.servlet" version="9.4.28.v20200408"/>
-      <unit id="org.eclipse.jetty.servlet.source" version="9.4.28.v20200408"/>
-      <unit id="org.eclipse.jetty.util" version="9.4.28.v20200408"/>
-      <unit id="org.eclipse.jetty.util.source" version="9.4.28.v20200408"/>
-      <repository id="jetty-9.4.25" location="https://download.eclipse.org/jetty/updates/jetty-bundles-9.x/9.4.28.v20200408/"/>
+      <unit id="org.eclipse.jetty.client" version="9.4.30.v20200611"/>
+      <unit id="org.eclipse.jetty.client.source" version="9.4.30.v20200611"/>
+      <unit id="org.eclipse.jetty.continuation" version="9.4.30.v20200611"/>
+      <unit id="org.eclipse.jetty.continuation.source" version="9.4.30.v20200611"/>
+      <unit id="org.eclipse.jetty.http" version="9.4.30.v20200611"/>
+      <unit id="org.eclipse.jetty.http.source" version="9.4.30.v20200611"/>
+      <unit id="org.eclipse.jetty.io" version="9.4.30.v20200611"/>
+      <unit id="org.eclipse.jetty.io.source" version="9.4.30.v20200611"/>
+      <unit id="org.eclipse.jetty.security" version="9.4.30.v20200611"/>
+      <unit id="org.eclipse.jetty.security.source" version="9.4.30.v20200611"/>
+      <unit id="org.eclipse.jetty.server" version="9.4.30.v20200611"/>
+      <unit id="org.eclipse.jetty.server.source" version="9.4.30.v20200611"/>
+      <unit id="org.eclipse.jetty.servlet" version="9.4.30.v20200611"/>
+      <unit id="org.eclipse.jetty.servlet.source" version="9.4.30.v20200611"/>
+      <unit id="org.eclipse.jetty.util" version="9.4.30.v20200611"/>
+      <unit id="org.eclipse.jetty.util.source" version="9.4.30.v20200611"/>
+      <repository id="jetty-9.4.30" location="https://download.eclipse.org/jetty/updates/jetty-bundles-9.x/9.4.30.v20200611/"/>
     </location>
     <location includeMode="slicer" includeAllPlatforms="false" includeSource="true" includeConfigurePhase="true" type="InstallableUnit">
       <unit id="com.google.gson" version="2.8.2.v20180104-1110"/>
@@ -41,14 +41,14 @@
       <unit id="net.i2p.crypto.eddsa.source" version="0.3.0.v20181102-1323"/>
       <unit id="org.apache.ant" version="1.10.8.v20200515-1239"/>
       <unit id="org.apache.ant.source" version="1.10.8.v20200515-1239"/>
-      <unit id="org.apache.commons.codec" version="1.13.0.v20200108-0001"/>
-      <unit id="org.apache.commons.codec.source" version="1.13.0.v20200108-0001"/>
+      <unit id="org.apache.commons.codec" version="1.14.0.v20200818-1422"/>
+      <unit id="org.apache.commons.codec.source" version="1.14.0.v20200818-1422"/>
       <unit id="org.apache.commons.compress" version="1.19.0.v20200106-2343"/>
       <unit id="org.apache.commons.compress.source" version="1.19.0.v20200106-2343"/>
       <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.10.v20200114-1512"/>
-      <unit id="org.apache.httpcomponents.httpclient.source" version="4.5.10.v20200114-1512"/>
+      <unit id="org.apache.httpcomponents.httpclient" version="4.5.10.v20200830-2311"/>
+      <unit id="org.apache.httpcomponents.httpclient.source" version="4.5.10.v20200830-2311"/>
       <unit id="org.apache.httpcomponents.httpcore" version="4.4.12.v20200108-1212"/>
       <unit id="org.apache.httpcomponents.httpcore.source" version="4.4.12.v20200108-1212"/>
       <unit id="org.apache.log4j" version="1.2.15.v201012070815"/>
@@ -84,7 +84,7 @@
       <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/R20200529191137/repository"/>
+      <repository location="https://download.eclipse.org/tools/orbit/downloads/drops/R20200831200620/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 9abd9b2..de349bd 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.x.tpd"
-include "orbit/R20200529191137-2020-06.tpd"
+include "orbit/R20200831200620-2020-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 2c09a17..2afbcb6 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,26 +1,26 @@
 <?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="1590935859">
+<target name="jgit-4.12" sequenceNumber="1598915260">
   <locations>
     <location includeMode="slicer" includeAllPlatforms="false" includeSource="true" includeConfigurePhase="true" type="InstallableUnit">
-      <unit id="org.eclipse.jetty.client" version="9.4.28.v20200408"/>
-      <unit id="org.eclipse.jetty.client.source" version="9.4.28.v20200408"/>
-      <unit id="org.eclipse.jetty.continuation" version="9.4.28.v20200408"/>
-      <unit id="org.eclipse.jetty.continuation.source" version="9.4.28.v20200408"/>
-      <unit id="org.eclipse.jetty.http" version="9.4.28.v20200408"/>
-      <unit id="org.eclipse.jetty.http.source" version="9.4.28.v20200408"/>
-      <unit id="org.eclipse.jetty.io" version="9.4.28.v20200408"/>
-      <unit id="org.eclipse.jetty.io.source" version="9.4.28.v20200408"/>
-      <unit id="org.eclipse.jetty.security" version="9.4.28.v20200408"/>
-      <unit id="org.eclipse.jetty.security.source" version="9.4.28.v20200408"/>
-      <unit id="org.eclipse.jetty.server" version="9.4.28.v20200408"/>
-      <unit id="org.eclipse.jetty.server.source" version="9.4.28.v20200408"/>
-      <unit id="org.eclipse.jetty.servlet" version="9.4.28.v20200408"/>
-      <unit id="org.eclipse.jetty.servlet.source" version="9.4.28.v20200408"/>
-      <unit id="org.eclipse.jetty.util" version="9.4.28.v20200408"/>
-      <unit id="org.eclipse.jetty.util.source" version="9.4.28.v20200408"/>
-      <repository id="jetty-9.4.25" location="https://download.eclipse.org/jetty/updates/jetty-bundles-9.x/9.4.28.v20200408/"/>
+      <unit id="org.eclipse.jetty.client" version="9.4.30.v20200611"/>
+      <unit id="org.eclipse.jetty.client.source" version="9.4.30.v20200611"/>
+      <unit id="org.eclipse.jetty.continuation" version="9.4.30.v20200611"/>
+      <unit id="org.eclipse.jetty.continuation.source" version="9.4.30.v20200611"/>
+      <unit id="org.eclipse.jetty.http" version="9.4.30.v20200611"/>
+      <unit id="org.eclipse.jetty.http.source" version="9.4.30.v20200611"/>
+      <unit id="org.eclipse.jetty.io" version="9.4.30.v20200611"/>
+      <unit id="org.eclipse.jetty.io.source" version="9.4.30.v20200611"/>
+      <unit id="org.eclipse.jetty.security" version="9.4.30.v20200611"/>
+      <unit id="org.eclipse.jetty.security.source" version="9.4.30.v20200611"/>
+      <unit id="org.eclipse.jetty.server" version="9.4.30.v20200611"/>
+      <unit id="org.eclipse.jetty.server.source" version="9.4.30.v20200611"/>
+      <unit id="org.eclipse.jetty.servlet" version="9.4.30.v20200611"/>
+      <unit id="org.eclipse.jetty.servlet.source" version="9.4.30.v20200611"/>
+      <unit id="org.eclipse.jetty.util" version="9.4.30.v20200611"/>
+      <unit id="org.eclipse.jetty.util.source" version="9.4.30.v20200611"/>
+      <repository id="jetty-9.4.30" location="https://download.eclipse.org/jetty/updates/jetty-bundles-9.x/9.4.30.v20200611/"/>
     </location>
     <location includeMode="slicer" includeAllPlatforms="false" includeSource="true" includeConfigurePhase="true" type="InstallableUnit">
       <unit id="com.google.gson" version="2.8.2.v20180104-1110"/>
@@ -41,14 +41,14 @@
       <unit id="net.i2p.crypto.eddsa.source" version="0.3.0.v20181102-1323"/>
       <unit id="org.apache.ant" version="1.10.8.v20200515-1239"/>
       <unit id="org.apache.ant.source" version="1.10.8.v20200515-1239"/>
-      <unit id="org.apache.commons.codec" version="1.13.0.v20200108-0001"/>
-      <unit id="org.apache.commons.codec.source" version="1.13.0.v20200108-0001"/>
+      <unit id="org.apache.commons.codec" version="1.14.0.v20200818-1422"/>
+      <unit id="org.apache.commons.codec.source" version="1.14.0.v20200818-1422"/>
       <unit id="org.apache.commons.compress" version="1.19.0.v20200106-2343"/>
       <unit id="org.apache.commons.compress.source" version="1.19.0.v20200106-2343"/>
       <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.10.v20200114-1512"/>
-      <unit id="org.apache.httpcomponents.httpclient.source" version="4.5.10.v20200114-1512"/>
+      <unit id="org.apache.httpcomponents.httpclient" version="4.5.10.v20200830-2311"/>
+      <unit id="org.apache.httpcomponents.httpclient.source" version="4.5.10.v20200830-2311"/>
       <unit id="org.apache.httpcomponents.httpcore" version="4.4.12.v20200108-1212"/>
       <unit id="org.apache.httpcomponents.httpcore.source" version="4.4.12.v20200108-1212"/>
       <unit id="org.apache.log4j" version="1.2.15.v201012070815"/>
@@ -84,7 +84,7 @@
       <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/R20200529191137/repository"/>
+      <repository location="https://download.eclipse.org/tools/orbit/downloads/drops/R20200831200620/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 e668a9d..4243073 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.x.tpd"
-include "orbit/R20200529191137-2020-06.tpd"
+include "orbit/R20200831200620-2020-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
index b92beb4..34c497a 100644
--- 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
@@ -1,26 +1,26 @@
 <?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="1590935871">
+<target name="jgit-4.13" sequenceNumber="1598915260">
   <locations>
     <location includeMode="slicer" includeAllPlatforms="false" includeSource="true" includeConfigurePhase="true" type="InstallableUnit">
-      <unit id="org.eclipse.jetty.client" version="9.4.28.v20200408"/>
-      <unit id="org.eclipse.jetty.client.source" version="9.4.28.v20200408"/>
-      <unit id="org.eclipse.jetty.continuation" version="9.4.28.v20200408"/>
-      <unit id="org.eclipse.jetty.continuation.source" version="9.4.28.v20200408"/>
-      <unit id="org.eclipse.jetty.http" version="9.4.28.v20200408"/>
-      <unit id="org.eclipse.jetty.http.source" version="9.4.28.v20200408"/>
-      <unit id="org.eclipse.jetty.io" version="9.4.28.v20200408"/>
-      <unit id="org.eclipse.jetty.io.source" version="9.4.28.v20200408"/>
-      <unit id="org.eclipse.jetty.security" version="9.4.28.v20200408"/>
-      <unit id="org.eclipse.jetty.security.source" version="9.4.28.v20200408"/>
-      <unit id="org.eclipse.jetty.server" version="9.4.28.v20200408"/>
-      <unit id="org.eclipse.jetty.server.source" version="9.4.28.v20200408"/>
-      <unit id="org.eclipse.jetty.servlet" version="9.4.28.v20200408"/>
-      <unit id="org.eclipse.jetty.servlet.source" version="9.4.28.v20200408"/>
-      <unit id="org.eclipse.jetty.util" version="9.4.28.v20200408"/>
-      <unit id="org.eclipse.jetty.util.source" version="9.4.28.v20200408"/>
-      <repository id="jetty-9.4.25" location="https://download.eclipse.org/jetty/updates/jetty-bundles-9.x/9.4.28.v20200408/"/>
+      <unit id="org.eclipse.jetty.client" version="9.4.30.v20200611"/>
+      <unit id="org.eclipse.jetty.client.source" version="9.4.30.v20200611"/>
+      <unit id="org.eclipse.jetty.continuation" version="9.4.30.v20200611"/>
+      <unit id="org.eclipse.jetty.continuation.source" version="9.4.30.v20200611"/>
+      <unit id="org.eclipse.jetty.http" version="9.4.30.v20200611"/>
+      <unit id="org.eclipse.jetty.http.source" version="9.4.30.v20200611"/>
+      <unit id="org.eclipse.jetty.io" version="9.4.30.v20200611"/>
+      <unit id="org.eclipse.jetty.io.source" version="9.4.30.v20200611"/>
+      <unit id="org.eclipse.jetty.security" version="9.4.30.v20200611"/>
+      <unit id="org.eclipse.jetty.security.source" version="9.4.30.v20200611"/>
+      <unit id="org.eclipse.jetty.server" version="9.4.30.v20200611"/>
+      <unit id="org.eclipse.jetty.server.source" version="9.4.30.v20200611"/>
+      <unit id="org.eclipse.jetty.servlet" version="9.4.30.v20200611"/>
+      <unit id="org.eclipse.jetty.servlet.source" version="9.4.30.v20200611"/>
+      <unit id="org.eclipse.jetty.util" version="9.4.30.v20200611"/>
+      <unit id="org.eclipse.jetty.util.source" version="9.4.30.v20200611"/>
+      <repository id="jetty-9.4.30" location="https://download.eclipse.org/jetty/updates/jetty-bundles-9.x/9.4.30.v20200611/"/>
     </location>
     <location includeMode="slicer" includeAllPlatforms="false" includeSource="true" includeConfigurePhase="true" type="InstallableUnit">
       <unit id="com.google.gson" version="2.8.2.v20180104-1110"/>
@@ -41,14 +41,14 @@
       <unit id="net.i2p.crypto.eddsa.source" version="0.3.0.v20181102-1323"/>
       <unit id="org.apache.ant" version="1.10.8.v20200515-1239"/>
       <unit id="org.apache.ant.source" version="1.10.8.v20200515-1239"/>
-      <unit id="org.apache.commons.codec" version="1.13.0.v20200108-0001"/>
-      <unit id="org.apache.commons.codec.source" version="1.13.0.v20200108-0001"/>
+      <unit id="org.apache.commons.codec" version="1.14.0.v20200818-1422"/>
+      <unit id="org.apache.commons.codec.source" version="1.14.0.v20200818-1422"/>
       <unit id="org.apache.commons.compress" version="1.19.0.v20200106-2343"/>
       <unit id="org.apache.commons.compress.source" version="1.19.0.v20200106-2343"/>
       <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.10.v20200114-1512"/>
-      <unit id="org.apache.httpcomponents.httpclient.source" version="4.5.10.v20200114-1512"/>
+      <unit id="org.apache.httpcomponents.httpclient" version="4.5.10.v20200830-2311"/>
+      <unit id="org.apache.httpcomponents.httpclient.source" version="4.5.10.v20200830-2311"/>
       <unit id="org.apache.httpcomponents.httpcore" version="4.4.12.v20200108-1212"/>
       <unit id="org.apache.httpcomponents.httpcore.source" version="4.4.12.v20200108-1212"/>
       <unit id="org.apache.log4j" version="1.2.15.v201012070815"/>
@@ -84,7 +84,7 @@
       <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/R20200529191137/repository"/>
+      <repository location="https://download.eclipse.org/tools/orbit/downloads/drops/R20200831200620/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.13.tpd b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.13.tpd
index 0499e3f..d886fd4 100644
--- 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
@@ -1,7 +1,7 @@
 target "jgit-4.13" with source configurePhase
 
 include "projects/jetty-9.4.x.tpd"
-include "orbit/R20200529191137-2020-06.tpd"
+include "orbit/R20200831200620-2020-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.14.target b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.14.target
index 6ab40f0..33bfc43 100644
--- a/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.14.target
+++ b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.14.target
@@ -1,26 +1,26 @@
 <?xml version="1.0" encoding="UTF-8" standalone="no"?>
 <?pde?>
 <!-- generated with https://github.com/eclipse-cbi/targetplatform-dsl -->
-<target name="jgit-4.14-staging" sequenceNumber="1590935878">
+<target name="jgit-4.14" sequenceNumber="1598915258">
   <locations>
     <location includeMode="slicer" includeAllPlatforms="false" includeSource="true" includeConfigurePhase="true" type="InstallableUnit">
-      <unit id="org.eclipse.jetty.client" version="9.4.28.v20200408"/>
-      <unit id="org.eclipse.jetty.client.source" version="9.4.28.v20200408"/>
-      <unit id="org.eclipse.jetty.continuation" version="9.4.28.v20200408"/>
-      <unit id="org.eclipse.jetty.continuation.source" version="9.4.28.v20200408"/>
-      <unit id="org.eclipse.jetty.http" version="9.4.28.v20200408"/>
-      <unit id="org.eclipse.jetty.http.source" version="9.4.28.v20200408"/>
-      <unit id="org.eclipse.jetty.io" version="9.4.28.v20200408"/>
-      <unit id="org.eclipse.jetty.io.source" version="9.4.28.v20200408"/>
-      <unit id="org.eclipse.jetty.security" version="9.4.28.v20200408"/>
-      <unit id="org.eclipse.jetty.security.source" version="9.4.28.v20200408"/>
-      <unit id="org.eclipse.jetty.server" version="9.4.28.v20200408"/>
-      <unit id="org.eclipse.jetty.server.source" version="9.4.28.v20200408"/>
-      <unit id="org.eclipse.jetty.servlet" version="9.4.28.v20200408"/>
-      <unit id="org.eclipse.jetty.servlet.source" version="9.4.28.v20200408"/>
-      <unit id="org.eclipse.jetty.util" version="9.4.28.v20200408"/>
-      <unit id="org.eclipse.jetty.util.source" version="9.4.28.v20200408"/>
-      <repository id="jetty-9.4.25" location="https://download.eclipse.org/jetty/updates/jetty-bundles-9.x/9.4.28.v20200408/"/>
+      <unit id="org.eclipse.jetty.client" version="9.4.30.v20200611"/>
+      <unit id="org.eclipse.jetty.client.source" version="9.4.30.v20200611"/>
+      <unit id="org.eclipse.jetty.continuation" version="9.4.30.v20200611"/>
+      <unit id="org.eclipse.jetty.continuation.source" version="9.4.30.v20200611"/>
+      <unit id="org.eclipse.jetty.http" version="9.4.30.v20200611"/>
+      <unit id="org.eclipse.jetty.http.source" version="9.4.30.v20200611"/>
+      <unit id="org.eclipse.jetty.io" version="9.4.30.v20200611"/>
+      <unit id="org.eclipse.jetty.io.source" version="9.4.30.v20200611"/>
+      <unit id="org.eclipse.jetty.security" version="9.4.30.v20200611"/>
+      <unit id="org.eclipse.jetty.security.source" version="9.4.30.v20200611"/>
+      <unit id="org.eclipse.jetty.server" version="9.4.30.v20200611"/>
+      <unit id="org.eclipse.jetty.server.source" version="9.4.30.v20200611"/>
+      <unit id="org.eclipse.jetty.servlet" version="9.4.30.v20200611"/>
+      <unit id="org.eclipse.jetty.servlet.source" version="9.4.30.v20200611"/>
+      <unit id="org.eclipse.jetty.util" version="9.4.30.v20200611"/>
+      <unit id="org.eclipse.jetty.util.source" version="9.4.30.v20200611"/>
+      <repository id="jetty-9.4.30" location="https://download.eclipse.org/jetty/updates/jetty-bundles-9.x/9.4.30.v20200611/"/>
     </location>
     <location includeMode="slicer" includeAllPlatforms="false" includeSource="true" includeConfigurePhase="true" type="InstallableUnit">
       <unit id="com.google.gson" version="2.8.2.v20180104-1110"/>
@@ -41,14 +41,14 @@
       <unit id="net.i2p.crypto.eddsa.source" version="0.3.0.v20181102-1323"/>
       <unit id="org.apache.ant" version="1.10.8.v20200515-1239"/>
       <unit id="org.apache.ant.source" version="1.10.8.v20200515-1239"/>
-      <unit id="org.apache.commons.codec" version="1.13.0.v20200108-0001"/>
-      <unit id="org.apache.commons.codec.source" version="1.13.0.v20200108-0001"/>
+      <unit id="org.apache.commons.codec" version="1.14.0.v20200818-1422"/>
+      <unit id="org.apache.commons.codec.source" version="1.14.0.v20200818-1422"/>
       <unit id="org.apache.commons.compress" version="1.19.0.v20200106-2343"/>
       <unit id="org.apache.commons.compress.source" version="1.19.0.v20200106-2343"/>
       <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.10.v20200114-1512"/>
-      <unit id="org.apache.httpcomponents.httpclient.source" version="4.5.10.v20200114-1512"/>
+      <unit id="org.apache.httpcomponents.httpclient" version="4.5.10.v20200830-2311"/>
+      <unit id="org.apache.httpcomponents.httpclient.source" version="4.5.10.v20200830-2311"/>
       <unit id="org.apache.httpcomponents.httpcore" version="4.4.12.v20200108-1212"/>
       <unit id="org.apache.httpcomponents.httpcore.source" version="4.4.12.v20200108-1212"/>
       <unit id="org.apache.log4j" version="1.2.15.v201012070815"/>
@@ -84,7 +84,7 @@
       <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/R20200529191137/repository"/>
+      <repository location="https://download.eclipse.org/tools/orbit/downloads/drops/R20200831200620/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.14.tpd b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.14.tpd
index c2fa119..eb92809 100644
--- a/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.14.tpd
+++ b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.14.tpd
@@ -1,7 +1,7 @@
-target "jgit-4.14-staging" with source configurePhase
+target "jgit-4.14" with source configurePhase
 
 include "projects/jetty-9.4.x.tpd"
-include "orbit/R20200529191137-2020-06.tpd"
+include "orbit/R20200831200620-2020-09.tpd"
 
 location "https://download.eclipse.org/releases/2019-12/201912181000/" {
 	org.eclipse.osgi lazy
diff --git a/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.15.target b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.15.target
index a7ca0dc..03b5cb7 100644
--- a/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.15.target
+++ b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.15.target
@@ -1,26 +1,26 @@
 <?xml version="1.0" encoding="UTF-8" standalone="no"?>
 <?pde?>
 <!-- generated with https://github.com/eclipse-cbi/targetplatform-dsl -->
-<target name="jgit-4.15" sequenceNumber="1590935883">
+<target name="jgit-4.15" sequenceNumber="1598915258">
   <locations>
     <location includeMode="slicer" includeAllPlatforms="false" includeSource="true" includeConfigurePhase="true" type="InstallableUnit">
-      <unit id="org.eclipse.jetty.client" version="9.4.28.v20200408"/>
-      <unit id="org.eclipse.jetty.client.source" version="9.4.28.v20200408"/>
-      <unit id="org.eclipse.jetty.continuation" version="9.4.28.v20200408"/>
-      <unit id="org.eclipse.jetty.continuation.source" version="9.4.28.v20200408"/>
-      <unit id="org.eclipse.jetty.http" version="9.4.28.v20200408"/>
-      <unit id="org.eclipse.jetty.http.source" version="9.4.28.v20200408"/>
-      <unit id="org.eclipse.jetty.io" version="9.4.28.v20200408"/>
-      <unit id="org.eclipse.jetty.io.source" version="9.4.28.v20200408"/>
-      <unit id="org.eclipse.jetty.security" version="9.4.28.v20200408"/>
-      <unit id="org.eclipse.jetty.security.source" version="9.4.28.v20200408"/>
-      <unit id="org.eclipse.jetty.server" version="9.4.28.v20200408"/>
-      <unit id="org.eclipse.jetty.server.source" version="9.4.28.v20200408"/>
-      <unit id="org.eclipse.jetty.servlet" version="9.4.28.v20200408"/>
-      <unit id="org.eclipse.jetty.servlet.source" version="9.4.28.v20200408"/>
-      <unit id="org.eclipse.jetty.util" version="9.4.28.v20200408"/>
-      <unit id="org.eclipse.jetty.util.source" version="9.4.28.v20200408"/>
-      <repository id="jetty-9.4.25" location="https://download.eclipse.org/jetty/updates/jetty-bundles-9.x/9.4.28.v20200408/"/>
+      <unit id="org.eclipse.jetty.client" version="9.4.30.v20200611"/>
+      <unit id="org.eclipse.jetty.client.source" version="9.4.30.v20200611"/>
+      <unit id="org.eclipse.jetty.continuation" version="9.4.30.v20200611"/>
+      <unit id="org.eclipse.jetty.continuation.source" version="9.4.30.v20200611"/>
+      <unit id="org.eclipse.jetty.http" version="9.4.30.v20200611"/>
+      <unit id="org.eclipse.jetty.http.source" version="9.4.30.v20200611"/>
+      <unit id="org.eclipse.jetty.io" version="9.4.30.v20200611"/>
+      <unit id="org.eclipse.jetty.io.source" version="9.4.30.v20200611"/>
+      <unit id="org.eclipse.jetty.security" version="9.4.30.v20200611"/>
+      <unit id="org.eclipse.jetty.security.source" version="9.4.30.v20200611"/>
+      <unit id="org.eclipse.jetty.server" version="9.4.30.v20200611"/>
+      <unit id="org.eclipse.jetty.server.source" version="9.4.30.v20200611"/>
+      <unit id="org.eclipse.jetty.servlet" version="9.4.30.v20200611"/>
+      <unit id="org.eclipse.jetty.servlet.source" version="9.4.30.v20200611"/>
+      <unit id="org.eclipse.jetty.util" version="9.4.30.v20200611"/>
+      <unit id="org.eclipse.jetty.util.source" version="9.4.30.v20200611"/>
+      <repository id="jetty-9.4.30" location="https://download.eclipse.org/jetty/updates/jetty-bundles-9.x/9.4.30.v20200611/"/>
     </location>
     <location includeMode="slicer" includeAllPlatforms="false" includeSource="true" includeConfigurePhase="true" type="InstallableUnit">
       <unit id="com.google.gson" version="2.8.2.v20180104-1110"/>
@@ -41,14 +41,14 @@
       <unit id="net.i2p.crypto.eddsa.source" version="0.3.0.v20181102-1323"/>
       <unit id="org.apache.ant" version="1.10.8.v20200515-1239"/>
       <unit id="org.apache.ant.source" version="1.10.8.v20200515-1239"/>
-      <unit id="org.apache.commons.codec" version="1.13.0.v20200108-0001"/>
-      <unit id="org.apache.commons.codec.source" version="1.13.0.v20200108-0001"/>
+      <unit id="org.apache.commons.codec" version="1.14.0.v20200818-1422"/>
+      <unit id="org.apache.commons.codec.source" version="1.14.0.v20200818-1422"/>
       <unit id="org.apache.commons.compress" version="1.19.0.v20200106-2343"/>
       <unit id="org.apache.commons.compress.source" version="1.19.0.v20200106-2343"/>
       <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.10.v20200114-1512"/>
-      <unit id="org.apache.httpcomponents.httpclient.source" version="4.5.10.v20200114-1512"/>
+      <unit id="org.apache.httpcomponents.httpclient" version="4.5.10.v20200830-2311"/>
+      <unit id="org.apache.httpcomponents.httpclient.source" version="4.5.10.v20200830-2311"/>
       <unit id="org.apache.httpcomponents.httpcore" version="4.4.12.v20200108-1212"/>
       <unit id="org.apache.httpcomponents.httpcore.source" version="4.4.12.v20200108-1212"/>
       <unit id="org.apache.log4j" version="1.2.15.v201012070815"/>
@@ -84,7 +84,7 @@
       <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/R20200529191137/repository"/>
+      <repository location="https://download.eclipse.org/tools/orbit/downloads/drops/R20200831200620/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.15.tpd b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.15.tpd
index ff55a7d..95249b4 100644
--- a/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.15.tpd
+++ b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.15.tpd
@@ -1,7 +1,7 @@
 target "jgit-4.15" with source configurePhase
 
 include "projects/jetty-9.4.x.tpd"
-include "orbit/R20200529191137-2020-06.tpd"
+include "orbit/R20200831200620-2020-09.tpd"
 
 location "https://download.eclipse.org/releases/2020-03/202003181000/" {
 	org.eclipse.osgi lazy
diff --git a/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.16-staging.tpd b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.16-staging.tpd
deleted file mode 100644
index 777aaf3..0000000
--- a/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.16-staging.tpd
+++ /dev/null
@@ -1,8 +0,0 @@
-target "jgit-4.15" with source configurePhase
-
-include "projects/jetty-9.4.x.tpd"
-include "orbit/R20200529191137-2020-06.tpd"
-
-location "https://download.eclipse.org/staging/2020-06/" {
-	org.eclipse.osgi lazy
-}
diff --git a/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.16-staging.target b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.16.target
similarity index 76%
copy from org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.16-staging.target
copy to org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.16.target
index 0aff796..a7470c1 100644
--- a/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.16-staging.target
+++ b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.16.target
@@ -1,26 +1,26 @@
 <?xml version="1.0" encoding="UTF-8" standalone="no"?>
 <?pde?>
 <!-- generated with https://github.com/eclipse-cbi/targetplatform-dsl -->
-<target name="jgit-4.15" sequenceNumber="1590935890">
+<target name="jgit-4.16" sequenceNumber="1598915255">
   <locations>
     <location includeMode="slicer" includeAllPlatforms="false" includeSource="true" includeConfigurePhase="true" type="InstallableUnit">
-      <unit id="org.eclipse.jetty.client" version="9.4.28.v20200408"/>
-      <unit id="org.eclipse.jetty.client.source" version="9.4.28.v20200408"/>
-      <unit id="org.eclipse.jetty.continuation" version="9.4.28.v20200408"/>
-      <unit id="org.eclipse.jetty.continuation.source" version="9.4.28.v20200408"/>
-      <unit id="org.eclipse.jetty.http" version="9.4.28.v20200408"/>
-      <unit id="org.eclipse.jetty.http.source" version="9.4.28.v20200408"/>
-      <unit id="org.eclipse.jetty.io" version="9.4.28.v20200408"/>
-      <unit id="org.eclipse.jetty.io.source" version="9.4.28.v20200408"/>
-      <unit id="org.eclipse.jetty.security" version="9.4.28.v20200408"/>
-      <unit id="org.eclipse.jetty.security.source" version="9.4.28.v20200408"/>
-      <unit id="org.eclipse.jetty.server" version="9.4.28.v20200408"/>
-      <unit id="org.eclipse.jetty.server.source" version="9.4.28.v20200408"/>
-      <unit id="org.eclipse.jetty.servlet" version="9.4.28.v20200408"/>
-      <unit id="org.eclipse.jetty.servlet.source" version="9.4.28.v20200408"/>
-      <unit id="org.eclipse.jetty.util" version="9.4.28.v20200408"/>
-      <unit id="org.eclipse.jetty.util.source" version="9.4.28.v20200408"/>
-      <repository id="jetty-9.4.25" location="https://download.eclipse.org/jetty/updates/jetty-bundles-9.x/9.4.28.v20200408/"/>
+      <unit id="org.eclipse.jetty.client" version="9.4.30.v20200611"/>
+      <unit id="org.eclipse.jetty.client.source" version="9.4.30.v20200611"/>
+      <unit id="org.eclipse.jetty.continuation" version="9.4.30.v20200611"/>
+      <unit id="org.eclipse.jetty.continuation.source" version="9.4.30.v20200611"/>
+      <unit id="org.eclipse.jetty.http" version="9.4.30.v20200611"/>
+      <unit id="org.eclipse.jetty.http.source" version="9.4.30.v20200611"/>
+      <unit id="org.eclipse.jetty.io" version="9.4.30.v20200611"/>
+      <unit id="org.eclipse.jetty.io.source" version="9.4.30.v20200611"/>
+      <unit id="org.eclipse.jetty.security" version="9.4.30.v20200611"/>
+      <unit id="org.eclipse.jetty.security.source" version="9.4.30.v20200611"/>
+      <unit id="org.eclipse.jetty.server" version="9.4.30.v20200611"/>
+      <unit id="org.eclipse.jetty.server.source" version="9.4.30.v20200611"/>
+      <unit id="org.eclipse.jetty.servlet" version="9.4.30.v20200611"/>
+      <unit id="org.eclipse.jetty.servlet.source" version="9.4.30.v20200611"/>
+      <unit id="org.eclipse.jetty.util" version="9.4.30.v20200611"/>
+      <unit id="org.eclipse.jetty.util.source" version="9.4.30.v20200611"/>
+      <repository id="jetty-9.4.30" location="https://download.eclipse.org/jetty/updates/jetty-bundles-9.x/9.4.30.v20200611/"/>
     </location>
     <location includeMode="slicer" includeAllPlatforms="false" includeSource="true" includeConfigurePhase="true" type="InstallableUnit">
       <unit id="com.google.gson" version="2.8.2.v20180104-1110"/>
@@ -41,14 +41,14 @@
       <unit id="net.i2p.crypto.eddsa.source" version="0.3.0.v20181102-1323"/>
       <unit id="org.apache.ant" version="1.10.8.v20200515-1239"/>
       <unit id="org.apache.ant.source" version="1.10.8.v20200515-1239"/>
-      <unit id="org.apache.commons.codec" version="1.13.0.v20200108-0001"/>
-      <unit id="org.apache.commons.codec.source" version="1.13.0.v20200108-0001"/>
+      <unit id="org.apache.commons.codec" version="1.14.0.v20200818-1422"/>
+      <unit id="org.apache.commons.codec.source" version="1.14.0.v20200818-1422"/>
       <unit id="org.apache.commons.compress" version="1.19.0.v20200106-2343"/>
       <unit id="org.apache.commons.compress.source" version="1.19.0.v20200106-2343"/>
       <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.10.v20200114-1512"/>
-      <unit id="org.apache.httpcomponents.httpclient.source" version="4.5.10.v20200114-1512"/>
+      <unit id="org.apache.httpcomponents.httpclient" version="4.5.10.v20200830-2311"/>
+      <unit id="org.apache.httpcomponents.httpclient.source" version="4.5.10.v20200830-2311"/>
       <unit id="org.apache.httpcomponents.httpcore" version="4.4.12.v20200108-1212"/>
       <unit id="org.apache.httpcomponents.httpcore.source" version="4.4.12.v20200108-1212"/>
       <unit id="org.apache.log4j" version="1.2.15.v201012070815"/>
@@ -84,11 +84,11 @@
       <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/R20200529191137/repository"/>
+      <repository location="https://download.eclipse.org/tools/orbit/downloads/drops/R20200831200620/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/staging/2020-06/"/>
+      <repository location="https://download.eclipse.org/releases/2020-06/"/>
     </location>
   </locations>
 </target>
diff --git a/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.16.tpd b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.16.tpd
new file mode 100644
index 0000000..7e6caac
--- /dev/null
+++ b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.16.tpd
@@ -0,0 +1,8 @@
+target "jgit-4.16" with source configurePhase
+
+include "projects/jetty-9.4.x.tpd"
+include "orbit/R20200831200620-2020-09.tpd"
+
+location "https://download.eclipse.org/releases/2020-06/" {
+	org.eclipse.osgi lazy
+}
diff --git a/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.16-staging.target b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.17-staging.target
similarity index 77%
rename from org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.16-staging.target
rename to org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.17-staging.target
index 0aff796..79e0211 100644
--- a/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.16-staging.target
+++ b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.17-staging.target
@@ -1,26 +1,26 @@
 <?xml version="1.0" encoding="UTF-8" standalone="no"?>
 <?pde?>
 <!-- generated with https://github.com/eclipse-cbi/targetplatform-dsl -->
-<target name="jgit-4.15" sequenceNumber="1590935890">
+<target name="jgit-4.17-staging" sequenceNumber="1598916122">
   <locations>
     <location includeMode="slicer" includeAllPlatforms="false" includeSource="true" includeConfigurePhase="true" type="InstallableUnit">
-      <unit id="org.eclipse.jetty.client" version="9.4.28.v20200408"/>
-      <unit id="org.eclipse.jetty.client.source" version="9.4.28.v20200408"/>
-      <unit id="org.eclipse.jetty.continuation" version="9.4.28.v20200408"/>
-      <unit id="org.eclipse.jetty.continuation.source" version="9.4.28.v20200408"/>
-      <unit id="org.eclipse.jetty.http" version="9.4.28.v20200408"/>
-      <unit id="org.eclipse.jetty.http.source" version="9.4.28.v20200408"/>
-      <unit id="org.eclipse.jetty.io" version="9.4.28.v20200408"/>
-      <unit id="org.eclipse.jetty.io.source" version="9.4.28.v20200408"/>
-      <unit id="org.eclipse.jetty.security" version="9.4.28.v20200408"/>
-      <unit id="org.eclipse.jetty.security.source" version="9.4.28.v20200408"/>
-      <unit id="org.eclipse.jetty.server" version="9.4.28.v20200408"/>
-      <unit id="org.eclipse.jetty.server.source" version="9.4.28.v20200408"/>
-      <unit id="org.eclipse.jetty.servlet" version="9.4.28.v20200408"/>
-      <unit id="org.eclipse.jetty.servlet.source" version="9.4.28.v20200408"/>
-      <unit id="org.eclipse.jetty.util" version="9.4.28.v20200408"/>
-      <unit id="org.eclipse.jetty.util.source" version="9.4.28.v20200408"/>
-      <repository id="jetty-9.4.25" location="https://download.eclipse.org/jetty/updates/jetty-bundles-9.x/9.4.28.v20200408/"/>
+      <unit id="org.eclipse.jetty.client" version="9.4.30.v20200611"/>
+      <unit id="org.eclipse.jetty.client.source" version="9.4.30.v20200611"/>
+      <unit id="org.eclipse.jetty.continuation" version="9.4.30.v20200611"/>
+      <unit id="org.eclipse.jetty.continuation.source" version="9.4.30.v20200611"/>
+      <unit id="org.eclipse.jetty.http" version="9.4.30.v20200611"/>
+      <unit id="org.eclipse.jetty.http.source" version="9.4.30.v20200611"/>
+      <unit id="org.eclipse.jetty.io" version="9.4.30.v20200611"/>
+      <unit id="org.eclipse.jetty.io.source" version="9.4.30.v20200611"/>
+      <unit id="org.eclipse.jetty.security" version="9.4.30.v20200611"/>
+      <unit id="org.eclipse.jetty.security.source" version="9.4.30.v20200611"/>
+      <unit id="org.eclipse.jetty.server" version="9.4.30.v20200611"/>
+      <unit id="org.eclipse.jetty.server.source" version="9.4.30.v20200611"/>
+      <unit id="org.eclipse.jetty.servlet" version="9.4.30.v20200611"/>
+      <unit id="org.eclipse.jetty.servlet.source" version="9.4.30.v20200611"/>
+      <unit id="org.eclipse.jetty.util" version="9.4.30.v20200611"/>
+      <unit id="org.eclipse.jetty.util.source" version="9.4.30.v20200611"/>
+      <repository id="jetty-9.4.30" location="https://download.eclipse.org/jetty/updates/jetty-bundles-9.x/9.4.30.v20200611/"/>
     </location>
     <location includeMode="slicer" includeAllPlatforms="false" includeSource="true" includeConfigurePhase="true" type="InstallableUnit">
       <unit id="com.google.gson" version="2.8.2.v20180104-1110"/>
@@ -41,14 +41,14 @@
       <unit id="net.i2p.crypto.eddsa.source" version="0.3.0.v20181102-1323"/>
       <unit id="org.apache.ant" version="1.10.8.v20200515-1239"/>
       <unit id="org.apache.ant.source" version="1.10.8.v20200515-1239"/>
-      <unit id="org.apache.commons.codec" version="1.13.0.v20200108-0001"/>
-      <unit id="org.apache.commons.codec.source" version="1.13.0.v20200108-0001"/>
+      <unit id="org.apache.commons.codec" version="1.14.0.v20200818-1422"/>
+      <unit id="org.apache.commons.codec.source" version="1.14.0.v20200818-1422"/>
       <unit id="org.apache.commons.compress" version="1.19.0.v20200106-2343"/>
       <unit id="org.apache.commons.compress.source" version="1.19.0.v20200106-2343"/>
       <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.10.v20200114-1512"/>
-      <unit id="org.apache.httpcomponents.httpclient.source" version="4.5.10.v20200114-1512"/>
+      <unit id="org.apache.httpcomponents.httpclient" version="4.5.10.v20200830-2311"/>
+      <unit id="org.apache.httpcomponents.httpclient.source" version="4.5.10.v20200830-2311"/>
       <unit id="org.apache.httpcomponents.httpcore" version="4.4.12.v20200108-1212"/>
       <unit id="org.apache.httpcomponents.httpcore.source" version="4.4.12.v20200108-1212"/>
       <unit id="org.apache.log4j" version="1.2.15.v201012070815"/>
@@ -84,11 +84,11 @@
       <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/R20200529191137/repository"/>
+      <repository location="https://download.eclipse.org/tools/orbit/downloads/drops/R20200831200620/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/staging/2020-06/"/>
+      <repository location="https://download.eclipse.org/staging/2020-09/"/>
     </location>
   </locations>
 </target>
diff --git a/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.17-staging.tpd b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.17-staging.tpd
new file mode 100644
index 0000000..07745cb
--- /dev/null
+++ b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.17-staging.tpd
@@ -0,0 +1,8 @@
+target "jgit-4.17-staging" with source configurePhase
+
+include "projects/jetty-9.4.x.tpd"
+include "orbit/R20200831200620-2020-09.tpd"
+
+location "https://download.eclipse.org/staging/2020-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 b07ddd0..566ef33 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,26 +1,26 @@
 <?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="1590935806">
+<target name="jgit-4.6" sequenceNumber="1598915275">
   <locations>
     <location includeMode="slicer" includeAllPlatforms="false" includeSource="true" includeConfigurePhase="true" type="InstallableUnit">
-      <unit id="org.eclipse.jetty.client" version="9.4.28.v20200408"/>
-      <unit id="org.eclipse.jetty.client.source" version="9.4.28.v20200408"/>
-      <unit id="org.eclipse.jetty.continuation" version="9.4.28.v20200408"/>
-      <unit id="org.eclipse.jetty.continuation.source" version="9.4.28.v20200408"/>
-      <unit id="org.eclipse.jetty.http" version="9.4.28.v20200408"/>
-      <unit id="org.eclipse.jetty.http.source" version="9.4.28.v20200408"/>
-      <unit id="org.eclipse.jetty.io" version="9.4.28.v20200408"/>
-      <unit id="org.eclipse.jetty.io.source" version="9.4.28.v20200408"/>
-      <unit id="org.eclipse.jetty.security" version="9.4.28.v20200408"/>
-      <unit id="org.eclipse.jetty.security.source" version="9.4.28.v20200408"/>
-      <unit id="org.eclipse.jetty.server" version="9.4.28.v20200408"/>
-      <unit id="org.eclipse.jetty.server.source" version="9.4.28.v20200408"/>
-      <unit id="org.eclipse.jetty.servlet" version="9.4.28.v20200408"/>
-      <unit id="org.eclipse.jetty.servlet.source" version="9.4.28.v20200408"/>
-      <unit id="org.eclipse.jetty.util" version="9.4.28.v20200408"/>
-      <unit id="org.eclipse.jetty.util.source" version="9.4.28.v20200408"/>
-      <repository id="jetty-9.4.25" location="https://download.eclipse.org/jetty/updates/jetty-bundles-9.x/9.4.28.v20200408/"/>
+      <unit id="org.eclipse.jetty.client" version="9.4.30.v20200611"/>
+      <unit id="org.eclipse.jetty.client.source" version="9.4.30.v20200611"/>
+      <unit id="org.eclipse.jetty.continuation" version="9.4.30.v20200611"/>
+      <unit id="org.eclipse.jetty.continuation.source" version="9.4.30.v20200611"/>
+      <unit id="org.eclipse.jetty.http" version="9.4.30.v20200611"/>
+      <unit id="org.eclipse.jetty.http.source" version="9.4.30.v20200611"/>
+      <unit id="org.eclipse.jetty.io" version="9.4.30.v20200611"/>
+      <unit id="org.eclipse.jetty.io.source" version="9.4.30.v20200611"/>
+      <unit id="org.eclipse.jetty.security" version="9.4.30.v20200611"/>
+      <unit id="org.eclipse.jetty.security.source" version="9.4.30.v20200611"/>
+      <unit id="org.eclipse.jetty.server" version="9.4.30.v20200611"/>
+      <unit id="org.eclipse.jetty.server.source" version="9.4.30.v20200611"/>
+      <unit id="org.eclipse.jetty.servlet" version="9.4.30.v20200611"/>
+      <unit id="org.eclipse.jetty.servlet.source" version="9.4.30.v20200611"/>
+      <unit id="org.eclipse.jetty.util" version="9.4.30.v20200611"/>
+      <unit id="org.eclipse.jetty.util.source" version="9.4.30.v20200611"/>
+      <repository id="jetty-9.4.30" location="https://download.eclipse.org/jetty/updates/jetty-bundles-9.x/9.4.30.v20200611/"/>
     </location>
     <location includeMode="slicer" includeAllPlatforms="false" includeSource="true" includeConfigurePhase="true" type="InstallableUnit">
       <unit id="com.google.gson" version="2.8.2.v20180104-1110"/>
@@ -41,14 +41,14 @@
       <unit id="net.i2p.crypto.eddsa.source" version="0.3.0.v20181102-1323"/>
       <unit id="org.apache.ant" version="1.10.8.v20200515-1239"/>
       <unit id="org.apache.ant.source" version="1.10.8.v20200515-1239"/>
-      <unit id="org.apache.commons.codec" version="1.13.0.v20200108-0001"/>
-      <unit id="org.apache.commons.codec.source" version="1.13.0.v20200108-0001"/>
+      <unit id="org.apache.commons.codec" version="1.14.0.v20200818-1422"/>
+      <unit id="org.apache.commons.codec.source" version="1.14.0.v20200818-1422"/>
       <unit id="org.apache.commons.compress" version="1.19.0.v20200106-2343"/>
       <unit id="org.apache.commons.compress.source" version="1.19.0.v20200106-2343"/>
       <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.10.v20200114-1512"/>
-      <unit id="org.apache.httpcomponents.httpclient.source" version="4.5.10.v20200114-1512"/>
+      <unit id="org.apache.httpcomponents.httpclient" version="4.5.10.v20200830-2311"/>
+      <unit id="org.apache.httpcomponents.httpclient.source" version="4.5.10.v20200830-2311"/>
       <unit id="org.apache.httpcomponents.httpcore" version="4.4.12.v20200108-1212"/>
       <unit id="org.apache.httpcomponents.httpcore.source" version="4.4.12.v20200108-1212"/>
       <unit id="org.apache.log4j" version="1.2.15.v201012070815"/>
@@ -84,7 +84,7 @@
       <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/R20200529191137/repository"/>
+      <repository location="https://download.eclipse.org/tools/orbit/downloads/drops/R20200831200620/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 d0c3c1b..d0024b6 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.x.tpd"
-include "orbit/R20200529191137-2020-06.tpd"
+include "orbit/R20200831200620-2020-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 351b0fc..5a690e8 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,26 +1,26 @@
 <?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="1590935820">
+<target name="jgit-4.7" sequenceNumber="1598915265">
   <locations>
     <location includeMode="slicer" includeAllPlatforms="false" includeSource="true" includeConfigurePhase="true" type="InstallableUnit">
-      <unit id="org.eclipse.jetty.client" version="9.4.28.v20200408"/>
-      <unit id="org.eclipse.jetty.client.source" version="9.4.28.v20200408"/>
-      <unit id="org.eclipse.jetty.continuation" version="9.4.28.v20200408"/>
-      <unit id="org.eclipse.jetty.continuation.source" version="9.4.28.v20200408"/>
-      <unit id="org.eclipse.jetty.http" version="9.4.28.v20200408"/>
-      <unit id="org.eclipse.jetty.http.source" version="9.4.28.v20200408"/>
-      <unit id="org.eclipse.jetty.io" version="9.4.28.v20200408"/>
-      <unit id="org.eclipse.jetty.io.source" version="9.4.28.v20200408"/>
-      <unit id="org.eclipse.jetty.security" version="9.4.28.v20200408"/>
-      <unit id="org.eclipse.jetty.security.source" version="9.4.28.v20200408"/>
-      <unit id="org.eclipse.jetty.server" version="9.4.28.v20200408"/>
-      <unit id="org.eclipse.jetty.server.source" version="9.4.28.v20200408"/>
-      <unit id="org.eclipse.jetty.servlet" version="9.4.28.v20200408"/>
-      <unit id="org.eclipse.jetty.servlet.source" version="9.4.28.v20200408"/>
-      <unit id="org.eclipse.jetty.util" version="9.4.28.v20200408"/>
-      <unit id="org.eclipse.jetty.util.source" version="9.4.28.v20200408"/>
-      <repository id="jetty-9.4.25" location="https://download.eclipse.org/jetty/updates/jetty-bundles-9.x/9.4.28.v20200408/"/>
+      <unit id="org.eclipse.jetty.client" version="9.4.30.v20200611"/>
+      <unit id="org.eclipse.jetty.client.source" version="9.4.30.v20200611"/>
+      <unit id="org.eclipse.jetty.continuation" version="9.4.30.v20200611"/>
+      <unit id="org.eclipse.jetty.continuation.source" version="9.4.30.v20200611"/>
+      <unit id="org.eclipse.jetty.http" version="9.4.30.v20200611"/>
+      <unit id="org.eclipse.jetty.http.source" version="9.4.30.v20200611"/>
+      <unit id="org.eclipse.jetty.io" version="9.4.30.v20200611"/>
+      <unit id="org.eclipse.jetty.io.source" version="9.4.30.v20200611"/>
+      <unit id="org.eclipse.jetty.security" version="9.4.30.v20200611"/>
+      <unit id="org.eclipse.jetty.security.source" version="9.4.30.v20200611"/>
+      <unit id="org.eclipse.jetty.server" version="9.4.30.v20200611"/>
+      <unit id="org.eclipse.jetty.server.source" version="9.4.30.v20200611"/>
+      <unit id="org.eclipse.jetty.servlet" version="9.4.30.v20200611"/>
+      <unit id="org.eclipse.jetty.servlet.source" version="9.4.30.v20200611"/>
+      <unit id="org.eclipse.jetty.util" version="9.4.30.v20200611"/>
+      <unit id="org.eclipse.jetty.util.source" version="9.4.30.v20200611"/>
+      <repository id="jetty-9.4.30" location="https://download.eclipse.org/jetty/updates/jetty-bundles-9.x/9.4.30.v20200611/"/>
     </location>
     <location includeMode="slicer" includeAllPlatforms="false" includeSource="true" includeConfigurePhase="true" type="InstallableUnit">
       <unit id="com.google.gson" version="2.8.2.v20180104-1110"/>
@@ -41,14 +41,14 @@
       <unit id="net.i2p.crypto.eddsa.source" version="0.3.0.v20181102-1323"/>
       <unit id="org.apache.ant" version="1.10.8.v20200515-1239"/>
       <unit id="org.apache.ant.source" version="1.10.8.v20200515-1239"/>
-      <unit id="org.apache.commons.codec" version="1.13.0.v20200108-0001"/>
-      <unit id="org.apache.commons.codec.source" version="1.13.0.v20200108-0001"/>
+      <unit id="org.apache.commons.codec" version="1.14.0.v20200818-1422"/>
+      <unit id="org.apache.commons.codec.source" version="1.14.0.v20200818-1422"/>
       <unit id="org.apache.commons.compress" version="1.19.0.v20200106-2343"/>
       <unit id="org.apache.commons.compress.source" version="1.19.0.v20200106-2343"/>
       <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.10.v20200114-1512"/>
-      <unit id="org.apache.httpcomponents.httpclient.source" version="4.5.10.v20200114-1512"/>
+      <unit id="org.apache.httpcomponents.httpclient" version="4.5.10.v20200830-2311"/>
+      <unit id="org.apache.httpcomponents.httpclient.source" version="4.5.10.v20200830-2311"/>
       <unit id="org.apache.httpcomponents.httpcore" version="4.4.12.v20200108-1212"/>
       <unit id="org.apache.httpcomponents.httpcore.source" version="4.4.12.v20200108-1212"/>
       <unit id="org.apache.log4j" version="1.2.15.v201012070815"/>
@@ -84,7 +84,7 @@
       <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/R20200529191137/repository"/>
+      <repository location="https://download.eclipse.org/tools/orbit/downloads/drops/R20200831200620/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 19790ff..ee9253f 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.x.tpd"
-include "orbit/R20200529191137-2020-06.tpd"
+include "orbit/R20200831200620-2020-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 be6108d..fe237d0 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,26 +1,26 @@
 <?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="1590935828">
+<target name="jgit-4.8" sequenceNumber="1598915261">
   <locations>
     <location includeMode="slicer" includeAllPlatforms="false" includeSource="true" includeConfigurePhase="true" type="InstallableUnit">
-      <unit id="org.eclipse.jetty.client" version="9.4.28.v20200408"/>
-      <unit id="org.eclipse.jetty.client.source" version="9.4.28.v20200408"/>
-      <unit id="org.eclipse.jetty.continuation" version="9.4.28.v20200408"/>
-      <unit id="org.eclipse.jetty.continuation.source" version="9.4.28.v20200408"/>
-      <unit id="org.eclipse.jetty.http" version="9.4.28.v20200408"/>
-      <unit id="org.eclipse.jetty.http.source" version="9.4.28.v20200408"/>
-      <unit id="org.eclipse.jetty.io" version="9.4.28.v20200408"/>
-      <unit id="org.eclipse.jetty.io.source" version="9.4.28.v20200408"/>
-      <unit id="org.eclipse.jetty.security" version="9.4.28.v20200408"/>
-      <unit id="org.eclipse.jetty.security.source" version="9.4.28.v20200408"/>
-      <unit id="org.eclipse.jetty.server" version="9.4.28.v20200408"/>
-      <unit id="org.eclipse.jetty.server.source" version="9.4.28.v20200408"/>
-      <unit id="org.eclipse.jetty.servlet" version="9.4.28.v20200408"/>
-      <unit id="org.eclipse.jetty.servlet.source" version="9.4.28.v20200408"/>
-      <unit id="org.eclipse.jetty.util" version="9.4.28.v20200408"/>
-      <unit id="org.eclipse.jetty.util.source" version="9.4.28.v20200408"/>
-      <repository id="jetty-9.4.25" location="https://download.eclipse.org/jetty/updates/jetty-bundles-9.x/9.4.28.v20200408/"/>
+      <unit id="org.eclipse.jetty.client" version="9.4.30.v20200611"/>
+      <unit id="org.eclipse.jetty.client.source" version="9.4.30.v20200611"/>
+      <unit id="org.eclipse.jetty.continuation" version="9.4.30.v20200611"/>
+      <unit id="org.eclipse.jetty.continuation.source" version="9.4.30.v20200611"/>
+      <unit id="org.eclipse.jetty.http" version="9.4.30.v20200611"/>
+      <unit id="org.eclipse.jetty.http.source" version="9.4.30.v20200611"/>
+      <unit id="org.eclipse.jetty.io" version="9.4.30.v20200611"/>
+      <unit id="org.eclipse.jetty.io.source" version="9.4.30.v20200611"/>
+      <unit id="org.eclipse.jetty.security" version="9.4.30.v20200611"/>
+      <unit id="org.eclipse.jetty.security.source" version="9.4.30.v20200611"/>
+      <unit id="org.eclipse.jetty.server" version="9.4.30.v20200611"/>
+      <unit id="org.eclipse.jetty.server.source" version="9.4.30.v20200611"/>
+      <unit id="org.eclipse.jetty.servlet" version="9.4.30.v20200611"/>
+      <unit id="org.eclipse.jetty.servlet.source" version="9.4.30.v20200611"/>
+      <unit id="org.eclipse.jetty.util" version="9.4.30.v20200611"/>
+      <unit id="org.eclipse.jetty.util.source" version="9.4.30.v20200611"/>
+      <repository id="jetty-9.4.30" location="https://download.eclipse.org/jetty/updates/jetty-bundles-9.x/9.4.30.v20200611/"/>
     </location>
     <location includeMode="slicer" includeAllPlatforms="false" includeSource="true" includeConfigurePhase="true" type="InstallableUnit">
       <unit id="com.google.gson" version="2.8.2.v20180104-1110"/>
@@ -41,14 +41,14 @@
       <unit id="net.i2p.crypto.eddsa.source" version="0.3.0.v20181102-1323"/>
       <unit id="org.apache.ant" version="1.10.8.v20200515-1239"/>
       <unit id="org.apache.ant.source" version="1.10.8.v20200515-1239"/>
-      <unit id="org.apache.commons.codec" version="1.13.0.v20200108-0001"/>
-      <unit id="org.apache.commons.codec.source" version="1.13.0.v20200108-0001"/>
+      <unit id="org.apache.commons.codec" version="1.14.0.v20200818-1422"/>
+      <unit id="org.apache.commons.codec.source" version="1.14.0.v20200818-1422"/>
       <unit id="org.apache.commons.compress" version="1.19.0.v20200106-2343"/>
       <unit id="org.apache.commons.compress.source" version="1.19.0.v20200106-2343"/>
       <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.10.v20200114-1512"/>
-      <unit id="org.apache.httpcomponents.httpclient.source" version="4.5.10.v20200114-1512"/>
+      <unit id="org.apache.httpcomponents.httpclient" version="4.5.10.v20200830-2311"/>
+      <unit id="org.apache.httpcomponents.httpclient.source" version="4.5.10.v20200830-2311"/>
       <unit id="org.apache.httpcomponents.httpcore" version="4.4.12.v20200108-1212"/>
       <unit id="org.apache.httpcomponents.httpcore.source" version="4.4.12.v20200108-1212"/>
       <unit id="org.apache.log4j" version="1.2.15.v201012070815"/>
@@ -84,7 +84,7 @@
       <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/R20200529191137/repository"/>
+      <repository location="https://download.eclipse.org/tools/orbit/downloads/drops/R20200831200620/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 5fe27fc..36c42f8 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.x.tpd"
-include "orbit/R20200529191137-2020-06.tpd"
+include "orbit/R20200831200620-2020-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 b9ad2cb..a812e7a 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,26 +1,26 @@
 <?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="1590935836">
+<target name="jgit-4.9" sequenceNumber="1598915260">
   <locations>
     <location includeMode="slicer" includeAllPlatforms="false" includeSource="true" includeConfigurePhase="true" type="InstallableUnit">
-      <unit id="org.eclipse.jetty.client" version="9.4.28.v20200408"/>
-      <unit id="org.eclipse.jetty.client.source" version="9.4.28.v20200408"/>
-      <unit id="org.eclipse.jetty.continuation" version="9.4.28.v20200408"/>
-      <unit id="org.eclipse.jetty.continuation.source" version="9.4.28.v20200408"/>
-      <unit id="org.eclipse.jetty.http" version="9.4.28.v20200408"/>
-      <unit id="org.eclipse.jetty.http.source" version="9.4.28.v20200408"/>
-      <unit id="org.eclipse.jetty.io" version="9.4.28.v20200408"/>
-      <unit id="org.eclipse.jetty.io.source" version="9.4.28.v20200408"/>
-      <unit id="org.eclipse.jetty.security" version="9.4.28.v20200408"/>
-      <unit id="org.eclipse.jetty.security.source" version="9.4.28.v20200408"/>
-      <unit id="org.eclipse.jetty.server" version="9.4.28.v20200408"/>
-      <unit id="org.eclipse.jetty.server.source" version="9.4.28.v20200408"/>
-      <unit id="org.eclipse.jetty.servlet" version="9.4.28.v20200408"/>
-      <unit id="org.eclipse.jetty.servlet.source" version="9.4.28.v20200408"/>
-      <unit id="org.eclipse.jetty.util" version="9.4.28.v20200408"/>
-      <unit id="org.eclipse.jetty.util.source" version="9.4.28.v20200408"/>
-      <repository id="jetty-9.4.25" location="https://download.eclipse.org/jetty/updates/jetty-bundles-9.x/9.4.28.v20200408/"/>
+      <unit id="org.eclipse.jetty.client" version="9.4.30.v20200611"/>
+      <unit id="org.eclipse.jetty.client.source" version="9.4.30.v20200611"/>
+      <unit id="org.eclipse.jetty.continuation" version="9.4.30.v20200611"/>
+      <unit id="org.eclipse.jetty.continuation.source" version="9.4.30.v20200611"/>
+      <unit id="org.eclipse.jetty.http" version="9.4.30.v20200611"/>
+      <unit id="org.eclipse.jetty.http.source" version="9.4.30.v20200611"/>
+      <unit id="org.eclipse.jetty.io" version="9.4.30.v20200611"/>
+      <unit id="org.eclipse.jetty.io.source" version="9.4.30.v20200611"/>
+      <unit id="org.eclipse.jetty.security" version="9.4.30.v20200611"/>
+      <unit id="org.eclipse.jetty.security.source" version="9.4.30.v20200611"/>
+      <unit id="org.eclipse.jetty.server" version="9.4.30.v20200611"/>
+      <unit id="org.eclipse.jetty.server.source" version="9.4.30.v20200611"/>
+      <unit id="org.eclipse.jetty.servlet" version="9.4.30.v20200611"/>
+      <unit id="org.eclipse.jetty.servlet.source" version="9.4.30.v20200611"/>
+      <unit id="org.eclipse.jetty.util" version="9.4.30.v20200611"/>
+      <unit id="org.eclipse.jetty.util.source" version="9.4.30.v20200611"/>
+      <repository id="jetty-9.4.30" location="https://download.eclipse.org/jetty/updates/jetty-bundles-9.x/9.4.30.v20200611/"/>
     </location>
     <location includeMode="slicer" includeAllPlatforms="false" includeSource="true" includeConfigurePhase="true" type="InstallableUnit">
       <unit id="com.google.gson" version="2.8.2.v20180104-1110"/>
@@ -41,14 +41,14 @@
       <unit id="net.i2p.crypto.eddsa.source" version="0.3.0.v20181102-1323"/>
       <unit id="org.apache.ant" version="1.10.8.v20200515-1239"/>
       <unit id="org.apache.ant.source" version="1.10.8.v20200515-1239"/>
-      <unit id="org.apache.commons.codec" version="1.13.0.v20200108-0001"/>
-      <unit id="org.apache.commons.codec.source" version="1.13.0.v20200108-0001"/>
+      <unit id="org.apache.commons.codec" version="1.14.0.v20200818-1422"/>
+      <unit id="org.apache.commons.codec.source" version="1.14.0.v20200818-1422"/>
       <unit id="org.apache.commons.compress" version="1.19.0.v20200106-2343"/>
       <unit id="org.apache.commons.compress.source" version="1.19.0.v20200106-2343"/>
       <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.10.v20200114-1512"/>
-      <unit id="org.apache.httpcomponents.httpclient.source" version="4.5.10.v20200114-1512"/>
+      <unit id="org.apache.httpcomponents.httpclient" version="4.5.10.v20200830-2311"/>
+      <unit id="org.apache.httpcomponents.httpclient.source" version="4.5.10.v20200830-2311"/>
       <unit id="org.apache.httpcomponents.httpcore" version="4.4.12.v20200108-1212"/>
       <unit id="org.apache.httpcomponents.httpcore.source" version="4.4.12.v20200108-1212"/>
       <unit id="org.apache.log4j" version="1.2.15.v201012070815"/>
@@ -84,7 +84,7 @@
       <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/R20200529191137/repository"/>
+      <repository location="https://download.eclipse.org/tools/orbit/downloads/drops/R20200831200620/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 4e39322..da2ea7e 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.x.tpd"
-include "orbit/R20200529191137-2020-06.tpd"
+include "orbit/R20200831200620-2020-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/S20200519202422.tpd b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/orbit/R20200831200620-2020-09.tpd
similarity index 80%
rename from org.eclipse.jgit.packaging/org.eclipse.jgit.target/orbit/S20200519202422.tpd
rename to org.eclipse.jgit.packaging/org.eclipse.jgit.target/orbit/R20200831200620-2020-09.tpd
index abe97e1..22e2b01 100644
--- a/org.eclipse.jgit.packaging/org.eclipse.jgit.target/orbit/S20200519202422.tpd
+++ b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/orbit/R20200831200620-2020-09.tpd
@@ -1,7 +1,7 @@
-target "S20200519202422" with source configurePhase
+target "R20200831200620-2020-09" with source configurePhase
 // see https://download.eclipse.org/tools/orbit/downloads/
 
-location "https://download.eclipse.org/tools/orbit/downloads/drops/S20200519202422/repository" {
+location "https://download.eclipse.org/tools/orbit/downloads/drops/R20200831200620/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]
@@ -20,14 +20,14 @@
 	net.i2p.crypto.eddsa.source [0.3.0.v20181102-1323,0.3.0.v20181102-1323]
 	org.apache.ant [1.10.8.v20200515-1239,1.10.8.v20200515-1239]
 	org.apache.ant.source [1.10.8.v20200515-1239,1.10.8.v20200515-1239]
-	org.apache.commons.codec [1.13.0.v20200108-0001,1.13.0.v20200108-0001]
-	org.apache.commons.codec.source [1.13.0.v20200108-0001,1.13.0.v20200108-0001]
+	org.apache.commons.codec [1.14.0.v20200818-1422,1.14.0.v20200818-1422]
+	org.apache.commons.codec.source [1.14.0.v20200818-1422,1.14.0.v20200818-1422]
 	org.apache.commons.compress [1.19.0.v20200106-2343,1.19.0.v20200106-2343]
 	org.apache.commons.compress.source [1.19.0.v20200106-2343,1.19.0.v20200106-2343]
 	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.10.v20200114-1512,4.5.10.v20200114-1512]
-	org.apache.httpcomponents.httpclient.source [4.5.10.v20200114-1512,4.5.10.v20200114-1512]
+	org.apache.httpcomponents.httpclient [4.5.10.v20200830-2311,4.5.10.v20200830-2311]
+	org.apache.httpcomponents.httpclient.source [4.5.10.v20200830-2311,4.5.10.v20200830-2311]
 	org.apache.httpcomponents.httpcore [4.4.12.v20200108-1212,4.4.12.v20200108-1212]
 	org.apache.httpcomponents.httpcore.source [4.4.12.v20200108-1212,4.4.12.v20200108-1212]
 	org.apache.log4j [1.2.15.v201012070815,1.2.15.v201012070815]
@@ -38,12 +38,12 @@
 	org.apache.sshd.sftp.source [2.4.0.v20200319-1547,2.4.0.v20200319-1547]
 	org.assertj [3.14.0.v20200120-1926,3.14.0.v20200120-1926]
 	org.assertj.source [3.14.0.v20200120-1926,3.14.0.v20200120-1926]
-	org.bouncycastle.bcpg [1.65.0.v20200502-2229,1.65.0.v20200502-2229]
-	org.bouncycastle.bcpg.source [1.65.0.v20200502-2229,1.65.0.v20200502-2229]
-	org.bouncycastle.bcpkix [1.65.0.v20200502-2229,1.65.0.v20200502-2229]
-	org.bouncycastle.bcpkix.source [1.65.0.v20200502-2229,1.65.0.v20200502-2229]
-	org.bouncycastle.bcprov [1.65.0.v20200502-2229,1.65.0.v20200502-2229]
-	org.bouncycastle.bcprov.source [1.65.0.v20200502-2229,1.65.0.v20200502-2229]
+	org.bouncycastle.bcpg [1.65.0.v20200527-1955,1.65.0.v20200527-1955]
+	org.bouncycastle.bcpg.source [1.65.0.v20200527-1955,1.65.0.v20200527-1955]
+	org.bouncycastle.bcpkix [1.65.0.v20200527-1955,1.65.0.v20200527-1955]
+	org.bouncycastle.bcpkix.source [1.65.0.v20200527-1955,1.65.0.v20200527-1955]
+	org.bouncycastle.bcprov [1.65.1.v20200529-1514,1.65.1.v20200529-1514]
+	org.bouncycastle.bcprov.source [1.65.1.v20200529-1514,1.65.1.v20200529-1514]
 	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]
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 2137cbb..020580d 100644
--- a/org.eclipse.jgit.packaging/org.eclipse.jgit.target/pom.xml
+++ b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/pom.xml
@@ -16,7 +16,7 @@
   <parent>
     <groupId>org.eclipse.jgit</groupId>
     <artifactId>jgit.tycho.parent</artifactId>
-    <version>5.8.2-SNAPSHOT</version>
+    <version>5.9.1-SNAPSHOT</version>
   </parent>
 
   <artifactId>org.eclipse.jgit.target</artifactId>
diff --git a/org.eclipse.jgit.packaging/org.eclipse.jgit.target/projects/jetty-9.4.x.tpd b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/projects/jetty-9.4.x.tpd
index 0eea06d..70c426c 100644
--- a/org.eclipse.jgit.packaging/org.eclipse.jgit.target/projects/jetty-9.4.x.tpd
+++ b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/projects/jetty-9.4.x.tpd
@@ -1,20 +1,20 @@
 target "jetty-9.4.x" with source configurePhase
 
-location jetty-9.4.25 "https://download.eclipse.org/jetty/updates/jetty-bundles-9.x/9.4.28.v20200408/" {
-	org.eclipse.jetty.client [9.4.28.v20200408,9.4.28.v20200408]
-	org.eclipse.jetty.client.source [9.4.28.v20200408,9.4.28.v20200408]
-	org.eclipse.jetty.continuation [9.4.28.v20200408,9.4.28.v20200408]
-	org.eclipse.jetty.continuation.source [9.4.28.v20200408,9.4.28.v20200408]
-	org.eclipse.jetty.http [9.4.28.v20200408,9.4.28.v20200408]
-	org.eclipse.jetty.http.source [9.4.28.v20200408,9.4.28.v20200408]
-	org.eclipse.jetty.io [9.4.28.v20200408,9.4.28.v20200408]
-	org.eclipse.jetty.io.source [9.4.28.v20200408,9.4.28.v20200408]
-	org.eclipse.jetty.security [9.4.28.v20200408,9.4.28.v20200408]
-	org.eclipse.jetty.security.source [9.4.28.v20200408,9.4.28.v20200408]
-	org.eclipse.jetty.server [9.4.28.v20200408,9.4.28.v20200408]
-	org.eclipse.jetty.server.source [9.4.28.v20200408,9.4.28.v20200408]
-	org.eclipse.jetty.servlet [9.4.28.v20200408,9.4.28.v20200408]
-	org.eclipse.jetty.servlet.source [9.4.28.v20200408,9.4.28.v20200408]
-	org.eclipse.jetty.util [9.4.28.v20200408,9.4.28.v20200408]
-	org.eclipse.jetty.util.source [9.4.28.v20200408,9.4.28.v20200408]
+location jetty-9.4.30 "https://download.eclipse.org/jetty/updates/jetty-bundles-9.x/9.4.30.v20200611/" {
+	org.eclipse.jetty.client [9.4.30.v20200611,9.4.30.v20200611]
+	org.eclipse.jetty.client.source [9.4.30.v20200611,9.4.30.v20200611]
+	org.eclipse.jetty.continuation [9.4.30.v20200611,9.4.30.v20200611]
+	org.eclipse.jetty.continuation.source [9.4.30.v20200611,9.4.30.v20200611]
+	org.eclipse.jetty.http [9.4.30.v20200611,9.4.30.v20200611]
+	org.eclipse.jetty.http.source [9.4.30.v20200611,9.4.30.v20200611]
+	org.eclipse.jetty.io [9.4.30.v20200611,9.4.30.v20200611]
+	org.eclipse.jetty.io.source [9.4.30.v20200611,9.4.30.v20200611]
+	org.eclipse.jetty.security [9.4.30.v20200611,9.4.30.v20200611]
+	org.eclipse.jetty.security.source [9.4.30.v20200611,9.4.30.v20200611]
+	org.eclipse.jetty.server [9.4.30.v20200611,9.4.30.v20200611]
+	org.eclipse.jetty.server.source [9.4.30.v20200611,9.4.30.v20200611]
+	org.eclipse.jetty.servlet [9.4.30.v20200611,9.4.30.v20200611]
+	org.eclipse.jetty.servlet.source [9.4.30.v20200611,9.4.30.v20200611]
+	org.eclipse.jetty.util [9.4.30.v20200611,9.4.30.v20200611]
+	org.eclipse.jetty.util.source [9.4.30.v20200611,9.4.30.v20200611]
 }
diff --git a/org.eclipse.jgit.packaging/pom.xml b/org.eclipse.jgit.packaging/pom.xml
index 6fcf674..935d9c5 100644
--- a/org.eclipse.jgit.packaging/pom.xml
+++ b/org.eclipse.jgit.packaging/pom.xml
@@ -16,7 +16,7 @@
 
   <groupId>org.eclipse.jgit</groupId>
   <artifactId>jgit.tycho.parent</artifactId>
-  <version>5.8.2-SNAPSHOT</version>
+  <version>5.9.1-SNAPSHOT</version>
   <packaging>pom</packaging>
 
   <name>JGit Tycho Parent</name>
@@ -212,7 +212,7 @@
         <plugin>
           <groupId>org.apache.maven.plugins</groupId>
           <artifactId>maven-resources-plugin</artifactId>
-          <version>3.1.0</version>
+          <version>3.2.0</version>
           <configuration>
             <encoding>ISO-8859-1</encoding>
           </configuration>
diff --git a/org.eclipse.jgit.pgm.test/.settings/org.eclipse.jdt.core.prefs b/org.eclipse.jgit.pgm.test/.settings/org.eclipse.jdt.core.prefs
index 3dd5840..4c4634a 100644
--- a/org.eclipse.jgit.pgm.test/.settings/org.eclipse.jdt.core.prefs
+++ b/org.eclipse.jgit.pgm.test/.settings/org.eclipse.jdt.core.prefs
@@ -52,7 +52,7 @@
 org.eclipse.jdt.core.compiler.problem.missingJavadocCommentsOverriding=disabled
 org.eclipse.jdt.core.compiler.problem.missingJavadocCommentsVisibility=protected
 org.eclipse.jdt.core.compiler.problem.missingJavadocTagDescription=return_tag
-org.eclipse.jdt.core.compiler.problem.missingJavadocTags=error
+org.eclipse.jdt.core.compiler.problem.missingJavadocTags=ignore
 org.eclipse.jdt.core.compiler.problem.missingJavadocTagsMethodTypeParameters=disabled
 org.eclipse.jdt.core.compiler.problem.missingJavadocTagsOverriding=disabled
 org.eclipse.jdt.core.compiler.problem.missingJavadocTagsVisibility=private
diff --git a/org.eclipse.jgit.pgm.test/META-INF/MANIFEST.MF b/org.eclipse.jgit.pgm.test/META-INF/MANIFEST.MF
index b3629f8..5ad5180 100644
--- a/org.eclipse.jgit.pgm.test/META-INF/MANIFEST.MF
+++ b/org.eclipse.jgit.pgm.test/META-INF/MANIFEST.MF
@@ -3,28 +3,28 @@
 Bundle-Name: %Bundle-Name
 Automatic-Module-Name: org.eclipse.jgit.pgm.test
 Bundle-SymbolicName: org.eclipse.jgit.pgm.test
-Bundle-Version: 5.8.2.qualifier
+Bundle-Version: 5.9.1.qualifier
 Bundle-Vendor: %Bundle-Vendor
 Bundle-Localization: plugin
 Bundle-ActivationPolicy: lazy
 Bundle-RequiredExecutionEnvironment: JavaSE-1.8
-Import-Package: org.eclipse.jgit.api;version="[5.8.2,5.9.0)",
- org.eclipse.jgit.api.errors;version="[5.8.2,5.9.0)",
- org.eclipse.jgit.diff;version="[5.8.2,5.9.0)",
- org.eclipse.jgit.dircache;version="[5.8.2,5.9.0)",
- org.eclipse.jgit.internal.storage.file;version="5.8.2",
- org.eclipse.jgit.junit;version="[5.8.2,5.9.0)",
- org.eclipse.jgit.lib;version="[5.8.2,5.9.0)",
- org.eclipse.jgit.merge;version="[5.8.2,5.9.0)",
- org.eclipse.jgit.pgm;version="[5.8.2,5.9.0)",
- org.eclipse.jgit.pgm.internal;version="[5.8.2,5.9.0)",
- org.eclipse.jgit.pgm.opt;version="[5.8.2,5.9.0)",
- org.eclipse.jgit.revwalk;version="[5.8.2,5.9.0)",
- org.eclipse.jgit.storage.file;version="[5.8.2,5.9.0)",
- org.eclipse.jgit.transport;version="[5.8.2,5.9.0)",
- org.eclipse.jgit.treewalk;version="[5.8.2,5.9.0)",
- org.eclipse.jgit.util;version="[5.8.2,5.9.0)",
- org.eclipse.jgit.util.io;version="[5.8.2,5.9.0)",
+Import-Package: org.eclipse.jgit.api;version="[5.9.1,5.10.0)",
+ org.eclipse.jgit.api.errors;version="[5.9.1,5.10.0)",
+ org.eclipse.jgit.diff;version="[5.9.1,5.10.0)",
+ org.eclipse.jgit.dircache;version="[5.9.1,5.10.0)",
+ org.eclipse.jgit.internal.storage.file;version="5.9.1",
+ org.eclipse.jgit.junit;version="[5.9.1,5.10.0)",
+ org.eclipse.jgit.lib;version="[5.9.1,5.10.0)",
+ org.eclipse.jgit.merge;version="[5.9.1,5.10.0)",
+ org.eclipse.jgit.pgm;version="[5.9.1,5.10.0)",
+ org.eclipse.jgit.pgm.internal;version="[5.9.1,5.10.0)",
+ org.eclipse.jgit.pgm.opt;version="[5.9.1,5.10.0)",
+ org.eclipse.jgit.revwalk;version="[5.9.1,5.10.0)",
+ org.eclipse.jgit.storage.file;version="[5.9.1,5.10.0)",
+ org.eclipse.jgit.transport;version="[5.9.1,5.10.0)",
+ org.eclipse.jgit.treewalk;version="[5.9.1,5.10.0)",
+ org.eclipse.jgit.util;version="[5.9.1,5.10.0)",
+ org.eclipse.jgit.util.io;version="[5.9.1,5.10.0)",
  org.hamcrest.core;bundle-version="[1.1.0,2.0.0)",
  org.junit;version="[4.13,5.0.0)",
  org.junit.rules;version="[4.13,5.0.0)",
diff --git a/org.eclipse.jgit.pgm.test/pom.xml b/org.eclipse.jgit.pgm.test/pom.xml
index e38443d..db4e93e 100644
--- a/org.eclipse.jgit.pgm.test/pom.xml
+++ b/org.eclipse.jgit.pgm.test/pom.xml
@@ -17,7 +17,7 @@
   <parent>
     <groupId>org.eclipse.jgit</groupId>
     <artifactId>org.eclipse.jgit-parent</artifactId>
-    <version>5.8.2-SNAPSHOT</version>
+    <version>5.9.1-SNAPSHOT</version>
   </parent>
 
   <artifactId>org.eclipse.jgit.pgm.test</artifactId>
diff --git a/org.eclipse.jgit.pgm/META-INF/MANIFEST.MF b/org.eclipse.jgit.pgm/META-INF/MANIFEST.MF
index 7868927..218f568 100644
--- a/org.eclipse.jgit.pgm/META-INF/MANIFEST.MF
+++ b/org.eclipse.jgit.pgm/META-INF/MANIFEST.MF
@@ -3,7 +3,7 @@
 Bundle-Name: %Bundle-Name
 Automatic-Module-Name: org.eclipse.jgit.pgm
 Bundle-SymbolicName: org.eclipse.jgit.pgm
-Bundle-Version: 5.8.2.qualifier
+Bundle-Version: 5.9.1.qualifier
 Bundle-Vendor: %Bundle-Vendor
 Bundle-Localization: plugin
 Bundle-RequiredExecutionEnvironment: JavaSE-1.8
@@ -13,48 +13,48 @@
  org.eclipse.jetty.servlet;version="[9.4.5,10.0.0)",
  org.eclipse.jetty.util;version="[9.4.5,10.0.0)",
  org.eclipse.jetty.util.component;version="[9.4.5,10.0.0)",
- org.eclipse.jgit.api;version="[5.8.2,5.9.0)",
- org.eclipse.jgit.api.errors;version="[5.8.2,5.9.0)",
- org.eclipse.jgit.archive;version="[5.8.2,5.9.0)",
- org.eclipse.jgit.awtui;version="[5.8.2,5.9.0)",
- org.eclipse.jgit.blame;version="[5.8.2,5.9.0)",
- org.eclipse.jgit.diff;version="[5.8.2,5.9.0)",
- org.eclipse.jgit.dircache;version="[5.8.2,5.9.0)",
- org.eclipse.jgit.errors;version="[5.8.2,5.9.0)",
- org.eclipse.jgit.gitrepo;version="[5.8.2,5.9.0)",
- org.eclipse.jgit.internal.ketch;version="[5.8.2,5.9.0)",
- org.eclipse.jgit.internal.storage.file;version="[5.8.2,5.9.0)",
- org.eclipse.jgit.internal.storage.io;version="[5.8.2,5.9.0)",
- org.eclipse.jgit.internal.storage.pack;version="[5.8.2,5.9.0)",
- org.eclipse.jgit.internal.storage.reftable;version="[5.8.2,5.9.0)",
- org.eclipse.jgit.internal.storage.reftree;version="[5.8.2,5.9.0)",
- org.eclipse.jgit.lfs;version="[5.8.2,5.9.0)",
- org.eclipse.jgit.lfs.server;version="[5.8.2,5.9.0)",
- org.eclipse.jgit.lfs.server.fs;version="[5.8.2,5.9.0)",
- org.eclipse.jgit.lfs.server.s3;version="[5.8.2,5.9.0)",
- org.eclipse.jgit.lib;version="[5.8.2,5.9.0)",
- org.eclipse.jgit.merge;version="[5.8.2,5.9.0)",
- org.eclipse.jgit.nls;version="[5.8.2,5.9.0)",
- org.eclipse.jgit.notes;version="[5.8.2,5.9.0)",
- org.eclipse.jgit.revplot;version="[5.8.2,5.9.0)",
- org.eclipse.jgit.revwalk;version="[5.8.2,5.9.0)",
- org.eclipse.jgit.revwalk.filter;version="[5.8.2,5.9.0)",
- org.eclipse.jgit.storage.file;version="[5.8.2,5.9.0)",
- org.eclipse.jgit.storage.pack;version="[5.8.2,5.9.0)",
- org.eclipse.jgit.transport;version="[5.8.2,5.9.0)",
- org.eclipse.jgit.transport.http.apache;version="[5.8.2,5.9.0)",
- org.eclipse.jgit.transport.resolver;version="[5.8.2,5.9.0)",
- org.eclipse.jgit.transport.sshd;version="[5.8.2,5.9.0)",
- org.eclipse.jgit.treewalk;version="[5.8.2,5.9.0)",
- org.eclipse.jgit.treewalk.filter;version="[5.8.2,5.9.0)",
- org.eclipse.jgit.util;version="[5.8.2,5.9.0)",
- org.eclipse.jgit.util.io;version="[5.8.2,5.9.0)",
+ org.eclipse.jgit.api;version="[5.9.1,5.10.0)",
+ org.eclipse.jgit.api.errors;version="[5.9.1,5.10.0)",
+ org.eclipse.jgit.archive;version="[5.9.1,5.10.0)",
+ org.eclipse.jgit.awtui;version="[5.9.1,5.10.0)",
+ org.eclipse.jgit.blame;version="[5.9.1,5.10.0)",
+ org.eclipse.jgit.diff;version="[5.9.1,5.10.0)",
+ org.eclipse.jgit.dircache;version="[5.9.1,5.10.0)",
+ org.eclipse.jgit.errors;version="[5.9.1,5.10.0)",
+ org.eclipse.jgit.gitrepo;version="[5.9.1,5.10.0)",
+ org.eclipse.jgit.internal.ketch;version="[5.9.1,5.10.0)",
+ org.eclipse.jgit.internal.storage.file;version="[5.9.1,5.10.0)",
+ org.eclipse.jgit.internal.storage.io;version="[5.9.1,5.10.0)",
+ org.eclipse.jgit.internal.storage.pack;version="[5.9.1,5.10.0)",
+ org.eclipse.jgit.internal.storage.reftable;version="[5.9.1,5.10.0)",
+ org.eclipse.jgit.internal.storage.reftree;version="[5.9.1,5.10.0)",
+ org.eclipse.jgit.lfs;version="[5.9.1,5.10.0)",
+ org.eclipse.jgit.lfs.server;version="[5.9.1,5.10.0)",
+ org.eclipse.jgit.lfs.server.fs;version="[5.9.1,5.10.0)",
+ org.eclipse.jgit.lfs.server.s3;version="[5.9.1,5.10.0)",
+ org.eclipse.jgit.lib;version="[5.9.1,5.10.0)",
+ org.eclipse.jgit.merge;version="[5.9.1,5.10.0)",
+ org.eclipse.jgit.nls;version="[5.9.1,5.10.0)",
+ org.eclipse.jgit.notes;version="[5.9.1,5.10.0)",
+ org.eclipse.jgit.revplot;version="[5.9.1,5.10.0)",
+ org.eclipse.jgit.revwalk;version="[5.9.1,5.10.0)",
+ org.eclipse.jgit.revwalk.filter;version="[5.9.1,5.10.0)",
+ org.eclipse.jgit.storage.file;version="[5.9.1,5.10.0)",
+ org.eclipse.jgit.storage.pack;version="[5.9.1,5.10.0)",
+ org.eclipse.jgit.transport;version="[5.9.1,5.10.0)",
+ org.eclipse.jgit.transport.http.apache;version="[5.9.1,5.10.0)",
+ org.eclipse.jgit.transport.resolver;version="[5.9.1,5.10.0)",
+ org.eclipse.jgit.transport.sshd;version="[5.9.1,5.10.0)",
+ org.eclipse.jgit.treewalk;version="[5.9.1,5.10.0)",
+ org.eclipse.jgit.treewalk.filter;version="[5.9.1,5.10.0)",
+ org.eclipse.jgit.util;version="[5.9.1,5.10.0)",
+ org.eclipse.jgit.util.io;version="[5.9.1,5.10.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.8.2";
+Export-Package: org.eclipse.jgit.console;version="5.9.1";
  uses:="org.eclipse.jgit.transport,
   org.eclipse.jgit.util",
- org.eclipse.jgit.pgm;version="5.8.2";
+ org.eclipse.jgit.pgm;version="5.9.1";
   uses:="org.eclipse.jgit.transport,
    org.eclipse.jgit.util.io,
    org.eclipse.jgit.awtui,
@@ -66,14 +66,14 @@
    org.eclipse.jgit.treewalk,
    org.eclipse.jgit.api,
    javax.swing",
- org.eclipse.jgit.pgm.debug;version="5.8.2";
+ org.eclipse.jgit.pgm.debug;version="5.9.1";
   uses:="org.eclipse.jgit.util.io,
    org.eclipse.jgit.pgm,
    org.eclipse.jetty.servlet",
- org.eclipse.jgit.pgm.internal;version="5.8.2";
+ org.eclipse.jgit.pgm.internal;version="5.9.1";
   x-friends:="org.eclipse.jgit.pgm.test,
    org.eclipse.jgit.test",
- org.eclipse.jgit.pgm.opt;version="5.8.2";
+ org.eclipse.jgit.pgm.opt;version="5.9.1";
   uses:="org.kohsuke.args4j,
    org.eclipse.jgit.lib,
    org.eclipse.jgit.revwalk,
diff --git a/org.eclipse.jgit.pgm/META-INF/SOURCE-MANIFEST.MF b/org.eclipse.jgit.pgm/META-INF/SOURCE-MANIFEST.MF
index 1b034ef..4df8f90 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.8.2.qualifier
-Eclipse-SourceBundle: org.eclipse.jgit.pgm;version="5.8.2.qualifier";roots="."
+Bundle-Version: 5.9.1.qualifier
+Eclipse-SourceBundle: org.eclipse.jgit.pgm;version="5.9.1.qualifier";roots="."
diff --git a/org.eclipse.jgit.pgm/pom.xml b/org.eclipse.jgit.pgm/pom.xml
index 602d260..0c26505 100644
--- a/org.eclipse.jgit.pgm/pom.xml
+++ b/org.eclipse.jgit.pgm/pom.xml
@@ -17,7 +17,7 @@
   <parent>
     <groupId>org.eclipse.jgit</groupId>
     <artifactId>org.eclipse.jgit-parent</artifactId>
-    <version>5.8.2-SNAPSHOT</version>
+    <version>5.9.1-SNAPSHOT</version>
   </parent>
 
   <artifactId>org.eclipse.jgit.pgm</artifactId>
diff --git a/org.eclipse.jgit.ssh.apache.test/.settings/org.eclipse.jdt.core.prefs b/org.eclipse.jgit.ssh.apache.test/.settings/org.eclipse.jdt.core.prefs
index 822846c..d483c77 100644
--- a/org.eclipse.jgit.ssh.apache.test/.settings/org.eclipse.jdt.core.prefs
+++ b/org.eclipse.jgit.ssh.apache.test/.settings/org.eclipse.jdt.core.prefs
@@ -52,7 +52,7 @@
 org.eclipse.jdt.core.compiler.problem.missingJavadocCommentsOverriding=disabled
 org.eclipse.jdt.core.compiler.problem.missingJavadocCommentsVisibility=protected
 org.eclipse.jdt.core.compiler.problem.missingJavadocTagDescription=return_tag
-org.eclipse.jdt.core.compiler.problem.missingJavadocTags=error
+org.eclipse.jdt.core.compiler.problem.missingJavadocTags=ignore
 org.eclipse.jdt.core.compiler.problem.missingJavadocTagsMethodTypeParameters=disabled
 org.eclipse.jdt.core.compiler.problem.missingJavadocTagsOverriding=disabled
 org.eclipse.jdt.core.compiler.problem.missingJavadocTagsVisibility=private
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 c82f42f..5c9ce9c 100644
--- a/org.eclipse.jgit.ssh.apache.test/META-INF/MANIFEST.MF
+++ b/org.eclipse.jgit.ssh.apache.test/META-INF/MANIFEST.MF
@@ -3,7 +3,7 @@
 Bundle-Name: %Bundle-Name
 Automatic-Module-Name: org.eclipse.jgit.ssh.apache.test
 Bundle-SymbolicName: org.eclipse.jgit.ssh.apache.test
-Bundle-Version: 5.8.2.qualifier
+Bundle-Version: 5.9.1.qualifier
 Bundle-Vendor: %Bundle-Vendor
 Bundle-Localization: plugin
 Bundle-RequiredExecutionEnvironment: JavaSE-1.8
@@ -15,14 +15,16 @@
  org.apache.sshd.common.session;version="[2.4.0,2.5.0)",
  org.apache.sshd.common.util.net;version="[2.4.0,2.5.0)",
  org.apache.sshd.common.util.security;version="[2.4.0,2.5.0)",
- org.eclipse.jgit.api.errors;version="[5.8.2,5.9.0)",
- org.eclipse.jgit.internal.transport.sshd.proxy;version="[5.8.2,5.9.0)",
- org.eclipse.jgit.junit;version="[5.8.2,5.9.0)",
- org.eclipse.jgit.junit.ssh;version="[5.8.2,5.9.0)",
- org.eclipse.jgit.lib;version="[5.8.2,5.9.0)",
- org.eclipse.jgit.transport;version="[5.8.2,5.9.0)",
- org.eclipse.jgit.transport.sshd;version="[5.8.2,5.9.0)",
- org.eclipse.jgit.util;version="[5.8.2,5.9.0)",
+ org.apache.sshd.server;version="[2.4.0,2.5.0)",
+ org.eclipse.jgit.api;version="[5.9.1,5.10.0)",
+ org.eclipse.jgit.api.errors;version="[5.9.1,5.10.0)",
+ org.eclipse.jgit.internal.transport.sshd.proxy;version="[5.9.1,5.10.0)",
+ org.eclipse.jgit.junit;version="[5.9.1,5.10.0)",
+ org.eclipse.jgit.junit.ssh;version="[5.9.1,5.10.0)",
+ org.eclipse.jgit.lib;version="[5.9.1,5.10.0)",
+ org.eclipse.jgit.transport;version="[5.9.1,5.10.0)",
+ org.eclipse.jgit.transport.sshd;version="[5.9.1,5.10.0)",
+ org.eclipse.jgit.util;version="[5.9.1,5.10.0)",
  org.junit;version="[4.13,5.0.0)",
  org.junit.experimental.theories;version="[4.13,5.0.0)",
  org.junit.runner;version="[4.13,5.0.0)"
diff --git a/org.eclipse.jgit.ssh.apache.test/pom.xml b/org.eclipse.jgit.ssh.apache.test/pom.xml
index d7f09b1..df319ad 100644
--- a/org.eclipse.jgit.ssh.apache.test/pom.xml
+++ b/org.eclipse.jgit.ssh.apache.test/pom.xml
@@ -17,7 +17,7 @@
   <parent>
     <groupId>org.eclipse.jgit</groupId>
     <artifactId>org.eclipse.jgit-parent</artifactId>
-    <version>5.8.2-SNAPSHOT</version>
+    <version>5.9.1-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 bfee042..651ae7d 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
@@ -11,6 +11,7 @@
 
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertThrows;
 import static org.junit.Assert.assertTrue;
 
 import java.io.File;
@@ -21,6 +22,9 @@
 import java.util.List;
 import java.util.stream.Collectors;
 import org.apache.sshd.client.config.hosts.KnownHostEntry;
+import org.apache.sshd.common.PropertyResolverUtils;
+import org.apache.sshd.server.ServerFactoryManager;
+import org.eclipse.jgit.api.Git;
 import org.eclipse.jgit.api.errors.TransportException;
 import org.eclipse.jgit.junit.ssh.SshTestBase;
 import org.eclipse.jgit.lib.Constants;
@@ -156,7 +160,7 @@
 				"IdentityFile " + privateKey1.getAbsolutePath());
 	}
 
-	@Test (expected = TransportException.class)
+	@Test
 	public void testHugePreamble() throws Exception {
 		// Test that the connection fails when the preamble is longer than 64k.
 		StringBuilder b = new StringBuilder();
@@ -169,10 +173,42 @@
 			lines[i] = line;
 		}
 		server.setPreamble(lines);
-		cloneWith(
-				"ssh://" + TEST_USER + "@localhost:" + testPort
-						+ "/doesntmatter",
-				defaultCloneDir, null,
+		TransportException e = assertThrows(TransportException.class,
+				() -> cloneWith(
+						"ssh://" + TEST_USER + "@localhost:" + testPort
+								+ "/doesntmatter",
+						defaultCloneDir, null,
+						"IdentityFile " + privateKey1.getAbsolutePath()));
+		// The assertions test that we don't run into bug 565394 / SSHD-1050
+		assertFalse(e.getMessage().contains("timeout"));
+		assertTrue(e.getMessage().contains("65536")
+				|| e.getMessage().contains("closed"));
+	}
+
+	/**
+	 * Test for SSHD-1028. If the server doesn't close sessions, the second
+	 * fetch will fail. Occurs on sshd 2.5.[01].
+	 *
+	 * @throws Exception
+	 *             on errors
+	 * @see <a href=
+	 *      "https://issues.apache.org/jira/projects/SSHD/issues/SSHD-1028">SSHD-1028</a>
+	 */
+	@Test
+	public void testCloneAndFetchWithSessionLimit() throws Exception {
+		PropertyResolverUtils.updateProperty(server.getPropertyResolver(),
+				ServerFactoryManager.MAX_CONCURRENT_SESSIONS, 2);
+		File localClone = cloneWith("ssh://localhost/doesntmatter",
+				defaultCloneDir, null, //
+				"Host localhost", //
+				"HostName localhost", //
+				"Port " + testPort, //
+				"User " + TEST_USER, //
 				"IdentityFile " + privateKey1.getAbsolutePath());
+		// Fetch a couple of times
+		try (Git git = Git.open(localClone)) {
+			git.fetch().call();
+			git.fetch().call();
+		}
 	}
 }
diff --git a/org.eclipse.jgit.ssh.apache/META-INF/MANIFEST.MF b/org.eclipse.jgit.ssh.apache/META-INF/MANIFEST.MF
index fe5cbf7..44265b3 100644
--- a/org.eclipse.jgit.ssh.apache/META-INF/MANIFEST.MF
+++ b/org.eclipse.jgit.ssh.apache/META-INF/MANIFEST.MF
@@ -6,9 +6,9 @@
 Bundle-Vendor: %Bundle-Vendor
 Bundle-Localization: plugin
 Bundle-ActivationPolicy: lazy
-Bundle-Version: 5.8.2.qualifier
+Bundle-Version: 5.9.1.qualifier
 Bundle-RequiredExecutionEnvironment: JavaSE-1.8
-Export-Package: org.eclipse.jgit.internal.transport.sshd;version="5.8.2";x-internal:=true;
+Export-Package: org.eclipse.jgit.internal.transport.sshd;version="5.9.1";x-internal:=true;
   uses:="org.apache.sshd.client,
    org.apache.sshd.client.auth,
    org.apache.sshd.client.auth.keyboard,
@@ -23,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.8.2";x-internal:=true,
- org.eclipse.jgit.internal.transport.sshd.proxy;version="5.8.2";x-friends:="org.eclipse.jgit.ssh.apache.test",
- org.eclipse.jgit.transport.sshd;version="5.8.2";
+ org.eclipse.jgit.internal.transport.sshd.auth;version="5.9.1";x-internal:=true,
+ org.eclipse.jgit.internal.transport.sshd.proxy;version="5.9.1";x-friends:="org.eclipse.jgit.ssh.apache.test",
+ org.eclipse.jgit.transport.sshd;version="5.9.1";
   uses:="org.eclipse.jgit.transport,
    org.apache.sshd.client.config.hosts,
    org.apache.sshd.common.keyprovider,
@@ -75,12 +75,12 @@
  org.apache.sshd.common.util.net;version="[2.4.0,2.5.0)",
  org.apache.sshd.common.util.security;version="[2.4.0,2.5.0)",
  org.apache.sshd.server.auth;version="[2.4.0,2.5.0)",
- org.eclipse.jgit.annotations;version="[5.8.2,5.9.0)",
- org.eclipse.jgit.errors;version="[5.8.2,5.9.0)",
- org.eclipse.jgit.fnmatch;version="[5.8.2,5.9.0)",
- org.eclipse.jgit.internal.storage.file;version="[5.8.2,5.9.0)",
- org.eclipse.jgit.internal.transport.ssh;version="[5.8.2,5.9.0)",
- org.eclipse.jgit.nls;version="[5.8.2,5.9.0)",
- org.eclipse.jgit.transport;version="[5.8.2,5.9.0)",
- org.eclipse.jgit.util;version="[5.8.2,5.9.0)",
+ org.eclipse.jgit.annotations;version="[5.9.1,5.10.0)",
+ org.eclipse.jgit.errors;version="[5.9.1,5.10.0)",
+ org.eclipse.jgit.fnmatch;version="[5.9.1,5.10.0)",
+ org.eclipse.jgit.internal.storage.file;version="[5.9.1,5.10.0)",
+ org.eclipse.jgit.internal.transport.ssh;version="[5.9.1,5.10.0)",
+ org.eclipse.jgit.nls;version="[5.9.1,5.10.0)",
+ org.eclipse.jgit.transport;version="[5.9.1,5.10.0)",
+ org.eclipse.jgit.util;version="[5.9.1,5.10.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 2669b93..c05bd95 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.8.2.qualifier
-Eclipse-SourceBundle: org.eclipse.jgit.ssh.apache;version="5.8.2.qualifier";roots="."
+Bundle-Version: 5.9.1.qualifier
+Eclipse-SourceBundle: org.eclipse.jgit.ssh.apache;version="5.9.1.qualifier";roots="."
diff --git a/org.eclipse.jgit.ssh.apache/pom.xml b/org.eclipse.jgit.ssh.apache/pom.xml
index cd83137..e995200 100644
--- a/org.eclipse.jgit.ssh.apache/pom.xml
+++ b/org.eclipse.jgit.ssh.apache/pom.xml
@@ -17,7 +17,7 @@
   <parent>
     <groupId>org.eclipse.jgit</groupId>
     <artifactId>org.eclipse.jgit-parent</artifactId>
-    <version>5.8.2-SNAPSHOT</version>
+    <version>5.9.1-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 4f85ebe..b89bc60 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
@@ -1,4 +1,5 @@
 authenticationCanceled=Authentication canceled: no password
+authenticationOnClosedSession=Authentication canceled: session is already closing or closed
 closeListenerFailed=Ssh session close listener failed
 configInvalidPath=Invalid path in ssh config key {0}: {1}
 configInvalidPattern=Invalid pattern in ssh config key {0}: {1}
@@ -75,6 +76,7 @@
 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
+sessionWithoutUsername=SSH session created without user name; cannot authenticate
 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
 sshProcessStillRunning={0} is not yet completed, cannot get exit code
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 420a1d1..0d6f302 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
@@ -18,21 +18,30 @@
 import java.security.GeneralSecurityException;
 import java.security.PublicKey;
 import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
 import java.util.Iterator;
 import java.util.LinkedHashSet;
 import java.util.List;
+import java.util.Map;
+import java.util.Objects;
 import java.util.Set;
 
 import org.apache.sshd.client.ClientFactoryManager;
 import org.apache.sshd.client.config.hosts.HostConfigEntry;
+import org.apache.sshd.client.future.AuthFuture;
 import org.apache.sshd.client.keyverifier.ServerKeyVerifier;
 import org.apache.sshd.client.session.ClientSessionImpl;
+import org.apache.sshd.client.session.ClientUserAuthService;
+import org.apache.sshd.common.AttributeRepository;
 import org.apache.sshd.common.FactoryManager;
+import org.apache.sshd.common.PropertyResolver;
 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.kex.KexState;
 import org.apache.sshd.common.util.Readable;
 import org.apache.sshd.common.util.buffer.Buffer;
 import org.eclipse.jgit.errors.InvalidPatternException;
@@ -68,6 +77,17 @@
 	private volatile StatefulProxyConnector proxyHandler;
 
 	/**
+	 * Work-around for bug 565394 / SSHD-1050; remove when using sshd 2.6.0.
+	 */
+	private volatile AuthFuture authFuture;
+
+	/** Records exceptions before there is an authFuture. */
+	private List<Throwable> earlyErrors = new ArrayList<>();
+
+	/** Guards setting an earlyError and the authFuture together. */
+	private final Object errorLock = new Object();
+
+	/**
 	 * @param manager
 	 * @param session
 	 * @throws Exception
@@ -77,6 +97,125 @@
 		super(manager, session);
 	}
 
+	// BEGIN Work-around for bug 565394 / SSHD-1050
+	// Remove when using sshd 2.6.0.
+
+	@Override
+	public AuthFuture auth() throws IOException {
+		if (getUsername() == null) {
+			throw new IllegalStateException(
+					SshdText.get().sessionWithoutUsername);
+		}
+		ClientUserAuthService authService = getUserAuthService();
+		String serviceName = nextServiceName();
+		List<Throwable> errors = null;
+		AuthFuture future;
+		// Guard both getting early errors and setting authFuture
+		synchronized (errorLock) {
+			future = authService.auth(serviceName);
+			if (future == null) {
+				// Internal error; no translation.
+				throw new IllegalStateException(
+						"No auth future generated by service '" //$NON-NLS-1$
+								+ serviceName + '\'');
+			}
+			errors = earlyErrors;
+			earlyErrors = null;
+			authFuture = future;
+		}
+		if (errors != null && !errors.isEmpty()) {
+			Iterator<Throwable> iter = errors.iterator();
+			Throwable first = iter.next();
+			iter.forEachRemaining(t -> {
+				if (t != first && t != null) {
+					first.addSuppressed(t);
+				}
+			});
+			// Mark the future as having had an exception; just to be on the
+			// safe side. Actually, there shouldn't be anyone waiting on this
+			// future yet.
+			future.setException(first);
+			if (log.isDebugEnabled()) {
+				log.debug("auth({}) early exception type={}: {}", //$NON-NLS-1$
+						this, first.getClass().getSimpleName(),
+						first.getMessage());
+			}
+			if (first instanceof SshException) {
+				throw new SshException(
+						((SshException) first).getDisconnectCode(),
+						first.getMessage(), first);
+			}
+			throw new IOException(first.getMessage(), first);
+		}
+		return future;
+	}
+
+	@Override
+	protected void signalAuthFailure(AuthFuture future, Throwable t) {
+		signalAuthFailure(t);
+	}
+
+	private void signalAuthFailure(Throwable t) {
+		AuthFuture future = authFuture;
+		if (future == null) {
+			synchronized (errorLock) {
+				if (earlyErrors != null) {
+					earlyErrors.add(t);
+				}
+				future = authFuture;
+			}
+		}
+		if (future != null) {
+			future.setException(t);
+		}
+		if (log.isDebugEnabled()) {
+			boolean signalled = future != null && t == future.getException();
+			log.debug("signalAuthFailure({}) type={}, signalled={}: {}", this, //$NON-NLS-1$
+					t.getClass().getSimpleName(), Boolean.valueOf(signalled),
+					t.getMessage());
+		}
+	}
+
+	@Override
+	public void exceptionCaught(Throwable t) {
+		signalAuthFailure(t);
+		super.exceptionCaught(t);
+	}
+
+	@Override
+	protected void preClose() {
+		signalAuthFailure(
+				new SshException(SshdText.get().authenticationOnClosedSession));
+		super.preClose();
+	}
+
+	@Override
+	protected void handleDisconnect(int code, String msg, String lang,
+			Buffer buffer) throws Exception {
+		signalAuthFailure(new SshException(code, msg));
+		super.handleDisconnect(code, msg, lang, buffer);
+	}
+
+	@Override
+	protected <C extends Collection<ClientSessionEvent>> C updateCurrentSessionState(
+			C newState) {
+		if (closeFuture.isClosed()) {
+			newState.add(ClientSessionEvent.CLOSED);
+		}
+		if (isAuthenticated()) { // authFuture.isSuccess()
+			newState.add(ClientSessionEvent.AUTHED);
+		}
+		if (KexState.DONE.equals(getKexState())) {
+			AuthFuture future = authFuture;
+			if (future == null || future.isFailure()) {
+				newState.add(ClientSessionEvent.WAIT_AUTH);
+			}
+		}
+		return newState;
+	}
+
+	// END Work-around for bug 565394 / SSHD-1050
+
 	/**
 	 * Retrieves the {@link HostConfigEntry} this session was created for.
 	 *
@@ -419,4 +558,122 @@
 		return b.toString();
 	}
 
+	@Override
+	public <T> T getAttribute(AttributeKey<T> key) {
+		T value = super.getAttribute(key);
+		if (value == null) {
+			IoSession ioSession = getIoSession();
+			if (ioSession != null) {
+				Object obj = ioSession.getAttribute(AttributeRepository.class);
+				if (obj instanceof AttributeRepository) {
+					AttributeRepository sessionAttributes = (AttributeRepository) obj;
+					value = sessionAttributes.resolveAttribute(key);
+				}
+			}
+		}
+		return value;
+	}
+
+	@Override
+	public PropertyResolver getParentPropertyResolver() {
+		IoSession ioSession = getIoSession();
+		if (ioSession != null) {
+			Object obj = ioSession.getAttribute(AttributeRepository.class);
+			if (obj instanceof PropertyResolver) {
+				return (PropertyResolver) obj;
+			}
+		}
+		return super.getParentPropertyResolver();
+	}
+
+	/**
+	 * An {@link AttributeRepository} that chains together two other attribute
+	 * sources in a hierarchy.
+	 */
+	public static class ChainingAttributes implements AttributeRepository {
+
+		private final AttributeRepository delegate;
+
+		private final AttributeRepository parent;
+
+		/**
+		 * Create a new {@link ChainingAttributes} attribute source.
+		 *
+		 * @param self
+		 *            to search for attributes first
+		 * @param parent
+		 *            to search for attributes if not found in {@code self}
+		 */
+		public ChainingAttributes(AttributeRepository self,
+				AttributeRepository parent) {
+			this.delegate = self;
+			this.parent = parent;
+		}
+
+		@Override
+		public int getAttributesCount() {
+			return delegate.getAttributesCount();
+		}
+
+		@Override
+		public <T> T getAttribute(AttributeKey<T> key) {
+			return delegate.getAttribute(Objects.requireNonNull(key));
+		}
+
+		@Override
+		public Collection<AttributeKey<?>> attributeKeys() {
+			return delegate.attributeKeys();
+		}
+
+		@Override
+		public <T> T resolveAttribute(AttributeKey<T> key) {
+			T value = getAttribute(Objects.requireNonNull(key));
+			if (value == null) {
+				return parent.getAttribute(key);
+			}
+			return value;
+		}
+	}
+
+	/**
+	 * A {@link ChainingAttributes} repository that doubles as a
+	 * {@link PropertyResolver}. The property map can be set via the attribute
+	 * key {@link SessionAttributes#PROPERTIES}.
+	 */
+	public static class SessionAttributes extends ChainingAttributes
+			implements PropertyResolver {
+
+		/** Key for storing a map of properties in the attributes. */
+		public static final AttributeKey<Map<String, Object>> PROPERTIES = new AttributeKey<>();
+
+		private final PropertyResolver parentProperties;
+
+		/**
+		 * Creates a new {@link SessionAttributes} attribute and property
+		 * source.
+		 *
+		 * @param self
+		 *            to search for attributes first
+		 * @param parent
+		 *            to search for attributes if not found in {@code self}
+		 * @param parentProperties
+		 *            to search for properties if not found in {@code self}
+		 */
+		public SessionAttributes(AttributeRepository self,
+				AttributeRepository parent, PropertyResolver parentProperties) {
+			super(self, parent);
+			this.parentProperties = parentProperties;
+		}
+
+		@Override
+		public PropertyResolver getParentPropertyResolver() {
+			return parentProperties;
+		}
+
+		@Override
+		public Map<String, Object> getProperties() {
+			Map<String, Object> props = getAttribute(PROPERTIES);
+			return props == null ? Collections.emptyMap() : props;
+		}
+	}
 }
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 b8dd60f..1825fb3 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
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2018, Thomas Wolf <thomas.wolf@paranor.ch> and others
+ * Copyright (C) 2018, 2020 Thomas Wolf <thomas.wolf@paranor.ch> and others
  *
  * This program and the accompanying materials are made available under the
  * terms of the Eclipse Distribution License v. 1.0 which is available at
@@ -23,12 +23,16 @@
 import java.security.GeneralSecurityException;
 import java.security.KeyPair;
 import java.util.Arrays;
+import java.util.Collections;
+import java.util.HashMap;
 import java.util.Iterator;
 import java.util.List;
+import java.util.Map;
 import java.util.NoSuchElementException;
 import java.util.Objects;
 import java.util.stream.Collectors;
 
+import org.apache.sshd.client.ClientAuthenticationManager;
 import org.apache.sshd.client.SshClient;
 import org.apache.sshd.client.config.hosts.HostConfigEntry;
 import org.apache.sshd.client.future.ConnectFuture;
@@ -45,6 +49,8 @@
 import org.apache.sshd.common.session.SessionContext;
 import org.apache.sshd.common.session.helpers.AbstractSession;
 import org.apache.sshd.common.util.ValidateUtils;
+import org.eclipse.jgit.internal.transport.sshd.JGitClientSession.ChainingAttributes;
+import org.eclipse.jgit.internal.transport.sshd.JGitClientSession.SessionAttributes;
 import org.eclipse.jgit.internal.transport.sshd.proxy.HttpClientConnector;
 import org.eclipse.jgit.internal.transport.sshd.proxy.Socks5ClientConnector;
 import org.eclipse.jgit.transport.CredentialsProvider;
@@ -52,6 +58,7 @@
 import org.eclipse.jgit.transport.sshd.KeyCache;
 import org.eclipse.jgit.transport.sshd.ProxyData;
 import org.eclipse.jgit.transport.sshd.ProxyDataFactory;
+import org.eclipse.jgit.util.StringUtils;
 
 /**
  * Customized {@link SshClient} for JGit. It creates specialized
@@ -100,35 +107,55 @@
 		int port = hostConfig.getPort();
 		ValidateUtils.checkTrue(port > 0, "Invalid port: %d", port); //$NON-NLS-1$
 		String userName = hostConfig.getUsername();
+		AttributeRepository attributes = chain(context, this);
 		InetSocketAddress address = new InetSocketAddress(host, port);
 		ConnectFuture connectFuture = new DefaultConnectFuture(
 				userName + '@' + address, null);
 		SshFutureListener<IoConnectFuture> listener = createConnectCompletionListener(
 				connectFuture, userName, address, hostConfig);
-		// sshd needs some entries from the host config already in the
-		// constructor of the session. Put those as properties on this client,
-		// where it will find them. We can set the host config only once the
-		// session object has been created.
-		copyProperty(
-				hostConfig.getProperty(SshConstants.PREFERRED_AUTHENTICATIONS,
-						getAttribute(PREFERRED_AUTHENTICATIONS)),
-				PREFERRED_AUTHS);
-		setAttribute(HOST_CONFIG_ENTRY, hostConfig);
-		setAttribute(ORIGINAL_REMOTE_ADDRESS, address);
+		attributes = sessionAttributes(attributes, hostConfig, address);
 		// Proxy support
 		ProxyData proxy = getProxyData(address);
 		if (proxy != null) {
 			address = configureProxy(proxy, address);
 			proxy.clearPassword();
 		}
-		connector.connect(address, this, localAddress).addListener(listener);
+		connector.connect(address, attributes, localAddress)
+				.addListener(listener);
 		return connectFuture;
 	}
 
-	private void copyProperty(String value, String key) {
-		if (value != null && !value.isEmpty()) {
-			getProperties().put(key, value);
+	private AttributeRepository chain(AttributeRepository self,
+			AttributeRepository parent) {
+		if (self == null) {
+			return Objects.requireNonNull(parent);
 		}
+		if (parent == null || parent == self) {
+			return self;
+		}
+		return new ChainingAttributes(self, parent);
+	}
+
+	private AttributeRepository sessionAttributes(AttributeRepository parent,
+			HostConfigEntry hostConfig, InetSocketAddress originalAddress) {
+		// sshd needs some entries from the host config already in the
+		// constructor of the session. Put those into a dedicated
+		// AttributeRepository for the new session where it will find them.
+		// We can set the host config only once the session object has been
+		// created.
+		Map<AttributeKey<?>, Object> data = new HashMap<>();
+		data.put(HOST_CONFIG_ENTRY, hostConfig);
+		data.put(ORIGINAL_REMOTE_ADDRESS, originalAddress);
+		String preferredAuths = hostConfig.getProperty(
+				SshConstants.PREFERRED_AUTHENTICATIONS,
+				resolveAttribute(PREFERRED_AUTHENTICATIONS));
+		if (!StringUtils.isEmptyOrNull(preferredAuths)) {
+			data.put(SessionAttributes.PROPERTIES,
+					Collections.singletonMap(PREFERRED_AUTHS, preferredAuths));
+		}
+		return new SessionAttributes(
+				AttributeRepository.ofAttributesMap(data),
+				parent, this);
 	}
 
 	private ProxyData getProxyData(InetSocketAddress remoteAddress) {
@@ -219,11 +246,6 @@
 		int numberOfPasswordPrompts = getNumberOfPasswordPrompts(hostConfig);
 		session.getProperties().put(PASSWORD_PROMPTS,
 				Integer.valueOf(numberOfPasswordPrompts));
-		FilePasswordProvider passwordProvider = getFilePasswordProvider();
-		if (passwordProvider instanceof RepeatingFilePasswordProvider) {
-			((RepeatingFilePasswordProvider) passwordProvider)
-					.setAttempts(numberOfPasswordPrompts);
-		}
 		List<Path> identities = hostConfig.getIdentities().stream()
 				.map(s -> {
 					try {
@@ -237,6 +259,7 @@
 				.collect(Collectors.toList());
 		CachingKeyPairProvider ourConfiguredKeysProvider = new CachingKeyPairProvider(
 				identities, keyCache);
+		FilePasswordProvider passwordProvider = getFilePasswordProvider();
 		ourConfiguredKeysProvider.setPasswordFinder(passwordProvider);
 		if (hostConfig.isIdentitiesOnly()) {
 			session.setKeyIdentityProvider(ourConfiguredKeysProvider);
@@ -265,9 +288,7 @@
 			log.warn(format(SshdText.get().configInvalidPositive,
 					SshConstants.NUMBER_OF_PASSWORD_PROMPTS, prompts));
 		}
-		// Default for NumberOfPasswordPrompts according to
-		// https://man.openbsd.org/ssh_config
-		return 3;
+		return ClientAuthenticationManager.DEFAULT_PASSWORD_PROMPTS;
 	}
 
 	/**
@@ -408,6 +429,5 @@
 
 			};
 		}
-
 	}
 }
diff --git a/org.eclipse.jgit.ssh.apache/src/org/eclipse/jgit/internal/transport/sshd/PasswordProviderWrapper.java b/org.eclipse.jgit.ssh.apache/src/org/eclipse/jgit/internal/transport/sshd/PasswordProviderWrapper.java
index 5b48a8c..078e411 100644
--- a/org.eclipse.jgit.ssh.apache/src/org/eclipse/jgit/internal/transport/sshd/PasswordProviderWrapper.java
+++ b/org.eclipse.jgit.ssh.apache/src/org/eclipse/jgit/internal/transport/sshd/PasswordProviderWrapper.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2018, Thomas Wolf <thomas.wolf@paranor.ch> and others
+ * Copyright (C) 2018, 2020 Thomas Wolf <thomas.wolf@paranor.ch> and others
  *
  * This program and the accompanying materials are made available under the
  * terms of the Eclipse Distribution License v. 1.0 which is available at
@@ -16,8 +16,12 @@
 import java.util.Map;
 import java.util.concurrent.ConcurrentHashMap;
 import java.util.concurrent.atomic.AtomicInteger;
+import java.util.function.Supplier;
 
+import org.apache.sshd.client.ClientAuthenticationManager;
+import org.apache.sshd.common.AttributeRepository.AttributeKey;
 import org.apache.sshd.common.NamedResource;
+import org.apache.sshd.common.config.keys.FilePasswordProvider;
 import org.apache.sshd.common.session.SessionContext;
 import org.eclipse.jgit.annotations.NonNull;
 import org.eclipse.jgit.transport.CredentialsProvider;
@@ -25,39 +29,61 @@
 import org.eclipse.jgit.transport.sshd.KeyPasswordProvider;
 
 /**
- * A bridge from sshd's {@link RepeatingFilePasswordProvider} to our
+ * A bridge from sshd's {@link FilePasswordProvider} to our per-session
  * {@link KeyPasswordProvider} API.
  */
-public class PasswordProviderWrapper implements RepeatingFilePasswordProvider {
+public class PasswordProviderWrapper implements FilePasswordProvider {
 
-	private final KeyPasswordProvider delegate;
+	private static final AttributeKey<PerSessionState> STATE = new AttributeKey<>();
 
-	private Map<String, AtomicInteger> counts = new ConcurrentHashMap<>();
+	private static class PerSessionState {
+
+		Map<String, AtomicInteger> counts = new ConcurrentHashMap<>();
+
+		KeyPasswordProvider delegate;
+
+	}
+
+	private final Supplier<KeyPasswordProvider> factory;
 
 	/**
-	 * @param delegate
+	 * Creates a new {@link PasswordProviderWrapper}.
+	 *
+	 * @param factory
+	 *            to use to create per-session {@link KeyPasswordProvider}s
 	 */
-	public PasswordProviderWrapper(@NonNull KeyPasswordProvider delegate) {
-		this.delegate = delegate;
+	public PasswordProviderWrapper(
+			@NonNull Supplier<KeyPasswordProvider> factory) {
+		this.factory = factory;
 	}
 
-	@Override
-	public void setAttempts(int numberOfPasswordPrompts) {
-		delegate.setAttempts(numberOfPasswordPrompts);
-	}
-
-	@Override
-	public int getAttempts() {
-		return delegate.getAttempts();
+	private PerSessionState getState(SessionContext context) {
+		PerSessionState state = context.getAttribute(STATE);
+		if (state == null) {
+			state = new PerSessionState();
+			state.delegate = factory.get();
+			Integer maxNumberOfAttempts = context
+					.getInteger(ClientAuthenticationManager.PASSWORD_PROMPTS);
+			if (maxNumberOfAttempts != null
+					&& maxNumberOfAttempts.intValue() > 0) {
+				state.delegate.setAttempts(maxNumberOfAttempts.intValue());
+			} else {
+				state.delegate.setAttempts(
+						ClientAuthenticationManager.DEFAULT_PASSWORD_PROMPTS);
+			}
+			context.setAttribute(STATE, state);
+		}
+		return state;
 	}
 
 	@Override
 	public String getPassword(SessionContext session, NamedResource resource,
 			int attemptIndex) throws IOException {
 		String key = resource.getName();
-		int attempt = counts
+		PerSessionState state = getState(session);
+		int attempt = state.counts
 				.computeIfAbsent(key, k -> new AtomicInteger()).get();
-		char[] passphrase = delegate.getPassphrase(toUri(key), attempt);
+		char[] passphrase = state.delegate.getPassphrase(toUri(key), attempt);
 		if (passphrase == null) {
 			return null;
 		}
@@ -74,18 +100,19 @@
 			String password, Exception err)
 			throws IOException, GeneralSecurityException {
 		String key = resource.getName();
-		AtomicInteger count = counts.get(key);
+		PerSessionState state = getState(session);
+		AtomicInteger count = state.counts.get(key);
 		int numberOfAttempts = count == null ? 0 : count.incrementAndGet();
 		ResourceDecodeResult result = null;
 		try {
-			if (delegate.keyLoaded(toUri(key), numberOfAttempts, err)) {
+			if (state.delegate.keyLoaded(toUri(key), numberOfAttempts, err)) {
 				result = ResourceDecodeResult.RETRY;
 			} else {
 				result = ResourceDecodeResult.TERMINATE;
 			}
 		} finally {
 			if (result != ResourceDecodeResult.RETRY) {
-				counts.remove(key);
+				state.counts.remove(key);
 			}
 		}
 		return result;
diff --git a/org.eclipse.jgit.ssh.apache/src/org/eclipse/jgit/internal/transport/sshd/RepeatingFilePasswordProvider.java b/org.eclipse.jgit.ssh.apache/src/org/eclipse/jgit/internal/transport/sshd/RepeatingFilePasswordProvider.java
deleted file mode 100644
index 86f0fe7..0000000
--- a/org.eclipse.jgit.ssh.apache/src/org/eclipse/jgit/internal/transport/sshd/RepeatingFilePasswordProvider.java
+++ /dev/null
@@ -1,41 +0,0 @@
-/*
- * Copyright (C) 2018, Thomas Wolf <thomas.wolf@paranor.ch> and others
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Distribution License v. 1.0 which is available at
- * https://www.eclipse.org/org/documents/edl-v10.php.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
-package org.eclipse.jgit.internal.transport.sshd;
-
-import org.apache.sshd.common.config.keys.FilePasswordProvider;
-
-/**
- * A {@link FilePasswordProvider} augmented to support repeatedly asking for
- * passwords.
- *
- */
-public interface RepeatingFilePasswordProvider extends FilePasswordProvider {
-
-	/**
-	 * Define the maximum number of attempts to get a password that should be
-	 * attempted for one identity resource through this provider.
-	 *
-	 * @param numberOfPasswordPrompts
-	 *            number of times to ask for a password;
-	 *            {@link IllegalArgumentException} may be thrown if <= 0
-	 */
-	void setAttempts(int numberOfPasswordPrompts);
-
-	/**
-	 * Gets the maximum number of attempts to get a password that should be
-	 * attempted for one identity resource through this provider.
-	 *
-	 * @return the maximum number of attempts to try, always >= 1.
-	 */
-	default int getAttempts() {
-		return 1;
-	}
-
-}
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 f67170e..22966f9 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
@@ -19,6 +19,7 @@
 
 	// @formatter:off
 	/***/ public String authenticationCanceled;
+	/***/ public String authenticationOnClosedSession;
 	/***/ public String closeListenerFailed;
 	/***/ public String configInvalidPath;
 	/***/ public String configInvalidPattern;
@@ -87,6 +88,7 @@
 	/***/ public String serverIdTooLong;
 	/***/ public String serverIdWithNul;
 	/***/ public String sessionCloseFailed;
+	/***/ public String sessionWithoutUsername;
 	/***/ public String sshClosingDown;
 	/***/ public String sshCommandTimeout;
 	/***/ public String sshProcessStillRunning;
diff --git a/org.eclipse.jgit.ssh.apache/src/org/eclipse/jgit/transport/sshd/SshdSession.java b/org.eclipse.jgit.ssh.apache/src/org/eclipse/jgit/transport/sshd/SshdSession.java
index 0c1533c..dfd7cca 100644
--- a/org.eclipse.jgit.ssh.apache/src/org/eclipse/jgit/transport/sshd/SshdSession.java
+++ b/org.eclipse.jgit.ssh.apache/src/org/eclipse/jgit/transport/sshd/SshdSession.java
@@ -13,7 +13,6 @@
 
 import java.io.IOException;
 import java.io.InputStream;
-import java.io.InterruptedIOException;
 import java.io.OutputStream;
 import java.time.Duration;
 import java.util.ArrayList;
@@ -134,28 +133,23 @@
 	public Process exec(String commandName, int timeout) throws IOException {
 		@SuppressWarnings("resource")
 		ChannelExec exec = session.createExecChannel(commandName);
-		long timeoutMillis = TimeUnit.SECONDS.toMillis(timeout);
-		try {
-			if (timeout <= 0) {
+		if (timeout <= 0) {
+			try {
 				exec.open().verify();
-			} else {
-				long start = System.nanoTime();
-				exec.open().verify(timeoutMillis);
-				timeoutMillis -= TimeUnit.NANOSECONDS
-						.toMillis(System.nanoTime() - start);
+			} catch (IOException | RuntimeException e) {
+				exec.close(true);
+				throw e;
 			}
-		} catch (IOException | RuntimeException e) {
-			exec.close(true);
-			throw e;
+		} else {
+			try {
+				exec.open().verify(TimeUnit.SECONDS.toMillis(timeout));
+			} catch (IOException | RuntimeException e) {
+				exec.close(true);
+				throw new IOException(format(SshdText.get().sshCommandTimeout,
+						commandName, Integer.valueOf(timeout)), e);
+			}
 		}
-		if (timeout > 0 && timeoutMillis <= 0) {
-			// We have used up the whole timeout for opening the channel
-			exec.close(true);
-			throw new InterruptedIOException(
-					format(SshdText.get().sshCommandTimeout, commandName,
-							Integer.valueOf(timeout)));
-		}
-		return new SshdExecProcess(exec, commandName, timeoutMillis);
+		return new SshdExecProcess(exec, commandName);
 	}
 
 	/**
@@ -195,14 +189,10 @@
 
 		private final ChannelExec channel;
 
-		private final long timeoutMillis;
-
 		private final String commandName;
 
-		public SshdExecProcess(ChannelExec channel, String commandName,
-				long timeoutMillis) {
+		public SshdExecProcess(ChannelExec channel, String commandName) {
 			this.channel = channel;
-			this.timeoutMillis = timeoutMillis > 0 ? timeoutMillis : -1L;
 			this.commandName = commandName;
 		}
 
@@ -223,7 +213,7 @@
 
 		@Override
 		public int waitFor() throws InterruptedException {
-			if (waitFor(timeoutMillis, TimeUnit.MILLISECONDS)) {
+			if (waitFor(-1L, TimeUnit.MILLISECONDS)) {
 				return exitValue();
 			}
 			return -1;
@@ -252,7 +242,7 @@
 		@Override
 		public void destroy() {
 			if (channel.isOpen()) {
-				channel.close(true);
+				channel.close(false);
 			}
 		}
 	}
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 bb4e49b..0f7ab84 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, 2019 Thomas Wolf <thomas.wolf@paranor.ch> and others
+ * Copyright (C) 2018, 2020 Thomas Wolf <thomas.wolf@paranor.ch> and others
  *
  * This program and the accompanying materials are made available under the
  * terms of the Eclipse Distribution License v. 1.0 which is available at
@@ -25,6 +25,7 @@
 import java.util.Set;
 import java.util.concurrent.ConcurrentHashMap;
 import java.util.concurrent.atomic.AtomicBoolean;
+import java.util.function.Supplier;
 import java.util.stream.Collectors;
 
 import org.apache.sshd.client.ClientBuilder;
@@ -194,12 +195,11 @@
 						home, sshDir);
 				KeyIdentityProvider defaultKeysProvider = toKeyIdentityProvider(
 						getDefaultKeys(sshDir));
-				KeyPasswordProvider passphrases = createKeyPasswordProvider(
-						credentialsProvider);
 				SshClient client = ClientBuilder.builder()
 						.factory(JGitSshClient::new)
-						.filePasswordProvider(
-								createFilePasswordProvider(passphrases))
+						.filePasswordProvider(createFilePasswordProvider(
+								() -> createKeyPasswordProvider(
+										credentialsProvider)))
 						.hostConfigEntryResolver(configFile)
 						.serverKeyVerifier(new JGitServerKeyVerifier(
 								getServerKeyDatabase(home, sshDir)))
@@ -536,14 +536,14 @@
 	/**
 	 * Creates a {@link FilePasswordProvider} for a new session.
 	 *
-	 * @param provider
-	 *            the {@link KeyPasswordProvider} to delegate to
+	 * @param providerFactory
+	 *            providing the {@link KeyPasswordProvider} to delegate to
 	 * @return a new {@link FilePasswordProvider}
 	 */
 	@NonNull
 	private FilePasswordProvider createFilePasswordProvider(
-			KeyPasswordProvider provider) {
-		return new PasswordProviderWrapper(provider);
+			Supplier<KeyPasswordProvider> providerFactory) {
+		return new PasswordProviderWrapper(providerFactory);
 	}
 
 	/**
diff --git a/org.eclipse.jgit.ssh.jsch.test/.settings/org.eclipse.jdt.core.prefs b/org.eclipse.jgit.ssh.jsch.test/.settings/org.eclipse.jdt.core.prefs
index 2bc2cf3..6139f38 100644
--- a/org.eclipse.jgit.ssh.jsch.test/.settings/org.eclipse.jdt.core.prefs
+++ b/org.eclipse.jgit.ssh.jsch.test/.settings/org.eclipse.jdt.core.prefs
@@ -53,7 +53,7 @@
 org.eclipse.jdt.core.compiler.problem.missingJavadocCommentsOverriding=disabled
 org.eclipse.jdt.core.compiler.problem.missingJavadocCommentsVisibility=protected
 org.eclipse.jdt.core.compiler.problem.missingJavadocTagDescription=return_tag
-org.eclipse.jdt.core.compiler.problem.missingJavadocTags=error
+org.eclipse.jdt.core.compiler.problem.missingJavadocTags=ignore
 org.eclipse.jdt.core.compiler.problem.missingJavadocTagsMethodTypeParameters=disabled
 org.eclipse.jdt.core.compiler.problem.missingJavadocTagsOverriding=disabled
 org.eclipse.jdt.core.compiler.problem.missingJavadocTagsVisibility=private
diff --git a/org.eclipse.jgit.ssh.jsch.test/META-INF/MANIFEST.MF b/org.eclipse.jgit.ssh.jsch.test/META-INF/MANIFEST.MF
index b62b0d6..345c3cf 100644
--- a/org.eclipse.jgit.ssh.jsch.test/META-INF/MANIFEST.MF
+++ b/org.eclipse.jgit.ssh.jsch.test/META-INF/MANIFEST.MF
@@ -3,21 +3,21 @@
 Bundle-Name: %Bundle-Name
 Automatic-Module-Name: org.eclipse.jgit.ssh.jsch.test
 Bundle-SymbolicName: org.eclipse.jgit.ssh.jsch.test
-Bundle-Version: 5.8.2.qualifier
+Bundle-Version: 5.9.1.qualifier
 Bundle-Vendor: %Bundle-Vendor
 Bundle-Localization: plugin
 Bundle-RequiredExecutionEnvironment: JavaSE-1.8
 Import-Package: com.jcraft.jsch;version="[0.1.54,0.2.0)",
- org.eclipse.jgit.errors;version="[5.8.2,5.9.0)",
- org.eclipse.jgit.junit;version="[5.8.2,5.9.0)",
- org.eclipse.jgit.junit.ssh;version="[5.8.2,5.9.0)",
- org.eclipse.jgit.lib;version="[5.8.2,5.9.0)",
- org.eclipse.jgit.transport;version="[5.8.2,5.9.0)",
- org.eclipse.jgit.util;version="[5.8.2,5.9.0)",
+ org.eclipse.jgit.errors;version="[5.9.1,5.10.0)",
+ org.eclipse.jgit.junit;version="[5.9.1,5.10.0)",
+ org.eclipse.jgit.junit.ssh;version="[5.9.1,5.10.0)",
+ org.eclipse.jgit.lib;version="[5.9.1,5.10.0)",
+ org.eclipse.jgit.transport;version="[5.9.1,5.10.0)",
+ org.eclipse.jgit.util;version="[5.9.1,5.10.0)",
  org.junit;version="[4.13,5.0.0)",
  org.junit.experimental.theories;version="[4.13,5.0.0)",
  org.junit.runner;version="[4.13,5.0.0)"
-Export-Package: org.eclipse.jgit.transport;version="5.8.2";
+Export-Package: org.eclipse.jgit.transport;version="5.9.1";
   uses:="org.eclipse.jgit.transport,
     org.eclipse.jgit.junit,
     org.eclipse.jgit.junit.ssh"
diff --git a/org.eclipse.jgit.ssh.jsch.test/pom.xml b/org.eclipse.jgit.ssh.jsch.test/pom.xml
index 86aa02a..24e1109 100644
--- a/org.eclipse.jgit.ssh.jsch.test/pom.xml
+++ b/org.eclipse.jgit.ssh.jsch.test/pom.xml
@@ -17,7 +17,7 @@
   <parent>
     <groupId>org.eclipse.jgit</groupId>
     <artifactId>org.eclipse.jgit-parent</artifactId>
-    <version>5.8.2-SNAPSHOT</version>
+    <version>5.9.1-SNAPSHOT</version>
   </parent>
 
   <artifactId>org.eclipse.jgit.ssh.jsch.test</artifactId>
diff --git a/org.eclipse.jgit.ssh.jsch/META-INF/MANIFEST.MF b/org.eclipse.jgit.ssh.jsch/META-INF/MANIFEST.MF
index 0f77004..715495a 100644
--- a/org.eclipse.jgit.ssh.jsch/META-INF/MANIFEST.MF
+++ b/org.eclipse.jgit.ssh.jsch/META-INF/MANIFEST.MF
@@ -3,24 +3,24 @@
 Bundle-Name: %Bundle-Name
 Automatic-Module-Name: org.eclipse.jgit.ssh.jsch
 Bundle-SymbolicName: org.eclipse.jgit.ssh.jsch;singleton:=true
-Fragment-Host: org.eclipse.jgit;bundle-version="[5.8.2,5.9.0)"
+Fragment-Host: org.eclipse.jgit;bundle-version="[5.9.1,5.10.0)"
 Bundle-Vendor: %Bundle-Vendor
 Bundle-Localization: plugin
 Bundle-ActivationPolicy: lazy
-Bundle-Version: 5.8.2.qualifier
+Bundle-Version: 5.9.1.qualifier
 Bundle-RequiredExecutionEnvironment: JavaSE-1.8
-Export-Package: org.eclipse.jgit.internal.transport.jsch;version="5.8.2";x-friends:="org.eclipse.egit.core",
- org.eclipse.jgit.transport;version="5.8.2";
+Export-Package: org.eclipse.jgit.internal.transport.jsch;version="5.9.1";x-friends:="org.eclipse.egit.core",
+ org.eclipse.jgit.transport;version="5.9.1";
   uses:="org.eclipse.jgit.transport,
    org.eclipse.jgit.internal.transport.ssh,
    org.eclipse.jgit.util,
    com.jcraft.jsch"
 Import-Package: com.jcraft.jsch;version="[0.1.37,0.2.0)",
- org.eclipse.jgit.errors;version="[5.8.2,5.9.0)",
- org.eclipse.jgit.internal;version="[5.8.2,5.9.0)",
- org.eclipse.jgit.internal.transport.ssh;version="[5.8.2,5.9.0)",
- org.eclipse.jgit.nls;version="[5.8.2,5.9.0)",
- org.eclipse.jgit.transport;version="[5.8.2,5.9.0)",
- org.eclipse.jgit.util;version="[5.8.2,5.9.0)",
- org.eclipse.jgit.util.io;version="[5.8.2,5.9.0)",
+ org.eclipse.jgit.errors;version="[5.9.1,5.10.0)",
+ org.eclipse.jgit.internal;version="[5.9.1,5.10.0)",
+ org.eclipse.jgit.internal.transport.ssh;version="[5.9.1,5.10.0)",
+ org.eclipse.jgit.nls;version="[5.9.1,5.10.0)",
+ org.eclipse.jgit.transport;version="[5.9.1,5.10.0)",
+ org.eclipse.jgit.util;version="[5.9.1,5.10.0)",
+ org.eclipse.jgit.util.io;version="[5.9.1,5.10.0)",
  org.slf4j;version="[1.7.0,2.0.0)"
diff --git a/org.eclipse.jgit.ssh.jsch/META-INF/SOURCE-MANIFEST.MF b/org.eclipse.jgit.ssh.jsch/META-INF/SOURCE-MANIFEST.MF
index 7657c4c..aaf7c2d 100644
--- a/org.eclipse.jgit.ssh.jsch/META-INF/SOURCE-MANIFEST.MF
+++ b/org.eclipse.jgit.ssh.jsch/META-INF/SOURCE-MANIFEST.MF
@@ -3,5 +3,5 @@
 Bundle-Name: org.eclipse.jgit.ssh.jsch - Sources
 Bundle-SymbolicName: org.eclipse.jgit.ssh.jsch.source
 Bundle-Vendor: Eclipse.org - JGit
-Bundle-Version: 5.8.2.qualifier
-Eclipse-SourceBundle: org.eclipse.jgit.ssh.jsch;version="5.8.2.qualifier";roots="."
+Bundle-Version: 5.9.1.qualifier
+Eclipse-SourceBundle: org.eclipse.jgit.ssh.jsch;version="5.9.1.qualifier";roots="."
diff --git a/org.eclipse.jgit.ssh.jsch/pom.xml b/org.eclipse.jgit.ssh.jsch/pom.xml
index 6b0ff9b..5916157 100644
--- a/org.eclipse.jgit.ssh.jsch/pom.xml
+++ b/org.eclipse.jgit.ssh.jsch/pom.xml
@@ -17,7 +17,7 @@
   <parent>
     <groupId>org.eclipse.jgit</groupId>
     <artifactId>org.eclipse.jgit-parent</artifactId>
-    <version>5.8.2-SNAPSHOT</version>
+    <version>5.9.1-SNAPSHOT</version>
   </parent>
 
   <artifactId>org.eclipse.jgit.ssh.jsch</artifactId>
@@ -123,7 +123,6 @@
         </configuration>
       </plugin>
 
-      <!-- No previous version to compare to
       <plugin>
           <groupId>com.github.siom79.japicmp</groupId>
           <artifactId>japicmp-maven-plugin</artifactId>
@@ -165,13 +164,11 @@
           </execution>
         </executions>
       </plugin>
-      -->
     </plugins>
   </build>
 
   <reporting>
     <plugins>
-      <!-- No previous version to compare to
       <plugin>
           <groupId>com.github.siom79.japicmp</groupId>
           <artifactId>japicmp-maven-plugin</artifactId>
@@ -212,7 +209,6 @@
               <skip>false</skip>
           </configuration>
       </plugin>
-      -->
     </plugins>
   </reporting>
 </project>
diff --git a/org.eclipse.jgit.ssh.jsch/src/org/eclipse/jgit/transport/JschSession.java b/org.eclipse.jgit.ssh.jsch/src/org/eclipse/jgit/transport/JschSession.java
index 300e03d..858bdf3 100644
--- a/org.eclipse.jgit.ssh.jsch/src/org/eclipse/jgit/transport/JschSession.java
+++ b/org.eclipse.jgit.ssh.jsch/src/org/eclipse/jgit/transport/JschSession.java
@@ -198,7 +198,7 @@
 		@Override
 		public int exitValue() {
 			if (isRunning())
-				throw new IllegalStateException();
+				throw new IllegalThreadStateException();
 			return channel.getExitStatus();
 		}
 
diff --git a/org.eclipse.jgit.test/.settings/org.eclipse.jdt.core.prefs b/org.eclipse.jgit.test/.settings/org.eclipse.jdt.core.prefs
index 3dd5840..4c4634a 100644
--- a/org.eclipse.jgit.test/.settings/org.eclipse.jdt.core.prefs
+++ b/org.eclipse.jgit.test/.settings/org.eclipse.jdt.core.prefs
@@ -52,7 +52,7 @@
 org.eclipse.jdt.core.compiler.problem.missingJavadocCommentsOverriding=disabled
 org.eclipse.jdt.core.compiler.problem.missingJavadocCommentsVisibility=protected
 org.eclipse.jdt.core.compiler.problem.missingJavadocTagDescription=return_tag
-org.eclipse.jdt.core.compiler.problem.missingJavadocTags=error
+org.eclipse.jdt.core.compiler.problem.missingJavadocTags=ignore
 org.eclipse.jdt.core.compiler.problem.missingJavadocTagsMethodTypeParameters=disabled
 org.eclipse.jdt.core.compiler.problem.missingJavadocTagsOverriding=disabled
 org.eclipse.jdt.core.compiler.problem.missingJavadocTagsVisibility=private
diff --git a/org.eclipse.jgit.test/META-INF/MANIFEST.MF b/org.eclipse.jgit.test/META-INF/MANIFEST.MF
index 02be3df..1ce4c2b 100644
--- a/org.eclipse.jgit.test/META-INF/MANIFEST.MF
+++ b/org.eclipse.jgit.test/META-INF/MANIFEST.MF
@@ -3,7 +3,7 @@
 Bundle-Name: %Bundle-Name
 Automatic-Module-Name: org.eclipse.jgit.test
 Bundle-SymbolicName: org.eclipse.jgit.test
-Bundle-Version: 5.8.2.qualifier
+Bundle-Version: 5.9.1.qualifier
 Bundle-Localization: plugin
 Bundle-Vendor: %Bundle-Vendor
 Bundle-RequiredExecutionEnvironment: JavaSE-1.8
@@ -16,58 +16,58 @@
  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.assertj.core.api;version="[3.14.0,4.0.0)",
- org.eclipse.jgit.annotations;version="[5.8.2,5.9.0)",
- org.eclipse.jgit.api;version="[5.8.2,5.9.0)",
- org.eclipse.jgit.api.errors;version="[5.8.2,5.9.0)",
- org.eclipse.jgit.archive;version="[5.8.2,5.9.0)",
- org.eclipse.jgit.attributes;version="[5.8.2,5.9.0)",
- org.eclipse.jgit.awtui;version="[5.8.2,5.9.0)",
- org.eclipse.jgit.blame;version="[5.8.2,5.9.0)",
- org.eclipse.jgit.diff;version="[5.8.2,5.9.0)",
- org.eclipse.jgit.dircache;version="[5.8.2,5.9.0)",
- org.eclipse.jgit.errors;version="[5.8.2,5.9.0)",
- org.eclipse.jgit.events;version="[5.8.2,5.9.0)",
- org.eclipse.jgit.fnmatch;version="[5.8.2,5.9.0)",
- org.eclipse.jgit.gitrepo;version="[5.8.2,5.9.0)",
- org.eclipse.jgit.hooks;version="[5.8.2,5.9.0)",
- org.eclipse.jgit.ignore;version="[5.8.2,5.9.0)",
- org.eclipse.jgit.ignore.internal;version="[5.8.2,5.9.0)",
- org.eclipse.jgit.internal;version="[5.8.2,5.9.0)",
- org.eclipse.jgit.internal.fsck;version="[5.8.2,5.9.0)",
- org.eclipse.jgit.internal.storage.dfs;version="[5.8.2,5.9.0)",
- org.eclipse.jgit.internal.storage.file;version="[5.8.2,5.9.0)",
- org.eclipse.jgit.internal.storage.io;version="[5.8.2,5.9.0)",
- org.eclipse.jgit.internal.storage.pack;version="[5.8.2,5.9.0)",
- org.eclipse.jgit.internal.storage.reftable;version="[5.8.2,5.9.0)",
- org.eclipse.jgit.internal.storage.reftree;version="[5.8.2,5.9.0)",
- org.eclipse.jgit.internal.transport.connectivity;version="[5.8.2,5.9.0)",
- org.eclipse.jgit.internal.transport.http;version="[5.8.2,5.9.0)",
- org.eclipse.jgit.internal.transport.parser;version="[5.8.2,5.9.0)",
- org.eclipse.jgit.junit;version="[5.8.2,5.9.0)",
- org.eclipse.jgit.junit.time;version="[5.8.2,5.9.0)",
- org.eclipse.jgit.lfs;version="[5.8.2,5.9.0)",
- org.eclipse.jgit.lib;version="[5.8.2,5.9.0)",
- org.eclipse.jgit.lib.internal;version="[5.8.2,5.9.0)",
- org.eclipse.jgit.merge;version="[5.8.2,5.9.0)",
- org.eclipse.jgit.nls;version="[5.8.2,5.9.0)",
- org.eclipse.jgit.notes;version="[5.8.2,5.9.0)",
- org.eclipse.jgit.patch;version="[5.8.2,5.9.0)",
- org.eclipse.jgit.pgm;version="[5.8.2,5.9.0)",
- org.eclipse.jgit.pgm.internal;version="[5.8.2,5.9.0)",
- org.eclipse.jgit.revplot;version="[5.8.2,5.9.0)",
- org.eclipse.jgit.revwalk;version="[5.8.2,5.9.0)",
- org.eclipse.jgit.revwalk.filter;version="[5.8.2,5.9.0)",
- org.eclipse.jgit.storage.file;version="[5.8.2,5.9.0)",
- org.eclipse.jgit.storage.pack;version="[5.8.2,5.9.0)",
- org.eclipse.jgit.submodule;version="[5.8.2,5.9.0)",
- org.eclipse.jgit.transport;version="[5.8.2,5.9.0)",
- org.eclipse.jgit.transport.http;version="[5.8.2,5.9.0)",
- org.eclipse.jgit.transport.resolver;version="[5.8.2,5.9.0)",
- org.eclipse.jgit.treewalk;version="[5.8.2,5.9.0)",
- org.eclipse.jgit.treewalk.filter;version="[5.8.2,5.9.0)",
- org.eclipse.jgit.util;version="[5.8.2,5.9.0)",
- org.eclipse.jgit.util.io;version="[5.8.2,5.9.0)",
- org.eclipse.jgit.util.sha1;version="[5.8.2,5.9.0)",
+ org.eclipse.jgit.annotations;version="[5.9.1,5.10.0)",
+ org.eclipse.jgit.api;version="[5.9.1,5.10.0)",
+ org.eclipse.jgit.api.errors;version="[5.9.1,5.10.0)",
+ org.eclipse.jgit.archive;version="[5.9.1,5.10.0)",
+ org.eclipse.jgit.attributes;version="[5.9.1,5.10.0)",
+ org.eclipse.jgit.awtui;version="[5.9.1,5.10.0)",
+ org.eclipse.jgit.blame;version="[5.9.1,5.10.0)",
+ org.eclipse.jgit.diff;version="[5.9.1,5.10.0)",
+ org.eclipse.jgit.dircache;version="[5.9.1,5.10.0)",
+ org.eclipse.jgit.errors;version="[5.9.1,5.10.0)",
+ org.eclipse.jgit.events;version="[5.9.1,5.10.0)",
+ org.eclipse.jgit.fnmatch;version="[5.9.1,5.10.0)",
+ org.eclipse.jgit.gitrepo;version="[5.9.1,5.10.0)",
+ org.eclipse.jgit.hooks;version="[5.9.1,5.10.0)",
+ org.eclipse.jgit.ignore;version="[5.9.1,5.10.0)",
+ org.eclipse.jgit.ignore.internal;version="[5.9.1,5.10.0)",
+ org.eclipse.jgit.internal;version="[5.9.1,5.10.0)",
+ org.eclipse.jgit.internal.fsck;version="[5.9.1,5.10.0)",
+ org.eclipse.jgit.internal.storage.dfs;version="[5.9.1,5.10.0)",
+ org.eclipse.jgit.internal.storage.file;version="[5.9.1,5.10.0)",
+ org.eclipse.jgit.internal.storage.io;version="[5.9.1,5.10.0)",
+ org.eclipse.jgit.internal.storage.pack;version="[5.9.1,5.10.0)",
+ org.eclipse.jgit.internal.storage.reftable;version="[5.9.1,5.10.0)",
+ org.eclipse.jgit.internal.storage.reftree;version="[5.9.1,5.10.0)",
+ org.eclipse.jgit.internal.transport.connectivity;version="[5.9.1,5.10.0)",
+ org.eclipse.jgit.internal.transport.http;version="[5.9.1,5.10.0)",
+ org.eclipse.jgit.internal.transport.parser;version="[5.9.1,5.10.0)",
+ org.eclipse.jgit.junit;version="[5.9.1,5.10.0)",
+ org.eclipse.jgit.junit.time;version="[5.9.1,5.10.0)",
+ org.eclipse.jgit.lfs;version="[5.9.1,5.10.0)",
+ org.eclipse.jgit.lib;version="[5.9.1,5.10.0)",
+ org.eclipse.jgit.lib.internal;version="[5.9.1,5.10.0)",
+ org.eclipse.jgit.merge;version="[5.9.1,5.10.0)",
+ org.eclipse.jgit.nls;version="[5.9.1,5.10.0)",
+ org.eclipse.jgit.notes;version="[5.9.1,5.10.0)",
+ org.eclipse.jgit.patch;version="[5.9.1,5.10.0)",
+ org.eclipse.jgit.pgm;version="[5.9.1,5.10.0)",
+ org.eclipse.jgit.pgm.internal;version="[5.9.1,5.10.0)",
+ org.eclipse.jgit.revplot;version="[5.9.1,5.10.0)",
+ org.eclipse.jgit.revwalk;version="[5.9.1,5.10.0)",
+ org.eclipse.jgit.revwalk.filter;version="[5.9.1,5.10.0)",
+ org.eclipse.jgit.storage.file;version="[5.9.1,5.10.0)",
+ org.eclipse.jgit.storage.pack;version="[5.9.1,5.10.0)",
+ org.eclipse.jgit.submodule;version="[5.9.1,5.10.0)",
+ org.eclipse.jgit.transport;version="[5.9.1,5.10.0)",
+ org.eclipse.jgit.transport.http;version="[5.9.1,5.10.0)",
+ org.eclipse.jgit.transport.resolver;version="[5.9.1,5.10.0)",
+ org.eclipse.jgit.treewalk;version="[5.9.1,5.10.0)",
+ org.eclipse.jgit.treewalk.filter;version="[5.9.1,5.10.0)",
+ org.eclipse.jgit.util;version="[5.9.1,5.10.0)",
+ org.eclipse.jgit.util.io;version="[5.9.1,5.10.0)",
+ org.eclipse.jgit.util.sha1;version="[5.9.1,5.10.0)",
  org.junit;version="[4.13,5.0.0)",
  org.junit.experimental.theories;version="[4.13,5.0.0)",
  org.junit.function;version="[4.13.0,5.0.0)",
diff --git a/org.eclipse.jgit.test/pom.xml b/org.eclipse.jgit.test/pom.xml
index ea503a1..d9c9a3d 100644
--- a/org.eclipse.jgit.test/pom.xml
+++ b/org.eclipse.jgit.test/pom.xml
@@ -19,7 +19,7 @@
   <parent>
     <groupId>org.eclipse.jgit</groupId>
     <artifactId>org.eclipse.jgit-parent</artifactId>
-    <version>5.8.2-SNAPSHOT</version>
+    <version>5.9.1-SNAPSHOT</version>
   </parent>
 
   <artifactId>org.eclipse.jgit.test</artifactId>
diff --git a/org.eclipse.jgit.test/tst-rsrc/org/eclipse/jgit/test/resources/gitgit.index.v4 b/org.eclipse.jgit.test/tst-rsrc/org/eclipse/jgit/test/resources/gitgit.index.v4
new file mode 100644
index 0000000..de49e56
--- /dev/null
+++ b/org.eclipse.jgit.test/tst-rsrc/org/eclipse/jgit/test/resources/gitgit.index.v4
Binary files differ
diff --git a/org.eclipse.jgit.test/tst-rsrc/org/eclipse/jgit/test/resources/pack-bad-fanout-table.idx b/org.eclipse.jgit.test/tst-rsrc/org/eclipse/jgit/test/resources/pack-bad-fanout-table.idx
new file mode 100644
index 0000000..2029915
--- /dev/null
+++ b/org.eclipse.jgit.test/tst-rsrc/org/eclipse/jgit/test/resources/pack-bad-fanout-table.idx
Binary files differ
diff --git a/org.eclipse.jgit.test/tst-rsrc/org/eclipse/jgit/test/resources/pack-bad-fanout-table.idxV2 b/org.eclipse.jgit.test/tst-rsrc/org/eclipse/jgit/test/resources/pack-bad-fanout-table.idxV2
new file mode 100644
index 0000000..28bd4a7
--- /dev/null
+++ b/org.eclipse.jgit.test/tst-rsrc/org/eclipse/jgit/test/resources/pack-bad-fanout-table.idxV2
Binary files differ
diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/EolStreamTypeUtilTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/EolStreamTypeUtilTest.java
index 1e3a39a..2a553ce 100644
--- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/EolStreamTypeUtilTest.java
+++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/EolStreamTypeUtilTest.java
@@ -1,43 +1,11 @@
 /*
- * Copyright (C) 2015, Ivan Motsch <ivan.motsch@bsiag.com>
+ * Copyright (C) 2015, 2020 Ivan Motsch <ivan.motsch@bsiag.com> and others
  *
- * 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
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Distribution License v. 1.0 which is available at
+ * https://www.eclipse.org/org/documents/edl-v10.php.
  *
- * 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.
+ * SPDX-License-Identifier: BSD-3-Clause
  */
 
 package org.eclipse.jgit.api;
@@ -90,16 +58,20 @@
 		testCheckout(TEXT_LF, AUTO_LF, "\r", "\r");
 		testCheckout(TEXT_LF, AUTO_LF, "\n", "\n");
 
-		testCheckout(TEXT_LF, AUTO_LF, "\r\n", "\n");
+		testCheckout(TEXT_LF, null, "\r\n", "\n");
+		testCheckout(null, AUTO_LF, "\r\n", "\r\n");
 		testCheckout(TEXT_LF, AUTO_LF, "\n\r", "\n\r");
 
-		testCheckout(TEXT_LF, AUTO_LF, "\n\r\n", "\n\n");
-		testCheckout(TEXT_LF, AUTO_LF, "\r\n\r", "\n\r");
+		testCheckout(TEXT_LF, null, "\n\r\n", "\n\n");
+		testCheckout(null, AUTO_LF, "\n\r\n", "\n\r\n");
+		testCheckout(TEXT_LF, null, "\r\n\r", "\n\r");
+		testCheckout(null, AUTO_LF, "\r\n\r", "\r\n\r");
 
 		testCheckout(TEXT_LF, AUTO_LF, "a\nb\n", "a\nb\n");
 		testCheckout(TEXT_LF, AUTO_LF, "a\rb\r", "a\rb\r");
 		testCheckout(TEXT_LF, AUTO_LF, "a\n\rb\n\r", "a\n\rb\n\r");
-		testCheckout(TEXT_LF, AUTO_LF, "a\r\nb\r\n", "a\nb\n");
+		testCheckout(TEXT_LF, null, "a\r\nb\r\n", "a\nb\n");
+		testCheckout(null, AUTO_LF, "a\r\nb\r\n", "a\r\nb\r\n");
 	}
 
 	@Test
@@ -153,45 +125,49 @@
 		byte[] outputBytes = output.getBytes(UTF_8);
 		byte[] expectedConversionBytes = expectedConversion.getBytes(UTF_8);
 
-		// test using output text and assuming it was declared TEXT
-		b = new ByteArrayOutputStream();
-		try (OutputStream out = EolStreamTypeUtil.wrapOutputStream(b,
-				streamTypeText)) {
-			out.write(outputBytes);
+		if (streamTypeText != null) {
+			// test using output text and assuming it was declared TEXT
+			b = new ByteArrayOutputStream();
+			try (OutputStream out = EolStreamTypeUtil.wrapOutputStream(b,
+					streamTypeText)) {
+				out.write(outputBytes);
+			}
+			assertArrayEquals(expectedConversionBytes, b.toByteArray());
 		}
-		assertArrayEquals(expectedConversionBytes, b.toByteArray());
-
-		// test using ouput text and assuming it was declared AUTO, using binary
-		// detection
-		b = new ByteArrayOutputStream();
-		try (OutputStream out = EolStreamTypeUtil.wrapOutputStream(b,
-				streamTypeWithBinaryCheck)) {
-			out.write(outputBytes);
+		if (streamTypeWithBinaryCheck != null) {
+			// test using output text and assuming it was declared AUTO, using
+			// binary detection
+			b = new ByteArrayOutputStream();
+			try (OutputStream out = EolStreamTypeUtil.wrapOutputStream(b,
+					streamTypeWithBinaryCheck)) {
+				out.write(outputBytes);
+			}
+			assertArrayEquals(expectedConversionBytes, b.toByteArray());
 		}
-		assertArrayEquals(expectedConversionBytes, b.toByteArray());
-
 		// now pollute output text with some binary bytes
 		outputBytes = extendWithBinaryData(outputBytes);
 		expectedConversionBytes = extendWithBinaryData(expectedConversionBytes);
 
-		// again, test using output text and assuming it was declared TEXT
-		b = new ByteArrayOutputStream();
-		try (OutputStream out = EolStreamTypeUtil.wrapOutputStream(b,
-				streamTypeText)) {
-			out.write(outputBytes);
+		if (streamTypeText != null) {
+			// again, test using output text and assuming it was declared TEXT
+			b = new ByteArrayOutputStream();
+			try (OutputStream out = EolStreamTypeUtil.wrapOutputStream(b,
+					streamTypeText)) {
+				out.write(outputBytes);
+			}
+			assertArrayEquals(expectedConversionBytes, b.toByteArray());
 		}
-		assertArrayEquals(expectedConversionBytes, b.toByteArray());
-
-		// again, test using ouput text and assuming it was declared AUTO, using
-		// binary
-		// detection
-		b = new ByteArrayOutputStream();
-		try (OutputStream out = EolStreamTypeUtil.wrapOutputStream(b,
-				streamTypeWithBinaryCheck)) {
-			out.write(outputBytes);
+		if (streamTypeWithBinaryCheck != null) {
+			// again, test using output text and assuming it was declared AUTO,
+			// using binary detection
+			b = new ByteArrayOutputStream();
+			try (OutputStream out = EolStreamTypeUtil.wrapOutputStream(b,
+					streamTypeWithBinaryCheck)) {
+				out.write(outputBytes);
+			}
+			// expect no conversion
+			assertArrayEquals(outputBytes, b.toByteArray());
 		}
-		// expect no conversion
-		assertArrayEquals(outputBytes, b.toByteArray());
 	}
 
 	@Test
diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/diff/DiffFormatterTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/diff/DiffFormatterTest.java
index 3d46a47..62824d3 100644
--- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/diff/DiffFormatterTest.java
+++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/diff/DiffFormatterTest.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2010, 2013 Google Inc. and others
+ * Copyright (C) 2010, 2020 Google Inc. and others
  *
  * This program and the accompanying materials are made available under the
  * terms of the Eclipse Distribution License v. 1.0 which is available at
@@ -11,12 +11,16 @@
 package org.eclipse.jgit.diff;
 
 import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertTrue;
 
 import java.io.BufferedOutputStream;
 import java.io.ByteArrayOutputStream;
 import java.io.File;
 
 import org.eclipse.jgit.api.Git;
+import org.eclipse.jgit.api.Status;
 import org.eclipse.jgit.diff.DiffEntry.ChangeType;
 import org.eclipse.jgit.dircache.DirCacheIterator;
 import org.eclipse.jgit.junit.RepositoryTestCase;
@@ -74,6 +78,17 @@
 	}
 
 	@Test
+	public void testDefaultRenameDetectorSettings() throws Exception {
+		RenameDetector rd = df.getRenameDetector();
+		assertNull(rd);
+		df.setDetectRenames(true);
+		rd = df.getRenameDetector();
+		assertNotNull(rd);
+		assertEquals(400, rd.getRenameLimit());
+		assertEquals(60, rd.getRenameScore());
+	}
+
+	@Test
 	public void testCreateFileHeader_Add() throws Exception {
 		ObjectId adId = blob("a\nd\n");
 		DiffEntry ent = DiffEntry.add("FOO", adId);
@@ -455,6 +470,58 @@
 	}
 
 	@Test
+	public void testTrackedFileInIgnoredFolderUnchanged()
+			throws Exception {
+		commitFile("empty/empty/foo", "", "master");
+		commitFile(".gitignore", "empty/*", "master");
+		try (Git git = new Git(db)) {
+			Status status = git.status().call();
+			assertTrue(status.isClean());
+		}
+		try (ByteArrayOutputStream os = new ByteArrayOutputStream();
+				DiffFormatter dfmt = new DiffFormatter(os)) {
+			dfmt.setRepository(db);
+			dfmt.format(new DirCacheIterator(db.readDirCache()),
+					new FileTreeIterator(db));
+			dfmt.flush();
+
+			String actual = os.toString("UTF-8");
+
+			assertEquals("", actual);
+		}
+	}
+
+	@Test
+	public void testTrackedFileInIgnoredFolderChanged()
+			throws Exception {
+		String expectedDiff = "diff --git a/empty/empty/foo b/empty/empty/foo\n"
+				+ "index e69de29..5ea2ed4 100644\n" //
+				+ "--- a/empty/empty/foo\n" //
+				+ "+++ b/empty/empty/foo\n" //
+				+ "@@ -0,0 +1 @@\n" //
+				+ "+changed\n";
+
+		commitFile("empty/empty/foo", "", "master");
+		commitFile(".gitignore", "empty/*", "master");
+		try (Git git = new Git(db)) {
+			Status status = git.status().call();
+			assertTrue(status.isClean());
+		}
+		try (ByteArrayOutputStream os = new ByteArrayOutputStream();
+				DiffFormatter dfmt = new DiffFormatter(os)) {
+			writeTrashFile("empty/empty/foo", "changed\n");
+			dfmt.setRepository(db);
+			dfmt.format(new DirCacheIterator(db.readDirCache()),
+					new FileTreeIterator(db));
+			dfmt.flush();
+
+			String actual = os.toString("UTF-8");
+
+			assertEquals(expectedDiff, actual);
+		}
+	}
+
+	@Test
 	public void testDiffAutoCrlfSmallFile() throws Exception {
 		String content = "01234\r\n01234\r\n01234\r\n";
 		String expectedDiff = "diff --git a/test.txt b/test.txt\n"
diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/dircache/DirCacheAfterCloneTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/dircache/DirCacheAfterCloneTest.java
new file mode 100644
index 0000000..f210760
--- /dev/null
+++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/dircache/DirCacheAfterCloneTest.java
@@ -0,0 +1,134 @@
+/*
+ * Copyright (C) 2020 Thomas Wolf <thomas.wolf@paranor.ch> and others.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Distribution License v. 1.0 which is available at
+ * https://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+package org.eclipse.jgit.dircache;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+
+import java.io.File;
+import java.util.EnumSet;
+import java.util.Set;
+
+import org.eclipse.jgit.api.CloneCommand;
+import org.eclipse.jgit.api.Git;
+import org.eclipse.jgit.api.ResetCommand.ResetType;
+import org.eclipse.jgit.dircache.DirCache.DirCacheVersion;
+import org.eclipse.jgit.junit.RepositoryTestCase;
+import org.eclipse.jgit.lib.StoredConfig;
+import org.eclipse.jgit.util.FileUtils;
+import org.eclipse.jgit.util.SystemReader;
+import org.junit.Test;
+
+/**
+ * Tests for initial DirCache version after a clone or after a mixed or hard
+ * reset.
+ */
+public class DirCacheAfterCloneTest extends RepositoryTestCase {
+
+	@Override
+	public void setUp() throws Exception {
+		super.setUp();
+		try (Git git = new Git(db)) {
+			writeTrashFile("Test.txt", "Hello world");
+			git.add().addFilepattern("Test.txt").call();
+			git.commit().setMessage("Initial commit").call();
+		}
+	}
+
+	private DirCacheVersion cloneAndCheck(Set<DirCacheVersion> expected)
+			throws Exception {
+		File directory = createTempDirectory("testCloneRepository");
+		CloneCommand command = Git.cloneRepository();
+		command.setDirectory(directory);
+		command.setURI("file://" + db.getWorkTree().getAbsolutePath());
+		Git git2 = command.call();
+		addRepoToClose(git2.getRepository());
+		assertNotNull(git2);
+		DirCache dc = DirCache.read(git2.getRepository());
+		DirCacheVersion version = dc.getVersion();
+		assertTrue(expected.contains(version));
+		return version;
+	}
+
+	@Test
+	public void testCloneV3OrV2() throws Exception {
+		cloneAndCheck(EnumSet.of(DirCacheVersion.DIRC_VERSION_MINIMUM,
+				DirCacheVersion.DIRC_VERSION_EXTENDED));
+	}
+
+	@Test
+	public void testCloneV4() throws Exception {
+		StoredConfig cfg = SystemReader.getInstance().getUserConfig();
+		cfg.load();
+		cfg.setInt("index", null, "version", 4);
+		cfg.save();
+		cloneAndCheck(EnumSet.of(DirCacheVersion.DIRC_VERSION_PATHCOMPRESS));
+	}
+
+	@Test
+	public void testCloneV4manyFiles() throws Exception {
+		StoredConfig cfg = SystemReader.getInstance().getUserConfig();
+		cfg.load();
+		cfg.setBoolean("feature", null, "manyFiles", true);
+		cfg.save();
+		cloneAndCheck(EnumSet.of(DirCacheVersion.DIRC_VERSION_PATHCOMPRESS));
+	}
+
+	@Test
+	public void testCloneV3CommitNoVersionChange() throws Exception {
+		DirCacheVersion initial = cloneAndCheck(
+				EnumSet.of(DirCacheVersion.DIRC_VERSION_MINIMUM,
+						DirCacheVersion.DIRC_VERSION_EXTENDED));
+		StoredConfig cfg = db.getConfig();
+		cfg.setInt("index", null, "version", 4);
+		cfg.save();
+		try (Git git = new Git(db)) {
+			writeTrashFile("Test.txt2", "Hello again");
+			git.add().addFilepattern("Test.txt2").call();
+			git.commit().setMessage("Second commit").call();
+		}
+		assertEquals("DirCache version should be unchanged", initial,
+				DirCache.read(db).getVersion());
+	}
+
+	@Test
+	public void testCloneV3ResetHardVersionChange() throws Exception {
+		cloneAndCheck(EnumSet.of(DirCacheVersion.DIRC_VERSION_MINIMUM,
+						DirCacheVersion.DIRC_VERSION_EXTENDED));
+		StoredConfig cfg = db.getConfig();
+		cfg.setInt("index", null, "version", 4);
+		cfg.save();
+		FileUtils.delete(new File(db.getDirectory(), "index"));
+		try (Git git = new Git(db)) {
+			git.reset().setMode(ResetType.HARD).call();
+		}
+		assertEquals("DirCache version should have changed",
+				DirCacheVersion.DIRC_VERSION_PATHCOMPRESS,
+				DirCache.read(db).getVersion());
+	}
+
+	@Test
+	public void testCloneV3ResetMixedVersionChange() throws Exception {
+		cloneAndCheck(EnumSet.of(DirCacheVersion.DIRC_VERSION_MINIMUM,
+				DirCacheVersion.DIRC_VERSION_EXTENDED));
+		StoredConfig cfg = db.getConfig();
+		cfg.setInt("index", null, "version", 4);
+		cfg.save();
+		FileUtils.delete(new File(db.getDirectory(), "index"));
+		try (Git git = new Git(db)) {
+			git.reset().setMode(ResetType.MIXED).call();
+		}
+		assertEquals("DirCache version should have changed",
+				DirCacheVersion.DIRC_VERSION_PATHCOMPRESS,
+				DirCache.read(db).getVersion());
+	}
+}
diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/dircache/DirCacheCGitCompatabilityTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/dircache/DirCacheCGitCompatabilityTest.java
index c57cb26..6d4d0b4 100644
--- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/dircache/DirCacheCGitCompatabilityTest.java
+++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/dircache/DirCacheCGitCompatabilityTest.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2008-2010, Google Inc. and others
+ * Copyright (C) 2008, 2020, Google Inc. and others
  *
  * This program and the accompanying materials are made available under the
  * terms of the Eclipse Distribution License v. 1.0 which is available at
@@ -28,6 +28,7 @@
 import java.util.LinkedHashMap;
 import java.util.Map;
 
+import org.eclipse.jgit.dircache.DirCache.DirCacheVersion;
 import org.eclipse.jgit.errors.CorruptObjectException;
 import org.eclipse.jgit.junit.JGitTestUtil;
 import org.eclipse.jgit.junit.LocalDiskRepositoryTestCase;
@@ -188,6 +189,28 @@
 		assertArrayEquals(expectedBytes, indexBytes);
 	}
 
+	@Test
+	public void testReadWriteV4() throws Exception {
+		final File file = pathOf("gitgit.index.v4");
+		final DirCache dc = new DirCache(file, FS.DETECTED);
+		dc.read();
+		assertEquals(DirCacheVersion.DIRC_VERSION_PATHCOMPRESS,
+				dc.getVersion());
+		assertEquals(5, dc.getEntryCount());
+		assertV4TreeEntry(0, "src/org/eclipse/jgit/atest/foo.txt", false, dc);
+		assertV4TreeEntry(1, "src/org/eclipse/jgit/atest/foobar.txt", false,
+				dc);
+		assertV4TreeEntry(2, "src/org/eclipse/jgit/other/bar.txt", true, dc);
+		assertV4TreeEntry(3, "test.txt", false, dc);
+		assertV4TreeEntry(4, "test.txt2", false, dc);
+
+		final ByteArrayOutputStream bos = new ByteArrayOutputStream();
+		dc.writeTo(null, bos);
+		final byte[] indexBytes = bos.toByteArray();
+		final byte[] expectedBytes = IO.readFully(file);
+		assertArrayEquals(expectedBytes, indexBytes);
+	}
+
 	private static void assertV3TreeEntry(int indexPosition, String path,
 			boolean skipWorkTree, boolean intentToAdd, DirCache dc) {
 		final DirCacheEntry entry = dc.getEntry(indexPosition);
@@ -196,6 +219,13 @@
 		assertEquals(intentToAdd, entry.isIntentToAdd());
 	}
 
+	private static void assertV4TreeEntry(int indexPosition, String path,
+			boolean skipWorkTree, DirCache dc) {
+		final DirCacheEntry entry = dc.getEntry(indexPosition);
+		assertEquals(path, entry.getPathString());
+		assertEquals(skipWorkTree, entry.isSkipWorkTree());
+	}
+
 	private static File pathOf(String name) {
 		return JGitTestUtil.getTestResourceFile(name);
 	}
diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/dircache/DirCacheEntryTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/dircache/DirCacheEntryTest.java
index f21c7f8..5477f56 100644
--- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/dircache/DirCacheEntryTest.java
+++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/dircache/DirCacheEntryTest.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2009, Google Inc. and others
+ * Copyright (C) 2009, 2020 Google Inc. and others
  *
  * This program and the accompanying materials are made available under the
  * terms of the Eclipse Distribution License v. 1.0 which is available at
@@ -11,14 +11,25 @@
 package org.eclipse.jgit.dircache;
 
 import static java.time.Instant.EPOCH;
+import static org.junit.Assert.assertArrayEquals;
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertFalse;
 import static org.junit.Assert.assertSame;
 import static org.junit.Assert.assertTrue;
 import static org.junit.Assert.fail;
 
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.security.MessageDigest;
+import java.time.Instant;
+import java.util.concurrent.TimeUnit;
+
+import org.eclipse.jgit.dircache.DirCache.DirCacheVersion;
+import org.eclipse.jgit.lib.Constants;
 import org.eclipse.jgit.lib.FileMode;
 import org.eclipse.jgit.lib.ObjectId;
+import org.eclipse.jgit.util.MutableInteger;
 import org.junit.Test;
 
 public class DirCacheEntryTest {
@@ -47,6 +58,95 @@
 		}
 	}
 
+	private static void checkPath(DirCacheVersion indexVersion,
+			DirCacheEntry previous, String name) throws IOException {
+		DirCacheEntry dce = new DirCacheEntry(name);
+		long now = System.currentTimeMillis();
+		long anHourAgo = now - TimeUnit.HOURS.toMillis(1);
+		dce.setLastModified(Instant.ofEpochMilli(anHourAgo));
+		ByteArrayOutputStream out = new ByteArrayOutputStream();
+		dce.write(out, indexVersion, previous);
+		byte[] raw = out.toByteArray();
+		MessageDigest md0 = Constants.newMessageDigest();
+		md0.update(raw);
+		ByteArrayInputStream in = new ByteArrayInputStream(raw);
+		MutableInteger infoAt = new MutableInteger();
+		byte[] sharedInfo = new byte[raw.length];
+		MessageDigest md = Constants.newMessageDigest();
+		DirCacheEntry read = new DirCacheEntry(sharedInfo, infoAt, in, md,
+				Instant.ofEpochMilli(now), indexVersion, previous);
+		assertEquals("Paths of length " + name.length() + " should match", name,
+				read.getPathString());
+		assertEquals("Should have been fully read", -1, in.read());
+		assertArrayEquals("Digests should match", md0.digest(),
+				md.digest());
+	}
+
+	@Test
+	public void testLongPath() throws Exception {
+		StringBuilder name = new StringBuilder(4094 + 16);
+		for (int i = 0; i < 4094; i++) {
+			name.append('a');
+		}
+		for (int j = 0; j < 16; j++) {
+			checkPath(DirCacheVersion.DIRC_VERSION_EXTENDED, null,
+					name.toString());
+			name.append('b');
+		}
+	}
+
+	@Test
+	public void testLongPathV4() throws Exception {
+		StringBuilder name = new StringBuilder(4094 + 16);
+		for (int i = 0; i < 4094; i++) {
+			name.append('a');
+		}
+		DirCacheEntry previous = new DirCacheEntry(name.toString());
+		for (int j = 0; j < 16; j++) {
+			checkPath(DirCacheVersion.DIRC_VERSION_PATHCOMPRESS, previous,
+					name.toString());
+			name.append('b');
+		}
+	}
+
+	@Test
+	public void testShortPath() throws Exception {
+		StringBuilder name = new StringBuilder(1 + 16);
+		name.append('a');
+		for (int j = 0; j < 16; j++) {
+			checkPath(DirCacheVersion.DIRC_VERSION_EXTENDED, null,
+					name.toString());
+			name.append('b');
+		}
+	}
+
+	@Test
+	public void testShortPathV4() throws Exception {
+		StringBuilder name = new StringBuilder(1 + 16);
+		name.append('a');
+		DirCacheEntry previous = new DirCacheEntry(name.toString());
+		for (int j = 0; j < 16; j++) {
+			checkPath(DirCacheVersion.DIRC_VERSION_PATHCOMPRESS, previous,
+					name.toString());
+			name.append('b');
+		}
+	}
+
+	@Test
+	public void testPathV4() throws Exception {
+		StringBuilder name = new StringBuilder();
+		for (int i = 0; i < 20; i++) {
+			name.append('a');
+		}
+		DirCacheEntry previous = new DirCacheEntry(name.toString());
+		for (int j = 0; j < 20; j++) {
+			name.setLength(name.length() - 1);
+			String newName = name.toString() + "bbb";
+			checkPath(DirCacheVersion.DIRC_VERSION_PATHCOMPRESS, previous,
+					newName);
+		}
+	}
+
 	@SuppressWarnings("unused")
 	@Test
 	public void testCreate_ByStringPath() {
diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/dfs/DfsBundleWriterTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/dfs/DfsBundleWriterTest.java
new file mode 100644
index 0000000..4238ee6
--- /dev/null
+++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/dfs/DfsBundleWriterTest.java
@@ -0,0 +1,85 @@
+/*
+ * Copyright (c) 2020, Google LLC  and others
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+package org.eclipse.jgit.internal.storage.dfs;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.util.Collections;
+import java.util.Set;
+
+import org.eclipse.jgit.junit.TestRepository;
+import org.eclipse.jgit.lib.NullProgressMonitor;
+import org.eclipse.jgit.lib.Ref;
+import org.eclipse.jgit.lib.Repository;
+import org.eclipse.jgit.revwalk.RevCommit;
+import org.eclipse.jgit.transport.FetchResult;
+import org.eclipse.jgit.transport.RefSpec;
+import org.eclipse.jgit.transport.TransportBundleStream;
+import org.eclipse.jgit.transport.URIish;
+import org.junit.Before;
+import org.junit.Test;
+
+public class DfsBundleWriterTest {
+	private TestRepository<InMemoryRepository> git;
+
+	private InMemoryRepository repo;
+
+	@Before
+	public void setUp() throws IOException {
+		DfsRepositoryDescription desc = new DfsRepositoryDescription("test");
+		git = new TestRepository<>(new InMemoryRepository(desc));
+		repo = git.getRepository();
+	}
+
+	@Test
+	public void testRepo() throws Exception {
+		RevCommit commit0 = git.commit().message("0").create();
+		RevCommit commit1 = git.commit().message("1").parent(commit0).create();
+		git.update("master", commit1);
+
+		RevCommit commit2 = git.commit().message("0").create();
+
+		byte[] bundle = makeBundle();
+		try (Repository newRepo = new InMemoryRepository(
+				new DfsRepositoryDescription("copy"))) {
+			fetchFromBundle(newRepo, bundle);
+			Ref ref = newRepo.exactRef("refs/heads/master");
+			assertNotNull(ref);
+			assertEquals(commit1.toObjectId(), ref.getObjectId());
+
+			// Unreferenced objects are included as well.
+			assertTrue(newRepo.getObjectDatabase().has(commit2));
+		}
+	}
+
+	private byte[] makeBundle() throws IOException {
+		ByteArrayOutputStream out = new ByteArrayOutputStream();
+		DfsBundleWriter.writeEntireRepositoryAsBundle(
+				NullProgressMonitor.INSTANCE, out, repo);
+		return out.toByteArray();
+	}
+
+	private static FetchResult fetchFromBundle(Repository newRepo,
+			byte[] bundle) throws Exception {
+		URIish uri = new URIish("in-memory://");
+		ByteArrayInputStream in = new ByteArrayInputStream(bundle);
+		RefSpec rs = new RefSpec("refs/heads/*:refs/heads/*");
+		Set<RefSpec> refs = Collections.singleton(rs);
+		try (TransportBundleStream transport = new TransportBundleStream(
+				newRepo, uri, in)) {
+			return transport.fetch(NullProgressMonitor.INSTANCE, refs);
+		}
+	}
+}
diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/file/ObjectDirectoryTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/file/ObjectDirectoryTest.java
index d269457..a0bc63a 100644
--- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/file/ObjectDirectoryTest.java
+++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/file/ObjectDirectoryTest.java
@@ -44,8 +44,12 @@
 
 import static java.nio.charset.StandardCharsets.UTF_8;
 import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNull;
 import static org.junit.Assert.assertThrows;
 import static org.junit.Assert.assertTrue;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.verify;
 
 import java.io.File;
 import java.io.IOException;
@@ -69,6 +73,7 @@
 import org.eclipse.jgit.util.FS;
 import org.junit.Assume;
 import org.junit.Test;
+import org.mockito.Mockito;
 
 public class ObjectDirectoryTest extends RepositoryTestCase {
 
@@ -195,6 +200,42 @@
 	}
 
 	@Test
+	public void testOpenLooseObjectSuppressStaleFileHandleException()
+			throws Exception {
+		ObjectId id = ObjectId
+				.fromString("873fb8d667d05436d728c52b1d7a09528e6eb59b");
+		WindowCursor curs = new WindowCursor(db.getObjectDatabase());
+
+		ObjectDirectory mock = mock(ObjectDirectory.class);
+		UnpackedObjectCache unpackedObjectCacheMock = mock(
+				UnpackedObjectCache.class);
+
+		Mockito.when(mock.getObjectLoader(any(), any(), any()))
+				.thenThrow(new IOException("Stale File Handle"));
+		Mockito.when(mock.openLooseObject(curs, id)).thenCallRealMethod();
+		Mockito.when(mock.unpackedObjectCache())
+				.thenReturn(unpackedObjectCacheMock);
+
+		assertNull(mock.openLooseObject(curs, id));
+		verify(unpackedObjectCacheMock).remove(id);
+	}
+
+	@Test
+	public void testOpenLooseObjectPropagatesIOExceptions() throws Exception {
+		ObjectId id = ObjectId
+				.fromString("873fb8d667d05436d728c52b1d7a09528e6eb59b");
+		WindowCursor curs = new WindowCursor(db.getObjectDatabase());
+
+		ObjectDirectory mock = mock(ObjectDirectory.class);
+
+		Mockito.when(mock.getObjectLoader(any(), any(), any()))
+				.thenThrow(new IOException("some IO failure"));
+		Mockito.when(mock.openLooseObject(curs, id)).thenCallRealMethod();
+
+		assertThrows(IOException.class, () -> mock.openLooseObject(curs, id));
+	}
+
+	@Test
 	public void testShallowFileCorrupt() throws Exception {
 		FileRepository repository = createBareRepository();
 		ObjectDirectory dir = repository.getObjectDatabase();
diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/file/PackIndexTestCase.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/file/PackIndexTestCase.java
index fe05fba..910b928 100644
--- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/file/PackIndexTestCase.java
+++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/file/PackIndexTestCase.java
@@ -12,13 +12,17 @@
 
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertThrows;
 import static org.junit.Assert.fail;
 
 import java.io.File;
+import java.io.FileInputStream;
+import java.io.IOException;
 import java.util.Iterator;
 import java.util.NoSuchElementException;
 
 import org.eclipse.jgit.errors.MissingObjectException;
+import org.eclipse.jgit.internal.JGitText;
 import org.eclipse.jgit.internal.storage.file.PackIndex.MutableEntry;
 import org.eclipse.jgit.junit.RepositoryTestCase;
 import org.junit.Test;
@@ -51,6 +55,13 @@
 	public abstract File getFileForPackdf2982f28();
 
 	/**
+	 * Return file with appropriate index version for bad fanout table test.
+	 *
+	 * @return file with index
+	 */
+	public abstract File getFileForBadFanoutTable();
+
+	/**
 	 * Verify CRC32 support.
 	 *
 	 * @throws MissingObjectException
@@ -158,4 +169,15 @@
 				.name());
 	}
 
+	@Test
+	public void testBadFanoutTable() {
+		IOException ex = assertThrows(IOException.class, () -> {
+			try (FileInputStream fis = new FileInputStream(
+					getFileForBadFanoutTable())) {
+				PackIndex.read(fis);
+			}
+		});
+		assertEquals(JGitText.get().indexFileIsTooLargeForJgit,
+				ex.getMessage());
+	}
 }
diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/file/PackIndexV1Test.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/file/PackIndexV1Test.java
index e41ded7..c4f6372 100644
--- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/file/PackIndexV1Test.java
+++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/file/PackIndexV1Test.java
@@ -35,6 +35,11 @@
                     "pack-df2982f284bbabb6bdb59ee3fcc6eb0983e20371.idx");
 	}
 
+	@Override
+	public File getFileForBadFanoutTable() {
+		return JGitTestUtil.getTestResourceFile("pack-bad-fanout-table.idx");
+	}
+
 	/**
 	 * Verify CRC32 - V1 should not index anything.
 	 *
diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/file/PackIndexV2Test.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/file/PackIndexV2Test.java
index c1da547..1d179ab 100644
--- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/file/PackIndexV2Test.java
+++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/file/PackIndexV2Test.java
@@ -35,6 +35,11 @@
 				"pack-df2982f284bbabb6bdb59ee3fcc6eb0983e20371.idxV2");
 	}
 
+	@Override
+	public File getFileForBadFanoutTable() {
+		return JGitTestUtil.getTestResourceFile("pack-bad-fanout-table.idxV2");
+	}
+
 	/**
 	 * Verify CRC32 indexing.
 	 *
diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/reftable/MergedReftableTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/reftable/MergedReftableTest.java
index a246ac9..0a03fc3 100644
--- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/reftable/MergedReftableTest.java
+++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/reftable/MergedReftableTest.java
@@ -329,22 +329,22 @@
 	public void overlappedUpdateIndices() throws IOException {
 		ByteArrayOutputStream buf = new ByteArrayOutputStream();
 		ReftableWriter writer = new ReftableWriter(buf)
-				.setMinUpdateIndex(1)
-				.setMaxUpdateIndex(3)
-				.begin();
-		writer.writeRef(ref("refs/heads/a", 1), 1);
-		writer.writeRef(ref("refs/heads/b", 2), 3);
-		writer.finish();
-		byte[] base = buf.toByteArray();
-
-		buf = new ByteArrayOutputStream();
-		writer = new ReftableWriter(buf)
 				.setMinUpdateIndex(2)
 				.setMaxUpdateIndex(4)
 				.begin();
 		writer.writeRef(ref("refs/heads/a", 10), 2);
 		writer.writeRef(ref("refs/heads/b", 20), 4);
 		writer.finish();
+		byte[] base = buf.toByteArray();
+
+		buf = new ByteArrayOutputStream();
+		writer = new ReftableWriter(buf)
+				.setMinUpdateIndex(1)
+				.setMaxUpdateIndex(3)
+				.begin();
+		writer.writeRef(ref("refs/heads/a", 1), 1);
+		writer.writeRef(ref("refs/heads/b", 2), 3);
+		writer.finish();
 		byte[] delta = buf.toByteArray();
 
 		MergedReftable mr = merge(base, delta);
@@ -368,22 +368,22 @@
 	public void enclosedUpdateIndices() throws IOException {
 		ByteArrayOutputStream buf = new ByteArrayOutputStream();
 		ReftableWriter writer = new ReftableWriter(buf)
-				.setMinUpdateIndex(1)
-				.setMaxUpdateIndex(4)
-				.begin();
-		writer.writeRef(ref("refs/heads/a", 1), 1);
-		writer.writeRef(ref("refs/heads/b", 20), 4);
-		writer.finish();
-		byte[] base = buf.toByteArray();
-
-		buf = new ByteArrayOutputStream();
-		writer = new ReftableWriter(buf)
 				.setMinUpdateIndex(2)
 				.setMaxUpdateIndex(3)
 				.begin();
 		writer.writeRef(ref("refs/heads/a", 10), 2);
 		writer.writeRef(ref("refs/heads/b", 2), 3);
 		writer.finish();
+		byte[] base = buf.toByteArray();
+
+		buf = new ByteArrayOutputStream();
+		writer = new ReftableWriter(buf)
+				.setMinUpdateIndex(1)
+				.setMaxUpdateIndex(4)
+				.begin();
+		writer.writeRef(ref("refs/heads/a", 1), 1);
+		writer.writeRef(ref("refs/heads/b", 20), 4);
+		writer.finish();
 		byte[] delta = buf.toByteArray();
 
 		MergedReftable mr = merge(base, delta);
diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/lib/CommitBuilderTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/lib/CommitBuilderTest.java
index 26294c7..dee58f9 100644
--- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/lib/CommitBuilderTest.java
+++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/lib/CommitBuilderTest.java
@@ -13,7 +13,7 @@
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertNull;
 import static org.junit.Assert.assertSame;
-import static org.junit.Assert.fail;
+import static org.junit.Assert.assertThrows;
 
 import java.io.ByteArrayOutputStream;
 import java.io.IOException;
@@ -24,6 +24,32 @@
 
 public class CommitBuilderTest {
 
+	// @formatter:off
+	private static final String SIGNATURE = "-----BEGIN PGP SIGNATURE-----\n" +
+			"Version: BCPG v1.60\n" +
+			"\n" +
+			"iQEcBAABCAAGBQJb9cVhAAoJEKX+6Axg/6TZeFsH/0CY0WX/z7U8+7S5giFX4wH4\n" +
+			"opvBwqyt6OX8lgNwTwBGHFNt8LdmDCCmKoq/XwkNi3ARVjLhe3gBcKXNoavvPk2Z\n" +
+			"gIg5ChevGkU4afWCOMLVEYnkCBGw2+86XhrK1P7gTHEk1Rd+Yv1ZRDJBY+fFO7yz\n" +
+			"uSBuF5RpEY2sJiIvp27Gub/rY3B5NTR/feO/z+b9oiP/fMUhpRwG5KuWUsn9NPjw\n" +
+			"3tvbgawYpU/2UnS+xnavMY4t2fjRYjsoxndPLb2MUX8X7vC7FgWLBlmI/rquLZVM\n" +
+			"IQEKkjnA+lhejjK1rv+ulq4kGZJFKGYWYYhRDwFg5PTkzhudhN2SGUq5Wxq1Eg4=\n" +
+			"=b9OI\n" +
+			"-----END PGP SIGNATURE-----";
+
+	private static final String EXPECTED = "-----BEGIN PGP SIGNATURE-----\n" +
+			" Version: BCPG v1.60\n" +
+			" \n" +
+			" iQEcBAABCAAGBQJb9cVhAAoJEKX+6Axg/6TZeFsH/0CY0WX/z7U8+7S5giFX4wH4\n" +
+			" opvBwqyt6OX8lgNwTwBGHFNt8LdmDCCmKoq/XwkNi3ARVjLhe3gBcKXNoavvPk2Z\n" +
+			" gIg5ChevGkU4afWCOMLVEYnkCBGw2+86XhrK1P7gTHEk1Rd+Yv1ZRDJBY+fFO7yz\n" +
+			" uSBuF5RpEY2sJiIvp27Gub/rY3B5NTR/feO/z+b9oiP/fMUhpRwG5KuWUsn9NPjw\n" +
+			" 3tvbgawYpU/2UnS+xnavMY4t2fjRYjsoxndPLb2MUX8X7vC7FgWLBlmI/rquLZVM\n" +
+			" IQEKkjnA+lhejjK1rv+ulq4kGZJFKGYWYYhRDwFg5PTkzhudhN2SGUq5Wxq1Eg4=\n" +
+			" =b9OI\n" +
+			" -----END PGP SIGNATURE-----";
+	// @formatter:on
+
 	private void assertGpgSignatureStringOutcome(String signature,
 			String expectedOutcome) throws IOException {
 		ByteArrayOutputStream out = new ByteArrayOutputStream();
@@ -33,47 +59,37 @@
 	}
 
 	@Test
-	public void writeGpgSignatureString_1() throws Exception {
-		// @formatter:off
-		String signature = "-----BEGIN PGP SIGNATURE-----\n" +
-				"Version: BCPG v1.60\n" +
-				"\n" +
-				"iQEcBAABCAAGBQJb9cVhAAoJEKX+6Axg/6TZeFsH/0CY0WX/z7U8+7S5giFX4wH4\n" +
-				"opvBwqyt6OX8lgNwTwBGHFNt8LdmDCCmKoq/XwkNi3ARVjLhe3gBcKXNoavvPk2Z\n" +
-				"gIg5ChevGkU4afWCOMLVEYnkCBGw2+86XhrK1P7gTHEk1Rd+Yv1ZRDJBY+fFO7yz\n" +
-				"uSBuF5RpEY2sJiIvp27Gub/rY3B5NTR/feO/z+b9oiP/fMUhpRwG5KuWUsn9NPjw\n" +
-				"3tvbgawYpU/2UnS+xnavMY4t2fjRYjsoxndPLb2MUX8X7vC7FgWLBlmI/rquLZVM\n" +
-				"IQEKkjnA+lhejjK1rv+ulq4kGZJFKGYWYYhRDwFg5PTkzhudhN2SGUq5Wxq1Eg4=\n" +
-				"=b9OI\n" +
-				"-----END PGP SIGNATURE-----";
-		String expectedOutcome = "-----BEGIN PGP SIGNATURE-----\n" +
-				" Version: BCPG v1.60\n" +
-				" \n" +
-				" iQEcBAABCAAGBQJb9cVhAAoJEKX+6Axg/6TZeFsH/0CY0WX/z7U8+7S5giFX4wH4\n" +
-				" opvBwqyt6OX8lgNwTwBGHFNt8LdmDCCmKoq/XwkNi3ARVjLhe3gBcKXNoavvPk2Z\n" +
-				" gIg5ChevGkU4afWCOMLVEYnkCBGw2+86XhrK1P7gTHEk1Rd+Yv1ZRDJBY+fFO7yz\n" +
-				" uSBuF5RpEY2sJiIvp27Gub/rY3B5NTR/feO/z+b9oiP/fMUhpRwG5KuWUsn9NPjw\n" +
-				" 3tvbgawYpU/2UnS+xnavMY4t2fjRYjsoxndPLb2MUX8X7vC7FgWLBlmI/rquLZVM\n" +
-				" IQEKkjnA+lhejjK1rv+ulq4kGZJFKGYWYYhRDwFg5PTkzhudhN2SGUq5Wxq1Eg4=\n" +
-				" =b9OI\n" +
-				" -----END PGP SIGNATURE-----";
-		// @formatter:on
-		assertGpgSignatureStringOutcome(signature, expectedOutcome);
+	public void writeGpgSignatureString() throws Exception {
+		assertGpgSignatureStringOutcome(SIGNATURE, EXPECTED);
+	}
+
+	@Test
+	public void writeGpgSignatureStringTrailingLF() throws Exception {
+		assertGpgSignatureStringOutcome(SIGNATURE + '\n', EXPECTED);
+	}
+
+	@Test
+	public void writeGpgSignatureStringCRLF() throws Exception {
+		assertGpgSignatureStringOutcome(SIGNATURE.replaceAll("\n", "\r\n"),
+				EXPECTED);
+	}
+
+	@Test
+	public void writeGpgSignatureStringTrailingCRLF() throws Exception {
+		assertGpgSignatureStringOutcome(
+				SIGNATURE.replaceAll("\n", "\r\n") + "\r\n", EXPECTED);
 	}
 
 	@Test
 	public void writeGpgSignatureString_failsForNonAscii() throws Exception {
 		String signature = "Ü Ä";
-		try {
-			CommitBuilder.writeGpgSignatureString(signature,
-					new ByteArrayOutputStream());
-			fail("Exception expected");
-		} catch (IllegalArgumentException e) {
-			// good
-			String message = MessageFormat.format(JGitText.get().notASCIIString,
-					signature);
-			assertEquals(message, e.getMessage());
-		}
+		IllegalArgumentException e = assertThrows(
+				IllegalArgumentException.class,
+				() -> CommitBuilder.writeGpgSignatureString(signature,
+						new ByteArrayOutputStream()));
+		String message = MessageFormat.format(JGitText.get().notASCIIString,
+				signature);
+		assertEquals(message, e.getMessage());
 	}
 
 	@Test
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 a272c8f..b943486 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
@@ -2,41 +2,13 @@
  * Copyright (C) 2007, Dave Watson <dwatson@mimvista.com>
  * Copyright (C) 2008-2011, Shawn O. Pearce <spearce@spearce.org>
  * Copyright (C) 2008-2011, Robin Rosenberg <robin.rosenberg@dewire.com>
- * Copyright (C) 2010-2011, Christian Halstrick <christian.halstrick@sap.com>
- * and other copyright owners as documented in the project's IP log.
+ * Copyright (C) 2010, 2020 Christian Halstrick <christian.halstrick@sap.com> and others
  *
  * 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
+ * terms of the Eclipse Distribution License v. 1.0 which is available at
+ * https://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.
+ * SPDX-License-Identifier: BSD-3-Clause
  */
 package org.eclipse.jgit.lib;
 
@@ -85,6 +57,7 @@
 import org.eclipse.jgit.treewalk.WorkingTreeIterator;
 import org.eclipse.jgit.util.FS;
 import org.eclipse.jgit.util.FileUtils;
+import org.eclipse.jgit.util.StringUtils;
 import org.junit.Assume;
 import org.junit.Test;
 
@@ -284,6 +257,86 @@
 		}
 	}
 
+	private void checkoutLineEndings(String inIndex, String expected,
+			String attributes) throws Exception {
+		try (Git git = new Git(db);
+				TestRepository<Repository> db_t = new TestRepository<>(db)) {
+			BranchBuilder master = db_t.branch("master");
+			master.commit().add("f", inIndex).message("m0").create();
+			if (!StringUtils.isEmptyOrNull(attributes)) {
+				master.commit().add(".gitattributes", attributes)
+						.message("attributes").create();
+			}
+			File f = new File(db.getWorkTree(), "f");
+			assertFalse(f.exists());
+			git.checkout().setName("master").call();
+			assertTrue(f.exists());
+			checkFile(f, expected);
+		}
+	}
+
+	@Test
+	public void testCheckoutWithCRLF() throws Exception {
+		checkoutLineEndings("first line\r\nsecond line\r\n",
+				"first line\r\nsecond line\r\n", null);
+	}
+
+	@Test
+	public void testCheckoutWithCRLFAuto() throws Exception {
+		checkoutLineEndings("first line\r\nsecond line\r\n",
+				"first line\r\nsecond line\r\n", "f text=auto");
+	}
+
+	@Test
+	public void testCheckoutWithCRLFAutoEolLf() throws Exception {
+		checkoutLineEndings("first line\r\nsecond line\r\n",
+				"first line\r\nsecond line\r\n", "f text=auto eol=lf");
+	}
+
+	@Test
+	public void testCheckoutWithCRLFAutoEolNative() throws Exception {
+		checkoutLineEndings("first line\r\nsecond line\r\n",
+				"first line\r\nsecond line\r\n", "f text=auto eol=native");
+	}
+
+	@Test
+	public void testCheckoutWithCRLFAutoEolCrLf() throws Exception {
+		checkoutLineEndings("first line\r\nsecond line\r\n",
+				"first line\r\nsecond line\r\n", "f text=auto eol=crlf");
+	}
+
+	@Test
+	public void testCheckoutWithLF() throws Exception {
+		checkoutLineEndings("first line\nsecond line\n",
+				"first line\nsecond line\n", null);
+	}
+
+	@Test
+	public void testCheckoutWithLFAuto() throws Exception {
+		checkoutLineEndings("first line\nsecond line\n",
+				"first line\nsecond line\n", "f text=auto");
+	}
+
+	@Test
+	public void testCheckoutWithLFAutoEolLf() throws Exception {
+		checkoutLineEndings("first line\nsecond line\n",
+				"first line\nsecond line\n", "f text=auto eol=lf");
+	}
+
+	@Test
+	public void testCheckoutWithLFAutoEolNative() throws Exception {
+		checkoutLineEndings(
+				"first line\nsecond line\n", "first line\nsecond line\n"
+						.replaceAll("\n", System.lineSeparator()),
+				"f text=auto eol=native");
+	}
+
+	@Test
+	public void testCheckoutWithLFAutoEolCrLf() throws Exception {
+		checkoutLineEndings("first line\nsecond line\n",
+				"first line\r\nsecond line\r\n", "f text=auto eol=crlf");
+	}
+
 	private DirCacheCheckout resetHard(RevCommit commit)
 			throws NoWorkTreeException,
 			CorruptObjectException, IOException {
diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/merge/GitlinkMergeTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/merge/GitlinkMergeTest.java
new file mode 100644
index 0000000..f410960
--- /dev/null
+++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/merge/GitlinkMergeTest.java
@@ -0,0 +1,368 @@
+/*
+ * Copyright (c) 2020, Google LLC  and others
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+package org.eclipse.jgit.merge;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+
+import java.io.IOException;
+
+import org.eclipse.jgit.annotations.Nullable;
+import org.eclipse.jgit.dircache.DirCache;
+import org.eclipse.jgit.dircache.DirCacheBuilder;
+import org.eclipse.jgit.dircache.DirCacheEntry;
+import org.eclipse.jgit.lib.CommitBuilder;
+import org.eclipse.jgit.lib.FileMode;
+import org.eclipse.jgit.lib.ObjectId;
+import org.eclipse.jgit.lib.ObjectInserter;
+import org.eclipse.jgit.lib.PersonIdent;
+import org.eclipse.jgit.test.resources.SampleDataRepositoryTestCase;
+import org.eclipse.jgit.treewalk.TreeWalk;
+import org.junit.Test;
+
+public class GitlinkMergeTest extends SampleDataRepositoryTestCase {
+	private static final String LINK_ID1 = "DEADBEEFDEADBEEFBABEDEADBEEFDEADBEEFBABE";
+	private static final String LINK_ID2 = "DEADDEADDEADDEADDEADDEADDEADDEADDEADDEAD";
+	private static final String LINK_ID3 = "BEEFBEEFBEEFBEEFBEEFBEEFBEEFBEEFBEEFBEEF";
+
+	private static final String SUBMODULE_PATH = "submodule.link";
+
+	@Test
+	public void testGitLinkMerging_AddNew() throws Exception {
+		assertGitLinkValue(
+				testGitLink(null, null, LINK_ID3, newResolveMerger(), true),
+				LINK_ID3);
+	}
+
+	@Test
+	public void testGitLinkMerging_Delete() throws Exception {
+		assertGitLinkDoesntExist(testGitLink(LINK_ID1, LINK_ID1, null,
+				newResolveMerger(), true));
+	}
+
+	@Test
+	public void testGitLinkMerging_UpdateDelete() throws Exception {
+		testGitLink(LINK_ID1, LINK_ID2, null, newResolveMerger(), false);
+	}
+
+	@Test
+	public void testGitLinkMerging_DeleteUpdate() throws Exception {
+		testGitLink(LINK_ID1, null, LINK_ID3, newResolveMerger(), false);
+	}
+
+	@Test
+	public void testGitLinkMerging_UpdateUpdate() throws Exception {
+		testGitLink(LINK_ID1, LINK_ID2, LINK_ID3, newResolveMerger(), false);
+	}
+
+	@Test
+	public void testGitLinkMerging_bothAddedSameLink() throws Exception {
+		assertGitLinkValue(
+				testGitLink(null, LINK_ID2, LINK_ID2, newResolveMerger(), true),
+				LINK_ID2);
+	}
+
+	@Test
+	public void testGitLinkMerging_bothAddedDifferentLink() throws Exception {
+		testGitLink(null, LINK_ID2, LINK_ID3, newResolveMerger(), false);
+	}
+
+	@Test
+	public void testGitLinkMerging_AddNew_ignoreConflicts() throws Exception {
+		assertGitLinkValue(
+				testGitLink(null, null, LINK_ID3, newIgnoreConflictMerger(),
+						true),
+				LINK_ID3);
+	}
+
+	@Test
+	public void testGitLinkMerging_Delete_ignoreConflicts() throws Exception {
+		assertGitLinkDoesntExist(testGitLink(LINK_ID1, LINK_ID1, null,
+				newIgnoreConflictMerger(), true));
+	}
+
+	@Test
+	public void testGitLinkMerging_UpdateDelete_ignoreConflicts()
+			throws Exception {
+		assertGitLinkValue(testGitLink(LINK_ID1, LINK_ID2, null,
+				newIgnoreConflictMerger(), true), LINK_ID2);
+	}
+
+	@Test
+	public void testGitLinkMerging_DeleteUpdate_ignoreConflicts()
+			throws Exception {
+		assertGitLinkDoesntExist(testGitLink(LINK_ID1, null, LINK_ID3,
+				newIgnoreConflictMerger(), true));
+	}
+
+	@Test
+	public void testGitLinkMerging_UpdateUpdate_ignoreConflicts()
+			throws Exception {
+		assertGitLinkValue(testGitLink(LINK_ID1, LINK_ID2, LINK_ID3,
+				newIgnoreConflictMerger(), true), LINK_ID2);
+	}
+
+	@Test
+	public void testGitLinkMerging_bothAddedSameLink_ignoreConflicts()
+			throws Exception {
+		assertGitLinkValue(testGitLink(null, LINK_ID2, LINK_ID2,
+				newIgnoreConflictMerger(), true), LINK_ID2);
+	}
+
+	@Test
+	public void testGitLinkMerging_bothAddedDifferentLink_ignoreConflicts()
+			throws Exception {
+		assertGitLinkValue(testGitLink(null, LINK_ID2, LINK_ID3,
+				newIgnoreConflictMerger(), true), LINK_ID2);
+	}
+
+	protected Merger testGitLink(@Nullable String baseLink,
+			@Nullable String oursLink, @Nullable String theirsLink,
+			Merger merger, boolean shouldMerge)
+			throws Exception {
+		DirCache treeB = db.readDirCache();
+		DirCache treeO = db.readDirCache();
+		DirCache treeT = db.readDirCache();
+
+		DirCacheBuilder bTreeBuilder = treeB.builder();
+		DirCacheBuilder oTreeBuilder = treeO.builder();
+		DirCacheBuilder tTreeBuilder = treeT.builder();
+
+		maybeAddLink(bTreeBuilder, baseLink);
+		maybeAddLink(oTreeBuilder, oursLink);
+		maybeAddLink(tTreeBuilder, theirsLink);
+
+		bTreeBuilder.finish();
+		oTreeBuilder.finish();
+		tTreeBuilder.finish();
+
+		ObjectInserter ow = db.newObjectInserter();
+		ObjectId b = commit(ow, treeB, new ObjectId[] {});
+		ObjectId o = commit(ow, treeO, new ObjectId[] { b });
+		ObjectId t = commit(ow, treeT, new ObjectId[] { b });
+
+		boolean merge = merger.merge(new ObjectId[] { o, t });
+		assertEquals(Boolean.valueOf(shouldMerge), Boolean.valueOf(merge));
+
+		return merger;
+	}
+
+	private Merger newResolveMerger() {
+		return MergeStrategy.RESOLVE.newMerger(db, true);
+	}
+
+	private Merger newIgnoreConflictMerger() {
+		return new ResolveMerger(db, true) {
+			@Override
+			protected boolean mergeImpl() throws IOException {
+				// emulate call with ignore conflicts.
+				return mergeTrees(mergeBase(), sourceTrees[0], sourceTrees[1],
+						true);
+			}
+		};
+	}
+
+	@Test
+	public void testGitLinkMerging_blobWithLink() throws Exception {
+		DirCache treeB = db.readDirCache();
+		DirCache treeO = db.readDirCache();
+		DirCache treeT = db.readDirCache();
+
+		DirCacheBuilder bTreeBuilder = treeB.builder();
+		DirCacheBuilder oTreeBuilder = treeO.builder();
+		DirCacheBuilder tTreeBuilder = treeT.builder();
+
+		bTreeBuilder.add(
+				createEntry(SUBMODULE_PATH, FileMode.REGULAR_FILE, "blob"));
+		oTreeBuilder.add(
+				createEntry(SUBMODULE_PATH, FileMode.REGULAR_FILE, "blob 2"));
+
+		maybeAddLink(tTreeBuilder, LINK_ID3);
+
+		bTreeBuilder.finish();
+		oTreeBuilder.finish();
+		tTreeBuilder.finish();
+
+		ObjectInserter ow = db.newObjectInserter();
+		ObjectId b = commit(ow, treeB, new ObjectId[] {});
+		ObjectId o = commit(ow, treeO, new ObjectId[] { b });
+		ObjectId t = commit(ow, treeT, new ObjectId[] { b });
+
+		Merger resolveMerger = MergeStrategy.RESOLVE.newMerger(db);
+		boolean merge = resolveMerger.merge(new ObjectId[] { o, t });
+		assertFalse(merge);
+	}
+
+	@Test
+	public void testGitLinkMerging_linkWithBlob() throws Exception {
+		DirCache treeB = db.readDirCache();
+		DirCache treeO = db.readDirCache();
+		DirCache treeT = db.readDirCache();
+
+		DirCacheBuilder bTreeBuilder = treeB.builder();
+		DirCacheBuilder oTreeBuilder = treeO.builder();
+		DirCacheBuilder tTreeBuilder = treeT.builder();
+
+		maybeAddLink(bTreeBuilder, LINK_ID1);
+		maybeAddLink(oTreeBuilder, LINK_ID2);
+		tTreeBuilder.add(
+				createEntry(SUBMODULE_PATH, FileMode.REGULAR_FILE, "blob 3"));
+
+		bTreeBuilder.finish();
+		oTreeBuilder.finish();
+		tTreeBuilder.finish();
+
+		ObjectInserter ow = db.newObjectInserter();
+		ObjectId b = commit(ow, treeB, new ObjectId[] {});
+		ObjectId o = commit(ow, treeO, new ObjectId[] { b });
+		ObjectId t = commit(ow, treeT, new ObjectId[] { b });
+
+		Merger resolveMerger = MergeStrategy.RESOLVE.newMerger(db);
+		boolean merge = resolveMerger.merge(new ObjectId[] { o, t });
+		assertFalse(merge);
+	}
+
+	@Test
+	public void testGitLinkMerging_linkWithLink() throws Exception {
+		DirCache treeB = db.readDirCache();
+		DirCache treeO = db.readDirCache();
+		DirCache treeT = db.readDirCache();
+
+		DirCacheBuilder bTreeBuilder = treeB.builder();
+		DirCacheBuilder oTreeBuilder = treeO.builder();
+		DirCacheBuilder tTreeBuilder = treeT.builder();
+
+		bTreeBuilder.add(
+				createEntry(SUBMODULE_PATH, FileMode.REGULAR_FILE, "blob"));
+		maybeAddLink(oTreeBuilder, LINK_ID2);
+		maybeAddLink(tTreeBuilder, LINK_ID3);
+
+		bTreeBuilder.finish();
+		oTreeBuilder.finish();
+		tTreeBuilder.finish();
+
+		ObjectInserter ow = db.newObjectInserter();
+		ObjectId b = commit(ow, treeB, new ObjectId[] {});
+		ObjectId o = commit(ow, treeO, new ObjectId[] { b });
+		ObjectId t = commit(ow, treeT, new ObjectId[] { b });
+
+		Merger resolveMerger = MergeStrategy.RESOLVE.newMerger(db);
+		boolean merge = resolveMerger.merge(new ObjectId[] { o, t });
+		assertFalse(merge);
+	}
+
+	@Test
+	public void testGitLinkMerging_blobWithBlobFromLink() throws Exception {
+		DirCache treeB = db.readDirCache();
+		DirCache treeO = db.readDirCache();
+		DirCache treeT = db.readDirCache();
+
+		DirCacheBuilder bTreeBuilder = treeB.builder();
+		DirCacheBuilder oTreeBuilder = treeO.builder();
+		DirCacheBuilder tTreeBuilder = treeT.builder();
+
+		maybeAddLink(bTreeBuilder, LINK_ID1);
+		oTreeBuilder.add(
+				createEntry(SUBMODULE_PATH, FileMode.REGULAR_FILE, "blob 2"));
+		tTreeBuilder.add(
+				createEntry(SUBMODULE_PATH, FileMode.REGULAR_FILE, "blob 3"));
+
+		bTreeBuilder.finish();
+		oTreeBuilder.finish();
+		tTreeBuilder.finish();
+
+		ObjectInserter ow = db.newObjectInserter();
+		ObjectId b = commit(ow, treeB, new ObjectId[] {});
+		ObjectId o = commit(ow, treeO, new ObjectId[] { b });
+		ObjectId t = commit(ow, treeT, new ObjectId[] { b });
+
+		Merger resolveMerger = MergeStrategy.RESOLVE.newMerger(db);
+		boolean merge = resolveMerger.merge(new ObjectId[] { o, t });
+		assertFalse(merge);
+	}
+
+	@Test
+	public void testGitLinkMerging_linkBlobDeleted() throws Exception {
+		// We changed a link to a blob, others has deleted this link.
+		DirCache treeB = db.readDirCache();
+		DirCache treeO = db.readDirCache();
+		DirCache treeT = db.readDirCache();
+
+		DirCacheBuilder bTreeBuilder = treeB.builder();
+		DirCacheBuilder oTreeBuilder = treeO.builder();
+		DirCacheBuilder tTreeBuilder = treeT.builder();
+
+		maybeAddLink(bTreeBuilder, LINK_ID1);
+		oTreeBuilder.add(
+				createEntry(SUBMODULE_PATH, FileMode.REGULAR_FILE, "blob 2"));
+
+		bTreeBuilder.finish();
+		oTreeBuilder.finish();
+		tTreeBuilder.finish();
+
+		ObjectInserter ow = db.newObjectInserter();
+		ObjectId b = commit(ow, treeB, new ObjectId[] {});
+		ObjectId o = commit(ow, treeO, new ObjectId[] { b });
+		ObjectId t = commit(ow, treeT, new ObjectId[] { b });
+
+		Merger resolveMerger = MergeStrategy.RESOLVE.newMerger(db);
+		boolean merge = resolveMerger.merge(new ObjectId[] { o, t });
+		assertFalse(merge);
+	}
+
+	private void maybeAddLink(DirCacheBuilder builder,
+			@Nullable String linkId) {
+		if (linkId == null) {
+			return;
+		}
+		DirCacheEntry newLink = createGitLink(SUBMODULE_PATH,
+				ObjectId.fromString(linkId));
+		builder.add(newLink);
+	}
+
+	private void assertGitLinkValue(Merger resolveMerger, String expectedValue)
+			throws Exception {
+		try (TreeWalk tw = new TreeWalk(db)) {
+			tw.setRecursive(true);
+			tw.reset(resolveMerger.getResultTreeId());
+
+			assertTrue(tw.next());
+			assertEquals(SUBMODULE_PATH, tw.getPathString());
+			assertEquals(ObjectId.fromString(expectedValue), tw.getObjectId(0));
+
+			assertFalse(tw.next());
+		}
+	}
+
+	private void assertGitLinkDoesntExist(Merger resolveMerger)
+			throws Exception {
+		try (TreeWalk tw = new TreeWalk(db)) {
+			tw.setRecursive(true);
+			tw.reset(resolveMerger.getResultTreeId());
+
+			assertFalse(tw.next());
+		}
+	}
+
+	private static ObjectId commit(ObjectInserter odi, DirCache treeB,
+			ObjectId[] parentIds) throws Exception {
+		CommitBuilder c = new CommitBuilder();
+		c.setTreeId(treeB.writeTree(odi));
+		c.setAuthor(new PersonIdent("A U Thor", "a.u.thor", 1L, 0));
+		c.setCommitter(c.getAuthor());
+		c.setParentIds(parentIds);
+		c.setMessage("Tree " + c.getTreeId().name());
+		ObjectId id = odi.insert(c);
+		odi.flush();
+		return id;
+	}
+}
diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/merge/MergerTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/merge/MergerTest.java
index 7a244e1..e2ac89b 100644
--- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/merge/MergerTest.java
+++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/merge/MergerTest.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2012, Robin Stocker <robin@nibor.org> and others
+ * Copyright (C) 2012, 2020 Robin Stocker <robin@nibor.org> and others
  *
  * This program and the accompanying materials are made available under the
  * terms of the Eclipse Distribution License v. 1.0 which is available at
@@ -367,6 +367,48 @@
 	}
 
 	@Theory
+	public void mergeConflictWithCrLfTextAuto(MergeStrategy strategy)
+			throws IOException, GitAPIException {
+		Git git = Git.wrap(db);
+		writeTrashFile("crlf.txt", "a crlf file\r\n");
+		git.add().addFilepattern("crlf.txt").call();
+		git.commit().setMessage("base").call();
+		assertEquals("[crlf.txt, mode:100644, content:a crlf file\r\n]",
+				indexState(CONTENT));
+		writeTrashFile(".gitattributes", "crlf.txt text=auto");
+		git.add().addFilepattern(".gitattributes").call();
+		git.commit().setMessage("attributes").call();
+
+		git.branchCreate().setName("brancha").call();
+
+		writeTrashFile("crlf.txt", "a crlf file\r\na second line\r\n");
+		git.add().addFilepattern("crlf.txt").call();
+		git.commit().setMessage("on master").call();
+		assertEquals(
+				"[.gitattributes, mode:100644, content:crlf.txt text=auto]"
+						+ "[crlf.txt, mode:100644, content:a crlf file\r\na second line\r\n]",
+				indexState(CONTENT));
+
+		git.checkout().setName("brancha").call();
+		File testFile = writeTrashFile("crlf.txt",
+				"a crlf file\r\nanother line\r\n");
+		git.add().addFilepattern("crlf.txt").call();
+		git.commit().setMessage("on brancha").call();
+
+		MergeResult mergeResult = git.merge().setStrategy(strategy)
+				.include(db.resolve("master")).call();
+		assertEquals(MergeResult.MergeStatus.CONFLICTING,
+				mergeResult.getMergeStatus());
+		checkFile(testFile,
+				"a crlf file\r\n" //
+						+ "<<<<<<< HEAD\n" //
+						+ "another line\r\n" //
+						+ "=======\n" //
+						+ "a second line\r\n" //
+						+ ">>>>>>> 8e9e704742f1bc8a41eac88aac4aeefd338b7384\n");
+	}
+
+	@Theory
 	public void mergeWithCrlfAutoCrlfTrue(MergeStrategy strategy)
 			throws IOException, GitAPIException {
 		Git git = Git.wrap(db);
diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/merge/SimpleMergeTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/merge/SimpleMergeTest.java
index 36805d3..798aebe 100644
--- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/merge/SimpleMergeTest.java
+++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/merge/SimpleMergeTest.java
@@ -109,33 +109,33 @@
 
 	@Test
 	public void testTrivialTwoWay_validSubtreeSort() throws Exception {
-		final DirCache treeB = db.readDirCache();
-		final DirCache treeO = db.readDirCache();
-		final DirCache treeT = db.readDirCache();
-		{
-			final DirCacheBuilder b = treeB.builder();
-			final DirCacheBuilder o = treeO.builder();
-			final DirCacheBuilder t = treeT.builder();
+		DirCache treeB = db.readDirCache();
+		DirCache treeO = db.readDirCache();
+		DirCache treeT = db.readDirCache();
 
-			b.add(createEntry("libelf-po/a", FileMode.REGULAR_FILE));
-			b.add(createEntry("libelf/c", FileMode.REGULAR_FILE));
+		DirCacheBuilder bTreeBuilder = treeB.builder();
+		DirCacheBuilder oTreeBuilder = treeO.builder();
+		DirCacheBuilder tTreeBuilder = treeT.builder();
 
-			o.add(createEntry("Makefile", FileMode.REGULAR_FILE));
-			o.add(createEntry("libelf-po/a", FileMode.REGULAR_FILE));
-			o.add(createEntry("libelf/c", FileMode.REGULAR_FILE));
+		bTreeBuilder.add(createEntry("libelf-po/a", FileMode.REGULAR_FILE));
+		bTreeBuilder.add(createEntry("libelf/c", FileMode.REGULAR_FILE));
 
-			t.add(createEntry("libelf-po/a", FileMode.REGULAR_FILE));
-			t.add(createEntry("libelf/c", FileMode.REGULAR_FILE, "blah"));
+		oTreeBuilder.add(createEntry("Makefile", FileMode.REGULAR_FILE));
+		oTreeBuilder.add(createEntry("libelf-po/a", FileMode.REGULAR_FILE));
+		oTreeBuilder.add(createEntry("libelf/c", FileMode.REGULAR_FILE));
 
-			b.finish();
-			o.finish();
-			t.finish();
-		}
+		tTreeBuilder.add(createEntry("libelf-po/a", FileMode.REGULAR_FILE));
+		tTreeBuilder
+				.add(createEntry("libelf/c", FileMode.REGULAR_FILE, "blah"));
 
-		final ObjectInserter ow = db.newObjectInserter();
-		final ObjectId b = commit(ow, treeB, new ObjectId[] {});
-		final ObjectId o = commit(ow, treeO, new ObjectId[] { b });
-		final ObjectId t = commit(ow, treeT, new ObjectId[] { b });
+		bTreeBuilder.finish();
+		oTreeBuilder.finish();
+		tTreeBuilder.finish();
+
+		ObjectInserter ow = db.newObjectInserter();
+		ObjectId b = commit(ow, treeB, new ObjectId[] {});
+		ObjectId o = commit(ow, treeO, new ObjectId[] { b });
+		ObjectId t = commit(ow, treeT, new ObjectId[] { b });
 
 		Merger ourMerger = MergeStrategy.SIMPLE_TWO_WAY_IN_CORE.newMerger(db);
 		boolean merge = ourMerger.merge(new ObjectId[] { o, t });
@@ -163,32 +163,31 @@
 
 	@Test
 	public void testTrivialTwoWay_concurrentSubtreeChange() throws Exception {
-		final DirCache treeB = db.readDirCache();
-		final DirCache treeO = db.readDirCache();
-		final DirCache treeT = db.readDirCache();
-		{
-			final DirCacheBuilder b = treeB.builder();
-			final DirCacheBuilder o = treeO.builder();
-			final DirCacheBuilder t = treeT.builder();
+		DirCache treeB = db.readDirCache();
+		DirCache treeO = db.readDirCache();
+		DirCache treeT = db.readDirCache();
 
-			b.add(createEntry("d/o", FileMode.REGULAR_FILE));
-			b.add(createEntry("d/t", FileMode.REGULAR_FILE));
+		DirCacheBuilder bTreeBuilder = treeB.builder();
+		DirCacheBuilder oTreeBuilder = treeO.builder();
+		DirCacheBuilder tTreeBuilder = treeT.builder();
 
-			o.add(createEntry("d/o", FileMode.REGULAR_FILE, "o !"));
-			o.add(createEntry("d/t", FileMode.REGULAR_FILE));
+		bTreeBuilder.add(createEntry("d/o", FileMode.REGULAR_FILE));
+		bTreeBuilder.add(createEntry("d/t", FileMode.REGULAR_FILE));
 
-			t.add(createEntry("d/o", FileMode.REGULAR_FILE));
-			t.add(createEntry("d/t", FileMode.REGULAR_FILE, "t !"));
+		oTreeBuilder.add(createEntry("d/o", FileMode.REGULAR_FILE, "o !"));
+		oTreeBuilder.add(createEntry("d/t", FileMode.REGULAR_FILE));
 
-			b.finish();
-			o.finish();
-			t.finish();
-		}
+		tTreeBuilder.add(createEntry("d/o", FileMode.REGULAR_FILE));
+		tTreeBuilder.add(createEntry("d/t", FileMode.REGULAR_FILE, "t !"));
 
-		final ObjectInserter ow = db.newObjectInserter();
-		final ObjectId b = commit(ow, treeB, new ObjectId[] {});
-		final ObjectId o = commit(ow, treeO, new ObjectId[] { b });
-		final ObjectId t = commit(ow, treeT, new ObjectId[] { b });
+		bTreeBuilder.finish();
+		oTreeBuilder.finish();
+		tTreeBuilder.finish();
+
+		ObjectInserter ow = db.newObjectInserter();
+		ObjectId b = commit(ow, treeB, new ObjectId[] {});
+		ObjectId o = commit(ow, treeO, new ObjectId[] { b });
+		ObjectId t = commit(ow, treeT, new ObjectId[] { b });
 
 		Merger ourMerger = MergeStrategy.SIMPLE_TWO_WAY_IN_CORE.newMerger(db);
 		boolean merge = ourMerger.merge(new ObjectId[] { o, t });
@@ -212,32 +211,31 @@
 
 	@Test
 	public void testTrivialTwoWay_conflictSubtreeChange() throws Exception {
-		final DirCache treeB = db.readDirCache();
-		final DirCache treeO = db.readDirCache();
-		final DirCache treeT = db.readDirCache();
-		{
-			final DirCacheBuilder b = treeB.builder();
-			final DirCacheBuilder o = treeO.builder();
-			final DirCacheBuilder t = treeT.builder();
+		DirCache treeB = db.readDirCache();
+		DirCache treeO = db.readDirCache();
+		DirCache treeT = db.readDirCache();
 
-			b.add(createEntry("d/o", FileMode.REGULAR_FILE));
-			b.add(createEntry("d/t", FileMode.REGULAR_FILE));
+		DirCacheBuilder bTreeBuilder = treeB.builder();
+		DirCacheBuilder oTreeBuilder = treeO.builder();
+		DirCacheBuilder tTreeBuilder = treeT.builder();
 
-			o.add(createEntry("d/o", FileMode.REGULAR_FILE));
-			o.add(createEntry("d/t", FileMode.REGULAR_FILE, "o !"));
+		bTreeBuilder.add(createEntry("d/o", FileMode.REGULAR_FILE));
+		bTreeBuilder.add(createEntry("d/t", FileMode.REGULAR_FILE));
 
-			t.add(createEntry("d/o", FileMode.REGULAR_FILE, "t !"));
-			t.add(createEntry("d/t", FileMode.REGULAR_FILE, "t !"));
+		oTreeBuilder.add(createEntry("d/o", FileMode.REGULAR_FILE));
+		oTreeBuilder.add(createEntry("d/t", FileMode.REGULAR_FILE, "o !"));
 
-			b.finish();
-			o.finish();
-			t.finish();
-		}
+		tTreeBuilder.add(createEntry("d/o", FileMode.REGULAR_FILE, "t !"));
+		tTreeBuilder.add(createEntry("d/t", FileMode.REGULAR_FILE, "t !"));
 
-		final ObjectInserter ow = db.newObjectInserter();
-		final ObjectId b = commit(ow, treeB, new ObjectId[] {});
-		final ObjectId o = commit(ow, treeO, new ObjectId[] { b });
-		final ObjectId t = commit(ow, treeT, new ObjectId[] { b });
+		bTreeBuilder.finish();
+		oTreeBuilder.finish();
+		tTreeBuilder.finish();
+
+		ObjectInserter ow = db.newObjectInserter();
+		ObjectId b = commit(ow, treeB, new ObjectId[] {});
+		ObjectId o = commit(ow, treeO, new ObjectId[] { b });
+		ObjectId t = commit(ow, treeT, new ObjectId[] { b });
 
 		Merger ourMerger = MergeStrategy.SIMPLE_TWO_WAY_IN_CORE.newMerger(db);
 		boolean merge = ourMerger.merge(new ObjectId[] { o, t });
@@ -246,31 +244,30 @@
 
 	@Test
 	public void testTrivialTwoWay_leftDFconflict1() throws Exception {
-		final DirCache treeB = db.readDirCache();
-		final DirCache treeO = db.readDirCache();
-		final DirCache treeT = db.readDirCache();
-		{
-			final DirCacheBuilder b = treeB.builder();
-			final DirCacheBuilder o = treeO.builder();
-			final DirCacheBuilder t = treeT.builder();
+		DirCache treeB = db.readDirCache();
+		DirCache treeO = db.readDirCache();
+		DirCache treeT = db.readDirCache();
 
-			b.add(createEntry("d/o", FileMode.REGULAR_FILE));
-			b.add(createEntry("d/t", FileMode.REGULAR_FILE));
+		DirCacheBuilder bTreeBuilder = treeB.builder();
+		DirCacheBuilder oTreeBuilder = treeO.builder();
+		DirCacheBuilder tTreeBuilder = treeT.builder();
 
-			o.add(createEntry("d", FileMode.REGULAR_FILE));
+		bTreeBuilder.add(createEntry("d/o", FileMode.REGULAR_FILE));
+		bTreeBuilder.add(createEntry("d/t", FileMode.REGULAR_FILE));
 
-			t.add(createEntry("d/o", FileMode.REGULAR_FILE));
-			t.add(createEntry("d/t", FileMode.REGULAR_FILE, "t !"));
+		oTreeBuilder.add(createEntry("d", FileMode.REGULAR_FILE));
 
-			b.finish();
-			o.finish();
-			t.finish();
-		}
+		tTreeBuilder.add(createEntry("d/o", FileMode.REGULAR_FILE));
+		tTreeBuilder.add(createEntry("d/t", FileMode.REGULAR_FILE, "t !"));
 
-		final ObjectInserter ow = db.newObjectInserter();
-		final ObjectId b = commit(ow, treeB, new ObjectId[] {});
-		final ObjectId o = commit(ow, treeO, new ObjectId[] { b });
-		final ObjectId t = commit(ow, treeT, new ObjectId[] { b });
+		bTreeBuilder.finish();
+		oTreeBuilder.finish();
+		tTreeBuilder.finish();
+
+		ObjectInserter ow = db.newObjectInserter();
+		ObjectId b = commit(ow, treeB, new ObjectId[] {});
+		ObjectId o = commit(ow, treeO, new ObjectId[] { b });
+		ObjectId t = commit(ow, treeT, new ObjectId[] { b });
 
 		Merger ourMerger = MergeStrategy.SIMPLE_TWO_WAY_IN_CORE.newMerger(db);
 		boolean merge = ourMerger.merge(new ObjectId[] { o, t });
@@ -279,31 +276,30 @@
 
 	@Test
 	public void testTrivialTwoWay_rightDFconflict1() throws Exception {
-		final DirCache treeB = db.readDirCache();
-		final DirCache treeO = db.readDirCache();
-		final DirCache treeT = db.readDirCache();
-		{
-			final DirCacheBuilder b = treeB.builder();
-			final DirCacheBuilder o = treeO.builder();
-			final DirCacheBuilder t = treeT.builder();
+		DirCache treeB = db.readDirCache();
+		DirCache treeO = db.readDirCache();
+		DirCache treeT = db.readDirCache();
 
-			b.add(createEntry("d/o", FileMode.REGULAR_FILE));
-			b.add(createEntry("d/t", FileMode.REGULAR_FILE));
+		DirCacheBuilder bTreeBuilder = treeB.builder();
+		DirCacheBuilder oTreeBuilder = treeO.builder();
+		DirCacheBuilder tTreeBuilder = treeT.builder();
 
-			o.add(createEntry("d/o", FileMode.REGULAR_FILE));
-			o.add(createEntry("d/t", FileMode.REGULAR_FILE, "o !"));
+		bTreeBuilder.add(createEntry("d/o", FileMode.REGULAR_FILE));
+		bTreeBuilder.add(createEntry("d/t", FileMode.REGULAR_FILE));
 
-			t.add(createEntry("d", FileMode.REGULAR_FILE));
+		oTreeBuilder.add(createEntry("d/o", FileMode.REGULAR_FILE));
+		oTreeBuilder.add(createEntry("d/t", FileMode.REGULAR_FILE, "o !"));
 
-			b.finish();
-			o.finish();
-			t.finish();
-		}
+		tTreeBuilder.add(createEntry("d", FileMode.REGULAR_FILE));
 
-		final ObjectInserter ow = db.newObjectInserter();
-		final ObjectId b = commit(ow, treeB, new ObjectId[] {});
-		final ObjectId o = commit(ow, treeO, new ObjectId[] { b });
-		final ObjectId t = commit(ow, treeT, new ObjectId[] { b });
+		bTreeBuilder.finish();
+		oTreeBuilder.finish();
+		tTreeBuilder.finish();
+
+		ObjectInserter ow = db.newObjectInserter();
+		ObjectId b = commit(ow, treeB, new ObjectId[] {});
+		ObjectId o = commit(ow, treeO, new ObjectId[] { b });
+		ObjectId t = commit(ow, treeT, new ObjectId[] { b });
 
 		Merger ourMerger = MergeStrategy.SIMPLE_TWO_WAY_IN_CORE.newMerger(db);
 		boolean merge = ourMerger.merge(new ObjectId[] { o, t });
@@ -312,29 +308,28 @@
 
 	@Test
 	public void testTrivialTwoWay_leftDFconflict2() throws Exception {
-		final DirCache treeB = db.readDirCache();
-		final DirCache treeO = db.readDirCache();
-		final DirCache treeT = db.readDirCache();
-		{
-			final DirCacheBuilder b = treeB.builder();
-			final DirCacheBuilder o = treeO.builder();
-			final DirCacheBuilder t = treeT.builder();
+		DirCache treeB = db.readDirCache();
+		DirCache treeO = db.readDirCache();
+		DirCache treeT = db.readDirCache();
 
-			b.add(createEntry("d", FileMode.REGULAR_FILE));
+		DirCacheBuilder bTreeBuilder = treeB.builder();
+		DirCacheBuilder oTreeBuilder = treeO.builder();
+		DirCacheBuilder tTreeBuilder = treeT.builder();
 
-			o.add(createEntry("d", FileMode.REGULAR_FILE, "o !"));
+		bTreeBuilder.add(createEntry("d", FileMode.REGULAR_FILE));
 
-			t.add(createEntry("d/o", FileMode.REGULAR_FILE));
+		oTreeBuilder.add(createEntry("d", FileMode.REGULAR_FILE, "o !"));
 
-			b.finish();
-			o.finish();
-			t.finish();
-		}
+		tTreeBuilder.add(createEntry("d/o", FileMode.REGULAR_FILE));
 
-		final ObjectInserter ow = db.newObjectInserter();
-		final ObjectId b = commit(ow, treeB, new ObjectId[] {});
-		final ObjectId o = commit(ow, treeO, new ObjectId[] { b });
-		final ObjectId t = commit(ow, treeT, new ObjectId[] { b });
+		bTreeBuilder.finish();
+		oTreeBuilder.finish();
+		tTreeBuilder.finish();
+
+		ObjectInserter ow = db.newObjectInserter();
+		ObjectId b = commit(ow, treeB, new ObjectId[] {});
+		ObjectId o = commit(ow, treeO, new ObjectId[] { b });
+		ObjectId t = commit(ow, treeT, new ObjectId[] { b });
 
 		Merger ourMerger = MergeStrategy.SIMPLE_TWO_WAY_IN_CORE.newMerger(db);
 		boolean merge = ourMerger.merge(new ObjectId[] { o, t });
@@ -343,29 +338,28 @@
 
 	@Test
 	public void testTrivialTwoWay_rightDFconflict2() throws Exception {
-		final DirCache treeB = db.readDirCache();
-		final DirCache treeO = db.readDirCache();
-		final DirCache treeT = db.readDirCache();
-		{
-			final DirCacheBuilder b = treeB.builder();
-			final DirCacheBuilder o = treeO.builder();
-			final DirCacheBuilder t = treeT.builder();
+		DirCache treeB = db.readDirCache();
+		DirCache treeO = db.readDirCache();
+		DirCache treeT = db.readDirCache();
 
-			b.add(createEntry("d", FileMode.REGULAR_FILE));
+		DirCacheBuilder bTreeBuilder = treeB.builder();
+		DirCacheBuilder oTreeBuilder = treeO.builder();
+		DirCacheBuilder tTreeBuilder = treeT.builder();
 
-			o.add(createEntry("d/o", FileMode.REGULAR_FILE));
+		bTreeBuilder.add(createEntry("d", FileMode.REGULAR_FILE));
 
-			t.add(createEntry("d", FileMode.REGULAR_FILE, "t !"));
+		oTreeBuilder.add(createEntry("d/o", FileMode.REGULAR_FILE));
 
-			b.finish();
-			o.finish();
-			t.finish();
-		}
+		tTreeBuilder.add(createEntry("d", FileMode.REGULAR_FILE, "t !"));
 
-		final ObjectInserter ow = db.newObjectInserter();
-		final ObjectId b = commit(ow, treeB, new ObjectId[] {});
-		final ObjectId o = commit(ow, treeO, new ObjectId[] { b });
-		final ObjectId t = commit(ow, treeT, new ObjectId[] { b });
+		bTreeBuilder.finish();
+		oTreeBuilder.finish();
+		tTreeBuilder.finish();
+
+		ObjectInserter ow = db.newObjectInserter();
+		ObjectId b = commit(ow, treeB, new ObjectId[] {});
+		ObjectId o = commit(ow, treeO, new ObjectId[] { b });
+		ObjectId t = commit(ow, treeT, new ObjectId[] { b });
 
 		Merger ourMerger = MergeStrategy.SIMPLE_TWO_WAY_IN_CORE.newMerger(db);
 		boolean merge = ourMerger.merge(new ObjectId[] { o, t });
@@ -377,10 +371,9 @@
 				.getObjectId(0));
 	}
 
-	private static ObjectId commit(final ObjectInserter odi,
-			final DirCache treeB,
-			final ObjectId[] parentIds) throws Exception {
-		final CommitBuilder c = new CommitBuilder();
+	private static ObjectId commit(ObjectInserter odi, DirCache treeB,
+			ObjectId[] parentIds) throws Exception {
+		CommitBuilder c = new CommitBuilder();
 		c.setTreeId(treeB.writeTree(odi));
 		c.setAuthor(new PersonIdent("A U Thor", "a.u.thor", 1L, 0));
 		c.setCommitter(c.getAuthor());
diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/transport/ProtocolV0ParserTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/transport/ProtocolV0ParserTest.java
index 965a2fa..c0db83a 100644
--- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/transport/ProtocolV0ParserTest.java
+++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/transport/ProtocolV0ParserTest.java
@@ -9,6 +9,10 @@
  */
 package org.eclipse.jgit.transport;
 
+import static org.eclipse.jgit.lib.Constants.OBJ_BLOB;
+import static org.eclipse.jgit.lib.Constants.OBJ_COMMIT;
+import static org.eclipse.jgit.lib.Constants.OBJ_TAG;
+import static org.eclipse.jgit.lib.Constants.OBJ_TREE;
 import static org.eclipse.jgit.transport.ObjectIdMatcher.hasOnlyObjectIds;
 import static org.hamcrest.MatcherAssert.assertThat;
 import static org.junit.Assert.assertEquals;
@@ -160,6 +164,10 @@
 		assertThat(request.getWantIds(),
 				hasOnlyObjectIds("4624442d68ee402a94364191085b77137618633e",
 						"f900c8326a43303685c46b279b9f70411bff1a4b"));
+		assertTrue(request.getFilterSpec().allowsType(OBJ_BLOB));
+		assertTrue(request.getFilterSpec().allowsType(OBJ_TREE));
+		assertTrue(request.getFilterSpec().allowsType(OBJ_COMMIT));
+		assertTrue(request.getFilterSpec().allowsType(OBJ_TAG));
 		assertEquals(13000, request.getFilterSpec().getBlobLimit());
 		assertEquals(-1, request.getFilterSpec().getTreeDepthLimit());
 	}
diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/transport/ProtocolV2ParserTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/transport/ProtocolV2ParserTest.java
index 038ce71..837bdce 100644
--- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/transport/ProtocolV2ParserTest.java
+++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/transport/ProtocolV2ParserTest.java
@@ -9,6 +9,10 @@
  */
 package org.eclipse.jgit.transport;
 
+import static org.eclipse.jgit.lib.Constants.OBJ_BLOB;
+import static org.eclipse.jgit.lib.Constants.OBJ_COMMIT;
+import static org.eclipse.jgit.lib.Constants.OBJ_TAG;
+import static org.eclipse.jgit.lib.Constants.OBJ_TREE;
 import static org.eclipse.jgit.transport.ObjectIdMatcher.hasOnlyObjectIds;
 import static org.hamcrest.MatcherAssert.assertThat;
 import static org.hamcrest.Matchers.hasItems;
@@ -195,7 +199,11 @@
 		ProtocolV2Parser parser = new ProtocolV2Parser(
 				ConfigBuilder.start().allowFilter().done());
 		FetchV2Request request = parser.parseFetchRequest(pckIn);
-		assertEquals(0, request.getFilterSpec().getBlobLimit());
+		assertFalse(request.getFilterSpec().allowsType(OBJ_BLOB));
+		assertTrue(request.getFilterSpec().allowsType(OBJ_TREE));
+		assertTrue(request.getFilterSpec().allowsType(OBJ_COMMIT));
+		assertTrue(request.getFilterSpec().allowsType(OBJ_TAG));
+		assertEquals(-1, request.getFilterSpec().getBlobLimit());
 		assertEquals(-1, request.getFilterSpec().getTreeDepthLimit());
 	}
 
@@ -207,6 +215,10 @@
 		ProtocolV2Parser parser = new ProtocolV2Parser(
 				ConfigBuilder.start().allowFilter().done());
 		FetchV2Request request = parser.parseFetchRequest(pckIn);
+		assertTrue(request.getFilterSpec().allowsType(OBJ_BLOB));
+		assertTrue(request.getFilterSpec().allowsType(OBJ_TREE));
+		assertTrue(request.getFilterSpec().allowsType(OBJ_COMMIT));
+		assertTrue(request.getFilterSpec().allowsType(OBJ_TAG));
 		assertEquals(15, request.getFilterSpec().getBlobLimit());
 		assertEquals(-1, request.getFilterSpec().getTreeDepthLimit());
 	}
@@ -219,6 +231,10 @@
 		ProtocolV2Parser parser = new ProtocolV2Parser(
 				ConfigBuilder.start().allowFilter().done());
 		FetchV2Request request = parser.parseFetchRequest(pckIn);
+		assertTrue(request.getFilterSpec().allowsType(OBJ_BLOB));
+		assertTrue(request.getFilterSpec().allowsType(OBJ_TREE));
+		assertTrue(request.getFilterSpec().allowsType(OBJ_COMMIT));
+		assertTrue(request.getFilterSpec().allowsType(OBJ_TAG));
 		assertEquals(-1, request.getFilterSpec().getBlobLimit());
 		assertEquals(3, request.getFilterSpec().getTreeDepthLimit());
 	}
diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/transport/PushConnectionTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/transport/PushConnectionTest.java
index 0179d8c..21fde3e 100644
--- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/transport/PushConnectionTest.java
+++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/transport/PushConnectionTest.java
@@ -162,7 +162,9 @@
 				fail("server did not abort");
 			} catch (TransportException e) {
 				String msg = e.getMessage();
-				assertEquals("remote: Too many commands", msg);
+				assertEquals(
+						"remote: Commands size exceeds limit defined in receive.maxCommandBytes",
+						msg);
 			}
 		}
 	}
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 d58e576..46ba3aa 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
@@ -38,6 +38,7 @@
 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.ConfigConstants;
 import org.eclipse.jgit.lib.NullProgressMonitor;
 import org.eclipse.jgit.lib.ObjectId;
 import org.eclipse.jgit.lib.ObjectInserter;
@@ -127,7 +128,7 @@
 	}
 
 	@Test
-	public void testFetchWithBlobNoneFilter() throws Exception {
+	public void testFetchWithBlobZeroFilter() throws Exception {
 		InMemoryRepository server2 = newRepo("server2");
 		try (TestRepository<InMemoryRepository> remote2 = new TestRepository<>(
 				server2)) {
@@ -298,6 +299,38 @@
 	}
 
 	@Test
+	public void testFetchWithTreeZeroFilter() throws Exception {
+		InMemoryRepository server2 = newRepo("server2");
+		try (TestRepository<InMemoryRepository> remote2 = new TestRepository<>(
+				server2)) {
+			RevBlob blob1 = remote2.blob("foobar");
+			RevBlob blob2 = remote2.blob("fooba");
+			RevTree tree = remote2.tree(remote2.file("1", blob1),
+					remote2.file("2", blob2));
+			RevCommit commit = remote2.commit(tree);
+			remote2.update("master", commit);
+
+			server2.getConfig().setBoolean("uploadpack", null, "allowfilter",
+					true);
+
+			testProtocol = new TestProtocol<>((Object req, Repository db) -> {
+				UploadPack up = new UploadPack(db);
+				return up;
+			}, null);
+			uri = testProtocol.register(ctx, server2);
+
+			try (Transport tn = testProtocol.open(uri, client, "server2")) {
+				tn.setFilterSpec(FilterSpec.withTreeDepthLimit(0));
+				tn.fetch(NullProgressMonitor.INSTANCE,
+						Collections.singletonList(new RefSpec(commit.name())));
+				assertFalse(client.getObjectDatabase().has(tree.toObjectId()));
+				assertFalse(client.getObjectDatabase().has(blob1.toObjectId()));
+				assertFalse(client.getObjectDatabase().has(blob2.toObjectId()));
+			}
+		}
+	}
+
+	@Test
 	public void testFetchWithNonSupportingServer() throws Exception {
 		InMemoryRepository server2 = newRepo("server2");
 		try (TestRepository<InMemoryRepository> remote2 = new TestRepository<>(
@@ -338,7 +371,9 @@
 
 		ByteArrayInputStream send = linesAsInputStream(inputLines);
 
-		server.getConfig().setString("protocol", null, "version", "2");
+		server.getConfig().setString(ConfigConstants.CONFIG_PROTOCOL_SECTION,
+				null, ConfigConstants.CONFIG_KEY_VERSION,
+				TransferConfig.ProtocolVersion.V2.version());
 		UploadPack up = new UploadPack(server);
 		if (postConstructionSetup != null) {
 			postConstructionSetup.accept(up);
@@ -2133,7 +2168,9 @@
 
 	@Test
 	public void testGetPeerAgentProtocolV2() throws Exception {
-		server.getConfig().setString("protocol", null, "version", "2");
+		server.getConfig().setString(ConfigConstants.CONFIG_PROTOCOL_SECTION,
+				null, ConfigConstants.CONFIG_KEY_VERSION,
+				TransferConfig.ProtocolVersion.V2.version());
 
 		RevCommit one = remote.commit().message("1").create();
 		remote.update("one", one);
diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/util/io/AutoLFInputStreamTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/util/io/AutoLFInputStreamTest.java
index fb90461..c391694 100644
--- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/util/io/AutoLFInputStreamTest.java
+++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/util/io/AutoLFInputStreamTest.java
@@ -1,6 +1,6 @@
 /*
  * Copyright (C) 2010, Marc Strapetz <marc.strapetz@syntevo.com>
- * Copyright (C) 2015, Ivan Motsch <ivan.motsch@bsiag.com> and others
+ * Copyright (C) 2015, 2020 Ivan Motsch <ivan.motsch@bsiag.com> and others
  *
  * This program and the accompanying materials are made available under the
  * terms of the Eclipse Distribution License v. 1.0 which is available at
@@ -17,7 +17,9 @@
 import java.io.ByteArrayInputStream;
 import java.io.IOException;
 import java.io.InputStream;
+import java.util.function.Function;
 
+import org.eclipse.jgit.util.io.AutoLFInputStream.StreamFlag;
 import org.junit.Test;
 
 public class AutoLFInputStreamTest {
@@ -25,47 +27,65 @@
 	@Test
 	public void testLF() throws IOException {
 		final byte[] bytes = asBytes("1\n2\n3");
-		test(bytes, bytes, false);
+		test(bytes, bytes);
 	}
 
 	@Test
 	public void testCR() throws IOException {
 		final byte[] bytes = asBytes("1\r2\r3");
-		test(bytes, bytes, false);
+		test(bytes, bytes);
 	}
 
 	@Test
 	public void testCRLF() throws IOException {
-		test(asBytes("1\r\n2\r\n3"), asBytes("1\n2\n3"), false);
+		test(asBytes("1\r\n2\r\n3"), asBytes("1\n2\n3"));
 	}
 
 	@Test
 	public void testLFCR() throws IOException {
 		final byte[] bytes = asBytes("1\n\r2\n\r3");
-		test(bytes, bytes, false);
+		test(bytes, bytes);
 	}
 
 	@Test
 	public void testEmpty() throws IOException {
 		final byte[] bytes = asBytes("");
-		test(bytes, bytes, false);
+		test(bytes, bytes);
 	}
 
 	@Test
 	public void testBinaryDetect() throws IOException {
 		final byte[] bytes = asBytes("1\r\n2\r\n3\0");
-		test(bytes, bytes, true);
+		test(bytes, bytes, StreamFlag.DETECT_BINARY);
 	}
 
 	@Test
 	public void testBinaryDontDetect() throws IOException {
-		test(asBytes("1\r\n2\r\n3\0"), asBytes("1\n2\n3\0"), false);
+		test(asBytes("1\r\n2\r\n3\0"), asBytes("1\n2\n3\0"));
+	}
+
+	@Test
+	public void testCrLf() throws IOException {
+		byte[] bytes = asBytes("1\r\n2\n3\r\n\r");
+		test(bytes, bytes, in -> AutoLFInputStream.create(in,
+				StreamFlag.DETECT_BINARY, StreamFlag.FOR_CHECKOUT));
+	}
+
+	@Test
+	public void testCrLfDontDetect() throws IOException {
+		test(asBytes("1\r\n2\r\n"), asBytes("1\n2\n"),
+				in -> AutoLFInputStream.create(in, StreamFlag.DETECT_BINARY));
+	}
+
+	private static void test(byte[] input, byte[] expected, StreamFlag... flags)
+			throws IOException {
+		test(input, expected, in -> AutoLFInputStream.create(in, flags));
 	}
 
 	private static void test(byte[] input, byte[] expected,
-			boolean detectBinary) throws IOException {
+			Function<InputStream, InputStream> factory) throws IOException {
 		try (InputStream bis1 = new ByteArrayInputStream(input);
-				InputStream cis1 = new AutoLFInputStream(bis1, detectBinary)) {
+				InputStream cis1 = factory.apply(bis1)) {
 			int index1 = 0;
 			for (int b = cis1.read(); b != -1; b = cis1.read()) {
 				assertEquals(expected[index1], (byte) b);
@@ -77,8 +97,7 @@
 			for (int bufferSize = 1; bufferSize < 10; bufferSize++) {
 				final byte[] buffer = new byte[bufferSize];
 				try (InputStream bis2 = new ByteArrayInputStream(input);
-						InputStream cis2 = new AutoLFInputStream(bis2,
-								detectBinary)) {
+						InputStream cis2 = factory.apply(bis2)) {
 
 					int read = 0;
 					for (int readNow = cis2.read(buffer, 0,
diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/util/io/AutoLFOutputStreamTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/util/io/AutoLFOutputStreamTest.java
new file mode 100644
index 0000000..1b7e55e
--- /dev/null
+++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/util/io/AutoLFOutputStreamTest.java
@@ -0,0 +1,84 @@
+/*
+ * Copyright (C) 2020, Thomas Wolf <thomas.wolf@paranor.ch> and others
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Distribution License v. 1.0 which is available at
+ * https://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+package org.eclipse.jgit.util.io;
+
+import static java.nio.charset.StandardCharsets.UTF_8;
+import static org.junit.Assert.assertArrayEquals;
+
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.OutputStream;
+
+import org.junit.Test;
+
+public class AutoLFOutputStreamTest {
+
+	@Test
+	public void testLF() throws IOException {
+		final byte[] bytes = asBytes("1\n2\n3");
+		test(bytes, bytes, false);
+	}
+
+	@Test
+	public void testCR() throws IOException {
+		final byte[] bytes = asBytes("1\r2\r3");
+		test(bytes, bytes, false);
+	}
+
+	@Test
+	public void testCRLFNoDetect() throws IOException {
+		test(asBytes("1\r\n2\r\n3"), asBytes("1\n2\n3"), false);
+	}
+
+	@Test
+	public void testLFCR() throws IOException {
+		final byte[] bytes = asBytes("1\n\r2\n\r3");
+		test(bytes, bytes, false);
+	}
+
+	@Test
+	public void testEmpty() throws IOException {
+		final byte[] bytes = asBytes("");
+		test(bytes, bytes, false);
+	}
+
+	@Test
+	public void testBinaryDetect() throws IOException {
+		final byte[] bytes = asBytes("1\r\n2\r\n3\0");
+		test(bytes, bytes, true);
+	}
+
+	@Test
+	public void testBinaryDontDetect() throws IOException {
+		test(asBytes("1\r\n2\r\n3\0"), asBytes("1\n2\n3\0"), false);
+	}
+
+	@Test
+	public void testCrLfDetect() throws IOException {
+		byte[] bytes = asBytes("1\r\n2\n3\r\n\r");
+		test(bytes, bytes, true);
+	}
+
+	private static void test(byte[] input, byte[] expected,
+			boolean detectBinary) throws IOException {
+		try (ByteArrayOutputStream result = new ByteArrayOutputStream();
+				OutputStream out = new AutoLFOutputStream(result,
+						detectBinary)) {
+			out.write(input);
+			out.close();
+			assertArrayEquals(expected, result.toByteArray());
+		}
+	}
+
+	private static byte[] asBytes(String in) {
+		return in.getBytes(UTF_8);
+	}
+}
diff --git a/org.eclipse.jgit.ui/META-INF/MANIFEST.MF b/org.eclipse.jgit.ui/META-INF/MANIFEST.MF
index 6e5c68b..d9b263f 100644
--- a/org.eclipse.jgit.ui/META-INF/MANIFEST.MF
+++ b/org.eclipse.jgit.ui/META-INF/MANIFEST.MF
@@ -4,14 +4,14 @@
 Bundle-Name: %Bundle-Name
 Automatic-Module-Name: org.eclipse.jgit.ui
 Bundle-SymbolicName: org.eclipse.jgit.ui
-Bundle-Version: 5.8.2.qualifier
+Bundle-Version: 5.9.1.qualifier
 Bundle-Vendor: %Bundle-Vendor
 Bundle-RequiredExecutionEnvironment: JavaSE-1.8
-Export-Package: org.eclipse.jgit.awtui;version="5.8.2"
-Import-Package: org.eclipse.jgit.errors;version="[5.8.2,5.9.0)",
- org.eclipse.jgit.lib;version="[5.8.2,5.9.0)",
- org.eclipse.jgit.nls;version="[5.8.2,5.9.0)",
- org.eclipse.jgit.revplot;version="[5.8.2,5.9.0)",
- org.eclipse.jgit.revwalk;version="[5.8.2,5.9.0)",
- org.eclipse.jgit.transport;version="[5.8.2,5.9.0)",
- org.eclipse.jgit.util;version="[5.8.2,5.9.0)"
+Export-Package: org.eclipse.jgit.awtui;version="5.9.1"
+Import-Package: org.eclipse.jgit.errors;version="[5.9.1,5.10.0)",
+ org.eclipse.jgit.lib;version="[5.9.1,5.10.0)",
+ org.eclipse.jgit.nls;version="[5.9.1,5.10.0)",
+ org.eclipse.jgit.revplot;version="[5.9.1,5.10.0)",
+ org.eclipse.jgit.revwalk;version="[5.9.1,5.10.0)",
+ org.eclipse.jgit.transport;version="[5.9.1,5.10.0)",
+ org.eclipse.jgit.util;version="[5.9.1,5.10.0)"
diff --git a/org.eclipse.jgit.ui/META-INF/SOURCE-MANIFEST.MF b/org.eclipse.jgit.ui/META-INF/SOURCE-MANIFEST.MF
index c4b022c..52de826 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.8.2.qualifier
-Eclipse-SourceBundle: org.eclipse.jgit.ui;version="5.8.2.qualifier";roots="."
+Bundle-Version: 5.9.1.qualifier
+Eclipse-SourceBundle: org.eclipse.jgit.ui;version="5.9.1.qualifier";roots="."
diff --git a/org.eclipse.jgit.ui/pom.xml b/org.eclipse.jgit.ui/pom.xml
index 3f3f40a..3c5c137 100644
--- a/org.eclipse.jgit.ui/pom.xml
+++ b/org.eclipse.jgit.ui/pom.xml
@@ -19,7 +19,7 @@
   <parent>
     <groupId>org.eclipse.jgit</groupId>
     <artifactId>org.eclipse.jgit-parent</artifactId>
-    <version>5.8.2-SNAPSHOT</version>
+    <version>5.9.1-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
deleted file mode 100644
index e2565bd..0000000
--- a/org.eclipse.jgit/.settings/.api_filters
+++ /dev/null
@@ -1,73 +0,0 @@
-<?xml version="1.0" encoding="UTF-8" standalone="no"?>
-<component id="org.eclipse.jgit" version="2">
-    <resource path="META-INF/MANIFEST.MF" type="org.eclipse.jgit.transport.CredentialsProviderUserInfo">
-        <filter id="305324134">
-            <message_arguments>
-                <message_argument value="org.eclipse.jgit.transport.CredentialsProviderUserInfo"/>
-                <message_argument value="org.eclipse.jgit_5.8.0"/>
-            </message_arguments>
-        </filter>
-    </resource>
-    <resource path="META-INF/MANIFEST.MF" type="org.eclipse.jgit.transport.DefaultSshSessionFactory">
-        <filter id="305324134">
-            <message_arguments>
-                <message_argument value="org.eclipse.jgit.transport.DefaultSshSessionFactory"/>
-                <message_argument value="org.eclipse.jgit_5.8.0"/>
-            </message_arguments>
-        </filter>
-    </resource>
-    <resource path="META-INF/MANIFEST.MF" type="org.eclipse.jgit.transport.JschConfigSessionFactory">
-        <filter id="305324134">
-            <message_arguments>
-                <message_argument value="org.eclipse.jgit.transport.JschConfigSessionFactory"/>
-                <message_argument value="org.eclipse.jgit_5.8.0"/>
-            </message_arguments>
-        </filter>
-    </resource>
-    <resource path="META-INF/MANIFEST.MF" type="org.eclipse.jgit.transport.JschSession">
-        <filter id="305324134">
-            <message_arguments>
-                <message_argument value="org.eclipse.jgit.transport.JschSession"/>
-                <message_argument value="org.eclipse.jgit_5.8.0"/>
-            </message_arguments>
-        </filter>
-    </resource>
-    <resource path="META-INF/MANIFEST.MF" type="org.eclipse.jgit.transport.OpenSshConfig">
-        <filter id="305324134">
-            <message_arguments>
-                <message_argument value="org.eclipse.jgit.transport.OpenSshConfig"/>
-                <message_argument value="org.eclipse.jgit_5.8.0"/>
-            </message_arguments>
-        </filter>
-    </resource>
-    <resource path="src/org/eclipse/jgit/lib/BitmapIndex.java" type="org.eclipse.jgit.lib.BitmapIndex$Bitmap">
-        <filter id="403804204">
-            <message_arguments>
-                <message_argument value="org.eclipse.jgit.lib.BitmapIndex.Bitmap"/>
-                <message_argument value="retrieveCompressed()"/>
-            </message_arguments>
-        </filter>
-    </resource>
-    <resource path="src/org/eclipse/jgit/transport/SshSessionFactory.java" type="org.eclipse.jgit.transport.SshSessionFactory">
-        <filter id="336695337">
-            <message_arguments>
-                <message_argument value="org.eclipse.jgit.transport.SshSessionFactory"/>
-                <message_argument value="getType()"/>
-            </message_arguments>
-        </filter>
-    </resource>
-    <resource path="src/org/eclipse/jgit/transport/http/HttpConnection.java" type="org.eclipse.jgit.transport.http.HttpConnection">
-        <filter id="403767336">
-            <message_arguments>
-                <message_argument value="org.eclipse.jgit.transport.http.HttpConnection"/>
-                <message_argument value="HTTP_11_MOVED_PERM"/>
-            </message_arguments>
-        </filter>
-        <filter id="403767336">
-            <message_arguments>
-                <message_argument value="org.eclipse.jgit.transport.http.HttpConnection"/>
-                <message_argument value="HTTP_NOT_AUTHORITATIVE"/>
-            </message_arguments>
-        </filter>
-    </resource>
-</component>
diff --git a/org.eclipse.jgit/BUILD b/org.eclipse.jgit/BUILD
index f797097..04873b0 100644
--- a/org.eclipse.jgit/BUILD
+++ b/org.eclipse.jgit/BUILD
@@ -14,7 +14,7 @@
 RESOURCES = glob(["resources/**"])
 
 java_library(
-    name = "jgit",
+    name = "jgit_non_stamped",
     srcs = SRCS,
     resource_strip_prefix = "org.eclipse.jgit/resources",
     resources = RESOURCES,
@@ -25,6 +25,27 @@
     ],
 )
 
+genrule(
+    name = "jgit",
+    srcs = [":jgit_non_stamped"],
+    outs = ["jgit.jar"],
+    cmd = " && ".join([
+        "ROOT=$$PWD",
+        "TMP=$$(mktemp -d || mktemp -d -t bazel-tmp)",
+        "TZ=UTC",
+        "export TZ",
+        "GEN_VERSION=$$(cat bazel-out/stable-status.txt | grep -w STABLE_BUILD_JGIT_LABEL | cut -d ' ' -f 2)",
+        "cd $$TMP",
+        "unzip -q $$ROOT/$<",
+        "echo \"Implementation-Version: $$GEN_VERSION\n$$(cat META-INF/MANIFEST.MF)\" > META-INF/MANIFEST.MF",
+        "find . -exec touch -t 198001010000 '{}' ';'",
+        "zip -Xqr $$ROOT/$@ .",
+        "rm -rf $$TMP",
+    ]),
+    stamp = 1,
+    visibility = ["//visibility:public"],
+)
+
 java_library(
     name = "insecure_cipher_factory",
     srcs = INSECURE_CIPHER_FACTORY,
diff --git a/org.eclipse.jgit/META-INF/MANIFEST.MF b/org.eclipse.jgit/META-INF/MANIFEST.MF
index e83d320..1348bde 100644
--- a/org.eclipse.jgit/META-INF/MANIFEST.MF
+++ b/org.eclipse.jgit/META-INF/MANIFEST.MF
@@ -3,12 +3,12 @@
 Bundle-Name: %Bundle-Name
 Automatic-Module-Name: org.eclipse.jgit
 Bundle-SymbolicName: org.eclipse.jgit
-Bundle-Version: 5.8.2.qualifier
+Bundle-Version: 5.9.1.qualifier
 Bundle-Localization: plugin
 Bundle-Vendor: %Bundle-Vendor
 Eclipse-ExtensibleAPI: true
-Export-Package: org.eclipse.jgit.annotations;version="5.8.2",
- org.eclipse.jgit.api;version="5.8.2";
+Export-Package: org.eclipse.jgit.annotations;version="5.9.1",
+ org.eclipse.jgit.api;version="5.9.1";
   uses:="org.eclipse.jgit.transport,
    org.eclipse.jgit.notes,
    org.eclipse.jgit.dircache,
@@ -23,18 +23,18 @@
    org.eclipse.jgit.revwalk.filter,
    org.eclipse.jgit.blame,
    org.eclipse.jgit.merge",
- org.eclipse.jgit.api.errors;version="5.8.2";
+ org.eclipse.jgit.api.errors;version="5.9.1";
   uses:="org.eclipse.jgit.lib,
    org.eclipse.jgit.errors",
- org.eclipse.jgit.attributes;version="5.8.2";
+ org.eclipse.jgit.attributes;version="5.9.1";
   uses:="org.eclipse.jgit.lib,
    org.eclipse.jgit.treewalk",
- org.eclipse.jgit.blame;version="5.8.2";
+ org.eclipse.jgit.blame;version="5.9.1";
   uses:="org.eclipse.jgit.lib,
    org.eclipse.jgit.revwalk,
    org.eclipse.jgit.treewalk.filter,
    org.eclipse.jgit.diff",
- org.eclipse.jgit.diff;version="5.8.2";
+ org.eclipse.jgit.diff;version="5.9.1";
   uses:="org.eclipse.jgit.lib,
    org.eclipse.jgit.attributes,
    org.eclipse.jgit.revwalk,
@@ -42,47 +42,47 @@
    org.eclipse.jgit.treewalk.filter,
    org.eclipse.jgit.treewalk,
    org.eclipse.jgit.util",
- org.eclipse.jgit.dircache;version="5.8.2";
+ org.eclipse.jgit.dircache;version="5.9.1";
   uses:="org.eclipse.jgit.events,
    org.eclipse.jgit.lib,
    org.eclipse.jgit.attributes,
    org.eclipse.jgit.treewalk,
    org.eclipse.jgit.util",
- org.eclipse.jgit.errors;version="5.8.2";
+ org.eclipse.jgit.errors;version="5.9.1";
   uses:="org.eclipse.jgit.transport,
    org.eclipse.jgit.dircache,
    org.eclipse.jgit.lib,
    org.eclipse.jgit.internal.storage.pack",
- org.eclipse.jgit.events;version="5.8.2";
+ org.eclipse.jgit.events;version="5.9.1";
   uses:="org.eclipse.jgit.lib",
- org.eclipse.jgit.fnmatch;version="5.8.2",
- org.eclipse.jgit.gitrepo;version="5.8.2";
+ org.eclipse.jgit.fnmatch;version="5.9.1",
+ org.eclipse.jgit.gitrepo;version="5.9.1";
   uses:="org.xml.sax.helpers,
    org.eclipse.jgit.api,
    org.eclipse.jgit.lib,
    org.eclipse.jgit.revwalk,
    org.xml.sax",
- org.eclipse.jgit.gitrepo.internal;version="5.8.2";x-internal:=true,
- org.eclipse.jgit.hooks;version="5.8.2";uses:="org.eclipse.jgit.lib",
- org.eclipse.jgit.ignore;version="5.8.2",
- org.eclipse.jgit.ignore.internal;version="5.8.2";
+ org.eclipse.jgit.gitrepo.internal;version="5.9.1";x-internal:=true,
+ org.eclipse.jgit.hooks;version="5.9.1";uses:="org.eclipse.jgit.lib",
+ org.eclipse.jgit.ignore;version="5.9.1",
+ org.eclipse.jgit.ignore.internal;version="5.9.1";
   x-friends:="org.eclipse.jgit.test",
- org.eclipse.jgit.internal;version="5.8.2";
+ org.eclipse.jgit.internal;version="5.9.1";
   x-friends:="org.eclipse.jgit.test,
    org.eclipse.jgit.http.test",
- org.eclipse.jgit.internal.fsck;version="5.8.2";
+ org.eclipse.jgit.internal.fsck;version="5.9.1";
   x-friends:="org.eclipse.jgit.test",
- org.eclipse.jgit.internal.ketch;version="5.8.2";
+ org.eclipse.jgit.internal.ketch;version="5.9.1";
   x-friends:="org.eclipse.jgit.junit,
    org.eclipse.jgit.test,
    org.eclipse.jgit.pgm",
- org.eclipse.jgit.internal.revwalk;version="5.8.2";x-internal:=true,
- org.eclipse.jgit.internal.storage.dfs;version="5.8.2";
+ org.eclipse.jgit.internal.revwalk;version="5.9.1";x-internal:=true,
+ org.eclipse.jgit.internal.storage.dfs;version="5.9.1";
   x-friends:="org.eclipse.jgit.test,
    org.eclipse.jgit.http.server,
    org.eclipse.jgit.http.test,
    org.eclipse.jgit.lfs.test",
- org.eclipse.jgit.internal.storage.file;version="5.8.2";
+ org.eclipse.jgit.internal.storage.file;version="5.9.1";
   x-friends:="org.eclipse.jgit.test,
    org.eclipse.jgit.junit,
    org.eclipse.jgit.junit.http,
@@ -91,35 +91,35 @@
    org.eclipse.jgit.pgm,
    org.eclipse.jgit.pgm.test,
    org.eclipse.jgit.ssh.apache",
- org.eclipse.jgit.internal.storage.io;version="5.8.2";
+ org.eclipse.jgit.internal.storage.io;version="5.9.1";
   x-friends:="org.eclipse.jgit.junit,
    org.eclipse.jgit.test,
    org.eclipse.jgit.pgm",
- org.eclipse.jgit.internal.storage.pack;version="5.8.2";
+ org.eclipse.jgit.internal.storage.pack;version="5.9.1";
   x-friends:="org.eclipse.jgit.junit,
    org.eclipse.jgit.test,
    org.eclipse.jgit.pgm",
- org.eclipse.jgit.internal.storage.reftable;version="5.8.2";
+ org.eclipse.jgit.internal.storage.reftable;version="5.9.1";
   x-friends:="org.eclipse.jgit.http.test,
    org.eclipse.jgit.junit,
    org.eclipse.jgit.test,
    org.eclipse.jgit.pgm",
- org.eclipse.jgit.internal.storage.reftree;version="5.8.2";
+ org.eclipse.jgit.internal.storage.reftree;version="5.9.1";
   x-friends:="org.eclipse.jgit.junit,
    org.eclipse.jgit.test,
    org.eclipse.jgit.pgm",
- org.eclipse.jgit.internal.submodule;version="5.8.2";x-internal:=true,
- org.eclipse.jgit.internal.transport.connectivity;version="5.8.2";
+ org.eclipse.jgit.internal.submodule;version="5.9.1";x-internal:=true,
+ org.eclipse.jgit.internal.transport.connectivity;version="5.9.1";
   x-friends:="org.eclipse.jgit.test",
- org.eclipse.jgit.internal.transport.http;version="5.8.2";
+ org.eclipse.jgit.internal.transport.http;version="5.9.1";
   x-friends:="org.eclipse.jgit.test",
- org.eclipse.jgit.internal.transport.parser;version="5.8.2";
+ org.eclipse.jgit.internal.transport.parser;version="5.9.1";
   x-friends:="org.eclipse.jgit.http.server,
    org.eclipse.jgit.test",
- org.eclipse.jgit.internal.transport.ssh;version="5.8.2";
+ org.eclipse.jgit.internal.transport.ssh;version="5.9.1";
   x-friends:="org.eclipse.jgit.ssh.apache,
    org.eclipse.jgit.ssh.jsch",
- org.eclipse.jgit.lib;version="5.8.2";
+ org.eclipse.jgit.lib;version="5.9.1";
   uses:="org.eclipse.jgit.transport,
    org.eclipse.jgit.util.sha1,
    org.eclipse.jgit.dircache,
@@ -133,9 +133,9 @@
    org.eclipse.jgit.util,
    org.eclipse.jgit.submodule,
    org.eclipse.jgit.util.time",
- org.eclipse.jgit.lib.internal;version="5.8.2";
+ org.eclipse.jgit.lib.internal;version="5.9.1";
   x-friends:="org.eclipse.jgit.test",
- org.eclipse.jgit.merge;version="5.8.2";
+ org.eclipse.jgit.merge;version="5.9.1";
   uses:="org.eclipse.jgit.dircache,
    org.eclipse.jgit.lib,
    org.eclipse.jgit.revwalk,
@@ -144,40 +144,40 @@
    org.eclipse.jgit.util,
    org.eclipse.jgit.api,
    org.eclipse.jgit.attributes",
- org.eclipse.jgit.nls;version="5.8.2",
- org.eclipse.jgit.notes;version="5.8.2";
+ org.eclipse.jgit.nls;version="5.9.1",
+ org.eclipse.jgit.notes;version="5.9.1";
   uses:="org.eclipse.jgit.lib,
    org.eclipse.jgit.revwalk,
    org.eclipse.jgit.treewalk,
    org.eclipse.jgit.merge",
- org.eclipse.jgit.patch;version="5.8.2";
+ org.eclipse.jgit.patch;version="5.9.1";
   uses:="org.eclipse.jgit.lib,
    org.eclipse.jgit.diff",
- org.eclipse.jgit.revplot;version="5.8.2";
+ org.eclipse.jgit.revplot;version="5.9.1";
   uses:="org.eclipse.jgit.lib,
    org.eclipse.jgit.revwalk",
- org.eclipse.jgit.revwalk;version="5.8.2";
+ org.eclipse.jgit.revwalk;version="5.9.1";
   uses:="org.eclipse.jgit.lib,
    org.eclipse.jgit.diff,
    org.eclipse.jgit.treewalk.filter,
    org.eclipse.jgit.revwalk.filter,
    org.eclipse.jgit.treewalk",
- org.eclipse.jgit.revwalk.filter;version="5.8.2";
+ org.eclipse.jgit.revwalk.filter;version="5.9.1";
   uses:="org.eclipse.jgit.revwalk,
    org.eclipse.jgit.lib,
    org.eclipse.jgit.util",
- org.eclipse.jgit.storage.file;version="5.8.2";
+ org.eclipse.jgit.storage.file;version="5.9.1";
   uses:="org.eclipse.jgit.lib,
    org.eclipse.jgit.util",
- org.eclipse.jgit.storage.pack;version="5.8.2";
+ org.eclipse.jgit.storage.pack;version="5.9.1";
   uses:="org.eclipse.jgit.lib",
- org.eclipse.jgit.submodule;version="5.8.2";
+ org.eclipse.jgit.submodule;version="5.9.1";
   uses:="org.eclipse.jgit.lib,
    org.eclipse.jgit.diff,
    org.eclipse.jgit.treewalk.filter,
    org.eclipse.jgit.treewalk,
    org.eclipse.jgit.util",
- org.eclipse.jgit.transport;version="5.8.2";
+ org.eclipse.jgit.transport;version="5.9.1";
   uses:="javax.crypto,
    org.eclipse.jgit.util.io,
    org.eclipse.jgit.lib,
@@ -190,21 +190,21 @@
    org.eclipse.jgit.transport.resolver,
    org.eclipse.jgit.storage.pack,
    org.eclipse.jgit.errors",
- org.eclipse.jgit.transport.http;version="5.8.2";
+ org.eclipse.jgit.transport.http;version="5.9.1";
   uses:="javax.net.ssl",
- org.eclipse.jgit.transport.resolver;version="5.8.2";
+ org.eclipse.jgit.transport.resolver;version="5.9.1";
   uses:="org.eclipse.jgit.transport,
    org.eclipse.jgit.lib",
- org.eclipse.jgit.treewalk;version="5.8.2";
+ org.eclipse.jgit.treewalk;version="5.9.1";
   uses:="org.eclipse.jgit.dircache,
    org.eclipse.jgit.lib,
    org.eclipse.jgit.attributes,
    org.eclipse.jgit.revwalk,
    org.eclipse.jgit.treewalk.filter,
    org.eclipse.jgit.util",
- org.eclipse.jgit.treewalk.filter;version="5.8.2";
+ org.eclipse.jgit.treewalk.filter;version="5.9.1";
   uses:="org.eclipse.jgit.treewalk",
- org.eclipse.jgit.util;version="5.8.2";
+ org.eclipse.jgit.util;version="5.9.1";
   uses:="org.eclipse.jgit.transport,
    org.eclipse.jgit.hooks,
    org.eclipse.jgit.revwalk,
@@ -217,12 +217,12 @@
    org.eclipse.jgit.treewalk,
    javax.net.ssl,
    org.eclipse.jgit.util.time",
- org.eclipse.jgit.util.io;version="5.8.2";
+ org.eclipse.jgit.util.io;version="5.9.1";
   uses:="org.eclipse.jgit.attributes,
    org.eclipse.jgit.lib,
    org.eclipse.jgit.treewalk",
- org.eclipse.jgit.util.sha1;version="5.8.2",
- org.eclipse.jgit.util.time;version="5.8.2"
+ org.eclipse.jgit.util.sha1;version="5.9.1",
+ org.eclipse.jgit.util.time;version="5.9.1"
 Bundle-RequiredExecutionEnvironment: JavaSE-1.8
 Import-Package: com.googlecode.javaewah;version="[1.1.6,2.0.0)",
  javax.crypto,
diff --git a/org.eclipse.jgit/META-INF/SOURCE-MANIFEST.MF b/org.eclipse.jgit/META-INF/SOURCE-MANIFEST.MF
index 9202c87..c561b7e 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.8.2.qualifier
-Eclipse-SourceBundle: org.eclipse.jgit;version="5.8.2.qualifier";roots="."
+Bundle-Version: 5.9.1.qualifier
+Eclipse-SourceBundle: org.eclipse.jgit;version="5.9.1.qualifier";roots="."
diff --git a/org.eclipse.jgit/pom.xml b/org.eclipse.jgit/pom.xml
index baa74cb..c899dfd 100644
--- a/org.eclipse.jgit/pom.xml
+++ b/org.eclipse.jgit/pom.xml
@@ -20,7 +20,7 @@
   <parent>
     <groupId>org.eclipse.jgit</groupId>
     <artifactId>org.eclipse.jgit-parent</artifactId>
-    <version>5.8.2-SNAPSHOT</version>
+    <version>5.9.1-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 c88b08d..2f3520d 100644
--- a/org.eclipse.jgit/resources/org/eclipse/jgit/internal/JGitText.properties
+++ b/org.eclipse.jgit/resources/org/eclipse/jgit/internal/JGitText.properties
@@ -202,10 +202,8 @@
 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
@@ -225,6 +223,8 @@
 dirCacheFileIsNotLocked=DirCache {0} not locked
 dirCacheIsNotLocked=DirCache is not locked
 DIRCChecksumMismatch=DIRC checksum mismatch
+DIRCCorruptLength=DIRC variable int {0} invalid after entry for {1}
+DIRCCorruptLengthFirst=DIRC variable int {0} invalid in first entry
 DIRCExtensionIsTooLargeAt=DIRC extension {0} is too large at {1} bytes.
 DIRCExtensionNotSupportedByThisVersion=DIRC extension {0} not supported by this version.
 DIRCHasTooManyEntries=DIRC has too many entries.
@@ -412,6 +412,11 @@
 lockOnNotHeld=Lock on {0} not held.
 lockStreamClosed=Output to lock on {0} already closed
 lockStreamMultiple=Output to lock on {0} already opened
+logInconsistentFiletimeDiff={}: inconsistent duration from file timestamps on {}, {}: {} > {}, but diff = {}. Aborting measurement at resolution {}.
+logLargerFiletimeDiff={}: inconsistent duration from file timestamps on {}, {}: diff = {} > {} (last good value). Aborting measurement.
+logSmallerFiletime={}: got smaller file timestamp on {}, {}: {} < {}. Aborting measurement at resolution {}.
+logXDGConfigHomeInvalid=Environment variable XDG_CONFIG_HOME contains an invalid path {}
+looseObjectHandleIsStale=loose-object {0} file handle is stale. retry {1} of {2}
 maxCountMustBeNonNegative=max count must be >= 0
 mergeConflictOnNonNoteEntries=Merge conflict on non-note entries: base = {0}, ours = {1}, theirs = {2}
 mergeConflictOnNotes=Merge conflict on note {0}. base = {1}, ours = {2}, theirs = {2}
@@ -625,6 +630,7 @@
 sourceRefNotSpecifiedForRefspec=Source ref not specified for refspec: {0}
 squashCommitNotUpdatingHEAD=Squash commit -- not updating HEAD
 sshCommandFailed=Execution of ssh command ''{0}'' failed with error ''{1}''
+sshCommandTimeout=Execution of ssh command ''{0}'' timed out after {1} seconds
 sslFailureExceptionMessage=Secure connection to {0} could not be established because of SSL problems
 sslFailureInfo=A secure connection to {0} could not be established because the server''s certificate could not be validated.
 sslFailureCause=SSL reported: {0}
@@ -665,7 +671,7 @@
 timeIsUncertain=Time is uncertain
 timerAlreadyTerminated=Timer already terminated
 timeoutMeasureFsTimestampResolution=measuring filesystem timestamp resolution for ''{0}'' timed out, fall back to resolution of 2 seconds
-tooManyCommands=Too many commands
+tooManyCommands=Commands size exceeds limit defined in receive.maxCommandBytes
 tooManyFilters=Too many "filter" lines in request
 tooManyIncludeRecursions=Too many recursions; circular includes in config file(s)?
 topologicalSortRequired=Topological sort required.
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/diff/ContentSource.java b/org.eclipse.jgit/src/org/eclipse/jgit/diff/ContentSource.java
index 7ae005a..1a41df3 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/diff/ContentSource.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/diff/ContentSource.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2010, Google Inc. and others
+ * Copyright (C) 2010, 2020 Google Inc. and others
  *
  * This program and the accompanying materials are made available under the
  * terms of the Eclipse Distribution License v. 1.0 which is available at
@@ -123,7 +123,8 @@
 		WorkingTreeIterator ptr;
 
 		WorkingTreeSource(WorkingTreeIterator iterator) {
-			this.tw = new TreeWalk((ObjectReader) null);
+			this.tw = new TreeWalk(iterator.getRepository(),
+					(ObjectReader) null);
 			this.tw.setRecursive(true);
 			this.iterator = iterator;
 		}
@@ -173,6 +174,15 @@
 		private void seek(String path) throws IOException {
 			if (!path.equals(current)) {
 				iterator.reset();
+				// Possibly this iterator had an associated DirCacheIterator,
+				// but we have no access to it and thus don't know about it.
+				// We have to reset this iterator here to work without
+				// DirCacheIterator and to descend always into ignored
+				// directories. Otherwise we might not find tracked files below
+				// ignored folders. Since we're looking only for a single
+				// specific path this is not a performance problem.
+				iterator.setWalkIgnoredDirectories(true);
+				iterator.setDirCacheIterator(null, -1);
 				tw.reset();
 				tw.addTree(iterator);
 				tw.setFilter(PathFilter.create(path));
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/diff/DiffFormatter.java b/org.eclipse.jgit/src/org/eclipse/jgit/diff/DiffFormatter.java
index 81367ea..ec21954 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/diff/DiffFormatter.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/diff/DiffFormatter.java
@@ -1,6 +1,6 @@
 /*
  * Copyright (C) 2009, Google Inc.
- * Copyright (C) 2008-2009, Johannes E. Schindelin <johannes.schindelin@gmx.de> and others
+ * Copyright (C) 2008-2020, Johannes E. Schindelin <johannes.schindelin@gmx.de> and others
  *
  * This program and the accompanying materials are made available under the
  * terms of the Eclipse Distribution License v. 1.0 which is available at
@@ -502,9 +502,18 @@
 			throws IOException {
 		assertHaveReader();
 
-		TreeWalk walk = new TreeWalk(reader);
-		walk.addTree(a);
-		walk.addTree(b);
+		TreeWalk walk = new TreeWalk(repository, reader);
+		int aIndex = walk.addTree(a);
+		int bIndex = walk.addTree(b);
+		if (repository != null) {
+			if (a instanceof WorkingTreeIterator
+					&& b instanceof DirCacheIterator) {
+				((WorkingTreeIterator) a).setDirCacheIterator(walk, bIndex);
+			} else if (b instanceof WorkingTreeIterator
+					&& a instanceof DirCacheIterator) {
+				((WorkingTreeIterator) b).setDirCacheIterator(walk, aIndex);
+			}
+		}
 		walk.setRecursive(true);
 
 		TreeFilter filter = getDiffTreeFilterFor(a, b);
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/dircache/DirCache.java b/org.eclipse.jgit/src/org/eclipse/jgit/dircache/DirCache.java
index b2764d7..03da615 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/dircache/DirCache.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/dircache/DirCache.java
@@ -1,7 +1,7 @@
 /*
- * Copyright (C) 2008-2010, Google Inc.
+ * Copyright (C) 2008, 2010, Google Inc.
  * Copyright (C) 2008, Shawn O. Pearce <spearce@spearce.org>
- * Copyright (C) 2011, Matthias Sohn <matthias.sohn@sap.com> and others
+ * Copyright (C) 2011, 2020, Matthias Sohn <matthias.sohn@sap.com> and others
  *
  * This program and the accompanying materials are made available under the
  * terms of the Eclipse Distribution License v. 1.0 which is available at
@@ -41,6 +41,9 @@
 import org.eclipse.jgit.internal.storage.file.FileSnapshot;
 import org.eclipse.jgit.internal.storage.file.LockFile;
 import org.eclipse.jgit.lib.AnyObjectId;
+import org.eclipse.jgit.lib.Config;
+import org.eclipse.jgit.lib.Config.ConfigEnum;
+import org.eclipse.jgit.lib.ConfigConstants;
 import org.eclipse.jgit.lib.Constants;
 import org.eclipse.jgit.lib.ObjectId;
 import org.eclipse.jgit.lib.ObjectInserter;
@@ -321,6 +324,9 @@
 	/** Repository containing this index */
 	private Repository repository;
 
+	/** If we read this index from disk, the original format. */
+	private DirCacheVersion version;
+
 	/**
 	 * Create a new in-core index representation.
 	 * <p>
@@ -364,6 +370,10 @@
 		return new DirCacheEditor(this, entryCnt + 16);
 	}
 
+	DirCacheVersion getVersion() {
+		return version;
+	}
+
 	void replace(DirCacheEntry[] e, int cnt) {
 		sortedEntries = e;
 		entryCnt = cnt;
@@ -445,13 +455,26 @@
 		md.update(hdr, 0, 12);
 		if (!is_DIRC(hdr))
 			throw new CorruptObjectException(JGitText.get().notADIRCFile);
-		final int ver = NB.decodeInt32(hdr, 4);
+		int versionCode = NB.decodeInt32(hdr, 4);
+		DirCacheVersion ver = DirCacheVersion.fromInt(versionCode);
+		if (ver == null) {
+			throw new CorruptObjectException(
+					MessageFormat.format(JGitText.get().unknownDIRCVersion,
+							Integer.valueOf(versionCode)));
+		}
 		boolean extended = false;
-		if (ver == 3)
+		switch (ver) {
+		case DIRC_VERSION_MINIMUM:
+			break;
+		case DIRC_VERSION_EXTENDED:
+		case DIRC_VERSION_PATHCOMPRESS:
 			extended = true;
-		else if (ver != 2)
-			throw new CorruptObjectException(MessageFormat.format(
-					JGitText.get().unknownDIRCVersion, Integer.valueOf(ver)));
+			break;
+		default:
+			throw new CorruptObjectException(MessageFormat
+					.format(JGitText.get().unknownDIRCVersion, ver));
+		}
+		version = ver;
 		entryCnt = NB.decodeInt32(hdr, 8);
 		if (entryCnt < 0)
 			throw new CorruptObjectException(JGitText.get().DIRCHasTooManyEntries);
@@ -467,7 +490,8 @@
 
 		final MutableInteger infoAt = new MutableInteger();
 		for (int i = 0; i < entryCnt; i++) {
-			sortedEntries[i] = new DirCacheEntry(infos, infoAt, in, md, smudge);
+			sortedEntries[i] = new DirCacheEntry(infos, infoAt, in, md, smudge,
+					version, i == 0 ? null : sortedEntries[i - 1]);
 		}
 
 		// After the file entries are index extensions, and then a footer.
@@ -606,11 +630,20 @@
 		final MessageDigest foot = Constants.newMessageDigest();
 		final DigestOutputStream dos = new DigestOutputStream(os, foot);
 
-		boolean extended = false;
-		for (int i = 0; i < entryCnt; i++) {
-			if (sortedEntries[i].isExtended()) {
-				extended = true;
-				break;
+		if (version == null && this.repository != null) {
+			// A new DirCache is being written.
+			DirCacheConfig config = repository.getConfig()
+					.get(DirCacheConfig::new);
+			version = config.getIndexVersion();
+		}
+		if (version == null
+				|| version == DirCacheVersion.DIRC_VERSION_MINIMUM) {
+			version = DirCacheVersion.DIRC_VERSION_MINIMUM;
+			for (int i = 0; i < entryCnt; i++) {
+				if (sortedEntries[i].isExtended()) {
+					version = DirCacheVersion.DIRC_VERSION_EXTENDED;
+					break;
+				}
 			}
 		}
 
@@ -618,7 +651,7 @@
 		//
 		final byte[] tmp = new byte[128];
 		System.arraycopy(SIG_DIRC, 0, tmp, 0, SIG_DIRC.length);
-		NB.encodeInt32(tmp, 4, extended ? 3 : 2);
+		NB.encodeInt32(tmp, 4, version.getVersionCode());
 		NB.encodeInt32(tmp, 8, entryCnt);
 		dos.write(tmp, 0, 12);
 
@@ -650,7 +683,7 @@
 			if (e.mightBeRacilyClean(smudge)) {
 				e.smudgeRacilyClean();
 			}
-			e.write(dos);
+			e.write(dos, version, i == 0 ? null : sortedEntries[i - 1]);
 		}
 
 		if (writeTree) {
@@ -982,4 +1015,76 @@
 			}
 		}
 	}
+
+	enum DirCacheVersion implements ConfigEnum {
+
+		/** Minimum index version on-disk format that we support. */
+		DIRC_VERSION_MINIMUM(2),
+		/** Version 3 supports extended flags. */
+		DIRC_VERSION_EXTENDED(3),
+		/**
+		 * Version 4 adds very simple "path compression": it strips out the
+		 * common prefix between the last entry written and the current entry.
+		 * Instead of writing two entries with paths "foo/bar/baz/a.txt" and
+		 * "foo/bar/baz/b.txt" it only writes "b.txt" for the second entry.
+		 * <p>
+		 * It is also <em>not</em> padded.
+		 * </p>
+		 */
+		DIRC_VERSION_PATHCOMPRESS(4);
+
+		private final int version;
+
+		private DirCacheVersion(int versionCode) {
+			this.version = versionCode;
+		}
+
+		public int getVersionCode() {
+			return version;
+		}
+
+		@Override
+		public String toConfigValue() {
+			return Integer.toString(version);
+		}
+
+		@Override
+		public boolean matchConfigValue(String in) {
+			try {
+				return version == Integer.parseInt(in);
+			} catch (NumberFormatException e) {
+				return false;
+			}
+		}
+
+		public static DirCacheVersion fromInt(int val) {
+			for (DirCacheVersion v : DirCacheVersion.values()) {
+				if (val == v.getVersionCode()) {
+					return v;
+				}
+			}
+			return null;
+		}
+	}
+
+	private static class DirCacheConfig {
+
+		private final DirCacheVersion indexVersion;
+
+		public DirCacheConfig(Config cfg) {
+			boolean manyFiles = cfg.getBoolean(
+					ConfigConstants.CONFIG_FEATURE_SECTION,
+					ConfigConstants.CONFIG_KEY_MANYFILES, false);
+			indexVersion = cfg.getEnum(DirCacheVersion.values(),
+					ConfigConstants.CONFIG_INDEX_SECTION, null,
+					ConfigConstants.CONFIG_KEY_VERSION,
+					manyFiles ? DirCacheVersion.DIRC_VERSION_PATHCOMPRESS
+							: DirCacheVersion.DIRC_VERSION_EXTENDED);
+		}
+
+		public DirCacheVersion getIndexVersion() {
+			return indexVersion;
+		}
+
+	}
 }
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/dircache/DirCacheEntry.java b/org.eclipse.jgit/src/org/eclipse/jgit/dircache/DirCacheEntry.java
index ced379f..dcb8482 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/dircache/DirCacheEntry.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/dircache/DirCacheEntry.java
@@ -1,8 +1,8 @@
 /*
- * Copyright (C) 2008-2009, Google Inc.
+ * Copyright (C) 2008, 2009, Google Inc.
  * Copyright (C) 2008, Shawn O. Pearce <spearce@spearce.org>
  * Copyright (C) 2010, Matthias Sohn <matthias.sohn@sap.com>
- * Copyright (C) 2010, Christian Halstrick <christian.halstrick@sap.com> and others
+ * Copyright (C) 2010, 2020, Christian Halstrick <christian.halstrick@sap.com> and others
  *
  * This program and the accompanying materials are made available under the
  * terms of the Eclipse Distribution License v. 1.0 which is available at
@@ -26,6 +26,7 @@
 import java.time.Instant;
 import java.util.Arrays;
 
+import org.eclipse.jgit.dircache.DirCache.DirCacheVersion;
 import org.eclipse.jgit.errors.CorruptObjectException;
 import org.eclipse.jgit.internal.JGitText;
 import org.eclipse.jgit.lib.AnyObjectId;
@@ -112,15 +113,16 @@
 	/** Flags which are never stored to disk. */
 	private byte inCoreFlags;
 
-	DirCacheEntry(final byte[] sharedInfo, final MutableInteger infoAt,
-			final InputStream in, final MessageDigest md, final Instant smudge)
+	DirCacheEntry(byte[] sharedInfo, MutableInteger infoAt, InputStream in,
+			MessageDigest md, Instant smudge, DirCacheVersion version,
+			DirCacheEntry previous)
 			throws IOException {
 		info = sharedInfo;
 		infoOffset = infoAt.value;
 
 		IO.readFully(in, info, infoOffset, INFO_LEN);
 
-		final int len;
+		int len;
 		if (isExtended()) {
 			len = INFO_LEN_EXTENDED;
 			IO.readFully(in, info, infoOffset + INFO_LEN, INFO_LEN_EXTENDED - INFO_LEN);
@@ -134,31 +136,66 @@
 		infoAt.value += len;
 		md.update(info, infoOffset, len);
 
+		int toRemove = 0;
+		if (version == DirCacheVersion.DIRC_VERSION_PATHCOMPRESS) {
+			// Read variable int and update digest
+			int b = in.read();
+			md.update((byte) b);
+			toRemove = b & 0x7F;
+			while ((b & 0x80) != 0) {
+				toRemove++;
+				b = in.read();
+				md.update((byte) b);
+				toRemove = (toRemove << 7) | (b & 0x7F);
+			}
+			if (toRemove < 0
+					|| (previous != null && toRemove > previous.path.length)) {
+				if (previous == null) {
+					throw new IOException(MessageFormat.format(
+							JGitText.get().DIRCCorruptLengthFirst,
+							Integer.valueOf(toRemove)));
+				}
+				throw new IOException(MessageFormat.format(
+						JGitText.get().DIRCCorruptLength,
+						Integer.valueOf(toRemove), previous.getPathString()));
+			}
+		}
 		int pathLen = NB.decodeUInt16(info, infoOffset + P_FLAGS) & NAME_MASK;
 		int skipped = 0;
 		if (pathLen < NAME_MASK) {
 			path = new byte[pathLen];
-			IO.readFully(in, path, 0, pathLen);
-			md.update(path, 0, pathLen);
-		} else {
-			final ByteArrayOutputStream tmp = new ByteArrayOutputStream();
-			{
-				final byte[] buf = new byte[NAME_MASK];
-				IO.readFully(in, buf, 0, NAME_MASK);
-				tmp.write(buf);
+			if (version == DirCacheVersion.DIRC_VERSION_PATHCOMPRESS
+					&& previous != null) {
+				System.arraycopy(previous.path, 0, path, 0,
+						previous.path.length - toRemove);
+				IO.readFully(in, path, previous.path.length - toRemove,
+						pathLen - (previous.path.length - toRemove));
+				md.update(path, previous.path.length - toRemove,
+						pathLen - (previous.path.length - toRemove));
+				pathLen = pathLen - (previous.path.length - toRemove);
+			} else {
+				IO.readFully(in, path, 0, pathLen);
+				md.update(path, 0, pathLen);
 			}
-			for (;;) {
-				final int c = in.read();
-				if (c < 0)
-					throw new EOFException(JGitText.get().shortReadOfBlock);
-				if (c == 0)
-					break;
-				tmp.write(c);
-			}
+		} else if (version != DirCacheVersion.DIRC_VERSION_PATHCOMPRESS
+				|| previous == null || toRemove == previous.path.length) {
+			ByteArrayOutputStream tmp = new ByteArrayOutputStream();
+			byte[] buf = new byte[NAME_MASK];
+			IO.readFully(in, buf, 0, NAME_MASK);
+			tmp.write(buf);
+			readNulTerminatedString(in, tmp);
 			path = tmp.toByteArray();
 			pathLen = path.length;
-			skipped = 1; // we already skipped 1 '\0' above to break the loop.
 			md.update(path, 0, pathLen);
+			skipped = 1; // we already skipped 1 '\0' in readNulTerminatedString
+			md.update((byte) 0);
+		} else {
+			ByteArrayOutputStream tmp = new ByteArrayOutputStream();
+			tmp.write(previous.path, 0, previous.path.length - toRemove);
+			pathLen = readNulTerminatedString(in, tmp);
+			path = tmp.toByteArray();
+			md.update(path, previous.path.length - toRemove, pathLen);
+			skipped = 1; // we already skipped 1 '\0' in readNulTerminatedString
 			md.update((byte) 0);
 		}
 
@@ -172,17 +209,26 @@
 			throw p;
 		}
 
-		// Index records are padded out to the next 8 byte alignment
-		// for historical reasons related to how C Git read the files.
-		//
-		final int actLen = len + pathLen;
-		final int expLen = (actLen + 8) & ~7;
-		final int padLen = expLen - actLen - skipped;
-		if (padLen > 0) {
-			IO.skipFully(in, padLen);
-			md.update(nullpad, 0, padLen);
+		if (version == DirCacheVersion.DIRC_VERSION_PATHCOMPRESS) {
+			if (skipped == 0) {
+				int b = in.read();
+				if (b < 0) {
+					throw new EOFException(JGitText.get().shortReadOfBlock);
+				}
+				md.update((byte) b);
+			}
+		} else {
+			// Index records are padded out to the next 8 byte alignment
+			// for historical reasons related to how C Git read the files.
+			//
+			final int actLen = len + pathLen;
+			final int expLen = (actLen + 8) & ~7;
+			final int padLen = expLen - actLen - skipped;
+			if (padLen > 0) {
+				IO.skipFully(in, padLen);
+				md.update(nullpad, 0, padLen);
+			}
 		}
-
 		if (mightBeRacilyClean(smudge)) {
 			smudgeRacilyClean();
 		}
@@ -283,19 +329,61 @@
 		System.arraycopy(src.info, src.infoOffset, info, 0, INFO_LEN);
 	}
 
-	void write(OutputStream os) throws IOException {
-		final int len = isExtended() ? INFO_LEN_EXTENDED : INFO_LEN;
-		final int pathLen = path.length;
-		os.write(info, infoOffset, len);
-		os.write(path, 0, pathLen);
+	private int readNulTerminatedString(InputStream in, OutputStream out)
+			throws IOException {
+		int n = 0;
+		for (;;) {
+			int c = in.read();
+			if (c < 0) {
+				throw new EOFException(JGitText.get().shortReadOfBlock);
+			}
+			if (c == 0) {
+				break;
+			}
+			out.write(c);
+			n++;
+		}
+		return n;
+	}
 
-		// Index records are padded out to the next 8 byte alignment
-		// for historical reasons related to how C Git read the files.
-		//
-		final int actLen = len + pathLen;
-		final int expLen = (actLen + 8) & ~7;
-		if (actLen != expLen)
-			os.write(nullpad, 0, expLen - actLen);
+	void write(OutputStream os, DirCacheVersion version, DirCacheEntry previous)
+			throws IOException {
+		final int len = isExtended() ? INFO_LEN_EXTENDED : INFO_LEN;
+		if (version != DirCacheVersion.DIRC_VERSION_PATHCOMPRESS) {
+			os.write(info, infoOffset, len);
+			os.write(path, 0, path.length);
+			// Index records are padded out to the next 8 byte alignment
+			// for historical reasons related to how C Git read the files.
+			//
+			int entryLen = len + path.length;
+			int expLen = (entryLen + 8) & ~7;
+			if (entryLen != expLen)
+				os.write(nullpad, 0, expLen - entryLen);
+		} else {
+			int pathCommon = 0;
+			int toRemove;
+			if (previous != null) {
+				// Figure out common prefix
+				int pathLen = Math.min(path.length, previous.path.length);
+				while (pathCommon < pathLen
+						&& path[pathCommon] == previous.path[pathCommon]) {
+					pathCommon++;
+				}
+				toRemove = previous.path.length - pathCommon;
+			} else {
+				toRemove = 0;
+			}
+			byte[] tmp = new byte[16];
+			int n = tmp.length;
+			tmp[--n] = (byte) (toRemove & 0x7F);
+			while ((toRemove >>>= 7) != 0) {
+				tmp[--n] = (byte) (0x80 | (--toRemove & 0x7F));
+			}
+			os.write(info, infoOffset, len);
+			os.write(tmp, n, tmp.length - n);
+			os.write(path, pathCommon, path.length - pathCommon);
+			os.write(0);
+		}
 	}
 
 	/**
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 ef0d477..22200c2 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/internal/JGitText.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/internal/JGitText.java
@@ -230,10 +230,8 @@
 	/***/ 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;
@@ -253,6 +251,8 @@
 	/***/ public String dirCacheFileIsNotLocked;
 	/***/ public String dirCacheIsNotLocked;
 	/***/ public String DIRCChecksumMismatch;
+	/***/ public String DIRCCorruptLength;
+	/***/ public String DIRCCorruptLengthFirst;
 	/***/ public String DIRCExtensionIsTooLargeAt;
 	/***/ public String DIRCExtensionNotSupportedByThisVersion;
 	/***/ public String DIRCHasTooManyEntries;
@@ -440,6 +440,11 @@
 	/***/ public String lockOnNotHeld;
 	/***/ public String lockStreamClosed;
 	/***/ public String lockStreamMultiple;
+	/***/ public String logInconsistentFiletimeDiff;
+	/***/ public String logLargerFiletimeDiff;
+	/***/ public String logSmallerFiletime;
+	/***/ public String logXDGConfigHomeInvalid;
+	/***/ public String looseObjectHandleIsStale;
 	/***/ public String maxCountMustBeNonNegative;
 	/***/ public String mergeConflictOnNonNoteEntries;
 	/***/ public String mergeConflictOnNotes;
@@ -653,6 +658,7 @@
 	/***/ public String sourceRefNotSpecifiedForRefspec;
 	/***/ public String squashCommitNotUpdatingHEAD;
 	/***/ public String sshCommandFailed;
+	/***/ public String sshCommandTimeout;
 	/***/ public String sslFailureExceptionMessage;
 	/***/ public String sslFailureInfo;
 	/***/ public String sslFailureCause;
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/dfs/DfsBundleWriter.java b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/dfs/DfsBundleWriter.java
new file mode 100644
index 0000000..736f381
--- /dev/null
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/dfs/DfsBundleWriter.java
@@ -0,0 +1,52 @@
+/*
+ * Copyright (c) 2020, Google LLC  and others
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+package org.eclipse.jgit.internal.storage.dfs;
+
+import java.io.IOException;
+import java.io.OutputStream;
+import java.util.ArrayList;
+import java.util.List;
+
+import org.eclipse.jgit.internal.storage.pack.CachedPack;
+import org.eclipse.jgit.lib.ProgressMonitor;
+import org.eclipse.jgit.transport.BundleWriter;
+
+/** Writes {@link DfsRepository} to a Git bundle. */
+public class DfsBundleWriter {
+	/**
+	 * Writes the entire {@link DfsRepository} to a Git bundle.
+	 * <p>
+	 * This method try to avoid traversing the pack files as much as possible
+	 * and dumps all objects as-is to a Git bundle.
+	 *
+	 * @param pm
+	 *            progress monitor
+	 * @param os
+	 *            Git bundle output
+	 * @param db
+	 *            repository
+	 * @throws IOException
+	 *             thrown if the output stream throws one.
+	 */
+	public static void writeEntireRepositoryAsBundle(ProgressMonitor pm,
+			OutputStream os, DfsRepository db) throws IOException {
+		BundleWriter bw = new BundleWriter(db);
+		db.getRefDatabase().getRefs().forEach(bw::include);
+		List<CachedPack> packs = new ArrayList<>();
+		for (DfsPackFile p : db.getObjectDatabase().getPacks()) {
+			packs.add(new DfsCachedPack(p));
+		}
+		bw.addObjectsAsIs(packs);
+		bw.writeBundle(pm, os);
+	}
+
+	private DfsBundleWriter() {
+	}
+}
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/BasePackBitmapIndex.java b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/BasePackBitmapIndex.java
index c9bb167..ec53818 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/BasePackBitmapIndex.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/BasePackBitmapIndex.java
@@ -59,12 +59,26 @@
 		 * @return the full bitmap
 		 */
 		EWAHCompressedBitmap getBitmap() {
+			EWAHCompressedBitmap bitmap = getBitmapWithoutCaching();
+			// Cache the result.
+			bitmapContainer = bitmap;
+			return bitmap;
+		}
+
+		/**
+		 * Compute and return the full bitmap, do NOT cache the expanded bitmap,
+		 * which saves memory and should only be used during bitmap creation in
+		 * garbage collection.
+		 *
+		 * @return the full bitmap
+		 */
+		EWAHCompressedBitmap getBitmapWithoutCaching() {
 			// Fast path to immediately return the expanded result.
 			Object r = bitmapContainer;
 			if (r instanceof EWAHCompressedBitmap)
 				return (EWAHCompressedBitmap) r;
 
-			// Expand the bitmap and cache the result.
+			// Expand the bitmap but not cache the result.
 			XorCompressedBitmap xb = (XorCompressedBitmap) r;
 			EWAHCompressedBitmap out = xb.bitmap;
 			for (;;) {
@@ -72,7 +86,6 @@
 				if (r instanceof EWAHCompressedBitmap) {
 					out = out.xor((EWAHCompressedBitmap) r);
 					out.trim();
-					bitmapContainer = out;
 					return out;
 				}
 				xb = (XorCompressedBitmap) r;
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 265b71d..9d1d457 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
@@ -85,6 +85,10 @@
 	/** Maximum number of candidates offered as resolutions of abbreviation. */
 	private static final int RESOLVE_ABBREV_LIMIT = 256;
 
+	/** Maximum number of attempts to read a loose object for which a stale file
+	 *  handle exception is thrown */
+	final static int MAX_LOOSE_OBJECT_STALE_READ_ATTEMPTS = 5;
+
 	private final AlternateHandle handle = new AlternateHandle(this);
 
 	private final Config config;
@@ -212,7 +216,7 @@
 	/** {@inheritDoc} */
 	@Override
 	public void close() {
-		unpackedObjectCache.clear();
+		unpackedObjectCache().clear();
 
 		final PackList packs = packList.get();
 		if (packs != NO_PACKS && packList.compareAndSet(packs, NO_PACKS)) {
@@ -277,7 +281,7 @@
 	/** {@inheritDoc} */
 	@Override
 	public boolean has(AnyObjectId objectId) {
-		return unpackedObjectCache.isUnpacked(objectId)
+		return unpackedObjectCache().isUnpacked(objectId)
 				|| hasPackedInSelfOrAlternate(objectId, null)
 				|| hasLooseInSelfOrAlternate(objectId, null);
 	}
@@ -395,7 +399,7 @@
 	@Override
 	ObjectLoader openObject(WindowCursor curs, AnyObjectId objectId)
 			throws IOException {
-		if (unpackedObjectCache.isUnpacked(objectId)) {
+		if (unpackedObjectCache().isUnpacked(objectId)) {
 			ObjectLoader ldr = openLooseObject(curs, objectId);
 			if (ldr != null) {
 				return ldr;
@@ -473,23 +477,71 @@
 	@Override
 	ObjectLoader openLooseObject(WindowCursor curs, AnyObjectId id)
 			throws IOException {
-		File path = fileFor(id);
-		try (FileInputStream in = new FileInputStream(path)) {
-			unpackedObjectCache.add(id);
-			return UnpackedObject.open(in, path, id, curs);
-		} catch (FileNotFoundException noFile) {
-			if (path.exists()) {
-				throw noFile;
+		int readAttempts = 0;
+		while (readAttempts < MAX_LOOSE_OBJECT_STALE_READ_ATTEMPTS) {
+			readAttempts++;
+			File path = fileFor(id);
+			try {
+				return getObjectLoader(curs, path, id);
+			} catch (FileNotFoundException noFile) {
+				if (path.exists()) {
+					throw noFile;
+				}
+				break;
+			} catch (IOException e) {
+				if (!FileUtils.isStaleFileHandleInCausalChain(e)) {
+					throw e;
+				}
+				if (LOG.isDebugEnabled()) {
+					LOG.debug(MessageFormat.format(
+							JGitText.get().looseObjectHandleIsStale, id.name(),
+							Integer.valueOf(readAttempts), Integer.valueOf(
+									MAX_LOOSE_OBJECT_STALE_READ_ATTEMPTS)));
+				}
 			}
-			unpackedObjectCache.remove(id);
-			return null;
 		}
+		unpackedObjectCache().remove(id);
+		return null;
+	}
+
+	/**
+	 * Provides a loader for an objectId
+	 *
+	 * @param curs
+	 *            cursor on the database
+	 * @param path
+	 *            the path of the loose object
+	 * @param id
+	 *            the object id
+	 * @return a loader for the loose file object
+	 * @throws IOException
+	 *             when file does not exist or it could not be opened
+	 */
+	ObjectLoader getObjectLoader(WindowCursor curs, File path, AnyObjectId id)
+			throws IOException {
+		try (FileInputStream in = new FileInputStream(path)) {
+			unpackedObjectCache().add(id);
+			return UnpackedObject.open(in, path, id, curs);
+		}
+	}
+
+	/**
+	 * <p>
+	 * Getter for the field <code>unpackedObjectCache</code>.
+	 * </p>
+	 * This accessor is particularly useful to allow mocking of this class for
+	 * testing purposes.
+	 *
+	 * @return the cache of the objects currently unpacked.
+	 */
+	UnpackedObjectCache unpackedObjectCache() {
+		return unpackedObjectCache;
 	}
 
 	@Override
 	long getObjectSize(WindowCursor curs, AnyObjectId id)
 			throws IOException {
-		if (unpackedObjectCache.isUnpacked(id)) {
+		if (unpackedObjectCache().isUnpacked(id)) {
 			long len = getLooseObjectSize(curs, id);
 			if (0 <= len) {
 				return len;
@@ -567,13 +619,13 @@
 			throws IOException {
 		File f = fileFor(id);
 		try (FileInputStream in = new FileInputStream(f)) {
-			unpackedObjectCache.add(id);
+			unpackedObjectCache().add(id);
 			return UnpackedObject.getSize(in, id, curs);
 		} catch (FileNotFoundException noFile) {
 			if (f.exists()) {
 				throw noFile;
 			}
-			unpackedObjectCache.remove(id);
+			unpackedObjectCache().remove(id);
 			return -1;
 		}
 	}
@@ -667,7 +719,7 @@
 			boolean createDuplicate) throws IOException {
 		// If the object is already in the repository, remove temporary file.
 		//
-		if (unpackedObjectCache.isUnpacked(id)) {
+		if (unpackedObjectCache().isUnpacked(id)) {
 			FileUtils.delete(tmp, FileUtils.RETRY);
 			return InsertLooseObjectResult.EXISTS_LOOSE;
 		}
@@ -723,7 +775,7 @@
 		Files.move(FileUtils.toPath(tmp), FileUtils.toPath(dst),
 				StandardCopyOption.ATOMIC_MOVE);
 		dst.setReadOnly();
-		unpackedObjectCache.add(id);
+		unpackedObjectCache().add(id);
 		return InsertLooseObjectResult.INSERTED;
 	}
 
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/PackBitmapIndexRemapper.java b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/PackBitmapIndexRemapper.java
index 4b25284..dd5d03c 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/PackBitmapIndexRemapper.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/PackBitmapIndexRemapper.java
@@ -156,7 +156,8 @@
 			return null;
 
 		inflated.clear();
-		for (IntIterator i = oldBitmap.getBitmap().intIterator(); i.hasNext();)
+		for (IntIterator i = oldBitmap.getBitmapWithoutCaching()
+				.intIterator(); i.hasNext();)
 			inflated.set(prevToNewMapping[i.next()]);
 		bitmap = inflated.toEWAHCompressedBitmap();
 		bitmap.trim();
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/PackIndexV1.java b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/PackIndexV1.java
index 9cf95d0..eb0ac6a 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/PackIndexV1.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/PackIndexV1.java
@@ -49,11 +49,11 @@
 			idxHeader[k] = NB.decodeUInt32(fanoutTable, k * 4);
 		idxdata = new byte[idxHeader.length][];
 		for (int k = 0; k < idxHeader.length; k++) {
-			int n;
+			long n;
 			if (k == 0) {
-				n = (int) (idxHeader[k]);
+				n = idxHeader[k];
 			} else {
-				n = (int) (idxHeader[k] - idxHeader[k - 1]);
+				n = idxHeader[k] - idxHeader[k - 1];
 			}
 			if (n > 0) {
 				final long len = n * (Constants.OBJECT_ID_LENGTH + 4);
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/WindowCache.java b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/WindowCache.java
index 80c8e10..3e8cb3a 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/WindowCache.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/WindowCache.java
@@ -1,6 +1,6 @@
 /*
- * Copyright (C) 2008-2009, Google Inc.
- * Copyright (C) 2008, Shawn O. Pearce <spearce@spearce.org> and others
+ * Copyright (C) 2008, 2009 Google Inc.
+ * Copyright (C) 2008, 2020 Shawn O. Pearce <spearce@spearce.org> and others
  *
  * This program and the accompanying materials are made available under the
  * terms of the Eclipse Distribution License v. 1.0 which is available at
@@ -19,6 +19,7 @@
 import java.util.Random;
 import java.util.concurrent.ConcurrentHashMap;
 import java.util.concurrent.ConcurrentLinkedQueue;
+import java.util.concurrent.atomic.AtomicBoolean;
 import java.util.concurrent.atomic.AtomicLong;
 import java.util.concurrent.atomic.AtomicReferenceArray;
 import java.util.concurrent.atomic.LongAdder;
@@ -376,14 +377,14 @@
 	 * @return the cached instance.
 	 */
 	public static WindowCache getInstance() {
-		return cache;
+		return cache.publishMBeanIfNeeded();
 	}
 
 	static final ByteWindow get(PackFile pack, long offset)
 			throws IOException {
 		final WindowCache c = cache;
 		final ByteWindow r = c.getOrLoad(pack, c.toStart(offset));
-		if (c != cache) {
+		if (c != cache.publishMBeanIfNeeded()) {
 			// The cache was reconfigured while we were using the old one
 			// to load this window. The window is still valid, but our
 			// cache may think its still live. Ensure the window is removed
@@ -433,6 +434,8 @@
 
 	private final StatsRecorderImpl mbean;
 
+	private final AtomicBoolean publishMBean = new AtomicBoolean();
+
 	private boolean useStrongRefs;
 
 	private WindowCache(WindowCacheConfig cfg) {
@@ -470,9 +473,7 @@
 
 		mbean = new StatsRecorderImpl();
 		statsRecorder = mbean;
-		if (cfg.getExposeStatsViaJmx()) {
-			Monitoring.registerMBean(mbean, "block_cache"); //$NON-NLS-1$
-		}
+		publishMBean.set(cfg.getExposeStatsViaJmx());
 
 		if (maxFiles < 1)
 			throw new IllegalArgumentException(JGitText.get().openFilesMustBeAtLeast1);
@@ -480,6 +481,13 @@
 			throw new IllegalArgumentException(JGitText.get().windowSizeMustBeLesserThanLimit);
 	}
 
+	private WindowCache publishMBeanIfNeeded() {
+		if (publishMBean.getAndSet(false)) {
+			Monitoring.registerMBean(mbean, "block_cache"); //$NON-NLS-1$
+		}
+		return this;
+	}
+
 	/**
 	 * @return cache statistics for the WindowCache
 	 */
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 824c62a..3e4b5df 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
@@ -756,6 +756,19 @@
 
 	/**
 	 * Prepare the list of objects to be written to the pack stream.
+	 *
+	 * <p>
+	 * PackWriter will concat and write out the specified packs as-is.
+	 *
+	 * @param c
+	 *            cached packs to be written.
+	 */
+	public void preparePack(Collection<? extends CachedPack> c) {
+		cachedPacks.addAll(c);
+	}
+
+	/**
+	 * Prepare the list of objects to be written to the pack stream.
 	 * <p>
 	 * Basing on these 2 sets, another set of objects to put in a pack file is
 	 * created: this set consists of all objects reachable (ancestors) from
@@ -1548,6 +1561,7 @@
 		endPhase(monitor);
 	}
 
+	@SuppressWarnings("Finally")
 	private void parallelDeltaSearch(ProgressMonitor monitor,
 			ObjectToPack[] list, int cnt, int threads) throws IOException {
 		DeltaCache dc = new ThreadSafeDeltaCache(config);
@@ -1569,15 +1583,22 @@
 			// Caller didn't give us a way to run the tasks, spawn up a
 			// temporary thread pool and make sure it tears down cleanly.
 			ExecutorService pool = Executors.newFixedThreadPool(threads);
+			Throwable e1 = null;
 			try {
 				runTasks(pool, pm, taskBlock, errors);
+			} catch (Exception e) {
+				e1 = e;
 			} finally {
 				pool.shutdown();
 				for (;;) {
 					try {
-						if (pool.awaitTermination(60, TimeUnit.SECONDS))
+						if (pool.awaitTermination(60, TimeUnit.SECONDS)) {
 							break;
+						}
 					} catch (InterruptedException e) {
+						if (e1 != null) {
+							e.addSuppressed(e1);
+						}
 						throw new IOException(JGitText
 								.get().packingCancelledDuringObjectsWriting, e);
 					}
@@ -2182,10 +2203,12 @@
 
 		// Check if this object needs to be rejected, doing the cheaper
 		// checks first.
-		boolean reject = filterSpec.getBlobLimit() >= 0 &&
-			type == OBJ_BLOB &&
-			!want.contains(src) &&
-			reader.getObjectSize(src, OBJ_BLOB) > filterSpec.getBlobLimit();
+		boolean reject =
+			(!filterSpec.allowsType(type) && !want.contains(src)) ||
+			(filterSpec.getBlobLimit() >= 0 &&
+				type == OBJ_BLOB &&
+				!want.contains(src) &&
+				reader.getObjectSize(src, OBJ_BLOB) > filterSpec.getBlobLimit());
 		if (!reject) {
 			addObject(src, type, pathHashCode);
 		}
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/reftable/MergedReftable.java b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/reftable/MergedReftable.java
index 3633515..a78f4d2 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/reftable/MergedReftable.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/reftable/MergedReftable.java
@@ -82,7 +82,7 @@
 			return 0;
 		}
 		long minUpdateIndex = tables[0].minUpdateIndex();
-		for (int i = 0; i < tables.length - 1; i++) {
+		for (int i = 1; i < tables.length; i++) {
 			if (tables[i].minUpdateIndex() < minUpdateIndex) {
 				minUpdateIndex = tables[i].minUpdateIndex();
 			}
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/lib/BitmapIndex.java b/org.eclipse.jgit/src/org/eclipse/jgit/lib/BitmapIndex.java
index f6695bd..b11b230 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/lib/BitmapIndex.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/lib/BitmapIndex.java
@@ -86,7 +86,7 @@
 
 		/**
 		 * Returns the corresponding raw compressed EWAH bitmap of the bitmap.
-		 * 
+		 *
 		 * @return the corresponding {@code EWAHCompressedBitmap}
 		 * @since 5.8
 		 */
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/lib/CommitBuilder.java b/org.eclipse.jgit/src/org/eclipse/jgit/lib/CommitBuilder.java
index 66d7d51..4f93fda 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/lib/CommitBuilder.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/lib/CommitBuilder.java
@@ -361,7 +361,9 @@
 	 * header</a>.
 	 * <p>
 	 * CRLF and CR will be sanitized to LF and signature will have a hanging
-	 * indent of one space starting with line two.
+	 * indent of one space starting with line two. A trailing line break is
+	 * <em>not</em> written; the caller is supposed to terminate the GPG
+	 * signature header by writing a single newline.
 	 * </p>
 	 *
 	 * @param in
@@ -375,22 +377,24 @@
 	 */
 	static void writeGpgSignatureString(String in, OutputStream out)
 			throws IOException, IllegalArgumentException {
-		for (int i = 0; i < in.length(); ++i) {
+		int length = in.length();
+		for (int i = 0; i < length; ++i) {
 			char ch = in.charAt(i);
 			switch (ch) {
 			case '\r':
-				if (i + 1 < in.length() && in.charAt(i + 1) == '\n') {
-					out.write('\n');
-					out.write(' ');
+				if (i + 1 < length && in.charAt(i + 1) == '\n') {
 					++i;
-				} else {
+				}
+				if (i + 1 < length) {
 					out.write('\n');
 					out.write(' ');
 				}
 				break;
 			case '\n':
-				out.write('\n');
-				out.write(' ');
+				if (i + 1 < length) {
+					out.write('\n');
+					out.write(' ');
+				}
 				break;
 			default:
 				// sanity check
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/lib/ConfigConstants.java b/org.eclipse.jgit/src/org/eclipse/jgit/lib/ConfigConstants.java
index eef822f..834fff5 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/lib/ConfigConstants.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/lib/ConfigConstants.java
@@ -1,7 +1,7 @@
 /*
  * Copyright (C) 2010, Mathias Kinzler <mathias.kinzler@sap.com>
  * Copyright (C) 2010, Chris Aniszczyk <caniszczyk@gmail.com>
- * Copyright (C) 2012-2013, Robin Rosenberg and others
+ * Copyright (C) 2012, 2020, Robin Rosenberg and others
  *
  * This program and the accompanying materials are made available under the
  * terms of the Eclipse Distribution License v. 1.0 which is available at
@@ -93,6 +93,12 @@
 	public static final String CONFIG_GPG_SECTION = "gpg";
 
 	/**
+	 * The "protocol" section
+	 * @since 5.9
+	 */
+	public static final String CONFIG_PROTOCOL_SECTION = "protocol";
+
+	/**
 	 * The "format" key
 	 * @since 5.2
 	 */
@@ -662,4 +668,33 @@
 	 * @since 5.8
 	 */
 	public static final String CONFIG_KEY_WINDOW_MEMORY = "windowmemory";
+
+	/**
+	 * The "feature" section
+	 *
+	 * @since 5.9
+	 */
+	public static final String CONFIG_FEATURE_SECTION = "feature";
+
+	/**
+	 * The "feature.manyFiles" key
+	 *
+	 * @since 5.9
+	 */
+	public static final String CONFIG_KEY_MANYFILES = "manyFiles";
+
+	/**
+	 * The "index" section
+	 *
+	 * @since 5.9
+	 */
+	public static final String CONFIG_INDEX_SECTION = "index";
+
+	/**
+	 * The "version" key
+	 *
+	 * @since 5.9
+	 */
+	public static final String CONFIG_KEY_VERSION = "version";
+
 }
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/merge/ResolveMerger.java b/org.eclipse.jgit/src/org/eclipse/jgit/merge/ResolveMerger.java
index 506d333..6c217fd 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/merge/ResolveMerger.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/merge/ResolveMerger.java
@@ -588,7 +588,8 @@
 		final int modeO = tw.getRawMode(T_OURS);
 		final int modeT = tw.getRawMode(T_THEIRS);
 		final int modeB = tw.getRawMode(T_BASE);
-
+		boolean gitLinkMerging = isGitLink(modeO) || isGitLink(modeT)
+				|| isGitLink(modeB);
 		if (modeO == 0 && modeT == 0 && modeB == 0)
 			// File is either untracked or new, staged but uncommitted
 			return true;
@@ -737,31 +738,28 @@
 				return false;
 			}
 
-			boolean gitlinkConflict = isGitLink(modeO) || isGitLink(modeT);
-			// Don't attempt to resolve submodule link conflicts
-			if (gitlinkConflict || !attributes.canBeContentMerged()) {
+			if (gitLinkMerging && ignoreConflicts) {
+				// Always select 'ours' in case of GITLINK merge failures so
+				// a caller can use virtual commit.
+				add(tw.getRawPath(), ours, DirCacheEntry.STAGE_0, EPOCH, 0);
+				return true;
+			} else if (gitLinkMerging) {
+				add(tw.getRawPath(), base, DirCacheEntry.STAGE_1, EPOCH, 0);
+				add(tw.getRawPath(), ours, DirCacheEntry.STAGE_2, EPOCH, 0);
+				add(tw.getRawPath(), theirs, DirCacheEntry.STAGE_3, EPOCH, 0);
+				MergeResult<SubmoduleConflict> result = createGitLinksMergeResult(
+						base, ours, theirs);
+				result.setContainsConflicts(true);
+				mergeResults.put(tw.getPathString(), result);
+				unmergedPaths.add(tw.getPathString());
+				return true;
+			} else if (!attributes.canBeContentMerged()) {
 				add(tw.getRawPath(), base, DirCacheEntry.STAGE_1, EPOCH, 0);
 				add(tw.getRawPath(), ours, DirCacheEntry.STAGE_2, EPOCH, 0);
 				add(tw.getRawPath(), theirs, DirCacheEntry.STAGE_3, EPOCH, 0);
 
-				if (gitlinkConflict) {
-					MergeResult<SubmoduleConflict> result = new MergeResult<>(
-							Arrays.asList(
-									new SubmoduleConflict(base == null ? null
-											: base.getEntryObjectId()),
-									new SubmoduleConflict(ours == null ? null
-											: ours.getEntryObjectId()),
-									new SubmoduleConflict(theirs == null ? null
-											: theirs.getEntryObjectId())));
-					result.setContainsConflicts(true);
-					mergeResults.put(tw.getPathString(), result);
-					if (!ignoreConflicts) {
-						unmergedPaths.add(tw.getPathString());
-					}
-				} else {
-					// attribute merge issues are conflicts but not failures
-					unmergedPaths.add(tw.getPathString());
-				}
+				// attribute merge issues are conflicts but not failures
+				unmergedPaths.add(tw.getPathString());
 				return true;
 			}
 
@@ -786,45 +784,73 @@
 			// OURS or THEIRS has been deleted
 			if (((modeO != 0 && !tw.idEqual(T_BASE, T_OURS)) || (modeT != 0 && !tw
 					.idEqual(T_BASE, T_THEIRS)))) {
-				MergeResult<RawText> result = contentMerge(base, ours, theirs,
-						attributes);
-
-				if (ignoreConflicts) {
-					// In case a conflict is detected the working tree file is
-					// again filled with new content (containing conflict
-					// markers). But also stage 0 of the index is filled with
-					// that content.
-					result.setContainsConflicts(false);
-					updateIndex(base, ours, theirs, result, attributes);
-				} else {
+				if (gitLinkMerging && ignoreConflicts) {
+					add(tw.getRawPath(), ours, DirCacheEntry.STAGE_0, EPOCH, 0);
+				} else if (gitLinkMerging) {
 					add(tw.getRawPath(), base, DirCacheEntry.STAGE_1, EPOCH, 0);
 					add(tw.getRawPath(), ours, DirCacheEntry.STAGE_2, EPOCH, 0);
-					DirCacheEntry e = add(tw.getRawPath(), theirs,
-							DirCacheEntry.STAGE_3, EPOCH, 0);
+					add(tw.getRawPath(), theirs, DirCacheEntry.STAGE_3, EPOCH, 0);
+					MergeResult<SubmoduleConflict> result = createGitLinksMergeResult(
+							base, ours, theirs);
+					result.setContainsConflicts(true);
+					mergeResults.put(tw.getPathString(), result);
+					unmergedPaths.add(tw.getPathString());
+				} else {
+					MergeResult<RawText> result = contentMerge(base, ours,
+							theirs, attributes);
 
-					// OURS was deleted checkout THEIRS
-					if (modeO == 0) {
-						// Check worktree before checking out THEIRS
-						if (isWorktreeDirty(work, ourDce)) {
-							return false;
-						}
-						if (nonTree(modeT)) {
-							if (e != null) {
-								addToCheckout(tw.getPathString(), e, attributes);
+					if (ignoreConflicts) {
+						// In case a conflict is detected the working tree file
+						// is again filled with new content (containing conflict
+						// markers). But also stage 0 of the index is filled
+						// with that content.
+						result.setContainsConflicts(false);
+						updateIndex(base, ours, theirs, result, attributes);
+					} else {
+						add(tw.getRawPath(), base, DirCacheEntry.STAGE_1, EPOCH,
+								0);
+						add(tw.getRawPath(), ours, DirCacheEntry.STAGE_2, EPOCH,
+								0);
+						DirCacheEntry e = add(tw.getRawPath(), theirs,
+								DirCacheEntry.STAGE_3, EPOCH, 0);
+
+						// OURS was deleted checkout THEIRS
+						if (modeO == 0) {
+							// Check worktree before checking out THEIRS
+							if (isWorktreeDirty(work, ourDce)) {
+								return false;
+							}
+							if (nonTree(modeT)) {
+								if (e != null) {
+									addToCheckout(tw.getPathString(), e,
+											attributes);
+								}
 							}
 						}
+
+						unmergedPaths.add(tw.getPathString());
+
+						// generate a MergeResult for the deleted file
+						mergeResults.put(tw.getPathString(), result);
 					}
-
-					unmergedPaths.add(tw.getPathString());
-
-					// generate a MergeResult for the deleted file
-					mergeResults.put(tw.getPathString(), result);
 				}
 			}
 		}
 		return true;
 	}
 
+	private static MergeResult<SubmoduleConflict> createGitLinksMergeResult(
+			CanonicalTreeParser base, CanonicalTreeParser ours,
+			CanonicalTreeParser theirs) {
+		return new MergeResult<>(Arrays.asList(
+				new SubmoduleConflict(
+						base == null ? null : base.getEntryObjectId()),
+				new SubmoduleConflict(
+						ours == null ? null : ours.getEntryObjectId()),
+				new SubmoduleConflict(
+						theirs == null ? null : theirs.getEntryObjectId())));
+	}
+
 	/**
 	 * Does the content merge. The three texts base, ours and theirs are
 	 * specified with {@link CanonicalTreeParser}. If any of the parsers is
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/transport/BundleWriter.java b/org.eclipse.jgit/src/org/eclipse/jgit/transport/BundleWriter.java
index 57eed3a..4649d33 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/transport/BundleWriter.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/transport/BundleWriter.java
@@ -17,12 +17,16 @@
 import java.io.OutputStreamWriter;
 import java.io.Writer;
 import java.text.MessageFormat;
+import java.util.ArrayList;
+import java.util.Collection;
 import java.util.HashSet;
+import java.util.List;
 import java.util.Map;
 import java.util.Set;
 import java.util.TreeMap;
 
 import org.eclipse.jgit.internal.JGitText;
+import org.eclipse.jgit.internal.storage.pack.CachedPack;
 import org.eclipse.jgit.internal.storage.pack.PackWriter;
 import org.eclipse.jgit.lib.AnyObjectId;
 import org.eclipse.jgit.lib.Constants;
@@ -62,6 +66,8 @@
 
 	private final Set<ObjectId> tagTargets;
 
+	private final List<CachedPack> cachedPacks = new ArrayList<>();
+
 	private PackConfig packConfig;
 
 	private ObjectCountCallback callback;
@@ -150,6 +156,26 @@
 	}
 
 	/**
+	 * Add objects to the bundle file.
+	 *
+	 * <p>
+	 * When this method is used, object traversal is disabled and specified pack
+	 * files are directly saved to the Git bundle file.
+	 *
+	 * <p>
+	 * Unlike {@link #include}, this doesn't affect the refs. Even if the
+	 * objects are not reachable from any ref, they will be included in the
+	 * bundle file.
+	 *
+	 * @param c
+	 *            pack to include
+	 * @since 5.9
+	 */
+	public void addObjectsAsIs(Collection<? extends CachedPack> c) {
+		cachedPacks.addAll(c);
+	}
+
+	/**
 	 * Assume a commit is available on the recipient's side.
 	 * <p>
 	 * In order to fetch from a bundle the recipient must have any assumed
@@ -187,19 +213,24 @@
 		try (PackWriter packWriter = newPackWriter()) {
 			packWriter.setObjectCountCallback(callback);
 
-			final HashSet<ObjectId> inc = new HashSet<>();
-			final HashSet<ObjectId> exc = new HashSet<>();
-			inc.addAll(include.values());
-			for (RevCommit r : assume)
-				exc.add(r.getId());
 			packWriter.setIndexDisabled(true);
 			packWriter.setDeltaBaseAsOffset(true);
-			packWriter.setThin(!exc.isEmpty());
 			packWriter.setReuseValidatingObjects(false);
-			if (exc.isEmpty()) {
-				packWriter.setTagTargets(tagTargets);
+			if (cachedPacks.isEmpty()) {
+				HashSet<ObjectId> inc = new HashSet<>();
+				HashSet<ObjectId> exc = new HashSet<>();
+				inc.addAll(include.values());
+				for (RevCommit r : assume) {
+					exc.add(r.getId());
+				}
+				if (exc.isEmpty()) {
+					packWriter.setTagTargets(tagTargets);
+				}
+				packWriter.setThin(!exc.isEmpty());
+				packWriter.preparePack(monitor, inc, exc);
+			} else {
+				packWriter.preparePack(cachedPacks);
 			}
-			packWriter.preparePack(monitor, inc, exc);
 
 			final Writer w = new OutputStreamWriter(os, UTF_8);
 			w.write(TransportBundle.V2_BUNDLE_SIGNATURE);
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/transport/FilterSpec.java b/org.eclipse.jgit/src/org/eclipse/jgit/transport/FilterSpec.java
index d09b557..a8cf849 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/transport/FilterSpec.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/transport/FilterSpec.java
@@ -10,6 +10,15 @@
 
 package org.eclipse.jgit.transport;
 
+import static java.math.BigInteger.ZERO;
+import static java.util.Objects.requireNonNull;
+import static org.eclipse.jgit.lib.Constants.OBJ_BLOB;
+import static org.eclipse.jgit.lib.Constants.OBJ_COMMIT;
+import static org.eclipse.jgit.lib.Constants.OBJ_TAG;
+import static org.eclipse.jgit.lib.Constants.OBJ_TREE;
+import static org.eclipse.jgit.transport.GitProtocolConstants.OPTION_FILTER;
+
+import java.math.BigInteger;
 import java.text.MessageFormat;
 
 import org.eclipse.jgit.annotations.Nullable;
@@ -24,11 +33,54 @@
  */
 public final class FilterSpec {
 
+	/** Immutable bit-set representation of a set of Git object types. */
+	static class ObjectTypes {
+		static ObjectTypes ALL = allow(OBJ_BLOB, OBJ_TREE, OBJ_COMMIT, OBJ_TAG);
+
+		private final BigInteger val;
+
+		private ObjectTypes(BigInteger val) {
+			this.val = requireNonNull(val);
+		}
+
+		static ObjectTypes allow(int... types) {
+			BigInteger bits = ZERO;
+			for (int type : types) {
+				bits = bits.setBit(type);
+			}
+			return new ObjectTypes(bits);
+		}
+
+		boolean contains(int type) {
+			return val.testBit(type);
+		}
+
+		/** {@inheritDoc} */
+		@Override
+		public boolean equals(Object obj) {
+			if (!(obj instanceof ObjectTypes)) {
+				return false;
+			}
+
+			ObjectTypes other = (ObjectTypes) obj;
+			return other.val.equals(val);
+		}
+
+		/** {@inheritDoc} */
+		@Override
+		public int hashCode() {
+			return val.hashCode();
+		}
+	}
+
+	private final ObjectTypes types;
+
 	private final long blobLimit;
 
 	private final long treeDepthLimit;
 
-	private FilterSpec(long blobLimit, long treeDepthLimit) {
+	private FilterSpec(ObjectTypes types, long blobLimit, long treeDepthLimit) {
+		this.types = requireNonNull(types);
 		this.blobLimit = blobLimit;
 		this.treeDepthLimit = treeDepthLimit;
 	}
@@ -53,7 +105,8 @@
 	public static FilterSpec fromFilterLine(String filterLine)
 			throws PackProtocolException {
 		if (filterLine.equals("blob:none")) { //$NON-NLS-1$
-			return FilterSpec.withBlobLimit(0);
+			return FilterSpec.withObjectTypes(
+					ObjectTypes.allow(OBJ_TREE, OBJ_COMMIT, OBJ_TAG));
 		} else if (filterLine.startsWith("blob:limit=")) { //$NON-NLS-1$
 			long blobLimit = -1;
 			try {
@@ -86,8 +139,18 @@
 	}
 
 	/**
+	 * @param types
+	 *            set of permitted object types, for use in "blob:none" and
+	 *            "object:none" filters
+	 * @return a filter spec which restricts to objects of the specified types
+	 */
+	static FilterSpec withObjectTypes(ObjectTypes types) {
+		return new FilterSpec(types, -1, -1);
+	}
+
+	/**
 	 * @param blobLimit
-	 *            the blob limit in a "blob:[limit]" or "blob:none" filter line
+	 *            the blob limit in a "blob:[limit]" filter line
 	 * @return a filter spec which filters blobs above a certain size
 	 */
 	static FilterSpec withBlobLimit(long blobLimit) {
@@ -95,7 +158,7 @@
 			throw new IllegalArgumentException(
 					"blobLimit cannot be negative: " + blobLimit); //$NON-NLS-1$
 		}
-		return new FilterSpec(blobLimit, -1);
+		return new FilterSpec(ObjectTypes.ALL, blobLimit, -1);
 	}
 
 	/**
@@ -109,13 +172,25 @@
 			throw new IllegalArgumentException(
 					"treeDepthLimit cannot be negative: " + treeDepthLimit); //$NON-NLS-1$
 		}
-		return new FilterSpec(-1, treeDepthLimit);
+		return new FilterSpec(ObjectTypes.ALL, -1, treeDepthLimit);
 	}
 
 	/**
 	 * A placeholder that indicates no filtering.
 	 */
-	public static final FilterSpec NO_FILTER = new FilterSpec(-1, -1);
+	public static final FilterSpec NO_FILTER = new FilterSpec(ObjectTypes.ALL, -1, -1);
+
+	/**
+	 * @param type
+	 *            a Git object type, such as
+	 *            {@link org.eclipse.jgit.lib.Constants#OBJ_BLOB}
+	 * @return whether this filter allows objects of the specified type
+	 *
+	 * @since 5.9
+	 */
+	public boolean allowsType(int type) {
+		return types.contains(type);
+	}
 
 	/**
 	 * @return -1 if this filter does not filter blobs based on size, or a
@@ -138,7 +213,7 @@
 	 * @return true if this filter doesn't filter out anything
 	 */
 	public boolean isNoOp() {
-		return blobLimit == -1 && treeDepthLimit == -1;
+		return types.equals(ObjectTypes.ALL) && blobLimit == -1 && treeDepthLimit == -1;
 	}
 
 	/**
@@ -146,14 +221,17 @@
 	 */
 	@Nullable
 	public String filterLine() {
-		if (blobLimit == 0) {
-			return GitProtocolConstants.OPTION_FILTER + " blob:none"; //$NON-NLS-1$
+		if (isNoOp()) {
+			return null;
+		} else if (types.equals(ObjectTypes.allow(OBJ_TREE, OBJ_COMMIT, OBJ_TAG)) &&
+					blobLimit == -1 && treeDepthLimit == -1) {
+			return OPTION_FILTER + " blob:none"; //$NON-NLS-1$
+		} else if (types.equals(ObjectTypes.ALL) && blobLimit >= 0 && treeDepthLimit == -1) {
+			return OPTION_FILTER + " blob:limit=" + blobLimit; //$NON-NLS-1$
+		} else if (types.equals(ObjectTypes.ALL) && blobLimit == -1 && treeDepthLimit >= 0) {
+			return OPTION_FILTER + " tree:" + treeDepthLimit; //$NON-NLS-1$
+		} else {
+			throw new IllegalStateException();
 		}
-
-		if (blobLimit > 0) {
-			return GitProtocolConstants.OPTION_FILTER + " blob:limit=" + blobLimit; //$NON-NLS-1$
-		}
-
-		return null;
 	}
 }
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/transport/RemoteSession.java b/org.eclipse.jgit/src/org/eclipse/jgit/transport/RemoteSession.java
index f9f50d4..dd4c967 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/transport/RemoteSession.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/transport/RemoteSession.java
@@ -4,7 +4,7 @@
  * Copyright (C) 2009, Google, Inc.
  * Copyright (C) 2009, JetBrains s.r.o.
  * Copyright (C) 2008, Robin Rosenberg <robin.rosenberg@dewire.com>
- * Copyright (C) 2008, Shawn O. Pearce <spearce@spearce.org> and others
+ * Copyright (C) 2008, 2020 Shawn O. Pearce <spearce@spearce.org> and others
  *
  * This program and the accompanying materials are made available under the
  * terms of the Eclipse Distribution License v. 1.0 which is available at
@@ -18,26 +18,20 @@
 import java.io.IOException;
 
 /**
- * Create a remote "session" for executing remote commands.
- * <p>
- * Clients should subclass RemoteSession to create an alternate way for JGit to
- * execute remote commands. (The client application may already have this
- * functionality available.) Note that this class is just a factory for creating
- * remote processes. If the application already has a persistent connection to
- * the remote machine, RemoteSession may do nothing more than return a new
- * RemoteProcess when exec is called.
+ * An abstraction of a remote "session" for executing remote commands.
  */
 public interface RemoteSession {
+
 	/**
-	 * Generate a new remote process to execute the given command. This function
-	 * should also start execution and may need to create the streams prior to
-	 * execution.
+	 * Creates a new remote {@link Process} to execute the given command. The
+	 * returned process's streams exist and are connected, and execution of the
+	 * process is already started.
 	 *
 	 * @param commandName
 	 *            command to execute
 	 * @param timeout
-	 *            timeout value, in seconds, for command execution
-	 * @return a new remote process
+	 *            timeout value, in seconds, for creating the remote process
+	 * @return a new remote process, already started
 	 * @throws java.io.IOException
 	 *             may be thrown in several cases. For example, on problems
 	 *             opening input or output streams or on problems connecting or
@@ -48,7 +42,7 @@
 	Process exec(String commandName, int timeout) throws IOException;
 
 	/**
-	 * Obtain an {@link FtpChannel} for performing FTP operations over this
+	 * Obtains an {@link FtpChannel} for performing FTP operations over this
 	 * {@link RemoteSession}. The default implementation returns {@code null}.
 	 *
 	 * @return the {@link FtpChannel}
@@ -59,7 +53,7 @@
 	}
 
 	/**
-	 * Disconnect the remote session
+	 * Disconnects the remote session.
 	 */
 	void disconnect();
 }
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/transport/SshSessionFactory.java b/org.eclipse.jgit/src/org/eclipse/jgit/transport/SshSessionFactory.java
index ef845f4..e216a56a 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/transport/SshSessionFactory.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/transport/SshSessionFactory.java
@@ -1,6 +1,6 @@
 /*
  * Copyright (C) 2008, Robin Rosenberg <robin.rosenberg@dewire.com>
- * Copyright (C) 2008, Shawn O. Pearce <spearce@spearce.org> and others
+ * Copyright (C) 2008, 2020 Shawn O. Pearce <spearce@spearce.org> and others
  *
  * This program and the accompanying materials are made available under the
  * terms of the Eclipse Distribution License v. 1.0 which is available at
@@ -27,12 +27,15 @@
  * Different implementations of the session factory may be used to control
  * communicating with the end-user as well as reading their personal SSH
  * configuration settings, such as known hosts and private keys.
+ * </p>
  * <p>
- * A {@link org.eclipse.jgit.transport.RemoteSession} must be returned to the
- * factory that created it. Callers are encouraged to retain the
- * SshSessionFactory for the duration of the period they are using the Session.
+ * A {@link RemoteSession} must be returned to the factory that created it.
+ * Callers are encouraged to retain the SshSessionFactory for the duration of
+ * the period they are using the session.
+ * </p>
  */
 public abstract class SshSessionFactory {
+
 	private static SshSessionFactory INSTANCE = loadSshSessionFactory();
 
 	private static SshSessionFactory loadSshSessionFactory() {
@@ -43,12 +46,13 @@
 		}
 		return null;
 	}
-	
+
 	/**
-	 * Get the currently configured JVM-wide factory.
+	 * Gets the currently configured JVM-wide factory.
 	 * <p>
-	 * By default the factory will read from the user's <code>$HOME/.ssh</code>
-	 * and assume OpenSSH compatibility.
+	 * By default the factory will read from the user's {@code $HOME/.ssh} and
+	 * assume OpenSSH compatibility.
+	 * </p>
 	 *
 	 * @return factory the current factory for this JVM.
 	 */
@@ -57,11 +61,11 @@
 	}
 
 	/**
-	 * Change the JVM-wide factory to a different implementation.
+	 * Changes the JVM-wide factory to a different implementation.
 	 *
 	 * @param newFactory
-	 *            factory for future sessions to be created through. If null the
-	 *            default factory will be restored.
+	 *            factory for future sessions to be created through; if
+	 *            {@code null} the default factory will be restored.
 	 */
 	public static void setInstance(SshSessionFactory newFactory) {
 		if (newFactory != null) {
@@ -85,26 +89,23 @@
 	}
 
 	/**
-	 * Open (or reuse) a session to a host.
-	 * <p>
-	 * A reasonable UserInfo that can interact with the end-user (if necessary)
-	 * is installed on the returned session by this method.
-	 * <p>
-	 * The caller must connect the session by invoking <code>connect()</code> if
-	 * it has not already been connected.
+	 * Opens (or reuses) a session to a host. The returned session is connected
+	 * and authenticated and is ready for further use.
 	 *
 	 * @param uri
-	 *            URI information about the remote host
+	 *            URI of the remote host to connect to
 	 * @param credentialsProvider
-	 *            provider to support authentication, may be null.
+	 *            provider to support authentication, may be {@code null} if no
+	 *            user input for authentication is needed
 	 * @param fs
-	 *            the file system abstraction which will be necessary to perform
-	 *            certain file system operations.
+	 *            the file system abstraction to use for certain file
+	 *            operations, such as reading configuration files
 	 * @param tms
-	 *            Timeout value, in milliseconds.
-	 * @return a session that can contact the remote host.
+	 *            connection timeout for creating the session, in milliseconds
+	 * @return a connected and authenticated session for communicating with the
+	 *         remote host given by the {@code uri}
 	 * @throws org.eclipse.jgit.errors.TransportException
-	 *             the session could not be created.
+	 *             if the session could not be created
 	 */
 	public abstract RemoteSession getSession(URIish uri,
 			CredentialsProvider credentialsProvider, FS fs, int tms)
@@ -120,7 +121,7 @@
 	public abstract String getType();
 
 	/**
-	 * Close (or recycle) a session to a host.
+	 * Closes (or recycles) a session to a host.
 	 *
 	 * @param session
 	 *            a session previously obtained from this factory's
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 cc577fa..0b38159 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/transport/TransferConfig.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/transport/TransferConfig.java
@@ -21,6 +21,7 @@
 import org.eclipse.jgit.annotations.Nullable;
 import org.eclipse.jgit.internal.storage.file.LazyObjectIdSetFile;
 import org.eclipse.jgit.lib.Config;
+import org.eclipse.jgit.lib.ConfigConstants;
 import org.eclipse.jgit.lib.Config.SectionParser;
 import org.eclipse.jgit.lib.ObjectChecker;
 import org.eclipse.jgit.lib.ObjectIdSet;
@@ -60,11 +61,19 @@
 	}
 
 	/**
-	 * A git configuration variable for which versions of the Git protocol to prefer.
-	 * Used in protocol.version.
+	 * A git configuration variable for which versions of the Git protocol to
+	 * prefer. Used in protocol.version.
+	 *
+	 * @since 5.9
 	 */
-	enum ProtocolVersion {
+	public enum ProtocolVersion {
+		/**
+		 * Git wire protocol version 0 (the default).
+		 */
 		V0("0"), //$NON-NLS-1$
+		/**
+		 * Git wire protocol version 2.
+		 */
 		V2("2"); //$NON-NLS-1$
 
 		final String name;
@@ -73,6 +82,15 @@
 			this.name = name;
 		}
 
+		/**
+		 * Returns version number
+		 *
+		 * @return string version
+		 */
+		public String version() {
+			return name;
+		}
+
 		@Nullable
 		static ProtocolVersion parse(@Nullable String name) {
 			if (name == null) {
@@ -177,7 +195,9 @@
 				"uploadpack", "allowreachablesha1inwant", false);
 		allowFilter = rc.getBoolean(
 				"uploadpack", "allowfilter", false);
-		protocolVersion = ProtocolVersion.parse(rc.getString("protocol", null, "version"));
+		protocolVersion = ProtocolVersion.parse(rc
+				.getString(ConfigConstants.CONFIG_PROTOCOL_SECTION, null,
+						ConfigConstants.CONFIG_KEY_VERSION));
 		hideRefs = rc.getStringList("uploadpack", null, "hiderefs");
 		allowSidebandAll = rc.getBoolean(
 				"uploadpack", "allowsidebandall", false);
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/treewalk/WorkingTreeIterator.java b/org.eclipse.jgit/src/org/eclipse/jgit/treewalk/WorkingTreeIterator.java
index 994af26..4c26dd0 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/treewalk/WorkingTreeIterator.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/treewalk/WorkingTreeIterator.java
@@ -2,7 +2,7 @@
  * Copyright (C) 2008, Shawn O. Pearce <spearce@spearce.org>
  * Copyright (C) 2010, Christian Halstrick <christian.halstrick@sap.com>
  * Copyright (C) 2010, Matthias Sohn <matthias.sohn@sap.com>
- * Copyright (C) 2012-2013, Robin Rosenberg and others
+ * Copyright (C) 2012-2020, Robin Rosenberg and others
  *
  * This program and the accompanying materials are made available under the
  * terms of the Eclipse Distribution License v. 1.0 which is available at
@@ -522,6 +522,17 @@
 		return state.options;
 	}
 
+	/**
+	 * Retrieves the {@link Repository} this {@link WorkingTreeIterator}
+	 * operates on.
+	 *
+	 * @return the {@link Repository}
+	 * @since 5.9
+	 */
+	public Repository getRepository() {
+		return repository;
+	}
+
 	/** {@inheritDoc} */
 	@Override
 	public int idOffset() {
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 91574ef..bf7b753 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/util/FS.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/util/FS.java
@@ -52,7 +52,7 @@
 import java.util.concurrent.Executor;
 import java.util.concurrent.ExecutorService;
 import java.util.concurrent.Executors;
-import java.util.concurrent.SynchronousQueue;
+import java.util.concurrent.LinkedBlockingQueue;
 import java.util.concurrent.ThreadPoolExecutor;
 import java.util.concurrent.TimeUnit;
 import java.util.concurrent.TimeoutException;
@@ -186,12 +186,18 @@
 	 */
 	public static final class FileStoreAttributes {
 
+		/**
+		 * Marker to detect undefined values when reading from the config file.
+		 */
 		private static final Duration UNDEFINED_DURATION = Duration
 				.ofNanos(Long.MAX_VALUE);
 
 		/**
 		 * Fallback filesystem timestamp resolution. The worst case timestamp
 		 * resolution on FAT filesystems is 2 seconds.
+		 * <p>
+		 * Must be at least 1 second.
+		 * </p>
 		 */
 		public static final Duration FALLBACK_TIMESTAMP_RESOLUTION = Duration
 				.ofMillis(2000);
@@ -204,6 +210,25 @@
 		public static final FileStoreAttributes FALLBACK_FILESTORE_ATTRIBUTES = new FileStoreAttributes(
 				FALLBACK_TIMESTAMP_RESOLUTION);
 
+		private static final long ONE_MICROSECOND = TimeUnit.MICROSECONDS
+				.toNanos(1);
+
+		private static final long ONE_MILLISECOND = TimeUnit.MILLISECONDS
+				.toNanos(1);
+
+		private static final long ONE_SECOND = TimeUnit.SECONDS.toNanos(1);
+
+		/**
+		 * Minimum file system timestamp resolution granularity to check, in
+		 * nanoseconds. Should be a positive power of ten smaller than
+		 * {@link #ONE_SECOND}. Must be strictly greater than zero, i.e.,
+		 * minimum value is 1 nanosecond.
+		 * <p>
+		 * Currently set to 1 microsecond, but could also be lower still.
+		 * </p>
+		 */
+		private static final long MINIMUM_RESOLUTION_NANOS = ONE_MICROSECOND;
+
 		private static final String JAVA_VERSION_PREFIX = System
 				.getProperty("java.vendor") + '|' //$NON-NLS-1$
 				+ System.getProperty("java.version") + '|'; //$NON-NLS-1$
@@ -235,9 +260,10 @@
 		 * @see java.util.concurrent.Executors#newCachedThreadPool()
 		 */
 		private static final Executor FUTURE_RUNNER = new ThreadPoolExecutor(0,
-				5, 30L, TimeUnit.SECONDS, new SynchronousQueue<Runnable>(),
+				5, 30L, TimeUnit.SECONDS, new LinkedBlockingQueue<Runnable>(),
 				runnable -> {
-					Thread t = new Thread(runnable, "FileStoreAttributeReader-" //$NON-NLS-1$
+					Thread t = new Thread(runnable,
+							"JGit-FileStoreAttributeReader-" //$NON-NLS-1$
 							+ threadNumber.getAndIncrement());
 					// Make sure these threads don't prevent application/JVM
 					// shutdown.
@@ -246,12 +272,34 @@
 				});
 
 		/**
+		 * Use a separate executor with at most one thread to synchronize
+		 * writing to the config. We write asynchronously since the config
+		 * itself might be on a different file system, which might otherwise
+		 * lead to locking problems.
+		 * <p>
+		 * Writing the config must not use a daemon thread, otherwise we may
+		 * leave an inconsistent state on disk when the JVM shuts down. Use a
+		 * small keep-alive time to avoid delays on shut-down.
+		 * </p>
+		 */
+		private static final Executor SAVE_RUNNER = new ThreadPoolExecutor(0, 1,
+				1L, TimeUnit.MILLISECONDS, new LinkedBlockingQueue<Runnable>(),
+				runnable -> {
+					Thread t = new Thread(runnable,
+							"JGit-FileStoreAttributeWriter-" //$NON-NLS-1$
+							+ threadNumber.getAndIncrement());
+					// Make sure these threads do finish
+					t.setDaemon(false);
+					return t;
+				});
+
+		/**
 		 * Whether FileStore attributes should be determined asynchronously
 		 *
 		 * @param async
 		 *            whether FileStore attributes should be determined
-		 *            asynchronously. If false access to cached attributes may block
-		 *            for some seconds for the first call per FileStore
+		 *            asynchronously. If false access to cached attributes may
+		 *            block for some seconds for the first call per FileStore
 		 * @since 5.6.2
 		 */
 		public static void setBackground(boolean async) {
@@ -294,6 +342,10 @@
 					return cached;
 				}
 				FileStoreAttributes attrs = getFileStoreAttributes(dir);
+				if (attrs == null) {
+					// Don't cache, result might be late
+					return FALLBACK_FILESTORE_ATTRIBUTES;
+				}
 				attrCacheByPath.put(dir, attrs);
 				return attrs;
 			} catch (SecurityException e) {
@@ -367,7 +419,9 @@
 									if (LOG.isDebugEnabled()) {
 										LOG.debug(c.toString());
 									}
-									saveToConfig(s, c);
+									FileStoreAttributes newAttrs = c;
+									SAVE_RUNNER.execute(
+											() -> saveToConfig(s, newAttrs));
 								}
 								attributes = Optional.of(c);
 							} finally {
@@ -382,12 +436,16 @@
 				});
 				// even if measuring in background wait a little - if the result
 				// arrives, it's better than returning the large fallback
-				Optional<FileStoreAttributes> d = background.get() ? f.get(
+				boolean runInBackground = background.get();
+				Optional<FileStoreAttributes> d = runInBackground ? f.get(
 						100, TimeUnit.MILLISECONDS) : f.get();
 				if (d.isPresent()) {
 					return d.get();
+				} else if (runInBackground) {
+					// return null until measurement is finished
+					return null;
 				}
-				// return fallback until measurement is finished
+				// fall through and return fallback
 			} catch (IOException | InterruptedException
 					| ExecutionException | CancellationException e) {
 				LOG.error(e.getMessage(), e);
@@ -467,24 +525,21 @@
 
 		private static Optional<Duration> measureFsTimestampResolution(
 			FileStore s, Path dir) {
-			LOG.debug("{}: start measure timestamp resolution {} in {}", //$NON-NLS-1$
-					Thread.currentThread(), s, dir);
+			if (LOG.isDebugEnabled()) {
+				LOG.debug("{}: start measure timestamp resolution {} in {}", //$NON-NLS-1$
+						Thread.currentThread(), s, dir);
+			}
 			Path probe = dir.resolve(".probe-" + UUID.randomUUID()); //$NON-NLS-1$
 			try {
 				Files.createFile(probe);
-				FileTime t1 = Files.getLastModifiedTime(probe);
-				FileTime t2 = t1;
-				Instant t1i = t1.toInstant();
-				for (long i = 1; t2.compareTo(t1) <= 0; i += 1 + i / 20) {
-					Files.setLastModifiedTime(probe,
-							FileTime.from(t1i.plusNanos(i * 1000)));
-					t2 = Files.getLastModifiedTime(probe);
-				}
-				Duration fsResolution = Duration.between(t1.toInstant(), t2.toInstant());
+				Duration fsResolution = getFsResolution(s, dir, probe);
 				Duration clockResolution = measureClockResolution();
 				fsResolution = fsResolution.plus(clockResolution);
-				LOG.debug("{}: end measure timestamp resolution {} in {}", //$NON-NLS-1$
-						Thread.currentThread(), s, dir);
+				if (LOG.isDebugEnabled()) {
+					LOG.debug(
+							"{}: end measure timestamp resolution {} in {}; got {}", //$NON-NLS-1$
+							Thread.currentThread(), s, dir, fsResolution);
+				}
 				return Optional.of(fsResolution);
 			} catch (SecurityException e) {
 				// Log it here; most likely deleteProbe() below will also run
@@ -501,6 +556,92 @@
 			return Optional.empty();
 		}
 
+		private static Duration getFsResolution(FileStore s, Path dir,
+				Path probe) throws IOException {
+			File probeFile = probe.toFile();
+			FileTime t1 = Files.getLastModifiedTime(probe);
+			Instant t1i = t1.toInstant();
+			FileTime t2;
+			Duration last = FALLBACK_TIMESTAMP_RESOLUTION;
+			long minScale = MINIMUM_RESOLUTION_NANOS;
+			long scale = ONE_SECOND;
+			long high = TimeUnit.MILLISECONDS.toSeconds(last.toMillis());
+			long low = 0;
+			// Try up-front at microsecond and millisecond
+			long[] tries = { ONE_MICROSECOND, ONE_MILLISECOND };
+			for (long interval : tries) {
+				if (interval >= ONE_MILLISECOND) {
+					probeFile.setLastModified(
+							t1i.plusNanos(interval).toEpochMilli());
+				} else {
+					Files.setLastModifiedTime(probe,
+							FileTime.from(t1i.plusNanos(interval)));
+				}
+				t2 = Files.getLastModifiedTime(probe);
+				if (t2.compareTo(t1) > 0) {
+					Duration diff = Duration.between(t1i, t2.toInstant());
+					if (!diff.isZero() && !diff.isNegative()
+							&& diff.compareTo(last) < 0) {
+						scale = interval;
+						high = 1;
+						last = diff;
+						break;
+					}
+				} else {
+					// Makes no sense going below
+					minScale = Math.max(minScale, interval);
+				}
+			}
+			// Binary search loop
+			while (high > low) {
+				long mid = (high + low) / 2;
+				if (mid == 0) {
+					// Smaller than current scale. Adjust scale.
+					long newScale = scale / 10;
+					if (newScale < minScale) {
+						break;
+					}
+					high *= scale / newScale;
+					low *= scale / newScale;
+					scale = newScale;
+					mid = (high + low) / 2;
+				}
+				long delta = mid * scale;
+				if (scale >= ONE_MILLISECOND) {
+					probeFile.setLastModified(
+							t1i.plusNanos(delta).toEpochMilli());
+				} else {
+					Files.setLastModifiedTime(probe,
+							FileTime.from(t1i.plusNanos(delta)));
+				}
+				t2 = Files.getLastModifiedTime(probe);
+				int cmp = t2.compareTo(t1);
+				if (cmp > 0) {
+					high = mid;
+					Duration diff = Duration.between(t1i, t2.toInstant());
+					if (diff.isZero() || diff.isNegative()) {
+						LOG.warn(JGitText.get().logInconsistentFiletimeDiff,
+								Thread.currentThread(), s, dir, t2, t1, diff,
+								last);
+						break;
+					} else if (diff.compareTo(last) > 0) {
+						LOG.warn(JGitText.get().logLargerFiletimeDiff,
+								Thread.currentThread(), s, dir, diff, last);
+						break;
+					}
+					last = diff;
+				} else if (cmp < 0) {
+					LOG.warn(JGitText.get().logSmallerFiletime,
+							Thread.currentThread(), s, dir, t2, t1, last);
+					break;
+				} else {
+					// No discernible difference
+					low = mid + 1;
+				}
+			}
+			return last;
+		}
+
 		private static Duration measureClockResolution() {
 			Duration clockResolution = Duration.ZERO;
 			for (int i = 0; i < 10; i++) {
@@ -1356,7 +1497,7 @@
 		String v;
 		try {
 			v = readPipe(gitExe.getParentFile(),
-				new String[] { "git", "--version" }, //$NON-NLS-1$ //$NON-NLS-2$
+					new String[] { gitExe.getPath(), "--version" }, //$NON-NLS-1$
 				Charset.defaultCharset().name());
 		} catch (CommandFailedException e) {
 			LOG.warn(e.getMessage());
@@ -1375,7 +1516,8 @@
 		String w;
 		try {
 			w = readPipe(gitExe.getParentFile(),
-				new String[] { "git", "config", "--system", "--edit" }, //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$
+					new String[] { gitExe.getPath(), "config", "--system", //$NON-NLS-1$ //$NON-NLS-2$
+							"--edit" }, //$NON-NLS-1$
 				Charset.defaultCharset().name(), env);
 		} catch (CommandFailedException e) {
 			LOG.warn(e.getMessage());
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 c9d2770..fb63dc0 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
@@ -54,6 +54,8 @@
 public class FS_POSIX extends FS {
 	private static final Logger LOG = LoggerFactory.getLogger(FS_POSIX.class);
 
+	private static final String DEFAULT_GIT_LOCATION = "/usr/bin/git"; //$NON-NLS-1$
+
 	private static final int DEFAULT_UMASK = 0022;
 	private volatile int umask = -1;
 
@@ -138,24 +140,46 @@
 		String path = SystemReader.getInstance().getenv("PATH"); //$NON-NLS-1$
 		File gitExe = searchPath(path, "git"); //$NON-NLS-1$
 
-		if (gitExe == null) {
-			if (SystemReader.getInstance().isMacOS()) {
+		if (SystemReader.getInstance().isMacOS()) {
+			if (gitExe == null
+					|| DEFAULT_GIT_LOCATION.equals(gitExe.getPath())) {
 				if (searchPath(path, "bash") != null) { //$NON-NLS-1$
 					// On MacOSX, PATH is shorter when Eclipse is launched from the
 					// Finder than from a terminal. Therefore try to launch bash as a
 					// login shell and search using that.
-					String w;
 					try {
-						w = readPipe(userHome(),
+						String w = readPipe(userHome(),
 							new String[]{"bash", "--login", "-c", "which git"}, // //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$
 							Charset.defaultCharset().name());
+						if (!StringUtils.isEmptyOrNull(w)) {
+							gitExe = new File(w);
+						}
 					} catch (CommandFailedException e) {
 						LOG.warn(e.getMessage());
-						return null;
 					}
-					if (!StringUtils.isEmptyOrNull(w)) {
-						gitExe = new File(w);
+				}
+			}
+			if (gitExe != null
+					&& DEFAULT_GIT_LOCATION.equals(gitExe.getPath())) {
+				// If we still have the default git exe, it's an XCode wrapper
+				// that may prompt the user to install the XCode command line
+				// tools if not already present. Avoid the prompt by returning
+				// null if no XCode git is there.
+				try {
+					String w = readPipe(userHome(),
+							new String[] { "xcode-select", "-p" }, //$NON-NLS-1$ //$NON-NLS-2$
+							Charset.defaultCharset().name());
+					if (StringUtils.isEmptyOrNull(w)) {
+						gitExe = null;
+					} else {
+						File realGitExe = new File(new File(w),
+								DEFAULT_GIT_LOCATION.substring(1));
+						if (!realGitExe.exists()) {
+							gitExe = null;
+						}
 					}
+				} catch (CommandFailedException e) {
+					gitExe = null;
 				}
 			}
 		}
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/util/SshSupport.java b/org.eclipse.jgit/src/org/eclipse/jgit/util/SshSupport.java
index a151cd3..e297041 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/util/SshSupport.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/util/SshSupport.java
@@ -11,6 +11,7 @@
 
 import java.io.IOException;
 import java.text.MessageFormat;
+import java.util.concurrent.TimeUnit;
 
 import org.eclipse.jgit.annotations.Nullable;
 import org.eclipse.jgit.errors.CommandFailedException;
@@ -61,11 +62,21 @@
 		CommandFailedException failure = null;
 		@SuppressWarnings("resource")
 		MessageWriter stderr = new MessageWriter();
+		@SuppressWarnings("resource")
+		MessageWriter stdout = new MessageWriter();
 		String out;
-		try (MessageWriter stdout = new MessageWriter()) {
+		try {
+			long start = System.nanoTime();
 			session = SshSessionFactory.getInstance().getSession(sshUri,
 					provider, fs, 1000 * timeout);
-			process = session.exec(command, 0);
+			int commandTimeout = timeout;
+			if (timeout > 0) {
+				commandTimeout = checkTimeout(command, timeout, start);
+			}
+			process = session.exec(command, commandTimeout);
+			if (timeout > 0) {
+				commandTimeout = checkTimeout(command, timeout, start);
+			}
 			errorThread = new StreamCopyThread(process.getErrorStream(),
 					stderr.getRawStream());
 			errorThread.start();
@@ -73,9 +84,15 @@
 					stdout.getRawStream());
 			outThread.start();
 			try {
-				// waitFor with timeout has a bug - JSch' exitValue() throws the
-				// wrong exception type :(
-				if (process.waitFor() == 0) {
+				boolean finished = false;
+				if (timeout <= 0) {
+					process.waitFor();
+					finished = true;
+				} else {
+					finished = process.waitFor(commandTimeout,
+							TimeUnit.SECONDS);
+				}
+				if (finished) {
 					out = stdout.toString();
 				} else {
 					out = null; // still running after timeout
@@ -103,15 +120,26 @@
 				}
 			}
 			if (process != null) {
-				if (process.exitValue() != 0) {
-					failure = new CommandFailedException(process.exitValue(),
+				try {
+					if (process.exitValue() != 0) {
+						failure = new CommandFailedException(
+								process.exitValue(),
+								MessageFormat.format(
+										JGitText.get().sshCommandFailed,
+										command, stderr.toString()));
+					}
+					// It was successful after all
+					out = stdout.toString();
+				} catch (IllegalThreadStateException e) {
+					failure = new CommandFailedException(0,
 							MessageFormat.format(
-							JGitText.get().sshCommandFailed, command,
-							stderr.toString()));
+									JGitText.get().sshCommandTimeout, command,
+									Integer.valueOf(timeout)));
 				}
 				process.destroy();
 			}
 			stderr.close();
+			stdout.close();
 			if (session != null) {
 				SshSessionFactory.getInstance().releaseSession(session);
 			}
@@ -122,4 +150,17 @@
 		return out;
 	}
 
+	private static int checkTimeout(String command, int timeout, long since)
+			throws CommandFailedException {
+		long elapsed = System.nanoTime() - since;
+		int newTimeout = timeout
+				- (int) TimeUnit.NANOSECONDS.toSeconds(elapsed);
+		if (newTimeout <= 0) {
+			// All time used up for connecting the session
+			throw new CommandFailedException(0,
+					MessageFormat.format(JGitText.get().sshCommandTimeout,
+							command, Integer.valueOf(timeout)));
+		}
+		return newTimeout;
+	}
 }
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 bcb8380..447f417 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/util/SystemReader.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/util/SystemReader.java
@@ -17,7 +17,6 @@
 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;
@@ -116,11 +115,9 @@
 						.getAbsolutePath();
 			}
 			try {
-				Path xdgHomePath = Paths.get(configHomePath);
-				Files.createDirectories(xdgHomePath);
-				return xdgHomePath;
-			} catch (IOException | InvalidPathException e) {
-				LOG.error(JGitText.get().createXDGConfigHomeFailed,
+				return Paths.get(configHomePath);
+			} catch (InvalidPathException e) {
+				LOG.error(JGitText.get().logXDGConfigHomeInvalid,
 						configHomePath, e);
 			}
 			return null;
@@ -130,16 +127,9 @@
 		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);
-				}
+				Path configPath = xdgPath.resolve("jgit") //$NON-NLS-1$
+						.resolve(Constants.CONFIG);
+				return new FileBasedConfig(parent, configPath.toFile(), fs);
 			}
 			return new FileBasedConfig(parent,
 					new File(fs.userHome(), ".jgitconfig"), fs); //$NON-NLS-1$
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/util/io/AutoLFInputStream.java b/org.eclipse.jgit/src/org/eclipse/jgit/util/io/AutoLFInputStream.java
index 8c9b1bf..0e335a9 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/util/io/AutoLFInputStream.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/util/io/AutoLFInputStream.java
@@ -1,6 +1,6 @@
 /*
  * Copyright (C) 2010, 2013 Marc Strapetz <marc.strapetz@syntevo.com>
- * Copyright (C) 2015, Ivan Motsch <ivan.motsch@bsiag.com> and others
+ * Copyright (C) 2015, 2020 Ivan Motsch <ivan.motsch@bsiag.com> and others
  *
  * This program and the accompanying materials are made available under the
  * terms of the Eclipse Distribution License v. 1.0 which is available at
@@ -13,26 +13,58 @@
 
 import java.io.IOException;
 import java.io.InputStream;
+import java.util.Arrays;
+import java.util.EnumSet;
+import java.util.Set;
 
 import org.eclipse.jgit.diff.RawText;
 
 /**
  * An InputStream that normalizes CRLF to LF.
- *
- * Existing single CR are not changed to LF, but retained as is.
- *
- * Optionally, a binary check on the first 8000 bytes is performed and in case
- * of binary files, canonicalization is turned off (for the complete file).
  * <p>
- * This is the former EolCanonicalizingInputStream with a new name in order to
- * have same naming for all LF / CRLF streams
+ * Existing single CR are not changed to LF but are retained as is.
+ * </p>
+ * <p>
+ * Optionally, a binary check on the first 8kB is performed and in case of
+ * binary files, canonicalization is turned off (for the complete file). If
+ * binary checking determines that the input is CR/LF-delimited text and the
+ * stream has been created for checkout, canonicalization is also turned off.
+ * </p>
  *
  * @since 4.3
  */
 public class AutoLFInputStream extends InputStream {
+
+	// This is the former EolCanonicalizingInputStream with a new name in order
+	// to have same naming for all LF / CRLF streams.
+
+	/**
+	 * Flags for controlling auto-detection of binary vs. text content (for
+	 * text=auto).
+	 *
+	 * @since 5.9
+	 */
+	public enum StreamFlag {
+		/**
+		 * Check the first 8kB for binary content and switch off
+		 * canonicalization off for the whole file if so.
+		 */
+		DETECT_BINARY,
+		/**
+		 * If {@link #DETECT_BINARY} is set, throw an {@link IsBinaryException}
+		 * if binary content is detected.
+		 */
+		ABORT_IF_BINARY,
+		/**
+		 * If {@link #DETECT_BINARY} is set and content is found to be CR-LF
+		 * delimited text, switch off canonicalization.
+		 */
+		FOR_CHECKOUT
+	}
+
 	private final byte[] single = new byte[1];
 
-	private final byte[] buf = new byte[8096];
+	private final byte[] buf = new byte[8 * 1024];
 
 	private final InputStream in;
 
@@ -40,11 +72,23 @@
 
 	private int ptr;
 
+	/**
+	 * Set to {@code true} if no CR/LF processing is to be done: if the input is
+	 * binary data, or CR/LF-delimited text and {@link StreamFlag#FOR_CHECKOUT}
+	 * was given.
+	 */
+	private boolean passAsIs;
+
+	/**
+	 * Set to {@code true} if the input was detected to be binary data.
+	 */
 	private boolean isBinary;
 
 	private boolean detectBinary;
 
-	private boolean abortIfBinary;
+	private final boolean abortIfBinary;
+
+	private final boolean forCheckout;
 
 	/**
 	 * A special exception thrown when {@link AutoLFInputStream} is told to
@@ -62,20 +106,64 @@
 	}
 
 	/**
-	 * Creates a new InputStream, wrapping the specified stream
+	 * Factory method for creating an {@link AutoLFInputStream} with the
+	 * specified {@link StreamFlag flags}.
+	 *
+	 * @param in
+	 *            raw input stream
+	 * @param flags
+	 *            {@link StreamFlag}s controlling the stream behavior
+	 * @return a new {@link AutoLFInputStream}
+	 * @since 5.9
+	 */
+	public static AutoLFInputStream create(InputStream in,
+			StreamFlag... flags) {
+		if (flags == null) {
+			return new AutoLFInputStream(in, null);
+		}
+		EnumSet<StreamFlag> set = EnumSet.noneOf(StreamFlag.class);
+		set.addAll(Arrays.asList(flags));
+		return new AutoLFInputStream(in, set);
+	}
+
+	/**
+	 * Creates a new InputStream, wrapping the specified stream.
+	 *
+	 * @param in
+	 *            raw input stream
+	 * @param flags
+	 *            {@link StreamFlag}s controlling the stream behavior;
+	 *            {@code null} is treated as an empty set
+	 * @since 5.9
+	 */
+	public AutoLFInputStream(InputStream in, Set<StreamFlag> flags) {
+		this.in = in;
+		this.detectBinary = flags != null
+				&& flags.contains(StreamFlag.DETECT_BINARY);
+		this.abortIfBinary = flags != null
+				&& flags.contains(StreamFlag.ABORT_IF_BINARY);
+		this.forCheckout = flags != null
+				&& flags.contains(StreamFlag.FOR_CHECKOUT);
+	}
+
+	/**
+	 * Creates a new InputStream, wrapping the specified stream.
 	 *
 	 * @param in
 	 *            raw input stream
 	 * @param detectBinary
 	 *            whether binaries should be detected
 	 * @since 2.0
+	 * @deprecated since 5.9, use {@link #create(InputStream, StreamFlag...)}
+	 *             instead
 	 */
+	@Deprecated
 	public AutoLFInputStream(InputStream in, boolean detectBinary) {
 		this(in, detectBinary, false);
 	}
 
 	/**
-	 * Creates a new InputStream, wrapping the specified stream
+	 * Creates a new InputStream, wrapping the specified stream.
 	 *
 	 * @param in
 	 *            raw input stream
@@ -84,12 +172,16 @@
 	 * @param abortIfBinary
 	 *            throw an IOException if the file is binary
 	 * @since 3.3
+	 * @deprecated since 5.9, use {@link #create(InputStream, StreamFlag...)}
+	 *             instead
 	 */
+	@Deprecated
 	public AutoLFInputStream(InputStream in, boolean detectBinary,
 			boolean abortIfBinary) {
 		this.in = in;
 		this.detectBinary = detectBinary;
 		this.abortIfBinary = abortIfBinary;
+		this.forCheckout = false;
 	}
 
 	/** {@inheritDoc} */
@@ -118,7 +210,7 @@
 			}
 
 			byte b = buf[ptr++];
-			if (isBinary || b != '\r') {
+			if (passAsIs || b != '\r') {
 				// Logic for binary files ends here
 				bs[i++] = b;
 				continue;
@@ -170,9 +262,14 @@
 		}
 		if (detectBinary) {
 			isBinary = RawText.isBinary(buf, cnt);
+			passAsIs = isBinary;
 			detectBinary = false;
-			if (isBinary && abortIfBinary)
+			if (isBinary && abortIfBinary) {
 				throw new IsBinaryException();
+			}
+			if (!passAsIs && forCheckout) {
+				passAsIs = RawText.isCrLfText(buf, cnt);
+			}
 		}
 		ptr = 0;
 		return true;
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/util/io/AutoLFOutputStream.java b/org.eclipse.jgit/src/org/eclipse/jgit/util/io/AutoLFOutputStream.java
index e235aa0..195fdb4 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/util/io/AutoLFOutputStream.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/util/io/AutoLFOutputStream.java
@@ -1,43 +1,12 @@
 /*
  * Copyright (C) 2015, Ivan Motsch <ivan.motsch@bsiag.com>
+ * Copyright (C) 2020, Thomas Wolf <thomas.wolf@paranor.ch> and others
  *
- * 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
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Distribution License v. 1.0 which is available at
+ * https://www.eclipse.org/org/documents/edl-v10.php.
  *
- * 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.
+ * SPDX-License-Identifier: BSD-3-Clause
  */
 
 package org.eclipse.jgit.util.io;
@@ -49,11 +18,15 @@
 
 /**
  * An OutputStream that reduces CRLF to LF.
- *
+ * <p>
  * Existing single CR are not changed to LF, but retained as is.
- *
+ * </p>
+ * <p>
  * A binary check on the first 8000 bytes is performed and in case of binary
- * files, canonicalization is turned off (for the complete file).
+ * files, canonicalization is turned off (for the complete file). If the binary
+ * check determines that the input is not binary but text with CR/LF,
+ * canonicalization is also turned off.
+ * </p>
  *
  * @since 4.3
  */
@@ -76,9 +49,7 @@
 	private boolean isBinary;
 
 	/**
-	 * <p>
 	 * Constructor for AutoLFOutputStream.
-	 * </p>
 	 *
 	 * @param out
 	 *            an {@link java.io.OutputStream} object.
@@ -88,9 +59,7 @@
 	}
 
 	/**
-	 * <p>
 	 * Constructor for AutoLFOutputStream.
-	 * </p>
 	 *
 	 * @param out
 	 *            an {@link java.io.OutputStream} object.
@@ -123,14 +92,11 @@
 	public void write(byte[] b, int startOff, int startLen)
 			throws IOException {
 		final int overflow = buffer(b, startOff, startLen);
-		if (overflow < 0) {
+		if (overflow <= 0) {
 			return;
 		}
 		final int off = startOff + startLen - overflow;
 		final int len = overflow;
-		if (len == 0) {
-			return;
-		}
 		int lastw = off;
 		if (isBinary) {
 			out.write(b, off, len);
@@ -190,6 +156,9 @@
 	private void decideMode() throws IOException {
 		if (detectBinary) {
 			isBinary = RawText.isBinary(binbuf, binbufcnt);
+			if (!isBinary) {
+				isBinary = RawText.isCrLfText(binbuf, binbufcnt);
+			}
 			detectBinary = false;
 		}
 		int cachedLen = binbufcnt;
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/util/io/EolStreamTypeUtil.java b/org.eclipse.jgit/src/org/eclipse/jgit/util/io/EolStreamTypeUtil.java
index c33c869..88ee2ae 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/util/io/EolStreamTypeUtil.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/util/io/EolStreamTypeUtil.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2015, Ivan Motsch <ivan.motsch@bsiag.com> and others
+ * Copyright (C) 2015, 2020 Ivan Motsch <ivan.motsch@bsiag.com> and others
  *
  * This program and the accompanying materials are made available under the
  * terms of the Eclipse Distribution License v. 1.0 which is available at
@@ -12,12 +12,14 @@
 
 import java.io.InputStream;
 import java.io.OutputStream;
+import java.util.EnumSet;
 
 import org.eclipse.jgit.attributes.Attributes;
 import org.eclipse.jgit.lib.CoreConfig.EolStreamType;
 import org.eclipse.jgit.treewalk.TreeWalk.OperationType;
 import org.eclipse.jgit.treewalk.WorkingTreeOptions;
 import org.eclipse.jgit.util.SystemReader;
+import org.eclipse.jgit.util.io.AutoLFInputStream.StreamFlag;
 
 /**
  * Utility used to create input and output stream wrappers for
@@ -71,7 +73,7 @@
 
 	/**
 	 * Wrap the input stream depending on
-	 * {@link org.eclipse.jgit.lib.CoreConfig.EolStreamType}
+	 * {@link org.eclipse.jgit.lib.CoreConfig.EolStreamType}.
 	 *
 	 * @param in
 	 *            original stream
@@ -82,15 +84,38 @@
 	 */
 	public static InputStream wrapInputStream(InputStream in,
 			EolStreamType conversion) {
+		return wrapInputStream(in, conversion, false);
+	}
+
+	/**
+	 * Wrap the input stream depending on
+	 * {@link org.eclipse.jgit.lib.CoreConfig.EolStreamType}.
+	 *
+	 * @param in
+	 *            original stream
+	 * @param conversion
+	 *            to be performed
+	 * @param forCheckout
+	 *            whether the stream is for checking out from the repository
+	 * @return the converted stream depending on
+	 *         {@link org.eclipse.jgit.lib.CoreConfig.EolStreamType}
+	 * @since 5.9
+	 */
+	public static InputStream wrapInputStream(InputStream in,
+			EolStreamType conversion, boolean forCheckout) {
 		switch (conversion) {
 		case TEXT_CRLF:
 			return new AutoCRLFInputStream(in, false);
 		case TEXT_LF:
-			return new AutoLFInputStream(in, false);
+			return AutoLFInputStream.create(in);
 		case AUTO_CRLF:
 			return new AutoCRLFInputStream(in, true);
 		case AUTO_LF:
-			return new AutoLFInputStream(in, true);
+			EnumSet<StreamFlag> flags = forCheckout
+					? EnumSet.of(StreamFlag.DETECT_BINARY,
+							StreamFlag.FOR_CHECKOUT)
+					: EnumSet.of(StreamFlag.DETECT_BINARY);
+			return new AutoLFInputStream(in, flags);
 		default:
 			return in;
 		}
@@ -98,7 +123,7 @@
 
 	/**
 	 * Wrap the output stream depending on
-	 * {@link org.eclipse.jgit.lib.CoreConfig.EolStreamType}
+	 * {@link org.eclipse.jgit.lib.CoreConfig.EolStreamType}.
 	 *
 	 * @param out
 	 *            original stream
diff --git a/pom.xml b/pom.xml
index 84aa576..a9d5a13 100644
--- a/pom.xml
+++ b/pom.xml
@@ -18,7 +18,7 @@
   <groupId>org.eclipse.jgit</groupId>
   <artifactId>org.eclipse.jgit-parent</artifactId>
   <packaging>pom</packaging>
-  <version>5.8.2-SNAPSHOT</version>
+  <version>5.9.1-SNAPSHOT</version>
 
   <name>JGit - Parent</name>
   <url>${jgit-url}</url>
@@ -33,13 +33,13 @@
   </description>
 
   <scm>
-    <url>http://git.eclipse.org/c/jgit/jgit.git/</url>
+    <url>https://git.eclipse.org/r/plugins/gitiles/jgit/jgit</url>
     <connection>scm:git:https://git.eclipse.org/r/jgit/jgit</connection>
   </scm>
 
   <ciManagement>
-    <system>hudson</system>
-    <url>https://hudson.eclipse.org/jgit/</url>
+    <system>Jenkins</system>
+    <url>https://ci.eclipse.org/jgit</url>
   </ciManagement>
 
   <developers>
@@ -140,7 +140,7 @@
   </licenses>
 
   <properties>
-    <jgit-url>http://www.eclipse.org/jgit/</jgit-url>
+    <jgit-url>https://www.eclipse.org/jgit/</jgit-url>
     <jgit-copyright>Copyright (c) 2005, 2009 Shawn Pearce, Robin Rosenberg, et.al.</jgit-copyright>
     <jgit.website.url>scp://build.eclipse.org/home/data/httpd/download.eclipse.org/jgit/site/${project.version}/</jgit.website.url>
 
@@ -151,7 +151,7 @@
     <maven.compiler.target>1.8</maven.compiler.target>
     <bundle-manifest>${project.build.directory}/META-INF/MANIFEST.MF</bundle-manifest>
 
-    <jgit-last-release-version>5.7.0.202003110725-r</jgit-last-release-version>
+    <jgit-last-release-version>5.8.0.202006091008-r</jgit-last-release-version>
     <apache-sshd-version>2.4.0</apache-sshd-version>
     <jsch-version>0.1.55</jsch-version>
     <jzlib-version>1.1.1</jzlib-version>
@@ -162,7 +162,7 @@
     <commons-compress-version>1.19</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.28.v20200408</jetty-version>
+    <jetty-version>9.4.30.v20200611</jetty-version>
     <japicmp-version>0.14.3</japicmp-version>
     <httpclient-version>4.5.10</httpclient-version>
     <httpcore-version>4.4.12</httpcore-version>
@@ -172,12 +172,13 @@
     <tycho-extras-version>1.7.0</tycho-extras-version>
     <gson-version>2.8.2</gson-version>
     <bouncycastle-version>1.65</bouncycastle-version>
-    <spotbugs-maven-plugin-version>4.0.0</spotbugs-maven-plugin-version>
+    <spotbugs-maven-plugin-version>4.0.4</spotbugs-maven-plugin-version>
     <maven-project-info-reports-plugin-version>3.1.0</maven-project-info-reports-plugin-version>
     <maven-jxr-plugin-version>3.0.0</maven-jxr-plugin-version>
     <maven-surefire-plugin-version>3.0.0-M4</maven-surefire-plugin-version>
     <maven-surefire-report-plugin-version>${maven-surefire-plugin-version}</maven-surefire-report-plugin-version>
     <maven-compiler-plugin-version>3.8.1</maven-compiler-plugin-version>
+    <plexus-compiler-version>2.8.8</plexus-compiler-version>
 
     <!-- Properties to enable jacoco code coverage analysis -->
     <sonar.core.codeCoveragePlugin>jacoco</sonar.core.codeCoveragePlugin>
@@ -275,7 +276,7 @@
         <plugin>
           <groupId>org.codehaus.mojo</groupId>
           <artifactId>build-helper-maven-plugin</artifactId>
-          <version>3.1.0</version>
+          <version>3.2.0</version>
         </plugin>
 
         <plugin>
@@ -341,7 +342,7 @@
         <plugin>
           <groupId>org.apache.maven.plugins</groupId>
           <artifactId>maven-site-plugin</artifactId>
-          <version>3.9.0</version>
+          <version>3.9.1</version>
           <dependencies>
             <dependency><!-- add support for ssh/scp -->
               <groupId>org.apache.maven.wagon</groupId>
@@ -383,7 +384,7 @@
         <plugin>
           <groupId>org.apache.maven.plugins</groupId>
           <artifactId>maven-resources-plugin</artifactId>
-          <version>3.1.0</version>
+          <version>3.2.0</version>
         </plugin>
         <plugin>
           <groupId>org.springframework.boot</groupId>
@@ -846,12 +847,12 @@
               <dependency>
                 <groupId>org.codehaus.plexus</groupId>
                 <artifactId>plexus-compiler-javac</artifactId>
-                <version>2.8.6</version>
+                <version>${plexus-compiler-version}</version>
               </dependency>
               <dependency>
                 <groupId>org.codehaus.plexus</groupId>
                 <artifactId>plexus-compiler-javac-errorprone</artifactId>
-                <version>2.8.6</version>
+                <version>${plexus-compiler-version}</version>
               </dependency>
               <!-- override plexus-compiler-javac-errorprone's dependency on
                   Error Prone with the latest version -->
@@ -890,12 +891,12 @@
               <dependency>
                 <groupId>org.codehaus.plexus</groupId>
                 <artifactId>plexus-compiler-eclipse</artifactId>
-                <version>2.8.6</version>
+                <version>${plexus-compiler-version}</version>
               </dependency>
               <dependency>
                 <groupId>org.eclipse.jdt</groupId>
                 <artifactId>ecj</artifactId>
-                <version>3.21.0</version>
+                <version>3.22.0</version>
               </dependency>
             </dependencies>
           </plugin>
@@ -924,12 +925,6 @@
           <plugin>
             <groupId>org.eclipse.tycho.extras</groupId>
             <artifactId>tycho-pack200a-plugin</artifactId>
-            <!-- TODO remove this configuration when https://git.eclipse.org/r/#/c/16027 is available -->
-            <configuration>
-              <supportedProjectTypes>
-                <supportedProjectType>jar</supportedProjectType>
-              </supportedProjectTypes>
-            </configuration>
             <executions>
               <execution>
                 <id>pack200-normalize</id>
@@ -956,12 +951,6 @@
           <plugin>
             <groupId>org.eclipse.tycho.extras</groupId>
             <artifactId>tycho-pack200b-plugin</artifactId>
-            <!-- TODO remove this configuration when https://git.eclipse.org/r/#/c/16027 is available -->
-            <configuration>
-              <supportedProjectTypes>
-                <supportedProjectType>jar</supportedProjectType>
-              </supportedProjectTypes>
-            </configuration>
             <executions>
               <execution>
                 <id>pack200-pack</id>
diff --git a/tools/workspace_status.py b/tools/workspace_status.py
new file mode 100644
index 0000000..ca9e0a9
--- /dev/null
+++ b/tools/workspace_status.py
@@ -0,0 +1,45 @@
+#!/usr/bin/env python
+# Copyright (C) 2020, David Ostrovsky <david@ostrovsky.org> and others
+#
+# This program and the accompanying materials are made available under the
+# terms of the Eclipse Distribution License v. 1.0 which is available at
+# http://www.eclipse.org/org/documents/edl-v10.php.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+
+# This script will be run by bazel when the build process starts to
+# generate key-value information that represents the status of the
+# workspace. The output should be like
+#
+# KEY1 VALUE1
+# KEY2 VALUE2
+#
+# If the script exits with non-zero code, it's considered as a failure
+# and the output will be discarded.
+
+from __future__ import print_function
+import os
+import subprocess
+import sys
+
+ROOT = os.path.abspath(__file__)
+while not os.path.exists(os.path.join(ROOT, 'WORKSPACE')):
+    ROOT = os.path.dirname(ROOT)
+CMD = ['git', 'describe', '--always', '--match', 'v[0-9].*', '--dirty']
+
+
+def revision(directory, parent):
+    try:
+        os.chdir(directory)
+        return subprocess.check_output(CMD).strip().decode("utf-8")
+    except OSError as err:
+        print('could not invoke git: %s' % err, file=sys.stderr)
+        sys.exit(1)
+    except subprocess.CalledProcessError as err:
+        # ignore "not a git repository error" to report unknown version
+        return None
+    finally:
+        os.chdir(parent)
+
+
+print("STABLE_BUILD_JGIT_LABEL %s" % revision(ROOT, ROOT))