Merge branch 'master' into next

* master: (47 commits)
  Fix @since from commit 64d0aaa2
  Prepare 5.13.0-SNAPSHOT builds
  Prepare 5.12.1-SNAPSHOT builds
  Teach independent negotiation (no pack file) using an option "wait-for-done"
  JGit v5.12.0.202106070339-r
  [license-check] Update list of project dependencies
  [errorprone] Fix warning InputStreamSlowMultibyteRead
  [errorprone] Make operator precedence explicit in OpenSshConfigFile
  Update jetty to 9.4.41.v20210516
  Prepare 5.1.17-SNAPSHOT builds
  JGit v5.1.16.202106041830-r
  Update Orbit to R20210602031627
  Prepare 5.12.0-SNAPSHOT builds
  Fixing visibility for HostEntry constructors.
  JGit v5.12.0.202106021050-rc1
  Prepare 5.12.0-SNAPSHOT builds
  JGit v5.12.0.202106011439-rc1
  Clarify operator precedence to fix errorprone error
  Prepare 5.12.0-SNAPSHOT builds
  Update Orbit to S20210518003616 and ant to 1.10.10.v20210426-1926
  ...

Change-Id: I76a1f155201648a62df11a41a9e02d97f522d00f
diff --git a/DEPENDENCIES b/DEPENDENCIES
index bffe3d9..9dbca62 100644
--- a/DEPENDENCIES
+++ b/DEPENDENCIES
@@ -12,8 +12,8 @@
 maven/mavencentral/net.bytebuddy/byte-buddy/1.9.0, Apache-2.0, approved, clearlydefined
 maven/mavencentral/net.i2p.crypto/eddsa/0.3.0, CC0, approved, CQ17804
 maven/mavencentral/net.sf.jopt-simple/jopt-simple/4.6, MIT, approved, clearlydefined
-maven/mavencentral/org.apache.ant/ant-launcher/1.10.8, Apache-2.0 AND W3C AND LicenseRef-Public-Domain, approved, CQ15560
-maven/mavencentral/org.apache.ant/ant/1.10.8, Apache-2.0 AND W3C AND LicenseRef-Public-Domain, approved, CQ15560
+maven/mavencentral/org.apache.ant/ant-launcher/1.10.10, Apache-2.0 AND W3C AND LicenseRef-Public-Domain, approved, CQ15560
+maven/mavencentral/org.apache.ant/ant/1.10.10, Apache-2.0 AND W3C AND LicenseRef-Public-Domain, approved, CQ15560
 maven/mavencentral/org.apache.commons/commons-compress/1.19, Apache-2.0, approved, clearlydefined
 maven/mavencentral/org.apache.commons/commons-math3/3.2, Apache-2.0, approved, clearlydefined
 maven/mavencentral/org.apache.httpcomponents/httpclient/4.5.13, Apache-2.0, approved, CQ22761
@@ -26,35 +26,35 @@
 maven/mavencentral/org.bouncycastle/bcpg-jdk15on/1.65, Apache-2.0, approved, CQ21975
 maven/mavencentral/org.bouncycastle/bcpkix-jdk15on/1.65, MIT AND LicenseRef-Public-Domain, approved, CQ21976
 maven/mavencentral/org.bouncycastle/bcprov-jdk15on/1.65.01, MIT AND LicenseRef-Public-Domain, approved, CQ21977
-maven/mavencentral/org.eclipse.jetty/jetty-http/9.4.36.v20210114, , approved, eclipse
-maven/mavencentral/org.eclipse.jetty/jetty-io/9.4.36.v20210114, , approved, eclipse
-maven/mavencentral/org.eclipse.jetty/jetty-security/9.4.36.v20210114, , approved, eclipse
-maven/mavencentral/org.eclipse.jetty/jetty-server/9.4.36.v20210114, , approved, eclipse
-maven/mavencentral/org.eclipse.jetty/jetty-servlet/9.4.36.v20210114, , approved, eclipse
-maven/mavencentral/org.eclipse.jetty/jetty-util-ajax/9.4.36.v20210114, , approved, eclipse
-maven/mavencentral/org.eclipse.jetty/jetty-util/9.4.36.v20210114, , approved, eclipse
-maven/mavencentral/org.eclipse.jgit/org.eclipse.jgit.ant.test/5.11.0-SNAPSHOT, , approved, eclipse
-maven/mavencentral/org.eclipse.jgit/org.eclipse.jgit.ant/5.11.0-SNAPSHOT, , approved, eclipse
-maven/mavencentral/org.eclipse.jgit/org.eclipse.jgit.archive/5.11.0-SNAPSHOT, , approved, eclipse
-maven/mavencentral/org.eclipse.jgit/org.eclipse.jgit.gpg.bc/5.11.0-SNAPSHOT, , approved, eclipse
-maven/mavencentral/org.eclipse.jgit/org.eclipse.jgit.http.apache/5.11.0-SNAPSHOT, , approved, eclipse
-maven/mavencentral/org.eclipse.jgit/org.eclipse.jgit.http.server/5.11.0-SNAPSHOT, , approved, eclipse
-maven/mavencentral/org.eclipse.jgit/org.eclipse.jgit.http.test/5.11.0-SNAPSHOT, , approved, eclipse
-maven/mavencentral/org.eclipse.jgit/org.eclipse.jgit.junit.http/5.11.0-SNAPSHOT, , approved, eclipse
-maven/mavencentral/org.eclipse.jgit/org.eclipse.jgit.junit.ssh/5.11.0-SNAPSHOT, , approved, eclipse
-maven/mavencentral/org.eclipse.jgit/org.eclipse.jgit.junit/5.11.0-SNAPSHOT, , approved, eclipse
-maven/mavencentral/org.eclipse.jgit/org.eclipse.jgit.lfs.server.test/5.11.0-SNAPSHOT, , approved, eclipse
-maven/mavencentral/org.eclipse.jgit/org.eclipse.jgit.lfs.server/5.11.0-SNAPSHOT, , approved, eclipse
-maven/mavencentral/org.eclipse.jgit/org.eclipse.jgit.lfs.test/5.11.0-SNAPSHOT, , approved, eclipse
-maven/mavencentral/org.eclipse.jgit/org.eclipse.jgit.lfs/5.11.0-SNAPSHOT, , approved, eclipse
-maven/mavencentral/org.eclipse.jgit/org.eclipse.jgit.pgm.test/5.11.0-SNAPSHOT, , approved, eclipse
-maven/mavencentral/org.eclipse.jgit/org.eclipse.jgit.pgm/5.11.0-SNAPSHOT, , approved, eclipse
-maven/mavencentral/org.eclipse.jgit/org.eclipse.jgit.ssh.apache.test/5.11.0-SNAPSHOT, , approved, eclipse
-maven/mavencentral/org.eclipse.jgit/org.eclipse.jgit.ssh.apache/5.11.0-SNAPSHOT, , approved, eclipse
-maven/mavencentral/org.eclipse.jgit/org.eclipse.jgit.ssh.jsch/5.11.0-SNAPSHOT, , approved, eclipse
-maven/mavencentral/org.eclipse.jgit/org.eclipse.jgit.test/5.11.0-SNAPSHOT, , approved, eclipse
-maven/mavencentral/org.eclipse.jgit/org.eclipse.jgit.ui/5.11.0-SNAPSHOT, , approved, eclipse
-maven/mavencentral/org.eclipse.jgit/org.eclipse.jgit/5.11.0-SNAPSHOT, , approved, eclipse
+maven/mavencentral/org.eclipse.jetty/jetty-http/9.4.41.v20210516, , approved, eclipse
+maven/mavencentral/org.eclipse.jetty/jetty-io/9.4.41.v20210516, , approved, eclipse
+maven/mavencentral/org.eclipse.jetty/jetty-security/9.4.41.v20210516, , approved, eclipse
+maven/mavencentral/org.eclipse.jetty/jetty-server/9.4.41.v20210516, , approved, eclipse
+maven/mavencentral/org.eclipse.jetty/jetty-servlet/9.4.41.v20210516, , approved, eclipse
+maven/mavencentral/org.eclipse.jetty/jetty-util-ajax/9.4.41.v20210516, , approved, eclipse
+maven/mavencentral/org.eclipse.jetty/jetty-util/9.4.41.v20210516, , approved, eclipse
+maven/mavencentral/org.eclipse.jgit/org.eclipse.jgit.ant.test/5.12.0-SNAPSHOT, , approved, eclipse
+maven/mavencentral/org.eclipse.jgit/org.eclipse.jgit.ant/5.12.0-SNAPSHOT, , approved, eclipse
+maven/mavencentral/org.eclipse.jgit/org.eclipse.jgit.archive/5.12.0-SNAPSHOT, , approved, eclipse
+maven/mavencentral/org.eclipse.jgit/org.eclipse.jgit.gpg.bc/5.12.0-SNAPSHOT, , approved, eclipse
+maven/mavencentral/org.eclipse.jgit/org.eclipse.jgit.http.apache/5.12.0-SNAPSHOT, , approved, eclipse
+maven/mavencentral/org.eclipse.jgit/org.eclipse.jgit.http.server/5.12.0-SNAPSHOT, , approved, eclipse
+maven/mavencentral/org.eclipse.jgit/org.eclipse.jgit.http.test/5.12.0-SNAPSHOT, , approved, eclipse
+maven/mavencentral/org.eclipse.jgit/org.eclipse.jgit.junit.http/5.12.0-SNAPSHOT, , approved, eclipse
+maven/mavencentral/org.eclipse.jgit/org.eclipse.jgit.junit.ssh/5.12.0-SNAPSHOT, , approved, eclipse
+maven/mavencentral/org.eclipse.jgit/org.eclipse.jgit.junit/5.12.0-SNAPSHOT, , approved, eclipse
+maven/mavencentral/org.eclipse.jgit/org.eclipse.jgit.lfs.server.test/5.12.0-SNAPSHOT, , approved, eclipse
+maven/mavencentral/org.eclipse.jgit/org.eclipse.jgit.lfs.server/5.12.0-SNAPSHOT, , approved, eclipse
+maven/mavencentral/org.eclipse.jgit/org.eclipse.jgit.lfs.test/5.12.0-SNAPSHOT, , approved, eclipse
+maven/mavencentral/org.eclipse.jgit/org.eclipse.jgit.lfs/5.12.0-SNAPSHOT, , approved, eclipse
+maven/mavencentral/org.eclipse.jgit/org.eclipse.jgit.pgm.test/5.12.0-SNAPSHOT, , approved, eclipse
+maven/mavencentral/org.eclipse.jgit/org.eclipse.jgit.pgm/5.12.0-SNAPSHOT, , approved, eclipse
+maven/mavencentral/org.eclipse.jgit/org.eclipse.jgit.ssh.apache.test/5.12.0-SNAPSHOT, , approved, eclipse
+maven/mavencentral/org.eclipse.jgit/org.eclipse.jgit.ssh.apache/5.12.0-SNAPSHOT, , approved, eclipse
+maven/mavencentral/org.eclipse.jgit/org.eclipse.jgit.ssh.jsch/5.12.0-SNAPSHOT, , approved, eclipse
+maven/mavencentral/org.eclipse.jgit/org.eclipse.jgit.test/5.12.0-SNAPSHOT, , approved, eclipse
+maven/mavencentral/org.eclipse.jgit/org.eclipse.jgit.ui/5.12.0-SNAPSHOT, , approved, eclipse
+maven/mavencentral/org.eclipse.jgit/org.eclipse.jgit/5.12.0-SNAPSHOT, , approved, eclipse
 maven/mavencentral/org.hamcrest/hamcrest-core/1.3, BSD-2-Clause, approved, CQ7063
 maven/mavencentral/org.mockito/mockito-core/2.23.0, MIT, approved, CQ17976
 maven/mavencentral/org.objenesis/objenesis/2.6, Apache-2.0, approved, CQ15478
diff --git a/WORKSPACE b/WORKSPACE
index 77c8451..d9c407a 100644
--- a/WORKSPACE
+++ b/WORKSPACE
@@ -237,55 +237,55 @@
     sha1 = "9180733b7df8542621dc12e21e87557e8c99b8cb",
 )
 
-JETTY_VER = "9.4.40.v20210413"
+JETTY_VER = "9.4.41.v20210516"
 
 maven_jar(
     name = "jetty-servlet",
     artifact = "org.eclipse.jetty:jetty-servlet:" + JETTY_VER,
-    sha1 = "41abc058d311baae3fe5411223e4108af212a24a",
-    src_sha1 = "2e5b2319bce4c74d760106db05deed2a405041ce",
+    sha1 = "ea45368ea7fd04026038f89e6910f17f70939641",
+    src_sha1 = "4acf6b0d1449ccd39b195783e3639ab0da51f7bf",
 )
 
 maven_jar(
     name = "jetty-security",
     artifact = "org.eclipse.jetty:jetty-security:" + JETTY_VER,
-    sha1 = "0c2807eff66ca21b565276e69aa8502524beb204",
-    src_sha1 = "b4873ec0ab5acc8a383df4dc9046ad5361b5616f",
+    sha1 = "5ba69b1189a9d1f425ed03cbc2c901e0e6023c4d",
+    src_sha1 = "d46f8cb4dad66751d3a588309c6bbc15b80fbad4",
 )
 
 maven_jar(
     name = "jetty-server",
     artifact = "org.eclipse.jetty:jetty-server:" + JETTY_VER,
-    sha1 = "a6d22f20c863d2d7669dbc2399a1a3b25b0f8a20",
-    src_sha1 = "09f789d2959ea38813be6bd2b751bba9db3a4494",
+    sha1 = "25b1963b0a1c56202ec37046adc55861815107ce",
+    src_sha1 = "a7f82c9df737316cf0dfafe4a33ca4ae89d780db",
 )
 
 maven_jar(
     name = "jetty-http",
     artifact = "org.eclipse.jetty:jetty-http:" + JETTY_VER,
-    sha1 = "dea7e5fe28a6580d6900e77d836e650aeecfa9c8",
-    src_sha1 = "b161959fac6fd932031022ac3fb8b6c34a422feb",
+    sha1 = "0d460bece4dd9666b46cbd18f8d7fd31cf02ecd9",
+    src_sha1 = "6fa009d950b8fdab8e94003e6295c08d42ee85b7",
 )
 
 maven_jar(
     name = "jetty-io",
     artifact = "org.eclipse.jetty:jetty-io:" + JETTY_VER,
-    sha1 = "c420368a360c20b40a57897676d581462d0a54c0",
-    src_sha1 = "6ae54fba76b91f24ec5880202920f0a61b1b050b",
+    sha1 = "820eea368623939c2113902b1ca7a98186f64a73",
+    src_sha1 = "4373285dafb5f79210815d9c15de106cc3e9ac4d",
 )
 
 maven_jar(
     name = "jetty-util",
     artifact = "org.eclipse.jetty:jetty-util:" + JETTY_VER,
-    sha1 = "1ab1a4f33f293110fdfb3da1911b2a00da78019b",
-    src_sha1 = "9d537ad9d22c7edfac0e38ba5afc04632716dca5",
+    sha1 = "548c76ea00d7eb3e2bcea273174e5d030639d109",
+    src_sha1 = "ba188de552a0c310f69cf12bea887413ce8f0e78",
 )
 
 maven_jar(
     name = "jetty-util-ajax",
     artifact = "org.eclipse.jetty:jetty-util-ajax:" + JETTY_VER,
-    sha1 = "62014fb386f1c3dce53029165fd76435bcb8bb6c",
-    src_sha1 = "99df1bf89bdd11c9caa0e56cc802b949f896e3d9",
+    sha1 = "d4c1d66fc62796a17548e6c344fbf89b5889f873",
+    src_sha1 = "b60cf77be68137eee4ee13d83c47d684d14b6d90",
 )
 
 BOUNCYCASTLE_VER = "1.65"
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 cb6dbeb..8cc851d 100644
--- a/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.10.target
+++ b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.10.target
@@ -1,28 +1,28 @@
 <?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="1619186290">
+<target name="jgit-4.10" sequenceNumber="1623012846">
   <locations>
     <location includeMode="slicer" includeAllPlatforms="false" includeSource="true" includeConfigurePhase="true" type="InstallableUnit">
-      <unit id="org.eclipse.jetty.client" version="9.4.40.v20210413"/>
-      <unit id="org.eclipse.jetty.client.source" version="9.4.40.v20210413"/>
-      <unit id="org.eclipse.jetty.continuation" version="9.4.40.v20210413"/>
-      <unit id="org.eclipse.jetty.continuation.source" version="9.4.40.v20210413"/>
-      <unit id="org.eclipse.jetty.http" version="9.4.40.v20210413"/>
-      <unit id="org.eclipse.jetty.http.source" version="9.4.40.v20210413"/>
-      <unit id="org.eclipse.jetty.io" version="9.4.40.v20210413"/>
-      <unit id="org.eclipse.jetty.io.source" version="9.4.40.v20210413"/>
-      <unit id="org.eclipse.jetty.security" version="9.4.40.v20210413"/>
-      <unit id="org.eclipse.jetty.security.source" version="9.4.40.v20210413"/>
-      <unit id="org.eclipse.jetty.server" version="9.4.40.v20210413"/>
-      <unit id="org.eclipse.jetty.server.source" version="9.4.40.v20210413"/>
-      <unit id="org.eclipse.jetty.servlet" version="9.4.40.v20210413"/>
-      <unit id="org.eclipse.jetty.servlet.source" version="9.4.40.v20210413"/>
-      <unit id="org.eclipse.jetty.util" version="9.4.40.v20210413"/>
-      <unit id="org.eclipse.jetty.util.source" version="9.4.40.v20210413"/>
-      <unit id="org.eclipse.jetty.util.ajax" version="9.4.40.v20210413"/>
-      <unit id="org.eclipse.jetty.util.ajax.source" version="9.4.40.v20210413"/>
-      <repository id="jetty-9.4.36" location="https://download.eclipse.org/jetty/updates/jetty-bundles-9.x/9.4.40.v20210413/"/>
+      <unit id="org.eclipse.jetty.client" version="9.4.41.v20210516"/>
+      <unit id="org.eclipse.jetty.client.source" version="9.4.41.v20210516"/>
+      <unit id="org.eclipse.jetty.continuation" version="9.4.41.v20210516"/>
+      <unit id="org.eclipse.jetty.continuation.source" version="9.4.41.v20210516"/>
+      <unit id="org.eclipse.jetty.http" version="9.4.41.v20210516"/>
+      <unit id="org.eclipse.jetty.http.source" version="9.4.41.v20210516"/>
+      <unit id="org.eclipse.jetty.io" version="9.4.41.v20210516"/>
+      <unit id="org.eclipse.jetty.io.source" version="9.4.41.v20210516"/>
+      <unit id="org.eclipse.jetty.security" version="9.4.41.v20210516"/>
+      <unit id="org.eclipse.jetty.security.source" version="9.4.41.v20210516"/>
+      <unit id="org.eclipse.jetty.server" version="9.4.41.v20210516"/>
+      <unit id="org.eclipse.jetty.server.source" version="9.4.41.v20210516"/>
+      <unit id="org.eclipse.jetty.servlet" version="9.4.41.v20210516"/>
+      <unit id="org.eclipse.jetty.servlet.source" version="9.4.41.v20210516"/>
+      <unit id="org.eclipse.jetty.util" version="9.4.41.v20210516"/>
+      <unit id="org.eclipse.jetty.util.source" version="9.4.41.v20210516"/>
+      <unit id="org.eclipse.jetty.util.ajax" version="9.4.41.v20210516"/>
+      <unit id="org.eclipse.jetty.util.ajax.source" version="9.4.41.v20210516"/>
+      <repository id="jetty-9.4.40" location="https://download.eclipse.org/jetty/updates/jetty-bundles-9.x/9.4.41.v20210516/"/>
     </location>
     <location includeMode="slicer" includeAllPlatforms="false" includeSource="true" includeConfigurePhase="true" type="InstallableUnit">
       <unit id="com.google.gson" version="2.8.6.v20201231-1626"/>
@@ -41,8 +41,8 @@
       <unit id="net.bytebuddy.byte-buddy.source" version="1.9.0.v20181107-1410"/>
       <unit id="net.i2p.crypto.eddsa" version="0.3.0.v20181102-1323"/>
       <unit id="net.i2p.crypto.eddsa.source" version="0.3.0.v20181102-1323"/>
-      <unit id="org.apache.ant" version="1.10.9.v20201106-1946"/>
-      <unit id="org.apache.ant.source" version="1.10.9.v20201106-1946"/>
+      <unit id="org.apache.ant" version="1.10.10.v20210426-1926"/>
+      <unit id="org.apache.ant.source" version="1.10.10.v20210426-1926"/>
       <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"/>
@@ -86,7 +86,7 @@
       <unit id="org.slf4j.binding.log4j12.source" version="1.7.30.v20201108-2042"/>
       <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/S20210406213021/repository"/>
+      <repository location="https://download.eclipse.org/tools/orbit/downloads/drops/R20210602031627/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 55a0950..6ba77b9 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/S20210406213021.tpd"
+include "orbit/R20210602031627-2021-06.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 21a6e1f..164cd82 100644
--- a/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.11.target
+++ b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.11.target
@@ -1,28 +1,28 @@
 <?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="1619186290">
+<target name="jgit-4.11" sequenceNumber="1623012873">
   <locations>
     <location includeMode="slicer" includeAllPlatforms="false" includeSource="true" includeConfigurePhase="true" type="InstallableUnit">
-      <unit id="org.eclipse.jetty.client" version="9.4.40.v20210413"/>
-      <unit id="org.eclipse.jetty.client.source" version="9.4.40.v20210413"/>
-      <unit id="org.eclipse.jetty.continuation" version="9.4.40.v20210413"/>
-      <unit id="org.eclipse.jetty.continuation.source" version="9.4.40.v20210413"/>
-      <unit id="org.eclipse.jetty.http" version="9.4.40.v20210413"/>
-      <unit id="org.eclipse.jetty.http.source" version="9.4.40.v20210413"/>
-      <unit id="org.eclipse.jetty.io" version="9.4.40.v20210413"/>
-      <unit id="org.eclipse.jetty.io.source" version="9.4.40.v20210413"/>
-      <unit id="org.eclipse.jetty.security" version="9.4.40.v20210413"/>
-      <unit id="org.eclipse.jetty.security.source" version="9.4.40.v20210413"/>
-      <unit id="org.eclipse.jetty.server" version="9.4.40.v20210413"/>
-      <unit id="org.eclipse.jetty.server.source" version="9.4.40.v20210413"/>
-      <unit id="org.eclipse.jetty.servlet" version="9.4.40.v20210413"/>
-      <unit id="org.eclipse.jetty.servlet.source" version="9.4.40.v20210413"/>
-      <unit id="org.eclipse.jetty.util" version="9.4.40.v20210413"/>
-      <unit id="org.eclipse.jetty.util.source" version="9.4.40.v20210413"/>
-      <unit id="org.eclipse.jetty.util.ajax" version="9.4.40.v20210413"/>
-      <unit id="org.eclipse.jetty.util.ajax.source" version="9.4.40.v20210413"/>
-      <repository id="jetty-9.4.36" location="https://download.eclipse.org/jetty/updates/jetty-bundles-9.x/9.4.40.v20210413/"/>
+      <unit id="org.eclipse.jetty.client" version="9.4.41.v20210516"/>
+      <unit id="org.eclipse.jetty.client.source" version="9.4.41.v20210516"/>
+      <unit id="org.eclipse.jetty.continuation" version="9.4.41.v20210516"/>
+      <unit id="org.eclipse.jetty.continuation.source" version="9.4.41.v20210516"/>
+      <unit id="org.eclipse.jetty.http" version="9.4.41.v20210516"/>
+      <unit id="org.eclipse.jetty.http.source" version="9.4.41.v20210516"/>
+      <unit id="org.eclipse.jetty.io" version="9.4.41.v20210516"/>
+      <unit id="org.eclipse.jetty.io.source" version="9.4.41.v20210516"/>
+      <unit id="org.eclipse.jetty.security" version="9.4.41.v20210516"/>
+      <unit id="org.eclipse.jetty.security.source" version="9.4.41.v20210516"/>
+      <unit id="org.eclipse.jetty.server" version="9.4.41.v20210516"/>
+      <unit id="org.eclipse.jetty.server.source" version="9.4.41.v20210516"/>
+      <unit id="org.eclipse.jetty.servlet" version="9.4.41.v20210516"/>
+      <unit id="org.eclipse.jetty.servlet.source" version="9.4.41.v20210516"/>
+      <unit id="org.eclipse.jetty.util" version="9.4.41.v20210516"/>
+      <unit id="org.eclipse.jetty.util.source" version="9.4.41.v20210516"/>
+      <unit id="org.eclipse.jetty.util.ajax" version="9.4.41.v20210516"/>
+      <unit id="org.eclipse.jetty.util.ajax.source" version="9.4.41.v20210516"/>
+      <repository id="jetty-9.4.40" location="https://download.eclipse.org/jetty/updates/jetty-bundles-9.x/9.4.41.v20210516/"/>
     </location>
     <location includeMode="slicer" includeAllPlatforms="false" includeSource="true" includeConfigurePhase="true" type="InstallableUnit">
       <unit id="com.google.gson" version="2.8.6.v20201231-1626"/>
@@ -41,8 +41,8 @@
       <unit id="net.bytebuddy.byte-buddy.source" version="1.9.0.v20181107-1410"/>
       <unit id="net.i2p.crypto.eddsa" version="0.3.0.v20181102-1323"/>
       <unit id="net.i2p.crypto.eddsa.source" version="0.3.0.v20181102-1323"/>
-      <unit id="org.apache.ant" version="1.10.9.v20201106-1946"/>
-      <unit id="org.apache.ant.source" version="1.10.9.v20201106-1946"/>
+      <unit id="org.apache.ant" version="1.10.10.v20210426-1926"/>
+      <unit id="org.apache.ant.source" version="1.10.10.v20210426-1926"/>
       <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"/>
@@ -86,7 +86,7 @@
       <unit id="org.slf4j.binding.log4j12.source" version="1.7.30.v20201108-2042"/>
       <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/S20210406213021/repository"/>
+      <repository location="https://download.eclipse.org/tools/orbit/downloads/drops/R20210602031627/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 12b0f75..f29a9fe 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/S20210406213021.tpd"
+include "orbit/R20210602031627-2021-06.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 79cf33d..ed8ad0b 100644
--- a/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.12.target
+++ b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.12.target
@@ -1,28 +1,28 @@
 <?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="1619186290">
+<target name="jgit-4.12" sequenceNumber="1623012873">
   <locations>
     <location includeMode="slicer" includeAllPlatforms="false" includeSource="true" includeConfigurePhase="true" type="InstallableUnit">
-      <unit id="org.eclipse.jetty.client" version="9.4.40.v20210413"/>
-      <unit id="org.eclipse.jetty.client.source" version="9.4.40.v20210413"/>
-      <unit id="org.eclipse.jetty.continuation" version="9.4.40.v20210413"/>
-      <unit id="org.eclipse.jetty.continuation.source" version="9.4.40.v20210413"/>
-      <unit id="org.eclipse.jetty.http" version="9.4.40.v20210413"/>
-      <unit id="org.eclipse.jetty.http.source" version="9.4.40.v20210413"/>
-      <unit id="org.eclipse.jetty.io" version="9.4.40.v20210413"/>
-      <unit id="org.eclipse.jetty.io.source" version="9.4.40.v20210413"/>
-      <unit id="org.eclipse.jetty.security" version="9.4.40.v20210413"/>
-      <unit id="org.eclipse.jetty.security.source" version="9.4.40.v20210413"/>
-      <unit id="org.eclipse.jetty.server" version="9.4.40.v20210413"/>
-      <unit id="org.eclipse.jetty.server.source" version="9.4.40.v20210413"/>
-      <unit id="org.eclipse.jetty.servlet" version="9.4.40.v20210413"/>
-      <unit id="org.eclipse.jetty.servlet.source" version="9.4.40.v20210413"/>
-      <unit id="org.eclipse.jetty.util" version="9.4.40.v20210413"/>
-      <unit id="org.eclipse.jetty.util.source" version="9.4.40.v20210413"/>
-      <unit id="org.eclipse.jetty.util.ajax" version="9.4.40.v20210413"/>
-      <unit id="org.eclipse.jetty.util.ajax.source" version="9.4.40.v20210413"/>
-      <repository id="jetty-9.4.36" location="https://download.eclipse.org/jetty/updates/jetty-bundles-9.x/9.4.40.v20210413/"/>
+      <unit id="org.eclipse.jetty.client" version="9.4.41.v20210516"/>
+      <unit id="org.eclipse.jetty.client.source" version="9.4.41.v20210516"/>
+      <unit id="org.eclipse.jetty.continuation" version="9.4.41.v20210516"/>
+      <unit id="org.eclipse.jetty.continuation.source" version="9.4.41.v20210516"/>
+      <unit id="org.eclipse.jetty.http" version="9.4.41.v20210516"/>
+      <unit id="org.eclipse.jetty.http.source" version="9.4.41.v20210516"/>
+      <unit id="org.eclipse.jetty.io" version="9.4.41.v20210516"/>
+      <unit id="org.eclipse.jetty.io.source" version="9.4.41.v20210516"/>
+      <unit id="org.eclipse.jetty.security" version="9.4.41.v20210516"/>
+      <unit id="org.eclipse.jetty.security.source" version="9.4.41.v20210516"/>
+      <unit id="org.eclipse.jetty.server" version="9.4.41.v20210516"/>
+      <unit id="org.eclipse.jetty.server.source" version="9.4.41.v20210516"/>
+      <unit id="org.eclipse.jetty.servlet" version="9.4.41.v20210516"/>
+      <unit id="org.eclipse.jetty.servlet.source" version="9.4.41.v20210516"/>
+      <unit id="org.eclipse.jetty.util" version="9.4.41.v20210516"/>
+      <unit id="org.eclipse.jetty.util.source" version="9.4.41.v20210516"/>
+      <unit id="org.eclipse.jetty.util.ajax" version="9.4.41.v20210516"/>
+      <unit id="org.eclipse.jetty.util.ajax.source" version="9.4.41.v20210516"/>
+      <repository id="jetty-9.4.40" location="https://download.eclipse.org/jetty/updates/jetty-bundles-9.x/9.4.41.v20210516/"/>
     </location>
     <location includeMode="slicer" includeAllPlatforms="false" includeSource="true" includeConfigurePhase="true" type="InstallableUnit">
       <unit id="com.google.gson" version="2.8.6.v20201231-1626"/>
@@ -41,8 +41,8 @@
       <unit id="net.bytebuddy.byte-buddy.source" version="1.9.0.v20181107-1410"/>
       <unit id="net.i2p.crypto.eddsa" version="0.3.0.v20181102-1323"/>
       <unit id="net.i2p.crypto.eddsa.source" version="0.3.0.v20181102-1323"/>
-      <unit id="org.apache.ant" version="1.10.9.v20201106-1946"/>
-      <unit id="org.apache.ant.source" version="1.10.9.v20201106-1946"/>
+      <unit id="org.apache.ant" version="1.10.10.v20210426-1926"/>
+      <unit id="org.apache.ant.source" version="1.10.10.v20210426-1926"/>
       <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"/>
@@ -86,7 +86,7 @@
       <unit id="org.slf4j.binding.log4j12.source" version="1.7.30.v20201108-2042"/>
       <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/S20210406213021/repository"/>
+      <repository location="https://download.eclipse.org/tools/orbit/downloads/drops/R20210602031627/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 6fc7443..35bf3b0 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/S20210406213021.tpd"
+include "orbit/R20210602031627-2021-06.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 bc2e3d3..993e112 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,28 +1,28 @@
 <?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="1619186290">
+<target name="jgit-4.13" sequenceNumber="1623012873">
   <locations>
     <location includeMode="slicer" includeAllPlatforms="false" includeSource="true" includeConfigurePhase="true" type="InstallableUnit">
-      <unit id="org.eclipse.jetty.client" version="9.4.40.v20210413"/>
-      <unit id="org.eclipse.jetty.client.source" version="9.4.40.v20210413"/>
-      <unit id="org.eclipse.jetty.continuation" version="9.4.40.v20210413"/>
-      <unit id="org.eclipse.jetty.continuation.source" version="9.4.40.v20210413"/>
-      <unit id="org.eclipse.jetty.http" version="9.4.40.v20210413"/>
-      <unit id="org.eclipse.jetty.http.source" version="9.4.40.v20210413"/>
-      <unit id="org.eclipse.jetty.io" version="9.4.40.v20210413"/>
-      <unit id="org.eclipse.jetty.io.source" version="9.4.40.v20210413"/>
-      <unit id="org.eclipse.jetty.security" version="9.4.40.v20210413"/>
-      <unit id="org.eclipse.jetty.security.source" version="9.4.40.v20210413"/>
-      <unit id="org.eclipse.jetty.server" version="9.4.40.v20210413"/>
-      <unit id="org.eclipse.jetty.server.source" version="9.4.40.v20210413"/>
-      <unit id="org.eclipse.jetty.servlet" version="9.4.40.v20210413"/>
-      <unit id="org.eclipse.jetty.servlet.source" version="9.4.40.v20210413"/>
-      <unit id="org.eclipse.jetty.util" version="9.4.40.v20210413"/>
-      <unit id="org.eclipse.jetty.util.source" version="9.4.40.v20210413"/>
-      <unit id="org.eclipse.jetty.util.ajax" version="9.4.40.v20210413"/>
-      <unit id="org.eclipse.jetty.util.ajax.source" version="9.4.40.v20210413"/>
-      <repository id="jetty-9.4.36" location="https://download.eclipse.org/jetty/updates/jetty-bundles-9.x/9.4.40.v20210413/"/>
+      <unit id="org.eclipse.jetty.client" version="9.4.41.v20210516"/>
+      <unit id="org.eclipse.jetty.client.source" version="9.4.41.v20210516"/>
+      <unit id="org.eclipse.jetty.continuation" version="9.4.41.v20210516"/>
+      <unit id="org.eclipse.jetty.continuation.source" version="9.4.41.v20210516"/>
+      <unit id="org.eclipse.jetty.http" version="9.4.41.v20210516"/>
+      <unit id="org.eclipse.jetty.http.source" version="9.4.41.v20210516"/>
+      <unit id="org.eclipse.jetty.io" version="9.4.41.v20210516"/>
+      <unit id="org.eclipse.jetty.io.source" version="9.4.41.v20210516"/>
+      <unit id="org.eclipse.jetty.security" version="9.4.41.v20210516"/>
+      <unit id="org.eclipse.jetty.security.source" version="9.4.41.v20210516"/>
+      <unit id="org.eclipse.jetty.server" version="9.4.41.v20210516"/>
+      <unit id="org.eclipse.jetty.server.source" version="9.4.41.v20210516"/>
+      <unit id="org.eclipse.jetty.servlet" version="9.4.41.v20210516"/>
+      <unit id="org.eclipse.jetty.servlet.source" version="9.4.41.v20210516"/>
+      <unit id="org.eclipse.jetty.util" version="9.4.41.v20210516"/>
+      <unit id="org.eclipse.jetty.util.source" version="9.4.41.v20210516"/>
+      <unit id="org.eclipse.jetty.util.ajax" version="9.4.41.v20210516"/>
+      <unit id="org.eclipse.jetty.util.ajax.source" version="9.4.41.v20210516"/>
+      <repository id="jetty-9.4.40" location="https://download.eclipse.org/jetty/updates/jetty-bundles-9.x/9.4.41.v20210516/"/>
     </location>
     <location includeMode="slicer" includeAllPlatforms="false" includeSource="true" includeConfigurePhase="true" type="InstallableUnit">
       <unit id="com.google.gson" version="2.8.6.v20201231-1626"/>
@@ -41,8 +41,8 @@
       <unit id="net.bytebuddy.byte-buddy.source" version="1.9.0.v20181107-1410"/>
       <unit id="net.i2p.crypto.eddsa" version="0.3.0.v20181102-1323"/>
       <unit id="net.i2p.crypto.eddsa.source" version="0.3.0.v20181102-1323"/>
-      <unit id="org.apache.ant" version="1.10.9.v20201106-1946"/>
-      <unit id="org.apache.ant.source" version="1.10.9.v20201106-1946"/>
+      <unit id="org.apache.ant" version="1.10.10.v20210426-1926"/>
+      <unit id="org.apache.ant.source" version="1.10.10.v20210426-1926"/>
       <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"/>
@@ -86,7 +86,7 @@
       <unit id="org.slf4j.binding.log4j12.source" version="1.7.30.v20201108-2042"/>
       <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/S20210406213021/repository"/>
+      <repository location="https://download.eclipse.org/tools/orbit/downloads/drops/R20210602031627/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 5dbcbb4..6da9b00 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/S20210406213021.tpd"
+include "orbit/R20210602031627-2021-06.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 23591b1..e8cfa60 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,28 +1,28 @@
 <?xml version="1.0" encoding="UTF-8" standalone="no"?>
 <?pde?>
 <!-- generated with https://github.com/eclipse-cbi/targetplatform-dsl -->
-<target name="jgit-4.14" sequenceNumber="1619186289">
+<target name="jgit-4.14" sequenceNumber="1623012870">
   <locations>
     <location includeMode="slicer" includeAllPlatforms="false" includeSource="true" includeConfigurePhase="true" type="InstallableUnit">
