Merge branch 'stable-6.4'

* stable-6.4:
  Shortcut during git fetch for avoiding looping through all local refs
  FetchCommand: fix fetchSubmodules to work on a Ref to a blob
  Silence API warnings introduced by I466dcde6
  Allow the exclusions of refs prefixes from bitmap
  PackWriterBitmapPreparer: do not include annotated tags in bitmap
  BatchingProgressMonitor: avoid int overflow when computing percentage
  Speedup GC listing objects referenced from reflogs
  FileSnapshotTest: Add more MISSING_FILE coverage

Change-Id: Id0ebfbd85eb815716383b9495eb7dd1f54cf4d74
diff --git a/WORKSPACE b/WORKSPACE
index ceb0e48..12332fe 100644
--- a/WORKSPACE
+++ b/WORKSPACE
@@ -80,14 +80,14 @@
 
 maven_jar(
     name = "httpclient",
-    artifact = "org.apache.httpcomponents:httpclient:4.5.13",
-    sha1 = "e5f6cae5ca7ecaac1ec2827a9e2d65ae2869cada",
+    artifact = "org.apache.httpcomponents:httpclient:4.5.14",
+    sha1 = "1194890e6f56ec29177673f2f12d0b8e627dec98",
 )
 
 maven_jar(
     name = "httpcore",
-    artifact = "org.apache.httpcomponents:httpcore:4.4.15",
-    sha1 = "7f2e0c573eaa7a74bac2e89b359e1f73d92a0a1d",
+    artifact = "org.apache.httpcomponents:httpcore:4.4.16",
+    sha1 = "51cf043c87253c9f58b539c9f7e44c8894223850",
 )
 
 SSHD_VERS = "2.9.2"
@@ -148,8 +148,8 @@
 
 maven_jar(
     name = "commons-compress",
-    artifact = "org.apache.commons:commons-compress:1.21",
-    sha1 = "4ec95b60d4e86b5c95a0e919cb172a0af98011ef",
+    artifact = "org.apache.commons:commons-compress:1.22",
+    sha1 = "691a8b4e6cf4248c3bc72c8b719337d5cb7359fa",
 )
 
 maven_jar(
@@ -210,59 +210,59 @@
 
 maven_jar(
     name = "gson",
-    artifact = "com.google.code.gson:gson:2.9.1",
-    sha1 = "02cc2131b98ebfb04e2b2c7dfb84431f4045096b",
+    artifact = "com.google.code.gson:gson:2.10",
+    sha1 = "dd9b193aef96e973d5a11ab13cd17430c2e4306b",
 )
 
-JETTY_VER = "10.0.6"
+JETTY_VER = "10.0.13"
 
 maven_jar(
     name = "jetty-servlet",
     artifact = "org.eclipse.jetty:jetty-servlet:" + JETTY_VER,
-    sha1 = "482165726bf54dd10ee7e2aeb4ae9481eee0c878",
-    src_sha1 = "8a8173a0bc6c0d215fc9fb9ba5fd50bae1690f9c",
+    sha1 = "a6ee6e48e98377863aa80f41ea979df678b17966",
+    src_sha1 = "5a01db2e1bae632879e9b90e845ae946059b46c9",
 )
 
 maven_jar(
     name = "jetty-security",
     artifact = "org.eclipse.jetty:jetty-security:" + JETTY_VER,
-    sha1 = "513f44ed9636ca5e0adefa0c0b81511065dfddd2",
-    src_sha1 = "2e7eb2edbf1592e15b338096651e379fea860859",
+    sha1 = "6d4c88cf068709d9f2499ca417b23f3f835b0c43",
+    src_sha1 = "887e7a7c457e149df9c23db89c7d2425c4444ccf",
 )
 
 maven_jar(
     name = "jetty-server",
     artifact = "org.eclipse.jetty:jetty-server:" + JETTY_VER,
-    sha1 = "125ee07e4d8182a6afca00d543f6a4dcc84f2678",
-    src_sha1 = "5c0789872ec6743ae893131ae81262aaefc87fe6",
+    sha1 = "f472705ebfce7e9a5b6cb8cbb84e73767e35fad7",
+    src_sha1 = "2689f8e616282b19f34d43f89800f67490ae65fa",
 )
 
 maven_jar(
     name = "jetty-http",
     artifact = "org.eclipse.jetty:jetty-http:" + JETTY_VER,
-    sha1 = "4c8eed25d577002a6c0f9f3ef340eb581390f696",
-    src_sha1 = "ac7214d6202ee0cbc4bdbcf90c7906ca716e84e5",
+    sha1 = "b3dc7ec1da090106031dd36cb1e2637a7fb6ce1c",
+    src_sha1 = "1bbb620e34218584bfdf11542e2b46781437335d",
 )
 
 maven_jar(
     name = "jetty-io",
     artifact = "org.eclipse.jetty:jetty-io:" + JETTY_VER,
-    sha1 = "1ab82ae5dfdbb07f0ffa07f28274fdf30e3e96ee",
-    src_sha1 = "c59082f3a09c024fafc281f432b67432d398b8c0",
+    sha1 = "be9d7f226022b02e174a83d597d088e22e12d365",
+    src_sha1 = "48f5b1ce8570a9d560e62c39170e754288a1d290",
 )
 
 maven_jar(
     name = "jetty-util",
     artifact = "org.eclipse.jetty:jetty-util:" + JETTY_VER,
-    sha1 = "4e2935749ea1c9fcabba61a857f8283c7f5f9885",
-    src_sha1 = "6baba651899c044e14ba37d43934950670d2aa4e",
+    sha1 = "35caf3afb3cca22ca4bc36908bf82e6d973c5be4",
+    src_sha1 = "9d7c19deb76c0247ad0d25afce6e4c0d681d2af0",
 )
 
 maven_jar(
     name = "jetty-util-ajax",
     artifact = "org.eclipse.jetty:jetty-util-ajax:" + JETTY_VER,
-    sha1 = "a801d4b5f5e906f134713ae82fd1ea10a15902c6",
-    src_sha1 = "f35f5525a5d30dc1237b85457d758d578e3ce8d0",
+    sha1 = "bc52bc38cb76b5c260ec109661ebcb02393d83a7",
+    src_sha1 = "b229198672cfb765ce7571e5e0e855e01170f881",
 )
 
 BOUNCYCASTLE_VER = "1.72"
diff --git a/org.eclipse.jgit.ant.test/META-INF/MANIFEST.MF b/org.eclipse.jgit.ant.test/META-INF/MANIFEST.MF
index 75d80a2..4d81f14 100644
--- a/org.eclipse.jgit.ant.test/META-INF/MANIFEST.MF
+++ b/org.eclipse.jgit.ant.test/META-INF/MANIFEST.MF
@@ -5,13 +5,13 @@
 Automatic-Module-Name: org.eclipse.jgit.ant.test
 Bundle-SymbolicName: org.eclipse.jgit.ant.test
 Bundle-Vendor: %Bundle-Vendor
-Bundle-Version: 6.4.1.qualifier
+Bundle-Version: 6.5.0.qualifier
 Bundle-ActivationPolicy: lazy
 Bundle-RequiredExecutionEnvironment: JavaSE-11
 Import-Package: org.apache.tools.ant,
- org.eclipse.jgit.ant.tasks;version="[6.4.1,6.5.0)",
- org.eclipse.jgit.junit;version="[6.4.1,6.5.0)",
- org.eclipse.jgit.lib;version="[6.4.1,6.5.0)",
- org.eclipse.jgit.util;version="[6.4.1,6.5.0)",
+ org.eclipse.jgit.ant.tasks;version="[6.5.0,6.6.0)",
+ org.eclipse.jgit.junit;version="[6.5.0,6.6.0)",
+ org.eclipse.jgit.lib;version="[6.5.0,6.6.0)",
+ org.eclipse.jgit.util;version="[6.5.0,6.6.0)",
  org.hamcrest.core;version="[1.1.0,3.0.0)",
  org.junit;version="[4.13,5.0.0)"
diff --git a/org.eclipse.jgit.ant.test/pom.xml b/org.eclipse.jgit.ant.test/pom.xml
index ac65936..95f7a75 100644
--- a/org.eclipse.jgit.ant.test/pom.xml
+++ b/org.eclipse.jgit.ant.test/pom.xml
@@ -17,7 +17,7 @@
   <parent>
     <groupId>org.eclipse.jgit</groupId>
     <artifactId>org.eclipse.jgit-parent</artifactId>
-    <version>6.4.1-SNAPSHOT</version>
+    <version>6.5.0-SNAPSHOT</version>
   </parent>
 
   <artifactId>org.eclipse.jgit.ant.test</artifactId>
diff --git a/org.eclipse.jgit.ant/META-INF/MANIFEST.MF b/org.eclipse.jgit.ant/META-INF/MANIFEST.MF
index 0bebf8e..5d637ac 100644
--- a/org.eclipse.jgit.ant/META-INF/MANIFEST.MF
+++ b/org.eclipse.jgit.ant/META-INF/MANIFEST.MF
@@ -3,13 +3,13 @@
 Bundle-Name: %Bundle-Name
 Automatic-Module-Name: org.eclipse.jgit.ant
 Bundle-SymbolicName: org.eclipse.jgit.ant
-Bundle-Version: 6.4.1.qualifier
+Bundle-Version: 6.5.0.qualifier
 Bundle-RequiredExecutionEnvironment: JavaSE-11
 Import-Package: org.apache.tools.ant,
-  org.eclipse.jgit.storage.file;version="[6.4.1,6.5.0)"
+  org.eclipse.jgit.storage.file;version="[6.5.0,6.6.0)"
 Bundle-Localization: plugin
 Bundle-Vendor: %Bundle-Vendor
-Export-Package: org.eclipse.jgit.ant;version="6.4.1",
- org.eclipse.jgit.ant.tasks;version="6.4.1";
+Export-Package: org.eclipse.jgit.ant;version="6.5.0",
+ org.eclipse.jgit.ant.tasks;version="6.5.0";
   uses:="org.apache.tools.ant,
    org.apache.tools.ant.types"
diff --git a/org.eclipse.jgit.ant/META-INF/SOURCE-MANIFEST.MF b/org.eclipse.jgit.ant/META-INF/SOURCE-MANIFEST.MF
index 1d0b760..d64367f 100644
--- a/org.eclipse.jgit.ant/META-INF/SOURCE-MANIFEST.MF
+++ b/org.eclipse.jgit.ant/META-INF/SOURCE-MANIFEST.MF
@@ -3,5 +3,5 @@
 Bundle-Name: org.eclipse.jgit.ant - Sources
 Bundle-SymbolicName: org.eclipse.jgit.ant.source
 Bundle-Vendor: Eclipse.org - JGit
-Bundle-Version: 6.4.1.qualifier
-Eclipse-SourceBundle: org.eclipse.jgit.ant;version="6.4.1.qualifier";roots="."
+Bundle-Version: 6.5.0.qualifier
+Eclipse-SourceBundle: org.eclipse.jgit.ant;version="6.5.0.qualifier";roots="."
diff --git a/org.eclipse.jgit.ant/pom.xml b/org.eclipse.jgit.ant/pom.xml
index 8110b0f..dca0a7f 100644
--- a/org.eclipse.jgit.ant/pom.xml
+++ b/org.eclipse.jgit.ant/pom.xml
@@ -15,7 +15,7 @@
   <parent>
     <groupId>org.eclipse.jgit</groupId>
     <artifactId>org.eclipse.jgit-parent</artifactId>
-    <version>6.4.1-SNAPSHOT</version>
+    <version>6.5.0-SNAPSHOT</version>
   </parent>
 
   <artifactId>org.eclipse.jgit.ant</artifactId>
diff --git a/org.eclipse.jgit.archive/META-INF/MANIFEST.MF b/org.eclipse.jgit.archive/META-INF/MANIFEST.MF
index d186e7b..1d01660 100644
--- a/org.eclipse.jgit.archive/META-INF/MANIFEST.MF
+++ b/org.eclipse.jgit.archive/META-INF/MANIFEST.MF
@@ -3,7 +3,7 @@
 Bundle-Name: %Bundle-Name
 Automatic-Module-Name: org.eclipse.jgit.archive
 Bundle-SymbolicName: org.eclipse.jgit.archive
-Bundle-Version: 6.4.1.qualifier
+Bundle-Version: 6.5.0.qualifier
 Bundle-Vendor: %Bundle-Vendor
 Bundle-Localization: plugin
 Bundle-RequiredExecutionEnvironment: JavaSE-11
@@ -13,17 +13,17 @@
  org.apache.commons.compress.compressors.bzip2;version="[1.4,2.0)",
  org.apache.commons.compress.compressors.gzip;version="[1.4,2.0)",
  org.apache.commons.compress.compressors.xz;version="[1.4,2.0)",
- org.eclipse.jgit.api;version="[6.4.1,6.5.0)",
- org.eclipse.jgit.lib;version="[6.4.1,6.5.0)",
- org.eclipse.jgit.nls;version="[6.4.1,6.5.0)",
- org.eclipse.jgit.revwalk;version="[6.4.1,6.5.0)",
- org.eclipse.jgit.util;version="[6.4.1,6.5.0)",
+ org.eclipse.jgit.api;version="[6.5.0,6.6.0)",
+ org.eclipse.jgit.lib;version="[6.5.0,6.6.0)",
+ org.eclipse.jgit.nls;version="[6.5.0,6.6.0)",
+ org.eclipse.jgit.revwalk;version="[6.5.0,6.6.0)",
+ org.eclipse.jgit.util;version="[6.5.0,6.6.0)",
  org.osgi.framework;version="[1.3.0,2.0.0)"
 Bundle-ActivationPolicy: lazy
 Bundle-Activator: org.eclipse.jgit.archive.FormatActivator
-Export-Package: org.eclipse.jgit.archive;version="6.4.1";
+Export-Package: org.eclipse.jgit.archive;version="6.5.0";
   uses:="org.eclipse.jgit.lib,
    org.eclipse.jgit.api,
    org.apache.commons.compress.archivers,
    org.osgi.framework",
- org.eclipse.jgit.archive.internal;version="6.4.1";x-internal:=true
+ org.eclipse.jgit.archive.internal;version="6.5.0";x-internal:=true
diff --git a/org.eclipse.jgit.archive/META-INF/SOURCE-MANIFEST.MF b/org.eclipse.jgit.archive/META-INF/SOURCE-MANIFEST.MF
index 590b30b..d4c3290 100644
--- a/org.eclipse.jgit.archive/META-INF/SOURCE-MANIFEST.MF
+++ b/org.eclipse.jgit.archive/META-INF/SOURCE-MANIFEST.MF
@@ -3,5 +3,5 @@
 Bundle-Name: org.eclipse.jgit.archive - Sources
 Bundle-SymbolicName: org.eclipse.jgit.archive.source
 Bundle-Vendor: Eclipse.org - JGit
-Bundle-Version: 6.4.1.qualifier
-Eclipse-SourceBundle: org.eclipse.jgit.archive;version="6.4.1.qualifier";roots="."
+Bundle-Version: 6.5.0.qualifier
+Eclipse-SourceBundle: org.eclipse.jgit.archive;version="6.5.0.qualifier";roots="."
diff --git a/org.eclipse.jgit.archive/pom.xml b/org.eclipse.jgit.archive/pom.xml
index 4a7265d..f3f5ab2 100644
--- a/org.eclipse.jgit.archive/pom.xml
+++ b/org.eclipse.jgit.archive/pom.xml
@@ -17,7 +17,7 @@
   <parent>
     <groupId>org.eclipse.jgit</groupId>
     <artifactId>org.eclipse.jgit-parent</artifactId>
-    <version>6.4.1-SNAPSHOT</version>
+    <version>6.5.0-SNAPSHOT</version>
   </parent>
 
   <artifactId>org.eclipse.jgit.archive</artifactId>
diff --git a/org.eclipse.jgit.benchmarks/pom.xml b/org.eclipse.jgit.benchmarks/pom.xml
index 3998b65..f7ef238 100644
--- a/org.eclipse.jgit.benchmarks/pom.xml
+++ b/org.eclipse.jgit.benchmarks/pom.xml
@@ -14,7 +14,7 @@
   <modelVersion>4.0.0</modelVersion>
 
   <groupId>org.eclipse.jgit</groupId>
-  <version>6.4.1-SNAPSHOT</version>
+  <version>6.5.0-SNAPSHOT</version>
   <artifactId>org.eclipse.jgit.benchmarks</artifactId>
   <packaging>jar</packaging>
 
@@ -56,7 +56,7 @@
       <plugin>
         <groupId>org.apache.maven.plugins</groupId>
         <artifactId>maven-enforcer-plugin</artifactId>
-        <version>3.0.0-M3</version>
+        <version>3.1.0</version>
         <executions>
           <execution>
             <id>enforce-maven</id>
@@ -76,7 +76,7 @@
       <plugin>
         <groupId>org.apache.maven.plugins</groupId>
         <artifactId>maven-compiler-plugin</artifactId>
-        <version>3.8.1</version>
+        <version>3.10.1</version>
         <configuration>
           <encoding>UTF-8</encoding>
           <release>${java.version}</release>
@@ -113,7 +113,7 @@
       <plugin>
         <groupId>org.apache.maven.plugins</groupId>
         <artifactId>maven-shade-plugin</artifactId>
-        <version>3.2.4</version>
+        <version>3.4.1</version>
         <executions>
           <execution>
             <phase>package</phase>
@@ -175,7 +175,7 @@
         <plugin>
           <groupId>org.apache.maven.plugins</groupId>
           <artifactId>maven-site-plugin</artifactId>
-          <version>3.9.1</version>
+          <version>4.0.0-M4</version>
           <dependencies>
             <dependency><!-- add support for ssh/scp -->
               <groupId>org.apache.maven.wagon</groupId>
@@ -187,17 +187,17 @@
         <plugin>
           <groupId>org.apache.maven.plugins</groupId>
           <artifactId>maven-surefire-report-plugin</artifactId>
-          <version>3.0.0-M5</version>
+          <version>3.0.0-M8</version>
         </plugin>
         <plugin>
           <groupId>org.apache.maven.plugins</groupId>
           <artifactId>maven-jxr-plugin</artifactId>
-          <version>3.1.1</version>
+          <version>3.3.0</version>
         </plugin>
         <plugin>
           <groupId>org.apache.maven.plugins</groupId>
           <artifactId>maven-project-info-reports-plugin</artifactId>
-          <version>3.1.1</version>
+          <version>3.4.2</version>
         </plugin>
       </plugins>
     </pluginManagement>
diff --git a/org.eclipse.jgit.coverage/pom.xml b/org.eclipse.jgit.coverage/pom.xml
index 7518dd9..797064a 100644
--- a/org.eclipse.jgit.coverage/pom.xml
+++ b/org.eclipse.jgit.coverage/pom.xml
@@ -14,7 +14,7 @@
   <parent>
     <groupId>org.eclipse.jgit</groupId>
     <artifactId>org.eclipse.jgit-parent</artifactId>
-    <version>6.4.1-SNAPSHOT</version>
+    <version>6.5.0-SNAPSHOT</version>
   </parent>
   <modelVersion>4.0.0</modelVersion>
 
@@ -27,88 +27,88 @@
     <dependency>
       <groupId>org.eclipse.jgit</groupId>
       <artifactId>org.eclipse.jgit</artifactId>
-      <version>6.4.1-SNAPSHOT</version>
+      <version>6.5.0-SNAPSHOT</version>
     </dependency>
     <dependency>
       <groupId>org.eclipse.jgit</groupId>
       <artifactId>org.eclipse.jgit.ant</artifactId>
-      <version>6.4.1-SNAPSHOT</version>
+      <version>6.5.0-SNAPSHOT</version>
     </dependency>
     <dependency>
       <groupId>org.eclipse.jgit</groupId>
       <artifactId>org.eclipse.jgit.archive</artifactId>
-      <version>6.4.1-SNAPSHOT</version>
+      <version>6.5.0-SNAPSHOT</version>
     </dependency>
     <dependency>
       <groupId>org.eclipse.jgit</groupId>
       <artifactId>org.eclipse.jgit.http.apache</artifactId>
-      <version>6.4.1-SNAPSHOT</version>
+      <version>6.5.0-SNAPSHOT</version>
     </dependency>
     <dependency>
       <groupId>org.eclipse.jgit</groupId>
       <artifactId>org.eclipse.jgit.http.server</artifactId>
-      <version>6.4.1-SNAPSHOT</version>
+      <version>6.5.0-SNAPSHOT</version>
     </dependency>
     <dependency>
       <groupId>org.eclipse.jgit</groupId>
       <artifactId>org.eclipse.jgit.lfs</artifactId>
-      <version>6.4.1-SNAPSHOT</version>
+      <version>6.5.0-SNAPSHOT</version>
     </dependency>
     <dependency>
       <groupId>org.eclipse.jgit</groupId>
       <artifactId>org.eclipse.jgit.lfs.server</artifactId>
-      <version>6.4.1-SNAPSHOT</version>
+      <version>6.5.0-SNAPSHOT</version>
     </dependency>
     <dependency>
       <groupId>org.eclipse.jgit</groupId>
       <artifactId>org.eclipse.jgit.pgm</artifactId>
-      <version>6.4.1-SNAPSHOT</version>
+      <version>6.5.0-SNAPSHOT</version>
     </dependency>
     <dependency>
       <groupId>org.eclipse.jgit</groupId>
       <artifactId>org.eclipse.jgit.ui</artifactId>
-      <version>6.4.1-SNAPSHOT</version>
+      <version>6.5.0-SNAPSHOT</version>
     </dependency>
     <dependency>
       <groupId>org.eclipse.jgit</groupId>
       <artifactId>org.eclipse.jgit.ssh.apache</artifactId>
-      <version>6.4.1-SNAPSHOT</version>
+      <version>6.5.0-SNAPSHOT</version>
     </dependency>
 
     <dependency>
       <groupId>org.eclipse.jgit</groupId>
       <artifactId>org.eclipse.jgit.test</artifactId>
-      <version>6.4.1-SNAPSHOT</version>
+      <version>6.5.0-SNAPSHOT</version>
     </dependency>
     <dependency>
       <groupId>org.eclipse.jgit</groupId>
       <artifactId>org.eclipse.jgit.ant.test</artifactId>
-      <version>6.4.1-SNAPSHOT</version>
+      <version>6.5.0-SNAPSHOT</version>
     </dependency>
     <dependency>
       <groupId>org.eclipse.jgit</groupId>
       <artifactId>org.eclipse.jgit.http.test</artifactId>
-      <version>6.4.1-SNAPSHOT</version>
+      <version>6.5.0-SNAPSHOT</version>
     </dependency>
     <dependency>
       <groupId>org.eclipse.jgit</groupId>
       <artifactId>org.eclipse.jgit.pgm.test</artifactId>
-      <version>6.4.1-SNAPSHOT</version>
+      <version>6.5.0-SNAPSHOT</version>
     </dependency>
     <dependency>
       <groupId>org.eclipse.jgit</groupId>
       <artifactId>org.eclipse.jgit.lfs.test</artifactId>
-      <version>6.4.1-SNAPSHOT</version>
+      <version>6.5.0-SNAPSHOT</version>
     </dependency>
     <dependency>
       <groupId>org.eclipse.jgit</groupId>
       <artifactId>org.eclipse.jgit.lfs.server.test</artifactId>
-      <version>6.4.1-SNAPSHOT</version>
+      <version>6.5.0-SNAPSHOT</version>
     </dependency>
     <dependency>
       <groupId>org.eclipse.jgit</groupId>
       <artifactId>org.eclipse.jgit.ssh.apache.test</artifactId>
-      <version>6.4.1-SNAPSHOT</version>
+      <version>6.5.0-SNAPSHOT</version>
     </dependency>
   </dependencies>
 
diff --git a/org.eclipse.jgit.gpg.bc.test/META-INF/MANIFEST.MF b/org.eclipse.jgit.gpg.bc.test/META-INF/MANIFEST.MF
index 3fc9043..58775a2 100644
--- a/org.eclipse.jgit.gpg.bc.test/META-INF/MANIFEST.MF
+++ b/org.eclipse.jgit.gpg.bc.test/META-INF/MANIFEST.MF
@@ -3,7 +3,7 @@
 Bundle-Name: %Bundle-Name
 Automatic-Module-Name: org.eclipse.jgit.gpg.bc.test
 Bundle-SymbolicName: org.eclipse.jgit.gpg.bc.test
-Bundle-Version: 6.4.1.qualifier
+Bundle-Version: 6.5.0.qualifier
 Bundle-Vendor: %Bundle-Vendor
 Bundle-Localization: plugin
 Bundle-RequiredExecutionEnvironment: JavaSE-11
@@ -12,9 +12,9 @@
  org.bouncycastle.openpgp.operator;version="[1.65.0,2.0.0)",
  org.bouncycastle.openpgp.operator.jcajce;version="[1.65.0,2.0.0)",
  org.bouncycastle.util.encoders;version="[1.65.0,2.0.0)",
- org.eclipse.jgit.gpg.bc.internal;version="[6.4.1,6.5.0)",
- org.eclipse.jgit.gpg.bc.internal.keys;version="[6.4.1,6.5.0)",
- org.eclipse.jgit.util.sha1;version="[6.4.1,6.5.0)",
+ org.eclipse.jgit.gpg.bc.internal;version="[6.5.0,6.6.0)",
+ org.eclipse.jgit.gpg.bc.internal.keys;version="[6.5.0,6.6.0)",
+ org.eclipse.jgit.util.sha1;version="[6.5.0,6.6.0)",
  org.hamcrest;version="[1.1.0,3.0.0)",
  org.junit;version="[4.13,5.0.0)",
  org.junit.runner;version="[4.13,5.0.0)",
diff --git a/org.eclipse.jgit.gpg.bc.test/pom.xml b/org.eclipse.jgit.gpg.bc.test/pom.xml
index 05a407b..7532ccc 100644
--- a/org.eclipse.jgit.gpg.bc.test/pom.xml
+++ b/org.eclipse.jgit.gpg.bc.test/pom.xml
@@ -17,7 +17,7 @@
   <parent>
     <groupId>org.eclipse.jgit</groupId>
     <artifactId>org.eclipse.jgit-parent</artifactId>
-    <version>6.4.1-SNAPSHOT</version>
+    <version>6.5.0-SNAPSHOT</version>
   </parent>
 
   <artifactId>org.eclipse.jgit.gpg.bc.test</artifactId>
diff --git a/org.eclipse.jgit.gpg.bc/META-INF/MANIFEST.MF b/org.eclipse.jgit.gpg.bc/META-INF/MANIFEST.MF
index dba21ee..758d196 100644
--- a/org.eclipse.jgit.gpg.bc/META-INF/MANIFEST.MF
+++ b/org.eclipse.jgit.gpg.bc/META-INF/MANIFEST.MF
@@ -3,10 +3,10 @@
 Bundle-Name: %Bundle-Name
 Automatic-Module-Name: org.eclipse.jgit.gpg.bc
 Bundle-SymbolicName: org.eclipse.jgit.gpg.bc;singleton:=true
-Fragment-Host: org.eclipse.jgit;bundle-version="[6.4.1,6.5.0)"
+Fragment-Host: org.eclipse.jgit;bundle-version="[6.5.0,6.6.0)"
 Bundle-Vendor: %Bundle-Vendor
 Bundle-Localization: plugin
-Bundle-Version: 6.4.1.qualifier
+Bundle-Version: 6.5.0.qualifier
 Bundle-RequiredExecutionEnvironment: JavaSE-11
 Import-Package: org.bouncycastle.asn1;version="[1.69.0,2.0.0)",
  org.bouncycastle.asn1.cryptlib;version="[1.69.0,2.0.0)",
@@ -29,9 +29,9 @@
  org.bouncycastle.util;version="[1.69.0,2.0.0)",
  org.bouncycastle.util.encoders;version="[1.69.0,2.0.0)",
  org.bouncycastle.util.io;version="[1.69.0,2.0.0)",
- org.eclipse.jgit.annotations;version="[6.4.1,6.5.0)",
- org.eclipse.jgit.api.errors;version="[6.4.1,6.5.0)",
+ org.eclipse.jgit.annotations;version="[6.5.0,6.6.0)",
+ org.eclipse.jgit.api.errors;version="[6.5.0,6.6.0)",
  org.slf4j;version="[1.7.0,2.0.0)"
-Export-Package: org.eclipse.jgit.gpg.bc;version="6.4.1",
- org.eclipse.jgit.gpg.bc.internal;version="6.4.1";x-friends:="org.eclipse.jgit.gpg.bc.test",
- org.eclipse.jgit.gpg.bc.internal.keys;version="6.4.1";x-friends:="org.eclipse.jgit.gpg.bc.test"
+Export-Package: org.eclipse.jgit.gpg.bc;version="6.5.0",
+ org.eclipse.jgit.gpg.bc.internal;version="6.5.0";x-friends:="org.eclipse.jgit.gpg.bc.test",
+ org.eclipse.jgit.gpg.bc.internal.keys;version="6.5.0";x-friends:="org.eclipse.jgit.gpg.bc.test"
diff --git a/org.eclipse.jgit.gpg.bc/META-INF/SOURCE-MANIFEST.MF b/org.eclipse.jgit.gpg.bc/META-INF/SOURCE-MANIFEST.MF
index 040c4c9..351236a 100644
--- a/org.eclipse.jgit.gpg.bc/META-INF/SOURCE-MANIFEST.MF
+++ b/org.eclipse.jgit.gpg.bc/META-INF/SOURCE-MANIFEST.MF
@@ -3,5 +3,5 @@
 Bundle-Name: org.eclipse.jgit.gpg.bc - Sources
 Bundle-SymbolicName: org.eclipse.jgit.gpg.bc.source
 Bundle-Vendor: Eclipse.org - JGit
-Bundle-Version: 6.4.1.qualifier
-Eclipse-SourceBundle: org.eclipse.jgit.gpg.bc;version="6.4.1.qualifier";roots="."
+Bundle-Version: 6.5.0.qualifier
+Eclipse-SourceBundle: org.eclipse.jgit.gpg.bc;version="6.5.0.qualifier";roots="."
diff --git a/org.eclipse.jgit.gpg.bc/pom.xml b/org.eclipse.jgit.gpg.bc/pom.xml
index bf3b015..b5f11a0 100644
--- a/org.eclipse.jgit.gpg.bc/pom.xml
+++ b/org.eclipse.jgit.gpg.bc/pom.xml
@@ -17,7 +17,7 @@
   <parent>
     <groupId>org.eclipse.jgit</groupId>
     <artifactId>org.eclipse.jgit-parent</artifactId>
-    <version>6.4.1-SNAPSHOT</version>
+    <version>6.5.0-SNAPSHOT</version>
   </parent>
 
   <artifactId>org.eclipse.jgit.gpg.bc</artifactId>
diff --git a/org.eclipse.jgit.http.apache/META-INF/MANIFEST.MF b/org.eclipse.jgit.http.apache/META-INF/MANIFEST.MF
index b7fd8ec..12d1dc2 100644
--- a/org.eclipse.jgit.http.apache/META-INF/MANIFEST.MF
+++ b/org.eclipse.jgit.http.apache/META-INF/MANIFEST.MF
@@ -3,7 +3,7 @@
 Bundle-Name: %Bundle-Name
 Automatic-Module-Name: org.eclipse.jgit.http.apache
 Bundle-SymbolicName: org.eclipse.jgit.http.apache
-Bundle-Version: 6.4.1.qualifier
+Bundle-Version: 6.5.0.qualifier
 Bundle-RequiredExecutionEnvironment: JavaSE-11
 Bundle-Localization: plugin
 Bundle-Vendor: %Bundle-Vendor
@@ -25,11 +25,11 @@
  org.apache.http.impl.conn;version="[4.4.0,5.0.0)",
  org.apache.http.params;version="[4.3.0,5.0.0)",
  org.apache.http.ssl;version="[4.3.0,5.0.0)",
- org.eclipse.jgit.annotations;version="[6.4.1,6.5.0)",
- org.eclipse.jgit.nls;version="[6.4.1,6.5.0)",
- org.eclipse.jgit.transport.http;version="[6.4.1,6.5.0)",
- org.eclipse.jgit.util;version="[6.4.1,6.5.0)"
-Export-Package: org.eclipse.jgit.transport.http.apache;version="6.4.1";
+ org.eclipse.jgit.annotations;version="[6.5.0,6.6.0)",
+ org.eclipse.jgit.nls;version="[6.5.0,6.6.0)",
+ org.eclipse.jgit.transport.http;version="[6.5.0,6.6.0)",
+ org.eclipse.jgit.util;version="[6.5.0,6.6.0)"
+Export-Package: org.eclipse.jgit.transport.http.apache;version="6.5.0";
   uses:="org.apache.http.client,
    org.eclipse.jgit.transport.http,
    org.apache.http.entity,
diff --git a/org.eclipse.jgit.http.apache/META-INF/SOURCE-MANIFEST.MF b/org.eclipse.jgit.http.apache/META-INF/SOURCE-MANIFEST.MF
index 16fdf72..9352810 100644
--- a/org.eclipse.jgit.http.apache/META-INF/SOURCE-MANIFEST.MF
+++ b/org.eclipse.jgit.http.apache/META-INF/SOURCE-MANIFEST.MF
@@ -3,5 +3,5 @@
 Bundle-Name: org.eclipse.jgit.http.apache - Sources
 Bundle-SymbolicName: org.eclipse.jgit.http.apache.source
 Bundle-Vendor: Eclipse.org - JGit
-Bundle-Version: 6.4.1.qualifier
-Eclipse-SourceBundle: org.eclipse.jgit.http.apache;version="6.4.1.qualifier";roots="."
+Bundle-Version: 6.5.0.qualifier
+Eclipse-SourceBundle: org.eclipse.jgit.http.apache;version="6.5.0.qualifier";roots="."
diff --git a/org.eclipse.jgit.http.apache/pom.xml b/org.eclipse.jgit.http.apache/pom.xml
index 454b01b..ea69981 100644
--- a/org.eclipse.jgit.http.apache/pom.xml
+++ b/org.eclipse.jgit.http.apache/pom.xml
@@ -15,7 +15,7 @@
   <parent>
     <groupId>org.eclipse.jgit</groupId>
     <artifactId>org.eclipse.jgit-parent</artifactId>
-    <version>6.4.1-SNAPSHOT</version>
+    <version>6.5.0-SNAPSHOT</version>
   </parent>
 
   <artifactId>org.eclipse.jgit.http.apache</artifactId>
diff --git a/org.eclipse.jgit.http.server/META-INF/MANIFEST.MF b/org.eclipse.jgit.http.server/META-INF/MANIFEST.MF
index 41a1fd7..37f4af4 100644
--- a/org.eclipse.jgit.http.server/META-INF/MANIFEST.MF
+++ b/org.eclipse.jgit.http.server/META-INF/MANIFEST.MF
@@ -3,13 +3,13 @@
 Bundle-Name: %Bundle-Name
 Automatic-Module-Name: org.eclipse.jgit.http.server
 Bundle-SymbolicName: org.eclipse.jgit.http.server
-Bundle-Version: 6.4.1.qualifier
+Bundle-Version: 6.5.0.qualifier
 Bundle-Localization: plugin
 Bundle-Vendor: %Bundle-Vendor
-Export-Package: org.eclipse.jgit.http.server;version="6.4.1",
- org.eclipse.jgit.http.server.glue;version="6.4.1";
+Export-Package: org.eclipse.jgit.http.server;version="6.5.0",
+ org.eclipse.jgit.http.server.glue;version="6.5.0";
   uses:="javax.servlet,javax.servlet.http",
- org.eclipse.jgit.http.server.resolver;version="6.4.1";
+ org.eclipse.jgit.http.server.resolver;version="6.5.0";
   uses:="org.eclipse.jgit.transport.resolver,
    org.eclipse.jgit.lib,
    org.eclipse.jgit.transport,
@@ -18,14 +18,14 @@
 Bundle-RequiredExecutionEnvironment: JavaSE-11
 Import-Package: javax.servlet;version="[2.5.0,5.0.0)",
  javax.servlet.http;version="[2.5.0,5.0.0)",
- org.eclipse.jgit.annotations;version="[6.4.1,6.5.0)",
- org.eclipse.jgit.errors;version="[6.4.1,6.5.0)",
- org.eclipse.jgit.internal.storage.dfs;version="[6.4.1,6.5.0)",
- org.eclipse.jgit.internal.storage.file;version="[6.4.1,6.5.0)",
- org.eclipse.jgit.internal.transport.parser;version="[6.4.1,6.5.0)",
- org.eclipse.jgit.lib;version="[6.4.1,6.5.0)",
- org.eclipse.jgit.nls;version="[6.4.1,6.5.0)",
- org.eclipse.jgit.revwalk;version="[6.4.1,6.5.0)",
- org.eclipse.jgit.transport;version="[6.4.1,6.5.0)",
- org.eclipse.jgit.transport.resolver;version="[6.4.1,6.5.0)",
- org.eclipse.jgit.util;version="[6.4.1,6.5.0)"
+ org.eclipse.jgit.annotations;version="[6.5.0,6.6.0)",
+ org.eclipse.jgit.errors;version="[6.5.0,6.6.0)",
+ org.eclipse.jgit.internal.storage.dfs;version="[6.5.0,6.6.0)",
+ org.eclipse.jgit.internal.storage.file;version="[6.5.0,6.6.0)",
+ org.eclipse.jgit.internal.transport.parser;version="[6.5.0,6.6.0)",
+ org.eclipse.jgit.lib;version="[6.5.0,6.6.0)",
+ org.eclipse.jgit.nls;version="[6.5.0,6.6.0)",
+ org.eclipse.jgit.revwalk;version="[6.5.0,6.6.0)",
+ org.eclipse.jgit.transport;version="[6.5.0,6.6.0)",
+ org.eclipse.jgit.transport.resolver;version="[6.5.0,6.6.0)",
+ org.eclipse.jgit.util;version="[6.5.0,6.6.0)"
diff --git a/org.eclipse.jgit.http.server/META-INF/SOURCE-MANIFEST.MF b/org.eclipse.jgit.http.server/META-INF/SOURCE-MANIFEST.MF
index 023b15c..0bed364 100644
--- a/org.eclipse.jgit.http.server/META-INF/SOURCE-MANIFEST.MF
+++ b/org.eclipse.jgit.http.server/META-INF/SOURCE-MANIFEST.MF
@@ -3,5 +3,5 @@
 Bundle-Name: org.eclipse.jgit.http.server - Sources
 Bundle-SymbolicName: org.eclipse.jgit.http.server.source
 Bundle-Vendor: Eclipse.org - JGit
-Bundle-Version: 6.4.1.qualifier
-Eclipse-SourceBundle: org.eclipse.jgit.http.server;version="6.4.1.qualifier";roots="."
+Bundle-Version: 6.5.0.qualifier
+Eclipse-SourceBundle: org.eclipse.jgit.http.server;version="6.5.0.qualifier";roots="."
diff --git a/org.eclipse.jgit.http.server/pom.xml b/org.eclipse.jgit.http.server/pom.xml
index 3c98883..7355a42 100644
--- a/org.eclipse.jgit.http.server/pom.xml
+++ b/org.eclipse.jgit.http.server/pom.xml
@@ -19,7 +19,7 @@
   <parent>
     <groupId>org.eclipse.jgit</groupId>
     <artifactId>org.eclipse.jgit-parent</artifactId>
-    <version>6.4.1-SNAPSHOT</version>
+    <version>6.5.0-SNAPSHOT</version>
   </parent>
 
   <artifactId>org.eclipse.jgit.http.server</artifactId>
diff --git a/org.eclipse.jgit.http.test/META-INF/MANIFEST.MF b/org.eclipse.jgit.http.test/META-INF/MANIFEST.MF
index 8347693..692d485 100644
--- a/org.eclipse.jgit.http.test/META-INF/MANIFEST.MF
+++ b/org.eclipse.jgit.http.test/META-INF/MANIFEST.MF
@@ -3,7 +3,7 @@
 Bundle-Name: %Bundle-Name
 Automatic-Module-Name: org.eclipse.jgit.http.test
 Bundle-SymbolicName: org.eclipse.jgit.http.test
-Bundle-Version: 6.4.1.qualifier
+Bundle-Version: 6.5.0.qualifier
 Bundle-Vendor: %Bundle-Vendor
 Bundle-Localization: plugin
 Bundle-RequiredExecutionEnvironment: JavaSE-11
@@ -26,26 +26,26 @@
  org.eclipse.jetty.util.log;version="[10.0.0,11.0.0)",
  org.eclipse.jetty.util.security;version="[10.0.0,11.0.0)",
  org.eclipse.jetty.util.thread;version="[10.0.0,11.0.0)",
- org.eclipse.jgit.api;version="[6.4.1,6.5.0)",
- org.eclipse.jgit.errors;version="[6.4.1,6.5.0)",
- org.eclipse.jgit.http.server;version="[6.4.1,6.5.0)",
- org.eclipse.jgit.http.server.glue;version="[6.4.1,6.5.0)",
- org.eclipse.jgit.http.server.resolver;version="[6.4.1,6.5.0)",
- org.eclipse.jgit.internal;version="[6.4.1,6.5.0)",
- org.eclipse.jgit.internal.storage.dfs;version="[6.4.1,6.5.0)",
- org.eclipse.jgit.internal.storage.file;version="[6.4.1,6.5.0)",
- org.eclipse.jgit.internal.storage.reftable;version="[6.4.1,6.5.0)",
- org.eclipse.jgit.junit;version="[6.4.1,6.5.0)",
- org.eclipse.jgit.junit.http;version="[6.4.1,6.5.0)",
- org.eclipse.jgit.lib;version="[6.4.1,6.5.0)",
- org.eclipse.jgit.nls;version="[6.4.1,6.5.0)",
- org.eclipse.jgit.revwalk;version="[6.4.1,6.5.0)",
- org.eclipse.jgit.storage.file;version="[6.4.1,6.5.0)",
- org.eclipse.jgit.transport;version="[6.4.1,6.5.0)",
- org.eclipse.jgit.transport.http;version="[6.4.1,6.5.0)",
- org.eclipse.jgit.transport.http.apache;version="[6.4.1,6.5.0)",
- org.eclipse.jgit.transport.resolver;version="[6.4.1,6.5.0)",
- org.eclipse.jgit.util;version="[6.4.1,6.5.0)",
+ org.eclipse.jgit.api;version="[6.5.0,6.6.0)",
+ org.eclipse.jgit.errors;version="[6.5.0,6.6.0)",
+ org.eclipse.jgit.http.server;version="[6.5.0,6.6.0)",
+ org.eclipse.jgit.http.server.glue;version="[6.5.0,6.6.0)",
+ org.eclipse.jgit.http.server.resolver;version="[6.5.0,6.6.0)",
+ org.eclipse.jgit.internal;version="[6.5.0,6.6.0)",
+ org.eclipse.jgit.internal.storage.dfs;version="[6.5.0,6.6.0)",
+ org.eclipse.jgit.internal.storage.file;version="[6.5.0,6.6.0)",
+ org.eclipse.jgit.internal.storage.reftable;version="[6.5.0,6.6.0)",
+ org.eclipse.jgit.junit;version="[6.5.0,6.6.0)",
+ org.eclipse.jgit.junit.http;version="[6.5.0,6.6.0)",
+ org.eclipse.jgit.lib;version="[6.5.0,6.6.0)",
+ org.eclipse.jgit.nls;version="[6.5.0,6.6.0)",
+ org.eclipse.jgit.revwalk;version="[6.5.0,6.6.0)",
+ org.eclipse.jgit.storage.file;version="[6.5.0,6.6.0)",
+ org.eclipse.jgit.transport;version="[6.5.0,6.6.0)",
+ org.eclipse.jgit.transport.http;version="[6.5.0,6.6.0)",
+ org.eclipse.jgit.transport.http.apache;version="[6.5.0,6.6.0)",
+ org.eclipse.jgit.transport.resolver;version="[6.5.0,6.6.0)",
+ org.eclipse.jgit.util;version="[6.5.0,6.6.0)",
  org.hamcrest;version="[1.1.0,3.0.0)",
  org.hamcrest.core;version="[1.1.0,3.0.0)",
  org.junit;version="[4.13,5.0.0)",
diff --git a/org.eclipse.jgit.http.test/pom.xml b/org.eclipse.jgit.http.test/pom.xml
index 39a11fa..5c357ac 100644
--- a/org.eclipse.jgit.http.test/pom.xml
+++ b/org.eclipse.jgit.http.test/pom.xml
@@ -18,7 +18,7 @@
   <parent>
     <groupId>org.eclipse.jgit</groupId>
     <artifactId>org.eclipse.jgit-parent</artifactId>
-    <version>6.4.1-SNAPSHOT</version>
+    <version>6.5.0-SNAPSHOT</version>
   </parent>
 
   <artifactId>org.eclipse.jgit.http.test</artifactId>
diff --git a/org.eclipse.jgit.junit.http/META-INF/MANIFEST.MF b/org.eclipse.jgit.junit.http/META-INF/MANIFEST.MF
index 5b5534f..22d1e89 100644
--- a/org.eclipse.jgit.junit.http/META-INF/MANIFEST.MF
+++ b/org.eclipse.jgit.junit.http/META-INF/MANIFEST.MF
@@ -3,7 +3,7 @@
 Bundle-Name: %Bundle-Name
 Automatic-Module-Name: org.eclipse.jgit.junit.http
 Bundle-SymbolicName: org.eclipse.jgit.junit.http
-Bundle-Version: 6.4.1.qualifier
+Bundle-Version: 6.5.0.qualifier
 Bundle-Localization: plugin
 Bundle-Vendor: %Bundle-Vendor
 Bundle-ActivationPolicy: lazy
@@ -21,17 +21,17 @@
  org.eclipse.jetty.util.log;version="[10.0.0,11.0.0)",
  org.eclipse.jetty.util.security;version="[10.0.0,11.0.0)",
  org.eclipse.jetty.util.ssl;version="[10.0.0,11.0.0)",
- org.eclipse.jgit.errors;version="[6.4.1,6.5.0)",
- org.eclipse.jgit.http.server;version="[6.4.1,6.5.0)",
- org.eclipse.jgit.internal.storage.file;version="[6.4.1,6.5.0)",
- org.eclipse.jgit.junit;version="[6.4.1,6.5.0)",
- org.eclipse.jgit.lib;version="[6.4.1,6.5.0)",
- org.eclipse.jgit.revwalk;version="[6.4.1,6.5.0)",
- org.eclipse.jgit.transport;version="[6.4.1,6.5.0)",
- org.eclipse.jgit.transport.resolver;version="[6.4.1,6.5.0)",
+ org.eclipse.jgit.errors;version="[6.5.0,6.6.0)",
+ org.eclipse.jgit.http.server;version="[6.5.0,6.6.0)",
+ org.eclipse.jgit.internal.storage.file;version="[6.5.0,6.6.0)",
+ org.eclipse.jgit.junit;version="[6.5.0,6.6.0)",
+ org.eclipse.jgit.lib;version="[6.5.0,6.6.0)",
+ org.eclipse.jgit.revwalk;version="[6.5.0,6.6.0)",
+ org.eclipse.jgit.transport;version="[6.5.0,6.6.0)",
+ org.eclipse.jgit.transport.resolver;version="[6.5.0,6.6.0)",
  org.junit;version="[4.13,5.0.0)",
  org.slf4j.helpers;version="[1.7.0,2.0.0)"
-Export-Package: org.eclipse.jgit.junit.http;version="6.4.1";
+Export-Package: org.eclipse.jgit.junit.http;version="6.5.0";
   uses:="org.eclipse.jgit.transport,
    org.eclipse.jgit.junit,
    javax.servlet.http,
diff --git a/org.eclipse.jgit.junit.http/META-INF/SOURCE-MANIFEST.MF b/org.eclipse.jgit.junit.http/META-INF/SOURCE-MANIFEST.MF
index 416d9b7..9b637cd3 100644
--- a/org.eclipse.jgit.junit.http/META-INF/SOURCE-MANIFEST.MF
+++ b/org.eclipse.jgit.junit.http/META-INF/SOURCE-MANIFEST.MF
@@ -3,5 +3,5 @@
 Bundle-Name: org.eclipse.jgit.junit.http - Sources
 Bundle-SymbolicName: org.eclipse.jgit.junit.http.source
 Bundle-Vendor: Eclipse.org - JGit
-Bundle-Version: 6.4.1.qualifier
-Eclipse-SourceBundle: org.eclipse.jgit.junit.http;version="6.4.1.qualifier";roots="."
+Bundle-Version: 6.5.0.qualifier
+Eclipse-SourceBundle: org.eclipse.jgit.junit.http;version="6.5.0.qualifier";roots="."
diff --git a/org.eclipse.jgit.junit.http/pom.xml b/org.eclipse.jgit.junit.http/pom.xml
index 8ebd77d..8131680 100644
--- a/org.eclipse.jgit.junit.http/pom.xml
+++ b/org.eclipse.jgit.junit.http/pom.xml
@@ -17,7 +17,7 @@
   <parent>
     <groupId>org.eclipse.jgit</groupId>
     <artifactId>org.eclipse.jgit-parent</artifactId>
-    <version>6.4.1-SNAPSHOT</version>
+    <version>6.5.0-SNAPSHOT</version>
   </parent>
 
   <artifactId>org.eclipse.jgit.junit.http</artifactId>
diff --git a/org.eclipse.jgit.junit.ssh/META-INF/MANIFEST.MF b/org.eclipse.jgit.junit.ssh/META-INF/MANIFEST.MF
index 79684e5..fb73903 100644
--- a/org.eclipse.jgit.junit.ssh/META-INF/MANIFEST.MF
+++ b/org.eclipse.jgit.junit.ssh/META-INF/MANIFEST.MF
@@ -3,7 +3,7 @@
 Bundle-Name: %Bundle-Name
 Automatic-Module-Name: org.eclipse.jgit.junit.ssh
 Bundle-SymbolicName: org.eclipse.jgit.junit.ssh
-Bundle-Version: 6.4.1.qualifier
+Bundle-Version: 6.5.0.qualifier
 Bundle-Localization: plugin
 Bundle-Vendor: %Bundle-Vendor
 Bundle-ActivationPolicy: lazy
@@ -33,16 +33,16 @@
  org.apache.sshd.server.subsystem;version="[2.9.2,2.10.0)",
  org.apache.sshd.sftp;version="[2.9.2,2.10.0)",
  org.apache.sshd.sftp.server;version="[2.9.2,2.10.0)",
- org.eclipse.jgit.annotations;version="[6.4.1,6.5.0)",
- org.eclipse.jgit.api;version="[6.4.1,6.5.0)",
- org.eclipse.jgit.api.errors;version="[6.4.1,6.5.0)",
- org.eclipse.jgit.errors;version="[6.4.1,6.5.0)",
- org.eclipse.jgit.junit;version="[6.4.1,6.5.0)",
- org.eclipse.jgit.lib;version="[6.4.1,6.5.0)",
- org.eclipse.jgit.revwalk;version="[6.4.1,6.5.0)",
- org.eclipse.jgit.transport;version="[6.4.1,6.5.0)",
- org.eclipse.jgit.util;version="[6.4.1,6.5.0)",
+ org.eclipse.jgit.annotations;version="[6.5.0,6.6.0)",
+ org.eclipse.jgit.api;version="[6.5.0,6.6.0)",
+ org.eclipse.jgit.api.errors;version="[6.5.0,6.6.0)",
+ org.eclipse.jgit.errors;version="[6.5.0,6.6.0)",
+ org.eclipse.jgit.junit;version="[6.5.0,6.6.0)",
+ org.eclipse.jgit.lib;version="[6.5.0,6.6.0)",
+ org.eclipse.jgit.revwalk;version="[6.5.0,6.6.0)",
+ org.eclipse.jgit.transport;version="[6.5.0,6.6.0)",
+ org.eclipse.jgit.util;version="[6.5.0,6.6.0)",
  org.junit;version="[4.13,5.0.0)",
  org.junit.experimental.theories;version="[4.13,5.0.0)",
  org.slf4j;version="[1.7.0,2.0.0)"
-Export-Package: org.eclipse.jgit.junit.ssh;version="6.4.1"
+Export-Package: org.eclipse.jgit.junit.ssh;version="6.5.0"
diff --git a/org.eclipse.jgit.junit.ssh/META-INF/SOURCE-MANIFEST.MF b/org.eclipse.jgit.junit.ssh/META-INF/SOURCE-MANIFEST.MF
index a1f99de..7a56ffe 100644
--- a/org.eclipse.jgit.junit.ssh/META-INF/SOURCE-MANIFEST.MF
+++ b/org.eclipse.jgit.junit.ssh/META-INF/SOURCE-MANIFEST.MF
@@ -3,5 +3,5 @@
 Bundle-Name: org.eclipse.jgit.junit.ssh - Sources
 Bundle-SymbolicName: org.eclipse.jgit.junit.ssh.source
 Bundle-Vendor: Eclipse.org - JGit
-Bundle-Version: 6.4.1.qualifier
-Eclipse-SourceBundle: org.eclipse.jgit.junit.ssh;version="6.4.1.qualifier";roots="."
+Bundle-Version: 6.5.0.qualifier
+Eclipse-SourceBundle: org.eclipse.jgit.junit.ssh;version="6.5.0.qualifier";roots="."
diff --git a/org.eclipse.jgit.junit.ssh/pom.xml b/org.eclipse.jgit.junit.ssh/pom.xml
index 9fb3d31..b997ed9 100644
--- a/org.eclipse.jgit.junit.ssh/pom.xml
+++ b/org.eclipse.jgit.junit.ssh/pom.xml
@@ -17,7 +17,7 @@
   <parent>
     <groupId>org.eclipse.jgit</groupId>
     <artifactId>org.eclipse.jgit-parent</artifactId>
-    <version>6.4.1-SNAPSHOT</version>
+    <version>6.5.0-SNAPSHOT</version>
   </parent>
 
   <artifactId>org.eclipse.jgit.junit.ssh</artifactId>
diff --git a/org.eclipse.jgit.junit/META-INF/MANIFEST.MF b/org.eclipse.jgit.junit/META-INF/MANIFEST.MF
index 320f4a7..a6b737a 100644
--- a/org.eclipse.jgit.junit/META-INF/MANIFEST.MF
+++ b/org.eclipse.jgit.junit/META-INF/MANIFEST.MF
@@ -3,35 +3,35 @@
 Bundle-Name: %Bundle-Name
 Automatic-Module-Name: org.eclipse.jgit.junit
 Bundle-SymbolicName: org.eclipse.jgit.junit
-Bundle-Version: 6.4.1.qualifier
+Bundle-Version: 6.5.0.qualifier
 Bundle-Localization: plugin
 Bundle-Vendor: %Bundle-Vendor
 Bundle-ActivationPolicy: lazy
 Bundle-RequiredExecutionEnvironment: JavaSE-11
-Import-Package: org.eclipse.jgit.annotations;version="[6.4.1,6.5.0)",
- org.eclipse.jgit.api;version="[6.4.1,6.5.0)",
- org.eclipse.jgit.api.errors;version="[6.4.1,6.5.0)",
- org.eclipse.jgit.dircache;version="[6.4.1,6.5.0)",
- org.eclipse.jgit.errors;version="[6.4.1,6.5.0)",
- org.eclipse.jgit.internal.storage.file;version="[6.4.1,6.5.0)",
- org.eclipse.jgit.internal.storage.pack;version="[6.4.1,6.5.0)",
- org.eclipse.jgit.lib;version="[6.4.1,6.5.0)",
- org.eclipse.jgit.merge;version="[6.4.1,6.5.0)",
- org.eclipse.jgit.revwalk;version="[6.4.1,6.5.0)",
- org.eclipse.jgit.storage.file;version="[6.4.1,6.5.0)",
- org.eclipse.jgit.transport;version="6.4.1",
- org.eclipse.jgit.treewalk;version="[6.4.1,6.5.0)",
- org.eclipse.jgit.treewalk.filter;version="[6.4.1,6.5.0)",
- org.eclipse.jgit.util;version="[6.4.1,6.5.0)",
- org.eclipse.jgit.util.io;version="[6.4.1,6.5.0)",
- org.eclipse.jgit.util.time;version="[6.4.1,6.5.0)",
+Import-Package: org.eclipse.jgit.annotations;version="[6.5.0,6.6.0)",
+ org.eclipse.jgit.api;version="[6.5.0,6.6.0)",
+ org.eclipse.jgit.api.errors;version="[6.5.0,6.6.0)",
+ org.eclipse.jgit.dircache;version="[6.5.0,6.6.0)",
+ org.eclipse.jgit.errors;version="[6.5.0,6.6.0)",
+ org.eclipse.jgit.internal.storage.file;version="[6.5.0,6.6.0)",
+ org.eclipse.jgit.internal.storage.pack;version="[6.5.0,6.6.0)",
+ org.eclipse.jgit.lib;version="[6.5.0,6.6.0)",
+ org.eclipse.jgit.merge;version="[6.5.0,6.6.0)",
+ org.eclipse.jgit.revwalk;version="[6.5.0,6.6.0)",
+ org.eclipse.jgit.storage.file;version="[6.5.0,6.6.0)",
+ org.eclipse.jgit.transport;version="6.5.0",
+ org.eclipse.jgit.treewalk;version="[6.5.0,6.6.0)",
+ org.eclipse.jgit.treewalk.filter;version="[6.5.0,6.6.0)",
+ org.eclipse.jgit.util;version="[6.5.0,6.6.0)",
+ org.eclipse.jgit.util.io;version="[6.5.0,6.6.0)",
+ org.eclipse.jgit.util.time;version="[6.5.0,6.6.0)",
  org.junit;version="[4.13,5.0.0)",
  org.junit.rules;version="[4.13,5.0.0)",
  org.junit.runner;version="[4.13,5.0.0)",
  org.junit.runners;version="[4.13,5.0.0)",
  org.junit.runners.model;version="[4.13,5.0.0)",
  org.slf4j;version="[1.7.0,2.0.0)"
-Export-Package: org.eclipse.jgit.junit;version="6.4.1";
+Export-Package: org.eclipse.jgit.junit;version="6.5.0";
   uses:="org.eclipse.jgit.dircache,
    org.eclipse.jgit.lib,
    org.eclipse.jgit.revwalk,
@@ -44,4 +44,4 @@
    org.junit.runners.model,
    org.junit.runner,
    org.eclipse.jgit.util.time",
- org.eclipse.jgit.junit.time;version="6.4.1";uses:="org.eclipse.jgit.util.time"
+ org.eclipse.jgit.junit.time;version="6.5.0";uses:="org.eclipse.jgit.util.time"
diff --git a/org.eclipse.jgit.junit/META-INF/SOURCE-MANIFEST.MF b/org.eclipse.jgit.junit/META-INF/SOURCE-MANIFEST.MF
index 367787c..5bb12e7 100644
--- a/org.eclipse.jgit.junit/META-INF/SOURCE-MANIFEST.MF
+++ b/org.eclipse.jgit.junit/META-INF/SOURCE-MANIFEST.MF
@@ -3,5 +3,5 @@
 Bundle-Name: org.eclipse.jgit.junit - Sources
 Bundle-SymbolicName: org.eclipse.jgit.junit.source
 Bundle-Vendor: Eclipse.org - JGit
-Bundle-Version: 6.4.1.qualifier
-Eclipse-SourceBundle: org.eclipse.jgit.junit;version="6.4.1.qualifier";roots="."
+Bundle-Version: 6.5.0.qualifier
+Eclipse-SourceBundle: org.eclipse.jgit.junit;version="6.5.0.qualifier";roots="."
diff --git a/org.eclipse.jgit.junit/pom.xml b/org.eclipse.jgit.junit/pom.xml
index 0a69906..d4b1cea 100644
--- a/org.eclipse.jgit.junit/pom.xml
+++ b/org.eclipse.jgit.junit/pom.xml
@@ -19,7 +19,7 @@
   <parent>
     <groupId>org.eclipse.jgit</groupId>
     <artifactId>org.eclipse.jgit-parent</artifactId>
-    <version>6.4.1-SNAPSHOT</version>
+    <version>6.5.0-SNAPSHOT</version>
   </parent>
 
   <artifactId>org.eclipse.jgit.junit</artifactId>
diff --git a/org.eclipse.jgit.lfs.server.test/META-INF/MANIFEST.MF b/org.eclipse.jgit.lfs.server.test/META-INF/MANIFEST.MF
index 7b3d7e0..aecf81f 100644
--- a/org.eclipse.jgit.lfs.server.test/META-INF/MANIFEST.MF
+++ b/org.eclipse.jgit.lfs.server.test/META-INF/MANIFEST.MF
@@ -3,7 +3,7 @@
 Bundle-Name: %Bundle-Name
 Automatic-Module-Name: org.eclipse.jgit.lfs.server.test
 Bundle-SymbolicName: org.eclipse.jgit.lfs.server.test
-Bundle-Version: 6.4.1.qualifier
+Bundle-Version: 6.5.0.qualifier
 Bundle-Vendor: %Bundle-Vendor
 Bundle-Localization: plugin
 Bundle-RequiredExecutionEnvironment: JavaSE-11
@@ -26,24 +26,24 @@
  org.eclipse.jetty.util.log;version="[10.0.0,11.0.0)",
  org.eclipse.jetty.util.security;version="[10.0.0,11.0.0)",
  org.eclipse.jetty.util.thread;version="[10.0.0,11.0.0)",
- org.eclipse.jgit.api;version="[6.4.1,6.5.0)",
- org.eclipse.jgit.api.errors;version="[6.4.1,6.5.0)",
- org.eclipse.jgit.internal.storage.file;version="[6.4.1,6.5.0)",
- org.eclipse.jgit.junit;version="[6.4.1,6.5.0)",
- org.eclipse.jgit.junit.http;version="[6.4.1,6.5.0)",
- org.eclipse.jgit.lfs;version="[6.4.1,6.5.0)",
- org.eclipse.jgit.lfs.errors;version="[6.4.1,6.5.0)",
- org.eclipse.jgit.lfs.lib;version="[6.4.1,6.5.0)",
- org.eclipse.jgit.lfs.server;version="[6.4.1,6.5.0)",
- org.eclipse.jgit.lfs.server.fs;version="[6.4.1,6.5.0)",
- org.eclipse.jgit.lfs.test;version="[6.4.1,6.5.0)",
- org.eclipse.jgit.lib;version="[6.4.1,6.5.0)",
- org.eclipse.jgit.revwalk;version="[6.4.1,6.5.0)",
- org.eclipse.jgit.storage.file;version="[6.4.1,6.5.0)",
- org.eclipse.jgit.transport;version="[6.4.1,6.5.0)",
- org.eclipse.jgit.treewalk;version="[6.4.1,6.5.0)",
- org.eclipse.jgit.treewalk.filter;version="[6.4.1,6.5.0)",
- org.eclipse.jgit.util;version="[6.4.1,6.5.0)",
+ org.eclipse.jgit.api;version="[6.5.0,6.6.0)",
+ org.eclipse.jgit.api.errors;version="[6.5.0,6.6.0)",
+ org.eclipse.jgit.internal.storage.file;version="[6.5.0,6.6.0)",
+ org.eclipse.jgit.junit;version="[6.5.0,6.6.0)",
+ org.eclipse.jgit.junit.http;version="[6.5.0,6.6.0)",
+ org.eclipse.jgit.lfs;version="[6.5.0,6.6.0)",
+ org.eclipse.jgit.lfs.errors;version="[6.5.0,6.6.0)",
+ org.eclipse.jgit.lfs.lib;version="[6.5.0,6.6.0)",
+ org.eclipse.jgit.lfs.server;version="[6.5.0,6.6.0)",
+ org.eclipse.jgit.lfs.server.fs;version="[6.5.0,6.6.0)",
+ org.eclipse.jgit.lfs.test;version="[6.5.0,6.6.0)",
+ org.eclipse.jgit.lib;version="[6.5.0,6.6.0)",
+ org.eclipse.jgit.revwalk;version="[6.5.0,6.6.0)",
+ org.eclipse.jgit.storage.file;version="[6.5.0,6.6.0)",
+ org.eclipse.jgit.transport;version="[6.5.0,6.6.0)",
+ org.eclipse.jgit.treewalk;version="[6.5.0,6.6.0)",
+ org.eclipse.jgit.treewalk.filter;version="[6.5.0,6.6.0)",
+ org.eclipse.jgit.util;version="[6.5.0,6.6.0)",
  org.hamcrest.core;version="[1.1.0,3.0.0)",
  org.junit;version="[4.13,5.0.0)",
  org.junit.rules;version="[4.13,5.0.0)",
diff --git a/org.eclipse.jgit.lfs.server.test/pom.xml b/org.eclipse.jgit.lfs.server.test/pom.xml
index b0f6a5b..0575fcf 100644
--- a/org.eclipse.jgit.lfs.server.test/pom.xml
+++ b/org.eclipse.jgit.lfs.server.test/pom.xml
@@ -17,7 +17,7 @@
   <parent>
     <groupId>org.eclipse.jgit</groupId>
     <artifactId>org.eclipse.jgit-parent</artifactId>
-    <version>6.4.1-SNAPSHOT</version>
+    <version>6.5.0-SNAPSHOT</version>
   </parent>
 
   <artifactId>org.eclipse.jgit.lfs.server.test</artifactId>
diff --git a/org.eclipse.jgit.lfs.server/META-INF/MANIFEST.MF b/org.eclipse.jgit.lfs.server/META-INF/MANIFEST.MF
index e27cc90..b673489 100644
--- a/org.eclipse.jgit.lfs.server/META-INF/MANIFEST.MF
+++ b/org.eclipse.jgit.lfs.server/META-INF/MANIFEST.MF
@@ -3,19 +3,19 @@
 Bundle-Name: %Bundle-Name
 Automatic-Module-Name: org.eclipse.jgit.lfs.server
 Bundle-SymbolicName: org.eclipse.jgit.lfs.server
-Bundle-Version: 6.4.1.qualifier
+Bundle-Version: 6.5.0.qualifier
 Bundle-Localization: plugin
 Bundle-Vendor: %Bundle-Vendor
-Export-Package: org.eclipse.jgit.lfs.server;version="6.4.1";
+Export-Package: org.eclipse.jgit.lfs.server;version="6.5.0";
   uses:="javax.servlet.http,
    org.eclipse.jgit.lfs.lib",
- org.eclipse.jgit.lfs.server.fs;version="6.4.1";
+ org.eclipse.jgit.lfs.server.fs;version="6.5.0";
   uses:="javax.servlet,
    javax.servlet.http,
    org.eclipse.jgit.lfs.server,
    org.eclipse.jgit.lfs.lib",
- org.eclipse.jgit.lfs.server.internal;version="6.4.1";x-internal:=true,
- org.eclipse.jgit.lfs.server.s3;version="6.4.1";
+ org.eclipse.jgit.lfs.server.internal;version="6.5.0";x-internal:=true,
+ org.eclipse.jgit.lfs.server.s3;version="6.5.0";
   uses:="org.eclipse.jgit.lfs.server,
    org.eclipse.jgit.lfs.lib"
 Bundle-RequiredExecutionEnvironment: JavaSE-11
@@ -24,15 +24,15 @@
  javax.servlet.annotation;version="[3.1.0,5.0.0)",
  javax.servlet.http;version="[3.1.0,5.0.0)",
  org.apache.http;version="[4.3.0,5.0.0)",
- org.eclipse.jgit.annotations;version="[6.4.1,6.5.0)",
- org.eclipse.jgit.internal;version="[6.4.1,6.5.0)",
- org.eclipse.jgit.internal.storage.file;version="[6.4.1,6.5.0)",
- org.eclipse.jgit.lfs.errors;version="[6.4.1,6.5.0)",
- org.eclipse.jgit.lfs.internal;version="[6.4.1,6.5.0)",
- org.eclipse.jgit.lfs.lib;version="[6.4.1,6.5.0)",
- org.eclipse.jgit.lib;version="[6.4.1,6.5.0)",
- org.eclipse.jgit.nls;version="[6.4.1,6.5.0)",
- org.eclipse.jgit.transport.http;version="[6.4.1,6.5.0)",
- org.eclipse.jgit.transport.http.apache;version="[6.4.1,6.5.0)",
- org.eclipse.jgit.util;version="[6.4.1,6.5.0)",
+ org.eclipse.jgit.annotations;version="[6.5.0,6.6.0)",
+ org.eclipse.jgit.internal;version="[6.5.0,6.6.0)",
+ org.eclipse.jgit.internal.storage.file;version="[6.5.0,6.6.0)",
+ org.eclipse.jgit.lfs.errors;version="[6.5.0,6.6.0)",
+ org.eclipse.jgit.lfs.internal;version="[6.5.0,6.6.0)",
+ org.eclipse.jgit.lfs.lib;version="[6.5.0,6.6.0)",
+ org.eclipse.jgit.lib;version="[6.5.0,6.6.0)",
+ org.eclipse.jgit.nls;version="[6.5.0,6.6.0)",
+ org.eclipse.jgit.transport.http;version="[6.5.0,6.6.0)",
+ org.eclipse.jgit.transport.http.apache;version="[6.5.0,6.6.0)",
+ org.eclipse.jgit.util;version="[6.5.0,6.6.0)",
  org.slf4j;version="[1.7.0,2.0.0)"
diff --git a/org.eclipse.jgit.lfs.server/META-INF/SOURCE-MANIFEST.MF b/org.eclipse.jgit.lfs.server/META-INF/SOURCE-MANIFEST.MF
index 595a04e..b243678 100644
--- a/org.eclipse.jgit.lfs.server/META-INF/SOURCE-MANIFEST.MF
+++ b/org.eclipse.jgit.lfs.server/META-INF/SOURCE-MANIFEST.MF
@@ -3,5 +3,5 @@
 Bundle-Name: org.eclipse.jgit.lfs.server - Sources
 Bundle-SymbolicName: org.eclipse.jgit.lfs.server.source
 Bundle-Vendor: Eclipse.org - JGit
-Bundle-Version: 6.4.1.qualifier
-Eclipse-SourceBundle: org.eclipse.jgit.lfs.server;version="6.4.1.qualifier";roots="."
+Bundle-Version: 6.5.0.qualifier
+Eclipse-SourceBundle: org.eclipse.jgit.lfs.server;version="6.5.0.qualifier";roots="."
diff --git a/org.eclipse.jgit.lfs.server/pom.xml b/org.eclipse.jgit.lfs.server/pom.xml
index 69336a6..31db1cb 100644
--- a/org.eclipse.jgit.lfs.server/pom.xml
+++ b/org.eclipse.jgit.lfs.server/pom.xml
@@ -17,7 +17,7 @@
   <parent>
     <groupId>org.eclipse.jgit</groupId>
     <artifactId>org.eclipse.jgit-parent</artifactId>
-    <version>6.4.1-SNAPSHOT</version>
+    <version>6.5.0-SNAPSHOT</version>
   </parent>
 
   <artifactId>org.eclipse.jgit.lfs.server</artifactId>
diff --git a/org.eclipse.jgit.lfs.test/META-INF/MANIFEST.MF b/org.eclipse.jgit.lfs.test/META-INF/MANIFEST.MF
index 8facd81..44c9b50 100644
--- a/org.eclipse.jgit.lfs.test/META-INF/MANIFEST.MF
+++ b/org.eclipse.jgit.lfs.test/META-INF/MANIFEST.MF
@@ -3,27 +3,27 @@
 Bundle-Name: %Bundle-Name
 Automatic-Module-Name: org.eclipse.jgit.lfs.test
 Bundle-SymbolicName: org.eclipse.jgit.lfs.test
-Bundle-Version: 6.4.1.qualifier
+Bundle-Version: 6.5.0.qualifier
 Bundle-Vendor: %Bundle-Vendor
 Bundle-Localization: plugin
 Bundle-RequiredExecutionEnvironment: JavaSE-11
-Import-Package: org.eclipse.jgit.api;version="[6.4.1,6.5.0)",
- org.eclipse.jgit.attributes;version="[6.4.1,6.5.0)",
- org.eclipse.jgit.internal.storage.dfs;version="[6.4.1,6.5.0)",
- org.eclipse.jgit.junit;version="[6.4.1,6.5.0)",
- org.eclipse.jgit.lfs;version="[6.4.1,6.5.0)",
- org.eclipse.jgit.lfs.errors;version="[6.4.1,6.5.0)",
- org.eclipse.jgit.lfs.internal;version="[6.4.1,6.5.0)",
- org.eclipse.jgit.lfs.lib;version="[6.4.1,6.5.0)",
- org.eclipse.jgit.lib;version="[6.4.1,6.5.0)",
- org.eclipse.jgit.revwalk;version="[6.4.1,6.5.0)",
- org.eclipse.jgit.transport;version="[6.4.1,6.5.0)",
- org.eclipse.jgit.transport.http;version="[6.4.1,6.5.0)",
- org.eclipse.jgit.treewalk;version="[6.4.1,6.5.0)",
- org.eclipse.jgit.treewalk.filter;version="[6.4.1,6.5.0)",
- org.eclipse.jgit.util;version="[6.4.1,6.5.0)",
+Import-Package: org.eclipse.jgit.api;version="[6.5.0,6.6.0)",
+ org.eclipse.jgit.attributes;version="[6.5.0,6.6.0)",
+ org.eclipse.jgit.internal.storage.dfs;version="[6.5.0,6.6.0)",
+ org.eclipse.jgit.junit;version="[6.5.0,6.6.0)",
+ org.eclipse.jgit.lfs;version="[6.5.0,6.6.0)",
+ org.eclipse.jgit.lfs.errors;version="[6.5.0,6.6.0)",
+ org.eclipse.jgit.lfs.internal;version="[6.5.0,6.6.0)",
+ org.eclipse.jgit.lfs.lib;version="[6.5.0,6.6.0)",
+ org.eclipse.jgit.lib;version="[6.5.0,6.6.0)",
+ org.eclipse.jgit.revwalk;version="[6.5.0,6.6.0)",
+ org.eclipse.jgit.transport;version="[6.5.0,6.6.0)",
+ org.eclipse.jgit.transport.http;version="[6.5.0,6.6.0)",
+ org.eclipse.jgit.treewalk;version="[6.5.0,6.6.0)",
+ org.eclipse.jgit.treewalk.filter;version="[6.5.0,6.6.0)",
+ org.eclipse.jgit.util;version="[6.5.0,6.6.0)",
  org.hamcrest.core;version="[1.1.0,3.0.0)",
  org.junit;version="[4.13,5.0.0)",
  org.junit.runner;version="[4.13,5.0.0)",
  org.junit.runners;version="[4.13,5.0.0)"
-Export-Package: org.eclipse.jgit.lfs.test;version="6.4.1";x-friends:="org.eclipse.jgit.lfs.server.test"
+Export-Package: org.eclipse.jgit.lfs.test;version="6.5.0";x-friends:="org.eclipse.jgit.lfs.server.test"
diff --git a/org.eclipse.jgit.lfs.test/pom.xml b/org.eclipse.jgit.lfs.test/pom.xml
index 43a5d08..6c10ac9 100644
--- a/org.eclipse.jgit.lfs.test/pom.xml
+++ b/org.eclipse.jgit.lfs.test/pom.xml
@@ -17,7 +17,7 @@
   <parent>
     <groupId>org.eclipse.jgit</groupId>
     <artifactId>org.eclipse.jgit-parent</artifactId>
-    <version>6.4.1-SNAPSHOT</version>
+    <version>6.5.0-SNAPSHOT</version>
   </parent>
 
   <artifactId>org.eclipse.jgit.lfs.test</artifactId>
diff --git a/org.eclipse.jgit.lfs/META-INF/MANIFEST.MF b/org.eclipse.jgit.lfs/META-INF/MANIFEST.MF
index f951183..dce8d06 100644
--- a/org.eclipse.jgit.lfs/META-INF/MANIFEST.MF
+++ b/org.eclipse.jgit.lfs/META-INF/MANIFEST.MF
@@ -3,32 +3,32 @@
 Bundle-Name: %Bundle-Name
 Automatic-Module-Name: org.eclipse.jgit.lfs
 Bundle-SymbolicName: org.eclipse.jgit.lfs
-Bundle-Version: 6.4.1.qualifier
+Bundle-Version: 6.5.0.qualifier
 Bundle-Localization: plugin
 Bundle-Vendor: %Bundle-Vendor
-Export-Package: org.eclipse.jgit.lfs;version="6.4.1",
- org.eclipse.jgit.lfs.errors;version="6.4.1",
- org.eclipse.jgit.lfs.internal;version="6.4.1";x-friends:="org.eclipse.jgit.lfs.test,org.eclipse.jgit.lfs.server.fs,org.eclipse.jgit.lfs.server",
- org.eclipse.jgit.lfs.lib;version="6.4.1"
+Export-Package: org.eclipse.jgit.lfs;version="6.5.0",
+ org.eclipse.jgit.lfs.errors;version="6.5.0",
+ org.eclipse.jgit.lfs.internal;version="6.5.0";x-friends:="org.eclipse.jgit.lfs.test,org.eclipse.jgit.lfs.server.fs,org.eclipse.jgit.lfs.server",
+ org.eclipse.jgit.lfs.lib;version="6.5.0"
 Bundle-RequiredExecutionEnvironment: JavaSE-11
 Import-Package: com.google.gson;version="[2.8.2,3.0.0)",
  com.google.gson.stream;version="[2.8.2,3.0.0)",
- org.eclipse.jgit.annotations;version="[6.4.1,6.5.0)";resolution:=optional,
- org.eclipse.jgit.api.errors;version="[6.4.1,6.5.0)",
- org.eclipse.jgit.attributes;version="[6.4.1,6.5.0)",
- org.eclipse.jgit.diff;version="[6.4.1,6.5.0)",
- org.eclipse.jgit.dircache;version="[6.4.1,6.5.0)",
- org.eclipse.jgit.errors;version="[6.4.1,6.5.0)",
- org.eclipse.jgit.hooks;version="[6.4.1,6.5.0)",
- org.eclipse.jgit.internal.storage.file;version="[6.4.1,6.5.0)",
- org.eclipse.jgit.lib;version="[6.4.1,6.5.0)",
- org.eclipse.jgit.nls;version="[6.4.1,6.5.0)",
- org.eclipse.jgit.revwalk;version="[6.4.1,6.5.0)",
- org.eclipse.jgit.storage.file;version="[6.4.1,6.5.0)",
- org.eclipse.jgit.storage.pack;version="[6.4.1,6.5.0)",
- org.eclipse.jgit.transport;version="[6.4.1,6.5.0)",
- org.eclipse.jgit.transport.http;version="[6.4.1,6.5.0)",
- org.eclipse.jgit.treewalk;version="[6.4.1,6.5.0)",
- org.eclipse.jgit.treewalk.filter;version="[6.4.1,6.5.0)",
- org.eclipse.jgit.util;version="[6.4.1,6.5.0)",
- org.eclipse.jgit.util.io;version="[6.4.1,6.5.0)"
+ org.eclipse.jgit.annotations;version="[6.5.0,6.6.0)";resolution:=optional,
+ org.eclipse.jgit.api.errors;version="[6.5.0,6.6.0)",
+ org.eclipse.jgit.attributes;version="[6.5.0,6.6.0)",
+ org.eclipse.jgit.diff;version="[6.5.0,6.6.0)",
+ org.eclipse.jgit.dircache;version="[6.5.0,6.6.0)",
+ org.eclipse.jgit.errors;version="[6.5.0,6.6.0)",
+ org.eclipse.jgit.hooks;version="[6.5.0,6.6.0)",
+ org.eclipse.jgit.internal.storage.file;version="[6.5.0,6.6.0)",
+ org.eclipse.jgit.lib;version="[6.5.0,6.6.0)",
+ org.eclipse.jgit.nls;version="[6.5.0,6.6.0)",
+ org.eclipse.jgit.revwalk;version="[6.5.0,6.6.0)",
+ org.eclipse.jgit.storage.file;version="[6.5.0,6.6.0)",
+ org.eclipse.jgit.storage.pack;version="[6.5.0,6.6.0)",
+ org.eclipse.jgit.transport;version="[6.5.0,6.6.0)",
+ org.eclipse.jgit.transport.http;version="[6.5.0,6.6.0)",
+ org.eclipse.jgit.treewalk;version="[6.5.0,6.6.0)",
+ org.eclipse.jgit.treewalk.filter;version="[6.5.0,6.6.0)",
+ org.eclipse.jgit.util;version="[6.5.0,6.6.0)",
+ org.eclipse.jgit.util.io;version="[6.5.0,6.6.0)"
diff --git a/org.eclipse.jgit.lfs/META-INF/SOURCE-MANIFEST.MF b/org.eclipse.jgit.lfs/META-INF/SOURCE-MANIFEST.MF
index 62dad42..887895c 100644
--- a/org.eclipse.jgit.lfs/META-INF/SOURCE-MANIFEST.MF
+++ b/org.eclipse.jgit.lfs/META-INF/SOURCE-MANIFEST.MF
@@ -3,5 +3,5 @@
 Bundle-Name: org.eclipse.jgit.lfs - Sources
 Bundle-SymbolicName: org.eclipse.jgit.lfs.source
 Bundle-Vendor: Eclipse.org - JGit
-Bundle-Version: 6.4.1.qualifier
-Eclipse-SourceBundle: org.eclipse.jgit.lfs;version="6.4.1.qualifier";roots="."
+Bundle-Version: 6.5.0.qualifier
+Eclipse-SourceBundle: org.eclipse.jgit.lfs;version="6.5.0.qualifier";roots="."
diff --git a/org.eclipse.jgit.lfs/pom.xml b/org.eclipse.jgit.lfs/pom.xml
index 18942f0..77ec8ce 100644
--- a/org.eclipse.jgit.lfs/pom.xml
+++ b/org.eclipse.jgit.lfs/pom.xml
@@ -17,7 +17,7 @@
   <parent>
     <groupId>org.eclipse.jgit</groupId>
     <artifactId>org.eclipse.jgit-parent</artifactId>
-    <version>6.4.1-SNAPSHOT</version>
+    <version>6.5.0-SNAPSHOT</version>
   </parent>
 
   <artifactId>org.eclipse.jgit.lfs</artifactId>
diff --git a/org.eclipse.jgit.packaging/org.eclipse.jgit.feature/feature.xml b/org.eclipse.jgit.packaging/org.eclipse.jgit.feature/feature.xml
index 7930aa1..7b53b08 100644
--- a/org.eclipse.jgit.packaging/org.eclipse.jgit.feature/feature.xml
+++ b/org.eclipse.jgit.packaging/org.eclipse.jgit.feature/feature.xml
@@ -2,7 +2,7 @@
 <feature
       id="org.eclipse.jgit"
       label="%featureName"
-      version="6.4.1.qualifier"
+      version="6.5.0.qualifier"
       provider-name="%providerName">
 
    <description url="http://www.eclipse.org/jgit/">
diff --git a/org.eclipse.jgit.packaging/org.eclipse.jgit.feature/pom.xml b/org.eclipse.jgit.packaging/org.eclipse.jgit.feature/pom.xml
index 93f42ab..9cb0cdb 100644
--- a/org.eclipse.jgit.packaging/org.eclipse.jgit.feature/pom.xml
+++ b/org.eclipse.jgit.packaging/org.eclipse.jgit.feature/pom.xml
@@ -17,7 +17,7 @@
   <parent>
     <groupId>org.eclipse.jgit</groupId>
     <artifactId>jgit.tycho.parent</artifactId>
-    <version>6.4.1-SNAPSHOT</version>
+    <version>6.5.0-SNAPSHOT</version>
   </parent>
 
   <groupId>org.eclipse.jgit.feature</groupId>
diff --git a/org.eclipse.jgit.packaging/org.eclipse.jgit.gpg.bc.feature/feature.xml b/org.eclipse.jgit.packaging/org.eclipse.jgit.gpg.bc.feature/feature.xml
index 5acf8ff..5b974e8 100644
--- a/org.eclipse.jgit.packaging/org.eclipse.jgit.gpg.bc.feature/feature.xml
+++ b/org.eclipse.jgit.packaging/org.eclipse.jgit.gpg.bc.feature/feature.xml
@@ -2,7 +2,7 @@
 <feature
       id="org.eclipse.jgit.gpg.bc"
       label="%featureName"
-      version="6.4.1.qualifier"
+      version="6.5.0.qualifier"
       provider-name="%providerName">
 
    <description url="http://www.eclipse.org/jgit/">
@@ -23,7 +23,7 @@
    </url>
 
    <requires>
-      <import plugin="org.eclipse.jgit" version="6.4.1" match="equivalent"/>
+      <import plugin="org.eclipse.jgit" version="6.5.0" match="equivalent"/>
    </requires>
 
    <plugin
diff --git a/org.eclipse.jgit.packaging/org.eclipse.jgit.gpg.bc.feature/pom.xml b/org.eclipse.jgit.packaging/org.eclipse.jgit.gpg.bc.feature/pom.xml
index bf6fe5d..7447206 100644
--- a/org.eclipse.jgit.packaging/org.eclipse.jgit.gpg.bc.feature/pom.xml
+++ b/org.eclipse.jgit.packaging/org.eclipse.jgit.gpg.bc.feature/pom.xml
@@ -17,7 +17,7 @@
   <parent>
     <groupId>org.eclipse.jgit</groupId>
     <artifactId>jgit.tycho.parent</artifactId>
-    <version>6.4.1-SNAPSHOT</version>
+    <version>6.5.0-SNAPSHOT</version>
   </parent>
 
   <groupId>org.eclipse.jgit.feature</groupId>
diff --git a/org.eclipse.jgit.packaging/org.eclipse.jgit.http.apache.feature/feature.xml b/org.eclipse.jgit.packaging/org.eclipse.jgit.http.apache.feature/feature.xml
index 85ff865..b5a3804 100644
--- a/org.eclipse.jgit.packaging/org.eclipse.jgit.http.apache.feature/feature.xml
+++ b/org.eclipse.jgit.packaging/org.eclipse.jgit.http.apache.feature/feature.xml
@@ -2,7 +2,7 @@
 <feature
       id="org.eclipse.jgit.http.apache"
       label="%featureName"
-      version="6.4.1.qualifier"
+      version="6.5.0.qualifier"
       provider-name="%providerName">
 
    <description url="http://www.eclipse.org/jgit/">
@@ -23,7 +23,7 @@
    </url>
 
    <requires>
-      <import plugin="org.eclipse.jgit" version="6.4.1" match="equivalent"/>
+      <import plugin="org.eclipse.jgit" version="6.5.0" match="equivalent"/>
    </requires>
 
    <plugin
diff --git a/org.eclipse.jgit.packaging/org.eclipse.jgit.http.apache.feature/pom.xml b/org.eclipse.jgit.packaging/org.eclipse.jgit.http.apache.feature/pom.xml
index a1f6f0f..a84941e 100644
--- a/org.eclipse.jgit.packaging/org.eclipse.jgit.http.apache.feature/pom.xml
+++ b/org.eclipse.jgit.packaging/org.eclipse.jgit.http.apache.feature/pom.xml
@@ -17,7 +17,7 @@
   <parent>
     <groupId>org.eclipse.jgit</groupId>
     <artifactId>jgit.tycho.parent</artifactId>
-    <version>6.4.1-SNAPSHOT</version>
+    <version>6.5.0-SNAPSHOT</version>
   </parent>
 
   <groupId>org.eclipse.jgit.feature</groupId>
diff --git a/org.eclipse.jgit.packaging/org.eclipse.jgit.junit.feature/feature.xml b/org.eclipse.jgit.packaging/org.eclipse.jgit.junit.feature/feature.xml
index 55fdba6..59bdb39 100644
--- a/org.eclipse.jgit.packaging/org.eclipse.jgit.junit.feature/feature.xml
+++ b/org.eclipse.jgit.packaging/org.eclipse.jgit.junit.feature/feature.xml
@@ -2,7 +2,7 @@
 <feature
       id="org.eclipse.jgit.junit"
       label="%featureName"
-      version="6.4.1.qualifier"
+      version="6.5.0.qualifier"
       provider-name="%providerName">
 
    <description url="http://www.eclipse.org/jgit/">
@@ -24,7 +24,7 @@
 
    <requires>
       <import plugin="com.jcraft.jsch"/>
-      <import plugin="org.eclipse.jgit" version="6.4.1" match="equivalent"/>
+      <import plugin="org.eclipse.jgit" version="6.5.0" match="equivalent"/>
    </requires>
 
    <plugin
diff --git a/org.eclipse.jgit.packaging/org.eclipse.jgit.junit.feature/pom.xml b/org.eclipse.jgit.packaging/org.eclipse.jgit.junit.feature/pom.xml
index 88b2cd2..c9f7096 100644
--- a/org.eclipse.jgit.packaging/org.eclipse.jgit.junit.feature/pom.xml
+++ b/org.eclipse.jgit.packaging/org.eclipse.jgit.junit.feature/pom.xml
@@ -17,7 +17,7 @@
   <parent>
     <groupId>org.eclipse.jgit</groupId>
     <artifactId>jgit.tycho.parent</artifactId>
-    <version>6.4.1-SNAPSHOT</version>
+    <version>6.5.0-SNAPSHOT</version>
   </parent>
 
   <groupId>org.eclipse.jgit.feature</groupId>
diff --git a/org.eclipse.jgit.packaging/org.eclipse.jgit.lfs.feature/feature.xml b/org.eclipse.jgit.packaging/org.eclipse.jgit.lfs.feature/feature.xml
index 4ef4c5d..b4388a6 100644
--- a/org.eclipse.jgit.packaging/org.eclipse.jgit.lfs.feature/feature.xml
+++ b/org.eclipse.jgit.packaging/org.eclipse.jgit.lfs.feature/feature.xml
@@ -2,7 +2,7 @@
 <feature
       id="org.eclipse.jgit.lfs"
       label="%featureName"
-      version="6.4.1.qualifier"
+      version="6.5.0.qualifier"
       provider-name="%providerName">
 
    <description url="http://www.eclipse.org/jgit/">
@@ -23,7 +23,7 @@
    </url>
 
    <requires>
-      <import feature="org.eclipse.jgit" version="6.4.1" match="equivalent"/>
+      <import feature="org.eclipse.jgit" version="6.5.0" match="equivalent"/>
    </requires>
 
    <plugin
diff --git a/org.eclipse.jgit.packaging/org.eclipse.jgit.lfs.feature/pom.xml b/org.eclipse.jgit.packaging/org.eclipse.jgit.lfs.feature/pom.xml
index 9a4d7fd..7427583 100644
--- a/org.eclipse.jgit.packaging/org.eclipse.jgit.lfs.feature/pom.xml
+++ b/org.eclipse.jgit.packaging/org.eclipse.jgit.lfs.feature/pom.xml
@@ -17,7 +17,7 @@
   <parent>
     <groupId>org.eclipse.jgit</groupId>
     <artifactId>jgit.tycho.parent</artifactId>
-    <version>6.4.1-SNAPSHOT</version>
+    <version>6.5.0-SNAPSHOT</version>
   </parent>
 
   <groupId>org.eclipse.jgit.feature</groupId>
diff --git a/org.eclipse.jgit.packaging/org.eclipse.jgit.pgm.feature/feature.xml b/org.eclipse.jgit.packaging/org.eclipse.jgit.pgm.feature/feature.xml
index 6573c6f..98360ca 100644
--- a/org.eclipse.jgit.packaging/org.eclipse.jgit.pgm.feature/feature.xml
+++ b/org.eclipse.jgit.packaging/org.eclipse.jgit.pgm.feature/feature.xml
@@ -2,7 +2,7 @@
 <feature
       id="org.eclipse.jgit.pgm"
       label="%featureName"
-      version="6.4.1.qualifier"
+      version="6.5.0.qualifier"
       provider-name="%providerName">
 
    <description url="http://www.eclipse.org/jgit/">
@@ -35,9 +35,9 @@
          version="0.0.0"/>
 
    <requires>
-      <import feature="org.eclipse.jgit" version="6.4.1" match="equivalent"/>
-      <import feature="org.eclipse.jgit.lfs" version="6.4.1" match="equivalent"/>
-      <import feature="org.eclipse.jgit.ssh.apache" version="6.4.1" match="equivalent"/>
+      <import feature="org.eclipse.jgit" version="6.5.0" match="equivalent"/>
+      <import feature="org.eclipse.jgit.lfs" version="6.5.0" match="equivalent"/>
+      <import feature="org.eclipse.jgit.ssh.apache" version="6.5.0" match="equivalent"/>
    </requires>
 
    <plugin
diff --git a/org.eclipse.jgit.packaging/org.eclipse.jgit.pgm.feature/pom.xml b/org.eclipse.jgit.packaging/org.eclipse.jgit.pgm.feature/pom.xml
index 979c357..fceb1d7 100644
--- a/org.eclipse.jgit.packaging/org.eclipse.jgit.pgm.feature/pom.xml
+++ b/org.eclipse.jgit.packaging/org.eclipse.jgit.pgm.feature/pom.xml
@@ -17,7 +17,7 @@
   <parent>
     <groupId>org.eclipse.jgit</groupId>
     <artifactId>jgit.tycho.parent</artifactId>
-    <version>6.4.1-SNAPSHOT</version>
+    <version>6.5.0-SNAPSHOT</version>
   </parent>
 
   <groupId>org.eclipse.jgit.feature</groupId>
diff --git a/org.eclipse.jgit.packaging/org.eclipse.jgit.repository/pom.xml b/org.eclipse.jgit.packaging/org.eclipse.jgit.repository/pom.xml
index a091a7e..c6ec82d 100644
--- a/org.eclipse.jgit.packaging/org.eclipse.jgit.repository/pom.xml
+++ b/org.eclipse.jgit.packaging/org.eclipse.jgit.repository/pom.xml
@@ -17,7 +17,7 @@
   <parent>
     <groupId>org.eclipse.jgit</groupId>
     <artifactId>jgit.tycho.parent</artifactId>
-    <version>6.4.1-SNAPSHOT</version>
+    <version>6.5.0-SNAPSHOT</version>
   </parent>
 
   <artifactId>org.eclipse.jgit.repository</artifactId>
diff --git a/org.eclipse.jgit.packaging/org.eclipse.jgit.source.feature/feature.xml b/org.eclipse.jgit.packaging/org.eclipse.jgit.source.feature/feature.xml
index 1b45654..f449c5b 100644
--- a/org.eclipse.jgit.packaging/org.eclipse.jgit.source.feature/feature.xml
+++ b/org.eclipse.jgit.packaging/org.eclipse.jgit.source.feature/feature.xml
@@ -2,7 +2,7 @@
 <feature
       id="org.eclipse.jgit.source"
       label="%featureName"
-      version="6.4.1.qualifier"
+      version="6.5.0.qualifier"
       provider-name="%providerName">
 
    <description url="http://www.eclipse.org/jgit/">
@@ -23,7 +23,7 @@
    </url>
 
    <requires>
-      <import feature="org.eclipse.jgit" version="6.4.1" match="equivalent"/>
+      <import feature="org.eclipse.jgit" version="6.5.0" match="equivalent"/>
    </requires>
 
    <plugin
diff --git a/org.eclipse.jgit.packaging/org.eclipse.jgit.source.feature/pom.xml b/org.eclipse.jgit.packaging/org.eclipse.jgit.source.feature/pom.xml
index 382375b..e467c45 100644
--- a/org.eclipse.jgit.packaging/org.eclipse.jgit.source.feature/pom.xml
+++ b/org.eclipse.jgit.packaging/org.eclipse.jgit.source.feature/pom.xml
@@ -17,7 +17,7 @@
   <parent>
     <groupId>org.eclipse.jgit</groupId>
     <artifactId>jgit.tycho.parent</artifactId>
-    <version>6.4.1-SNAPSHOT</version>
+    <version>6.5.0-SNAPSHOT</version>
   </parent>
 
   <groupId>org.eclipse.jgit.feature</groupId>
@@ -30,7 +30,7 @@
     <dependency>
       <groupId>org.eclipse.jgit.feature</groupId>
       <artifactId>org.eclipse.jgit</artifactId>
-      <version>6.4.1-SNAPSHOT</version>
+      <version>6.5.0-SNAPSHOT</version>
     </dependency>
   </dependencies>
 
diff --git a/org.eclipse.jgit.packaging/org.eclipse.jgit.ssh.apache.feature/feature.xml b/org.eclipse.jgit.packaging/org.eclipse.jgit.ssh.apache.feature/feature.xml
index c904e2d..e965de1 100644
--- a/org.eclipse.jgit.packaging/org.eclipse.jgit.ssh.apache.feature/feature.xml
+++ b/org.eclipse.jgit.packaging/org.eclipse.jgit.ssh.apache.feature/feature.xml
@@ -2,7 +2,7 @@
 <feature
       id="org.eclipse.jgit.ssh.apache"
       label="%featureName"
-      version="6.4.1.qualifier"
+      version="6.5.0.qualifier"
       provider-name="%providerName">
 
    <description url="http://www.eclipse.org/jgit/">
@@ -23,7 +23,7 @@
    </url>
 
    <requires>
-      <import feature="org.eclipse.jgit" version="6.4.1" match="equivalent"/>
+      <import feature="org.eclipse.jgit" version="6.5.0" match="equivalent"/>
    </requires>
 
    <plugin
diff --git a/org.eclipse.jgit.packaging/org.eclipse.jgit.ssh.apache.feature/pom.xml b/org.eclipse.jgit.packaging/org.eclipse.jgit.ssh.apache.feature/pom.xml
index 669213d..6d99c4f 100644
--- a/org.eclipse.jgit.packaging/org.eclipse.jgit.ssh.apache.feature/pom.xml
+++ b/org.eclipse.jgit.packaging/org.eclipse.jgit.ssh.apache.feature/pom.xml
@@ -17,7 +17,7 @@
   <parent>
     <groupId>org.eclipse.jgit</groupId>
     <artifactId>jgit.tycho.parent</artifactId>
-    <version>6.4.1-SNAPSHOT</version>
+    <version>6.5.0-SNAPSHOT</version>
   </parent>
 
   <groupId>org.eclipse.jgit.feature</groupId>
diff --git a/org.eclipse.jgit.packaging/org.eclipse.jgit.ssh.jsch.feature/feature.xml b/org.eclipse.jgit.packaging/org.eclipse.jgit.ssh.jsch.feature/feature.xml
index 8c4a14b..c835dcc 100644
--- a/org.eclipse.jgit.packaging/org.eclipse.jgit.ssh.jsch.feature/feature.xml
+++ b/org.eclipse.jgit.packaging/org.eclipse.jgit.ssh.jsch.feature/feature.xml
@@ -2,7 +2,7 @@
 <feature
       id="org.eclipse.jgit.ssh.jsch"
       label="%featureName"
-      version="6.4.1.qualifier"
+      version="6.5.0.qualifier"
       provider-name="%providerName">
 
    <description url="http://www.eclipse.org/jgit/">
@@ -23,7 +23,7 @@
    </url>
 
    <requires>
-      <import plugin="org.eclipse.jgit" version="6.4.1" match="equivalent"/>
+      <import plugin="org.eclipse.jgit" version="6.5.0" match="equivalent"/>
    </requires>
 
    <plugin
diff --git a/org.eclipse.jgit.packaging/org.eclipse.jgit.ssh.jsch.feature/pom.xml b/org.eclipse.jgit.packaging/org.eclipse.jgit.ssh.jsch.feature/pom.xml
index 7d1a08f..033a789 100644
--- a/org.eclipse.jgit.packaging/org.eclipse.jgit.ssh.jsch.feature/pom.xml
+++ b/org.eclipse.jgit.packaging/org.eclipse.jgit.ssh.jsch.feature/pom.xml
@@ -17,7 +17,7 @@
   <parent>
     <groupId>org.eclipse.jgit</groupId>
     <artifactId>jgit.tycho.parent</artifactId>
-    <version>6.4.1-SNAPSHOT</version>
+    <version>6.5.0-SNAPSHOT</version>
   </parent>
 
   <groupId>org.eclipse.jgit.feature</groupId>
diff --git a/org.eclipse.jgit.packaging/org.eclipse.jgit.target/META-INF/MANIFEST.MF b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/META-INF/MANIFEST.MF
index ee07a32..6c9e0bb 100644
--- a/org.eclipse.jgit.packaging/org.eclipse.jgit.target/META-INF/MANIFEST.MF
+++ b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/META-INF/MANIFEST.MF
@@ -2,4 +2,4 @@
 Bundle-ManifestVersion: 2
 Bundle-Name: JGit Target Platform Bundle
 Bundle-SymbolicName: org.eclipse.jgit.target
-Bundle-Version: 6.4.1.qualifier
+Bundle-Version: 6.5.0.qualifier
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 d5ee87b..72f96f3 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,30 +1,26 @@
 <?xml version="1.0" encoding="UTF-8" standalone="no"?>
 <?pde?>
 <!-- generated with https://github.com/eclipse-cbi/targetplatform-dsl -->
-<target name="jgit-4.17" sequenceNumber="1669195943">
+<target name="jgit-4.17" sequenceNumber="1673875570">
   <locations>
     <location includeMode="slicer" includeAllPlatforms="false" includeSource="true" includeConfigurePhase="true" type="InstallableUnit">
+      <unit id="org.eclipse.jetty.http" version="10.0.13"/>
+      <unit id="org.eclipse.jetty.io" version="10.0.13"/>
+      <unit id="org.eclipse.jetty.security" version="10.0.13"/>
+      <unit id="org.eclipse.jetty.server" version="10.0.13"/>
+      <unit id="org.eclipse.jetty.servlet" version="10.0.13"/>
+      <unit id="org.eclipse.jetty.util" version="10.0.13"/>
+      <unit id="org.eclipse.jetty.util.ajax" version="10.0.13"/>
+      <repository id="jetty-10.0.x" location="https://download.eclipse.org/oomph/jetty/release/10.0.13/"/>
+    </location>
+    <location includeMode="slicer" includeAllPlatforms="false" includeSource="true" includeConfigurePhase="true" type="InstallableUnit">
       <unit id="jakarta.servlet-api" version="4.0.0"/>
       <unit id="jakarta.servlet-api.source" version="4.0.0"/>
-      <unit id="org.eclipse.jetty.http" version="10.0.6"/>
-      <unit id="org.eclipse.jetty.http.source" version="10.0.6"/>
-      <unit id="org.eclipse.jetty.io" version="10.0.6"/>
-      <unit id="org.eclipse.jetty.io.source" version="10.0.6"/>
-      <unit id="org.eclipse.jetty.security" version="10.0.6"/>
-      <unit id="org.eclipse.jetty.security.source" version="10.0.6"/>
-      <unit id="org.eclipse.jetty.server" version="10.0.6"/>
-      <unit id="org.eclipse.jetty.server.source" version="10.0.6"/>
-      <unit id="org.eclipse.jetty.servlet" version="10.0.6"/>
-      <unit id="org.eclipse.jetty.servlet.source" version="10.0.6"/>
-      <unit id="org.eclipse.jetty.util" version="10.0.6"/>
-      <unit id="org.eclipse.jetty.util.source" version="10.0.6"/>
-      <unit id="org.eclipse.jetty.util.ajax" version="10.0.6"/>
-      <unit id="org.eclipse.jetty.util.ajax.source" version="10.0.6"/>
-      <repository id="jetty-10.0.x" location="https://download.eclipse.org/eclipse/jetty/10.0.6/"/>
+      <repository id="jetty-10.0.6" location="https://download.eclipse.org/eclipse/jetty/10.0.6/"/>
     </location>
     <location includeMode="slicer" includeAllPlatforms="false" includeSource="true" includeConfigurePhase="true" type="InstallableUnit">
-      <unit id="com.google.gson" version="2.9.1.v20220915-1632"/>
-      <unit id="com.google.gson.source" version="2.9.1.v20220915-1632"/>
+      <unit id="com.google.gson" version="2.10.0.v20221207-1049"/>
+      <unit id="com.google.gson.source" version="2.10.0.v20221207-1049"/>
       <unit id="com.jcraft.jsch" version="0.1.55.v20221112-0806"/>
       <unit id="com.jcraft.jsch.source" version="0.1.55.v20221112-0806"/>
       <unit id="com.jcraft.jzlib" version="1.1.3.v20220502-1820"/>
@@ -45,14 +41,14 @@
       <unit id="org.apache.ant.source" version="1.10.12.v20211102-1452"/>
       <unit id="org.apache.commons.codec" version="1.14.0.v20221112-0806"/>
       <unit id="org.apache.commons.codec.source" version="1.14.0.v20221112-0806"/>
-      <unit id="org.apache.commons.compress" version="1.21.0.v20211103-2100"/>
-      <unit id="org.apache.commons.compress.source" version="1.21.0.v20211103-2100"/>
+      <unit id="org.apache.commons.compress" version="1.22.0.v20221207-1049"/>
+      <unit id="org.apache.commons.compress.source" version="1.22.0.v20221207-1049"/>
       <unit id="org.apache.commons.logging" version="1.2.0.v20180409-1502"/>
       <unit id="org.apache.commons.logging.source" version="1.2.0.v20180409-1502"/>
-      <unit id="org.apache.httpcomponents.httpclient" version="4.5.13.v20221112-0806"/>
-      <unit id="org.apache.httpcomponents.httpclient.source" version="4.5.13.v20221112-0806"/>
-      <unit id="org.apache.httpcomponents.httpcore" version="4.4.15.v20220209-2345"/>
-      <unit id="org.apache.httpcomponents.httpcore.source" version="4.4.15.v20220209-2345"/>
+      <unit id="org.apache.httpcomponents.httpclient" version="4.5.14.v20221207-1049"/>
+      <unit id="org.apache.httpcomponents.httpclient.source" version="4.5.14.v20221207-1049"/>
+      <unit id="org.apache.httpcomponents.httpcore" version="4.4.16.v20221207-1049"/>
+      <unit id="org.apache.httpcomponents.httpcore.source" version="4.4.16.v20221207-1049"/>
       <unit id="org.apache.sshd.osgi" version="2.9.2.v20221117-1942"/>
       <unit id="org.apache.sshd.osgi.source" version="2.9.2.v20221117-1942"/>
       <unit id="org.apache.sshd.sftp" version="2.9.2.v20221117-1942"/>
@@ -87,7 +83,7 @@
       <unit id="org.slf4j.binding.simple.source" version="1.7.30.v20221112-0806"/>
       <unit id="org.tukaani.xz" version="1.9.0.v20210624-1259"/>
       <unit id="org.tukaani.xz.source" version="1.9.0.v20210624-1259"/>
-      <repository location="https://download.eclipse.org/tools/orbit/downloads/drops/R20221123021534/repository"/>
+      <repository location="https://download.eclipse.org/tools/orbit/downloads/drops/S20230101190934/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 60438d7..ef498ef 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-10.0.x.tpd"
-include "orbit/R20221123021534-2022-12.tpd"
+include "orbit/S20230101190934.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 36e37b1..a871c58 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,30 +1,26 @@
 <?xml version="1.0" encoding="UTF-8" standalone="no"?>
 <?pde?>
 <!-- generated with https://github.com/eclipse-cbi/targetplatform-dsl -->
-<target name="jgit-4.18" sequenceNumber="1669195943">
+<target name="jgit-4.18" sequenceNumber="1673875570">
   <locations>
     <location includeMode="slicer" includeAllPlatforms="false" includeSource="true" includeConfigurePhase="true" type="InstallableUnit">
+      <unit id="org.eclipse.jetty.http" version="10.0.13"/>
+      <unit id="org.eclipse.jetty.io" version="10.0.13"/>
+      <unit id="org.eclipse.jetty.security" version="10.0.13"/>
+      <unit id="org.eclipse.jetty.server" version="10.0.13"/>
+      <unit id="org.eclipse.jetty.servlet" version="10.0.13"/>
+      <unit id="org.eclipse.jetty.util" version="10.0.13"/>
+      <unit id="org.eclipse.jetty.util.ajax" version="10.0.13"/>
+      <repository id="jetty-10.0.x" location="https://download.eclipse.org/oomph/jetty/release/10.0.13/"/>
+    </location>
+    <location includeMode="slicer" includeAllPlatforms="false" includeSource="true" includeConfigurePhase="true" type="InstallableUnit">
       <unit id="jakarta.servlet-api" version="4.0.0"/>
       <unit id="jakarta.servlet-api.source" version="4.0.0"/>
-      <unit id="org.eclipse.jetty.http" version="10.0.6"/>
-      <unit id="org.eclipse.jetty.http.source" version="10.0.6"/>
-      <unit id="org.eclipse.jetty.io" version="10.0.6"/>
-      <unit id="org.eclipse.jetty.io.source" version="10.0.6"/>
-      <unit id="org.eclipse.jetty.security" version="10.0.6"/>
-      <unit id="org.eclipse.jetty.security.source" version="10.0.6"/>
-      <unit id="org.eclipse.jetty.server" version="10.0.6"/>
-      <unit id="org.eclipse.jetty.server.source" version="10.0.6"/>
-      <unit id="org.eclipse.jetty.servlet" version="10.0.6"/>
-      <unit id="org.eclipse.jetty.servlet.source" version="10.0.6"/>
-      <unit id="org.eclipse.jetty.util" version="10.0.6"/>
-      <unit id="org.eclipse.jetty.util.source" version="10.0.6"/>
-      <unit id="org.eclipse.jetty.util.ajax" version="10.0.6"/>
-      <unit id="org.eclipse.jetty.util.ajax.source" version="10.0.6"/>
-      <repository id="jetty-10.0.x" location="https://download.eclipse.org/eclipse/jetty/10.0.6/"/>
+      <repository id="jetty-10.0.6" location="https://download.eclipse.org/eclipse/jetty/10.0.6/"/>
     </location>
     <location includeMode="slicer" includeAllPlatforms="false" includeSource="true" includeConfigurePhase="true" type="InstallableUnit">
-      <unit id="com.google.gson" version="2.9.1.v20220915-1632"/>
-      <unit id="com.google.gson.source" version="2.9.1.v20220915-1632"/>
+      <unit id="com.google.gson" version="2.10.0.v20221207-1049"/>
+      <unit id="com.google.gson.source" version="2.10.0.v20221207-1049"/>
       <unit id="com.jcraft.jsch" version="0.1.55.v20221112-0806"/>
       <unit id="com.jcraft.jsch.source" version="0.1.55.v20221112-0806"/>
       <unit id="com.jcraft.jzlib" version="1.1.3.v20220502-1820"/>
@@ -45,14 +41,14 @@
       <unit id="org.apache.ant.source" version="1.10.12.v20211102-1452"/>
       <unit id="org.apache.commons.codec" version="1.14.0.v20221112-0806"/>
       <unit id="org.apache.commons.codec.source" version="1.14.0.v20221112-0806"/>
-      <unit id="org.apache.commons.compress" version="1.21.0.v20211103-2100"/>
-      <unit id="org.apache.commons.compress.source" version="1.21.0.v20211103-2100"/>
+      <unit id="org.apache.commons.compress" version="1.22.0.v20221207-1049"/>
+      <unit id="org.apache.commons.compress.source" version="1.22.0.v20221207-1049"/>
       <unit id="org.apache.commons.logging" version="1.2.0.v20180409-1502"/>
       <unit id="org.apache.commons.logging.source" version="1.2.0.v20180409-1502"/>
-      <unit id="org.apache.httpcomponents.httpclient" version="4.5.13.v20221112-0806"/>
-      <unit id="org.apache.httpcomponents.httpclient.source" version="4.5.13.v20221112-0806"/>
-      <unit id="org.apache.httpcomponents.httpcore" version="4.4.15.v20220209-2345"/>
-      <unit id="org.apache.httpcomponents.httpcore.source" version="4.4.15.v20220209-2345"/>
+      <unit id="org.apache.httpcomponents.httpclient" version="4.5.14.v20221207-1049"/>
+      <unit id="org.apache.httpcomponents.httpclient.source" version="4.5.14.v20221207-1049"/>
+      <unit id="org.apache.httpcomponents.httpcore" version="4.4.16.v20221207-1049"/>
+      <unit id="org.apache.httpcomponents.httpcore.source" version="4.4.16.v20221207-1049"/>
       <unit id="org.apache.sshd.osgi" version="2.9.2.v20221117-1942"/>
       <unit id="org.apache.sshd.osgi.source" version="2.9.2.v20221117-1942"/>
       <unit id="org.apache.sshd.sftp" version="2.9.2.v20221117-1942"/>
@@ -87,7 +83,7 @@
       <unit id="org.slf4j.binding.simple.source" version="1.7.30.v20221112-0806"/>
       <unit id="org.tukaani.xz" version="1.9.0.v20210624-1259"/>
       <unit id="org.tukaani.xz.source" version="1.9.0.v20210624-1259"/>
-      <repository location="https://download.eclipse.org/tools/orbit/downloads/drops/R20221123021534/repository"/>
+      <repository location="https://download.eclipse.org/tools/orbit/downloads/drops/S20230101190934/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 c894dfe..3abc209 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-10.0.x.tpd"
-include "orbit/R20221123021534-2022-12.tpd"
+include "orbit/S20230101190934.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 2966e88..819a065 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,30 +1,26 @@
 <?xml version="1.0" encoding="UTF-8" standalone="no"?>
 <?pde?>
 <!-- generated with https://github.com/eclipse-cbi/targetplatform-dsl -->
-<target name="jgit-4.19-staging" sequenceNumber="1669195941">
+<target name="jgit-4.19-staging" sequenceNumber="1673875570">
   <locations>
     <location includeMode="slicer" includeAllPlatforms="false" includeSource="true" includeConfigurePhase="true" type="InstallableUnit">
+      <unit id="org.eclipse.jetty.http" version="10.0.13"/>
+      <unit id="org.eclipse.jetty.io" version="10.0.13"/>
+      <unit id="org.eclipse.jetty.security" version="10.0.13"/>
+      <unit id="org.eclipse.jetty.server" version="10.0.13"/>
+      <unit id="org.eclipse.jetty.servlet" version="10.0.13"/>
+      <unit id="org.eclipse.jetty.util" version="10.0.13"/>
+      <unit id="org.eclipse.jetty.util.ajax" version="10.0.13"/>
+      <repository id="jetty-10.0.x" location="https://download.eclipse.org/oomph/jetty/release/10.0.13/"/>
+    </location>
+    <location includeMode="slicer" includeAllPlatforms="false" includeSource="true" includeConfigurePhase="true" type="InstallableUnit">
       <unit id="jakarta.servlet-api" version="4.0.0"/>
       <unit id="jakarta.servlet-api.source" version="4.0.0"/>
-      <unit id="org.eclipse.jetty.http" version="10.0.6"/>
-      <unit id="org.eclipse.jetty.http.source" version="10.0.6"/>
-      <unit id="org.eclipse.jetty.io" version="10.0.6"/>
-      <unit id="org.eclipse.jetty.io.source" version="10.0.6"/>
-      <unit id="org.eclipse.jetty.security" version="10.0.6"/>
-      <unit id="org.eclipse.jetty.security.source" version="10.0.6"/>
-      <unit id="org.eclipse.jetty.server" version="10.0.6"/>
-      <unit id="org.eclipse.jetty.server.source" version="10.0.6"/>
-      <unit id="org.eclipse.jetty.servlet" version="10.0.6"/>
-      <unit id="org.eclipse.jetty.servlet.source" version="10.0.6"/>
-      <unit id="org.eclipse.jetty.util" version="10.0.6"/>
-      <unit id="org.eclipse.jetty.util.source" version="10.0.6"/>
-      <unit id="org.eclipse.jetty.util.ajax" version="10.0.6"/>
-      <unit id="org.eclipse.jetty.util.ajax.source" version="10.0.6"/>
-      <repository id="jetty-10.0.x" location="https://download.eclipse.org/eclipse/jetty/10.0.6/"/>
+      <repository id="jetty-10.0.6" location="https://download.eclipse.org/eclipse/jetty/10.0.6/"/>
     </location>
     <location includeMode="slicer" includeAllPlatforms="false" includeSource="true" includeConfigurePhase="true" type="InstallableUnit">
-      <unit id="com.google.gson" version="2.9.1.v20220915-1632"/>
-      <unit id="com.google.gson.source" version="2.9.1.v20220915-1632"/>
+      <unit id="com.google.gson" version="2.10.0.v20221207-1049"/>
+      <unit id="com.google.gson.source" version="2.10.0.v20221207-1049"/>
       <unit id="com.jcraft.jsch" version="0.1.55.v20221112-0806"/>
       <unit id="com.jcraft.jsch.source" version="0.1.55.v20221112-0806"/>
       <unit id="com.jcraft.jzlib" version="1.1.3.v20220502-1820"/>
@@ -45,14 +41,14 @@
       <unit id="org.apache.ant.source" version="1.10.12.v20211102-1452"/>
       <unit id="org.apache.commons.codec" version="1.14.0.v20221112-0806"/>
       <unit id="org.apache.commons.codec.source" version="1.14.0.v20221112-0806"/>
-      <unit id="org.apache.commons.compress" version="1.21.0.v20211103-2100"/>
-      <unit id="org.apache.commons.compress.source" version="1.21.0.v20211103-2100"/>
+      <unit id="org.apache.commons.compress" version="1.22.0.v20221207-1049"/>
+      <unit id="org.apache.commons.compress.source" version="1.22.0.v20221207-1049"/>
       <unit id="org.apache.commons.logging" version="1.2.0.v20180409-1502"/>
       <unit id="org.apache.commons.logging.source" version="1.2.0.v20180409-1502"/>
-      <unit id="org.apache.httpcomponents.httpclient" version="4.5.13.v20221112-0806"/>
-      <unit id="org.apache.httpcomponents.httpclient.source" version="4.5.13.v20221112-0806"/>
-      <unit id="org.apache.httpcomponents.httpcore" version="4.4.15.v20220209-2345"/>
-      <unit id="org.apache.httpcomponents.httpcore.source" version="4.4.15.v20220209-2345"/>
+      <unit id="org.apache.httpcomponents.httpclient" version="4.5.14.v20221207-1049"/>
+      <unit id="org.apache.httpcomponents.httpclient.source" version="4.5.14.v20221207-1049"/>
+      <unit id="org.apache.httpcomponents.httpcore" version="4.4.16.v20221207-1049"/>
+      <unit id="org.apache.httpcomponents.httpcore.source" version="4.4.16.v20221207-1049"/>
       <unit id="org.apache.sshd.osgi" version="2.9.2.v20221117-1942"/>
       <unit id="org.apache.sshd.osgi.source" version="2.9.2.v20221117-1942"/>
       <unit id="org.apache.sshd.sftp" version="2.9.2.v20221117-1942"/>
@@ -87,7 +83,7 @@
       <unit id="org.slf4j.binding.simple.source" version="1.7.30.v20221112-0806"/>
       <unit id="org.tukaani.xz" version="1.9.0.v20210624-1259"/>
       <unit id="org.tukaani.xz.source" version="1.9.0.v20210624-1259"/>
-      <repository location="https://download.eclipse.org/tools/orbit/downloads/drops/R20221123021534/repository"/>
+      <repository location="https://download.eclipse.org/tools/orbit/downloads/drops/S20230101190934/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 6157842..a13bc20 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-10.0.x.tpd"
-include "orbit/R20221123021534-2022-12.tpd"
+include "orbit/S20230101190934.tpd"
 
 location "https://download.eclipse.org/releases/2021-03/" {
 	org.eclipse.osgi lazy
diff --git a/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.20.target b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.20.target
index 6e6e7fb..cd615ff 100644
--- a/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.20.target
+++ b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.20.target
@@ -1,30 +1,26 @@
 <?xml version="1.0" encoding="UTF-8" standalone="no"?>
 <?pde?>
 <!-- generated with https://github.com/eclipse-cbi/targetplatform-dsl -->
-<target name="jgit-4.20" sequenceNumber="1669195941">
+<target name="jgit-4.20" sequenceNumber="1673875570">
   <locations>
     <location includeMode="slicer" includeAllPlatforms="false" includeSource="true" includeConfigurePhase="true" type="InstallableUnit">
+      <unit id="org.eclipse.jetty.http" version="10.0.13"/>
+      <unit id="org.eclipse.jetty.io" version="10.0.13"/>
+      <unit id="org.eclipse.jetty.security" version="10.0.13"/>
+      <unit id="org.eclipse.jetty.server" version="10.0.13"/>
+      <unit id="org.eclipse.jetty.servlet" version="10.0.13"/>
+      <unit id="org.eclipse.jetty.util" version="10.0.13"/>
+      <unit id="org.eclipse.jetty.util.ajax" version="10.0.13"/>
+      <repository id="jetty-10.0.x" location="https://download.eclipse.org/oomph/jetty/release/10.0.13/"/>
+    </location>
+    <location includeMode="slicer" includeAllPlatforms="false" includeSource="true" includeConfigurePhase="true" type="InstallableUnit">
       <unit id="jakarta.servlet-api" version="4.0.0"/>
       <unit id="jakarta.servlet-api.source" version="4.0.0"/>
-      <unit id="org.eclipse.jetty.http" version="10.0.6"/>
-      <unit id="org.eclipse.jetty.http.source" version="10.0.6"/>
-      <unit id="org.eclipse.jetty.io" version="10.0.6"/>
-      <unit id="org.eclipse.jetty.io.source" version="10.0.6"/>
-      <unit id="org.eclipse.jetty.security" version="10.0.6"/>
-      <unit id="org.eclipse.jetty.security.source" version="10.0.6"/>
-      <unit id="org.eclipse.jetty.server" version="10.0.6"/>
-      <unit id="org.eclipse.jetty.server.source" version="10.0.6"/>
-      <unit id="org.eclipse.jetty.servlet" version="10.0.6"/>
-      <unit id="org.eclipse.jetty.servlet.source" version="10.0.6"/>
-      <unit id="org.eclipse.jetty.util" version="10.0.6"/>
-      <unit id="org.eclipse.jetty.util.source" version="10.0.6"/>
-      <unit id="org.eclipse.jetty.util.ajax" version="10.0.6"/>
-      <unit id="org.eclipse.jetty.util.ajax.source" version="10.0.6"/>
-      <repository id="jetty-10.0.x" location="https://download.eclipse.org/eclipse/jetty/10.0.6/"/>
+      <repository id="jetty-10.0.6" location="https://download.eclipse.org/eclipse/jetty/10.0.6/"/>
     </location>
     <location includeMode="slicer" includeAllPlatforms="false" includeSource="true" includeConfigurePhase="true" type="InstallableUnit">
-      <unit id="com.google.gson" version="2.9.1.v20220915-1632"/>
-      <unit id="com.google.gson.source" version="2.9.1.v20220915-1632"/>
+      <unit id="com.google.gson" version="2.10.0.v20221207-1049"/>
+      <unit id="com.google.gson.source" version="2.10.0.v20221207-1049"/>
       <unit id="com.jcraft.jsch" version="0.1.55.v20221112-0806"/>
       <unit id="com.jcraft.jsch.source" version="0.1.55.v20221112-0806"/>
       <unit id="com.jcraft.jzlib" version="1.1.3.v20220502-1820"/>
@@ -45,14 +41,14 @@
       <unit id="org.apache.ant.source" version="1.10.12.v20211102-1452"/>
       <unit id="org.apache.commons.codec" version="1.14.0.v20221112-0806"/>
       <unit id="org.apache.commons.codec.source" version="1.14.0.v20221112-0806"/>
-      <unit id="org.apache.commons.compress" version="1.21.0.v20211103-2100"/>
-      <unit id="org.apache.commons.compress.source" version="1.21.0.v20211103-2100"/>
+      <unit id="org.apache.commons.compress" version="1.22.0.v20221207-1049"/>
+      <unit id="org.apache.commons.compress.source" version="1.22.0.v20221207-1049"/>
       <unit id="org.apache.commons.logging" version="1.2.0.v20180409-1502"/>
       <unit id="org.apache.commons.logging.source" version="1.2.0.v20180409-1502"/>
-      <unit id="org.apache.httpcomponents.httpclient" version="4.5.13.v20221112-0806"/>
-      <unit id="org.apache.httpcomponents.httpclient.source" version="4.5.13.v20221112-0806"/>
-      <unit id="org.apache.httpcomponents.httpcore" version="4.4.15.v20220209-2345"/>
-      <unit id="org.apache.httpcomponents.httpcore.source" version="4.4.15.v20220209-2345"/>
+      <unit id="org.apache.httpcomponents.httpclient" version="4.5.14.v20221207-1049"/>
+      <unit id="org.apache.httpcomponents.httpclient.source" version="4.5.14.v20221207-1049"/>
+      <unit id="org.apache.httpcomponents.httpcore" version="4.4.16.v20221207-1049"/>
+      <unit id="org.apache.httpcomponents.httpcore.source" version="4.4.16.v20221207-1049"/>
       <unit id="org.apache.sshd.osgi" version="2.9.2.v20221117-1942"/>
       <unit id="org.apache.sshd.osgi.source" version="2.9.2.v20221117-1942"/>
       <unit id="org.apache.sshd.sftp" version="2.9.2.v20221117-1942"/>
@@ -87,7 +83,7 @@
       <unit id="org.slf4j.binding.simple.source" version="1.7.30.v20221112-0806"/>
       <unit id="org.tukaani.xz" version="1.9.0.v20210624-1259"/>
       <unit id="org.tukaani.xz.source" version="1.9.0.v20210624-1259"/>
-      <repository location="https://download.eclipse.org/tools/orbit/downloads/drops/R20221123021534/repository"/>
+      <repository location="https://download.eclipse.org/tools/orbit/downloads/drops/S20230101190934/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.tpd b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.20.tpd
index afc5f34..9faf529 100644
--- a/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.20.tpd
+++ b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.20.tpd
@@ -1,7 +1,7 @@
 target "jgit-4.20" with source configurePhase
 
 include "projects/jetty-10.0.x.tpd"
-include "orbit/R20221123021534-2022-12.tpd"
+include "orbit/S20230101190934.tpd"
 
 location "https://download.eclipse.org/releases/2021-06/" {
 	org.eclipse.osgi lazy
diff --git a/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.21.target b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.21.target
index edfc027..993c93f 100644
--- a/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.21.target
+++ b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.21.target
@@ -1,30 +1,26 @@
 <?xml version="1.0" encoding="UTF-8" standalone="no"?>
 <?pde?>
 <!-- generated with https://github.com/eclipse-cbi/targetplatform-dsl -->
-<target name="jgit-4.21" sequenceNumber="1669195941">
+<target name="jgit-4.21" sequenceNumber="1673875570">
   <locations>
     <location includeMode="slicer" includeAllPlatforms="false" includeSource="true" includeConfigurePhase="true" type="InstallableUnit">
+      <unit id="org.eclipse.jetty.http" version="10.0.13"/>
+      <unit id="org.eclipse.jetty.io" version="10.0.13"/>
+      <unit id="org.eclipse.jetty.security" version="10.0.13"/>
+      <unit id="org.eclipse.jetty.server" version="10.0.13"/>
+      <unit id="org.eclipse.jetty.servlet" version="10.0.13"/>
+      <unit id="org.eclipse.jetty.util" version="10.0.13"/>
+      <unit id="org.eclipse.jetty.util.ajax" version="10.0.13"/>
+      <repository id="jetty-10.0.x" location="https://download.eclipse.org/oomph/jetty/release/10.0.13/"/>
+    </location>
+    <location includeMode="slicer" includeAllPlatforms="false" includeSource="true" includeConfigurePhase="true" type="InstallableUnit">
       <unit id="jakarta.servlet-api" version="4.0.0"/>
       <unit id="jakarta.servlet-api.source" version="4.0.0"/>
-      <unit id="org.eclipse.jetty.http" version="10.0.6"/>
-      <unit id="org.eclipse.jetty.http.source" version="10.0.6"/>
-      <unit id="org.eclipse.jetty.io" version="10.0.6"/>
-      <unit id="org.eclipse.jetty.io.source" version="10.0.6"/>
-      <unit id="org.eclipse.jetty.security" version="10.0.6"/>
-      <unit id="org.eclipse.jetty.security.source" version="10.0.6"/>
-      <unit id="org.eclipse.jetty.server" version="10.0.6"/>
-      <unit id="org.eclipse.jetty.server.source" version="10.0.6"/>
-      <unit id="org.eclipse.jetty.servlet" version="10.0.6"/>
-      <unit id="org.eclipse.jetty.servlet.source" version="10.0.6"/>
-      <unit id="org.eclipse.jetty.util" version="10.0.6"/>
-      <unit id="org.eclipse.jetty.util.source" version="10.0.6"/>
-      <unit id="org.eclipse.jetty.util.ajax" version="10.0.6"/>
-      <unit id="org.eclipse.jetty.util.ajax.source" version="10.0.6"/>
-      <repository id="jetty-10.0.x" location="https://download.eclipse.org/eclipse/jetty/10.0.6/"/>
+      <repository id="jetty-10.0.6" location="https://download.eclipse.org/eclipse/jetty/10.0.6/"/>
     </location>
     <location includeMode="slicer" includeAllPlatforms="false" includeSource="true" includeConfigurePhase="true" type="InstallableUnit">
-      <unit id="com.google.gson" version="2.9.1.v20220915-1632"/>
-      <unit id="com.google.gson.source" version="2.9.1.v20220915-1632"/>
+      <unit id="com.google.gson" version="2.10.0.v20221207-1049"/>
+      <unit id="com.google.gson.source" version="2.10.0.v20221207-1049"/>
       <unit id="com.jcraft.jsch" version="0.1.55.v20221112-0806"/>
       <unit id="com.jcraft.jsch.source" version="0.1.55.v20221112-0806"/>
       <unit id="com.jcraft.jzlib" version="1.1.3.v20220502-1820"/>
@@ -45,14 +41,14 @@
       <unit id="org.apache.ant.source" version="1.10.12.v20211102-1452"/>
       <unit id="org.apache.commons.codec" version="1.14.0.v20221112-0806"/>
       <unit id="org.apache.commons.codec.source" version="1.14.0.v20221112-0806"/>
-      <unit id="org.apache.commons.compress" version="1.21.0.v20211103-2100"/>
-      <unit id="org.apache.commons.compress.source" version="1.21.0.v20211103-2100"/>
+      <unit id="org.apache.commons.compress" version="1.22.0.v20221207-1049"/>
+      <unit id="org.apache.commons.compress.source" version="1.22.0.v20221207-1049"/>
       <unit id="org.apache.commons.logging" version="1.2.0.v20180409-1502"/>
       <unit id="org.apache.commons.logging.source" version="1.2.0.v20180409-1502"/>
-      <unit id="org.apache.httpcomponents.httpclient" version="4.5.13.v20221112-0806"/>
-      <unit id="org.apache.httpcomponents.httpclient.source" version="4.5.13.v20221112-0806"/>
-      <unit id="org.apache.httpcomponents.httpcore" version="4.4.15.v20220209-2345"/>
-      <unit id="org.apache.httpcomponents.httpcore.source" version="4.4.15.v20220209-2345"/>
+      <unit id="org.apache.httpcomponents.httpclient" version="4.5.14.v20221207-1049"/>
+      <unit id="org.apache.httpcomponents.httpclient.source" version="4.5.14.v20221207-1049"/>
+      <unit id="org.apache.httpcomponents.httpcore" version="4.4.16.v20221207-1049"/>
+      <unit id="org.apache.httpcomponents.httpcore.source" version="4.4.16.v20221207-1049"/>
       <unit id="org.apache.sshd.osgi" version="2.9.2.v20221117-1942"/>
       <unit id="org.apache.sshd.osgi.source" version="2.9.2.v20221117-1942"/>
       <unit id="org.apache.sshd.sftp" version="2.9.2.v20221117-1942"/>
@@ -87,7 +83,7 @@
       <unit id="org.slf4j.binding.simple.source" version="1.7.30.v20221112-0806"/>
       <unit id="org.tukaani.xz" version="1.9.0.v20210624-1259"/>
       <unit id="org.tukaani.xz.source" version="1.9.0.v20210624-1259"/>
-      <repository location="https://download.eclipse.org/tools/orbit/downloads/drops/R20221123021534/repository"/>
+      <repository location="https://download.eclipse.org/tools/orbit/downloads/drops/S20230101190934/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.21.tpd b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.21.tpd
index b701c81..5d861c9 100644
--- a/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.21.tpd
+++ b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.21.tpd
@@ -1,7 +1,7 @@
 target "jgit-4.21" with source configurePhase
 
 include "projects/jetty-10.0.x.tpd"
-include "orbit/R20221123021534-2022-12.tpd"
+include "orbit/S20230101190934.tpd"
 
 location "https://download.eclipse.org/releases/2021-09/" {
 	org.eclipse.osgi lazy
diff --git a/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.22.target b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.22.target
index f5efb8c..86444a5 100644
--- a/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.22.target
+++ b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.22.target
@@ -1,30 +1,26 @@
 <?xml version="1.0" encoding="UTF-8" standalone="no"?>
 <?pde?>
 <!-- generated with https://github.com/eclipse-cbi/targetplatform-dsl -->
-<target name="jgit-4.22" sequenceNumber="1669195941">
+<target name="jgit-4.22" sequenceNumber="1673875570">
   <locations>
     <location includeMode="slicer" includeAllPlatforms="false" includeSource="true" includeConfigurePhase="true" type="InstallableUnit">
+      <unit id="org.eclipse.jetty.http" version="10.0.13"/>
+      <unit id="org.eclipse.jetty.io" version="10.0.13"/>
+      <unit id="org.eclipse.jetty.security" version="10.0.13"/>
+      <unit id="org.eclipse.jetty.server" version="10.0.13"/>
+      <unit id="org.eclipse.jetty.servlet" version="10.0.13"/>
+      <unit id="org.eclipse.jetty.util" version="10.0.13"/>
+      <unit id="org.eclipse.jetty.util.ajax" version="10.0.13"/>
+      <repository id="jetty-10.0.x" location="https://download.eclipse.org/oomph/jetty/release/10.0.13/"/>
+    </location>
+    <location includeMode="slicer" includeAllPlatforms="false" includeSource="true" includeConfigurePhase="true" type="InstallableUnit">
       <unit id="jakarta.servlet-api" version="4.0.0"/>
       <unit id="jakarta.servlet-api.source" version="4.0.0"/>
-      <unit id="org.eclipse.jetty.http" version="10.0.6"/>
-      <unit id="org.eclipse.jetty.http.source" version="10.0.6"/>
-      <unit id="org.eclipse.jetty.io" version="10.0.6"/>
-      <unit id="org.eclipse.jetty.io.source" version="10.0.6"/>
-      <unit id="org.eclipse.jetty.security" version="10.0.6"/>
-      <unit id="org.eclipse.jetty.security.source" version="10.0.6"/>
-      <unit id="org.eclipse.jetty.server" version="10.0.6"/>
-      <unit id="org.eclipse.jetty.server.source" version="10.0.6"/>
-      <unit id="org.eclipse.jetty.servlet" version="10.0.6"/>
-      <unit id="org.eclipse.jetty.servlet.source" version="10.0.6"/>
-      <unit id="org.eclipse.jetty.util" version="10.0.6"/>
-      <unit id="org.eclipse.jetty.util.source" version="10.0.6"/>
-      <unit id="org.eclipse.jetty.util.ajax" version="10.0.6"/>
-      <unit id="org.eclipse.jetty.util.ajax.source" version="10.0.6"/>
-      <repository id="jetty-10.0.x" location="https://download.eclipse.org/eclipse/jetty/10.0.6/"/>
+      <repository id="jetty-10.0.6" location="https://download.eclipse.org/eclipse/jetty/10.0.6/"/>
     </location>
     <location includeMode="slicer" includeAllPlatforms="false" includeSource="true" includeConfigurePhase="true" type="InstallableUnit">
-      <unit id="com.google.gson" version="2.9.1.v20220915-1632"/>
-      <unit id="com.google.gson.source" version="2.9.1.v20220915-1632"/>
+      <unit id="com.google.gson" version="2.10.0.v20221207-1049"/>
+      <unit id="com.google.gson.source" version="2.10.0.v20221207-1049"/>
       <unit id="com.jcraft.jsch" version="0.1.55.v20221112-0806"/>
       <unit id="com.jcraft.jsch.source" version="0.1.55.v20221112-0806"/>
       <unit id="com.jcraft.jzlib" version="1.1.3.v20220502-1820"/>
@@ -45,14 +41,14 @@
       <unit id="org.apache.ant.source" version="1.10.12.v20211102-1452"/>
       <unit id="org.apache.commons.codec" version="1.14.0.v20221112-0806"/>
       <unit id="org.apache.commons.codec.source" version="1.14.0.v20221112-0806"/>
-      <unit id="org.apache.commons.compress" version="1.21.0.v20211103-2100"/>
-      <unit id="org.apache.commons.compress.source" version="1.21.0.v20211103-2100"/>
+      <unit id="org.apache.commons.compress" version="1.22.0.v20221207-1049"/>
+      <unit id="org.apache.commons.compress.source" version="1.22.0.v20221207-1049"/>
       <unit id="org.apache.commons.logging" version="1.2.0.v20180409-1502"/>
       <unit id="org.apache.commons.logging.source" version="1.2.0.v20180409-1502"/>
-      <unit id="org.apache.httpcomponents.httpclient" version="4.5.13.v20221112-0806"/>
-      <unit id="org.apache.httpcomponents.httpclient.source" version="4.5.13.v20221112-0806"/>
-      <unit id="org.apache.httpcomponents.httpcore" version="4.4.15.v20220209-2345"/>
-      <unit id="org.apache.httpcomponents.httpcore.source" version="4.4.15.v20220209-2345"/>
+      <unit id="org.apache.httpcomponents.httpclient" version="4.5.14.v20221207-1049"/>
+      <unit id="org.apache.httpcomponents.httpclient.source" version="4.5.14.v20221207-1049"/>
+      <unit id="org.apache.httpcomponents.httpcore" version="4.4.16.v20221207-1049"/>
+      <unit id="org.apache.httpcomponents.httpcore.source" version="4.4.16.v20221207-1049"/>
       <unit id="org.apache.sshd.osgi" version="2.9.2.v20221117-1942"/>
       <unit id="org.apache.sshd.osgi.source" version="2.9.2.v20221117-1942"/>
       <unit id="org.apache.sshd.sftp" version="2.9.2.v20221117-1942"/>
@@ -87,7 +83,7 @@
       <unit id="org.slf4j.binding.simple.source" version="1.7.30.v20221112-0806"/>
       <unit id="org.tukaani.xz" version="1.9.0.v20210624-1259"/>
       <unit id="org.tukaani.xz.source" version="1.9.0.v20210624-1259"/>
-      <repository location="https://download.eclipse.org/tools/orbit/downloads/drops/R20221123021534/repository"/>
+      <repository location="https://download.eclipse.org/tools/orbit/downloads/drops/S20230101190934/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.22.tpd b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.22.tpd
index e69ab0a..b21ab17 100644
--- a/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.22.tpd
+++ b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.22.tpd
@@ -1,7 +1,7 @@
 target "jgit-4.22" with source configurePhase
 
 include "projects/jetty-10.0.x.tpd"
-include "orbit/R20221123021534-2022-12.tpd"
+include "orbit/S20230101190934.tpd"
 
 location "https://download.eclipse.org/releases/2021-12/" {
 	org.eclipse.osgi lazy
diff --git a/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.23.target b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.23.target
index 1100bf2..2c1692f 100644
--- a/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.23.target
+++ b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.23.target
@@ -1,30 +1,26 @@
 <?xml version="1.0" encoding="UTF-8" standalone="no"?>
 <?pde?>
 <!-- generated with https://github.com/eclipse-cbi/targetplatform-dsl -->
-<target name="jgit-4.23" sequenceNumber="1669195941">
+<target name="jgit-4.23" sequenceNumber="1673875570">
   <locations>
     <location includeMode="slicer" includeAllPlatforms="false" includeSource="true" includeConfigurePhase="true" type="InstallableUnit">
+      <unit id="org.eclipse.jetty.http" version="10.0.13"/>
+      <unit id="org.eclipse.jetty.io" version="10.0.13"/>
+      <unit id="org.eclipse.jetty.security" version="10.0.13"/>
+      <unit id="org.eclipse.jetty.server" version="10.0.13"/>
+      <unit id="org.eclipse.jetty.servlet" version="10.0.13"/>
+      <unit id="org.eclipse.jetty.util" version="10.0.13"/>
+      <unit id="org.eclipse.jetty.util.ajax" version="10.0.13"/>
+      <repository id="jetty-10.0.x" location="https://download.eclipse.org/oomph/jetty/release/10.0.13/"/>
+    </location>
+    <location includeMode="slicer" includeAllPlatforms="false" includeSource="true" includeConfigurePhase="true" type="InstallableUnit">
       <unit id="jakarta.servlet-api" version="4.0.0"/>
       <unit id="jakarta.servlet-api.source" version="4.0.0"/>
-      <unit id="org.eclipse.jetty.http" version="10.0.6"/>
-      <unit id="org.eclipse.jetty.http.source" version="10.0.6"/>
-      <unit id="org.eclipse.jetty.io" version="10.0.6"/>
-      <unit id="org.eclipse.jetty.io.source" version="10.0.6"/>
-      <unit id="org.eclipse.jetty.security" version="10.0.6"/>
-      <unit id="org.eclipse.jetty.security.source" version="10.0.6"/>
-      <unit id="org.eclipse.jetty.server" version="10.0.6"/>
-      <unit id="org.eclipse.jetty.server.source" version="10.0.6"/>
-      <unit id="org.eclipse.jetty.servlet" version="10.0.6"/>
-      <unit id="org.eclipse.jetty.servlet.source" version="10.0.6"/>
-      <unit id="org.eclipse.jetty.util" version="10.0.6"/>
-      <unit id="org.eclipse.jetty.util.source" version="10.0.6"/>
-      <unit id="org.eclipse.jetty.util.ajax" version="10.0.6"/>
-      <unit id="org.eclipse.jetty.util.ajax.source" version="10.0.6"/>
-      <repository id="jetty-10.0.x" location="https://download.eclipse.org/eclipse/jetty/10.0.6/"/>
+      <repository id="jetty-10.0.6" location="https://download.eclipse.org/eclipse/jetty/10.0.6/"/>
     </location>
     <location includeMode="slicer" includeAllPlatforms="false" includeSource="true" includeConfigurePhase="true" type="InstallableUnit">
-      <unit id="com.google.gson" version="2.9.1.v20220915-1632"/>
-      <unit id="com.google.gson.source" version="2.9.1.v20220915-1632"/>
+      <unit id="com.google.gson" version="2.10.0.v20221207-1049"/>
+      <unit id="com.google.gson.source" version="2.10.0.v20221207-1049"/>
       <unit id="com.jcraft.jsch" version="0.1.55.v20221112-0806"/>
       <unit id="com.jcraft.jsch.source" version="0.1.55.v20221112-0806"/>
       <unit id="com.jcraft.jzlib" version="1.1.3.v20220502-1820"/>
@@ -45,14 +41,14 @@
       <unit id="org.apache.ant.source" version="1.10.12.v20211102-1452"/>
       <unit id="org.apache.commons.codec" version="1.14.0.v20221112-0806"/>
       <unit id="org.apache.commons.codec.source" version="1.14.0.v20221112-0806"/>
-      <unit id="org.apache.commons.compress" version="1.21.0.v20211103-2100"/>
-      <unit id="org.apache.commons.compress.source" version="1.21.0.v20211103-2100"/>
+      <unit id="org.apache.commons.compress" version="1.22.0.v20221207-1049"/>
+      <unit id="org.apache.commons.compress.source" version="1.22.0.v20221207-1049"/>
       <unit id="org.apache.commons.logging" version="1.2.0.v20180409-1502"/>
       <unit id="org.apache.commons.logging.source" version="1.2.0.v20180409-1502"/>
-      <unit id="org.apache.httpcomponents.httpclient" version="4.5.13.v20221112-0806"/>
-      <unit id="org.apache.httpcomponents.httpclient.source" version="4.5.13.v20221112-0806"/>
-      <unit id="org.apache.httpcomponents.httpcore" version="4.4.15.v20220209-2345"/>
-      <unit id="org.apache.httpcomponents.httpcore.source" version="4.4.15.v20220209-2345"/>
+      <unit id="org.apache.httpcomponents.httpclient" version="4.5.14.v20221207-1049"/>
+      <unit id="org.apache.httpcomponents.httpclient.source" version="4.5.14.v20221207-1049"/>
+      <unit id="org.apache.httpcomponents.httpcore" version="4.4.16.v20221207-1049"/>
+      <unit id="org.apache.httpcomponents.httpcore.source" version="4.4.16.v20221207-1049"/>
       <unit id="org.apache.sshd.osgi" version="2.9.2.v20221117-1942"/>
       <unit id="org.apache.sshd.osgi.source" version="2.9.2.v20221117-1942"/>
       <unit id="org.apache.sshd.sftp" version="2.9.2.v20221117-1942"/>
@@ -87,7 +83,7 @@
       <unit id="org.slf4j.binding.simple.source" version="1.7.30.v20221112-0806"/>
       <unit id="org.tukaani.xz" version="1.9.0.v20210624-1259"/>
       <unit id="org.tukaani.xz.source" version="1.9.0.v20210624-1259"/>
-      <repository location="https://download.eclipse.org/tools/orbit/downloads/drops/R20221123021534/repository"/>
+      <repository location="https://download.eclipse.org/tools/orbit/downloads/drops/S20230101190934/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.23.tpd b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.23.tpd
index 87a7b7f..a23ba3b 100644
--- a/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.23.tpd
+++ b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.23.tpd
@@ -1,7 +1,7 @@
 target "jgit-4.23" with source configurePhase
 
 include "projects/jetty-10.0.x.tpd"
-include "orbit/R20221123021534-2022-12.tpd"
+include "orbit/S20230101190934.tpd"
 
 location "https://download.eclipse.org/releases/2022-03/" {
 	org.eclipse.osgi lazy
diff --git a/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.24.target b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.24.target
index ccd8d23..3c296b5 100644
--- a/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.24.target
+++ b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.24.target
@@ -1,30 +1,26 @@
 <?xml version="1.0" encoding="UTF-8" standalone="no"?>
 <?pde?>
 <!-- generated with https://github.com/eclipse-cbi/targetplatform-dsl -->
-<target name="jgit-4.24" sequenceNumber="1669195941">
+<target name="jgit-4.24" sequenceNumber="1673875570">
   <locations>
     <location includeMode="slicer" includeAllPlatforms="false" includeSource="true" includeConfigurePhase="true" type="InstallableUnit">
+      <unit id="org.eclipse.jetty.http" version="10.0.13"/>
+      <unit id="org.eclipse.jetty.io" version="10.0.13"/>
+      <unit id="org.eclipse.jetty.security" version="10.0.13"/>
+      <unit id="org.eclipse.jetty.server" version="10.0.13"/>
+      <unit id="org.eclipse.jetty.servlet" version="10.0.13"/>
+      <unit id="org.eclipse.jetty.util" version="10.0.13"/>
+      <unit id="org.eclipse.jetty.util.ajax" version="10.0.13"/>
+      <repository id="jetty-10.0.x" location="https://download.eclipse.org/oomph/jetty/release/10.0.13/"/>
+    </location>
+    <location includeMode="slicer" includeAllPlatforms="false" includeSource="true" includeConfigurePhase="true" type="InstallableUnit">
       <unit id="jakarta.servlet-api" version="4.0.0"/>
       <unit id="jakarta.servlet-api.source" version="4.0.0"/>
-      <unit id="org.eclipse.jetty.http" version="10.0.6"/>
-      <unit id="org.eclipse.jetty.http.source" version="10.0.6"/>
-      <unit id="org.eclipse.jetty.io" version="10.0.6"/>
-      <unit id="org.eclipse.jetty.io.source" version="10.0.6"/>
-      <unit id="org.eclipse.jetty.security" version="10.0.6"/>
-      <unit id="org.eclipse.jetty.security.source" version="10.0.6"/>
-      <unit id="org.eclipse.jetty.server" version="10.0.6"/>
-      <unit id="org.eclipse.jetty.server.source" version="10.0.6"/>
-      <unit id="org.eclipse.jetty.servlet" version="10.0.6"/>
-      <unit id="org.eclipse.jetty.servlet.source" version="10.0.6"/>
-      <unit id="org.eclipse.jetty.util" version="10.0.6"/>
-      <unit id="org.eclipse.jetty.util.source" version="10.0.6"/>
-      <unit id="org.eclipse.jetty.util.ajax" version="10.0.6"/>
-      <unit id="org.eclipse.jetty.util.ajax.source" version="10.0.6"/>
-      <repository id="jetty-10.0.x" location="https://download.eclipse.org/eclipse/jetty/10.0.6/"/>
+      <repository id="jetty-10.0.6" location="https://download.eclipse.org/eclipse/jetty/10.0.6/"/>
     </location>
     <location includeMode="slicer" includeAllPlatforms="false" includeSource="true" includeConfigurePhase="true" type="InstallableUnit">
-      <unit id="com.google.gson" version="2.9.1.v20220915-1632"/>
-      <unit id="com.google.gson.source" version="2.9.1.v20220915-1632"/>
+      <unit id="com.google.gson" version="2.10.0.v20221207-1049"/>
+      <unit id="com.google.gson.source" version="2.10.0.v20221207-1049"/>
       <unit id="com.jcraft.jsch" version="0.1.55.v20221112-0806"/>
       <unit id="com.jcraft.jsch.source" version="0.1.55.v20221112-0806"/>
       <unit id="com.jcraft.jzlib" version="1.1.3.v20220502-1820"/>
@@ -45,14 +41,14 @@
       <unit id="org.apache.ant.source" version="1.10.12.v20211102-1452"/>
       <unit id="org.apache.commons.codec" version="1.14.0.v20221112-0806"/>
       <unit id="org.apache.commons.codec.source" version="1.14.0.v20221112-0806"/>
-      <unit id="org.apache.commons.compress" version="1.21.0.v20211103-2100"/>
-      <unit id="org.apache.commons.compress.source" version="1.21.0.v20211103-2100"/>
+      <unit id="org.apache.commons.compress" version="1.22.0.v20221207-1049"/>
+      <unit id="org.apache.commons.compress.source" version="1.22.0.v20221207-1049"/>
       <unit id="org.apache.commons.logging" version="1.2.0.v20180409-1502"/>
       <unit id="org.apache.commons.logging.source" version="1.2.0.v20180409-1502"/>
-      <unit id="org.apache.httpcomponents.httpclient" version="4.5.13.v20221112-0806"/>
-      <unit id="org.apache.httpcomponents.httpclient.source" version="4.5.13.v20221112-0806"/>
-      <unit id="org.apache.httpcomponents.httpcore" version="4.4.15.v20220209-2345"/>
-      <unit id="org.apache.httpcomponents.httpcore.source" version="4.4.15.v20220209-2345"/>
+      <unit id="org.apache.httpcomponents.httpclient" version="4.5.14.v20221207-1049"/>
+      <unit id="org.apache.httpcomponents.httpclient.source" version="4.5.14.v20221207-1049"/>
+      <unit id="org.apache.httpcomponents.httpcore" version="4.4.16.v20221207-1049"/>
+      <unit id="org.apache.httpcomponents.httpcore.source" version="4.4.16.v20221207-1049"/>
       <unit id="org.apache.sshd.osgi" version="2.9.2.v20221117-1942"/>
       <unit id="org.apache.sshd.osgi.source" version="2.9.2.v20221117-1942"/>
       <unit id="org.apache.sshd.sftp" version="2.9.2.v20221117-1942"/>
@@ -87,7 +83,7 @@
       <unit id="org.slf4j.binding.simple.source" version="1.7.30.v20221112-0806"/>
       <unit id="org.tukaani.xz" version="1.9.0.v20210624-1259"/>
       <unit id="org.tukaani.xz.source" version="1.9.0.v20210624-1259"/>
-      <repository location="https://download.eclipse.org/tools/orbit/downloads/drops/R20221123021534/repository"/>
+      <repository location="https://download.eclipse.org/tools/orbit/downloads/drops/S20230101190934/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.24.tpd b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.24.tpd
index 91108fc..ceea7a8 100644
--- a/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.24.tpd
+++ b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.24.tpd
@@ -1,7 +1,7 @@
 target "jgit-4.24" with source configurePhase
 
 include "projects/jetty-10.0.x.tpd"
-include "orbit/R20221123021534-2022-12.tpd"
+include "orbit/S20230101190934.tpd"
 
 location "https://download.eclipse.org/releases/2022-06/" {
 	org.eclipse.osgi lazy
diff --git a/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.25.target b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.25.target
index 364f49e..ad5d995 100644
--- a/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.25.target
+++ b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.25.target
@@ -1,30 +1,26 @@
 <?xml version="1.0" encoding="UTF-8" standalone="no"?>
 <?pde?>
 <!-- generated with https://github.com/eclipse-cbi/targetplatform-dsl -->
-<target name="jgit-4.25" sequenceNumber="1669195941">
+<target name="jgit-4.25" sequenceNumber="1673875570">
   <locations>
     <location includeMode="slicer" includeAllPlatforms="false" includeSource="true" includeConfigurePhase="true" type="InstallableUnit">
+      <unit id="org.eclipse.jetty.http" version="10.0.13"/>
+      <unit id="org.eclipse.jetty.io" version="10.0.13"/>
+      <unit id="org.eclipse.jetty.security" version="10.0.13"/>
+      <unit id="org.eclipse.jetty.server" version="10.0.13"/>
+      <unit id="org.eclipse.jetty.servlet" version="10.0.13"/>
+      <unit id="org.eclipse.jetty.util" version="10.0.13"/>
+      <unit id="org.eclipse.jetty.util.ajax" version="10.0.13"/>
+      <repository id="jetty-10.0.x" location="https://download.eclipse.org/oomph/jetty/release/10.0.13/"/>
+    </location>
+    <location includeMode="slicer" includeAllPlatforms="false" includeSource="true" includeConfigurePhase="true" type="InstallableUnit">
       <unit id="jakarta.servlet-api" version="4.0.0"/>
       <unit id="jakarta.servlet-api.source" version="4.0.0"/>
-      <unit id="org.eclipse.jetty.http" version="10.0.6"/>
-      <unit id="org.eclipse.jetty.http.source" version="10.0.6"/>
-      <unit id="org.eclipse.jetty.io" version="10.0.6"/>
-      <unit id="org.eclipse.jetty.io.source" version="10.0.6"/>
-      <unit id="org.eclipse.jetty.security" version="10.0.6"/>
-      <unit id="org.eclipse.jetty.security.source" version="10.0.6"/>
-      <unit id="org.eclipse.jetty.server" version="10.0.6"/>
-      <unit id="org.eclipse.jetty.server.source" version="10.0.6"/>
-      <unit id="org.eclipse.jetty.servlet" version="10.0.6"/>
-      <unit id="org.eclipse.jetty.servlet.source" version="10.0.6"/>
-      <unit id="org.eclipse.jetty.util" version="10.0.6"/>
-      <unit id="org.eclipse.jetty.util.source" version="10.0.6"/>
-      <unit id="org.eclipse.jetty.util.ajax" version="10.0.6"/>
-      <unit id="org.eclipse.jetty.util.ajax.source" version="10.0.6"/>
-      <repository id="jetty-10.0.x" location="https://download.eclipse.org/eclipse/jetty/10.0.6/"/>
+      <repository id="jetty-10.0.6" location="https://download.eclipse.org/eclipse/jetty/10.0.6/"/>
     </location>
     <location includeMode="slicer" includeAllPlatforms="false" includeSource="true" includeConfigurePhase="true" type="InstallableUnit">
-      <unit id="com.google.gson" version="2.9.1.v20220915-1632"/>
-      <unit id="com.google.gson.source" version="2.9.1.v20220915-1632"/>
+      <unit id="com.google.gson" version="2.10.0.v20221207-1049"/>
+      <unit id="com.google.gson.source" version="2.10.0.v20221207-1049"/>
       <unit id="com.jcraft.jsch" version="0.1.55.v20221112-0806"/>
       <unit id="com.jcraft.jsch.source" version="0.1.55.v20221112-0806"/>
       <unit id="com.jcraft.jzlib" version="1.1.3.v20220502-1820"/>
@@ -45,14 +41,14 @@
       <unit id="org.apache.ant.source" version="1.10.12.v20211102-1452"/>
       <unit id="org.apache.commons.codec" version="1.14.0.v20221112-0806"/>
       <unit id="org.apache.commons.codec.source" version="1.14.0.v20221112-0806"/>
-      <unit id="org.apache.commons.compress" version="1.21.0.v20211103-2100"/>
-      <unit id="org.apache.commons.compress.source" version="1.21.0.v20211103-2100"/>
+      <unit id="org.apache.commons.compress" version="1.22.0.v20221207-1049"/>
+      <unit id="org.apache.commons.compress.source" version="1.22.0.v20221207-1049"/>
       <unit id="org.apache.commons.logging" version="1.2.0.v20180409-1502"/>
       <unit id="org.apache.commons.logging.source" version="1.2.0.v20180409-1502"/>
-      <unit id="org.apache.httpcomponents.httpclient" version="4.5.13.v20221112-0806"/>
-      <unit id="org.apache.httpcomponents.httpclient.source" version="4.5.13.v20221112-0806"/>
-      <unit id="org.apache.httpcomponents.httpcore" version="4.4.15.v20220209-2345"/>
-      <unit id="org.apache.httpcomponents.httpcore.source" version="4.4.15.v20220209-2345"/>
+      <unit id="org.apache.httpcomponents.httpclient" version="4.5.14.v20221207-1049"/>
+      <unit id="org.apache.httpcomponents.httpclient.source" version="4.5.14.v20221207-1049"/>
+      <unit id="org.apache.httpcomponents.httpcore" version="4.4.16.v20221207-1049"/>
+      <unit id="org.apache.httpcomponents.httpcore.source" version="4.4.16.v20221207-1049"/>
       <unit id="org.apache.sshd.osgi" version="2.9.2.v20221117-1942"/>
       <unit id="org.apache.sshd.osgi.source" version="2.9.2.v20221117-1942"/>
       <unit id="org.apache.sshd.sftp" version="2.9.2.v20221117-1942"/>
@@ -87,7 +83,7 @@
       <unit id="org.slf4j.binding.simple.source" version="1.7.30.v20221112-0806"/>
       <unit id="org.tukaani.xz" version="1.9.0.v20210624-1259"/>
       <unit id="org.tukaani.xz.source" version="1.9.0.v20210624-1259"/>
-      <repository location="https://download.eclipse.org/tools/orbit/downloads/drops/R20221123021534/repository"/>
+      <repository location="https://download.eclipse.org/tools/orbit/downloads/drops/S20230101190934/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.25.tpd b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.25.tpd
index 7a67a97..3cb98c9 100644
--- a/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.25.tpd
+++ b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.25.tpd
@@ -1,7 +1,7 @@
 target "jgit-4.25" with source configurePhase
 
 include "projects/jetty-10.0.x.tpd"
-include "orbit/R20221123021534-2022-12.tpd"
+include "orbit/S20230101190934.tpd"
 
 location "https://download.eclipse.org/releases/2022-09/" {
 	org.eclipse.osgi lazy
diff --git a/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.26.target b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.26.target
index 257f45e..dce8c55 100644
--- a/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.26.target
+++ b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.26.target
@@ -1,30 +1,26 @@
 <?xml version="1.0" encoding="UTF-8" standalone="no"?>
 <?pde?>
 <!-- generated with https://github.com/eclipse-cbi/targetplatform-dsl -->
-<target name="jgit-4.25" sequenceNumber="1669195949">
+<target name="jgit-4.26" sequenceNumber="1673875557">
   <locations>
     <location includeMode="slicer" includeAllPlatforms="false" includeSource="true" includeConfigurePhase="true" type="InstallableUnit">
+      <unit id="org.eclipse.jetty.http" version="10.0.13"/>
+      <unit id="org.eclipse.jetty.io" version="10.0.13"/>
+      <unit id="org.eclipse.jetty.security" version="10.0.13"/>
+      <unit id="org.eclipse.jetty.server" version="10.0.13"/>
+      <unit id="org.eclipse.jetty.servlet" version="10.0.13"/>
+      <unit id="org.eclipse.jetty.util" version="10.0.13"/>
+      <unit id="org.eclipse.jetty.util.ajax" version="10.0.13"/>
+      <repository id="jetty-10.0.x" location="https://download.eclipse.org/oomph/jetty/release/10.0.13/"/>
+    </location>
+    <location includeMode="slicer" includeAllPlatforms="false" includeSource="true" includeConfigurePhase="true" type="InstallableUnit">
       <unit id="jakarta.servlet-api" version="4.0.0"/>
       <unit id="jakarta.servlet-api.source" version="4.0.0"/>
-      <unit id="org.eclipse.jetty.http" version="10.0.6"/>
-      <unit id="org.eclipse.jetty.http.source" version="10.0.6"/>
-      <unit id="org.eclipse.jetty.io" version="10.0.6"/>
-      <unit id="org.eclipse.jetty.io.source" version="10.0.6"/>
-      <unit id="org.eclipse.jetty.security" version="10.0.6"/>
-      <unit id="org.eclipse.jetty.security.source" version="10.0.6"/>
-      <unit id="org.eclipse.jetty.server" version="10.0.6"/>
-      <unit id="org.eclipse.jetty.server.source" version="10.0.6"/>
-      <unit id="org.eclipse.jetty.servlet" version="10.0.6"/>
-      <unit id="org.eclipse.jetty.servlet.source" version="10.0.6"/>
-      <unit id="org.eclipse.jetty.util" version="10.0.6"/>
-      <unit id="org.eclipse.jetty.util.source" version="10.0.6"/>
-      <unit id="org.eclipse.jetty.util.ajax" version="10.0.6"/>
-      <unit id="org.eclipse.jetty.util.ajax.source" version="10.0.6"/>
-      <repository id="jetty-10.0.x" location="https://download.eclipse.org/eclipse/jetty/10.0.6/"/>
+      <repository id="jetty-10.0.6" location="https://download.eclipse.org/eclipse/jetty/10.0.6/"/>
     </location>
     <location includeMode="slicer" includeAllPlatforms="false" includeSource="true" includeConfigurePhase="true" type="InstallableUnit">
-      <unit id="com.google.gson" version="2.9.1.v20220915-1632"/>
-      <unit id="com.google.gson.source" version="2.9.1.v20220915-1632"/>
+      <unit id="com.google.gson" version="2.10.0.v20221207-1049"/>
+      <unit id="com.google.gson.source" version="2.10.0.v20221207-1049"/>
       <unit id="com.jcraft.jsch" version="0.1.55.v20221112-0806"/>
       <unit id="com.jcraft.jsch.source" version="0.1.55.v20221112-0806"/>
       <unit id="com.jcraft.jzlib" version="1.1.3.v20220502-1820"/>
@@ -45,14 +41,14 @@
       <unit id="org.apache.ant.source" version="1.10.12.v20211102-1452"/>
       <unit id="org.apache.commons.codec" version="1.14.0.v20221112-0806"/>
       <unit id="org.apache.commons.codec.source" version="1.14.0.v20221112-0806"/>
-      <unit id="org.apache.commons.compress" version="1.21.0.v20211103-2100"/>
-      <unit id="org.apache.commons.compress.source" version="1.21.0.v20211103-2100"/>
+      <unit id="org.apache.commons.compress" version="1.22.0.v20221207-1049"/>
+      <unit id="org.apache.commons.compress.source" version="1.22.0.v20221207-1049"/>
       <unit id="org.apache.commons.logging" version="1.2.0.v20180409-1502"/>
       <unit id="org.apache.commons.logging.source" version="1.2.0.v20180409-1502"/>
-      <unit id="org.apache.httpcomponents.httpclient" version="4.5.13.v20221112-0806"/>
-      <unit id="org.apache.httpcomponents.httpclient.source" version="4.5.13.v20221112-0806"/>
-      <unit id="org.apache.httpcomponents.httpcore" version="4.4.15.v20220209-2345"/>
-      <unit id="org.apache.httpcomponents.httpcore.source" version="4.4.15.v20220209-2345"/>
+      <unit id="org.apache.httpcomponents.httpclient" version="4.5.14.v20221207-1049"/>
+      <unit id="org.apache.httpcomponents.httpclient.source" version="4.5.14.v20221207-1049"/>
+      <unit id="org.apache.httpcomponents.httpcore" version="4.4.16.v20221207-1049"/>
+      <unit id="org.apache.httpcomponents.httpcore.source" version="4.4.16.v20221207-1049"/>
       <unit id="org.apache.sshd.osgi" version="2.9.2.v20221117-1942"/>
       <unit id="org.apache.sshd.osgi.source" version="2.9.2.v20221117-1942"/>
       <unit id="org.apache.sshd.sftp" version="2.9.2.v20221117-1942"/>
@@ -87,11 +83,11 @@
       <unit id="org.slf4j.binding.simple.source" version="1.7.30.v20221112-0806"/>
       <unit id="org.tukaani.xz" version="1.9.0.v20210624-1259"/>
       <unit id="org.tukaani.xz.source" version="1.9.0.v20210624-1259"/>
-      <repository location="https://download.eclipse.org/tools/orbit/downloads/drops/R20221123021534/repository"/>
+      <repository location="https://download.eclipse.org/tools/orbit/downloads/drops/S20230101190934/repository"/>
     </location>
     <location includeMode="slicer" includeAllPlatforms="false" includeSource="true" includeConfigurePhase="true" type="InstallableUnit">
       <unit id="org.eclipse.osgi" version="0.0.0"/>
-      <repository location="https://download.eclipse.org/staging/2022-12/"/>
+      <repository location="https://download.eclipse.org/releases/2022-12/"/>
     </location>
   </locations>
 </target>
diff --git a/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.26.tpd b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.26.tpd
index 5fc49cd..8174d09 100644
--- a/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.26.tpd
+++ b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.26.tpd
@@ -1,8 +1,8 @@
-target "jgit-4.25" with source configurePhase
+target "jgit-4.26" with source configurePhase
 
 include "projects/jetty-10.0.x.tpd"
-include "orbit/R20221123021534-2022-12.tpd"
+include "orbit/S20230101190934.tpd"
 
-location "https://download.eclipse.org/staging/2022-12/" {
+location "https://download.eclipse.org/releases/2022-12/" {
 	org.eclipse.osgi lazy
 }
diff --git a/org.eclipse.jgit.packaging/org.eclipse.jgit.target/orbit/R20221123021534-2022-12.tpd b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/orbit/R20221123021534-2022-12.tpd
index bc4929b..378b848 100644
--- a/org.eclipse.jgit.packaging/org.eclipse.jgit.target/orbit/R20221123021534-2022-12.tpd
+++ b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/orbit/R20221123021534-2022-12.tpd
@@ -1,4 +1,4 @@
-target "R20221123021534-2022-12" with source configurePhase
+target "S20230101190934" with source configurePhase
 // see https://download.eclipse.org/tools/orbit/downloads/
 
 location "https://download.eclipse.org/tools/orbit/downloads/drops/R20221123021534/repository" {
diff --git a/org.eclipse.jgit.packaging/org.eclipse.jgit.target/orbit/S20230101190934.tpd b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/orbit/S20230101190934.tpd
new file mode 100644
index 0000000..ecc4b81
--- /dev/null
+++ b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/orbit/S20230101190934.tpd
@@ -0,0 +1,69 @@
+target "S20230101190934" with source configurePhase
+// see https://download.eclipse.org/tools/orbit/downloads/
+
+location "https://download.eclipse.org/tools/orbit/downloads/drops/S20230101190934/repository" {
+	com.google.gson [2.10.0.v20221207-1049,2.10.0.v20221207-1049]
+	com.google.gson.source [2.10.0.v20221207-1049,2.10.0.v20221207-1049]
+	com.jcraft.jsch [0.1.55.v20221112-0806,0.1.55.v20221112-0806]
+	com.jcraft.jsch.source [0.1.55.v20221112-0806,0.1.55.v20221112-0806]
+	com.jcraft.jzlib [1.1.3.v20220502-1820,1.1.3.v20220502-1820]
+	com.jcraft.jzlib.source [1.1.3.v20220502-1820,1.1.3.v20220502-1820]
+	com.sun.jna [5.12.1.v20221103-2317,5.12.1.v20221103-2317]
+	com.sun.jna.source [5.12.1.v20221103-2317,5.12.1.v20221103-2317]
+	com.sun.jna.platform [5.12.1.v20221103-2317,5.12.1.v20221103-2317]
+	com.sun.jna.platform.source [5.12.1.v20221103-2317,5.12.1.v20221103-2317]
+	javaewah [1.1.13.v20211029-0839,1.1.13.v20211029-0839]
+	javaewah.source [1.1.13.v20211029-0839,1.1.13.v20211029-0839]
+	net.bytebuddy.byte-buddy [1.12.18.v20221114-2102,1.12.18.v20221114-2102]
+	net.bytebuddy.byte-buddy.source [1.12.18.v20221114-2102,1.12.18.v20221114-2102]
+	net.bytebuddy.byte-buddy-agent [1.12.18.v20221114-2102,1.12.18.v20221114-2102]
+	net.bytebuddy.byte-buddy-agent.source [1.12.18.v20221114-2102,1.12.18.v20221114-2102]
+	net.i2p.crypto.eddsa [0.3.0.v20220506-1020,0.3.0.v20220506-1020]
+	net.i2p.crypto.eddsa.source [0.3.0.v20220506-1020,0.3.0.v20220506-1020]
+	org.apache.ant [1.10.12.v20211102-1452,1.10.12.v20211102-1452]
+	org.apache.ant.source [1.10.12.v20211102-1452,1.10.12.v20211102-1452]
+	org.apache.commons.codec [1.14.0.v20221112-0806,1.14.0.v20221112-0806]
+	org.apache.commons.codec.source [1.14.0.v20221112-0806,1.14.0.v20221112-0806]
+	org.apache.commons.compress [1.22.0.v20221207-1049,1.22.0.v20221207-1049]
+	org.apache.commons.compress.source [1.22.0.v20221207-1049,1.22.0.v20221207-1049]
+	org.apache.commons.logging [1.2.0.v20180409-1502,1.2.0.v20180409-1502]
+	org.apache.commons.logging.source [1.2.0.v20180409-1502,1.2.0.v20180409-1502]
+	org.apache.httpcomponents.httpclient [4.5.14.v20221207-1049,4.5.14.v20221207-1049]
+	org.apache.httpcomponents.httpclient.source [4.5.14.v20221207-1049,4.5.14.v20221207-1049]
+	org.apache.httpcomponents.httpcore [4.4.16.v20221207-1049,4.4.16.v20221207-1049]
+	org.apache.httpcomponents.httpcore.source [4.4.16.v20221207-1049,4.4.16.v20221207-1049]
+	org.apache.sshd.osgi [2.9.2.v20221117-1942,2.9.2.v20221117-1942]
+	org.apache.sshd.osgi.source [2.9.2.v20221117-1942,2.9.2.v20221117-1942]
+	org.apache.sshd.sftp [2.9.2.v20221117-1942,2.9.2.v20221117-1942]
+	org.apache.sshd.sftp.source [2.9.2.v20221117-1942,2.9.2.v20221117-1942]
+	org.assertj [3.20.2.v20210706-1104,3.20.2.v20210706-1104]
+	org.assertj.source [3.20.2.v20210706-1104,3.20.2.v20210706-1104]
+	org.bouncycastle.bcpg [1.72.0.v20221013-1810,1.72.0.v20221013-1810]
+	org.bouncycastle.bcpg.source [1.72.0.v20221013-1810,1.72.0.v20221013-1810]
+	org.bouncycastle.bcpkix [1.72.0.v20221013-1810,1.72.0.v20221013-1810]
+	org.bouncycastle.bcpkix.source [1.72.0.v20221013-1810,1.72.0.v20221013-1810]
+	org.bouncycastle.bcprov [1.72.0.v20221013-1810,1.72.0.v20221013-1810]
+	org.bouncycastle.bcprov.source [1.72.0.v20221013-1810,1.72.0.v20221013-1810]
+	org.bouncycastle.bcutil [1.72.0.v20221013-1810,1.72.0.v20221013-1810]
+	org.bouncycastle.bcutil.source [1.72.0.v20221013-1810,1.72.0.v20221013-1810]
+	org.hamcrest [2.2.0.v20210711-0821,2.2.0.v20210711-0821]
+	org.hamcrest.source [2.2.0.v20210711-0821,2.2.0.v20210711-0821]
+	org.hamcrest.core [1.3.0.v20180420-1519,1.3.0.v20180420-1519]
+	org.hamcrest.core.source [1.3.0.v20180420-1519,1.3.0.v20180420-1519]
+	org.hamcrest.library [1.3.0.v20180524-2246,1.3.0.v20180524-2246]
+	org.hamcrest.library.source [1.3.0.v20180524-2246,1.3.0.v20180524-2246]
+	org.junit [4.13.2.v20211018-1956,4.13.2.v20211018-1956]
+	org.junit.source [4.13.2.v20211018-1956,4.13.2.v20211018-1956]
+	org.kohsuke.args4j [2.33.0.v20160323-2218,2.33.0.v20160323-2218]
+	org.kohsuke.args4j.source [2.33.0.v20160323-2218,2.33.0.v20160323-2218]
+	org.mockito.mockito-core [4.8.1.v20221103-2317,4.8.1.v20221103-2317]
+	org.mockito.mockito-core.source [4.8.1.v20221103-2317,4.8.1.v20221103-2317]
+	org.objenesis [3.3.0.v20221103-2317,3.3.0.v20221103-2317]
+	org.objenesis.source [3.3.0.v20221103-2317,3.3.0.v20221103-2317]
+	org.slf4j.api [1.7.30.v20221112-0806,1.7.30.v20221112-0806]
+	org.slf4j.api.source [1.7.30.v20221112-0806,1.7.30.v20221112-0806]
+	org.slf4j.binding.simple [1.7.30.v20221112-0806,1.7.30.v20221112-0806]
+	org.slf4j.binding.simple.source [1.7.30.v20221112-0806,1.7.30.v20221112-0806]
+	org.tukaani.xz [1.9.0.v20210624-1259,1.9.0.v20210624-1259]
+	org.tukaani.xz.source [1.9.0.v20210624-1259,1.9.0.v20210624-1259]
+}
diff --git a/org.eclipse.jgit.packaging/org.eclipse.jgit.target/pom.xml b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/pom.xml
index fbcb20c..7924007 100644
--- a/org.eclipse.jgit.packaging/org.eclipse.jgit.target/pom.xml
+++ b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/pom.xml
@@ -16,7 +16,7 @@
   <parent>
     <groupId>org.eclipse.jgit</groupId>
     <artifactId>jgit.tycho.parent</artifactId>
-    <version>6.4.1-SNAPSHOT</version>
+    <version>6.5.0-SNAPSHOT</version>
   </parent>
 
   <artifactId>org.eclipse.jgit.target</artifactId>
diff --git a/org.eclipse.jgit.packaging/org.eclipse.jgit.target/projects/jetty-10.0.x.tpd b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/projects/jetty-10.0.x.tpd
index 6c3ee18..e1afcff 100644
--- a/org.eclipse.jgit.packaging/org.eclipse.jgit.target/projects/jetty-10.0.x.tpd
+++ b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/projects/jetty-10.0.x.tpd
@@ -1,20 +1,16 @@
 target "jetty-10.0.x" with source configurePhase
 
-location jetty-10.0.x "https://download.eclipse.org/eclipse/jetty/10.0.6/" {
+location jetty-10.0.x "https://download.eclipse.org/oomph/jetty/release/10.0.13/" {
+	org.eclipse.jetty.http [10.0.13,10.0.14]
+	org.eclipse.jetty.io [10.0.13,10.0.14]
+	org.eclipse.jetty.security [10.0.13,10.0.14]
+	org.eclipse.jetty.server [10.0.13,10.0.14]
+	org.eclipse.jetty.servlet [10.0.13,10.0.14]
+	org.eclipse.jetty.util [10.0.13,10.0.14]
+	org.eclipse.jetty.util.ajax [10.0.13,10.0.14]
+}
+
+location jetty-10.0.6 "https://download.eclipse.org/eclipse/jetty/10.0.6/" {
 	jakarta.servlet-api [4.0.0, 5.0.0)
 	jakarta.servlet-api.source [4.0.0, 5.0.0)
-	org.eclipse.jetty.http [10.0.6,10.0.6]
-	org.eclipse.jetty.http.source [10.0.6,10.0.6]
-	org.eclipse.jetty.io [10.0.6,10.0.6]
-	org.eclipse.jetty.io.source [10.0.6,10.0.6]
-	org.eclipse.jetty.security [10.0.6,10.0.6]
-	org.eclipse.jetty.security.source [10.0.6,10.0.6]
-	org.eclipse.jetty.server [10.0.6,10.0.6]
-	org.eclipse.jetty.server.source [10.0.6,10.0.6]
-	org.eclipse.jetty.servlet [10.0.6,10.0.6]
-	org.eclipse.jetty.servlet.source [10.0.6,10.0.6]
-	org.eclipse.jetty.util [10.0.6,10.0.6]
-	org.eclipse.jetty.util.source [10.0.6,10.0.6]
-	org.eclipse.jetty.util.ajax [10.0.6,10.0.6]
-	org.eclipse.jetty.util.ajax.source [10.0.6,10.0.6]
-}
+}
\ No newline at end of file
diff --git a/org.eclipse.jgit.packaging/pom.xml b/org.eclipse.jgit.packaging/pom.xml
index 3ccac7d..53ca7e3 100644
--- a/org.eclipse.jgit.packaging/pom.xml
+++ b/org.eclipse.jgit.packaging/pom.xml
@@ -16,7 +16,7 @@
 
   <groupId>org.eclipse.jgit</groupId>
   <artifactId>jgit.tycho.parent</artifactId>
-  <version>6.4.1-SNAPSHOT</version>
+  <version>6.5.0-SNAPSHOT</version>
   <packaging>pom</packaging>
 
   <name>JGit Tycho Parent</name>
@@ -24,7 +24,6 @@
   <properties>
     <java.version>11</java.version>
     <tycho-version>2.7.5</tycho-version>
-    <tycho-extras-version>${tycho-version}</tycho-extras-version>
     <target-platform>jgit-4.17</target-platform>
   </properties>
 
diff --git a/org.eclipse.jgit.pgm.test/META-INF/MANIFEST.MF b/org.eclipse.jgit.pgm.test/META-INF/MANIFEST.MF
index 0bdc408..745c648 100644
--- a/org.eclipse.jgit.pgm.test/META-INF/MANIFEST.MF
+++ b/org.eclipse.jgit.pgm.test/META-INF/MANIFEST.MF
@@ -3,30 +3,30 @@
 Bundle-Name: %Bundle-Name
 Automatic-Module-Name: org.eclipse.jgit.pgm.test
 Bundle-SymbolicName: org.eclipse.jgit.pgm.test
-Bundle-Version: 6.4.1.qualifier
+Bundle-Version: 6.5.0.qualifier
 Bundle-Vendor: %Bundle-Vendor
 Bundle-Localization: plugin
 Bundle-ActivationPolicy: lazy
 Bundle-RequiredExecutionEnvironment: JavaSE-11
-Import-Package: org.eclipse.jgit.api;version="[6.4.1,6.5.0)",
- org.eclipse.jgit.api.errors;version="[6.4.1,6.5.0)",
- org.eclipse.jgit.diff;version="[6.4.1,6.5.0)",
- org.eclipse.jgit.dircache;version="[6.4.1,6.5.0)",
- org.eclipse.jgit.internal.diffmergetool;version="6.4.1",
- org.eclipse.jgit.internal.storage.file;version="6.4.1",
- org.eclipse.jgit.junit;version="[6.4.1,6.5.0)",
- org.eclipse.jgit.lib;version="[6.4.1,6.5.0)",
- org.eclipse.jgit.lib.internal;version="[6.4.1,6.5.0)",
- org.eclipse.jgit.merge;version="[6.4.1,6.5.0)",
- org.eclipse.jgit.pgm;version="[6.4.1,6.5.0)",
- org.eclipse.jgit.pgm.internal;version="[6.4.1,6.5.0)",
- org.eclipse.jgit.pgm.opt;version="[6.4.1,6.5.0)",
- org.eclipse.jgit.revwalk;version="[6.4.1,6.5.0)",
- org.eclipse.jgit.storage.file;version="[6.4.1,6.5.0)",
- org.eclipse.jgit.transport;version="[6.4.1,6.5.0)",
- org.eclipse.jgit.treewalk;version="[6.4.1,6.5.0)",
- org.eclipse.jgit.util;version="[6.4.1,6.5.0)",
- org.eclipse.jgit.util.io;version="[6.4.1,6.5.0)",
+Import-Package: org.eclipse.jgit.api;version="[6.5.0,6.6.0)",
+ org.eclipse.jgit.api.errors;version="[6.5.0,6.6.0)",
+ org.eclipse.jgit.diff;version="[6.5.0,6.6.0)",
+ org.eclipse.jgit.dircache;version="[6.5.0,6.6.0)",
+ org.eclipse.jgit.internal.diffmergetool;version="6.5.0",
+ org.eclipse.jgit.internal.storage.file;version="6.5.0",
+ org.eclipse.jgit.junit;version="[6.5.0,6.6.0)",
+ org.eclipse.jgit.lib;version="[6.5.0,6.6.0)",
+ org.eclipse.jgit.lib.internal;version="[6.5.0,6.6.0)",
+ org.eclipse.jgit.merge;version="[6.5.0,6.6.0)",
+ org.eclipse.jgit.pgm;version="[6.5.0,6.6.0)",
+ org.eclipse.jgit.pgm.internal;version="[6.5.0,6.6.0)",
+ org.eclipse.jgit.pgm.opt;version="[6.5.0,6.6.0)",
+ org.eclipse.jgit.revwalk;version="[6.5.0,6.6.0)",
+ org.eclipse.jgit.storage.file;version="[6.5.0,6.6.0)",
+ org.eclipse.jgit.transport;version="[6.5.0,6.6.0)",
+ org.eclipse.jgit.treewalk;version="[6.5.0,6.6.0)",
+ org.eclipse.jgit.util;version="[6.5.0,6.6.0)",
+ org.eclipse.jgit.util.io;version="[6.5.0,6.6.0)",
  org.hamcrest.core;bundle-version="[1.1.0,3.0.0)",
  org.junit;version="[4.13,5.0.0)",
  org.junit.rules;version="[4.13,5.0.0)",
diff --git a/org.eclipse.jgit.pgm.test/pom.xml b/org.eclipse.jgit.pgm.test/pom.xml
index dad9288..cd445c2 100644
--- a/org.eclipse.jgit.pgm.test/pom.xml
+++ b/org.eclipse.jgit.pgm.test/pom.xml
@@ -17,7 +17,7 @@
   <parent>
     <groupId>org.eclipse.jgit</groupId>
     <artifactId>org.eclipse.jgit-parent</artifactId>
-    <version>6.4.1-SNAPSHOT</version>
+    <version>6.5.0-SNAPSHOT</version>
   </parent>
 
   <artifactId>org.eclipse.jgit.pgm.test</artifactId>
diff --git a/org.eclipse.jgit.pgm.test/tst/org/eclipse/jgit/pgm/CloneTest.java b/org.eclipse.jgit.pgm.test/tst/org/eclipse/jgit/pgm/CloneTest.java
index 4cbd61c..cbb5bbb 100644
--- a/org.eclipse.jgit.pgm.test/tst/org/eclipse/jgit/pgm/CloneTest.java
+++ b/org.eclipse.jgit.pgm.test/tst/org/eclipse/jgit/pgm/CloneTest.java
@@ -17,14 +17,20 @@
 import static org.junit.Assert.assertTrue;
 
 import java.io.File;
+import java.time.Instant;
 import java.util.List;
+import java.util.Set;
+import java.util.stream.Collectors;
+import java.util.stream.StreamSupport;
 
 import org.eclipse.jgit.api.Git;
 import org.eclipse.jgit.junit.JGitTestUtil;
 import org.eclipse.jgit.junit.MockSystemReader;
+import org.eclipse.jgit.junit.TestRepository;
 import org.eclipse.jgit.lib.CLIRepositoryTestCase;
 import org.eclipse.jgit.lib.Constants;
 import org.eclipse.jgit.lib.ObjectId;
+import org.eclipse.jgit.lib.PersonIdent;
 import org.eclipse.jgit.lib.Ref;
 import org.eclipse.jgit.lib.RefUpdate;
 import org.eclipse.jgit.lib.Repository;
@@ -41,10 +47,14 @@ public class CloneTest extends CLIRepositoryTestCase {
 
 	private Git git;
 
+	private TestRepository<Repository> tr;
+
 	@Override
 	@Before
 	public void setUp() throws Exception {
 		super.setUp();
+
+		tr = new TestRepository<>(db);
 		git = new Git(db);
 	}
 
@@ -112,6 +122,22 @@ private RevCommit createInitialCommit() throws Exception {
 		return git.commit().setMessage("Initial commit").call();
 	}
 
+	private RevCommit createSecondCommit() throws Exception {
+		JGitTestUtil.writeTrashFile(db, "Test.txt", "Some change");
+		git.add().addFilepattern("Test.txt").call();
+		return git.commit()
+				.setCommitter(new PersonIdent(this.committer, tr.getDate()))
+				.setMessage("Second commit").call();
+	}
+
+	private RevCommit createThirdCommit() throws Exception {
+		JGitTestUtil.writeTrashFile(db, "change.txt", "another change");
+		git.add().addFilepattern("change.txt").call();
+		return git.commit()
+				.setCommitter(new PersonIdent(this.committer, tr.getDate()))
+				.setMessage("Third commit").call();
+	}
+
 	@Test
 	public void testCloneEmpty() throws Exception {
 		File gitDir = db.getDirectory();
@@ -203,4 +229,117 @@ public void testCloneMirror() throws Exception {
 		assertEquals("refs/*", fetchRefSpec.getDestination());
 		assertNotNull(git2.getRepository().exactRef("refs/meta/foo/bar"));
 	}
+
+	@Test
+	public void testDepth() throws Exception {
+		createInitialCommit();
+		createSecondCommit();
+		createThirdCommit();
+
+		File gitDir = db.getDirectory();
+		String sourceURI = gitDir.toURI().toString();
+		File target = createTempDirectory("target");
+		String cmd = "git clone --depth 1 " + sourceURI + " "
+				+ shellQuote(target.getPath());
+		String[] result = execute(cmd);
+		assertArrayEquals(new String[] {
+				"Cloning into '" + target.getPath() + "'...", "", "" }, result);
+
+		Git git2 = Git.open(target);
+		addRepoToClose(git2.getRepository());
+
+		List<RevCommit> log = StreamSupport
+				.stream(git2.log().all().call().spliterator(), false)
+				.collect(Collectors.toList());
+		assertEquals(1, log.size());
+		RevCommit commit = log.get(0);
+		assertEquals(Set.of(commit.getId()),
+				git2.getRepository().getObjectDatabase().getShallowCommits());
+		assertEquals("Third commit", commit.getFullMessage());
+		assertEquals(0, commit.getParentCount());
+	}
+
+	@Test
+	public void testDepth2() throws Exception {
+		createInitialCommit();
+		createSecondCommit();
+		createThirdCommit();
+
+		File gitDir = db.getDirectory();
+		String sourceURI = gitDir.toURI().toString();
+		File target = createTempDirectory("target");
+		String cmd = "git clone --depth 2 " + sourceURI + " "
+				+ shellQuote(target.getPath());
+		String[] result = execute(cmd);
+		assertArrayEquals(new String[] {
+				"Cloning into '" + target.getPath() + "'...", "", "" }, result);
+
+		Git git2 = Git.open(target);
+		addRepoToClose(git2.getRepository());
+
+		List<RevCommit> log = StreamSupport
+				.stream(git2.log().all().call().spliterator(), false)
+				.collect(Collectors.toList());
+		assertEquals(2, log.size());
+		assertEquals(List.of("Third commit", "Second commit"), log.stream()
+				.map(RevCommit::getFullMessage).collect(Collectors.toList()));
+	}
+
+	@Test
+	public void testCloneRepositoryWithShallowSince() throws Exception {
+		createInitialCommit();
+		tr.tick(30);
+		RevCommit secondCommit = createSecondCommit();
+		tr.tick(45);
+		createThirdCommit();
+
+		File gitDir = db.getDirectory();
+		String sourceURI = gitDir.toURI().toString();
+		File target = createTempDirectory("target");
+		String cmd = "git clone --shallow-since="
+				+ Instant.ofEpochSecond(secondCommit.getCommitTime()).toString()
+				+ " " + sourceURI + " " + shellQuote(target.getPath());
+		String[] result = execute(cmd);
+		assertArrayEquals(new String[] {
+				"Cloning into '" + target.getPath() + "'...", "", "" }, result);
+
+		Git git2 = Git.open(target);
+		addRepoToClose(git2.getRepository());
+
+		List<RevCommit> log = StreamSupport
+				.stream(git2.log().all().call().spliterator(), false)
+				.collect(Collectors.toList());
+		assertEquals(2, log.size());
+		assertEquals(List.of("Third commit", "Second commit"), log.stream()
+				.map(RevCommit::getFullMessage).collect(Collectors.toList()));
+	}
+
+	@Test
+	public void testCloneRepositoryWithShallowExclude() throws Exception {
+		final RevCommit firstCommit = createInitialCommit();
+		final RevCommit secondCommit = createSecondCommit();
+		createThirdCommit();
+
+		File gitDir = db.getDirectory();
+		String sourceURI = gitDir.toURI().toString();
+		File target = createTempDirectory("target");
+		String cmd = "git clone --shallow-exclude="
+				+ firstCommit.getId().getName() + " --shallow-exclude="
+				+ secondCommit.getId().getName() + " " + sourceURI + " "
+				+ shellQuote(target.getPath());
+		String[] result = execute(cmd);
+		assertArrayEquals(new String[] {
+				"Cloning into '" + target.getPath() + "'...", "", "" }, result);
+
+		Git git2 = Git.open(target);
+		addRepoToClose(git2.getRepository());
+
+		List<RevCommit> log = StreamSupport
+				.stream(git2.log().all().call().spliterator(), false)
+				.collect(Collectors.toList());
+		assertEquals(1, log.size());
+		assertEquals(List.of("Third commit"), log.stream()
+				.map(RevCommit::getFullMessage).collect(Collectors.toList()));
+	}
+
 }
diff --git a/org.eclipse.jgit.pgm/META-INF/MANIFEST.MF b/org.eclipse.jgit.pgm/META-INF/MANIFEST.MF
index ecbb24c..0dc43ff 100644
--- a/org.eclipse.jgit.pgm/META-INF/MANIFEST.MF
+++ b/org.eclipse.jgit.pgm/META-INF/MANIFEST.MF
@@ -3,7 +3,7 @@
 Bundle-Name: %Bundle-Name
 Automatic-Module-Name: org.eclipse.jgit.pgm
 Bundle-SymbolicName: org.eclipse.jgit.pgm
-Bundle-Version: 6.4.1.qualifier
+Bundle-Version: 6.5.0.qualifier
 Bundle-Vendor: %Bundle-Vendor
 Bundle-Localization: plugin
 Bundle-RequiredExecutionEnvironment: JavaSE-11
@@ -14,49 +14,49 @@
  org.eclipse.jetty.servlet;version="[10.0.0,11.0.0)",
  org.eclipse.jetty.util;version="[10.0.0,11.0.0)",
  org.eclipse.jetty.util.component;version="[10.0.0,11.0.0)",
- org.eclipse.jgit.api;version="[6.4.1,6.5.0)",
- org.eclipse.jgit.api.errors;version="[6.4.1,6.5.0)",
- org.eclipse.jgit.archive;version="[6.4.1,6.5.0)",
- org.eclipse.jgit.awtui;version="[6.4.1,6.5.0)",
- org.eclipse.jgit.blame;version="[6.4.1,6.5.0)",
- org.eclipse.jgit.diff;version="[6.4.1,6.5.0)",
- org.eclipse.jgit.dircache;version="[6.4.1,6.5.0)",
- org.eclipse.jgit.errors;version="[6.4.1,6.5.0)",
- org.eclipse.jgit.gitrepo;version="[6.4.1,6.5.0)",
- org.eclipse.jgit.internal.storage.file;version="[6.4.1,6.5.0)",
- org.eclipse.jgit.internal.diffmergetool;version="[6.4.1,6.5.0)",
- org.eclipse.jgit.internal.storage.io;version="[6.4.1,6.5.0)",
- org.eclipse.jgit.internal.storage.pack;version="[6.4.1,6.5.0)",
- org.eclipse.jgit.internal.storage.reftable;version="[6.4.1,6.5.0)",
- org.eclipse.jgit.lfs;version="[6.4.1,6.5.0)",
- org.eclipse.jgit.lfs.server;version="[6.4.1,6.5.0)",
- org.eclipse.jgit.lfs.server.fs;version="[6.4.1,6.5.0)",
- org.eclipse.jgit.lfs.server.s3;version="[6.4.1,6.5.0)",
- org.eclipse.jgit.lib;version="[6.4.1,6.5.0)",
- org.eclipse.jgit.merge;version="[6.4.1,6.5.0)",
- org.eclipse.jgit.lib.internal;version="[6.4.1,6.5.0)",
- org.eclipse.jgit.nls;version="[6.4.1,6.5.0)",
- org.eclipse.jgit.notes;version="[6.4.1,6.5.0)",
- org.eclipse.jgit.revplot;version="[6.4.1,6.5.0)",
- org.eclipse.jgit.revwalk;version="[6.4.1,6.5.0)",
- org.eclipse.jgit.revwalk.filter;version="[6.4.1,6.5.0)",
- org.eclipse.jgit.storage.file;version="[6.4.1,6.5.0)",
- org.eclipse.jgit.storage.pack;version="[6.4.1,6.5.0)",
- org.eclipse.jgit.transport;version="[6.4.1,6.5.0)",
- org.eclipse.jgit.transport.http.apache;version="[6.4.1,6.5.0)",
- org.eclipse.jgit.transport.resolver;version="[6.4.1,6.5.0)",
- org.eclipse.jgit.transport.ssh.jsch;version="[6.4.1,6.5.0)",
- org.eclipse.jgit.transport.sshd;version="[6.4.1,6.5.0)",
- org.eclipse.jgit.treewalk;version="[6.4.1,6.5.0)",
- org.eclipse.jgit.treewalk.filter;version="[6.4.1,6.5.0)",
- org.eclipse.jgit.util;version="[6.4.1,6.5.0)",
- org.eclipse.jgit.util.io;version="[6.4.1,6.5.0)",
+ org.eclipse.jgit.api;version="[6.5.0,6.6.0)",
+ org.eclipse.jgit.api.errors;version="[6.5.0,6.6.0)",
+ org.eclipse.jgit.archive;version="[6.5.0,6.6.0)",
+ org.eclipse.jgit.awtui;version="[6.5.0,6.6.0)",
+ org.eclipse.jgit.blame;version="[6.5.0,6.6.0)",
+ org.eclipse.jgit.diff;version="[6.5.0,6.6.0)",
+ org.eclipse.jgit.dircache;version="[6.5.0,6.6.0)",
+ org.eclipse.jgit.errors;version="[6.5.0,6.6.0)",
+ org.eclipse.jgit.gitrepo;version="[6.5.0,6.6.0)",
+ org.eclipse.jgit.internal.storage.file;version="[6.5.0,6.6.0)",
+ org.eclipse.jgit.internal.diffmergetool;version="[6.5.0,6.6.0)",
+ org.eclipse.jgit.internal.storage.io;version="[6.5.0,6.6.0)",
+ org.eclipse.jgit.internal.storage.pack;version="[6.5.0,6.6.0)",
+ org.eclipse.jgit.internal.storage.reftable;version="[6.5.0,6.6.0)",
+ org.eclipse.jgit.lfs;version="[6.5.0,6.6.0)",
+ org.eclipse.jgit.lfs.server;version="[6.5.0,6.6.0)",
+ org.eclipse.jgit.lfs.server.fs;version="[6.5.0,6.6.0)",
+ org.eclipse.jgit.lfs.server.s3;version="[6.5.0,6.6.0)",
+ org.eclipse.jgit.lib;version="[6.5.0,6.6.0)",
+ org.eclipse.jgit.merge;version="[6.5.0,6.6.0)",
+ org.eclipse.jgit.lib.internal;version="[6.5.0,6.6.0)",
+ org.eclipse.jgit.nls;version="[6.5.0,6.6.0)",
+ org.eclipse.jgit.notes;version="[6.5.0,6.6.0)",
+ org.eclipse.jgit.revplot;version="[6.5.0,6.6.0)",
+ org.eclipse.jgit.revwalk;version="[6.5.0,6.6.0)",
+ org.eclipse.jgit.revwalk.filter;version="[6.5.0,6.6.0)",
+ org.eclipse.jgit.storage.file;version="[6.5.0,6.6.0)",
+ org.eclipse.jgit.storage.pack;version="[6.5.0,6.6.0)",
+ org.eclipse.jgit.transport;version="[6.5.0,6.6.0)",
+ org.eclipse.jgit.transport.http.apache;version="[6.5.0,6.6.0)",
+ org.eclipse.jgit.transport.resolver;version="[6.5.0,6.6.0)",
+ org.eclipse.jgit.transport.ssh.jsch;version="[6.5.0,6.6.0)",
+ org.eclipse.jgit.transport.sshd;version="[6.5.0,6.6.0)",
+ org.eclipse.jgit.treewalk;version="[6.5.0,6.6.0)",
+ org.eclipse.jgit.treewalk.filter;version="[6.5.0,6.6.0)",
+ org.eclipse.jgit.util;version="[6.5.0,6.6.0)",
+ org.eclipse.jgit.util.io;version="[6.5.0,6.6.0)",
  org.kohsuke.args4j;version="[2.33.0,3.0.0)",
  org.kohsuke.args4j.spi;version="[2.33.0,3.0.0)"
-Export-Package: org.eclipse.jgit.console;version="6.4.1";
+Export-Package: org.eclipse.jgit.console;version="6.5.0";
  uses:="org.eclipse.jgit.transport,
   org.eclipse.jgit.util",
- org.eclipse.jgit.pgm;version="6.4.1";
+ org.eclipse.jgit.pgm;version="6.5.0";
   uses:="org.eclipse.jgit.transport,
    org.eclipse.jgit.util.io,
    org.eclipse.jgit.awtui,
@@ -68,14 +68,14 @@
    org.eclipse.jgit.treewalk,
    org.eclipse.jgit.api,
    javax.swing",
- org.eclipse.jgit.pgm.debug;version="6.4.1";
+ org.eclipse.jgit.pgm.debug;version="6.5.0";
   uses:="org.eclipse.jgit.util.io,
    org.eclipse.jgit.pgm,
    org.eclipse.jetty.servlet",
- org.eclipse.jgit.pgm.internal;version="6.4.1";
+ org.eclipse.jgit.pgm.internal;version="6.5.0";
   x-friends:="org.eclipse.jgit.pgm.test,
    org.eclipse.jgit.test",
- org.eclipse.jgit.pgm.opt;version="6.4.1";
+ org.eclipse.jgit.pgm.opt;version="6.5.0";
   uses:="org.kohsuke.args4j,
    org.eclipse.jgit.lib,
    org.eclipse.jgit.revwalk,
diff --git a/org.eclipse.jgit.pgm/META-INF/SOURCE-MANIFEST.MF b/org.eclipse.jgit.pgm/META-INF/SOURCE-MANIFEST.MF
index e2bc4f0..ddbeb6e 100644
--- a/org.eclipse.jgit.pgm/META-INF/SOURCE-MANIFEST.MF
+++ b/org.eclipse.jgit.pgm/META-INF/SOURCE-MANIFEST.MF
@@ -3,5 +3,5 @@
 Bundle-Name: org.eclipse.jgit.pgm - Sources
 Bundle-SymbolicName: org.eclipse.jgit.pgm.source
 Bundle-Vendor: Eclipse.org - JGit
-Bundle-Version: 6.4.1.qualifier
-Eclipse-SourceBundle: org.eclipse.jgit.pgm;version="6.4.1.qualifier";roots="."
+Bundle-Version: 6.5.0.qualifier
+Eclipse-SourceBundle: org.eclipse.jgit.pgm;version="6.5.0.qualifier";roots="."
diff --git a/org.eclipse.jgit.pgm/pom.xml b/org.eclipse.jgit.pgm/pom.xml
index eda51f1..420f556 100644
--- a/org.eclipse.jgit.pgm/pom.xml
+++ b/org.eclipse.jgit.pgm/pom.xml
@@ -17,7 +17,7 @@
   <parent>
     <groupId>org.eclipse.jgit</groupId>
     <artifactId>org.eclipse.jgit-parent</artifactId>
-    <version>6.4.1-SNAPSHOT</version>
+    <version>6.5.0-SNAPSHOT</version>
   </parent>
 
   <artifactId>org.eclipse.jgit.pgm</artifactId>
diff --git a/org.eclipse.jgit.pgm/resources/org/eclipse/jgit/pgm/internal/CLIText.properties b/org.eclipse.jgit.pgm/resources/org/eclipse/jgit/pgm/internal/CLIText.properties
index 48f4e85..98d711d 100644
--- a/org.eclipse.jgit.pgm/resources/org/eclipse/jgit/pgm/internal/CLIText.properties
+++ b/org.eclipse.jgit.pgm/resources/org/eclipse/jgit/pgm/internal/CLIText.properties
@@ -137,6 +137,7 @@
 metaVar_commitPaths=paths
 metaVar_configFile=FILE
 metaVar_connProp=conn.prop
+metaVar_depth=<depth>
 metaVar_diffAlg=ALGORITHM
 metaVar_directory=DIRECTORY
 metaVar_extraArgument=ours|theirs
@@ -144,6 +145,7 @@
 metaVar_filepattern=filepattern
 metaVar_gitDir=GIT_DIR
 metaVar_hostName=HOSTNAME
+metaVar_instant=<instant>
 metaVar_lfsStorage=STORAGE
 metaVar_linesOfContext=lines
 metaVar_message=message
@@ -168,6 +170,8 @@
 metaVar_s3StorageClass=STORAGE-CLASS
 metaVar_seconds=SECONDS
 metaVar_service=SERVICE
+metaVar_shallowExclude=<revision>
+metaVar_shallowSince=<date>
 metaVar_tagLocalUser=<GPG key ID>
 metaVar_tool=TOOL
 metaVar_treeish=tree-ish
@@ -374,6 +378,7 @@
 usage_diffAlgorithm=the diff algorithm to use. Currently supported are: 'myers', 'histogram'
 usage_DiffTool=git difftool is a Git command that allows you to compare and edit files between revisions using common diff tools.\ngit difftool is a frontend to git diff and accepts the same options and arguments.
 usage_MergeTool=git-mergetool - Run merge conflict resolution tools to resolve merge conflicts.\nUse git mergetool to run one of several merge utilities to resolve merge conflicts. It is typically run after git merge.
+usage_depth=Limit fetching to the specified number of commits from the tip of each remote branch history.
 usage_directoriesToExport=directories to export
 usage_disableTheServiceInAllRepositories=disable the service in all repositories
 usage_displayAListOfAllRegisteredJgitCommands=Display a list of all registered jgit commands
@@ -447,6 +452,8 @@
 usage_runLfsStore=Run LFS Store in a given directory
 usage_S3NoSslVerify=Skip verification of Amazon server certificate and hostname
 usage_setTheGitRepositoryToOperateOn=set the git repository to operate on
+usage_shallowExclude=Deepen or shorten the history of a shallow repository to exclude commits reachable from a specified remote branch or tag. 
+usage_shallowSince=Deepen or shorten the history of a shallow repository to include all reachable commits after <date>.
 usage_show=Display one commit
 usage_showRefNamesMatchingCommits=Show ref names matching commits
 usage_showPatch=display patch
diff --git a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/Clone.java b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/Clone.java
index f28915d..9f9fa8f 100644
--- a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/Clone.java
+++ b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/Clone.java
@@ -13,7 +13,10 @@
 import java.io.File;
 import java.io.IOException;
 import java.text.MessageFormat;
+import java.time.Instant;
+import java.util.ArrayList;
 import java.util.Collection;
+import java.util.List;
 
 import org.eclipse.jgit.api.CloneCommand;
 import org.eclipse.jgit.api.Git;
@@ -48,6 +51,15 @@ class Clone extends AbstractFetchCommand implements CloneCommand.Callback {
 	@Option(name = "--quiet", usage = "usage_quiet")
 	private Boolean quiet;
 
+	@Option(name = "--depth", metaVar = "metaVar_depth", usage = "usage_depth")
+	private Integer depth = null;
+
+	@Option(name = "--shallow-since", metaVar = "metaVar_shallowSince", usage = "usage_shallowSince")
+	private Instant shallowSince = null;
+
+	@Option(name = "--shallow-exclude", metaVar = "metaVar_shallowExclude", usage = "usage_shallowExclude")
+	private List<String> shallowExcludes = new ArrayList<>();
+
 	@Option(name = "--recurse-submodules", usage = "usage_recurseSubmodules")
 	private boolean cloneSubmodules;
 
@@ -97,6 +109,16 @@ protected void run() throws Exception {
 				.setMirror(isMirror).setNoCheckout(noCheckout).setBranch(branch)
 				.setCloneSubmodules(cloneSubmodules).setTimeout(timeout);
 
+		if (depth != null) {
+			command.setDepth(depth.intValue());
+		}
+		if (shallowSince != null) {
+			command.setShallowSince(shallowSince);
+		}
+		for (String shallowExclude : shallowExcludes) {
+			command.addShallowExclude(shallowExclude);
+		}
+
 		command.setGitDir(gitdir == null ? null : new File(gitdir));
 		command.setDirectory(localNameF);
 		boolean msgs = quiet == null || !quiet.booleanValue();
diff --git a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/Fetch.java b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/Fetch.java
index fbce4a5..2e0c36b 100644
--- a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/Fetch.java
+++ b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/Fetch.java
@@ -14,6 +14,8 @@
 
 import java.io.IOException;
 import java.text.MessageFormat;
+import java.time.Instant;
+import java.util.ArrayList;
 import java.util.List;
 
 import org.eclipse.jgit.api.FetchCommand;
@@ -62,6 +64,15 @@ void nothin(@SuppressWarnings("unused") final boolean ignored) {
 	@Option(name = "--tags", usage="usage_tags", aliases = { "-t" })
 	private Boolean tags;
 
+	@Option(name = "--depth", metaVar = "metaVar_depth", usage = "usage_depth")
+	private Integer depth = null;
+
+	@Option(name = "--shallow-since", metaVar = "metaVar_shallowSince", usage = "usage_shallowSince")
+	private Instant shallowSince = null;
+
+	@Option(name = "--shallow-exclude", metaVar = "metaVar_shallowExclude", usage = "usage_shallowExclude")
+	private List<String> shallowExcludes = new ArrayList<>();
+
 	@Option(name = "--no-tags", usage = "usage_notags", aliases = { "-n" })
 	void notags(@SuppressWarnings("unused")
 	final boolean ignored) {
@@ -120,6 +131,15 @@ protected void run() {
 				fetch.setTagOpt(tags.booleanValue() ? TagOpt.FETCH_TAGS
 						: TagOpt.NO_TAGS);
 			}
+			if (depth != null) {
+				fetch.setDepth(depth.intValue());
+			}
+			if (shallowSince != null) {
+				fetch.setShallowSince(shallowSince);
+			}
+			for (String shallowExclude : shallowExcludes) {
+				fetch.addShallowExclude(shallowExclude);
+			}
 			if (0 <= timeout) {
 				fetch.setTimeout(timeout);
 			}
diff --git a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/internal/CLIText.java b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/internal/CLIText.java
index 490f800..d07268b 100644
--- a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/internal/CLIText.java
+++ b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/internal/CLIText.java
@@ -214,6 +214,7 @@ public static String fatalError(String message) {
 	/***/ public String metaVar_filepattern;
 	/***/ public String metaVar_gitDir;
 	/***/ public String metaVar_hostName;
+	/***/ public String metaVar_instant;
 	/***/ public String metaVar_lfsStorage;
 	/***/ public String metaVar_linesOfContext;
 	/***/ public String metaVar_message;
diff --git a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/opt/CmdLineParser.java b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/opt/CmdLineParser.java
index 5d32e65..df0b39b 100644
--- a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/opt/CmdLineParser.java
+++ b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/opt/CmdLineParser.java
@@ -13,6 +13,7 @@
 import java.io.IOException;
 import java.io.Writer;
 import java.lang.reflect.Field;
+import java.time.Instant;
 import java.util.ArrayList;
 import java.util.Iterator;
 import java.util.List;
@@ -55,6 +56,7 @@ public class CmdLineParser extends org.kohsuke.args4j.CmdLineParser {
 		registry.registerHandler(RevCommit.class, RevCommitHandler.class);
 		registry.registerHandler(RevTree.class, RevTreeHandler.class);
 		registry.registerHandler(List.class, OptionWithValuesListHandler.class);
+		registry.registerHandler(Instant.class, InstantHandler.class);
 	}
 
 	private final Repository db;
diff --git a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/opt/InstantHandler.java b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/opt/InstantHandler.java
new file mode 100644
index 0000000..feee78e
--- /dev/null
+++ b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/opt/InstantHandler.java
@@ -0,0 +1,60 @@
+/*
+ * Copyright (C) 2022, Harald Weiner 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.opt;
+
+import java.time.Instant;
+
+import org.eclipse.jgit.pgm.internal.CLIText;
+import org.kohsuke.args4j.CmdLineException;
+import org.kohsuke.args4j.CmdLineParser;
+import org.kohsuke.args4j.OptionDef;
+import org.kohsuke.args4j.spi.OptionHandler;
+import org.kohsuke.args4j.spi.Parameters;
+import org.kohsuke.args4j.spi.Setter;
+
+/**
+ * Custom argument handler {@link java.time.Instant} from string values.
+ * <p>
+ * Assumes the parser has been initialized with a Repository.
+ *
+ * @since 6.5
+ */
+public class InstantHandler extends OptionHandler<Instant> {
+	/**
+	 * Create a new handler for the command name.
+	 * <p>
+	 * This constructor is used only by args4j.
+	 *
+	 * @param parser
+	 *            a {@link org.kohsuke.args4j.CmdLineParser} object.
+	 * @param option
+	 *            a {@link org.kohsuke.args4j.OptionDef} object.
+	 * @param setter
+	 *            a {@link org.kohsuke.args4j.spi.Setter} object.
+	 */
+	public InstantHandler(CmdLineParser parser, OptionDef option,
+			Setter<? super Instant> setter) {
+		super(parser, option, setter);
+	}
+
+	/** {@inheritDoc} */
+	@Override
+	public int parseArguments(Parameters params) throws CmdLineException {
+		Instant instant = Instant.parse(params.getParameter(0));
+		setter.addValue(instant);
+		return 1;
+	}
+
+	/** {@inheritDoc} */
+	@Override
+	public String getDefaultMetaVariable() {
+		return CLIText.get().metaVar_instant;
+	}
+}
diff --git a/org.eclipse.jgit.ssh.apache.agent/META-INF/MANIFEST.MF b/org.eclipse.jgit.ssh.apache.agent/META-INF/MANIFEST.MF
index 0f26a38..81ea587 100644
--- a/org.eclipse.jgit.ssh.apache.agent/META-INF/MANIFEST.MF
+++ b/org.eclipse.jgit.ssh.apache.agent/META-INF/MANIFEST.MF
@@ -2,16 +2,16 @@
 Bundle-ManifestVersion: 2
 Bundle-Name: %Bundle-Name
 Bundle-SymbolicName: org.eclipse.jgit.ssh.apache.agent;singleton:=true
-Bundle-Version: 6.4.1.qualifier
+Bundle-Version: 6.5.0.qualifier
 Bundle-Localization: plugin
 Bundle-Vendor: %Bundle-Vendor
-Fragment-Host: org.eclipse.jgit.ssh.apache;bundle-version="[6.4.1,6.5.0)"
+Fragment-Host: org.eclipse.jgit.ssh.apache;bundle-version="[6.5.0,6.6.0)"
 Bundle-ActivationPolicy: lazy
 Automatic-Module-Name: org.eclipse.jgit.ssh.apache.agent
 Bundle-RequiredExecutionEnvironment: JavaSE-11
-Import-Package: org.eclipse.jgit.transport.sshd;version="[6.4.1,6.5.0)",
- org.eclipse.jgit.nls;version="[6.4.1,6.5.0)",
- org.eclipse.jgit.util;version="[6.4.1,6.5.0)"
+Import-Package: org.eclipse.jgit.transport.sshd;version="[6.5.0,6.6.0)",
+ org.eclipse.jgit.nls;version="[6.5.0,6.6.0)",
+ org.eclipse.jgit.util;version="[6.5.0,6.6.0)"
 Require-Bundle: com.sun.jna;bundle-version="[5.8.0,6.0.0)",
  com.sun.jna.platform;bundle-version="[5.8.0,6.0.0)"
-Export-Package: org.eclipse.jgit.internal.transport.sshd.agent.connector;version="6.4.1";x-internal:=true
+Export-Package: org.eclipse.jgit.internal.transport.sshd.agent.connector;version="6.5.0";x-internal:=true
diff --git a/org.eclipse.jgit.ssh.apache.agent/META-INF/SOURCE-MANIFEST.MF b/org.eclipse.jgit.ssh.apache.agent/META-INF/SOURCE-MANIFEST.MF
index f59f6fe..8e73926b 100644
--- a/org.eclipse.jgit.ssh.apache.agent/META-INF/SOURCE-MANIFEST.MF
+++ b/org.eclipse.jgit.ssh.apache.agent/META-INF/SOURCE-MANIFEST.MF
@@ -3,5 +3,5 @@
 Bundle-Name: org.eclipse.jgit.ssh.apache.agent - Sources
 Bundle-SymbolicName: org.eclipse.jgit.ssh.apache.agent.source
 Bundle-Vendor: Eclipse.org - JGit
-Bundle-Version: 6.4.1.qualifier
-Eclipse-SourceBundle: org.eclipse.jgit.ssh.apache.agent;version="6.4.1.qualifier";roots="."
+Bundle-Version: 6.5.0.qualifier
+Eclipse-SourceBundle: org.eclipse.jgit.ssh.apache.agent;version="6.5.0.qualifier";roots="."
diff --git a/org.eclipse.jgit.ssh.apache.agent/pom.xml b/org.eclipse.jgit.ssh.apache.agent/pom.xml
index 9f16d47..28c7c73 100644
--- a/org.eclipse.jgit.ssh.apache.agent/pom.xml
+++ b/org.eclipse.jgit.ssh.apache.agent/pom.xml
@@ -17,7 +17,7 @@
   <parent>
     <groupId>org.eclipse.jgit</groupId>
     <artifactId>org.eclipse.jgit-parent</artifactId>
-    <version>6.4.1-SNAPSHOT</version>
+    <version>6.5.0-SNAPSHOT</version>
   </parent>
 
   <artifactId>org.eclipse.jgit.ssh.apache.agent</artifactId>
diff --git a/org.eclipse.jgit.ssh.apache.test/META-INF/MANIFEST.MF b/org.eclipse.jgit.ssh.apache.test/META-INF/MANIFEST.MF
index 3175a4a..58353e6 100644
--- a/org.eclipse.jgit.ssh.apache.test/META-INF/MANIFEST.MF
+++ b/org.eclipse.jgit.ssh.apache.test/META-INF/MANIFEST.MF
@@ -3,7 +3,7 @@
 Bundle-Name: %Bundle-Name
 Automatic-Module-Name: org.eclipse.jgit.ssh.apache.test
 Bundle-SymbolicName: org.eclipse.jgit.ssh.apache.test
-Bundle-Version: 6.4.1.qualifier
+Bundle-Version: 6.5.0.qualifier
 Bundle-Vendor: %Bundle-Vendor
 Bundle-Localization: plugin
 Bundle-RequiredExecutionEnvironment: JavaSE-11
@@ -21,16 +21,16 @@
  org.apache.sshd.core;version="[2.9.2,2.10.0)",
  org.apache.sshd.server;version="[2.9.2,2.10.0)",
  org.apache.sshd.server.forward;version="[2.9.2,2.10.0)",
- org.eclipse.jgit.api;version="[6.4.1,6.5.0)",
- org.eclipse.jgit.api.errors;version="[6.4.1,6.5.0)",
- org.eclipse.jgit.internal.transport.sshd.proxy;version="[6.4.1,6.5.0)",
- org.eclipse.jgit.junit;version="[6.4.1,6.5.0)",
- org.eclipse.jgit.junit.ssh;version="[6.4.1,6.5.0)",
- org.eclipse.jgit.lib;version="[6.4.1,6.5.0)",
- org.eclipse.jgit.transport;version="[6.4.1,6.5.0)",
- org.eclipse.jgit.transport.sshd;version="[6.4.1,6.5.0)",
- org.eclipse.jgit.transport.sshd.agent;version="[6.4.1,6.5.0)",
- org.eclipse.jgit.util;version="[6.4.1,6.5.0)",
+ org.eclipse.jgit.api;version="[6.5.0,6.6.0)",
+ org.eclipse.jgit.api.errors;version="[6.5.0,6.6.0)",
+ org.eclipse.jgit.internal.transport.sshd.proxy;version="[6.5.0,6.6.0)",
+ org.eclipse.jgit.junit;version="[6.5.0,6.6.0)",
+ org.eclipse.jgit.junit.ssh;version="[6.5.0,6.6.0)",
+ org.eclipse.jgit.lib;version="[6.5.0,6.6.0)",
+ org.eclipse.jgit.transport;version="[6.5.0,6.6.0)",
+ org.eclipse.jgit.transport.sshd;version="[6.5.0,6.6.0)",
+ org.eclipse.jgit.transport.sshd.agent;version="[6.5.0,6.6.0)",
+ org.eclipse.jgit.util;version="[6.5.0,6.6.0)",
  org.hamcrest;version="[1.1.0,3.0.0)",
  org.junit;version="[4.13,5.0.0)",
  org.junit.experimental.theories;version="[4.13,5.0.0)",
diff --git a/org.eclipse.jgit.ssh.apache.test/pom.xml b/org.eclipse.jgit.ssh.apache.test/pom.xml
index 6adcb89..eee4c80 100644
--- a/org.eclipse.jgit.ssh.apache.test/pom.xml
+++ b/org.eclipse.jgit.ssh.apache.test/pom.xml
@@ -17,7 +17,7 @@
   <parent>
     <groupId>org.eclipse.jgit</groupId>
     <artifactId>org.eclipse.jgit-parent</artifactId>
-    <version>6.4.1-SNAPSHOT</version>
+    <version>6.5.0-SNAPSHOT</version>
   </parent>
 
   <artifactId>org.eclipse.jgit.ssh.apache.test</artifactId>
diff --git a/org.eclipse.jgit.ssh.apache/META-INF/MANIFEST.MF b/org.eclipse.jgit.ssh.apache/META-INF/MANIFEST.MF
index 786c664..6aba841 100644
--- a/org.eclipse.jgit.ssh.apache/META-INF/MANIFEST.MF
+++ b/org.eclipse.jgit.ssh.apache/META-INF/MANIFEST.MF
@@ -6,9 +6,9 @@
 Bundle-Vendor: %Bundle-Vendor
 Bundle-Localization: plugin
 Bundle-ActivationPolicy: lazy
-Bundle-Version: 6.4.1.qualifier
+Bundle-Version: 6.5.0.qualifier
 Bundle-RequiredExecutionEnvironment: JavaSE-11
-Export-Package: org.eclipse.jgit.internal.transport.sshd;version="6.4.1";x-internal:=true;
+Export-Package: org.eclipse.jgit.internal.transport.sshd;version="6.5.0";x-internal:=true;
   uses:="org.apache.sshd.client,
    org.apache.sshd.client.auth,
    org.apache.sshd.client.auth.keyboard,
@@ -23,17 +23,17 @@
    org.apache.sshd.common.signature,
    org.apache.sshd.common.util.buffer,
    org.eclipse.jgit.transport",
- org.eclipse.jgit.internal.transport.sshd.agent;version="6.4.1";x-internal:=true,
- org.eclipse.jgit.internal.transport.sshd.auth;version="6.4.1";x-internal:=true,
- org.eclipse.jgit.internal.transport.sshd.proxy;version="6.4.1";x-friends:="org.eclipse.jgit.ssh.apache.test",
- org.eclipse.jgit.transport.sshd;version="6.4.1";
+ org.eclipse.jgit.internal.transport.sshd.agent;version="6.5.0";x-internal:=true,
+ org.eclipse.jgit.internal.transport.sshd.auth;version="6.5.0";x-internal:=true,
+ org.eclipse.jgit.internal.transport.sshd.proxy;version="6.5.0";x-friends:="org.eclipse.jgit.ssh.apache.test",
+ org.eclipse.jgit.transport.sshd;version="6.5.0";
   uses:="org.eclipse.jgit.transport,
    org.apache.sshd.client.config.hosts,
    org.apache.sshd.common.keyprovider,
    org.eclipse.jgit.util,
    org.apache.sshd.client.session,
    org.apache.sshd.client.keyverifier",
- org.eclipse.jgit.transport.sshd.agent;version="6.4.1"
+ org.eclipse.jgit.transport.sshd.agent;version="6.5.0"
 Import-Package: net.i2p.crypto.eddsa;version="[0.3.0,0.4.0)",
  org.apache.sshd.agent;version="[2.9.2,2.10.0)",
  org.apache.sshd.client;version="[2.9.2,2.10.0)",
@@ -86,12 +86,12 @@
  org.apache.sshd.sftp;version="[2.9.2,2.10.0)",
  org.apache.sshd.sftp.client;version="[2.9.2,2.10.0)",
  org.apache.sshd.sftp.common;version="[2.9.2,2.10.0)",
- org.eclipse.jgit.annotations;version="[6.4.1,6.5.0)",
- org.eclipse.jgit.errors;version="[6.4.1,6.5.0)",
- org.eclipse.jgit.fnmatch;version="[6.4.1,6.5.0)",
- org.eclipse.jgit.internal.storage.file;version="[6.4.1,6.5.0)",
- org.eclipse.jgit.internal.transport.ssh;version="[6.4.1,6.5.0)",
- org.eclipse.jgit.nls;version="[6.4.1,6.5.0)",
- org.eclipse.jgit.transport;version="[6.4.1,6.5.0)",
- org.eclipse.jgit.util;version="[6.4.1,6.5.0)",
+ org.eclipse.jgit.annotations;version="[6.5.0,6.6.0)",
+ org.eclipse.jgit.errors;version="[6.5.0,6.6.0)",
+ org.eclipse.jgit.fnmatch;version="[6.5.0,6.6.0)",
+ org.eclipse.jgit.internal.storage.file;version="[6.5.0,6.6.0)",
+ org.eclipse.jgit.internal.transport.ssh;version="[6.5.0,6.6.0)",
+ org.eclipse.jgit.nls;version="[6.5.0,6.6.0)",
+ org.eclipse.jgit.transport;version="[6.5.0,6.6.0)",
+ org.eclipse.jgit.util;version="[6.5.0,6.6.0)",
  org.slf4j;version="[1.7.0,2.0.0)"
diff --git a/org.eclipse.jgit.ssh.apache/META-INF/SOURCE-MANIFEST.MF b/org.eclipse.jgit.ssh.apache/META-INF/SOURCE-MANIFEST.MF
index 2693c45..93a4e23 100644
--- a/org.eclipse.jgit.ssh.apache/META-INF/SOURCE-MANIFEST.MF
+++ b/org.eclipse.jgit.ssh.apache/META-INF/SOURCE-MANIFEST.MF
@@ -3,5 +3,5 @@
 Bundle-Name: org.eclipse.jgit.ssh.apache - Sources
 Bundle-SymbolicName: org.eclipse.jgit.ssh.apache.source
 Bundle-Vendor: Eclipse.org - JGit
-Bundle-Version: 6.4.1.qualifier
-Eclipse-SourceBundle: org.eclipse.jgit.ssh.apache;version="6.4.1.qualifier";roots="."
+Bundle-Version: 6.5.0.qualifier
+Eclipse-SourceBundle: org.eclipse.jgit.ssh.apache;version="6.5.0.qualifier";roots="."
diff --git a/org.eclipse.jgit.ssh.apache/pom.xml b/org.eclipse.jgit.ssh.apache/pom.xml
index e68e68a..8ce5f25 100644
--- a/org.eclipse.jgit.ssh.apache/pom.xml
+++ b/org.eclipse.jgit.ssh.apache/pom.xml
@@ -17,7 +17,7 @@
   <parent>
     <groupId>org.eclipse.jgit</groupId>
     <artifactId>org.eclipse.jgit-parent</artifactId>
-    <version>6.4.1-SNAPSHOT</version>
+    <version>6.5.0-SNAPSHOT</version>
   </parent>
 
   <artifactId>org.eclipse.jgit.ssh.apache</artifactId>
diff --git a/org.eclipse.jgit.ssh.jsch.test/META-INF/MANIFEST.MF b/org.eclipse.jgit.ssh.jsch.test/META-INF/MANIFEST.MF
index 106cf13..1f0b25b 100644
--- a/org.eclipse.jgit.ssh.jsch.test/META-INF/MANIFEST.MF
+++ b/org.eclipse.jgit.ssh.jsch.test/META-INF/MANIFEST.MF
@@ -3,18 +3,18 @@
 Bundle-Name: %Bundle-Name
 Automatic-Module-Name: org.eclipse.jgit.ssh.jsch.test
 Bundle-SymbolicName: org.eclipse.jgit.ssh.jsch.test
-Bundle-Version: 6.4.1.qualifier
+Bundle-Version: 6.5.0.qualifier
 Bundle-Vendor: %Bundle-Vendor
 Bundle-Localization: plugin
 Bundle-RequiredExecutionEnvironment: JavaSE-11
 Import-Package: com.jcraft.jsch;version="[0.1.54,0.2.0)",
- org.eclipse.jgit.errors;version="[6.4.1,6.5.0)",
- org.eclipse.jgit.junit;version="[6.4.1,6.5.0)",
- org.eclipse.jgit.junit.ssh;version="[6.4.1,6.5.0)",
- org.eclipse.jgit.lib;version="[6.4.1,6.5.0)",
- org.eclipse.jgit.transport;version="[6.4.1,6.5.0)",
- org.eclipse.jgit.transport.ssh.jsch;version="[6.4.1,6.5.0)",
- org.eclipse.jgit.util;version="[6.4.1,6.5.0)",
+ org.eclipse.jgit.errors;version="[6.5.0,6.6.0)",
+ org.eclipse.jgit.junit;version="[6.5.0,6.6.0)",
+ org.eclipse.jgit.junit.ssh;version="[6.5.0,6.6.0)",
+ org.eclipse.jgit.lib;version="[6.5.0,6.6.0)",
+ org.eclipse.jgit.transport;version="[6.5.0,6.6.0)",
+ org.eclipse.jgit.transport.ssh.jsch;version="[6.5.0,6.6.0)",
+ org.eclipse.jgit.util;version="[6.5.0,6.6.0)",
  org.hamcrest;version="[1.1.0,3.0.0)",
  org.junit;version="[4.13,5.0.0)",
  org.junit.experimental.theories;version="[4.13,5.0.0)",
diff --git a/org.eclipse.jgit.ssh.jsch.test/pom.xml b/org.eclipse.jgit.ssh.jsch.test/pom.xml
index 8984813..df37c58 100644
--- a/org.eclipse.jgit.ssh.jsch.test/pom.xml
+++ b/org.eclipse.jgit.ssh.jsch.test/pom.xml
@@ -17,7 +17,7 @@
   <parent>
     <groupId>org.eclipse.jgit</groupId>
     <artifactId>org.eclipse.jgit-parent</artifactId>
-    <version>6.4.1-SNAPSHOT</version>
+    <version>6.5.0-SNAPSHOT</version>
   </parent>
 
   <artifactId>org.eclipse.jgit.ssh.jsch.test</artifactId>
diff --git a/org.eclipse.jgit.ssh.jsch/META-INF/MANIFEST.MF b/org.eclipse.jgit.ssh.jsch/META-INF/MANIFEST.MF
index 785b873..483f28f 100644
--- a/org.eclipse.jgit.ssh.jsch/META-INF/MANIFEST.MF
+++ b/org.eclipse.jgit.ssh.jsch/META-INF/MANIFEST.MF
@@ -3,19 +3,19 @@
 Bundle-Name: %Bundle-Name
 Automatic-Module-Name: org.eclipse.jgit.ssh.jsch
 Bundle-SymbolicName: org.eclipse.jgit.ssh.jsch;singleton:=true
-Fragment-Host: org.eclipse.jgit;bundle-version="[6.4.1,6.5.0)"
+Fragment-Host: org.eclipse.jgit;bundle-version="[6.5.0,6.6.0)"
 Bundle-Vendor: %Bundle-Vendor
 Bundle-Localization: plugin
 Bundle-ActivationPolicy: lazy
-Bundle-Version: 6.4.1.qualifier
+Bundle-Version: 6.5.0.qualifier
 Bundle-RequiredExecutionEnvironment: JavaSE-11
-Export-Package: org.eclipse.jgit.transport.ssh.jsch;version="6.4.1"
+Export-Package: org.eclipse.jgit.transport.ssh.jsch;version="6.5.0"
 Import-Package: com.jcraft.jsch;version="[0.1.37,0.2.0)",
- org.eclipse.jgit.errors;version="[6.4.1,6.5.0)",
- org.eclipse.jgit.internal;version="[6.4.1,6.5.0)",
- org.eclipse.jgit.internal.transport.ssh;version="[6.4.1,6.5.0)",
- org.eclipse.jgit.nls;version="[6.4.1,6.5.0)",
- org.eclipse.jgit.transport;version="[6.4.1,6.5.0)",
- org.eclipse.jgit.util;version="[6.4.1,6.5.0)",
- org.eclipse.jgit.util.io;version="[6.4.1,6.5.0)",
+ org.eclipse.jgit.errors;version="[6.5.0,6.6.0)",
+ org.eclipse.jgit.internal;version="[6.5.0,6.6.0)",
+ org.eclipse.jgit.internal.transport.ssh;version="[6.5.0,6.6.0)",
+ org.eclipse.jgit.nls;version="[6.5.0,6.6.0)",
+ org.eclipse.jgit.transport;version="[6.5.0,6.6.0)",
+ org.eclipse.jgit.util;version="[6.5.0,6.6.0)",
+ org.eclipse.jgit.util.io;version="[6.5.0,6.6.0)",
  org.slf4j;version="[1.7.0,2.0.0)"
diff --git a/org.eclipse.jgit.ssh.jsch/META-INF/SOURCE-MANIFEST.MF b/org.eclipse.jgit.ssh.jsch/META-INF/SOURCE-MANIFEST.MF
index 37aaf8d..e2d73fb 100644
--- a/org.eclipse.jgit.ssh.jsch/META-INF/SOURCE-MANIFEST.MF
+++ b/org.eclipse.jgit.ssh.jsch/META-INF/SOURCE-MANIFEST.MF
@@ -3,5 +3,5 @@
 Bundle-Name: org.eclipse.jgit.ssh.jsch - Sources
 Bundle-SymbolicName: org.eclipse.jgit.ssh.jsch.source
 Bundle-Vendor: Eclipse.org - JGit
-Bundle-Version: 6.4.1.qualifier
-Eclipse-SourceBundle: org.eclipse.jgit.ssh.jsch;version="6.4.1.qualifier";roots="."
+Bundle-Version: 6.5.0.qualifier
+Eclipse-SourceBundle: org.eclipse.jgit.ssh.jsch;version="6.5.0.qualifier";roots="."
diff --git a/org.eclipse.jgit.ssh.jsch/pom.xml b/org.eclipse.jgit.ssh.jsch/pom.xml
index f859caf..bc099fc 100644
--- a/org.eclipse.jgit.ssh.jsch/pom.xml
+++ b/org.eclipse.jgit.ssh.jsch/pom.xml
@@ -17,7 +17,7 @@
   <parent>
     <groupId>org.eclipse.jgit</groupId>
     <artifactId>org.eclipse.jgit-parent</artifactId>
-    <version>6.4.1-SNAPSHOT</version>
+    <version>6.5.0-SNAPSHOT</version>
   </parent>
 
   <artifactId>org.eclipse.jgit.ssh.jsch</artifactId>
diff --git a/org.eclipse.jgit.test/META-INF/MANIFEST.MF b/org.eclipse.jgit.test/META-INF/MANIFEST.MF
index a68d5e3..df4a39c 100644
--- a/org.eclipse.jgit.test/META-INF/MANIFEST.MF
+++ b/org.eclipse.jgit.test/META-INF/MANIFEST.MF
@@ -3,7 +3,7 @@
 Bundle-Name: %Bundle-Name
 Automatic-Module-Name: org.eclipse.jgit.test
 Bundle-SymbolicName: org.eclipse.jgit.test
-Bundle-Version: 6.4.1.qualifier
+Bundle-Version: 6.5.0.qualifier
 Bundle-Localization: plugin
 Bundle-Vendor: %Bundle-Vendor
 Bundle-RequiredExecutionEnvironment: JavaSE-11
@@ -16,62 +16,64 @@
  org.apache.commons.compress.compressors.gzip;version="[1.15.0,2.0)",
  org.apache.commons.compress.compressors.xz;version="[1.15.0,2.0)",
  org.assertj.core.api;version="[3.14.0,4.0.0)",
- org.eclipse.jgit.annotations;version="[6.4.1,6.5.0)",
- org.eclipse.jgit.api;version="[6.4.1,6.5.0)",
- org.eclipse.jgit.api.errors;version="[6.4.1,6.5.0)",
- org.eclipse.jgit.archive;version="[6.4.1,6.5.0)",
- org.eclipse.jgit.attributes;version="[6.4.1,6.5.0)",
- org.eclipse.jgit.awtui;version="[6.4.1,6.5.0)",
- org.eclipse.jgit.blame;version="[6.4.1,6.5.0)",
- org.eclipse.jgit.diff;version="[6.4.1,6.5.0)",
- org.eclipse.jgit.dircache;version="[6.4.1,6.5.0)",
- org.eclipse.jgit.errors;version="[6.4.1,6.5.0)",
- org.eclipse.jgit.events;version="[6.4.1,6.5.0)",
- org.eclipse.jgit.fnmatch;version="[6.4.1,6.5.0)",
- org.eclipse.jgit.gitrepo;version="[6.4.1,6.5.0)",
- org.eclipse.jgit.hooks;version="[6.4.1,6.5.0)",
- org.eclipse.jgit.ignore;version="[6.4.1,6.5.0)",
- org.eclipse.jgit.ignore.internal;version="[6.4.1,6.5.0)",
- org.eclipse.jgit.internal;version="[6.4.1,6.5.0)",
- org.eclipse.jgit.internal.diff;version="[6.4.1,6.5.0)",
- org.eclipse.jgit.internal.diffmergetool;version="[6.4.1,6.5.0)",
- org.eclipse.jgit.internal.fsck;version="[6.4.1,6.5.0)",
- org.eclipse.jgit.internal.revwalk;version="[6.4.1,6.5.0)",
- org.eclipse.jgit.internal.storage.dfs;version="[6.4.1,6.5.0)",
- org.eclipse.jgit.internal.storage.file;version="[6.4.1,6.5.0)",
- org.eclipse.jgit.internal.storage.io;version="[6.4.1,6.5.0)",
- org.eclipse.jgit.internal.storage.pack;version="[6.4.1,6.5.0)",
- org.eclipse.jgit.internal.storage.reftable;version="[6.4.1,6.5.0)",
- org.eclipse.jgit.internal.transport.connectivity;version="[6.4.1,6.5.0)",
- org.eclipse.jgit.internal.transport.http;version="[6.4.1,6.5.0)",
- org.eclipse.jgit.internal.transport.parser;version="[6.4.1,6.5.0)",
- org.eclipse.jgit.internal.transport.ssh;version="[6.4.1,6.5.0)",
- org.eclipse.jgit.junit;version="[6.4.1,6.5.0)",
- org.eclipse.jgit.junit.time;version="[6.4.1,6.5.0)",
- org.eclipse.jgit.lfs;version="[6.4.1,6.5.0)",
- org.eclipse.jgit.lib;version="[6.4.1,6.5.0)",
- org.eclipse.jgit.lib.internal;version="[6.4.1,6.5.0)",
- org.eclipse.jgit.logging;version="[6.4.1,6.5.0)",
- org.eclipse.jgit.merge;version="[6.4.1,6.5.0)",
- org.eclipse.jgit.nls;version="[6.4.1,6.5.0)",
- org.eclipse.jgit.notes;version="[6.4.1,6.5.0)",
- org.eclipse.jgit.patch;version="[6.4.1,6.5.0)",
- org.eclipse.jgit.pgm;version="[6.4.1,6.5.0)",
- org.eclipse.jgit.pgm.internal;version="[6.4.1,6.5.0)",
- org.eclipse.jgit.revplot;version="[6.4.1,6.5.0)",
- org.eclipse.jgit.revwalk;version="[6.4.1,6.5.0)",
- org.eclipse.jgit.revwalk.filter;version="[6.4.1,6.5.0)",
- org.eclipse.jgit.storage.file;version="[6.4.1,6.5.0)",
- org.eclipse.jgit.storage.pack;version="[6.4.1,6.5.0)",
- org.eclipse.jgit.submodule;version="[6.4.1,6.5.0)",
- org.eclipse.jgit.transport;version="[6.4.1,6.5.0)",
- org.eclipse.jgit.transport.http;version="[6.4.1,6.5.0)",
- org.eclipse.jgit.transport.resolver;version="[6.4.1,6.5.0)",
- org.eclipse.jgit.treewalk;version="[6.4.1,6.5.0)",
- org.eclipse.jgit.treewalk.filter;version="[6.4.1,6.5.0)",
- org.eclipse.jgit.util;version="[6.4.1,6.5.0)",
- org.eclipse.jgit.util.io;version="[6.4.1,6.5.0)",
- org.eclipse.jgit.util.sha1;version="[6.4.1,6.5.0)",
+ org.eclipse.jgit.annotations;version="[6.5.0,6.6.0)",
+ org.eclipse.jgit.api;version="[6.5.0,6.6.0)",
+ org.eclipse.jgit.api.errors;version="[6.5.0,6.6.0)",
+ org.eclipse.jgit.archive;version="[6.5.0,6.6.0)",
+ org.eclipse.jgit.attributes;version="[6.5.0,6.6.0)",
+ org.eclipse.jgit.awtui;version="[6.5.0,6.6.0)",
+ org.eclipse.jgit.blame;version="[6.5.0,6.6.0)",
+ org.eclipse.jgit.diff;version="[6.5.0,6.6.0)",
+ org.eclipse.jgit.dircache;version="[6.5.0,6.6.0)",
+ org.eclipse.jgit.errors;version="[6.5.0,6.6.0)",
+ org.eclipse.jgit.events;version="[6.5.0,6.6.0)",
+ org.eclipse.jgit.fnmatch;version="[6.5.0,6.6.0)",
+ org.eclipse.jgit.gitrepo;version="[6.5.0,6.6.0)",
+ org.eclipse.jgit.hooks;version="[6.5.0,6.6.0)",
+ org.eclipse.jgit.ignore;version="[6.5.0,6.6.0)",
+ org.eclipse.jgit.ignore.internal;version="[6.5.0,6.6.0)",
+ org.eclipse.jgit.internal;version="[6.5.0,6.6.0)",
+ org.eclipse.jgit.internal.diff;version="[6.5.0,6.6.0)",
+ org.eclipse.jgit.internal.diffmergetool;version="[6.5.0,6.6.0)",
+ org.eclipse.jgit.internal.fsck;version="[6.5.0,6.6.0)",
+ org.eclipse.jgit.internal.revwalk;version="[6.5.0,6.6.0)",
+ org.eclipse.jgit.internal.storage.commitgraph;version="6.5.0",
+ org.eclipse.jgit.internal.storage.dfs;version="[6.5.0,6.6.0)",
+ org.eclipse.jgit.internal.storage.file;version="[6.5.0,6.6.0)",
+ org.eclipse.jgit.internal.storage.io;version="[6.5.0,6.6.0)",
+ org.eclipse.jgit.internal.storage.memory;version="[6.5.0,6.6.0)",
+ org.eclipse.jgit.internal.storage.pack;version="[6.5.0,6.6.0)",
+ org.eclipse.jgit.internal.storage.reftable;version="[6.5.0,6.6.0)",
+ org.eclipse.jgit.internal.transport.connectivity;version="[6.5.0,6.6.0)",
+ org.eclipse.jgit.internal.transport.http;version="[6.5.0,6.6.0)",
+ org.eclipse.jgit.internal.transport.parser;version="[6.5.0,6.6.0)",
+ org.eclipse.jgit.internal.transport.ssh;version="[6.5.0,6.6.0)",
+ org.eclipse.jgit.junit;version="[6.5.0,6.6.0)",
+ org.eclipse.jgit.junit.time;version="[6.5.0,6.6.0)",
+ org.eclipse.jgit.lfs;version="[6.5.0,6.6.0)",
+ org.eclipse.jgit.lib;version="[6.5.0,6.6.0)",
+ org.eclipse.jgit.lib.internal;version="[6.5.0,6.6.0)",
+ org.eclipse.jgit.logging;version="[6.5.0,6.6.0)",
+ org.eclipse.jgit.merge;version="[6.5.0,6.6.0)",
+ org.eclipse.jgit.nls;version="[6.5.0,6.6.0)",
+ org.eclipse.jgit.notes;version="[6.5.0,6.6.0)",
+ org.eclipse.jgit.patch;version="[6.5.0,6.6.0)",
+ org.eclipse.jgit.pgm;version="[6.5.0,6.6.0)",
+ org.eclipse.jgit.pgm.internal;version="[6.5.0,6.6.0)",
+ org.eclipse.jgit.revplot;version="[6.5.0,6.6.0)",
+ org.eclipse.jgit.revwalk;version="[6.5.0,6.6.0)",
+ org.eclipse.jgit.revwalk.filter;version="[6.5.0,6.6.0)",
+ org.eclipse.jgit.storage.file;version="[6.5.0,6.6.0)",
+ org.eclipse.jgit.storage.pack;version="[6.5.0,6.6.0)",
+ org.eclipse.jgit.submodule;version="[6.5.0,6.6.0)",
+ org.eclipse.jgit.transport;version="[6.5.0,6.6.0)",
+ org.eclipse.jgit.transport.http;version="[6.5.0,6.6.0)",
+ org.eclipse.jgit.transport.resolver;version="[6.5.0,6.6.0)",
+ org.eclipse.jgit.treewalk;version="[6.5.0,6.6.0)",
+ org.eclipse.jgit.treewalk.filter;version="[6.5.0,6.6.0)",
+ org.eclipse.jgit.util;version="[6.5.0,6.6.0)",
+ org.eclipse.jgit.util.io;version="[6.5.0,6.6.0)",
+ org.eclipse.jgit.util.sha1;version="[6.5.0,6.6.0)",
  org.hamcrest;version="[1.1.0,3.0.0)",
  org.hamcrest.collection;version="[1.1.0,3.0.0)",
  org.junit;version="[4.13,5.0.0)",
diff --git a/org.eclipse.jgit.test/pom.xml b/org.eclipse.jgit.test/pom.xml
index 0274fa9..f0a7811 100644
--- a/org.eclipse.jgit.test/pom.xml
+++ b/org.eclipse.jgit.test/pom.xml
@@ -19,7 +19,7 @@
   <parent>
     <groupId>org.eclipse.jgit</groupId>
     <artifactId>org.eclipse.jgit-parent</artifactId>
-    <version>6.4.1-SNAPSHOT</version>
+    <version>6.5.0-SNAPSHOT</version>
   </parent>
 
   <artifactId>org.eclipse.jgit.test</artifactId>
diff --git a/org.eclipse.jgit.test/tst-rsrc/org/eclipse/jgit/diff/x_add_nl.patch b/org.eclipse.jgit.test/tst-rsrc/org/eclipse/jgit/diff/x_add_nl.patch
new file mode 100644
index 0000000..444f7f7
--- /dev/null
+++ b/org.eclipse.jgit.test/tst-rsrc/org/eclipse/jgit/diff/x_add_nl.patch
@@ -0,0 +1,11 @@
+diff --git a/x_add_nl b/x_add_nl
+index 33a3e0e..71ac1b5 100644
+--- a/x_add_nl
++++ b/x_add_nl
+@@ -5,4 +5,4 @@ d
+ e
+ f
+ g
+-h
+\ No newline at end of file
++h
diff --git a/org.eclipse.jgit.test/tst-rsrc/org/eclipse/jgit/diff/x_add_nl_PostImage b/org.eclipse.jgit.test/tst-rsrc/org/eclipse/jgit/diff/x_add_nl_PostImage
new file mode 100644
index 0000000..71ac1b5
--- /dev/null
+++ b/org.eclipse.jgit.test/tst-rsrc/org/eclipse/jgit/diff/x_add_nl_PostImage
@@ -0,0 +1,8 @@
+a
+b
+c
+d
+e
+f
+g
+h
diff --git a/org.eclipse.jgit.test/tst-rsrc/org/eclipse/jgit/diff/x_add_nl_PreImage b/org.eclipse.jgit.test/tst-rsrc/org/eclipse/jgit/diff/x_add_nl_PreImage
new file mode 100644
index 0000000..33a3e0e
--- /dev/null
+++ b/org.eclipse.jgit.test/tst-rsrc/org/eclipse/jgit/diff/x_add_nl_PreImage
@@ -0,0 +1,8 @@
+a
+b
+c
+d
+e
+f
+g
+h
\ No newline at end of file
diff --git a/org.eclipse.jgit.test/tst-rsrc/org/eclipse/jgit/diff/x_add_nl_crlf.patch b/org.eclipse.jgit.test/tst-rsrc/org/eclipse/jgit/diff/x_add_nl_crlf.patch
new file mode 100644
index 0000000..503d345
--- /dev/null
+++ b/org.eclipse.jgit.test/tst-rsrc/org/eclipse/jgit/diff/x_add_nl_crlf.patch
@@ -0,0 +1,11 @@
+diff --git a/x_add_nl_crlf b/x_add_nl_crlf
+index 33a3e0e..71ac1b5 100644
+--- a/x_add_nl_crlf
++++ b/x_add_nl_crlf
+@@ -5,4 +5,4 @@ d
+ e
+ f
+ g
+-h
+\ No newline at end of file
++h
diff --git a/org.eclipse.jgit.test/tst-rsrc/org/eclipse/jgit/diff/x_add_nl_crlf_PostImage b/org.eclipse.jgit.test/tst-rsrc/org/eclipse/jgit/diff/x_add_nl_crlf_PostImage
new file mode 100644
index 0000000..95801b0
--- /dev/null
+++ b/org.eclipse.jgit.test/tst-rsrc/org/eclipse/jgit/diff/x_add_nl_crlf_PostImage
@@ -0,0 +1,8 @@
+a

+b

+c

+d

+e

+f

+g

+h

diff --git a/org.eclipse.jgit.test/tst-rsrc/org/eclipse/jgit/diff/x_add_nl_crlf_PreImage b/org.eclipse.jgit.test/tst-rsrc/org/eclipse/jgit/diff/x_add_nl_crlf_PreImage
new file mode 100644
index 0000000..a8a98da
--- /dev/null
+++ b/org.eclipse.jgit.test/tst-rsrc/org/eclipse/jgit/diff/x_add_nl_crlf_PreImage
@@ -0,0 +1,8 @@
+a

+b

+c

+d

+e

+f

+g

+h
\ No newline at end of file
diff --git a/org.eclipse.jgit.test/tst-rsrc/org/eclipse/jgit/diff/x_d.patch b/org.eclipse.jgit.test/tst-rsrc/org/eclipse/jgit/diff/x_d.patch
new file mode 100644
index 0000000..cc90256
--- /dev/null
+++ b/org.eclipse.jgit.test/tst-rsrc/org/eclipse/jgit/diff/x_d.patch
@@ -0,0 +1,13 @@
+diff --git a/x_d b/x_d
+index 33a3e0e..9d2bc43 100644
+--- a/x_d
++++ b/x_d
+@@ -1,7 +1,7 @@
+ a
+ b
+ c
+-d
++D
+ e
+ f
+ g
diff --git a/org.eclipse.jgit.test/tst-rsrc/org/eclipse/jgit/diff/x_d_PostImage b/org.eclipse.jgit.test/tst-rsrc/org/eclipse/jgit/diff/x_d_PostImage
new file mode 100644
index 0000000..9d2bc43
--- /dev/null
+++ b/org.eclipse.jgit.test/tst-rsrc/org/eclipse/jgit/diff/x_d_PostImage
@@ -0,0 +1,8 @@
+a
+b
+c
+D
+e
+f
+g
+h
\ No newline at end of file
diff --git a/org.eclipse.jgit.test/tst-rsrc/org/eclipse/jgit/diff/x_d_PreImage b/org.eclipse.jgit.test/tst-rsrc/org/eclipse/jgit/diff/x_d_PreImage
new file mode 100644
index 0000000..33a3e0e
--- /dev/null
+++ b/org.eclipse.jgit.test/tst-rsrc/org/eclipse/jgit/diff/x_d_PreImage
@@ -0,0 +1,8 @@
+a
+b
+c
+d
+e
+f
+g
+h
\ No newline at end of file
diff --git a/org.eclipse.jgit.test/tst-rsrc/org/eclipse/jgit/diff/x_d_crlf.patch b/org.eclipse.jgit.test/tst-rsrc/org/eclipse/jgit/diff/x_d_crlf.patch
new file mode 100644
index 0000000..8ec3f8b
--- /dev/null
+++ b/org.eclipse.jgit.test/tst-rsrc/org/eclipse/jgit/diff/x_d_crlf.patch
@@ -0,0 +1,13 @@
+diff --git a/x_d_crlf b/x_d_crlf
+index 33a3e0e..9d2bc43 100644
+--- a/x_d_crlf
++++ b/x_d_crlf
+@@ -1,7 +1,7 @@
+ a
+ b
+ c
+-d
++D
+ e
+ f
+ g
diff --git a/org.eclipse.jgit.test/tst-rsrc/org/eclipse/jgit/diff/x_d_crlf_PostImage b/org.eclipse.jgit.test/tst-rsrc/org/eclipse/jgit/diff/x_d_crlf_PostImage
new file mode 100644
index 0000000..ecae1d6
--- /dev/null
+++ b/org.eclipse.jgit.test/tst-rsrc/org/eclipse/jgit/diff/x_d_crlf_PostImage
@@ -0,0 +1,8 @@
+a

+b

+c

+D

+e

+f

+g

+h
\ No newline at end of file
diff --git a/org.eclipse.jgit.test/tst-rsrc/org/eclipse/jgit/diff/x_d_crlf_PreImage b/org.eclipse.jgit.test/tst-rsrc/org/eclipse/jgit/diff/x_d_crlf_PreImage
new file mode 100644
index 0000000..a8a98da
--- /dev/null
+++ b/org.eclipse.jgit.test/tst-rsrc/org/eclipse/jgit/diff/x_d_crlf_PreImage
@@ -0,0 +1,8 @@
+a

+b

+c

+d

+e

+f

+g

+h
\ No newline at end of file
diff --git a/org.eclipse.jgit.test/tst-rsrc/org/eclipse/jgit/diff/x_e.patch b/org.eclipse.jgit.test/tst-rsrc/org/eclipse/jgit/diff/x_e.patch
new file mode 100644
index 0000000..413e4f8
--- /dev/null
+++ b/org.eclipse.jgit.test/tst-rsrc/org/eclipse/jgit/diff/x_e.patch
@@ -0,0 +1,14 @@
+diff --git a/x_e b/x_e
+index 33a3e0e..b3ab996 100644
+--- a/x_e
++++ b/x_e
+@@ -2,7 +2,7 @@ a
+ b
+ c
+ d
+-e
++E
+ f
+ g
+ h
+\ No newline at end of file
diff --git a/org.eclipse.jgit.test/tst-rsrc/org/eclipse/jgit/diff/x_e_PostImage b/org.eclipse.jgit.test/tst-rsrc/org/eclipse/jgit/diff/x_e_PostImage
new file mode 100644
index 0000000..b3ab996
--- /dev/null
+++ b/org.eclipse.jgit.test/tst-rsrc/org/eclipse/jgit/diff/x_e_PostImage
@@ -0,0 +1,8 @@
+a
+b
+c
+d
+E
+f
+g
+h
\ No newline at end of file
diff --git a/org.eclipse.jgit.test/tst-rsrc/org/eclipse/jgit/diff/x_e_PreImage b/org.eclipse.jgit.test/tst-rsrc/org/eclipse/jgit/diff/x_e_PreImage
new file mode 100644
index 0000000..33a3e0e
--- /dev/null
+++ b/org.eclipse.jgit.test/tst-rsrc/org/eclipse/jgit/diff/x_e_PreImage
@@ -0,0 +1,8 @@
+a
+b
+c
+d
+e
+f
+g
+h
\ No newline at end of file
diff --git a/org.eclipse.jgit.test/tst-rsrc/org/eclipse/jgit/diff/x_e_crlf.patch b/org.eclipse.jgit.test/tst-rsrc/org/eclipse/jgit/diff/x_e_crlf.patch
new file mode 100644
index 0000000..e674454
--- /dev/null
+++ b/org.eclipse.jgit.test/tst-rsrc/org/eclipse/jgit/diff/x_e_crlf.patch
@@ -0,0 +1,14 @@
+diff --git a/x_e_crlf b/x_e_crlf
+index 33a3e0e..b3ab996 100644
+--- a/x_e_crlf
++++ b/x_e_crlf
+@@ -2,7 +2,7 @@ a
+ b
+ c
+ d
+-e
++E
+ f
+ g
+ h
+\ No newline at end of file
diff --git a/org.eclipse.jgit.test/tst-rsrc/org/eclipse/jgit/diff/x_e_crlf_PostImage b/org.eclipse.jgit.test/tst-rsrc/org/eclipse/jgit/diff/x_e_crlf_PostImage
new file mode 100644
index 0000000..d327752
--- /dev/null
+++ b/org.eclipse.jgit.test/tst-rsrc/org/eclipse/jgit/diff/x_e_crlf_PostImage
@@ -0,0 +1,8 @@
+a

+b

+c

+d

+E

+f

+g

+h
\ No newline at end of file
diff --git a/org.eclipse.jgit.test/tst-rsrc/org/eclipse/jgit/diff/x_e_crlf_PreImage b/org.eclipse.jgit.test/tst-rsrc/org/eclipse/jgit/diff/x_e_crlf_PreImage
new file mode 100644
index 0000000..a8a98da
--- /dev/null
+++ b/org.eclipse.jgit.test/tst-rsrc/org/eclipse/jgit/diff/x_e_crlf_PreImage
@@ -0,0 +1,8 @@
+a

+b

+c

+d

+e

+f

+g

+h
\ No newline at end of file
diff --git a/org.eclipse.jgit.test/tst-rsrc/org/eclipse/jgit/diff/x_last_rm_nl.patch b/org.eclipse.jgit.test/tst-rsrc/org/eclipse/jgit/diff/x_last_rm_nl.patch
new file mode 100644
index 0000000..34ed246
--- /dev/null
+++ b/org.eclipse.jgit.test/tst-rsrc/org/eclipse/jgit/diff/x_last_rm_nl.patch
@@ -0,0 +1,15 @@
+diff --git a/x_last_rm_nl b/x_last_rm_nl
+index 71ac1b5..b3ab996 100644
+--- a/x_last_rm_nl
++++ b/x_last_rm_nl
+@@ -2,7 +2,7 @@ a
+ b
+ c
+ d
+-e
++E
+ f
+ g
+-h
++h
+\ No newline at end of file
diff --git a/org.eclipse.jgit.test/tst-rsrc/org/eclipse/jgit/diff/x_last_rm_nl_PostImage b/org.eclipse.jgit.test/tst-rsrc/org/eclipse/jgit/diff/x_last_rm_nl_PostImage
new file mode 100644
index 0000000..b3ab996
--- /dev/null
+++ b/org.eclipse.jgit.test/tst-rsrc/org/eclipse/jgit/diff/x_last_rm_nl_PostImage
@@ -0,0 +1,8 @@
+a
+b
+c
+d
+E
+f
+g
+h
\ No newline at end of file
diff --git a/org.eclipse.jgit.test/tst-rsrc/org/eclipse/jgit/diff/x_last_rm_nl_PreImage b/org.eclipse.jgit.test/tst-rsrc/org/eclipse/jgit/diff/x_last_rm_nl_PreImage
new file mode 100644
index 0000000..71ac1b5
--- /dev/null
+++ b/org.eclipse.jgit.test/tst-rsrc/org/eclipse/jgit/diff/x_last_rm_nl_PreImage
@@ -0,0 +1,8 @@
+a
+b
+c
+d
+e
+f
+g
+h
diff --git a/org.eclipse.jgit.test/tst-rsrc/org/eclipse/jgit/diff/x_last_rm_nl_crlf.patch b/org.eclipse.jgit.test/tst-rsrc/org/eclipse/jgit/diff/x_last_rm_nl_crlf.patch
new file mode 100644
index 0000000..3f74024
--- /dev/null
+++ b/org.eclipse.jgit.test/tst-rsrc/org/eclipse/jgit/diff/x_last_rm_nl_crlf.patch
@@ -0,0 +1,15 @@
+diff --git a/x_last_rm_nl_crlf b/x_last_rm_nl_crlf
+index 71ac1b5..b3ab996 100644
+--- a/x_last_rm_nl_crlf
++++ b/x_last_rm_nl_crlf
+@@ -2,7 +2,7 @@ a
+ b
+ c
+ d
+-e
++E
+ f
+ g
+-h
++h
+\ No newline at end of file
diff --git a/org.eclipse.jgit.test/tst-rsrc/org/eclipse/jgit/diff/x_last_rm_nl_crlf_PostImage b/org.eclipse.jgit.test/tst-rsrc/org/eclipse/jgit/diff/x_last_rm_nl_crlf_PostImage
new file mode 100644
index 0000000..d327752
--- /dev/null
+++ b/org.eclipse.jgit.test/tst-rsrc/org/eclipse/jgit/diff/x_last_rm_nl_crlf_PostImage
@@ -0,0 +1,8 @@
+a

+b

+c

+d

+E

+f

+g

+h
\ No newline at end of file
diff --git a/org.eclipse.jgit.test/tst-rsrc/org/eclipse/jgit/diff/x_last_rm_nl_crlf_PreImage b/org.eclipse.jgit.test/tst-rsrc/org/eclipse/jgit/diff/x_last_rm_nl_crlf_PreImage
new file mode 100644
index 0000000..95801b0
--- /dev/null
+++ b/org.eclipse.jgit.test/tst-rsrc/org/eclipse/jgit/diff/x_last_rm_nl_crlf_PreImage
@@ -0,0 +1,8 @@
+a

+b

+c

+d

+e

+f

+g

+h

diff --git a/org.eclipse.jgit.test/tst-rsrc/org/eclipse/jgit/diff/z_e.patch b/org.eclipse.jgit.test/tst-rsrc/org/eclipse/jgit/diff/z_e.patch
new file mode 100644
index 0000000..f531033
--- /dev/null
+++ b/org.eclipse.jgit.test/tst-rsrc/org/eclipse/jgit/diff/z_e.patch
@@ -0,0 +1,297 @@
+diff --git a/z_e b/z_e
+index 8d8786f..7888356 100644
+--- a/z_e
++++ b/z_e
+@@ -20,6 +20,7 @@
+ package org.jsonschema2pojo.util;
+ 
+ import java.util.ArrayList;
++import java.util.Collections;
+ import java.util.List;
+ import java.util.regex.Matcher;
+ import java.util.regex.Pattern;
+@@ -36,76 +37,81 @@
+     private static final Pattern UNDERSCORE_PATTERN_1 = Pattern.compile("([A-Z]+)([A-Z][a-z])");
+     private static final Pattern UNDERSCORE_PATTERN_2 = Pattern.compile("([a-z\\d])([A-Z])");
+ 
+-    private List<RuleAndReplacement> plurals = new ArrayList<RuleAndReplacement>();
+-    private List<RuleAndReplacement> singulars = new ArrayList<RuleAndReplacement>();
+-    private List<String> uncountables = new ArrayList<String>();
++    private final List<RuleAndReplacement> plurals;
++    private final List<RuleAndReplacement> singulars;
++    private final List<String> uncountables;
+ 
+-    private static Inflector instance  = new Inflector();
++    private static Inflector instance  = createDefaultBuilder().build();
+ 
+-    private Inflector() {
+-        // Woo, you can't touch me.
+-
+-        initialize();
++    private Inflector(Builder builder) {
++        plurals = Collections.unmodifiableList(builder.plurals);
++        singulars = Collections.unmodifiableList(builder.singulars);
++        uncountables = Collections.unmodifiableList(builder.uncountables);
+     }
+ 
+-    private void initialize() {
+-        plural("$", "s");
+-        plural("s$", "s");
+-        plural("(ax|test)is$", "$1es");
+-        plural("(octop|vir)us$", "$1i");
+-        plural("(alias|status)$", "$1es");
+-        plural("(bu)s$", "$1es");
+-        plural("(buffal|tomat)o$", "$1oes");
+-        plural("([ti])um$", "$1a");
+-        plural("sis$", "ses");
+-        plural("(?:([^f])fe|([lr])f)$", "$1$2ves");
+-        plural("(hive)$", "$1s");
+-        plural("([^aeiouy]|qu)y$", "$1ies");
+-        plural("([^aeiouy]|qu)ies$", "$1y");
+-        plural("(x|ch|ss|sh)$", "$1es");
+-        plural("(matr|vert|ind)ix|ex$", "$1ices");
+-        plural("([m|l])ouse$", "$1ice");
+-        plural("(ox)$", "$1en");
+-        plural("(quiz)$", "$1zes");
++    public static Inflector.Builder createDefaultBuilder()
++    {
++        Builder builder = builder();
+ 
+-        singular("s$", "");
+-        singular("(n)ews$", "$1ews");
+-        singular("([ti])a$", "$1um");
+-        singular("((a)naly|(b)a|(d)iagno|(p)arenthe|(p)rogno|(s)ynop|(t)he)ses$", "$1$2sis");
+-        singular("(^analy)ses$", "$1sis");
+-        singular("([^f])ves$", "$1fe");
+-        singular("(hive)s$", "$1");
+-        singular("(tive)s$", "$1");
+-        singular("([lr])ves$", "$1f");
+-        singular("([^aeiouy]|qu)ies$", "$1y");
+-        singular("(s)eries$", "$1eries");
+-        singular("(m)ovies$", "$1ovie");
+-        singular("(x|ch|ss|sh)es$", "$1");
+-        singular("([m|l])ice$", "$1ouse");
+-        singular("(bus)es$", "$1");
+-        singular("(o)es$", "$1");
+-        singular("(shoe)s$", "$1");
+-        singular("(cris|ax|test)es$", "$1is");
+-        singular("([octop|vir])i$", "$1us");
+-        singular("(alias|status)es$", "$1");
+-        singular("^(ox)en", "$1");
+-        singular("(vert|ind)ices$", "$1ex");
+-        singular("(matr)ices$", "$1ix");
+-        singular("(quiz)zes$", "$1");
+-        singular("(ess)$", "$1");
++        builder.plural("$", "s")
++            .plural("s$", "s")
++            .plural("(ax|test)is$", "$1es")
++            .plural("(octop|vir)us$", "$1i")
++            .plural("(alias|status)$", "$1es")
++            .plural("(bu)s$", "$1es")
++            .plural("(buffal|tomat)o$", "$1oes")
++            .plural("([ti])um$", "$1a")
++            .plural("sis$", "ses")
++            .plural("(?:([^f])fe|([lr])f)$", "$1$2ves")
++            .plural("(hive)$", "$1s")
++            .plural("([^aeiouy]|qu)y$", "$1ies")
++            .plural("([^aeiouy]|qu)ies$", "$1y")
++            .plural("(x|ch|ss|sh)$", "$1es")
++            .plural("(matr|vert|ind)ix|ex$", "$1ices")
++            .plural("([m|l])ouse$", "$1ice")
++            .plural("(ox)$", "$1en")
++            .plural("(quiz)$", "$1zes");
+ 
+-        singular("men$", "man");
+-        plural("man$", "men");
++        builder.singular("s$", "")
++            .singular("(n)ews$", "$1ews")
++            .singular("([ti])a$", "$1um")
++            .singular("((a)naly|(b)a|(d)iagno|(p)arenthe|(p)rogno|(s)ynop|(t)he)ses$", "$1$2sis")
++            .singular("(^analy)ses$", "$1sis")
++            .singular("([^f])ves$", "$1fe")
++            .singular("(hive)s$", "$1")
++            .singular("(tive)s$", "$1")
++            .singular("([lr])ves$", "$1f")
++            .singular("([^aeiouy]|qu)ies$", "$1y")
++            .singular("(s)eries$", "$1eries")
++            .singular("(m)ovies$", "$1ovie")
++            .singular("(x|ch|ss|sh)es$", "$1")
++            .singular("([m|l])ice$", "$1ouse")
++            .singular("(bus)es$", "$1")
++            .singular("(o)es$", "$1")
++            .singular("(shoe)s$", "$1")
++            .singular("(cris|ax|test)es$", "$1is")
++            .singular("([octop|vir])i$", "$1us")
++            .singular("(alias|status)es$", "$1")
++            .singular("^(ox)en", "$1")
++            .singular("(vert|ind)ices$", "$1ex")
++            .singular("(matr)ices$", "$1ix")
++            .singular("(quiz)zes$", "$1")
++            .singular("(ess)$", "$1");
+ 
+-        irregular("curve", "curves");
+-        irregular("leaf", "leaves");
+-        irregular("roof", "rooves");
+-        irregular("person", "people");
+-        irregular("child", "children");
+-        irregular("sex", "sexes");
+-        irregular("move", "moves");
++        builder.singular("men$", "man")
++            .plural("man$", "men");
+ 
+-        uncountable(new String[] { "equipment", "information", "rice", "money", "species", "series", "fish", "sheep", "s" });
++        builder.irregular("curve", "curves")
++            .irregular("leaf", "leaves")
++            .irregular("roof", "rooves")
++            .irregular("person", "people")
++            .irregular("child", "children")
++            .irregular("sex", "sexes")
++            .irregular("move", "moves");
++
++        builder.uncountable(new String[] { "equipment", "information", "rice", "money", "species", "series", "fish", "sheep", "s" });
++
++        return builder;
+     }
+ 
+     public static Inflector getInstance() {
+@@ -122,28 +128,27 @@
+         return underscoredWord;
+     }
+ 
+-    public synchronized String pluralize(String word) {
++    public String pluralize(String word) {
+         if (uncountables.contains(word.toLowerCase())) {
+             return word;
+         }
+         return replaceWithFirstRule(word, plurals);
+     }
+ 
+-    public synchronized String singularize(String word) {
++    public String singularize(String word) {
+         if (uncountables.contains(word.toLowerCase())) {
+             return word;
+         }
+         return replaceWithFirstRule(word, singulars);
+     }
+ 
+-    private String replaceWithFirstRule(String word, List<RuleAndReplacement> ruleAndReplacements) {
++    private static String replaceWithFirstRule(String word, List<RuleAndReplacement> ruleAndReplacements) {
+ 
+         for (RuleAndReplacement rar : ruleAndReplacements) {
+-            String rule = rar.getRule();
+             String replacement = rar.getReplacement();
+ 
+             // Return if we find a match.
+-            Matcher matcher = Pattern.compile(rule, Pattern.CASE_INSENSITIVE).matcher(word);
++            Matcher matcher = rar.getPattern().matcher(word);
+             if (matcher.find()) {
+                 return matcher.replaceAll(replacement);
+             }
+@@ -161,49 +166,68 @@
+         return tableize(className);
+     }
+ 
+-    private void plural(String rule, String replacement) {
+-        plurals.add(0, new RuleAndReplacement(rule, replacement));
++    public static Builder builder()
++    {
++        return new Builder();
+     }
+ 
+-    private void singular(String rule, String replacement) {
+-        singulars.add(0, new RuleAndReplacement(rule, replacement));
++    // Ugh, no open structs in Java (not-natively at least).
++    private static class RuleAndReplacement {
++        private final String rule;
++        private final String replacement;
++        private final Pattern pattern;
++
++        public RuleAndReplacement(String rule, String replacement) {
++            this.rule = rule;
++            this.replacement = replacement;
++            this.pattern = Pattern.compile(rule, Pattern.CASE_INSENSITIVE);
++        }
++
++        public String getReplacement() {
++            return replacement;
++        }
++
++        public String getRule() {
++            return rule;
++        }
++
++        public Pattern getPattern() {
++            return pattern;
++        }
+     }
+ 
+-    private void irregular(String singular, String plural) {
+-        plural(singular, plural);
+-        singular(plural, singular);
+-    }
++    public static class Builder
++    {
++        private List<RuleAndReplacement> plurals = new ArrayList<RuleAndReplacement>();
++        private List<RuleAndReplacement> singulars = new ArrayList<RuleAndReplacement>();
++        private List<String> uncountables = new ArrayList<String>();
+ 
+-    private void uncountable(String... words) {
+-        for (String word : words) {
+-            uncountables.add(word);
++        public Builder plural(String rule, String replacement) {
++            plurals.add(0, new RuleAndReplacement(rule, replacement));
++            return this;
++        }
++
++        public Builder singular(String rule, String replacement) {
++            singulars.add(0, new RuleAndReplacement(rule, replacement));
++            return this;
++        }
++
++        public Builder irregular(String singular, String plural) {
++            plural(singular, plural);
++            singular(plural, singular);
++            return this;
++        }
++
++        public Builder uncountable(String... words) {
++            for (String word : words) {
++                uncountables.add(word);
++            }
++            return this;
++        }
++
++        public Inflector build()
++        {
++            return new Inflector(this);
+         }
+     }
+ }
+-
+-// Ugh, no open structs in Java (not-natively at least).
+-class RuleAndReplacement {
+-    private String rule;
+-    private String replacement;
+-
+-    public RuleAndReplacement(String rule, String replacement) {
+-        this.rule = rule;
+-        this.replacement = replacement;
+-    }
+-
+-    public String getReplacement() {
+-        return replacement;
+-    }
+-
+-    public void setReplacement(String replacement) {
+-        this.replacement = replacement;
+-    }
+-
+-    public String getRule() {
+-        return rule;
+-    }
+-
+-    public void setRule(String rule) {
+-        this.rule = rule;
+-    }
+-}
+\ No newline at end of file
diff --git a/org.eclipse.jgit.test/tst-rsrc/org/eclipse/jgit/diff/z_e_PostImage b/org.eclipse.jgit.test/tst-rsrc/org/eclipse/jgit/diff/z_e_PostImage
new file mode 100644
index 0000000..7888356
--- /dev/null
+++ b/org.eclipse.jgit.test/tst-rsrc/org/eclipse/jgit/diff/z_e_PostImage
@@ -0,0 +1,233 @@
+/**
+ * Copyright © 2007 Chu Yeow Cheah
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * 
+ * Copied verbatim from http://dzone.com/snippets/java-inflections, used 
+ * and licensed with express permission from the author Chu Yeow Cheah.
+ */
+
+package org.jsonschema2pojo.util;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+/**
+ * Transforms words (from singular to plural, from camelCase to under_score,
+ * etc.). I got bored of doing Real Work...
+ * 
+ * @author chuyeow
+ */
+public class Inflector {
+
+    // Pfft, can't think of a better name, but this is needed to avoid the price of initializing the pattern on each call.
+    private static final Pattern UNDERSCORE_PATTERN_1 = Pattern.compile("([A-Z]+)([A-Z][a-z])");
+    private static final Pattern UNDERSCORE_PATTERN_2 = Pattern.compile("([a-z\\d])([A-Z])");
+
+    private final List<RuleAndReplacement> plurals;
+    private final List<RuleAndReplacement> singulars;
+    private final List<String> uncountables;
+
+    private static Inflector instance  = createDefaultBuilder().build();
+
+    private Inflector(Builder builder) {
+        plurals = Collections.unmodifiableList(builder.plurals);
+        singulars = Collections.unmodifiableList(builder.singulars);
+        uncountables = Collections.unmodifiableList(builder.uncountables);
+    }
+
+    public static Inflector.Builder createDefaultBuilder()
+    {
+        Builder builder = builder();
+
+        builder.plural("$", "s")
+            .plural("s$", "s")
+            .plural("(ax|test)is$", "$1es")
+            .plural("(octop|vir)us$", "$1i")
+            .plural("(alias|status)$", "$1es")
+            .plural("(bu)s$", "$1es")
+            .plural("(buffal|tomat)o$", "$1oes")
+            .plural("([ti])um$", "$1a")
+            .plural("sis$", "ses")
+            .plural("(?:([^f])fe|([lr])f)$", "$1$2ves")
+            .plural("(hive)$", "$1s")
+            .plural("([^aeiouy]|qu)y$", "$1ies")
+            .plural("([^aeiouy]|qu)ies$", "$1y")
+            .plural("(x|ch|ss|sh)$", "$1es")
+            .plural("(matr|vert|ind)ix|ex$", "$1ices")
+            .plural("([m|l])ouse$", "$1ice")
+            .plural("(ox)$", "$1en")
+            .plural("(quiz)$", "$1zes");
+
+        builder.singular("s$", "")
+            .singular("(n)ews$", "$1ews")
+            .singular("([ti])a$", "$1um")
+            .singular("((a)naly|(b)a|(d)iagno|(p)arenthe|(p)rogno|(s)ynop|(t)he)ses$", "$1$2sis")
+            .singular("(^analy)ses$", "$1sis")
+            .singular("([^f])ves$", "$1fe")
+            .singular("(hive)s$", "$1")
+            .singular("(tive)s$", "$1")
+            .singular("([lr])ves$", "$1f")
+            .singular("([^aeiouy]|qu)ies$", "$1y")
+            .singular("(s)eries$", "$1eries")
+            .singular("(m)ovies$", "$1ovie")
+            .singular("(x|ch|ss|sh)es$", "$1")
+            .singular("([m|l])ice$", "$1ouse")
+            .singular("(bus)es$", "$1")
+            .singular("(o)es$", "$1")
+            .singular("(shoe)s$", "$1")
+            .singular("(cris|ax|test)es$", "$1is")
+            .singular("([octop|vir])i$", "$1us")
+            .singular("(alias|status)es$", "$1")
+            .singular("^(ox)en", "$1")
+            .singular("(vert|ind)ices$", "$1ex")
+            .singular("(matr)ices$", "$1ix")
+            .singular("(quiz)zes$", "$1")
+            .singular("(ess)$", "$1");
+
+        builder.singular("men$", "man")
+            .plural("man$", "men");
+
+        builder.irregular("curve", "curves")
+            .irregular("leaf", "leaves")
+            .irregular("roof", "rooves")
+            .irregular("person", "people")
+            .irregular("child", "children")
+            .irregular("sex", "sexes")
+            .irregular("move", "moves");
+
+        builder.uncountable(new String[] { "equipment", "information", "rice", "money", "species", "series", "fish", "sheep", "s" });
+
+        return builder;
+    }
+
+    public static Inflector getInstance() {
+        return instance;
+    }
+
+    private String underscore(String camelCasedWord) {
+
+        // Regexes in Java are fucking stupid...
+        String underscoredWord = UNDERSCORE_PATTERN_1.matcher(camelCasedWord).replaceAll("$1_$2");
+        underscoredWord = UNDERSCORE_PATTERN_2.matcher(underscoredWord).replaceAll("$1_$2");
+        underscoredWord = underscoredWord.replace('-', '_').toLowerCase();
+
+        return underscoredWord;
+    }
+
+    public String pluralize(String word) {
+        if (uncountables.contains(word.toLowerCase())) {
+            return word;
+        }
+        return replaceWithFirstRule(word, plurals);
+    }
+
+    public String singularize(String word) {
+        if (uncountables.contains(word.toLowerCase())) {
+            return word;
+        }
+        return replaceWithFirstRule(word, singulars);
+    }
+
+    private static String replaceWithFirstRule(String word, List<RuleAndReplacement> ruleAndReplacements) {
+
+        for (RuleAndReplacement rar : ruleAndReplacements) {
+            String replacement = rar.getReplacement();
+
+            // Return if we find a match.
+            Matcher matcher = rar.getPattern().matcher(word);
+            if (matcher.find()) {
+                return matcher.replaceAll(replacement);
+            }
+        }
+        return word;
+    }
+
+    private String tableize(String className) {
+        return pluralize(underscore(className));
+    }
+
+    private String tableize(Class<?> klass) {
+        // Strip away package name - we only want the 'base' class name.
+        String className = klass.getName().replace(klass.getPackage().getName() + ".", "");
+        return tableize(className);
+    }
+
+    public static Builder builder()
+    {
+        return new Builder();
+    }
+
+    // Ugh, no open structs in Java (not-natively at least).
+    private static class RuleAndReplacement {
+        private final String rule;
+        private final String replacement;
+        private final Pattern pattern;
+
+        public RuleAndReplacement(String rule, String replacement) {
+            this.rule = rule;
+            this.replacement = replacement;
+            this.pattern = Pattern.compile(rule, Pattern.CASE_INSENSITIVE);
+        }
+
+        public String getReplacement() {
+            return replacement;
+        }
+
+        public String getRule() {
+            return rule;
+        }
+
+        public Pattern getPattern() {
+            return pattern;
+        }
+    }
+
+    public static class Builder
+    {
+        private List<RuleAndReplacement> plurals = new ArrayList<RuleAndReplacement>();
+        private List<RuleAndReplacement> singulars = new ArrayList<RuleAndReplacement>();
+        private List<String> uncountables = new ArrayList<String>();
+
+        public Builder plural(String rule, String replacement) {
+            plurals.add(0, new RuleAndReplacement(rule, replacement));
+            return this;
+        }
+
+        public Builder singular(String rule, String replacement) {
+            singulars.add(0, new RuleAndReplacement(rule, replacement));
+            return this;
+        }
+
+        public Builder irregular(String singular, String plural) {
+            plural(singular, plural);
+            singular(plural, singular);
+            return this;
+        }
+
+        public Builder uncountable(String... words) {
+            for (String word : words) {
+                uncountables.add(word);
+            }
+            return this;
+        }
+
+        public Inflector build()
+        {
+            return new Inflector(this);
+        }
+    }
+}
diff --git a/org.eclipse.jgit.test/tst-rsrc/org/eclipse/jgit/diff/z_e_PreImage b/org.eclipse.jgit.test/tst-rsrc/org/eclipse/jgit/diff/z_e_PreImage
new file mode 100644
index 0000000..8d8786f
--- /dev/null
+++ b/org.eclipse.jgit.test/tst-rsrc/org/eclipse/jgit/diff/z_e_PreImage
@@ -0,0 +1,209 @@
+/**
+ * Copyright © 2007 Chu Yeow Cheah
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * 
+ * Copied verbatim from http://dzone.com/snippets/java-inflections, used 
+ * and licensed with express permission from the author Chu Yeow Cheah.
+ */
+
+package org.jsonschema2pojo.util;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+/**
+ * Transforms words (from singular to plural, from camelCase to under_score,
+ * etc.). I got bored of doing Real Work...
+ * 
+ * @author chuyeow
+ */
+public class Inflector {
+
+    // Pfft, can't think of a better name, but this is needed to avoid the price of initializing the pattern on each call.
+    private static final Pattern UNDERSCORE_PATTERN_1 = Pattern.compile("([A-Z]+)([A-Z][a-z])");
+    private static final Pattern UNDERSCORE_PATTERN_2 = Pattern.compile("([a-z\\d])([A-Z])");
+
+    private List<RuleAndReplacement> plurals = new ArrayList<RuleAndReplacement>();
+    private List<RuleAndReplacement> singulars = new ArrayList<RuleAndReplacement>();
+    private List<String> uncountables = new ArrayList<String>();
+
+    private static Inflector instance  = new Inflector();
+
+    private Inflector() {
+        // Woo, you can't touch me.
+
+        initialize();
+    }
+
+    private void initialize() {
+        plural("$", "s");
+        plural("s$", "s");
+        plural("(ax|test)is$", "$1es");
+        plural("(octop|vir)us$", "$1i");
+        plural("(alias|status)$", "$1es");
+        plural("(bu)s$", "$1es");
+        plural("(buffal|tomat)o$", "$1oes");
+        plural("([ti])um$", "$1a");
+        plural("sis$", "ses");
+        plural("(?:([^f])fe|([lr])f)$", "$1$2ves");
+        plural("(hive)$", "$1s");
+        plural("([^aeiouy]|qu)y$", "$1ies");
+        plural("([^aeiouy]|qu)ies$", "$1y");
+        plural("(x|ch|ss|sh)$", "$1es");
+        plural("(matr|vert|ind)ix|ex$", "$1ices");
+        plural("([m|l])ouse$", "$1ice");
+        plural("(ox)$", "$1en");
+        plural("(quiz)$", "$1zes");
+
+        singular("s$", "");
+        singular("(n)ews$", "$1ews");
+        singular("([ti])a$", "$1um");
+        singular("((a)naly|(b)a|(d)iagno|(p)arenthe|(p)rogno|(s)ynop|(t)he)ses$", "$1$2sis");
+        singular("(^analy)ses$", "$1sis");
+        singular("([^f])ves$", "$1fe");
+        singular("(hive)s$", "$1");
+        singular("(tive)s$", "$1");
+        singular("([lr])ves$", "$1f");
+        singular("([^aeiouy]|qu)ies$", "$1y");
+        singular("(s)eries$", "$1eries");
+        singular("(m)ovies$", "$1ovie");
+        singular("(x|ch|ss|sh)es$", "$1");
+        singular("([m|l])ice$", "$1ouse");
+        singular("(bus)es$", "$1");
+        singular("(o)es$", "$1");
+        singular("(shoe)s$", "$1");
+        singular("(cris|ax|test)es$", "$1is");
+        singular("([octop|vir])i$", "$1us");
+        singular("(alias|status)es$", "$1");
+        singular("^(ox)en", "$1");
+        singular("(vert|ind)ices$", "$1ex");
+        singular("(matr)ices$", "$1ix");
+        singular("(quiz)zes$", "$1");
+        singular("(ess)$", "$1");
+
+        singular("men$", "man");
+        plural("man$", "men");
+
+        irregular("curve", "curves");
+        irregular("leaf", "leaves");
+        irregular("roof", "rooves");
+        irregular("person", "people");
+        irregular("child", "children");
+        irregular("sex", "sexes");
+        irregular("move", "moves");
+
+        uncountable(new String[] { "equipment", "information", "rice", "money", "species", "series", "fish", "sheep", "s" });
+    }
+
+    public static Inflector getInstance() {
+        return instance;
+    }
+
+    private String underscore(String camelCasedWord) {
+
+        // Regexes in Java are fucking stupid...
+        String underscoredWord = UNDERSCORE_PATTERN_1.matcher(camelCasedWord).replaceAll("$1_$2");
+        underscoredWord = UNDERSCORE_PATTERN_2.matcher(underscoredWord).replaceAll("$1_$2");
+        underscoredWord = underscoredWord.replace('-', '_').toLowerCase();
+
+        return underscoredWord;
+    }
+
+    public synchronized String pluralize(String word) {
+        if (uncountables.contains(word.toLowerCase())) {
+            return word;
+        }
+        return replaceWithFirstRule(word, plurals);
+    }
+
+    public synchronized String singularize(String word) {
+        if (uncountables.contains(word.toLowerCase())) {
+            return word;
+        }
+        return replaceWithFirstRule(word, singulars);
+    }
+
+    private String replaceWithFirstRule(String word, List<RuleAndReplacement> ruleAndReplacements) {
+
+        for (RuleAndReplacement rar : ruleAndReplacements) {
+            String rule = rar.getRule();
+            String replacement = rar.getReplacement();
+
+            // Return if we find a match.
+            Matcher matcher = Pattern.compile(rule, Pattern.CASE_INSENSITIVE).matcher(word);
+            if (matcher.find()) {
+                return matcher.replaceAll(replacement);
+            }
+        }
+        return word;
+    }
+
+    private String tableize(String className) {
+        return pluralize(underscore(className));
+    }
+
+    private String tableize(Class<?> klass) {
+        // Strip away package name - we only want the 'base' class name.
+        String className = klass.getName().replace(klass.getPackage().getName() + ".", "");
+        return tableize(className);
+    }
+
+    private void plural(String rule, String replacement) {
+        plurals.add(0, new RuleAndReplacement(rule, replacement));
+    }
+
+    private void singular(String rule, String replacement) {
+        singulars.add(0, new RuleAndReplacement(rule, replacement));
+    }
+
+    private void irregular(String singular, String plural) {
+        plural(singular, plural);
+        singular(plural, singular);
+    }
+
+    private void uncountable(String... words) {
+        for (String word : words) {
+            uncountables.add(word);
+        }
+    }
+}
+
+// Ugh, no open structs in Java (not-natively at least).
+class RuleAndReplacement {
+    private String rule;
+    private String replacement;
+
+    public RuleAndReplacement(String rule, String replacement) {
+        this.rule = rule;
+        this.replacement = replacement;
+    }
+
+    public String getReplacement() {
+        return replacement;
+    }
+
+    public void setReplacement(String replacement) {
+        this.replacement = replacement;
+    }
+
+    public String getRule() {
+        return rule;
+    }
+
+    public void setRule(String rule) {
+        this.rule = rule;
+    }
+}
\ No newline at end of file
diff --git a/org.eclipse.jgit.test/tst-rsrc/org/eclipse/jgit/diff/z_e_add_nl.patch b/org.eclipse.jgit.test/tst-rsrc/org/eclipse/jgit/diff/z_e_add_nl.patch
new file mode 100644
index 0000000..0fe4b45
--- /dev/null
+++ b/org.eclipse.jgit.test/tst-rsrc/org/eclipse/jgit/diff/z_e_add_nl.patch
@@ -0,0 +1,17 @@
+diff --git a/z_e_add_nl b/z_e_add_nl
+index 33a3e0e..274cb0e 100644
+--- a/z_e_add_nl
++++ b/z_e_add_nl
+@@ -2,7 +2,7 @@ a
+ b
+ c
+ d
+-e
+-f
+-g
+-h
+\ No newline at end of file
++E
++F
++G
++H
diff --git a/org.eclipse.jgit.test/tst-rsrc/org/eclipse/jgit/diff/z_e_add_nl_PostImage b/org.eclipse.jgit.test/tst-rsrc/org/eclipse/jgit/diff/z_e_add_nl_PostImage
new file mode 100644
index 0000000..274cb0e
--- /dev/null
+++ b/org.eclipse.jgit.test/tst-rsrc/org/eclipse/jgit/diff/z_e_add_nl_PostImage
@@ -0,0 +1,8 @@
+a
+b
+c
+d
+E
+F
+G
+H
diff --git a/org.eclipse.jgit.test/tst-rsrc/org/eclipse/jgit/diff/z_e_add_nl_PreImage b/org.eclipse.jgit.test/tst-rsrc/org/eclipse/jgit/diff/z_e_add_nl_PreImage
new file mode 100644
index 0000000..33a3e0e
--- /dev/null
+++ b/org.eclipse.jgit.test/tst-rsrc/org/eclipse/jgit/diff/z_e_add_nl_PreImage
@@ -0,0 +1,8 @@
+a
+b
+c
+d
+e
+f
+g
+h
\ No newline at end of file
diff --git a/org.eclipse.jgit.test/tst-rsrc/org/eclipse/jgit/diff/z_e_no_nl.patch b/org.eclipse.jgit.test/tst-rsrc/org/eclipse/jgit/diff/z_e_no_nl.patch
new file mode 100644
index 0000000..bce13e4
--- /dev/null
+++ b/org.eclipse.jgit.test/tst-rsrc/org/eclipse/jgit/diff/z_e_no_nl.patch
@@ -0,0 +1,18 @@
+diff --git a/z_e_no_nl b/z_e_no_nl
+index 33a3e0e..234fedc 100644
+--- a/z_e_no_nl
++++ b/z_e_no_nl
+@@ -2,7 +2,7 @@ a
+ b
+ c
+ d
+-e
+-f
+-g
+-h
+\ No newline at end of file
++E
++F
++G
++H
+\ No newline at end of file
diff --git a/org.eclipse.jgit.test/tst-rsrc/org/eclipse/jgit/diff/z_e_no_nl_PostImage b/org.eclipse.jgit.test/tst-rsrc/org/eclipse/jgit/diff/z_e_no_nl_PostImage
new file mode 100644
index 0000000..234fedc
--- /dev/null
+++ b/org.eclipse.jgit.test/tst-rsrc/org/eclipse/jgit/diff/z_e_no_nl_PostImage
@@ -0,0 +1,8 @@
+a
+b
+c
+d
+E
+F
+G
+H
\ No newline at end of file
diff --git a/org.eclipse.jgit.test/tst-rsrc/org/eclipse/jgit/diff/z_e_no_nl_PreImage b/org.eclipse.jgit.test/tst-rsrc/org/eclipse/jgit/diff/z_e_no_nl_PreImage
new file mode 100644
index 0000000..33a3e0e
--- /dev/null
+++ b/org.eclipse.jgit.test/tst-rsrc/org/eclipse/jgit/diff/z_e_no_nl_PreImage
@@ -0,0 +1,8 @@
+a
+b
+c
+d
+e
+f
+g
+h
\ No newline at end of file
diff --git a/org.eclipse.jgit.test/tst-rsrc/org/eclipse/jgit/diff/z_e_rm_nl.patch b/org.eclipse.jgit.test/tst-rsrc/org/eclipse/jgit/diff/z_e_rm_nl.patch
new file mode 100644
index 0000000..d669706
--- /dev/null
+++ b/org.eclipse.jgit.test/tst-rsrc/org/eclipse/jgit/diff/z_e_rm_nl.patch
@@ -0,0 +1,17 @@
+diff --git a/z_e_rm_nl b/z_e_rm_nl
+index 71ac1b5..234fedc 100644
+--- a/z_e_rm_nl
++++ b/z_e_rm_nl
+@@ -2,7 +2,7 @@ a
+ b
+ c
+ d
+-e
+-f
+-g
+-h
++E
++F
++G
++H
+\ No newline at end of file
diff --git a/org.eclipse.jgit.test/tst-rsrc/org/eclipse/jgit/diff/z_e_rm_nl_PostImage b/org.eclipse.jgit.test/tst-rsrc/org/eclipse/jgit/diff/z_e_rm_nl_PostImage
new file mode 100644
index 0000000..234fedc
--- /dev/null
+++ b/org.eclipse.jgit.test/tst-rsrc/org/eclipse/jgit/diff/z_e_rm_nl_PostImage
@@ -0,0 +1,8 @@
+a
+b
+c
+d
+E
+F
+G
+H
\ No newline at end of file
diff --git a/org.eclipse.jgit.test/tst-rsrc/org/eclipse/jgit/diff/z_e_rm_nl_PreImage b/org.eclipse.jgit.test/tst-rsrc/org/eclipse/jgit/diff/z_e_rm_nl_PreImage
new file mode 100644
index 0000000..71ac1b5
--- /dev/null
+++ b/org.eclipse.jgit.test/tst-rsrc/org/eclipse/jgit/diff/z_e_rm_nl_PreImage
@@ -0,0 +1,8 @@
+a
+b
+c
+d
+e
+f
+g
+h
diff --git a/org.eclipse.jgit.test/tst-rsrc/org/eclipse/jgit/test/resources/commit-graph.v1 b/org.eclipse.jgit.test/tst-rsrc/org/eclipse/jgit/test/resources/commit-graph.v1
new file mode 100644
index 0000000..941c0a7
--- /dev/null
+++ b/org.eclipse.jgit.test/tst-rsrc/org/eclipse/jgit/test/resources/commit-graph.v1
Binary files differ
diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/commitgraph/CommitGraphBuilderTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/commitgraph/CommitGraphBuilderTest.java
new file mode 100644
index 0000000..8ecf5df
--- /dev/null
+++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/commitgraph/CommitGraphBuilderTest.java
@@ -0,0 +1,82 @@
+/*
+ * Copyright (C) 2022, Tencent.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Distribution License v. 1.0 which is available at
+ * https://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+package org.eclipse.jgit.internal.storage.commitgraph;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertThrows;
+
+import org.junit.Test;
+
+public class CommitGraphBuilderTest {
+
+	@Test
+	public void testRepeatedChunk() throws Exception {
+		byte[] buffer = new byte[2048];
+
+		CommitGraphBuilder builder1 = CommitGraphBuilder.builder();
+		builder1.addOidFanout(buffer);
+		Exception e1 = assertThrows(CommitGraphFormatException.class, () -> {
+			builder1.addOidFanout(buffer);
+		});
+		assertEquals("commit-graph chunk id 0x4f494446 appears multiple times",
+				e1.getMessage());
+
+		CommitGraphBuilder builder2 = CommitGraphBuilder.builder();
+		builder2.addOidLookUp(buffer);
+		Exception e2 = assertThrows(CommitGraphFormatException.class, () -> {
+			builder2.addOidLookUp(buffer);
+		});
+		assertEquals("commit-graph chunk id 0x4f49444c appears multiple times",
+				e2.getMessage());
+
+		CommitGraphBuilder builder3 = CommitGraphBuilder.builder();
+		builder3.addCommitData(buffer);
+		Exception e3 = assertThrows(CommitGraphFormatException.class, () -> {
+			builder3.addCommitData(buffer);
+		});
+		assertEquals("commit-graph chunk id 0x43444154 appears multiple times",
+				e3.getMessage());
+
+		CommitGraphBuilder builder4 = CommitGraphBuilder.builder();
+		builder4.addExtraList(buffer);
+		Exception e4 = assertThrows(CommitGraphFormatException.class, () -> {
+			builder4.addExtraList(buffer);
+		});
+		assertEquals("commit-graph chunk id 0x45444745 appears multiple times",
+				e4.getMessage());
+	}
+
+	@Test
+	public void testNeededChunk() {
+		byte[] buffer = new byte[2048];
+
+		Exception e1 = assertThrows(CommitGraphFormatException.class, () -> {
+			CommitGraphBuilder.builder().addOidLookUp(buffer)
+					.addCommitData(buffer).build();
+		});
+		assertEquals("commit-graph 0x4f494446 chunk has not been loaded",
+				e1.getMessage());
+
+		Exception e2 = assertThrows(CommitGraphFormatException.class, () -> {
+			CommitGraphBuilder.builder().addOidFanout(buffer)
+					.addCommitData(buffer).build();
+		});
+		assertEquals("commit-graph 0x4f49444c chunk has not been loaded",
+				e2.getMessage());
+
+		Exception e3 = assertThrows(CommitGraphFormatException.class, () -> {
+			CommitGraphBuilder.builder().addOidFanout(buffer)
+					.addOidLookUp(buffer).build();
+		});
+		assertEquals("commit-graph 0x43444154 chunk has not been loaded",
+				e3.getMessage());
+	}
+}
diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/commitgraph/CommitGraphLoaderTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/commitgraph/CommitGraphLoaderTest.java
new file mode 100644
index 0000000..fd427a1
--- /dev/null
+++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/commitgraph/CommitGraphLoaderTest.java
@@ -0,0 +1,75 @@
+/*
+ * Copyright (C) 2022, Tencent.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Distribution License v. 1.0 which is available at
+ * https://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+package org.eclipse.jgit.internal.storage.commitgraph;
+
+import static org.junit.Assert.assertArrayEquals;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+
+import org.eclipse.jgit.internal.storage.commitgraph.CommitGraph.CommitData;
+import org.eclipse.jgit.junit.JGitTestUtil;
+import org.eclipse.jgit.lib.ObjectId;
+import org.junit.Test;
+
+/**
+ * Test CommitGraphLoader by reading the commit-graph file generated by Cgit.
+ */
+public class CommitGraphLoaderTest {
+
+	private CommitGraph commitGraph;
+
+	@Test
+	public void readCommitGraphV1() throws Exception {
+		commitGraph = CommitGraphLoader
+				.open(JGitTestUtil.getTestResourceFile("commit-graph.v1"));
+		assertNotNull(commitGraph);
+		assertEquals(10, commitGraph.getCommitCnt());
+		verifyGraphObjectIndex();
+
+		assertCommitData("85b0176af27fa1640868f061f224d01e0b295f59",
+				new int[] { 5, 6 }, 1670570408L, 3, 0);
+		assertCommitData("d4f7c00aab3f0160168c9e5991abb6194a4e0d9e",
+				new int[] {}, 1670569901L, 1, 1);
+		assertCommitData("4d03aaf9c20c97d6ccdc05cb7f146b1deb6c01d5",
+				new int[] { 5 }, 1670570119L, 3, 2);
+		assertCommitData("a2f409b753880bf83b18bfb433dd340a6185e8be",
+				new int[] { 7 }, 1670569935L, 3, 3);
+		assertCommitData("431343847343979bbe31127ed905a24fed9a636c",
+				new int[] { 3, 2, 8 }, 1670570644L, 4, 4);
+		assertCommitData("c3f745ad8928ef56b5dbf33740fc8ede6b598290",
+				new int[] { 1 }, 1670570106L, 2, 5);
+		assertCommitData("95b12422c8ea4371e54cd58925eeed9d960ff1f0",
+				new int[] { 1 }, 1670570163L, 2, 6);
+		assertCommitData("de0ea882503cdd9c984c0a43238014569a123cac",
+				new int[] { 1 }, 1670569921L, 2, 7);
+		assertCommitData("102c9d6481559b1a113eb66bf55085903de6fb00",
+				new int[] { 6 }, 1670570616L, 3, 8);
+		assertCommitData("b5de2a84867f8ffc6321649dabf8c0680661ec03",
+				new int[] { 7, 5 }, 1670570364L, 3, 9);
+	}
+
+	private void verifyGraphObjectIndex() {
+		for (int i = 0; i < commitGraph.getCommitCnt(); i++) {
+			ObjectId id = commitGraph.getObjectId(i);
+			int pos = commitGraph.findGraphPosition(id);
+			assertEquals(i, pos);
+		}
+	}
+
+	private void assertCommitData(String expectedTree, int[] expectedParents,
+			long expectedCommitTime, int expectedGeneration, int graphPos) {
+		CommitData commitData = commitGraph.getCommitData(graphPos);
+		assertEquals(ObjectId.fromString(expectedTree), commitData.getTree());
+		assertArrayEquals(expectedParents, commitData.getParents());
+		assertEquals(expectedCommitTime, commitData.getCommitTime());
+		assertEquals(expectedGeneration, commitData.getGeneration());
+	}
+}
diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/commitgraph/CommitGraphTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/commitgraph/CommitGraphTest.java
new file mode 100644
index 0000000..9797656
--- /dev/null
+++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/commitgraph/CommitGraphTest.java
@@ -0,0 +1,255 @@
+/*
+ * Copyright (C) 2022, Tencent.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Distribution License v. 1.0 which is available at
+ * https://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+package org.eclipse.jgit.internal.storage.commitgraph;
+
+import static org.eclipse.jgit.lib.Constants.COMMIT_GENERATION_UNKNOWN;
+import static org.junit.Assert.assertArrayEquals;
+import static org.junit.Assert.assertEquals;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.InputStream;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.Set;
+
+import org.eclipse.jgit.internal.storage.file.FileRepository;
+import org.eclipse.jgit.junit.RepositoryTestCase;
+import org.eclipse.jgit.junit.TestRepository;
+import org.eclipse.jgit.lib.NullProgressMonitor;
+import org.eclipse.jgit.lib.ObjectId;
+import org.eclipse.jgit.revwalk.RevCommit;
+import org.eclipse.jgit.revwalk.RevWalk;
+import org.junit.Before;
+import org.junit.Test;
+
+/**
+ * Test writing and then reading the commit-graph.
+ */
+public class CommitGraphTest extends RepositoryTestCase {
+
+	private TestRepository<FileRepository> tr;
+
+	private CommitGraph commitGraph;
+
+	@Override
+	@Before
+	public void setUp() throws Exception {
+		super.setUp();
+		tr = new TestRepository<>(db, new RevWalk(db), mockSystemReader);
+	}
+
+	@Test
+	public void testGraphWithSingleCommit() throws Exception {
+		RevCommit root = commit();
+		writeAndReadCommitGraph(Collections.singleton(root));
+		verifyCommitGraph();
+		assertEquals(1, getGenerationNumber(root));
+	}
+
+	@Test
+	public void testGraphWithManyParents() throws Exception {
+		int parentsNum = 40;
+		RevCommit root = commit();
+
+		RevCommit[] parents = new RevCommit[parentsNum];
+		for (int i = 0; i < parents.length; i++) {
+			parents[i] = commit(root);
+		}
+		RevCommit tip = commit(parents);
+
+		Set<ObjectId> wants = Collections.singleton(tip);
+		writeAndReadCommitGraph(wants);
+		assertEquals(parentsNum + 2, commitGraph.getCommitCnt());
+		verifyCommitGraph();
+
+		assertEquals(1, getGenerationNumber(root));
+		for (RevCommit parent : parents) {
+			assertEquals(2, getGenerationNumber(parent));
+		}
+		assertEquals(3, getGenerationNumber(tip));
+	}
+
+	@Test
+	public void testGraphLinearHistory() throws Exception {
+		int commitNum = 20;
+		RevCommit[] commits = new RevCommit[commitNum];
+		for (int i = 0; i < commitNum; i++) {
+			if (i == 0) {
+				commits[i] = commit();
+			} else {
+				commits[i] = commit(commits[i - 1]);
+			}
+		}
+
+		Set<ObjectId> wants = Collections.singleton(commits[commitNum - 1]);
+		writeAndReadCommitGraph(wants);
+		assertEquals(commitNum, commitGraph.getCommitCnt());
+		verifyCommitGraph();
+		for (int i = 0; i < commitNum; i++) {
+			assertEquals(i + 1, getGenerationNumber(commits[i]));
+		}
+	}
+
+	@Test
+	public void testGraphWithMerges() throws Exception {
+		RevCommit c1 = commit();
+		RevCommit c2 = commit(c1);
+		RevCommit c3 = commit(c2);
+		RevCommit c4 = commit(c1);
+		RevCommit c5 = commit(c4);
+		RevCommit c6 = commit(c1);
+		RevCommit c7 = commit(c6);
+
+		RevCommit m1 = commit(c2, c4);
+		RevCommit m2 = commit(c4, c6);
+		RevCommit m3 = commit(c3, c5, c7);
+
+		Set<ObjectId> wants = new HashSet<>();
+
+		/*
+		 * <pre>
+		 * current graph structure:
+		 *    M1
+		 *   /  \
+		 *  2    4
+		 *  |___/
+		 *  1
+		 * </pre>
+		 */
+		wants.add(m1);
+		writeAndReadCommitGraph(wants);
+		assertEquals(4, commitGraph.getCommitCnt());
+		verifyCommitGraph();
+
+		/*
+		 * <pre>
+		 * current graph structure:
+		 *    M1   M2
+		 *   /  \ /  \
+		 *  2    4    6
+		 *  |___/____/
+		 *  1
+		 * </pre>
+		 */
+		wants.add(m2);
+		writeAndReadCommitGraph(wants);
+		assertEquals(6, commitGraph.getCommitCnt());
+		verifyCommitGraph();
+
+		/*
+		 * <pre>
+		 * current graph structure:
+		 *
+		 *    __M3___
+		 *   /   |   \
+		 *  3 M1 5 M2 7
+		 *  |/  \|/  \|
+		 *  2    4    6
+		 *  |___/____/
+		 *  1
+		 * </pre>
+		 */
+		wants.add(m3);
+		writeAndReadCommitGraph(wants);
+		assertEquals(10, commitGraph.getCommitCnt());
+		verifyCommitGraph();
+
+		/*
+		 * <pre>
+		 * current graph structure:
+		 *       8
+		 *       |
+		 *    __M3___
+		 *   /   |   \
+		 *  3 M1 5 M2 7
+		 *  |/  \|/  \|
+		 *  2    4    6
+		 *  |___/____/
+		 *  1
+		 * </pre>
+		 */
+		RevCommit c8 = commit(m3);
+		wants.add(c8);
+		writeAndReadCommitGraph(wants);
+		assertEquals(11, commitGraph.getCommitCnt());
+		verifyCommitGraph();
+
+		assertEquals(getGenerationNumber(c1), 1);
+		assertEquals(getGenerationNumber(c2), 2);
+		assertEquals(getGenerationNumber(c4), 2);
+		assertEquals(getGenerationNumber(c6), 2);
+		assertEquals(getGenerationNumber(c3), 3);
+		assertEquals(getGenerationNumber(c5), 3);
+		assertEquals(getGenerationNumber(c7), 3);
+		assertEquals(getGenerationNumber(m1), 3);
+		assertEquals(getGenerationNumber(m2), 3);
+		assertEquals(getGenerationNumber(m3), 4);
+		assertEquals(getGenerationNumber(c8), 5);
+	}
+
+	void writeAndReadCommitGraph(Set<ObjectId> wants) throws Exception {
+		NullProgressMonitor m = NullProgressMonitor.INSTANCE;
+		try (RevWalk walk = new RevWalk(db)) {
+			CommitGraphWriter writer = new CommitGraphWriter(
+					GraphCommits.fromWalk(m, wants, walk));
+			ByteArrayOutputStream os = new ByteArrayOutputStream();
+			writer.write(m, os);
+			InputStream inputStream = new ByteArrayInputStream(
+					os.toByteArray());
+			commitGraph = CommitGraphLoader.read(inputStream);
+		}
+	}
+
+	void verifyCommitGraph() throws Exception {
+		try (RevWalk walk = new RevWalk(db)) {
+			for (int i = 0; i < commitGraph.getCommitCnt(); i++) {
+				ObjectId objId = commitGraph.getObjectId(i);
+
+				// check the objectId index of commit-graph
+				int pos = commitGraph.findGraphPosition(objId);
+				assertEquals(i, pos);
+
+				// check the commit meta of commit-graph
+				CommitGraph.CommitData commit = commitGraph.getCommitData(i);
+				int[] pList = commit.getParents();
+
+				RevCommit expect = walk.lookupCommit(objId);
+				walk.parseBody(expect);
+
+				assertEquals(expect.getCommitTime(), commit.getCommitTime());
+				assertEquals(expect.getTree(), commit.getTree());
+				assertEquals(expect.getParentCount(), pList.length);
+
+				if (pList.length > 0) {
+					ObjectId[] parents = new ObjectId[pList.length];
+					for (int j = 0; j < parents.length; j++) {
+						parents[j] = commitGraph.getObjectId(pList[j]);
+					}
+					assertArrayEquals(expect.getParents(), parents);
+				}
+			}
+		}
+	}
+
+	int getGenerationNumber(ObjectId id) {
+		int graphPos = commitGraph.findGraphPosition(id);
+		CommitGraph.CommitData commitData = commitGraph.getCommitData(graphPos);
+		if (commitData != null) {
+			return commitData.getGeneration();
+		}
+		return COMMIT_GENERATION_UNKNOWN;
+	}
+
+	RevCommit commit(RevCommit... parents) throws Exception {
+		return tr.commit(parents);
+	}
+}
diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/commitgraph/CommitGraphWriterTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/commitgraph/CommitGraphWriterTest.java
new file mode 100644
index 0000000..6c5e5e5
--- /dev/null
+++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/commitgraph/CommitGraphWriterTest.java
@@ -0,0 +1,113 @@
+/*
+ * Copyright (C) 2021, Tencent.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Distribution License v. 1.0 which is available at
+ * https://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+package org.eclipse.jgit.internal.storage.commitgraph;
+
+import static org.junit.Assert.assertArrayEquals;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+
+import java.io.ByteArrayOutputStream;
+import java.util.Collections;
+import java.util.Set;
+
+import org.eclipse.jgit.internal.storage.file.FileRepository;
+import org.eclipse.jgit.junit.RepositoryTestCase;
+import org.eclipse.jgit.junit.TestRepository;
+import org.eclipse.jgit.lib.NullProgressMonitor;
+import org.eclipse.jgit.lib.ObjectId;
+import org.eclipse.jgit.revwalk.RevCommit;
+import org.eclipse.jgit.revwalk.RevWalk;
+import org.eclipse.jgit.util.NB;
+import org.junit.Before;
+import org.junit.Test;
+
+public class CommitGraphWriterTest extends RepositoryTestCase {
+
+	private TestRepository<FileRepository> tr;
+
+	private ByteArrayOutputStream os;
+
+	private CommitGraphWriter writer;
+
+	private RevWalk walk;
+
+	@Override
+	@Before
+	public void setUp() throws Exception {
+		super.setUp();
+		os = new ByteArrayOutputStream();
+		tr = new TestRepository<>(db, new RevWalk(db), mockSystemReader);
+		walk = new RevWalk(db);
+	}
+
+	@Test
+	public void testWriteInEmptyRepo() throws Exception {
+		NullProgressMonitor m = NullProgressMonitor.INSTANCE;
+		writer = new CommitGraphWriter(
+				GraphCommits.fromWalk(m, Collections.emptySet(), walk));
+		writer.write(m, os);
+		assertEquals(0, os.size());
+	}
+
+	@Test
+	public void testWriterWithExtraEdgeList() throws Exception {
+		RevCommit root = commit();
+		RevCommit a = commit(root);
+		RevCommit b = commit(root);
+		RevCommit c = commit(root);
+		RevCommit tip = commit(a, b, c);
+
+		Set<ObjectId> wants = Collections.singleton(tip);
+		NullProgressMonitor m = NullProgressMonitor.INSTANCE;
+		GraphCommits graphCommits = GraphCommits.fromWalk(m, wants, walk);
+		writer = new CommitGraphWriter(graphCommits);
+		writer.write(m, os);
+
+		assertEquals(5, graphCommits.size());
+		byte[] data = os.toByteArray();
+		assertTrue(data.length > 0);
+		byte[] headers = new byte[8];
+		System.arraycopy(data, 0, headers, 0, 8);
+		assertArrayEquals(new byte[] {'C', 'G', 'P', 'H', 1, 1, 4, 0}, headers);
+		assertEquals(CommitGraphConstants.CHUNK_ID_OID_FANOUT, NB.decodeInt32(data, 8));
+		assertEquals(CommitGraphConstants.CHUNK_ID_OID_LOOKUP, NB.decodeInt32(data, 20));
+		assertEquals(CommitGraphConstants.CHUNK_ID_COMMIT_DATA, NB.decodeInt32(data, 32));
+		assertEquals(CommitGraphConstants.CHUNK_ID_EXTRA_EDGE_LIST, NB.decodeInt32(data, 44));
+	}
+
+	@Test
+	public void testWriterWithoutExtraEdgeList() throws Exception {
+		RevCommit root = commit();
+		RevCommit a = commit(root);
+		RevCommit b = commit(root);
+		RevCommit tip = commit(a, b);
+
+		Set<ObjectId> wants = Collections.singleton(tip);
+		NullProgressMonitor m = NullProgressMonitor.INSTANCE;
+		GraphCommits graphCommits = GraphCommits.fromWalk(m, wants, walk);
+		writer = new CommitGraphWriter(graphCommits);
+		writer.write(m, os);
+
+		assertEquals(4, graphCommits.size());
+		byte[] data = os.toByteArray();
+		assertTrue(data.length > 0);
+		byte[] headers = new byte[8];
+		System.arraycopy(data, 0, headers, 0, 8);
+		assertArrayEquals(new byte[] {'C', 'G', 'P', 'H', 1, 1, 3, 0}, headers);
+		assertEquals(CommitGraphConstants.CHUNK_ID_OID_FANOUT, NB.decodeInt32(data, 8));
+		assertEquals(CommitGraphConstants.CHUNK_ID_OID_LOOKUP, NB.decodeInt32(data, 20));
+		assertEquals(CommitGraphConstants.CHUNK_ID_COMMIT_DATA, NB.decodeInt32(data, 32));
+	}
+
+	RevCommit commit(RevCommit... parents) throws Exception {
+		return tr.commit(parents);
+	}
+}
diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/commitgraph/GraphCommitsTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/commitgraph/GraphCommitsTest.java
new file mode 100644
index 0000000..fc05feb
--- /dev/null
+++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/commitgraph/GraphCommitsTest.java
@@ -0,0 +1,119 @@
+/*
+ * Copyright (C) 2021, Tencent.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Distribution License v. 1.0 which is available at
+ * https://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+package org.eclipse.jgit.internal.storage.commitgraph;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertThrows;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Iterator;
+import java.util.List;
+
+import org.eclipse.jgit.errors.MissingObjectException;
+import org.eclipse.jgit.internal.storage.file.FileRepository;
+import org.eclipse.jgit.junit.RepositoryTestCase;
+import org.eclipse.jgit.junit.TestRepository;
+import org.eclipse.jgit.lib.NullProgressMonitor;
+import org.eclipse.jgit.revwalk.RevCommit;
+import org.eclipse.jgit.revwalk.RevWalk;
+import org.junit.Before;
+import org.junit.Test;
+
+public class GraphCommitsTest extends RepositoryTestCase {
+
+	private TestRepository<FileRepository> tr;
+
+	@Override
+	@Before
+	public void setUp() throws Exception {
+		super.setUp();
+		tr = new TestRepository<>(db, new RevWalk(db), mockSystemReader);
+	}
+
+	@Test
+	public void testEmptyRepo() throws Exception {
+		try (RevWalk rw = new RevWalk(db)) {
+			GraphCommits commits = GraphCommits.fromWalk(
+					NullProgressMonitor.INSTANCE, Collections.emptySet(), rw);
+			assertEquals(0, commits.size());
+			assertEquals(0, commits.getExtraEdgeCnt());
+			assertFalse(commits.iterator().hasNext());
+		}
+	}
+
+	@Test
+	public void testRepoWithoutExtraEdges() throws Exception {
+		try (RevWalk rw = new RevWalk(db)) {
+			RevCommit root = commit();
+			RevCommit a = commit(root);
+			RevCommit b = commit(root);
+			RevCommit tip = commit(a, b);
+			GraphCommits commits = GraphCommits.fromWalk(
+					NullProgressMonitor.INSTANCE, Collections.singleton(tip),
+					rw);
+			assertEquals(4, commits.size());
+			assertEquals(0, commits.getExtraEdgeCnt());
+			verifyOrderOfLookup(List.of(root, a, b, tip), commits);
+		}
+	}
+
+	@Test
+	public void testRepoWithExtraEdges() throws Exception {
+		try (RevWalk rw = new RevWalk(db)) {
+			RevCommit root = commit();
+			RevCommit a = commit(root);
+			RevCommit b = commit(root);
+			RevCommit c = commit(root);
+			RevCommit tip = commit(a, b, c);
+			GraphCommits commits = GraphCommits.fromWalk(
+					NullProgressMonitor.INSTANCE, Collections.singleton(tip),
+					rw);
+			assertEquals(5, commits.size());
+			assertEquals(2, commits.getExtraEdgeCnt());
+			verifyOrderOfLookup(List.of(root, a, b, c, tip), commits);
+		}
+	}
+
+	@Test
+	public void testCommitNotInLookup() throws Exception {
+		try (RevWalk rw = new RevWalk(db)) {
+			RevCommit a = commit();
+			RevCommit b = commit(a);
+			GraphCommits commits = GraphCommits.fromWalk(
+					NullProgressMonitor.INSTANCE, Collections.singleton(a), rw);
+			assertEquals(1, commits.size());
+			assertEquals(0, commits.getExtraEdgeCnt());
+			Iterator<RevCommit> iterator = commits.iterator();
+			assertEquals(a, iterator.next());
+			assertFalse(iterator.hasNext());
+			assertThrows(MissingObjectException.class,
+					() -> commits.getOidPosition(b));
+		}
+	}
+
+	private void verifyOrderOfLookup(List<RevCommit> commits,
+			GraphCommits graphCommits) {
+		commits = new ArrayList<>(commits);
+		Collections.sort(commits);
+		Iterator<RevCommit> expected = commits.iterator();
+		Iterator<RevCommit> actual = graphCommits.iterator();
+		while (expected.hasNext()) {
+			assertEquals(expected.next(), actual.next());
+		}
+		assertFalse(actual.hasNext());
+	}
+
+	RevCommit commit(RevCommit... parents) throws Exception {
+		return tr.commit(parents);
+	}
+}
diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/file/GcCommitGraphTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/file/GcCommitGraphTest.java
new file mode 100644
index 0000000..358e19e
--- /dev/null
+++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/file/GcCommitGraphTest.java
@@ -0,0 +1,173 @@
+/*
+ * Copyright (C) 2022, Tencent.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Distribution License v. 1.0 which is available at
+ * https://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+package org.eclipse.jgit.internal.storage.file;
+
+import static org.junit.Assert.assertArrayEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.InputStream;
+import java.util.Collections;
+
+import org.eclipse.jgit.junit.TestRepository;
+import org.eclipse.jgit.lib.ConfigConstants;
+import org.eclipse.jgit.lib.Constants;
+import org.eclipse.jgit.lib.StoredConfig;
+import org.eclipse.jgit.revwalk.RevCommit;
+import org.eclipse.jgit.util.IO;
+import org.junit.Test;
+
+public class GcCommitGraphTest extends GcTestCase {
+
+	@Test
+	public void testCommitGraphConfig() {
+		StoredConfig config = repo.getConfig();
+		assertFalse(gc.shouldWriteCommitGraphWhenGc());
+
+		config.setBoolean(ConfigConstants.CONFIG_GC_SECTION, null,
+				ConfigConstants.CONFIG_KEY_WRITE_COMMIT_GRAPH, true);
+		assertTrue(gc.shouldWriteCommitGraphWhenGc());
+
+		config.setBoolean(ConfigConstants.CONFIG_GC_SECTION, null,
+				ConfigConstants.CONFIG_KEY_WRITE_COMMIT_GRAPH, false);
+		assertFalse(gc.shouldWriteCommitGraphWhenGc());
+	}
+
+	@Test
+	public void testWriteEmptyRepo() throws Exception {
+		StoredConfig config = repo.getConfig();
+		config.setBoolean(ConfigConstants.CONFIG_CORE_SECTION, null,
+				ConfigConstants.CONFIG_COMMIT_GRAPH, true);
+		config.setBoolean(ConfigConstants.CONFIG_GC_SECTION, null,
+				ConfigConstants.CONFIG_KEY_WRITE_COMMIT_GRAPH, true);
+
+		assertTrue(gc.shouldWriteCommitGraphWhenGc());
+		gc.writeCommitGraph(Collections.emptySet());
+		File graphFile = new File(repo.getObjectsDirectory(),
+				Constants.INFO_COMMIT_GRAPH);
+		assertFalse(graphFile.exists());
+	}
+
+	@Test
+	public void testWriteShallowRepo() throws Exception {
+		StoredConfig config = repo.getConfig();
+		config.setBoolean(ConfigConstants.CONFIG_CORE_SECTION, null,
+				ConfigConstants.CONFIG_COMMIT_GRAPH, true);
+		config.setBoolean(ConfigConstants.CONFIG_GC_SECTION, null,
+				ConfigConstants.CONFIG_KEY_WRITE_COMMIT_GRAPH, true);
+
+		RevCommit tip = commitChain(2);
+		TestRepository.BranchBuilder bb = tr.branch("refs/heads/master");
+		bb.update(tip);
+		repo.getObjectDatabase().setShallowCommits(Collections.singleton(tip));
+
+		gc.writeCommitGraph(Collections.singleton(tip));
+		File graphFile = new File(repo.getObjectsDirectory(),
+				Constants.INFO_COMMIT_GRAPH);
+		assertFalse(graphFile.exists());
+	}
+
+	@Test
+	public void testWriteWhenGc() throws Exception {
+		StoredConfig config = repo.getConfig();
+		config.setBoolean(ConfigConstants.CONFIG_CORE_SECTION, null,
+				ConfigConstants.CONFIG_COMMIT_GRAPH, true);
+		config.setBoolean(ConfigConstants.CONFIG_GC_SECTION, null,
+				ConfigConstants.CONFIG_KEY_WRITE_COMMIT_GRAPH, true);
+
+		RevCommit tip = commitChain(10);
+		TestRepository.BranchBuilder bb = tr.branch("refs/heads/master");
+		bb.update(tip);
+
+		assertTrue(gc.shouldWriteCommitGraphWhenGc());
+		gc.gc();
+		File graphFile = new File(repo.getObjectsDirectory(),
+				Constants.INFO_COMMIT_GRAPH);
+		assertGraphFile(graphFile);
+	}
+
+	@Test
+	public void testDefaultWriteWhenGc() throws Exception {
+		RevCommit tip = commitChain(10);
+		TestRepository.BranchBuilder bb = tr.branch("refs/heads/master");
+		bb.update(tip);
+
+		assertFalse(gc.shouldWriteCommitGraphWhenGc());
+		gc.gc();
+		File graphFile = new File(repo.getObjectsDirectory(),
+				Constants.INFO_COMMIT_GRAPH);
+		assertFalse(graphFile.exists());
+	}
+
+	@Test
+	public void testDisableWriteWhenGc() throws Exception {
+		RevCommit tip = commitChain(10);
+		TestRepository.BranchBuilder bb = tr.branch("refs/heads/master");
+		bb.update(tip);
+		File graphFile = new File(repo.getObjectsDirectory(),
+				Constants.INFO_COMMIT_GRAPH);
+
+		StoredConfig config = repo.getConfig();
+		config.setBoolean(ConfigConstants.CONFIG_CORE_SECTION, null,
+				ConfigConstants.CONFIG_COMMIT_GRAPH, false);
+		config.setBoolean(ConfigConstants.CONFIG_GC_SECTION, null,
+				ConfigConstants.CONFIG_KEY_WRITE_COMMIT_GRAPH, true);
+
+		gc.gc();
+		assertFalse(graphFile.exists());
+
+		config.setBoolean(ConfigConstants.CONFIG_CORE_SECTION, null,
+				ConfigConstants.CONFIG_COMMIT_GRAPH, true);
+		config.setBoolean(ConfigConstants.CONFIG_GC_SECTION, null,
+				ConfigConstants.CONFIG_KEY_WRITE_COMMIT_GRAPH, false);
+		gc.gc();
+		assertFalse(graphFile.exists());
+
+		config.setBoolean(ConfigConstants.CONFIG_CORE_SECTION, null,
+				ConfigConstants.CONFIG_COMMIT_GRAPH, false);
+		config.setBoolean(ConfigConstants.CONFIG_GC_SECTION, null,
+				ConfigConstants.CONFIG_KEY_WRITE_COMMIT_GRAPH, false);
+		gc.gc();
+		assertFalse(graphFile.exists());
+	}
+
+	@Test
+	public void testWriteCommitGraphOnly() throws Exception {
+		RevCommit tip = commitChain(10);
+		TestRepository.BranchBuilder bb = tr.branch("refs/heads/master");
+		bb.update(tip);
+
+		StoredConfig config = repo.getConfig();
+		config.setBoolean(ConfigConstants.CONFIG_CORE_SECTION, null,
+				ConfigConstants.CONFIG_COMMIT_GRAPH, false);
+		gc.writeCommitGraph(Collections.singleton(tip));
+
+		File graphFile = new File(repo.getObjectsDirectory(),
+				Constants.INFO_COMMIT_GRAPH);
+		assertFalse(graphFile.exists());
+
+		config.setBoolean(ConfigConstants.CONFIG_CORE_SECTION, null,
+				ConfigConstants.CONFIG_COMMIT_GRAPH, true);
+		gc.writeCommitGraph(Collections.singleton(tip));
+		assertGraphFile(graphFile);
+	}
+
+	private void assertGraphFile(File graphFile) throws Exception {
+		assertTrue(graphFile.exists());
+		try (InputStream os = new FileInputStream(graphFile)) {
+			byte[] magic = new byte[4];
+			IO.readFully(os, magic, 0, 4);
+			assertArrayEquals(new byte[] { 'C', 'G', 'P', 'H' }, magic);
+		}
+	}
+}
diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/file/GcOrphanFilesTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/file/GcOrphanFilesTest.java
index 620aedf..342e559 100644
--- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/file/GcOrphanFilesTest.java
+++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/file/GcOrphanFilesTest.java
@@ -10,6 +10,7 @@
 
 package org.eclipse.jgit.internal.storage.file;
 
+import static org.eclipse.jgit.internal.storage.pack.PackExt.REVERSE_INDEX;
 import static org.junit.Assert.assertFalse;
 import static org.junit.Assert.assertTrue;
 
@@ -36,6 +37,14 @@ public class GcOrphanFilesTest extends GcTestCase {
 
 	private static final String PACK_File_3 = PACK + "-3.pack";
 
+	private static final String REVERSE_File_2 = PACK + "-2."
+			+ REVERSE_INDEX.getExtension();
+
+	private static final String REVERSE_File_4 = PACK + "-4."
+			+ REVERSE_INDEX.getExtension();
+
+	private static final String NONEXISTENT_EXT = PACK + "-4.xxxxx";
+
 	private File packDir;
 
 	@Override
@@ -46,14 +55,27 @@ public void setUp() throws Exception {
 	}
 
 	@Test
-	public void bitmapAndIdxDeletedButPackNot() throws Exception {
+	public void indexesDeletedButPackNot() throws Exception {
 		createFileInPackFolder(BITMAP_File_1);
 		createFileInPackFolder(IDX_File_2);
 		createFileInPackFolder(PACK_File_3);
+		createFileInPackFolder(REVERSE_File_4);
 		gc.gc().get();
 		assertFalse(new File(packDir, BITMAP_File_1).exists());
 		assertFalse(new File(packDir, IDX_File_2).exists());
 		assertTrue(new File(packDir, PACK_File_3).exists());
+		assertFalse(new File(packDir, REVERSE_File_4).exists());
+	}
+
+	@Test
+	public void noPacks_allIndexesDeleted() throws Exception {
+		createFileInPackFolder(BITMAP_File_1);
+		createFileInPackFolder(IDX_File_2);
+		createFileInPackFolder(REVERSE_File_4);
+		gc.gc().get();
+		assertFalse(new File(packDir, BITMAP_File_1).exists());
+		assertFalse(new File(packDir, IDX_File_2).exists());
+		assertFalse(new File(packDir, REVERSE_File_4).exists());
 	}
 
 	@Test
@@ -77,18 +99,27 @@ public void malformedIdxNotDeleted() throws Exception {
 	}
 
 	@Test
+	public void nonexistantExtensionNotDeleted() throws Exception {
+		createFileInPackFolder(NONEXISTENT_EXT);
+		gc.gc().get();
+		assertTrue(new File(packDir, NONEXISTENT_EXT).exists());
+	}
+
+	@Test
 	public void keepPreventsDeletionOfIndexFilesForMissingPackFile()
 			throws Exception {
 		createFileInPackFolder(BITMAP_File_1);
-		createFileInPackFolder(IDX_File_2);
 		createFileInPackFolder(BITMAP_File_2);
+		createFileInPackFolder(IDX_File_2);
 		createFileInPackFolder(KEEP_File_2);
+		createFileInPackFolder(REVERSE_File_2);
 		createFileInPackFolder(PACK_File_3);
 		gc.gc().get();
 		assertFalse(new File(packDir, BITMAP_File_1).exists());
 		assertTrue(new File(packDir, BITMAP_File_2).exists());
 		assertTrue(new File(packDir, IDX_File_2).exists());
 		assertTrue(new File(packDir, KEEP_File_2).exists());
+		assertTrue(new File(packDir, REVERSE_File_2).exists());
 		assertTrue(new File(packDir, PACK_File_3).exists());
 	}
 
diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/file/ObjectDirectoryTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/file/ObjectDirectoryTest.java
index 1a3b378..ddc4a9d 100644
--- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/file/ObjectDirectoryTest.java
+++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/file/ObjectDirectoryTest.java
@@ -43,6 +43,7 @@
 package org.eclipse.jgit.internal.storage.file;
 
 import static java.nio.charset.StandardCharsets.UTF_8;
+import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertFalse;
 import static org.junit.Assert.assertNull;
 import static org.junit.Assert.assertThrows;
@@ -236,6 +237,26 @@ public void testOpenLooseObjectPropagatesIOExceptions() throws Exception {
 	}
 
 	@Test
+	public void testWindowCursorGetCommitGraph() throws Exception {
+		db.getConfig().setBoolean(ConfigConstants.CONFIG_CORE_SECTION, null,
+				ConfigConstants.CONFIG_COMMIT_GRAPH, true);
+		db.getConfig().setBoolean(ConfigConstants.CONFIG_GC_SECTION, null,
+				ConfigConstants.CONFIG_KEY_WRITE_COMMIT_GRAPH, true);
+
+		WindowCursor curs = new WindowCursor(db.getObjectDatabase());
+		assertTrue(curs.getCommitGraph().isEmpty());
+		commitFile("file.txt", "content", "master");
+		GC gc = new GC(db);
+		gc.gc();
+		assertTrue(curs.getCommitGraph().isPresent());
+
+		db.getConfig().setBoolean(ConfigConstants.CONFIG_CORE_SECTION, null,
+				ConfigConstants.CONFIG_COMMIT_GRAPH, false);
+
+		assertTrue(curs.getCommitGraph().isEmpty());
+	}
+
+	@Test
 	public void testShallowFileCorrupt() throws Exception {
 		FileRepository repository = createBareRepository();
 		ObjectDirectory dir = repository.getObjectDatabase();
@@ -251,6 +272,50 @@ public void testShallowFileCorrupt() throws Exception {
 				IOException.class, () -> dir.getShallowCommits());
 	}
 
+	@Test
+	public void testGetCommitGraph() throws Exception {
+		db.getConfig().setBoolean(ConfigConstants.CONFIG_CORE_SECTION, null,
+				ConfigConstants.CONFIG_COMMIT_GRAPH, true);
+		db.getConfig().setBoolean(ConfigConstants.CONFIG_GC_SECTION, null,
+				ConfigConstants.CONFIG_KEY_WRITE_COMMIT_GRAPH, true);
+
+		// no commit-graph
+		ObjectDirectory dir = db.getObjectDatabase();
+		assertTrue(dir.getCommitGraph().isEmpty());
+
+		// add commit-graph
+		commitFile("file.txt", "content", "master");
+		GC gc = new GC(db);
+		gc.gc();
+		File file = new File(db.getObjectsDirectory(),
+				Constants.INFO_COMMIT_GRAPH);
+		assertTrue(file.exists());
+		assertTrue(file.isFile());
+		assertTrue(dir.getCommitGraph().isPresent());
+		assertEquals(1, dir.getCommitGraph().get().getCommitCnt());
+
+		// update commit-graph
+		commitFile("file2.txt", "content", "master");
+		gc.gc();
+		assertEquals(2, dir.getCommitGraph().get().getCommitCnt());
+
+		// delete commit-graph
+		file.delete();
+		assertFalse(file.exists());
+		assertTrue(dir.getCommitGraph().isEmpty());
+
+		// commit-graph is corrupt
+		try (PrintWriter writer = new PrintWriter(file, UTF_8.name())) {
+			writer.println("this is a corrupt commit-graph");
+		}
+		assertTrue(dir.getCommitGraph().isEmpty());
+
+		// add commit-graph again
+		gc.gc();
+		assertTrue(dir.getCommitGraph().isPresent());
+		assertEquals(2, dir.getCommitGraph().get().getCommitCnt());
+	}
+
 	private Collection<Callable<ObjectId>> blobInsertersForTheSameFanOutDir(
 			final ObjectDirectory dir) {
 		Callable<ObjectId> callable = () -> dir.newInserter()
diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/memory/TernarySearchTreeTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/memory/TernarySearchTreeTest.java
new file mode 100644
index 0000000..623c92f
--- /dev/null
+++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/memory/TernarySearchTreeTest.java
@@ -0,0 +1,330 @@
+/*
+ * Copyright (C) 2021, Matthias Sohn <matthias.sohn@sap.com> and others
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Distribution License v. 1.0 which is available at
+ * https://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+package org.eclipse.jgit.internal.storage.memory;
+
+import static java.util.Map.entry;
+import static org.junit.Assert.assertArrayEquals;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertThrows;
+import static org.junit.Assert.assertTrue;
+
+import java.util.Arrays;
+import java.util.List;
+import java.util.Map;
+import java.util.function.Consumer;
+import java.util.stream.Collectors;
+import java.util.stream.StreamSupport;
+
+import org.junit.Before;
+import org.junit.Test;
+
+public class TernarySearchTreeTest {
+
+	private TernarySearchTree<String> tree;
+
+	@Before
+	public void setup() {
+		tree = new TernarySearchTree<>();
+		tree.insert("foo", "1");
+		tree.insert("bar", "2");
+		tree.insert("foobar", "3");
+		tree.insert("foobaz", "4");
+		tree.insert("johndoe", "5");
+	}
+
+	@Test
+	public void testInsert() {
+		int initialSize = tree.size();
+		tree.insert("foobarbaz", "6");
+		assertEquals(initialSize + 1, tree.size());
+		assertEquals("6", tree.get("foobarbaz"));
+	}
+
+	@Test
+	public void testBatchInsert() {
+		Map<String, String> m = Map.ofEntries(
+				entry("refs/heads/master", "master"),
+				entry("refs/heads/stable-1.0", "stable-1.0"),
+				entry("refs/heads/stable-2.1", "stable-2.1"),
+				entry("refs/heads/stable-2.0", "stable-2.0"),
+				entry("refs/heads/stable-1.1", "stable-1.1"),
+				entry("refs/heads/stable-2.2", "stable-2.2"),
+				entry("aaa", "aaa"), entry("refs/tags/xyz", "xyz"),
+				entry("refs/tags/v1.1", "v1.1"),
+				entry("refs/tags/v2.2", "v2.2"),
+				entry("refs/tags/v1.0", "v1.0"),
+				entry("refs/tags/v2.1", "v2.1"),
+				entry("refs/tags/v2.0", "v2.0"));
+		tree.insert(m);
+		assertArrayEquals(
+				new String[] { "refs/heads/master", "refs/heads/stable-1.0",
+						"refs/heads/stable-1.1", "refs/heads/stable-2.0",
+						"refs/heads/stable-2.1", "refs/heads/stable-2.2" },
+				toArray(tree.getKeysWithPrefix("refs/heads/")));
+		assertArrayEquals(
+				new String[] { "refs/tags/v1.0", "refs/tags/v1.1",
+						"refs/tags/v2.0", "refs/tags/v2.1", "refs/tags/v2.2",
+						"refs/tags/xyz" },
+				toArray(tree.getKeysWithPrefix("refs/tags/")));
+		assertEquals("aaa", tree.get("aaa"));
+	}
+
+	@Test
+	public void testInsertWithNullKey() {
+		Exception exception = assertThrows(IllegalArgumentException.class,
+				() -> {
+					tree.insert(null, "42");
+				});
+		assertTrue(exception.getMessage()
+				.contains("TernarySearchTree key must not be null or empty"));
+	}
+
+	@Test
+	public void testOverwriteValue() {
+		int initialSize = tree.size();
+		tree.insert("foo", "overwritten");
+		assertEquals(initialSize, tree.size());
+		assertEquals("overwritten", tree.get("foo"));
+	}
+
+	@Test
+	public void testInsertNullValue() {
+		Exception exception = assertThrows(IllegalArgumentException.class,
+				() -> {
+					tree.insert("xxx", null);
+				});
+		assertTrue(exception.getMessage()
+				.contains("cannot insert null value into TernarySearchTree"));
+	}
+
+	@Test
+	public void testReloadAll() {
+		Map<String, String> map = Map.of("foo", "foo-value", "bar",
+				"bar-value");
+		tree.replace(map.entrySet());
+		assertArrayEquals(new String[] { "bar", "foo" },
+				toArray(tree.getKeys()));
+	}
+
+	@Test
+	public void testReload() {
+		int initialSize = tree.size();
+		Map<String, String> map = Map.of("foo", "foo-value", "bar",
+				"bar-value");
+		tree.reload(map.entrySet());
+		assertEquals("foo-value", tree.get("foo"));
+		assertEquals("bar-value", tree.get("bar"));
+		assertEquals("3", tree.get("foobar"));
+		assertEquals("4", tree.get("foobaz"));
+		assertEquals("5", tree.get("johndoe"));
+		assertEquals(initialSize, tree.size());
+	}
+
+	@Test
+	public void testContains() {
+		assertTrue(tree.contains("foo"));
+		assertTrue(tree.contains("foobaz"));
+		assertFalse(tree.contains("ship"));
+	}
+
+	@Test
+	public void testContainsWithNullKey() {
+		Exception exception = assertThrows(IllegalArgumentException.class,
+				() -> {
+					tree.contains(null);
+				});
+		assertTrue(exception.getMessage()
+				.contains("TernarySearchTree key must not be null or empty"));
+	}
+
+	@Test
+	public void testGet() {
+		assertEquals("1", tree.get("foo"));
+		assertEquals("5", tree.get("johndoe"));
+		assertNull(tree.get("ship"));
+	}
+
+	@Test
+	public void testGetWithNullKey() {
+		Exception exception = assertThrows(IllegalArgumentException.class,
+				() -> {
+					tree.get(null);
+				});
+		assertTrue(exception.getMessage()
+				.contains("TernarySearchTree key must not be null or empty"));
+	}
+
+	@Test
+	public void testDeleteExisting() {
+		int initialSize = tree.size();
+		tree.delete("foo");
+		assertNull(tree.get("foo"));
+		assertEquals(initialSize - 1, tree.size());
+		tree.delete("cake");
+		assertEquals(4, tree.size());
+	}
+
+	@Test
+	public void testDeleteNonExisting() {
+		int initialSize = tree.size();
+		tree.delete("non-existent-key");
+		assertEquals(initialSize, tree.size());
+	}
+
+	@Test
+	public void testDeleteWithNullKey() {
+		Exception exception = assertThrows(IllegalArgumentException.class,
+				() -> {
+					tree.delete((String) null);
+				});
+		assertTrue(exception.getMessage()
+				.contains("TernarySearchTree key must not be null or empty"));
+	}
+
+	@Test
+	public void testDeleteMultiple() {
+		int initialSize = tree.size();
+		List<String> keys = toList(tree.getKeys());
+		keys.remove("foobar");
+		keys.remove("johndoe");
+		tree.delete(Arrays.asList(new String[] { "foobar", "johndoe" }));
+		assertEquals(initialSize - 2, tree.size());
+		assertArrayEquals(keys.toArray(), toArray(tree.getKeys()));
+	}
+
+	@Test
+	public void testClear() {
+		assertEquals(5, tree.size());
+		tree.clear();
+		assertEquals(0, tree.size());
+		tree.getKeys().forEach(new Consumer<String>() {
+
+			@Override
+			public void accept(String t) {
+				throw new IllegalStateException("should find no key");
+			}
+		});
+	}
+
+	@Test
+	public void testKeyLongestPrefix() {
+		assertEquals("foobar", tree.keyLongestPrefixOf("foobari"));
+		assertEquals("foo", tree.keyLongestPrefixOf("foocake"));
+		assertEquals("", tree.keyLongestPrefixOf("faabar"));
+		assertEquals("johndoe", tree.keyLongestPrefixOf("johndoea"));
+		assertEquals("", tree.keyLongestPrefixOf("wxy"));
+		assertNull(tree.keyLongestPrefixOf(""));
+		assertNull(tree.keyLongestPrefixOf(null));
+	}
+
+	@Test
+	public void testGetKeys() {
+		assertArrayEquals(
+				new String[] { "bar", "foo", "foobar", "foobaz", "johndoe" },
+				toArray(tree.getKeys()));
+	}
+
+	@Test
+	public void testGetKeysWithPrefix() {
+		assertArrayEquals(new String[] { "foo", "foobar", "foobaz" },
+				toArray(tree.getKeysWithPrefix("foo")));
+		assertArrayEquals(new String[] { "johndoe" },
+				toArray(tree.getKeysWithPrefix("john")));
+		assertArrayEquals(new String[0],
+				toArray(tree.getKeysWithPrefix("cake")));
+		assertArrayEquals(
+				new String[] { "bar", "foo", "foobar", "foobaz", "johndoe" },
+				toArray(tree.getKeysWithPrefix("")));
+		assertArrayEquals(new String[0], toArray(tree.getKeysWithPrefix(null)));
+	}
+
+	@Test
+	public void testGetWithPrefixFoo() {
+		Map<String, String> result = tree.getWithPrefix("foo");
+		assertEquals(3, result.size());
+		assertEquals("1", result.get("foo"));
+		assertEquals("3", result.get("foobar"));
+		assertEquals("4", result.get("foobaz"));
+	}
+
+	@Test
+	public void testGetWithPrefixNotFound() {
+		Map<String, String> result = tree.getWithPrefix("cheese");
+		assertEquals(0, result.size());
+	}
+
+	@Test
+	public void testGetWithPrefixNull() {
+		Map<String, String> result = tree.getWithPrefix(null);
+		assertEquals(0, result.size());
+	}
+
+	@Test
+	public void testGetWithPrefixEmptyPrefix() {
+		Map<String, String> result = tree.getWithPrefix("");
+		assertEquals(5, result.size());
+		assertEquals("1", result.get("foo"));
+		assertEquals("2", result.get("bar"));
+		assertEquals("3", result.get("foobar"));
+		assertEquals("4", result.get("foobaz"));
+		assertEquals("5", result.get("johndoe"));
+	}
+
+	@Test
+	public void testGetValuesWithPrefixFoo() {
+		List<String> result = tree.getValuesWithPrefix("foo");
+		assertEquals(3, result.size());
+		assertArrayEquals(new String[] { "1", "3", "4" },
+				result.toArray());
+	}
+
+	@Test
+	public void testGetValuesWithPrefixNotFound() {
+		List<String> result = tree.getValuesWithPrefix("cheese");
+		assertEquals(0, result.size());
+	}
+
+	@Test
+	public void testGetValuesWithPrefixNull() {
+		List<String> result = tree.getValuesWithPrefix(null);
+		assertEquals(0, result.size());
+	}
+
+	@Test
+	public void testGetValuesWithPrefixEmptyPrefix() {
+		List<String> result = tree.getValuesWithPrefix("");
+		assertEquals(5, result.size());
+		assertArrayEquals(new String[] { "2", "1", "3", "4", "5" },
+				result.toArray());
+	}
+
+	@Test
+	public void testGetKeysMatching() {
+		assertArrayEquals(new String[] { "foobar" },
+				toArray(tree.getKeysMatching("fo?bar")));
+		assertArrayEquals(new String[] { "foobar", "foobaz" },
+				toArray(tree.getKeysMatching("fooba?")));
+		assertArrayEquals(new String[] { "foobar", "foobaz" },
+				toArray(tree.getKeysMatching("?o?ba?")));
+		assertArrayEquals(new String[0], toArray(tree.getKeysMatching("")));
+		assertArrayEquals(new String[0], toArray(tree.getKeysMatching(null)));
+	}
+
+	private static List<String> toList(Iterable<String> iter) {
+		return StreamSupport.stream(iter.spliterator(), false)
+				.collect(Collectors.toList());
+	}
+
+	private static String[] toArray(Iterable<String> iter) {
+		return toList(iter).toArray(new String[0]);
+	}
+}
diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/lib/ConfigTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/lib/ConfigTest.java
index a85a4f4..8f9d105 100644
--- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/lib/ConfigTest.java
+++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/lib/ConfigTest.java
@@ -1581,6 +1581,20 @@ public void testCommitTemplateWithInvalidPath()
 		config.get(CommitConfig.KEY).getCommitTemplateContent(repo);
 	}
 
+	@Test
+	public void testCoreCommitGraphConfig() {
+		Config config = new Config();
+		assertFalse(config.get(CoreConfig.KEY).enableCommitGraph());
+
+		config.setBoolean(ConfigConstants.CONFIG_CORE_SECTION, null,
+				ConfigConstants.CONFIG_COMMIT_GRAPH, true);
+		assertTrue(config.get(CoreConfig.KEY).enableCommitGraph());
+
+		config.setBoolean(ConfigConstants.CONFIG_CORE_SECTION, null,
+				ConfigConstants.CONFIG_COMMIT_GRAPH, false);
+		assertFalse(config.get(CoreConfig.KEY).enableCommitGraph());
+	}
+
 	private static void assertValueRoundTrip(String value)
 			throws ConfigInvalidException {
 		assertValueRoundTrip(value, value);
diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/patch/PatchApplierTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/patch/PatchApplierTest.java
index aeb3e61..bcde022 100644
--- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/patch/PatchApplierTest.java
+++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/patch/PatchApplierTest.java
@@ -73,7 +73,8 @@ public abstract static class Base extends RepositoryTestCase {
 
 		protected void init(String aName, boolean preExists, boolean postExists)
 				throws Exception {
-			/* Patch and pre/postimage are read from data org.eclipse.jgit.test/tst-rsrc/org/eclipse/jgit/diff/ */
+			// Patch and pre/postimage are read from data
+			// org.eclipse.jgit.test/tst-rsrc/org/eclipse/jgit/diff/
 			this.name = aName;
 			if (postExists) {
 				postImage = IO
@@ -121,14 +122,16 @@ void verifyChange(Result result, String aName) throws Exception {
 			verifyChange(result, aName, true);
 		}
 
-		protected void verifyContent(Result result, String path, boolean exists) throws Exception {
+		protected void verifyContent(Result result, String path, boolean exists)
+				throws Exception {
 			if (inCore) {
 				byte[] output = readBlob(result.getTreeId(), path);
 				if (!exists)
 					assertNull(output);
 				else {
 					assertNotNull(output);
-					assertEquals(new String(output, StandardCharsets.UTF_8), expectedText);
+					assertEquals(expectedText,
+							new String(output, StandardCharsets.UTF_8));
 				}
 			} else {
 				File f = new File(db.getWorkTree(), path);
@@ -139,12 +142,14 @@ protected void verifyContent(Result result, String path, boolean exists) throws
 			}
 		}
 
-		void verifyChange(Result result, String aName, boolean exists) throws Exception {
+		void verifyChange(Result result, String aName, boolean exists)
+				throws Exception {
 			assertEquals(1, result.getPaths().size());
 			verifyContent(result, aName, exists);
 		}
 
-		protected byte[] readBlob(ObjectId treeish, String path) throws Exception {
+		protected byte[] readBlob(ObjectId treeish, String path)
+				throws Exception {
 			try (TestRepository<?> tr = new TestRepository<>(db);
 					RevWalk rw = tr.getRevWalk()) {
 				db.incrementOpen();
@@ -153,15 +158,18 @@ void verifyChange(Result result, String aName, boolean exists) throws Exception
 					if (tw == null) {
 						return null;
 					}
-					return tw.getObjectReader().open(tw.getObjectId(0), OBJ_BLOB).getBytes();
+					return tw.getObjectReader()
+							.open(tw.getObjectId(0), OBJ_BLOB).getBytes();
 				}
 			}
 		}
 
-		protected void checkBinary(Result result, int numberOfFiles) throws Exception {
+		protected void checkBinary(Result result, int numberOfFiles)
+				throws Exception {
 			assertEquals(numberOfFiles, result.getPaths().size());
 			if (inCore) {
-				assertArrayEquals(postImage, readBlob(result.getTreeId(), result.getPaths().get(0)));
+				assertArrayEquals(postImage,
+						readBlob(result.getTreeId(), result.getPaths().get(0)));
 			} else {
 				File f = new File(db.getWorkTree(), name);
 				assertArrayEquals(postImage, Files.readAllBytes(f.toPath()));
@@ -346,6 +354,7 @@ public void testShiftDown2() throws Exception {
 			Result result = applyPatch();
 			verifyChange(result, "ShiftDown2");
 		}
+
 	}
 
 	public static class InCore extends Base {
@@ -353,10 +362,44 @@ public static class InCore extends Base {
 		public InCore() {
 			super(true);
 		}
+
+		@Test
+		public void testNoNewlineAtEnd() throws Exception {
+			init("x_d");
+
+			Result result = applyPatch();
+			verifyChange(result, "x_d");
+		}
+
+		@Test
+		public void testNoNewlineAtEndInHunk() throws Exception {
+			init("x_e");
+
+			Result result = applyPatch();
+			verifyChange(result, "x_e");
+		}
+
+		@Test
+		public void testAddNewlineAtEnd() throws Exception {
+			init("x_add_nl");
+
+			Result result = applyPatch();
+			verifyChange(result, "x_add_nl");
+		}
+
+		@Test
+		public void testRemoveNewlineAtEnd() throws Exception {
+			init("x_last_rm_nl");
+
+			Result result = applyPatch();
+			verifyChange(result, "x_last_rm_nl");
+		}
 	}
 
 	public static class WithWorktree extends Base {
-		public WithWorktree() { super(false); }
+		public WithWorktree() {
+			super(false);
+		}
 
 		@Test
 		public void testModifyNL1() throws Exception {
@@ -369,8 +412,8 @@ public void testModifyNL1() throws Exception {
 		@Test
 		public void testCrLf() throws Exception {
 			try {
-				db.getConfig().setBoolean(ConfigConstants.CONFIG_CORE_SECTION, null,
-						ConfigConstants.CONFIG_KEY_AUTOCRLF, true);
+				db.getConfig().setBoolean(ConfigConstants.CONFIG_CORE_SECTION,
+						null, ConfigConstants.CONFIG_KEY_AUTOCRLF, true);
 				init("crlf", true, true);
 
 				Result result = applyPatch();
@@ -385,8 +428,8 @@ public void testCrLf() throws Exception {
 		@Test
 		public void testCrLfOff() throws Exception {
 			try {
-				db.getConfig().setBoolean(ConfigConstants.CONFIG_CORE_SECTION, null,
-						ConfigConstants.CONFIG_KEY_AUTOCRLF, false);
+				db.getConfig().setBoolean(ConfigConstants.CONFIG_CORE_SECTION,
+						null, ConfigConstants.CONFIG_KEY_AUTOCRLF, false);
 				init("crlf", true, true);
 
 				Result result = applyPatch();
@@ -401,8 +444,8 @@ public void testCrLfOff() throws Exception {
 		@Test
 		public void testCrLfEmptyCommitted() throws Exception {
 			try {
-				db.getConfig().setBoolean(ConfigConstants.CONFIG_CORE_SECTION, null,
-						ConfigConstants.CONFIG_KEY_AUTOCRLF, true);
+				db.getConfig().setBoolean(ConfigConstants.CONFIG_CORE_SECTION,
+						null, ConfigConstants.CONFIG_KEY_AUTOCRLF, true);
 				init("crlf3", true, true);
 
 				Result result = applyPatch();
@@ -417,8 +460,8 @@ public void testCrLfEmptyCommitted() throws Exception {
 		@Test
 		public void testCrLfNewFile() throws Exception {
 			try {
-				db.getConfig().setBoolean(ConfigConstants.CONFIG_CORE_SECTION, null,
-						ConfigConstants.CONFIG_KEY_AUTOCRLF, true);
+				db.getConfig().setBoolean(ConfigConstants.CONFIG_CORE_SECTION,
+						null, ConfigConstants.CONFIG_KEY_AUTOCRLF, true);
 				init("crlf4", false, true);
 
 				Result result = applyPatch();
@@ -433,8 +476,8 @@ public void testCrLfNewFile() throws Exception {
 		@Test
 		public void testPatchWithCrLf() throws Exception {
 			try {
-				db.getConfig().setBoolean(ConfigConstants.CONFIG_CORE_SECTION, null,
-						ConfigConstants.CONFIG_KEY_AUTOCRLF, false);
+				db.getConfig().setBoolean(ConfigConstants.CONFIG_CORE_SECTION,
+						null, ConfigConstants.CONFIG_KEY_AUTOCRLF, false);
 				init("crlf2", true, true);
 
 				Result result = applyPatch();
@@ -450,11 +493,11 @@ public void testPatchWithCrLf() throws Exception {
 		public void testPatchWithCrLf2() throws Exception {
 			String aName = "crlf2";
 			try (Git git = new Git(db)) {
-				db.getConfig().setBoolean(ConfigConstants.CONFIG_CORE_SECTION, null,
-						ConfigConstants.CONFIG_KEY_AUTOCRLF, false);
+				db.getConfig().setBoolean(ConfigConstants.CONFIG_CORE_SECTION,
+						null, ConfigConstants.CONFIG_KEY_AUTOCRLF, false);
 				init(aName, true, true);
-				db.getConfig().setBoolean(ConfigConstants.CONFIG_CORE_SECTION, null,
-						ConfigConstants.CONFIG_KEY_AUTOCRLF, true);
+				db.getConfig().setBoolean(ConfigConstants.CONFIG_CORE_SECTION,
+						null, ConfigConstants.CONFIG_KEY_AUTOCRLF, true);
 
 				Result result = applyPatch();
 
@@ -465,10 +508,234 @@ public void testPatchWithCrLf2() throws Exception {
 			}
 		}
 
-		// 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.
+		@Test
+		public void testNoNewlineAtEndAutoCRLF_true() throws Exception {
+			try {
+				db.getConfig().setBoolean(ConfigConstants.CONFIG_CORE_SECTION,
+						null, ConfigConstants.CONFIG_KEY_AUTOCRLF, true);
+
+				init("x_d_crlf", true, true);
+
+				Result result = applyPatch();
+				verifyChange(result, "x_d_crlf");
+			} finally {
+				db.getConfig().unset(ConfigConstants.CONFIG_CORE_SECTION, null,
+						ConfigConstants.CONFIG_KEY_AUTOCRLF);
+			}
+		}
+
+		@Test
+		public void testNoNewlineAtEndAutoCRLF_false() throws Exception {
+			try {
+				db.getConfig().setBoolean(ConfigConstants.CONFIG_CORE_SECTION,
+						null, ConfigConstants.CONFIG_KEY_AUTOCRLF, false);
+
+				init("x_d", true, true);
+
+				Result result = applyPatch();
+				verifyChange(result, "x_d");
+			} finally {
+				db.getConfig().unset(ConfigConstants.CONFIG_CORE_SECTION, null,
+						ConfigConstants.CONFIG_KEY_AUTOCRLF);
+			}
+		}
+
+		@Test
+		public void testNoNewlineAtEndAutoCRLF_input() throws Exception {
+			try {
+				db.getConfig().setString(ConfigConstants.CONFIG_CORE_SECTION,
+						null, ConfigConstants.CONFIG_KEY_AUTOCRLF, "input");
+
+				init("x_d", true, true);
+
+				Result result = applyPatch();
+				verifyChange(result, "x_d");
+			} finally {
+				db.getConfig().unset(ConfigConstants.CONFIG_CORE_SECTION, null,
+						ConfigConstants.CONFIG_KEY_AUTOCRLF);
+			}
+		}
+
+		@Test
+		public void testNoNewlineAtEndInHunkAutoCRLF_true() throws Exception {
+			try {
+				db.getConfig().setBoolean(ConfigConstants.CONFIG_CORE_SECTION,
+						null, ConfigConstants.CONFIG_KEY_AUTOCRLF, true);
+
+				init("x_e_crlf", true, true);
+
+				Result result = applyPatch();
+				verifyChange(result, "x_e_crlf");
+			} finally {
+				db.getConfig().unset(ConfigConstants.CONFIG_CORE_SECTION, null,
+						ConfigConstants.CONFIG_KEY_AUTOCRLF);
+			}
+		}
+
+		@Test
+		public void testNoNewlineAtEndInHunkAutoCRLF_false() throws Exception {
+			try {
+				db.getConfig().setBoolean(ConfigConstants.CONFIG_CORE_SECTION,
+						null, ConfigConstants.CONFIG_KEY_AUTOCRLF, false);
+
+				init("x_e", true, true);
+
+				Result result = applyPatch();
+				verifyChange(result, "x_e");
+			} finally {
+				db.getConfig().unset(ConfigConstants.CONFIG_CORE_SECTION, null,
+						ConfigConstants.CONFIG_KEY_AUTOCRLF);
+			}
+		}
+
+		@Test
+		public void testNoNewlineAtEndInHunkAutoCRLF_input() throws Exception {
+			try {
+				db.getConfig().setString(ConfigConstants.CONFIG_CORE_SECTION,
+						null, ConfigConstants.CONFIG_KEY_AUTOCRLF, "input");
+
+				init("x_e", true, true);
+
+				Result result = applyPatch();
+				verifyChange(result, "x_e");
+			} finally {
+				db.getConfig().unset(ConfigConstants.CONFIG_CORE_SECTION, null,
+						ConfigConstants.CONFIG_KEY_AUTOCRLF);
+			}
+		}
+
+		@Test
+		public void testAddNewlineAtEndAutoCRLF_true() throws Exception {
+			try {
+				db.getConfig().setBoolean(ConfigConstants.CONFIG_CORE_SECTION,
+						null, ConfigConstants.CONFIG_KEY_AUTOCRLF, true);
+
+				init("x_add_nl_crlf", true, true);
+
+				Result result = applyPatch();
+				verifyChange(result, "x_add_nl_crlf");
+			} finally {
+				db.getConfig().unset(ConfigConstants.CONFIG_CORE_SECTION, null,
+						ConfigConstants.CONFIG_KEY_AUTOCRLF);
+			}
+		}
+
+		@Test
+		public void testAddNewlineAtEndAutoCRLF_false() throws Exception {
+			try {
+				db.getConfig().setBoolean(ConfigConstants.CONFIG_CORE_SECTION,
+						null, ConfigConstants.CONFIG_KEY_AUTOCRLF, false);
+
+				init("x_add_nl", true, true);
+
+				Result result = applyPatch();
+				verifyChange(result, "x_add_nl");
+			} finally {
+				db.getConfig().unset(ConfigConstants.CONFIG_CORE_SECTION, null,
+						ConfigConstants.CONFIG_KEY_AUTOCRLF);
+			}
+		}
+
+		@Test
+		public void testAddNewlineAtEndAutoCRLF_input() throws Exception {
+			try {
+				db.getConfig().setString(ConfigConstants.CONFIG_CORE_SECTION,
+						null, ConfigConstants.CONFIG_KEY_AUTOCRLF, "input");
+
+				init("x_add_nl", true, true);
+
+				Result result = applyPatch();
+				verifyChange(result, "x_add_nl");
+			} finally {
+				db.getConfig().unset(ConfigConstants.CONFIG_CORE_SECTION, null,
+						ConfigConstants.CONFIG_KEY_AUTOCRLF);
+			}
+		}
+
+		@Test
+		public void testRemoveNewlineAtEndAutoCRLF_true() throws Exception {
+			try {
+				db.getConfig().setBoolean(ConfigConstants.CONFIG_CORE_SECTION,
+						null, ConfigConstants.CONFIG_KEY_AUTOCRLF, true);
+
+				init("x_last_rm_nl_crlf", true, true);
+
+				Result result = applyPatch();
+				verifyChange(result, "x_last_rm_nl_crlf");
+			} finally {
+				db.getConfig().unset(ConfigConstants.CONFIG_CORE_SECTION, null,
+						ConfigConstants.CONFIG_KEY_AUTOCRLF);
+			}
+		}
+
+		@Test
+		public void testRemoveNewlineAtEndAutoCRLF_false() throws Exception {
+			try {
+				db.getConfig().setBoolean(ConfigConstants.CONFIG_CORE_SECTION,
+						null, ConfigConstants.CONFIG_KEY_AUTOCRLF, false);
+
+				init("x_last_rm_nl", true, true);
+
+				Result result = applyPatch();
+				verifyChange(result, "x_last_rm_nl");
+			} finally {
+				db.getConfig().unset(ConfigConstants.CONFIG_CORE_SECTION, null,
+						ConfigConstants.CONFIG_KEY_AUTOCRLF);
+			}
+		}
+
+		@Test
+		public void testRemoveNewlineAtEndAutoCRLF_input() throws Exception {
+			try {
+				db.getConfig().setString(ConfigConstants.CONFIG_CORE_SECTION,
+						null, ConfigConstants.CONFIG_KEY_AUTOCRLF, "input");
+
+				init("x_last_rm_nl", true, true);
+
+				Result result = applyPatch();
+				verifyChange(result, "x_last_rm_nl");
+			} finally {
+				db.getConfig().unset(ConfigConstants.CONFIG_CORE_SECTION, null,
+						ConfigConstants.CONFIG_KEY_AUTOCRLF);
+			}
+		}
+
+		@Test
+		public void testEditExample() throws Exception {
+			init("z_e", true, true);
+
+			Result result = applyPatch();
+			verifyChange(result, "z_e");
+		}
+
+		@Test
+		public void testEditNoNewline() throws Exception {
+			init("z_e_no_nl", true, true);
+
+			Result result = applyPatch();
+			verifyChange(result, "z_e_no_nl");
+		}
+
+		@Test
+		public void testEditAddNewline() throws Exception {
+			init("z_e_add_nl", true, true);
+
+			Result result = applyPatch();
+			verifyChange(result, "z_e_add_nl");
+		}
+
+		@Test
+		public void testEditRemoveNewline() throws Exception {
+			init("z_e_rm_nl", true, true);
+
+			Result result = applyPatch();
+			verifyChange(result, "z_e_rm_nl");
+		}
+
+		// 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;
@@ -501,8 +768,10 @@ public int run() throws IOException {
 		@Test
 		public void testFiltering() throws Exception {
 			// Set up filter
-			FilterCommandFactory clean = (repo, in, out) -> new ReplaceFilter(in, out, 'A', 'E');
-			FilterCommandFactory smudge = (repo, in, out) -> new ReplaceFilter(in, out, 'E', 'A');
+			FilterCommandFactory clean =
+					(repo, in, out) -> new ReplaceFilter(in, out, 'A', 'E');
+			FilterCommandFactory smudge =
+					(repo, in, out) -> new ReplaceFilter(in, out, 'E', 'A');
 			FilterCommandRegistry.register("jgit://builtin/a2e/clean", clean);
 			FilterCommandRegistry.register("jgit://builtin/a2e/smudge", smudge);
 			Config config = db.getConfig();
diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/revwalk/RevWalkCommitGraphTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/revwalk/RevWalkCommitGraphTest.java
new file mode 100644
index 0000000..05e023b
--- /dev/null
+++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/revwalk/RevWalkCommitGraphTest.java
@@ -0,0 +1,319 @@
+/*
+ * Copyright (C) 2023, Tencent.
+ *
+ * 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.revwalk;
+
+import static org.eclipse.jgit.internal.storage.commitgraph.CommitGraph.EMPTY;
+import static org.junit.Assert.assertArrayEquals;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertTrue;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
+import org.eclipse.jgit.api.Git;
+import org.eclipse.jgit.internal.storage.file.GC;
+import org.eclipse.jgit.lib.ConfigConstants;
+import org.eclipse.jgit.lib.Constants;
+import org.eclipse.jgit.lib.Ref;
+import org.eclipse.jgit.revwalk.filter.MessageRevFilter;
+import org.eclipse.jgit.revwalk.filter.RevFilter;
+import org.eclipse.jgit.treewalk.filter.AndTreeFilter;
+import org.eclipse.jgit.treewalk.filter.PathFilter;
+import org.eclipse.jgit.treewalk.filter.TreeFilter;
+import org.junit.Test;
+
+public class RevWalkCommitGraphTest extends RevWalkTestCase {
+
+	private RevWalk rw;
+
+	@Override
+	public void setUp() throws Exception {
+		super.setUp();
+		rw = new RevWalk(db);
+	}
+
+	@Test
+	public void testParseHeaders() throws Exception {
+		RevCommit c1 = commitFile("file1", "1", "master");
+
+		RevCommit notParseInGraph = rw.lookupCommit(c1);
+		rw.parseHeaders(notParseInGraph);
+		assertFalse(notParseInGraph instanceof RevCommitCG);
+		assertNotNull(notParseInGraph.getRawBuffer());
+		assertEquals(Constants.COMMIT_GENERATION_UNKNOWN,
+				notParseInGraph.getGeneration());
+
+		enableAndWriteCommitGraph();
+
+		reinitializeRevWalk();
+		RevCommit parseInGraph = rw.lookupCommit(c1);
+		parseInGraph.parseHeaders(rw);
+
+		assertTrue(parseInGraph instanceof RevCommitCG);
+		assertNotNull(parseInGraph.getRawBuffer());
+		assertEquals(1, parseInGraph.getGeneration());
+		assertEquals(notParseInGraph.getId(), parseInGraph.getId());
+		assertEquals(notParseInGraph.getTree(), parseInGraph.getTree());
+		assertEquals(notParseInGraph.getCommitTime(), parseInGraph.getCommitTime());
+		assertArrayEquals(notParseInGraph.getParents(), parseInGraph.getParents());
+
+		reinitializeRevWalk();
+		rw.setRetainBody(false);
+		RevCommit noBody = rw.lookupCommit(c1);
+		noBody.parseHeaders(rw);
+
+		assertTrue(noBody instanceof RevCommitCG);
+		assertNull(noBody.getRawBuffer());
+		assertEquals(1, noBody.getGeneration());
+		assertEquals(notParseInGraph.getId(), noBody.getId());
+		assertEquals(notParseInGraph.getTree(), noBody.getTree());
+		assertEquals(notParseInGraph.getCommitTime(), noBody.getCommitTime());
+		assertArrayEquals(notParseInGraph.getParents(), noBody.getParents());
+	}
+
+	@Test
+	public void testInitializeShallowCommits() throws Exception {
+		RevCommit c1 = commit(commit());
+		branch(c1, "master");
+		enableAndWriteCommitGraph();
+		assertCommitCntInGraph(2);
+
+		db.getObjectDatabase().setShallowCommits(Collections.singleton(c1));
+		RevCommit parseInGraph = rw.lookupCommit(c1);
+		parseInGraph.parseHeaders(rw);
+
+		assertTrue(parseInGraph instanceof RevCommitCG);
+		assertNotNull(parseInGraph.getRawBuffer());
+		assertEquals(2, parseInGraph.getGeneration());
+		assertEquals(0, parseInGraph.getParentCount());
+	}
+
+	@Test
+	public void testTreeFilter() throws Exception {
+		RevCommit c1 = commitFile("file1", "1", "master");
+		RevCommit c2 = commitFile("file2", "2", "master");
+		RevCommit c3 = commitFile("file1", "3", "master");
+		RevCommit c4 = commitFile("file2", "4", "master");
+
+		enableAndWriteCommitGraph();
+		assertCommitCntInGraph(4);
+
+		rw.markStart(rw.lookupCommit(c4));
+		rw.setTreeFilter(AndTreeFilter.create(PathFilter.create("file1"),
+				TreeFilter.ANY_DIFF));
+		assertEquals(c3, rw.next());
+		assertEquals(c1, rw.next());
+		assertNull(rw.next());
+
+		reinitializeRevWalk();
+		rw.markStart(rw.lookupCommit(c4));
+		rw.setTreeFilter(AndTreeFilter.create(PathFilter.create("file2"),
+				TreeFilter.ANY_DIFF));
+		assertEquals(c4, rw.next());
+		assertEquals(c2, rw.next());
+		assertNull(rw.next());
+	}
+
+	@Test
+	public void testWalkWithCommitMessageFilter() throws Exception {
+		RevCommit a = commit();
+		RevCommit b = commitBuilder().parent(a)
+				.message("The quick brown fox jumps over the lazy dog!")
+				.create();
+		RevCommit c = commitBuilder().parent(b).message("commit-c").create();
+		branch(c, "master");
+
+		enableAndWriteCommitGraph();
+		assertCommitCntInGraph(3);
+
+		rw.setRevFilter(MessageRevFilter.create("quick brown fox jumps"));
+		rw.markStart(rw.lookupCommit(c));
+		assertEquals(b, rw.next());
+		assertNull(rw.next());
+	}
+
+	@Test
+	public void testCommitsWalk() throws Exception {
+		RevCommit c1 = commit();
+		branch(c1, "commits/1");
+		RevCommit c2 = commit(c1);
+		branch(c2, "commits/2");
+		RevCommit c3 = commit(c2);
+		branch(c3, "commits/3");
+
+		enableAndWriteCommitGraph();
+		assertCommitCntInGraph(3);
+		testRevWalkBehavior("commits/1", "commits/3");
+
+		// add more commits
+		RevCommit c4 = commit(c1);
+		RevCommit c5 = commit(c4);
+		RevCommit c6 = commit(c1);
+		RevCommit c7 = commit(c6);
+
+		RevCommit m1 = commit(c2, c4);
+		branch(m1, "merge/1");
+		RevCommit m2 = commit(c4, c6);
+		branch(m2, "merge/2");
+		RevCommit m3 = commit(c3, c5, c7);
+		branch(m3, "merge/3");
+
+		/*
+		 * <pre>
+		 * current graph structure:
+		 *
+		 *    __M3___
+		 *   /   |   \
+		 *  3 M1 5 M2 7
+		 *  |/  \|/  \|
+		 *  2    4    6
+		 *  |___/____/
+		 *  1
+		 * </pre>
+		 */
+		enableAndWriteCommitGraph();
+		reinitializeRevWalk();
+		assertCommitCntInGraph(10);
+		testRevWalkBehavior("merge/1", "merge/2");
+		testRevWalkBehavior("merge/1", "merge/3");
+		testRevWalkBehavior("merge/2", "merge/3");
+
+		// add one more commit
+		RevCommit c8 = commit(m3);
+		branch(c8, "commits/8");
+
+		/*
+		 * <pre>
+		 * current graph structure:
+		 *       8
+		 *       |
+		 *    __M3___
+		 *   /   |   \
+		 *  3 M1 5 M2 7
+		 *  |/  \|/  \|
+		 *  2    4    6
+		 *  |___/____/
+		 *  1
+		 * </pre>
+		 */
+		testRevWalkBehavior("commits/8", "merge/1");
+		testRevWalkBehavior("commits/8", "merge/2");
+
+		enableAndWriteCommitGraph();
+		reinitializeRevWalk();
+		assertCommitCntInGraph(11);
+		testRevWalkBehavior("commits/8", "merge/1");
+		testRevWalkBehavior("commits/8", "merge/2");
+	}
+
+	void testRevWalkBehavior(String branch, String compare) throws Exception {
+		assertCommits(
+				travel(TreeFilter.ALL, RevFilter.MERGE_BASE, RevSort.NONE, true,
+						branch, compare),
+				travel(TreeFilter.ALL, RevFilter.MERGE_BASE, RevSort.NONE,
+						false, branch, compare));
+
+		assertCommits(
+				travel(TreeFilter.ALL, RevFilter.ALL, RevSort.TOPO, true,
+						branch),
+				travel(TreeFilter.ALL, RevFilter.ALL, RevSort.TOPO, false,
+						branch));
+
+		assertCommits(
+				travel(TreeFilter.ALL, RevFilter.ALL, RevSort.TOPO, true,
+						compare),
+				travel(TreeFilter.ALL, RevFilter.ALL, RevSort.TOPO, false,
+						compare));
+
+		assertCommits(
+				travel(TreeFilter.ALL, RevFilter.ALL, RevSort.COMMIT_TIME_DESC,
+						true, branch),
+				travel(TreeFilter.ALL, RevFilter.ALL, RevSort.COMMIT_TIME_DESC,
+						false, branch));
+
+		assertCommits(
+				travel(TreeFilter.ALL, RevFilter.ALL, RevSort.COMMIT_TIME_DESC,
+						true, compare),
+				travel(TreeFilter.ALL, RevFilter.ALL, RevSort.COMMIT_TIME_DESC,
+						false, compare));
+	}
+
+	void assertCommitCntInGraph(int expect) {
+		assertEquals(expect, rw.commitGraph().getCommitCnt());
+	}
+
+	void assertCommits(List<RevCommit> expect, List<RevCommit> actual) {
+		assertEquals(expect.size(), actual.size());
+
+		for (int i = 0; i < expect.size(); i++) {
+			RevCommit c1 = expect.get(i);
+			RevCommit c2 = actual.get(i);
+
+			assertEquals(c1.getId(), c2.getId());
+			assertEquals(c1.getTree(), c2.getTree());
+			assertEquals(c1.getCommitTime(), c2.getCommitTime());
+			assertArrayEquals(c1.getParents(), c2.getParents());
+			assertArrayEquals(c1.getRawBuffer(), c2.getRawBuffer());
+		}
+	}
+
+	Ref branch(RevCommit commit, String name) throws Exception {
+		return Git.wrap(db).branchCreate().setName(name)
+				.setStartPoint(commit.name()).call();
+	}
+
+	List<RevCommit> travel(TreeFilter treeFilter, RevFilter revFilter,
+			RevSort revSort, boolean enableCommitGraph, String... starts)
+			throws Exception {
+		db.getConfig().setBoolean(ConfigConstants.CONFIG_CORE_SECTION, null,
+				ConfigConstants.CONFIG_COMMIT_GRAPH, enableCommitGraph);
+
+		try (RevWalk walk = new RevWalk(db)) {
+			walk.setTreeFilter(treeFilter);
+			walk.setRevFilter(revFilter);
+			walk.sort(revSort);
+			walk.setRetainBody(false);
+			for (String start : starts) {
+				walk.markStart(walk.lookupCommit(db.resolve(start)));
+			}
+			List<RevCommit> commits = new ArrayList<>();
+
+			if (enableCommitGraph) {
+				assertTrue(walk.commitGraph().getCommitCnt() > 0);
+			} else {
+				assertEquals(EMPTY, walk.commitGraph());
+			}
+
+			for (RevCommit commit : walk) {
+				commits.add(commit);
+			}
+			return commits;
+		}
+	}
+
+	void enableAndWriteCommitGraph() throws Exception {
+		db.getConfig().setBoolean(ConfigConstants.CONFIG_CORE_SECTION, null,
+				ConfigConstants.CONFIG_COMMIT_GRAPH, true);
+		db.getConfig().setBoolean(ConfigConstants.CONFIG_GC_SECTION, null,
+				ConfigConstants.CONFIG_KEY_WRITE_COMMIT_GRAPH, true);
+		GC gc = new GC(db);
+		gc.gc();
+	}
+
+	private void reinitializeRevWalk() {
+		rw.close();
+		rw = new RevWalk(db);
+	}
+}
diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/util/io/TimeoutInputStreamTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/util/io/TimeoutInputStreamTest.java
index 6484169..76bda6a 100644
--- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/util/io/TimeoutInputStreamTest.java
+++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/util/io/TimeoutInputStreamTest.java
@@ -91,7 +91,7 @@ public void testTimeout_readBuffer_Success1() throws IOException {
 		final byte[] exp = new byte[] { 'a', 'b', 'c' };
 		final byte[] act = new byte[exp.length];
 		out.write(exp);
-		IO.readFully(is, act, 0, act.length);
+		IO.readFully(is, act);
 		assertArrayEquals(exp, act);
 	}
 
@@ -110,7 +110,7 @@ public void testTimeout_readBuffer_Success2() throws IOException {
 	public void testTimeout_readBuffer_Timeout() throws IOException {
 		beginRead();
 		try {
-			IO.readFully(is, new byte[512], 0, 512);
+			IO.readFully(is, new byte[512]);
 			fail("incorrectly read bytes");
 		} catch (InterruptedIOException e) {
 			// expected
diff --git a/org.eclipse.jgit.ui/META-INF/MANIFEST.MF b/org.eclipse.jgit.ui/META-INF/MANIFEST.MF
index 0d3324d..3916cd2 100644
--- a/org.eclipse.jgit.ui/META-INF/MANIFEST.MF
+++ b/org.eclipse.jgit.ui/META-INF/MANIFEST.MF
@@ -4,14 +4,14 @@
 Bundle-Name: %Bundle-Name
 Automatic-Module-Name: org.eclipse.jgit.ui
 Bundle-SymbolicName: org.eclipse.jgit.ui
-Bundle-Version: 6.4.1.qualifier
+Bundle-Version: 6.5.0.qualifier
 Bundle-Vendor: %Bundle-Vendor
 Bundle-RequiredExecutionEnvironment: JavaSE-11
-Export-Package: org.eclipse.jgit.awtui;version="6.4.1"
-Import-Package: org.eclipse.jgit.errors;version="[6.4.1,6.5.0)",
- org.eclipse.jgit.lib;version="[6.4.1,6.5.0)",
- org.eclipse.jgit.nls;version="[6.4.1,6.5.0)",
- org.eclipse.jgit.revplot;version="[6.4.1,6.5.0)",
- org.eclipse.jgit.revwalk;version="[6.4.1,6.5.0)",
- org.eclipse.jgit.transport;version="[6.4.1,6.5.0)",
- org.eclipse.jgit.util;version="[6.4.1,6.5.0)"
+Export-Package: org.eclipse.jgit.awtui;version="6.5.0"
+Import-Package: org.eclipse.jgit.errors;version="[6.5.0,6.6.0)",
+ org.eclipse.jgit.lib;version="[6.5.0,6.6.0)",
+ org.eclipse.jgit.nls;version="[6.5.0,6.6.0)",
+ org.eclipse.jgit.revplot;version="[6.5.0,6.6.0)",
+ org.eclipse.jgit.revwalk;version="[6.5.0,6.6.0)",
+ org.eclipse.jgit.transport;version="[6.5.0,6.6.0)",
+ org.eclipse.jgit.util;version="[6.5.0,6.6.0)"
diff --git a/org.eclipse.jgit.ui/META-INF/SOURCE-MANIFEST.MF b/org.eclipse.jgit.ui/META-INF/SOURCE-MANIFEST.MF
index 4700584..5bb9b0f 100644
--- a/org.eclipse.jgit.ui/META-INF/SOURCE-MANIFEST.MF
+++ b/org.eclipse.jgit.ui/META-INF/SOURCE-MANIFEST.MF
@@ -3,5 +3,5 @@
 Bundle-Name: org.eclipse.jgit.ui - Sources
 Bundle-SymbolicName: org.eclipse.jgit.ui.source
 Bundle-Vendor: Eclipse.org - JGit
-Bundle-Version: 6.4.1.qualifier
-Eclipse-SourceBundle: org.eclipse.jgit.ui;version="6.4.1.qualifier";roots="."
+Bundle-Version: 6.5.0.qualifier
+Eclipse-SourceBundle: org.eclipse.jgit.ui;version="6.5.0.qualifier";roots="."
diff --git a/org.eclipse.jgit.ui/pom.xml b/org.eclipse.jgit.ui/pom.xml
index a46fdbc..b7afe39 100644
--- a/org.eclipse.jgit.ui/pom.xml
+++ b/org.eclipse.jgit.ui/pom.xml
@@ -19,7 +19,7 @@
   <parent>
     <groupId>org.eclipse.jgit</groupId>
     <artifactId>org.eclipse.jgit-parent</artifactId>
-    <version>6.4.1-SNAPSHOT</version>
+    <version>6.5.0-SNAPSHOT</version>
   </parent>
 
   <artifactId>org.eclipse.jgit.ui</artifactId>
diff --git a/org.eclipse.jgit/.settings/.api_filters b/org.eclipse.jgit/.settings/.api_filters
new file mode 100644
index 0000000..107b7d5
--- /dev/null
+++ b/org.eclipse.jgit/.settings/.api_filters
@@ -0,0 +1,75 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<component id="org.eclipse.jgit" version="2">
+    <resource path="src/org/eclipse/jgit/lib/ConfigConstants.java" type="org.eclipse.jgit.lib.ConfigConstants">
+        <filter id="1142947843">
+            <message_arguments>
+                <message_argument value="5.13.2"/>
+                <message_argument value="CONFIG_KEY_BITMAP_EXCLUDED_REFS_PREFIXES"/>
+            </message_arguments>
+        </filter>
+        <filter id="1142947843">
+            <message_arguments>
+                <message_argument value="6.1.1"/>
+                <message_argument value="CONFIG_KEY_TRUST_PACKED_REFS_STAT"/>
+            </message_arguments>
+        </filter>
+    </resource>
+    <resource path="src/org/eclipse/jgit/lib/CoreConfig.java" type="org.eclipse.jgit.lib.CoreConfig">
+        <filter id="336658481">
+            <message_arguments>
+                <message_argument value="org.eclipse.jgit.lib.CoreConfig"/>
+                <message_argument value="DEFAULT_COMMIT_GRAPH_ENABLE"/>
+            </message_arguments>
+        </filter>
+    </resource>
+    <resource path="src/org/eclipse/jgit/lib/CoreConfig.java" type="org.eclipse.jgit.lib.CoreConfig$TrustPackedRefsStat">
+        <filter id="1142947843">
+            <message_arguments>
+                <message_argument value="6.1.1"/>
+                <message_argument value="TrustPackedRefsStat"/>
+            </message_arguments>
+        </filter>
+    </resource>
+    <resource path="src/org/eclipse/jgit/lib/RefDatabase.java" type="org.eclipse.jgit.lib.RefDatabase">
+        <filter id="336658481">
+            <message_arguments>
+                <message_argument value="org.eclipse.jgit.lib.RefDatabase"/>
+                <message_argument value="additionalRefsNames"/>
+            </message_arguments>
+        </filter>
+    </resource>
+    <resource path="src/org/eclipse/jgit/lib/Repository.java" type="org.eclipse.jgit.lib.Repository">
+        <filter id="1142947843">
+            <message_arguments>
+                <message_argument value="5.13.2"/>
+                <message_argument value="getReflogReader(Ref)"/>
+            </message_arguments>
+        </filter>
+    </resource>
+    <resource path="src/org/eclipse/jgit/storage/pack/PackConfig.java" type="org.eclipse.jgit.storage.pack.PackConfig">
+        <filter id="336658481">
+            <message_arguments>
+                <message_argument value="org.eclipse.jgit.storage.pack.PackConfig"/>
+                <message_argument value="DEFAULT_BITMAP_EXCLUDED_REFS_PREFIXES"/>
+            </message_arguments>
+        </filter>
+        <filter id="1142947843">
+            <message_arguments>
+                <message_argument value="5.13.2"/>
+                <message_argument value="DEFAULT_BITMAP_EXCLUDED_REFS_PREFIXES"/>
+            </message_arguments>
+        </filter>
+        <filter id="1142947843">
+            <message_arguments>
+                <message_argument value="5.13.2"/>
+                <message_argument value="getBitmapExcludedRefsPrefixes()"/>
+            </message_arguments>
+        </filter>
+        <filter id="1142947843">
+            <message_arguments>
+                <message_argument value="5.13.2"/>
+                <message_argument value="setBitmapExcludedRefsPrefixes(String[])"/>
+            </message_arguments>
+        </filter>
+    </resource>
+</component>
diff --git a/org.eclipse.jgit/META-INF/MANIFEST.MF b/org.eclipse.jgit/META-INF/MANIFEST.MF
index 7f18cfb..1fad623 100644
--- a/org.eclipse.jgit/META-INF/MANIFEST.MF
+++ b/org.eclipse.jgit/META-INF/MANIFEST.MF
@@ -3,12 +3,12 @@
 Bundle-Name: %Bundle-Name
 Automatic-Module-Name: org.eclipse.jgit
 Bundle-SymbolicName: org.eclipse.jgit
-Bundle-Version: 6.4.1.qualifier
+Bundle-Version: 6.5.0.qualifier
 Bundle-Localization: plugin
 Bundle-Vendor: %Bundle-Vendor
 Eclipse-ExtensibleAPI: true
-Export-Package: org.eclipse.jgit.annotations;version="6.4.1",
- org.eclipse.jgit.api;version="6.4.1";
+Export-Package: org.eclipse.jgit.annotations;version="6.5.0",
+ org.eclipse.jgit.api;version="6.5.0";
   uses:="org.eclipse.jgit.transport,
    org.eclipse.jgit.notes,
    org.eclipse.jgit.dircache,
@@ -23,18 +23,18 @@
    org.eclipse.jgit.revwalk.filter,
    org.eclipse.jgit.blame,
    org.eclipse.jgit.merge",
- org.eclipse.jgit.api.errors;version="6.4.1";
+ org.eclipse.jgit.api.errors;version="6.5.0";
   uses:="org.eclipse.jgit.lib,
    org.eclipse.jgit.errors",
- org.eclipse.jgit.attributes;version="6.4.1";
+ org.eclipse.jgit.attributes;version="6.5.0";
   uses:="org.eclipse.jgit.lib,
    org.eclipse.jgit.treewalk",
- org.eclipse.jgit.blame;version="6.4.1";
+ org.eclipse.jgit.blame;version="6.5.0";
   uses:="org.eclipse.jgit.lib,
    org.eclipse.jgit.revwalk,
    org.eclipse.jgit.treewalk.filter,
    org.eclipse.jgit.diff",
- org.eclipse.jgit.diff;version="6.4.1";
+ org.eclipse.jgit.diff;version="6.5.0";
   uses:="org.eclipse.jgit.lib,
    org.eclipse.jgit.attributes,
    org.eclipse.jgit.revwalk,
@@ -42,51 +42,53 @@
    org.eclipse.jgit.treewalk.filter,
    org.eclipse.jgit.treewalk,
    org.eclipse.jgit.util",
- org.eclipse.jgit.dircache;version="6.4.1";
+ org.eclipse.jgit.dircache;version="6.5.0";
   uses:="org.eclipse.jgit.events,
    org.eclipse.jgit.lib,
    org.eclipse.jgit.attributes,
    org.eclipse.jgit.treewalk,
    org.eclipse.jgit.util",
- org.eclipse.jgit.errors;version="6.4.1";
+ org.eclipse.jgit.errors;version="6.5.0";
   uses:="org.eclipse.jgit.transport,
    org.eclipse.jgit.dircache,
    org.eclipse.jgit.lib,
    org.eclipse.jgit.internal.storage.pack",
- org.eclipse.jgit.events;version="6.4.1";
+ org.eclipse.jgit.events;version="6.5.0";
   uses:="org.eclipse.jgit.lib",
- org.eclipse.jgit.fnmatch;version="6.4.1",
- org.eclipse.jgit.gitrepo;version="6.4.1";
+ org.eclipse.jgit.fnmatch;version="6.5.0",
+ org.eclipse.jgit.gitrepo;version="6.5.0";
   uses:="org.xml.sax.helpers,
    org.eclipse.jgit.api,
    org.eclipse.jgit.lib,
    org.eclipse.jgit.revwalk,
    org.xml.sax",
- org.eclipse.jgit.gitrepo.internal;version="6.4.1";x-internal:=true,
- org.eclipse.jgit.hooks;version="6.4.1";uses:="org.eclipse.jgit.lib",
- org.eclipse.jgit.ignore;version="6.4.1",
- org.eclipse.jgit.ignore.internal;version="6.4.1";
+ org.eclipse.jgit.gitrepo.internal;version="6.5.0";x-internal:=true,
+ org.eclipse.jgit.hooks;version="6.5.0";uses:="org.eclipse.jgit.lib",
+ org.eclipse.jgit.ignore;version="6.5.0",
+ org.eclipse.jgit.ignore.internal;version="6.5.0";
   x-friends:="org.eclipse.jgit.test",
- org.eclipse.jgit.internal;version="6.4.1";
+ org.eclipse.jgit.internal;version="6.5.0";
   x-friends:="org.eclipse.jgit.test,
    org.eclipse.jgit.http.test",
- org.eclipse.jgit.internal.diff;version="6.4.1";
+ org.eclipse.jgit.internal.diff;version="6.5.0";
   x-friends:="org.eclipse.jgit.test",
- org.eclipse.jgit.internal.diffmergetool;version="6.4.1";
+ org.eclipse.jgit.internal.diffmergetool;version="6.5.0";
   x-friends:="org.eclipse.jgit.test,
    org.eclipse.jgit.pgm.test,
    org.eclipse.jgit.pgm,
    org.eclipse.egit.ui",
- org.eclipse.jgit.internal.fsck;version="6.4.1";
+ org.eclipse.jgit.internal.fsck;version="6.5.0";
   x-friends:="org.eclipse.jgit.test",
- org.eclipse.jgit.internal.revwalk;version="6.4.1";
+ org.eclipse.jgit.internal.revwalk;version="6.5.0";
   x-friends:="org.eclipse.jgit.test",
- org.eclipse.jgit.internal.storage.dfs;version="6.4.1";
+ org.eclipse.jgit.internal.storage.commitgraph;version="6.5.0";
+  x-friends:="org.eclipse.jgit.test",
+ org.eclipse.jgit.internal.storage.dfs;version="6.5.0";
   x-friends:="org.eclipse.jgit.test,
    org.eclipse.jgit.http.server,
    org.eclipse.jgit.http.test,
    org.eclipse.jgit.lfs.test",
- org.eclipse.jgit.internal.storage.file;version="6.4.1";
+ org.eclipse.jgit.internal.storage.file;version="6.5.0";
   x-friends:="org.eclipse.jgit.test,
    org.eclipse.jgit.junit,
    org.eclipse.jgit.junit.http,
@@ -95,32 +97,34 @@
    org.eclipse.jgit.pgm,
    org.eclipse.jgit.pgm.test,
    org.eclipse.jgit.ssh.apache",
- org.eclipse.jgit.internal.storage.io;version="6.4.1";
+ org.eclipse.jgit.internal.storage.io;version="6.5.0";
   x-friends:="org.eclipse.jgit.junit,
    org.eclipse.jgit.test,
    org.eclipse.jgit.pgm",
- org.eclipse.jgit.internal.storage.pack;version="6.4.1";
+ org.eclipse.jgit.internal.storage.memory;version="6.5.0";
+  x-friends:="org.eclipse.jgit.test",
+ org.eclipse.jgit.internal.storage.pack;version="6.5.0";
   x-friends:="org.eclipse.jgit.junit,
    org.eclipse.jgit.test,
    org.eclipse.jgit.pgm",
- org.eclipse.jgit.internal.storage.reftable;version="6.4.1";
+ org.eclipse.jgit.internal.storage.reftable;version="6.5.0";
   x-friends:="org.eclipse.jgit.http.test,
    org.eclipse.jgit.junit,
    org.eclipse.jgit.test,
    org.eclipse.jgit.pgm",
- org.eclipse.jgit.internal.submodule;version="6.4.1";x-internal:=true,
- org.eclipse.jgit.internal.transport.connectivity;version="6.4.1";
+ org.eclipse.jgit.internal.submodule;version="6.5.0";x-internal:=true,
+ org.eclipse.jgit.internal.transport.connectivity;version="6.5.0";
   x-friends:="org.eclipse.jgit.test",
- org.eclipse.jgit.internal.transport.http;version="6.4.1";
+ org.eclipse.jgit.internal.transport.http;version="6.5.0";
   x-friends:="org.eclipse.jgit.test",
- org.eclipse.jgit.internal.transport.parser;version="6.4.1";
+ org.eclipse.jgit.internal.transport.parser;version="6.5.0";
   x-friends:="org.eclipse.jgit.http.server,
    org.eclipse.jgit.test",
- org.eclipse.jgit.internal.transport.ssh;version="6.4.1";
+ org.eclipse.jgit.internal.transport.ssh;version="6.5.0";
   x-friends:="org.eclipse.jgit.ssh.apache,
    org.eclipse.jgit.ssh.jsch,
    org.eclipse.jgit.test",
- org.eclipse.jgit.lib;version="6.4.1";
+ org.eclipse.jgit.lib;version="6.5.0";
   uses:="org.eclipse.jgit.transport,
    org.eclipse.jgit.util.sha1,
    org.eclipse.jgit.dircache,
@@ -134,12 +138,12 @@
    org.eclipse.jgit.util,
    org.eclipse.jgit.submodule,
    org.eclipse.jgit.util.time",
- org.eclipse.jgit.lib.internal;version="6.4.1";
+ org.eclipse.jgit.lib.internal;version="6.5.0";
   x-friends:="org.eclipse.jgit.test,
    org.eclipse.jgit.pgm,
    org.eclipse.egit.ui",
- org.eclipse.jgit.logging;version="6.4.1",
- org.eclipse.jgit.merge;version="6.4.1";
+ org.eclipse.jgit.logging;version="6.5.0",
+ org.eclipse.jgit.merge;version="6.5.0";
   uses:="org.eclipse.jgit.dircache,
    org.eclipse.jgit.lib,
    org.eclipse.jgit.revwalk,
@@ -148,40 +152,40 @@
    org.eclipse.jgit.util,
    org.eclipse.jgit.api,
    org.eclipse.jgit.attributes",
- org.eclipse.jgit.nls;version="6.4.1",
- org.eclipse.jgit.notes;version="6.4.1";
+ org.eclipse.jgit.nls;version="6.5.0",
+ org.eclipse.jgit.notes;version="6.5.0";
   uses:="org.eclipse.jgit.lib,
    org.eclipse.jgit.revwalk,
    org.eclipse.jgit.treewalk,
    org.eclipse.jgit.merge",
- org.eclipse.jgit.patch;version="6.4.1";
+ org.eclipse.jgit.patch;version="6.5.0";
   uses:="org.eclipse.jgit.lib,
    org.eclipse.jgit.diff",
- org.eclipse.jgit.revplot;version="6.4.1";
+ org.eclipse.jgit.revplot;version="6.5.0";
   uses:="org.eclipse.jgit.lib,
    org.eclipse.jgit.revwalk",
- org.eclipse.jgit.revwalk;version="6.4.1";
+ org.eclipse.jgit.revwalk;version="6.5.0";
   uses:="org.eclipse.jgit.lib,
    org.eclipse.jgit.diff,
    org.eclipse.jgit.treewalk.filter,
    org.eclipse.jgit.revwalk.filter,
    org.eclipse.jgit.treewalk",
- org.eclipse.jgit.revwalk.filter;version="6.4.1";
+ org.eclipse.jgit.revwalk.filter;version="6.5.0";
   uses:="org.eclipse.jgit.revwalk,
    org.eclipse.jgit.lib,
    org.eclipse.jgit.util",
- org.eclipse.jgit.storage.file;version="6.4.1";
+ org.eclipse.jgit.storage.file;version="6.5.0";
   uses:="org.eclipse.jgit.lib,
    org.eclipse.jgit.util",
- org.eclipse.jgit.storage.pack;version="6.4.1";
+ org.eclipse.jgit.storage.pack;version="6.5.0";
   uses:="org.eclipse.jgit.lib",
- org.eclipse.jgit.submodule;version="6.4.1";
+ org.eclipse.jgit.submodule;version="6.5.0";
   uses:="org.eclipse.jgit.lib,
    org.eclipse.jgit.diff,
    org.eclipse.jgit.treewalk.filter,
    org.eclipse.jgit.treewalk,
    org.eclipse.jgit.util",
- org.eclipse.jgit.transport;version="6.4.1";
+ org.eclipse.jgit.transport;version="6.5.0";
   uses:="javax.crypto,
    org.eclipse.jgit.util.io,
    org.eclipse.jgit.lib,
@@ -194,21 +198,21 @@
    org.eclipse.jgit.transport.resolver,
    org.eclipse.jgit.storage.pack,
    org.eclipse.jgit.errors",
- org.eclipse.jgit.transport.http;version="6.4.1";
+ org.eclipse.jgit.transport.http;version="6.5.0";
   uses:="javax.net.ssl",
- org.eclipse.jgit.transport.resolver;version="6.4.1";
+ org.eclipse.jgit.transport.resolver;version="6.5.0";
   uses:="org.eclipse.jgit.transport,
    org.eclipse.jgit.lib",
- org.eclipse.jgit.treewalk;version="6.4.1";
+ org.eclipse.jgit.treewalk;version="6.5.0";
   uses:="org.eclipse.jgit.dircache,
    org.eclipse.jgit.lib,
    org.eclipse.jgit.attributes,
    org.eclipse.jgit.revwalk,
    org.eclipse.jgit.treewalk.filter,
    org.eclipse.jgit.util",
- org.eclipse.jgit.treewalk.filter;version="6.4.1";
+ org.eclipse.jgit.treewalk.filter;version="6.5.0";
   uses:="org.eclipse.jgit.treewalk",
- org.eclipse.jgit.util;version="6.4.1";
+ org.eclipse.jgit.util;version="6.5.0";
   uses:="org.eclipse.jgit.transport,
    org.eclipse.jgit.hooks,
    org.eclipse.jgit.revwalk,
@@ -221,12 +225,12 @@
    org.eclipse.jgit.treewalk,
    javax.net.ssl,
    org.eclipse.jgit.util.time",
- org.eclipse.jgit.util.io;version="6.4.1";
+ org.eclipse.jgit.util.io;version="6.5.0";
   uses:="org.eclipse.jgit.attributes,
    org.eclipse.jgit.lib,
    org.eclipse.jgit.treewalk",
- org.eclipse.jgit.util.sha1;version="6.4.1",
- org.eclipse.jgit.util.time;version="6.4.1"
+ org.eclipse.jgit.util.sha1;version="6.5.0",
+ org.eclipse.jgit.util.time;version="6.5.0"
 Bundle-RequiredExecutionEnvironment: JavaSE-11
 Import-Package: com.googlecode.javaewah;version="[1.1.6,2.0.0)",
  javax.crypto,
diff --git a/org.eclipse.jgit/META-INF/SOURCE-MANIFEST.MF b/org.eclipse.jgit/META-INF/SOURCE-MANIFEST.MF
index 28f3fa1..7cff83b 100644
--- a/org.eclipse.jgit/META-INF/SOURCE-MANIFEST.MF
+++ b/org.eclipse.jgit/META-INF/SOURCE-MANIFEST.MF
@@ -3,5 +3,5 @@
 Bundle-Name: org.eclipse.jgit - Sources
 Bundle-SymbolicName: org.eclipse.jgit.source
 Bundle-Vendor: Eclipse.org - JGit
-Bundle-Version: 6.4.1.qualifier
-Eclipse-SourceBundle: org.eclipse.jgit;version="6.4.1.qualifier";roots="."
+Bundle-Version: 6.5.0.qualifier
+Eclipse-SourceBundle: org.eclipse.jgit;version="6.5.0.qualifier";roots="."
diff --git a/org.eclipse.jgit/pom.xml b/org.eclipse.jgit/pom.xml
index 1a33e72..680bda8 100644
--- a/org.eclipse.jgit/pom.xml
+++ b/org.eclipse.jgit/pom.xml
@@ -20,7 +20,7 @@
   <parent>
     <groupId>org.eclipse.jgit</groupId>
     <artifactId>org.eclipse.jgit-parent</artifactId>
-    <version>6.4.1-SNAPSHOT</version>
+    <version>6.5.0-SNAPSHOT</version>
   </parent>
 
   <artifactId>org.eclipse.jgit</artifactId>
diff --git a/org.eclipse.jgit/resources/org/eclipse/jgit/internal/JGitText.properties b/org.eclipse.jgit/resources/org/eclipse/jgit/internal/JGitText.properties
index 93269d5..bdf35d8 100644
--- a/org.eclipse.jgit/resources/org/eclipse/jgit/internal/JGitText.properties
+++ b/org.eclipse.jgit/resources/org/eclipse/jgit/internal/JGitText.properties
@@ -143,11 +143,17 @@
 commandClosedStderrButDidntExit=Command {0} closed stderr stream but didn''t exit within timeout {1} seconds
 commandRejectedByHook=Rejected by "{0}" hook.\n{1}
 commandWasCalledInTheWrongState=Command {0} was called in the wrong state
+commitGraphChunkNeeded=commit-graph 0x{0} chunk has not been loaded
+commitGraphChunkRepeated=commit-graph chunk id 0x{0} appears multiple times
+commitGraphChunkUnknown=unknown commit-graph chunk: 0x{0}
+commitGraphFileIsTooLargeForJgit=commit-graph file is too large for jgit
+commitGraphWritingCancelled=commit-graph writing was canceled
 commitMessageNotSpecified=commit message not specified
 commitOnRepoWithoutHEADCurrentlyNotSupported=Commit on repo without HEAD currently not supported
 commitAmendOnInitialNotPossible=Amending is not possible on initial commit.
 commitsHaveAlreadyBeenMarkedAsStart=Commits have already been marked as walk starts.
 compressingObjects=Compressing objects
+computingCommitGeneration=Computing commit-graph generation numbers
 configSubsectionContainsNewline=config subsection name contains newline
 configSubsectionContainsNullByte=config subsection name contains byte 0x00
 configValueContainsNullByte=config value contains byte 0x00
@@ -158,6 +164,7 @@
 contextMustBeNonNegative=context must be >= 0
 cookieFilePathRelative=git config http.cookieFile contains a relative path, should be absolute: {0}
 copyFileFailedNullFiles=Cannot copy file. Either origin or destination files are null
+corruptCommitGraph=commit-graph file {0} is corrupt
 corruptionDetectedReReadingAt=Corruption detected re-reading at {0}
 corruptObjectBadDate=bad date
 corruptObjectBadEmail=bad email
@@ -300,6 +307,7 @@
 exceptionOccurredDuringAddingOfOptionToALogCommand=Exception occurred during adding of {0} as option to a Log command
 exceptionOccurredDuringReadingOfGIT_DIR=Exception occurred during reading of $GIT_DIR/{0}. {1}
 exceptionWhileFindingUserHome=Problem determining the user home directory, trying Java user.home
+exceptionWhileLoadingCommitGraph=Exception caught while loading commit-graph file {0}, the commit-graph file might be corrupt.
 exceptionWhileReadingPack=Exception caught while accessing pack file {0}, the pack file might be corrupt. Caught {1} consecutive errors while trying to read this pack.
 expectedACKNAKFoundEOF=Expected ACK/NAK, found EOF
 expectedACKNAKGot=Expected ACK/NAK, got: {0}
@@ -328,6 +336,7 @@
 filterExecutionFailed=Execution of filter command ''{0}'' on file ''{1}'' failed
 filterExecutionFailedRc=Execution of filter command ''{0}'' on file ''{1}'' failed with return code ''{2}'', message on stderr: ''{3}''
 filterRequiresCapability=filter requires server to advertise that capability
+findingCommitsForCommitGraph=Finding commits for commit-graph
 findingGarbage=Finding garbage
 flagIsDisposed={0} is disposed.
 flagNotFromThis={0} not from this.
@@ -351,6 +360,8 @@
 illegalCombinationOfArguments=The combination of arguments {0} and {1} is not allowed
 illegalHookName=Illegal hook name {0}
 illegalPackingPhase=Illegal packing phase {0}
+illegalTernarySearchTreeKey=TernarySearchTree key must not be null or empty
+illegalTernarySearchTreeValue=cannot insert null value into TernarySearchTree
 incorrectHashFor=Incorrect hash for {0}; computed {1} as a {2} from {3} bytes.
 incorrectOBJECT_ID_LENGTH=Incorrect OBJECT_ID_LENGTH.
 indexFileCorruptedNegativeBucketCount=Invalid negative bucket count read from pack v2 index file: {0}
@@ -382,6 +393,7 @@
 invalidEncoding=Invalid encoding from git config i18n.commitEncoding: {0}
 invalidEncryption=Invalid encryption
 invalidExpandWildcard=ExpandFromSource on a refspec that can have mismatched wildcards does not make sense.
+invalidExtraEdgeListPosition=Invalid position in Extra Edge List chunk: {0}
 invalidFilter=Invalid filter: {0}
 invalidGitdirRef = Invalid .git reference in file ''{0}''
 invalidGitModules=Invalid .gitmodules file
@@ -512,6 +524,7 @@
 noSuchSubmodule=no such submodule {0}
 notABoolean=Not a boolean: {0}
 notABundle=not a bundle
+notACommitGraph=not a commit-graph
 notADIRCFile=Not a DIRC file.
 notAGitDirectory=not a git directory
 notAPACKFile=Not a PACK file.
@@ -794,6 +807,7 @@
 unmergedPath=Unmerged path: {0}
 unmergedPaths=Repository contains unmerged paths
 unpackException=Exception while parsing pack stream
+unreadableCommitGraph=Unreadable commit-graph: {0}
 unreadablePackIndex=Unreadable pack index: {0}
 unrecognizedPackExtension=Unrecognized pack extension: {0}
 unrecognizedRef=Unrecognized ref: {0}
@@ -801,6 +815,7 @@
 unsupportedAlternates=Alternates not supported
 unsupportedArchiveFormat=Unknown archive format ''{0}''
 unsupportedCommand0=unsupported command 0
+unsupportedCommitGraphVersion=Unsupported commit-graph version: {0}
 unsupportedEncryptionAlgorithm=Unsupported encryption algorithm: {0}
 unsupportedEncryptionVersion=Unsupported encryption version: {0}
 unsupportedGC=Unsupported garbage collector for repository type: {0}
@@ -839,6 +854,7 @@
 writeTimedOut=Write timed out after {0} ms
 writingNotPermitted=Writing not permitted
 writingNotSupported=Writing {0} not supported.
+writingOutCommitGraph=Writing out commit-graph in {0} passes
 writingObjects=Writing objects
 wrongDecompressedLength=wrong decompressed length
 wrongRepositoryState=Wrong Repository State: {0}
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/internal/JGitText.java b/org.eclipse.jgit/src/org/eclipse/jgit/internal/JGitText.java
index d89d689..b502a1a 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/internal/JGitText.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/internal/JGitText.java
@@ -171,11 +171,17 @@ public static JGitText get() {
 	/***/ public String commandClosedStderrButDidntExit;
 	/***/ public String commandRejectedByHook;
 	/***/ public String commandWasCalledInTheWrongState;
+	/***/ public String commitGraphChunkNeeded;
+	/***/ public String commitGraphChunkRepeated;
+	/***/ public String commitGraphChunkUnknown;
+	/***/ public String commitGraphFileIsTooLargeForJgit;
+	/***/ public String commitGraphWritingCancelled;
 	/***/ public String commitMessageNotSpecified;
 	/***/ public String commitOnRepoWithoutHEADCurrentlyNotSupported;
 	/***/ public String commitAmendOnInitialNotPossible;
 	/***/ public String commitsHaveAlreadyBeenMarkedAsStart;
 	/***/ public String compressingObjects;
+	/***/ public String computingCommitGeneration;
 	/***/ public String configSubsectionContainsNewline;
 	/***/ public String configSubsectionContainsNullByte;
 	/***/ public String configValueContainsNullByte;
@@ -186,6 +192,7 @@ public static JGitText get() {
 	/***/ public String contextMustBeNonNegative;
 	/***/ public String cookieFilePathRelative;
 	/***/ public String copyFileFailedNullFiles;
+	/***/ public String corruptCommitGraph;
 	/***/ public String corruptionDetectedReReadingAt;
 	/***/ public String corruptObjectBadDate;
 	/***/ public String corruptObjectBadEmail;
@@ -328,6 +335,7 @@ public static JGitText get() {
 	/***/ public String exceptionOccurredDuringAddingOfOptionToALogCommand;
 	/***/ public String exceptionOccurredDuringReadingOfGIT_DIR;
 	/***/ public String exceptionWhileFindingUserHome;
+	/***/ public String exceptionWhileLoadingCommitGraph;
 	/***/ public String exceptionWhileReadingPack;
 	/***/ public String expectedACKNAKFoundEOF;
 	/***/ public String expectedACKNAKGot;
@@ -356,6 +364,7 @@ public static JGitText get() {
 	/***/ public String filterExecutionFailed;
 	/***/ public String filterExecutionFailedRc;
 	/***/ public String filterRequiresCapability;
+	/***/ public String findingCommitsForCommitGraph;
 	/***/ public String findingGarbage;
 	/***/ public String flagIsDisposed;
 	/***/ public String flagNotFromThis;
@@ -379,6 +388,8 @@ public static JGitText get() {
 	/***/ public String illegalCombinationOfArguments;
 	/***/ public String illegalHookName;
 	/***/ public String illegalPackingPhase;
+	/***/ public String illegalTernarySearchTreeKey;
+	/***/ public String illegalTernarySearchTreeValue;
 	/***/ public String incorrectHashFor;
 	/***/ public String incorrectOBJECT_ID_LENGTH;
 	/***/ public String indexFileCorruptedNegativeBucketCount;
@@ -410,6 +421,7 @@ public static JGitText get() {
 	/***/ public String invalidEncoding;
 	/***/ public String invalidEncryption;
 	/***/ public String invalidExpandWildcard;
+	/***/ public String invalidExtraEdgeListPosition;
 	/***/ public String invalidFilter;
 	/***/ public String invalidGitdirRef;
 	/***/ public String invalidGitModules;
@@ -540,6 +552,7 @@ public static JGitText get() {
 	/***/ public String noSuchSubmodule;
 	/***/ public String notABoolean;
 	/***/ public String notABundle;
+	/***/ public String notACommitGraph;
 	/***/ public String notADIRCFile;
 	/***/ public String notAGitDirectory;
 	/***/ public String notAPACKFile;
@@ -822,6 +835,7 @@ public static JGitText get() {
 	/***/ public String unmergedPath;
 	/***/ public String unmergedPaths;
 	/***/ public String unpackException;
+	/***/ public String unreadableCommitGraph;
 	/***/ public String unreadablePackIndex;
 	/***/ public String unrecognizedPackExtension;
 	/***/ public String unrecognizedRef;
@@ -829,6 +843,7 @@ public static JGitText get() {
 	/***/ public String unsupportedAlternates;
 	/***/ public String unsupportedArchiveFormat;
 	/***/ public String unsupportedCommand0;
+	/***/ public String unsupportedCommitGraphVersion;
 	/***/ public String unsupportedEncryptionAlgorithm;
 	/***/ public String unsupportedEncryptionVersion;
 	/***/ public String unsupportedGC;
@@ -867,6 +882,7 @@ public static JGitText get() {
 	/***/ public String writeTimedOut;
 	/***/ public String writingNotPermitted;
 	/***/ public String writingNotSupported;
+	/***/ public String writingOutCommitGraph;
 	/***/ public String writingObjects;
 	/***/ public String wrongDecompressedLength;
 	/***/ public String wrongRepositoryState;
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/commitgraph/CommitGraph.java b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/commitgraph/CommitGraph.java
new file mode 100644
index 0000000..0796293
--- /dev/null
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/commitgraph/CommitGraph.java
@@ -0,0 +1,145 @@
+/*
+ * Copyright (C) 2022, Tencent.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Distribution License v. 1.0 which is available at
+ * https://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+package org.eclipse.jgit.internal.storage.commitgraph;
+
+import org.eclipse.jgit.lib.AnyObjectId;
+import org.eclipse.jgit.lib.ObjectId;
+
+/**
+ * The CommitGraph is a supplemental data structure that accelerates commit
+ * graph walks.
+ * <p>
+ * If a user downgrades or disables the <code>core.commitGraph</code> config
+ * setting, then the existing object database is sufficient.
+ * </p>
+ * <p>
+ * It stores the commit graph structure along with some extra metadata to speed
+ * up graph walks. By listing commit OIDs in lexicographic order, we can
+ * identify an integer position for each commit and refer to the parents of a
+ * commit using those integer positions. We use binary search to find initial
+ * commits and then use the integer positions for fast lookups during the walk.
+ * </p>
+ */
+public interface CommitGraph {
+
+	/** Empty {@link CommitGraph} with no results. */
+	CommitGraph EMPTY = new CommitGraph() {
+		/** {@inheritDoc} */
+		@Override
+		public int findGraphPosition(AnyObjectId commit) {
+			return -1;
+		}
+
+		/** {@inheritDoc} */
+		@Override
+		public CommitData getCommitData(int graphPos) {
+			return null;
+		}
+
+		/** {@inheritDoc} */
+		@Override
+		public ObjectId getObjectId(int graphPos) {
+			return null;
+		}
+
+		/** {@inheritDoc} */
+		@Override
+		public long getCommitCnt() {
+			return 0;
+		}
+	};
+
+	/**
+	 * Find the position in the commit-graph of the commit.
+	 * <p>
+	 * The position can only be used within the CommitGraph Instance you got it
+	 * from. That's because the graph position of the same commit may be
+	 * different in CommitGraph obtained at different times (eg., regenerated
+	 * new commit-graph).
+	 *
+	 * @param commit
+	 *            the commit for which the commit-graph position will be found.
+	 * @return the commit-graph position or -1 if the object was not found.
+	 */
+	int findGraphPosition(AnyObjectId commit);
+
+	/**
+	 * Get the metadata of a commit。
+	 * <p>
+	 * This function runs in time O(1).
+	 * <p>
+	 * In the process of commit history traversal,
+	 * {@link CommitData#getParents()} makes us get the graphPos of the commit's
+	 * parents in advance, so that we can avoid O(logN) lookup and use O(1)
+	 * lookup instead.
+	 *
+	 * @param graphPos
+	 *            the position in the commit-graph of the object.
+	 * @return the metadata of a commit or null if it's not found.
+	 */
+	CommitData getCommitData(int graphPos);
+
+	/**
+	 * Get the object at the commit-graph position.
+	 *
+	 * @param graphPos
+	 *            the position in the commit-graph of the object.
+	 * @return the ObjectId or null if it's not found.
+	 */
+	ObjectId getObjectId(int graphPos);
+
+	/**
+	 * Obtain the total number of commits described by this commit-graph.
+	 *
+	 * @return number of commits in this commit-graph.
+	 */
+	long getCommitCnt();
+
+	/**
+	 * Metadata of a commit in commit data chunk.
+	 */
+	interface CommitData {
+
+		/**
+		 * Get a reference to this commit's tree.
+		 *
+		 * @return tree of this commit.
+		 */
+		ObjectId getTree();
+
+		/**
+		 * Obtain an array of all parents.
+		 * <p>
+		 * The method only provides the graph positions of parents in
+		 * commit-graph, call {@link CommitGraph#getObjectId(int)} to get the
+		 * real objectId.
+		 *
+		 * @return the array of parents.
+		 */
+		int[] getParents();
+
+		/**
+		 * Time from the "committer" line.
+		 *
+		 * @return the commit time in seconds since EPOCH.
+		 */
+		long getCommitTime();
+
+		/**
+		 * Get the generation number (the distance from the root) of the commit.
+		 *
+		 * @return the generation number or
+		 *         {@link org.eclipse.jgit.lib.Constants#COMMIT_GENERATION_NOT_COMPUTED}
+		 *         if the writer didn't calculate it.
+		 */
+		int getGeneration();
+	}
+}
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/commitgraph/CommitGraphBuilder.java b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/commitgraph/CommitGraphBuilder.java
new file mode 100644
index 0000000..a6af3bc
--- /dev/null
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/commitgraph/CommitGraphBuilder.java
@@ -0,0 +1,104 @@
+/*
+ * Copyright (C) 2022, Tencent.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Distribution License v. 1.0 which is available at
+ * https://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+package org.eclipse.jgit.internal.storage.commitgraph;
+
+import static org.eclipse.jgit.internal.storage.commitgraph.CommitGraphConstants.CHUNK_ID_COMMIT_DATA;
+import static org.eclipse.jgit.internal.storage.commitgraph.CommitGraphConstants.CHUNK_ID_EXTRA_EDGE_LIST;
+import static org.eclipse.jgit.internal.storage.commitgraph.CommitGraphConstants.CHUNK_ID_OID_FANOUT;
+import static org.eclipse.jgit.internal.storage.commitgraph.CommitGraphConstants.CHUNK_ID_OID_LOOKUP;
+import static org.eclipse.jgit.lib.Constants.OBJECT_ID_LENGTH;
+
+import java.text.MessageFormat;
+
+import org.eclipse.jgit.internal.JGitText;
+
+/**
+ * Builder for {@link CommitGraph}.
+ */
+class CommitGraphBuilder {
+
+	private final int hashLength;
+
+	private byte[] oidFanout;
+
+	private byte[] oidLookup;
+
+	private byte[] commitData;
+
+	private byte[] extraList;
+
+	/** @return A builder of {@link CommitGraph}. */
+	static CommitGraphBuilder builder() {
+		return new CommitGraphBuilder(OBJECT_ID_LENGTH);
+	}
+
+	private CommitGraphBuilder(int hashLength) {
+		this.hashLength = hashLength;
+	}
+
+	CommitGraphBuilder addOidFanout(byte[] buffer)
+			throws CommitGraphFormatException {
+		assertChunkNotSeenYet(oidFanout, CHUNK_ID_OID_FANOUT);
+		oidFanout = buffer;
+		return this;
+	}
+
+	CommitGraphBuilder addOidLookUp(byte[] buffer)
+			throws CommitGraphFormatException {
+		assertChunkNotSeenYet(oidLookup, CHUNK_ID_OID_LOOKUP);
+		oidLookup = buffer;
+		return this;
+	}
+
+	CommitGraphBuilder addCommitData(byte[] buffer)
+			throws CommitGraphFormatException {
+		assertChunkNotSeenYet(commitData, CHUNK_ID_COMMIT_DATA);
+		commitData = buffer;
+		return this;
+	}
+
+	CommitGraphBuilder addExtraList(byte[] buffer)
+			throws CommitGraphFormatException {
+		assertChunkNotSeenYet(extraList, CHUNK_ID_EXTRA_EDGE_LIST);
+		extraList = buffer;
+		return this;
+	}
+
+	CommitGraph build() throws CommitGraphFormatException {
+		assertChunkNotNull(oidFanout, CHUNK_ID_OID_FANOUT);
+		assertChunkNotNull(oidLookup, CHUNK_ID_OID_LOOKUP);
+		assertChunkNotNull(commitData, CHUNK_ID_COMMIT_DATA);
+
+		GraphObjectIndex index = new GraphObjectIndex(hashLength, oidFanout,
+				oidLookup);
+		GraphCommitData commitDataChunk = new GraphCommitData(hashLength,
+				commitData, extraList);
+		return new CommitGraphV1(index, commitDataChunk);
+	}
+
+	private void assertChunkNotNull(Object object, int chunkId)
+			throws CommitGraphFormatException {
+		if (object == null) {
+			throw new CommitGraphFormatException(
+					MessageFormat.format(JGitText.get().commitGraphChunkNeeded,
+							Integer.toHexString(chunkId)));
+		}
+	}
+
+	private void assertChunkNotSeenYet(Object object, int chunkId)
+			throws CommitGraphFormatException {
+		if (object != null) {
+			throw new CommitGraphFormatException(MessageFormat.format(
+					JGitText.get().commitGraphChunkRepeated,
+					Integer.toHexString(chunkId)));
+		}
+	}
+}
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/commitgraph/CommitGraphConstants.java b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/commitgraph/CommitGraphConstants.java
new file mode 100644
index 0000000..a074833
--- /dev/null
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/commitgraph/CommitGraphConstants.java
@@ -0,0 +1,55 @@
+/*
+ * Copyright (C) 2021, Tencent.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Distribution License v. 1.0 which is available at
+ * https://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+package org.eclipse.jgit.internal.storage.commitgraph;
+
+/**
+ * Constants relating to commit-graph.
+ */
+class CommitGraphConstants {
+
+	static final int COMMIT_GRAPH_MAGIC = 0x43475048; /* "CGPH" */
+
+	static final int CHUNK_ID_OID_FANOUT = 0x4f494446; /* "OIDF" */
+
+	static final int CHUNK_ID_OID_LOOKUP = 0x4f49444c; /* "OIDL" */
+
+	static final int CHUNK_ID_COMMIT_DATA = 0x43444154; /* "CDAT" */
+
+	static final int CHUNK_ID_EXTRA_EDGE_LIST = 0x45444745; /* "EDGE" */
+
+	/**
+	 * First 4 bytes describe the chunk id. Value 0 is a terminating label.
+	 * Other 8 bytes provide the byte-offset in current file for chunk to start.
+	 */
+	static final int CHUNK_LOOKUP_WIDTH = 12;
+
+	/**
+	 * First 8 bytes are for the positions of the first two parents of the ith
+	 * commit. The next 8 bytes store the generation number of the commit and
+	 * the commit time in seconds since EPOCH.
+	 */
+	static final int COMMIT_DATA_WIDTH = 16;
+
+	/** Mask to make the last edgeValue into position */
+	static final int GRAPH_EDGE_LAST_MASK = 0x7fffffff;
+
+	/** EdgeValue & GRAPH_LAST_EDGE != 0 means it is the last edgeValue */
+	static final int GRAPH_LAST_EDGE = 0x80000000;
+
+	/** EdgeValue == GRAPH_NO_PARENT means it has no parents */
+	static final int GRAPH_NO_PARENT = 0x70000000;
+
+	/**
+	 * EdgeValue & GRAPH_EXTRA_EDGES_NEEDED != 0 means its other parents are in
+	 * Chunk Extra Edge List
+	 */
+	static final int GRAPH_EXTRA_EDGES_NEEDED = 0x80000000;
+}
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/commitgraph/CommitGraphFormatException.java b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/commitgraph/CommitGraphFormatException.java
new file mode 100644
index 0000000..352bf4b
--- /dev/null
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/commitgraph/CommitGraphFormatException.java
@@ -0,0 +1,31 @@
+/*
+ * Copyright (C) 2022, Tencent.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Distribution License v. 1.0 which is available at
+ * https://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+package org.eclipse.jgit.internal.storage.commitgraph;
+
+import java.io.IOException;
+
+/**
+ * Thrown when a commit-graph file's format is different from we expected
+ */
+public class CommitGraphFormatException extends IOException {
+
+	private static final long serialVersionUID = 1L;
+
+	/**
+	 * Construct an exception.
+	 *
+	 * @param why
+	 *            description of the type of error.
+	 */
+	CommitGraphFormatException(String why) {
+		super(why);
+	}
+}
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/commitgraph/CommitGraphLoader.java b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/commitgraph/CommitGraphLoader.java
new file mode 100644
index 0000000..571f5f4
--- /dev/null
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/commitgraph/CommitGraphLoader.java
@@ -0,0 +1,186 @@
+/*
+ * Copyright (C) 2022, Tencent.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Distribution License v. 1.0 which is available at
+ * https://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+package org.eclipse.jgit.internal.storage.commitgraph;
+
+import static org.eclipse.jgit.internal.storage.commitgraph.CommitGraphConstants.CHUNK_ID_COMMIT_DATA;
+import static org.eclipse.jgit.internal.storage.commitgraph.CommitGraphConstants.CHUNK_ID_EXTRA_EDGE_LIST;
+import static org.eclipse.jgit.internal.storage.commitgraph.CommitGraphConstants.CHUNK_ID_OID_FANOUT;
+import static org.eclipse.jgit.internal.storage.commitgraph.CommitGraphConstants.CHUNK_ID_OID_LOOKUP;
+import static org.eclipse.jgit.internal.storage.commitgraph.CommitGraphConstants.CHUNK_LOOKUP_WIDTH;
+import static org.eclipse.jgit.internal.storage.commitgraph.CommitGraphConstants.COMMIT_GRAPH_MAGIC;
+
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.io.InputStream;
+import java.text.MessageFormat;
+import java.util.ArrayList;
+import java.util.List;
+
+import org.eclipse.jgit.internal.JGitText;
+import org.eclipse.jgit.util.IO;
+import org.eclipse.jgit.util.NB;
+import org.eclipse.jgit.util.io.SilentFileInputStream;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * The loader returns the representation of the commit-graph file content.
+ */
+public class CommitGraphLoader {
+
+	private final static Logger LOG = LoggerFactory
+			.getLogger(CommitGraphLoader.class);
+
+	/**
+	 * Open an existing commit-graph file for reading.
+	 * <p>
+	 * The format of the file will be automatically detected and a proper access
+	 * implementation for that format will be constructed and returned to the
+	 * caller. The file may or may not be held open by the returned instance.
+	 *
+	 * @param graphFile
+	 *            existing commit-graph to read.
+	 * @return a copy of the commit-graph file in memory
+	 * @throws FileNotFoundException
+	 *             the file does not exist.
+	 * @throws CommitGraphFormatException
+	 *             commit-graph file's format is different from we expected.
+	 * @throws java.io.IOException
+	 *             the file exists but could not be read due to security errors
+	 *             or unexpected data corruption.
+	 */
+	public static CommitGraph open(File graphFile) throws FileNotFoundException,
+			CommitGraphFormatException, IOException {
+		try (SilentFileInputStream fd = new SilentFileInputStream(graphFile)) {
+			try {
+				return read(fd);
+			} catch (CommitGraphFormatException fe) {
+				throw fe;
+			} catch (IOException ioe) {
+				throw new IOException(MessageFormat.format(
+						JGitText.get().unreadableCommitGraph,
+						graphFile.getAbsolutePath()), ioe);
+			}
+		}
+	}
+
+	/**
+	 * Read an existing commit-graph file from a buffered stream.
+	 * <p>
+	 * The format of the file will be automatically detected and a proper access
+	 * implementation for that format will be constructed and returned to the
+	 * caller. The file may or may not be held open by the returned instance.
+	 *
+	 * @param fd
+	 *            stream to read the commit-graph file from. The stream must be
+	 *            buffered as some small IOs are performed against the stream.
+	 *            The caller is responsible for closing the stream.
+	 *
+	 * @return a copy of the commit-graph file in memory
+	 * @throws CommitGraphFormatException
+	 *             the commit-graph file's format is different from we expected.
+	 * @throws java.io.IOException
+	 *             the stream cannot be read.
+	 */
+	public static CommitGraph read(InputStream fd)
+			throws CommitGraphFormatException, IOException {
+		byte[] hdr = new byte[8];
+		IO.readFully(fd, hdr, 0, hdr.length);
+
+		int magic = NB.decodeInt32(hdr, 0);
+		if (magic != COMMIT_GRAPH_MAGIC) {
+			throw new CommitGraphFormatException(
+					JGitText.get().notACommitGraph);
+		}
+
+		// Read the hash version (1 byte)
+		// 1 => SHA-1
+		// 2 => SHA-256 nonsupport now
+		int hashVersion = hdr[5];
+		if (hashVersion != 1) {
+			throw new CommitGraphFormatException(
+					JGitText.get().incorrectOBJECT_ID_LENGTH);
+		}
+
+		// Check commit-graph version
+		int v = hdr[4];
+		if (v != 1) {
+			throw new CommitGraphFormatException(MessageFormat.format(
+					JGitText.get().unsupportedCommitGraphVersion,
+					Integer.valueOf(v)));
+		}
+
+		// Read the number of "chunkOffsets" (1 byte)
+		int numberOfChunks = hdr[6];
+
+		// hdr[7] is the number of base commit-graphs, which is not supported in
+		// current version
+
+		byte[] lookupBuffer = new byte[CHUNK_LOOKUP_WIDTH
+				* (numberOfChunks + 1)];
+		IO.readFully(fd, lookupBuffer, 0, lookupBuffer.length);
+		List<ChunkSegment> chunks = new ArrayList<>(numberOfChunks + 1);
+		for (int i = 0; i <= numberOfChunks; i++) {
+			// chunks[numberOfChunks] is just a marker, in order to record the
+			// length of the last chunk.
+			int id = NB.decodeInt32(lookupBuffer, i * 12);
+			long offset = NB.decodeInt64(lookupBuffer, i * 12 + 4);
+			chunks.add(new ChunkSegment(id, offset));
+		}
+
+		CommitGraphBuilder builder = CommitGraphBuilder.builder();
+		for (int i = 0; i < numberOfChunks; i++) {
+			long chunkOffset = chunks.get(i).offset;
+			int chunkId = chunks.get(i).id;
+			long len = chunks.get(i + 1).offset - chunkOffset;
+
+			if (len > Integer.MAX_VALUE - 8) { // http://stackoverflow.com/a/8381338
+				throw new CommitGraphFormatException(
+						JGitText.get().commitGraphFileIsTooLargeForJgit);
+			}
+
+			byte buffer[] = new byte[(int) len];
+			IO.readFully(fd, buffer, 0, buffer.length);
+
+			switch (chunkId) {
+			case CHUNK_ID_OID_FANOUT:
+				builder.addOidFanout(buffer);
+				break;
+			case CHUNK_ID_OID_LOOKUP:
+				builder.addOidLookUp(buffer);
+				break;
+			case CHUNK_ID_COMMIT_DATA:
+				builder.addCommitData(buffer);
+				break;
+			case CHUNK_ID_EXTRA_EDGE_LIST:
+				builder.addExtraList(buffer);
+				break;
+			default:
+				LOG.warn(MessageFormat.format(
+						JGitText.get().commitGraphChunkUnknown,
+						Integer.toHexString(chunkId)));
+			}
+		}
+		return builder.build();
+	}
+
+	private static class ChunkSegment {
+		final int id;
+
+		final long offset;
+
+		private ChunkSegment(int id, long offset) {
+			this.id = id;
+			this.offset = offset;
+		}
+	}
+}
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/commitgraph/CommitGraphV1.java b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/commitgraph/CommitGraphV1.java
new file mode 100644
index 0000000..da17219
--- /dev/null
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/commitgraph/CommitGraphV1.java
@@ -0,0 +1,58 @@
+/*
+ * Copyright (C) 2022, Tencent.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Distribution License v. 1.0 which is available at
+ * https://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+package org.eclipse.jgit.internal.storage.commitgraph;
+
+import org.eclipse.jgit.lib.AnyObjectId;
+import org.eclipse.jgit.lib.ObjectId;
+
+/**
+ * Support for the commit-graph v1 format.
+ *
+ * @see CommitGraph
+ */
+class CommitGraphV1 implements CommitGraph {
+
+	private final GraphObjectIndex idx;
+
+	private final GraphCommitData commitData;
+
+	CommitGraphV1(GraphObjectIndex index, GraphCommitData commitData) {
+		this.idx = index;
+		this.commitData = commitData;
+	}
+
+	/** {@inheritDoc} */
+	@Override
+	public int findGraphPosition(AnyObjectId commit) {
+		return idx.findGraphPosition(commit);
+	}
+
+	/** {@inheritDoc} */
+	@Override
+	public CommitData getCommitData(int graphPos) {
+		if (graphPos < 0 || graphPos >= getCommitCnt()) {
+			return null;
+		}
+		return commitData.getCommitData(graphPos);
+	}
+
+	/** {@inheritDoc} */
+	@Override
+	public ObjectId getObjectId(int graphPos) {
+		return idx.getObjectId(graphPos);
+	}
+
+	/** {@inheritDoc} */
+	@Override
+	public long getCommitCnt() {
+		return idx.getCommitCnt();
+	}
+}
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/commitgraph/CommitGraphWriter.java b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/commitgraph/CommitGraphWriter.java
new file mode 100644
index 0000000..a58a9eb
--- /dev/null
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/commitgraph/CommitGraphWriter.java
@@ -0,0 +1,338 @@
+/*
+ * Copyright (C) 2021, Tencent.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Distribution License v. 1.0 which is available at
+ * https://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+package org.eclipse.jgit.internal.storage.commitgraph;
+
+import static org.eclipse.jgit.internal.storage.commitgraph.CommitGraphConstants.CHUNK_ID_COMMIT_DATA;
+import static org.eclipse.jgit.internal.storage.commitgraph.CommitGraphConstants.CHUNK_ID_EXTRA_EDGE_LIST;
+import static org.eclipse.jgit.internal.storage.commitgraph.CommitGraphConstants.CHUNK_ID_OID_FANOUT;
+import static org.eclipse.jgit.internal.storage.commitgraph.CommitGraphConstants.CHUNK_ID_OID_LOOKUP;
+import static org.eclipse.jgit.internal.storage.commitgraph.CommitGraphConstants.CHUNK_LOOKUP_WIDTH;
+import static org.eclipse.jgit.internal.storage.commitgraph.CommitGraphConstants.COMMIT_DATA_WIDTH;
+import static org.eclipse.jgit.internal.storage.commitgraph.CommitGraphConstants.COMMIT_GRAPH_MAGIC;
+import static org.eclipse.jgit.internal.storage.commitgraph.CommitGraphConstants.GRAPH_EXTRA_EDGES_NEEDED;
+import static org.eclipse.jgit.internal.storage.commitgraph.CommitGraphConstants.GRAPH_LAST_EDGE;
+import static org.eclipse.jgit.internal.storage.commitgraph.CommitGraphConstants.GRAPH_NO_PARENT;
+import static org.eclipse.jgit.lib.Constants.COMMIT_GENERATION_NOT_COMPUTED;
+import static org.eclipse.jgit.lib.Constants.COMMIT_GENERATION_UNKNOWN;
+import static org.eclipse.jgit.lib.Constants.OBJECT_ID_LENGTH;
+
+import java.io.IOException;
+import java.io.InterruptedIOException;
+import java.io.OutputStream;
+import java.text.MessageFormat;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Stack;
+
+import org.eclipse.jgit.annotations.NonNull;
+import org.eclipse.jgit.errors.MissingObjectException;
+import org.eclipse.jgit.internal.JGitText;
+import org.eclipse.jgit.internal.storage.io.CancellableDigestOutputStream;
+import org.eclipse.jgit.lib.ObjectId;
+import org.eclipse.jgit.lib.ProgressMonitor;
+import org.eclipse.jgit.revwalk.RevCommit;
+import org.eclipse.jgit.util.NB;
+
+/**
+ * Writes a commit-graph formatted file.
+ *
+ * @since 6.5
+ */
+public class CommitGraphWriter {
+
+	private static final int COMMIT_GRAPH_VERSION_GENERATED = 1;
+
+	private static final int OID_HASH_VERSION = 1;
+
+	private static final int GRAPH_FANOUT_SIZE = 4 * 256;
+
+	private static final int GENERATION_NUMBER_MAX = 0x3FFFFFFF;
+
+	private final int hashsz;
+
+	private final GraphCommits graphCommits;
+
+	/**
+	 * Create commit-graph writer for these commits.
+	 *
+	 * @param graphCommits
+	 *            the commits which will be writen to the commit-graph.
+	 */
+	public CommitGraphWriter(@NonNull GraphCommits graphCommits) {
+		this.graphCommits = graphCommits;
+		this.hashsz = OBJECT_ID_LENGTH;
+	}
+
+	/**
+	 * Write commit-graph to the supplied stream.
+	 *
+	 * @param monitor
+	 *            progress monitor to report the number of items written.
+	 * @param commitGraphStream
+	 *            output stream of commit-graph data. The stream should be
+	 *            buffered by the caller. The caller is responsible for closing
+	 *            the stream.
+	 * @throws IOException
+	 */
+	public void write(@NonNull ProgressMonitor monitor,
+			@NonNull OutputStream commitGraphStream) throws IOException {
+		if (graphCommits.size() == 0) {
+			return;
+		}
+
+		List<ChunkHeader> chunks = createChunks();
+		long writeCount = 256 + 2 * graphCommits.size()
+				+ graphCommits.getExtraEdgeCnt();
+		monitor.beginTask(
+				MessageFormat.format(JGitText.get().writingOutCommitGraph,
+						Integer.valueOf(chunks.size())),
+				(int) writeCount);
+
+		try (CancellableDigestOutputStream out = new CancellableDigestOutputStream(
+				monitor, commitGraphStream)) {
+			writeHeader(out, chunks.size());
+			writeChunkLookup(out, chunks);
+			writeChunks(monitor, out, chunks);
+			writeCheckSum(out);
+		} catch (InterruptedIOException e) {
+			throw new IOException(JGitText.get().commitGraphWritingCancelled,
+					e);
+		} finally {
+			monitor.endTask();
+		}
+	}
+
+	private List<ChunkHeader> createChunks() {
+		List<ChunkHeader> chunks = new ArrayList<>();
+		chunks.add(new ChunkHeader(CHUNK_ID_OID_FANOUT, GRAPH_FANOUT_SIZE));
+		chunks.add(new ChunkHeader(CHUNK_ID_OID_LOOKUP,
+				hashsz * graphCommits.size()));
+		chunks.add(new ChunkHeader(CHUNK_ID_COMMIT_DATA,
+				(hashsz + 16) * graphCommits.size()));
+		if (graphCommits.getExtraEdgeCnt() > 0) {
+			chunks.add(new ChunkHeader(CHUNK_ID_EXTRA_EDGE_LIST,
+					graphCommits.getExtraEdgeCnt() * 4));
+		}
+		return chunks;
+	}
+
+	private void writeHeader(CancellableDigestOutputStream out, int numChunks)
+			throws IOException {
+		byte[] headerBuffer = new byte[8];
+		NB.encodeInt32(headerBuffer, 0, COMMIT_GRAPH_MAGIC);
+		byte[] buff = { (byte) COMMIT_GRAPH_VERSION_GENERATED,
+				(byte) OID_HASH_VERSION, (byte) numChunks, (byte) 0 };
+		System.arraycopy(buff, 0, headerBuffer, 4, 4);
+		out.write(headerBuffer, 0, 8);
+		out.flush();
+	}
+
+	private void writeChunkLookup(CancellableDigestOutputStream out,
+			List<ChunkHeader> chunks) throws IOException {
+		int numChunks = chunks.size();
+		long chunkOffset = 8 + (numChunks + 1) * CHUNK_LOOKUP_WIDTH;
+		byte[] buffer = new byte[CHUNK_LOOKUP_WIDTH];
+		for (ChunkHeader chunk : chunks) {
+			NB.encodeInt32(buffer, 0, chunk.id);
+			NB.encodeInt64(buffer, 4, chunkOffset);
+			out.write(buffer);
+			chunkOffset += chunk.size;
+		}
+		NB.encodeInt32(buffer, 0, 0);
+		NB.encodeInt64(buffer, 4, chunkOffset);
+		out.write(buffer);
+	}
+
+	private void writeChunks(ProgressMonitor monitor,
+			CancellableDigestOutputStream out, List<ChunkHeader> chunks)
+			throws IOException {
+		for (ChunkHeader chunk : chunks) {
+			int chunkId = chunk.id;
+
+			switch (chunkId) {
+			case CHUNK_ID_OID_FANOUT:
+				writeFanoutTable(out);
+				break;
+			case CHUNK_ID_OID_LOOKUP:
+				writeOidLookUp(out);
+				break;
+			case CHUNK_ID_COMMIT_DATA:
+				writeCommitData(monitor, out);
+				break;
+			case CHUNK_ID_EXTRA_EDGE_LIST:
+				writeExtraEdges(out);
+				break;
+			}
+		}
+	}
+
+	private void writeCheckSum(CancellableDigestOutputStream out)
+			throws IOException {
+		out.write(out.getDigest());
+		out.flush();
+	}
+
+	private void writeFanoutTable(CancellableDigestOutputStream out)
+			throws IOException {
+		byte[] tmp = new byte[4];
+		int[] fanout = new int[256];
+		for (RevCommit c : graphCommits) {
+			fanout[c.getFirstByte() & 0xff]++;
+		}
+		for (int i = 1; i < fanout.length; i++) {
+			fanout[i] += fanout[i - 1];
+		}
+		for (int n : fanout) {
+			NB.encodeInt32(tmp, 0, n);
+			out.write(tmp, 0, 4);
+			out.getWriteMonitor().update(1);
+		}
+	}
+
+	private void writeOidLookUp(CancellableDigestOutputStream out)
+			throws IOException {
+		byte[] tmp = new byte[4 + hashsz];
+
+		for (RevCommit c : graphCommits) {
+			c.copyRawTo(tmp, 0);
+			out.write(tmp, 0, hashsz);
+			out.getWriteMonitor().update(1);
+		}
+	}
+
+	private void writeCommitData(ProgressMonitor monitor,
+			CancellableDigestOutputStream out) throws IOException {
+		int[] generations = computeGenerationNumbers(monitor);
+		int num = 0;
+		byte[] tmp = new byte[hashsz + COMMIT_DATA_WIDTH];
+		int i = 0;
+		for (RevCommit commit : graphCommits) {
+			int edgeValue;
+			int[] packedDate = new int[2];
+
+			ObjectId treeId = commit.getTree();
+			treeId.copyRawTo(tmp, 0);
+
+			RevCommit[] parents = commit.getParents();
+			if (parents.length == 0) {
+				edgeValue = GRAPH_NO_PARENT;
+			} else {
+				RevCommit parent = parents[0];
+				edgeValue = graphCommits.getOidPosition(parent);
+			}
+			NB.encodeInt32(tmp, hashsz, edgeValue);
+			if (parents.length == 1) {
+				edgeValue = GRAPH_NO_PARENT;
+			} else if (parents.length == 2) {
+				RevCommit parent = parents[1];
+				edgeValue = graphCommits.getOidPosition(parent);
+			} else if (parents.length > 2) {
+				edgeValue = GRAPH_EXTRA_EDGES_NEEDED | num;
+				num += parents.length - 1;
+			}
+
+			NB.encodeInt32(tmp, hashsz + 4, edgeValue);
+
+			packedDate[0] = 0; // commitTime is an int in JGit now
+			packedDate[0] |= generations[i] << 2;
+			packedDate[1] = commit.getCommitTime();
+			NB.encodeInt32(tmp, hashsz + 8, packedDate[0]);
+			NB.encodeInt32(tmp, hashsz + 12, packedDate[1]);
+
+			out.write(tmp);
+			out.getWriteMonitor().update(1);
+			i++;
+		}
+	}
+
+	private int[] computeGenerationNumbers(ProgressMonitor monitor)
+			throws MissingObjectException {
+		int[] generations = new int[graphCommits.size()];
+		monitor.beginTask(JGitText.get().computingCommitGeneration,
+				graphCommits.size());
+		for (RevCommit cmit : graphCommits) {
+			monitor.update(1);
+			int generation = generations[graphCommits.getOidPosition(cmit)];
+			if (generation != COMMIT_GENERATION_NOT_COMPUTED
+					&& generation != COMMIT_GENERATION_UNKNOWN) {
+				continue;
+			}
+
+			Stack<RevCommit> commitStack = new Stack<>();
+			commitStack.push(cmit);
+
+			while (!commitStack.empty()) {
+				int maxGeneration = 0;
+				boolean allParentComputed = true;
+				RevCommit current = commitStack.peek();
+				RevCommit parent;
+
+				for (int i = 0; i < current.getParentCount(); i++) {
+					parent = current.getParent(i);
+					generation = generations[graphCommits
+							.getOidPosition(parent)];
+					if (generation == COMMIT_GENERATION_NOT_COMPUTED
+							|| generation == COMMIT_GENERATION_UNKNOWN) {
+						allParentComputed = false;
+						commitStack.push(parent);
+						break;
+					} else if (generation > maxGeneration) {
+						maxGeneration = generation;
+					}
+				}
+
+				if (allParentComputed) {
+					RevCommit commit = commitStack.pop();
+					generation = maxGeneration + 1;
+					if (generation > GENERATION_NUMBER_MAX) {
+						generation = GENERATION_NUMBER_MAX;
+					}
+					generations[graphCommits
+							.getOidPosition(commit)] = generation;
+				}
+			}
+		}
+		monitor.endTask();
+		return generations;
+	}
+
+	private void writeExtraEdges(CancellableDigestOutputStream out)
+			throws IOException {
+		byte[] tmp = new byte[4];
+		for (RevCommit commit : graphCommits) {
+			RevCommit[] parents = commit.getParents();
+			if (parents.length > 2) {
+				int edgeValue;
+				for (int n = 1; n < parents.length; n++) {
+					RevCommit parent = parents[n];
+					edgeValue = graphCommits.getOidPosition(parent);
+					if (n == parents.length - 1) {
+						edgeValue |= GRAPH_LAST_EDGE;
+					}
+					NB.encodeInt32(tmp, 0, edgeValue);
+					out.write(tmp);
+					out.getWriteMonitor().update(1);
+				}
+			}
+		}
+	}
+
+	private static class ChunkHeader {
+		final int id;
+
+		final long size;
+
+		public ChunkHeader(int id, long size) {
+			this.id = id;
+			this.size = size;
+		}
+	}
+}
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/commitgraph/GraphCommitData.java b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/commitgraph/GraphCommitData.java
new file mode 100644
index 0000000..6ae40ff
--- /dev/null
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/commitgraph/GraphCommitData.java
@@ -0,0 +1,172 @@
+/*
+ * Copyright (C) 2022, Tencent.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Distribution License v. 1.0 which is available at
+ * https://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+package org.eclipse.jgit.internal.storage.commitgraph;
+
+import static org.eclipse.jgit.internal.storage.commitgraph.CommitGraphConstants.COMMIT_DATA_WIDTH;
+import static org.eclipse.jgit.internal.storage.commitgraph.CommitGraphConstants.GRAPH_EDGE_LAST_MASK;
+import static org.eclipse.jgit.internal.storage.commitgraph.CommitGraphConstants.GRAPH_EXTRA_EDGES_NEEDED;
+import static org.eclipse.jgit.internal.storage.commitgraph.CommitGraphConstants.GRAPH_LAST_EDGE;
+import static org.eclipse.jgit.internal.storage.commitgraph.CommitGraphConstants.GRAPH_NO_PARENT;
+
+import java.text.MessageFormat;
+import java.util.Arrays;
+
+import org.eclipse.jgit.annotations.NonNull;
+import org.eclipse.jgit.internal.JGitText;
+import org.eclipse.jgit.internal.storage.commitgraph.CommitGraph.CommitData;
+import org.eclipse.jgit.lib.ObjectId;
+import org.eclipse.jgit.util.NB;
+
+/**
+ * Represent the collection of {@link CommitData}.
+ */
+class GraphCommitData {
+
+	private static final int[] NO_PARENTS = {};
+
+	private final byte[] data;
+
+	private final byte[] extraList;
+
+	private final int hashLength;
+
+	private final int commitDataLength;
+
+	/**
+	 * Initialize the GraphCommitData.
+	 *
+	 * @param hashLength
+	 *            length of object hash.
+	 * @param commitData
+	 *            content of CommitData Chunk.
+	 * @param extraList
+	 *            content of Extra Edge List Chunk.
+	 */
+	GraphCommitData(int hashLength, @NonNull byte[] commitData,
+			byte[] extraList) {
+		this.data = commitData;
+		this.extraList = extraList;
+		this.hashLength = hashLength;
+		this.commitDataLength = hashLength + COMMIT_DATA_WIDTH;
+	}
+
+	/**
+	 * Get the metadata of a commit。
+	 *
+	 * @param graphPos
+	 *            the position in the commit-graph of the object.
+	 * @return the metadata of a commit or null if not found.
+	 */
+	CommitData getCommitData(int graphPos) {
+		int dataIdx = commitDataLength * graphPos;
+
+		// parse tree
+		ObjectId tree = ObjectId.fromRaw(data, dataIdx);
+
+		// parse date
+		long dateHigh = NB.decodeUInt32(data, dataIdx + hashLength + 8) & 0x3;
+		long dateLow = NB.decodeUInt32(data, dataIdx + hashLength + 12);
+		long commitTime = dateHigh << 32 | dateLow;
+
+		// parse generation
+		int generation = NB.decodeInt32(data, dataIdx + hashLength + 8) >> 2;
+
+		// parse first parent
+		int parent1 = NB.decodeInt32(data, dataIdx + hashLength);
+		if (parent1 == GRAPH_NO_PARENT) {
+			return new CommitDataImpl(tree, NO_PARENTS, commitTime, generation);
+		}
+
+		// parse second parent
+		int parent2 = NB.decodeInt32(data, dataIdx + hashLength + 4);
+		if (parent2 == GRAPH_NO_PARENT) {
+			return new CommitDataImpl(tree, new int[] { parent1 }, commitTime,
+					generation);
+		}
+
+		if ((parent2 & GRAPH_EXTRA_EDGES_NEEDED) == 0) {
+			return new CommitDataImpl(tree, new int[] { parent1, parent2 },
+					commitTime, generation);
+		}
+
+		// parse parents for octopus merge
+		return new CommitDataImpl(tree,
+				findParentsForOctopusMerge(parent1,
+						parent2 & GRAPH_EDGE_LAST_MASK),
+				commitTime, generation);
+	}
+
+	private int[] findParentsForOctopusMerge(int parent1, int extraEdgePos) {
+		int maxOffset = extraList.length - 4;
+		int offset = extraEdgePos * 4;
+		if (offset < 0 || offset > maxOffset) {
+			throw new IllegalArgumentException(MessageFormat.format(
+					JGitText.get().invalidExtraEdgeListPosition,
+					Integer.valueOf(extraEdgePos)));
+		}
+		int[] pList = new int[32];
+		pList[0] = parent1;
+		int count = 1;
+		int parentPosition;
+		for (; offset <= maxOffset; offset += 4) {
+			if (count >= pList.length) {
+				// expand the pList
+				pList = Arrays.copyOf(pList, pList.length + 32);
+			}
+			parentPosition = NB.decodeInt32(extraList, offset);
+			if ((parentPosition & GRAPH_LAST_EDGE) != 0) {
+				pList[count++] = parentPosition & GRAPH_EDGE_LAST_MASK;
+				break;
+			}
+			pList[count++] = parentPosition;
+		}
+		return Arrays.copyOf(pList, count);
+	}
+
+	private static class CommitDataImpl implements CommitData {
+
+		private final ObjectId tree;
+
+		private final int[] parents;
+
+		private final long commitTime;
+
+		private final int generation;
+
+		public CommitDataImpl(ObjectId tree, int[] parents, long commitTime,
+				int generation) {
+			this.tree = tree;
+			this.parents = parents;
+			this.commitTime = commitTime;
+			this.generation = generation;
+		}
+
+		@Override
+		public ObjectId getTree() {
+			return tree;
+		}
+
+		@Override
+		public int[] getParents() {
+			return parents;
+		}
+
+		@Override
+		public long getCommitTime() {
+			return commitTime;
+		}
+
+		@Override
+		public int getGeneration() {
+			return generation;
+		}
+	}
+}
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/commitgraph/GraphCommits.java b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/commitgraph/GraphCommits.java
new file mode 100644
index 0000000..ccf6d0e
--- /dev/null
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/commitgraph/GraphCommits.java
@@ -0,0 +1,142 @@
+/*
+ * Copyright (C) 2021, Tencent.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Distribution License v. 1.0 which is available at
+ * https://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+package org.eclipse.jgit.internal.storage.commitgraph;
+
+import java.io.IOException;
+import java.util.Collections;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Set;
+
+import org.eclipse.jgit.annotations.NonNull;
+import org.eclipse.jgit.errors.MissingObjectException;
+import org.eclipse.jgit.internal.JGitText;
+import org.eclipse.jgit.lib.AnyObjectId;
+import org.eclipse.jgit.lib.Constants;
+import org.eclipse.jgit.lib.ObjectId;
+import org.eclipse.jgit.lib.ObjectIdOwnerMap;
+import org.eclipse.jgit.lib.ProgressMonitor;
+import org.eclipse.jgit.revwalk.RevCommit;
+import org.eclipse.jgit.revwalk.RevObject;
+import org.eclipse.jgit.revwalk.RevSort;
+import org.eclipse.jgit.revwalk.RevWalk;
+import org.eclipse.jgit.util.BlockList;
+
+/**
+ * The commits which are used by the commit-graph writer to:
+ * <ul>
+ * <li>List commits in SHA1 order.</li>
+ * <li>Get the position of a specific SHA1 in the list.</li>
+ * </ul>
+ *
+ * @since 6.5
+ */
+public class GraphCommits implements Iterable<RevCommit> {
+
+	/**
+	 * Prepare and create the commits for
+	 * {@link org.eclipse.jgit.internal.storage.commitgraph.CommitGraphWriter}
+	 * from the RevWalk.
+	 *
+	 * @param pm
+	 *            progress monitor.
+	 * @param wants
+	 *            the list of wanted objects, writer walks commits starting at
+	 *            these. Must not be {@code null}.
+	 * @param walk
+	 *            the RevWalk to use. Must not be {@code null}.
+	 * @return the commits' collection which are used by the commit-graph
+	 *         writer. Never null.
+	 * @throws IOException
+	 */
+	public static GraphCommits fromWalk(ProgressMonitor pm,
+			@NonNull Set<? extends ObjectId> wants, @NonNull RevWalk walk)
+			throws IOException {
+		walk.reset();
+		walk.sort(RevSort.NONE);
+		walk.setRetainBody(false);
+		for (ObjectId id : wants) {
+			RevObject o = walk.parseAny(id);
+			if (o instanceof RevCommit) {
+				walk.markStart((RevCommit) o);
+			}
+		}
+		List<RevCommit> commits = new BlockList<>();
+		RevCommit c;
+		pm.beginTask(JGitText.get().findingCommitsForCommitGraph,
+				ProgressMonitor.UNKNOWN);
+		while ((c = walk.next()) != null) {
+			pm.update(1);
+			commits.add(c);
+		}
+		pm.endTask();
+		return new GraphCommits(commits);
+	}
+
+	private final List<RevCommit> sortedCommits;
+
+	private final ObjectIdOwnerMap<CommitWithPosition> commitPosMap;
+
+	private final int extraEdgeCnt;
+
+	/**
+	 * Initialize the GraphCommits.
+	 *
+	 * @param commits
+	 *            list of commits with their headers already parsed.
+	 */
+	private GraphCommits(List<RevCommit> commits) {
+		Collections.sort(commits); // sorted by name
+		sortedCommits = commits;
+		commitPosMap = new ObjectIdOwnerMap<>();
+		int cnt = 0;
+		for (int i = 0; i < commits.size(); i++) {
+			RevCommit c = sortedCommits.get(i);
+			if (c.getParentCount() > 2) {
+				cnt += c.getParentCount() - 1;
+			}
+			commitPosMap.add(new CommitWithPosition(c, i));
+		}
+		this.extraEdgeCnt = cnt;
+	}
+
+	int getOidPosition(RevCommit c) throws MissingObjectException {
+		CommitWithPosition commitWithPosition = commitPosMap.get(c);
+		if (commitWithPosition == null) {
+			throw new MissingObjectException(c, Constants.OBJ_COMMIT);
+		}
+		return commitWithPosition.position;
+	}
+
+	int getExtraEdgeCnt() {
+		return extraEdgeCnt;
+	}
+
+	int size() {
+		return sortedCommits.size();
+	}
+
+	/** {@inheritDoc} */
+	@Override
+	public Iterator<RevCommit> iterator() {
+		return sortedCommits.iterator();
+	}
+
+	private static class CommitWithPosition extends ObjectIdOwnerMap.Entry {
+
+		final int position;
+
+		CommitWithPosition(AnyObjectId id, int position) {
+			super(id);
+			this.position = position;
+		}
+	}
+}
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/commitgraph/GraphObjectIndex.java b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/commitgraph/GraphObjectIndex.java
new file mode 100644
index 0000000..b0df467
--- /dev/null
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/commitgraph/GraphObjectIndex.java
@@ -0,0 +1,119 @@
+/*
+ * Copyright (C) 2022, Tencent.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Distribution License v. 1.0 which is available at
+ * https://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+package org.eclipse.jgit.internal.storage.commitgraph;
+
+import org.eclipse.jgit.annotations.NonNull;
+import org.eclipse.jgit.internal.JGitText;
+import org.eclipse.jgit.lib.AnyObjectId;
+import org.eclipse.jgit.lib.ObjectId;
+import org.eclipse.jgit.util.NB;
+
+/**
+ * The index which are used by the commit-graph to:
+ * <ul>
+ * <li>Get the object in commit-graph by using a specific position.</li>
+ * <li>Get the position of a specific object in commit-graph.</li>
+ * </ul>
+ */
+class GraphObjectIndex {
+
+	private static final int FANOUT = 256;
+
+	private final int hashLength;
+
+	private final int[] fanoutTable;
+
+	private final byte[] oidLookup;
+
+	private final long commitCnt;
+
+	/**
+	 * Initialize the GraphObjectIndex.
+	 *
+	 * @param hashLength
+	 *            length of object hash.
+	 * @param oidFanout
+	 *            content of OID Fanout Chunk.
+	 * @param oidLookup
+	 *            content of OID Lookup Chunk.
+	 * @throws CommitGraphFormatException
+	 *             commit-graph file's format is different from we expected.
+	 */
+	GraphObjectIndex(int hashLength, @NonNull byte[] oidFanout,
+			@NonNull byte[] oidLookup) throws CommitGraphFormatException {
+		this.hashLength = hashLength;
+		this.oidLookup = oidLookup;
+
+		int[] table = new int[FANOUT];
+		long uint32;
+		for (int k = 0; k < table.length; k++) {
+			uint32 = NB.decodeUInt32(oidFanout, k * 4);
+			if (table[k] > Integer.MAX_VALUE) {
+				throw new CommitGraphFormatException(
+						JGitText.get().commitGraphFileIsTooLargeForJgit);
+			}
+			table[k] = (int) uint32;
+		}
+		this.fanoutTable = table;
+		this.commitCnt = table[FANOUT - 1];
+	}
+
+	/**
+	 * Find the position in the commit-graph of the specified id.
+	 *
+	 * @param id
+	 *            the id for which the commit-graph position will be found.
+	 * @return the commit-graph position or -1 if the object was not found.
+	 */
+	int findGraphPosition(AnyObjectId id) {
+		int levelOne = id.getFirstByte();
+		int high = fanoutTable[levelOne];
+		int low = 0;
+		if (levelOne > 0) {
+			low = fanoutTable[levelOne - 1];
+		}
+		do {
+			int mid = (low + high) >>> 1;
+			int pos = objIdOffset(mid);
+			int cmp = id.compareTo(oidLookup, pos);
+			if (cmp < 0) {
+				high = mid;
+			} else if (cmp == 0) {
+				return mid;
+			} else {
+				low = mid + 1;
+			}
+		} while (low < high);
+		return -1;
+	}
+
+	/**
+	 * Get the object at the commit-graph position.
+	 *
+	 * @param graphPos
+	 *            the position in the commit-graph of the object.
+	 * @return the ObjectId or null if it's not found.
+	 */
+	ObjectId getObjectId(int graphPos) {
+		if (graphPos < 0 || graphPos >= commitCnt) {
+			return null;
+		}
+		return ObjectId.fromRaw(oidLookup, objIdOffset(graphPos));
+	}
+
+	long getCommitCnt() {
+		return commitCnt;
+	}
+
+	private int objIdOffset(int pos) {
+		return hashLength * pos;
+	}
+}
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/CachedObjectDirectory.java b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/CachedObjectDirectory.java
index 9272bf3..2e19580 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/CachedObjectDirectory.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/CachedObjectDirectory.java
@@ -15,6 +15,7 @@
 import java.io.IOException;
 import java.util.Collection;
 import java.util.HashSet;
+import java.util.Optional;
 import java.util.Set;
 
 import org.eclipse.jgit.internal.storage.file.ObjectDirectory.AlternateHandle;
@@ -22,6 +23,7 @@
 import org.eclipse.jgit.internal.storage.pack.PackWriter;
 import org.eclipse.jgit.lib.AbbreviatedObjectId;
 import org.eclipse.jgit.lib.AnyObjectId;
+import org.eclipse.jgit.internal.storage.commitgraph.CommitGraph;
 import org.eclipse.jgit.lib.Config;
 import org.eclipse.jgit.lib.Constants;
 import org.eclipse.jgit.lib.ObjectDatabase;
@@ -259,6 +261,12 @@ Collection<Pack> getPacks() {
 		return wrapped.getPacks();
 	}
 
+	/** {@inheritDoc} */
+	@Override
+	public Optional<CommitGraph> getCommitGraph() {
+		return wrapped.getCommitGraph();
+	}
+
 	private static class UnpackedObjectId extends ObjectIdOwnerMap.Entry {
 		UnpackedObjectId(AnyObjectId id) {
 			super(id);
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/FileCommitGraph.java b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/FileCommitGraph.java
new file mode 100644
index 0000000..3e411a1
--- /dev/null
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/FileCommitGraph.java
@@ -0,0 +1,135 @@
+/*
+ * Copyright (C) 2022, Tencent.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Distribution License v. 1.0 which is available at
+ * https://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+package org.eclipse.jgit.internal.storage.file;
+
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.text.MessageFormat;
+import java.util.concurrent.atomic.AtomicReference;
+
+import org.eclipse.jgit.annotations.NonNull;
+import org.eclipse.jgit.internal.JGitText;
+import org.eclipse.jgit.internal.storage.commitgraph.CommitGraphFormatException;
+import org.eclipse.jgit.internal.storage.commitgraph.CommitGraphLoader;
+import org.eclipse.jgit.internal.storage.commitgraph.CommitGraph;
+import org.eclipse.jgit.lib.Constants;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Traditional file system for commit-graph.
+ * <p>
+ * This is the commit-graph file representation for a Git object database. Each
+ * call to {@link FileCommitGraph#get()} will recheck for newer versions.
+ */
+public class FileCommitGraph {
+	private final static Logger LOG = LoggerFactory
+			.getLogger(FileCommitGraph.class);
+
+	private final AtomicReference<GraphSnapshot> baseGraph;
+
+	/**
+	 * Initialize a reference to an on-disk commit-graph.
+	 *
+	 * @param objectsDir
+	 *            the location of the <code>objects</code> directory.
+	 */
+	FileCommitGraph(File objectsDir) {
+		this.baseGraph = new AtomicReference<>(new GraphSnapshot(
+				new File(objectsDir, Constants.INFO_COMMIT_GRAPH)));
+	}
+
+	/**
+	 * The method will first scan whether the ".git/objects/info/commit-graph"
+	 * has been modified, if so, it will re-parse the file, otherwise it will
+	 * return the same result as the last time.
+	 *
+	 * @return commit-graph or null if commit-graph file does not exist or
+	 *         corrupt.
+	 */
+	CommitGraph get() {
+		GraphSnapshot original = baseGraph.get();
+		synchronized (baseGraph) {
+			GraphSnapshot o, n;
+			do {
+				o = baseGraph.get();
+				if (o != original) {
+					// Another thread did the scan for us, while we
+					// were blocked on the monitor above.
+					//
+					return o.getCommitGraph();
+				}
+				n = o.refresh();
+				if (n == o) {
+					return n.getCommitGraph();
+				}
+			} while (!baseGraph.compareAndSet(o, n));
+			return n.getCommitGraph();
+		}
+	}
+
+	private static final class GraphSnapshot {
+		private final File file;
+
+		private final FileSnapshot snapshot;
+
+		private final CommitGraph graph;
+
+		GraphSnapshot(@NonNull File file) {
+			this(file, FileSnapshot.save(file), null);
+		}
+
+		GraphSnapshot(@NonNull File file, @NonNull FileSnapshot snapshot,
+				CommitGraph graph) {
+			this.file = file;
+			this.snapshot = snapshot;
+			this.graph = graph;
+		}
+
+		CommitGraph getCommitGraph() {
+			return graph;
+		}
+
+		GraphSnapshot refresh() {
+			if (graph == null && !file.exists()) {
+				// commit-graph file didn't exist
+				return this;
+			}
+			if (!snapshot.isModified(file)) {
+				// commit-graph file was not modified
+				return this;
+			}
+			return new GraphSnapshot(file, FileSnapshot.save(file), open(file));
+		}
+
+		private static CommitGraph open(File file) {
+			try {
+				return CommitGraphLoader.open(file);
+			} catch (FileNotFoundException noFile) {
+				// ignore if file do not exist
+				return null;
+			} catch (IOException e) {
+				if (e instanceof CommitGraphFormatException) {
+					LOG.warn(
+							MessageFormat.format(
+									JGitText.get().corruptCommitGraph, file),
+							e);
+				} else {
+					LOG.error(MessageFormat.format(
+							JGitText.get().exceptionWhileLoadingCommitGraph,
+							file), e);
+				}
+				return null;
+			}
+		}
+	}
+}
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/FileObjectDatabase.java b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/FileObjectDatabase.java
index e97ed39..aa578d3 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/FileObjectDatabase.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/FileObjectDatabase.java
@@ -13,8 +13,10 @@
 import java.io.File;
 import java.io.IOException;
 import java.util.Collection;
+import java.util.Optional;
 import java.util.Set;
 
+import org.eclipse.jgit.internal.storage.commitgraph.CommitGraph;
 import org.eclipse.jgit.internal.storage.pack.ObjectToPack;
 import org.eclipse.jgit.internal.storage.pack.PackWriter;
 import org.eclipse.jgit.lib.AbbreviatedObjectId;
@@ -72,4 +74,6 @@ abstract InsertLooseObjectResult insertUnpackedObject(File tmp,
 	abstract Pack openPack(File pack) throws IOException;
 
 	abstract Collection<Pack> getPacks();
+
+	abstract Optional<CommitGraph> getCommitGraph();
 }
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/GC.java b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/GC.java
index 8c0aca5..d41aea4 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/GC.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/GC.java
@@ -14,6 +14,7 @@
 import static org.eclipse.jgit.internal.storage.pack.PackExt.INDEX;
 import static org.eclipse.jgit.internal.storage.pack.PackExt.KEEP;
 import static org.eclipse.jgit.internal.storage.pack.PackExt.PACK;
+import static org.eclipse.jgit.internal.storage.pack.PackExt.REVERSE_INDEX;
 
 import java.io.File;
 import java.io.FileOutputStream;
@@ -44,6 +45,7 @@
 import java.util.List;
 import java.util.Map;
 import java.util.Objects;
+import java.util.Optional;
 import java.util.Set;
 import java.util.TreeMap;
 import java.util.concurrent.CompletableFuture;
@@ -61,10 +63,13 @@
 import org.eclipse.jgit.errors.MissingObjectException;
 import org.eclipse.jgit.errors.NoWorkTreeException;
 import org.eclipse.jgit.internal.JGitText;
+import org.eclipse.jgit.internal.storage.commitgraph.CommitGraphWriter;
+import org.eclipse.jgit.internal.storage.commitgraph.GraphCommits;
 import org.eclipse.jgit.internal.storage.pack.PackExt;
 import org.eclipse.jgit.internal.storage.pack.PackWriter;
 import org.eclipse.jgit.lib.ConfigConstants;
 import org.eclipse.jgit.lib.Constants;
+import org.eclipse.jgit.lib.CoreConfig;
 import org.eclipse.jgit.lib.FileMode;
 import org.eclipse.jgit.lib.NullProgressMonitor;
 import org.eclipse.jgit.lib.ObjectId;
@@ -110,19 +115,17 @@ public class GC {
 	private static final Pattern PATTERN_LOOSE_OBJECT = Pattern
 			.compile("[0-9a-fA-F]{38}"); //$NON-NLS-1$
 
-	private static final String PACK_EXT = "." + PackExt.PACK.getExtension();//$NON-NLS-1$
+	private static final Set<PackExt> PARENT_EXTS = Set.of(PACK, KEEP);
 
-	private static final String BITMAP_EXT = "." //$NON-NLS-1$
-			+ PackExt.BITMAP_INDEX.getExtension();
-
-	private static final String INDEX_EXT = "." + PackExt.INDEX.getExtension(); //$NON-NLS-1$
-
-	private static final String KEEP_EXT = "." + PackExt.KEEP.getExtension(); //$NON-NLS-1$
+	private static final Set<PackExt> CHILD_EXTS = Set.of(BITMAP_INDEX, INDEX,
+			REVERSE_INDEX);
 
 	private static final int DEFAULT_AUTOPACKLIMIT = 50;
 
 	private static final int DEFAULT_AUTOLIMIT = 6700;
 
+	private static final boolean DEFAULT_WRITE_COMMIT_GRAPH = false;
+
 	private static volatile ExecutorService executor;
 
 	/**
@@ -268,6 +271,9 @@ private Collection<Pack> doGc() throws IOException, ParseException {
 		Collection<Pack> newPacks = repack();
 		prune(Collections.emptySet());
 		// TODO: implement rerere_gc(pm);
+		if (shouldWriteCommitGraphWhenGc()) {
+			writeCommitGraph(refsToObjectIds(getAllRefs()));
+		}
 		return newPacks;
 	}
 
@@ -881,6 +887,105 @@ public Collection<Pack> repack() throws IOException {
 		return ret;
 	}
 
+	private Set<ObjectId> refsToObjectIds(Collection<Ref> refs)
+			throws IOException {
+		Set<ObjectId> objectIds = new HashSet<>();
+		for (Ref ref : refs) {
+			checkCancelled();
+			if (ref.getPeeledObjectId() != null) {
+				objectIds.add(ref.getPeeledObjectId());
+				continue;
+			}
+
+			if (ref.getObjectId() != null) {
+				objectIds.add(ref.getObjectId());
+			}
+		}
+		return objectIds;
+	}
+
+	/**
+	 * Generate a new commit-graph file when 'core.commitGraph' is true.
+	 *
+	 * @param wants
+	 *            the list of wanted objects, writer walks commits starting at
+	 *            these. Must not be {@code null}.
+	 * @throws IOException
+	 */
+	void writeCommitGraph(@NonNull Set<? extends ObjectId> wants)
+			throws IOException {
+		if (!repo.getConfig().get(CoreConfig.KEY).enableCommitGraph()) {
+			return;
+		}
+		if (repo.getObjectDatabase().getShallowCommits().size() > 0) {
+			return;
+		}
+		checkCancelled();
+		if (wants.isEmpty()) {
+			return;
+		}
+		File tmpFile = null;
+		try (RevWalk walk = new RevWalk(repo)) {
+			CommitGraphWriter writer = new CommitGraphWriter(
+					GraphCommits.fromWalk(pm, wants, walk));
+			tmpFile = File.createTempFile("commit_", ".graph_tmp", //$NON-NLS-1$//$NON-NLS-2$
+					repo.getObjectDatabase().getInfoDirectory());
+			// write the commit-graph file
+			try (FileOutputStream fos = new FileOutputStream(tmpFile);
+					FileChannel channel = fos.getChannel();
+					OutputStream channelStream = Channels
+							.newOutputStream(channel)) {
+				writer.write(pm, channelStream);
+				channel.force(true);
+			}
+
+			// rename the temporary file to real file
+			File realFile = new File(repo.getObjectsDirectory(),
+					Constants.INFO_COMMIT_GRAPH);
+			FileUtils.rename(tmpFile, realFile, StandardCopyOption.ATOMIC_MOVE);
+		} finally {
+			if (tmpFile != null && tmpFile.exists()) {
+				tmpFile.delete();
+			}
+		}
+		deleteTempCommitGraph();
+	}
+
+	private void deleteTempCommitGraph() {
+		Path objectsDir = repo.getObjectDatabase().getInfoDirectory().toPath();
+		Instant threshold = Instant.now().minus(1, ChronoUnit.DAYS);
+		if (!Files.exists(objectsDir)) {
+			return;
+		}
+		try (DirectoryStream<Path> stream = Files.newDirectoryStream(objectsDir,
+				"commit_*_tmp")) { //$NON-NLS-1$
+			stream.forEach(t -> {
+				try {
+					Instant lastModified = Files.getLastModifiedTime(t)
+							.toInstant();
+					if (lastModified.isBefore(threshold)) {
+						Files.deleteIfExists(t);
+					}
+				} catch (IOException e) {
+					LOG.error(e.getMessage(), e);
+				}
+			});
+		} catch (IOException e) {
+			LOG.error(e.getMessage(), e);
+		}
+	}
+
+	/**
+	 * If {@code true}, will rewrite the commit-graph file when gc is run.
+	 *
+	 * @return true if commit-graph should be writen. Default is {@code false}.
+	 */
+	boolean shouldWriteCommitGraphWhenGc() {
+		return repo.getConfig().getBoolean(ConfigConstants.CONFIG_GC_SECTION,
+				ConfigConstants.CONFIG_KEY_WRITE_COMMIT_GRAPH,
+				DEFAULT_WRITE_COMMIT_GRAPH);
+	}
+
 	private static boolean isHead(Ref ref) {
 		return ref.getName().startsWith(Constants.R_HEADS);
 	}
@@ -941,47 +1046,52 @@ private void delete(Path d) {
 		}
 	}
 
+	private static Optional<PackFile> toPackFileWithValidExt(
+			Path packFilePath) {
+		try {
+			PackFile packFile = new PackFile(packFilePath.toFile());
+			if (packFile.getPackExt() == null) {
+				return Optional.empty();
+			}
+			return Optional.of(packFile);
+		} catch (IllegalArgumentException e) {
+			return Optional.empty();
+		}
+	}
+
 	/**
 	 * Deletes orphans
 	 * <p>
-	 * A file is considered an orphan if it is either a "bitmap" or an index
-	 * file, and its corresponding pack file is missing in the list.
+	 * A file is considered an orphan if it is some type of index file, but
+	 * there is not a corresponding pack or keep file present in the directory.
 	 * </p>
 	 */
 	private void deleteOrphans() {
 		Path packDir = repo.getObjectDatabase().getPackDirectory().toPath();
-		List<String> fileNames = null;
+		List<PackFile> childFiles;
+		Set<String> seenParentIds = new HashSet<>();
 		try (Stream<Path> files = Files.list(packDir)) {
-			fileNames = files.map(path -> path.getFileName().toString())
-					.filter(name -> (name.endsWith(PACK_EXT)
-							|| name.endsWith(BITMAP_EXT)
-							|| name.endsWith(INDEX_EXT)
-							|| name.endsWith(KEEP_EXT)))
-					// sort files with same base name in the order:
-					// .pack, .keep, .index, .bitmap to avoid look ahead
-					.sorted(Collections.reverseOrder())
-					.collect(Collectors.toList());
+			childFiles = files.map(GC::toPackFileWithValidExt)
+					.filter(Optional::isPresent).map(Optional::get)
+					.filter(packFile -> {
+						PackExt ext = packFile.getPackExt();
+						if (PARENT_EXTS.contains(ext)) {
+							seenParentIds.add(packFile.getId());
+							return false;
+						}
+						return CHILD_EXTS.contains(ext);
+					}).collect(Collectors.toList());
 		} catch (IOException e) {
 			LOG.error(e.getMessage(), e);
 			return;
 		}
-		if (fileNames == null) {
-			return;
-		}
 
-		String latestId = null;
-		for (String n : fileNames) {
-			PackFile pf = new PackFile(packDir.toFile(), n);
-			PackExt ext = pf.getPackExt();
-			if (ext.equals(PACK) || ext.equals(KEEP)) {
-				latestId = pf.getId();
-			}
-			if (latestId == null || !pf.getId().equals(latestId)) {
-				// no pack or keep for this id
+		for (PackFile child : childFiles) {
+			if (!seenParentIds.contains(child.getId())) {
 				try {
-					FileUtils.delete(pf,
+					FileUtils.delete(child,
 							FileUtils.RETRY | FileUtils.SKIP_MISSING);
-					LOG.warn(JGitText.get().deletedOrphanInPackDir, pf);
+					LOG.warn(JGitText.get().deletedOrphanInPackDir, child);
 				} catch (IOException e) {
 					LOG.error(e.getMessage(), e);
 				}
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/ObjectDirectory.java b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/ObjectDirectory.java
index 2bee58f..e341674 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/ObjectDirectory.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/ObjectDirectory.java
@@ -28,6 +28,7 @@
 import java.util.HashSet;
 import java.util.List;
 import java.util.Objects;
+import java.util.Optional;
 import java.util.Set;
 import java.util.concurrent.atomic.AtomicReference;
 
@@ -37,8 +38,10 @@
 import org.eclipse.jgit.internal.storage.pack.PackWriter;
 import org.eclipse.jgit.lib.AbbreviatedObjectId;
 import org.eclipse.jgit.lib.AnyObjectId;
+import org.eclipse.jgit.internal.storage.commitgraph.CommitGraph;
 import org.eclipse.jgit.lib.Config;
 import org.eclipse.jgit.lib.Constants;
+import org.eclipse.jgit.lib.CoreConfig;
 import org.eclipse.jgit.lib.ObjectDatabase;
 import org.eclipse.jgit.lib.ObjectId;
 import org.eclipse.jgit.lib.ObjectLoader;
@@ -85,6 +88,8 @@ public class ObjectDirectory extends FileObjectDatabase {
 
 	private final File alternatesFile;
 
+	private final FileCommitGraph fileCommitGraph;
+
 	private final FS fs;
 
 	private final AtomicReference<AlternateHandle[]> alternates;
@@ -124,6 +129,7 @@ public ObjectDirectory(final Config cfg, final File dir,
 		loose = new LooseObjects(config, objects);
 		packed = new PackDirectory(config, packDirectory);
 		preserved = new PackDirectory(config, preservedDirectory);
+		fileCommitGraph = new FileCommitGraph(objects);
 		this.fs = fs;
 		this.shallowFile = shallowFile;
 
@@ -227,6 +233,15 @@ public long getApproximateObjectCount() {
 		return count;
 	}
 
+	/** {@inheritDoc} */
+	@Override
+	public Optional<CommitGraph> getCommitGraph() {
+		if (config.get(CoreConfig.KEY).enableCommitGraph()) {
+			return Optional.ofNullable(fileCommitGraph.get());
+		}
+		return Optional.empty();
+	}
+
 	/**
 	 * {@inheritDoc}
 	 * <p>
@@ -805,4 +820,8 @@ CachedObjectDirectory newCachedFileObjectDatabase() {
 	AlternateHandle.Id getAlternateId() {
 		return handle.getId();
 	}
+
+	File getInfoDirectory() {
+		return infoDirectory;
+	}
 }
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/PackBitmapIndexV1.java b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/PackBitmapIndexV1.java
index 21aba3e..988dc6c 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/PackBitmapIndexV1.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/PackBitmapIndexV1.java
@@ -220,7 +220,7 @@ public int findPosition(AnyObjectId objectId) {
 		long offset = packIndex.findOffset(objectId);
 		if (offset == -1)
 			return -1;
-		return reverseIndex.findPostion(offset);
+		return reverseIndex.findPosition(offset);
 	}
 
 	/** {@inheritDoc} */
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/PackReverseIndex.java b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/PackReverseIndex.java
index ee458e2..1a5adb4 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/PackReverseIndex.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/PackReverseIndex.java
@@ -158,7 +158,7 @@ public long findNextOffset(long offset, long maxOffset)
 		return index.getOffset(nth[ith + 1]);
 	}
 
-	int findPostion(long offset) {
+	int findPosition(long offset) {
 		return binarySearch(offset);
 	}
 
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 348a22c..7f8f56b 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
@@ -111,11 +111,6 @@ public class RefDirectory extends RefDatabase {
 	/** If in the header, denotes the file has peeled data. */
 	public static final String PACKED_REFS_PEELED = " peeled"; //$NON-NLS-1$
 
-	/** The names of the additional refs supported by this class */
-	private static final String[] additionalRefsNames = new String[] {
-			Constants.MERGE_HEAD, Constants.FETCH_HEAD, Constants.ORIG_HEAD,
-			Constants.CHERRY_PICK_HEAD };
-
 	@SuppressWarnings("boxing")
 	private static final List<Integer> RETRY_SLEEP_MS =
 			Collections.unmodifiableList(Arrays.asList(0, 100, 200, 400, 800, 1600));
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/WindowCursor.java b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/WindowCursor.java
index e7fd7b9..fa743ba 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/WindowCursor.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/WindowCursor.java
@@ -16,6 +16,7 @@
 import java.util.Collections;
 import java.util.HashSet;
 import java.util.List;
+import java.util.Optional;
 import java.util.Set;
 import java.util.zip.DataFormatException;
 import java.util.zip.Inflater;
@@ -34,6 +35,7 @@
 import org.eclipse.jgit.lib.AnyObjectId;
 import org.eclipse.jgit.lib.BitmapIndex;
 import org.eclipse.jgit.lib.BitmapIndex.BitmapBuilder;
+import org.eclipse.jgit.internal.storage.commitgraph.CommitGraph;
 import org.eclipse.jgit.lib.Constants;
 import org.eclipse.jgit.lib.InflaterCache;
 import org.eclipse.jgit.lib.ObjectId;
@@ -96,6 +98,12 @@ public BitmapIndex getBitmapIndex() throws IOException {
 
 	/** {@inheritDoc} */
 	@Override
+	public Optional<CommitGraph> getCommitGraph() {
+		return db.getCommitGraph();
+	}
+
+	/** {@inheritDoc} */
+	@Override
 	public Collection<CachedPack> getCachedPacksAndUpdate(
 			BitmapBuilder needBitmap) throws IOException {
 		for (Pack pack : db.getPacks()) {
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/memory/TernarySearchTree.java b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/memory/TernarySearchTree.java
new file mode 100644
index 0000000..1ac6627
--- /dev/null
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/memory/TernarySearchTree.java
@@ -0,0 +1,597 @@
+/*
+ * Copyright (C) 2021, Matthias Sohn <matthias.sohn@sap.com> and others
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Distribution License v. 1.0 which is available at
+ * https://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+package org.eclipse.jgit.internal.storage.memory;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.Queue;
+import java.util.concurrent.atomic.AtomicInteger;
+import java.util.concurrent.locks.ReadWriteLock;
+import java.util.concurrent.locks.ReentrantReadWriteLock;
+
+import org.eclipse.jgit.annotations.Nullable;
+import org.eclipse.jgit.internal.JGitText;
+import org.eclipse.jgit.util.StringUtils;
+
+/**
+ * A ternary search tree with String keys and generic values.
+ *
+ * TernarySearchTree is a type of trie (sometimes called a prefix tree) where
+ * nodes are arranged in a manner similar to a binary search tree, but with up
+ * to three children rather than the binary tree's limit of two. Like other
+ * prefix trees, a ternary search tree can be used as an associative map
+ * structure with the ability for incremental string search. However, ternary
+ * search trees are more space efficient compared to standard prefix trees, at
+ * the cost of speed.
+ *
+ * Keys must not be null or empty. Values cannot be null.
+ *
+ * This class is thread safe.
+ *
+ * @param <Value>
+ *            type of values in this tree
+ * @since 6.5
+ */
+public final class TernarySearchTree<Value> {
+
+	private static final char WILDCARD = '?';
+
+	private static class Node<Value> {
+		final char c;
+
+		Node<Value> lo, eq, hi;
+
+		Value val;
+
+		Node(char c) {
+			this.c = c;
+		}
+
+		boolean hasValue() {
+			return val != null;
+		}
+	}
+
+	/**
+	 * Loader to load key-value pairs to be cached in the tree
+	 *
+	 * @param <Value>
+	 *            type of values
+	 */
+	public static interface Loader<Value> {
+		/**
+		 * Load map of all key value pairs
+		 *
+		 * @return map of all key value pairs to cache in the tree
+		 */
+		Map<String, Value> loadAll();
+	}
+
+	private static void validateKey(String key) {
+		if (StringUtils.isEmptyOrNull(key)) {
+			throw new IllegalArgumentException(
+					JGitText.get().illegalTernarySearchTreeKey);
+		}
+	}
+
+	private static <V> void validateValue(V value) {
+		if (value == null) {
+			throw new IllegalArgumentException(
+					JGitText.get().illegalTernarySearchTreeValue);
+		}
+	}
+
+	private final ReadWriteLock lock;
+
+	private final AtomicInteger size = new AtomicInteger(0);
+
+	private Node<Value> root;
+
+	/**
+	 * Construct a new ternary search tree
+	 */
+	public TernarySearchTree() {
+		lock = new ReentrantReadWriteLock();
+	}
+
+	/**
+	 * Get the lock guarding read and write access to the cache.
+	 *
+	 * @return lock guarding read and write access to the cache
+	 */
+	public ReadWriteLock getLock() {
+		return lock;
+	}
+
+	/**
+	 * Replace the tree with a new tree containing all entries provided by an
+	 * iterable
+	 *
+	 * @param loader
+	 *            iterable providing key-value pairs to load
+	 * @return number of key-value pairs after replacing finished
+	 */
+	public int replace(Iterable<Entry<String, Value>> loader) {
+		lock.writeLock().lock();
+		try {
+			clear();
+			for (Entry<String, Value> e : loader) {
+				insertImpl(e.getKey(), e.getValue());
+			}
+		} finally {
+			lock.writeLock().unlock();
+		}
+		return size.get();
+	}
+
+	/**
+	 * Reload the tree entries provided by loader
+	 *
+	 * @param loader
+	 *            iterable providing key-value pairs to load
+	 * @return number of key-value pairs
+	 */
+	public int reload(Iterable<Entry<String, Value>> loader) {
+		lock.writeLock().lock();
+		try {
+			for (Entry<String, Value> e : loader) {
+				insertImpl(e.getKey(), e.getValue());
+			}
+		} finally {
+			lock.writeLock().unlock();
+		}
+		return size.get();
+	}
+
+	/**
+	 * Delete entries
+	 *
+	 * @param delete
+	 *            iterable providing keys of entries to be deleted
+	 * @return number of key-value pairs
+	 */
+	public int delete(Iterable<String> delete) {
+		lock.writeLock().lock();
+		try {
+			for (String s : delete) {
+				delete(s);
+			}
+		} finally {
+			lock.writeLock().unlock();
+		}
+		return size.get();
+	}
+
+	/**
+	 * Get the number of key value pairs in this trie
+	 *
+	 * @return number of key value pairs in this trie
+	 */
+	public int size() {
+		return size.get();
+	}
+
+	/**
+	 * Get the value associated to a key or {@code null}.
+	 *
+	 * @param key
+	 *            the key
+	 * @return the value associated to this key
+	 */
+	@Nullable
+	public Value get(String key) {
+		validateKey(key);
+		lock.readLock().lock();
+		try {
+			Node<Value> node = get(root, key, 0);
+			if (node == null) {
+				return null;
+			}
+			return node.val;
+		} finally {
+			lock.readLock().unlock();
+		}
+	}
+
+	/**
+	 * Check whether this tree contains the given key.
+	 *
+	 * @param key
+	 *            a key
+	 * @return whether this tree contains this key
+	 */
+	public boolean contains(String key) {
+		return get(key) != null;
+	}
+
+	/**
+	 * Insert a key-value pair. If the key already exists the old value is
+	 * overwritten.
+	 *
+	 * @param key
+	 *            the key
+	 * @param value
+	 *            the value
+	 * @return number of key-value pairs after adding the entry
+	 */
+	public int insert(String key, Value value) {
+		lock.writeLock().lock();
+		try {
+			insertImpl(key, value);
+			return size.get();
+		} finally {
+			lock.writeLock().unlock();
+		}
+	}
+
+	/**
+	 * Insert map of key-value pairs. Values of existing keys are overwritten.
+	 * Use this method to insert multiple key-value pairs.
+	 *
+	 * @param map
+	 *            map of key-value pairs to insert
+	 * @return number of key-value pairs after adding entries
+	 */
+	public int insert(Map<String, Value> map) {
+		lock.writeLock().lock();
+		try {
+			for (Entry<String, Value> e : map.entrySet()) {
+				insertImpl(e.getKey(), e.getValue());
+			}
+			return size.get();
+		} finally {
+			lock.writeLock().unlock();
+		}
+	}
+
+	private void insertImpl(String key, Value value) {
+		validateValue(value);
+		if (!contains(key)) {
+			size.addAndGet(1);
+		}
+		root = insert(root, key, value, 0);
+	}
+
+	/**
+	 * Delete a key-value pair. Does nothing if the key doesn't exist.
+	 *
+	 * @param key
+	 *            the key
+	 * @return number of key-value pairs after the deletion
+	 */
+	public int delete(String key) {
+		lock.writeLock().lock();
+		try {
+			if (contains(key)) {
+				size.addAndGet(-1);
+				root = insert(root, key, null, 0);
+			}
+			return size.get();
+		} finally {
+			lock.writeLock().unlock();
+		}
+	}
+
+	/**
+	 * Remove all key value pairs from this tree
+	 */
+	public void clear() {
+		lock.writeLock().lock();
+		try {
+			size.set(0);
+			root = null;
+		} finally {
+			lock.writeLock().unlock();
+		}
+	}
+
+	/**
+	 * Find the key which is the longest prefix of the given query string.
+	 *
+	 * @param query
+	 * @return the key which is the longest prefix of the given query string or
+	 *         {@code null} if none exists.
+	 */
+	@Nullable
+	public String keyLongestPrefixOf(String query) {
+		if (StringUtils.isEmptyOrNull(query)) {
+			return null;
+		}
+		lock.readLock().lock();
+		try {
+			int length = 0;
+			Node<Value> node = root;
+			int i = 0;
+			while (node != null && i < query.length()) {
+				char c = query.charAt(i);
+				if (node.c > c) {
+					node = node.lo;
+				} else if (node.c < c) {
+					node = node.hi;
+				} else {
+					i++;
+					if (node.hasValue()) {
+						length = i;
+					}
+					node = node.eq;
+				}
+			}
+			return query.substring(0, length);
+		} finally {
+			lock.readLock().unlock();
+		}
+	}
+
+	/**
+	 * Get all keys.
+	 *
+	 * @return all keys
+	 */
+	public Iterable<String> getKeys() {
+		Queue<String> queue = new LinkedList<>();
+		lock.readLock().lock();
+		try {
+			findKeysWithPrefix(root, new StringBuilder(), queue);
+			return queue;
+		} finally {
+			lock.readLock().unlock();
+		}
+	}
+
+	/**
+	 * Get keys starting with given prefix
+	 *
+	 * @param prefix
+	 *            key prefix
+	 * @return keys starting with given prefix
+	 */
+	public Iterable<String> getKeysWithPrefix(String prefix) {
+		Queue<String> keys = new LinkedList<>();
+		if (prefix == null) {
+			return keys;
+		}
+		if (prefix.isEmpty()) {
+			return getKeys();
+		}
+		lock.readLock().lock();
+		try {
+			validateKey(prefix);
+			Node<Value> node = get(root, prefix, 0);
+			if (node == null) {
+				return keys;
+			}
+			if (node.hasValue()) {
+				keys.add(prefix);
+			}
+			findKeysWithPrefix(node.eq, new StringBuilder(prefix), keys);
+			return keys;
+		} finally {
+			lock.readLock().unlock();
+		}
+	}
+
+	/**
+	 * Get all entries.
+	 *
+	 * @return all entries
+	 */
+	public Map<String, Value> getAll() {
+		Map<String, Value> entries = new HashMap<>();
+		lock.readLock().lock();
+		try {
+			findWithPrefix(root, new StringBuilder(), entries);
+			return entries;
+		} finally {
+			lock.readLock().unlock();
+		}
+	}
+
+	/**
+	 * Get all values.
+	 *
+	 * @return all values
+	 */
+	public List<Value> getAllValues() {
+		List<Value> values = new ArrayList<>();
+		lock.readLock().lock();
+		try {
+			findValuesWithPrefix(root, new StringBuilder(), values);
+			return values;
+		} finally {
+			lock.readLock().unlock();
+		}
+	}
+
+	/**
+	 * Get all entries with given prefix
+	 *
+	 * @param prefix
+	 *            key prefix
+	 * @return entries with given prefix
+	 */
+	public Map<String, Value> getWithPrefix(String prefix) {
+		Map<String, Value> entries = new HashMap<>();
+		if (prefix == null) {
+			return entries;
+		}
+		if (prefix.isEmpty()) {
+			return getAll();
+		}
+		lock.readLock().lock();
+		try {
+			validateKey(prefix);
+			Node<Value> node = get(root, prefix, 0);
+			if (node == null) {
+				return entries;
+			}
+			if (node.hasValue()) {
+				entries.put(prefix, node.val);
+			}
+			findWithPrefix(node.eq, new StringBuilder(prefix), entries);
+			return entries;
+		} finally {
+			lock.readLock().unlock();
+		}
+	}
+
+	/**
+	 * Get all values with given key prefix
+	 *
+	 * @param prefix
+	 *            key prefix
+	 * @return entries with given prefix
+	 */
+	public List<Value> getValuesWithPrefix(String prefix) {
+		List<Value> values = new ArrayList<>();
+		if (prefix == null) {
+			return values;
+		}
+		if (prefix.isEmpty()) {
+			return getAllValues();
+		}
+		lock.readLock().lock();
+		try {
+			validateKey(prefix);
+			Node<Value> node = get(root, prefix, 0);
+			if (node == null) {
+				return values;
+			}
+			if (node.hasValue()) {
+				values.add(node.val);
+			}
+			findValuesWithPrefix(node.eq, new StringBuilder(prefix), values);
+			return values;
+		} finally {
+			lock.readLock().unlock();
+		}
+	}
+
+	/**
+	 * Get keys matching given pattern using '?' as wildcard character.
+	 *
+	 * @param pattern
+	 *            search pattern
+	 * @return keys matching given pattern.
+	 */
+	public Iterable<String> getKeysMatching(String pattern) {
+		Queue<String> keys = new LinkedList<>();
+		lock.readLock().lock();
+		try {
+			findKeysWithPrefix(root, new StringBuilder(), 0, pattern, keys);
+			return keys;
+		} finally {
+			lock.readLock().unlock();
+		}
+	}
+
+	private Node<Value> get(Node<Value> node, String key, int depth) {
+		if (node == null) {
+			return null;
+		}
+		char c = key.charAt(depth);
+		if (node.c > c) {
+			return get(node.lo, key, depth);
+		} else if (node.c < c) {
+			return get(node.hi, key, depth);
+		} else if (depth < key.length() - 1) {
+			return get(node.eq, key, depth + 1);
+		} else {
+			return node;
+		}
+	}
+
+	private Node<Value> insert(Node<Value> node, String key, Value val,
+			int depth) {
+		char c = key.charAt(depth);
+		if (node == null) {
+			node = new Node<>(c);
+		}
+		if (node.c > c) {
+			node.lo = insert(node.lo, key, val, depth);
+		} else if (node.c < c) {
+			node.hi = insert(node.hi, key, val, depth);
+		} else if (depth < key.length() - 1) {
+			node.eq = insert(node.eq, key, val, depth + 1);
+		} else {
+			node.val = val;
+		}
+		return node;
+	}
+
+	private void findKeysWithPrefix(Node<Value> node, StringBuilder prefix,
+			Queue<String> keys) {
+		if (node == null) {
+			return;
+		}
+		findKeysWithPrefix(node.lo, prefix, keys);
+		if (node.hasValue()) {
+			keys.add(prefix.toString() + node.c);
+		}
+		findKeysWithPrefix(node.eq, prefix.append(node.c), keys);
+		prefix.deleteCharAt(prefix.length() - 1);
+		findKeysWithPrefix(node.hi, prefix, keys);
+	}
+
+	private void findWithPrefix(Node<Value> node, StringBuilder prefix,
+			Map<String, Value> entries) {
+		if (node == null) {
+			return;
+		}
+		findWithPrefix(node.lo, prefix, entries);
+		if (node.hasValue()) {
+			entries.put(prefix.toString() + node.c, node.val);
+		}
+		findWithPrefix(node.eq, prefix.append(node.c), entries);
+		prefix.deleteCharAt(prefix.length() - 1);
+		findWithPrefix(node.hi, prefix, entries);
+	}
+
+	private void findValuesWithPrefix(Node<Value> node, StringBuilder prefix,
+			List<Value> values) {
+		if (node == null) {
+			return;
+		}
+		findValuesWithPrefix(node.lo, prefix, values);
+		if (node.hasValue()) {
+			values.add(node.val);
+		}
+		findValuesWithPrefix(node.eq, prefix.append(node.c), values);
+		prefix.deleteCharAt(prefix.length() - 1);
+		findValuesWithPrefix(node.hi, prefix, values);
+	}
+
+	private void findKeysWithPrefix(Node<Value> node, StringBuilder prefix,
+			int i, String pattern, Queue<String> keys) {
+		if (node == null || StringUtils.isEmptyOrNull(pattern)) {
+			return;
+		}
+		char c = pattern.charAt(i);
+		if (c == WILDCARD || node.c > c) {
+			findKeysWithPrefix(node.lo, prefix, i, pattern, keys);
+		}
+		if (c == WILDCARD || node.c == c) {
+			if (i == pattern.length() - 1 && node.hasValue()) {
+				keys.add(prefix.toString() + node.c);
+			}
+			if (i < pattern.length() - 1) {
+				findKeysWithPrefix(node.eq, prefix.append(node.c), i + 1,
+						pattern, keys);
+				prefix.deleteCharAt(prefix.length() - 1);
+			}
+		}
+		if (c == WILDCARD || node.c < c) {
+			findKeysWithPrefix(node.hi, prefix, i, pattern, keys);
+		}
+	}
+}
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/pack/PackExt.java b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/pack/PackExt.java
index c006995..1d02c02 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/pack/PackExt.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/pack/PackExt.java
@@ -30,7 +30,10 @@ public enum PackExt {
 	REFTABLE("ref"), //$NON-NLS-1$
 
 	/** A pack reverse index file extension. */
-	REVERSE_INDEX("rev"); //$NON-NLS-1$
+	REVERSE_INDEX("rev"), //$NON-NLS-1$
+
+	/** A commit graph file extension. */
+	COMMIT_GRAPH("graph"); //$NON-NLS-1$
 
 	private final String ext;
 
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/pack/PackWriter.java b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/pack/PackWriter.java
index 8653c32..d42d348 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/pack/PackWriter.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/pack/PackWriter.java
@@ -2371,10 +2371,14 @@ public boolean prepareBitmapIndex(ProgressMonitor pm) throws IOException {
 
 		int numCommits = objectsLists[OBJ_COMMIT].size();
 		List<ObjectToPack> byName = sortByName();
+		// Reset sortedByName before the array that it points to is mutated by
+		// PackBitmapIndexBuilder, to prevent other methods referencing the
+		// mutated array afterwards.
 		sortedByName = null;
 		objectsLists = null;
 		objectsMap = null;
 		writeBitmaps = new PackBitmapIndexBuilder(byName);
+		// Allow byName to be GC'd if JVM GC runs before the end of the method.
 		byName = null;
 
 		PackWriterBitmapPreparer bitmapPreparer = new PackWriterBitmapPreparer(
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 ef1379a..e2bebfe 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/lib/BatchRefUpdate.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/lib/BatchRefUpdate.java
@@ -498,17 +498,14 @@ public void execute(RevWalk walk, ProgressMonitor monitor,
 				try {
 					if (cmd.getResult() == NOT_ATTEMPTED) {
 						cmd.updateType(walk);
-						RefUpdate ru = newUpdate(cmd);
 						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:
+								RefUpdate ru = newUpdate(cmd);
 								cmd.setResult(ru.update(walk));
 								break;
 						}
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 011c9fa..ed4bf31 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/lib/ConfigConstants.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/lib/ConfigConstants.java
@@ -893,6 +893,20 @@ public final class ConfigConstants {
 	public static final String CONFIG_KEY_ABBREV = "abbrev";
 
 	/**
+	 * The "writeCommitGraph" key
+	 *
+	 * @since 6.5
+	 */
+	public static final String CONFIG_KEY_WRITE_COMMIT_GRAPH = "writeCommitGraph";
+
+	/**
+	 * The "commitGraph" used by commit-graph feature
+	 *
+	 * @since 6.5
+	 */
+	public static final String CONFIG_COMMIT_GRAPH = "commitGraph";
+
+	/**
 	 * The "trustPackedRefsStat" key
 	 *
 	 * @since 6.1.1
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/lib/Constants.java b/org.eclipse.jgit/src/org/eclipse/jgit/lib/Constants.java
index 30a0074..0b8bf8c 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/lib/Constants.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/lib/Constants.java
@@ -284,6 +284,12 @@ public final class Constants {
 	 */
 	public static final String INFO_HTTP_ALTERNATES = "info/http-alternates";
 
+	/**
+	 * info commit-graph file (goes under OBJECTS)
+	 * @since 6.5
+	 */
+	public static final String INFO_COMMIT_GRAPH = "info/commit-graph";
+
 	/** Packed refs file */
 	public static final String PACKED_REFS = "packed-refs";
 
@@ -754,6 +760,23 @@ public static int decodeTypeString(final AnyObjectId id,
 	 */
 	public static final int INFINITE_DEPTH = 0x7fffffff;
 
+	/**
+	 * We use ({@value}) as generation number for commits not in the
+	 * commit-graph file.
+	 *
+	 * @since 6.5
+	 */
+	public static int COMMIT_GENERATION_UNKNOWN = Integer.MAX_VALUE;
+
+	/**
+	 * If a commit-graph file was written by a version of Git that did not
+	 * compute generation numbers, then those commits will have generation
+	 * number represented by ({@value}).
+	 *
+	 * @since 6.5
+	 */
+	public static int COMMIT_GENERATION_NOT_COMPUTED = 0;
+
 	private Constants() {
 		// Hide the default constructor
 	}
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/lib/CoreConfig.java b/org.eclipse.jgit/src/org/eclipse/jgit/lib/CoreConfig.java
index fc82a5f..4de1801 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/lib/CoreConfig.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/lib/CoreConfig.java
@@ -117,6 +117,13 @@ public enum LogRefUpdates {
 	}
 
 	/**
+	 * Default value of commit graph enable option: {@value}
+	 *
+	 * @since 6.5
+	 */
+	public static final boolean DEFAULT_COMMIT_GRAPH_ENABLE = false;
+
+	/**
 	 * Permissible values for {@code core.trustPackedRefsStat}.
 	 *
 	 * @since 6.1.1
@@ -147,6 +154,8 @@ public enum TrustPackedRefsStat {
 
 	private final String attributesfile;
 
+	private final boolean commitGraph;
+
 	/**
 	 * Options for symlink handling
 	 *
@@ -188,6 +197,9 @@ private CoreConfig(Config rc) {
 				ConfigConstants.CONFIG_KEY_EXCLUDESFILE);
 		attributesfile = rc.getString(ConfigConstants.CONFIG_CORE_SECTION,
 				null, ConfigConstants.CONFIG_KEY_ATTRIBUTESFILE);
+		commitGraph = rc.getBoolean(ConfigConstants.CONFIG_CORE_SECTION,
+				ConfigConstants.CONFIG_COMMIT_GRAPH,
+				DEFAULT_COMMIT_GRAPH_ENABLE);
 	}
 
 	/**
@@ -240,4 +252,16 @@ public String getExcludesFile() {
 	public String getAttributesFile() {
 		return attributesfile;
 	}
+
+	/**
+	 * Whether to read the commit-graph file (if it exists) to parse the graph
+	 * structure of commits. Default to
+	 * {@value org.eclipse.jgit.lib.CoreConfig#DEFAULT_COMMIT_GRAPH_ENABLE}.
+	 *
+	 * @return whether to read the commit-graph file
+	 * @since 6.5
+	 */
+	public boolean enableCommitGraph() {
+		return commitGraph;
+	}
 }
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/lib/ObjectReader.java b/org.eclipse.jgit/src/org/eclipse/jgit/lib/ObjectReader.java
index 081f40e..ae0cf42 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/lib/ObjectReader.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/lib/ObjectReader.java
@@ -17,6 +17,7 @@
 import java.util.Collection;
 import java.util.Iterator;
 import java.util.List;
+import java.util.Optional;
 import java.util.Set;
 
 import org.eclipse.jgit.annotations.NonNull;
@@ -27,6 +28,7 @@
 import org.eclipse.jgit.internal.revwalk.BitmappedReachabilityChecker;
 import org.eclipse.jgit.internal.revwalk.PedestrianObjectReachabilityChecker;
 import org.eclipse.jgit.internal.revwalk.PedestrianReachabilityChecker;
+import org.eclipse.jgit.internal.storage.commitgraph.CommitGraph;
 import org.eclipse.jgit.revwalk.ObjectReachabilityChecker;
 import org.eclipse.jgit.revwalk.ObjectWalk;
 import org.eclipse.jgit.revwalk.ReachabilityChecker;
@@ -500,6 +502,23 @@ public ObjectReachabilityChecker createObjectReachabilityChecker(
 	}
 
 	/**
+	 * Get the commit-graph for this repository if available.
+	 * <p>
+	 * The commit graph can be created/modified/deleted while the repository is
+	 * open and specific implementations decide when to refresh it.
+	 *
+	 * @return the commit-graph or empty if the commit-graph does not exist or
+	 *         is invalid; always returns empty when core.commitGraph is false
+	 *         (default is
+	 *         {@value org.eclipse.jgit.lib.CoreConfig#DEFAULT_COMMIT_GRAPH_ENABLE}).
+	 *
+	 * @since 6.5
+	 */
+	public Optional<CommitGraph> getCommitGraph() {
+		return Optional.empty();
+	}
+
+	/**
 	 * Get the {@link org.eclipse.jgit.lib.ObjectInserter} from which this
 	 * reader was created using {@code inserter.newReader()}
 	 *
@@ -642,6 +661,11 @@ public BitmapIndex getBitmapIndex() throws IOException {
 		}
 
 		@Override
+		public Optional<CommitGraph> getCommitGraph() {
+			return delegate().getCommitGraph();
+		}
+
+		@Override
 		@Nullable
 		public ObjectInserter getCreatedFromInserter() {
 			return delegate().getCreatedFromInserter();
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/lib/RefDatabase.java b/org.eclipse.jgit/src/org/eclipse/jgit/lib/RefDatabase.java
index 7b7bdeb..98089fb 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/lib/RefDatabase.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/lib/RefDatabase.java
@@ -40,10 +40,10 @@ public abstract class RefDatabase {
 	/**
 	 * Order of prefixes to search when using non-absolute references.
 	 * <p>
-	 * {@link #findRef(String)} takes this search space into consideration
-	 * when locating a reference by name. The first entry in the path is
-	 * always {@code ""}, ensuring that absolute references are resolved
-	 * without further mangling.
+	 * {@link #findRef(String)} takes this search space into consideration when
+	 * locating a reference by name. The first entry in the path is always
+	 * {@code ""}, ensuring that absolute references are resolved without
+	 * further mangling.
 	 */
 	protected static final String[] SEARCH_PATH = { "", //$NON-NLS-1$
 			Constants.R_REFS, //
@@ -69,6 +69,15 @@ public abstract class RefDatabase {
 	public static final String ALL = "";//$NON-NLS-1$
 
 	/**
+	 * The names of additional refs
+	 *
+	 * @since 6.5
+	 */
+	protected static final String[] additionalRefsNames = new String[] {
+			Constants.MERGE_HEAD, Constants.FETCH_HEAD, Constants.ORIG_HEAD,
+			Constants.CHERRY_PICK_HEAD, Constants.REVERT_HEAD };
+
+	/**
 	 * Initialize a new reference database at this location.
 	 *
 	 * @throws java.io.IOException
@@ -341,12 +350,12 @@ public Ref firstExactRef(String... refs) throws IOException {
 	/**
 	 * Returns all refs.
 	 * <p>
-	 * This includes {@code HEAD}, branches under {@code ref/heads/}, tags
-	 * under {@code refs/tags/}, etc. It does not include pseudo-refs like
+	 * This includes {@code HEAD}, branches under {@code ref/heads/}, tags under
+	 * {@code refs/tags/}, etc. It does not include pseudo-refs like
 	 * {@code FETCH_HEAD}; for those, see {@link #getAdditionalRefs}.
 	 * <p>
-	 * Symbolic references to a non-existent ref (for example,
-	 * {@code HEAD} pointing to a branch yet to be born) are not included.
+	 * Symbolic references to a non-existent ref (for example, {@code HEAD}
+	 * pointing to a branch yet to be born) are not included.
 	 * <p>
 	 * Callers interested in only a portion of the ref hierarchy can call
 	 * {@link #getRefsByPrefix} instead.
@@ -386,8 +395,9 @@ public List<Ref> getRefs() throws IOException {
 	 * {@link RefDatabase} should override this method directly if a better
 	 * implementation is possible.
 	 *
-	 * @param prefix string that names of refs should start with; may be
-	 *             empty (to return all refs).
+	 * @param prefix
+	 *            string that names of refs should start with; may be empty (to
+	 *            return all refs).
 	 * @return immutable list of refs whose names start with {@code prefix}.
 	 * @throws java.io.IOException
 	 *             the reference space cannot be accessed.
@@ -417,18 +427,22 @@ public List<Ref> getRefsByPrefix(String prefix) throws IOException {
 	}
 
 	/**
-	 * Returns refs whose names start with a given prefix excluding all refs that
-	 * start with one of the given prefixes.
+	 * Returns refs whose names start with a given prefix excluding all refs
+	 * that start with one of the given prefixes.
 	 *
 	 * <p>
-	 * The default implementation is not efficient. Implementors of {@link RefDatabase}
-	 * should override this method directly if a better implementation is possible.
-	 * 
-	 * @param include string that names of refs should start with; may be empty.
-	 * @param excludes strings that names of refs can't start with; may be empty.
-	 * @return immutable list of refs whose names start with {@code prefix} and none
-	 *         of the strings in {@code exclude}.
-	 * @throws java.io.IOException the reference space cannot be accessed.
+	 * The default implementation is not efficient. Implementors of
+	 * {@link RefDatabase} should override this method directly if a better
+	 * implementation is possible.
+	 *
+	 * @param include
+	 *            string that names of refs should start with; may be empty.
+	 * @param excludes
+	 *            strings that names of refs can't start with; may be empty.
+	 * @return immutable list of refs whose names start with {@code prefix} and
+	 *         none of the strings in {@code exclude}.
+	 * @throws java.io.IOException
+	 *             the reference space cannot be accessed.
 	 * @since 5.11
 	 */
 	@NonNull
@@ -492,13 +506,14 @@ public Set<Ref> getTipsWithSha1(ObjectId id) throws IOException {
 	}
 
 	/**
-	 * If the ref database does not support fast inverse queries, it may
-	 * be advantageous to build a complete SHA1 to ref map in advance for
-	 * multiple uses. To let applications decide on this decision,
-	 * this function indicates whether the inverse map is available.
+	 * If the ref database does not support fast inverse queries, it may be
+	 * advantageous to build a complete SHA1 to ref map in advance for multiple
+	 * uses. To let applications decide on this decision, this function
+	 * indicates whether the inverse map is available.
 	 *
 	 * @return whether this RefDatabase supports fast inverse ref queries.
-	 * @throws IOException on I/O problems.
+	 * @throws IOException
+	 *             on I/O problems.
 	 * @since 5.6
 	 */
 	public boolean hasFastTipsWithSha1() throws IOException {
@@ -509,10 +524,10 @@ public boolean hasFastTipsWithSha1() throws IOException {
 	 * Check if any refs exist in the ref database.
 	 * <p>
 	 * This uses the same definition of refs as {@link #getRefs()}. In
-	 * particular, returns {@code false} in a new repository with no refs
-	 * under {@code refs/} and {@code HEAD} pointing to a branch yet to be
-	 * born, and returns {@code true} in a repository with no refs under
-	 * {@code refs/} and a detached {@code HEAD} pointing to history.
+	 * particular, returns {@code false} in a new repository with no refs under
+	 * {@code refs/} and {@code HEAD} pointing to a branch yet to be born, and
+	 * returns {@code true} in a repository with no refs under {@code refs/} and
+	 * a detached {@code HEAD} pointing to history.
 	 *
 	 * @return true if the database has refs.
 	 * @throws java.io.IOException
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/lib/RefWriter.java b/org.eclipse.jgit/src/org/eclipse/jgit/lib/RefWriter.java
index c80d80f..d2c3f9d 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/lib/RefWriter.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/lib/RefWriter.java
@@ -138,8 +138,7 @@ public void writePackedRefs() throws IOException {
 		final StringWriter w = new StringWriter();
 		if (peeled) {
 			w.write(RefDirectory.PACKED_REFS_HEADER);
-			if (peeled)
-				w.write(RefDirectory.PACKED_REFS_PEELED);
+			w.write(RefDirectory.PACKED_REFS_PEELED);
 			w.write('\n');
 		}
 
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/patch/PatchApplier.java b/org.eclipse.jgit/src/org/eclipse/jgit/patch/PatchApplier.java
index ca8ea5d..2a4de13 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/patch/PatchApplier.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/patch/PatchApplier.java
@@ -24,6 +24,7 @@
 import java.text.MessageFormat;
 import java.time.Instant;
 import java.util.ArrayList;
+import java.util.Arrays;
 import java.util.HashSet;
 import java.util.Iterator;
 import java.util.List;
@@ -68,12 +69,14 @@
 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.LfsFactory;
 import org.eclipse.jgit.util.LfsFactory.LfsInputStream;
 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;
@@ -91,6 +94,9 @@
  */
 public class PatchApplier {
 
+	private static final byte[] NO_EOL = "\\ No newline at end of file" //$NON-NLS-1$
+			.getBytes(StandardCharsets.US_ASCII);
+
 	/** The tree before applying the patch. Only non-null for inCore operation. */
 	@Nullable
 	private final RevTree beforeTree;
@@ -180,7 +186,7 @@ public ObjectId getTreeId() {
 	public Result applyPatch(InputStream patchInput)
 			throws PatchFormatException, PatchApplyException {
 		Result result = new Result();
-		org.eclipse.jgit.patch.Patch p = new org.eclipse.jgit.patch.Patch();
+		Patch p = new Patch();
 		try (InputStream inStream = patchInput) {
 			p.parse(inStream);
 
@@ -193,7 +199,7 @@ public Result applyPatch(InputStream patchInput)
 
 			DirCacheBuilder dirCacheBuilder = dirCache.builder();
 			Set<String> modifiedPaths = new HashSet<>();
-			for (org.eclipse.jgit.patch.FileHeader fh : p.getFiles()) {
+			for (FileHeader fh : p.getFiles()) {
 				ChangeType type = fh.getChangeType();
 				switch (type) {
 				case ADD: {
@@ -345,8 +351,8 @@ private TreeWalk getTreeWalkForFile(String path, DirCache cache)
 	 * @throws PatchApplyException
 	 */
 	private void apply(String pathWithOriginalContent, DirCache dirCache,
-			DirCacheBuilder dirCacheBuilder, @Nullable File f,
-			org.eclipse.jgit.patch.FileHeader fh) throws PatchApplyException {
+			DirCacheBuilder dirCacheBuilder, @Nullable File f, FileHeader fh)
+			throws PatchApplyException {
 		if (PatchType.BINARY.equals(fh.getPatchType())) {
 			// This patch type just says "something changed". We can't do
 			// anything with that.
@@ -484,7 +490,7 @@ private DirCacheEntry insertToIndex(InputStream input, byte[] path,
 		}
 		dce.setLength(length);
 
-		try (LfsInputStream is = org.eclipse.jgit.util.LfsFactory.getInstance()
+		try (LfsInputStream is = LfsFactory.getInstance()
 				.applyCleanFilter(repo, input, length, lfsAttribute)) {
 			dce.setObjectId(inserter.insert(OBJ_BLOB, is.getLength(), is));
 		}
@@ -522,15 +528,13 @@ private RawText getRawText(@Nullable File file,
 			// conversion.
 			try (InputStream input = filterClean(repo, path,
 					fileStreamSupplier.load(), convertCrLf, filterCommand)) {
-				return new RawText(org.eclipse.jgit.util.IO
-						.readWholeStream(input, 0).array());
+				return new RawText(IO.readWholeStream(input, 0).array());
 			}
 		}
 		if (convertCrLf) {
 			try (InputStream input = EolStreamTypeUtil.wrapInputStream(
 					fileStreamSupplier.load(), EolStreamType.TEXT_LF)) {
-				return new RawText(org.eclipse.jgit.util.IO
-						.readWholeStream(input, 0).array());
+				return new RawText(IO.readWholeStream(input, 0).array());
 			}
 		}
 		if (inCore() && fileId.equals(ObjectId.zeroId())) {
@@ -547,12 +551,12 @@ private InputStream filterClean(Repository repository, String path,
 			input = EolStreamTypeUtil.wrapInputStream(input,
 					EolStreamType.TEXT_LF);
 		}
-		if (org.eclipse.jgit.util.StringUtils.isEmptyOrNull(filterCommand)) {
+		if (StringUtils.isEmptyOrNull(filterCommand)) {
 			return input;
 		}
 		if (FilterCommandRegistry.isRegistered(filterCommand)) {
-			LocalFile buffer = new org.eclipse.jgit.util.TemporaryBuffer.LocalFile(
-					null, inCoreSizeLimit);
+			LocalFile buffer = new TemporaryBuffer.LocalFile(null,
+					inCoreSizeLimit);
 			FilterCommand command = FilterCommandRegistry.createFilterCommand(
 					filterCommand, repository, input, buffer);
 			while (command.run() != -1) {
@@ -560,7 +564,7 @@ private InputStream filterClean(Repository repository, String path,
 			}
 			return buffer.openInputStreamWithAutoDestroy();
 		}
-		org.eclipse.jgit.util.FS fs = repository.getFS();
+		FS fs = repository.getFS();
 		ProcessBuilder filterProcessBuilder = fs.runInShell(filterCommand,
 				new String[0]);
 		filterProcessBuilder.directory(repository.getWorkTree());
@@ -577,14 +581,14 @@ private InputStream filterClean(Repository repository, String path,
 		if (rc != 0) {
 			throw new IOException(new FilterFailedException(rc, filterCommand,
 					path, result.getStdout().toByteArray(4096),
-					org.eclipse.jgit.util.RawParseUtils
+					RawParseUtils
 							.decode(result.getStderr().toByteArray(4096))));
 		}
 		return result.getStdout().openInputStreamWithAutoDestroy();
 	}
 
-	private boolean needsCrLfConversion(File f,
-			org.eclipse.jgit.patch.FileHeader fileHeader) throws IOException {
+	private boolean needsCrLfConversion(File f, FileHeader fileHeader)
+			throws IOException {
 		if (PatchType.GIT_BINARY.equals(fileHeader.getPatchType())) {
 			return false;
 		}
@@ -596,12 +600,11 @@ private boolean needsCrLfConversion(File f,
 		return false;
 	}
 
-	private static boolean hasCrLf(
-			org.eclipse.jgit.patch.FileHeader fileHeader) {
+	private static boolean hasCrLf(FileHeader fileHeader) {
 		if (PatchType.GIT_BINARY.equals(fileHeader.getPatchType())) {
 			return false;
 		}
-		for (org.eclipse.jgit.patch.HunkHeader header : fileHeader.getHunks()) {
+		for (HunkHeader header : fileHeader.getHunks()) {
 			byte[] buf = header.getBuffer();
 			int hunkEnd = header.getEndOffset();
 			int lineStart = header.getStartOffset();
@@ -702,15 +705,15 @@ private static class ContentStreamLoader {
 	 * @throws IOException
 	 * @throws UnsupportedOperationException
 	 */
-	private ContentStreamLoader applyBinary(String path, File f,
-			org.eclipse.jgit.patch.FileHeader fh, StreamSupplier inputSupplier,
-			ObjectId id) throws PatchApplyException, IOException,
+	private ContentStreamLoader applyBinary(String path, File f, FileHeader fh,
+			StreamSupplier inputSupplier, ObjectId id)
+			throws PatchApplyException, IOException,
 			UnsupportedOperationException {
 		if (!fh.getOldId().isComplete() || !fh.getNewId().isComplete()) {
 			throw new PatchApplyException(MessageFormat
 					.format(JGitText.get().applyBinaryOidTooShort, path));
 		}
-		org.eclipse.jgit.patch.BinaryHunk hunk = fh.getForwardBinaryHunk();
+		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(),
@@ -753,8 +756,7 @@ private ContentStreamLoader applyBinary(String path, File f,
 		}
 	}
 
-	private ContentStreamLoader applyText(RawText rt,
-			org.eclipse.jgit.patch.FileHeader fh)
+	private ContentStreamLoader applyText(RawText rt, FileHeader fh)
 			throws IOException, PatchApplyException {
 		List<ByteBuffer> oldLines = new ArrayList<>(rt.size());
 		for (int i = 0; i < rt.size(); i++) {
@@ -764,7 +766,9 @@ private ContentStreamLoader applyText(RawText rt,
 		int afterLastHunk = 0;
 		int lineNumberShift = 0;
 		int lastHunkNewLine = -1;
-		for (org.eclipse.jgit.patch.HunkHeader hh : fh.getHunks()) {
+		boolean lastWasRemoval = false;
+		boolean noNewLineAtEndOfNew = false;
+		for (HunkHeader hh : fh.getHunks()) {
 			// We assume hunks to be ordered
 			if (hh.getNewStartLine() <= lastHunkNewLine) {
 				throw new PatchApplyException(MessageFormat
@@ -852,17 +856,26 @@ && canApplyAt(hunkLines, newLines, 0)) {
 				if (!hunkLine.hasRemaining()) {
 					// Completely empty line; accept as empty context line
 					applyAt++;
+					lastWasRemoval = false;
 					continue;
 				}
 				switch (hunkLine.array()[hunkLine.position()]) {
 				case ' ':
 					applyAt++;
+					lastWasRemoval = false;
 					break;
 				case '-':
 					newLines.remove(applyAt);
+					lastWasRemoval = true;
 					break;
 				case '+':
 					newLines.add(applyAt++, slice(hunkLine, 1));
+					lastWasRemoval = false;
+					break;
+				case '\\':
+					if (!lastWasRemoval && isNoNewlineAtEnd(hunkLine)) {
+						noNewLineAtEndOfNew = true;
+					}
 					break;
 				default:
 					break;
@@ -870,12 +883,15 @@ && canApplyAt(hunkLines, newLines, 0)) {
 			}
 			afterLastHunk = applyAt;
 		}
-		if (!isNoNewlineAtEndOfFile(fh)) {
+		// If the last line should have a newline, add a null sentinel
+		if (lastHunkNewLine >= 0 && afterLastHunk == newLines.size()) {
+			// Last line came from the patch
+			if (!noNewLineAtEndOfNew) {
+				newLines.add(null);
+			}
+		} else if (!rt.isMissingNewlineAtEnd()) {
 			newLines.add(null);
 		}
-		if (!rt.isMissingNewlineAtEnd()) {
-			oldLines.add(null);
-		}
 
 		// We could check if old == new, but the short-circuiting complicates
 		// logic for inCore patching, so just write the new thing regardless.
@@ -933,21 +949,9 @@ private ByteBuffer slice(ByteBuffer b, int off) {
 		return ByteBuffer.wrap(b.array(), newOffset, b.limit() - newOffset);
 	}
 
-	private boolean isNoNewlineAtEndOfFile(
-			org.eclipse.jgit.patch.FileHeader fh) {
-		List<? extends org.eclipse.jgit.patch.HunkHeader> hunks = fh.getHunks();
-		if (hunks == null || hunks.isEmpty()) {
-			return false;
-		}
-		org.eclipse.jgit.patch.HunkHeader lastHunk = hunks
-				.get(hunks.size() - 1);
-		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$
+	private boolean isNoNewlineAtEnd(ByteBuffer hunkLine) {
+		return Arrays.equals(NO_EOL, 0, NO_EOL.length, hunkLine.array(),
+				hunkLine.position(), hunkLine.limit());
 	}
 
 	/**
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/RevCommit.java b/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/RevCommit.java
index 6b644ce..e155a25 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/RevCommit.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/RevCommit.java
@@ -105,7 +105,12 @@ public static RevCommit parse(RevWalk rw, byte[] raw) throws IOException {
 
 	static final RevCommit[] NO_PARENTS = {};
 
-	private RevTree tree;
+	/**
+	 * Tree reference of the commit.
+	 *
+	 * @since 6.5
+	 */
+	protected RevTree tree;
 
 	/**
 	 * Avoid accessing this field directly. Use method
@@ -657,6 +662,24 @@ public final List<String> getFooterLines(FooterKey keyName) {
 	}
 
 	/**
+	 * Get the distance of the commit from the root, as defined in
+	 * {@link org.eclipse.jgit.internal.storage.commitgraph.CommitGraph}
+	 * <p>
+	 * Generation number is
+	 * {@link org.eclipse.jgit.lib.Constants#COMMIT_GENERATION_UNKNOWN} when the
+	 * commit is not in the commit-graph. If a commit-graph file was written by
+	 * a version of Git that did not compute generation numbers, then those
+	 * commits in commit-graph will have generation number represented by
+	 * {@link org.eclipse.jgit.lib.Constants#COMMIT_GENERATION_NOT_COMPUTED}.
+	 *
+	 * @return the generation number
+	 * @since 6.5
+	 */
+	int getGeneration() {
+		return Constants.COMMIT_GENERATION_UNKNOWN;
+	}
+
+	/**
 	 * Reset this commit to allow another RevWalk with the same instances.
 	 * <p>
 	 * Subclasses <b>must</b> call <code>super.reset()</code> to ensure the
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/RevCommitCG.java b/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/RevCommitCG.java
new file mode 100644
index 0000000..b68f65b
--- /dev/null
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/RevCommitCG.java
@@ -0,0 +1,93 @@
+/*
+ * Copyright (C) 2023, Tencent.
+ *
+ * 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.revwalk;
+
+import java.io.IOException;
+
+import org.eclipse.jgit.errors.IncorrectObjectTypeException;
+import org.eclipse.jgit.errors.MissingObjectException;
+import org.eclipse.jgit.internal.storage.commitgraph.CommitGraph;
+import org.eclipse.jgit.lib.AnyObjectId;
+import org.eclipse.jgit.lib.Constants;
+import org.eclipse.jgit.lib.ObjectId;
+
+/**
+ * RevCommit parsed from
+ * {@link org.eclipse.jgit.internal.storage.commitgraph.CommitGraph}.
+ *
+ * @since 6.5
+ */
+class RevCommitCG extends RevCommit {
+
+	private final int graphPosition;
+
+	private int generation = Constants.COMMIT_GENERATION_UNKNOWN;
+
+	/**
+	 * Create a new commit reference.
+	 *
+	 * @param id
+	 *            object name for the commit.
+	 * @param graphPosition
+	 *            the position in the commit-graph of the object.
+	 */
+	protected RevCommitCG(AnyObjectId id, int graphPosition) {
+		super(id);
+		this.graphPosition = graphPosition;
+	}
+
+	/** {@inheritDoc} */
+	@Override
+	void parseHeaders(RevWalk walk) throws MissingObjectException,
+			IncorrectObjectTypeException, IOException {
+		CommitGraph graph = walk.commitGraph();
+		CommitGraph.CommitData data = graph.getCommitData(graphPosition);
+		if (data == null) {
+			// RevCommitCG was created because we got its graphPosition from
+			// commit-graph. If now the commit-graph doesn't know about it,
+			// something went wrong.
+			throw new IllegalStateException();
+		}
+		if (!walk.shallowCommitsInitialized) {
+			walk.initializeShallowCommits(this);
+		}
+
+		this.tree = walk.lookupTree(data.getTree());
+		this.commitTime = (int) data.getCommitTime();
+		this.generation = data.getGeneration();
+
+		if (getParents() == null) {
+			int[] pGraphList = data.getParents();
+			if (pGraphList.length == 0) {
+				this.parents = RevCommit.NO_PARENTS;
+			} else {
+				RevCommit[] pList = new RevCommit[pGraphList.length];
+				for (int i = 0; i < pList.length; i++) {
+					int graphPos = pGraphList[i];
+					ObjectId objId = graph.getObjectId(graphPos);
+					pList[i] = walk.lookupCommit(objId, graphPos);
+				}
+				this.parents = pList;
+			}
+		}
+
+		flags |= PARSED;
+		if (walk.isRetainBody()) {
+			super.parseBody(walk);
+		}
+	}
+
+	/** {@inheritDoc} */
+	@Override
+	int getGeneration() {
+		return generation;
+	}
+}
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/RevWalk.java b/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/RevWalk.java
index 8da36c5..a66e7c8 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/RevWalk.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/RevWalk.java
@@ -12,6 +12,8 @@
 
 package org.eclipse.jgit.revwalk;
 
+import static org.eclipse.jgit.internal.storage.commitgraph.CommitGraph.EMPTY;
+
 import java.io.IOException;
 import java.text.MessageFormat;
 import java.util.ArrayList;
@@ -30,6 +32,7 @@
 import org.eclipse.jgit.internal.JGitText;
 import org.eclipse.jgit.lib.AnyObjectId;
 import org.eclipse.jgit.lib.AsyncObjectLoaderQueue;
+import org.eclipse.jgit.internal.storage.commitgraph.CommitGraph;
 import org.eclipse.jgit.lib.Constants;
 import org.eclipse.jgit.lib.MutableObjectId;
 import org.eclipse.jgit.lib.NullProgressMonitor;
@@ -189,6 +192,8 @@ public class RevWalk implements Iterable<RevCommit>, AutoCloseable {
 
 	private TreeFilter treeFilter;
 
+	private CommitGraph commitGraph;
+
 	private boolean retainBody = true;
 
 	private boolean rewriteParents = true;
@@ -237,6 +242,7 @@ public RevWalk(ObjectReader or) {
 		filter = RevFilter.ALL;
 		treeFilter = TreeFilter.ALL;
 		this.closeReader = closeReader;
+		commitGraph = null;
 	}
 
 	/**
@@ -900,6 +906,29 @@ public RevCommit lookupCommit(AnyObjectId id) {
 	}
 
 	/**
+	 * This method is intended to be invoked only by {@link RevCommitCG}, in
+	 * order to give commit the correct graphPosition before accessing the
+	 * commit-graph. In this way, the headers of the commit can be obtained in
+	 * constant time.
+	 *
+	 * @param id
+	 *            name of the commit object.
+	 * @param graphPos
+	 *            the position in the commit-graph of the object.
+	 * @return reference to the commit object. Never null.
+	 * @since 6.5
+	 */
+	@NonNull
+	protected RevCommit lookupCommit(AnyObjectId id, int graphPos) {
+		RevCommit c = (RevCommit) objects.get(id);
+		if (c == null) {
+			c = createCommit(id, graphPos);
+			objects.add(c);
+		}
+		return c;
+	}
+
+	/**
 	 * Locate a reference to a tag without loading it.
 	 * <p>
 	 * The tag may or may not exist in the repository. It is impossible to tell
@@ -1136,6 +1165,21 @@ private RevObject parseNew(AnyObjectId id, ObjectLoader ldr)
 	}
 
 	/**
+	 * Get the commit-graph.
+	 *
+	 * @return the commit-graph. Never null.
+	 * @since 6.5
+	 */
+	@NonNull
+	CommitGraph commitGraph() {
+		if (commitGraph == null) {
+			commitGraph = reader != null ? reader.getCommitGraph().orElse(EMPTY)
+					: EMPTY;
+		}
+		return commitGraph;
+	}
+
+	/**
 	 * Asynchronous object parsing.
 	 *
 	 * @param objectIds
@@ -1650,6 +1694,13 @@ public ObjectWalk toObjectWalkWithSameObjects() {
 	 * @return a new unparsed reference for the object.
 	 */
 	protected RevCommit createCommit(AnyObjectId id) {
+		return createCommit(id, commitGraph().findGraphPosition(id));
+	}
+
+	private RevCommit createCommit(AnyObjectId id, int graphPos) {
+		if (graphPos >= 0) {
+			return new RevCommitCG(id, graphPos);
+		}
 		return new RevCommit(id);
 	}
 
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/transport/WalkPushConnection.java b/org.eclipse.jgit/src/org/eclipse/jgit/transport/WalkPushConnection.java
index 03ef852..a54fd8e 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/transport/WalkPushConnection.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/transport/WalkPushConnection.java
@@ -230,7 +230,7 @@ private void sendpack(final List<RemoteRefUpdate> updates,
 				// offsets from appearing to clients.
 				//
 				dest.writeInfoPacks(packNames.keySet());
-				dest.deleteFile(idx.getPath());
+				dest.deleteFile(sanitizedPath(idx));
 			}
 
 			// Write the pack file, then the index, as readers look the
@@ -238,13 +238,13 @@ private void sendpack(final List<RemoteRefUpdate> updates,
 			//
 			String wt = "Put " + pack.getName().substring(0, 12); //$NON-NLS-1$
 			try (OutputStream os = new BufferedOutputStream(
-					dest.writeFile(pack.getPath(), monitor,
+					dest.writeFile(sanitizedPath(pack), monitor,
 							wt + "." + pack.getPackExt().getExtension()))) { //$NON-NLS-1$
 				writer.writePack(monitor, monitor, os);
 			}
 
 			try (OutputStream os = new BufferedOutputStream(
-					dest.writeFile(idx.getPath(), monitor,
+					dest.writeFile(sanitizedPath(idx), monitor,
 							wt + "." + idx.getPackExt().getExtension()))) { //$NON-NLS-1$
 				writer.writeIndex(os);
 			}
@@ -269,7 +269,7 @@ private void sendpack(final List<RemoteRefUpdate> updates,
 	private void safeDelete(File path) {
 		if (path != null) {
 			try {
-				dest.deleteFile(path.getPath());
+				dest.deleteFile(sanitizedPath(path));
 			} catch (IOException cleanupFailure) {
 				// Ignore the deletion failure. We probably are
 				// already failing and were just trying to pick
@@ -366,4 +366,13 @@ private static String pickHEAD(List<RemoteRefUpdate> updates) {
 		}
 		return updates.get(0).getRemoteName();
 	}
+
+	private static String sanitizedPath(File file) {
+		String path = file.getPath();
+		if (File.separatorChar != '/') {
+			path = path.replace(File.separatorChar, '/');
+		}
+		return path;
+	}
+
 }
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/util/IO.java b/org.eclipse.jgit/src/org/eclipse/jgit/util/IO.java
index 6d5694e..80877bb 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/util/IO.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/util/IO.java
@@ -207,6 +207,25 @@ public static void readFully(final InputStream fd, final byte[] dst,
 	}
 
 	/**
+	 * Read from input until the entire byte array filled, or throw an exception
+	 * if stream ends first.
+	 *
+	 * @param fd
+	 *            input stream to read the data from.
+	 * @param dst
+	 *            buffer that must be fully populated
+	 * @throws EOFException
+	 *             the stream ended before dst was fully populated.
+	 * @throws java.io.IOException
+	 *             there was an error reading from the stream.
+	 * @since 6.5
+	 */
+	public static void readFully(InputStream fd, byte[] dst)
+			throws IOException {
+		readFully(fd, dst, 0, dst.length);
+	}
+
+	/**
 	 * Read as much of the array as possible from a channel.
 	 *
 	 * @param channel
diff --git a/pom.xml b/pom.xml
index d271641..f3afee2 100644
--- a/pom.xml
+++ b/pom.xml
@@ -18,7 +18,7 @@
   <groupId>org.eclipse.jgit</groupId>
   <artifactId>org.eclipse.jgit-parent</artifactId>
   <packaging>pom</packaging>
-  <version>6.4.1-SNAPSHOT</version>
+  <version>6.5.0-SNAPSHOT</version>
 
   <name>JGit - Parent</name>
   <url>${jgit-url}</url>
@@ -150,7 +150,7 @@
     <java.version>11</java.version>
     <bundle-manifest>${project.build.directory}/META-INF/MANIFEST.MF</bundle-manifest>
 
-    <jgit-last-release-version>6.2.0.202206071550-r</jgit-last-release-version>
+    <jgit-last-release-version>6.4.0.202211300538-r</jgit-last-release-version>
     <ant-version>1.10.12</ant-version>
     <apache-sshd-version>2.9.2</apache-sshd-version>
     <jsch-version>0.1.55</jsch-version>
@@ -159,24 +159,23 @@
     <junit-version>4.13.2</junit-version>
     <test-fork-count>1C</test-fork-count>
     <args4j-version>2.33</args4j-version>
-    <commons-compress-version>1.21</commons-compress-version>
+    <commons-compress-version>1.22</commons-compress-version>
     <osgi-core-version>6.0.0</osgi-core-version>
     <servlet-api-version>4.0.0</servlet-api-version>
-    <jetty-version>10.0.6</jetty-version>
-    <japicmp-version>0.15.3</japicmp-version>
-    <httpclient-version>4.5.13</httpclient-version>
-    <httpcore-version>4.4.15</httpcore-version>
+    <jetty-version>10.0.13</jetty-version>
+    <japicmp-version>0.17.1</japicmp-version>
+    <httpclient-version>4.5.14</httpclient-version>
+    <httpcore-version>4.4.16</httpcore-version>
     <slf4j-version>1.7.30</slf4j-version>
-    <maven-javadoc-plugin-version>3.3.1</maven-javadoc-plugin-version>
-    <tycho-extras-version>2.6.0</tycho-extras-version>
-    <gson-version>2.9.1</gson-version>
+    <maven-javadoc-plugin-version>3.4.1</maven-javadoc-plugin-version>
+    <gson-version>2.10</gson-version>
     <bouncycastle-version>1.72</bouncycastle-version>
-    <spotbugs-maven-plugin-version>4.3.0</spotbugs-maven-plugin-version>
-    <maven-project-info-reports-plugin-version>3.1.2</maven-project-info-reports-plugin-version>
-    <maven-jxr-plugin-version>3.1.1</maven-jxr-plugin-version>
-    <maven-surefire-plugin-version>3.0.0-M5</maven-surefire-plugin-version>
+    <spotbugs-maven-plugin-version>4.7.3.0</spotbugs-maven-plugin-version>
+    <maven-project-info-reports-plugin-version>3.4.2</maven-project-info-reports-plugin-version>
+    <maven-jxr-plugin-version>3.3.0</maven-jxr-plugin-version>
+    <maven-surefire-plugin-version>3.0.0-M8</maven-surefire-plugin-version>
     <maven-surefire-report-plugin-version>${maven-surefire-plugin-version}</maven-surefire-report-plugin-version>
-    <maven-compiler-plugin-version>3.8.1</maven-compiler-plugin-version>
+    <maven-compiler-plugin-version>3.10.1</maven-compiler-plugin-version>
     <plexus-compiler-version>2.12.1</plexus-compiler-version>
     <hamcrest-version>2.2</hamcrest-version>
     <assertj-version>3.20.2</assertj-version>
@@ -223,7 +222,7 @@
         <plugin>
           <groupId>org.apache.maven.plugins</groupId>
           <artifactId>maven-jar-plugin</artifactId>
-          <version>3.2.0</version>
+          <version>3.3.0</version>
           <configuration>
             <archive>
               <manifestEntries>
@@ -242,25 +241,25 @@
 
         <plugin>
           <artifactId>maven-clean-plugin</artifactId>
-          <version>3.1.0</version>
+          <version>3.2.0</version>
         </plugin>
 
         <plugin>
           <groupId>org.apache.maven.plugins</groupId>
           <artifactId>maven-shade-plugin</artifactId>
-          <version>3.2.4</version>
+          <version>3.4.1</version>
         </plugin>
 
         <plugin>
           <groupId>org.apache.maven.plugins</groupId>
           <artifactId>maven-antrun-plugin</artifactId>
-          <version>3.0.0</version>
+          <version>3.1.0</version>
         </plugin>
 
         <plugin>
           <groupId>org.apache.maven.plugins</groupId>
           <artifactId>maven-dependency-plugin</artifactId>
-          <version>3.2.0</version>
+          <version>3.5.0</version>
         </plugin>
 
         <plugin>
@@ -289,7 +288,7 @@
         <plugin>
           <groupId>org.codehaus.mojo</groupId>
           <artifactId>build-helper-maven-plugin</artifactId>
-          <version>3.2.0</version>
+          <version>3.3.0</version>
         </plugin>
 
         <plugin>
@@ -312,7 +311,7 @@
         <plugin>
           <groupId>org.apache.maven.plugins</groupId>
           <artifactId>maven-pmd-plugin</artifactId>
-          <version>3.15.0</version>
+          <version>3.20.0</version>
           <configuration>
             <sourceEncoding>utf-8</sourceEncoding>
             <minimumTokens>100</minimumTokens>
@@ -335,17 +334,17 @@
         <plugin>
           <groupId>org.eclipse.cbi.maven.plugins</groupId>
           <artifactId>eclipse-jarsigner-plugin</artifactId>
-          <version>1.3.2</version>
+          <version>1.3.5</version>
         </plugin>
         <plugin>
           <groupId>org.jacoco</groupId>
           <artifactId>jacoco-maven-plugin</artifactId>
-          <version>0.8.7</version>
+          <version>0.8.8</version>
         </plugin>
         <plugin>
           <groupId>org.apache.maven.plugins</groupId>
           <artifactId>maven-site-plugin</artifactId>
-          <version>3.9.1</version>
+          <version>4.0.0-M4</version>
           <dependencies>
             <dependency><!-- add support for ssh/scp -->
               <groupId>org.apache.maven.wagon</groupId>
@@ -372,12 +371,12 @@
         <plugin>
           <groupId>org.apache.maven.plugins</groupId>
           <artifactId>maven-deploy-plugin</artifactId>
-          <version>3.0.0-M1</version>
+          <version>3.0.0</version>
         </plugin>
         <plugin>
           <groupId>org.apache.maven.plugins</groupId>
           <artifactId>maven-install-plugin</artifactId>
-          <version>3.0.0-M1</version>
+          <version>3.1.0</version>
         </plugin>
         <plugin>
           <groupId>org.apache.maven.plugins</groupId>
@@ -387,12 +386,12 @@
         <plugin>
           <groupId>org.apache.maven.plugins</groupId>
           <artifactId>maven-resources-plugin</artifactId>
-          <version>3.2.0</version>
+          <version>3.3.0</version>
         </plugin>
         <plugin>
           <groupId>org.springframework.boot</groupId>
           <artifactId>spring-boot-maven-plugin</artifactId>
-          <version>2.5.4</version>
+          <version>2.7.7</version>
         </plugin>
         <plugin>
           <groupId>org.eclipse.dash</groupId>
@@ -406,7 +405,7 @@
       <plugin>
         <groupId>org.apache.maven.plugins</groupId>
         <artifactId>maven-enforcer-plugin</artifactId>
-        <version>3.0.0</version>
+        <version>3.1.0</version>
         <executions>
           <execution>
             <id>enforce-maven</id>