-      <unit id="org.eclipse.jetty.client" version="9.4.40.v20210413"/>
-      <unit id="org.eclipse.jetty.client.source" version="9.4.40.v20210413"/>
-      <unit id="org.eclipse.jetty.continuation" version="9.4.40.v20210413"/>
-      <unit id="org.eclipse.jetty.continuation.source" version="9.4.40.v20210413"/>
-      <unit id="org.eclipse.jetty.http" version="9.4.40.v20210413"/>
-      <unit id="org.eclipse.jetty.http.source" version="9.4.40.v20210413"/>
-      <unit id="org.eclipse.jetty.io" version="9.4.40.v20210413"/>
-      <unit id="org.eclipse.jetty.io.source" version="9.4.40.v20210413"/>
-      <unit id="org.eclipse.jetty.security" version="9.4.40.v20210413"/>
-      <unit id="org.eclipse.jetty.security.source" version="9.4.40.v20210413"/>
-      <unit id="org.eclipse.jetty.server" version="9.4.40.v20210413"/>
-      <unit id="org.eclipse.jetty.server.source" version="9.4.40.v20210413"/>
-      <unit id="org.eclipse.jetty.servlet" version="9.4.40.v20210413"/>
-      <unit id="org.eclipse.jetty.servlet.source" version="9.4.40.v20210413"/>
-      <unit id="org.eclipse.jetty.util" version="9.4.40.v20210413"/>
-      <unit id="org.eclipse.jetty.util.source" version="9.4.40.v20210413"/>
-      <unit id="org.eclipse.jetty.util.ajax" version="9.4.40.v20210413"/>
-      <unit id="org.eclipse.jetty.util.ajax.source" version="9.4.40.v20210413"/>
-      <repository id="jetty-9.4.36" location="https://download.eclipse.org/jetty/updates/jetty-bundles-9.x/9.4.40.v20210413/"/>
+      <unit id="org.eclipse.jetty.client" version="9.4.41.v20210516"/>
+      <unit id="org.eclipse.jetty.client.source" version="9.4.41.v20210516"/>
+      <unit id="org.eclipse.jetty.continuation" version="9.4.41.v20210516"/>
+      <unit id="org.eclipse.jetty.continuation.source" version="9.4.41.v20210516"/>
+      <unit id="org.eclipse.jetty.http" version="9.4.41.v20210516"/>
+      <unit id="org.eclipse.jetty.http.source" version="9.4.41.v20210516"/>
+      <unit id="org.eclipse.jetty.io" version="9.4.41.v20210516"/>
+      <unit id="org.eclipse.jetty.io.source" version="9.4.41.v20210516"/>
+      <unit id="org.eclipse.jetty.security" version="9.4.41.v20210516"/>
+      <unit id="org.eclipse.jetty.security.source" version="9.4.41.v20210516"/>
+      <unit id="org.eclipse.jetty.server" version="9.4.41.v20210516"/>
+      <unit id="org.eclipse.jetty.server.source" version="9.4.41.v20210516"/>
+      <unit id="org.eclipse.jetty.servlet" version="9.4.41.v20210516"/>
+      <unit id="org.eclipse.jetty.servlet.source" version="9.4.41.v20210516"/>
+      <unit id="org.eclipse.jetty.util" version="9.4.41.v20210516"/>
+      <unit id="org.eclipse.jetty.util.source" version="9.4.41.v20210516"/>
+      <unit id="org.eclipse.jetty.util.ajax" version="9.4.41.v20210516"/>
+      <unit id="org.eclipse.jetty.util.ajax.source" version="9.4.41.v20210516"/>
+      <repository id="jetty-9.4.40" location="https://download.eclipse.org/jetty/updates/jetty-bundles-9.x/9.4.41.v20210516/"/>
     </location>
     <location includeMode="slicer" includeAllPlatforms="false" includeSource="true" includeConfigurePhase="true" type="InstallableUnit">
       <unit id="com.google.gson" version="2.8.6.v20201231-1626"/>
@@ -41,8 +41,8 @@
       <unit id="net.bytebuddy.byte-buddy.source" version="1.9.0.v20181107-1410"/>
       <unit id="net.i2p.crypto.eddsa" version="0.3.0.v20181102-1323"/>
       <unit id="net.i2p.crypto.eddsa.source" version="0.3.0.v20181102-1323"/>
-      <unit id="org.apache.ant" version="1.10.9.v20201106-1946"/>
-      <unit id="org.apache.ant.source" version="1.10.9.v20201106-1946"/>
+      <unit id="org.apache.ant" version="1.10.10.v20210426-1926"/>
+      <unit id="org.apache.ant.source" version="1.10.10.v20210426-1926"/>
       <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"/>
@@ -86,7 +86,7 @@
       <unit id="org.slf4j.binding.log4j12.source" version="1.7.30.v20201108-2042"/>
       <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/S20210406213021/repository"/>
+      <repository location="https://download.eclipse.org/tools/orbit/downloads/drops/R20210602031627/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 3da7ed4..70dce0c 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" with source configurePhase
 
 include "projects/jetty-9.4.x.tpd"
-include "orbit/S20210406213021.tpd"
+include "orbit/R20210602031627-2021-06.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 1a11dff..81c6450 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,28 +1,28 @@
 <?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="1619186289">
+<target name="jgit-4.15" sequenceNumber="1623012870">
   <locations>
     <location includeMode="slicer" includeAllPlatforms="false" includeSource="true" includeConfigurePhase="true" type="InstallableUnit">
-      <unit id="org.eclipse.jetty.client" version="9.4.40.v20210413"/>
-      <unit id="org.eclipse.jetty.client.source" version="9.4.40.v20210413"/>
-      <unit id="org.eclipse.jetty.continuation" version="9.4.40.v20210413"/>
-      <unit id="org.eclipse.jetty.continuation.source" version="9.4.40.v20210413"/>
-      <unit id="org.eclipse.jetty.http" version="9.4.40.v20210413"/>
-      <unit id="org.eclipse.jetty.http.source" version="9.4.40.v20210413"/>
-      <unit id="org.eclipse.jetty.io" version="9.4.40.v20210413"/>
-      <unit id="org.eclipse.jetty.io.source" version="9.4.40.v20210413"/>
-      <unit id="org.eclipse.jetty.security" version="9.4.40.v20210413"/>
-      <unit id="org.eclipse.jetty.security.source" version="9.4.40.v20210413"/>
-      <unit id="org.eclipse.jetty.server" version="9.4.40.v20210413"/>
-      <unit id="org.eclipse.jetty.server.source" version="9.4.40.v20210413"/>
-      <unit id="org.eclipse.jetty.servlet" version="9.4.40.v20210413"/>
-      <unit id="org.eclipse.jetty.servlet.source" version="9.4.40.v20210413"/>
-      <unit id="org.eclipse.jetty.util" version="9.4.40.v20210413"/>
-      <unit id="org.eclipse.jetty.util.source" version="9.4.40.v20210413"/>
-      <unit id="org.eclipse.jetty.util.ajax" version="9.4.40.v20210413"/>
-      <unit id="org.eclipse.jetty.util.ajax.source" version="9.4.40.v20210413"/>
-      <repository id="jetty-9.4.36" location="https://download.eclipse.org/jetty/updates/jetty-bundles-9.x/9.4.40.v20210413/"/>
+      <unit id="org.eclipse.jetty.client" version="9.4.41.v20210516"/>
+      <unit id="org.eclipse.jetty.client.source" version="9.4.41.v20210516"/>
+      <unit id="org.eclipse.jetty.continuation" version="9.4.41.v20210516"/>
+      <unit id="org.eclipse.jetty.continuation.source" version="9.4.41.v20210516"/>
+      <unit id="org.eclipse.jetty.http" version="9.4.41.v20210516"/>
+      <unit id="org.eclipse.jetty.http.source" version="9.4.41.v20210516"/>
+      <unit id="org.eclipse.jetty.io" version="9.4.41.v20210516"/>
+      <unit id="org.eclipse.jetty.io.source" version="9.4.41.v20210516"/>
+      <unit id="org.eclipse.jetty.security" version="9.4.41.v20210516"/>
+      <unit id="org.eclipse.jetty.security.source" version="9.4.41.v20210516"/>
+      <unit id="org.eclipse.jetty.server" version="9.4.41.v20210516"/>
+      <unit id="org.eclipse.jetty.server.source" version="9.4.41.v20210516"/>
+      <unit id="org.eclipse.jetty.servlet" version="9.4.41.v20210516"/>
+      <unit id="org.eclipse.jetty.servlet.source" version="9.4.41.v20210516"/>
+      <unit id="org.eclipse.jetty.util" version="9.4.41.v20210516"/>
+      <unit id="org.eclipse.jetty.util.source" version="9.4.41.v20210516"/>
+      <unit id="org.eclipse.jetty.util.ajax" version="9.4.41.v20210516"/>
+      <unit id="org.eclipse.jetty.util.ajax.source" version="9.4.41.v20210516"/>
+      <repository id="jetty-9.4.40" location="https://download.eclipse.org/jetty/updates/jetty-bundles-9.x/9.4.41.v20210516/"/>
     </location>
     <location includeMode="slicer" includeAllPlatforms="false" includeSource="true" includeConfigurePhase="true" type="InstallableUnit">
       <unit id="com.google.gson" version="2.8.6.v20201231-1626"/>
@@ -41,8 +41,8 @@
       <unit id="net.bytebuddy.byte-buddy.source" version="1.9.0.v20181107-1410"/>
       <unit id="net.i2p.crypto.eddsa" version="0.3.0.v20181102-1323"/>
       <unit id="net.i2p.crypto.eddsa.source" version="0.3.0.v20181102-1323"/>
-      <unit id="org.apache.ant" version="1.10.9.v20201106-1946"/>
-      <unit id="org.apache.ant.source" version="1.10.9.v20201106-1946"/>
+      <unit id="org.apache.ant" version="1.10.10.v20210426-1926"/>
+      <unit id="org.apache.ant.source" version="1.10.10.v20210426-1926"/>
       <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"/>
@@ -86,7 +86,7 @@
       <unit id="org.slf4j.binding.log4j12.source" version="1.7.30.v20201108-2042"/>
       <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/S20210406213021/repository"/>
+      <repository location="https://download.eclipse.org/tools/orbit/downloads/drops/R20210602031627/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 49ae4ea..edf5cec 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/S20210406213021.tpd"
+include "orbit/R20210602031627-2021-06.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.target b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.16.target
index ae9511a..3afc3b8 100644
--- a/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.16.target
+++ b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.16.target
@@ -1,28 +1,28 @@
 <?xml version="1.0" encoding="UTF-8" standalone="no"?>
 <?pde?>
 <!-- generated with https://github.com/eclipse-cbi/targetplatform-dsl -->
-<target name="jgit-4.16" sequenceNumber="1619186290">
+<target name="jgit-4.16" sequenceNumber="1623012874">
   <locations>
     <location includeMode="slicer" includeAllPlatforms="false" includeSource="true" includeConfigurePhase="true" type="InstallableUnit">
-      <unit id="org.eclipse.jetty.client" version="9.4.40.v20210413"/>
-      <unit id="org.eclipse.jetty.client.source" version="9.4.40.v20210413"/>
-      <unit id="org.eclipse.jetty.continuation" version="9.4.40.v20210413"/>
-      <unit id="org.eclipse.jetty.continuation.source" version="9.4.40.v20210413"/>
-      <unit id="org.eclipse.jetty.http" version="9.4.40.v20210413"/>
-      <unit id="org.eclipse.jetty.http.source" version="9.4.40.v20210413"/>
-      <unit id="org.eclipse.jetty.io" version="9.4.40.v20210413"/>
-      <unit id="org.eclipse.jetty.io.source" version="9.4.40.v20210413"/>
-      <unit id="org.eclipse.jetty.security" version="9.4.40.v20210413"/>
-      <unit id="org.eclipse.jetty.security.source" version="9.4.40.v20210413"/>
-      <unit id="org.eclipse.jetty.server" version="9.4.40.v20210413"/>
-      <unit id="org.eclipse.jetty.server.source" version="9.4.40.v20210413"/>
-      <unit id="org.eclipse.jetty.servlet" version="9.4.40.v20210413"/>
-      <unit id="org.eclipse.jetty.servlet.source" version="9.4.40.v20210413"/>
-      <unit id="org.eclipse.jetty.util" version="9.4.40.v20210413"/>
-      <unit id="org.eclipse.jetty.util.source" version="9.4.40.v20210413"/>
-      <unit id="org.eclipse.jetty.util.ajax" version="9.4.40.v20210413"/>
-      <unit id="org.eclipse.jetty.util.ajax.source" version="9.4.40.v20210413"/>
-      <repository id="jetty-9.4.36" location="https://download.eclipse.org/jetty/updates/jetty-bundles-9.x/9.4.40.v20210413/"/>
+      <unit id="org.eclipse.jetty.client" version="9.4.41.v20210516"/>
+      <unit id="org.eclipse.jetty.client.source" version="9.4.41.v20210516"/>
+      <unit id="org.eclipse.jetty.continuation" version="9.4.41.v20210516"/>
+      <unit id="org.eclipse.jetty.continuation.source" version="9.4.41.v20210516"/>
+      <unit id="org.eclipse.jetty.http" version="9.4.41.v20210516"/>
+      <unit id="org.eclipse.jetty.http.source" version="9.4.41.v20210516"/>
+      <unit id="org.eclipse.jetty.io" version="9.4.41.v20210516"/>
+      <unit id="org.eclipse.jetty.io.source" version="9.4.41.v20210516"/>
+      <unit id="org.eclipse.jetty.security" version="9.4.41.v20210516"/>
+      <unit id="org.eclipse.jetty.security.source" version="9.4.41.v20210516"/>
+      <unit id="org.eclipse.jetty.server" version="9.4.41.v20210516"/>
+      <unit id="org.eclipse.jetty.server.source" version="9.4.41.v20210516"/>
+      <unit id="org.eclipse.jetty.servlet" version="9.4.41.v20210516"/>
+      <unit id="org.eclipse.jetty.servlet.source" version="9.4.41.v20210516"/>
+      <unit id="org.eclipse.jetty.util" version="9.4.41.v20210516"/>
+      <unit id="org.eclipse.jetty.util.source" version="9.4.41.v20210516"/>
+      <unit id="org.eclipse.jetty.util.ajax" version="9.4.41.v20210516"/>
+      <unit id="org.eclipse.jetty.util.ajax.source" version="9.4.41.v20210516"/>
+      <repository id="jetty-9.4.40" location="https://download.eclipse.org/jetty/updates/jetty-bundles-9.x/9.4.41.v20210516/"/>
     </location>
     <location includeMode="slicer" includeAllPlatforms="false" includeSource="true" includeConfigurePhase="true" type="InstallableUnit">
       <unit id="com.google.gson" version="2.8.6.v20201231-1626"/>
@@ -41,8 +41,8 @@
       <unit id="net.bytebuddy.byte-buddy.source" version="1.9.0.v20181107-1410"/>
       <unit id="net.i2p.crypto.eddsa" version="0.3.0.v20181102-1323"/>
       <unit id="net.i2p.crypto.eddsa.source" version="0.3.0.v20181102-1323"/>
-      <unit id="org.apache.ant" version="1.10.9.v20201106-1946"/>
-      <unit id="org.apache.ant.source" version="1.10.9.v20201106-1946"/>
+      <unit id="org.apache.ant" version="1.10.10.v20210426-1926"/>
+      <unit id="org.apache.ant.source" version="1.10.10.v20210426-1926"/>
       <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"/>
@@ -86,7 +86,7 @@
       <unit id="org.slf4j.binding.log4j12.source" version="1.7.30.v20201108-2042"/>
       <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/S20210406213021/repository"/>
+      <repository location="https://download.eclipse.org/tools/orbit/downloads/drops/R20210602031627/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.16.tpd b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.16.tpd
index 4e6a745..54e8a96 100644
--- 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
@@ -1,7 +1,7 @@
 target "jgit-4.16" with source configurePhase
 
 include "projects/jetty-9.4.x.tpd"
-include "orbit/S20210406213021.tpd"
+include "orbit/R20210602031627-2021-06.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.17.target b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.17.target
index 5578abb..f61261f 100644
--- a/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.17.target
+++ b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.17.target
@@ -1,28 +1,28 @@
 <?xml version="1.0" encoding="UTF-8" standalone="no"?>
 <?pde?>
 <!-- generated with https://github.com/eclipse-cbi/targetplatform-dsl -->
-<target name="jgit-4.17" sequenceNumber="1619186290">
+<target name="jgit-4.17" sequenceNumber="1623012875">
   <locations>
     <location includeMode="slicer" includeAllPlatforms="false" includeSource="true" includeConfigurePhase="true" type="InstallableUnit">
-      <unit id="org.eclipse.jetty.client" version="9.4.40.v20210413"/>
-      <unit id="org.eclipse.jetty.client.source" version="9.4.40.v20210413"/>
-      <unit id="org.eclipse.jetty.continuation" version="9.4.40.v20210413"/>
-      <unit id="org.eclipse.jetty.continuation.source" version="9.4.40.v20210413"/>
-      <unit id="org.eclipse.jetty.http" version="9.4.40.v20210413"/>
-      <unit id="org.eclipse.jetty.http.source" version="9.4.40.v20210413"/>
-      <unit id="org.eclipse.jetty.io" version="9.4.40.v20210413"/>
-      <unit id="org.eclipse.jetty.io.source" version="9.4.40.v20210413"/>
-      <unit id="org.eclipse.jetty.security" version="9.4.40.v20210413"/>
-      <unit id="org.eclipse.jetty.security.source" version="9.4.40.v20210413"/>
-      <unit id="org.eclipse.jetty.server" version="9.4.40.v20210413"/>
-      <unit id="org.eclipse.jetty.server.source" version="9.4.40.v20210413"/>
-      <unit id="org.eclipse.jetty.servlet" version="9.4.40.v20210413"/>
-      <unit id="org.eclipse.jetty.servlet.source" version="9.4.40.v20210413"/>
-      <unit id="org.eclipse.jetty.util" version="9.4.40.v20210413"/>
-      <unit id="org.eclipse.jetty.util.source" version="9.4.40.v20210413"/>
-      <unit id="org.eclipse.jetty.util.ajax" version="9.4.40.v20210413"/>
-      <unit id="org.eclipse.jetty.util.ajax.source" version="9.4.40.v20210413"/>
-      <repository id="jetty-9.4.36" location="https://download.eclipse.org/jetty/updates/jetty-bundles-9.x/9.4.40.v20210413/"/>
+      <unit id="org.eclipse.jetty.client" version="9.4.41.v20210516"/>
+      <unit id="org.eclipse.jetty.client.source" version="9.4.41.v20210516"/>
+      <unit id="org.eclipse.jetty.continuation" version="9.4.41.v20210516"/>
+      <unit id="org.eclipse.jetty.continuation.source" version="9.4.41.v20210516"/>
+      <unit id="org.eclipse.jetty.http" version="9.4.41.v20210516"/>
+      <unit id="org.eclipse.jetty.http.source" version="9.4.41.v20210516"/>
+      <unit id="org.eclipse.jetty.io" version="9.4.41.v20210516"/>
+      <unit id="org.eclipse.jetty.io.source" version="9.4.41.v20210516"/>
+      <unit id="org.eclipse.jetty.security" version="9.4.41.v20210516"/>
+      <unit id="org.eclipse.jetty.security.source" version="9.4.41.v20210516"/>
+      <unit id="org.eclipse.jetty.server" version="9.4.41.v20210516"/>
+      <unit id="org.eclipse.jetty.server.source" version="9.4.41.v20210516"/>
+      <unit id="org.eclipse.jetty.servlet" version="9.4.41.v20210516"/>
+      <unit id="org.eclipse.jetty.servlet.source" version="9.4.41.v20210516"/>
+      <unit id="org.eclipse.jetty.util" version="9.4.41.v20210516"/>
+      <unit id="org.eclipse.jetty.util.source" version="9.4.41.v20210516"/>
+      <unit id="org.eclipse.jetty.util.ajax" version="9.4.41.v20210516"/>
+      <unit id="org.eclipse.jetty.util.ajax.source" version="9.4.41.v20210516"/>
+      <repository id="jetty-9.4.40" location="https://download.eclipse.org/jetty/updates/jetty-bundles-9.x/9.4.41.v20210516/"/>
     </location>
     <location includeMode="slicer" includeAllPlatforms="false" includeSource="true" includeConfigurePhase="true" type="InstallableUnit">
       <unit id="com.google.gson" version="2.8.6.v20201231-1626"/>
@@ -41,8 +41,8 @@
       <unit id="net.bytebuddy.byte-buddy.source" version="1.9.0.v20181107-1410"/>
       <unit id="net.i2p.crypto.eddsa" version="0.3.0.v20181102-1323"/>
       <unit id="net.i2p.crypto.eddsa.source" version="0.3.0.v20181102-1323"/>
-      <unit id="org.apache.ant" version="1.10.9.v20201106-1946"/>
-      <unit id="org.apache.ant.source" version="1.10.9.v20201106-1946"/>
+      <unit id="org.apache.ant" version="1.10.10.v20210426-1926"/>
+      <unit id="org.apache.ant.source" version="1.10.10.v20210426-1926"/>
       <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"/>
@@ -86,7 +86,7 @@
       <unit id="org.slf4j.binding.log4j12.source" version="1.7.30.v20201108-2042"/>
       <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/S20210406213021/repository"/>
+      <repository location="https://download.eclipse.org/tools/orbit/downloads/drops/R20210602031627/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.17.tpd b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.17.tpd
index cad8a5c..2b2af1a 100644
--- a/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.17.tpd
+++ b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.17.tpd
@@ -1,7 +1,7 @@
 target "jgit-4.17" with source configurePhase
 
 include "projects/jetty-9.4.x.tpd"
-include "orbit/S20210406213021.tpd"
+include "orbit/R20210602031627-2021-06.tpd"
 
 location "https://download.eclipse.org/releases/2020-09/" {
 	org.eclipse.osgi lazy
diff --git a/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.18.target b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.18.target
index 42bfa0c..c17c1c8 100644
--- a/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.18.target
+++ b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.18.target
@@ -1,28 +1,28 @@
 <?xml version="1.0" encoding="UTF-8" standalone="no"?>
 <?pde?>
 <!-- generated with https://github.com/eclipse-cbi/targetplatform-dsl -->
-<target name="jgit-4.18" sequenceNumber="1619186290">
+<target name="jgit-4.18" sequenceNumber="1623012874">
   <locations>
     <location includeMode="slicer" includeAllPlatforms="false" includeSource="true" includeConfigurePhase="true" type="InstallableUnit">
-      <unit id="org.eclipse.jetty.client" version="9.4.40.v20210413"/>
-      <unit id="org.eclipse.jetty.client.source" version="9.4.40.v20210413"/>
-      <unit id="org.eclipse.jetty.continuation" version="9.4.40.v20210413"/>
-      <unit id="org.eclipse.jetty.continuation.source" version="9.4.40.v20210413"/>
-      <unit id="org.eclipse.jetty.http" version="9.4.40.v20210413"/>
-      <unit id="org.eclipse.jetty.http.source" version="9.4.40.v20210413"/>
-      <unit id="org.eclipse.jetty.io" version="9.4.40.v20210413"/>
-      <unit id="org.eclipse.jetty.io.source" version="9.4.40.v20210413"/>
-      <unit id="org.eclipse.jetty.security" version="9.4.40.v20210413"/>
-      <unit id="org.eclipse.jetty.security.source" version="9.4.40.v20210413"/>
-      <unit id="org.eclipse.jetty.server" version="9.4.40.v20210413"/>
-      <unit id="org.eclipse.jetty.server.source" version="9.4.40.v20210413"/>
-      <unit id="org.eclipse.jetty.servlet" version="9.4.40.v20210413"/>
-      <unit id="org.eclipse.jetty.servlet.source" version="9.4.40.v20210413"/>
-      <unit id="org.eclipse.jetty.util" version="9.4.40.v20210413"/>
-      <unit id="org.eclipse.jetty.util.source" version="9.4.40.v20210413"/>
-      <unit id="org.eclipse.jetty.util.ajax" version="9.4.40.v20210413"/>
-      <unit id="org.eclipse.jetty.util.ajax.source" version="9.4.40.v20210413"/>
-      <repository id="jetty-9.4.36" location="https://download.eclipse.org/jetty/updates/jetty-bundles-9.x/9.4.40.v20210413/"/>
+      <unit id="org.eclipse.jetty.client" version="9.4.41.v20210516"/>
+      <unit id="org.eclipse.jetty.client.source" version="9.4.41.v20210516"/>
+      <unit id="org.eclipse.jetty.continuation" version="9.4.41.v20210516"/>
+      <unit id="org.eclipse.jetty.continuation.source" version="9.4.41.v20210516"/>
+      <unit id="org.eclipse.jetty.http" version="9.4.41.v20210516"/>
+      <unit id="org.eclipse.jetty.http.source" version="9.4.41.v20210516"/>
+      <unit id="org.eclipse.jetty.io" version="9.4.41.v20210516"/>
+      <unit id="org.eclipse.jetty.io.source" version="9.4.41.v20210516"/>
+      <unit id="org.eclipse.jetty.security" version="9.4.41.v20210516"/>
+      <unit id="org.eclipse.jetty.security.source" version="9.4.41.v20210516"/>
+      <unit id="org.eclipse.jetty.server" version="9.4.41.v20210516"/>
+      <unit id="org.eclipse.jetty.server.source" version="9.4.41.v20210516"/>
+      <unit id="org.eclipse.jetty.servlet" version="9.4.41.v20210516"/>
+      <unit id="org.eclipse.jetty.servlet.source" version="9.4.41.v20210516"/>
+      <unit id="org.eclipse.jetty.util" version="9.4.41.v20210516"/>
+      <unit id="org.eclipse.jetty.util.source" version="9.4.41.v20210516"/>
+      <unit id="org.eclipse.jetty.util.ajax" version="9.4.41.v20210516"/>
+      <unit id="org.eclipse.jetty.util.ajax.source" version="9.4.41.v20210516"/>
+      <repository id="jetty-9.4.40" location="https://download.eclipse.org/jetty/updates/jetty-bundles-9.x/9.4.41.v20210516/"/>
     </location>
     <location includeMode="slicer" includeAllPlatforms="false" includeSource="true" includeConfigurePhase="true" type="InstallableUnit">
       <unit id="com.google.gson" version="2.8.6.v20201231-1626"/>
@@ -41,8 +41,8 @@
       <unit id="net.bytebuddy.byte-buddy.source" version="1.9.0.v20181107-1410"/>
       <unit id="net.i2p.crypto.eddsa" version="0.3.0.v20181102-1323"/>
       <unit id="net.i2p.crypto.eddsa.source" version="0.3.0.v20181102-1323"/>
-      <unit id="org.apache.ant" version="1.10.9.v20201106-1946"/>
-      <unit id="org.apache.ant.source" version="1.10.9.v20201106-1946"/>
+      <unit id="org.apache.ant" version="1.10.10.v20210426-1926"/>
+      <unit id="org.apache.ant.source" version="1.10.10.v20210426-1926"/>
       <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"/>
@@ -86,7 +86,7 @@
       <unit id="org.slf4j.binding.log4j12.source" version="1.7.30.v20201108-2042"/>
       <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/S20210406213021/repository"/>
+      <repository location="https://download.eclipse.org/tools/orbit/downloads/drops/R20210602031627/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.18.tpd b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.18.tpd
index 6f0b0c3..0f42bb6 100644
--- a/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.18.tpd
+++ b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.18.tpd
@@ -1,7 +1,7 @@
 target "jgit-4.18" with source configurePhase
 
 include "projects/jetty-9.4.x.tpd"
-include "orbit/S20210406213021.tpd"
+include "orbit/R20210602031627-2021-06.tpd"
 
 location "https://download.eclipse.org/releases/2020-12/" {
 	org.eclipse.osgi lazy
diff --git a/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.19.target b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.19.target
index 16af400..6db7fe1 100644
--- a/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.19.target
+++ b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.19.target
@@ -1,28 +1,28 @@
 <?xml version="1.0" encoding="UTF-8" standalone="no"?>
 <?pde?>
 <!-- generated with https://github.com/eclipse-cbi/targetplatform-dsl -->
-<target name="jgit-4.19-staging" sequenceNumber="1619186288">
+<target name="jgit-4.19-staging" sequenceNumber="1623012870">
   <locations>
     <location includeMode="slicer" includeAllPlatforms="false" includeSource="true" includeConfigurePhase="true" type="InstallableUnit">
-      <unit id="org.eclipse.jetty.client" version="9.4.40.v20210413"/>
-      <unit id="org.eclipse.jetty.client.source" version="9.4.40.v20210413"/>
-      <unit id="org.eclipse.jetty.continuation" version="9.4.40.v20210413"/>
-      <unit id="org.eclipse.jetty.continuation.source" version="9.4.40.v20210413"/>
-      <unit id="org.eclipse.jetty.http" version="9.4.40.v20210413"/>
-      <unit id="org.eclipse.jetty.http.source" version="9.4.40.v20210413"/>
-      <unit id="org.eclipse.jetty.io" version="9.4.40.v20210413"/>
-      <unit id="org.eclipse.jetty.io.source" version="9.4.40.v20210413"/>
-      <unit id="org.eclipse.jetty.security" version="9.4.40.v20210413"/>
-      <unit id="org.eclipse.jetty.security.source" version="9.4.40.v20210413"/>
-      <unit id="org.eclipse.jetty.server" version="9.4.40.v20210413"/>
-      <unit id="org.eclipse.jetty.server.source" version="9.4.40.v20210413"/>
-      <unit id="org.eclipse.jetty.servlet" version="9.4.40.v20210413"/>
-      <unit id="org.eclipse.jetty.servlet.source" version="9.4.40.v20210413"/>
-      <unit id="org.eclipse.jetty.util" version="9.4.40.v20210413"/>
-      <unit id="org.eclipse.jetty.util.source" version="9.4.40.v20210413"/>
-      <unit id="org.eclipse.jetty.util.ajax" version="9.4.40.v20210413"/>
-      <unit id="org.eclipse.jetty.util.ajax.source" version="9.4.40.v20210413"/>
-      <repository id="jetty-9.4.36" location="https://download.eclipse.org/jetty/updates/jetty-bundles-9.x/9.4.40.v20210413/"/>
+      <unit id="org.eclipse.jetty.client" version="9.4.41.v20210516"/>
+      <unit id="org.eclipse.jetty.client.source" version="9.4.41.v20210516"/>
+      <unit id="org.eclipse.jetty.continuation" version="9.4.41.v20210516"/>
+      <unit id="org.eclipse.jetty.continuation.source" version="9.4.41.v20210516"/>
+      <unit id="org.eclipse.jetty.http" version="9.4.41.v20210516"/>
+      <unit id="org.eclipse.jetty.http.source" version="9.4.41.v20210516"/>
+      <unit id="org.eclipse.jetty.io" version="9.4.41.v20210516"/>
+      <unit id="org.eclipse.jetty.io.source" version="9.4.41.v20210516"/>
+      <unit id="org.eclipse.jetty.security" version="9.4.41.v20210516"/>
+      <unit id="org.eclipse.jetty.security.source" version="9.4.41.v20210516"/>
+      <unit id="org.eclipse.jetty.server" version="9.4.41.v20210516"/>
+      <unit id="org.eclipse.jetty.server.source" version="9.4.41.v20210516"/>
+      <unit id="org.eclipse.jetty.servlet" version="9.4.41.v20210516"/>
+      <unit id="org.eclipse.jetty.servlet.source" version="9.4.41.v20210516"/>
+      <unit id="org.eclipse.jetty.util" version="9.4.41.v20210516"/>
+      <unit id="org.eclipse.jetty.util.source" version="9.4.41.v20210516"/>
+      <unit id="org.eclipse.jetty.util.ajax" version="9.4.41.v20210516"/>
+      <unit id="org.eclipse.jetty.util.ajax.source" version="9.4.41.v20210516"/>
+      <repository id="jetty-9.4.40" location="https://download.eclipse.org/jetty/updates/jetty-bundles-9.x/9.4.41.v20210516/"/>
     </location>
     <location includeMode="slicer" includeAllPlatforms="false" includeSource="true" includeConfigurePhase="true" type="InstallableUnit">
       <unit id="com.google.gson" version="2.8.6.v20201231-1626"/>
@@ -41,8 +41,8 @@
       <unit id="net.bytebuddy.byte-buddy.source" version="1.9.0.v20181107-1410"/>
       <unit id="net.i2p.crypto.eddsa" version="0.3.0.v20181102-1323"/>
       <unit id="net.i2p.crypto.eddsa.source" version="0.3.0.v20181102-1323"/>
-      <unit id="org.apache.ant" version="1.10.9.v20201106-1946"/>
-      <unit id="org.apache.ant.source" version="1.10.9.v20201106-1946"/>
+      <unit id="org.apache.ant" version="1.10.10.v20210426-1926"/>
+      <unit id="org.apache.ant.source" version="1.10.10.v20210426-1926"/>
       <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"/>
@@ -86,7 +86,7 @@
       <unit id="org.slf4j.binding.log4j12.source" version="1.7.30.v20201108-2042"/>
       <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/S20210406213021/repository"/>
+      <repository location="https://download.eclipse.org/tools/orbit/downloads/drops/R20210602031627/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.19.tpd b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.19.tpd
index 6809f05..5e4305c 100644
--- a/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.19.tpd
+++ b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.19.tpd
@@ -1,7 +1,7 @@
 target "jgit-4.19-staging" with source configurePhase
 
 include "projects/jetty-9.4.x.tpd"
-include "orbit/S20210406213021.tpd"
+include "orbit/R20210602031627-2021-06.tpd"
 
 location "https://download.eclipse.org/staging/2021-03/" {
 	org.eclipse.osgi lazy
diff --git a/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.20-staging.target b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.20-staging.target
index 28471a3..f256622 100644
--- a/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.20-staging.target
+++ b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.20-staging.target
@@ -1,28 +1,28 @@
 <?xml version="1.0" encoding="UTF-8" standalone="no"?>
 <?pde?>
 <!-- generated with https://github.com/eclipse-cbi/targetplatform-dsl -->
-<target name="jgit-4.20-staging" sequenceNumber="1619186291">
+<target name="jgit-4.20-staging" sequenceNumber="1623012876">
   <locations>
     <location includeMode="slicer" includeAllPlatforms="false" includeSource="true" includeConfigurePhase="true" type="InstallableUnit">
-      <unit id="org.eclipse.jetty.client" version="9.4.40.v20210413"/>
-      <unit id="org.eclipse.jetty.client.source" version="9.4.40.v20210413"/>
-      <unit id="org.eclipse.jetty.continuation" version="9.4.40.v20210413"/>
-      <unit id="org.eclipse.jetty.continuation.source" version="9.4.40.v20210413"/>
-      <unit id="org.eclipse.jetty.http" version="9.4.40.v20210413"/>
-      <unit id="org.eclipse.jetty.http.source" version="9.4.40.v20210413"/>
-      <unit id="org.eclipse.jetty.io" version="9.4.40.v20210413"/>
-      <unit id="org.eclipse.jetty.io.source" version="9.4.40.v20210413"/>
-      <unit id="org.eclipse.jetty.security" version="9.4.40.v20210413"/>
-      <unit id="org.eclipse.jetty.security.source" version="9.4.40.v20210413"/>
-      <unit id="org.eclipse.jetty.server" version="9.4.40.v20210413"/>
-      <unit id="org.eclipse.jetty.server.source" version="9.4.40.v20210413"/>
-      <unit id="org.eclipse.jetty.servlet" version="9.4.40.v20210413"/>
-      <unit id="org.eclipse.jetty.servlet.source" version="9.4.40.v20210413"/>
-      <unit id="org.eclipse.jetty.util" version="9.4.40.v20210413"/>
-      <unit id="org.eclipse.jetty.util.source" version="9.4.40.v20210413"/>
-      <unit id="org.eclipse.jetty.util.ajax" version="9.4.40.v20210413"/>
-      <unit id="org.eclipse.jetty.util.ajax.source" version="9.4.40.v20210413"/>
-      <repository id="jetty-9.4.36" location="https://download.eclipse.org/jetty/updates/jetty-bundles-9.x/9.4.40.v20210413/"/>
+      <unit id="org.eclipse.jetty.client" version="9.4.41.v20210516"/>
+      <unit id="org.eclipse.jetty.client.source" version="9.4.41.v20210516"/>
+      <unit id="org.eclipse.jetty.continuation" version="9.4.41.v20210516"/>
+      <unit id="org.eclipse.jetty.continuation.source" version="9.4.41.v20210516"/>
+      <unit id="org.eclipse.jetty.http" version="9.4.41.v20210516"/>
+      <unit id="org.eclipse.jetty.http.source" version="9.4.41.v20210516"/>
+      <unit id="org.eclipse.jetty.io" version="9.4.41.v20210516"/>
+      <unit id="org.eclipse.jetty.io.source" version="9.4.41.v20210516"/>
+      <unit id="org.eclipse.jetty.security" version="9.4.41.v20210516"/>
+      <unit id="org.eclipse.jetty.security.source" version="9.4.41.v20210516"/>
+      <unit id="org.eclipse.jetty.server" version="9.4.41.v20210516"/>
+      <unit id="org.eclipse.jetty.server.source" version="9.4.41.v20210516"/>
+      <unit id="org.eclipse.jetty.servlet" version="9.4.41.v20210516"/>
+      <unit id="org.eclipse.jetty.servlet.source" version="9.4.41.v20210516"/>
+      <unit id="org.eclipse.jetty.util" version="9.4.41.v20210516"/>
+      <unit id="org.eclipse.jetty.util.source" version="9.4.41.v20210516"/>
+      <unit id="org.eclipse.jetty.util.ajax" version="9.4.41.v20210516"/>
+      <unit id="org.eclipse.jetty.util.ajax.source" version="9.4.41.v20210516"/>
+      <repository id="jetty-9.4.40" location="https://download.eclipse.org/jetty/updates/jetty-bundles-9.x/9.4.41.v20210516/"/>
     </location>
     <location includeMode="slicer" includeAllPlatforms="false" includeSource="true" includeConfigurePhase="true" type="InstallableUnit">
       <unit id="com.google.gson" version="2.8.6.v20201231-1626"/>
@@ -41,8 +41,8 @@
       <unit id="net.bytebuddy.byte-buddy.source" version="1.9.0.v20181107-1410"/>
       <unit id="net.i2p.crypto.eddsa" version="0.3.0.v20181102-1323"/>
       <unit id="net.i2p.crypto.eddsa.source" version="0.3.0.v20181102-1323"/>
-      <unit id="org.apache.ant" version="1.10.9.v20201106-1946"/>
-      <unit id="org.apache.ant.source" version="1.10.9.v20201106-1946"/>
+      <unit id="org.apache.ant" version="1.10.10.v20210426-1926"/>
+      <unit id="org.apache.ant.source" version="1.10.10.v20210426-1926"/>
       <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"/>
@@ -86,7 +86,7 @@
       <unit id="org.slf4j.binding.log4j12.source" version="1.7.30.v20201108-2042"/>
       <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/S20210406213021/repository"/>
+      <repository location="https://download.eclipse.org/tools/orbit/downloads/drops/R20210602031627/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.20-staging.tpd b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.20-staging.tpd
index e7d4f25..de929b5 100644
--- a/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.20-staging.tpd
+++ b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.20-staging.tpd
@@ -1,7 +1,7 @@
 target "jgit-4.20-staging" with source configurePhase
 
 include "projects/jetty-9.4.x.tpd"
-include "orbit/S20210406213021.tpd"
+include "orbit/R20210602031627-2021-06.tpd"
 
 location "https://download.eclipse.org/staging/2021-06/" {
 	org.eclipse.osgi lazy
diff --git a/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.6.target b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.6.target
index 8aa7d08..ca1696b 100644
--- a/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.6.target
+++ b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.6.target
@@ -1,28 +1,28 @@
 <?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="1619186309">
+<target name="jgit-4.6" sequenceNumber="1623012886">
   <locations>
     <location includeMode="slicer" includeAllPlatforms="false" includeSource="true" includeConfigurePhase="true" type="InstallableUnit">
-      <unit id="org.eclipse.jetty.client" version="9.4.40.v20210413"/>
-      <unit id="org.eclipse.jetty.client.source" version="9.4.40.v20210413"/>
-      <unit id="org.eclipse.jetty.continuation" version="9.4.40.v20210413"/>
-      <unit id="org.eclipse.jetty.continuation.source" version="9.4.40.v20210413"/>
-      <unit id="org.eclipse.jetty.http" version="9.4.40.v20210413"/>
-      <unit id="org.eclipse.jetty.http.source" version="9.4.40.v20210413"/>
-      <unit id="org.eclipse.jetty.io" version="9.4.40.v20210413"/>
-      <unit id="org.eclipse.jetty.io.source" version="9.4.40.v20210413"/>
-      <unit id="org.eclipse.jetty.security" version="9.4.40.v20210413"/>
-      <unit id="org.eclipse.jetty.security.source" version="9.4.40.v20210413"/>
-      <unit id="org.eclipse.jetty.server" version="9.4.40.v20210413"/>
-      <unit id="org.eclipse.jetty.server.source" version="9.4.40.v20210413"/>
-      <unit id="org.eclipse.jetty.servlet" version="9.4.40.v20210413"/>
-      <unit id="org.eclipse.jetty.servlet.source" version="9.4.40.v20210413"/>
-      <unit id="org.eclipse.jetty.util" version="9.4.40.v20210413"/>
-      <unit id="org.eclipse.jetty.util.source" version="9.4.40.v20210413"/>
-      <unit id="org.eclipse.jetty.util.ajax" version="9.4.40.v20210413"/>
-      <unit id="org.eclipse.jetty.util.ajax.source" version="9.4.40.v20210413"/>
-      <repository id="jetty-9.4.36" location="https://download.eclipse.org/jetty/updates/jetty-bundles-9.x/9.4.40.v20210413/"/>
+      <unit id="org.eclipse.jetty.client" version="9.4.41.v20210516"/>
+      <unit id="org.eclipse.jetty.client.source" version="9.4.41.v20210516"/>
+      <unit id="org.eclipse.jetty.continuation" version="9.4.41.v20210516"/>
+      <unit id="org.eclipse.jetty.continuation.source" version="9.4.41.v20210516"/>
+      <unit id="org.eclipse.jetty.http" version="9.4.41.v20210516"/>
+      <unit id="org.eclipse.jetty.http.source" version="9.4.41.v20210516"/>
+      <unit id="org.eclipse.jetty.io" version="9.4.41.v20210516"/>
+      <unit id="org.eclipse.jetty.io.source" version="9.4.41.v20210516"/>
+      <unit id="org.eclipse.jetty.security" version="9.4.41.v20210516"/>
+      <unit id="org.eclipse.jetty.security.source" version="9.4.41.v20210516"/>
+      <unit id="org.eclipse.jetty.server" version="9.4.41.v20210516"/>
+      <unit id="org.eclipse.jetty.server.source" version="9.4.41.v20210516"/>
+      <unit id="org.eclipse.jetty.servlet" version="9.4.41.v20210516"/>
+      <unit id="org.eclipse.jetty.servlet.source" version="9.4.41.v20210516"/>
+      <unit id="org.eclipse.jetty.util" version="9.4.41.v20210516"/>
+      <unit id="org.eclipse.jetty.util.source" version="9.4.41.v20210516"/>
+      <unit id="org.eclipse.jetty.util.ajax" version="9.4.41.v20210516"/>
+      <unit id="org.eclipse.jetty.util.ajax.source" version="9.4.41.v20210516"/>
+      <repository id="jetty-9.4.40" location="https://download.eclipse.org/jetty/updates/jetty-bundles-9.x/9.4.41.v20210516/"/>
     </location>
     <location includeMode="slicer" includeAllPlatforms="false" includeSource="true" includeConfigurePhase="true" type="InstallableUnit">
       <unit id="com.google.gson" version="2.8.6.v20201231-1626"/>
@@ -41,8 +41,8 @@
       <unit id="net.bytebuddy.byte-buddy.source" version="1.9.0.v20181107-1410"/>
       <unit id="net.i2p.crypto.eddsa" version="0.3.0.v20181102-1323"/>
       <unit id="net.i2p.crypto.eddsa.source" version="0.3.0.v20181102-1323"/>
-      <unit id="org.apache.ant" version="1.10.9.v20201106-1946"/>
-      <unit id="org.apache.ant.source" version="1.10.9.v20201106-1946"/>
+      <unit id="org.apache.ant" version="1.10.10.v20210426-1926"/>
+      <unit id="org.apache.ant.source" version="1.10.10.v20210426-1926"/>
       <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"/>
@@ -86,7 +86,7 @@
       <unit id="org.slf4j.binding.log4j12.source" version="1.7.30.v20201108-2042"/>
       <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/S20210406213021/repository"/>
+      <repository location="https://download.eclipse.org/tools/orbit/downloads/drops/R20210602031627/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 4128209..96a6073 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/S20210406213021.tpd"
+include "orbit/R20210602031627-2021-06.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 178640a..6098388 100644
--- a/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.7.target
+++ b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.7.target
@@ -1,28 +1,28 @@
 <?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="1619186297">
+<target name="jgit-4.7" sequenceNumber="1623012878">
   <locations>
     <location includeMode="slicer" includeAllPlatforms="false" includeSource="true" includeConfigurePhase="true" type="InstallableUnit">
-      <unit id="org.eclipse.jetty.client" version="9.4.40.v20210413"/>
-      <unit id="org.eclipse.jetty.client.source" version="9.4.40.v20210413"/>
-      <unit id="org.eclipse.jetty.continuation" version="9.4.40.v20210413"/>
-      <unit id="org.eclipse.jetty.continuation.source" version="9.4.40.v20210413"/>
-      <unit id="org.eclipse.jetty.http" version="9.4.40.v20210413"/>
-      <unit id="org.eclipse.jetty.http.source" version="9.4.40.v20210413"/>
-      <unit id="org.eclipse.jetty.io" version="9.4.40.v20210413"/>
-      <unit id="org.eclipse.jetty.io.source" version="9.4.40.v20210413"/>
-      <unit id="org.eclipse.jetty.security" version="9.4.40.v20210413"/>
-      <unit id="org.eclipse.jetty.security.source" version="9.4.40.v20210413"/>
-      <unit id="org.eclipse.jetty.server" version="9.4.40.v20210413"/>
-      <unit id="org.eclipse.jetty.server.source" version="9.4.40.v20210413"/>
-      <unit id="org.eclipse.jetty.servlet" version="9.4.40.v20210413"/>
-      <unit id="org.eclipse.jetty.servlet.source" version="9.4.40.v20210413"/>
-      <unit id="org.eclipse.jetty.util" version="9.4.40.v20210413"/>
-      <unit id="org.eclipse.jetty.util.source" version="9.4.40.v20210413"/>
-      <unit id="org.eclipse.jetty.util.ajax" version="9.4.40.v20210413"/>
-      <unit id="org.eclipse.jetty.util.ajax.source" version="9.4.40.v20210413"/>
-      <repository id="jetty-9.4.36" location="https://download.eclipse.org/jetty/updates/jetty-bundles-9.x/9.4.40.v20210413/"/>
+      <unit id="org.eclipse.jetty.client" version="9.4.41.v20210516"/>
+      <unit id="org.eclipse.jetty.client.source" version="9.4.41.v20210516"/>
+      <unit id="org.eclipse.jetty.continuation" version="9.4.41.v20210516"/>
+      <unit id="org.eclipse.jetty.continuation.source" version="9.4.41.v20210516"/>
+      <unit id="org.eclipse.jetty.http" version="9.4.41.v20210516"/>
+      <unit id="org.eclipse.jetty.http.source" version="9.4.41.v20210516"/>
+      <unit id="org.eclipse.jetty.io" version="9.4.41.v20210516"/>
+      <unit id="org.eclipse.jetty.io.source" version="9.4.41.v20210516"/>
+      <unit id="org.eclipse.jetty.security" version="9.4.41.v20210516"/>
+      <unit id="org.eclipse.jetty.security.source" version="9.4.41.v20210516"/>
+      <unit id="org.eclipse.jetty.server" version="9.4.41.v20210516"/>
+      <unit id="org.eclipse.jetty.server.source" version="9.4.41.v20210516"/>
+      <unit id="org.eclipse.jetty.servlet" version="9.4.41.v20210516"/>
+      <unit id="org.eclipse.jetty.servlet.source" version="9.4.41.v20210516"/>
+      <unit id="org.eclipse.jetty.util" version="9.4.41.v20210516"/>
+      <unit id="org.eclipse.jetty.util.source" version="9.4.41.v20210516"/>
+      <unit id="org.eclipse.jetty.util.ajax" version="9.4.41.v20210516"/>
+      <unit id="org.eclipse.jetty.util.ajax.source" version="9.4.41.v20210516"/>
+      <repository id="jetty-9.4.40" location="https://download.eclipse.org/jetty/updates/jetty-bundles-9.x/9.4.41.v20210516/"/>
     </location>
     <location includeMode="slicer" includeAllPlatforms="false" includeSource="true" includeConfigurePhase="true" type="InstallableUnit">
       <unit id="com.google.gson" version="2.8.6.v20201231-1626"/>
@@ -41,8 +41,8 @@
       <unit id="net.bytebuddy.byte-buddy.source" version="1.9.0.v20181107-1410"/>
       <unit id="net.i2p.crypto.eddsa" version="0.3.0.v20181102-1323"/>
       <unit id="net.i2p.crypto.eddsa.source" version="0.3.0.v20181102-1323"/>
-      <unit id="org.apache.ant" version="1.10.9.v20201106-1946"/>
-      <unit id="org.apache.ant.source" version="1.10.9.v20201106-1946"/>
+      <unit id="org.apache.ant" version="1.10.10.v20210426-1926"/>
+      <unit id="org.apache.ant.source" version="1.10.10.v20210426-1926"/>
       <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"/>
@@ -86,7 +86,7 @@
       <unit id="org.slf4j.binding.log4j12.source" version="1.7.30.v20201108-2042"/>
       <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/S20210406213021/repository"/>
+      <repository location="https://download.eclipse.org/tools/orbit/downloads/drops/R20210602031627/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 68c6b7b..bfb68b2 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/S20210406213021.tpd"
+include "orbit/R20210602031627-2021-06.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 e5d0829..180b814 100644
--- a/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.8.target
+++ b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.8.target
@@ -1,28 +1,28 @@
 <?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="1619186290">
+<target name="jgit-4.8" sequenceNumber="1623012874">
   <locations>
     <location includeMode="slicer" includeAllPlatforms="false" includeSource="true" includeConfigurePhase="true" type="InstallableUnit">
-      <unit id="org.eclipse.jetty.client" version="9.4.40.v20210413"/>
-      <unit id="org.eclipse.jetty.client.source" version="9.4.40.v20210413"/>
-      <unit id="org.eclipse.jetty.continuation" version="9.4.40.v20210413"/>
-      <unit id="org.eclipse.jetty.continuation.source" version="9.4.40.v20210413"/>
-      <unit id="org.eclipse.jetty.http" version="9.4.40.v20210413"/>
-      <unit id="org.eclipse.jetty.http.source" version="9.4.40.v20210413"/>
-      <unit id="org.eclipse.jetty.io" version="9.4.40.v20210413"/>
-      <unit id="org.eclipse.jetty.io.source" version="9.4.40.v20210413"/>
-      <unit id="org.eclipse.jetty.security" version="9.4.40.v20210413"/>
-      <unit id="org.eclipse.jetty.security.source" version="9.4.40.v20210413"/>
-      <unit id="org.eclipse.jetty.server" version="9.4.40.v20210413"/>
-      <unit id="org.eclipse.jetty.server.source" version="9.4.40.v20210413"/>
-      <unit id="org.eclipse.jetty.servlet" version="9.4.40.v20210413"/>
-      <unit id="org.eclipse.jetty.servlet.source" version="9.4.40.v20210413"/>
-      <unit id="org.eclipse.jetty.util" version="9.4.40.v20210413"/>
-      <unit id="org.eclipse.jetty.util.source" version="9.4.40.v20210413"/>
-      <unit id="org.eclipse.jetty.util.ajax" version="9.4.40.v20210413"/>
-      <unit id="org.eclipse.jetty.util.ajax.source" version="9.4.40.v20210413"/>
-      <repository id="jetty-9.4.36" location="https://download.eclipse.org/jetty/updates/jetty-bundles-9.x/9.4.40.v20210413/"/>
+      <unit id="org.eclipse.jetty.client" version="9.4.41.v20210516"/>
+      <unit id="org.eclipse.jetty.client.source" version="9.4.41.v20210516"/>
+      <unit id="org.eclipse.jetty.continuation" version="9.4.41.v20210516"/>
+      <unit id="org.eclipse.jetty.continuation.source" version="9.4.41.v20210516"/>
+      <unit id="org.eclipse.jetty.http" version="9.4.41.v20210516"/>
+      <unit id="org.eclipse.jetty.http.source" version="9.4.41.v20210516"/>
+      <unit id="org.eclipse.jetty.io" version="9.4.41.v20210516"/>
+      <unit id="org.eclipse.jetty.io.source" version="9.4.41.v20210516"/>
+      <unit id="org.eclipse.jetty.security" version="9.4.41.v20210516"/>
+      <unit id="org.eclipse.jetty.security.source" version="9.4.41.v20210516"/>
+      <unit id="org.eclipse.jetty.server" version="9.4.41.v20210516"/>
+      <unit id="org.eclipse.jetty.server.source" version="9.4.41.v20210516"/>
+      <unit id="org.eclipse.jetty.servlet" version="9.4.41.v20210516"/>
+      <unit id="org.eclipse.jetty.servlet.source" version="9.4.41.v20210516"/>
+      <unit id="org.eclipse.jetty.util" version="9.4.41.v20210516"/>
+      <unit id="org.eclipse.jetty.util.source" version="9.4.41.v20210516"/>
+      <unit id="org.eclipse.jetty.util.ajax" version="9.4.41.v20210516"/>
+      <unit id="org.eclipse.jetty.util.ajax.source" version="9.4.41.v20210516"/>
+      <repository id="jetty-9.4.40" location="https://download.eclipse.org/jetty/updates/jetty-bundles-9.x/9.4.41.v20210516/"/>
     </location>
     <location includeMode="slicer" includeAllPlatforms="false" includeSource="true" includeConfigurePhase="true" type="InstallableUnit">
       <unit id="com.google.gson" version="2.8.6.v20201231-1626"/>
@@ -41,8 +41,8 @@
       <unit id="net.bytebuddy.byte-buddy.source" version="1.9.0.v20181107-1410"/>
       <unit id="net.i2p.crypto.eddsa" version="0.3.0.v20181102-1323"/>
       <unit id="net.i2p.crypto.eddsa.source" version="0.3.0.v20181102-1323"/>
-      <unit id="org.apache.ant" version="1.10.9.v20201106-1946"/>
-      <unit id="org.apache.ant.source" version="1.10.9.v20201106-1946"/>
+      <unit id="org.apache.ant" version="1.10.10.v20210426-1926"/>
+      <unit id="org.apache.ant.source" version="1.10.10.v20210426-1926"/>
       <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"/>
@@ -86,7 +86,7 @@
       <unit id="org.slf4j.binding.log4j12.source" version="1.7.30.v20201108-2042"/>
       <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/S20210406213021/repository"/>
+      <repository location="https://download.eclipse.org/tools/orbit/downloads/drops/R20210602031627/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 f7ac2c0..e3e6b21 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/S20210406213021.tpd"
+include "orbit/R20210602031627-2021-06.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 46c2644..27b3096 100644
--- a/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.9.target
+++ b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.9.target
@@ -1,28 +1,28 @@
 <?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="1619186290">
+<target name="jgit-4.9" sequenceNumber="1623012874">
   <locations>
     <location includeMode="slicer" includeAllPlatforms="false" includeSource="true" includeConfigurePhase="true" type="InstallableUnit">
-      <unit id="org.eclipse.jetty.client" version="9.4.40.v20210413"/>
-      <unit id="org.eclipse.jetty.client.source" version="9.4.40.v20210413"/>
-      <unit id="org.eclipse.jetty.continuation" version="9.4.40.v20210413"/>
-      <unit id="org.eclipse.jetty.continuation.source" version="9.4.40.v20210413"/>
-      <unit id="org.eclipse.jetty.http" version="9.4.40.v20210413"/>
-      <unit id="org.eclipse.jetty.http.source" version="9.4.40.v20210413"/>
-      <unit id="org.eclipse.jetty.io" version="9.4.40.v20210413"/>
-      <unit id="org.eclipse.jetty.io.source" version="9.4.40.v20210413"/>
-      <unit id="org.eclipse.jetty.security" version="9.4.40.v20210413"/>
-      <unit id="org.eclipse.jetty.security.source" version="9.4.40.v20210413"/>
-      <unit id="org.eclipse.jetty.server" version="9.4.40.v20210413"/>
-      <unit id="org.eclipse.jetty.server.source" version="9.4.40.v20210413"/>
-      <unit id="org.eclipse.jetty.servlet" version="9.4.40.v20210413"/>
-      <unit id="org.eclipse.jetty.servlet.source" version="9.4.40.v20210413"/>
-      <unit id="org.eclipse.jetty.util" version="9.4.40.v20210413"/>
-      <unit id="org.eclipse.jetty.util.source" version="9.4.40.v20210413"/>
-      <unit id="org.eclipse.jetty.util.ajax" version="9.4.40.v20210413"/>
-      <unit id="org.eclipse.jetty.util.ajax.source" version="9.4.40.v20210413"/>
-      <repository id="jetty-9.4.36" location="https://download.eclipse.org/jetty/updates/jetty-bundles-9.x/9.4.40.v20210413/"/>
+      <unit id="org.eclipse.jetty.client" version="9.4.41.v20210516"/>
+      <unit id="org.eclipse.jetty.client.source" version="9.4.41.v20210516"/>
+      <unit id="org.eclipse.jetty.continuation" version="9.4.41.v20210516"/>
+      <unit id="org.eclipse.jetty.continuation.source" version="9.4.41.v20210516"/>
+      <unit id="org.eclipse.jetty.http" version="9.4.41.v20210516"/>
+      <unit id="org.eclipse.jetty.http.source" version="9.4.41.v20210516"/>
+      <unit id="org.eclipse.jetty.io" version="9.4.41.v20210516"/>
+      <unit id="org.eclipse.jetty.io.source" version="9.4.41.v20210516"/>
+      <unit id="org.eclipse.jetty.security" version="9.4.41.v20210516"/>
+      <unit id="org.eclipse.jetty.security.source" version="9.4.41.v20210516"/>
+      <unit id="org.eclipse.jetty.server" version="9.4.41.v20210516"/>
+      <unit id="org.eclipse.jetty.server.source" version="9.4.41.v20210516"/>
+      <unit id="org.eclipse.jetty.servlet" version="9.4.41.v20210516"/>
+      <unit id="org.eclipse.jetty.servlet.source" version="9.4.41.v20210516"/>
+      <unit id="org.eclipse.jetty.util" version="9.4.41.v20210516"/>
+      <unit id="org.eclipse.jetty.util.source" version="9.4.41.v20210516"/>
+      <unit id="org.eclipse.jetty.util.ajax" version="9.4.41.v20210516"/>
+      <unit id="org.eclipse.jetty.util.ajax.source" version="9.4.41.v20210516"/>
+      <repository id="jetty-9.4.40" location="https://download.eclipse.org/jetty/updates/jetty-bundles-9.x/9.4.41.v20210516/"/>
     </location>
     <location includeMode="slicer" includeAllPlatforms="false" includeSource="true" includeConfigurePhase="true" type="InstallableUnit">
       <unit id="com.google.gson" version="2.8.6.v20201231-1626"/>
@@ -41,8 +41,8 @@
       <unit id="net.bytebuddy.byte-buddy.source" version="1.9.0.v20181107-1410"/>
       <unit id="net.i2p.crypto.eddsa" version="0.3.0.v20181102-1323"/>
       <unit id="net.i2p.crypto.eddsa.source" version="0.3.0.v20181102-1323"/>
-      <unit id="org.apache.ant" version="1.10.9.v20201106-1946"/>
-      <unit id="org.apache.ant.source" version="1.10.9.v20201106-1946"/>
+      <unit id="org.apache.ant" version="1.10.10.v20210426-1926"/>
+      <unit id="org.apache.ant.source" version="1.10.10.v20210426-1926"/>
       <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"/>
@@ -86,7 +86,7 @@
       <unit id="org.slf4j.binding.log4j12.source" version="1.7.30.v20201108-2042"/>
       <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/S20210406213021/repository"/>
+      <repository location="https://download.eclipse.org/tools/orbit/downloads/drops/R20210602031627/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 c77376a..938d80b 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/S20210406213021.tpd"
+include "orbit/R20210602031627-2021-06.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/S20210406213021.tpd b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/orbit/R20210602031627-2021-06.tpd
similarity index 94%
rename from org.eclipse.jgit.packaging/org.eclipse.jgit.target/orbit/S20210406213021.tpd
rename to org.eclipse.jgit.packaging/org.eclipse.jgit.target/orbit/R20210602031627-2021-06.tpd
index 45d0fd1..83b5bb3 100644
--- a/org.eclipse.jgit.packaging/org.eclipse.jgit.target/orbit/S20210406213021.tpd
+++ b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/orbit/R20210602031627-2021-06.tpd
@@ -1,7 +1,7 @@
-target "S20210406213021" with source configurePhase
+target "R20210602031627-2021-06" with source configurePhase
 // see https://download.eclipse.org/tools/orbit/downloads/
 
-location "https://download.eclipse.org/tools/orbit/downloads/drops/S20210406213021/repository" {
+location "https://download.eclipse.org/tools/orbit/downloads/drops/R20210602031627/repository" {
 	com.google.gson [2.8.6.v20201231-1626,2.8.6.v20201231-1626]
 	com.google.gson.source [2.8.6.v20201231-1626,2.8.6.v20201231-1626]
 	com.jcraft.jsch [0.1.55.v20190404-1902,0.1.55.v20190404-1902]
@@ -18,8 +18,8 @@
 	net.bytebuddy.byte-buddy.source [1.9.0.v20181107-1410,1.9.0.v20181107-1410]
 	net.i2p.crypto.eddsa [0.3.0.v20181102-1323,0.3.0.v20181102-1323]
 	net.i2p.crypto.eddsa.source [0.3.0.v20181102-1323,0.3.0.v20181102-1323]
-	org.apache.ant [1.10.9.v20201106-1946,1.10.9.v20201106-1946]
-	org.apache.ant.source [1.10.9.v20201106-1946,1.10.9.v20201106-1946]
+	org.apache.ant [1.10.10.v20210426-1926,1.10.10.v20210426-1926]
+	org.apache.ant.source [1.10.10.v20210426-1926,1.10.10.v20210426-1926]
 	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]
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 0f0b100..fb0df1e 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,22 +1,22 @@
 target "jetty-9.4.x" with source configurePhase
 
-location jetty-9.4.40 "https://download.eclipse.org/jetty/updates/jetty-bundles-9.x/9.4.40.v20210413/" {
-	org.eclipse.jetty.client [9.4.40.v20210413,9.4.40.v20210413]
-	org.eclipse.jetty.client.source [9.4.40.v20210413,9.4.40.v20210413]
-	org.eclipse.jetty.continuation [9.4.40.v20210413,9.4.40.v20210413]
-	org.eclipse.jetty.continuation.source [9.4.40.v20210413,9.4.40.v20210413]
-	org.eclipse.jetty.http [9.4.40.v20210413,9.4.40.v20210413]
-	org.eclipse.jetty.http.source [9.4.40.v20210413,9.4.40.v20210413]
-	org.eclipse.jetty.io [9.4.40.v20210413,9.4.40.v20210413]
-	org.eclipse.jetty.io.source [9.4.40.v20210413,9.4.40.v20210413]
-	org.eclipse.jetty.security [9.4.40.v20210413,9.4.40.v20210413]
-	org.eclipse.jetty.security.source [9.4.40.v20210413,9.4.40.v20210413]
-	org.eclipse.jetty.server [9.4.40.v20210413,9.4.40.v20210413]
-	org.eclipse.jetty.server.source [9.4.40.v20210413,9.4.40.v20210413]
-	org.eclipse.jetty.servlet [9.4.40.v20210413,9.4.40.v20210413]
-	org.eclipse.jetty.servlet.source [9.4.40.v20210413,9.4.40.v20210413]
-	org.eclipse.jetty.util [9.4.40.v20210413,9.4.40.v20210413]
-	org.eclipse.jetty.util.source [9.4.40.v20210413,9.4.40.v20210413]
-	org.eclipse.jetty.util.ajax [9.4.40.v20210413,9.4.40.v20210413]
-	org.eclipse.jetty.util.ajax.source [9.4.40.v20210413,9.4.40.v20210413]
+location jetty-9.4.40 "https://download.eclipse.org/jetty/updates/jetty-bundles-9.x/9.4.41.v20210516/" {
+	org.eclipse.jetty.client [9.4.41.v20210516,9.4.41.v20210516]
+	org.eclipse.jetty.client.source [9.4.41.v20210516,9.4.41.v20210516]
+	org.eclipse.jetty.continuation [9.4.41.v20210516,9.4.41.v20210516]
+	org.eclipse.jetty.continuation.source [9.4.41.v20210516,9.4.41.v20210516]
+	org.eclipse.jetty.http [9.4.41.v20210516,9.4.41.v20210516]
+	org.eclipse.jetty.http.source [9.4.41.v20210516,9.4.41.v20210516]
+	org.eclipse.jetty.io [9.4.41.v20210516,9.4.41.v20210516]
+	org.eclipse.jetty.io.source [9.4.41.v20210516,9.4.41.v20210516]
+	org.eclipse.jetty.security [9.4.41.v20210516,9.4.41.v20210516]
+	org.eclipse.jetty.security.source [9.4.41.v20210516,9.4.41.v20210516]
+	org.eclipse.jetty.server [9.4.41.v20210516,9.4.41.v20210516]
+	org.eclipse.jetty.server.source [9.4.41.v20210516,9.4.41.v20210516]
+	org.eclipse.jetty.servlet [9.4.41.v20210516,9.4.41.v20210516]
+	org.eclipse.jetty.servlet.source [9.4.41.v20210516,9.4.41.v20210516]
+	org.eclipse.jetty.util [9.4.41.v20210516,9.4.41.v20210516]
+	org.eclipse.jetty.util.source [9.4.41.v20210516,9.4.41.v20210516]
+	org.eclipse.jetty.util.ajax [9.4.41.v20210516,9.4.41.v20210516]
+	org.eclipse.jetty.util.ajax.source [9.4.41.v20210516,9.4.41.v20210516]
 }
diff --git a/org.eclipse.jgit.pgm.test/tst/org/eclipse/jgit/pgm/RevListTest.java b/org.eclipse.jgit.pgm.test/tst/org/eclipse/jgit/pgm/RevListTest.java
new file mode 100644
index 0000000..06fddc2
--- /dev/null
+++ b/org.eclipse.jgit.pgm.test/tst/org/eclipse/jgit/pgm/RevListTest.java
@@ -0,0 +1,75 @@
+/*
+ * Copyright (C) 2021, kylezhao <kylezhao@tencent.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
+ * https://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+package org.eclipse.jgit.pgm;
+
+import static org.junit.Assert.assertEquals;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.eclipse.jgit.api.Git;
+import org.eclipse.jgit.lib.CLIRepositoryTestCase;
+import org.eclipse.jgit.revwalk.RevCommit;
+import org.junit.Before;
+import org.junit.Test;
+
+public class RevListTest extends CLIRepositoryTestCase {
+
+	private Git git;
+
+	@Override
+	@Before
+	public void setUp() throws Exception {
+		super.setUp();
+		git = new Git(db);
+	}
+
+	@Test
+	public void testWithParentsFlag() throws Exception {
+		List<RevCommit> commits = createCommitsForParentsFlag(git);
+		String result = toString(
+				execute("git rev-list HEAD --parents -- Test.txt"));
+
+		String expect = toString(
+				commits.get(3).name() + ' ' + commits.get(1).name(),
+				commits.get(1).name());
+
+		assertEquals(expect, result);
+	}
+
+	@Test
+	public void testWithoutParentsFlag() throws Exception {
+		List<RevCommit> commits = createCommitsForParentsFlag(git);
+		String result = toString(execute("git rev-list HEAD -- Test.txt"));
+
+		String expect = toString(commits.get(3).name(), commits.get(1).name());
+
+		assertEquals(expect, result);
+	}
+
+	private List<RevCommit> createCommitsForParentsFlag(Git git)
+			throws Exception {
+		List<RevCommit> commits = new ArrayList<>();
+		writeTrashFile("Test1.txt", "Hello world");
+		git.add().addFilepattern("Test1.txt").call();
+		commits.add(git.commit().setMessage("commit#0").call());
+		writeTrashFile("Test.txt", "Hello world!");
+		git.add().addFilepattern("Test.txt").call();
+		commits.add(git.commit().setMessage("commit#1").call());
+		writeTrashFile("Test1.txt", "Hello world!!");
+		git.add().addFilepattern("Test1.txt").call();
+		commits.add(git.commit().setMessage("commit#2").call());
+		writeTrashFile("Test.txt", "Hello world!!!");
+		git.add().addFilepattern("Test.txt").call();
+		commits.add(git.commit().setMessage("commit#3").call());
+		return commits;
+	}
+}
diff --git a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/RevWalkTextBuiltin.java b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/RevWalkTextBuiltin.java
index 822f899..696a924 100644
--- a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/RevWalkTextBuiltin.java
+++ b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/RevWalkTextBuiltin.java
@@ -129,6 +129,9 @@
 			walk.setTreeFilter(AndTreeFilter.create(pathFilter,
 					TreeFilter.ANY_DIFF));
 		}
+		if (parents) {
+			walk.setRewriteParents(true);
+		}
 
 		if (revLimiter.size() == 1)
 			walk.setRevFilter(revLimiter.get(0));
diff --git a/org.eclipse.jgit.ssh.jsch.test/tst/org/eclipse/jgit/transport/OpenSshConfigTest.java b/org.eclipse.jgit.ssh.jsch.test/tst/org/eclipse/jgit/transport/OpenSshConfigTest.java
index 4be2271..93d85e2 100644
--- a/org.eclipse.jgit.ssh.jsch.test/tst/org/eclipse/jgit/transport/OpenSshConfigTest.java
+++ b/org.eclipse.jgit.ssh.jsch.test/tst/org/eclipse/jgit/transport/OpenSshConfigTest.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2008, 2017 Google Inc. and others
+ * Copyright (C) 2008, 2021 Google Inc. and others
  *
  * This program and the accompanying materials are made available under the
  * terms of the Eclipse Distribution License v. 1.0 which is available at
@@ -517,4 +517,76 @@
 		assertEquals("/tmp/${TST_VAR/bar",
 				c.getValue(SshConstants.IDENTITY_AGENT));
 	}
+
+	@Test
+	public void testNegativeMatch() throws Exception {
+		config("Host foo.bar !foobar.baz *.baz\n" + "Port 29418\n");
+		Host h = osc.lookup("foo.bar");
+		assertNotNull(h);
+		assertEquals(29418, h.getPort());
+		h = osc.lookup("foobar.baz");
+		assertNotNull(h);
+		assertEquals(22, h.getPort());
+		h = osc.lookup("foo.baz");
+		assertNotNull(h);
+		assertEquals(29418, h.getPort());
+	}
+
+	@Test
+	public void testNegativeMatch2() throws Exception {
+		// Negative match after the positive match.
+		config("Host foo.bar *.baz !foobar.baz\n" + "Port 29418\n");
+		Host h = osc.lookup("foo.bar");
+		assertNotNull(h);
+		assertEquals(29418, h.getPort());
+		h = osc.lookup("foobar.baz");
+		assertNotNull(h);
+		assertEquals(22, h.getPort());
+		h = osc.lookup("foo.baz");
+		assertNotNull(h);
+		assertEquals(29418, h.getPort());
+	}
+
+	@Test
+	public void testNoMatch() throws Exception {
+		config("Host !host1 !host2\n" + "Port 29418\n");
+		Host h = osc.lookup("host1");
+		assertNotNull(h);
+		assertEquals(22, h.getPort());
+		h = osc.lookup("host2");
+		assertNotNull(h);
+		assertEquals(22, h.getPort());
+		h = osc.lookup("host3");
+		assertNotNull(h);
+		assertEquals(22, h.getPort());
+	}
+
+	@Test
+	public void testMultipleMatch() throws Exception {
+		config("Host foo.bar\nPort 29418\nIdentityFile /foo\n\n"
+				+ "Host *.bar\nPort 22\nIdentityFile /bar\n"
+				+ "Host foo.bar\nPort 47\nIdentityFile /baz\n");
+		Host h = osc.lookup("foo.bar");
+		assertNotNull(h);
+		assertEquals(29418, h.getPort());
+		assertArrayEquals(new Object[] { "/foo", "/bar", "/baz" },
+				h.getConfig().getValues("IdentityFile"));
+	}
+
+	@Test
+	public void testWhitespace() throws Exception {
+		config("Host foo \tbar   baz\nPort 29418\n");
+		Host h = osc.lookup("foo");
+		assertNotNull(h);
+		assertEquals(29418, h.getPort());
+		h = osc.lookup("bar");
+		assertNotNull(h);
+		assertEquals(29418, h.getPort());
+		h = osc.lookup("baz");
+		assertNotNull(h);
+		assertEquals(29418, h.getPort());
+		h = osc.lookup("\tbar");
+		assertNotNull(h);
+		assertEquals(22, h.getPort());
+	}
 }
diff --git a/org.eclipse.jgit.test/.settings/org.eclipse.core.resources.prefs b/org.eclipse.jgit.test/.settings/org.eclipse.core.resources.prefs
index 6a9621d..cddb99d 100644
--- a/org.eclipse.jgit.test/.settings/org.eclipse.core.resources.prefs
+++ b/org.eclipse.jgit.test/.settings/org.eclipse.core.resources.prefs
@@ -1,5 +1,6 @@
-#Sat Dec 20 21:21:24 CET 2008
 eclipse.preferences.version=1
+encoding//tst-rsrc/org/eclipse/jgit/diff/umlaut.patch=ISO-8859-1
+encoding//tst-rsrc/org/eclipse/jgit/diff/umlaut_PostImage=ISO-8859-1
 encoding//tst-rsrc/org/eclipse/jgit/patch/testGetText_BothISO88591.patch=ISO-8859-1
 encoding//tst-rsrc/org/eclipse/jgit/patch/testGetText_Convert.patch=ISO-8859-1
 encoding//tst-rsrc/org/eclipse/jgit/patch/testGetText_DiffCc.patch=ISO-8859-1
diff --git a/org.eclipse.jgit.test/tst-rsrc/org/eclipse/jgit/diff/.gitattributes b/org.eclipse.jgit.test/tst-rsrc/org/eclipse/jgit/diff/.gitattributes
index c5831d9..28caa2f 100644
--- a/org.eclipse.jgit.test/tst-rsrc/org/eclipse/jgit/diff/.gitattributes
+++ b/org.eclipse.jgit.test/tst-rsrc/org/eclipse/jgit/diff/.gitattributes
@@ -1,3 +1,5 @@
 *.patch -crlf
 *Image -crlf
 *.out -crlf
+delta* -text
+literal* -text
diff --git a/org.eclipse.jgit.test/tst-rsrc/org/eclipse/jgit/diff/crlf.patch b/org.eclipse.jgit.test/tst-rsrc/org/eclipse/jgit/diff/crlf.patch
new file mode 100644
index 0000000..01eb0b9
--- /dev/null
+++ b/org.eclipse.jgit.test/tst-rsrc/org/eclipse/jgit/diff/crlf.patch
@@ -0,0 +1,9 @@
+diff --git a/crlf b/crlf
+index 9206ee6..95dd193 100644
+--- a/crlf
++++ b/crlf
+@@ -1,3 +1,3 @@
+ foo
+-fie
++bar
+ fum
diff --git a/org.eclipse.jgit.test/tst-rsrc/org/eclipse/jgit/diff/crlf2.patch b/org.eclipse.jgit.test/tst-rsrc/org/eclipse/jgit/diff/crlf2.patch
new file mode 100644
index 0000000..5a62104
--- /dev/null
+++ b/org.eclipse.jgit.test/tst-rsrc/org/eclipse/jgit/diff/crlf2.patch
@@ -0,0 +1,9 @@
+diff --git a/crlf2 b/crlf2
+index 05c1c78..91e246d 100644
+--- a/crlf2
++++ b/crlf2
+@@ -1,3 +1,3 @@
+ foo

+-fie

++bar

+ fum

diff --git a/org.eclipse.jgit.test/tst-rsrc/org/eclipse/jgit/diff/crlf2_PostImage b/org.eclipse.jgit.test/tst-rsrc/org/eclipse/jgit/diff/crlf2_PostImage
new file mode 100644
index 0000000..91e246d
--- /dev/null
+++ b/org.eclipse.jgit.test/tst-rsrc/org/eclipse/jgit/diff/crlf2_PostImage
@@ -0,0 +1,3 @@
+foo

+bar

+fum

diff --git a/org.eclipse.jgit.test/tst-rsrc/org/eclipse/jgit/diff/crlf2_PreImage b/org.eclipse.jgit.test/tst-rsrc/org/eclipse/jgit/diff/crlf2_PreImage
new file mode 100644
index 0000000..05c1c78
--- /dev/null
+++ b/org.eclipse.jgit.test/tst-rsrc/org/eclipse/jgit/diff/crlf2_PreImage
@@ -0,0 +1,3 @@
+foo

+fie

+fum

diff --git a/org.eclipse.jgit.test/tst-rsrc/org/eclipse/jgit/diff/crlf3.patch b/org.eclipse.jgit.test/tst-rsrc/org/eclipse/jgit/diff/crlf3.patch
new file mode 100644
index 0000000..b155148
--- /dev/null
+++ b/org.eclipse.jgit.test/tst-rsrc/org/eclipse/jgit/diff/crlf3.patch
@@ -0,0 +1,8 @@
+diff --git a/crlf3 b/crlf3
+index e69de29..9206ee6 100644
+--- a/crlf3
++++ b/crlf3
+@@ -0,0 +1,3 @@
++foo
++fie
++fum
diff --git a/org.eclipse.jgit.test/tst-rsrc/org/eclipse/jgit/diff/crlf3_PostImage b/org.eclipse.jgit.test/tst-rsrc/org/eclipse/jgit/diff/crlf3_PostImage
new file mode 100644
index 0000000..05c1c78
--- /dev/null
+++ b/org.eclipse.jgit.test/tst-rsrc/org/eclipse/jgit/diff/crlf3_PostImage
@@ -0,0 +1,3 @@
+foo

+fie

+fum

diff --git a/org.eclipse.jgit.test/tst-rsrc/org/eclipse/jgit/diff/crlf3_PreImage b/org.eclipse.jgit.test/tst-rsrc/org/eclipse/jgit/diff/crlf3_PreImage
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/org.eclipse.jgit.test/tst-rsrc/org/eclipse/jgit/diff/crlf3_PreImage
diff --git a/org.eclipse.jgit.test/tst-rsrc/org/eclipse/jgit/diff/crlf4.patch b/org.eclipse.jgit.test/tst-rsrc/org/eclipse/jgit/diff/crlf4.patch
new file mode 100644
index 0000000..0cf6063
--- /dev/null
+++ b/org.eclipse.jgit.test/tst-rsrc/org/eclipse/jgit/diff/crlf4.patch
@@ -0,0 +1,9 @@
+diff --git a/crlf4 b/crlf4
+new file mode 100644
+index 0000000..9206ee6
+--- /dev/null
++++ b/crlf4
+@@ -0,0 +1,3 @@
++foo
++fie
++fum
diff --git a/org.eclipse.jgit.test/tst-rsrc/org/eclipse/jgit/diff/crlf4_PostImage b/org.eclipse.jgit.test/tst-rsrc/org/eclipse/jgit/diff/crlf4_PostImage
new file mode 100644
index 0000000..05c1c78
--- /dev/null
+++ b/org.eclipse.jgit.test/tst-rsrc/org/eclipse/jgit/diff/crlf4_PostImage
@@ -0,0 +1,3 @@
+foo

+fie

+fum

diff --git a/org.eclipse.jgit.test/tst-rsrc/org/eclipse/jgit/diff/crlf_PostImage b/org.eclipse.jgit.test/tst-rsrc/org/eclipse/jgit/diff/crlf_PostImage
new file mode 100644
index 0000000..91e246d
--- /dev/null
+++ b/org.eclipse.jgit.test/tst-rsrc/org/eclipse/jgit/diff/crlf_PostImage
@@ -0,0 +1,3 @@
+foo

+bar

+fum

diff --git a/org.eclipse.jgit.test/tst-rsrc/org/eclipse/jgit/diff/crlf_PreImage b/org.eclipse.jgit.test/tst-rsrc/org/eclipse/jgit/diff/crlf_PreImage
new file mode 100644
index 0000000..05c1c78
--- /dev/null
+++ b/org.eclipse.jgit.test/tst-rsrc/org/eclipse/jgit/diff/crlf_PreImage
@@ -0,0 +1,3 @@
+foo

+fie

+fum

diff --git a/org.eclipse.jgit.test/tst-rsrc/org/eclipse/jgit/diff/delta.patch b/org.eclipse.jgit.test/tst-rsrc/org/eclipse/jgit/diff/delta.patch
new file mode 100644
index 0000000..8485530
--- /dev/null
+++ b/org.eclipse.jgit.test/tst-rsrc/org/eclipse/jgit/diff/delta.patch
@@ -0,0 +1,8 @@
+diff --git a/delta b/delta
+index b4527005bf9e4da2dd1d7185b51bdac623a4218f..8b370bb5f2bc3261b6b62e80d6edd784a61ec225 100644
+GIT binary patch
+delta 14
+ScmZp0Xmwa1z*+$U3j_csN(Dmz
+
+delta 12
+TcmZp5XmD5{u!xa=5hEi28?FP4
diff --git a/org.eclipse.jgit.test/tst-rsrc/org/eclipse/jgit/diff/delta_PostImage b/org.eclipse.jgit.test/tst-rsrc/org/eclipse/jgit/diff/delta_PostImage
new file mode 100644
index 0000000..8b370bb
--- /dev/null
+++ b/org.eclipse.jgit.test/tst-rsrc/org/eclipse/jgit/diff/delta_PostImage
Binary files differ
diff --git a/org.eclipse.jgit.test/tst-rsrc/org/eclipse/jgit/diff/delta_PreImage b/org.eclipse.jgit.test/tst-rsrc/org/eclipse/jgit/diff/delta_PreImage
new file mode 100644
index 0000000..b452700
--- /dev/null
+++ b/org.eclipse.jgit.test/tst-rsrc/org/eclipse/jgit/diff/delta_PreImage
Binary files differ
diff --git a/org.eclipse.jgit.test/tst-rsrc/org/eclipse/jgit/diff/emptyLine.patch b/org.eclipse.jgit.test/tst-rsrc/org/eclipse/jgit/diff/emptyLine.patch
new file mode 100644
index 0000000..18c80c4
--- /dev/null
+++ b/org.eclipse.jgit.test/tst-rsrc/org/eclipse/jgit/diff/emptyLine.patch
@@ -0,0 +1,10 @@
+diff --git a/emptyLine b/emptyLine
+index 1fd3fa2..45c2c9b 100644
+--- a/emptyLine
++++ b/emptyLine
+@@ -1,4 +1,4 @@
+ foo
+
+-fie
++bar
+ fum
diff --git a/org.eclipse.jgit.test/tst-rsrc/org/eclipse/jgit/diff/emptyLine_PostImage b/org.eclipse.jgit.test/tst-rsrc/org/eclipse/jgit/diff/emptyLine_PostImage
new file mode 100644
index 0000000..45c2c9b
--- /dev/null
+++ b/org.eclipse.jgit.test/tst-rsrc/org/eclipse/jgit/diff/emptyLine_PostImage
@@ -0,0 +1,4 @@
+foo
+
+bar
+fum
diff --git a/org.eclipse.jgit.test/tst-rsrc/org/eclipse/jgit/diff/emptyLine_PreImage b/org.eclipse.jgit.test/tst-rsrc/org/eclipse/jgit/diff/emptyLine_PreImage
new file mode 100644
index 0000000..1fd3fa2
--- /dev/null
+++ b/org.eclipse.jgit.test/tst-rsrc/org/eclipse/jgit/diff/emptyLine_PreImage
@@ -0,0 +1,4 @@
+foo
+
+fie
+fum
diff --git a/org.eclipse.jgit.test/tst-rsrc/org/eclipse/jgit/diff/hello.patch b/org.eclipse.jgit.test/tst-rsrc/org/eclipse/jgit/diff/hello.patch
new file mode 100644
index 0000000..f015a38
--- /dev/null
+++ b/org.eclipse.jgit.test/tst-rsrc/org/eclipse/jgit/diff/hello.patch
@@ -0,0 +1,16 @@
+diff --git a/hello b/hello
+index b6fc4c6..0abaeaa 100644
+--- a/hello
++++ b/hello
+@@ -1 +1 @@
+-hello
+\ No newline at end of file
++bye
+\ No newline at end of file
+diff --git a/yello b/yello
+index 391a8cb..d1ed081 100644
+--- a/yello
++++ b/yello
+@@ -1 +1 @@
+-yello
++yellow
diff --git a/org.eclipse.jgit.test/tst-rsrc/org/eclipse/jgit/diff/hello_PostImage b/org.eclipse.jgit.test/tst-rsrc/org/eclipse/jgit/diff/hello_PostImage
new file mode 100644
index 0000000..0abaeaa
--- /dev/null
+++ b/org.eclipse.jgit.test/tst-rsrc/org/eclipse/jgit/diff/hello_PostImage
@@ -0,0 +1 @@
+bye
\ No newline at end of file
diff --git a/org.eclipse.jgit.test/tst-rsrc/org/eclipse/jgit/diff/hello_PreImage b/org.eclipse.jgit.test/tst-rsrc/org/eclipse/jgit/diff/hello_PreImage
new file mode 100644
index 0000000..b6fc4c6
--- /dev/null
+++ b/org.eclipse.jgit.test/tst-rsrc/org/eclipse/jgit/diff/hello_PreImage
@@ -0,0 +1 @@
+hello
\ No newline at end of file
diff --git a/org.eclipse.jgit.test/tst-rsrc/org/eclipse/jgit/diff/literal.patch b/org.eclipse.jgit.test/tst-rsrc/org/eclipse/jgit/diff/literal.patch
new file mode 100644
index 0000000..c8811d5
--- /dev/null
+++ b/org.eclipse.jgit.test/tst-rsrc/org/eclipse/jgit/diff/literal.patch
@@ -0,0 +1,126 @@
+diff --git a/literal b/literal
+index 799df8578e3cae8a5e979182391b8e9a6a3deded..74e4201af6378ac87bf9e118fbab6553c7fd355c 100644
+GIT binary patch
+literal 5389
+zcmc&&X;f25x2=0gFa(g;$fO8C5fl|r2$Mhpf-;XXh+qO@qwRo*3aF3^Peq(ZoX{Y4
+zI{-=?P(d+4RGeCZATuQ301AQ)VKCt)uP*jm>#bhz`}L-^YNgIORkhFFyDIsSoS=YZ
+zn$&4j0Dz{qmq!QyC=5|RQGrv{71I}RA|<%_y8&?Pi28Ue8RkfG$TD|u^R3|*xU(zB
+zZ@K5P&3+xejCMcUc0Y!I$?Wj6>+rQxa)B}|OzgvWV`Bp=t=@L+unvcheY-FGWVHFi
+zl+hUAG;tQLGGOrYEIbZ_wx8)lP#?yGs}Q8a$4&`AtDjvvjQwm{y=_{&ObKM)zwukV
+z?ApAEov=%*pABr(4!6O;+fK5~27)yC*}z_K8|2pNXFEZO(FtixfQbDV^<ft6u(gj}
+zSC|82*zP^S3I<T1uU)sNCEWAL&!)}Kw$+yaA^88K>TUBe=x-IU#ZN;Z$u`KA0EhnA
+zLo!6&-=5&_Z6}_v3(9Hrv4vE{zR(;7T<!3NRBZ_#yzScjq09-#h*cXn+I(!G@U~z_
+z!ZgAPc<`rzP%@*_*SXEl9x^9fBJPDD4z!0H2ur<f+C6N<kOR@qjwlkhU?&cMscqL%
+zhyS<&`_{mT?h_Y5koRY_`V)#E!ww(Ew!gJNMTF1oK6YY%A|N<J!zVCdQQ~h0sY?7N
+zY=lg_C-8mjpg@QKuSpVM*8y8Y5PwM0iU^=@KG0`aBwTIrA}$L;br3g26x*Pj3By~w
+ztf4<$z7B*6Uwg3+lnh_m&u#GW5DpN`f1V|*n|KcdNr+6a?SvdAx`_RujSP6CjnE6<
+z47^st95Hl^IBu6bXFLc#{o$=40ioc^rK_ah|3Fo|$Tx=bzuWUJx)*5{-%L%}w*Bel
+zf`iWvXdK25A&Ten@k#CHlVp=WHM)!ref;*rpnU34L+k$L)@fs>997ReQrr7yVJYLD
+z`dVs3lYV+~Opo@m+<1RMi}Zelv(aO{zFtaOw^J2so#)_}Rh^3mTy5Ulm5u0bd1$sd
+z%1SaNcGG8UC;ePqht{0v`kKJ63u}K_vov5v_U_lm!{_Bh8qW{?ZT<4o4jb||uFmi^
+z30ZU^a{;@{vf9?de5)Ugd$z>m!pd1kt}&nNxfQ%$Cv5tI#JL~tM!fXdm38~gug64p
+zPQHzsxrEPoH~acuuiPqwgeLkX9stl@czd`lPi^UIPuqI(lTP(tdKzaJng-1~7E-it
+z^}F4)Uyk$l@U7J3X7b1TZoizoMla|<)LiP!1Nk#4H#fGIR{!zvUg_6cr7kf6jdd66
+zD!Qc#F=d2LiSHOK8+x;I0C(Yj=B4!G8I;6d7oDZ^(^PBbaSI=dUyaxIy}Ywy^7z`I
+zRoLoo=^Wk)|L%+9vXYI@<NWfT=E$bT^qf>|SURQQGX8NqLpNr;n9In~x$Y`9UUu4b
+z=jT}O9W^IA>!s^fWqQta2@~XR4QTc%_W6`nbn@Ne3#VgO$O3|`e3XWjkL%m<?vOKe
+zb2CqU`O2NWXYrpV!mV5izrz?U9?b^5xQTGb|5BQBGZWPP_web96Qm(opzdnbdm2Fg
+z)o6BNV}K&e1cnnIN3Lp;Sm2+d$HALooxX)yk_}1a(1qLop<2mDTb5wA6*Nu-lN33i
+zg*3>QV8j1RJ?y=7L@4SY`!CkuNp2*<-VN6L3(>ruD2jFae>PqZX-`bsIQ&+JMt{gP
+zMGkCfg<q`wb?lc#E0ep22R3Da>v$FQnqcs~f~OdiY|DPg!rmxM$kF4{{`Zqm(~$&i
+z+QAv2st76{Qlo6S65)=WRxC)<duc}3ce!gr+Sgk%m!7&tp9n1I15p%OBQK2gJ>yUy
+z;w?RL0h<wH!iwS+^y(Xb8ec)9-(Z$tM(IRp6|$}9=bU&q3#`M_$bSBA*j>dV)Qm>*
+zBES}EqfdtubT$WSPJnZ!yI~I$dFb&`ckB_IEzK!M8+oC^5DKk{7mRf$B2MJ7ftooS
+z7m`<B;I}d(T$==0*KNI-t^9`2=zQ)raw`zeA{Z|H?r)t#XGL?JUfR2FTnO<42dpRG
+z%BHiTl&A7So!x2lVkVxOd@ziJJdxGC&P$e>QD_Z3v!u!If;5QIFAc%E+N2j>1FKgg
+z7%ZjHi<qUcGp-~we173yz&%-aHszdq76``Y@>24miQsya7RW(wcks%Keps;zu)b0A
+zs25JPhFO?2aFvEEbVje2)&!nBGNI6va`ZjV^<&<;*oAIbv0|%zcTmYw4&4OpddEAL
+z6i|AB&Whx=JaY`U$^x-?&ZhXh-V_q@PFA<@aasSI*_5LVydg75<c7WbOR?19tEG+`
+zPB12P_t09`-dO1d{gbW&NUl888@|yt-l&!;;py_^Nu<dBKwDc3yvDD~93~QHBFPzX
+z$G#|R)2KvAx@yYAiV3kYcbiuU_N%uvQMREli`W_U?ca#0ykauM*S--sF`dfW4U5wQ
+zE7ub3t|hJ~raAA6P*h`7IkqQrp(Bm+fcs(YV$l>>Np#kd?j=AhtCi>#xxE@)4Jm|^
+z<YR&fD_LoV+<l#m`AP-*>s9C!Q5#be(DKW;PJqrzQr-nDtV8hy!9XcqM*>Kc{Hi)Y
+zPmTmm2c(`po-3dPH8V+oB5Go4z_^Jy6~>KBLl`$QO+h7U>07{50ljGbu$HFq9!STl
+zRQU5*u}TW)qryW}P=qcYIYJU%0T=Mg2!9T1opK-OQxml?Ex>xTe&mRTFc(zdmsR+t
+ztR(Ivu${EFe*mQyVqfLUoaL3f?`<5A#U40Ybl`&(Ya7=bOd)MOJ2G-U=Z>H$_T|0Y
+z^{W@KQn>cOguJ0?aGWf-7(JT(@|I5iBf%`}C~BFpWn|N#tKb_RgYeZTSsi<x{iU7%
+zSYQK|B9*-Z&;2olq8~VrNhdZPJ_S_p^Q7--gBF}2UYx1WojVy6qgjK;A5g4od1O$6
+ztxP<e4W{F1;5+rf#t1`_{+AjO79k9*PGDoF6wx4+EVX)l4|~c~1MY}KXLC*0eD%~E
+zKsN=ekXb`6{dD^z#V6)6K$`}^?x$OJULWGpyb%@&JVN)5wLN*7Y#FoC8_>w02)mW;
+zvgwkPnZPcejj(JX5!D~Nk~Vjrw9#|*0yG^^1WJ@@<2`R|zz2lx1OkxK8@F%oTSx+v
+zp`5$JW&137yLLy#O#u!FXR4^OH*u1oLwc>28fXL7)Um@g{(VmPZizpTP_aRKYb4TI
+z*llsqd3ccr733kJ;G2m^Rr<}i{_2P}cOcP_#NKNavgOg9e~mw%r_cj!h+n+Q(e7dY
+zC7;|xx2D1TQPpU?h~b)&6iQnTo2o=U9Xl>ccTK6SsO(t4G6P%VNTRCVMTO(8c(IO9
+ztdEfH%PZ8bO#&%E{E-yYlWb6<iUXkm>kB6USjj8Yqt(D$@XA3B!#=%_Dwqv+wirB8
+zL^qgwAuxFziHukE)?`+00Gm~<kLn0Bc(3P7HY4^`M<TXk_+)E!s6=B8`KWZKmPi}M
+zhQE?UwF7~O3If|$g#(=o-lQ=K$P>>VH3$dQxU2S<Eo81=NtO7zo(?wp_@^p}09v=v
+zRB`vB&*aK*u$dfGMdcJ!$7rmjWF-LMj|+oCj!1Opu#q*z?li#WVN3GB-n0txTIXaS
+z)DZ^i%a06?X${sVk|)^^g^;D-wad+}dO4a^AV-8#Slv`tV4NEL?8H^8GAf8xM!&nf
+z3phWH5cHj3>gG17fWu(#onhwJB<(sSx0V4UlzdrHG%y;vzb`345ye5k10>)4L5IP;
+zI`Paa7l+a12C$+Z@l=KLP~eg`bYR1*#VVLKkmcS@$g~*cC3h|a5><(KK90MXhsr(-
+zS*DXf9uTQ(;M&~LdwT{0V;*V4H`CKtJ43iN(f5JSYLWRl6-*t-_9iQ%61lUAJ!kUg
+z(L+JGpp!~(Y}EpKiZ`@b=pr(v=o>StUA>||(UbKYh<pR^M0vzL`SdAA9l_mKm$>J5
+z-VuxUVj8GE-%=*eT>9*iKn*b<vDT+}^s$%Ijwp0V@xK6<@2PhcbzSeo7<LfN-!yBM
+zv}W$UKrW6hQpW~I_j2te&mD#%tmsu>4#VW5Z`H%<XGMbT$XQjEZGzhwMbU3v4eT=P
+zjY|H?jI$$!iSvIS8*W@6Q~?FSiC0oaNBxQ-M<Nyo)q%y?@J8uz<KfZZV<z(Tx{^sC
+zcr@U2MgXT%Iy_aZ*iRlqMX4>uP25`v85fP34#l;zORy_|pRt|oo&HcS`K{o|XYD2B
+zJ7zeBa7)ogsKao*=)JgoOWdFR*}770hIp{Vxa^gDK(ef_Bn(Rd&92Af^K>|x*b?pq
+z^dPeNYe@*U035~{RBN)ZOyG{>0&8ibxsV2O6<<kBh_If09@u~;**t9y8LZ~Upa%ix
+zTZs>*3EtogHERT`5X?k$L43Zz2vG&`zYC@zG9><*Ko|Ln#1{*GL0XV_zF;!)3W>if
+zpd#f+`~!h1Qi#Mq5}?RAB(=wijm3dgvIBbgde~LPJMuNM<c44~5{0DpS*^rEz$*Cx
+z-F$7VTXCFxjU=fMaFA(8{3Ss&5;}~$@ZnxUcNonNnMC)+XH(C#mVddvLu0NR)TaB#
+zkIsyT_61PV_1<akF0S8cFKslFlonbi5BKCK)=_DLm31qx?#}DI87GY}<wT8nR`BO4
+zRx@5_a1GE5?KOP2bP+oTyI-K$@K8%uM5Fy!5@TP?;*!xTp2mF~HOQD>yC(Rxh+U4g
+zUUkq6#}v28CoPlCukTBh>Mh`0>y4h}Tg&ESk7r!yE=O>(dSt(ALywPCZytwK9m#d$
+zUPt$*@ckG@_#W!myqe{smjppbnDdfPTRpkQP{j*IeS42pi12jTuZ6ys1T5r_(hW9$
+zdU7+-&x42VYT#sQ({uaa88Y>$n@=VcSoT;2u<YMvKF(5fkq&m{bq7fG%q7;{4ps#M
+z2jqmq)pc{0a@U~^{D3?9_#bL#YMkDbh}h?_+TuG0S=?CECw19NPdE>znU|sX9<|8I
+z#a`x8Ju?m%F#NNYeFlr`c&}3+utiFXL*IBnB%_2G1?n<i?eB)Y8b5lh{8^6OB&|!Z
+z7gJ)$v5+0m{!Z`yz{4P$llNkGja?S8FJcC}v|LM6@lR^{FGiaZ2`S~ew_K#lMC<}A
+zEn3TY#Sg(qe;cE44!G=~--S*oy%n5g?O~Rrf6&RqE&43QVxLbC?J3D^<|ca92Q=zI
+z{!%oniDD7H>1oIEO?&oxik>_V5QV2zH0A7$&pmD5vGXmi?%F>v^^WO~RO=R2-$8j>
+z$9#dRvai_64=G}G`Q{gD#mTbl6~b3Hm)jlbG5!s?KJG3&RG_$|YwdjQi9{E#S|Ew}
+zkgR3d$ZSKM=4o=NyOt`Csy}G%=@s6PWyc6xp66bC`^7jFIWoQ3akGcgz=9JSjufwm
+zP`;}AAj@X6zHDlrem}uB$*zX^8l9|B?|3VpYe?RjSh!xi9$!6|^Xyqm<F<-M=0$Xe
+zYkm2~xE#eoouegx6?I;ojeoG98+^Ty(a;u=hF_kS-<?*<ogLMj+hZJyyi6@C3{+Ab
+z@mUM#KelWycg$|NBVWeB?^w|tM>vH8ll0z*^LmU^ke9M!>G+BM)T9M<yiAc`1=;ka
+z<Zv(3OtFezv?Xrc^FYdb!CCUSW7VjxUT*rh?EA{sHNMSE9UtXqJ<*%X%!dGPCim1>
+zvbft3*&THeF9!a=qS6Gt{Qt`(rJo+ZM=+B3-uVBe{r`m2>TuR2Gvx|d^>(M0_1^{J
+z&OOgkw(AystYHt|E^z)78usIKcv{%8i?zQQxwP+SKCpk(P++5}ym5b3NZWww$fh${
+z+z&czyqYIeTzcz0oSZKBoa(Z#PTn*0gDZ_->&rhr!vd6b34w3Fxi*Jyc-Y>4e@$^4
+cxguN4kni(NU3<6%{;31JJp(*$x^uGr9fGaZv;Y7A
+
+literal 1629
+zcmV-j2BP_iP)<h;3K|Lk000e1NJLTq001BW001Be1^@s6b9#F800004b3#c}2nYxW
+zd<bNS000IQNkl<ZScS!xeQcH08Nh$fdGGB9P;Q}RCD0F7u}~l_3X>XOp-ouEG7tw0
+zrz1-=F%F0OAZ*Bt%4AWe%cd6G%m`sY6u$yfhB9DOrfkevkPjQ|7bz{Y^t;geeV+Z%
+z-b-(9d+9KXPx9t{&pFR|p5ODF^FHT&;Y${|kx3oD%S#{awv*l7K)tMQzWRR$@NLb_
+zw;H}v)GQIf6%3j8H~%fa;jd>h$695QRWckW+^S($6E4nXW;Y+LsHg~iVF2&*`MKhR
+zHmmCQ1byyU`lD^F&Xm<pKK62+wdxsmqG|_L|6&~1bD!4kKAp&iGu%LLdCpHn>|TNV
+z%8R3a_|Tzmm#*3P@Q-HSUYM1eH!<b#!H-eZVZxGBjLfoXADrNsadU=e>c3jMs;&&F
+z8VCRQ^d#Seu9v{M5A2zz4}Ep>n<uhf6p_p+1vzZn`55CfJnY+hl#T1RV8b?1fPFTV
+zMq{}1RLvXzNtgju#D6Av7dYQX?EYncy0!eD=hJtHNE$$UTQ~nWa)NIxE}{6=0&;V+
+zNSKLeLKv&c>a1}yj<<B4tsNF%LuSqsh<Qk$W5YWI51(ur^O}gH4%BIH@8;;=D_OL-
+zgyP!@m^v+w?3^qDfgml-9f=^^DlE+!TezpC>$BEqf8?QeYhH<1JqFP0=f?}mZ~v(g
+zxoJ3q`BNsdeb*C=&+znTPg(oGZ>TsNm*p6-s^<dE)uQU^{eA!w88Fs9)AywRE_>-~
+zo<z<8YO5Qmue&%PLSgx;vV_h7j7ULpIBiX|4d5%!S)|C<QMHv#>5qiMvi`c3fXjnY
+z?nzI>n30qgyK(yTm1Cj+ioF{^3@0CWrSO)>rn{c}{@GoeufLXs+vZGT(^C&#7eYib
+z@v#)Z=<7IOmIA1i6V}+JBXJIJp`n@GI}ZTx-oB4$Ywcp$iqa857|UG%CfGW821q7=
+zq9+APM+z`d>S`Lf|K3fsw_Ssnls$oQ<HruEuZBecMsac?omI_gbs~~-BLDz3)fc$`
+z-e1wt-p#TVrMzFUg##aK;af}Q#pw!orcPa&X4EpdpGluTlGk>l&LdL&c>{lV@vUe(
+zB{i9~>+T+MNs|1@lU%4xMhqz7rXF{kl4D#XI<rJf|J}hcee;cpJz~<*Mw6VBg4gGb
+zooq-lR=Ch_!L_ceK5qAmI2hv|_7ZWTAd$Xz_Z*|K;WE%ypkCQ=fIu+*%<#Kh7hMP!
+z=r839ZtBcdRV$IO`b<Y78%j(+fEkbhUvG%-EPj-E3uaPZcZr7cEpa(i)PL^WtF5k7
+zKc{_3+6ywu7%f6L4wOU{)g}fo*D?^Jr|{7Sp8?<)H^ESE%sf%~un+ua7rY{J06+}0
+zBy8Rps2H|^J|j+2+~rC4Fn?hY0JCP_Lh7i|L+U9?*al+&tkFFXsf0HCR$sKt{%-N*
+z3RR6+FmIp}5m(&$ue@g=bLJKRFlTN7-&`_x$UWlocgCh)3Al~C9R)~fZF~*18f4VZ
+z7oA&Ukw3@K+7SLg7mjhqTqW}hV+`Lhzc5b6=kLU7I5v9W<&&Sk(HI4gO@x470;o9m
+zY+rTyJynfaG+&^Lp59A<M5C)XcqYbh#lf@DF@T<{7x4#s21TzuZbDB++R+zw^S<u0
+z;g3DVz_f{JftkB1C;cKAHg^r29JT@cfi7H53U1dZYR<KAsi_ldm7Uv;a`aFYDEI>1
+zbX{p6Z2g0st1+xPRr~fQk-nI>L$^#A<JHs;1&T!MQ?sAF12H_pkRrHUeIPC;nNZkA
+zAlOSN><5PaL=!6;PSwBuOsthb;@vtaN3H8!fg-Rw7QQgI>Pk?49a|gzM^OzTtUX=(
+z<{t+S#TiXq)6|eE-gzSI0rP_+YmYB4y}5I>Ds?yLyvmA{4domX6nRy|Tb{c@gw3Go
+zSAy>Q%C;02*syDzNaO$;UaV@p5uVP-xx6jWU($8IpY(BDzOQ7j6qV%)(*@c8YURW;
+zzpcp2S4#n^S%{1S+QBwkHC1k7_I_Hk`;+V09uYtc%=Ww#?-e@}G}|!}PU;OD{-Qsp
+bU%LDkMDBWX&Ru`<00000NkvXXu0mjfJA@b~
+
diff --git a/org.eclipse.jgit.test/tst-rsrc/org/eclipse/jgit/diff/literal_PostImage b/org.eclipse.jgit.test/tst-rsrc/org/eclipse/jgit/diff/literal_PostImage
new file mode 100644
index 0000000..74e4201
--- /dev/null
+++ b/org.eclipse.jgit.test/tst-rsrc/org/eclipse/jgit/diff/literal_PostImage
Binary files differ
diff --git a/org.eclipse.jgit.test/tst-rsrc/org/eclipse/jgit/diff/literal_PreImage b/org.eclipse.jgit.test/tst-rsrc/org/eclipse/jgit/diff/literal_PreImage
new file mode 100644
index 0000000..799df85
--- /dev/null
+++ b/org.eclipse.jgit.test/tst-rsrc/org/eclipse/jgit/diff/literal_PreImage
Binary files differ
diff --git a/org.eclipse.jgit.test/tst-rsrc/org/eclipse/jgit/diff/literal_add.patch b/org.eclipse.jgit.test/tst-rsrc/org/eclipse/jgit/diff/literal_add.patch
new file mode 100644
index 0000000..bb6a9e4
--- /dev/null
+++ b/org.eclipse.jgit.test/tst-rsrc/org/eclipse/jgit/diff/literal_add.patch
@@ -0,0 +1,40 @@
+diff --git a/literal_add b/literal_add
+new file mode 100644
+index 0000000000000000000000000000000000000000..799df8578e3cae8a5e979182391b8e9a6a3deded
+GIT binary patch
+literal 1629
+zcmV-j2BP_iP)<h;3K|Lk000e1NJLTq001BW001Be1^@s6b9#F800004b3#c}2nYxW
+zd<bNS000IQNkl<ZScS!xeQcH08Nh$fdGGB9P;Q}RCD0F7u}~l_3X>XOp-ouEG7tw0
+zrz1-=F%F0OAZ*Bt%4AWe%cd6G%m`sY6u$yfhB9DOrfkevkPjQ|7bz{Y^t;geeV+Z%
+z-b-(9d+9KXPx9t{&pFR|p5ODF^FHT&;Y${|kx3oD%S#{awv*l7K)tMQzWRR$@NLb_
+zw;H}v)GQIf6%3j8H~%fa;jd>h$695QRWckW+^S($6E4nXW;Y+LsHg~iVF2&*`MKhR
+zHmmCQ1byyU`lD^F&Xm<pKK62+wdxsmqG|_L|6&~1bD!4kKAp&iGu%LLdCpHn>|TNV
+z%8R3a_|Tzmm#*3P@Q-HSUYM1eH!<b#!H-eZVZxGBjLfoXADrNsadU=e>c3jMs;&&F
+z8VCRQ^d#Seu9v{M5A2zz4}Ep>n<uhf6p_p+1vzZn`55CfJnY+hl#T1RV8b?1fPFTV
+zMq{}1RLvXzNtgju#D6Av7dYQX?EYncy0!eD=hJtHNE$$UTQ~nWa)NIxE}{6=0&;V+
+zNSKLeLKv&c>a1}yj<<B4tsNF%LuSqsh<Qk$W5YWI51(ur^O}gH4%BIH@8;;=D_OL-
+zgyP!@m^v+w?3^qDfgml-9f=^^DlE+!TezpC>$BEqf8?QeYhH<1JqFP0=f?}mZ~v(g
+zxoJ3q`BNsdeb*C=&+znTPg(oGZ>TsNm*p6-s^<dE)uQU^{eA!w88Fs9)AywRE_>-~
+zo<z<8YO5Qmue&%PLSgx;vV_h7j7ULpIBiX|4d5%!S)|C<QMHv#>5qiMvi`c3fXjnY
+z?nzI>n30qgyK(yTm1Cj+ioF{^3@0CWrSO)>rn{c}{@GoeufLXs+vZGT(^C&#7eYib
+z@v#)Z=<7IOmIA1i6V}+JBXJIJp`n@GI}ZTx-oB4$Ywcp$iqa857|UG%CfGW821q7=
+zq9+APM+z`d>S`Lf|K3fsw_Ssnls$oQ<HruEuZBecMsac?omI_gbs~~-BLDz3)fc$`
+z-e1wt-p#TVrMzFUg##aK;af}Q#pw!orcPa&X4EpdpGluTlGk>l&LdL&c>{lV@vUe(
+zB{i9~>+T+MNs|1@lU%4xMhqz7rXF{kl4D#XI<rJf|J}hcee;cpJz~<*Mw6VBg4gGb
+zooq-lR=Ch_!L_ceK5qAmI2hv|_7ZWTAd$Xz_Z*|K;WE%ypkCQ=fIu+*%<#Kh7hMP!
+z=r839ZtBcdRV$IO`b<Y78%j(+fEkbhUvG%-EPj-E3uaPZcZr7cEpa(i)PL^WtF5k7
+zKc{_3+6ywu7%f6L4wOU{)g}fo*D?^Jr|{7Sp8?<)H^ESE%sf%~un+ua7rY{J06+}0
+zBy8Rps2H|^J|j+2+~rC4Fn?hY0JCP_Lh7i|L+U9?*al+&tkFFXsf0HCR$sKt{%-N*
+z3RR6+FmIp}5m(&$ue@g=bLJKRFlTN7-&`_x$UWlocgCh)3Al~C9R)~fZF~*18f4VZ
+z7oA&Ukw3@K+7SLg7mjhqTqW}hV+`Lhzc5b6=kLU7I5v9W<&&Sk(HI4gO@x470;o9m
+zY+rTyJynfaG+&^Lp59A<M5C)XcqYbh#lf@DF@T<{7x4#s21TzuZbDB++R+zw^S<u0
+z;g3DVz_f{JftkB1C;cKAHg^r29JT@cfi7H53U1dZYR<KAsi_ldm7Uv;a`aFYDEI>1
+zbX{p6Z2g0st1+xPRr~fQk-nI>L$^#A<JHs;1&T!MQ?sAF12H_pkRrHUeIPC;nNZkA
+zAlOSN><5PaL=!6;PSwBuOsthb;@vtaN3H8!fg-Rw7QQgI>Pk?49a|gzM^OzTtUX=(
+z<{t+S#TiXq)6|eE-gzSI0rP_+YmYB4y}5I>Ds?yLyvmA{4domX6nRy|Tb{c@gw3Go
+zSAy>Q%C;02*syDzNaO$;UaV@p5uVP-xx6jWU($8IpY(BDzOQ7j6qV%)(*@c8YURW;
+zzpcp2S4#n^S%{1S+QBwkHC1k7_I_Hk`;+V09uYtc%=Ww#?-e@}G}|!}PU;OD{-Qsp
+bU%LDkMDBWX&Ru`<00000NkvXXu0mjfJA@b~
+
+literal 0
+HcmV?d00001
diff --git a/org.eclipse.jgit.test/tst-rsrc/org/eclipse/jgit/diff/literal_add_PostImage b/org.eclipse.jgit.test/tst-rsrc/org/eclipse/jgit/diff/literal_add_PostImage
new file mode 100644
index 0000000..799df85
--- /dev/null
+++ b/org.eclipse.jgit.test/tst-rsrc/org/eclipse/jgit/diff/literal_add_PostImage
Binary files differ
diff --git a/org.eclipse.jgit.test/tst-rsrc/org/eclipse/jgit/diff/smudgetest.patch b/org.eclipse.jgit.test/tst-rsrc/org/eclipse/jgit/diff/smudgetest.patch
new file mode 100644
index 0000000..ab4d426
--- /dev/null
+++ b/org.eclipse.jgit.test/tst-rsrc/org/eclipse/jgit/diff/smudgetest.patch
@@ -0,0 +1,9 @@
+diff --git a/smudgetest b/smudgetest
+index a24d41e..762c4d0 100644
+--- a/smudgetest
++++ b/smudgetest
+@@ -1,3 +1,3 @@
+ PERLE
+-HEBLE
++sprich
+ speak
diff --git a/org.eclipse.jgit.test/tst-rsrc/org/eclipse/jgit/diff/smudgetest_PostImage b/org.eclipse.jgit.test/tst-rsrc/org/eclipse/jgit/diff/smudgetest_PostImage
new file mode 100644
index 0000000..ad63089
--- /dev/null
+++ b/org.eclipse.jgit.test/tst-rsrc/org/eclipse/jgit/diff/smudgetest_PostImage
@@ -0,0 +1,3 @@
+PARLA
+sprich
+speak
diff --git a/org.eclipse.jgit.test/tst-rsrc/org/eclipse/jgit/diff/smudgetest_PreImage b/org.eclipse.jgit.test/tst-rsrc/org/eclipse/jgit/diff/smudgetest_PreImage
new file mode 100644
index 0000000..9bbd8c7
--- /dev/null
+++ b/org.eclipse.jgit.test/tst-rsrc/org/eclipse/jgit/diff/smudgetest_PreImage
@@ -0,0 +1,3 @@
+PARLA
+HABLA
+speak
diff --git a/org.eclipse.jgit.test/tst-rsrc/org/eclipse/jgit/diff/umlaut.patch b/org.eclipse.jgit.test/tst-rsrc/org/eclipse/jgit/diff/umlaut.patch
new file mode 100644
index 0000000..7380dbe
--- /dev/null
+++ b/org.eclipse.jgit.test/tst-rsrc/org/eclipse/jgit/diff/umlaut.patch
@@ -0,0 +1,7 @@
+diff --git a/umlaut b/umlaut
+index 003a054..557f72f 100644
+--- a/umlaut
++++ b/umlaut
+@@ -1 +1 @@
+-ÄÖÜ
++ÄÖÜ
diff --git a/org.eclipse.jgit.test/tst-rsrc/org/eclipse/jgit/diff/umlaut_PostImage b/org.eclipse.jgit.test/tst-rsrc/org/eclipse/jgit/diff/umlaut_PostImage
new file mode 100644
index 0000000..557f72f
--- /dev/null
+++ b/org.eclipse.jgit.test/tst-rsrc/org/eclipse/jgit/diff/umlaut_PostImage
@@ -0,0 +1 @@
+ÄÖÜ
diff --git a/org.eclipse.jgit.test/tst-rsrc/org/eclipse/jgit/diff/umlaut_PreImage b/org.eclipse.jgit.test/tst-rsrc/org/eclipse/jgit/diff/umlaut_PreImage
new file mode 100644
index 0000000..003a054
--- /dev/null
+++ b/org.eclipse.jgit.test/tst-rsrc/org/eclipse/jgit/diff/umlaut_PreImage
@@ -0,0 +1 @@
+ÄÖÜ
diff --git a/org.eclipse.jgit.test/tst-rsrc/org/eclipse/jgit/util/io/delta1.forward b/org.eclipse.jgit.test/tst-rsrc/org/eclipse/jgit/util/io/delta1.forward
new file mode 100644
index 0000000..878b167
--- /dev/null
+++ b/org.eclipse.jgit.test/tst-rsrc/org/eclipse/jgit/util/io/delta1.forward
@@ -0,0 +1 @@
+ScmZp0Xmwa1z*+$U3j_csN(Dmz
diff --git a/org.eclipse.jgit.test/tst-rsrc/org/eclipse/jgit/util/io/delta1.reverse b/org.eclipse.jgit.test/tst-rsrc/org/eclipse/jgit/util/io/delta1.reverse
new file mode 100644
index 0000000..7ff7a08
--- /dev/null
+++ b/org.eclipse.jgit.test/tst-rsrc/org/eclipse/jgit/util/io/delta1.reverse
@@ -0,0 +1 @@
+TcmZp5XmD5{u!xa=5hEi28?FP4
diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/ApplyCommandTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/ApplyCommandTest.java
index 055eba7..867310b 100644
--- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/ApplyCommandTest.java
+++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/ApplyCommandTest.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2011, 2020 IBM Corporation and others
+ * Copyright (C) 2011, 2021 IBM Corporation 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,6 +9,7 @@
  */
 package org.eclipse.jgit.api;
 
+import static org.junit.Assert.assertArrayEquals;
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertFalse;
 import static org.junit.Assert.assertTrue;
@@ -18,11 +19,20 @@
 import java.io.File;
 import java.io.IOException;
 import java.io.InputStream;
+import java.io.OutputStream;
+import java.nio.charset.StandardCharsets;
+import java.nio.file.Files;
 
 import org.eclipse.jgit.api.errors.PatchApplyException;
 import org.eclipse.jgit.api.errors.PatchFormatException;
+import org.eclipse.jgit.attributes.FilterCommand;
+import org.eclipse.jgit.attributes.FilterCommandFactory;
+import org.eclipse.jgit.attributes.FilterCommandRegistry;
 import org.eclipse.jgit.diff.RawText;
 import org.eclipse.jgit.junit.RepositoryTestCase;
+import org.eclipse.jgit.lib.Config;
+import org.eclipse.jgit.lib.ConfigConstants;
+import org.eclipse.jgit.util.IO;
 import org.junit.Test;
 
 public class ApplyCommandTest extends RepositoryTestCase {
@@ -58,6 +68,260 @@
 	}
 
 	@Test
+	public void testCrLf() throws Exception {
+		try {
+			db.getConfig().setBoolean(ConfigConstants.CONFIG_CORE_SECTION, null,
+					ConfigConstants.CONFIG_KEY_AUTOCRLF, true);
+			ApplyResult result = init("crlf", true, true);
+			assertEquals(1, result.getUpdatedFiles().size());
+			assertEquals(new File(db.getWorkTree(), "crlf"),
+					result.getUpdatedFiles().get(0));
+			checkFile(new File(db.getWorkTree(), "crlf"),
+					b.getString(0, b.size(), false));
+		} finally {
+			db.getConfig().unset(ConfigConstants.CONFIG_CORE_SECTION, null,
+					ConfigConstants.CONFIG_KEY_AUTOCRLF);
+		}
+	}
+
+	@Test
+	public void testCrLfOff() throws Exception {
+		try {
+			db.getConfig().setBoolean(ConfigConstants.CONFIG_CORE_SECTION, null,
+					ConfigConstants.CONFIG_KEY_AUTOCRLF, false);
+			ApplyResult result = init("crlf", true, true);
+			assertEquals(1, result.getUpdatedFiles().size());
+			assertEquals(new File(db.getWorkTree(), "crlf"),
+					result.getUpdatedFiles().get(0));
+			checkFile(new File(db.getWorkTree(), "crlf"),
+					b.getString(0, b.size(), false));
+		} finally {
+			db.getConfig().unset(ConfigConstants.CONFIG_CORE_SECTION, null,
+					ConfigConstants.CONFIG_KEY_AUTOCRLF);
+		}
+	}
+
+	@Test
+	public void testCrLfEmptyCommitted() throws Exception {
+		try {
+			db.getConfig().setBoolean(ConfigConstants.CONFIG_CORE_SECTION, null,
+					ConfigConstants.CONFIG_KEY_AUTOCRLF, true);
+			ApplyResult result = init("crlf3", true, true);
+			assertEquals(1, result.getUpdatedFiles().size());
+			assertEquals(new File(db.getWorkTree(), "crlf3"),
+					result.getUpdatedFiles().get(0));
+			checkFile(new File(db.getWorkTree(), "crlf3"),
+					b.getString(0, b.size(), false));
+		} finally {
+			db.getConfig().unset(ConfigConstants.CONFIG_CORE_SECTION, null,
+					ConfigConstants.CONFIG_KEY_AUTOCRLF);
+		}
+	}
+
+	@Test
+	public void testCrLfNewFile() throws Exception {
+		try {
+			db.getConfig().setBoolean(ConfigConstants.CONFIG_CORE_SECTION, null,
+					ConfigConstants.CONFIG_KEY_AUTOCRLF, true);
+			ApplyResult result = init("crlf4", false, true);
+			assertEquals(1, result.getUpdatedFiles().size());
+			assertEquals(new File(db.getWorkTree(), "crlf4"),
+					result.getUpdatedFiles().get(0));
+			checkFile(new File(db.getWorkTree(), "crlf4"),
+					b.getString(0, b.size(), false));
+		} finally {
+			db.getConfig().unset(ConfigConstants.CONFIG_CORE_SECTION, null,
+					ConfigConstants.CONFIG_KEY_AUTOCRLF);
+		}
+	}
+
+	@Test
+	public void testPatchWithCrLf() throws Exception {
+		try {
+			db.getConfig().setBoolean(ConfigConstants.CONFIG_CORE_SECTION, null,
+					ConfigConstants.CONFIG_KEY_AUTOCRLF, false);
+			ApplyResult result = init("crlf2", true, true);
+			assertEquals(1, result.getUpdatedFiles().size());
+			assertEquals(new File(db.getWorkTree(), "crlf2"),
+					result.getUpdatedFiles().get(0));
+			checkFile(new File(db.getWorkTree(), "crlf2"),
+					b.getString(0, b.size(), false));
+		} finally {
+			db.getConfig().unset(ConfigConstants.CONFIG_CORE_SECTION, null,
+					ConfigConstants.CONFIG_KEY_AUTOCRLF);
+		}
+	}
+
+	@Test
+	public void testPatchWithCrLf2() throws Exception {
+		String name = "crlf2";
+		try (Git git = new Git(db)) {
+			db.getConfig().setBoolean(ConfigConstants.CONFIG_CORE_SECTION, null,
+					ConfigConstants.CONFIG_KEY_AUTOCRLF, false);
+			a = new RawText(readFile(name + "_PreImage"));
+			write(new File(db.getWorkTree(), name),
+					a.getString(0, a.size(), false));
+
+			git.add().addFilepattern(name).call();
+			git.commit().setMessage("PreImage").call();
+
+			b = new RawText(readFile(name + "_PostImage"));
+
+			db.getConfig().setBoolean(ConfigConstants.CONFIG_CORE_SECTION, null,
+					ConfigConstants.CONFIG_KEY_AUTOCRLF, true);
+			ApplyResult result = git.apply()
+					.setPatch(getTestResource(name + ".patch")).call();
+			assertEquals(1, result.getUpdatedFiles().size());
+			assertEquals(new File(db.getWorkTree(), name),
+					result.getUpdatedFiles().get(0));
+			checkFile(new File(db.getWorkTree(), name),
+					b.getString(0, b.size(), false));
+		} finally {
+			db.getConfig().unset(ConfigConstants.CONFIG_CORE_SECTION, null,
+					ConfigConstants.CONFIG_KEY_AUTOCRLF);
+		}
+	}
+
+	// Clean/smudge filter for testFiltering. The smudgetest test resources were
+	// created with C git using a clean filter sed -e "s/A/E/g" and the smudge
+	// filter sed -e "s/E/A/g". To keep the test independent of the presence of
+	// sed, implement this with a built-in filter.
+	private static class ReplaceFilter extends FilterCommand {
+
+		private final char toReplace;
+
+		private final char replacement;
+
+		ReplaceFilter(InputStream in, OutputStream out, char toReplace,
+				char replacement) {
+			super(in, out);
+			this.toReplace = toReplace;
+			this.replacement = replacement;
+		}
+
+		@Override
+		public int run() throws IOException {
+			int b = in.read();
+			if (b < 0) {
+				in.close();
+				out.close();
+				return -1;
+			}
+			if ((b & 0xFF) == toReplace) {
+				b = replacement;
+			}
+			out.write(b);
+			return 1;
+		}
+	}
+
+	@Test
+	public void testFiltering() throws Exception {
+		// Set up filter
+		FilterCommandFactory clean = (repo, in, out) -> {
+			return new ReplaceFilter(in, out, 'A', 'E');
+		};
+		FilterCommandFactory smudge = (repo, in, out) -> {
+			return new ReplaceFilter(in, out, 'E', 'A');
+		};
+		FilterCommandRegistry.register("jgit://builtin/a2e/clean", clean);
+		FilterCommandRegistry.register("jgit://builtin/a2e/smudge", smudge);
+		try (Git git = new Git(db)) {
+			Config config = db.getConfig();
+			config.setString(ConfigConstants.CONFIG_FILTER_SECTION, "a2e",
+					"clean", "jgit://builtin/a2e/clean");
+			config.setString(ConfigConstants.CONFIG_FILTER_SECTION, "a2e",
+					"smudge", "jgit://builtin/a2e/smudge");
+			write(new File(db.getWorkTree(), ".gitattributes"),
+					"smudgetest filter=a2e");
+			git.add().addFilepattern(".gitattributes").call();
+			git.commit().setMessage("Attributes").call();
+			ApplyResult result = init("smudgetest", true, true);
+			assertEquals(1, result.getUpdatedFiles().size());
+			assertEquals(new File(db.getWorkTree(), "smudgetest"),
+					result.getUpdatedFiles().get(0));
+			checkFile(new File(db.getWorkTree(), "smudgetest"),
+					b.getString(0, b.size(), false));
+
+		} finally {
+			// Tear down filter
+			FilterCommandRegistry.unregister("jgit://builtin/a2e/clean");
+			FilterCommandRegistry.unregister("jgit://builtin/a2e/smudge");
+		}
+	}
+
+	private void checkBinary(String name, boolean hasPreImage)
+			throws Exception {
+		checkBinary(name, hasPreImage, 1);
+	}
+
+	private void checkBinary(String name, boolean hasPreImage,
+			int numberOfFiles) throws Exception {
+		try (Git git = new Git(db)) {
+			byte[] post = IO
+					.readWholeStream(getTestResource(name + "_PostImage"), 0)
+					.array();
+			File f = new File(db.getWorkTree(), name);
+			if (hasPreImage) {
+				byte[] pre = IO
+						.readWholeStream(getTestResource(name + "_PreImage"), 0)
+						.array();
+				Files.write(f.toPath(), pre);
+				git.add().addFilepattern(name).call();
+				git.commit().setMessage("PreImage").call();
+			}
+			ApplyResult result = git.apply()
+					.setPatch(getTestResource(name + ".patch")).call();
+			assertEquals(numberOfFiles, result.getUpdatedFiles().size());
+			assertEquals(f, result.getUpdatedFiles().get(0));
+			assertArrayEquals(post, Files.readAllBytes(f.toPath()));
+		}
+	}
+
+	@Test
+	public void testBinaryDelta() throws Exception {
+		checkBinary("delta", true);
+	}
+
+	@Test
+	public void testBinaryLiteral() throws Exception {
+		checkBinary("literal", true);
+	}
+
+	@Test
+	public void testBinaryLiteralAdd() throws Exception {
+		checkBinary("literal_add", false);
+	}
+
+	@Test
+	public void testEncodingChange() throws Exception {
+		// This is a text patch that changes a file containing ÄÖÜ in UTF-8 to
+		// the same characters in ISO-8859-1. The patch file itself uses mixed
+		// encoding. Since checkFile() works with strings use the binary check.
+		checkBinary("umlaut", true);
+	}
+
+	@Test
+	public void testEmptyLine() throws Exception {
+		// C git accepts completely empty lines as empty context lines.
+		// According to comments in the C git sources (apply.c), newer GNU diff
+		// may produce such diffs.
+		checkBinary("emptyLine", true);
+	}
+
+	@Test
+	public void testMultiFileNoNewline() throws Exception {
+		// This test needs two files. One is in the test resources.
+		try (Git git = new Git(db)) {
+			Files.write(db.getWorkTree().toPath().resolve("yello"),
+					"yello".getBytes(StandardCharsets.US_ASCII));
+			git.add().addFilepattern("yello").call();
+			git.commit().setMessage("yello").call();
+		}
+		checkBinary("hello", true, 2);
+	}
+
+	@Test
 	public void testAddA1() throws Exception {
 		ApplyResult result = init("A1", false, true);
 		assertEquals(1, result.getUpdatedFiles().size());
diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/diff/RenameDetectorTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/diff/RenameDetectorTest.java
index 2ea3cd7..5edb60c 100644
--- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/diff/RenameDetectorTest.java
+++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/diff/RenameDetectorTest.java
@@ -580,6 +580,57 @@
 	}
 
 	@Test
+	public void testExactRenameForBinaryFile_isIdentified() throws Exception {
+		ObjectId aId = blob("a\nb\nc\n\0\0\0\0d\n");
+
+		DiffEntry a = DiffEntry.add(PATH_A, aId);
+		DiffEntry b = DiffEntry.delete(PATH_Q, aId);
+
+		rd.add(a);
+		rd.add(b);
+
+		List<DiffEntry> entries = rd.compute();
+		assertEquals(1, entries.size());
+		assertRename(b, a, 100, entries.get(0));
+	}
+
+	@Test
+	public void testInexactRenameForBinaryFile_identifiedByDefault() throws Exception {
+		ObjectId aId = blob("a\nb\nc\n\0\0\0\0d\n");
+		ObjectId bId = blob("a\nb\nc\n\0\0\0d\n");
+
+		DiffEntry a = DiffEntry.add(PATH_A, aId);
+		DiffEntry b = DiffEntry.delete(PATH_Q, bId);
+
+		rd.add(a);
+		rd.add(b);
+		rd.setRenameScore(40);
+
+		List<DiffEntry> entries = rd.compute();
+		assertEquals(1, entries.size());
+		assertRename(b, a, 50, entries.get(0));
+	}
+
+	@Test
+	public void testInexactRenameForBinaryFile_notIdentifiedIfSkipParameterSet() throws Exception {
+		ObjectId aId = blob("a\nb\nc\n\0\0\0\0d\n");
+		ObjectId bId = blob("a\nb\nc\n\0\0\0d\n");
+
+		DiffEntry a = DiffEntry.add(PATH_A, aId);
+		DiffEntry b = DiffEntry.delete(PATH_Q, bId);
+
+		rd.add(a);
+		rd.add(b);
+		rd.setRenameScore(40);
+		rd.setSkipContentRenamesForBinaryFiles(true);
+
+		List<DiffEntry> entries = rd.compute();
+		assertEquals(2, entries.size());
+		assertAdd(PATH_A, aId, FileMode.REGULAR_FILE, entries.get(0));
+		assertDelete(PATH_Q, bId, FileMode.REGULAR_FILE, entries.get(1));
+	}
+
+	@Test
 	public void testSetRenameScore_IllegalArgs() throws Exception {
 		try {
 			rd.setRenameScore(-1);
diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/gitrepo/RepoCommandTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/gitrepo/RepoCommandTest.java
index ae4db0b..509adc2 100644
--- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/gitrepo/RepoCommandTest.java
+++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/gitrepo/RepoCommandTest.java
@@ -46,6 +46,8 @@
 import org.eclipse.jgit.storage.file.FileBasedConfig;
 import org.eclipse.jgit.treewalk.TreeWalk;
 import org.eclipse.jgit.util.FS;
+import org.eclipse.jgit.util.IO;
+import org.eclipse.jgit.util.RawParseUtils;
 import org.junit.Test;
 
 public class RepoCommandTest extends RepositoryTestCase {
@@ -749,10 +751,56 @@
 			String gitlink = localDb.resolve(Constants.HEAD + ":foo").name();
 			assertEquals("The gitlink is same as remote head",
 					oldCommitId.name(), gitlink);
+
+			File dotmodules = new File(localDb.getWorkTree(),
+					Constants.DOT_GIT_MODULES);
+			assertTrue(dotmodules.exists());
+			// The .gitmodules file should have "branch" lines
+			String gitModulesContents = RawParseUtils
+					.decode(IO.readFully(dotmodules));
+			assertTrue(gitModulesContents.contains("branch = branch"));
 		}
 	}
 
 	@Test
+	public void testRevisionBare_ignoreTags() throws Exception {
+		Repository remoteDb = createBareRepository();
+		Repository tempDb = createWorkRepository();
+
+		StringBuilder xmlContent = new StringBuilder();
+		xmlContent.append("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n")
+				.append("<manifest>")
+				.append("<remote name=\"remote1\" fetch=\".\" />")
+				.append("<default revision=\"").append("refs/tags/" + TAG)
+				.append("\" remote=\"remote1\" />")
+				.append("<project path=\"foo\" name=\"")
+				.append(defaultUri)
+				.append("\" />").append("</manifest>");
+		JGitTestUtil.writeTrashFile(tempDb, "manifest.xml",
+				xmlContent.toString());
+		RepoCommand command = new RepoCommand(remoteDb);
+		command.setPath(
+				tempDb.getWorkTree().getAbsolutePath() + "/manifest.xml")
+				.setURI(rootUri).call();
+		// Clone it
+		File directory = createTempDirectory("testReplaceManifestBare");
+		File dotmodules;
+		try (Repository localDb = Git.cloneRepository().setDirectory(directory)
+				.setURI(remoteDb.getDirectory().toURI().toString()).call()
+				.getRepository()) {
+			dotmodules = new File(localDb.getWorkTree(),
+					Constants.DOT_GIT_MODULES);
+			assertTrue(dotmodules.exists());
+		}
+
+		// The .gitmodules file should not have "branch" lines
+		String gitModulesContents = RawParseUtils
+				.decode(IO.readFully(dotmodules));
+		assertFalse(gitModulesContents.contains("branch"));
+		assertTrue(gitModulesContents.contains("ref = refs/tags/" + TAG));
+	}
+
+	@Test
 	public void testCopyFileBare() throws Exception {
 		Repository remoteDb = createBareRepository();
 		Repository tempDb = createWorkRepository();
diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/file/BatchRefUpdateTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/file/BatchRefUpdateTest.java
index 25cd227..6357a0b 100644
--- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/file/BatchRefUpdateTest.java
+++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/file/BatchRefUpdateTest.java
@@ -190,15 +190,28 @@
 		if (atomic) {
 			assertResults(cmds, TRANSACTION_ABORTED, REJECTED_NONFASTFORWARD);
 			assertRefs("refs/heads/master", A, "refs/heads/masters", B);
-			assertEquals(1, refsChangedEvents);
 		} else {
 			assertResults(cmds, OK, REJECTED_NONFASTFORWARD);
 			assertRefs("refs/heads/master", B, "refs/heads/masters", B);
-			assertEquals(2, refsChangedEvents);
 		}
 	}
 
 	@Test
+	public void simpleNoForceRefsChangedEvents() throws IOException {
+		writeLooseRefs("refs/heads/master", A, "refs/heads/masters", B);
+		int initialRefsChangedEvents = refsChangedEvents;
+
+		List<ReceiveCommand> cmds = Arrays.asList(
+				new ReceiveCommand(A, B, "refs/heads/master", UPDATE),
+				new ReceiveCommand(B, A, "refs/heads/masters",
+						UPDATE_NONFASTFORWARD));
+		execute(newBatchUpdate(cmds));
+
+		assertEquals(atomic ? initialRefsChangedEvents
+				: initialRefsChangedEvents + 1, refsChangedEvents);
+	}
+
+	@Test
 	public void simpleForce() throws IOException {
 		writeLooseRefs("refs/heads/master", A, "refs/heads/masters", B);
 
@@ -210,7 +223,21 @@
 
 		assertResults(cmds, OK, OK);
 		assertRefs("refs/heads/master", B, "refs/heads/masters", A);
-		assertEquals(batchesRefUpdates() ? 2 : 3, refsChangedEvents);
+	}
+
+	@Test
+	public void simpleForceRefsChangedEvents() throws IOException {
+		writeLooseRefs("refs/heads/master", A, "refs/heads/masters", B);
+		int initialRefsChangedEvents = refsChangedEvents;
+
+		List<ReceiveCommand> cmds = Arrays.asList(
+				new ReceiveCommand(A, B, "refs/heads/master", UPDATE),
+				new ReceiveCommand(B, A, "refs/heads/masters",
+						UPDATE_NONFASTFORWARD));
+		execute(newBatchUpdate(cmds).setAllowNonFastForwards(true));
+
+		assertEquals(batchesRefUpdates() ? initialRefsChangedEvents + 1
+				: initialRefsChangedEvents + 2, refsChangedEvents);
 	}
 
 	@Test
@@ -232,7 +259,27 @@
 
 		assertResults(cmds, OK);
 		assertRefs("refs/heads/master", A);
-		assertEquals(2, refsChangedEvents);
+	}
+
+	@Test
+	public void nonFastForwardDoesNotDoExpensiveMergeCheckRefsChangedEvents()
+			throws IOException {
+		writeLooseRef("refs/heads/master", B);
+		int initialRefsChangedEvents = refsChangedEvents;
+
+		List<ReceiveCommand> cmds = Arrays.asList(new ReceiveCommand(B, A,
+				"refs/heads/master", UPDATE_NONFASTFORWARD));
+		try (RevWalk rw = new RevWalk(diskRepo) {
+			@Override
+			public boolean isMergedInto(RevCommit base, RevCommit tip) {
+				throw new AssertionError("isMergedInto() should not be called");
+			}
+		}) {
+			newBatchUpdate(cmds).setAllowNonFastForwards(true).execute(rw,
+					new StrictWorkMonitor());
+		}
+
+		assertEquals(initialRefsChangedEvents + 1, refsChangedEvents);
 	}
 
 	@Test
@@ -251,17 +298,30 @@
 			assertResults(cmds, LOCK_FAILURE, TRANSACTION_ABORTED,
 					TRANSACTION_ABORTED);
 			assertRefs("refs/heads/master", A, "refs/heads/masters", B);
-			assertEquals(1, refsChangedEvents);
 		} else {
 			// Non-atomic updates are applied in order: master succeeds, then
 			// master/x fails due to conflict.
 			assertResults(cmds, OK, LOCK_FAILURE, LOCK_FAILURE);
 			assertRefs("refs/heads/master", B, "refs/heads/masters", B);
-			assertEquals(2, refsChangedEvents);
 		}
 	}
 
 	@Test
+	public void fileDirectoryConflictRefsChangedEvents() throws IOException {
+		writeLooseRefs("refs/heads/master", A, "refs/heads/masters", B);
+		int initialRefsChangedEvents = refsChangedEvents;
+
+		List<ReceiveCommand> cmds = Arrays.asList(
+				new ReceiveCommand(A, B, "refs/heads/master", UPDATE),
+				new ReceiveCommand(zeroId(), A, "refs/heads/master/x", CREATE),
+				new ReceiveCommand(zeroId(), A, "refs/heads", CREATE));
+		execute(newBatchUpdate(cmds).setAllowNonFastForwards(true), false);
+
+		assertEquals(atomic ? initialRefsChangedEvents
+				: initialRefsChangedEvents + 1, refsChangedEvents);
+	}
+
+	@Test
 	public void conflictThanksToDelete() throws IOException {
 		writeLooseRefs("refs/heads/master", A, "refs/heads/masters", B);
 
@@ -273,15 +333,21 @@
 
 		assertResults(cmds, OK, OK, OK);
 		assertRefs("refs/heads/master", B, "refs/heads/masters/x", A);
-		if (atomic) {
-			assertEquals(2, refsChangedEvents);
-		} else if (!useReftable) {
-			// The non-atomic case actually produces 5 events, but that's an
-			// implementation detail. We expect at least 4 events, one for the
-			// initial read due to writeLooseRef(), and then one for each
-			// successful ref update.
-			assertTrue(refsChangedEvents >= 4);
-		}
+	}
+
+	@Test
+	public void conflictThanksToDeleteRefsChangedEvents() throws IOException {
+		writeLooseRefs("refs/heads/master", A, "refs/heads/masters", B);
+		int initialRefsChangedEvents = refsChangedEvents;
+
+		List<ReceiveCommand> cmds = Arrays.asList(
+				new ReceiveCommand(A, B, "refs/heads/master", UPDATE),
+				new ReceiveCommand(zeroId(), A, "refs/heads/masters/x", CREATE),
+				new ReceiveCommand(B, zeroId(), "refs/heads/masters", DELETE));
+		execute(newBatchUpdate(cmds).setAllowNonFastForwards(true));
+
+		assertEquals(batchesRefUpdates() ? initialRefsChangedEvents + 1
+				: initialRefsChangedEvents + 3, refsChangedEvents);
 	}
 
 	@Test
@@ -298,15 +364,29 @@
 		if (atomic) {
 			assertResults(cmds, REJECTED_MISSING_OBJECT, TRANSACTION_ABORTED);
 			assertRefs("refs/heads/master", A);
-			assertEquals(1, refsChangedEvents);
 		} else {
 			assertResults(cmds, REJECTED_MISSING_OBJECT, OK);
 			assertRefs("refs/heads/master", A, "refs/heads/foo2", B);
-			assertEquals(2, refsChangedEvents);
 		}
 	}
 
 	@Test
+	public void updateToMissingObjectRefsChangedEvents() throws IOException {
+		writeLooseRef("refs/heads/master", A);
+		int initialRefsChangedEvents = refsChangedEvents;
+
+		ObjectId bad = ObjectId
+				.fromString("deadbeefdeadbeefdeadbeefdeadbeefdeadbeef");
+		List<ReceiveCommand> cmds = Arrays.asList(
+				new ReceiveCommand(A, bad, "refs/heads/master", UPDATE),
+				new ReceiveCommand(zeroId(), B, "refs/heads/foo2", CREATE));
+		execute(newBatchUpdate(cmds).setAllowNonFastForwards(true), false);
+
+		assertEquals(atomic ? initialRefsChangedEvents
+				: initialRefsChangedEvents + 1, refsChangedEvents);
+	}
+
+	@Test
 	public void addMissingObject() throws IOException {
 		writeLooseRef("refs/heads/master", A);
 
@@ -320,15 +400,29 @@
 		if (atomic) {
 			assertResults(cmds, TRANSACTION_ABORTED, REJECTED_MISSING_OBJECT);
 			assertRefs("refs/heads/master", A);
-			assertEquals(1, refsChangedEvents);
 		} else {
 			assertResults(cmds, OK, REJECTED_MISSING_OBJECT);
 			assertRefs("refs/heads/master", B);
-			assertEquals(2, refsChangedEvents);
 		}
 	}
 
 	@Test
+	public void addMissingObjectRefsChangedEvents() throws IOException {
+		writeLooseRef("refs/heads/master", A);
+		int initialRefsChangedEvents = refsChangedEvents;
+
+		ObjectId bad = ObjectId
+				.fromString("deadbeefdeadbeefdeadbeefdeadbeefdeadbeef");
+		List<ReceiveCommand> cmds = Arrays.asList(
+				new ReceiveCommand(A, B, "refs/heads/master", UPDATE),
+				new ReceiveCommand(zeroId(), bad, "refs/heads/foo2", CREATE));
+		execute(newBatchUpdate(cmds).setAllowNonFastForwards(true), false);
+
+		assertEquals(atomic ? initialRefsChangedEvents
+				: initialRefsChangedEvents + 1, refsChangedEvents);
+	}
+
+	@Test
 	public void oneNonExistentRef() throws IOException {
 		List<ReceiveCommand> cmds = Arrays.asList(
 				new ReceiveCommand(A, B, "refs/heads/foo1", UPDATE),
@@ -358,15 +452,27 @@
 		if (atomic) {
 			assertResults(cmds, LOCK_FAILURE, TRANSACTION_ABORTED);
 			assertRefs("refs/heads/master", A);
-			assertEquals(1, refsChangedEvents);
 		} else {
 			assertResults(cmds, LOCK_FAILURE, OK);
 			assertRefs("refs/heads/master", A, "refs/heads/foo2", B);
-			assertEquals(2, refsChangedEvents);
 		}
 	}
 
 	@Test
+	public void oneRefWrongOldValueRefsChangedEvents() throws IOException {
+		writeLooseRef("refs/heads/master", A);
+		int initialRefsChangedEvents = refsChangedEvents;
+
+		List<ReceiveCommand> cmds = Arrays.asList(
+				new ReceiveCommand(B, B, "refs/heads/master", UPDATE),
+				new ReceiveCommand(zeroId(), B, "refs/heads/foo2", CREATE));
+		execute(newBatchUpdate(cmds).setAllowNonFastForwards(true));
+
+		assertEquals(atomic ? initialRefsChangedEvents
+				: initialRefsChangedEvents + 1, refsChangedEvents);
+	}
+
+	@Test
 	public void nonExistentRef() throws IOException {
 		writeLooseRef("refs/heads/master", A);
 
@@ -378,17 +484,31 @@
 		if (atomic) {
 			assertResults(cmds, TRANSACTION_ABORTED, LOCK_FAILURE);
 			assertRefs("refs/heads/master", A);
-			assertEquals(1, refsChangedEvents);
 		} else {
 			assertResults(cmds, OK, LOCK_FAILURE);
 			assertRefs("refs/heads/master", B);
-			assertEquals(2, refsChangedEvents);
 		}
 	}
 
 	@Test
+	public void nonExistentRefRefsChangedEvents() throws IOException {
+		writeLooseRef("refs/heads/master", A);
+
+		int initialRefsChangedEvents = refsChangedEvents;
+
+		List<ReceiveCommand> cmds = Arrays.asList(
+				new ReceiveCommand(A, B, "refs/heads/master", UPDATE),
+				new ReceiveCommand(A, zeroId(), "refs/heads/foo2", DELETE));
+		execute(newBatchUpdate(cmds).setAllowNonFastForwards(true));
+
+		assertEquals(atomic ? initialRefsChangedEvents
+				: initialRefsChangedEvents + 1, refsChangedEvents);
+	}
+
+	@Test
 	public void noRefLog() throws IOException {
 		writeRef("refs/heads/master", A);
+		int initialRefsChangedEvents = refsChangedEvents;
 
 		Map<String, ReflogEntry> oldLogs = getLastReflogs("refs/heads/master",
 				"refs/heads/branch");
@@ -402,7 +522,8 @@
 
 		assertResults(cmds, OK, OK);
 		assertRefs("refs/heads/master", B, "refs/heads/branch", B);
-		assertEquals(batchesRefUpdates() ? 2 : 3, refsChangedEvents);
+		assertEquals(batchesRefUpdates() ? initialRefsChangedEvents + 1
+				: initialRefsChangedEvents + 2, refsChangedEvents);
 		assertReflogUnchanged(oldLogs, "refs/heads/master");
 		assertReflogUnchanged(oldLogs, "refs/heads/branch");
 	}
@@ -411,6 +532,7 @@
 	public void reflogDefaultIdent() throws IOException {
 		writeRef("refs/heads/master", A);
 		writeRef("refs/heads/branch2", A);
+		int initialRefsChangedEvents = refsChangedEvents;
 
 		Map<String, ReflogEntry> oldLogs = getLastReflogs("refs/heads/master",
 				"refs/heads/branch1", "refs/heads/branch2");
@@ -423,7 +545,8 @@
 		assertResults(cmds, OK, OK);
 		assertRefs("refs/heads/master", B, "refs/heads/branch1", B,
 				"refs/heads/branch2", A);
-		assertEquals(batchesRefUpdates() ? 3 : 4, refsChangedEvents);
+		assertEquals(batchesRefUpdates() ? initialRefsChangedEvents + 1
+				: initialRefsChangedEvents + 2, refsChangedEvents);
 		assertReflogEquals(reflog(A, B, new PersonIdent(diskRepo), "a reflog"),
 				getLastReflog("refs/heads/master"));
 		assertReflogEquals(
@@ -436,6 +559,7 @@
 	public void reflogAppendStatusNoMessage() throws IOException {
 		writeRef("refs/heads/master", A);
 		writeRef("refs/heads/branch1", B);
+		int initialRefsChangedEvents = refsChangedEvents;
 
 		List<ReceiveCommand> cmds = Arrays.asList(
 				new ReceiveCommand(A, B, "refs/heads/master", UPDATE),
@@ -448,7 +572,8 @@
 		assertResults(cmds, OK, OK, OK);
 		assertRefs("refs/heads/master", B, "refs/heads/branch1", A,
 				"refs/heads/branch2", A);
-		assertEquals(batchesRefUpdates() ? 3 : 5, refsChangedEvents);
+		assertEquals(batchesRefUpdates() ? initialRefsChangedEvents + 1
+				: initialRefsChangedEvents + 3, refsChangedEvents);
 		assertReflogEquals(
 				// Always forced; setAllowNonFastForwards(true) bypasses the
 				// check.
@@ -465,6 +590,7 @@
 	@Test
 	public void reflogAppendStatusFastForward() throws IOException {
 		writeRef("refs/heads/master", A);
+		int initialRefsChangedEvents = refsChangedEvents;
 
 		List<ReceiveCommand> cmds = Arrays
 				.asList(new ReceiveCommand(A, B, "refs/heads/master", UPDATE));
@@ -472,7 +598,7 @@
 
 		assertResults(cmds, OK);
 		assertRefs("refs/heads/master", B);
-		assertEquals(2, refsChangedEvents);
+		assertEquals(initialRefsChangedEvents + 1, refsChangedEvents);
 		assertReflogEquals(
 				reflog(A, B, new PersonIdent(diskRepo), "fast-forward"),
 				getLastReflog("refs/heads/master"));
@@ -481,6 +607,7 @@
 	@Test
 	public void reflogAppendStatusWithMessage() throws IOException {
 		writeRef("refs/heads/master", A);
+		int initialRefsChangedEvents = refsChangedEvents;
 
 		List<ReceiveCommand> cmds = Arrays.asList(
 				new ReceiveCommand(A, B, "refs/heads/master", UPDATE),
@@ -489,7 +616,8 @@
 
 		assertResults(cmds, OK, OK);
 		assertRefs("refs/heads/master", B, "refs/heads/branch", A);
-		assertEquals(batchesRefUpdates() ? 2 : 3, refsChangedEvents);
+		assertEquals(batchesRefUpdates() ? initialRefsChangedEvents + 1
+				: initialRefsChangedEvents + 2, refsChangedEvents);
 		assertReflogEquals(
 				reflog(A, B, new PersonIdent(diskRepo),
 						"a reflog: fast-forward"),
@@ -503,6 +631,7 @@
 	@Test
 	public void reflogCustomIdent() throws IOException {
 		writeRef("refs/heads/master", A);
+		int initialRefsChangedEvents = refsChangedEvents;
 
 		List<ReceiveCommand> cmds = Arrays.asList(
 				new ReceiveCommand(A, B, "refs/heads/master", UPDATE),
@@ -513,7 +642,8 @@
 				.setRefLogIdent(ident));
 
 		assertResults(cmds, OK, OK);
-		assertEquals(batchesRefUpdates() ? 2 : 3, refsChangedEvents);
+		assertEquals(batchesRefUpdates() ? initialRefsChangedEvents + 1
+				: initialRefsChangedEvents + 2, refsChangedEvents);
 		assertRefs("refs/heads/master", B, "refs/heads/branch", B);
 		assertReflogEquals(reflog(A, B, ident, "a reflog"),
 				getLastReflog("refs/heads/master"), true);
@@ -525,6 +655,7 @@
 	public void reflogDelete() throws IOException {
 		writeRef("refs/heads/master", A);
 		writeRef("refs/heads/branch", A);
+		int initialRefsChangedEvents = refsChangedEvents;
 		assertEquals(2, getLastReflogs("refs/heads/master", "refs/heads/branch")
 				.size());
 
@@ -535,7 +666,8 @@
 
 		assertResults(cmds, OK, OK);
 		assertRefs("refs/heads/branch", B);
-		assertEquals(batchesRefUpdates() ? 3 : 4, refsChangedEvents);
+		assertEquals(batchesRefUpdates() ? initialRefsChangedEvents + 1
+				: initialRefsChangedEvents + 2, refsChangedEvents);
 		if (useReftable) {
 			// reftable retains reflog entries for deleted branches.
 			assertReflogEquals(
@@ -551,6 +683,7 @@
 	@Test
 	public void reflogFileDirectoryConflict() throws IOException {
 		writeRef("refs/heads/master", A);
+		int initialRefsChangedEvents = refsChangedEvents;
 
 		List<ReceiveCommand> cmds = Arrays.asList(
 				new ReceiveCommand(A, zeroId(), "refs/heads/master", DELETE),
@@ -559,7 +692,8 @@
 
 		assertResults(cmds, OK, OK);
 		assertRefs("refs/heads/master/x", A);
-		assertEquals(batchesRefUpdates() ? 2 : 3, refsChangedEvents);
+		assertEquals(batchesRefUpdates() ? initialRefsChangedEvents + 1
+				: initialRefsChangedEvents + 2, refsChangedEvents);
 		if (!useReftable) {
 			// reftable retains reflog entries for deleted branches.
 			assertNull(getLastReflog("refs/heads/master"));
@@ -572,6 +706,7 @@
 	@Test
 	public void reflogOnLockFailure() throws IOException {
 		writeRef("refs/heads/master", A);
+		int initialRefsChangedEvents = refsChangedEvents;
 
 		Map<String, ReflogEntry> oldLogs = getLastReflogs("refs/heads/master",
 				"refs/heads/branch");
@@ -583,12 +718,12 @@
 
 		if (atomic) {
 			assertResults(cmds, TRANSACTION_ABORTED, LOCK_FAILURE);
-			assertEquals(1, refsChangedEvents);
+			assertEquals(initialRefsChangedEvents, refsChangedEvents);
 			assertReflogUnchanged(oldLogs, "refs/heads/master");
 			assertReflogUnchanged(oldLogs, "refs/heads/branch");
 		} else {
 			assertResults(cmds, OK, LOCK_FAILURE);
-			assertEquals(2, refsChangedEvents);
+			assertEquals(initialRefsChangedEvents + 1, refsChangedEvents);
 			assertReflogEquals(
 					reflog(A, B, new PersonIdent(diskRepo), "a reflog"),
 					getLastReflog("refs/heads/master"));
@@ -599,6 +734,7 @@
 	@Test
 	public void overrideRefLogMessage() throws Exception {
 		writeRef("refs/heads/master", A);
+		int initialRefsChangedEvents = refsChangedEvents;
 
 		List<ReceiveCommand> cmds = Arrays.asList(
 				new ReceiveCommand(A, B, "refs/heads/master", UPDATE),
@@ -609,7 +745,8 @@
 				.setRefLogMessage("a reflog", true));
 
 		assertResults(cmds, OK, OK);
-		assertEquals(batchesRefUpdates() ? 2 : 3, refsChangedEvents);
+		assertEquals(batchesRefUpdates() ? initialRefsChangedEvents + 1
+				: initialRefsChangedEvents + 2, refsChangedEvents);
 		assertReflogEquals(reflog(A, B, ident, "custom log"),
 				getLastReflog("refs/heads/master"), true);
 		assertReflogEquals(reflog(zeroId(), B, ident, "a reflog: created"),
@@ -619,6 +756,7 @@
 	@Test
 	public void overrideDisableRefLog() throws Exception {
 		writeRef("refs/heads/master", A);
+		int initialRefsChangedEvents = refsChangedEvents;
 
 		Map<String, ReflogEntry> oldLogs = getLastReflogs("refs/heads/master",
 				"refs/heads/branch");
@@ -630,7 +768,8 @@
 		execute(newBatchUpdate(cmds).setRefLogMessage("a reflog", true));
 
 		assertResults(cmds, OK, OK);
-		assertEquals(batchesRefUpdates() ? 2 : 3, refsChangedEvents);
+		assertEquals(batchesRefUpdates() ? initialRefsChangedEvents + 1
+				: initialRefsChangedEvents + 2, refsChangedEvents);
 		assertReflogUnchanged(oldLogs, "refs/heads/master");
 		assertReflogEquals(
 				reflog(zeroId(), B, new PersonIdent(diskRepo),
@@ -641,6 +780,7 @@
 	@Test
 	public void refLogNotWrittenWithoutConfigOption() throws Exception {
 		assumeFalse(useReftable);
+
 		setLogAllRefUpdates(false);
 		writeRef("refs/heads/master", A);
 
@@ -661,6 +801,7 @@
 	@Test
 	public void forceRefLogInUpdate() throws Exception {
 		assumeFalse(useReftable);
+
 		setLogAllRefUpdates(false);
 		writeRef("refs/heads/master", A);
 		assertTrue(getLastReflogs("refs/heads/master", "refs/heads/branch")
@@ -683,6 +824,7 @@
 	@Test
 	public void forceRefLogInCommand() throws Exception {
 		assumeFalse(useReftable);
+
 		setLogAllRefUpdates(false);
 		writeRef("refs/heads/master", A);
 
@@ -723,13 +865,11 @@
 			if (atomic) {
 				assertResults(cmds, LOCK_FAILURE, TRANSACTION_ABORTED);
 				assertRefs("refs/heads/master", A);
-				assertEquals(1, refsChangedEvents);
 			} else {
 				// Only operates on loose refs, doesn't care that packed-refs is
 				// locked.
 				assertResults(cmds, OK, OK);
 				assertRefs("refs/heads/master", B, "refs/heads/branch", B);
-				assertEquals(3, refsChangedEvents);
 			}
 		} finally {
 			myLock.unlock();
@@ -737,6 +877,28 @@
 	}
 
 	@Test
+	public void packedRefsLockFailureRefsChangedEvents() throws Exception {
+		assumeFalse(useReftable);
+
+		writeLooseRef("refs/heads/master", A);
+		int initialRefsChangedEvents = refsChangedEvents;
+
+		List<ReceiveCommand> cmds = Arrays.asList(
+				new ReceiveCommand(A, B, "refs/heads/master", UPDATE),
+				new ReceiveCommand(zeroId(), B, "refs/heads/branch", CREATE));
+
+		LockFile myLock = refdir.lockPackedRefs();
+		try {
+			execute(newBatchUpdate(cmds).setAllowNonFastForwards(true));
+
+			assertEquals(atomic ? initialRefsChangedEvents
+					: initialRefsChangedEvents + 2, refsChangedEvents);
+		} finally {
+			myLock.unlock();
+		}
+	}
+
+	@Test
 	public void oneRefLockFailure() throws Exception {
 		assumeFalse(useReftable);
 
@@ -757,11 +919,9 @@
 			if (atomic) {
 				assertResults(cmds, TRANSACTION_ABORTED, LOCK_FAILURE);
 				assertRefs("refs/heads/master", A);
-				assertEquals(1, refsChangedEvents);
 			} else {
 				assertResults(cmds, OK, LOCK_FAILURE);
 				assertRefs("refs/heads/branch", B, "refs/heads/master", A);
-				assertEquals(2, refsChangedEvents);
 			}
 		} finally {
 			myLock.unlock();
@@ -769,8 +929,32 @@
 	}
 
 	@Test
+	public void oneRefLockFailureRefsChangedEvents() throws Exception {
+		assumeFalse(useReftable);
+
+		writeLooseRef("refs/heads/master", A);
+		int initialRefsChangedEvents = refsChangedEvents;
+
+		List<ReceiveCommand> cmds = Arrays.asList(
+				new ReceiveCommand(zeroId(), B, "refs/heads/branch", CREATE),
+				new ReceiveCommand(A, B, "refs/heads/master", UPDATE));
+
+		LockFile myLock = new LockFile(refdir.fileFor("refs/heads/master"));
+		assertTrue(myLock.lock());
+		try {
+			execute(newBatchUpdate(cmds).setAllowNonFastForwards(true));
+
+			assertEquals(atomic ? initialRefsChangedEvents
+					: initialRefsChangedEvents + 1, refsChangedEvents);
+		} finally {
+			myLock.unlock();
+		}
+	}
+
+	@Test
 	public void singleRefUpdateDoesNotRequirePackedRefsLock() throws Exception {
 		assumeFalse(useReftable);
+
 		writeLooseRef("refs/heads/master", A);
 
 		List<ReceiveCommand> cmds = Arrays
@@ -782,7 +966,6 @@
 
 			assertFalse(getLockFile("refs/heads/master").exists());
 			assertResults(cmds, OK);
-			assertEquals(2, refsChangedEvents);
 			assertRefs("refs/heads/master", B);
 		} finally {
 			myLock.unlock();
@@ -790,6 +973,27 @@
 	}
 
 	@Test
+	public void singleRefUpdateDoesNotRequirePackedRefsLockRefsChangedEvents()
+			throws Exception {
+		assumeFalse(useReftable);
+
+		writeLooseRef("refs/heads/master", A);
+		int initialRefsChangedEvents = refsChangedEvents;
+
+		List<ReceiveCommand> cmds = Arrays
+				.asList(new ReceiveCommand(A, B, "refs/heads/master", UPDATE));
+
+		LockFile myLock = refdir.lockPackedRefs();
+		try {
+			execute(newBatchUpdate(cmds).setAllowNonFastForwards(true));
+
+			assertEquals(initialRefsChangedEvents + 1, refsChangedEvents);
+		} finally {
+			myLock.unlock();
+		}
+	}
+
+	@Test
 	public void atomicUpdateRespectsInProcessLock() throws Exception {
 		assumeTrue(atomic);
 		assumeFalse(useReftable);
@@ -838,10 +1042,56 @@
 		}
 
 		assertResults(cmds, OK, OK);
-		assertEquals(2, refsChangedEvents);
 		assertRefs("refs/heads/master", B, "refs/heads/branch", B);
 	}
 
+	@Test
+	public void atomicUpdateRespectsInProcessLockRefsChangedEvents()
+			throws Exception {
+		assumeTrue(atomic);
+		assumeFalse(useReftable);
+
+		writeLooseRef("refs/heads/master", A);
+		int initialRefsChangedEvents = refsChangedEvents;
+
+		List<ReceiveCommand> cmds = Arrays.asList(
+				new ReceiveCommand(A, B, "refs/heads/master", UPDATE),
+				new ReceiveCommand(zeroId(), B, "refs/heads/branch", CREATE));
+
+		Thread t = new Thread(() -> {
+			try {
+				execute(newBatchUpdate(cmds).setAllowNonFastForwards(true));
+			} catch (Exception e) {
+				throw new RuntimeException(e);
+			}
+		});
+
+		ReentrantLock l = refdir.inProcessPackedRefsLock;
+		l.lock();
+		try {
+			t.start();
+			long timeoutSecs = 10;
+
+			// Hold onto the lock until we observe the worker thread has
+			// attempted to
+			// acquire it.
+			while (l.getQueueLength() == 0) {
+				Thread.sleep(3);
+			}
+
+			// Once we unlock, the worker thread should finish the update
+			// promptly.
+			l.unlock();
+			t.join(SECONDS.toMillis(timeoutSecs));
+		} finally {
+			if (l.isHeldByCurrentThread()) {
+				l.unlock();
+			}
+		}
+
+		assertEquals(initialRefsChangedEvents + 1, refsChangedEvents);
+	}
+
 	private void setLogAllRefUpdates(boolean enable) throws Exception {
 		StoredConfig cfg = diskRepo.getConfig();
 		cfg.load();
@@ -855,6 +1105,11 @@
 			writeRef(name, id);
 		} else {
 			write(new File(diskRepo.getDirectory(), name), id.name() + "\n");
+			// force the refs-changed event to be fired for the loose ref that
+			// was created. We do this to get the events fired during the test
+			// 'setup' out of the way and this allows us to now accurately
+			// assert only for the new events fired during the BatchRefUpdate.
+			refdir.exactRef(name);
 		}
 	}
 
@@ -957,11 +1212,11 @@
 	}
 
 	enum Result {
-		OK(ReceiveCommand.Result.OK), LOCK_FAILURE(
-				ReceiveCommand.Result.LOCK_FAILURE), REJECTED_NONFASTFORWARD(
-						ReceiveCommand.Result.REJECTED_NONFASTFORWARD), REJECTED_MISSING_OBJECT(
-								ReceiveCommand.Result.REJECTED_MISSING_OBJECT), TRANSACTION_ABORTED(
-										ReceiveCommand::isTransactionAborted);
+		OK(ReceiveCommand.Result.OK),
+		LOCK_FAILURE(ReceiveCommand.Result.LOCK_FAILURE),
+		REJECTED_NONFASTFORWARD(ReceiveCommand.Result.REJECTED_NONFASTFORWARD),
+		REJECTED_MISSING_OBJECT(ReceiveCommand.Result.REJECTED_MISSING_OBJECT),
+		TRANSACTION_ABORTED(ReceiveCommand::isTransactionAborted);
 
 		@SuppressWarnings("ImmutableEnumChecker")
 		final Predicate<? super ReceiveCommand> p;
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 5045e94..b0b5f68 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
@@ -999,6 +999,108 @@
 	}
 
 	@Test
+	public void testV2FetchWithoutWaitForDoneReceivesPackfile()
+			throws Exception {
+		String commonInBlob = "abcdefghijklmnopqrstuvwxyz";
+
+		RevBlob parentBlob = remote.blob(commonInBlob + "a");
+		RevCommit parent = remote
+				.commit(remote.tree(remote.file("foo", parentBlob)));
+		remote.update("branch1", parent);
+
+		RevCommit localParent = null;
+		RevCommit localChild = null;
+		try (TestRepository<InMemoryRepository> local = new TestRepository<>(
+				client)) {
+			RevBlob localParentBlob = local.blob(commonInBlob + "a");
+			localParent = local
+					.commit(local.tree(local.file("foo", localParentBlob)));
+			RevBlob localChildBlob = local.blob(commonInBlob + "b");
+			localChild = local.commit(
+					local.tree(local.file("foo", localChildBlob)), localParent);
+			local.update("branch1", localChild);
+		}
+
+		ByteArrayInputStream recvStream = uploadPackV2("command=fetch\n",
+				PacketLineIn.delimiter(),
+				"have " + localParent.toObjectId().getName() + "\n",
+				"have " + localChild.toObjectId().getName() + "\n",
+				PacketLineIn.end());
+		PacketLineIn pckIn = new PacketLineIn(recvStream);
+		assertThat(pckIn.readString(), is("acknowledgments"));
+		assertThat(Arrays.asList(pckIn.readString()),
+				hasItems("ACK " + parent.toObjectId().getName()));
+		assertThat(pckIn.readString(), is("ready"));
+		assertTrue(PacketLineIn.isDelimiter(pckIn.readString()));
+		assertThat(pckIn.readString(), is("packfile"));
+		parsePack(recvStream);
+	}
+
+	@Test
+	public void testV2FetchWithWaitForDoneOnlyDoesNegotiation()
+			throws Exception {
+		String commonInBlob = "abcdefghijklmnopqrstuvwxyz";
+
+		RevBlob parentBlob = remote.blob(commonInBlob + "a");
+		RevCommit parent = remote
+				.commit(remote.tree(remote.file("foo", parentBlob)));
+		remote.update("branch1", parent);
+
+		RevCommit localParent = null;
+		RevCommit localChild = null;
+		try (TestRepository<InMemoryRepository> local = new TestRepository<>(
+				client)) {
+			RevBlob localParentBlob = local.blob(commonInBlob + "a");
+			localParent = local
+					.commit(local.tree(local.file("foo", localParentBlob)));
+			RevBlob localChildBlob = local.blob(commonInBlob + "b");
+			localChild = local.commit(
+					local.tree(local.file("foo", localChildBlob)), localParent);
+			local.update("branch1", localChild);
+		}
+
+		ByteArrayInputStream recvStream = uploadPackV2("command=fetch\n",
+				PacketLineIn.delimiter(), "wait-for-done\n",
+				"have " + localParent.toObjectId().getName() + "\n",
+				"have " + localChild.toObjectId().getName() + "\n",
+				PacketLineIn.end());
+		PacketLineIn pckIn = new PacketLineIn(recvStream);
+		assertThat(pckIn.readString(), is("acknowledgments"));
+		assertThat(Arrays.asList(pckIn.readString()),
+				hasItems("ACK " + parent.toObjectId().getName()));
+		assertTrue(PacketLineIn.isEnd(pckIn.readString()));
+	}
+
+	@Test
+	public void testV2FetchWithWaitForDoneOnlyDoesNegotiationAndNothingToAck()
+			throws Exception {
+		String commonInBlob = "abcdefghijklmnopqrstuvwxyz";
+
+		RevCommit localParent = null;
+		RevCommit localChild = null;
+		try (TestRepository<InMemoryRepository> local = new TestRepository<>(
+				client)) {
+			RevBlob localParentBlob = local.blob(commonInBlob + "a");
+			localParent = local
+					.commit(local.tree(local.file("foo", localParentBlob)));
+			RevBlob localChildBlob = local.blob(commonInBlob + "b");
+			localChild = local.commit(
+					local.tree(local.file("foo", localChildBlob)), localParent);
+			local.update("branch1", localChild);
+		}
+
+		ByteArrayInputStream recvStream = uploadPackV2("command=fetch\n",
+				PacketLineIn.delimiter(), "wait-for-done\n",
+				"have " + localParent.toObjectId().getName() + "\n",
+				"have " + localChild.toObjectId().getName() + "\n",
+				PacketLineIn.end());
+		PacketLineIn pckIn = new PacketLineIn(recvStream);
+		assertThat(pckIn.readString(), is("acknowledgments"));
+		assertThat(pckIn.readString(), is("NAK"));
+		assertTrue(PacketLineIn.isEnd(pckIn.readString()));
+	}
+
+	@Test
 	public void testV2FetchThinPack() throws Exception {
 		String commonInBlob = "abcdefghijklmnopqrstuvwxyz";
 
diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/util/Base85Test.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/util/Base85Test.java
new file mode 100644
index 0000000..a49878c
--- /dev/null
+++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/util/Base85Test.java
@@ -0,0 +1,87 @@
+/*
+ * Copyright (C) 2021 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;
+
+import static org.junit.Assert.assertArrayEquals;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertThrows;
+import static org.junit.Assert.assertTrue;
+
+import java.nio.charset.StandardCharsets;
+
+import org.junit.Test;
+
+/**
+ * Tests for {@link Base85}.
+ */
+public class Base85Test {
+
+	private static final String VALID_CHARS = "0123456789"
+			+ "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"
+			+ "!#$%&()*+-;<=>?@^_`{|}~";
+
+	@Test
+	public void testChars() {
+		for (int i = 0; i < 256; i++) {
+			byte[] testData = { '1', '2', '3', '4', (byte) i };
+			if (VALID_CHARS.indexOf(i) >= 0) {
+				byte[] decoded = Base85.decode(testData, 4);
+				assertNotNull(decoded);
+			} else {
+				assertThrows(IllegalArgumentException.class,
+						() -> Base85.decode(testData, 4));
+			}
+		}
+	}
+
+	private void roundtrip(byte[] data, int expectedLength) {
+		byte[] encoded = Base85.encode(data);
+		assertEquals(expectedLength, encoded.length);
+		assertArrayEquals(data, Base85.decode(encoded, data.length));
+	}
+
+	private void roundtrip(String data, int expectedLength) {
+		roundtrip(data.getBytes(StandardCharsets.US_ASCII), expectedLength);
+	}
+
+	@Test
+	public void testPadding() {
+		roundtrip("", 0);
+		roundtrip("a", 5);
+		roundtrip("ab", 5);
+		roundtrip("abc", 5);
+		roundtrip("abcd", 5);
+		roundtrip("abcde", 10);
+		roundtrip("abcdef", 10);
+		roundtrip("abcdefg", 10);
+		roundtrip("abcdefgh", 10);
+		roundtrip("abcdefghi", 15);
+	}
+
+	@Test
+	public void testBinary() {
+		roundtrip(new byte[] { 1 }, 5);
+		roundtrip(new byte[] { 1, 2 }, 5);
+		roundtrip(new byte[] { 1, 2, 3 }, 5);
+		roundtrip(new byte[] { 1, 2, 3, 4 }, 5);
+		roundtrip(new byte[] { 1, 2, 3, 4, 5 }, 10);
+		roundtrip(new byte[] { 1, 2, 3, 4, 5, 0, 0, 0 }, 10);
+		roundtrip(new byte[] { 1, 2, 3, 4, 0, 0, 0, 5 }, 10);
+	}
+
+	@Test
+	public void testOverflow() {
+		IllegalArgumentException e = assertThrows(
+				IllegalArgumentException.class,
+				() -> Base85.decode(new byte[] { '~', '~', '~', '~', '~' }, 4));
+		assertTrue(e.getMessage().contains("overflow"));
+	}
+}
diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/util/io/BinaryDeltaInputStreamTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/util/io/BinaryDeltaInputStreamTest.java
new file mode 100644
index 0000000..d9297fc
--- /dev/null
+++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/util/io/BinaryDeltaInputStreamTest.java
@@ -0,0 +1,103 @@
+/*
+ * Copyright (C) 2021 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 org.junit.Assert.assertArrayEquals;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+
+import java.io.ByteArrayOutputStream;
+import java.io.InputStream;
+import java.util.zip.InflaterInputStream;
+
+import org.junit.Test;
+
+/**
+ * Crude tests for the {@link BinaryDeltaInputStream} using delta diffs
+ * generated by C git.
+ */
+public class BinaryDeltaInputStreamTest {
+
+	private InputStream getBinaryHunk(String name) {
+		return this.getClass().getResourceAsStream(name);
+	}
+
+	@Test
+	public void testBinaryDelta() throws Exception {
+		// Prepare our test data
+		byte[] data = new byte[8192];
+		for (int i = 0; i < data.length; i++) {
+			data[i] = (byte) (255 - (i % 256));
+		}
+		// Same, but with five 'x' inserted in the middle.
+		int middle = data.length / 2;
+		byte[] newData = new byte[data.length + 5];
+		System.arraycopy(data, 0, newData, 0, middle);
+		for (int i = 0; i < 5; i++) {
+			newData[middle + i] = 'x';
+		}
+		System.arraycopy(data, middle, newData, middle + 5, middle);
+		// delta1.forward has the instructions
+		// @formatter:off
+		// COPY 0 4096
+		// INSERT 5 xxxxx
+		// COPY 0 4096
+		// @formatter:on
+		// Note that the way we built newData could be expressed as
+		// @formatter:off
+		// COPY 0 4096
+		// INSERT 5 xxxxx
+		// COPY 4096 4096
+		// @formatter:on
+		try (ByteArrayOutputStream out = new ByteArrayOutputStream();
+				BinaryDeltaInputStream input = new BinaryDeltaInputStream(data,
+						new InflaterInputStream(new BinaryHunkInputStream(
+								getBinaryHunk("delta1.forward"))))) {
+			byte[] buf = new byte[1024];
+			int n;
+			while ((n = input.read(buf)) >= 0) {
+				out.write(buf, 0, n);
+			}
+			assertArrayEquals(newData, out.toByteArray());
+			assertTrue(input.isFullyConsumed());
+		}
+		// delta1.reverse has the instructions
+		// @formatter:off
+		// COPY 0 4096
+		// COPY 256 3840
+		// COPY 256 256
+		// @formatter:on
+		// Note that there are alternatives, for instance
+		// @formatter:off
+		// COPY 0 4096
+		// COPY 4101 4096
+		// @formatter:on
+		// or
+		// @formatter:off
+		// COPY 0 4096
+		// COPY 0 4096
+		// @formatter:on
+		try (ByteArrayOutputStream out = new ByteArrayOutputStream();
+				BinaryDeltaInputStream input = new BinaryDeltaInputStream(
+						newData,
+						new InflaterInputStream(new BinaryHunkInputStream(
+								getBinaryHunk("delta1.reverse"))))) {
+			long expectedSize = input.getExpectedResultSize();
+			assertEquals(data.length, expectedSize);
+			byte[] buf = new byte[1024];
+			int n;
+			while ((n = input.read(buf)) >= 0) {
+				out.write(buf, 0, n);
+			}
+			assertArrayEquals(data, out.toByteArray());
+			assertTrue(input.isFullyConsumed());
+		}
+	}
+}
diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/util/io/BinaryHunkStreamTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/util/io/BinaryHunkStreamTest.java
new file mode 100644
index 0000000..b198c32
--- /dev/null
+++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/util/io/BinaryHunkStreamTest.java
@@ -0,0 +1,146 @@
+/*
+ * Copyright (C) 2021 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 org.junit.Assert.assertArrayEquals;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.util.Arrays;
+
+import org.junit.Test;
+
+/**
+ * Tests for {@link BinaryHunkInputStream} and {@link BinaryHunkOutputStream}.
+ */
+public class BinaryHunkStreamTest {
+
+	@Test
+	public void testRoundtripWholeBuffer() throws IOException {
+		for (int length = 1; length < 520 + 52; length++) {
+			byte[] data = new byte[length];
+			for (int i = 0; i < data.length; i++) {
+				data[i] = (byte) (255 - (i % 256));
+			}
+			try (ByteArrayOutputStream bos = new ByteArrayOutputStream();
+					BinaryHunkOutputStream out = new BinaryHunkOutputStream(
+							bos)) {
+				out.write(data);
+				out.flush();
+				byte[] encoded = bos.toByteArray();
+				assertFalse(Arrays.equals(data, encoded));
+				try (BinaryHunkInputStream in = new BinaryHunkInputStream(
+						new ByteArrayInputStream(encoded))) {
+					byte[] decoded = new byte[data.length];
+					int newLength = in.read(decoded);
+					assertEquals(newLength, decoded.length);
+					assertEquals(-1, in.read());
+					assertArrayEquals(data, decoded);
+				}
+			}
+		}
+	}
+
+	@Test
+	public void testRoundtripChunks() throws IOException {
+		for (int length = 1; length < 520 + 52; length++) {
+			byte[] data = new byte[length];
+			for (int i = 0; i < data.length; i++) {
+				data[i] = (byte) (255 - (i % 256));
+			}
+			try (ByteArrayOutputStream bos = new ByteArrayOutputStream();
+					BinaryHunkOutputStream out = new BinaryHunkOutputStream(
+							bos)) {
+				out.write(data, 0, data.length / 2);
+				out.write(data, data.length / 2, data.length - data.length / 2);
+				out.flush();
+				byte[] encoded = bos.toByteArray();
+				assertFalse(Arrays.equals(data, encoded));
+				try (BinaryHunkInputStream in = new BinaryHunkInputStream(
+						new ByteArrayInputStream(encoded))) {
+					byte[] decoded = new byte[data.length];
+					int p = 0;
+					int n;
+					while ((n = in.read(decoded, p,
+							Math.min(decoded.length - p, 57))) >= 0) {
+						p += n;
+						if (p == decoded.length) {
+							break;
+						}
+					}
+					assertEquals(p, decoded.length);
+					assertEquals(-1, in.read());
+					assertArrayEquals(data, decoded);
+				}
+			}
+		}
+	}
+
+	@Test
+	public void testRoundtripBytes() throws IOException {
+		for (int length = 1; length < 520 + 52; length++) {
+			byte[] data = new byte[length];
+			for (int i = 0; i < data.length; i++) {
+				data[i] = (byte) (255 - (i % 256));
+			}
+			try (ByteArrayOutputStream bos = new ByteArrayOutputStream();
+					BinaryHunkOutputStream out = new BinaryHunkOutputStream(
+							bos)) {
+				for (int i = 0; i < data.length; i++) {
+					out.write(data[i]);
+				}
+				out.flush();
+				byte[] encoded = bos.toByteArray();
+				assertFalse(Arrays.equals(data, encoded));
+				try (BinaryHunkInputStream in = new BinaryHunkInputStream(
+						new ByteArrayInputStream(encoded))) {
+					byte[] decoded = new byte[data.length];
+					for (int i = 0; i < decoded.length; i++) {
+						int val = in.read();
+						assertTrue(0 <= val && val <= 255);
+						decoded[i] = (byte) val;
+					}
+					assertEquals(-1, in.read());
+					assertArrayEquals(data, decoded);
+				}
+			}
+		}
+	}
+
+	@Test
+	public void testRoundtripWithClose() throws IOException {
+		for (int length = 1; length < 520 + 52; length++) {
+			byte[] data = new byte[length];
+			for (int i = 0; i < data.length; i++) {
+				data[i] = (byte) (255 - (i % 256));
+			}
+			try (ByteArrayOutputStream bos = new ByteArrayOutputStream()) {
+				try (BinaryHunkOutputStream out = new BinaryHunkOutputStream(
+						bos)) {
+					out.write(data);
+				}
+				byte[] encoded = bos.toByteArray();
+				assertFalse(Arrays.equals(data, encoded));
+				try (BinaryHunkInputStream in = new BinaryHunkInputStream(
+						new ByteArrayInputStream(encoded))) {
+					byte[] decoded = new byte[data.length];
+					int newLength = in.read(decoded);
+					assertEquals(newLength, decoded.length);
+					assertEquals(-1, in.read());
+					assertArrayEquals(data, decoded);
+				}
+			}
+		}
+	}
+}
diff --git a/org.eclipse.jgit/.settings/.api_filters b/org.eclipse.jgit/.settings/.api_filters
new file mode 100644
index 0000000..33331fb
--- /dev/null
+++ b/org.eclipse.jgit/.settings/.api_filters
@@ -0,0 +1,11 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<component id="org.eclipse.jgit" version="2">
+    <resource path="src/org/eclipse/jgit/transport/SshConstants.java" type="org.eclipse.jgit.transport.SshConstants">
+        <filter id="1142947843">
+            <message_arguments>
+                <message_argument value="5.11.1"/>
+                <message_argument value="PUBKEY_ACCEPTED_ALGORITHMS"/>
+            </message_arguments>
+        </filter>
+    </resource>
+</component>
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 2fa8713..962324e 100644
--- a/org.eclipse.jgit/resources/org/eclipse/jgit/internal/JGitText.properties
+++ b/org.eclipse.jgit/resources/org/eclipse/jgit/internal/JGitText.properties
@@ -13,6 +13,9 @@
 aNewObjectIdIsRequired=A NewObjectId is required.
 anExceptionOccurredWhileTryingToAddTheIdOfHEAD=An exception occurred while trying to add the Id of HEAD
 anSSHSessionHasBeenAlreadyCreated=An SSH session has been already created
+applyBinaryBaseOidWrong=Cannot apply binary patch; OID for file {0} does not match
+applyBinaryOidTooShort=Binary patch for file {0} does not have full IDs
+applyBinaryResultOidWrong=Result of binary patch for file {0} has wrong OID.
 applyingCommit=Applying {0}
 archiveFormatAlreadyAbsent=Archive format already absent: {0}
 archiveFormatAlreadyRegistered=Archive format already registered with different implementation: {0}
@@ -37,7 +40,19 @@
 badSectionEntry=Bad section entry: {0}
 badShallowLine=Bad shallow line: {0}
 bareRepositoryNoWorkdirAndIndex=Bare Repository has neither a working tree, nor an index
+base85invalidChar=Invalid base-85 character: 0x{0}
+base85length=Base-85 encoded data must have a length that is a multiple of 5
+base85overflow=Base-85 value overflow, does not fit into 32 bits: 0x{0}
+base85tooLong=Extra base-85 encoded data for output size of {0} bytes
+base85tooShort=Base-85 data decoded into less than {0} bytes
 baseLengthIncorrect=base length incorrect
+binaryDeltaBaseLengthMismatch=Binary delta base length does not match, expected {0}, got {1}
+binaryDeltaInvalidOffset=Binary delta offset + length too large: {0} + {1}
+binaryDeltaInvalidResultLength=Binary delta expected result length is negative
+binaryHunkDecodeError=Binary hunk, line {0}: invalid input
+binaryHunkInvalidLength=Binary hunk, line {0}: input corrupt; expected length byte, got 0x{1}
+binaryHunkLineTooShort=Binary hunk, line {0}: input ended prematurely
+binaryHunkMissingNewline=Binary hunk, line {0}: input line not terminated by newline
 bitmapMissingObject=Bitmap at {0} is missing {1}.
 bitmapsMustBePrepared=Bitmaps must be prepared before they may be written.
 blameNotCommittedYet=Not Committed Yet
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/api/ApplyCommand.java b/org.eclipse.jgit/src/org/eclipse/jgit/api/ApplyCommand.java
index e228e82..583767a 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/api/ApplyCommand.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/api/ApplyCommand.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2011, 2020 IBM Corporation and others
+ * Copyright (C) 2011, 2021 IBM Corporation 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,29 +9,68 @@
  */
 package org.eclipse.jgit.api;
 
+import java.io.BufferedInputStream;
+import java.io.ByteArrayInputStream;
 import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
 import java.io.IOException;
 import java.io.InputStream;
-import java.io.Writer;
+import java.io.OutputStream;
+import java.nio.ByteBuffer;
 import java.nio.file.Files;
 import java.nio.file.StandardCopyOption;
 import java.text.MessageFormat;
 import java.util.ArrayList;
 import java.util.Iterator;
 import java.util.List;
+import java.util.zip.InflaterInputStream;
 
+import org.eclipse.jgit.api.errors.FilterFailedException;
 import org.eclipse.jgit.api.errors.GitAPIException;
 import org.eclipse.jgit.api.errors.PatchApplyException;
 import org.eclipse.jgit.api.errors.PatchFormatException;
+import org.eclipse.jgit.attributes.FilterCommand;
+import org.eclipse.jgit.attributes.FilterCommandRegistry;
 import org.eclipse.jgit.diff.DiffEntry.ChangeType;
 import org.eclipse.jgit.diff.RawText;
+import org.eclipse.jgit.dircache.DirCache;
+import org.eclipse.jgit.dircache.DirCacheCheckout;
+import org.eclipse.jgit.dircache.DirCacheCheckout.CheckoutMetadata;
+import org.eclipse.jgit.dircache.DirCacheIterator;
+import org.eclipse.jgit.errors.LargeObjectException;
+import org.eclipse.jgit.errors.MissingObjectException;
 import org.eclipse.jgit.internal.JGitText;
+import org.eclipse.jgit.lib.Constants;
+import org.eclipse.jgit.lib.CoreConfig.EolStreamType;
 import org.eclipse.jgit.lib.FileMode;
+import org.eclipse.jgit.lib.ObjectId;
+import org.eclipse.jgit.lib.ObjectLoader;
+import org.eclipse.jgit.lib.ObjectStream;
 import org.eclipse.jgit.lib.Repository;
+import org.eclipse.jgit.patch.BinaryHunk;
 import org.eclipse.jgit.patch.FileHeader;
+import org.eclipse.jgit.patch.FileHeader.PatchType;
 import org.eclipse.jgit.patch.HunkHeader;
 import org.eclipse.jgit.patch.Patch;
+import org.eclipse.jgit.treewalk.FileTreeIterator;
+import org.eclipse.jgit.treewalk.TreeWalk;
+import org.eclipse.jgit.treewalk.TreeWalk.OperationType;
+import org.eclipse.jgit.treewalk.filter.AndTreeFilter;
+import org.eclipse.jgit.treewalk.filter.NotIgnoredFilter;
+import org.eclipse.jgit.treewalk.filter.PathFilterGroup;
+import org.eclipse.jgit.util.FS;
+import org.eclipse.jgit.util.FS.ExecutionResult;
 import org.eclipse.jgit.util.FileUtils;
+import org.eclipse.jgit.util.IO;
+import org.eclipse.jgit.util.RawParseUtils;
+import org.eclipse.jgit.util.StringUtils;
+import org.eclipse.jgit.util.TemporaryBuffer;
+import org.eclipse.jgit.util.TemporaryBuffer.LocalFile;
+import org.eclipse.jgit.util.io.BinaryDeltaInputStream;
+import org.eclipse.jgit.util.io.BinaryHunkInputStream;
+import org.eclipse.jgit.util.io.EolStreamTypeUtil;
+import org.eclipse.jgit.util.sha1.SHA1;
 
 /**
  * Apply a patch to files and/or to the index.
@@ -45,7 +84,7 @@
 	private InputStream in;
 
 	/**
-	 * Constructs the command if the patch is to be applied to the index.
+	 * Constructs the command.
 	 *
 	 * @param repo
 	 */
@@ -79,6 +118,7 @@
 	public ApplyResult call() throws GitAPIException, PatchFormatException,
 			PatchApplyException {
 		checkCallable();
+		setCallable(false);
 		ApplyResult r = new ApplyResult();
 		try {
 			final Patch p = new Patch();
@@ -87,19 +127,22 @@
 			} finally {
 				in.close();
 			}
-			if (!p.getErrors().isEmpty())
+			if (!p.getErrors().isEmpty()) {
 				throw new PatchFormatException(p.getErrors());
+			}
+			Repository repository = getRepository();
+			DirCache cache = repository.readDirCache();
 			for (FileHeader fh : p.getFiles()) {
 				ChangeType type = fh.getChangeType();
 				File f = null;
 				switch (type) {
 				case ADD:
 					f = getFile(fh.getNewPath(), true);
-					apply(f, fh);
+					apply(repository, fh.getNewPath(), cache, f, fh);
 					break;
 				case MODIFY:
 					f = getFile(fh.getOldPath(), false);
-					apply(f, fh);
+					apply(repository, fh.getOldPath(), cache, f, fh);
 					break;
 				case DELETE:
 					f = getFile(fh.getOldPath(), false);
@@ -118,14 +161,14 @@
 						throw new PatchApplyException(MessageFormat.format(
 								JGitText.get().renameFileFailed, f, dest), e);
 					}
-					apply(dest, fh);
+					apply(repository, fh.getOldPath(), cache, dest, fh);
 					break;
 				case COPY:
 					f = getFile(fh.getOldPath(), false);
 					File target = getFile(fh.getNewPath(), false);
 					FileUtils.mkdirs(target.getParentFile(), true);
 					Files.copy(f.toPath(), target.toPath());
-					apply(target, fh);
+					apply(repository, fh.getOldPath(), cache, target, fh);
 				}
 				r.addUpdatedFile(f);
 			}
@@ -133,14 +176,13 @@
 			throw new PatchApplyException(MessageFormat.format(
 					JGitText.get().patchApplyException, e.getMessage()), e);
 		}
-		setCallable(false);
 		return r;
 	}
 
 	private File getFile(String path, boolean create)
 			throws PatchApplyException {
 		File f = new File(getRepository().getWorkTree(), path);
-		if (create)
+		if (create) {
 			try {
 				File parent = f.getParentFile();
 				FileUtils.mkdirs(parent, true);
@@ -149,22 +191,366 @@
 				throw new PatchApplyException(MessageFormat.format(
 						JGitText.get().createNewFileFailed, f), e);
 			}
+		}
 		return f;
 	}
 
+	private void apply(Repository repository, String path, DirCache cache,
+			File f, FileHeader fh) throws IOException, PatchApplyException {
+		if (PatchType.BINARY.equals(fh.getPatchType())) {
+			return;
+		}
+		boolean convertCrLf = needsCrLfConversion(f, fh);
+		// Use a TreeWalk with a DirCacheIterator to pick up the correct
+		// clean/smudge filters. CR-LF handling is completely determined by
+		// whether the file or the patch have CR-LF line endings.
+		try (TreeWalk walk = new TreeWalk(repository)) {
+			walk.setOperationType(OperationType.CHECKIN_OP);
+			FileTreeIterator files = new FileTreeIterator(repository);
+			int fileIdx = walk.addTree(files);
+			int cacheIdx = walk.addTree(new DirCacheIterator(cache));
+			files.setDirCacheIterator(walk, cacheIdx);
+			walk.setFilter(AndTreeFilter.create(
+					PathFilterGroup.createFromStrings(path),
+					new NotIgnoredFilter(fileIdx)));
+			walk.setRecursive(true);
+			if (walk.next()) {
+				// If the file on disk has no newline characters, convertCrLf
+				// will be false. In that case we want to honor the normal git
+				// settings.
+				EolStreamType streamType = convertCrLf ? EolStreamType.TEXT_CRLF
+						: walk.getEolStreamType(OperationType.CHECKOUT_OP);
+				String command = walk.getFilterCommand(
+						Constants.ATTR_FILTER_TYPE_SMUDGE);
+				CheckoutMetadata checkOut = new CheckoutMetadata(streamType, command);
+				FileTreeIterator file = walk.getTree(fileIdx,
+						FileTreeIterator.class);
+				if (file != null) {
+					if (PatchType.GIT_BINARY.equals(fh.getPatchType())) {
+						applyBinary(repository, path, f, fh,
+								file::openEntryStream, file.getEntryObjectId(),
+								checkOut);
+					} else {
+						command = walk.getFilterCommand(
+								Constants.ATTR_FILTER_TYPE_CLEAN);
+						RawText raw;
+						// Can't use file.openEntryStream() as it would do CR-LF
+						// conversion as usual, not as wanted by us.
+						try (InputStream input = filterClean(repository, path,
+								new FileInputStream(f), convertCrLf, command)) {
+							raw = new RawText(
+									IO.readWholeStream(input, 0).array());
+						}
+						applyText(repository, path, raw, f, fh, checkOut);
+					}
+					return;
+				}
+			}
+		}
+		// File ignored?
+		RawText raw;
+		CheckoutMetadata checkOut;
+		if (PatchType.GIT_BINARY.equals(fh.getPatchType())) {
+			checkOut = new CheckoutMetadata(EolStreamType.DIRECT, null);
+			applyBinary(repository, path, f, fh, () -> new FileInputStream(f),
+					null, checkOut);
+		} else {
+			if (convertCrLf) {
+				try (InputStream input = EolStreamTypeUtil.wrapInputStream(
+						new FileInputStream(f), EolStreamType.TEXT_LF)) {
+					raw = new RawText(IO.readWholeStream(input, 0).array());
+				}
+				checkOut = new CheckoutMetadata(EolStreamType.TEXT_CRLF, null);
+			} else {
+				raw = new RawText(f);
+				checkOut = new CheckoutMetadata(EolStreamType.DIRECT, null);
+			}
+			applyText(repository, path, raw, f, fh, checkOut);
+		}
+	}
+
+	private boolean needsCrLfConversion(File f, FileHeader fileHeader)
+			throws IOException {
+		if (PatchType.GIT_BINARY.equals(fileHeader.getPatchType())) {
+			return false;
+		}
+		if (!hasCrLf(fileHeader)) {
+			try (InputStream input = new FileInputStream(f)) {
+				return RawText.isCrLfText(input);
+			}
+		}
+		return false;
+	}
+
+	private static boolean hasCrLf(FileHeader fileHeader) {
+		if (PatchType.GIT_BINARY.equals(fileHeader.getPatchType())) {
+			return false;
+		}
+		for (HunkHeader header : fileHeader.getHunks()) {
+			byte[] buf = header.getBuffer();
+			int hunkEnd = header.getEndOffset();
+			int lineStart = header.getStartOffset();
+			while (lineStart < hunkEnd) {
+				int nextLineStart = RawParseUtils.nextLF(buf, lineStart);
+				if (nextLineStart > hunkEnd) {
+					nextLineStart = hunkEnd;
+				}
+				if (nextLineStart <= lineStart) {
+					break;
+				}
+				if (nextLineStart - lineStart > 1) {
+					char first = (char) (buf[lineStart] & 0xFF);
+					if (first == ' ' || first == '-') {
+						// It's an old line. Does it end in CR-LF?
+						if (buf[nextLineStart - 2] == '\r') {
+							return true;
+						}
+					}
+				}
+				lineStart = nextLineStart;
+			}
+		}
+		return false;
+	}
+
+	private InputStream filterClean(Repository repository, String path,
+			InputStream fromFile, boolean convertCrLf, String filterCommand)
+			throws IOException {
+		InputStream input = fromFile;
+		if (convertCrLf) {
+			input = EolStreamTypeUtil.wrapInputStream(input,
+					EolStreamType.TEXT_LF);
+		}
+		if (StringUtils.isEmptyOrNull(filterCommand)) {
+			return input;
+		}
+		if (FilterCommandRegistry.isRegistered(filterCommand)) {
+			LocalFile buffer = new TemporaryBuffer.LocalFile(null);
+			FilterCommand command = FilterCommandRegistry.createFilterCommand(
+					filterCommand, repository, input, buffer);
+			while (command.run() != -1) {
+				// loop as long as command.run() tells there is work to do
+			}
+			return buffer.openInputStreamWithAutoDestroy();
+		}
+		FS fs = repository.getFS();
+		ProcessBuilder filterProcessBuilder = fs.runInShell(filterCommand,
+				new String[0]);
+		filterProcessBuilder.directory(repository.getWorkTree());
+		filterProcessBuilder.environment().put(Constants.GIT_DIR_KEY,
+				repository.getDirectory().getAbsolutePath());
+		ExecutionResult result;
+		try {
+			result = fs.execute(filterProcessBuilder, in);
+		} catch (IOException | InterruptedException e) {
+			throw new IOException(
+					new FilterFailedException(e, filterCommand, path));
+		}
+		int rc = result.getRc();
+		if (rc != 0) {
+			throw new IOException(new FilterFailedException(rc, filterCommand,
+					path, result.getStdout().toByteArray(4096), RawParseUtils
+							.decode(result.getStderr().toByteArray(4096))));
+		}
+		return result.getStdout().openInputStreamWithAutoDestroy();
+	}
+
 	/**
-	 * @param f
-	 * @param fh
-	 * @throws IOException
-	 * @throws PatchApplyException
+	 * Something that can supply an {@link InputStream}.
 	 */
-	private void apply(File f, FileHeader fh)
+	private interface StreamSupplier {
+		InputStream load() throws IOException;
+	}
+
+	/**
+	 * We write the patch result to a {@link TemporaryBuffer} and then use
+	 * {@link DirCacheCheckout}.getContent() to run the result through the CR-LF
+	 * and smudge filters. DirCacheCheckout needs an ObjectLoader, not a
+	 * TemporaryBuffer, so this class bridges between the two, making any Stream
+	 * provided by a {@link StreamSupplier} look like an ordinary git blob to
+	 * DirCacheCheckout.
+	 */
+	private static class StreamLoader extends ObjectLoader {
+
+		private StreamSupplier data;
+
+		private long size;
+
+		StreamLoader(StreamSupplier data, long length) {
+			this.data = data;
+			this.size = length;
+		}
+
+		@Override
+		public int getType() {
+			return Constants.OBJ_BLOB;
+		}
+
+		@Override
+		public long getSize() {
+			return size;
+		}
+
+		@Override
+		public boolean isLarge() {
+			return true;
+		}
+
+		@Override
+		public byte[] getCachedBytes() throws LargeObjectException {
+			throw new LargeObjectException();
+		}
+
+		@Override
+		public ObjectStream openStream()
+				throws MissingObjectException, IOException {
+			return new ObjectStream.Filter(getType(), getSize(),
+					new BufferedInputStream(data.load()));
+		}
+	}
+
+	private void initHash(SHA1 hash, long size) {
+		hash.update(Constants.encodedTypeString(Constants.OBJ_BLOB));
+		hash.update((byte) ' ');
+		hash.update(Constants.encodeASCII(size));
+		hash.update((byte) 0);
+	}
+
+	private ObjectId hash(File f) throws IOException {
+		SHA1 hash = SHA1.newInstance();
+		initHash(hash, f.length());
+		try (InputStream input = new FileInputStream(f)) {
+			byte[] buf = new byte[8192];
+			int n;
+			while ((n = input.read(buf)) >= 0) {
+				hash.update(buf, 0, n);
+			}
+		}
+		return hash.toObjectId();
+	}
+
+	private void checkOid(ObjectId baseId, ObjectId id, ChangeType type, File f,
+			String path)
+			throws PatchApplyException, IOException {
+		boolean hashOk = false;
+		if (id != null) {
+			hashOk = baseId.equals(id);
+			if (!hashOk && ChangeType.ADD.equals(type)
+					&& ObjectId.zeroId().equals(baseId)) {
+				// We create the file first. The OID of an empty file is not the
+				// zero id!
+				hashOk = Constants.EMPTY_BLOB_ID.equals(id);
+			}
+		} else {
+			if (ObjectId.zeroId().equals(baseId)) {
+				// File empty is OK.
+				hashOk = !f.exists() || f.length() == 0;
+			} else {
+				hashOk = baseId.equals(hash(f));
+			}
+		}
+		if (!hashOk) {
+			throw new PatchApplyException(MessageFormat
+					.format(JGitText.get().applyBinaryBaseOidWrong, path));
+		}
+	}
+
+	private void applyBinary(Repository repository, String path, File f,
+			FileHeader fh, StreamSupplier loader, ObjectId id,
+			CheckoutMetadata checkOut)
+			throws PatchApplyException, IOException {
+		if (!fh.getOldId().isComplete() || !fh.getNewId().isComplete()) {
+			throw new PatchApplyException(MessageFormat
+					.format(JGitText.get().applyBinaryOidTooShort, path));
+		}
+		BinaryHunk hunk = fh.getForwardBinaryHunk();
+		// A BinaryHunk has the start at the "literal" or "delta" token. Data
+		// starts on the next line.
+		int start = RawParseUtils.nextLF(hunk.getBuffer(),
+				hunk.getStartOffset());
+		int length = hunk.getEndOffset() - start;
+		SHA1 hash = SHA1.newInstance();
+		// Write to a buffer and copy to the file only if everything was fine
+		TemporaryBuffer buffer = new TemporaryBuffer.LocalFile(null);
+		try {
+			switch (hunk.getType()) {
+			case LITERAL_DEFLATED:
+				// This just overwrites the file. We need to check the hash of
+				// the base.
+				checkOid(fh.getOldId().toObjectId(), id, fh.getChangeType(), f,
+						path);
+				initHash(hash, hunk.getSize());
+				try (OutputStream out = buffer;
+						InputStream inflated = new SHA1InputStream(hash,
+								new InflaterInputStream(
+										new BinaryHunkInputStream(
+												new ByteArrayInputStream(
+														hunk.getBuffer(), start,
+														length))))) {
+					DirCacheCheckout.getContent(repository, path, checkOut,
+							new StreamLoader(() -> inflated, hunk.getSize()),
+							null, out);
+					if (!fh.getNewId().toObjectId().equals(hash.toObjectId())) {
+						throw new PatchApplyException(MessageFormat.format(
+								JGitText.get().applyBinaryResultOidWrong,
+								path));
+					}
+				}
+				try (InputStream bufIn = buffer.openInputStream()) {
+					Files.copy(bufIn, f.toPath(),
+							StandardCopyOption.REPLACE_EXISTING);
+				}
+				break;
+			case DELTA_DEFLATED:
+				// Unfortunately delta application needs random access to the
+				// base to construct the result.
+				byte[] base;
+				try (InputStream input = loader.load()) {
+					base = IO.readWholeStream(input, 0).array();
+				}
+				// At least stream the result!
+				try (BinaryDeltaInputStream input = new BinaryDeltaInputStream(
+						base,
+						new InflaterInputStream(new BinaryHunkInputStream(
+								new ByteArrayInputStream(hunk.getBuffer(),
+										start, length))))) {
+					long finalSize = input.getExpectedResultSize();
+					initHash(hash, finalSize);
+					try (OutputStream out = buffer;
+							SHA1InputStream hashed = new SHA1InputStream(hash,
+									input)) {
+						DirCacheCheckout.getContent(repository, path, checkOut,
+								new StreamLoader(() -> hashed, finalSize), null,
+								out);
+						if (!fh.getNewId().toObjectId()
+								.equals(hash.toObjectId())) {
+							throw new PatchApplyException(MessageFormat.format(
+									JGitText.get().applyBinaryResultOidWrong,
+									path));
+						}
+					}
+				}
+				try (InputStream bufIn = buffer.openInputStream()) {
+					Files.copy(bufIn, f.toPath(),
+							StandardCopyOption.REPLACE_EXISTING);
+				}
+				break;
+			default:
+				break;
+			}
+		} finally {
+			buffer.destroy();
+		}
+	}
+
+	private void applyText(Repository repository, String path, RawText rt,
+			File f, FileHeader fh, CheckoutMetadata checkOut)
 			throws IOException, PatchApplyException {
-		RawText rt = new RawText(f);
-		List<String> oldLines = new ArrayList<>(rt.size());
-		for (int i = 0; i < rt.size(); i++)
-			oldLines.add(rt.getString(i));
-		List<String> newLines = new ArrayList<>(oldLines);
+		List<ByteBuffer> oldLines = new ArrayList<>(rt.size());
+		for (int i = 0; i < rt.size(); i++) {
+			oldLines.add(rt.getRawString(i));
+		}
+		List<ByteBuffer> newLines = new ArrayList<>(oldLines);
 		int afterLastHunk = 0;
 		int lineNumberShift = 0;
 		int lastHunkNewLine = -1;
@@ -182,9 +568,9 @@
 					b.length);
 			RawText hrt = new RawText(b);
 
-			List<String> hunkLines = new ArrayList<>(hrt.size());
+			List<ByteBuffer> hunkLines = new ArrayList<>(hrt.size());
 			for (int i = 0; i < hrt.size(); i++) {
-				hunkLines.add(hrt.getString(i));
+				hunkLines.add(hrt.getRawString(i));
 			}
 
 			if (hh.getNewStartLine() == 0) {
@@ -253,8 +639,13 @@
 			lineNumberShift = applyAt - hh.getNewStartLine() + 1;
 			int sz = hunkLines.size();
 			for (int j = 1; j < sz; j++) {
-				String hunkLine = hunkLines.get(j);
-				switch (hunkLine.charAt(0)) {
+				ByteBuffer hunkLine = hunkLines.get(j);
+				if (!hunkLine.hasRemaining()) {
+					// Completely empty line; accept as empty context line
+					applyAt++;
+					continue;
+				}
+				switch (hunkLine.array()[hunkLine.position()]) {
 				case ' ':
 					applyAt++;
 					break;
@@ -262,7 +653,7 @@
 					newLines.remove(applyAt);
 					break;
 				case '+':
-					newLines.add(applyAt++, hunkLine.substring(1));
+					newLines.add(applyAt++, slice(hunkLine, 1));
 					break;
 				default:
 					break;
@@ -271,39 +662,64 @@
 			afterLastHunk = applyAt;
 		}
 		if (!isNoNewlineAtEndOfFile(fh)) {
-			newLines.add(""); //$NON-NLS-1$
+			newLines.add(null);
 		}
 		if (!rt.isMissingNewlineAtEnd()) {
-			oldLines.add(""); //$NON-NLS-1$
+			oldLines.add(null);
 		}
-		if (!isChanged(oldLines, newLines)) {
-			return; // Don't touch the file
+		if (oldLines.equals(newLines)) {
+			return; // Unchanged; don't touch the file
 		}
-		try (Writer fw = Files.newBufferedWriter(f.toPath())) {
-			for (Iterator<String> l = newLines.iterator(); l.hasNext();) {
-				fw.write(l.next());
-				if (l.hasNext()) {
-					// Don't bother handling line endings - if it was Windows,
-					// the \r is still there!
-					fw.write('\n');
+
+		TemporaryBuffer buffer = new TemporaryBuffer.LocalFile(null);
+		try {
+			try (OutputStream out = buffer) {
+				for (Iterator<ByteBuffer> l = newLines.iterator(); l
+						.hasNext();) {
+					ByteBuffer line = l.next();
+					if (line == null) {
+						// Must be the marker for the final newline
+						break;
+					}
+					out.write(line.array(), line.position(), line.remaining());
+					if (l.hasNext()) {
+						out.write('\n');
+					}
 				}
 			}
+			try (OutputStream output = new FileOutputStream(f)) {
+				DirCacheCheckout.getContent(repository, path, checkOut,
+						new StreamLoader(buffer::openInputStream,
+								buffer.length()),
+						null, output);
+			}
+		} finally {
+			buffer.destroy();
 		}
-		getRepository().getFS().setExecute(f, fh.getNewMode() == FileMode.EXECUTABLE_FILE);
+		repository.getFS().setExecute(f,
+				fh.getNewMode() == FileMode.EXECUTABLE_FILE);
 	}
 
-	private boolean canApplyAt(List<String> hunkLines, List<String> newLines,
-			int line) {
+	private boolean canApplyAt(List<ByteBuffer> hunkLines,
+			List<ByteBuffer> newLines, int line) {
 		int sz = hunkLines.size();
 		int limit = newLines.size();
 		int pos = line;
 		for (int j = 1; j < sz; j++) {
-			String hunkLine = hunkLines.get(j);
-			switch (hunkLine.charAt(0)) {
+			ByteBuffer hunkLine = hunkLines.get(j);
+			if (!hunkLine.hasRemaining()) {
+				// Empty line. Accept as empty context line.
+				if (pos >= limit || newLines.get(pos).hasRemaining()) {
+					return false;
+				}
+				pos++;
+				continue;
+			}
+			switch (hunkLine.array()[hunkLine.position()]) {
 			case ' ':
 			case '-':
 				if (pos >= limit
-						|| !newLines.get(pos).equals(hunkLine.substring(1))) {
+						|| !newLines.get(pos).equals(slice(hunkLine, 1))) {
 					return false;
 				}
 				pos++;
@@ -315,13 +731,9 @@
 		return true;
 	}
 
-	private static boolean isChanged(List<String> ol, List<String> nl) {
-		if (ol.size() != nl.size())
-			return true;
-		for (int i = 0; i < ol.size(); i++)
-			if (!ol.get(i).equals(nl.get(i)))
-				return true;
-		return false;
+	private ByteBuffer slice(ByteBuffer b, int off) {
+		int newOffset = b.position() + off;
+		return ByteBuffer.wrap(b.array(), newOffset, b.limit() - newOffset);
 	}
 
 	private boolean isNoNewlineAtEndOfFile(FileHeader fh) {
@@ -330,8 +742,51 @@
 			return false;
 		}
 		HunkHeader lastHunk = hunks.get(hunks.size() - 1);
-		RawText lhrt = new RawText(lastHunk.getBuffer());
+		byte[] buf = new byte[lastHunk.getEndOffset()
+				- lastHunk.getStartOffset()];
+		System.arraycopy(lastHunk.getBuffer(), lastHunk.getStartOffset(), buf,
+				0, buf.length);
+		RawText lhrt = new RawText(buf);
 		return lhrt.getString(lhrt.size() - 1)
 				.equals("\\ No newline at end of file"); //$NON-NLS-1$
 	}
+
+	/**
+	 * An {@link InputStream} that updates a {@link SHA1} on every byte read.
+	 * The hash is supposed to have been initialized before reading starts.
+	 */
+	private static class SHA1InputStream extends InputStream {
+
+		private final SHA1 hash;
+
+		private final InputStream in;
+
+		SHA1InputStream(SHA1 hash, InputStream in) {
+			this.hash = hash;
+			this.in = in;
+		}
+
+		@Override
+		public int read() throws IOException {
+			int b = in.read();
+			if (b >= 0) {
+				hash.update((byte) b);
+			}
+			return b;
+		}
+
+		@Override
+		public int read(byte[] b, int off, int len) throws IOException {
+			int n = in.read(b, off, len);
+			if (n > 0) {
+				hash.update(b, off, n);
+			}
+			return n;
+		}
+
+		@Override
+		public void close() throws IOException {
+			in.close();
+		}
+	}
 }
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/api/MergeCommand.java b/org.eclipse.jgit/src/org/eclipse/jgit/api/MergeCommand.java
index c611f91..ef56d80 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/api/MergeCommand.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/api/MergeCommand.java
@@ -87,6 +87,20 @@
 	private ProgressMonitor monitor = NullProgressMonitor.INSTANCE;
 
 	/**
+	 * Values for the "merge.conflictStyle" git config.
+	 *
+	 * @since 5.12
+	 */
+	public enum ConflictStyle {
+
+		/** "merge" style: only ours/theirs. This is the default. */
+		MERGE,
+
+		/** "diff3" style: ours/base/theirs. */
+		DIFF3
+	}
+
+	/**
 	 * The modes available for fast forward merges corresponding to the
 	 * <code>--ff</code>, <code>--no-ff</code> and <code>--ff-only</code>
 	 * options under <code>branch.&lt;name&gt;.mergeoptions</code>.
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/diff/RawText.java b/org.eclipse.jgit/src/org/eclipse/jgit/diff/RawText.java
index 9f4b1fa..d09da01 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/diff/RawText.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/diff/RawText.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-2021, 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
@@ -16,6 +16,7 @@
 import java.io.IOException;
 import java.io.InputStream;
 import java.io.OutputStream;
+import java.nio.ByteBuffer;
 
 import org.eclipse.jgit.errors.BinaryBlobException;
 import org.eclipse.jgit.errors.LargeObjectException;
@@ -165,6 +166,27 @@
 	}
 
 	/**
+	 * Get the raw text for a single line.
+	 *
+	 * @param i
+	 *            index of the line to extract. Note this is 0-based, so line
+	 *            number 1 is actually index 0.
+	 * @return the text for the line, without a trailing LF, as a
+	 *         {@link ByteBuffer} that is backed by a slice of the
+	 *         {@link #getRawContent() raw content}, with the buffer's position
+	 *         on the start of the line and the limit at the end.
+	 * @since 5.12
+	 */
+	public ByteBuffer getRawString(int i) {
+		int s = getStart(i);
+		int e = getEnd(i);
+		if (e > 0 && content[e - 1] == '\n') {
+			e--;
+		}
+		return ByteBuffer.wrap(content, s, e - s);
+	}
+
+	/**
 	 * Get the text for a region of lines.
 	 *
 	 * @param begin
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/diff/RenameDetector.java b/org.eclipse.jgit/src/org/eclipse/jgit/diff/RenameDetector.java
index 75784c2..ba1f63b 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/diff/RenameDetector.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/diff/RenameDetector.java
@@ -104,6 +104,13 @@
 	 */
 	private int bigFileThreshold = DEFAULT_BIG_FILE_THRESHOLD;
 
+	/**
+	 * Skip detecting content renames for binary files. Content renames are
+	 * those that are not exact, that is with a slight content modification
+	 * between the two files.
+	 */
+	private boolean skipContentRenamesForBinaryFiles = false;
+
 	/** Set if the number of adds or deletes was over the limit. */
 	private boolean overRenameLimit;
 
@@ -236,6 +243,26 @@
 	}
 
 	/**
+	 * Get skipping detecting content renames for binary files.
+	 *
+	 * @return true if content renames should be skipped for binary files, false otherwise.
+	 * @since 5.12
+	 */
+	public boolean getSkipContentRenamesForBinaryFiles() {
+		return skipContentRenamesForBinaryFiles;
+	}
+
+	/**
+	 * Sets skipping detecting content renames for binary files.
+	 *
+	 * @param value true if content renames should be skipped for binary files, false otherwise.
+	 * @since 5.12
+	 */
+	public void setSkipContentRenamesForBinaryFiles(boolean value) {
+		this.skipContentRenamesForBinaryFiles = value;
+	}
+
+	/**
 	 * Check if the detector is over the rename limit.
 	 * <p>
 	 * This method can be invoked either before or after {@code getEntries} has
@@ -521,6 +548,7 @@
 			d = new SimilarityRenameDetector(reader, deleted, added);
 			d.setRenameScore(getRenameScore());
 			d.setBigFileThreshold(getBigFileThreshold());
+			d.setSkipBinaryFiles(getSkipContentRenamesForBinaryFiles());
 			d.compute(pm);
 			overRenameLimit |= d.isTableOverflow();
 			deleted = d.getLeftOverSources();
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/diff/SimilarityIndex.java b/org.eclipse.jgit/src/org/eclipse/jgit/diff/SimilarityIndex.java
index fb6e5df..661369b 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/diff/SimilarityIndex.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/diff/SimilarityIndex.java
@@ -102,6 +102,15 @@
 		idGrowAt = growAt(idHashBits);
 	}
 
+	static boolean isBinary(ObjectLoader obj) throws IOException {
+		if (obj.isLarge()) {
+			try (ObjectStream in1 = obj.openStream()) {
+				return RawText.isBinary(in1);
+			}
+		}
+		return RawText.isBinary(obj.getCachedBytes());
+	}
+
 	void hash(ObjectLoader obj) throws MissingObjectException, IOException,
 			TableFullException {
 		if (obj.isLarge()) {
@@ -115,9 +124,7 @@
 	private void hashLargeObject(ObjectLoader obj) throws IOException,
 			TableFullException {
 		boolean text;
-		try (ObjectStream in1 = obj.openStream()) {
-			text = !RawText.isBinary(in1);
-		}
+		text = !isBinary(obj);
 
 		try (ObjectStream in2 = obj.openStream()) {
 			hash(in2, in2.getSize(), text);
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/diff/SimilarityRenameDetector.java b/org.eclipse.jgit/src/org/eclipse/jgit/diff/SimilarityRenameDetector.java
index 082f31d..5871b4a 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/diff/SimilarityRenameDetector.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/diff/SimilarityRenameDetector.java
@@ -26,6 +26,7 @@
 import org.eclipse.jgit.internal.JGitText;
 import org.eclipse.jgit.lib.FileMode;
 import org.eclipse.jgit.lib.NullProgressMonitor;
+import org.eclipse.jgit.lib.ObjectLoader;
 import org.eclipse.jgit.lib.ProgressMonitor;
 
 class SimilarityRenameDetector {
@@ -87,6 +88,9 @@
 	 */
 	private int bigFileThreshold = DEFAULT_BIG_FILE_THRESHOLD;
 
+	/** Skip content renames for binary files. */
+	private boolean skipBinaryFiles = false;
+
 	/** Set if any {@link SimilarityIndex.TableFullException} occurs. */
 	private boolean tableOverflow;
 
@@ -107,6 +111,10 @@
 		bigFileThreshold = threshold;
 	}
 
+	void setSkipBinaryFiles(boolean value) {
+		skipBinaryFiles = value;
+	}
+
 	void compute(ProgressMonitor pm) throws IOException, CancelledException {
 		if (pm == null)
 			pm = NullProgressMonitor.INSTANCE;
@@ -271,7 +279,12 @@
 
 				if (s == null) {
 					try {
-						s = hash(OLD, srcEnt);
+						ObjectLoader loader = reader.open(OLD, srcEnt);
+						if (skipBinaryFiles && SimilarityIndex.isBinary(loader)) {
+							pm.update(1);
+							continue SRC;
+						}
+						s = hash(loader);
 					} catch (TableFullException tableFull) {
 						tableOverflow = true;
 						continue SRC;
@@ -280,7 +293,12 @@
 
 				SimilarityIndex d;
 				try {
-					d = hash(NEW, dstEnt);
+					ObjectLoader loader = reader.open(NEW, dstEnt);
+					if (skipBinaryFiles && SimilarityIndex.isBinary(loader)) {
+						pm.update(1);
+						continue;
+					}
+					d = hash(loader);
 				} catch (TableFullException tableFull) {
 					if (dstTooLarge == null)
 						dstTooLarge = new BitSet(dsts.size());
@@ -364,10 +382,10 @@
 		return (((dirScoreLtr + dirScoreRtl) * 25) + (fileScore * 50)) / 100;
 	}
 
-	private SimilarityIndex hash(DiffEntry.Side side, DiffEntry ent)
+	private SimilarityIndex hash(ObjectLoader objectLoader)
 			throws IOException, TableFullException {
 		SimilarityIndex r = new SimilarityIndex();
-		r.hash(reader.open(side, ent));
+		r.hash(objectLoader);
 		r.sort();
 		return r;
 	}
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/gitrepo/RepoCommand.java b/org.eclipse.jgit/src/org/eclipse/jgit/gitrepo/RepoCommand.java
index c039aaf..552315d 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/gitrepo/RepoCommand.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/gitrepo/RepoCommand.java
@@ -12,6 +12,7 @@
 import static java.nio.charset.StandardCharsets.UTF_8;
 import static org.eclipse.jgit.lib.Constants.DEFAULT_REMOTE_NAME;
 import static org.eclipse.jgit.lib.Constants.R_REMOTES;
+import static org.eclipse.jgit.lib.Constants.R_TAGS;
 
 import java.io.File;
 import java.io.FileInputStream;
@@ -79,6 +80,13 @@
  * @since 3.4
  */
 public class RepoCommand extends GitCommand<RevCommit> {
+	private static final int LOCK_FAILURE_MAX_RETRIES = 5;
+
+	// Retry exponentially with delays in this range
+	private static final int LOCK_FAILURE_MIN_RETRY_DELAY_MILLIS = 50;
+
+	private static final int LOCK_FAILURE_MAX_RETRY_DELAY_MILLIS = 5000;
+
 	private String manifestPath;
 	private String baseUri;
 	private URI targetUri;
@@ -587,8 +595,11 @@
 							throw new RemoteUnavailableException(url);
 						}
 						if (recordRemoteBranch) {
-							// can be branch or tag
-							cfg.setString("submodule", name, "branch", //$NON-NLS-1$ //$NON-NLS-2$
+							// "branch" field is only for non-tag references.
+							// Keep tags in "ref" field as hint for other tools.
+							String field = proj.getRevision().startsWith(
+									R_TAGS) ? "ref" : "branch"; //$NON-NLS-1$ //$NON-NLS-2$
+							cfg.setString("submodule", name, field, //$NON-NLS-1$
 									proj.getRevision());
 						}
 
@@ -682,50 +693,22 @@
 				builder.finish();
 				ObjectId treeId = index.writeTree(inserter);
 
-				// Create a Commit object, populate it and write it
-				ObjectId headId = repo.resolve(targetBranch + "^{commit}"); //$NON-NLS-1$
-				if (headId != null && rw.parseCommit(headId).getTree().getId().equals(treeId)) {
-					// No change. Do nothing.
-					return rw.parseCommit(headId);
+				long prevDelay = 0;
+				for (int i = 0; i < LOCK_FAILURE_MAX_RETRIES - 1; i++) {
+					try {
+						return commitTreeOnCurrentTip(
+							inserter, rw, treeId);
+					} catch (ConcurrentRefUpdateException e) {
+						prevDelay = FileUtils.delay(prevDelay,
+								LOCK_FAILURE_MIN_RETRY_DELAY_MILLIS,
+								LOCK_FAILURE_MAX_RETRY_DELAY_MILLIS);
+						Thread.sleep(prevDelay);
+						repo.getRefDatabase().refresh();
+					}
 				}
-
-				CommitBuilder commit = new CommitBuilder();
-				commit.setTreeId(treeId);
-				if (headId != null)
-					commit.setParentIds(headId);
-				commit.setAuthor(author);
-				commit.setCommitter(author);
-				commit.setMessage(RepoText.get().repoCommitMessage);
-
-				ObjectId commitId = inserter.insert(commit);
-				inserter.flush();
-
-				RefUpdate ru = repo.updateRef(targetBranch);
-				ru.setNewObjectId(commitId);
-				ru.setExpectedOldObjectId(headId != null ? headId : ObjectId.zeroId());
-				Result rc = ru.update(rw);
-
-				switch (rc) {
-					case NEW:
-					case FORCED:
-					case FAST_FORWARD:
-						// Successful. Do nothing.
-						break;
-					case REJECTED:
-					case LOCK_FAILURE:
-						throw new ConcurrentRefUpdateException(
-								MessageFormat.format(
-										JGitText.get().cannotLock, targetBranch),
-								ru.getRef(),
-								rc);
-					default:
-						throw new JGitInternalException(MessageFormat.format(
-								JGitText.get().updatingRefFailed,
-								targetBranch, commitId.name(), rc));
-				}
-
-				return rw.parseCommit(commitId);
-			} catch (GitAPIException | IOException e) {
+				// In the last try, just propagate the exceptions
+				return commitTreeOnCurrentTip(inserter, rw, treeId);
+			} catch (GitAPIException | IOException | InterruptedException e) {
 				throw new ManifestErrorException(e);
 			}
 		}
@@ -742,6 +725,51 @@
 		}
 	}
 
+
+	private RevCommit commitTreeOnCurrentTip(ObjectInserter inserter,
+			RevWalk rw, ObjectId treeId)
+			throws IOException, ConcurrentRefUpdateException {
+		ObjectId headId = repo.resolve(targetBranch + "^{commit}"); //$NON-NLS-1$
+		if (headId != null && rw.parseCommit(headId).getTree().getId().equals(treeId)) {
+			// No change. Do nothing.
+			return rw.parseCommit(headId);
+		}
+
+		CommitBuilder commit = new CommitBuilder();
+		commit.setTreeId(treeId);
+		if (headId != null)
+			commit.setParentIds(headId);
+		commit.setAuthor(author);
+		commit.setCommitter(author);
+		commit.setMessage(RepoText.get().repoCommitMessage);
+
+		ObjectId commitId = inserter.insert(commit);
+		inserter.flush();
+
+		RefUpdate ru = repo.updateRef(targetBranch);
+		ru.setNewObjectId(commitId);
+		ru.setExpectedOldObjectId(headId != null ? headId : ObjectId.zeroId());
+		Result rc = ru.update(rw);
+		switch (rc) {
+			case NEW:
+			case FORCED:
+			case FAST_FORWARD:
+				// Successful. Do nothing.
+				break;
+			case REJECTED:
+			case LOCK_FAILURE:
+				throw new ConcurrentRefUpdateException(MessageFormat
+						.format(JGitText.get().cannotLock, targetBranch),
+						ru.getRef(), rc);
+			default:
+				throw new JGitInternalException(MessageFormat.format(
+						JGitText.get().updatingRefFailed,
+						targetBranch, commitId.name(), rc));
+		}
+
+		return rw.parseCommit(commitId);
+	}
+
 	private void addSubmodule(String name, String url, String path,
 			String revision, List<CopyFile> copyfiles, List<LinkFile> linkfiles,
 			Git git) throws GitAPIException, IOException {
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 ab9fc5c..fd54986 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/internal/JGitText.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/internal/JGitText.java
@@ -41,6 +41,9 @@
 	/***/ public String aNewObjectIdIsRequired;
 	/***/ public String anExceptionOccurredWhileTryingToAddTheIdOfHEAD;
 	/***/ public String anSSHSessionHasBeenAlreadyCreated;
+	/***/ public String applyBinaryBaseOidWrong;
+	/***/ public String applyBinaryOidTooShort;
+	/***/ public String applyBinaryResultOidWrong;
 	/***/ public String applyingCommit;
 	/***/ public String archiveFormatAlreadyAbsent;
 	/***/ public String archiveFormatAlreadyRegistered;
@@ -65,7 +68,19 @@
 	/***/ public String badSectionEntry;
 	/***/ public String badShallowLine;
 	/***/ public String bareRepositoryNoWorkdirAndIndex;
+	/***/ public String base85invalidChar;
+	/***/ public String base85length;
+	/***/ public String base85overflow;
+	/***/ public String base85tooLong;
+	/***/ public String base85tooShort;
 	/***/ public String baseLengthIncorrect;
+	/***/ public String binaryDeltaBaseLengthMismatch;
+	/***/ public String binaryDeltaInvalidOffset;
+	/***/ public String binaryDeltaInvalidResultLength;
+	/***/ public String binaryHunkDecodeError;
+	/***/ public String binaryHunkInvalidLength;
+	/***/ public String binaryHunkLineTooShort;
+	/***/ public String binaryHunkMissingNewline;
 	/***/ public String bitmapMissingObject;
 	/***/ public String bitmapsMustBePrepared;
 	/***/ public String blameNotCommittedYet;
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/RefDirectory.java b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/RefDirectory.java
index 7d108fe..17a9100 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/RefDirectory.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/RefDirectory.java
@@ -244,47 +244,18 @@
 	/** {@inheritDoc} */
 	@Override
 	public boolean isNameConflicting(String name) throws IOException {
-		RefList<Ref> packed = getPackedRefs();
-		RefList<LooseRef> loose = getLooseRefs();
-
 		// Cannot be nested within an existing reference.
 		int lastSlash = name.lastIndexOf('/');
 		while (0 < lastSlash) {
 			String needle = name.substring(0, lastSlash);
-			if (loose.contains(needle) || packed.contains(needle))
+			if (exactRef(needle) != null) {
 				return true;
+			}
 			lastSlash = name.lastIndexOf('/', lastSlash - 1);
 		}
 
 		// Cannot be the container of an existing reference.
-		String prefix = name + '/';
-		int idx;
-
-		idx = -(packed.find(prefix) + 1);
-		if (idx < packed.size() && packed.get(idx).getName().startsWith(prefix))
-			return true;
-
-		idx = -(loose.find(prefix) + 1);
-		if (idx < loose.size() && loose.get(idx).getName().startsWith(prefix))
-			return true;
-
-		return false;
-	}
-
-	private RefList<LooseRef> getLooseRefs() {
-		final RefList<LooseRef> oldLoose = looseRefs.get();
-
-		LooseScanner scan = new LooseScanner(oldLoose);
-		scan.scan(ALL);
-
-		RefList<LooseRef> loose;
-		if (scan.newLoose != null) {
-			loose = scan.newLoose.toRefList();
-			if (looseRefs.compareAndSet(oldLoose, loose))
-				modCnt.incrementAndGet();
-		} else
-			loose = oldLoose;
-		return loose;
+		return !getRefsByPrefix(name + '/').isEmpty();
 	}
 
 	@Nullable
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/internal/transport/ssh/OpenSshConfigFile.java b/org.eclipse.jgit/src/org/eclipse/jgit/internal/transport/ssh/OpenSshConfigFile.java
index de6a346..228c25f 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/internal/transport/ssh/OpenSshConfigFile.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/internal/transport/ssh/OpenSshConfigFile.java
@@ -1,6 +1,6 @@
 /*
  * Copyright (C) 2008, 2017, Google Inc.
- * Copyright (C) 2017, 2018, Thomas Wolf <thomas.wolf@paranor.ch> and others
+ * Copyright (C) 2017, 2021, 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
@@ -21,7 +21,8 @@
 import java.util.ArrayList;
 import java.util.Collections;
 import java.util.HashMap;
-import java.util.LinkedHashMap;
+import java.util.Iterator;
+import java.util.LinkedList;
 import java.util.List;
 import java.util.Map;
 import java.util.Set;
@@ -82,12 +83,6 @@
  */
 public class OpenSshConfigFile implements SshConfigStore {
 
-	/**
-	 * "Host" name of the HostEntry for the default options before the first
-	 * host block in a config file.
-	 */
-	private static final String DEFAULT_NAME = ""; //$NON-NLS-1$
-
 	/** The user's home directory, as key files may be relative to here. */
 	private final File home;
 
@@ -105,11 +100,9 @@
 	 * fully resolved entries created from that.
 	 */
 	private static class State {
-		// Keyed by pattern; if a "Host" line has multiple patterns, we generate
-		// duplicate HostEntry objects
-		Map<String, HostEntry> entries = new LinkedHashMap<>();
+		List<HostEntry> entries = new LinkedList<>();
 
-		// Keyed by user@hostname:port
+		// Previous lookups, keyed by user@hostname:port
 		Map<String, HostEntry> hosts = new HashMap<>();
 
 		@Override
@@ -165,14 +158,16 @@
 			return h;
 		}
 		HostEntry fullConfig = new HostEntry();
-		// Initialize with default entries at the top of the file, before the
-		// first Host block.
-		fullConfig.merge(cache.entries.get(DEFAULT_NAME));
-		for (Map.Entry<String, HostEntry> e : cache.entries.entrySet()) {
-			String pattern = e.getKey();
-			if (isHostMatch(pattern, hostName)) {
-				fullConfig.merge(e.getValue());
-			}
+		Iterator<HostEntry> entries = cache.entries.iterator();
+		if (entries.hasNext()) {
+			// Should always have at least the first top entry containing
+			// key-value pairs before the first Host block
+			fullConfig.merge(entries.next());
+			entries.forEachRemaining(entry -> {
+				if (entry.matches(hostName)) {
+					fullConfig.merge(entry);
+				}
+			});
 		}
 		fullConfig.substitute(hostName, port, userName, localUserName, home);
 		cache.hosts.put(cacheKey, fullConfig);
@@ -208,20 +203,19 @@
 		return state;
 	}
 
-	private Map<String, HostEntry> parse(BufferedReader reader)
+	private List<HostEntry> parse(BufferedReader reader)
 			throws IOException {
-		final Map<String, HostEntry> entries = new LinkedHashMap<>();
-		final List<HostEntry> current = new ArrayList<>(4);
-		String line;
+		final List<HostEntry> entries = new LinkedList<>();
 
 		// The man page doesn't say so, but the openssh parser (readconf.c)
 		// starts out in active mode and thus always applies any lines that
 		// occur before the first host block. We gather those options in a
 		// HostEntry for DEFAULT_NAME.
 		HostEntry defaults = new HostEntry();
-		current.add(defaults);
-		entries.put(DEFAULT_NAME, defaults);
+		HostEntry current = defaults;
+		entries.add(defaults);
 
+		String line;
 		while ((line = reader.readLine()) != null) {
 			// OpenSsh ignores trailing comments on a line. Anything after the
 			// first # on a line is trimmed away (yes, even if the hash is
@@ -246,38 +240,17 @@
 			String argValue = parts.length > 1 ? parts[1].trim() : ""; //$NON-NLS-1$
 
 			if (StringUtils.equalsIgnoreCase(SshConstants.HOST, keyword)) {
-				current.clear();
-				for (String name : parseList(argValue)) {
-					if (name == null || name.isEmpty()) {
-						// null should not occur, but better be safe than sorry.
-						continue;
-					}
-					HostEntry c = entries.get(name);
-					if (c == null) {
-						c = new HostEntry();
-						entries.put(name, c);
-					}
-					current.add(c);
-				}
-				continue;
-			}
-
-			if (current.isEmpty()) {
-				// We received an option outside of a Host block. We
-				// don't know who this should match against, so skip.
+				current = new HostEntry(parseList(argValue));
+				entries.add(current);
 				continue;
 			}
 
 			if (HostEntry.isListKey(keyword)) {
 				List<String> args = validate(keyword, parseList(argValue));
-				for (HostEntry entry : current) {
-					entry.setValue(keyword, args);
-				}
+				current.setValue(keyword, args);
 			} else if (!argValue.isEmpty()) {
 				argValue = validate(keyword, dequote(argValue));
-				for (HostEntry entry : current) {
-					entry.setValue(keyword, argValue);
-				}
+				current.setValue(keyword, argValue);
 			}
 		}
 
@@ -300,7 +273,7 @@
 		int length = argument.length();
 		while (start < length) {
 			// Skip whitespace
-			if (Character.isSpaceChar(argument.charAt(start))) {
+			if (Character.isWhitespace(argument.charAt(start))) {
 				start++;
 				continue;
 			}
@@ -315,7 +288,7 @@
 			} else {
 				int stop = start + 1;
 				while (stop < length
-						&& !Character.isSpaceChar(argument.charAt(stop))) {
+						&& !Character.isWhitespace(argument.charAt(stop))) {
 					stop++;
 				}
 				result.add(argument.substring(start, stop));
@@ -358,13 +331,6 @@
 		return value;
 	}
 
-	private static boolean isHostMatch(String pattern, String name) {
-		if (pattern.startsWith("!")) { //$NON-NLS-1$
-			return !patternMatchesHost(pattern.substring(1), name);
-		}
-		return patternMatchesHost(pattern, name);
-	}
-
 	private static boolean patternMatchesHost(String pattern, String name) {
 		if (pattern.indexOf('*') >= 0 || pattern.indexOf('?') >= 0) {
 			final FileNameMatcher fn;
@@ -389,9 +355,12 @@
 
 	private static String stripWhitespace(String value) {
 		final StringBuilder b = new StringBuilder();
-		for (int i = 0; i < value.length(); i++) {
-			if (!Character.isSpaceChar(value.charAt(i)))
-				b.append(value.charAt(i));
+		int length = value.length();
+		for (int i = 0; i < length; i++) {
+			char ch = value.charAt(i);
+			if (!Character.isWhitespace(ch)) {
+				b.append(ch);
+			}
 		}
 		return b.toString();
 	}
@@ -511,6 +480,38 @@
 
 		private Map<String, List<String>> listOptions;
 
+		private final List<String> patterns;
+
+		/**
+		 * Constructor used to build the merged entry; never matches anything
+		 */
+		public HostEntry() {
+			this.patterns = Collections.emptyList();
+		}
+
+		/**
+		 * @param patterns
+		 *            to be used in matching against host name.
+		 */
+		public HostEntry(List<String> patterns) {
+			this.patterns = patterns;
+		}
+
+		boolean matches(String hostName) {
+			boolean doesMatch = false;
+			for (String pattern : patterns) {
+				if (pattern.startsWith("!")) { //$NON-NLS-1$
+					if (patternMatchesHost(pattern.substring(1), hostName)) {
+						return false;
+					}
+				} else if (!doesMatch
+						&& patternMatchesHost(pattern, hostName)) {
+					doesMatch = true;
+				}
+			}
+			return doesMatch;
+		}
+
 		private static String toKey(String key) {
 			String k = ALIASES.get(key);
 			return k != null ? k : key;
@@ -886,8 +887,8 @@
 		public String substitute(String input, String allowed,
 				boolean withEnv) {
 			if (input == null || input.length() <= 1
-					|| input.indexOf('%') < 0
-							&& (!withEnv || input.indexOf("${") < 0)) { //$NON-NLS-1$
+					|| (input.indexOf('%') < 0
+							&& (!withEnv || input.indexOf("${") < 0))) { //$NON-NLS-1$
 				return input;
 			}
 			StringBuilder builder = new StringBuilder();
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/lib/BatchRefUpdate.java b/org.eclipse.jgit/src/org/eclipse/jgit/lib/BatchRefUpdate.java
index 06009f8..ef1379a 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/lib/BatchRefUpdate.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/lib/BatchRefUpdate.java
@@ -13,7 +13,6 @@
 
 import static org.eclipse.jgit.transport.ReceiveCommand.Result.NOT_ATTEMPTED;
 import static org.eclipse.jgit.transport.ReceiveCommand.Result.REJECTED_OTHER_REASON;
-import static java.util.stream.Collectors.toCollection;
 
 import java.io.IOException;
 import java.text.MessageFormat;
@@ -29,7 +28,6 @@
 import org.eclipse.jgit.annotations.Nullable;
 import org.eclipse.jgit.errors.MissingObjectException;
 import org.eclipse.jgit.internal.JGitText;
-import org.eclipse.jgit.lib.RefUpdate.Result;
 import org.eclipse.jgit.revwalk.RevWalk;
 import org.eclipse.jgit.transport.PushCertificate;
 import org.eclipse.jgit.transport.ReceiveCommand;
@@ -495,42 +493,24 @@
 			}
 		}
 		if (!commands2.isEmpty()) {
-			// What part of the name space is already taken
-			Collection<String> takenNames = refdb.getRefs().stream()
-					.map(Ref::getName)
-					.collect(toCollection(HashSet::new));
-			Collection<String> takenPrefixes = getTakenPrefixes(takenNames);
-
-			// Now to the update that may require more room in the name space
+			// Perform updates that may require more room in the name space
 			for (ReceiveCommand cmd : commands2) {
 				try {
 					if (cmd.getResult() == NOT_ATTEMPTED) {
 						cmd.updateType(walk);
 						RefUpdate ru = newUpdate(cmd);
-						SWITCH: switch (cmd.getType()) {
-						case DELETE:
-							// Performed in the first phase
-							break;
-						case UPDATE:
-						case UPDATE_NONFASTFORWARD:
-							RefUpdate ruu = newUpdate(cmd);
-							cmd.setResult(ruu.update(walk));
-							break;
-						case CREATE:
-							for (String prefix : getPrefixes(cmd.getRefName())) {
-								if (takenNames.contains(prefix)) {
-									cmd.setResult(Result.LOCK_FAILURE);
-									break SWITCH;
-								}
-							}
-							if (takenPrefixes.contains(cmd.getRefName())) {
-								cmd.setResult(Result.LOCK_FAILURE);
-								break SWITCH;
-							}
-							ru.setCheckConflicting(false);
-							takenPrefixes.addAll(getPrefixes(cmd.getRefName()));
-							takenNames.add(cmd.getRefName());
-							cmd.setResult(ru.update(walk));
+						switch (cmd.getType()) {
+							case DELETE:
+								// Performed in the first phase
+								break;
+							case UPDATE:
+							case UPDATE_NONFASTFORWARD:
+								RefUpdate ruu = newUpdate(cmd);
+								cmd.setResult(ruu.update(walk));
+								break;
+							case CREATE:
+								cmd.setResult(ru.update(walk));
+								break;
 						}
 					}
 				} catch (IOException err) {
@@ -602,14 +582,6 @@
 		execute(walk, monitor, null);
 	}
 
-	private static Collection<String> getTakenPrefixes(Collection<String> names) {
-		Collection<String> ref = new HashSet<>();
-		for (String name : names) {
-			addPrefixesTo(name, ref);
-		}
-		return ref;
-	}
-
 	/**
 	 * Get all path prefixes of a ref name.
 	 *
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 03c1ef9..3e3d9b5 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/lib/ConfigConstants.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/lib/ConfigConstants.java
@@ -398,7 +398,15 @@
 	public static final String CONFIG_KEY_FF = "ff";
 
 	/**
+	 * The "conflictStyle" key.
+	 *
+	 * @since 5.12
+	 */
+	public static final String CONFIG_KEY_CONFLICTSTYLE = "conflictStyle";
+
+	/**
 	 * The "checkstat" key
+	 *
 	 * @since 3.0
 	 */
 	public static final String CONFIG_KEY_CHECKSTAT = "checkstat";
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/transport/FetchV2Request.java b/org.eclipse.jgit/src/org/eclipse/jgit/transport/FetchV2Request.java
index ea63933..50fb9d2 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/transport/FetchV2Request.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/transport/FetchV2Request.java
@@ -36,6 +36,8 @@
 
 	private final boolean doneReceived;
 
+	private final boolean waitForDone;
+
 	@NonNull
 	private final List<String> serverOptions;
 
@@ -50,7 +52,8 @@
 			@NonNull Set<ObjectId> clientShallowCommits, int deepenSince,
 			@NonNull List<String> deepenNotRefs, int depth,
 			@NonNull FilterSpec filterSpec,
-			boolean doneReceived, @NonNull Set<String> clientCapabilities,
+			boolean doneReceived, boolean waitForDone,
+			@NonNull Set<String> clientCapabilities,
 			@Nullable String agent, @NonNull List<String> serverOptions,
 			boolean sidebandAll, @NonNull List<String> packfileUriProtocols) {
 		super(wantIds, depth, clientShallowCommits, filterSpec,
@@ -59,6 +62,7 @@
 		this.peerHas = requireNonNull(peerHas);
 		this.wantedRefs = requireNonNull(wantedRefs);
 		this.doneReceived = doneReceived;
+		this.waitForDone = waitForDone;
 		this.serverOptions = requireNonNull(serverOptions);
 		this.sidebandAll = sidebandAll;
 		this.packfileUriProtocols = packfileUriProtocols;
@@ -90,7 +94,14 @@
 	}
 
 	/**
-	 * Options received in server-option lines. The caller can choose to act on
+	 * @return true if the request had a "wait-for-done" line
+	 */
+	boolean wasWaitForDoneReceived() {
+		return waitForDone;
+	}
+
+	/**
+	 * Options received in server-option lines. The caller can choose to	 act on
 	 * these in an application-specific way
 	 *
 	 * @return Immutable list of server options received in the request
@@ -141,6 +152,8 @@
 
 		boolean doneReceived;
 
+		boolean waitForDone;
+
 		@Nullable
 		String agent;
 
@@ -280,6 +293,16 @@
 		}
 
 		/**
+		 * Mark that the "wait-for-done" line has been received.
+		 *
+		 * @return this builder
+		 */
+		Builder setWaitForDone() {
+			waitForDone = true;
+			return this;
+		}
+
+		/**
 		 * Value of an agent line received after the command and before the
 		 * arguments. E.g. "agent=a.b.c/1.0" should set "a.b.c/1.0".
 		 *
@@ -328,7 +351,7 @@
 		FetchV2Request build() {
 			return new FetchV2Request(peerHas, wantedRefs, wantIds,
 					clientShallowCommits, deepenSince, deepenNotRefs,
-					depth, filterSpec, doneReceived, clientCapabilities,
+					depth, filterSpec, doneReceived, waitForDone, clientCapabilities,
 					agent, Collections.unmodifiableList(serverOptions),
 					sidebandAll,
 					Collections.unmodifiableList(packfileUriProtocols));
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/transport/GitProtocolConstants.java b/org.eclipse.jgit/src/org/eclipse/jgit/transport/GitProtocolConstants.java
index 36fce7a..c5e52be 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/transport/GitProtocolConstants.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/transport/GitProtocolConstants.java
@@ -149,6 +149,13 @@
 	public static final String OPTION_SIDEBAND_ALL = "sideband-all"; //$NON-NLS-1$
 
 	/**
+	 * The server waits for client to send "done" before sending any packs back.
+	 *
+	 * @since 5.13
+	 */
+	public static final String OPTION_WAIT_FOR_DONE = "wait-for-done"; //$NON-NLS-1$
+
+	/**
 	 * The client supports atomic pushes. If this option is used, the server
 	 * will update all refs within one atomic transaction.
 	 *
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/transport/ProtocolV2Parser.java b/org.eclipse.jgit/src/org/eclipse/jgit/transport/ProtocolV2Parser.java
index faccc25..92f0133 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/transport/ProtocolV2Parser.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/transport/ProtocolV2Parser.java
@@ -19,6 +19,7 @@
 import static org.eclipse.jgit.transport.GitProtocolConstants.OPTION_SIDEBAND_ALL;
 import static org.eclipse.jgit.transport.GitProtocolConstants.OPTION_SIDE_BAND_64K;
 import static org.eclipse.jgit.transport.GitProtocolConstants.OPTION_THIN_PACK;
+import static org.eclipse.jgit.transport.GitProtocolConstants.OPTION_WAIT_FOR_DONE;
 import static org.eclipse.jgit.transport.GitProtocolConstants.OPTION_WANT_REF;
 
 import java.io.IOException;
@@ -123,6 +124,8 @@
 				reqBuilder.addPeerHas(ObjectId.fromString(line2.substring(5)));
 			} else if (line2.equals("done")) { //$NON-NLS-1$
 				reqBuilder.setDoneReceived();
+			} else if (line2.equals(OPTION_WAIT_FOR_DONE)) {
+				reqBuilder.setWaitForDone();
 			} else if (line2.equals(OPTION_THIN_PACK)) {
 				reqBuilder.addClientCapability(OPTION_THIN_PACK);
 			} else if (line2.equals(OPTION_NO_PROGRESS)) {
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/transport/SshConstants.java b/org.eclipse.jgit/src/org/eclipse/jgit/transport/SshConstants.java
index be55cd1..5cd5b33 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/transport/SshConstants.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/transport/SshConstants.java
@@ -118,7 +118,7 @@
 	 * Key in an ssh config file; defines signature algorithms for public key
 	 * authentication as a comma-separated list.
 	 *
-	 * @since 5.11
+	 * @since 5.11.1
 	 */
 	public static final String PUBKEY_ACCEPTED_ALGORITHMS = "PubkeyAcceptedAlgorithms";
 
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 83ffd41..da97f1e 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/transport/TransferConfig.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/transport/TransferConfig.java
@@ -120,7 +120,10 @@
 	private final boolean allowReachableSha1InWant;
 	private final boolean allowFilter;
 	private final boolean allowSidebandAll;
+
 	private final boolean advertiseSidebandAll;
+	private final boolean advertiseWaitForDone;
+
 	final @Nullable ProtocolVersion protocolVersion;
 	final String[] hideRefs;
 
@@ -206,6 +209,8 @@
 				"uploadpack", "allowsidebandall", false);
 		advertiseSidebandAll = rc.getBoolean("uploadpack",
 				"advertisesidebandall", false);
+		advertiseWaitForDone = rc.getBoolean("uploadpack",
+				"advertisewaitfordone", false);
 	}
 
 	/**
@@ -305,6 +310,14 @@
 	}
 
 	/**
+	 * @return true to advertise wait-for-done all to the clients
+	 * @since 5.13
+	 */
+	public boolean isAdvertiseWaitForDone() {
+		return advertiseWaitForDone;
+	}
+
+	/**
 	 * Get {@link org.eclipse.jgit.transport.RefFilter} respecting configured
 	 * hidden refs.
 	 *
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/transport/UploadPack.java b/org.eclipse.jgit/src/org/eclipse/jgit/transport/UploadPack.java
index 7f1ddaa..ecf1751 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/transport/UploadPack.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/transport/UploadPack.java
@@ -33,6 +33,7 @@
 import static org.eclipse.jgit.transport.GitProtocolConstants.OPTION_SIDE_BAND;
 import static org.eclipse.jgit.transport.GitProtocolConstants.OPTION_SIDE_BAND_64K;
 import static org.eclipse.jgit.transport.GitProtocolConstants.OPTION_THIN_PACK;
+import static org.eclipse.jgit.transport.GitProtocolConstants.OPTION_WAIT_FOR_DONE;
 import static org.eclipse.jgit.transport.GitProtocolConstants.VERSION_2_REQUEST;
 import static org.eclipse.jgit.util.RefMap.toRefMap;
 
@@ -1192,9 +1193,10 @@
 			walk.assumeShallow(req.getClientShallowCommits());
 
 		if (req.wasDoneReceived()) {
-			processHaveLines(req.getPeerHas(), ObjectId.zeroId(),
+			processHaveLines(
+					req.getPeerHas(), ObjectId.zeroId(),
 					new PacketLineOut(NullOutputStream.INSTANCE, false),
-					accumulator);
+					accumulator, req.wasWaitForDoneReceived() ? Option.WAIT_FOR_DONE : Option.NONE);
 		} else {
 			pckOut.writeString(
 					GitProtocolConstants.SECTION_ACKNOWLEDGMENTS + '\n');
@@ -1205,8 +1207,8 @@
 			}
 			processHaveLines(req.getPeerHas(), ObjectId.zeroId(),
 					new PacketLineOut(NullOutputStream.INSTANCE, false),
-					accumulator);
-			if (okToGiveUp()) {
+					accumulator, Option.NONE);
+			if (!req.wasWaitForDoneReceived() && okToGiveUp()) {
 				pckOut.writeString("ready\n"); //$NON-NLS-1$
 			} else if (commonBase.isEmpty()) {
 				pckOut.writeString("NAK\n"); //$NON-NLS-1$
@@ -1214,7 +1216,7 @@
 			sectionSent = true;
 		}
 
-		if (req.wasDoneReceived() || okToGiveUp()) {
+		if (req.wasDoneReceived() || (!req.wasWaitForDoneReceived() && okToGiveUp())) {
 			if (mayHaveShallow) {
 				if (sectionSent)
 					pckOut.writeDelim();
@@ -1312,6 +1314,9 @@
 						? OPTION_SIDEBAND_ALL + ' '
 						: "")
 				+ (cachedPackUriProvider != null ? "packfile-uris " : "")
+				+ (transferConfig.isAdvertiseWaitForDone()
+						? OPTION_WAIT_FOR_DONE + ' '
+						: "")
 				+ OPTION_SHALLOW);
 		caps.add(CAPABILITY_SERVER_OPTION);
 		return caps;
@@ -1656,7 +1661,7 @@
 			}
 
 			if (PacketLineIn.isEnd(line)) {
-				last = processHaveLines(peerHas, last, pckOut, accumulator);
+				last = processHaveLines(peerHas, last, pckOut, accumulator, Option.NONE);
 				if (commonBase.isEmpty() || multiAck != MultiAck.OFF)
 					pckOut.writeString("NAK\n"); //$NON-NLS-1$
 				if (noDone && sentReady) {
@@ -1671,7 +1676,7 @@
 				peerHas.add(ObjectId.fromString(line.substring(5)));
 				accumulator.haves++;
 			} else if (line.equals("done")) { //$NON-NLS-1$
-				last = processHaveLines(peerHas, last, pckOut, accumulator);
+				last = processHaveLines(peerHas, last, pckOut, accumulator, Option.NONE);
 
 				if (commonBase.isEmpty())
 					pckOut.writeString("NAK\n"); //$NON-NLS-1$
@@ -1687,8 +1692,14 @@
 		}
 	}
 
+	private enum Option {
+		WAIT_FOR_DONE,
+		NONE;
+	}
+
 	private ObjectId processHaveLines(List<ObjectId> peerHas, ObjectId last,
-			PacketLineOut out, PackStatistics.Accumulator accumulator)
+			PacketLineOut out, PackStatistics.Accumulator accumulator,
+			Option option)
 			throws IOException {
 		preUploadHook.onBeginNegotiateRound(this, wantIds, peerHas.size());
 		if (wantAll.isEmpty() && !wantIds.isEmpty())
@@ -1754,6 +1765,18 @@
 		// create a pack at this point, let the client know so it stops
 		// telling us about its history.
 		//
+		if (option != Option.WAIT_FOR_DONE) {
+			sentReady = shouldGiveUp(peerHas, out, missCnt);
+		}
+
+		preUploadHook.onEndNegotiateRound(this, wantAll, haveCnt, missCnt, sentReady);
+		peerHas.clear();
+		return last;
+	}
+
+	private boolean shouldGiveUp(List<ObjectId> peerHas, PacketLineOut out, int missCnt)
+			throws IOException {
+		boolean sentReady = false;
 		boolean didOkToGiveUp = false;
 		if (0 < missCnt) {
 			for (int i = peerHas.size() - 1; i >= 0; i--) {
@@ -1765,10 +1788,12 @@
 						case OFF:
 							break;
 						case CONTINUE:
-							out.writeString("ACK " + id.name() + " continue\n"); //$NON-NLS-1$ //$NON-NLS-2$
+							out.writeString(
+									"ACK " + id.name() + " continue\n"); //$NON-NLS-1$ //$NON-NLS-2$
 							break;
 						case DETAILED:
-							out.writeString("ACK " + id.name() + " ready\n"); //$NON-NLS-1$ //$NON-NLS-2$
+							out.writeString(
+									"ACK " + id.name() + " ready\n"); //$NON-NLS-1$ //$NON-NLS-2$
 							sentReady = true;
 							break;
 						}
@@ -1778,15 +1803,14 @@
 			}
 		}
 
-		if (multiAck == MultiAck.DETAILED && !didOkToGiveUp && okToGiveUp()) {
+		if (multiAck == MultiAck.DETAILED && !didOkToGiveUp
+				&& okToGiveUp()) {
 			ObjectId id = peerHas.get(peerHas.size() - 1);
 			out.writeString("ACK " + id.name() + " ready\n"); //$NON-NLS-1$ //$NON-NLS-2$
 			sentReady = true;
 		}
 
-		preUploadHook.onEndNegotiateRound(this, wantAll, haveCnt, missCnt, sentReady);
-		peerHas.clear();
-		return last;
+		return sentReady;
 	}
 
 	private void parseWants(PackStatistics.Accumulator accumulator) throws IOException {
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/util/Base85.java b/org.eclipse.jgit/src/org/eclipse/jgit/util/Base85.java
new file mode 100644
index 0000000..54b7cfc
--- /dev/null
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/util/Base85.java
@@ -0,0 +1,195 @@
+/*
+ * Copyright (C) 2021 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;
+
+import java.nio.charset.StandardCharsets;
+import java.text.MessageFormat;
+import java.util.Arrays;
+
+import org.eclipse.jgit.internal.JGitText;
+
+/**
+ * Base-85 encoder/decoder.
+ *
+ * @since 5.12
+ */
+public final class Base85 {
+
+	private static final byte[] ENCODE = ("0123456789" //$NON-NLS-1$
+			+ "ABCDEFGHIJKLMNOPQRSTUVWXYZ" //$NON-NLS-1$
+			+ "abcdefghijklmnopqrstuvwxyz" //$NON-NLS-1$
+			+ "!#$%&()*+-;<=>?@^_`{|}~") //$NON-NLS-1$
+					.getBytes(StandardCharsets.US_ASCII);
+
+	private static final int[] DECODE = new int[256];
+
+	static {
+		Arrays.fill(DECODE, -1);
+		for (int i = 0; i < ENCODE.length; i++) {
+			DECODE[ENCODE[i]] = i;
+		}
+	}
+
+	private Base85() {
+		// No instantiation
+	}
+
+	/**
+	 * Determines the length of the base-85 encoding for {@code rawLength}
+	 * bytes.
+	 *
+	 * @param rawLength
+	 *            number of bytes to encode
+	 * @return number of bytes needed for the base-85 encoding of
+	 *         {@code rawLength} bytes
+	 */
+	public static int encodedLength(int rawLength) {
+		return (rawLength + 3) / 4 * 5;
+	}
+
+	/**
+	 * Encodes the given {@code data} in Base-85.
+	 *
+	 * @param data
+	 *            to encode
+	 * @return encoded data
+	 */
+	public static byte[] encode(byte[] data) {
+		return encode(data, 0, data.length);
+	}
+
+	/**
+	 * Encodes {@code length} bytes of {@code data} in Base-85, beginning at the
+	 * {@code start} index.
+	 *
+	 * @param data
+	 *            to encode
+	 * @param start
+	 *            index of the first byte to encode
+	 * @param length
+	 *            number of bytes to encode
+	 * @return encoded data
+	 */
+	public static byte[] encode(byte[] data, int start, int length) {
+		byte[] result = new byte[encodedLength(length)];
+		int end = start + length;
+		int in = start;
+		int out = 0;
+		while (in < end) {
+			// Accumulate remaining bytes MSB first as a 32bit value
+			long accumulator = ((long) (data[in++] & 0xFF)) << 24;
+			if (in < end) {
+				accumulator |= (data[in++] & 0xFF) << 16;
+				if (in < end) {
+					accumulator |= (data[in++] & 0xFF) << 8;
+					if (in < end) {
+						accumulator |= (data[in++] & 0xFF);
+					}
+				}
+			}
+			// Write the 32bit value in base-85 encoding, also MSB first
+			for (int i = 4; i >= 0; i--) {
+				result[out + i] = ENCODE[(int) (accumulator % 85)];
+				accumulator /= 85;
+			}
+			out += 5;
+		}
+		return result;
+	}
+
+	/**
+	 * Decodes the Base-85 {@code encoded} data into a byte array of
+	 * {@code expectedSize} bytes.
+	 *
+	 * @param encoded
+	 *            Base-85 encoded data
+	 * @param expectedSize
+	 *            of the result
+	 * @return the decoded bytes
+	 * @throws IllegalArgumentException
+	 *             if expectedSize doesn't match, the encoded data has a length
+	 *             that is not a multiple of 5, or there are invalid characters
+	 *             in the encoded data
+	 */
+	public static byte[] decode(byte[] encoded, int expectedSize) {
+		return decode(encoded, 0, encoded.length, expectedSize);
+	}
+
+	/**
+	 * Decodes {@code length} bytes of Base-85 {@code encoded} data, beginning
+	 * at the {@code start} index, into a byte array of {@code expectedSize}
+	 * bytes.
+	 *
+	 * @param encoded
+	 *            Base-85 encoded data
+	 * @param start
+	 *            index at which the data to decode starts in {@code encoded}
+	 * @param length
+	 *            of the Base-85 encoded data
+	 * @param expectedSize
+	 *            of the result
+	 * @return the decoded bytes
+	 * @throws IllegalArgumentException
+	 *             if expectedSize doesn't match, {@code length} is not a
+	 *             multiple of 5, or there are invalid characters in the encoded
+	 *             data
+	 */
+	public static byte[] decode(byte[] encoded, int start, int length,
+			int expectedSize) {
+		if (length % 5 != 0) {
+			throw new IllegalArgumentException(JGitText.get().base85length);
+		}
+		byte[] result = new byte[expectedSize];
+		int end = start + length;
+		int in = start;
+		int out = 0;
+		while (in < end && out < expectedSize) {
+			// Accumulate 5 bytes, "MSB" first
+			long accumulator = 0;
+			for (int i = 4; i >= 0; i--) {
+				int val = DECODE[encoded[in++] & 0xFF];
+				if (val < 0) {
+					throw new IllegalArgumentException(MessageFormat.format(
+							JGitText.get().base85invalidChar,
+							Integer.toHexString(encoded[in - 1] & 0xFF)));
+				}
+				accumulator = accumulator * 85 + val;
+			}
+			if (accumulator > 0xFFFF_FFFFL) {
+				throw new IllegalArgumentException(
+						MessageFormat.format(JGitText.get().base85overflow,
+								Long.toHexString(accumulator)));
+			}
+			// Write remaining bytes, MSB first
+			result[out++] = (byte) (accumulator >>> 24);
+			if (out < expectedSize) {
+				result[out++] = (byte) (accumulator >>> 16);
+				if (out < expectedSize) {
+					result[out++] = (byte) (accumulator >>> 8);
+					if (out < expectedSize) {
+						result[out++] = (byte) accumulator;
+					}
+				}
+			}
+		}
+		// Should have exhausted 'in' and filled 'out' completely
+		if (in < end) {
+			throw new IllegalArgumentException(
+					MessageFormat.format(JGitText.get().base85tooLong,
+							Integer.valueOf(expectedSize)));
+		}
+		if (out < expectedSize) {
+			throw new IllegalArgumentException(
+					MessageFormat.format(JGitText.get().base85tooShort,
+							Integer.valueOf(expectedSize)));
+		}
+		return result;
+	}
+}
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/util/io/BinaryDeltaInputStream.java b/org.eclipse.jgit/src/org/eclipse/jgit/util/io/BinaryDeltaInputStream.java
new file mode 100644
index 0000000..9eceeb8
--- /dev/null
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/util/io/BinaryDeltaInputStream.java
@@ -0,0 +1,211 @@
+/*
+ * Copyright (C) 2021 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 java.io.EOFException;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.StreamCorruptedException;
+import java.text.MessageFormat;
+
+import org.eclipse.jgit.internal.JGitText;
+
+/**
+ * An {@link InputStream} that applies a binary delta to a base on the fly.
+ * <p>
+ * Delta application to a base needs random access to the base data. The delta
+ * is expressed as a sequence of copy and insert instructions. A copy
+ * instruction has the form "COPY fromOffset length" and says "copy length bytes
+ * from the base, starting at offset fromOffset, to the result". An insert
+ * instruction has the form "INSERT length" followed by length bytes and says
+ * "copy the next length bytes from the delta to the result".
+ * </p>
+ * <p>
+ * These instructions are generated using a content-defined chunking algorithm
+ * (currently C git uses the standard Rabin variant; but there are others that
+ * could be used) that identifies equal chunks. It is entirely possible that a
+ * later copy instruction has a fromOffset that is before the fromOffset of an
+ * earlier copy instruction.
+ * </p>
+ * <p>
+ * This makes it impossible to stream the base.
+ * </p>
+ * <p>
+ * JGit is limited to 2GB maximum size for the base since array indices are
+ * signed 32bit values.
+ *
+ * @since 5.12
+ */
+public class BinaryDeltaInputStream extends InputStream {
+
+	private final byte[] base;
+
+	private final InputStream delta;
+
+	private long resultLength;
+
+	private long toDeliver = -1;
+
+	private int fromBase;
+
+	private int fromDelta;
+
+	private int baseOffset = -1;
+
+	/**
+	 * Creates a new {@link BinaryDeltaInputStream} that applies {@code delta}
+	 * to {@code base}.
+	 *
+	 * @param base
+	 *            data to apply the delta to
+	 * @param delta
+	 *            {@link InputStream} delivering the delta to apply
+	 */
+	public BinaryDeltaInputStream(byte[] base, InputStream delta) {
+		this.base = base;
+		this.delta = delta;
+	}
+
+	@Override
+	public int read() throws IOException {
+		int b = readNext();
+		if (b >= 0) {
+			toDeliver--;
+		}
+		return b;
+	}
+
+	@Override
+	public int read(byte[] b, int off, int len) throws IOException {
+		return super.read(b, off, len);
+	}
+
+	private void initialize() throws IOException {
+		long baseSize = readVarInt(delta);
+		if (baseSize > Integer.MAX_VALUE || baseSize < 0
+				|| (int) baseSize != base.length) {
+			throw new IOException(MessageFormat.format(
+					JGitText.get().binaryDeltaBaseLengthMismatch,
+					Integer.valueOf(base.length), Long.valueOf(baseSize)));
+		}
+		resultLength = readVarInt(delta);
+		if (resultLength < 0) {
+			throw new StreamCorruptedException(
+					JGitText.get().binaryDeltaInvalidResultLength);
+		}
+		toDeliver = resultLength;
+		baseOffset = 0;
+	}
+
+	private int readNext() throws IOException {
+		if (baseOffset < 0) {
+			initialize();
+		}
+		if (fromBase > 0) {
+			fromBase--;
+			return base[baseOffset++] & 0xFF;
+		} else if (fromDelta > 0) {
+			fromDelta--;
+			return delta.read();
+		}
+		int command = delta.read();
+		if (command < 0) {
+			return -1;
+		}
+		if ((command & 0x80) != 0) {
+			// Decode offset and length to read from base
+			long copyOffset = 0;
+			for (int i = 1, shift = 0; i < 0x10; i *= 2, shift += 8) {
+				if ((command & i) != 0) {
+					copyOffset |= ((long) next(delta)) << shift;
+				}
+			}
+			int copySize = 0;
+			for (int i = 0x10, shift = 0; i < 0x80; i *= 2, shift += 8) {
+				if ((command & i) != 0) {
+					copySize |= next(delta) << shift;
+				}
+			}
+			if (copySize == 0) {
+				copySize = 0x10000;
+			}
+			if (copyOffset > base.length - copySize) {
+				throw new StreamCorruptedException(MessageFormat.format(
+						JGitText.get().binaryDeltaInvalidOffset,
+						Long.valueOf(copyOffset), Integer.valueOf(copySize)));
+			}
+			baseOffset = (int) copyOffset;
+			fromBase = copySize;
+			return readNext();
+		} else if (command != 0) {
+			// The next 'command' bytes come from the delta
+			fromDelta = command - 1;
+			return delta.read();
+		} else {
+			// Zero is reserved
+			throw new StreamCorruptedException(
+					JGitText.get().unsupportedCommand0);
+		}
+	}
+
+	private int next(InputStream in) throws IOException {
+		int b = in.read();
+		if (b < 0) {
+			throw new EOFException();
+		}
+		return b;
+	}
+
+	private long readVarInt(InputStream in) throws IOException {
+		long val = 0;
+		int shift = 0;
+		int b;
+		do {
+			b = next(in);
+			val |= ((long) (b & 0x7f)) << shift;
+			shift += 7;
+		} while ((b & 0x80) != 0);
+		return val;
+	}
+
+	/**
+	 * Tells the expected size of the final result.
+	 *
+	 * @return the size
+	 * @throws IOException
+	 *             if the size cannot be determined from {@code delta}
+	 */
+	public long getExpectedResultSize() throws IOException {
+		if (baseOffset < 0) {
+			initialize();
+		}
+		return resultLength;
+	}
+
+	/**
+	 * Tells whether the delta has been fully consumed, and the expected number
+	 * of bytes for the combined result have been read from this
+	 * {@link BinaryDeltaInputStream}.
+	 *
+	 * @return whether delta application was successful
+	 */
+	public boolean isFullyConsumed() {
+		try {
+			return toDeliver == 0 && delta.read() < 0;
+		} catch (IOException e) {
+			return toDeliver == 0;
+		}
+	}
+
+	@Override
+	public void close() throws IOException {
+		delta.close();
+	}
+}
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/util/io/BinaryHunkInputStream.java b/org.eclipse.jgit/src/org/eclipse/jgit/util/io/BinaryHunkInputStream.java
new file mode 100644
index 0000000..4f940d7
--- /dev/null
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/util/io/BinaryHunkInputStream.java
@@ -0,0 +1,118 @@
+/*
+ * Copyright (C) 2021 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 java.io.EOFException;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.StreamCorruptedException;
+import java.text.MessageFormat;
+
+import org.eclipse.jgit.internal.JGitText;
+import org.eclipse.jgit.util.Base85;
+
+/**
+ * A stream that decodes git binary patch data on the fly.
+ *
+ * @since 5.12
+ */
+public class BinaryHunkInputStream extends InputStream {
+
+	private final InputStream in;
+
+	private int lineNumber;
+
+	private byte[] buffer;
+
+	private int pos = 0;
+
+	/**
+	 * Creates a new {@link BinaryHunkInputStream}.
+	 *
+	 * @param in
+	 *            {@link InputStream} to read the base-85 encoded patch data
+	 *            from
+	 */
+	public BinaryHunkInputStream(InputStream in) {
+		this.in = in;
+	}
+
+	@Override
+	public int read() throws IOException {
+		if (pos < 0) {
+			return -1;
+		}
+		if (buffer == null || pos == buffer.length) {
+			fillBuffer();
+		}
+		if (pos >= 0) {
+			return buffer[pos++] & 0xFF;
+		}
+		return -1;
+	}
+
+	@Override
+	public int read(byte[] b, int off, int len) throws IOException {
+		return super.read(b, off, len);
+	}
+
+	@Override
+	public void close() throws IOException {
+		in.close();
+		buffer = null;
+	}
+
+	private void fillBuffer() throws IOException {
+		int length = in.read();
+		if (length < 0) {
+			pos = length;
+			buffer = null;
+			return;
+		}
+		lineNumber++;
+		// Length is encoded with characters, A..Z for 1..26 and a..z for 27..52
+		if ('A' <= length && length <= 'Z') {
+			length = length - 'A' + 1;
+		} else if ('a' <= length && length <= 'z') {
+			length = length - 'a' + 27;
+		} else {
+			throw new StreamCorruptedException(MessageFormat.format(
+					JGitText.get().binaryHunkInvalidLength,
+					Integer.valueOf(lineNumber), Integer.toHexString(length)));
+		}
+		byte[] encoded = new byte[Base85.encodedLength(length)];
+		for (int i = 0; i < encoded.length; i++) {
+			int b = in.read();
+			if (b < 0 || b == '\n') {
+				throw new EOFException(MessageFormat.format(
+						JGitText.get().binaryHunkInvalidLength,
+						Integer.valueOf(lineNumber)));
+			}
+			encoded[i] = (byte) b;
+		}
+		// Must be followed by a newline; tolerate EOF.
+		int b = in.read();
+		if (b >= 0 && b != '\n') {
+			throw new StreamCorruptedException(MessageFormat.format(
+					JGitText.get().binaryHunkMissingNewline,
+					Integer.valueOf(lineNumber)));
+		}
+		try {
+			buffer = Base85.decode(encoded, length);
+		} catch (IllegalArgumentException e) {
+			StreamCorruptedException ex = new StreamCorruptedException(
+					MessageFormat.format(JGitText.get().binaryHunkDecodeError,
+							Integer.valueOf(lineNumber)));
+			ex.initCause(e);
+			throw ex;
+		}
+		pos = 0;
+	}
+}
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/util/io/BinaryHunkOutputStream.java b/org.eclipse.jgit/src/org/eclipse/jgit/util/io/BinaryHunkOutputStream.java
new file mode 100644
index 0000000..30551c0
--- /dev/null
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/util/io/BinaryHunkOutputStream.java
@@ -0,0 +1,116 @@
+/*
+ * Copyright (C) 2021 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 java.io.IOException;
+import java.io.OutputStream;
+
+import org.eclipse.jgit.util.Base85;
+
+/**
+ * An {@link OutputStream} that encodes data for a git binary patch.
+ *
+ * @since 5.12
+ */
+public class BinaryHunkOutputStream extends OutputStream {
+
+	private static final int MAX_BYTES = 52;
+
+	private final OutputStream out;
+
+	private final byte[] buffer = new byte[MAX_BYTES];
+
+	private int pos;
+
+	/**
+	 * Creates a new {@link BinaryHunkOutputStream}.
+	 *
+	 * @param out
+	 *            {@link OutputStream} to write the encoded data to
+	 */
+	public BinaryHunkOutputStream(OutputStream out) {
+		this.out = out;
+	}
+
+	/**
+	 * Flushes and closes this stream, and closes the underlying
+	 * {@link OutputStream}.
+	 */
+	@Override
+	public void close() throws IOException {
+		flush();
+		out.close();
+	}
+
+	/**
+	 * Writes any buffered output as a binary patch line to the underlying
+	 * {@link OutputStream} and flushes that stream, too.
+	 */
+	@Override
+	public void flush() throws IOException {
+		if (pos > 0) {
+			encode(buffer, 0, pos);
+			pos = 0;
+		}
+		out.flush();
+	}
+
+	@Override
+	public void write(int b) throws IOException {
+		buffer[pos++] = (byte) b;
+		if (pos == buffer.length) {
+			encode(buffer, 0, pos);
+			pos = 0;
+		}
+	}
+
+	@Override
+	public void write(byte[] b, int off, int len) throws IOException {
+		if (len == 0) {
+			return;
+		}
+		int toCopy = len;
+		int in = off;
+		if (pos > 0) {
+			// Fill the buffer
+			int chunk = Math.min(toCopy, buffer.length - pos);
+			System.arraycopy(b, in, buffer, pos, chunk);
+			in += chunk;
+			pos += chunk;
+			toCopy -= chunk;
+			if (pos == buffer.length) {
+				encode(buffer, 0, pos);
+				pos = 0;
+			}
+			if (toCopy == 0) {
+				return;
+			}
+		}
+		while (toCopy >= MAX_BYTES) {
+			encode(b, in, MAX_BYTES);
+			toCopy -= MAX_BYTES;
+			in += MAX_BYTES;
+		}
+		if (toCopy > 0) {
+			System.arraycopy(b, in, buffer, 0, toCopy);
+			pos = toCopy;
+		}
+	}
+
+	private void encode(byte[] data, int off, int length) throws IOException {
+		if (length <= 26) {
+			out.write('A' + length - 1);
+		} else {
+			out.write('a' + length - 27);
+		}
+		out.write(Base85.encode(data, off, length));
+		out.write('\n');
+	}
+}