Merge branch 'stable-6.6' into stable-6.7

* stable-6.6:
  Introduce a PriorityQueue sorting RevCommits by commit timestamp
  Remove org.eclipse.jgit.benchmark/.factorypath
  Update jmh to 1.37 for org.eclipse.jgit.benchmark

Change-Id: I76ebca527e523f124bfe81c821169c790eddccb6
diff --git a/Documentation/config-options.md b/Documentation/config-options.md
index 9075a59..810bbc6 100644
--- a/Documentation/config-options.md
+++ b/Documentation/config-options.md
@@ -9,6 +9,13 @@
 
 For details on native git options see also the official [git config documentation](https://git-scm.com/docs/git-config).
 
+## __commitGraph__ options
+
+|  option | default | git option | description |
+|---------|---------|------------|-------------|
+| `commitGraph.writeChangedPaths` | `false`| ⃞ | Whether bloom filter should be written to commit-graph. |
+| `commitGraph.readChangedPaths` | `false` | ✅ | Whether to use the changed-path Bloom filters in the commit-graph file (if it exists, and they are present). |
+
 ## __core__ options
 
 |  option | default | git option | description |
@@ -18,6 +25,7 @@
 | `core.bare` | set automatically on init or clone | ✅ | If true this repository is assumed to be bare and has no working directory associated with it. If this is the case a number of commands that require a working directory will be disabled |
 | `core.bigFileThreshold` | `50 MiB` | ✅ | Files larger than this size are stored deflated, without attempting delta compression. Storing large files without delta compression avoids excessive memory usage, at the slight expense of increased disk usage. Additionally files larger than this size are always treated as binary. |
 | `core.checkstat` |  | ✅ | When missing or is set to `default`, many fields in the stat structure are checked to detect if a file has been modified since Git looked at it. Checks as much of the dircache stat info as possible (in JGit limited by Java filesystem API). When set to `minimum` only checks the size and whole second part of time stamp when comparing the stat info in the dircache with actual file stat info. |
+| `core.commitGraph`| `false` | ✅ | Whether to read the commit-graph file (if it exists) to parse the graph structure of commits. |
 | `core.compression` | `-1` (zlib default) | ✅ | An integer `-1..9`, indicating a default compression level. `-1` is the zlib default. `0` means no compression, and `1..9` are various speed/size tradeoffs, `9` being slowest.|
 | `core.deltaBaseCacheLimit` | `10 MiB` | ✅ | Maximum number of bytes to reserve for caching base objects that multiple deltafied objects reference. By storing the entire decompressed base object in a cache Git is able to avoid unpacking and decompressing frequently used base objects multiple times. |
 | `core.dfs.blockLimit` | `30 MiB` | ⃞ | Maximum number bytes of heap memory to dedicate to caching pack file data in DFS block cache. |
@@ -38,6 +46,7 @@
 | `core.packedGitMmap` | `false` | ✅ | Whether to use Java NIO virtual memory mapping for JGit buffer cache. When set to `true` enables use of Java NIO virtual memory mapping for cache windows, `false` reads entire window into a `byte[]` with standard read calls. `true` is experimental and may cause instabilities and crashes since Java doesn't support explicit unmapping of file regions mapped to virtual memory. |
 | `core.packedGitOpenFiles` | `128` | ⃞ | Maximum number of streams to open at a time. Open packs count against the process limits. |
 | `core.packedGitUseStrongRefs` | `false` | ⃞ | Whether the window cache should use strong references (`true`) or SoftReferences (`false`). When `false` the JVM will drop data cached in the JGit block cache when heap usage comes close to the maximum heap size. |
+| `core.packedIndexGitUseStrongRefs` | `true` | ⃞ | Whether pack indices should use strong references (`true`) or SoftReferences (`false`). When `false` the JVM will drop data cached in the JGit pack indices when heap usage comes close to the maximum heap size. |
 | `core.packedGitWindowSize` | `8 kiB` | ✅ | Number of bytes of a pack file to load into memory in a single read operation. This is the "page size" of the JGit buffer cache, used for all pack access operations. All disk IO occurs as single window reads. Setting this too large may cause the process to load more data than is required; setting this too small may increase the frequency of read() system calls. |
 | `core.precomposeUnicode` | `true` on Mac OS | ✅ | MacOS only. When `true`, JGit reverts the unicode decomposition of filenames done by Mac OS. |
 | `core.quotePath` | `true` | ✅ | Commands that output paths (e.g. ls-files, diff), will quote "unusual" characters in the pathname by enclosing the pathname in double-quotes and escaping those characters with backslashes in the same way C escapes control characters (e.g. `\t` for TAB, `\n` for LF, `\\` for backslash) or bytes with values larger than `0x80` (e.g. octal `\302\265` for "micro" in UTF-8). |
diff --git a/WORKSPACE b/WORKSPACE
index 4c959c0..652ceec 100644
--- a/WORKSPACE
+++ b/WORKSPACE
@@ -118,8 +118,8 @@
 
 maven_jar(
     name = "commons-codec",
-    artifact = "commons-codec:commons-codec:1.15",
-    sha1 = "49d94806b6e3dc933dacbd8acb0fdbab8ebd1e5d",
+    artifact = "commons-codec:commons-codec:1.16.0",
+    sha1 = "4e3eb3d79888d76b54e28b350915b5dc3919c9de",
 )
 
 maven_jar(
@@ -178,8 +178,8 @@
 
 maven_jar(
     name = "mockito",
-    artifact = "org.mockito:mockito-core:4.8.1",
-    sha1 = "d8eb9dec8747d08645347bb8c69088ac83197975",
+    artifact = "org.mockito:mockito-core:5.5.0",
+    sha1 = "1660ec3ce0af7f713af923817b225a37cc5cf965",
 )
 
 maven_jar(
@@ -188,18 +188,18 @@
     sha1 = "ebbf338e33f893139459ce5df023115971c2786f",
 )
 
-BYTE_BUDDY_VERSION = "1.12.18"
+BYTE_BUDDY_VERSION = "1.14.7"
 
 maven_jar(
     name = "bytebuddy",
     artifact = "net.bytebuddy:byte-buddy:" + BYTE_BUDDY_VERSION,
-    sha1 = "875a9c3f29d2f6f499dfd60d76e97a343f9b1233",
+    sha1 = "34efde5f0bb93afc94aaf9d400521899c4806873",
 )
 
 maven_jar(
     name = "bytebuddy-agent",
     artifact = "net.bytebuddy:byte-buddy-agent:" + BYTE_BUDDY_VERSION,
-    sha1 = "417a7310a7bf1c1aae5ca502d26515f9c2f94396",
+    sha1 = "38b49d37e3e14793ef10977ba75f761c8678e20e",
 )
 
 maven_jar(
@@ -265,32 +265,32 @@
     src_sha1 = "135448f8b3b3b06f7f3312d222992525ae4bdd25",
 )
 
-BOUNCYCASTLE_VER = "1.73"
+BOUNCYCASTLE_VER = "1.76"
 
 maven_jar(
     name = "bcpg",
     artifact = "org.bouncycastle:bcpg-jdk18on:" + BOUNCYCASTLE_VER,
-    sha1 = "2838f8c35e6e716349ce780c9c88271cab32065d",
-    src_sha1 = "3ea8d8e88569024cb37c303384d33f12e8be1ca3",
+    sha1 = "d5c23d0470261254d0e84dde1d4237d228540298",
+    src_sha1 = "68d49cdd07da2121a904f481e2e92ca864c08d05",
 )
 
 maven_jar(
     name = "bcprov",
     artifact = "org.bouncycastle:bcprov-jdk18on:" + BOUNCYCASTLE_VER,
-    sha1 = "4bd3de48e5153059fe3f80cbcf86ea221795ee55",
-    src_sha1 = "665f03dc0b10ef2fc90a11c28e48c84a3a9a7323",
+    sha1 = "3a785d0b41806865ad7e311162bfa3fa60b3965b",
+    src_sha1 = "9e00748625819d7e3cc1447366dfa76f0b354a2d",
 )
 
 maven_jar(
     name = "bcutil",
     artifact = "org.bouncycastle:bcutil-jdk18on:" + BOUNCYCASTLE_VER,
-    sha1 = "073a680acd04b249a6773f49200092cadb670bf0",
-    src_sha1 = "573ebc8e83bc846e815e68e4c624f2d0aef941b9",
+    sha1 = "8c7594e651a278bcde18e038d8ab55b1f97f4d31",
+    src_sha1 = "836bb2c42f10b29127b470ebe5c648927dd4ddc6",
 )
 
 maven_jar(
     name = "bcpkix",
     artifact = "org.bouncycastle:bcpkix-jdk18on:" + BOUNCYCASTLE_VER,
-    sha1 = "fd41dae0f564a93888ed5ade426281de94824717",
-    src_sha1 = "e11d418a87536d6f5a9537f7cb1f15a3e5c505e9",
+    sha1 = "10c9cf5c1b4d64abeda28ee32fbade3b74373622",
+    src_sha1 = "e5700c1de407652c1af5961ac8a04fab02eda365",
 )
diff --git a/lib/BUILD b/lib/BUILD
index 6be9e57..29669b5 100644
--- a/lib/BUILD
+++ b/lib/BUILD
@@ -21,6 +21,10 @@
 
 java_library(
     name = "commons-codec",
+    visibility = [
+        "//org.eclipse.jgit:__pkg__",
+        "//org.eclipse.jgit.test:__pkg__",
+    ],
     exports = ["@commons-codec//jar"],
 )
 
diff --git a/org.eclipse.jgit.ant.test/META-INF/MANIFEST.MF b/org.eclipse.jgit.ant.test/META-INF/MANIFEST.MF
index 9659eb2..94263bc 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.6.2.qualifier
+Bundle-Version: 6.7.1.qualifier
 Bundle-ActivationPolicy: lazy
 Bundle-RequiredExecutionEnvironment: JavaSE-11
 Import-Package: org.apache.tools.ant,
- org.eclipse.jgit.ant.tasks;version="[6.6.2,6.7.0)",
- org.eclipse.jgit.junit;version="[6.6.2,6.7.0)",
- org.eclipse.jgit.lib;version="[6.6.2,6.7.0)",
- org.eclipse.jgit.util;version="[6.6.2,6.7.0)",
+ org.eclipse.jgit.ant.tasks;version="[6.7.1,6.8.0)",
+ org.eclipse.jgit.junit;version="[6.7.1,6.8.0)",
+ org.eclipse.jgit.lib;version="[6.7.1,6.8.0)",
+ org.eclipse.jgit.util;version="[6.7.1,6.8.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 bd0c93c..58751db 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.6.2-SNAPSHOT</version>
+    <version>6.7.1-SNAPSHOT</version>
   </parent>
 
   <artifactId>org.eclipse.jgit.ant.test</artifactId>
diff --git a/org.eclipse.jgit.ant/.settings/org.eclipse.jdt.core.prefs b/org.eclipse.jgit.ant/.settings/org.eclipse.jdt.core.prefs
index f79df5b..a08ba7b 100644
--- a/org.eclipse.jgit.ant/.settings/org.eclipse.jdt.core.prefs
+++ b/org.eclipse.jgit.ant/.settings/org.eclipse.jdt.core.prefs
@@ -52,7 +52,7 @@
 org.eclipse.jdt.core.compiler.problem.missingJavadocComments=error
 org.eclipse.jdt.core.compiler.problem.missingJavadocCommentsOverriding=disabled
 org.eclipse.jdt.core.compiler.problem.missingJavadocCommentsVisibility=protected
-org.eclipse.jdt.core.compiler.problem.missingJavadocTagDescription=return_tag
+org.eclipse.jdt.core.compiler.problem.missingJavadocTagDescription=all_standard_tags
 org.eclipse.jdt.core.compiler.problem.missingJavadocTags=error
 org.eclipse.jdt.core.compiler.problem.missingJavadocTagsMethodTypeParameters=disabled
 org.eclipse.jdt.core.compiler.problem.missingJavadocTagsOverriding=disabled
diff --git a/org.eclipse.jgit.ant/META-INF/MANIFEST.MF b/org.eclipse.jgit.ant/META-INF/MANIFEST.MF
index 93fdd8d..e175108 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.6.2.qualifier
+Bundle-Version: 6.7.1.qualifier
 Bundle-RequiredExecutionEnvironment: JavaSE-11
 Import-Package: org.apache.tools.ant,
-  org.eclipse.jgit.storage.file;version="[6.6.2,6.7.0)"
+  org.eclipse.jgit.storage.file;version="[6.7.1,6.8.0)"
 Bundle-Localization: plugin
 Bundle-Vendor: %Bundle-Vendor
-Export-Package: org.eclipse.jgit.ant;version="6.6.2",
- org.eclipse.jgit.ant.tasks;version="6.6.2";
+Export-Package: org.eclipse.jgit.ant;version="6.7.1",
+ org.eclipse.jgit.ant.tasks;version="6.7.1";
   uses:="org.apache.tools.ant,
    org.apache.tools.ant.types"
diff --git a/org.eclipse.jgit.ant/META-INF/SOURCE-MANIFEST.MF b/org.eclipse.jgit.ant/META-INF/SOURCE-MANIFEST.MF
index b4e80a3..7b13950 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.6.2.qualifier
-Eclipse-SourceBundle: org.eclipse.jgit.ant;version="6.6.2.qualifier";roots="."
+Bundle-Version: 6.7.1.qualifier
+Eclipse-SourceBundle: org.eclipse.jgit.ant;version="6.7.1.qualifier";roots="."
diff --git a/org.eclipse.jgit.ant/pom.xml b/org.eclipse.jgit.ant/pom.xml
index 5d9d889..39c8a2f 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.6.2-SNAPSHOT</version>
+    <version>6.7.1-SNAPSHOT</version>
   </parent>
 
   <artifactId>org.eclipse.jgit.ant</artifactId>
diff --git a/org.eclipse.jgit.ant/src/org/eclipse/jgit/ant/tasks/GitAddTask.java b/org.eclipse.jgit.ant/src/org/eclipse/jgit/ant/tasks/GitAddTask.java
index 0d409bb..07b60cf 100644
--- a/org.eclipse.jgit.ant/src/org/eclipse/jgit/ant/tasks/GitAddTask.java
+++ b/org.eclipse.jgit.ant/src/org/eclipse/jgit/ant/tasks/GitAddTask.java
@@ -75,7 +75,6 @@
 		return path;
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public void execute() throws BuildException {
 		if (src == null) {
diff --git a/org.eclipse.jgit.ant/src/org/eclipse/jgit/ant/tasks/GitCheckoutTask.java b/org.eclipse.jgit.ant/src/org/eclipse/jgit/ant/tasks/GitCheckoutTask.java
index 1f10588..ecb5f9a 100644
--- a/org.eclipse.jgit.ant/src/org/eclipse/jgit/ant/tasks/GitCheckoutTask.java
+++ b/org.eclipse.jgit.ant/src/org/eclipse/jgit/ant/tasks/GitCheckoutTask.java
@@ -77,7 +77,6 @@
 		this.force = force;
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public void execute() throws BuildException {
 		CheckoutCommand checkout;
diff --git a/org.eclipse.jgit.ant/src/org/eclipse/jgit/ant/tasks/GitCloneTask.java b/org.eclipse.jgit.ant/src/org/eclipse/jgit/ant/tasks/GitCloneTask.java
index c143c9c..facf2ac 100644
--- a/org.eclipse.jgit.ant/src/org/eclipse/jgit/ant/tasks/GitCloneTask.java
+++ b/org.eclipse.jgit.ant/src/org/eclipse/jgit/ant/tasks/GitCloneTask.java
@@ -76,7 +76,6 @@
 		this.branch = branch;
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public void execute() throws BuildException {
 		log("Cloning repository " + uri);
diff --git a/org.eclipse.jgit.ant/src/org/eclipse/jgit/ant/tasks/GitInitTask.java b/org.eclipse.jgit.ant/src/org/eclipse/jgit/ant/tasks/GitInitTask.java
index 161168f..5c2a26b 100644
--- a/org.eclipse.jgit.ant/src/org/eclipse/jgit/ant/tasks/GitInitTask.java
+++ b/org.eclipse.jgit.ant/src/org/eclipse/jgit/ant/tasks/GitInitTask.java
@@ -48,7 +48,6 @@
 		this.bare = bare;
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public void execute() throws BuildException {
 		if (bare) {
diff --git a/org.eclipse.jgit.archive/.settings/org.eclipse.jdt.core.prefs b/org.eclipse.jgit.archive/.settings/org.eclipse.jdt.core.prefs
index 2abe952..b27b6c3 100644
--- a/org.eclipse.jgit.archive/.settings/org.eclipse.jdt.core.prefs
+++ b/org.eclipse.jgit.archive/.settings/org.eclipse.jdt.core.prefs
@@ -52,7 +52,7 @@
 org.eclipse.jdt.core.compiler.problem.missingJavadocComments=error
 org.eclipse.jdt.core.compiler.problem.missingJavadocCommentsOverriding=disabled
 org.eclipse.jdt.core.compiler.problem.missingJavadocCommentsVisibility=protected
-org.eclipse.jdt.core.compiler.problem.missingJavadocTagDescription=return_tag
+org.eclipse.jdt.core.compiler.problem.missingJavadocTagDescription=all_standard_tags
 org.eclipse.jdt.core.compiler.problem.missingJavadocTags=error
 org.eclipse.jdt.core.compiler.problem.missingJavadocTagsMethodTypeParameters=disabled
 org.eclipse.jdt.core.compiler.problem.missingJavadocTagsOverriding=disabled
diff --git a/org.eclipse.jgit.archive/META-INF/MANIFEST.MF b/org.eclipse.jgit.archive/META-INF/MANIFEST.MF
index 7f72ee2..a8ec4c9 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.6.2.qualifier
+Bundle-Version: 6.7.1.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.6.2,6.7.0)",
- org.eclipse.jgit.lib;version="[6.6.2,6.7.0)",
- org.eclipse.jgit.nls;version="[6.6.2,6.7.0)",
- org.eclipse.jgit.revwalk;version="[6.6.2,6.7.0)",
- org.eclipse.jgit.util;version="[6.6.2,6.7.0)",
+ org.eclipse.jgit.api;version="[6.7.1,6.8.0)",
+ org.eclipse.jgit.lib;version="[6.7.1,6.8.0)",
+ org.eclipse.jgit.nls;version="[6.7.1,6.8.0)",
+ org.eclipse.jgit.revwalk;version="[6.7.1,6.8.0)",
+ org.eclipse.jgit.util;version="[6.7.1,6.8.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.6.2";
+Export-Package: org.eclipse.jgit.archive;version="6.7.1";
   uses:="org.eclipse.jgit.lib,
    org.eclipse.jgit.api,
    org.apache.commons.compress.archivers,
    org.osgi.framework",
- org.eclipse.jgit.archive.internal;version="6.6.2";x-internal:=true
+ org.eclipse.jgit.archive.internal;version="6.7.1";x-internal:=true
diff --git a/org.eclipse.jgit.archive/META-INF/SOURCE-MANIFEST.MF b/org.eclipse.jgit.archive/META-INF/SOURCE-MANIFEST.MF
index 2ab44a7..b08cf20 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.6.2.qualifier
-Eclipse-SourceBundle: org.eclipse.jgit.archive;version="6.6.2.qualifier";roots="."
+Bundle-Version: 6.7.1.qualifier
+Eclipse-SourceBundle: org.eclipse.jgit.archive;version="6.7.1.qualifier";roots="."
diff --git a/org.eclipse.jgit.archive/pom.xml b/org.eclipse.jgit.archive/pom.xml
index 06e9559..e94732b 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.6.2-SNAPSHOT</version>
+    <version>6.7.1-SNAPSHOT</version>
   </parent>
 
   <artifactId>org.eclipse.jgit.archive</artifactId>
diff --git a/org.eclipse.jgit.archive/src/org/eclipse/jgit/archive/BaseFormat.java b/org.eclipse.jgit.archive/src/org/eclipse/jgit/archive/BaseFormat.java
index 0ebac77..25cd368 100644
--- a/org.eclipse.jgit.archive/src/org/eclipse/jgit/archive/BaseFormat.java
+++ b/org.eclipse.jgit.archive/src/org/eclipse/jgit/archive/BaseFormat.java
@@ -40,6 +40,7 @@
 	 *            options map
 	 * @return stream with option applied
 	 * @throws IOException
+	 *             if an IO error occurred
 	 */
 	protected ArchiveOutputStream applyFormatOptions(ArchiveOutputStream s,
 			Map<String, Object> o) throws IOException {
diff --git a/org.eclipse.jgit.archive/src/org/eclipse/jgit/archive/TarFormat.java b/org.eclipse.jgit.archive/src/org/eclipse/jgit/archive/TarFormat.java
index 702bad6..dfa6032 100644
--- a/org.eclipse.jgit.archive/src/org/eclipse/jgit/archive/TarFormat.java
+++ b/org.eclipse.jgit.archive/src/org/eclipse/jgit/archive/TarFormat.java
@@ -39,7 +39,6 @@
 	private static final List<String> SUFFIXES = Collections
 			.unmodifiableList(Arrays.asList(".tar")); //$NON-NLS-1$
 
-	/** {@inheritDoc} */
 	@Override
 	public ArchiveOutputStream createArchiveOutputStream(OutputStream s)
 			throws IOException {
@@ -47,7 +46,6 @@
 				Collections.<String, Object> emptyMap());
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public ArchiveOutputStream createArchiveOutputStream(OutputStream s,
 			Map<String, Object> o) throws IOException {
@@ -58,7 +56,6 @@
 		return applyFormatOptions(out, o);
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public void putEntry(ArchiveOutputStream out,
 			ObjectId tree, String path, FileMode mode, ObjectLoader loader)
@@ -108,19 +105,16 @@
 		out.closeArchiveEntry();
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public Iterable<String> suffixes() {
 		return SUFFIXES;
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public boolean equals(Object other) {
 		return (other instanceof TarFormat);
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public int hashCode() {
 		return getClass().hashCode();
diff --git a/org.eclipse.jgit.archive/src/org/eclipse/jgit/archive/Tbz2Format.java b/org.eclipse.jgit.archive/src/org/eclipse/jgit/archive/Tbz2Format.java
index 940dafd..26da431 100644
--- a/org.eclipse.jgit.archive/src/org/eclipse/jgit/archive/Tbz2Format.java
+++ b/org.eclipse.jgit.archive/src/org/eclipse/jgit/archive/Tbz2Format.java
@@ -33,7 +33,6 @@
 
 	private final ArchiveCommand.Format<ArchiveOutputStream> tarFormat = new TarFormat();
 
-	/** {@inheritDoc} */
 	@Override
 	public ArchiveOutputStream createArchiveOutputStream(OutputStream s)
 			throws IOException {
@@ -41,7 +40,6 @@
 				Collections.<String, Object> emptyMap());
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public ArchiveOutputStream createArchiveOutputStream(OutputStream s,
 			Map<String, Object> o) throws IOException {
@@ -55,7 +53,6 @@
 		return tarFormat.createArchiveOutputStream(out, o);
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public void putEntry(ArchiveOutputStream out,
 			ObjectId tree, String path, FileMode mode, ObjectLoader loader)
@@ -63,19 +60,16 @@
 		tarFormat.putEntry(out, tree, path, mode, loader);
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public Iterable<String> suffixes() {
 		return SUFFIXES;
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public boolean equals(Object other) {
 		return (other instanceof Tbz2Format);
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public int hashCode() {
 		return getClass().hashCode();
diff --git a/org.eclipse.jgit.archive/src/org/eclipse/jgit/archive/TgzFormat.java b/org.eclipse.jgit.archive/src/org/eclipse/jgit/archive/TgzFormat.java
index 72e2439..d1ed035 100644
--- a/org.eclipse.jgit.archive/src/org/eclipse/jgit/archive/TgzFormat.java
+++ b/org.eclipse.jgit.archive/src/org/eclipse/jgit/archive/TgzFormat.java
@@ -34,7 +34,6 @@
 
 	private final ArchiveCommand.Format<ArchiveOutputStream> tarFormat = new TarFormat();
 
-	/** {@inheritDoc} */
 	@Override
 	public ArchiveOutputStream createArchiveOutputStream(OutputStream s)
 			throws IOException {
@@ -42,7 +41,6 @@
 				Collections.<String, Object> emptyMap());
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public ArchiveOutputStream createArchiveOutputStream(OutputStream s,
 			Map<String, Object> o) throws IOException {
@@ -58,7 +56,6 @@
 		return tarFormat.createArchiveOutputStream(out, o);
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public void putEntry(ArchiveOutputStream out,
 			ObjectId tree, String path, FileMode mode, ObjectLoader loader)
@@ -66,19 +63,16 @@
 		tarFormat.putEntry(out, tree, path, mode, loader);
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public Iterable<String> suffixes() {
 		return SUFFIXES;
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public boolean equals(Object other) {
 		return (other instanceof TgzFormat);
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public int hashCode() {
 		return getClass().hashCode();
diff --git a/org.eclipse.jgit.archive/src/org/eclipse/jgit/archive/TxzFormat.java b/org.eclipse.jgit.archive/src/org/eclipse/jgit/archive/TxzFormat.java
index b16fb6d..42549de 100644
--- a/org.eclipse.jgit.archive/src/org/eclipse/jgit/archive/TxzFormat.java
+++ b/org.eclipse.jgit.archive/src/org/eclipse/jgit/archive/TxzFormat.java
@@ -33,7 +33,6 @@
 
 	private final ArchiveCommand.Format<ArchiveOutputStream> tarFormat = new TarFormat();
 
-	/** {@inheritDoc} */
 	@Override
 	public ArchiveOutputStream createArchiveOutputStream(OutputStream s)
 			throws IOException {
@@ -41,7 +40,6 @@
 				Collections.<String, Object> emptyMap());
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public ArchiveOutputStream createArchiveOutputStream(OutputStream s,
 			Map<String, Object> o) throws IOException {
@@ -55,7 +53,6 @@
 		return tarFormat.createArchiveOutputStream(out, o);
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public void putEntry(ArchiveOutputStream out,
 			ObjectId tree, String path, FileMode mode, ObjectLoader loader)
@@ -63,19 +60,16 @@
 		tarFormat.putEntry(out, tree, path, mode, loader);
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public Iterable<String> suffixes() {
 		return SUFFIXES;
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public boolean equals(Object other) {
 		return (other instanceof TxzFormat);
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public int hashCode() {
 		return getClass().hashCode();
diff --git a/org.eclipse.jgit.archive/src/org/eclipse/jgit/archive/ZipFormat.java b/org.eclipse.jgit.archive/src/org/eclipse/jgit/archive/ZipFormat.java
index 97a24c7..6cb42ae 100644
--- a/org.eclipse.jgit.archive/src/org/eclipse/jgit/archive/ZipFormat.java
+++ b/org.eclipse.jgit.archive/src/org/eclipse/jgit/archive/ZipFormat.java
@@ -35,7 +35,6 @@
 	private static final List<String> SUFFIXES = Collections
 			.unmodifiableList(Arrays.asList(".zip")); //$NON-NLS-1$
 
-	/** {@inheritDoc} */
 	@Override
 	public ArchiveOutputStream createArchiveOutputStream(OutputStream s)
 			throws IOException {
@@ -43,7 +42,6 @@
 				Collections.<String, Object> emptyMap());
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public ArchiveOutputStream createArchiveOutputStream(OutputStream s,
 			Map<String, Object> o) throws IOException {
@@ -55,7 +53,6 @@
 		return applyFormatOptions(out, o);
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public void putEntry(ArchiveOutputStream out,
 			ObjectId tree, String path, FileMode mode, ObjectLoader loader)
@@ -97,19 +94,16 @@
 		out.closeArchiveEntry();
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public Iterable<String> suffixes() {
 		return SUFFIXES;
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public boolean equals(Object other) {
 		return (other instanceof ZipFormat);
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public int hashCode() {
 		return getClass().hashCode();
diff --git a/org.eclipse.jgit.benchmarks/BUILD b/org.eclipse.jgit.benchmarks/BUILD
index ecd268c..6198e4d 100644
--- a/org.eclipse.jgit.benchmarks/BUILD
+++ b/org.eclipse.jgit.benchmarks/BUILD
@@ -7,9 +7,11 @@
 jmh_java_benchmarks(
     name = "benchmarks",
     srcs = SRCS,
+    testonly = 1,
     deps = [
         "//lib:javaewah",
         "//lib:slf4j-api",
         "//org.eclipse.jgit:jgit",
+        "//org.eclipse.jgit.junit:junit",
     ],
 )
diff --git a/org.eclipse.jgit.benchmarks/pom.xml b/org.eclipse.jgit.benchmarks/pom.xml
index d96fe48..b3edc49 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.6.2-SNAPSHOT</version>
+  <version>6.7.1-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.1.0</version>
+        <version>3.3.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.10.1</version>
+        <version>3.11.0</version>
         <configuration>
           <encoding>UTF-8</encoding>
           <release>${java.version}</release>
@@ -175,7 +175,7 @@
         <plugin>
           <groupId>org.apache.maven.plugins</groupId>
           <artifactId>maven-site-plugin</artifactId>
-          <version>3.12.1</version>
+          <version>4.0.0-M9</version>
           <dependencies>
             <dependency><!-- add support for ssh/scp -->
               <groupId>org.apache.maven.wagon</groupId>
@@ -187,7 +187,7 @@
         <plugin>
           <groupId>org.apache.maven.plugins</groupId>
           <artifactId>maven-surefire-report-plugin</artifactId>
-          <version>3.0.0-M8</version>
+          <version>3.0.0</version>
         </plugin>
         <plugin>
           <groupId>org.apache.maven.plugins</groupId>
@@ -197,7 +197,7 @@
         <plugin>
           <groupId>org.apache.maven.plugins</groupId>
           <artifactId>maven-project-info-reports-plugin</artifactId>
-          <version>3.4.2</version>
+          <version>3.4.3</version>
         </plugin>
       </plugins>
     </pluginManagement>
diff --git a/org.eclipse.jgit.coverage/pom.xml b/org.eclipse.jgit.coverage/pom.xml
index 868802c..bed98fc 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.6.2-SNAPSHOT</version>
+    <version>6.7.1-SNAPSHOT</version>
   </parent>
   <modelVersion>4.0.0</modelVersion>
 
@@ -27,88 +27,88 @@
     <dependency>
       <groupId>org.eclipse.jgit</groupId>
       <artifactId>org.eclipse.jgit</artifactId>
-      <version>6.6.2-SNAPSHOT</version>
+      <version>6.7.1-SNAPSHOT</version>
     </dependency>
     <dependency>
       <groupId>org.eclipse.jgit</groupId>
       <artifactId>org.eclipse.jgit.ant</artifactId>
-      <version>6.6.2-SNAPSHOT</version>
+      <version>6.7.1-SNAPSHOT</version>
     </dependency>
     <dependency>
       <groupId>org.eclipse.jgit</groupId>
       <artifactId>org.eclipse.jgit.archive</artifactId>
-      <version>6.6.2-SNAPSHOT</version>
+      <version>6.7.1-SNAPSHOT</version>
     </dependency>
     <dependency>
       <groupId>org.eclipse.jgit</groupId>
       <artifactId>org.eclipse.jgit.http.apache</artifactId>
-      <version>6.6.2-SNAPSHOT</version>
+      <version>6.7.1-SNAPSHOT</version>
     </dependency>
     <dependency>
       <groupId>org.eclipse.jgit</groupId>
       <artifactId>org.eclipse.jgit.http.server</artifactId>
-      <version>6.6.2-SNAPSHOT</version>
+      <version>6.7.1-SNAPSHOT</version>
     </dependency>
     <dependency>
       <groupId>org.eclipse.jgit</groupId>
       <artifactId>org.eclipse.jgit.lfs</artifactId>
-      <version>6.6.2-SNAPSHOT</version>
+      <version>6.7.1-SNAPSHOT</version>
     </dependency>
     <dependency>
       <groupId>org.eclipse.jgit</groupId>
       <artifactId>org.eclipse.jgit.lfs.server</artifactId>
-      <version>6.6.2-SNAPSHOT</version>
+      <version>6.7.1-SNAPSHOT</version>
     </dependency>
     <dependency>
       <groupId>org.eclipse.jgit</groupId>
       <artifactId>org.eclipse.jgit.pgm</artifactId>
-      <version>6.6.2-SNAPSHOT</version>
+      <version>6.7.1-SNAPSHOT</version>
     </dependency>
     <dependency>
       <groupId>org.eclipse.jgit</groupId>
       <artifactId>org.eclipse.jgit.ui</artifactId>
-      <version>6.6.2-SNAPSHOT</version>
+      <version>6.7.1-SNAPSHOT</version>
     </dependency>
     <dependency>
       <groupId>org.eclipse.jgit</groupId>
       <artifactId>org.eclipse.jgit.ssh.apache</artifactId>
-      <version>6.6.2-SNAPSHOT</version>
+      <version>6.7.1-SNAPSHOT</version>
     </dependency>
 
     <dependency>
       <groupId>org.eclipse.jgit</groupId>
       <artifactId>org.eclipse.jgit.test</artifactId>
-      <version>6.6.2-SNAPSHOT</version>
+      <version>6.7.1-SNAPSHOT</version>
     </dependency>
     <dependency>
       <groupId>org.eclipse.jgit</groupId>
       <artifactId>org.eclipse.jgit.ant.test</artifactId>
-      <version>6.6.2-SNAPSHOT</version>
+      <version>6.7.1-SNAPSHOT</version>
     </dependency>
     <dependency>
       <groupId>org.eclipse.jgit</groupId>
       <artifactId>org.eclipse.jgit.http.test</artifactId>
-      <version>6.6.2-SNAPSHOT</version>
+      <version>6.7.1-SNAPSHOT</version>
     </dependency>
     <dependency>
       <groupId>org.eclipse.jgit</groupId>
       <artifactId>org.eclipse.jgit.pgm.test</artifactId>
-      <version>6.6.2-SNAPSHOT</version>
+      <version>6.7.1-SNAPSHOT</version>
     </dependency>
     <dependency>
       <groupId>org.eclipse.jgit</groupId>
       <artifactId>org.eclipse.jgit.lfs.test</artifactId>
-      <version>6.6.2-SNAPSHOT</version>
+      <version>6.7.1-SNAPSHOT</version>
     </dependency>
     <dependency>
       <groupId>org.eclipse.jgit</groupId>
       <artifactId>org.eclipse.jgit.lfs.server.test</artifactId>
-      <version>6.6.2-SNAPSHOT</version>
+      <version>6.7.1-SNAPSHOT</version>
     </dependency>
     <dependency>
       <groupId>org.eclipse.jgit</groupId>
       <artifactId>org.eclipse.jgit.ssh.apache.test</artifactId>
-      <version>6.6.2-SNAPSHOT</version>
+      <version>6.7.1-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 f70a945..c58b5ce 100644
--- a/org.eclipse.jgit.gpg.bc.test/META-INF/MANIFEST.MF
+++ b/org.eclipse.jgit.gpg.bc.test/META-INF/MANIFEST.MF
@@ -3,19 +3,19 @@
 Bundle-Name: %Bundle-Name
 Automatic-Module-Name: org.eclipse.jgit.gpg.bc.test
 Bundle-SymbolicName: org.eclipse.jgit.gpg.bc.test
-Bundle-Version: 6.6.2.qualifier
+Bundle-Version: 6.7.1.qualifier
 Bundle-Vendor: %Bundle-Vendor
 Bundle-Localization: plugin
 Bundle-RequiredExecutionEnvironment: JavaSE-11
+Require-Bundle: org.hamcrest.core;bundle-version="[1.3.0,2.0.0)"
 Import-Package: org.bouncycastle.jce.provider;version="[1.65.0,2.0.0)",
  org.bouncycastle.openpgp;version="[1.65.0,2.0.0)",
  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.6.2,6.7.0)",
- org.eclipse.jgit.gpg.bc.internal.keys;version="[6.6.2,6.7.0)",
- org.eclipse.jgit.util.sha1;version="[6.6.2,6.7.0)",
- org.hamcrest;version="[1.1.0,3.0.0)",
+ org.eclipse.jgit.gpg.bc.internal;version="[6.7.1,6.8.0)",
+ org.eclipse.jgit.gpg.bc.internal.keys;version="[6.7.1,6.8.0)",
+ org.eclipse.jgit.util.sha1;version="[6.7.1,6.8.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)"
diff --git a/org.eclipse.jgit.gpg.bc.test/pom.xml b/org.eclipse.jgit.gpg.bc.test/pom.xml
index 2e6d7c8..9479948 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.6.2-SNAPSHOT</version>
+    <version>6.7.1-SNAPSHOT</version>
   </parent>
 
   <artifactId>org.eclipse.jgit.gpg.bc.test</artifactId>
diff --git a/org.eclipse.jgit.gpg.bc/.settings/org.eclipse.jdt.core.prefs b/org.eclipse.jgit.gpg.bc/.settings/org.eclipse.jdt.core.prefs
index d1f54bb..d5c0e6c 100644
--- a/org.eclipse.jgit.gpg.bc/.settings/org.eclipse.jdt.core.prefs
+++ b/org.eclipse.jgit.gpg.bc/.settings/org.eclipse.jdt.core.prefs
@@ -52,7 +52,7 @@
 org.eclipse.jdt.core.compiler.problem.missingJavadocComments=error
 org.eclipse.jdt.core.compiler.problem.missingJavadocCommentsOverriding=disabled
 org.eclipse.jdt.core.compiler.problem.missingJavadocCommentsVisibility=protected
-org.eclipse.jdt.core.compiler.problem.missingJavadocTagDescription=return_tag
+org.eclipse.jdt.core.compiler.problem.missingJavadocTagDescription=all_standard_tags
 org.eclipse.jdt.core.compiler.problem.missingJavadocTags=error
 org.eclipse.jdt.core.compiler.problem.missingJavadocTagsMethodTypeParameters=disabled
 org.eclipse.jdt.core.compiler.problem.missingJavadocTagsOverriding=disabled
diff --git a/org.eclipse.jgit.gpg.bc/META-INF/MANIFEST.MF b/org.eclipse.jgit.gpg.bc/META-INF/MANIFEST.MF
index 1df6959..c3657f7 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.6.2,6.7.0)"
+Fragment-Host: org.eclipse.jgit;bundle-version="[6.7.1,6.8.0)"
 Bundle-Vendor: %Bundle-Vendor
 Bundle-Localization: plugin
-Bundle-Version: 6.6.2.qualifier
+Bundle-Version: 6.7.1.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.6.2,6.7.0)",
- org.eclipse.jgit.api.errors;version="[6.6.2,6.7.0)",
+ org.eclipse.jgit.annotations;version="[6.7.1,6.8.0)",
+ org.eclipse.jgit.api.errors;version="[6.7.1,6.8.0)",
  org.slf4j;version="[1.7.0,2.0.0)"
-Export-Package: org.eclipse.jgit.gpg.bc;version="6.6.2",
- org.eclipse.jgit.gpg.bc.internal;version="6.6.2";x-friends:="org.eclipse.jgit.gpg.bc.test",
- org.eclipse.jgit.gpg.bc.internal.keys;version="6.6.2";x-friends:="org.eclipse.jgit.gpg.bc.test"
+Export-Package: org.eclipse.jgit.gpg.bc;version="6.7.1",
+ org.eclipse.jgit.gpg.bc.internal;version="6.7.1";x-friends:="org.eclipse.jgit.gpg.bc.test",
+ org.eclipse.jgit.gpg.bc.internal.keys;version="6.7.1";x-friends:="org.eclipse.jgit.gpg.bc.test"
diff --git a/org.eclipse.jgit.gpg.bc/META-INF/SOURCE-MANIFEST.MF b/org.eclipse.jgit.gpg.bc/META-INF/SOURCE-MANIFEST.MF
index 5d97eb9..1215b8c 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.6.2.qualifier
-Eclipse-SourceBundle: org.eclipse.jgit.gpg.bc;version="6.6.2.qualifier";roots="."
+Bundle-Version: 6.7.1.qualifier
+Eclipse-SourceBundle: org.eclipse.jgit.gpg.bc;version="6.7.1.qualifier";roots="."
diff --git a/org.eclipse.jgit.gpg.bc/pom.xml b/org.eclipse.jgit.gpg.bc/pom.xml
index b44db9f..d822bdb 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.6.2-SNAPSHOT</version>
+    <version>6.7.1-SNAPSHOT</version>
   </parent>
 
   <artifactId>org.eclipse.jgit.gpg.bc</artifactId>
diff --git a/org.eclipse.jgit.gpg.bc/src/org/eclipse/jgit/gpg/bc/internal/BouncyCastleGpgKeyLocator.java b/org.eclipse.jgit.gpg.bc/src/org/eclipse/jgit/gpg/bc/internal/BouncyCastleGpgKeyLocator.java
index 8cd03bd..d7bf34e 100644
--- a/org.eclipse.jgit.gpg.bc/src/org/eclipse/jgit/gpg/bc/internal/BouncyCastleGpgKeyLocator.java
+++ b/org.eclipse.jgit.gpg.bc/src/org/eclipse/jgit/gpg/bc/internal/BouncyCastleGpgKeyLocator.java
@@ -324,7 +324,9 @@
 	 * @throws IOException
 	 *             in case of problems reading the file
 	 * @throws NoSuchAlgorithmException
+	 *             if an algorithm isn't available
 	 * @throws NoSuchProviderException
+	 *             if a provider isn't available
 	 * @throws NoOpenPgpKeyException
 	 *             if the file does not contain any OpenPGP key
 	 */
@@ -368,12 +370,17 @@
 	 * @throws IOException
 	 *             in case of issues reading key files
 	 * @throws NoSuchAlgorithmException
+	 *             algorithm is not available
 	 * @throws NoSuchProviderException
+	 *             provider is not available
 	 * @throws PGPException
 	 *             in case of issues finding a key, including no key found
 	 * @throws CanceledException
+	 *             operation was cancelled
 	 * @throws URISyntaxException
+	 *             URI is invalid
 	 * @throws UnsupportedCredentialItem
+	 *             credential item is not supported
 	 */
 	@NonNull
 	public BouncyCastleGpgKey findSecretKey() throws IOException,
@@ -543,10 +550,11 @@
 	/**
 	 * Return the first suitable key for signing in the key ring collection. For
 	 * this case we only expect there to be one key available for signing.
-	 * </p>
 	 *
 	 * @param signingkey
+	 *            the signing key
 	 * @param secringFile
+	 *            the secring file
 	 *
 	 * @return the first suitable PGP secret key found for signing
 	 * @throws IOException
diff --git a/org.eclipse.jgit.gpg.bc/src/org/eclipse/jgit/gpg/bc/internal/BouncyCastleGpgKeyPassphrasePrompt.java b/org.eclipse.jgit.gpg.bc/src/org/eclipse/jgit/gpg/bc/internal/BouncyCastleGpgKeyPassphrasePrompt.java
index 6144195..463b661 100644
--- a/org.eclipse.jgit.gpg.bc/src/org/eclipse/jgit/gpg/bc/internal/BouncyCastleGpgKeyPassphrasePrompt.java
+++ b/org.eclipse.jgit.gpg.bc/src/org/eclipse/jgit/gpg/bc/internal/BouncyCastleGpgKeyPassphrasePrompt.java
@@ -69,10 +69,13 @@
 	 *            the location the key was loaded from
 	 * @return the passphrase (maybe <code>null</code>)
 	 * @throws PGPException
+	 *             if a PGP problem occurred
 	 * @throws CanceledException
 	 *             in case passphrase was not entered by user
 	 * @throws URISyntaxException
+	 *             if the URI isn't parseable
 	 * @throws UnsupportedCredentialItem
+	 *             if a credential item isn't supported
 	 */
 	public char[] getPassphrase(byte[] keyFingerprint, Path keyLocation)
 			throws PGPException, CanceledException, UnsupportedCredentialItem,
diff --git a/org.eclipse.jgit.gpg.bc/src/org/eclipse/jgit/gpg/bc/internal/keys/KeyGrip.java b/org.eclipse.jgit.gpg.bc/src/org/eclipse/jgit/gpg/bc/internal/keys/KeyGrip.java
index c931724..3eee18a 100644
--- a/org.eclipse.jgit.gpg.bc/src/org/eclipse/jgit/gpg/bc/internal/keys/KeyGrip.java
+++ b/org.eclipse.jgit.gpg.bc/src/org/eclipse/jgit/gpg/bc/internal/keys/KeyGrip.java
@@ -36,8 +36,8 @@
  * Utilities to compute the <em>keygrip</em> of a key. A keygrip is a SHA1 hash
  * over the public key parameters and is used internally by the gpg-agent to
  * find the secret key belonging to a public key: the secret key is stored in a
- * file under ~/.gnupg/private-keys-v1.d/ with a name "&lt;keygrip>.key". While
- * this storage organization is an implementation detail of GPG, the way
+ * file under ~/.gnupg/private-keys-v1.d/ with a name "&lt;keygrip&gt;.key".
+ * While this storage organization is an implementation detail of GPG, the way
  * keygrips are computed is not; they are computed by libgcrypt and their
  * definition is stable.
  */
diff --git a/org.eclipse.jgit.gpg.bc/src/org/eclipse/jgit/gpg/bc/internal/keys/SExprParser.java b/org.eclipse.jgit.gpg.bc/src/org/eclipse/jgit/gpg/bc/internal/keys/SExprParser.java
index a9bb22c..c93c216 100644
--- a/org.eclipse.jgit.gpg.bc/src/org/eclipse/jgit/gpg/bc/internal/keys/SExprParser.java
+++ b/org.eclipse.jgit.gpg.bc/src/org/eclipse/jgit/gpg/bc/internal/keys/SExprParser.java
@@ -95,7 +95,9 @@
 	 *
 	 * @return a secret key object.
 	 * @throws IOException
+	 *             if an IO error occurred
 	 * @throws PGPException
+	 *             if some PGP error occurred
 	 */
 	public PGPSecretKey parseSecretKey(InputStream inputStream,
 			PBEProtectionRemoverFactory keyProtectionRemoverFactory,
@@ -252,7 +254,9 @@
 	 *
 	 * @return a secret key object.
 	 * @throws IOException
+	 *             if an IO error occurred
 	 * @throws PGPException
+	 *             if a PGP error occurred
 	 */
 	public PGPSecretKey parseSecretKey(InputStream inputStream,
 			PBEProtectionRemoverFactory keyProtectionRemoverFactory,
diff --git a/org.eclipse.jgit.gpg.bc/src/org/eclipse/jgit/gpg/bc/internal/keys/SecretKeys.java b/org.eclipse.jgit.gpg.bc/src/org/eclipse/jgit/gpg/bc/internal/keys/SecretKeys.java
index 269a1ba..a659d38 100644
--- a/org.eclipse.jgit.gpg.bc/src/org/eclipse/jgit/gpg/bc/internal/keys/SecretKeys.java
+++ b/org.eclipse.jgit.gpg.bc/src/org/eclipse/jgit/gpg/bc/internal/keys/SecretKeys.java
@@ -373,6 +373,7 @@
 	 *            index of the closing quote in {@code in}
 	 * @return the dequoted raw string value
 	 * @throws StreamCorruptedException
+	 *             if object stream is corrupt
 	 */
 	private static byte[] dequote(byte[] in, int from, int to)
 			throws StreamCorruptedException {
diff --git a/org.eclipse.jgit.http.apache/.settings/org.eclipse.jdt.core.prefs b/org.eclipse.jgit.http.apache/.settings/org.eclipse.jdt.core.prefs
index f79df5b..a08ba7b 100644
--- a/org.eclipse.jgit.http.apache/.settings/org.eclipse.jdt.core.prefs
+++ b/org.eclipse.jgit.http.apache/.settings/org.eclipse.jdt.core.prefs
@@ -52,7 +52,7 @@
 org.eclipse.jdt.core.compiler.problem.missingJavadocComments=error
 org.eclipse.jdt.core.compiler.problem.missingJavadocCommentsOverriding=disabled
 org.eclipse.jdt.core.compiler.problem.missingJavadocCommentsVisibility=protected
-org.eclipse.jdt.core.compiler.problem.missingJavadocTagDescription=return_tag
+org.eclipse.jdt.core.compiler.problem.missingJavadocTagDescription=all_standard_tags
 org.eclipse.jdt.core.compiler.problem.missingJavadocTags=error
 org.eclipse.jdt.core.compiler.problem.missingJavadocTagsMethodTypeParameters=disabled
 org.eclipse.jdt.core.compiler.problem.missingJavadocTagsOverriding=disabled
diff --git a/org.eclipse.jgit.http.apache/META-INF/MANIFEST.MF b/org.eclipse.jgit.http.apache/META-INF/MANIFEST.MF
index d28b700..dbc3947 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.6.2.qualifier
+Bundle-Version: 6.7.1.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.6.2,6.7.0)",
- org.eclipse.jgit.nls;version="[6.6.2,6.7.0)",
- org.eclipse.jgit.transport.http;version="[6.6.2,6.7.0)",
- org.eclipse.jgit.util;version="[6.6.2,6.7.0)"
-Export-Package: org.eclipse.jgit.transport.http.apache;version="6.6.2";
+ org.eclipse.jgit.annotations;version="[6.7.1,6.8.0)",
+ org.eclipse.jgit.nls;version="[6.7.1,6.8.0)",
+ org.eclipse.jgit.transport.http;version="[6.7.1,6.8.0)",
+ org.eclipse.jgit.util;version="[6.7.1,6.8.0)"
+Export-Package: org.eclipse.jgit.transport.http.apache;version="6.7.1";
   uses:="org.apache.http.client,
    org.eclipse.jgit.transport.http,
    org.apache.http.entity,
diff --git a/org.eclipse.jgit.http.apache/META-INF/SOURCE-MANIFEST.MF b/org.eclipse.jgit.http.apache/META-INF/SOURCE-MANIFEST.MF
index 20b3c64..d0decf5 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.6.2.qualifier
-Eclipse-SourceBundle: org.eclipse.jgit.http.apache;version="6.6.2.qualifier";roots="."
+Bundle-Version: 6.7.1.qualifier
+Eclipse-SourceBundle: org.eclipse.jgit.http.apache;version="6.7.1.qualifier";roots="."
diff --git a/org.eclipse.jgit.http.apache/pom.xml b/org.eclipse.jgit.http.apache/pom.xml
index ef7bf99..6820f65 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.6.2-SNAPSHOT</version>
+    <version>6.7.1-SNAPSHOT</version>
   </parent>
 
   <artifactId>org.eclipse.jgit.http.apache</artifactId>
diff --git a/org.eclipse.jgit.http.apache/src/org/eclipse/jgit/transport/http/apache/HttpClientConnection.java b/org.eclipse.jgit.http.apache/src/org/eclipse/jgit/transport/http/apache/HttpClientConnection.java
index 90348f5..6d806de 100644
--- a/org.eclipse.jgit.http.apache/src/org/eclipse/jgit/transport/http/apache/HttpClientConnection.java
+++ b/org.eclipse.jgit.http.apache/src/org/eclipse/jgit/transport/http/apache/HttpClientConnection.java
@@ -203,6 +203,7 @@
 	 * Sets the buffer from which to take the request body
 	 *
 	 * @param buffer
+	 *            the buffer
 	 */
 	public void setBuffer(TemporaryBuffer buffer) {
 		this.entity = new TemporaryBufferEntity(buffer);
@@ -212,7 +213,9 @@
 	 * Constructor for HttpClientConnection.
 	 *
 	 * @param urlStr
+	 *            url string
 	 * @throws MalformedURLException
+	 *             if url is malformed
 	 */
 	public HttpClientConnection(String urlStr) throws MalformedURLException {
 		this(urlStr, null);
@@ -222,8 +225,11 @@
 	 * Constructor for HttpClientConnection.
 	 *
 	 * @param urlStr
+	 *            url string
 	 * @param proxy
+	 *            proxy
 	 * @throws MalformedURLException
+	 *             if url is malformed
 	 */
 	public HttpClientConnection(String urlStr, Proxy proxy)
 			throws MalformedURLException {
@@ -234,9 +240,13 @@
 	 * Constructor for HttpClientConnection.
 	 *
 	 * @param urlStr
+	 *            url string
 	 * @param proxy
+	 *            proxy
 	 * @param cl
+	 *            client
 	 * @throws MalformedURLException
+	 *             if url is malformed
 	 */
 	public HttpClientConnection(String urlStr, Proxy proxy, HttpClient cl)
 			throws MalformedURLException {
@@ -245,20 +255,17 @@
 		this.proxy = proxy;
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public int getResponseCode() throws IOException {
 		execute();
 		return resp.getStatusLine().getStatusCode();
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public URL getURL() {
 		return url;
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public String getResponseMessage() throws IOException {
 		execute();
@@ -287,7 +294,6 @@
 		}
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public Map<String, List<String>> getHeaderFields() {
 		Map<String, List<String>> ret = new HashMap<>();
@@ -304,13 +310,11 @@
 		return ret;
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public void setRequestProperty(String name, String value) {
 		req.addHeader(name, value);
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public void setRequestMethod(String method) throws ProtocolException {
 		this.method = method;
@@ -328,25 +332,21 @@
 		}
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public void setUseCaches(boolean usecaches) {
 		// not needed
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public void setConnectTimeout(int timeout) {
 		this.timeout = Integer.valueOf(timeout);
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public void setReadTimeout(int readTimeout) {
 		this.readTimeout = Integer.valueOf(readTimeout);
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public String getContentType() {
 		HttpEntity responseEntity = resp.getEntity();
@@ -358,7 +358,6 @@
 		return null;
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public InputStream getInputStream() throws IOException {
 		execute();
@@ -366,7 +365,6 @@
 	}
 
 	// will return only the first field
-	/** {@inheritDoc} */
 	@Override
 	public String getHeaderField(@NonNull String name) {
 		Header header = resp.getFirstHeader(name);
@@ -379,7 +377,6 @@
 				.stream().map(Header::getValue).collect(Collectors.toList()));
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public int getContentLength() {
 		Header contentLength = resp.getFirstHeader("content-length"); //$NON-NLS-1$
@@ -395,19 +392,16 @@
 		}
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public void setInstanceFollowRedirects(boolean followRedirects) {
 		this.followRedirects = Boolean.valueOf(followRedirects);
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public void setDoOutput(boolean dooutput) {
 		// TODO: check whether we can really ignore this.
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public void setFixedLengthStreamingMode(int contentLength) {
 		if (entity != null)
@@ -416,7 +410,6 @@
 		entity.setContentLength(contentLength);
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public OutputStream getOutputStream() throws IOException {
 		if (entity == null)
@@ -424,7 +417,6 @@
 		return entity.getBuffer();
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public void setChunkedStreamingMode(int chunklen) {
 		if (entity == null)
@@ -432,31 +424,26 @@
 		entity.setChunked(true);
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public String getRequestMethod() {
 		return method;
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public boolean usingProxy() {
 		return isUsingProxy;
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public void connect() throws IOException {
 		execute();
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public void setHostnameVerifier(HostnameVerifier hostnameverifier) {
 		this.hostnameverifier = hostnameverifier;
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public void configure(KeyManager[] km, TrustManager[] tm,
 			SecureRandom random) throws KeyManagementException {
diff --git a/org.eclipse.jgit.http.apache/src/org/eclipse/jgit/transport/http/apache/TemporaryBufferEntity.java b/org.eclipse.jgit.http.apache/src/org/eclipse/jgit/transport/http/apache/TemporaryBufferEntity.java
index 101886c..40be074 100644
--- a/org.eclipse.jgit.http.apache/src/org/eclipse/jgit/transport/http/apache/TemporaryBufferEntity.java
+++ b/org.eclipse.jgit.http.apache/src/org/eclipse/jgit/transport/http/apache/TemporaryBufferEntity.java
@@ -33,6 +33,7 @@
 	 * content stored in the specified buffer
 	 *
 	 * @param buffer
+	 *            the buffer
 	 */
 	public TemporaryBufferEntity(TemporaryBuffer buffer) {
 		this.buffer = buffer;
@@ -47,13 +48,11 @@
 		return buffer;
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public boolean isRepeatable() {
 		return true;
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public long getContentLength() {
 		if (contentLength != null)
@@ -61,20 +60,17 @@
 		return buffer.length();
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public InputStream getContent() throws IOException, IllegalStateException {
 		return buffer.openInputStream();
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public void writeTo(OutputStream outstream) throws IOException {
 		// TODO: dont we need a progressmonitor
 		buffer.writeTo(outstream, null);
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public boolean isStreaming() {
 		return false;
@@ -84,6 +80,7 @@
 	 * Set the <code>contentLength</code>
 	 *
 	 * @param contentLength
+	 *            content length
 	 */
 	public void setContentLength(int contentLength) {
 		this.contentLength = Integer.valueOf(contentLength);
diff --git a/org.eclipse.jgit.http.server/.settings/org.eclipse.jdt.core.prefs b/org.eclipse.jgit.http.server/.settings/org.eclipse.jdt.core.prefs
index f79df5b..a08ba7b 100644
--- a/org.eclipse.jgit.http.server/.settings/org.eclipse.jdt.core.prefs
+++ b/org.eclipse.jgit.http.server/.settings/org.eclipse.jdt.core.prefs
@@ -52,7 +52,7 @@
 org.eclipse.jdt.core.compiler.problem.missingJavadocComments=error
 org.eclipse.jdt.core.compiler.problem.missingJavadocCommentsOverriding=disabled
 org.eclipse.jdt.core.compiler.problem.missingJavadocCommentsVisibility=protected
-org.eclipse.jdt.core.compiler.problem.missingJavadocTagDescription=return_tag
+org.eclipse.jdt.core.compiler.problem.missingJavadocTagDescription=all_standard_tags
 org.eclipse.jdt.core.compiler.problem.missingJavadocTags=error
 org.eclipse.jdt.core.compiler.problem.missingJavadocTagsMethodTypeParameters=disabled
 org.eclipse.jdt.core.compiler.problem.missingJavadocTagsOverriding=disabled
diff --git a/org.eclipse.jgit.http.server/META-INF/MANIFEST.MF b/org.eclipse.jgit.http.server/META-INF/MANIFEST.MF
index 43c2879..f604473 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.6.2.qualifier
+Bundle-Version: 6.7.1.qualifier
 Bundle-Localization: plugin
 Bundle-Vendor: %Bundle-Vendor
-Export-Package: org.eclipse.jgit.http.server;version="6.6.2",
- org.eclipse.jgit.http.server.glue;version="6.6.2";
+Export-Package: org.eclipse.jgit.http.server;version="6.7.1",
+ org.eclipse.jgit.http.server.glue;version="6.7.1";
   uses:="javax.servlet,javax.servlet.http",
- org.eclipse.jgit.http.server.resolver;version="6.6.2";
+ org.eclipse.jgit.http.server.resolver;version="6.7.1";
   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.6.2,6.7.0)",
- org.eclipse.jgit.errors;version="[6.6.2,6.7.0)",
- org.eclipse.jgit.internal.storage.dfs;version="[6.6.2,6.7.0)",
- org.eclipse.jgit.internal.storage.file;version="[6.6.2,6.7.0)",
- org.eclipse.jgit.internal.transport.parser;version="[6.6.2,6.7.0)",
- org.eclipse.jgit.lib;version="[6.6.2,6.7.0)",
- org.eclipse.jgit.nls;version="[6.6.2,6.7.0)",
- org.eclipse.jgit.revwalk;version="[6.6.2,6.7.0)",
- org.eclipse.jgit.transport;version="[6.6.2,6.7.0)",
- org.eclipse.jgit.transport.resolver;version="[6.6.2,6.7.0)",
- org.eclipse.jgit.util;version="[6.6.2,6.7.0)"
+ org.eclipse.jgit.annotations;version="[6.7.1,6.8.0)",
+ org.eclipse.jgit.errors;version="[6.7.1,6.8.0)",
+ org.eclipse.jgit.internal.storage.dfs;version="[6.7.1,6.8.0)",
+ org.eclipse.jgit.internal.storage.file;version="[6.7.1,6.8.0)",
+ org.eclipse.jgit.internal.transport.parser;version="[6.7.1,6.8.0)",
+ org.eclipse.jgit.lib;version="[6.7.1,6.8.0)",
+ org.eclipse.jgit.nls;version="[6.7.1,6.8.0)",
+ org.eclipse.jgit.revwalk;version="[6.7.1,6.8.0)",
+ org.eclipse.jgit.transport;version="[6.7.1,6.8.0)",
+ org.eclipse.jgit.transport.resolver;version="[6.7.1,6.8.0)",
+ org.eclipse.jgit.util;version="[6.7.1,6.8.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 4c3d783..7f25f9b 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.6.2.qualifier
-Eclipse-SourceBundle: org.eclipse.jgit.http.server;version="6.6.2.qualifier";roots="."
+Bundle-Version: 6.7.1.qualifier
+Eclipse-SourceBundle: org.eclipse.jgit.http.server;version="6.7.1.qualifier";roots="."
diff --git a/org.eclipse.jgit.http.server/pom.xml b/org.eclipse.jgit.http.server/pom.xml
index 648575b..b3df6c7 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.6.2-SNAPSHOT</version>
+    <version>6.7.1-SNAPSHOT</version>
   </parent>
 
   <artifactId>org.eclipse.jgit.http.server</artifactId>
diff --git a/org.eclipse.jgit.http.server/src/org/eclipse/jgit/http/server/AsIsFileFilter.java b/org.eclipse.jgit.http.server/src/org/eclipse/jgit/http/server/AsIsFileFilter.java
index 59dc309..fb74dc7 100644
--- a/org.eclipse.jgit.http.server/src/org/eclipse/jgit/http/server/AsIsFileFilter.java
+++ b/org.eclipse.jgit.http.server/src/org/eclipse/jgit/http/server/AsIsFileFilter.java
@@ -37,19 +37,16 @@
 		this.asIs = getAnyFile;
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public void init(FilterConfig config) throws ServletException {
 		// Do nothing.
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public void destroy() {
 		// Do nothing.
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public void doFilter(ServletRequest request, ServletResponse response,
 			FilterChain chain) throws IOException, ServletException {
diff --git a/org.eclipse.jgit.http.server/src/org/eclipse/jgit/http/server/GitFilter.java b/org.eclipse.jgit.http.server/src/org/eclipse/jgit/http/server/GitFilter.java
index 0957cc8..2f3eee4 100644
--- a/org.eclipse.jgit.http.server/src/org/eclipse/jgit/http/server/GitFilter.java
+++ b/org.eclipse.jgit.http.server/src/org/eclipse/jgit/http/server/GitFilter.java
@@ -189,7 +189,6 @@
 			throw new IllegalStateException(HttpServerText.get().alreadyInitializedByContainer);
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public void init(FilterConfig filterConfig) throws ServletException {
 		super.init(filterConfig);
@@ -305,7 +304,6 @@
 		}
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	protected ServletBinder register(ServletBinder binder) {
 		if (resolver == null)
diff --git a/org.eclipse.jgit.http.server/src/org/eclipse/jgit/http/server/GitServlet.java b/org.eclipse.jgit.http.server/src/org/eclipse/jgit/http/server/GitServlet.java
index 8e49b37..0157dff 100644
--- a/org.eclipse.jgit.http.server/src/org/eclipse/jgit/http/server/GitServlet.java
+++ b/org.eclipse.jgit.http.server/src/org/eclipse/jgit/http/server/GitServlet.java
@@ -170,7 +170,6 @@
 		gitFilter.addReceivePackFilter(filter);
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public void init(ServletConfig config) throws ServletException {
 		gitFilter.init(new FilterConfig() {
diff --git a/org.eclipse.jgit.http.server/src/org/eclipse/jgit/http/server/InfoPacksServlet.java b/org.eclipse.jgit.http.server/src/org/eclipse/jgit/http/server/InfoPacksServlet.java
index e90580b..d94cc41 100644
--- a/org.eclipse.jgit.http.server/src/org/eclipse/jgit/http/server/InfoPacksServlet.java
+++ b/org.eclipse.jgit.http.server/src/org/eclipse/jgit/http/server/InfoPacksServlet.java
@@ -27,7 +27,6 @@
 class InfoPacksServlet extends HttpServlet {
 	private static final long serialVersionUID = 1L;
 
-	/** {@inheritDoc} */
 	@Override
 	public void doGet(final HttpServletRequest req,
 			final HttpServletResponse rsp) throws IOException {
diff --git a/org.eclipse.jgit.http.server/src/org/eclipse/jgit/http/server/InfoRefsServlet.java b/org.eclipse.jgit.http.server/src/org/eclipse/jgit/http/server/InfoRefsServlet.java
index f67313d..4d86be1 100644
--- a/org.eclipse.jgit.http.server/src/org/eclipse/jgit/http/server/InfoRefsServlet.java
+++ b/org.eclipse.jgit.http.server/src/org/eclipse/jgit/http/server/InfoRefsServlet.java
@@ -29,7 +29,6 @@
 class InfoRefsServlet extends HttpServlet {
 	private static final long serialVersionUID = 1L;
 
-	/** {@inheritDoc} */
 	@Override
 	public void doGet(final HttpServletRequest req,
 			final HttpServletResponse rsp) throws IOException {
diff --git a/org.eclipse.jgit.http.server/src/org/eclipse/jgit/http/server/IsLocalFilter.java b/org.eclipse.jgit.http.server/src/org/eclipse/jgit/http/server/IsLocalFilter.java
index e0d9512..434cdb4 100644
--- a/org.eclipse.jgit.http.server/src/org/eclipse/jgit/http/server/IsLocalFilter.java
+++ b/org.eclipse.jgit.http.server/src/org/eclipse/jgit/http/server/IsLocalFilter.java
@@ -33,19 +33,16 @@
  * downstream servlet can directly access its contents on disk.
  */
 class IsLocalFilter implements Filter {
-	/** {@inheritDoc} */
 	@Override
 	public void init(FilterConfig config) throws ServletException {
 		// Do nothing.
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public void destroy() {
 		// Do nothing.
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public void doFilter(ServletRequest request, ServletResponse response,
 			FilterChain chain) throws IOException, ServletException {
diff --git a/org.eclipse.jgit.http.server/src/org/eclipse/jgit/http/server/NoCacheFilter.java b/org.eclipse.jgit.http.server/src/org/eclipse/jgit/http/server/NoCacheFilter.java
index 4f9e6f2..b1a2b30 100644
--- a/org.eclipse.jgit.http.server/src/org/eclipse/jgit/http/server/NoCacheFilter.java
+++ b/org.eclipse.jgit.http.server/src/org/eclipse/jgit/http/server/NoCacheFilter.java
@@ -26,19 +26,16 @@
 
 /** Add HTTP response headers to prevent caching by proxies/browsers. */
 class NoCacheFilter implements Filter {
-	/** {@inheritDoc} */
 	@Override
 	public void init(FilterConfig config) throws ServletException {
 		// Do nothing.
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public void destroy() {
 		// Do nothing.
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public void doFilter(ServletRequest request, ServletResponse response,
 			FilterChain chain) throws IOException, ServletException {
diff --git a/org.eclipse.jgit.http.server/src/org/eclipse/jgit/http/server/ObjectFileServlet.java b/org.eclipse.jgit.http.server/src/org/eclipse/jgit/http/server/ObjectFileServlet.java
index 625ab3e..e581707 100644
--- a/org.eclipse.jgit.http.server/src/org/eclipse/jgit/http/server/ObjectFileServlet.java
+++ b/org.eclipse.jgit.http.server/src/org/eclipse/jgit/http/server/ObjectFileServlet.java
@@ -87,14 +87,12 @@
 
 	abstract String etag(FileSender sender) throws IOException;
 
-	/** {@inheritDoc} */
 	@Override
 	public void doGet(final HttpServletRequest req,
 			final HttpServletResponse rsp) throws IOException {
 		serve(req, rsp, true);
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	protected void doHead(final HttpServletRequest req,
 			final HttpServletResponse rsp) throws ServletException, IOException {
diff --git a/org.eclipse.jgit.http.server/src/org/eclipse/jgit/http/server/ReceivePackErrorHandler.java b/org.eclipse.jgit.http.server/src/org/eclipse/jgit/http/server/ReceivePackErrorHandler.java
index a7ca4d0..c87bbe6 100644
--- a/org.eclipse.jgit.http.server/src/org/eclipse/jgit/http/server/ReceivePackErrorHandler.java
+++ b/org.eclipse.jgit.http.server/src/org/eclipse/jgit/http/server/ReceivePackErrorHandler.java
@@ -42,6 +42,7 @@
 	 * @param r
 	 *            A continuation that handles a git-receive-pack request.
 	 * @throws IOException
+	 *             if an IO error occurred
 	 */
 	void receive(HttpServletRequest req, HttpServletResponse rsp,
 			ReceivePackRunnable r) throws IOException;
@@ -52,7 +53,9 @@
 		 * See {@link ReceivePack#receiveWithExceptionPropagation}.
 		 *
 		 * @throws ServiceMayNotContinueException
+		 *             if transport service cannot continue
 		 * @throws IOException
+		 *             if an IO error occurred
 		 */
 		void receive() throws ServiceMayNotContinueException, IOException;
 	}
diff --git a/org.eclipse.jgit.http.server/src/org/eclipse/jgit/http/server/ReceivePackServlet.java b/org.eclipse.jgit.http.server/src/org/eclipse/jgit/http/server/ReceivePackServlet.java
index f8c95f5..56b4c80 100644
--- a/org.eclipse.jgit.http.server/src/org/eclipse/jgit/http/server/ReceivePackServlet.java
+++ b/org.eclipse.jgit.http.server/src/org/eclipse/jgit/http/server/ReceivePackServlet.java
@@ -136,7 +136,6 @@
 		this.handler = handler;
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public void doPost(final HttpServletRequest req,
 			final HttpServletResponse rsp) throws IOException {
diff --git a/org.eclipse.jgit.http.server/src/org/eclipse/jgit/http/server/RepositoryFilter.java b/org.eclipse.jgit.http.server/src/org/eclipse/jgit/http/server/RepositoryFilter.java
index 943e7f5..9ff922b 100644
--- a/org.eclipse.jgit.http.server/src/org/eclipse/jgit/http/server/RepositoryFilter.java
+++ b/org.eclipse.jgit.http.server/src/org/eclipse/jgit/http/server/RepositoryFilter.java
@@ -71,19 +71,16 @@
 		this.resolver = resolver;
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public void init(FilterConfig config) throws ServletException {
 		context = config.getServletContext();
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public void destroy() {
 		context = null;
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public void doFilter(final ServletRequest request,
 			final ServletResponse response, final FilterChain chain)
diff --git a/org.eclipse.jgit.http.server/src/org/eclipse/jgit/http/server/SmartOutputStream.java b/org.eclipse.jgit.http.server/src/org/eclipse/jgit/http/server/SmartOutputStream.java
index 11123d0..fdac79d 100644
--- a/org.eclipse.jgit.http.server/src/org/eclipse/jgit/http/server/SmartOutputStream.java
+++ b/org.eclipse.jgit.http.server/src/org/eclipse/jgit/http/server/SmartOutputStream.java
@@ -50,7 +50,6 @@
 		this.compressStream = compressStream;
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	protected OutputStream overflow() throws IOException {
 		startedOutput = true;
@@ -63,7 +62,6 @@
 		return out;
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public void close() throws IOException {
 		super.close();
diff --git a/org.eclipse.jgit.http.server/src/org/eclipse/jgit/http/server/SmartServiceInfoRefs.java b/org.eclipse.jgit.http.server/src/org/eclipse/jgit/http/server/SmartServiceInfoRefs.java
index 6110bff..aa04431 100644
--- a/org.eclipse.jgit.http.server/src/org/eclipse/jgit/http/server/SmartServiceInfoRefs.java
+++ b/org.eclipse.jgit.http.server/src/org/eclipse/jgit/http/server/SmartServiceInfoRefs.java
@@ -47,19 +47,16 @@
 		this.filters = filters.toArray(new Filter[0]);
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public void init(FilterConfig config) throws ServletException {
 		// Do nothing.
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public void destroy() {
 		// Do nothing.
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public void doFilter(ServletRequest request, ServletResponse response,
 			FilterChain chain) throws IOException, ServletException {
@@ -122,8 +119,12 @@
 	 * @param db
 	 *            repository
 	 * @throws IOException
+	 *             if an IO error occurred
 	 * @throws ServiceNotEnabledException
+	 *             if a service is not available
 	 * @throws ServiceNotAuthorizedException
+	 *             if service requires authentication and the current user
+	 *             didn't provide credentials
 	 */
 	protected abstract void begin(HttpServletRequest req, Repository db)
 			throws IOException, ServiceNotEnabledException,
@@ -135,35 +136,43 @@
 	 * @param req
 	 *            request
 	 * @param pck
+	 *            used to frame lines in PacketLineOut format
 	 * @throws IOException
+	 *             if an IO error occurred
 	 * @throws ServiceNotEnabledException
+	 *             if a service is not available
 	 * @throws ServiceNotAuthorizedException
+	 *             if service requires authentication and the current user
+	 *             didn't provide credentials
 	 */
 	protected abstract void advertise(HttpServletRequest req,
 			PacketLineOutRefAdvertiser pck) throws IOException,
 			ServiceNotEnabledException, ServiceNotAuthorizedException;
 
 	/**
-	 * Writes the appropriate response to an info/refs request received by
-	 * a smart service. In protocol v0, this starts with "#
-	 * service=serviceName" followed by a flush packet, but this is not
-	 * necessarily the case in other protocol versions.
+	 * Writes the appropriate response to an info/refs request received by a
+	 * smart service. In protocol v0, this starts with "# service=serviceName"
+	 * followed by a flush packet, but this is not necessarily the case in other
+	 * protocol versions.
 	 * <p>
-	 * The default implementation writes "# service=serviceName" and a
-	 * flush packet, then calls {@link #advertise}. Subclasses should
-	 * override this method if they support protocol versions other than
-	 * protocol v0.
+	 * The default implementation writes "# service=serviceName" and a flush
+	 * packet, then calls {@link #advertise}. Subclasses should override this
+	 * method if they support protocol versions other than protocol v0.
 	 *
 	 * @param req
 	 *            request
 	 * @param pckOut
 	 *            destination of response
 	 * @param serviceName
-	 *            service name to be written out in protocol v0; may or may
-	 *            not be used in other versions
+	 *            service name to be written out in protocol v0; may or may not
+	 *            be used in other versions
 	 * @throws IOException
+	 *             if an IO error occurred
 	 * @throws ServiceNotEnabledException
+	 *             if a service is not available
 	 * @throws ServiceNotAuthorizedException
+	 *             if service requires authentication and the current user
+	 *             didn't provide credentials
 	 */
 	protected void respond(HttpServletRequest req,
 			PacketLineOut pckOut, String serviceName)
diff --git a/org.eclipse.jgit.http.server/src/org/eclipse/jgit/http/server/TextFileServlet.java b/org.eclipse.jgit.http.server/src/org/eclipse/jgit/http/server/TextFileServlet.java
index df8eb77..0b225e7 100644
--- a/org.eclipse.jgit.http.server/src/org/eclipse/jgit/http/server/TextFileServlet.java
+++ b/org.eclipse.jgit.http.server/src/org/eclipse/jgit/http/server/TextFileServlet.java
@@ -35,7 +35,6 @@
 		this.fileName = name;
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public void doGet(final HttpServletRequest req,
 			final HttpServletResponse rsp) throws IOException {
diff --git a/org.eclipse.jgit.http.server/src/org/eclipse/jgit/http/server/UploadPackErrorHandler.java b/org.eclipse.jgit.http.server/src/org/eclipse/jgit/http/server/UploadPackErrorHandler.java
index 2aadbbc..aaf537f 100644
--- a/org.eclipse.jgit.http.server/src/org/eclipse/jgit/http/server/UploadPackErrorHandler.java
+++ b/org.eclipse.jgit.http.server/src/org/eclipse/jgit/http/server/UploadPackErrorHandler.java
@@ -58,6 +58,7 @@
 		}
 		return SC_INTERNAL_SERVER_ERROR;
 	}
+
 	/**
 	 * @param req
 	 *            The HTTP request
@@ -66,6 +67,7 @@
 	 * @param r
 	 *            A continuation that handles a git-upload-pack request.
 	 * @throws IOException
+	 *             if an IO error occurred
 	 */
 	void upload(HttpServletRequest req, HttpServletResponse rsp,
 			UploadPackRunnable r) throws IOException;
@@ -76,7 +78,9 @@
 		 * See {@link UploadPack#uploadWithExceptionPropagation}.
 		 *
 		 * @throws ServiceMayNotContinueException
+		 *             transport service cannot continue
 		 * @throws IOException
+		 *             if an IO error occurred
 		 */
 		void upload() throws ServiceMayNotContinueException, IOException;
 	}
diff --git a/org.eclipse.jgit.http.server/src/org/eclipse/jgit/http/server/UploadPackServlet.java b/org.eclipse.jgit.http.server/src/org/eclipse/jgit/http/server/UploadPackServlet.java
index f16e56d..74419a5 100644
--- a/org.eclipse.jgit.http.server/src/org/eclipse/jgit/http/server/UploadPackServlet.java
+++ b/org.eclipse.jgit.http.server/src/org/eclipse/jgit/http/server/UploadPackServlet.java
@@ -158,7 +158,6 @@
 				: this::defaultUploadPackHandler;
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public void doPost(HttpServletRequest req, HttpServletResponse rsp)
 			throws IOException {
diff --git a/org.eclipse.jgit.http.server/src/org/eclipse/jgit/http/server/glue/ErrorServlet.java b/org.eclipse.jgit.http.server/src/org/eclipse/jgit/http/server/glue/ErrorServlet.java
index 7f4243a..822bb79 100644
--- a/org.eclipse.jgit.http.server/src/org/eclipse/jgit/http/server/glue/ErrorServlet.java
+++ b/org.eclipse.jgit.http.server/src/org/eclipse/jgit/http/server/glue/ErrorServlet.java
@@ -35,7 +35,6 @@
 		this.status = status;
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	protected void doGet(HttpServletRequest req, HttpServletResponse rsp)
 			throws ServletException, IOException {
diff --git a/org.eclipse.jgit.http.server/src/org/eclipse/jgit/http/server/glue/MetaFilter.java b/org.eclipse.jgit.http.server/src/org/eclipse/jgit/http/server/glue/MetaFilter.java
index 772b996..e626bec 100644
--- a/org.eclipse.jgit.http.server/src/org/eclipse/jgit/http/server/glue/MetaFilter.java
+++ b/org.eclipse.jgit.http.server/src/org/eclipse/jgit/http/server/glue/MetaFilter.java
@@ -97,13 +97,11 @@
 		return register(new RegexPipeline.Binder(pattern));
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public void init(FilterConfig filterConfig) throws ServletException {
 		servletContext = filterConfig.getServletContext();
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public void destroy() {
 		if (pipelines != null) {
@@ -140,7 +138,6 @@
 		};
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public void doFilter(ServletRequest request, ServletResponse response,
 			FilterChain chain) throws IOException, ServletException {
diff --git a/org.eclipse.jgit.http.server/src/org/eclipse/jgit/http/server/glue/MetaServlet.java b/org.eclipse.jgit.http.server/src/org/eclipse/jgit/http/server/glue/MetaServlet.java
index a0fa5ea..9a1a249 100644
--- a/org.eclipse.jgit.http.server/src/org/eclipse/jgit/http/server/glue/MetaServlet.java
+++ b/org.eclipse.jgit.http.server/src/org/eclipse/jgit/http/server/glue/MetaServlet.java
@@ -88,7 +88,6 @@
 		return filter.serveRegex(expression);
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public void init(ServletConfig config) throws ServletException {
 		String name = filter.getClass().getName();
@@ -96,13 +95,11 @@
 		filter.init(new NoParameterFilterConfig(name, ctx));
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public void destroy() {
 		filter.destroy();
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	protected void service(HttpServletRequest req, HttpServletResponse res)
 			throws ServletException, IOException {
diff --git a/org.eclipse.jgit.http.server/src/org/eclipse/jgit/http/server/glue/NoParameterFilterConfig.java b/org.eclipse.jgit.http.server/src/org/eclipse/jgit/http/server/glue/NoParameterFilterConfig.java
index ebe2728..3f7ee2a 100644
--- a/org.eclipse.jgit.http.server/src/org/eclipse/jgit/http/server/glue/NoParameterFilterConfig.java
+++ b/org.eclipse.jgit.http.server/src/org/eclipse/jgit/http/server/glue/NoParameterFilterConfig.java
@@ -26,13 +26,11 @@
 		this.context = context;
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public String getInitParameter(String name) {
 		return null;
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public Enumeration<String> getInitParameterNames() {
 		return new Enumeration<>() {
@@ -49,13 +47,11 @@
 		};
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public ServletContext getServletContext() {
 		return context;
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public String getFilterName() {
 		return filterName;
diff --git a/org.eclipse.jgit.http.server/src/org/eclipse/jgit/http/server/glue/RegexGroupFilter.java b/org.eclipse.jgit.http.server/src/org/eclipse/jgit/http/server/glue/RegexGroupFilter.java
index a321c96..c8ff6a3 100644
--- a/org.eclipse.jgit.http.server/src/org/eclipse/jgit/http/server/glue/RegexGroupFilter.java
+++ b/org.eclipse.jgit.http.server/src/org/eclipse/jgit/http/server/glue/RegexGroupFilter.java
@@ -49,19 +49,16 @@
 		this.groupIdx = groupIdx - 1;
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public void init(FilterConfig config) throws ServletException {
 		// Do nothing.
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public void destroy() {
 		// Do nothing.
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public void doFilter(final ServletRequest request,
 			final ServletResponse rsp, final FilterChain chain)
diff --git a/org.eclipse.jgit.http.server/src/org/eclipse/jgit/http/server/glue/RegexPipeline.java b/org.eclipse.jgit.http.server/src/org/eclipse/jgit/http/server/glue/RegexPipeline.java
index 431202b..5baa14a 100644
--- a/org.eclipse.jgit.http.server/src/org/eclipse/jgit/http/server/glue/RegexPipeline.java
+++ b/org.eclipse.jgit.http.server/src/org/eclipse/jgit/http/server/glue/RegexPipeline.java
@@ -131,7 +131,6 @@
 		}
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public String toString() {
 		return "Pipeline[regex: " + pattern + " ]";
diff --git a/org.eclipse.jgit.http.server/src/org/eclipse/jgit/http/server/glue/ServletBinderImpl.java b/org.eclipse.jgit.http.server/src/org/eclipse/jgit/http/server/glue/ServletBinderImpl.java
index 21f1800..cd49023 100644
--- a/org.eclipse.jgit.http.server/src/org/eclipse/jgit/http/server/glue/ServletBinderImpl.java
+++ b/org.eclipse.jgit.http.server/src/org/eclipse/jgit/http/server/glue/ServletBinderImpl.java
@@ -28,7 +28,6 @@
 		this.filters = new ArrayList<>();
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public ServletBinder through(Filter filter) {
 		if (filter == null)
@@ -37,7 +36,6 @@
 		return this;
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public void with(HttpServlet servlet) {
 		if (servlet == null)
diff --git a/org.eclipse.jgit.http.server/src/org/eclipse/jgit/http/server/glue/SuffixPipeline.java b/org.eclipse.jgit.http.server/src/org/eclipse/jgit/http/server/glue/SuffixPipeline.java
index 86441b1..39d57b5 100644
--- a/org.eclipse.jgit.http.server/src/org/eclipse/jgit/http/server/glue/SuffixPipeline.java
+++ b/org.eclipse.jgit.http.server/src/org/eclipse/jgit/http/server/glue/SuffixPipeline.java
@@ -70,7 +70,6 @@
 		super.service(new WrappedRequest(req, newPath, newInfo), rsp);
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public String toString() {
 		return "Pipeline[ *" + suffix + " ]";
diff --git a/org.eclipse.jgit.http.server/src/org/eclipse/jgit/http/server/glue/WrappedRequest.java b/org.eclipse.jgit.http.server/src/org/eclipse/jgit/http/server/glue/WrappedRequest.java
index e6bc934..4bac040 100644
--- a/org.eclipse.jgit.http.server/src/org/eclipse/jgit/http/server/glue/WrappedRequest.java
+++ b/org.eclipse.jgit.http.server/src/org/eclipse/jgit/http/server/glue/WrappedRequest.java
@@ -38,20 +38,17 @@
 		this.pathInfo = pathInfo;
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public String getPathTranslated() {
 		final String p = getPathInfo();
 		return p != null ? getSession().getServletContext().getRealPath(p) : null;
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public String getPathInfo() {
 		return pathInfo;
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public String getServletPath() {
 		return path;
diff --git a/org.eclipse.jgit.http.server/src/org/eclipse/jgit/http/server/resolver/DefaultReceivePackFactory.java b/org.eclipse.jgit.http.server/src/org/eclipse/jgit/http/server/resolver/DefaultReceivePackFactory.java
index 16b27e8..0bf10cb 100644
--- a/org.eclipse.jgit.http.server/src/org/eclipse/jgit/http/server/resolver/DefaultReceivePackFactory.java
+++ b/org.eclipse.jgit.http.server/src/org/eclipse/jgit/http/server/resolver/DefaultReceivePackFactory.java
@@ -47,7 +47,6 @@
 		}
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public ReceivePack create(HttpServletRequest req, Repository db)
 			throws ServiceNotEnabledException, ServiceNotAuthorizedException {
diff --git a/org.eclipse.jgit.http.server/src/org/eclipse/jgit/http/server/resolver/DefaultUploadPackFactory.java b/org.eclipse.jgit.http.server/src/org/eclipse/jgit/http/server/resolver/DefaultUploadPackFactory.java
index d362a96..2931435 100644
--- a/org.eclipse.jgit.http.server/src/org/eclipse/jgit/http/server/resolver/DefaultUploadPackFactory.java
+++ b/org.eclipse.jgit.http.server/src/org/eclipse/jgit/http/server/resolver/DefaultUploadPackFactory.java
@@ -38,7 +38,6 @@
 		}
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public UploadPack create(HttpServletRequest req, Repository db)
 			throws ServiceNotEnabledException, ServiceNotAuthorizedException {
diff --git a/org.eclipse.jgit.http.test/META-INF/MANIFEST.MF b/org.eclipse.jgit.http.test/META-INF/MANIFEST.MF
index c589d8e..ae776dc 100644
--- a/org.eclipse.jgit.http.test/META-INF/MANIFEST.MF
+++ b/org.eclipse.jgit.http.test/META-INF/MANIFEST.MF
@@ -3,10 +3,12 @@
 Bundle-Name: %Bundle-Name
 Automatic-Module-Name: org.eclipse.jgit.http.test
 Bundle-SymbolicName: org.eclipse.jgit.http.test
-Bundle-Version: 6.6.2.qualifier
+Bundle-Version: 6.7.1.qualifier
 Bundle-Vendor: %Bundle-Vendor
 Bundle-Localization: plugin
 Bundle-RequiredExecutionEnvironment: JavaSE-11
+Require-Bundle: org.hamcrest.core;bundle-version="[1.3.0,2.0.0)",
+ org.hamcrest.library;bundle-version="[1.3.0,2.0.0)"
 Import-Package: javax.servlet;version="[2.5.0,5.0.0)",
  javax.servlet.http;version="[2.5.0,5.0.0)",
  org.apache.commons.codec;version="[1.6.0,2.0.0)",
@@ -26,28 +28,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.6.2,6.7.0)",
- org.eclipse.jgit.errors;version="[6.6.2,6.7.0)",
- org.eclipse.jgit.http.server;version="[6.6.2,6.7.0)",
- org.eclipse.jgit.http.server.glue;version="[6.6.2,6.7.0)",
- org.eclipse.jgit.http.server.resolver;version="[6.6.2,6.7.0)",
- org.eclipse.jgit.internal;version="[6.6.2,6.7.0)",
- org.eclipse.jgit.internal.storage.dfs;version="[6.6.2,6.7.0)",
- org.eclipse.jgit.internal.storage.file;version="[6.6.2,6.7.0)",
- org.eclipse.jgit.internal.storage.reftable;version="[6.6.2,6.7.0)",
- org.eclipse.jgit.junit;version="[6.6.2,6.7.0)",
- org.eclipse.jgit.junit.http;version="[6.6.2,6.7.0)",
- org.eclipse.jgit.lib;version="[6.6.2,6.7.0)",
- org.eclipse.jgit.nls;version="[6.6.2,6.7.0)",
- org.eclipse.jgit.revwalk;version="[6.6.2,6.7.0)",
- org.eclipse.jgit.storage.file;version="[6.6.2,6.7.0)",
- org.eclipse.jgit.transport;version="[6.6.2,6.7.0)",
- org.eclipse.jgit.transport.http;version="[6.6.2,6.7.0)",
- org.eclipse.jgit.transport.http.apache;version="[6.6.2,6.7.0)",
- org.eclipse.jgit.transport.resolver;version="[6.6.2,6.7.0)",
- org.eclipse.jgit.util;version="[6.6.2,6.7.0)",
- org.hamcrest;version="[1.1.0,3.0.0)",
- org.hamcrest.core;version="[1.1.0,3.0.0)",
+ org.eclipse.jgit.api;version="[6.7.1,6.8.0)",
+ org.eclipse.jgit.errors;version="[6.7.1,6.8.0)",
+ org.eclipse.jgit.http.server;version="[6.7.1,6.8.0)",
+ org.eclipse.jgit.http.server.glue;version="[6.7.1,6.8.0)",
+ org.eclipse.jgit.http.server.resolver;version="[6.7.1,6.8.0)",
+ org.eclipse.jgit.internal;version="[6.7.1,6.8.0)",
+ org.eclipse.jgit.internal.storage.dfs;version="[6.7.1,6.8.0)",
+ org.eclipse.jgit.internal.storage.file;version="[6.7.1,6.8.0)",
+ org.eclipse.jgit.internal.storage.reftable;version="[6.7.1,6.8.0)",
+ org.eclipse.jgit.junit;version="[6.7.1,6.8.0)",
+ org.eclipse.jgit.junit.http;version="[6.7.1,6.8.0)",
+ org.eclipse.jgit.lib;version="[6.7.1,6.8.0)",
+ org.eclipse.jgit.nls;version="[6.7.1,6.8.0)",
+ org.eclipse.jgit.revwalk;version="[6.7.1,6.8.0)",
+ org.eclipse.jgit.storage.file;version="[6.7.1,6.8.0)",
+ org.eclipse.jgit.transport;version="[6.7.1,6.8.0)",
+ org.eclipse.jgit.transport.http;version="[6.7.1,6.8.0)",
+ org.eclipse.jgit.transport.http.apache;version="[6.7.1,6.8.0)",
+ org.eclipse.jgit.transport.resolver;version="[6.7.1,6.8.0)",
+ org.eclipse.jgit.util;version="[6.7.1,6.8.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)",
diff --git a/org.eclipse.jgit.http.test/pom.xml b/org.eclipse.jgit.http.test/pom.xml
index a5e677b..8546be4 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.6.2-SNAPSHOT</version>
+    <version>6.7.1-SNAPSHOT</version>
   </parent>
 
   <artifactId>org.eclipse.jgit.http.test</artifactId>
diff --git a/org.eclipse.jgit.http.test/src/org/eclipse/jgit/http/test/RefsUnreadableInMemoryRepository.java b/org.eclipse.jgit.http.test/src/org/eclipse/jgit/http/test/RefsUnreadableInMemoryRepository.java
index 4167b03..86da87f 100644
--- a/org.eclipse.jgit.http.test/src/org/eclipse/jgit/http/test/RefsUnreadableInMemoryRepository.java
+++ b/org.eclipse.jgit.http.test/src/org/eclipse/jgit/http/test/RefsUnreadableInMemoryRepository.java
@@ -36,7 +36,6 @@
 		failing = false;
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public RefDatabase getRefDatabase() {
 		return refs;
@@ -54,7 +53,6 @@
 
 	private class RefsUnreadableRefDatabase extends MemRefDatabase {
 
-		/** {@inheritDoc} */
 		@Override
 		public Ref exactRef(String name) throws IOException {
 			if (failing) {
@@ -63,7 +61,6 @@
 			return super.exactRef(name);
 		}
 
-		/** {@inheritDoc} */
 		@Override
 		public Map<String, Ref> getRefs(String prefix) throws IOException {
 			if (failing) {
@@ -73,7 +70,6 @@
 			return super.getRefs(prefix);
 		}
 
-		/** {@inheritDoc} */
 		@Override
 		public List<Ref> getRefsByPrefix(String prefix) throws IOException {
 			if (failing) {
@@ -83,7 +79,6 @@
 			return super.getRefsByPrefix(prefix);
 		}
 
-		/** {@inheritDoc} */
 		@Override
 		public List<Ref> getRefsByPrefixWithExclusions(String include, Set<String> excludes)
 				throws IOException {
@@ -94,7 +89,6 @@
 			return super.getRefsByPrefixWithExclusions(include, excludes);
 		}
 
-		/** {@inheritDoc} */
 		@Override
 		public Set<Ref> getTipsWithSha1(ObjectId id) throws IOException {
 			if (failing) {
diff --git a/org.eclipse.jgit.http.test/src/org/eclipse/jgit/http/test/TestRepositoryResolver.java b/org.eclipse.jgit.http.test/src/org/eclipse/jgit/http/test/TestRepositoryResolver.java
index 6478b94..82168d1 100644
--- a/org.eclipse.jgit.http.test/src/org/eclipse/jgit/http/test/TestRepositoryResolver.java
+++ b/org.eclipse.jgit.http.test/src/org/eclipse/jgit/http/test/TestRepositoryResolver.java
@@ -41,7 +41,6 @@
 		this.repoName = repoName;
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public Repository open(HttpServletRequest req, String name)
 			throws RepositoryNotFoundException, ServiceNotEnabledException {
diff --git a/org.eclipse.jgit.junit.http/META-INF/MANIFEST.MF b/org.eclipse.jgit.junit.http/META-INF/MANIFEST.MF
index 98533a4..df6934e 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.6.2.qualifier
+Bundle-Version: 6.7.1.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.6.2,6.7.0)",
- org.eclipse.jgit.http.server;version="[6.6.2,6.7.0)",
- org.eclipse.jgit.internal.storage.file;version="[6.6.2,6.7.0)",
- org.eclipse.jgit.junit;version="[6.6.2,6.7.0)",
- org.eclipse.jgit.lib;version="[6.6.2,6.7.0)",
- org.eclipse.jgit.revwalk;version="[6.6.2,6.7.0)",
- org.eclipse.jgit.transport;version="[6.6.2,6.7.0)",
- org.eclipse.jgit.transport.resolver;version="[6.6.2,6.7.0)",
+ org.eclipse.jgit.errors;version="[6.7.1,6.8.0)",
+ org.eclipse.jgit.http.server;version="[6.7.1,6.8.0)",
+ org.eclipse.jgit.internal.storage.file;version="[6.7.1,6.8.0)",
+ org.eclipse.jgit.junit;version="[6.7.1,6.8.0)",
+ org.eclipse.jgit.lib;version="[6.7.1,6.8.0)",
+ org.eclipse.jgit.revwalk;version="[6.7.1,6.8.0)",
+ org.eclipse.jgit.transport;version="[6.7.1,6.8.0)",
+ org.eclipse.jgit.transport.resolver;version="[6.7.1,6.8.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.6.2";
+Export-Package: org.eclipse.jgit.junit.http;version="6.7.1";
   uses:="org.eclipse.jgit.transport,
    org.eclipse.jgit.junit,
    javax.servlet.http,
diff --git a/org.eclipse.jgit.junit.http/META-INF/SOURCE-MANIFEST.MF b/org.eclipse.jgit.junit.http/META-INF/SOURCE-MANIFEST.MF
index d2a0690..30be81f 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.6.2.qualifier
-Eclipse-SourceBundle: org.eclipse.jgit.junit.http;version="6.6.2.qualifier";roots="."
+Bundle-Version: 6.7.1.qualifier
+Eclipse-SourceBundle: org.eclipse.jgit.junit.http;version="6.7.1.qualifier";roots="."
diff --git a/org.eclipse.jgit.junit.http/pom.xml b/org.eclipse.jgit.junit.http/pom.xml
index 6618b63..4684725 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.6.2-SNAPSHOT</version>
+    <version>6.7.1-SNAPSHOT</version>
   </parent>
 
   <artifactId>org.eclipse.jgit.junit.http</artifactId>
diff --git a/org.eclipse.jgit.junit.http/src/org/eclipse/jgit/junit/http/AccessEvent.java b/org.eclipse.jgit.junit.http/src/org/eclipse/jgit/junit/http/AccessEvent.java
index 873d430..3d4f379 100644
--- a/org.eclipse.jgit.junit.http/src/org/eclipse/jgit/junit/http/AccessEvent.java
+++ b/org.eclipse.jgit.junit.http/src/org/eclipse/jgit/junit/http/AccessEvent.java
@@ -146,7 +146,6 @@
 		return responseHeaders != null ? responseHeaders.get(name) : null;
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public String toString() {
 		StringBuilder b = new StringBuilder();
diff --git a/org.eclipse.jgit.junit.http/src/org/eclipse/jgit/junit/http/AppServer.java b/org.eclipse.jgit.junit.http/src/org/eclipse/jgit/junit/http/AppServer.java
index 36f2f2b..de4535a 100644
--- a/org.eclipse.jgit.junit.http/src/org/eclipse/jgit/junit/http/AppServer.java
+++ b/org.eclipse.jgit.junit.http/src/org/eclipse/jgit/junit/http/AppServer.java
@@ -260,7 +260,9 @@
 	 * Configure basic authentication.
 	 *
 	 * @param ctx
+	 *            servlet context handler
 	 * @param methods
+	 *            the methods
 	 * @return servlet context handler
 	 */
 	public ServletContextHandler authBasic(ServletContextHandler ctx,
diff --git a/org.eclipse.jgit.junit.http/src/org/eclipse/jgit/junit/http/HttpTestCase.java b/org.eclipse.jgit.junit.http/src/org/eclipse/jgit/junit/http/HttpTestCase.java
index 877b918..8a4d363 100644
--- a/org.eclipse.jgit.junit.http/src/org/eclipse/jgit/junit/http/HttpTestCase.java
+++ b/org.eclipse.jgit.junit.http/src/org/eclipse/jgit/junit/http/HttpTestCase.java
@@ -45,14 +45,12 @@
 	/** In-memory application server; subclass must start. */
 	protected AppServer server;
 
-	/** {@inheritDoc} */
 	@Override
 	public void setUp() throws Exception {
 		super.setUp();
 		server = createServer();
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public void tearDown() throws Exception {
 		server.tearDown();
@@ -78,6 +76,7 @@
 	 *
 	 * @return the TestRepository
 	 * @throws IOException
+	 *             if an IO error occurred
 	 */
 	protected TestRepository<Repository> createTestRepository()
 			throws IOException {
@@ -90,8 +89,10 @@
 	 * Convert path to URIish
 	 *
 	 * @param path
+	 *            the path
 	 * @return the URIish
 	 * @throws URISyntaxException
+	 *             if URI is invalid
 	 */
 	protected URIish toURIish(String path) throws URISyntaxException {
 		URI u = server.getURI().resolve(path);
@@ -102,9 +103,12 @@
 	 * Convert a path relative to the app's context path to a URIish
 	 *
 	 * @param app
+	 *            app name
 	 * @param name
+	 *            context path name
 	 * @return the warnings (if any) from the last execution
 	 * @throws URISyntaxException
+	 *             if URI is invalid
 	 */
 	protected URIish toURIish(ServletContextHandler app, String name)
 			throws URISyntaxException {
@@ -128,7 +132,9 @@
 	 * Get requests.
 	 *
 	 * @param base
+	 *            base URI
 	 * @param path
+	 *            the request path relative to {@code base}
 	 *
 	 * @return list of events
 	 */
@@ -140,6 +146,7 @@
 	 * Get requests.
 	 *
 	 * @param path
+	 *            request path
 	 *
 	 * @return list of events
 	 */
@@ -151,8 +158,11 @@
 	 * Run fsck
 	 *
 	 * @param db
+	 *            the repository
 	 * @param tips
+	 *            tips to start checking from
 	 * @throws Exception
+	 *             if an error occurred
 	 */
 	protected static void fsck(Repository db, RevObject... tips)
 			throws Exception {
@@ -166,6 +176,7 @@
 	 * Mirror refs
 	 *
 	 * @param refs
+	 *            the refs
 	 * @return set of RefSpecs
 	 */
 	protected static Set<RefSpec> mirror(String... refs) {
@@ -183,9 +194,12 @@
 	 * Push a commit
 	 *
 	 * @param from
+	 *            repository from which to push
 	 * @param q
+	 *            commit to push
 	 * @return collection of RefUpdates
 	 * @throws IOException
+	 *             if an IO error occurred
 	 */
 	protected static Collection<RemoteRefUpdate> push(TestRepository from,
 			RevCommit q) throws IOException {
@@ -205,7 +219,9 @@
 	 * Create loose object path
 	 *
 	 * @param base
+	 *            base URI
 	 * @param id
+	 *            objectId
 	 * @return path of the loose object
 	 */
 	public static String loose(URIish base, AnyObjectId id) {
@@ -219,6 +235,7 @@
 	 * Join a base URIish and a path
 	 *
 	 * @param base
+	 *            base URI
 	 * @param path
 	 *            a relative path
 	 * @return the joined path
@@ -237,8 +254,11 @@
 	 * Rewrite a url
 	 *
 	 * @param url
+	 *            the URL
 	 * @param newProtocol
+	 *            new protocol
 	 * @param newPort
+	 *            new port
 	 * @return the rewritten url
 	 */
 	protected static String rewriteUrl(String url, String newProtocol,
@@ -263,9 +283,12 @@
 	 * Extend a path
 	 *
 	 * @param uri
+	 *            the URI
 	 * @param pathComponents
+	 *            path components
 	 * @return the extended URIish
 	 * @throws URISyntaxException
+	 *             if URI is invalid
 	 */
 	protected static URIish extendPath(URIish uri, String pathComponents)
 			throws URISyntaxException {
diff --git a/org.eclipse.jgit.junit.http/src/org/eclipse/jgit/junit/http/MockServletConfig.java b/org.eclipse.jgit.junit.http/src/org/eclipse/jgit/junit/http/MockServletConfig.java
index 715fd19..cd1eba4 100644
--- a/org.eclipse.jgit.junit.http/src/org/eclipse/jgit/junit/http/MockServletConfig.java
+++ b/org.eclipse.jgit.junit.http/src/org/eclipse/jgit/junit/http/MockServletConfig.java
@@ -28,19 +28,19 @@
 	 * Set init parameter.
 	 *
 	 * @param name
+	 *            parameter name
 	 * @param value
+	 *            parameter value
 	 */
 	public void setInitParameter(String name, String value) {
 		parameters.put(name, value);
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public String getInitParameter(String name) {
 		return parameters.get(name);
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public Enumeration<String> getInitParameterNames() {
 		final Iterator<String> i = parameters.keySet().iterator();
@@ -58,13 +58,11 @@
 		};
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public String getServletName() {
 		return "MOCK_SERVLET";
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public ServletContext getServletContext() {
 		return null;
diff --git a/org.eclipse.jgit.junit.http/src/org/eclipse/jgit/junit/http/RecordingLogger.java b/org.eclipse.jgit.junit.http/src/org/eclipse/jgit/junit/http/RecordingLogger.java
index af63084..f56e1fa 100644
--- a/org.eclipse.jgit.junit.http/src/org/eclipse/jgit/junit/http/RecordingLogger.java
+++ b/org.eclipse.jgit.junit.http/src/org/eclipse/jgit/junit/http/RecordingLogger.java
@@ -70,6 +70,7 @@
 	 * Constructor for <code>RecordingLogger</code>.
 	 *
 	 * @param name
+	 *            logger name
 	 */
 	public RecordingLogger(String name) {
 		this.name = name;
diff --git a/org.eclipse.jgit.junit.http/src/org/eclipse/jgit/junit/http/SimpleHttpServer.java b/org.eclipse.jgit.junit.http/src/org/eclipse/jgit/junit/http/SimpleHttpServer.java
index 2493f99..01f18da 100644
--- a/org.eclipse.jgit.junit.http/src/org/eclipse/jgit/junit/http/SimpleHttpServer.java
+++ b/org.eclipse.jgit.junit.http/src/org/eclipse/jgit/junit/http/SimpleHttpServer.java
@@ -40,6 +40,7 @@
 	 * Constructor for <code>SimpleHttpServer</code>.
 	 *
 	 * @param repository
+	 *            the repository
 	 */
 	public SimpleHttpServer(Repository repository) {
 		this(repository, false);
@@ -49,7 +50,9 @@
 	 * Constructor for <code>SimpleHttpServer</code>.
 	 *
 	 * @param repository
+	 *            the repository
 	 * @param withSsl
+	 *            whether to encrypt the communication
 	 */
 	public SimpleHttpServer(Repository repository, boolean withSsl) {
 		this.db = repository;
@@ -60,6 +63,7 @@
 	 * Start the server
 	 *
 	 * @throws Exception
+	 *             if an error occurred
 	 */
 	public void start() throws Exception {
 		ServletContextHandler sBasic = server.authBasic(smart("/sbasic"));
@@ -76,6 +80,7 @@
 	 * Stop the server.
 	 *
 	 * @throws Exception
+	 *             if an error occurred
 	 */
 	public void stop() throws Exception {
 		server.tearDown();
diff --git a/org.eclipse.jgit.junit.http/src/org/eclipse/jgit/junit/http/TestRequestLog.java b/org.eclipse.jgit.junit.http/src/org/eclipse/jgit/junit/http/TestRequestLog.java
index 04cb242..afa8c35 100644
--- a/org.eclipse.jgit.junit.http/src/org/eclipse/jgit/junit/http/TestRequestLog.java
+++ b/org.eclipse.jgit.junit.http/src/org/eclipse/jgit/junit/http/TestRequestLog.java
@@ -72,7 +72,6 @@
 		}
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public void handle(String target, Request baseRequest,
 			HttpServletRequest request, HttpServletResponse response)
diff --git a/org.eclipse.jgit.junit.ssh/.settings/.api_filters b/org.eclipse.jgit.junit.ssh/.settings/.api_filters
deleted file mode 100644
index 44c9dfa..0000000
--- a/org.eclipse.jgit.junit.ssh/.settings/.api_filters
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8" standalone="no"?>
-<component id="org.eclipse.jgit.junit.ssh" version="2">
-    <resource path="src/org/eclipse/jgit/junit/ssh/SshTestHarness.java" type="org.eclipse.jgit.junit.ssh.SshTestHarness">
-        <filter id="336658481">
-            <message_arguments>
-                <message_argument value="org.eclipse.jgit.junit.ssh.SshTestHarness"/>
-                <message_argument value="publicKey2"/>
-    </resource>
-    <resource path="META-INF/MANIFEST.MF">
-        <filter id="923795461">
-            <message_arguments>
-                <message_argument value="5.11.2"/>
-                <message_argument value="5.10.0"/>
-            </message_arguments>
-        </filter>
-    </resource>
-    <resource path="src/org/eclipse/jgit/junit/ssh/SshTestBase.java" type="org.eclipse.jgit.junit.ssh.SshTestBase">
-        <filter id="338792546">
-            <message_arguments>
-                <message_argument value="org.eclipse.jgit.junit.ssh.SshTestBase"/>
-                <message_argument value="testSshWithConfig()"/>
-            </message_arguments>
-        </filter>
-    </resource>
-</component>
diff --git a/org.eclipse.jgit.junit.ssh/META-INF/MANIFEST.MF b/org.eclipse.jgit.junit.ssh/META-INF/MANIFEST.MF
index 8729675..6a9561e 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.6.2.qualifier
+Bundle-Version: 6.7.1.qualifier
 Bundle-Localization: plugin
 Bundle-Vendor: %Bundle-Vendor
 Bundle-ActivationPolicy: lazy
@@ -33,16 +33,16 @@
  org.apache.sshd.server.subsystem;version="[2.10.0,2.11.0)",
  org.apache.sshd.sftp;version="[2.10.0,2.11.0)",
  org.apache.sshd.sftp.server;version="[2.10.0,2.11.0)",
- org.eclipse.jgit.annotations;version="[6.6.2,6.7.0)",
- org.eclipse.jgit.api;version="[6.6.2,6.7.0)",
- org.eclipse.jgit.api.errors;version="[6.6.2,6.7.0)",
- org.eclipse.jgit.errors;version="[6.6.2,6.7.0)",
- org.eclipse.jgit.junit;version="[6.6.2,6.7.0)",
- org.eclipse.jgit.lib;version="[6.6.2,6.7.0)",
- org.eclipse.jgit.revwalk;version="[6.6.2,6.7.0)",
- org.eclipse.jgit.transport;version="[6.6.2,6.7.0)",
- org.eclipse.jgit.util;version="[6.6.2,6.7.0)",
+ org.eclipse.jgit.annotations;version="[6.7.1,6.8.0)",
+ org.eclipse.jgit.api;version="[6.7.1,6.8.0)",
+ org.eclipse.jgit.api.errors;version="[6.7.1,6.8.0)",
+ org.eclipse.jgit.errors;version="[6.7.1,6.8.0)",
+ org.eclipse.jgit.junit;version="[6.7.1,6.8.0)",
+ org.eclipse.jgit.lib;version="[6.7.1,6.8.0)",
+ org.eclipse.jgit.revwalk;version="[6.7.1,6.8.0)",
+ org.eclipse.jgit.transport;version="[6.7.1,6.8.0)",
+ org.eclipse.jgit.util;version="[6.7.1,6.8.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.6.2"
+Export-Package: org.eclipse.jgit.junit.ssh;version="6.7.1"
diff --git a/org.eclipse.jgit.junit.ssh/META-INF/SOURCE-MANIFEST.MF b/org.eclipse.jgit.junit.ssh/META-INF/SOURCE-MANIFEST.MF
index 1bb45a1..1b0a63c 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.6.2.qualifier
-Eclipse-SourceBundle: org.eclipse.jgit.junit.ssh;version="6.6.2.qualifier";roots="."
+Bundle-Version: 6.7.1.qualifier
+Eclipse-SourceBundle: org.eclipse.jgit.junit.ssh;version="6.7.1.qualifier";roots="."
diff --git a/org.eclipse.jgit.junit.ssh/pom.xml b/org.eclipse.jgit.junit.ssh/pom.xml
index 1d01ec3..40e128c 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.6.2-SNAPSHOT</version>
+    <version>6.7.1-SNAPSHOT</version>
   </parent>
 
   <artifactId>org.eclipse.jgit.junit.ssh</artifactId>
diff --git a/org.eclipse.jgit.junit.ssh/src/org/eclipse/jgit/junit/ssh/SshTestGitServer.java b/org.eclipse.jgit.junit.ssh/src/org/eclipse/jgit/junit/ssh/SshTestGitServer.java
index 5d043ff..1138be8 100644
--- a/org.eclipse.jgit.junit.ssh/src/org/eclipse/jgit/junit/ssh/SshTestGitServer.java
+++ b/org.eclipse.jgit.junit.ssh/src/org/eclipse/jgit/junit/ssh/SshTestGitServer.java
@@ -116,7 +116,9 @@
 	 * @param hostKey
 	 *            the unencrypted private key to use as host key
 	 * @throws IOException
+	 *             if an IO error occurred
 	 * @throws GeneralSecurityException
+	 *             if something went wrong
 	 */
 	public SshTestGitServer(@NonNull String testUser, @NonNull Path testKey,
 			@NonNull Repository repository, @NonNull byte[] hostKey)
@@ -138,7 +140,9 @@
 	 * @param hostKey
 	 *            the unencrypted private key to use as host key
 	 * @throws IOException
+	 *             if an IO error occurred
 	 * @throws GeneralSecurityException
+	 *             if something went wrong
 	 * @since 5.9
 	 */
 	public SshTestGitServer(@NonNull String testUser, @NonNull Path testKey,
@@ -413,6 +417,7 @@
 	 * @return the port the server listens on; test clients should connect to
 	 *         that port
 	 * @throws IOException
+	 *             if an IO error occurred
 	 */
 	public int start() throws IOException {
 		server.start();
@@ -423,6 +428,7 @@
 	 * Stops the test server.
 	 *
 	 * @throws IOException
+	 *             if an IO error occurred
 	 */
 	public void stop() throws IOException {
 		executorService.shutdownNow();
diff --git a/org.eclipse.jgit.junit.ssh/src/org/eclipse/jgit/junit/ssh/SshTestHarness.java b/org.eclipse.jgit.junit.ssh/src/org/eclipse/jgit/junit/ssh/SshTestHarness.java
index a28d5eb..b183b22 100644
--- a/org.eclipse.jgit.junit.ssh/src/org/eclipse/jgit/junit/ssh/SshTestHarness.java
+++ b/org.eclipse.jgit.junit.ssh/src/org/eclipse/jgit/junit/ssh/SshTestHarness.java
@@ -89,8 +89,6 @@
 
 	protected File knownHosts;
 
-	private File homeDir;
-
 	@Override
 	public void setUp() throws Exception {
 		super.setUp();
@@ -99,13 +97,8 @@
 			git.add().addFilepattern("file.txt").call();
 			git.commit().setMessage("Initial commit").call();
 		}
-		mockSystemReader.setProperty("user.home",
-				getTemporaryDirectory().getAbsolutePath());
-		mockSystemReader.setProperty("HOME",
-				getTemporaryDirectory().getAbsolutePath());
-		homeDir = FS.DETECTED.userHome();
-		FS.DETECTED.setUserHome(getTemporaryDirectory().getAbsoluteFile());
-		sshDir = new File(getTemporaryDirectory(), ".ssh");
+		// The home directory is mocked here
+		sshDir = new File(FS.DETECTED.userHome(), ".ssh");
 		assertTrue(sshDir.mkdir());
 		File serverDir = new File(getTemporaryDirectory(), "srv");
 		assertTrue(serverDir.mkdir());
@@ -191,6 +184,7 @@
 	 *            to use
 	 * @return the public-key part of the line
 	 * @throws IOException
+	 *             if an IO error occurred
 	 */
 	protected static String createKnownHostsFile(File file, String host,
 			int port, File publicKey) throws IOException {
@@ -235,7 +229,6 @@
 			server.stop();
 			server = null;
 		}
-		FS.DETECTED.setUserHome(homeDir);
 		SshSessionFactory.setInstance(null);
 		factory = null;
 	}
diff --git a/org.eclipse.jgit.junit/.settings/org.eclipse.jdt.core.prefs b/org.eclipse.jgit.junit/.settings/org.eclipse.jdt.core.prefs
index bdfba71..bb15648 100644
--- a/org.eclipse.jgit.junit/.settings/org.eclipse.jdt.core.prefs
+++ b/org.eclipse.jgit.junit/.settings/org.eclipse.jdt.core.prefs
@@ -56,7 +56,7 @@
 org.eclipse.jdt.core.compiler.problem.missingJavadocComments=error
 org.eclipse.jdt.core.compiler.problem.missingJavadocCommentsOverriding=disabled
 org.eclipse.jdt.core.compiler.problem.missingJavadocCommentsVisibility=protected
-org.eclipse.jdt.core.compiler.problem.missingJavadocTagDescription=return_tag
+org.eclipse.jdt.core.compiler.problem.missingJavadocTagDescription=all_standard_tags
 org.eclipse.jdt.core.compiler.problem.missingJavadocTags=error
 org.eclipse.jdt.core.compiler.problem.missingJavadocTagsMethodTypeParameters=disabled
 org.eclipse.jdt.core.compiler.problem.missingJavadocTagsOverriding=disabled
diff --git a/org.eclipse.jgit.junit/META-INF/MANIFEST.MF b/org.eclipse.jgit.junit/META-INF/MANIFEST.MF
index f195156..29410b4 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.6.2.qualifier
+Bundle-Version: 6.7.1.qualifier
 Bundle-Localization: plugin
 Bundle-Vendor: %Bundle-Vendor
 Bundle-ActivationPolicy: lazy
 Bundle-RequiredExecutionEnvironment: JavaSE-11
-Import-Package: org.eclipse.jgit.annotations;version="[6.6.2,6.7.0)",
- org.eclipse.jgit.api;version="[6.6.2,6.7.0)",
- org.eclipse.jgit.api.errors;version="[6.6.2,6.7.0)",
- org.eclipse.jgit.dircache;version="[6.6.2,6.7.0)",
- org.eclipse.jgit.errors;version="[6.6.2,6.7.0)",
- org.eclipse.jgit.internal.storage.file;version="[6.6.2,6.7.0)",
- org.eclipse.jgit.internal.storage.pack;version="[6.6.2,6.7.0)",
- org.eclipse.jgit.lib;version="[6.6.2,6.7.0)",
- org.eclipse.jgit.merge;version="[6.6.2,6.7.0)",
- org.eclipse.jgit.revwalk;version="[6.6.2,6.7.0)",
- org.eclipse.jgit.storage.file;version="[6.6.2,6.7.0)",
- org.eclipse.jgit.transport;version="6.6.2",
- org.eclipse.jgit.treewalk;version="[6.6.2,6.7.0)",
- org.eclipse.jgit.treewalk.filter;version="[6.6.2,6.7.0)",
- org.eclipse.jgit.util;version="[6.6.2,6.7.0)",
- org.eclipse.jgit.util.io;version="[6.6.2,6.7.0)",
- org.eclipse.jgit.util.time;version="[6.6.2,6.7.0)",
+Import-Package: org.eclipse.jgit.annotations;version="[6.7.1,6.8.0)",
+ org.eclipse.jgit.api;version="[6.7.1,6.8.0)",
+ org.eclipse.jgit.api.errors;version="[6.7.1,6.8.0)",
+ org.eclipse.jgit.dircache;version="[6.7.1,6.8.0)",
+ org.eclipse.jgit.errors;version="[6.7.1,6.8.0)",
+ org.eclipse.jgit.internal.storage.file;version="[6.7.1,6.8.0)",
+ org.eclipse.jgit.internal.storage.pack;version="[6.7.1,6.8.0)",
+ org.eclipse.jgit.lib;version="[6.7.1,6.8.0)",
+ org.eclipse.jgit.merge;version="[6.7.1,6.8.0)",
+ org.eclipse.jgit.revwalk;version="[6.7.1,6.8.0)",
+ org.eclipse.jgit.storage.file;version="[6.7.1,6.8.0)",
+ org.eclipse.jgit.transport;version="6.7.1",
+ org.eclipse.jgit.treewalk;version="[6.7.1,6.8.0)",
+ org.eclipse.jgit.treewalk.filter;version="[6.7.1,6.8.0)",
+ org.eclipse.jgit.util;version="[6.7.1,6.8.0)",
+ org.eclipse.jgit.util.io;version="[6.7.1,6.8.0)",
+ org.eclipse.jgit.util.time;version="[6.7.1,6.8.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.6.2";
+Export-Package: org.eclipse.jgit.junit;version="6.7.1";
   uses:="org.eclipse.jgit.dircache,
    org.eclipse.jgit.lib,
    org.eclipse.jgit.revwalk,
@@ -44,4 +44,4 @@
    org.junit.runners.model,
    org.junit.runner,
    org.eclipse.jgit.util.time",
- org.eclipse.jgit.junit.time;version="6.6.2";uses:="org.eclipse.jgit.util.time"
+ org.eclipse.jgit.junit.time;version="6.7.1";uses:="org.eclipse.jgit.util.time"
diff --git a/org.eclipse.jgit.junit/META-INF/SOURCE-MANIFEST.MF b/org.eclipse.jgit.junit/META-INF/SOURCE-MANIFEST.MF
index a420be6..9855442 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.6.2.qualifier
-Eclipse-SourceBundle: org.eclipse.jgit.junit;version="6.6.2.qualifier";roots="."
+Bundle-Version: 6.7.1.qualifier
+Eclipse-SourceBundle: org.eclipse.jgit.junit;version="6.7.1.qualifier";roots="."
diff --git a/org.eclipse.jgit.junit/pom.xml b/org.eclipse.jgit.junit/pom.xml
index a86842b..620325b 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.6.2-SNAPSHOT</version>
+    <version>6.7.1-SNAPSHOT</version>
   </parent>
 
   <artifactId>org.eclipse.jgit.junit</artifactId>
diff --git a/org.eclipse.jgit.junit/src/org/eclipse/jgit/junit/JGitTestUtil.java b/org.eclipse.jgit.junit/src/org/eclipse/jgit/junit/JGitTestUtil.java
index 61d3b86..177d873 100644
--- a/org.eclipse.jgit.junit/src/org/eclipse/jgit/junit/JGitTestUtil.java
+++ b/org.eclipse.jgit.junit/src/org/eclipse/jgit/junit/JGitTestUtil.java
@@ -107,6 +107,7 @@
 	 * Get test resource file.
 	 *
 	 * @param fileName
+	 *            file name
 	 * @return the test resource file
 	 */
 	public static File getTestResourceFile(String fileName) {
@@ -141,8 +142,11 @@
 	 * Copy test resource.
 	 *
 	 * @param name
+	 *            resource name
 	 * @param dest
+	 *            destination file
 	 * @throws IOException
+	 *             if an IO error occurred
 	 */
 	public static void copyTestResource(String name, File dest)
 			throws IOException {
@@ -165,10 +169,14 @@
 	 * Write a trash file.
 	 *
 	 * @param db
+	 *            the repository
 	 * @param name
+	 *            file name
 	 * @param data
+	 *            file content
 	 * @return the trash file
 	 * @throws IOException
+	 *             if an IO error occurred
 	 */
 	public static File writeTrashFile(final Repository db,
 			final String name, final String data) throws IOException {
@@ -181,11 +189,16 @@
 	 * Write a trash file.
 	 *
 	 * @param db
+	 *            the repository
 	 * @param subdir
+	 *            under working tree
 	 * @param name
+	 *            file name
 	 * @param data
+	 *            file content
 	 * @return the trash file
 	 * @throws IOException
+	 *             if an IO error occurred
 	 */
 	public static File writeTrashFile(final Repository db,
 			final String subdir,
@@ -237,9 +250,12 @@
 	 * Read a file's content
 	 *
 	 * @param db
+	 *            the repository
 	 * @param name
+	 *            file name
 	 * @return the content of the file
 	 * @throws IOException
+	 *             if an IO error occurred
 	 */
 	public static String read(Repository db, String name)
 			throws IOException {
@@ -251,6 +267,7 @@
 	 * Check if file exists
 	 *
 	 * @param db
+	 *            the repository
 	 * @param name
 	 *            name of the file
 	 * @return {@code true} if the file exists
@@ -264,8 +281,11 @@
 	 * Delete a trash file.
 	 *
 	 * @param db
+	 *            the repository
 	 * @param name
+	 *            file name
 	 * @throws IOException
+	 *             if an IO error occurred
 	 */
 	public static void deleteTrashFile(final Repository db,
 			final String name) throws IOException {
@@ -284,6 +304,7 @@
 	 *            the target of the symbolic link
 	 * @return the path to the symbolic link
 	 * @throws Exception
+	 *             if an error occurred
 	 * @since 4.2
 	 */
 	public static Path writeLink(Repository db, String link,
diff --git a/org.eclipse.jgit.junit/src/org/eclipse/jgit/junit/LocalDiskRepositoryTestCase.java b/org.eclipse.jgit.junit/src/org/eclipse/jgit/junit/LocalDiskRepositoryTestCase.java
index 59662ce..f816158 100644
--- a/org.eclipse.jgit.junit/src/org/eclipse/jgit/junit/LocalDiskRepositoryTestCase.java
+++ b/org.eclipse.jgit.junit/src/org/eclipse/jgit/junit/LocalDiskRepositoryTestCase.java
@@ -85,6 +85,8 @@
 	private final Set<Repository> toClose = new HashSet<>();
 	private File tmp;
 
+	private File homeDir;
+
 	/**
 	 * The current test name.
 	 *
@@ -107,6 +109,7 @@
 	 * Setup test
 	 *
 	 * @throws Exception
+	 *             if an error occurred
 	 */
 	@Before
 	public void setUp() throws Exception {
@@ -118,6 +121,14 @@
 		mockSystemReader = new MockSystemReader();
 		SystemReader.setInstance(mockSystemReader);
 
+		// Mock the home directory. We don't want to pick up the real user's git
+		// config, or global git ignore.
+		// XDG_CONFIG_HOME isn't set in the MockSystemReader.
+		mockSystemReader.setProperty("user.home", tmp.getAbsolutePath());
+		mockSystemReader.setProperty("HOME", tmp.getAbsolutePath());
+		homeDir = FS.DETECTED.userHome();
+		FS.DETECTED.setUserHome(tmp.getAbsoluteFile());
+
 		// Measure timer resolution before the test to avoid time critical tests
 		// are affected by time needed for measurement.
 		// The MockSystemReader must be configured first since we need to use
@@ -189,25 +200,30 @@
 	 * Tear down the test
 	 *
 	 * @throws Exception
+	 *             if an error occurred
 	 */
 	@After
 	public void tearDown() throws Exception {
 		RepositoryCache.clear();
-		for (Repository r : toClose)
+		for (Repository r : toClose) {
 			r.close();
+		}
 		toClose.clear();
 
 		// Since memory mapping is controlled by the GC we need to
 		// tell it this is a good time to clean up and unlock
 		// memory mapped files.
 		//
-		if (useMMAP)
+		if (useMMAP) {
 			System.gc();
-		if (tmp != null)
+		}
+		FS.DETECTED.setUserHome(homeDir);
+		if (tmp != null) {
 			recursiveDelete(tmp, false, true);
-		if (tmp != null && !tmp.exists())
+		}
+		if (tmp != null && !tmp.exists()) {
 			CleanupThread.removed(tmp);
-
+		}
 		SystemReader.setInstance(null);
 	}
 
@@ -314,11 +330,11 @@
 	 *            {@link #CONTENT} controlling which info is present in the
 	 *            resulting string.
 	 * @return a string encoding the index state
-	 * @throws IllegalStateException
 	 * @throws IOException
+	 *             if an IO error occurred
 	 */
 	public static String indexState(Repository repo, int includedOptions)
-			throws IllegalStateException, IOException {
+			throws IOException {
 		DirCache dc = repo.readDirCache();
 		StringBuilder sb = new StringBuilder();
 		TreeSet<Instant> timeStamps = new TreeSet<>();
@@ -452,6 +468,7 @@
 	 *            a subdirectory
 	 * @return a unique directory for a test
 	 * @throws IOException
+	 *             if an IO error occurred
 	 */
 	protected File createTempDirectory(String name) throws IOException {
 		File directory = new File(createTempFile(), name);
@@ -467,6 +484,7 @@
 	 *            working directory
 	 * @return a unique directory for a test repository
 	 * @throws IOException
+	 *             if an IO error occurred
 	 */
 	protected File createUniqueTestGitDir(boolean bare) throws IOException {
 		String gitdirName = createTempFile().getPath();
@@ -487,6 +505,7 @@
 	 *
 	 * @return a unique path that does not exist.
 	 * @throws IOException
+	 *             if an IO error occurred
 	 */
 	protected File createTempFile() throws IOException {
 		File p = File.createTempFile("tmp_", "", tmp);
@@ -586,6 +605,7 @@
 	 *            the file
 	 * @return the content of the file
 	 * @throws IOException
+	 *             if an IO error occurred
 	 */
 	protected String read(File f) throws IOException {
 		return JGitTestUtil.read(f);
diff --git a/org.eclipse.jgit.junit/src/org/eclipse/jgit/junit/MockSystemReader.java b/org.eclipse.jgit.junit/src/org/eclipse/jgit/junit/MockSystemReader.java
index 6bfe706..4dbfc59 100644
--- a/org.eclipse.jgit.junit/src/org/eclipse/jgit/junit/MockSystemReader.java
+++ b/org.eclipse.jgit.junit/src/org/eclipse/jgit/junit/MockSystemReader.java
@@ -144,32 +144,30 @@
 	 * Set a property
 	 *
 	 * @param key
+	 *            the key
 	 * @param value
+	 *            the value
 	 */
 	public void setProperty(String key, String value) {
 		values.put(key, value);
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public String getenv(String variable) {
 		return values.get(variable);
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public String getProperty(String key) {
 		return values.get(key);
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public FileBasedConfig openUserConfig(Config parent, FS fs) {
 		assert parent == null || parent == systemGitConfig;
 		return userGitConfig;
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public FileBasedConfig openSystemConfig(Config parent, FS fs) {
 		assert parent == null;
@@ -193,19 +191,16 @@
 		return systemGitConfig;
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public String getHostname() {
 		return "fake.host.example.com";
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public long getCurrentTime() {
 		return now;
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public MonotonicClock getClock() {
 		return () -> {
@@ -236,31 +231,26 @@
 		now += secDelta * 1000L;
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public int getTimezone(long when) {
 		return getTimeZone().getOffset(when) / (60 * 1000);
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public TimeZone getTimeZone() {
 		return TimeZone.getTimeZone("GMT-03:30");
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public Locale getLocale() {
 		return Locale.US;
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public SimpleDateFormat getSimpleDateFormat(String pattern) {
 		return new SimpleDateFormat(pattern, getLocale());
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public DateFormat getDateTimeInstance(int dateStyle, int timeStyle) {
 		return DateFormat
diff --git a/org.eclipse.jgit.junit/src/org/eclipse/jgit/junit/Repeat.java b/org.eclipse.jgit.junit/src/org/eclipse/jgit/junit/Repeat.java
index 343aa92..4bf2eb5 100644
--- a/org.eclipse.jgit.junit/src/org/eclipse/jgit/junit/Repeat.java
+++ b/org.eclipse.jgit.junit/src/org/eclipse/jgit/junit/Repeat.java
@@ -21,6 +21,8 @@
 public @interface Repeat {
 	/**
 	 * Number of repetitions
+	 *
+	 * @return number of repetitions
 	 */
 	public abstract int n();
 
diff --git a/org.eclipse.jgit.junit/src/org/eclipse/jgit/junit/RepeatRule.java b/org.eclipse.jgit.junit/src/org/eclipse/jgit/junit/RepeatRule.java
index adcc10c..30fffe9 100644
--- a/org.eclipse.jgit.junit/src/org/eclipse/jgit/junit/RepeatRule.java
+++ b/org.eclipse.jgit.junit/src/org/eclipse/jgit/junit/RepeatRule.java
@@ -125,7 +125,6 @@
 		}
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public Statement apply(Statement statement, Description description) {
 		Statement result = statement;
diff --git a/org.eclipse.jgit.junit/src/org/eclipse/jgit/junit/RepositoryTestCase.java b/org.eclipse.jgit.junit/src/org/eclipse/jgit/junit/RepositoryTestCase.java
index 04988f6..3a283ce 100644
--- a/org.eclipse.jgit.junit/src/org/eclipse/jgit/junit/RepositoryTestCase.java
+++ b/org.eclipse.jgit.junit/src/org/eclipse/jgit/junit/RepositoryTestCase.java
@@ -62,8 +62,11 @@
 	 * Copy a file
 	 *
 	 * @param src
+	 *            file to copy
 	 * @param dst
+	 *            destination of the copy
 	 * @throws IOException
+	 *             if an IO error occurred
 	 */
 	protected static void copyFile(File src, File dst)
 			throws IOException {
@@ -81,9 +84,12 @@
 	 * Write a trash file
 	 *
 	 * @param name
+	 *            file name
 	 * @param data
+	 *            file content
 	 * @return the trash file
 	 * @throws IOException
+	 *             if an IO error occurred
 	 */
 	protected File writeTrashFile(String name, String data)
 			throws IOException {
@@ -99,6 +105,7 @@
 	 *            the target of the symbolic link
 	 * @return the path to the symbolic link
 	 * @throws Exception
+	 *             if an error occurred
 	 * @since 4.2
 	 */
 	protected Path writeLink(String link, String target)
@@ -110,10 +117,14 @@
 	 * Write a trash file
 	 *
 	 * @param subdir
+	 *            in working tree
 	 * @param name
+	 *            file name
 	 * @param data
+	 *            file content
 	 * @return the trash file
 	 * @throws IOException
+	 *             if an IO error occurred
 	 */
 	protected File writeTrashFile(final String subdir, final String name,
 			final String data)
@@ -125,8 +136,10 @@
 	 * Read content of a file
 	 *
 	 * @param name
+	 *            file name
 	 * @return the file's content
 	 * @throws IOException
+	 *             if an IO error occurred
 	 */
 	protected String read(String name) throws IOException {
 		return JGitTestUtil.read(db, name);
@@ -149,6 +162,7 @@
 	 * @param name
 	 *            file name
 	 * @throws IOException
+	 *             if an IO error occurred
 	 */
 	protected void deleteTrashFile(String name) throws IOException {
 		JGitTestUtil.deleteTrashFile(db, name);
@@ -158,9 +172,11 @@
 	 * Check content of a file.
 	 *
 	 * @param f
+	 *            file
 	 * @param checkData
 	 *            expected content
 	 * @throws IOException
+	 *             if an IO error occurred
 	 */
 	protected static void checkFile(File f, String checkData)
 			throws IOException {
@@ -181,7 +197,6 @@
 	/** Working directory of {@link #db}. */
 	protected File trash;
 
-	/** {@inheritDoc} */
 	@Override
 	@Before
 	public void setUp() throws Exception {
@@ -229,11 +244,11 @@
 	 *            {@link #CONTENT} controlling which info is present in the
 	 *            resulting string.
 	 * @return a string encoding the index state
-	 * @throws IllegalStateException
 	 * @throws IOException
+	 *             if an IO error occurred
 	 */
 	public String indexState(int includedOptions)
-			throws IllegalStateException, IOException {
+			throws IOException {
 		return indexState(db, includedOptions);
 	}
 
@@ -251,7 +266,9 @@
 	 *            a {@link org.eclipse.jgit.treewalk.FileTreeIterator} which
 	 *            determines which files should go into the new index
 	 * @throws FileNotFoundException
+	 *             file was not found
 	 * @throws IOException
+	 *             if an IO error occurred
 	 */
 	protected void resetIndex(FileTreeIterator treeItr)
 			throws FileNotFoundException, IOException {
@@ -339,7 +356,9 @@
 	 * @return return the last measured value of the filesystem timer which is
 	 *         greater than then the lastmodification time of lastfile.
 	 * @throws InterruptedException
+	 *             if thread was interrupted
 	 * @throws IOException
+	 *             if an IO error occurred
 	 * @since 5.1.9
 	 */
 	public static Instant fsTick(File lastFile)
@@ -378,8 +397,11 @@
 	 * Create a branch
 	 *
 	 * @param objectId
+	 *            new value to create the branch on
 	 * @param branchName
+	 *            branch name
 	 * @throws IOException
+	 *             if an IO error occurred
 	 */
 	protected void createBranch(ObjectId objectId, String branchName)
 			throws IOException {
@@ -393,6 +415,7 @@
 	 *
 	 * @return list of refs
 	 * @throws IOException
+	 *             if an IO error occurred
 	 */
 	public List<Ref> getRefs() throws IOException {
 		return db.getRefDatabase().getRefs();
@@ -402,11 +425,12 @@
 	 * Checkout a branch
 	 *
 	 * @param branchName
-	 * @throws IllegalStateException
+	 *            branch name
 	 * @throws IOException
+	 *             if an IO error occurred
 	 */
 	protected void checkoutBranch(String branchName)
-			throws IllegalStateException, IOException {
+			throws IOException {
 		try (RevWalk walk = new RevWalk(db)) {
 			RevCommit head = walk.parseCommit(db.resolve(Constants.HEAD));
 			RevCommit branch = walk.parseCommit(db.resolve(branchName));
@@ -436,7 +460,9 @@
 	 *            the contents which should be written into the files
 	 * @return the File object associated to the last written file.
 	 * @throws IOException
+	 *             if an IO error occurred
 	 * @throws InterruptedException
+	 *             if thread was interrupted
 	 */
 	protected File writeTrashFiles(boolean ensureDistinctTimestamps,
 			String... contents)
@@ -459,8 +485,11 @@
 	 * one.
 	 *
 	 * @param filename
+	 *            file name
 	 * @param contents
+	 *            file content
 	 * @param branch
+	 *            branch name
 	 * @return the created commit
 	 */
 	protected RevCommit commitFile(String filename, String contents, String branch) {
@@ -494,7 +523,9 @@
 	 * Create <code>DirCacheEntry</code>
 	 *
 	 * @param path
+	 *            file path
 	 * @param mode
+	 *            file mode
 	 * @return the DirCacheEntry
 	 */
 	protected DirCacheEntry createEntry(String path, FileMode mode) {
@@ -505,8 +536,11 @@
 	 * Create <code>DirCacheEntry</code>
 	 *
 	 * @param path
+	 *            file path
 	 * @param mode
+	 *            file mode
 	 * @param content
+	 *            file content
 	 * @return the DirCacheEntry
 	 */
 	protected DirCacheEntry createEntry(final String path, final FileMode mode,
@@ -518,9 +552,13 @@
 	 * Create <code>DirCacheEntry</code>
 	 *
 	 * @param path
+	 *            file path
 	 * @param mode
+	 *            file mode
 	 * @param stage
+	 *            stage index of the new entry
 	 * @param content
+	 *            file content
 	 * @return the DirCacheEntry
 	 */
 	protected DirCacheEntry createEntry(final String path, final FileMode mode,
@@ -538,7 +576,9 @@
 	 * Create <code>DirCacheEntry</code>
 	 *
 	 * @param path
+	 *            file path
 	 * @param objectId
+	 *            of the entry
 	 * @return the DirCacheEntry
 	 */
 	protected DirCacheEntry createGitLink(String path, AnyObjectId objectId) {
@@ -553,8 +593,11 @@
 	 * Assert files are equal
 	 *
 	 * @param expected
+	 *            expected file
 	 * @param actual
+	 *            actual file
 	 * @throws IOException
+	 *             if an IO error occurred
 	 */
 	public static void assertEqualsFile(File expected, File actual)
 			throws IOException {
diff --git a/org.eclipse.jgit.junit/src/org/eclipse/jgit/junit/StrictWorkMonitor.java b/org.eclipse.jgit.junit/src/org/eclipse/jgit/junit/StrictWorkMonitor.java
index c77bca9..0168ece 100644
--- a/org.eclipse.jgit.junit/src/org/eclipse/jgit/junit/StrictWorkMonitor.java
+++ b/org.eclipse.jgit.junit/src/org/eclipse/jgit/junit/StrictWorkMonitor.java
@@ -20,32 +20,27 @@
 public final class StrictWorkMonitor implements ProgressMonitor {
 	private int lastWork, totalWork;
 
-	/** {@inheritDoc} */
 	@Override
 	public void start(int totalTasks) {
 		// empty
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public void beginTask(String title, int total) {
 		this.totalWork = total;
 		lastWork = 0;
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public void update(int completed) {
 		lastWork += completed;
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public void endTask() {
 		assertEquals("Units of work recorded", totalWork, lastWork);
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public boolean isCancelled() {
 		return false;
diff --git a/org.eclipse.jgit.junit/src/org/eclipse/jgit/junit/TestRepository.java b/org.eclipse.jgit.junit/src/org/eclipse/jgit/junit/TestRepository.java
index 483b9a7..4b45535 100644
--- a/org.eclipse.jgit.junit/src/org/eclipse/jgit/junit/TestRepository.java
+++ b/org.eclipse.jgit.junit/src/org/eclipse/jgit/junit/TestRepository.java
@@ -115,6 +115,7 @@
 	 * @param db
 	 *            the test repository to write into.
 	 * @throws IOException
+	 *             if an IO error occurred
 	 */
 	public TestRepository(R db) throws IOException {
 		this(db, new RevWalk(db), new MockSystemReader());
@@ -128,6 +129,7 @@
 	 * @param rw
 	 *            the RevObject pool to use for object lookup.
 	 * @throws IOException
+	 *             if an IO error occurred
 	 */
 	public TestRepository(R db, RevWalk rw) throws IOException {
 		this(db, rw, new MockSystemReader());
@@ -144,6 +146,7 @@
 	 *            the MockSystemReader to use for clock and other system
 	 *            operations.
 	 * @throws IOException
+	 *             if an IO error occurred
 	 * @since 4.2
 	 */
 	public TestRepository(R db, RevWalk rw, MockSystemReader reader)
@@ -235,6 +238,7 @@
 	 *            file content, will be UTF-8 encoded.
 	 * @return reference to the blob.
 	 * @throws Exception
+	 *             if an error occurred
 	 */
 	public RevBlob blob(String content) throws Exception {
 		return blob(content.getBytes(UTF_8));
@@ -247,6 +251,7 @@
 	 *            binary file content.
 	 * @return the new, fully parsed blob.
 	 * @throws Exception
+	 *             if an error occurred
 	 */
 	public RevBlob blob(byte[] content) throws Exception {
 		ObjectId id;
@@ -266,6 +271,7 @@
 	 *            a blob, previously constructed in the repository.
 	 * @return the entry.
 	 * @throws Exception
+	 *             if an error occurred
 	 */
 	public DirCacheEntry file(String path, RevBlob blob)
 			throws Exception {
@@ -284,6 +290,7 @@
 	 *            a blob, previously constructed in the repository.
 	 * @return the entry.
 	 * @throws Exception
+	 *             if an error occurred
 	 * @since 6.3
 	 */
 	public DirCacheEntry link(String path, RevBlob blob) throws Exception {
@@ -301,6 +308,7 @@
 	 *            to be sorted properly and may be empty.
 	 * @return the new, fully parsed tree specified by the entry list.
 	 * @throws Exception
+	 *             if an error occurred
 	 */
 	public RevTree tree(DirCacheEntry... entries) throws Exception {
 		final DirCache dc = DirCache.newInCore();
@@ -326,6 +334,7 @@
 	 *            the path to find the entry of.
 	 * @return the parsed object entry at this path, never null.
 	 * @throws Exception
+	 *             if an error occurred
 	 */
 	public RevObject get(RevTree tree, String path)
 			throws Exception {
@@ -357,6 +366,7 @@
 	 *            zero or more IDs of the commit's parents.
 	 * @return the ID of the new commit.
 	 * @throws Exception
+	 *             if an error occurred
 	 * @since 5.5
 	 */
 	public ObjectId unparsedCommit(ObjectId... parents) throws Exception {
@@ -373,6 +383,7 @@
 	 *            zero or more parents of the commit.
 	 * @return the new commit.
 	 * @throws Exception
+	 *             if an error occurred
 	 */
 	public RevCommit commit(RevCommit... parents) throws Exception {
 		return commit(1, tree(), parents);
@@ -389,6 +400,7 @@
 	 *            zero or more parents of the commit.
 	 * @return the new commit.
 	 * @throws Exception
+	 *             if an error occurred
 	 */
 	public RevCommit commit(RevTree tree, RevCommit... parents)
 			throws Exception {
@@ -407,6 +419,7 @@
 	 *            zero or more parents of the commit.
 	 * @return the new commit.
 	 * @throws Exception
+	 *             if an error occurred
 	 */
 	public RevCommit commit(int secDelta, RevCommit... parents)
 			throws Exception {
@@ -428,6 +441,7 @@
 	 *            zero or more parents of the commit.
 	 * @return the new, fully parsed commit.
 	 * @throws Exception
+	 *             if an error occurred
 	 */
 	public RevCommit commit(final int secDelta, final RevTree tree,
 			final RevCommit... parents) throws Exception {
@@ -450,6 +464,7 @@
 	 *            zero or more IDs of the commit's parents.
 	 * @return the ID of the new commit.
 	 * @throws Exception
+	 *             if an error occurred
 	 * @since 5.5
 	 */
 	public ObjectId unparsedCommit(final int secDelta, final RevTree tree,
@@ -496,6 +511,7 @@
 	 *            object the tag should be pointed at.
 	 * @return the new, fully parsed annotated tag object.
 	 * @throws Exception
+	 *             if an error occurred
 	 */
 	public RevTag tag(String name, RevObject dst) throws Exception {
 		final TagBuilder t = new TagBuilder();
@@ -524,6 +540,7 @@
 	 *            the target object.
 	 * @return the target object.
 	 * @throws Exception
+	 *             if an error occurred
 	 */
 	public RevCommit update(String ref, CommitBuilder to) throws Exception {
 		return update(ref, to.create());
@@ -534,12 +551,13 @@
 	 *
 	 * @param ref
 	 *            the name of the reference to amend, which must already exist.
-	 *            If {@code ref} does not start with {@code refs/} and is not the
-	 *            magic names {@code HEAD} {@code FETCH_HEAD} or {@code
-	 *            MERGE_HEAD}, then {@code refs/heads/} will be prefixed in front
-	 *            of the given name, thereby assuming it is a branch.
+	 *            If {@code ref} does not start with {@code refs/} and is not
+	 *            the magic names {@code HEAD} {@code FETCH_HEAD} or {@code
+	 *            MERGE_HEAD}, then {@code refs/heads/} will be prefixed in
+	 *            front of the given name, thereby assuming it is a branch.
 	 * @return commit builder that amends the branch on commit.
 	 * @throws Exception
+	 *             if an error occurred
 	 */
 	public CommitBuilder amendRef(String ref) throws Exception {
 		String name = normalizeRef(ref);
@@ -556,6 +574,7 @@
 	 *            the id of the commit to amend.
 	 * @return commit builder.
 	 * @throws Exception
+	 *             if an error occurred
 	 */
 	public CommitBuilder amend(AnyObjectId id) throws Exception {
 		return amend(pool.parseCommit(id), commit());
@@ -610,6 +629,7 @@
 	 *            the target object.
 	 * @return the target object.
 	 * @throws Exception
+	 *             if an error occurred
 	 */
 	public <T extends AnyObjectId> T update(String ref, T obj) throws Exception {
 		ref = normalizeRef(ref);
@@ -632,9 +652,10 @@
 	 * Delete a reference.
 	 *
 	 * @param ref
-	 *	      the name of the reference to delete. This is normalized
-	 *	      in the same way as {@link #update(String, AnyObjectId)}.
+	 *            the name of the reference to delete. This is normalized in the
+	 *            same way as {@link #update(String, AnyObjectId)}.
 	 * @throws Exception
+	 *             if an error occurred
 	 * @since 4.4
 	 */
 	public void delete(String ref) throws Exception {
@@ -674,6 +695,7 @@
 	 * @param id
 	 *            ID of detached head.
 	 * @throws Exception
+	 *             if an error occurred
 	 * @see #reset(String)
 	 */
 	public void reset(AnyObjectId id) throws Exception {
@@ -695,13 +717,14 @@
 	/**
 	 * Soft-reset HEAD to a different commit.
 	 * <p>
-	 * This is equivalent to {@code git reset --soft} in that it modifies HEAD but
-	 * not the index or the working tree of a non-bare repository.
+	 * This is equivalent to {@code git reset --soft} in that it modifies HEAD
+	 * but not the index or the working tree of a non-bare repository.
 	 *
 	 * @param name
-	 *            revision string; either an existing ref name, or something that
-	 *            can be parsed to an object ID.
+	 *            revision string; either an existing ref name, or something
+	 *            that can be parsed to an object ID.
 	 * @throws Exception
+	 *             if an error occurred
 	 */
 	public void reset(String name) throws Exception {
 		RefUpdate.Result result;
@@ -735,6 +758,7 @@
 	 * @return the new, fully parsed commit, or null if no work was done due to
 	 *         the resulting tree being identical.
 	 * @throws Exception
+	 *             if an error occurred
 	 */
 	public RevCommit cherryPick(AnyObjectId id) throws Exception {
 		RevCommit commit = pool.parseCommit(id);
@@ -779,6 +803,7 @@
 	 * Update the dumb client server info files.
 	 *
 	 * @throws Exception
+	 *             if an error occurred
 	 */
 	public void updateServerInfo() throws Exception {
 		if (db instanceof FileRepository) {
@@ -816,6 +841,7 @@
 	 *            parsing of.
 	 * @return {@code object}
 	 * @throws Exception
+	 *             if an error occurred
 	 */
 	public <T extends RevObject> T parseBody(T object) throws Exception {
 		pool.parseBody(object);
@@ -851,6 +877,7 @@
 	 *            the object to tag
 	 * @return the tagged object
 	 * @throws Exception
+	 *             if an error occurred
 	 */
 	public ObjectId lightweightTag(String name, ObjectId obj) throws Exception {
 		if (!name.startsWith(Constants.R_TAGS))
@@ -868,8 +895,11 @@
 	 *            the tips to start checking from; if not supplied the refs of
 	 *            the repository are used instead.
 	 * @throws MissingObjectException
+	 *             if object is missing
 	 * @throws IncorrectObjectTypeException
+	 *             if object has unexpected type
 	 * @throws IOException
+	 *             if an IO error occurred
 	 */
 	public void fsck(RevObject... tips) throws MissingObjectException,
 			IncorrectObjectTypeException, IOException {
@@ -922,6 +952,7 @@
 	 * not removed.
 	 *
 	 * @throws Exception
+	 *             if an error occurred
 	 */
 	public void packAndPrune() throws Exception {
 		if (db.getObjectDatabase() instanceof ObjectDirectory) {
@@ -1022,6 +1053,7 @@
 		 *            the commit to update to.
 		 * @return {@code to}.
 		 * @throws Exception
+		 *             if an error occurred
 		 */
 		public RevCommit update(CommitBuilder to) throws Exception {
 			return update(to.create());
@@ -1034,6 +1066,7 @@
 		 *            the commit to update to.
 		 * @return {@code to}.
 		 * @throws Exception
+		 *             if an error occurred
 		 */
 		public RevCommit update(RevCommit to) throws Exception {
 			return TestRepository.this.update(ref, to);
@@ -1041,7 +1074,9 @@
 
 		/**
 		 * Delete this branch.
+		 *
 		 * @throws Exception
+		 *             if an error occurred
 		 * @since 4.4
 		 */
 		public void delete() throws Exception {
@@ -1102,6 +1137,7 @@
 		 *            parent commit
 		 * @return this commit builder
 		 * @throws Exception
+		 *             if an error occurred
 		 */
 		public CommitBuilder parent(RevCommit p) throws Exception {
 			if (parents.isEmpty()) {
@@ -1165,6 +1201,7 @@
 		 *            the file content
 		 * @return this commit builder
 		 * @throws Exception
+		 *             if an error occurred
 		 */
 		public CommitBuilder add(String path, String content) throws Exception {
 			return add(path, blob(content));
@@ -1179,6 +1216,7 @@
 		 *            blob for this file
 		 * @return this commit builder
 		 * @throws Exception
+		 *             if an error occurred
 		 */
 		public CommitBuilder add(String path, RevBlob id)
 				throws Exception {
@@ -1404,6 +1442,7 @@
 		 *
 		 * @return child commit builder
 		 * @throws Exception
+		 *             if an error occurred
 		 */
 		public CommitBuilder child() throws Exception {
 			return new CommitBuilder(this);
diff --git a/org.eclipse.jgit.junit/src/org/eclipse/jgit/junit/time/MonotonicFakeClock.java b/org.eclipse.jgit.junit/src/org/eclipse/jgit/junit/time/MonotonicFakeClock.java
index e5338d3..31db6a2 100644
--- a/org.eclipse.jgit.junit/src/org/eclipse/jgit/junit/time/MonotonicFakeClock.java
+++ b/org.eclipse.jgit.junit/src/org/eclipse/jgit/junit/time/MonotonicFakeClock.java
@@ -40,7 +40,6 @@
 		now += unit.toMillis(add);
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public ProposedTimestamp propose() {
 		long t = now++;
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 432a9f8..79f0677 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.6.2.qualifier
+Bundle-Version: 6.7.1.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.6.2,6.7.0)",
- org.eclipse.jgit.api.errors;version="[6.6.2,6.7.0)",
- org.eclipse.jgit.internal.storage.file;version="[6.6.2,6.7.0)",
- org.eclipse.jgit.junit;version="[6.6.2,6.7.0)",
- org.eclipse.jgit.junit.http;version="[6.6.2,6.7.0)",
- org.eclipse.jgit.lfs;version="[6.6.2,6.7.0)",
- org.eclipse.jgit.lfs.errors;version="[6.6.2,6.7.0)",
- org.eclipse.jgit.lfs.lib;version="[6.6.2,6.7.0)",
- org.eclipse.jgit.lfs.server;version="[6.6.2,6.7.0)",
- org.eclipse.jgit.lfs.server.fs;version="[6.6.2,6.7.0)",
- org.eclipse.jgit.lfs.test;version="[6.6.2,6.7.0)",
- org.eclipse.jgit.lib;version="[6.6.2,6.7.0)",
- org.eclipse.jgit.revwalk;version="[6.6.2,6.7.0)",
- org.eclipse.jgit.storage.file;version="[6.6.2,6.7.0)",
- org.eclipse.jgit.transport;version="[6.6.2,6.7.0)",
- org.eclipse.jgit.treewalk;version="[6.6.2,6.7.0)",
- org.eclipse.jgit.treewalk.filter;version="[6.6.2,6.7.0)",
- org.eclipse.jgit.util;version="[6.6.2,6.7.0)",
+ org.eclipse.jgit.api;version="[6.7.1,6.8.0)",
+ org.eclipse.jgit.api.errors;version="[6.7.1,6.8.0)",
+ org.eclipse.jgit.internal.storage.file;version="[6.7.1,6.8.0)",
+ org.eclipse.jgit.junit;version="[6.7.1,6.8.0)",
+ org.eclipse.jgit.junit.http;version="[6.7.1,6.8.0)",
+ org.eclipse.jgit.lfs;version="[6.7.1,6.8.0)",
+ org.eclipse.jgit.lfs.errors;version="[6.7.1,6.8.0)",
+ org.eclipse.jgit.lfs.lib;version="[6.7.1,6.8.0)",
+ org.eclipse.jgit.lfs.server;version="[6.7.1,6.8.0)",
+ org.eclipse.jgit.lfs.server.fs;version="[6.7.1,6.8.0)",
+ org.eclipse.jgit.lfs.test;version="[6.7.1,6.8.0)",
+ org.eclipse.jgit.lib;version="[6.7.1,6.8.0)",
+ org.eclipse.jgit.revwalk;version="[6.7.1,6.8.0)",
+ org.eclipse.jgit.storage.file;version="[6.7.1,6.8.0)",
+ org.eclipse.jgit.transport;version="[6.7.1,6.8.0)",
+ org.eclipse.jgit.treewalk;version="[6.7.1,6.8.0)",
+ org.eclipse.jgit.treewalk.filter;version="[6.7.1,6.8.0)",
+ org.eclipse.jgit.util;version="[6.7.1,6.8.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 53d2e0e..4592990 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.6.2-SNAPSHOT</version>
+    <version>6.7.1-SNAPSHOT</version>
   </parent>
 
   <artifactId>org.eclipse.jgit.lfs.server.test</artifactId>
diff --git a/org.eclipse.jgit.lfs.server/.settings/org.eclipse.jdt.core.prefs b/org.eclipse.jgit.lfs.server/.settings/org.eclipse.jdt.core.prefs
index 0857bc1..3a92f0c 100644
--- a/org.eclipse.jgit.lfs.server/.settings/org.eclipse.jdt.core.prefs
+++ b/org.eclipse.jgit.lfs.server/.settings/org.eclipse.jdt.core.prefs
@@ -52,7 +52,7 @@
 org.eclipse.jdt.core.compiler.problem.missingJavadocComments=error
 org.eclipse.jdt.core.compiler.problem.missingJavadocCommentsOverriding=disabled
 org.eclipse.jdt.core.compiler.problem.missingJavadocCommentsVisibility=protected
-org.eclipse.jdt.core.compiler.problem.missingJavadocTagDescription=return_tag
+org.eclipse.jdt.core.compiler.problem.missingJavadocTagDescription=all_standard_tags
 org.eclipse.jdt.core.compiler.problem.missingJavadocTags=error
 org.eclipse.jdt.core.compiler.problem.missingJavadocTagsMethodTypeParameters=disabled
 org.eclipse.jdt.core.compiler.problem.missingJavadocTagsOverriding=disabled
diff --git a/org.eclipse.jgit.lfs.server/META-INF/MANIFEST.MF b/org.eclipse.jgit.lfs.server/META-INF/MANIFEST.MF
index 247fcfe..79d2947 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.6.2.qualifier
+Bundle-Version: 6.7.1.qualifier
 Bundle-Localization: plugin
 Bundle-Vendor: %Bundle-Vendor
-Export-Package: org.eclipse.jgit.lfs.server;version="6.6.2";
+Export-Package: org.eclipse.jgit.lfs.server;version="6.7.1";
   uses:="javax.servlet.http,
    org.eclipse.jgit.lfs.lib",
- org.eclipse.jgit.lfs.server.fs;version="6.6.2";
+ org.eclipse.jgit.lfs.server.fs;version="6.7.1";
   uses:="javax.servlet,
    javax.servlet.http,
    org.eclipse.jgit.lfs.server,
    org.eclipse.jgit.lfs.lib",
- org.eclipse.jgit.lfs.server.internal;version="6.6.2";x-internal:=true,
- org.eclipse.jgit.lfs.server.s3;version="6.6.2";
+ org.eclipse.jgit.lfs.server.internal;version="6.7.1";x-internal:=true,
+ org.eclipse.jgit.lfs.server.s3;version="6.7.1";
   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.6.2,6.7.0)",
- org.eclipse.jgit.internal;version="[6.6.2,6.7.0)",
- org.eclipse.jgit.internal.storage.file;version="[6.6.2,6.7.0)",
- org.eclipse.jgit.lfs.errors;version="[6.6.2,6.7.0)",
- org.eclipse.jgit.lfs.internal;version="[6.6.2,6.7.0)",
- org.eclipse.jgit.lfs.lib;version="[6.6.2,6.7.0)",
- org.eclipse.jgit.lib;version="[6.6.2,6.7.0)",
- org.eclipse.jgit.nls;version="[6.6.2,6.7.0)",
- org.eclipse.jgit.transport.http;version="[6.6.2,6.7.0)",
- org.eclipse.jgit.transport.http.apache;version="[6.6.2,6.7.0)",
- org.eclipse.jgit.util;version="[6.6.2,6.7.0)",
+ org.eclipse.jgit.annotations;version="[6.7.1,6.8.0)",
+ org.eclipse.jgit.internal;version="[6.7.1,6.8.0)",
+ org.eclipse.jgit.internal.storage.file;version="[6.7.1,6.8.0)",
+ org.eclipse.jgit.lfs.errors;version="[6.7.1,6.8.0)",
+ org.eclipse.jgit.lfs.internal;version="[6.7.1,6.8.0)",
+ org.eclipse.jgit.lfs.lib;version="[6.7.1,6.8.0)",
+ org.eclipse.jgit.lib;version="[6.7.1,6.8.0)",
+ org.eclipse.jgit.nls;version="[6.7.1,6.8.0)",
+ org.eclipse.jgit.transport.http;version="[6.7.1,6.8.0)",
+ org.eclipse.jgit.transport.http.apache;version="[6.7.1,6.8.0)",
+ org.eclipse.jgit.util;version="[6.7.1,6.8.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 1214daf..ed5b2e6 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.6.2.qualifier
-Eclipse-SourceBundle: org.eclipse.jgit.lfs.server;version="6.6.2.qualifier";roots="."
+Bundle-Version: 6.7.1.qualifier
+Eclipse-SourceBundle: org.eclipse.jgit.lfs.server;version="6.7.1.qualifier";roots="."
diff --git a/org.eclipse.jgit.lfs.server/pom.xml b/org.eclipse.jgit.lfs.server/pom.xml
index 623ec95..74d3ae8 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.6.2-SNAPSHOT</version>
+    <version>6.7.1-SNAPSHOT</version>
   </parent>
 
   <artifactId>org.eclipse.jgit.lfs.server</artifactId>
diff --git a/org.eclipse.jgit.lfs.server/src/org/eclipse/jgit/lfs/server/LargeFileRepository.java b/org.eclipse.jgit.lfs.server/src/org/eclipse/jgit/lfs/server/LargeFileRepository.java
index 5e37664..4c81baf 100644
--- a/org.eclipse.jgit.lfs.server/src/org/eclipse/jgit/lfs/server/LargeFileRepository.java
+++ b/org.eclipse.jgit.lfs.server/src/org/eclipse/jgit/lfs/server/LargeFileRepository.java
@@ -60,6 +60,7 @@
 	 * @return length of the object content in bytes, -1 if the object doesn't
 	 *         exist
 	 * @throws java.io.IOException
+	 *             if an IO error occurred
 	 */
 	long getSize(AnyLongObjectId id) throws IOException;
 }
diff --git a/org.eclipse.jgit.lfs.server/src/org/eclipse/jgit/lfs/server/LfsProtocolServlet.java b/org.eclipse.jgit.lfs.server/src/org/eclipse/jgit/lfs/server/LfsProtocolServlet.java
index 3ec08ec..6747b01 100644
--- a/org.eclipse.jgit.lfs.server/src/org/eclipse/jgit/lfs/server/LfsProtocolServlet.java
+++ b/org.eclipse.jgit.lfs.server/src/org/eclipse/jgit/lfs/server/LfsProtocolServlet.java
@@ -164,7 +164,6 @@
 		}
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	protected void doPost(HttpServletRequest req, HttpServletResponse res)
 			throws ServletException, IOException {
diff --git a/org.eclipse.jgit.lfs.server/src/org/eclipse/jgit/lfs/server/fs/FileLfsRepository.java b/org.eclipse.jgit.lfs.server/src/org/eclipse/jgit/lfs/server/fs/FileLfsRepository.java
index 31d5b2f..ff648aa 100644
--- a/org.eclipse.jgit.lfs.server/src/org/eclipse/jgit/lfs/server/fs/FileLfsRepository.java
+++ b/org.eclipse.jgit.lfs.server/src/org/eclipse/jgit/lfs/server/fs/FileLfsRepository.java
@@ -38,13 +38,16 @@
 	private final Path dir;
 
 	/**
-	 * <p>Constructor for FileLfsRepository.</p>
+	 * <p>
+	 * Constructor for FileLfsRepository.
+	 * </p>
 	 *
 	 * @param url
 	 *            external URL of this repository
 	 * @param dir
 	 *            storage directory
 	 * @throws java.io.IOException
+	 *             if an IO error occurred
 	 */
 	public FileLfsRepository(String url, Path dir) throws IOException {
 		this.url = url;
@@ -52,26 +55,22 @@
 		Files.createDirectories(dir);
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public Response.Action getDownloadAction(AnyLongObjectId id) {
 		return getAction(id);
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public Action getUploadAction(AnyLongObjectId id, long size) {
 		return getAction(id);
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	@Nullable
 	public Action getVerifyAction(AnyLongObjectId id) {
 		return null;
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public long getSize(AnyLongObjectId id) throws IOException {
 		Path p = getPath(id);
@@ -148,6 +147,8 @@
 	}
 
 	/**
+	 * Get URL of content server
+	 *
 	 * @return the url of the content server
 	 * @since 4.11
 	 */
@@ -156,6 +157,8 @@
 	}
 
 	/**
+	 * Set the URL of the content server
+	 *
 	 * @param url
 	 *            the url of the content server
 	 * @since 4.11
diff --git a/org.eclipse.jgit.lfs.server/src/org/eclipse/jgit/lfs/server/fs/ObjectDownloadListener.java b/org.eclipse.jgit.lfs.server/src/org/eclipse/jgit/lfs/server/fs/ObjectDownloadListener.java
index d427011..2ea92da 100644
--- a/org.eclipse.jgit.lfs.server/src/org/eclipse/jgit/lfs/server/fs/ObjectDownloadListener.java
+++ b/org.eclipse.jgit.lfs.server/src/org/eclipse/jgit/lfs/server/fs/ObjectDownloadListener.java
@@ -50,7 +50,9 @@
 	private ByteBuffer buffer = ByteBuffer.allocateDirect(8192);
 
 	/**
-	 * <p>Constructor for ObjectDownloadListener.</p>
+	 * <p>
+	 * Constructor for ObjectDownloadListener.
+	 * </p>
 	 *
 	 * @param repository
 	 *            the repository storing large objects
@@ -61,6 +63,7 @@
 	 * @param id
 	 *            id of the object to be downloaded
 	 * @throws java.io.IOException
+	 *             if an IO error occurred
 	 */
 	public ObjectDownloadListener(FileLfsRepository repository,
 			AsyncContext context, HttpServletResponse response,
diff --git a/org.eclipse.jgit.lfs.server/src/org/eclipse/jgit/lfs/server/fs/ObjectUploadListener.java b/org.eclipse.jgit.lfs.server/src/org/eclipse/jgit/lfs/server/fs/ObjectUploadListener.java
index f5212fe..1ac2b20 100644
--- a/org.eclipse.jgit.lfs.server/src/org/eclipse/jgit/lfs/server/fs/ObjectUploadListener.java
+++ b/org.eclipse.jgit.lfs.server/src/org/eclipse/jgit/lfs/server/fs/ObjectUploadListener.java
@@ -92,7 +92,9 @@
 	 * @param id
 	 *            a {@link org.eclipse.jgit.lfs.lib.AnyLongObjectId} object.
 	 * @throws java.io.FileNotFoundException
+	 *             if file wasn't found
 	 * @throws java.io.IOException
+	 *             if an IO error occurred
 	 */
 	public ObjectUploadListener(FileLfsRepository repository,
 			AsyncContext context, HttpServletRequest request,
@@ -146,7 +148,6 @@
 		}
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public void onAllDataRead() throws IOException {
 		close();
@@ -156,6 +157,7 @@
 	 * Close resources held by this listener
 	 *
 	 * @throws java.io.IOException
+	 *             if an IO error occurred
 	 */
 	protected void close() throws IOException {
 		try {
@@ -174,7 +176,6 @@
 		}
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public void onError(Throwable e) {
 		try {
diff --git a/org.eclipse.jgit.lfs.server/src/org/eclipse/jgit/lfs/server/s3/S3Repository.java b/org.eclipse.jgit.lfs.server/src/org/eclipse/jgit/lfs/server/s3/S3Repository.java
index c7c7a71..5ebce5d 100644
--- a/org.eclipse.jgit.lfs.server/src/org/eclipse/jgit/lfs/server/s3/S3Repository.java
+++ b/org.eclipse.jgit.lfs.server/src/org/eclipse/jgit/lfs/server/s3/S3Repository.java
@@ -58,7 +58,6 @@
 		this.s3Config = config;
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public Response.Action getDownloadAction(AnyLongObjectId oid) {
 		URL endpointUrl = getObjectUrl(oid);
@@ -75,7 +74,6 @@
 		return a;
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public Response.Action getUploadAction(AnyLongObjectId oid, long size) {
 		cacheObjectMetaData(oid, size);
@@ -95,13 +93,11 @@
 		return a;
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public Action getVerifyAction(AnyLongObjectId id) {
 		return null; // TODO(ms) implement this
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public long getSize(AnyLongObjectId oid) throws IOException {
 		URL endpointUrl = getObjectUrl(oid);
@@ -130,7 +126,7 @@
 			String contentLengthHeader = conn
 					.getHeaderField(HDR_CONTENT_LENGTH);
 			if (contentLengthHeader != null) {
-				return Integer.parseInt(contentLengthHeader);
+				return Long.parseLong(contentLengthHeader);
 			}
 		}
 		return -1;
diff --git a/org.eclipse.jgit.lfs.test/META-INF/MANIFEST.MF b/org.eclipse.jgit.lfs.test/META-INF/MANIFEST.MF
index 8683977..a368244 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.6.2.qualifier
+Bundle-Version: 6.7.1.qualifier
 Bundle-Vendor: %Bundle-Vendor
 Bundle-Localization: plugin
 Bundle-RequiredExecutionEnvironment: JavaSE-11
-Import-Package: org.eclipse.jgit.api;version="[6.6.2,6.7.0)",
- org.eclipse.jgit.attributes;version="[6.6.2,6.7.0)",
- org.eclipse.jgit.internal.storage.dfs;version="[6.6.2,6.7.0)",
- org.eclipse.jgit.junit;version="[6.6.2,6.7.0)",
- org.eclipse.jgit.lfs;version="[6.6.2,6.7.0)",
- org.eclipse.jgit.lfs.errors;version="[6.6.2,6.7.0)",
- org.eclipse.jgit.lfs.internal;version="[6.6.2,6.7.0)",
- org.eclipse.jgit.lfs.lib;version="[6.6.2,6.7.0)",
- org.eclipse.jgit.lib;version="[6.6.2,6.7.0)",
- org.eclipse.jgit.revwalk;version="[6.6.2,6.7.0)",
- org.eclipse.jgit.transport;version="[6.6.2,6.7.0)",
- org.eclipse.jgit.transport.http;version="[6.6.2,6.7.0)",
- org.eclipse.jgit.treewalk;version="[6.6.2,6.7.0)",
- org.eclipse.jgit.treewalk.filter;version="[6.6.2,6.7.0)",
- org.eclipse.jgit.util;version="[6.6.2,6.7.0)",
+Import-Package: org.eclipse.jgit.api;version="[6.7.1,6.8.0)",
+ org.eclipse.jgit.attributes;version="[6.7.1,6.8.0)",
+ org.eclipse.jgit.internal.storage.dfs;version="[6.7.1,6.8.0)",
+ org.eclipse.jgit.junit;version="[6.7.1,6.8.0)",
+ org.eclipse.jgit.lfs;version="[6.7.1,6.8.0)",
+ org.eclipse.jgit.lfs.errors;version="[6.7.1,6.8.0)",
+ org.eclipse.jgit.lfs.internal;version="[6.7.1,6.8.0)",
+ org.eclipse.jgit.lfs.lib;version="[6.7.1,6.8.0)",
+ org.eclipse.jgit.lib;version="[6.7.1,6.8.0)",
+ org.eclipse.jgit.revwalk;version="[6.7.1,6.8.0)",
+ org.eclipse.jgit.transport;version="[6.7.1,6.8.0)",
+ org.eclipse.jgit.transport.http;version="[6.7.1,6.8.0)",
+ org.eclipse.jgit.treewalk;version="[6.7.1,6.8.0)",
+ org.eclipse.jgit.treewalk.filter;version="[6.7.1,6.8.0)",
+ org.eclipse.jgit.util;version="[6.7.1,6.8.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.6.2";x-friends:="org.eclipse.jgit.lfs.server.test"
+Export-Package: org.eclipse.jgit.lfs.test;version="6.7.1";x-friends:="org.eclipse.jgit.lfs.server.test"
diff --git a/org.eclipse.jgit.lfs.test/pom.xml b/org.eclipse.jgit.lfs.test/pom.xml
index 092d2c0..680e1ca 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.6.2-SNAPSHOT</version>
+    <version>6.7.1-SNAPSHOT</version>
   </parent>
 
   <artifactId>org.eclipse.jgit.lfs.test</artifactId>
diff --git a/org.eclipse.jgit.lfs/.settings/org.eclipse.jdt.core.prefs b/org.eclipse.jgit.lfs/.settings/org.eclipse.jdt.core.prefs
index 0857bc1..3a92f0c 100644
--- a/org.eclipse.jgit.lfs/.settings/org.eclipse.jdt.core.prefs
+++ b/org.eclipse.jgit.lfs/.settings/org.eclipse.jdt.core.prefs
@@ -52,7 +52,7 @@
 org.eclipse.jdt.core.compiler.problem.missingJavadocComments=error
 org.eclipse.jdt.core.compiler.problem.missingJavadocCommentsOverriding=disabled
 org.eclipse.jdt.core.compiler.problem.missingJavadocCommentsVisibility=protected
-org.eclipse.jdt.core.compiler.problem.missingJavadocTagDescription=return_tag
+org.eclipse.jdt.core.compiler.problem.missingJavadocTagDescription=all_standard_tags
 org.eclipse.jdt.core.compiler.problem.missingJavadocTags=error
 org.eclipse.jdt.core.compiler.problem.missingJavadocTagsMethodTypeParameters=disabled
 org.eclipse.jdt.core.compiler.problem.missingJavadocTagsOverriding=disabled
diff --git a/org.eclipse.jgit.lfs/META-INF/MANIFEST.MF b/org.eclipse.jgit.lfs/META-INF/MANIFEST.MF
index 9f24a81..436b177 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.6.2.qualifier
+Bundle-Version: 6.7.1.qualifier
 Bundle-Localization: plugin
 Bundle-Vendor: %Bundle-Vendor
-Export-Package: org.eclipse.jgit.lfs;version="6.6.2",
- org.eclipse.jgit.lfs.errors;version="6.6.2",
- org.eclipse.jgit.lfs.internal;version="6.6.2";x-friends:="org.eclipse.jgit.lfs.test,org.eclipse.jgit.lfs.server.fs,org.eclipse.jgit.lfs.server",
- org.eclipse.jgit.lfs.lib;version="6.6.2"
+Export-Package: org.eclipse.jgit.lfs;version="6.7.1",
+ org.eclipse.jgit.lfs.errors;version="6.7.1",
+ org.eclipse.jgit.lfs.internal;version="6.7.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.7.1"
 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.6.2,6.7.0)";resolution:=optional,
- org.eclipse.jgit.api.errors;version="[6.6.2,6.7.0)",
- org.eclipse.jgit.attributes;version="[6.6.2,6.7.0)",
- org.eclipse.jgit.diff;version="[6.6.2,6.7.0)",
- org.eclipse.jgit.dircache;version="[6.6.2,6.7.0)",
- org.eclipse.jgit.errors;version="[6.6.2,6.7.0)",
- org.eclipse.jgit.hooks;version="[6.6.2,6.7.0)",
- org.eclipse.jgit.internal.storage.file;version="[6.6.2,6.7.0)",
- org.eclipse.jgit.lib;version="[6.6.2,6.7.0)",
- org.eclipse.jgit.nls;version="[6.6.2,6.7.0)",
- org.eclipse.jgit.revwalk;version="[6.6.2,6.7.0)",
- org.eclipse.jgit.storage.file;version="[6.6.2,6.7.0)",
- org.eclipse.jgit.storage.pack;version="[6.6.2,6.7.0)",
- org.eclipse.jgit.transport;version="[6.6.2,6.7.0)",
- org.eclipse.jgit.transport.http;version="[6.6.2,6.7.0)",
- org.eclipse.jgit.treewalk;version="[6.6.2,6.7.0)",
- org.eclipse.jgit.treewalk.filter;version="[6.6.2,6.7.0)",
- org.eclipse.jgit.util;version="[6.6.2,6.7.0)",
- org.eclipse.jgit.util.io;version="[6.6.2,6.7.0)"
+ org.eclipse.jgit.annotations;version="[6.7.1,6.8.0)";resolution:=optional,
+ org.eclipse.jgit.api.errors;version="[6.7.1,6.8.0)",
+ org.eclipse.jgit.attributes;version="[6.7.1,6.8.0)",
+ org.eclipse.jgit.diff;version="[6.7.1,6.8.0)",
+ org.eclipse.jgit.dircache;version="[6.7.1,6.8.0)",
+ org.eclipse.jgit.errors;version="[6.7.1,6.8.0)",
+ org.eclipse.jgit.hooks;version="[6.7.1,6.8.0)",
+ org.eclipse.jgit.internal.storage.file;version="[6.7.1,6.8.0)",
+ org.eclipse.jgit.lib;version="[6.7.1,6.8.0)",
+ org.eclipse.jgit.nls;version="[6.7.1,6.8.0)",
+ org.eclipse.jgit.revwalk;version="[6.7.1,6.8.0)",
+ org.eclipse.jgit.storage.file;version="[6.7.1,6.8.0)",
+ org.eclipse.jgit.storage.pack;version="[6.7.1,6.8.0)",
+ org.eclipse.jgit.transport;version="[6.7.1,6.8.0)",
+ org.eclipse.jgit.transport.http;version="[6.7.1,6.8.0)",
+ org.eclipse.jgit.treewalk;version="[6.7.1,6.8.0)",
+ org.eclipse.jgit.treewalk.filter;version="[6.7.1,6.8.0)",
+ org.eclipse.jgit.util;version="[6.7.1,6.8.0)",
+ org.eclipse.jgit.util.io;version="[6.7.1,6.8.0)"
diff --git a/org.eclipse.jgit.lfs/META-INF/SOURCE-MANIFEST.MF b/org.eclipse.jgit.lfs/META-INF/SOURCE-MANIFEST.MF
index decae54..eca1e3a 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.6.2.qualifier
-Eclipse-SourceBundle: org.eclipse.jgit.lfs;version="6.6.2.qualifier";roots="."
+Bundle-Version: 6.7.1.qualifier
+Eclipse-SourceBundle: org.eclipse.jgit.lfs;version="6.7.1.qualifier";roots="."
diff --git a/org.eclipse.jgit.lfs/pom.xml b/org.eclipse.jgit.lfs/pom.xml
index 178990f..16931f2 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.6.2-SNAPSHOT</version>
+    <version>6.7.1-SNAPSHOT</version>
   </parent>
 
   <artifactId>org.eclipse.jgit.lfs</artifactId>
diff --git a/org.eclipse.jgit.lfs/src/org/eclipse/jgit/lfs/CleanFilter.java b/org.eclipse.jgit.lfs/src/org/eclipse/jgit/lfs/CleanFilter.java
index f0526ff..13b74df 100644
--- a/org.eclipse.jgit.lfs/src/org/eclipse/jgit/lfs/CleanFilter.java
+++ b/org.eclipse.jgit.lfs/src/org/eclipse/jgit/lfs/CleanFilter.java
@@ -95,7 +95,6 @@
 		this.aOut = new AtomicObjectOutputStream(tmpFile.toAbsolutePath());
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public int run() throws IOException {
 		try {
diff --git a/org.eclipse.jgit.lfs/src/org/eclipse/jgit/lfs/LfsPointer.java b/org.eclipse.jgit.lfs/src/org/eclipse/jgit/lfs/LfsPointer.java
index 0a8a3fa..afe9636 100644
--- a/org.eclipse.jgit.lfs/src/org/eclipse/jgit/lfs/LfsPointer.java
+++ b/org.eclipse.jgit.lfs/src/org/eclipse/jgit/lfs/LfsPointer.java
@@ -136,6 +136,7 @@
 	 * @return an {@link org.eclipse.jgit.lfs.LfsPointer} or {@code null} if the
 	 *         stream was not parseable as LfsPointer
 	 * @throws java.io.IOException
+	 *             if an IO error occurred
 	 */
 	@Nullable
 	public static LfsPointer parseLfsPointer(InputStream in)
@@ -264,7 +265,6 @@
 		return VERSION.equals(rest) || VERSION_LEGACY.equals(rest);
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public String toString() {
 		return "LfsPointer: oid=" + oid.name() + ", size=" //$NON-NLS-1$ //$NON-NLS-2$
diff --git a/org.eclipse.jgit.lfs/src/org/eclipse/jgit/lfs/SmudgeFilter.java b/org.eclipse.jgit.lfs/src/org/eclipse/jgit/lfs/SmudgeFilter.java
index c26a1bf..b6515b9 100644
--- a/org.eclipse.jgit.lfs/src/org/eclipse/jgit/lfs/SmudgeFilter.java
+++ b/org.eclipse.jgit.lfs/src/org/eclipse/jgit/lfs/SmudgeFilter.java
@@ -127,6 +127,7 @@
 	 *            the objects to download
 	 * @return the paths of all mediafiles which have been downloaded
 	 * @throws IOException
+	 *             if an IO error occurred
 	 * @since 4.11
 	 */
 	public static Collection<Path> downloadLfsResource(Lfs lfs, Repository db,
@@ -217,7 +218,6 @@
 		return downloadedPaths;
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public int run() throws IOException {
 		try {
diff --git a/org.eclipse.jgit.lfs/src/org/eclipse/jgit/lfs/internal/AtomicObjectOutputStream.java b/org.eclipse.jgit.lfs/src/org/eclipse/jgit/lfs/internal/AtomicObjectOutputStream.java
index 3f1f0ac..0092502 100644
--- a/org.eclipse.jgit.lfs/src/org/eclipse/jgit/lfs/internal/AtomicObjectOutputStream.java
+++ b/org.eclipse.jgit.lfs/src/org/eclipse/jgit/lfs/internal/AtomicObjectOutputStream.java
@@ -45,6 +45,7 @@
 	 * @param id
 	 *            a {@link org.eclipse.jgit.lfs.lib.AnyLongObjectId} object.
 	 * @throws java.io.IOException
+	 *             if an IO error occurred
 	 */
 	public AtomicObjectOutputStream(Path path, AnyLongObjectId id)
 			throws IOException {
@@ -61,6 +62,7 @@
 	 * @param path
 	 *            a {@link java.nio.file.Path} object.
 	 * @throws java.io.IOException
+	 *             if an IO error occurred
 	 */
 	public AtomicObjectOutputStream(Path path) throws IOException {
 		this(path, null);
@@ -78,25 +80,21 @@
 		return id;
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public void write(int b) throws IOException {
 		out.write(b);
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public void write(byte[] b) throws IOException {
 		out.write(b);
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public void write(byte[] b, int off, int len) throws IOException {
 		out.write(b, off, len);
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public void close() throws IOException {
 		out.close();
diff --git a/org.eclipse.jgit.lfs/src/org/eclipse/jgit/lfs/internal/LfsConfig.java b/org.eclipse.jgit.lfs/src/org/eclipse/jgit/lfs/internal/LfsConfig.java
index 857ccbe..0469337 100644
--- a/org.eclipse.jgit.lfs/src/org/eclipse/jgit/lfs/internal/LfsConfig.java
+++ b/org.eclipse.jgit.lfs/src/org/eclipse/jgit/lfs/internal/LfsConfig.java
@@ -70,6 +70,7 @@
 	 *
 	 * @return the delegate {@link Config}
 	 * @throws IOException
+	 *             if an IO error occurred
 	 */
 	private Config getDelegate() throws IOException {
 		if (delegate == null) {
@@ -86,6 +87,7 @@
 	 * @return The loaded lfs config
 	 *
 	 * @throws IOException
+	 *             if an IO error occurred
 	 */
 	private Config load() throws IOException {
 		Config result = null;
@@ -114,6 +116,7 @@
 	 *
 	 * @return the config, or <code>null</code>
 	 * @throws IOException
+	 *             if an IO error occurred
 	 */
 	@Nullable
 	private Config loadFromWorkingTree()
@@ -139,6 +142,7 @@
 	 *
 	 * @return the config, or <code>null</code> if the entry does not exist
 	 * @throws IOException
+	 *             if an IO error occurred
 	 */
 	@Nullable
 	private Config loadFromIndex()
@@ -162,6 +166,7 @@
 	 *
 	 * @return the config, or <code>null</code> if the file does not exist
 	 * @throws IOException
+	 *             if an IO error occurred
 	 */
 	@Nullable
 	private Config loadFromHead() throws IOException {
@@ -207,6 +212,7 @@
 	 *            the key name
 	 * @return a String value from the config, <code>null</code> if not found
 	 * @throws IOException
+	 *             if an IO error occurred
 	 */
 	@Nullable
 	public String getString(final String section, final String subsection,
diff --git a/org.eclipse.jgit.lfs/src/org/eclipse/jgit/lfs/internal/LfsConnectionFactory.java b/org.eclipse.jgit.lfs/src/org/eclipse/jgit/lfs/internal/LfsConnectionFactory.java
index 12b688d..f9c623d 100644
--- a/org.eclipse.jgit.lfs/src/org/eclipse/jgit/lfs/internal/LfsConnectionFactory.java
+++ b/org.eclipse.jgit.lfs/src/org/eclipse/jgit/lfs/internal/LfsConnectionFactory.java
@@ -67,6 +67,7 @@
 	 * @return the connection for the lfs server. e.g.
 	 *         "https://github.com/github/git-lfs.git/info/lfs"
 	 * @throws IOException
+	 *             if an IO error occurred
 	 */
 	public static HttpConnection getLfsConnection(Repository db, String method,
 			String purpose) throws IOException {
@@ -287,6 +288,7 @@
 		 * no timeout can be determined, the token will be used only once.
 		 *
 		 * @param action
+		 *            action with an additional expiration timestamp
 		 */
 		public AuthCache(Protocol.ExpiringAction action) {
 			this.cachedAction = action;
diff --git a/org.eclipse.jgit.lfs/src/org/eclipse/jgit/lfs/lib/AbbreviatedLongObjectId.java b/org.eclipse.jgit.lfs/src/org/eclipse/jgit/lfs/lib/AbbreviatedLongObjectId.java
index 9016e53..7ae805c 100644
--- a/org.eclipse.jgit.lfs/src/org/eclipse/jgit/lfs/lib/AbbreviatedLongObjectId.java
+++ b/org.eclipse.jgit.lfs/src/org/eclipse/jgit/lfs/lib/AbbreviatedLongObjectId.java
@@ -314,13 +314,11 @@
 		return mask(nibbles, word, v);
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public int hashCode() {
 		return (int) (w1 >> 32);
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public boolean equals(Object o) {
 		if (o instanceof AbbreviatedLongObjectId) {
@@ -355,7 +353,6 @@
 		return new String(b, 0, nibbles);
 	}
 
-	/** {@inheritDoc} */
 	@SuppressWarnings("nls")
 	@Override
 	public String toString() {
diff --git a/org.eclipse.jgit.lfs/src/org/eclipse/jgit/lfs/lib/AnyLongObjectId.java b/org.eclipse.jgit.lfs/src/org/eclipse/jgit/lfs/lib/AnyLongObjectId.java
index d866db4..75d500e 100644
--- a/org.eclipse.jgit.lfs/src/org/eclipse/jgit/lfs/lib/AnyLongObjectId.java
+++ b/org.eclipse.jgit.lfs/src/org/eclipse/jgit/lfs/lib/AnyLongObjectId.java
@@ -249,7 +249,6 @@
 		return abbr.prefixCompare(this) == 0;
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public final int hashCode() {
 		return (int) (w1 >> 32);
@@ -267,7 +266,6 @@
 		return other != null ? equals(this, other) : false;
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public final boolean equals(Object o) {
 		if (o instanceof AnyLongObjectId) {
@@ -475,7 +473,6 @@
 			dst[o--] = '0';
 	}
 
-	/** {@inheritDoc} */
 	@SuppressWarnings("nls")
 	@Override
 	public String toString() {
diff --git a/org.eclipse.jgit.lfs/src/org/eclipse/jgit/lfs/lib/LfsPointerFilter.java b/org.eclipse.jgit.lfs/src/org/eclipse/jgit/lfs/lib/LfsPointerFilter.java
index 99bae49..75798ca 100644
--- a/org.eclipse.jgit.lfs/src/org/eclipse/jgit/lfs/lib/LfsPointerFilter.java
+++ b/org.eclipse.jgit.lfs/src/org/eclipse/jgit/lfs/lib/LfsPointerFilter.java
@@ -41,7 +41,6 @@
 		return pointer;
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public boolean include(TreeWalk walk) throws MissingObjectException,
 			IncorrectObjectTypeException, IOException {
@@ -63,13 +62,11 @@
 		}
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public boolean shouldBeRecursive() {
 		return false;
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public TreeFilter clone() {
 		return new LfsPointerFilter();
diff --git a/org.eclipse.jgit.lfs/src/org/eclipse/jgit/lfs/lib/LongObjectId.java b/org.eclipse.jgit.lfs/src/org/eclipse/jgit/lfs/lib/LongObjectId.java
index 15b3ca4..3959115 100644
--- a/org.eclipse.jgit.lfs/src/org/eclipse/jgit/lfs/lib/LongObjectId.java
+++ b/org.eclipse.jgit.lfs/src/org/eclipse/jgit/lfs/lib/LongObjectId.java
@@ -256,7 +256,6 @@
 		w4 = src.w4;
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public LongObjectId toObjectId() {
 		return this;
diff --git a/org.eclipse.jgit.lfs/src/org/eclipse/jgit/lfs/lib/MutableLongObjectId.java b/org.eclipse.jgit.lfs/src/org/eclipse/jgit/lfs/lib/MutableLongObjectId.java
index 012e4ae..5397d81 100644
--- a/org.eclipse.jgit.lfs/src/org/eclipse/jgit/lfs/lib/MutableLongObjectId.java
+++ b/org.eclipse.jgit.lfs/src/org/eclipse/jgit/lfs/lib/MutableLongObjectId.java
@@ -221,7 +221,6 @@
 		}
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public LongObjectId toObjectId() {
 		return new LongObjectId(this);
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 d5db5b2..1fce720 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.6.2.qualifier"
+      version="6.7.1.qualifier"
       provider-name="%providerName">
 
    <description url="http://www.eclipse.org/jgit/">
diff --git a/org.eclipse.jgit.packaging/org.eclipse.jgit.feature/pom.xml b/org.eclipse.jgit.packaging/org.eclipse.jgit.feature/pom.xml
index 9c9eb31..3d9949e 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.6.2-SNAPSHOT</version>
+    <version>6.7.1-SNAPSHOT</version>
   </parent>
 
   <groupId>org.eclipse.jgit.feature</groupId>
diff --git a/org.eclipse.jgit.packaging/org.eclipse.jgit.gpg.bc.feature/feature.xml b/org.eclipse.jgit.packaging/org.eclipse.jgit.gpg.bc.feature/feature.xml
index b38d002..2291429 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.6.2.qualifier"
+      version="6.7.1.qualifier"
       provider-name="%providerName">
 
    <description url="http://www.eclipse.org/jgit/">
@@ -23,7 +23,7 @@
    </url>
 
    <requires>
-      <import plugin="org.eclipse.jgit" version="6.6.2" match="equivalent"/>
+      <import plugin="org.eclipse.jgit" version="6.7.1" match="equivalent"/>
    </requires>
 
    <plugin
diff --git a/org.eclipse.jgit.packaging/org.eclipse.jgit.gpg.bc.feature/pom.xml b/org.eclipse.jgit.packaging/org.eclipse.jgit.gpg.bc.feature/pom.xml
index 5770ced..bccaf7c 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.6.2-SNAPSHOT</version>
+    <version>6.7.1-SNAPSHOT</version>
   </parent>
 
   <groupId>org.eclipse.jgit.feature</groupId>
diff --git a/org.eclipse.jgit.packaging/org.eclipse.jgit.http.apache.feature/feature.xml b/org.eclipse.jgit.packaging/org.eclipse.jgit.http.apache.feature/feature.xml
index 384add8..7c18420 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.6.2.qualifier"
+      version="6.7.1.qualifier"
       provider-name="%providerName">
 
    <description url="http://www.eclipse.org/jgit/">
@@ -23,7 +23,7 @@
    </url>
 
    <requires>
-      <import plugin="org.eclipse.jgit" version="6.6.2" match="equivalent"/>
+      <import plugin="org.eclipse.jgit" version="6.7.1" match="equivalent"/>
    </requires>
 
    <plugin
diff --git a/org.eclipse.jgit.packaging/org.eclipse.jgit.http.apache.feature/pom.xml b/org.eclipse.jgit.packaging/org.eclipse.jgit.http.apache.feature/pom.xml
index 104793b..af9b03d 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.6.2-SNAPSHOT</version>
+    <version>6.7.1-SNAPSHOT</version>
   </parent>
 
   <groupId>org.eclipse.jgit.feature</groupId>
diff --git a/org.eclipse.jgit.packaging/org.eclipse.jgit.junit.feature/feature.xml b/org.eclipse.jgit.packaging/org.eclipse.jgit.junit.feature/feature.xml
index 7b95d3b..63aa2cc 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.6.2.qualifier"
+      version="6.7.1.qualifier"
       provider-name="%providerName">
 
    <description url="http://www.eclipse.org/jgit/">
@@ -24,7 +24,7 @@
 
    <requires>
       <import plugin="com.jcraft.jsch"/>
-      <import plugin="org.eclipse.jgit" version="6.6.2" match="equivalent"/>
+      <import plugin="org.eclipse.jgit" version="6.7.1" match="equivalent"/>
    </requires>
 
    <plugin
diff --git a/org.eclipse.jgit.packaging/org.eclipse.jgit.junit.feature/pom.xml b/org.eclipse.jgit.packaging/org.eclipse.jgit.junit.feature/pom.xml
index 8cd1c49..df69320 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.6.2-SNAPSHOT</version>
+    <version>6.7.1-SNAPSHOT</version>
   </parent>
 
   <groupId>org.eclipse.jgit.feature</groupId>
diff --git a/org.eclipse.jgit.packaging/org.eclipse.jgit.lfs.feature/feature.xml b/org.eclipse.jgit.packaging/org.eclipse.jgit.lfs.feature/feature.xml
index 0c1cbd0..df3a3f1 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.6.2.qualifier"
+      version="6.7.1.qualifier"
       provider-name="%providerName">
 
    <description url="http://www.eclipse.org/jgit/">
@@ -23,7 +23,7 @@
    </url>
 
    <requires>
-      <import feature="org.eclipse.jgit" version="6.6.2" match="equivalent"/>
+      <import feature="org.eclipse.jgit" version="6.7.1" match="equivalent"/>
    </requires>
 
    <plugin
diff --git a/org.eclipse.jgit.packaging/org.eclipse.jgit.lfs.feature/pom.xml b/org.eclipse.jgit.packaging/org.eclipse.jgit.lfs.feature/pom.xml
index 6a6fdef..1a224ab 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.6.2-SNAPSHOT</version>
+    <version>6.7.1-SNAPSHOT</version>
   </parent>
 
   <groupId>org.eclipse.jgit.feature</groupId>
diff --git a/org.eclipse.jgit.packaging/org.eclipse.jgit.pgm.feature/feature.xml b/org.eclipse.jgit.packaging/org.eclipse.jgit.pgm.feature/feature.xml
index c3be149..503e14d 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.6.2.qualifier"
+      version="6.7.1.qualifier"
       provider-name="%providerName">
 
    <description url="http://www.eclipse.org/jgit/">
@@ -35,9 +35,9 @@
          version="0.0.0"/>
 
    <requires>
-      <import feature="org.eclipse.jgit" version="6.6.2" match="equivalent"/>
-      <import feature="org.eclipse.jgit.lfs" version="6.6.2" match="equivalent"/>
-      <import feature="org.eclipse.jgit.ssh.apache" version="6.6.2" match="equivalent"/>
+      <import feature="org.eclipse.jgit" version="6.7.1" match="equivalent"/>
+      <import feature="org.eclipse.jgit.lfs" version="6.7.1" match="equivalent"/>
+      <import feature="org.eclipse.jgit.ssh.apache" version="6.7.1" match="equivalent"/>
    </requires>
 
    <plugin
diff --git a/org.eclipse.jgit.packaging/org.eclipse.jgit.pgm.feature/pom.xml b/org.eclipse.jgit.packaging/org.eclipse.jgit.pgm.feature/pom.xml
index 176ca74..37c30b3 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.6.2-SNAPSHOT</version>
+    <version>6.7.1-SNAPSHOT</version>
   </parent>
 
   <groupId>org.eclipse.jgit.feature</groupId>
diff --git a/org.eclipse.jgit.packaging/org.eclipse.jgit.repository/category.xml b/org.eclipse.jgit.packaging/org.eclipse.jgit.repository/category.xml
index a5d2304..e0c790a 100644
--- a/org.eclipse.jgit.packaging/org.eclipse.jgit.repository/category.xml
+++ b/org.eclipse.jgit.packaging/org.eclipse.jgit.repository/category.xml
@@ -39,9 +39,6 @@
    <bundle id="org.eclipse.jgit.ui" version="0.0.0">
       <category name="JGit-additional-bundles"/>
    </bundle>
-   <bundle id="assertj-core">
-      <category name="JGit-dependency-bundles"/>
-   </bundle>
    <bundle id="com.google.gson">
       <category name="JGit-dependency-bundles"/>
    </bundle>
@@ -228,6 +225,18 @@
    <bundle id="org.tukaani.xz.source">
       <category name="JGit-dependency-bundles"/>
    </bundle>
+   <bundle id="org.eclipse.osgi">
+      <category name="JGit-dependency-bundles"/>
+   </bundle>
+   <bundle id="org.eclipse.osgi.source">
+      <category name="JGit-dependency-bundles"/>
+   </bundle>
+   <bundle id="org.osgi.service.cm">
+      <category name="JGit-dependency-bundles"/>
+   </bundle>
+   <bundle id="org.osgi.service.cm.source">
+      <category name="JGit-dependency-bundles"/>
+   </bundle>
    <category-def name="JGit" label="Java implementation of Git">
       <description>
          Java implementation of Git
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 ae31d3a..979dcae 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.6.2-SNAPSHOT</version>
+    <version>6.7.1-SNAPSHOT</version>
   </parent>
 
   <artifactId>org.eclipse.jgit.repository</artifactId>
diff --git a/org.eclipse.jgit.packaging/org.eclipse.jgit.source.feature/feature.xml b/org.eclipse.jgit.packaging/org.eclipse.jgit.source.feature/feature.xml
index 2989aa8..2ba6d18 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.6.2.qualifier"
+      version="6.7.1.qualifier"
       provider-name="%providerName">
 
    <description url="http://www.eclipse.org/jgit/">
@@ -23,7 +23,7 @@
    </url>
 
    <requires>
-      <import feature="org.eclipse.jgit" version="6.6.2" match="equivalent"/>
+      <import feature="org.eclipse.jgit" version="6.7.1" match="equivalent"/>
    </requires>
 
    <plugin
diff --git a/org.eclipse.jgit.packaging/org.eclipse.jgit.source.feature/pom.xml b/org.eclipse.jgit.packaging/org.eclipse.jgit.source.feature/pom.xml
index fc45feb..0d1e70f 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.6.2-SNAPSHOT</version>
+    <version>6.7.1-SNAPSHOT</version>
   </parent>
 
   <groupId>org.eclipse.jgit.feature</groupId>
@@ -30,7 +30,7 @@
     <dependency>
       <groupId>org.eclipse.jgit.feature</groupId>
       <artifactId>org.eclipse.jgit</artifactId>
-      <version>6.6.2-SNAPSHOT</version>
+      <version>6.7.1-SNAPSHOT</version>
     </dependency>
   </dependencies>
 
diff --git a/org.eclipse.jgit.packaging/org.eclipse.jgit.ssh.apache.feature/feature.xml b/org.eclipse.jgit.packaging/org.eclipse.jgit.ssh.apache.feature/feature.xml
index e838d1f..1faa07d 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.6.2.qualifier"
+      version="6.7.1.qualifier"
       provider-name="%providerName">
 
    <description url="http://www.eclipse.org/jgit/">
@@ -23,7 +23,7 @@
    </url>
 
    <requires>
-      <import feature="org.eclipse.jgit" version="6.6.2" match="equivalent"/>
+      <import feature="org.eclipse.jgit" version="6.7.1" match="equivalent"/>
    </requires>
 
    <plugin
diff --git a/org.eclipse.jgit.packaging/org.eclipse.jgit.ssh.apache.feature/pom.xml b/org.eclipse.jgit.packaging/org.eclipse.jgit.ssh.apache.feature/pom.xml
index b93597f..72b51fe 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.6.2-SNAPSHOT</version>
+    <version>6.7.1-SNAPSHOT</version>
   </parent>
 
   <groupId>org.eclipse.jgit.feature</groupId>
diff --git a/org.eclipse.jgit.packaging/org.eclipse.jgit.ssh.jsch.feature/feature.xml b/org.eclipse.jgit.packaging/org.eclipse.jgit.ssh.jsch.feature/feature.xml
index 126c5ba..305b969 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.6.2.qualifier"
+      version="6.7.1.qualifier"
       provider-name="%providerName">
 
    <description url="http://www.eclipse.org/jgit/">
@@ -23,7 +23,7 @@
    </url>
 
    <requires>
-      <import plugin="org.eclipse.jgit" version="6.6.2" match="equivalent"/>
+      <import plugin="org.eclipse.jgit" version="6.7.1" match="equivalent"/>
    </requires>
 
    <plugin
diff --git a/org.eclipse.jgit.packaging/org.eclipse.jgit.ssh.jsch.feature/pom.xml b/org.eclipse.jgit.packaging/org.eclipse.jgit.ssh.jsch.feature/pom.xml
index 8f72b4e..a1c7c23 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.6.2-SNAPSHOT</version>
+    <version>6.7.1-SNAPSHOT</version>
   </parent>
 
   <groupId>org.eclipse.jgit.feature</groupId>
diff --git a/org.eclipse.jgit.packaging/org.eclipse.jgit.target/META-INF/MANIFEST.MF b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/META-INF/MANIFEST.MF
index 7c4a732..5e3aacb 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.6.2.qualifier
+Bundle-Version: 6.7.1.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 04ff3f5..3e515c5 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,7 +1,7 @@
 <?xml version="1.0" encoding="UTF-8" standalone="no"?>
 <?pde?>
 <!-- generated with https://github.com/eclipse-cbi/targetplatform-dsl -->
-<target name="jgit-4.17" sequenceNumber="1686300730">
+<target name="jgit-4.17" sequenceNumber="1693839266">
   <locations>
     <location includeMode="slicer" includeAllPlatforms="false" includeSource="true" includeConfigurePhase="true" type="InstallableUnit">
       <unit id="com.jcraft.jsch" version="0.1.55.v20221112-0806"/>
@@ -12,21 +12,21 @@
       <unit id="net.i2p.crypto.eddsa.source" version="0.3.0.v20220506-1020"/>
       <unit id="org.apache.ant" version="1.10.12.v20211102-1452"/>
       <unit id="org.apache.ant.source" version="1.10.12.v20211102-1452"/>
-      <unit id="org.apache.httpcomponents.httpclient" version="4.5.14.v20230516-1249"/>
-      <unit id="org.apache.httpcomponents.httpclient.source" version="4.5.14.v20230516-1249"/>
-      <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.hamcrest.core" version="1.3.0.v20180420-1519"/>
-      <unit id="org.hamcrest.core.source" version="1.3.0.v20180420-1519"/>
-      <unit id="org.hamcrest.library" version="1.3.0.v20180524-2246"/>
-      <unit id="org.hamcrest.library.source" version="1.3.0.v20180524-2246"/>
-      <unit id="org.junit" version="4.13.2.v20211018-1956"/>
-      <unit id="org.junit.source" version="4.13.2.v20211018-1956"/>
-      <unit id="org.mockito.mockito-core" version="4.8.1.v20221103-2317"/>
-      <unit id="org.mockito.mockito-core.source" version="4.8.1.v20221103-2317"/>
-      <unit id="org.objenesis" version="3.3.0.v20221103-2317"/>
-      <unit id="org.objenesis.source" version="3.3.0.v20221103-2317"/>
-      <repository location="https://download.eclipse.org/tools/orbit/downloads/drops/R20230531010532/repository"/>
+      <unit id="org.apache.httpcomponents.httpclient" version="4.5.14"/>
+      <unit id="org.apache.httpcomponents.httpclient.source" version="4.5.14"/>
+      <unit id="org.apache.httpcomponents.httpcore" version="4.4.16"/>
+      <unit id="org.apache.httpcomponents.httpcore.source" version="4.4.16"/>
+      <unit id="org.hamcrest.core" version="1.3.0.v20230809-1000"/>
+      <unit id="org.hamcrest.core.source" version="1.3.0.v20230809-1000"/>
+      <unit id="org.hamcrest.library" version="1.3.0.v20230809-1000"/>
+      <unit id="org.hamcrest.library.source" version="1.3.0.v20230809-1000"/>
+      <unit id="org.junit" version="4.13.2.v20230809-1000"/>
+      <unit id="org.junit.source" version="4.13.2.v20230809-1000"/>
+      <unit id="org.objenesis" version="3.3.0"/>
+      <unit id="org.objenesis.source" version="3.3.0"/>
+      <unit id="org.osgi.service.cm" version="1.6.1.202109301733"/>
+      <unit id="org.osgi.service.cm.source" version="1.6.1.202109301733"/>
+      <repository location="https://download.eclipse.org/tools/orbit/simrel/orbit-aggregation/release/4.29.0"/>
     </location>
     <location includeMode="slicer" includeAllPlatforms="false" includeSource="true" includeConfigurePhase="true" type="InstallableUnit">
       <unit id="org.eclipse.osgi" version="0.0.0"/>
@@ -74,6 +74,16 @@
     	</dependency>
     </dependencies>
     </location>
+    <location includeDependencyDepth="none" includeDependencyScopes="compile" includeSource="true" missingManifest="error" type="Maven" label="mockito">
+    <dependencies>
+    	<dependency>
+    		<groupId>org.mockito</groupId>
+    		<artifactId>mockito-core</artifactId>
+    		<version>5.5.0</version>
+    		<type>jar</type>
+    	</dependency>
+    </dependencies>
+    </location>
     <location includeDependencyDepth="none" includeDependencyScopes="compile" includeSource="true" missingManifest="error" type="Maven" label="jna">
     <dependencies>
     	<dependency>
@@ -177,13 +187,13 @@
     	<dependency>
     		<groupId>net.bytebuddy</groupId>
     		<artifactId>byte-buddy</artifactId>
-    		<version>1.12.18</version>
+    		<version>1.14.7</version>
     		<type>jar</type>
     	</dependency>
     	<dependency>
     		<groupId>net.bytebuddy</groupId>
     		<artifactId>byte-buddy-agent</artifactId>
-    		<version>1.12.18</version>
+    		<version>1.14.7</version>
     		<type>jar</type>
     	</dependency>
     </dependencies>
@@ -193,25 +203,25 @@
     	<dependency>
     		<groupId>org.bouncycastle</groupId>
     		<artifactId>bcpg-jdk18on</artifactId>
-    		<version>1.73</version>
+    		<version>1.76</version>
     		<type>jar</type>
     	</dependency>
     	<dependency>
     		<groupId>org.bouncycastle</groupId>
     		<artifactId>bcprov-jdk18on</artifactId>
-    		<version>1.73</version>
+    		<version>1.76</version>
     		<type>jar</type>
     	</dependency>
     	<dependency>
     		<groupId>org.bouncycastle</groupId>
     		<artifactId>bcpkix-jdk18on</artifactId>
-    		<version>1.73</version>
+    		<version>1.76</version>
     		<type>jar</type>
     	</dependency>
     	<dependency>
     		<groupId>org.bouncycastle</groupId>
     		<artifactId>bcutil-jdk18on</artifactId>
-    		<version>1.73</version>
+    		<version>1.76</version>
     		<type>jar</type>
     	</dependency>
     </dependencies>
@@ -241,7 +251,7 @@
     	<dependency>
     		<groupId>commons-codec</groupId>
     		<artifactId>commons-codec</artifactId>
-    		<version>1.15</version>
+    		<version>1.16.0</version>
     		<type>jar</type>
     	</dependency>
     	<dependency>
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 2560b0c..074ba5c 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,6 +1,6 @@
 target "jgit-4.17" with source configurePhase
 
-include "orbit/R20230531010532-2023-06.tpd"
+include "orbit/orbit-4.29.tpd"
 include "maven/dependencies.tpd"
 
 location "https://download.eclipse.org/releases/2020-09/" {
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 156cfd6..c7ac6e7 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,7 +1,7 @@
 <?xml version="1.0" encoding="UTF-8" standalone="no"?>
 <?pde?>
 <!-- generated with https://github.com/eclipse-cbi/targetplatform-dsl -->
-<target name="jgit-4.18" sequenceNumber="1686300731">
+<target name="jgit-4.18" sequenceNumber="1693839266">
   <locations>
     <location includeMode="slicer" includeAllPlatforms="false" includeSource="true" includeConfigurePhase="true" type="InstallableUnit">
       <unit id="com.jcraft.jsch" version="0.1.55.v20221112-0806"/>
@@ -12,21 +12,21 @@
       <unit id="net.i2p.crypto.eddsa.source" version="0.3.0.v20220506-1020"/>
       <unit id="org.apache.ant" version="1.10.12.v20211102-1452"/>
       <unit id="org.apache.ant.source" version="1.10.12.v20211102-1452"/>
-      <unit id="org.apache.httpcomponents.httpclient" version="4.5.14.v20230516-1249"/>
-      <unit id="org.apache.httpcomponents.httpclient.source" version="4.5.14.v20230516-1249"/>
-      <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.hamcrest.core" version="1.3.0.v20180420-1519"/>
-      <unit id="org.hamcrest.core.source" version="1.3.0.v20180420-1519"/>
-      <unit id="org.hamcrest.library" version="1.3.0.v20180524-2246"/>
-      <unit id="org.hamcrest.library.source" version="1.3.0.v20180524-2246"/>
-      <unit id="org.junit" version="4.13.2.v20211018-1956"/>
-      <unit id="org.junit.source" version="4.13.2.v20211018-1956"/>
-      <unit id="org.mockito.mockito-core" version="4.8.1.v20221103-2317"/>
-      <unit id="org.mockito.mockito-core.source" version="4.8.1.v20221103-2317"/>
-      <unit id="org.objenesis" version="3.3.0.v20221103-2317"/>
-      <unit id="org.objenesis.source" version="3.3.0.v20221103-2317"/>
-      <repository location="https://download.eclipse.org/tools/orbit/downloads/drops/R20230531010532/repository"/>
+      <unit id="org.apache.httpcomponents.httpclient" version="4.5.14"/>
+      <unit id="org.apache.httpcomponents.httpclient.source" version="4.5.14"/>
+      <unit id="org.apache.httpcomponents.httpcore" version="4.4.16"/>
+      <unit id="org.apache.httpcomponents.httpcore.source" version="4.4.16"/>
+      <unit id="org.hamcrest.core" version="1.3.0.v20230809-1000"/>
+      <unit id="org.hamcrest.core.source" version="1.3.0.v20230809-1000"/>
+      <unit id="org.hamcrest.library" version="1.3.0.v20230809-1000"/>
+      <unit id="org.hamcrest.library.source" version="1.3.0.v20230809-1000"/>
+      <unit id="org.junit" version="4.13.2.v20230809-1000"/>
+      <unit id="org.junit.source" version="4.13.2.v20230809-1000"/>
+      <unit id="org.objenesis" version="3.3.0"/>
+      <unit id="org.objenesis.source" version="3.3.0"/>
+      <unit id="org.osgi.service.cm" version="1.6.1.202109301733"/>
+      <unit id="org.osgi.service.cm.source" version="1.6.1.202109301733"/>
+      <repository location="https://download.eclipse.org/tools/orbit/simrel/orbit-aggregation/release/4.29.0"/>
     </location>
     <location includeMode="slicer" includeAllPlatforms="false" includeSource="true" includeConfigurePhase="true" type="InstallableUnit">
       <unit id="org.eclipse.osgi" version="0.0.0"/>
@@ -74,6 +74,16 @@
     	</dependency>
     </dependencies>
     </location>
+    <location includeDependencyDepth="none" includeDependencyScopes="compile" includeSource="true" missingManifest="error" type="Maven" label="mockito">
+    <dependencies>
+    	<dependency>
+    		<groupId>org.mockito</groupId>
+    		<artifactId>mockito-core</artifactId>
+    		<version>5.5.0</version>
+    		<type>jar</type>
+    	</dependency>
+    </dependencies>
+    </location>
     <location includeDependencyDepth="none" includeDependencyScopes="compile" includeSource="true" missingManifest="error" type="Maven" label="jna">
     <dependencies>
     	<dependency>
@@ -177,13 +187,13 @@
     	<dependency>
     		<groupId>net.bytebuddy</groupId>
     		<artifactId>byte-buddy</artifactId>
-    		<version>1.12.18</version>
+    		<version>1.14.7</version>
     		<type>jar</type>
     	</dependency>
     	<dependency>
     		<groupId>net.bytebuddy</groupId>
     		<artifactId>byte-buddy-agent</artifactId>
-    		<version>1.12.18</version>
+    		<version>1.14.7</version>
     		<type>jar</type>
     	</dependency>
     </dependencies>
@@ -193,25 +203,25 @@
     	<dependency>
     		<groupId>org.bouncycastle</groupId>
     		<artifactId>bcpg-jdk18on</artifactId>
-    		<version>1.73</version>
+    		<version>1.76</version>
     		<type>jar</type>
     	</dependency>
     	<dependency>
     		<groupId>org.bouncycastle</groupId>
     		<artifactId>bcprov-jdk18on</artifactId>
-    		<version>1.73</version>
+    		<version>1.76</version>
     		<type>jar</type>
     	</dependency>
     	<dependency>
     		<groupId>org.bouncycastle</groupId>
     		<artifactId>bcpkix-jdk18on</artifactId>
-    		<version>1.73</version>
+    		<version>1.76</version>
     		<type>jar</type>
     	</dependency>
     	<dependency>
     		<groupId>org.bouncycastle</groupId>
     		<artifactId>bcutil-jdk18on</artifactId>
-    		<version>1.73</version>
+    		<version>1.76</version>
     		<type>jar</type>
     	</dependency>
     </dependencies>
@@ -241,7 +251,7 @@
     	<dependency>
     		<groupId>commons-codec</groupId>
     		<artifactId>commons-codec</artifactId>
-    		<version>1.15</version>
+    		<version>1.16.0</version>
     		<type>jar</type>
     	</dependency>
     	<dependency>
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 de0655f..79028fe 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,6 +1,6 @@
 target "jgit-4.18" with source configurePhase
 
-include "orbit/R20230531010532-2023-06.tpd"
+include "orbit/orbit-4.29.tpd"
 include "maven/dependencies.tpd"
 
 location "https://download.eclipse.org/releases/2020-12/" {
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 14b15fa..1a90799 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,7 +1,7 @@
 <?xml version="1.0" encoding="UTF-8" standalone="no"?>
 <?pde?>
 <!-- generated with https://github.com/eclipse-cbi/targetplatform-dsl -->
-<target name="jgit-4.19-staging" sequenceNumber="1686300730">
+<target name="jgit-4.19-staging" sequenceNumber="1693839266">
   <locations>
     <location includeMode="slicer" includeAllPlatforms="false" includeSource="true" includeConfigurePhase="true" type="InstallableUnit">
       <unit id="com.jcraft.jsch" version="0.1.55.v20221112-0806"/>
@@ -12,21 +12,21 @@
       <unit id="net.i2p.crypto.eddsa.source" version="0.3.0.v20220506-1020"/>
       <unit id="org.apache.ant" version="1.10.12.v20211102-1452"/>
       <unit id="org.apache.ant.source" version="1.10.12.v20211102-1452"/>
-      <unit id="org.apache.httpcomponents.httpclient" version="4.5.14.v20230516-1249"/>
-      <unit id="org.apache.httpcomponents.httpclient.source" version="4.5.14.v20230516-1249"/>
-      <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.hamcrest.core" version="1.3.0.v20180420-1519"/>
-      <unit id="org.hamcrest.core.source" version="1.3.0.v20180420-1519"/>
-      <unit id="org.hamcrest.library" version="1.3.0.v20180524-2246"/>
-      <unit id="org.hamcrest.library.source" version="1.3.0.v20180524-2246"/>
-      <unit id="org.junit" version="4.13.2.v20211018-1956"/>
-      <unit id="org.junit.source" version="4.13.2.v20211018-1956"/>
-      <unit id="org.mockito.mockito-core" version="4.8.1.v20221103-2317"/>
-      <unit id="org.mockito.mockito-core.source" version="4.8.1.v20221103-2317"/>
-      <unit id="org.objenesis" version="3.3.0.v20221103-2317"/>
-      <unit id="org.objenesis.source" version="3.3.0.v20221103-2317"/>
-      <repository location="https://download.eclipse.org/tools/orbit/downloads/drops/R20230531010532/repository"/>
+      <unit id="org.apache.httpcomponents.httpclient" version="4.5.14"/>
+      <unit id="org.apache.httpcomponents.httpclient.source" version="4.5.14"/>
+      <unit id="org.apache.httpcomponents.httpcore" version="4.4.16"/>
+      <unit id="org.apache.httpcomponents.httpcore.source" version="4.4.16"/>
+      <unit id="org.hamcrest.core" version="1.3.0.v20230809-1000"/>
+      <unit id="org.hamcrest.core.source" version="1.3.0.v20230809-1000"/>
+      <unit id="org.hamcrest.library" version="1.3.0.v20230809-1000"/>
+      <unit id="org.hamcrest.library.source" version="1.3.0.v20230809-1000"/>
+      <unit id="org.junit" version="4.13.2.v20230809-1000"/>
+      <unit id="org.junit.source" version="4.13.2.v20230809-1000"/>
+      <unit id="org.objenesis" version="3.3.0"/>
+      <unit id="org.objenesis.source" version="3.3.0"/>
+      <unit id="org.osgi.service.cm" version="1.6.1.202109301733"/>
+      <unit id="org.osgi.service.cm.source" version="1.6.1.202109301733"/>
+      <repository location="https://download.eclipse.org/tools/orbit/simrel/orbit-aggregation/release/4.29.0"/>
     </location>
     <location includeMode="slicer" includeAllPlatforms="false" includeSource="true" includeConfigurePhase="true" type="InstallableUnit">
       <unit id="org.eclipse.osgi" version="0.0.0"/>
@@ -74,6 +74,16 @@
     	</dependency>
     </dependencies>
     </location>
+    <location includeDependencyDepth="none" includeDependencyScopes="compile" includeSource="true" missingManifest="error" type="Maven" label="mockito">
+    <dependencies>
+    	<dependency>
+    		<groupId>org.mockito</groupId>
+    		<artifactId>mockito-core</artifactId>
+    		<version>5.5.0</version>
+    		<type>jar</type>
+    	</dependency>
+    </dependencies>
+    </location>
     <location includeDependencyDepth="none" includeDependencyScopes="compile" includeSource="true" missingManifest="error" type="Maven" label="jna">
     <dependencies>
     	<dependency>
@@ -177,13 +187,13 @@
     	<dependency>
     		<groupId>net.bytebuddy</groupId>
     		<artifactId>byte-buddy</artifactId>
-    		<version>1.12.18</version>
+    		<version>1.14.7</version>
     		<type>jar</type>
     	</dependency>
     	<dependency>
     		<groupId>net.bytebuddy</groupId>
     		<artifactId>byte-buddy-agent</artifactId>
-    		<version>1.12.18</version>
+    		<version>1.14.7</version>
     		<type>jar</type>
     	</dependency>
     </dependencies>
@@ -193,25 +203,25 @@
     	<dependency>
     		<groupId>org.bouncycastle</groupId>
     		<artifactId>bcpg-jdk18on</artifactId>
-    		<version>1.73</version>
+    		<version>1.76</version>
     		<type>jar</type>
     	</dependency>
     	<dependency>
     		<groupId>org.bouncycastle</groupId>
     		<artifactId>bcprov-jdk18on</artifactId>
-    		<version>1.73</version>
+    		<version>1.76</version>
     		<type>jar</type>
     	</dependency>
     	<dependency>
     		<groupId>org.bouncycastle</groupId>
     		<artifactId>bcpkix-jdk18on</artifactId>
-    		<version>1.73</version>
+    		<version>1.76</version>
     		<type>jar</type>
     	</dependency>
     	<dependency>
     		<groupId>org.bouncycastle</groupId>
     		<artifactId>bcutil-jdk18on</artifactId>
-    		<version>1.73</version>
+    		<version>1.76</version>
     		<type>jar</type>
     	</dependency>
     </dependencies>
@@ -241,7 +251,7 @@
     	<dependency>
     		<groupId>commons-codec</groupId>
     		<artifactId>commons-codec</artifactId>
-    		<version>1.15</version>
+    		<version>1.16.0</version>
     		<type>jar</type>
     	</dependency>
     	<dependency>
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 9f1802d..3fb1e19 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,6 +1,6 @@
 target "jgit-4.19-staging" with source configurePhase
 
-include "orbit/R20230531010532-2023-06.tpd"
+include "orbit/orbit-4.29.tpd"
 include "maven/dependencies.tpd"
 
 location "https://download.eclipse.org/releases/2021-03/" {
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 0d7b240..8b10aa2 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,7 +1,7 @@
 <?xml version="1.0" encoding="UTF-8" standalone="no"?>
 <?pde?>
 <!-- generated with https://github.com/eclipse-cbi/targetplatform-dsl -->
-<target name="jgit-4.20" sequenceNumber="1686300731">
+<target name="jgit-4.20" sequenceNumber="1693839266">
   <locations>
     <location includeMode="slicer" includeAllPlatforms="false" includeSource="true" includeConfigurePhase="true" type="InstallableUnit">
       <unit id="com.jcraft.jsch" version="0.1.55.v20221112-0806"/>
@@ -12,21 +12,21 @@
       <unit id="net.i2p.crypto.eddsa.source" version="0.3.0.v20220506-1020"/>
       <unit id="org.apache.ant" version="1.10.12.v20211102-1452"/>
       <unit id="org.apache.ant.source" version="1.10.12.v20211102-1452"/>
-      <unit id="org.apache.httpcomponents.httpclient" version="4.5.14.v20230516-1249"/>
-      <unit id="org.apache.httpcomponents.httpclient.source" version="4.5.14.v20230516-1249"/>
-      <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.hamcrest.core" version="1.3.0.v20180420-1519"/>
-      <unit id="org.hamcrest.core.source" version="1.3.0.v20180420-1519"/>
-      <unit id="org.hamcrest.library" version="1.3.0.v20180524-2246"/>
-      <unit id="org.hamcrest.library.source" version="1.3.0.v20180524-2246"/>
-      <unit id="org.junit" version="4.13.2.v20211018-1956"/>
-      <unit id="org.junit.source" version="4.13.2.v20211018-1956"/>
-      <unit id="org.mockito.mockito-core" version="4.8.1.v20221103-2317"/>
-      <unit id="org.mockito.mockito-core.source" version="4.8.1.v20221103-2317"/>
-      <unit id="org.objenesis" version="3.3.0.v20221103-2317"/>
-      <unit id="org.objenesis.source" version="3.3.0.v20221103-2317"/>
-      <repository location="https://download.eclipse.org/tools/orbit/downloads/drops/R20230531010532/repository"/>
+      <unit id="org.apache.httpcomponents.httpclient" version="4.5.14"/>
+      <unit id="org.apache.httpcomponents.httpclient.source" version="4.5.14"/>
+      <unit id="org.apache.httpcomponents.httpcore" version="4.4.16"/>
+      <unit id="org.apache.httpcomponents.httpcore.source" version="4.4.16"/>
+      <unit id="org.hamcrest.core" version="1.3.0.v20230809-1000"/>
+      <unit id="org.hamcrest.core.source" version="1.3.0.v20230809-1000"/>
+      <unit id="org.hamcrest.library" version="1.3.0.v20230809-1000"/>
+      <unit id="org.hamcrest.library.source" version="1.3.0.v20230809-1000"/>
+      <unit id="org.junit" version="4.13.2.v20230809-1000"/>
+      <unit id="org.junit.source" version="4.13.2.v20230809-1000"/>
+      <unit id="org.objenesis" version="3.3.0"/>
+      <unit id="org.objenesis.source" version="3.3.0"/>
+      <unit id="org.osgi.service.cm" version="1.6.1.202109301733"/>
+      <unit id="org.osgi.service.cm.source" version="1.6.1.202109301733"/>
+      <repository location="https://download.eclipse.org/tools/orbit/simrel/orbit-aggregation/release/4.29.0"/>
     </location>
     <location includeMode="slicer" includeAllPlatforms="false" includeSource="true" includeConfigurePhase="true" type="InstallableUnit">
       <unit id="org.eclipse.osgi" version="0.0.0"/>
@@ -74,6 +74,16 @@
     	</dependency>
     </dependencies>
     </location>
+    <location includeDependencyDepth="none" includeDependencyScopes="compile" includeSource="true" missingManifest="error" type="Maven" label="mockito">
+    <dependencies>
+    	<dependency>
+    		<groupId>org.mockito</groupId>
+    		<artifactId>mockito-core</artifactId>
+    		<version>5.5.0</version>
+    		<type>jar</type>
+    	</dependency>
+    </dependencies>
+    </location>
     <location includeDependencyDepth="none" includeDependencyScopes="compile" includeSource="true" missingManifest="error" type="Maven" label="jna">
     <dependencies>
     	<dependency>
@@ -177,13 +187,13 @@
     	<dependency>
     		<groupId>net.bytebuddy</groupId>
     		<artifactId>byte-buddy</artifactId>
-    		<version>1.12.18</version>
+    		<version>1.14.7</version>
     		<type>jar</type>
     	</dependency>
     	<dependency>
     		<groupId>net.bytebuddy</groupId>
     		<artifactId>byte-buddy-agent</artifactId>
-    		<version>1.12.18</version>
+    		<version>1.14.7</version>
     		<type>jar</type>
     	</dependency>
     </dependencies>
@@ -193,25 +203,25 @@
     	<dependency>
     		<groupId>org.bouncycastle</groupId>
     		<artifactId>bcpg-jdk18on</artifactId>
-    		<version>1.73</version>
+    		<version>1.76</version>
     		<type>jar</type>
     	</dependency>
     	<dependency>
     		<groupId>org.bouncycastle</groupId>
     		<artifactId>bcprov-jdk18on</artifactId>
-    		<version>1.73</version>
+    		<version>1.76</version>
     		<type>jar</type>
     	</dependency>
     	<dependency>
     		<groupId>org.bouncycastle</groupId>
     		<artifactId>bcpkix-jdk18on</artifactId>
-    		<version>1.73</version>
+    		<version>1.76</version>
     		<type>jar</type>
     	</dependency>
     	<dependency>
     		<groupId>org.bouncycastle</groupId>
     		<artifactId>bcutil-jdk18on</artifactId>
-    		<version>1.73</version>
+    		<version>1.76</version>
     		<type>jar</type>
     	</dependency>
     </dependencies>
@@ -241,7 +251,7 @@
     	<dependency>
     		<groupId>commons-codec</groupId>
     		<artifactId>commons-codec</artifactId>
-    		<version>1.15</version>
+    		<version>1.16.0</version>
     		<type>jar</type>
     	</dependency>
     	<dependency>
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 97a5e82..ebc7857 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,6 +1,6 @@
 target "jgit-4.20" with source configurePhase
 
-include "orbit/R20230531010532-2023-06.tpd"
+include "orbit/orbit-4.29.tpd"
 include "maven/dependencies.tpd"
 
 location "https://download.eclipse.org/releases/2021-06/" {
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 94f671d..733f608 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,7 +1,7 @@
 <?xml version="1.0" encoding="UTF-8" standalone="no"?>
 <?pde?>
 <!-- generated with https://github.com/eclipse-cbi/targetplatform-dsl -->
-<target name="jgit-4.21" sequenceNumber="1686300731">
+<target name="jgit-4.21" sequenceNumber="1693839266">
   <locations>
     <location includeMode="slicer" includeAllPlatforms="false" includeSource="true" includeConfigurePhase="true" type="InstallableUnit">
       <unit id="com.jcraft.jsch" version="0.1.55.v20221112-0806"/>
@@ -12,21 +12,21 @@
       <unit id="net.i2p.crypto.eddsa.source" version="0.3.0.v20220506-1020"/>
       <unit id="org.apache.ant" version="1.10.12.v20211102-1452"/>
       <unit id="org.apache.ant.source" version="1.10.12.v20211102-1452"/>
-      <unit id="org.apache.httpcomponents.httpclient" version="4.5.14.v20230516-1249"/>
-      <unit id="org.apache.httpcomponents.httpclient.source" version="4.5.14.v20230516-1249"/>
-      <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.hamcrest.core" version="1.3.0.v20180420-1519"/>
-      <unit id="org.hamcrest.core.source" version="1.3.0.v20180420-1519"/>
-      <unit id="org.hamcrest.library" version="1.3.0.v20180524-2246"/>
-      <unit id="org.hamcrest.library.source" version="1.3.0.v20180524-2246"/>
-      <unit id="org.junit" version="4.13.2.v20211018-1956"/>
-      <unit id="org.junit.source" version="4.13.2.v20211018-1956"/>
-      <unit id="org.mockito.mockito-core" version="4.8.1.v20221103-2317"/>
-      <unit id="org.mockito.mockito-core.source" version="4.8.1.v20221103-2317"/>
-      <unit id="org.objenesis" version="3.3.0.v20221103-2317"/>
-      <unit id="org.objenesis.source" version="3.3.0.v20221103-2317"/>
-      <repository location="https://download.eclipse.org/tools/orbit/downloads/drops/R20230531010532/repository"/>
+      <unit id="org.apache.httpcomponents.httpclient" version="4.5.14"/>
+      <unit id="org.apache.httpcomponents.httpclient.source" version="4.5.14"/>
+      <unit id="org.apache.httpcomponents.httpcore" version="4.4.16"/>
+      <unit id="org.apache.httpcomponents.httpcore.source" version="4.4.16"/>
+      <unit id="org.hamcrest.core" version="1.3.0.v20230809-1000"/>
+      <unit id="org.hamcrest.core.source" version="1.3.0.v20230809-1000"/>
+      <unit id="org.hamcrest.library" version="1.3.0.v20230809-1000"/>
+      <unit id="org.hamcrest.library.source" version="1.3.0.v20230809-1000"/>
+      <unit id="org.junit" version="4.13.2.v20230809-1000"/>
+      <unit id="org.junit.source" version="4.13.2.v20230809-1000"/>
+      <unit id="org.objenesis" version="3.3.0"/>
+      <unit id="org.objenesis.source" version="3.3.0"/>
+      <unit id="org.osgi.service.cm" version="1.6.1.202109301733"/>
+      <unit id="org.osgi.service.cm.source" version="1.6.1.202109301733"/>
+      <repository location="https://download.eclipse.org/tools/orbit/simrel/orbit-aggregation/release/4.29.0"/>
     </location>
     <location includeMode="slicer" includeAllPlatforms="false" includeSource="true" includeConfigurePhase="true" type="InstallableUnit">
       <unit id="org.eclipse.osgi" version="0.0.0"/>
@@ -74,6 +74,16 @@
     	</dependency>
     </dependencies>
     </location>
+    <location includeDependencyDepth="none" includeDependencyScopes="compile" includeSource="true" missingManifest="error" type="Maven" label="mockito">
+    <dependencies>
+    	<dependency>
+    		<groupId>org.mockito</groupId>
+    		<artifactId>mockito-core</artifactId>
+    		<version>5.5.0</version>
+    		<type>jar</type>
+    	</dependency>
+    </dependencies>
+    </location>
     <location includeDependencyDepth="none" includeDependencyScopes="compile" includeSource="true" missingManifest="error" type="Maven" label="jna">
     <dependencies>
     	<dependency>
@@ -177,13 +187,13 @@
     	<dependency>
     		<groupId>net.bytebuddy</groupId>
     		<artifactId>byte-buddy</artifactId>
-    		<version>1.12.18</version>
+    		<version>1.14.7</version>
     		<type>jar</type>
     	</dependency>
     	<dependency>
     		<groupId>net.bytebuddy</groupId>
     		<artifactId>byte-buddy-agent</artifactId>
-    		<version>1.12.18</version>
+    		<version>1.14.7</version>
     		<type>jar</type>
     	</dependency>
     </dependencies>
@@ -193,25 +203,25 @@
     	<dependency>
     		<groupId>org.bouncycastle</groupId>
     		<artifactId>bcpg-jdk18on</artifactId>
-    		<version>1.73</version>
+    		<version>1.76</version>
     		<type>jar</type>
     	</dependency>
     	<dependency>
     		<groupId>org.bouncycastle</groupId>
     		<artifactId>bcprov-jdk18on</artifactId>
-    		<version>1.73</version>
+    		<version>1.76</version>
     		<type>jar</type>
     	</dependency>
     	<dependency>
     		<groupId>org.bouncycastle</groupId>
     		<artifactId>bcpkix-jdk18on</artifactId>
-    		<version>1.73</version>
+    		<version>1.76</version>
     		<type>jar</type>
     	</dependency>
     	<dependency>
     		<groupId>org.bouncycastle</groupId>
     		<artifactId>bcutil-jdk18on</artifactId>
-    		<version>1.73</version>
+    		<version>1.76</version>
     		<type>jar</type>
     	</dependency>
     </dependencies>
@@ -241,7 +251,7 @@
     	<dependency>
     		<groupId>commons-codec</groupId>
     		<artifactId>commons-codec</artifactId>
-    		<version>1.15</version>
+    		<version>1.16.0</version>
     		<type>jar</type>
     	</dependency>
     	<dependency>
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 be43474..126438d 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,6 +1,6 @@
 target "jgit-4.21" with source configurePhase
 
-include "orbit/R20230531010532-2023-06.tpd"
+include "orbit/orbit-4.29.tpd"
 include "maven/dependencies.tpd"
 
 location "https://download.eclipse.org/releases/2021-09/" {
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 e14dd30..f241937 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,7 +1,7 @@
 <?xml version="1.0" encoding="UTF-8" standalone="no"?>
 <?pde?>
 <!-- generated with https://github.com/eclipse-cbi/targetplatform-dsl -->
-<target name="jgit-4.22" sequenceNumber="1686300729">
+<target name="jgit-4.22" sequenceNumber="1693839266">
   <locations>
     <location includeMode="slicer" includeAllPlatforms="false" includeSource="true" includeConfigurePhase="true" type="InstallableUnit">
       <unit id="com.jcraft.jsch" version="0.1.55.v20221112-0806"/>
@@ -12,21 +12,21 @@
       <unit id="net.i2p.crypto.eddsa.source" version="0.3.0.v20220506-1020"/>
       <unit id="org.apache.ant" version="1.10.12.v20211102-1452"/>
       <unit id="org.apache.ant.source" version="1.10.12.v20211102-1452"/>
-      <unit id="org.apache.httpcomponents.httpclient" version="4.5.14.v20230516-1249"/>
-      <unit id="org.apache.httpcomponents.httpclient.source" version="4.5.14.v20230516-1249"/>
-      <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.hamcrest.core" version="1.3.0.v20180420-1519"/>
-      <unit id="org.hamcrest.core.source" version="1.3.0.v20180420-1519"/>
-      <unit id="org.hamcrest.library" version="1.3.0.v20180524-2246"/>
-      <unit id="org.hamcrest.library.source" version="1.3.0.v20180524-2246"/>
-      <unit id="org.junit" version="4.13.2.v20211018-1956"/>
-      <unit id="org.junit.source" version="4.13.2.v20211018-1956"/>
-      <unit id="org.mockito.mockito-core" version="4.8.1.v20221103-2317"/>
-      <unit id="org.mockito.mockito-core.source" version="4.8.1.v20221103-2317"/>
-      <unit id="org.objenesis" version="3.3.0.v20221103-2317"/>
-      <unit id="org.objenesis.source" version="3.3.0.v20221103-2317"/>
-      <repository location="https://download.eclipse.org/tools/orbit/downloads/drops/R20230531010532/repository"/>
+      <unit id="org.apache.httpcomponents.httpclient" version="4.5.14"/>
+      <unit id="org.apache.httpcomponents.httpclient.source" version="4.5.14"/>
+      <unit id="org.apache.httpcomponents.httpcore" version="4.4.16"/>
+      <unit id="org.apache.httpcomponents.httpcore.source" version="4.4.16"/>
+      <unit id="org.hamcrest.core" version="1.3.0.v20230809-1000"/>
+      <unit id="org.hamcrest.core.source" version="1.3.0.v20230809-1000"/>
+      <unit id="org.hamcrest.library" version="1.3.0.v20230809-1000"/>
+      <unit id="org.hamcrest.library.source" version="1.3.0.v20230809-1000"/>
+      <unit id="org.junit" version="4.13.2.v20230809-1000"/>
+      <unit id="org.junit.source" version="4.13.2.v20230809-1000"/>
+      <unit id="org.objenesis" version="3.3.0"/>
+      <unit id="org.objenesis.source" version="3.3.0"/>
+      <unit id="org.osgi.service.cm" version="1.6.1.202109301733"/>
+      <unit id="org.osgi.service.cm.source" version="1.6.1.202109301733"/>
+      <repository location="https://download.eclipse.org/tools/orbit/simrel/orbit-aggregation/release/4.29.0"/>
     </location>
     <location includeMode="slicer" includeAllPlatforms="false" includeSource="true" includeConfigurePhase="true" type="InstallableUnit">
       <unit id="org.eclipse.osgi" version="0.0.0"/>
@@ -74,6 +74,16 @@
     	</dependency>
     </dependencies>
     </location>
+    <location includeDependencyDepth="none" includeDependencyScopes="compile" includeSource="true" missingManifest="error" type="Maven" label="mockito">
+    <dependencies>
+    	<dependency>
+    		<groupId>org.mockito</groupId>
+    		<artifactId>mockito-core</artifactId>
+    		<version>5.5.0</version>
+    		<type>jar</type>
+    	</dependency>
+    </dependencies>
+    </location>
     <location includeDependencyDepth="none" includeDependencyScopes="compile" includeSource="true" missingManifest="error" type="Maven" label="jna">
     <dependencies>
     	<dependency>
@@ -177,13 +187,13 @@
     	<dependency>
     		<groupId>net.bytebuddy</groupId>
     		<artifactId>byte-buddy</artifactId>
-    		<version>1.12.18</version>
+    		<version>1.14.7</version>
     		<type>jar</type>
     	</dependency>
     	<dependency>
     		<groupId>net.bytebuddy</groupId>
     		<artifactId>byte-buddy-agent</artifactId>
-    		<version>1.12.18</version>
+    		<version>1.14.7</version>
     		<type>jar</type>
     	</dependency>
     </dependencies>
@@ -193,25 +203,25 @@
     	<dependency>
     		<groupId>org.bouncycastle</groupId>
     		<artifactId>bcpg-jdk18on</artifactId>
-    		<version>1.73</version>
+    		<version>1.76</version>
     		<type>jar</type>
     	</dependency>
     	<dependency>
     		<groupId>org.bouncycastle</groupId>
     		<artifactId>bcprov-jdk18on</artifactId>
-    		<version>1.73</version>
+    		<version>1.76</version>
     		<type>jar</type>
     	</dependency>
     	<dependency>
     		<groupId>org.bouncycastle</groupId>
     		<artifactId>bcpkix-jdk18on</artifactId>
-    		<version>1.73</version>
+    		<version>1.76</version>
     		<type>jar</type>
     	</dependency>
     	<dependency>
     		<groupId>org.bouncycastle</groupId>
     		<artifactId>bcutil-jdk18on</artifactId>
-    		<version>1.73</version>
+    		<version>1.76</version>
     		<type>jar</type>
     	</dependency>
     </dependencies>
@@ -241,7 +251,7 @@
     	<dependency>
     		<groupId>commons-codec</groupId>
     		<artifactId>commons-codec</artifactId>
-    		<version>1.15</version>
+    		<version>1.16.0</version>
     		<type>jar</type>
     	</dependency>
     	<dependency>
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 2f8f60e..f258eee 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,6 +1,6 @@
 target "jgit-4.22" with source configurePhase
 
-include "orbit/R20230531010532-2023-06.tpd"
+include "orbit/orbit-4.29.tpd"
 include "maven/dependencies.tpd"
 
 location "https://download.eclipse.org/releases/2021-12/" {
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 5455f07..3468e11 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,7 +1,7 @@
 <?xml version="1.0" encoding="UTF-8" standalone="no"?>
 <?pde?>
 <!-- generated with https://github.com/eclipse-cbi/targetplatform-dsl -->
-<target name="jgit-4.23" sequenceNumber="1686300730">
+<target name="jgit-4.23" sequenceNumber="1693839266">
   <locations>
     <location includeMode="slicer" includeAllPlatforms="false" includeSource="true" includeConfigurePhase="true" type="InstallableUnit">
       <unit id="com.jcraft.jsch" version="0.1.55.v20221112-0806"/>
@@ -12,21 +12,21 @@
       <unit id="net.i2p.crypto.eddsa.source" version="0.3.0.v20220506-1020"/>
       <unit id="org.apache.ant" version="1.10.12.v20211102-1452"/>
       <unit id="org.apache.ant.source" version="1.10.12.v20211102-1452"/>
-      <unit id="org.apache.httpcomponents.httpclient" version="4.5.14.v20230516-1249"/>
-      <unit id="org.apache.httpcomponents.httpclient.source" version="4.5.14.v20230516-1249"/>
-      <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.hamcrest.core" version="1.3.0.v20180420-1519"/>
-      <unit id="org.hamcrest.core.source" version="1.3.0.v20180420-1519"/>
-      <unit id="org.hamcrest.library" version="1.3.0.v20180524-2246"/>
-      <unit id="org.hamcrest.library.source" version="1.3.0.v20180524-2246"/>
-      <unit id="org.junit" version="4.13.2.v20211018-1956"/>
-      <unit id="org.junit.source" version="4.13.2.v20211018-1956"/>
-      <unit id="org.mockito.mockito-core" version="4.8.1.v20221103-2317"/>
-      <unit id="org.mockito.mockito-core.source" version="4.8.1.v20221103-2317"/>
-      <unit id="org.objenesis" version="3.3.0.v20221103-2317"/>
-      <unit id="org.objenesis.source" version="3.3.0.v20221103-2317"/>
-      <repository location="https://download.eclipse.org/tools/orbit/downloads/drops/R20230531010532/repository"/>
+      <unit id="org.apache.httpcomponents.httpclient" version="4.5.14"/>
+      <unit id="org.apache.httpcomponents.httpclient.source" version="4.5.14"/>
+      <unit id="org.apache.httpcomponents.httpcore" version="4.4.16"/>
+      <unit id="org.apache.httpcomponents.httpcore.source" version="4.4.16"/>
+      <unit id="org.hamcrest.core" version="1.3.0.v20230809-1000"/>
+      <unit id="org.hamcrest.core.source" version="1.3.0.v20230809-1000"/>
+      <unit id="org.hamcrest.library" version="1.3.0.v20230809-1000"/>
+      <unit id="org.hamcrest.library.source" version="1.3.0.v20230809-1000"/>
+      <unit id="org.junit" version="4.13.2.v20230809-1000"/>
+      <unit id="org.junit.source" version="4.13.2.v20230809-1000"/>
+      <unit id="org.objenesis" version="3.3.0"/>
+      <unit id="org.objenesis.source" version="3.3.0"/>
+      <unit id="org.osgi.service.cm" version="1.6.1.202109301733"/>
+      <unit id="org.osgi.service.cm.source" version="1.6.1.202109301733"/>
+      <repository location="https://download.eclipse.org/tools/orbit/simrel/orbit-aggregation/release/4.29.0"/>
     </location>
     <location includeMode="slicer" includeAllPlatforms="false" includeSource="true" includeConfigurePhase="true" type="InstallableUnit">
       <unit id="org.eclipse.osgi" version="0.0.0"/>
@@ -74,6 +74,16 @@
     	</dependency>
     </dependencies>
     </location>
+    <location includeDependencyDepth="none" includeDependencyScopes="compile" includeSource="true" missingManifest="error" type="Maven" label="mockito">
+    <dependencies>
+    	<dependency>
+    		<groupId>org.mockito</groupId>
+    		<artifactId>mockito-core</artifactId>
+    		<version>5.5.0</version>
+    		<type>jar</type>
+    	</dependency>
+    </dependencies>
+    </location>
     <location includeDependencyDepth="none" includeDependencyScopes="compile" includeSource="true" missingManifest="error" type="Maven" label="jna">
     <dependencies>
     	<dependency>
@@ -177,13 +187,13 @@
     	<dependency>
     		<groupId>net.bytebuddy</groupId>
     		<artifactId>byte-buddy</artifactId>
-    		<version>1.12.18</version>
+    		<version>1.14.7</version>
     		<type>jar</type>
     	</dependency>
     	<dependency>
     		<groupId>net.bytebuddy</groupId>
     		<artifactId>byte-buddy-agent</artifactId>
-    		<version>1.12.18</version>
+    		<version>1.14.7</version>
     		<type>jar</type>
     	</dependency>
     </dependencies>
@@ -193,25 +203,25 @@
     	<dependency>
     		<groupId>org.bouncycastle</groupId>
     		<artifactId>bcpg-jdk18on</artifactId>
-    		<version>1.73</version>
+    		<version>1.76</version>
     		<type>jar</type>
     	</dependency>
     	<dependency>
     		<groupId>org.bouncycastle</groupId>
     		<artifactId>bcprov-jdk18on</artifactId>
-    		<version>1.73</version>
+    		<version>1.76</version>
     		<type>jar</type>
     	</dependency>
     	<dependency>
     		<groupId>org.bouncycastle</groupId>
     		<artifactId>bcpkix-jdk18on</artifactId>
-    		<version>1.73</version>
+    		<version>1.76</version>
     		<type>jar</type>
     	</dependency>
     	<dependency>
     		<groupId>org.bouncycastle</groupId>
     		<artifactId>bcutil-jdk18on</artifactId>
-    		<version>1.73</version>
+    		<version>1.76</version>
     		<type>jar</type>
     	</dependency>
     </dependencies>
@@ -241,7 +251,7 @@
     	<dependency>
     		<groupId>commons-codec</groupId>
     		<artifactId>commons-codec</artifactId>
-    		<version>1.15</version>
+    		<version>1.16.0</version>
     		<type>jar</type>
     	</dependency>
     	<dependency>
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 a4a1c52..5bdffae 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,6 +1,6 @@
 target "jgit-4.23" with source configurePhase
 
-include "orbit/R20230531010532-2023-06.tpd"
+include "orbit/orbit-4.29.tpd"
 include "maven/dependencies.tpd"
 
 location "https://download.eclipse.org/releases/2022-03/" {
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 c383bce..2c1d961 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,7 +1,7 @@
 <?xml version="1.0" encoding="UTF-8" standalone="no"?>
 <?pde?>
 <!-- generated with https://github.com/eclipse-cbi/targetplatform-dsl -->
-<target name="jgit-4.24" sequenceNumber="1686300729">
+<target name="jgit-4.24" sequenceNumber="1693839266">
   <locations>
     <location includeMode="slicer" includeAllPlatforms="false" includeSource="true" includeConfigurePhase="true" type="InstallableUnit">
       <unit id="com.jcraft.jsch" version="0.1.55.v20221112-0806"/>
@@ -12,21 +12,21 @@
       <unit id="net.i2p.crypto.eddsa.source" version="0.3.0.v20220506-1020"/>
       <unit id="org.apache.ant" version="1.10.12.v20211102-1452"/>
       <unit id="org.apache.ant.source" version="1.10.12.v20211102-1452"/>
-      <unit id="org.apache.httpcomponents.httpclient" version="4.5.14.v20230516-1249"/>
-      <unit id="org.apache.httpcomponents.httpclient.source" version="4.5.14.v20230516-1249"/>
-      <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.hamcrest.core" version="1.3.0.v20180420-1519"/>
-      <unit id="org.hamcrest.core.source" version="1.3.0.v20180420-1519"/>
-      <unit id="org.hamcrest.library" version="1.3.0.v20180524-2246"/>
-      <unit id="org.hamcrest.library.source" version="1.3.0.v20180524-2246"/>
-      <unit id="org.junit" version="4.13.2.v20211018-1956"/>
-      <unit id="org.junit.source" version="4.13.2.v20211018-1956"/>
-      <unit id="org.mockito.mockito-core" version="4.8.1.v20221103-2317"/>
-      <unit id="org.mockito.mockito-core.source" version="4.8.1.v20221103-2317"/>
-      <unit id="org.objenesis" version="3.3.0.v20221103-2317"/>
-      <unit id="org.objenesis.source" version="3.3.0.v20221103-2317"/>
-      <repository location="https://download.eclipse.org/tools/orbit/downloads/drops/R20230531010532/repository"/>
+      <unit id="org.apache.httpcomponents.httpclient" version="4.5.14"/>
+      <unit id="org.apache.httpcomponents.httpclient.source" version="4.5.14"/>
+      <unit id="org.apache.httpcomponents.httpcore" version="4.4.16"/>
+      <unit id="org.apache.httpcomponents.httpcore.source" version="4.4.16"/>
+      <unit id="org.hamcrest.core" version="1.3.0.v20230809-1000"/>
+      <unit id="org.hamcrest.core.source" version="1.3.0.v20230809-1000"/>
+      <unit id="org.hamcrest.library" version="1.3.0.v20230809-1000"/>
+      <unit id="org.hamcrest.library.source" version="1.3.0.v20230809-1000"/>
+      <unit id="org.junit" version="4.13.2.v20230809-1000"/>
+      <unit id="org.junit.source" version="4.13.2.v20230809-1000"/>
+      <unit id="org.objenesis" version="3.3.0"/>
+      <unit id="org.objenesis.source" version="3.3.0"/>
+      <unit id="org.osgi.service.cm" version="1.6.1.202109301733"/>
+      <unit id="org.osgi.service.cm.source" version="1.6.1.202109301733"/>
+      <repository location="https://download.eclipse.org/tools/orbit/simrel/orbit-aggregation/release/4.29.0"/>
     </location>
     <location includeMode="slicer" includeAllPlatforms="false" includeSource="true" includeConfigurePhase="true" type="InstallableUnit">
       <unit id="org.eclipse.osgi" version="0.0.0"/>
@@ -74,6 +74,16 @@
     	</dependency>
     </dependencies>
     </location>
+    <location includeDependencyDepth="none" includeDependencyScopes="compile" includeSource="true" missingManifest="error" type="Maven" label="mockito">
+    <dependencies>
+    	<dependency>
+    		<groupId>org.mockito</groupId>
+    		<artifactId>mockito-core</artifactId>
+    		<version>5.5.0</version>
+    		<type>jar</type>
+    	</dependency>
+    </dependencies>
+    </location>
     <location includeDependencyDepth="none" includeDependencyScopes="compile" includeSource="true" missingManifest="error" type="Maven" label="jna">
     <dependencies>
     	<dependency>
@@ -177,13 +187,13 @@
     	<dependency>
     		<groupId>net.bytebuddy</groupId>
     		<artifactId>byte-buddy</artifactId>
-    		<version>1.12.18</version>
+    		<version>1.14.7</version>
     		<type>jar</type>
     	</dependency>
     	<dependency>
     		<groupId>net.bytebuddy</groupId>
     		<artifactId>byte-buddy-agent</artifactId>
-    		<version>1.12.18</version>
+    		<version>1.14.7</version>
     		<type>jar</type>
     	</dependency>
     </dependencies>
@@ -193,25 +203,25 @@
     	<dependency>
     		<groupId>org.bouncycastle</groupId>
     		<artifactId>bcpg-jdk18on</artifactId>
-    		<version>1.73</version>
+    		<version>1.76</version>
     		<type>jar</type>
     	</dependency>
     	<dependency>
     		<groupId>org.bouncycastle</groupId>
     		<artifactId>bcprov-jdk18on</artifactId>
-    		<version>1.73</version>
+    		<version>1.76</version>
     		<type>jar</type>
     	</dependency>
     	<dependency>
     		<groupId>org.bouncycastle</groupId>
     		<artifactId>bcpkix-jdk18on</artifactId>
-    		<version>1.73</version>
+    		<version>1.76</version>
     		<type>jar</type>
     	</dependency>
     	<dependency>
     		<groupId>org.bouncycastle</groupId>
     		<artifactId>bcutil-jdk18on</artifactId>
-    		<version>1.73</version>
+    		<version>1.76</version>
     		<type>jar</type>
     	</dependency>
     </dependencies>
@@ -241,7 +251,7 @@
     	<dependency>
     		<groupId>commons-codec</groupId>
     		<artifactId>commons-codec</artifactId>
-    		<version>1.15</version>
+    		<version>1.16.0</version>
     		<type>jar</type>
     	</dependency>
     	<dependency>
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 980e7f9..cd61ee0 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,6 +1,6 @@
 target "jgit-4.24" with source configurePhase
 
-include "orbit/R20230531010532-2023-06.tpd"
+include "orbit/orbit-4.29.tpd"
 include "maven/dependencies.tpd"
 
 location "https://download.eclipse.org/releases/2022-06/" {
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 185b543..ed3cd4d 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,7 +1,7 @@
 <?xml version="1.0" encoding="UTF-8" standalone="no"?>
 <?pde?>
 <!-- generated with https://github.com/eclipse-cbi/targetplatform-dsl -->
-<target name="jgit-4.25" sequenceNumber="1686300730">
+<target name="jgit-4.25" sequenceNumber="1693839266">
   <locations>
     <location includeMode="slicer" includeAllPlatforms="false" includeSource="true" includeConfigurePhase="true" type="InstallableUnit">
       <unit id="com.jcraft.jsch" version="0.1.55.v20221112-0806"/>
@@ -12,21 +12,21 @@
       <unit id="net.i2p.crypto.eddsa.source" version="0.3.0.v20220506-1020"/>
       <unit id="org.apache.ant" version="1.10.12.v20211102-1452"/>
       <unit id="org.apache.ant.source" version="1.10.12.v20211102-1452"/>
-      <unit id="org.apache.httpcomponents.httpclient" version="4.5.14.v20230516-1249"/>
-      <unit id="org.apache.httpcomponents.httpclient.source" version="4.5.14.v20230516-1249"/>
-      <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.hamcrest.core" version="1.3.0.v20180420-1519"/>
-      <unit id="org.hamcrest.core.source" version="1.3.0.v20180420-1519"/>
-      <unit id="org.hamcrest.library" version="1.3.0.v20180524-2246"/>
-      <unit id="org.hamcrest.library.source" version="1.3.0.v20180524-2246"/>
-      <unit id="org.junit" version="4.13.2.v20211018-1956"/>
-      <unit id="org.junit.source" version="4.13.2.v20211018-1956"/>
-      <unit id="org.mockito.mockito-core" version="4.8.1.v20221103-2317"/>
-      <unit id="org.mockito.mockito-core.source" version="4.8.1.v20221103-2317"/>
-      <unit id="org.objenesis" version="3.3.0.v20221103-2317"/>
-      <unit id="org.objenesis.source" version="3.3.0.v20221103-2317"/>
-      <repository location="https://download.eclipse.org/tools/orbit/downloads/drops/R20230531010532/repository"/>
+      <unit id="org.apache.httpcomponents.httpclient" version="4.5.14"/>
+      <unit id="org.apache.httpcomponents.httpclient.source" version="4.5.14"/>
+      <unit id="org.apache.httpcomponents.httpcore" version="4.4.16"/>
+      <unit id="org.apache.httpcomponents.httpcore.source" version="4.4.16"/>
+      <unit id="org.hamcrest.core" version="1.3.0.v20230809-1000"/>
+      <unit id="org.hamcrest.core.source" version="1.3.0.v20230809-1000"/>
+      <unit id="org.hamcrest.library" version="1.3.0.v20230809-1000"/>
+      <unit id="org.hamcrest.library.source" version="1.3.0.v20230809-1000"/>
+      <unit id="org.junit" version="4.13.2.v20230809-1000"/>
+      <unit id="org.junit.source" version="4.13.2.v20230809-1000"/>
+      <unit id="org.objenesis" version="3.3.0"/>
+      <unit id="org.objenesis.source" version="3.3.0"/>
+      <unit id="org.osgi.service.cm" version="1.6.1.202109301733"/>
+      <unit id="org.osgi.service.cm.source" version="1.6.1.202109301733"/>
+      <repository location="https://download.eclipse.org/tools/orbit/simrel/orbit-aggregation/release/4.29.0"/>
     </location>
     <location includeMode="slicer" includeAllPlatforms="false" includeSource="true" includeConfigurePhase="true" type="InstallableUnit">
       <unit id="org.eclipse.osgi" version="0.0.0"/>
@@ -74,6 +74,16 @@
     	</dependency>
     </dependencies>
     </location>
+    <location includeDependencyDepth="none" includeDependencyScopes="compile" includeSource="true" missingManifest="error" type="Maven" label="mockito">
+    <dependencies>
+    	<dependency>
+    		<groupId>org.mockito</groupId>
+    		<artifactId>mockito-core</artifactId>
+    		<version>5.5.0</version>
+    		<type>jar</type>
+    	</dependency>
+    </dependencies>
+    </location>
     <location includeDependencyDepth="none" includeDependencyScopes="compile" includeSource="true" missingManifest="error" type="Maven" label="jna">
     <dependencies>
     	<dependency>
@@ -177,13 +187,13 @@
     	<dependency>
     		<groupId>net.bytebuddy</groupId>
     		<artifactId>byte-buddy</artifactId>
-    		<version>1.12.18</version>
+    		<version>1.14.7</version>
     		<type>jar</type>
     	</dependency>
     	<dependency>
     		<groupId>net.bytebuddy</groupId>
     		<artifactId>byte-buddy-agent</artifactId>
-    		<version>1.12.18</version>
+    		<version>1.14.7</version>
     		<type>jar</type>
     	</dependency>
     </dependencies>
@@ -193,25 +203,25 @@
     	<dependency>
     		<groupId>org.bouncycastle</groupId>
     		<artifactId>bcpg-jdk18on</artifactId>
-    		<version>1.73</version>
+    		<version>1.76</version>
     		<type>jar</type>
     	</dependency>
     	<dependency>
     		<groupId>org.bouncycastle</groupId>
     		<artifactId>bcprov-jdk18on</artifactId>
-    		<version>1.73</version>
+    		<version>1.76</version>
     		<type>jar</type>
     	</dependency>
     	<dependency>
     		<groupId>org.bouncycastle</groupId>
     		<artifactId>bcpkix-jdk18on</artifactId>
-    		<version>1.73</version>
+    		<version>1.76</version>
     		<type>jar</type>
     	</dependency>
     	<dependency>
     		<groupId>org.bouncycastle</groupId>
     		<artifactId>bcutil-jdk18on</artifactId>
-    		<version>1.73</version>
+    		<version>1.76</version>
     		<type>jar</type>
     	</dependency>
     </dependencies>
@@ -241,7 +251,7 @@
     	<dependency>
     		<groupId>commons-codec</groupId>
     		<artifactId>commons-codec</artifactId>
-    		<version>1.15</version>
+    		<version>1.16.0</version>
     		<type>jar</type>
     	</dependency>
     	<dependency>
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 c6f636e..c7f1591 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,6 +1,6 @@
 target "jgit-4.25" with source configurePhase
 
-include "orbit/R20230531010532-2023-06.tpd"
+include "orbit/orbit-4.29.tpd"
 include "maven/dependencies.tpd"
 
 location "https://download.eclipse.org/releases/2022-09/" {
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 811eb84..cfd906f 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,7 +1,7 @@
 <?xml version="1.0" encoding="UTF-8" standalone="no"?>
 <?pde?>
 <!-- generated with https://github.com/eclipse-cbi/targetplatform-dsl -->
-<target name="jgit-4.26" sequenceNumber="1686300730">
+<target name="jgit-4.26" sequenceNumber="1693839266">
   <locations>
     <location includeMode="slicer" includeAllPlatforms="false" includeSource="true" includeConfigurePhase="true" type="InstallableUnit">
       <unit id="com.jcraft.jsch" version="0.1.55.v20221112-0806"/>
@@ -12,21 +12,21 @@
       <unit id="net.i2p.crypto.eddsa.source" version="0.3.0.v20220506-1020"/>
       <unit id="org.apache.ant" version="1.10.12.v20211102-1452"/>
       <unit id="org.apache.ant.source" version="1.10.12.v20211102-1452"/>
-      <unit id="org.apache.httpcomponents.httpclient" version="4.5.14.v20230516-1249"/>
-      <unit id="org.apache.httpcomponents.httpclient.source" version="4.5.14.v20230516-1249"/>
-      <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.hamcrest.core" version="1.3.0.v20180420-1519"/>
-      <unit id="org.hamcrest.core.source" version="1.3.0.v20180420-1519"/>
-      <unit id="org.hamcrest.library" version="1.3.0.v20180524-2246"/>
-      <unit id="org.hamcrest.library.source" version="1.3.0.v20180524-2246"/>
-      <unit id="org.junit" version="4.13.2.v20211018-1956"/>
-      <unit id="org.junit.source" version="4.13.2.v20211018-1956"/>
-      <unit id="org.mockito.mockito-core" version="4.8.1.v20221103-2317"/>
-      <unit id="org.mockito.mockito-core.source" version="4.8.1.v20221103-2317"/>
-      <unit id="org.objenesis" version="3.3.0.v20221103-2317"/>
-      <unit id="org.objenesis.source" version="3.3.0.v20221103-2317"/>
-      <repository location="https://download.eclipse.org/tools/orbit/downloads/drops/R20230531010532/repository"/>
+      <unit id="org.apache.httpcomponents.httpclient" version="4.5.14"/>
+      <unit id="org.apache.httpcomponents.httpclient.source" version="4.5.14"/>
+      <unit id="org.apache.httpcomponents.httpcore" version="4.4.16"/>
+      <unit id="org.apache.httpcomponents.httpcore.source" version="4.4.16"/>
+      <unit id="org.hamcrest.core" version="1.3.0.v20230809-1000"/>
+      <unit id="org.hamcrest.core.source" version="1.3.0.v20230809-1000"/>
+      <unit id="org.hamcrest.library" version="1.3.0.v20230809-1000"/>
+      <unit id="org.hamcrest.library.source" version="1.3.0.v20230809-1000"/>
+      <unit id="org.junit" version="4.13.2.v20230809-1000"/>
+      <unit id="org.junit.source" version="4.13.2.v20230809-1000"/>
+      <unit id="org.objenesis" version="3.3.0"/>
+      <unit id="org.objenesis.source" version="3.3.0"/>
+      <unit id="org.osgi.service.cm" version="1.6.1.202109301733"/>
+      <unit id="org.osgi.service.cm.source" version="1.6.1.202109301733"/>
+      <repository location="https://download.eclipse.org/tools/orbit/simrel/orbit-aggregation/release/4.29.0"/>
     </location>
     <location includeMode="slicer" includeAllPlatforms="false" includeSource="true" includeConfigurePhase="true" type="InstallableUnit">
       <unit id="org.eclipse.osgi" version="0.0.0"/>
@@ -74,6 +74,16 @@
     	</dependency>
     </dependencies>
     </location>
+    <location includeDependencyDepth="none" includeDependencyScopes="compile" includeSource="true" missingManifest="error" type="Maven" label="mockito">
+    <dependencies>
+    	<dependency>
+    		<groupId>org.mockito</groupId>
+    		<artifactId>mockito-core</artifactId>
+    		<version>5.5.0</version>
+    		<type>jar</type>
+    	</dependency>
+    </dependencies>
+    </location>
     <location includeDependencyDepth="none" includeDependencyScopes="compile" includeSource="true" missingManifest="error" type="Maven" label="jna">
     <dependencies>
     	<dependency>
@@ -177,13 +187,13 @@
     	<dependency>
     		<groupId>net.bytebuddy</groupId>
     		<artifactId>byte-buddy</artifactId>
-    		<version>1.12.18</version>
+    		<version>1.14.7</version>
     		<type>jar</type>
     	</dependency>
     	<dependency>
     		<groupId>net.bytebuddy</groupId>
     		<artifactId>byte-buddy-agent</artifactId>
-    		<version>1.12.18</version>
+    		<version>1.14.7</version>
     		<type>jar</type>
     	</dependency>
     </dependencies>
@@ -193,25 +203,25 @@
     	<dependency>
     		<groupId>org.bouncycastle</groupId>
     		<artifactId>bcpg-jdk18on</artifactId>
-    		<version>1.73</version>
+    		<version>1.76</version>
     		<type>jar</type>
     	</dependency>
     	<dependency>
     		<groupId>org.bouncycastle</groupId>
     		<artifactId>bcprov-jdk18on</artifactId>
-    		<version>1.73</version>
+    		<version>1.76</version>
     		<type>jar</type>
     	</dependency>
     	<dependency>
     		<groupId>org.bouncycastle</groupId>
     		<artifactId>bcpkix-jdk18on</artifactId>
-    		<version>1.73</version>
+    		<version>1.76</version>
     		<type>jar</type>
     	</dependency>
     	<dependency>
     		<groupId>org.bouncycastle</groupId>
     		<artifactId>bcutil-jdk18on</artifactId>
-    		<version>1.73</version>
+    		<version>1.76</version>
     		<type>jar</type>
     	</dependency>
     </dependencies>
@@ -241,7 +251,7 @@
     	<dependency>
     		<groupId>commons-codec</groupId>
     		<artifactId>commons-codec</artifactId>
-    		<version>1.15</version>
+    		<version>1.16.0</version>
     		<type>jar</type>
     	</dependency>
     	<dependency>
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 1e2c19a..6d2fea1 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,6 +1,6 @@
 target "jgit-4.26" with source configurePhase
 
-include "orbit/R20230531010532-2023-06.tpd"
+include "orbit/orbit-4.29.tpd"
 include "maven/dependencies.tpd"
 
 location "https://download.eclipse.org/releases/2022-12/" {
diff --git a/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.27.target b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.27.target
index a1e02e7..0e63b9f 100644
--- a/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.27.target
+++ b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.27.target
@@ -1,7 +1,7 @@
 <?xml version="1.0" encoding="UTF-8" standalone="no"?>
 <?pde?>
 <!-- generated with https://github.com/eclipse-cbi/targetplatform-dsl -->
-<target name="jgit-4.27" sequenceNumber="1686300730">
+<target name="jgit-4.27" sequenceNumber="1693839266">
   <locations>
     <location includeMode="slicer" includeAllPlatforms="false" includeSource="true" includeConfigurePhase="true" type="InstallableUnit">
       <unit id="com.jcraft.jsch" version="0.1.55.v20221112-0806"/>
@@ -12,21 +12,21 @@
       <unit id="net.i2p.crypto.eddsa.source" version="0.3.0.v20220506-1020"/>
       <unit id="org.apache.ant" version="1.10.12.v20211102-1452"/>
       <unit id="org.apache.ant.source" version="1.10.12.v20211102-1452"/>
-      <unit id="org.apache.httpcomponents.httpclient" version="4.5.14.v20230516-1249"/>
-      <unit id="org.apache.httpcomponents.httpclient.source" version="4.5.14.v20230516-1249"/>
-      <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.hamcrest.core" version="1.3.0.v20180420-1519"/>
-      <unit id="org.hamcrest.core.source" version="1.3.0.v20180420-1519"/>
-      <unit id="org.hamcrest.library" version="1.3.0.v20180524-2246"/>
-      <unit id="org.hamcrest.library.source" version="1.3.0.v20180524-2246"/>
-      <unit id="org.junit" version="4.13.2.v20211018-1956"/>
-      <unit id="org.junit.source" version="4.13.2.v20211018-1956"/>
-      <unit id="org.mockito.mockito-core" version="4.8.1.v20221103-2317"/>
-      <unit id="org.mockito.mockito-core.source" version="4.8.1.v20221103-2317"/>
-      <unit id="org.objenesis" version="3.3.0.v20221103-2317"/>
-      <unit id="org.objenesis.source" version="3.3.0.v20221103-2317"/>
-      <repository location="https://download.eclipse.org/tools/orbit/downloads/drops/R20230531010532/repository"/>
+      <unit id="org.apache.httpcomponents.httpclient" version="4.5.14"/>
+      <unit id="org.apache.httpcomponents.httpclient.source" version="4.5.14"/>
+      <unit id="org.apache.httpcomponents.httpcore" version="4.4.16"/>
+      <unit id="org.apache.httpcomponents.httpcore.source" version="4.4.16"/>
+      <unit id="org.hamcrest.core" version="1.3.0.v20230809-1000"/>
+      <unit id="org.hamcrest.core.source" version="1.3.0.v20230809-1000"/>
+      <unit id="org.hamcrest.library" version="1.3.0.v20230809-1000"/>
+      <unit id="org.hamcrest.library.source" version="1.3.0.v20230809-1000"/>
+      <unit id="org.junit" version="4.13.2.v20230809-1000"/>
+      <unit id="org.junit.source" version="4.13.2.v20230809-1000"/>
+      <unit id="org.objenesis" version="3.3.0"/>
+      <unit id="org.objenesis.source" version="3.3.0"/>
+      <unit id="org.osgi.service.cm" version="1.6.1.202109301733"/>
+      <unit id="org.osgi.service.cm.source" version="1.6.1.202109301733"/>
+      <repository location="https://download.eclipse.org/tools/orbit/simrel/orbit-aggregation/release/4.29.0"/>
     </location>
     <location includeMode="slicer" includeAllPlatforms="false" includeSource="true" includeConfigurePhase="true" type="InstallableUnit">
       <unit id="org.eclipse.osgi" version="0.0.0"/>
@@ -74,6 +74,16 @@
     	</dependency>
     </dependencies>
     </location>
+    <location includeDependencyDepth="none" includeDependencyScopes="compile" includeSource="true" missingManifest="error" type="Maven" label="mockito">
+    <dependencies>
+    	<dependency>
+    		<groupId>org.mockito</groupId>
+    		<artifactId>mockito-core</artifactId>
+    		<version>5.5.0</version>
+    		<type>jar</type>
+    	</dependency>
+    </dependencies>
+    </location>
     <location includeDependencyDepth="none" includeDependencyScopes="compile" includeSource="true" missingManifest="error" type="Maven" label="jna">
     <dependencies>
     	<dependency>
@@ -177,13 +187,13 @@
     	<dependency>
     		<groupId>net.bytebuddy</groupId>
     		<artifactId>byte-buddy</artifactId>
-    		<version>1.12.18</version>
+    		<version>1.14.7</version>
     		<type>jar</type>
     	</dependency>
     	<dependency>
     		<groupId>net.bytebuddy</groupId>
     		<artifactId>byte-buddy-agent</artifactId>
-    		<version>1.12.18</version>
+    		<version>1.14.7</version>
     		<type>jar</type>
     	</dependency>
     </dependencies>
@@ -193,25 +203,25 @@
     	<dependency>
     		<groupId>org.bouncycastle</groupId>
     		<artifactId>bcpg-jdk18on</artifactId>
-    		<version>1.73</version>
+    		<version>1.76</version>
     		<type>jar</type>
     	</dependency>
     	<dependency>
     		<groupId>org.bouncycastle</groupId>
     		<artifactId>bcprov-jdk18on</artifactId>
-    		<version>1.73</version>
+    		<version>1.76</version>
     		<type>jar</type>
     	</dependency>
     	<dependency>
     		<groupId>org.bouncycastle</groupId>
     		<artifactId>bcpkix-jdk18on</artifactId>
-    		<version>1.73</version>
+    		<version>1.76</version>
     		<type>jar</type>
     	</dependency>
     	<dependency>
     		<groupId>org.bouncycastle</groupId>
     		<artifactId>bcutil-jdk18on</artifactId>
-    		<version>1.73</version>
+    		<version>1.76</version>
     		<type>jar</type>
     	</dependency>
     </dependencies>
@@ -241,7 +251,7 @@
     	<dependency>
     		<groupId>commons-codec</groupId>
     		<artifactId>commons-codec</artifactId>
-    		<version>1.15</version>
+    		<version>1.16.0</version>
     		<type>jar</type>
     	</dependency>
     	<dependency>
diff --git a/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.27.tpd b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.27.tpd
index bbb4baf..c359ccd 100644
--- a/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.27.tpd
+++ b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.27.tpd
@@ -1,6 +1,6 @@
 target "jgit-4.27" with source configurePhase
 
-include "orbit/R20230531010532-2023-06.tpd"
+include "orbit/orbit-4.29.tpd"
 include "maven/dependencies.tpd"
 
 location "https://download.eclipse.org/releases/2023-03/" {
diff --git a/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.28.target b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.28.target
index cd8f781..4d7d67f 100644
--- a/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.28.target
+++ b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.28.target
@@ -1,7 +1,7 @@
 <?xml version="1.0" encoding="UTF-8" standalone="no"?>
 <?pde?>
 <!-- generated with https://github.com/eclipse-cbi/targetplatform-dsl -->
-<target name="jgit-4.28" sequenceNumber="1686300646">
+<target name="jgit-4.28" sequenceNumber="1693839266">
   <locations>
     <location includeMode="slicer" includeAllPlatforms="false" includeSource="true" includeConfigurePhase="true" type="InstallableUnit">
       <unit id="com.jcraft.jsch" version="0.1.55.v20221112-0806"/>
@@ -12,25 +12,25 @@
       <unit id="net.i2p.crypto.eddsa.source" version="0.3.0.v20220506-1020"/>
       <unit id="org.apache.ant" version="1.10.12.v20211102-1452"/>
       <unit id="org.apache.ant.source" version="1.10.12.v20211102-1452"/>
-      <unit id="org.apache.httpcomponents.httpclient" version="4.5.14.v20230516-1249"/>
-      <unit id="org.apache.httpcomponents.httpclient.source" version="4.5.14.v20230516-1249"/>
-      <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.hamcrest.core" version="1.3.0.v20180420-1519"/>
-      <unit id="org.hamcrest.core.source" version="1.3.0.v20180420-1519"/>
-      <unit id="org.hamcrest.library" version="1.3.0.v20180524-2246"/>
-      <unit id="org.hamcrest.library.source" version="1.3.0.v20180524-2246"/>
-      <unit id="org.junit" version="4.13.2.v20211018-1956"/>
-      <unit id="org.junit.source" version="4.13.2.v20211018-1956"/>
-      <unit id="org.mockito.mockito-core" version="4.8.1.v20221103-2317"/>
-      <unit id="org.mockito.mockito-core.source" version="4.8.1.v20221103-2317"/>
-      <unit id="org.objenesis" version="3.3.0.v20221103-2317"/>
-      <unit id="org.objenesis.source" version="3.3.0.v20221103-2317"/>
-      <repository location="https://download.eclipse.org/tools/orbit/downloads/drops/R20230531010532/repository"/>
+      <unit id="org.apache.httpcomponents.httpclient" version="4.5.14"/>
+      <unit id="org.apache.httpcomponents.httpclient.source" version="4.5.14"/>
+      <unit id="org.apache.httpcomponents.httpcore" version="4.4.16"/>
+      <unit id="org.apache.httpcomponents.httpcore.source" version="4.4.16"/>
+      <unit id="org.hamcrest.core" version="1.3.0.v20230809-1000"/>
+      <unit id="org.hamcrest.core.source" version="1.3.0.v20230809-1000"/>
+      <unit id="org.hamcrest.library" version="1.3.0.v20230809-1000"/>
+      <unit id="org.hamcrest.library.source" version="1.3.0.v20230809-1000"/>
+      <unit id="org.junit" version="4.13.2.v20230809-1000"/>
+      <unit id="org.junit.source" version="4.13.2.v20230809-1000"/>
+      <unit id="org.objenesis" version="3.3.0"/>
+      <unit id="org.objenesis.source" version="3.3.0"/>
+      <unit id="org.osgi.service.cm" version="1.6.1.202109301733"/>
+      <unit id="org.osgi.service.cm.source" version="1.6.1.202109301733"/>
+      <repository location="https://download.eclipse.org/tools/orbit/simrel/orbit-aggregation/release/4.29.0"/>
     </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/2023-06"/>
+      <repository location="https://download.eclipse.org/releases/2023-06"/>
     </location>
     <location includeDependencyDepth="none" includeDependencyScopes="compile" includeSource="true" missingManifest="error" type="Maven" label="xz">
     <dependencies>
@@ -74,6 +74,16 @@
     	</dependency>
     </dependencies>
     </location>
+    <location includeDependencyDepth="none" includeDependencyScopes="compile" includeSource="true" missingManifest="error" type="Maven" label="mockito">
+    <dependencies>
+    	<dependency>
+    		<groupId>org.mockito</groupId>
+    		<artifactId>mockito-core</artifactId>
+    		<version>5.5.0</version>
+    		<type>jar</type>
+    	</dependency>
+    </dependencies>
+    </location>
     <location includeDependencyDepth="none" includeDependencyScopes="compile" includeSource="true" missingManifest="error" type="Maven" label="jna">
     <dependencies>
     	<dependency>
@@ -177,13 +187,13 @@
     	<dependency>
     		<groupId>net.bytebuddy</groupId>
     		<artifactId>byte-buddy</artifactId>
-    		<version>1.12.18</version>
+    		<version>1.14.7</version>
     		<type>jar</type>
     	</dependency>
     	<dependency>
     		<groupId>net.bytebuddy</groupId>
     		<artifactId>byte-buddy-agent</artifactId>
-    		<version>1.12.18</version>
+    		<version>1.14.7</version>
     		<type>jar</type>
     	</dependency>
     </dependencies>
@@ -193,25 +203,25 @@
     	<dependency>
     		<groupId>org.bouncycastle</groupId>
     		<artifactId>bcpg-jdk18on</artifactId>
-    		<version>1.73</version>
+    		<version>1.76</version>
     		<type>jar</type>
     	</dependency>
     	<dependency>
     		<groupId>org.bouncycastle</groupId>
     		<artifactId>bcprov-jdk18on</artifactId>
-    		<version>1.73</version>
+    		<version>1.76</version>
     		<type>jar</type>
     	</dependency>
     	<dependency>
     		<groupId>org.bouncycastle</groupId>
     		<artifactId>bcpkix-jdk18on</artifactId>
-    		<version>1.73</version>
+    		<version>1.76</version>
     		<type>jar</type>
     	</dependency>
     	<dependency>
     		<groupId>org.bouncycastle</groupId>
     		<artifactId>bcutil-jdk18on</artifactId>
-    		<version>1.73</version>
+    		<version>1.76</version>
     		<type>jar</type>
     	</dependency>
     </dependencies>
@@ -241,7 +251,7 @@
     	<dependency>
     		<groupId>commons-codec</groupId>
     		<artifactId>commons-codec</artifactId>
-    		<version>1.15</version>
+    		<version>1.16.0</version>
     		<type>jar</type>
     	</dependency>
     	<dependency>
diff --git a/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.28.tpd b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.28.tpd
index 46185ca..814b121 100644
--- a/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.28.tpd
+++ b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.28.tpd
@@ -1,8 +1,8 @@
 target "jgit-4.28" with source configurePhase
 
-include "orbit/R20230531010532-2023-06.tpd"
+include "orbit/orbit-4.29.tpd"
 include "maven/dependencies.tpd"
 
-location "https://download.eclipse.org/staging/2023-06" {
+location "https://download.eclipse.org/releases/2023-06" {
 	org.eclipse.osgi lazy
 }
diff --git a/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.29.target b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.29.target
new file mode 100644
index 0000000..1fcfdbc
--- /dev/null
+++ b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.29.target
@@ -0,0 +1,272 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<?pde?>
+<!-- generated with https://github.com/eclipse-cbi/targetplatform-dsl -->
+<target name="jgit-4.29" sequenceNumber="1693839266">
+  <locations>
+    <location includeMode="slicer" includeAllPlatforms="false" includeSource="true" includeConfigurePhase="true" type="InstallableUnit">
+      <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"/>
+      <unit id="com.jcraft.jzlib.source" version="1.1.3.v20220502-1820"/>
+      <unit id="net.i2p.crypto.eddsa" version="0.3.0.v20220506-1020"/>
+      <unit id="net.i2p.crypto.eddsa.source" version="0.3.0.v20220506-1020"/>
+      <unit id="org.apache.ant" version="1.10.12.v20211102-1452"/>
+      <unit id="org.apache.ant.source" version="1.10.12.v20211102-1452"/>
+      <unit id="org.apache.httpcomponents.httpclient" version="4.5.14"/>
+      <unit id="org.apache.httpcomponents.httpclient.source" version="4.5.14"/>
+      <unit id="org.apache.httpcomponents.httpcore" version="4.4.16"/>
+      <unit id="org.apache.httpcomponents.httpcore.source" version="4.4.16"/>
+      <unit id="org.hamcrest.core" version="1.3.0.v20230809-1000"/>
+      <unit id="org.hamcrest.core.source" version="1.3.0.v20230809-1000"/>
+      <unit id="org.hamcrest.library" version="1.3.0.v20230809-1000"/>
+      <unit id="org.hamcrest.library.source" version="1.3.0.v20230809-1000"/>
+      <unit id="org.junit" version="4.13.2.v20230809-1000"/>
+      <unit id="org.junit.source" version="4.13.2.v20230809-1000"/>
+      <unit id="org.objenesis" version="3.3.0"/>
+      <unit id="org.objenesis.source" version="3.3.0"/>
+      <unit id="org.osgi.service.cm" version="1.6.1.202109301733"/>
+      <unit id="org.osgi.service.cm.source" version="1.6.1.202109301733"/>
+      <repository location="https://download.eclipse.org/tools/orbit/simrel/orbit-aggregation/release/4.29.0"/>
+    </location>
+    <location includeMode="slicer" includeAllPlatforms="false" includeSource="true" includeConfigurePhase="true" type="InstallableUnit">
+      <unit id="org.eclipse.osgi" version="0.0.0"/>
+      <repository location="https://download.eclipse.org/releases/2023-09"/>
+    </location>
+    <location includeDependencyDepth="none" includeDependencyScopes="compile" includeSource="true" missingManifest="error" type="Maven" label="xz">
+    <dependencies>
+    	<dependency>
+    		<groupId>org.tukaani</groupId>
+    		<artifactId>xz</artifactId>
+    		<version>1.9</version>
+    		<type>jar</type>
+    	</dependency>
+    </dependencies>
+    </location>
+    <location includeDependencyDepth="none" includeDependencyScopes="compile" includeSource="true" missingManifest="error" type="Maven" label="slf4j">
+    <dependencies>
+    	<dependency>
+    		<groupId>org.slf4j</groupId>
+    		<artifactId>slf4j-api</artifactId>
+    		<version>1.7.36</version>
+    		<type>jar</type>
+    	</dependency>
+    	<dependency>
+    		<groupId>org.slf4j</groupId>
+    		<artifactId>slf4j-simple</artifactId>
+    		<version>1.7.36</version>
+    		<type>jar</type>
+    	</dependency>
+    </dependencies>
+    </location>
+    <location includeDependencyDepth="none" includeDependencyScopes="compile" includeSource="true" missingManifest="error" type="Maven" label="sshd">
+    <dependencies>
+    	<dependency>
+    		<groupId>org.apache.sshd</groupId>
+    		<artifactId>sshd-osgi</artifactId>
+    		<version>2.10.0</version>
+    		<type>jar</type>
+    	</dependency>
+    	<dependency>
+    		<groupId>org.apache.sshd</groupId>
+    		<artifactId>sshd-sftp</artifactId>
+    		<version>2.10.0</version>
+    		<type>jar</type>
+    	</dependency>
+    </dependencies>
+    </location>
+    <location includeDependencyDepth="none" includeDependencyScopes="compile" includeSource="true" missingManifest="error" type="Maven" label="mockito">
+    <dependencies>
+    	<dependency>
+    		<groupId>org.mockito</groupId>
+    		<artifactId>mockito-core</artifactId>
+    		<version>5.5.0</version>
+    		<type>jar</type>
+    	</dependency>
+    </dependencies>
+    </location>
+    <location includeDependencyDepth="none" includeDependencyScopes="compile" includeSource="true" missingManifest="error" type="Maven" label="jna">
+    <dependencies>
+    	<dependency>
+    		<groupId>net.java.dev.jna</groupId>
+    		<artifactId>jna</artifactId>
+    		<version>5.13.0</version>
+    		<type>jar</type>
+    	</dependency>
+    	<dependency>
+    		<groupId>net.java.dev.jna</groupId>
+    		<artifactId>jna-platform</artifactId>
+    		<version>5.13.0</version>
+    		<type>jar</type>
+    	</dependency>
+    </dependencies>
+    </location>
+    <location includeDependencyDepth="none" includeDependencyScopes="compile" includeSource="true" missingManifest="error" type="Maven" label="jetty">
+    <dependencies>
+    	<dependency>
+    		<groupId>org.eclipse.jetty</groupId>
+    		<artifactId>jetty-http</artifactId>
+    		<version>10.0.15</version>
+    		<type>jar</type>
+    	</dependency>
+    	<dependency>
+    		<groupId>org.eclipse.jetty</groupId>
+    		<artifactId>jetty-io</artifactId>
+    		<version>10.0.15</version>
+    		<type>jar</type>
+    	</dependency>
+    	<dependency>
+    		<groupId>org.eclipse.jetty</groupId>
+    		<artifactId>jetty-security</artifactId>
+    		<version>10.0.15</version>
+    		<type>jar</type>
+    	</dependency>
+    	<dependency>
+    		<groupId>org.eclipse.jetty</groupId>
+    		<artifactId>jetty-server</artifactId>
+    		<version>10.0.15</version>
+    		<type>jar</type>
+    	</dependency>
+    	<dependency>
+    		<groupId>org.eclipse.jetty</groupId>
+    		<artifactId>jetty-servlet</artifactId>
+    		<version>10.0.15</version>
+    		<type>jar</type>
+    	</dependency>
+    	<dependency>
+    		<groupId>org.eclipse.jetty</groupId>
+    		<artifactId>jetty-util</artifactId>
+    		<version>10.0.15</version>
+    		<type>jar</type>
+    	</dependency>
+    	<dependency>
+    		<groupId>org.eclipse.jetty</groupId>
+    		<artifactId>jetty-util-ajax</artifactId>
+    		<version>10.0.15</version>
+    		<type>jar</type>
+    	</dependency>
+    	<dependency>
+    		<groupId>jakarta.servlet</groupId>
+    		<artifactId>jakarta.servlet-api</artifactId>
+    		<version>4.0.4</version>
+    		<type>jar</type>
+    	</dependency>
+    </dependencies>
+    </location>
+    <location includeDependencyDepth="none" includeDependencyScopes="compile" includeSource="true" missingManifest="error" type="Maven" label="javaewah">
+    <dependencies>
+    	<dependency>
+    		<groupId>com.googlecode.javaewah</groupId>
+    		<artifactId>JavaEWAH</artifactId>
+    		<version>1.2.3</version>
+    		<type>jar</type>
+    	</dependency>
+    </dependencies>
+    </location>
+    <location includeDependencyDepth="none" includeDependencyScopes="compile" includeSource="true" missingManifest="error" type="Maven" label="hamcrest">
+    <dependencies>
+    	<dependency>
+    		<groupId>org.hamcrest</groupId>
+    		<artifactId>hamcrest</artifactId>
+    		<version>2.2</version>
+    		<type>jar</type>
+    	</dependency>
+    </dependencies>
+    </location>
+    <location includeDependencyDepth="none" includeDependencyScopes="compile" includeSource="true" missingManifest="error" type="Maven" label="gson">
+    <dependencies>
+    	<dependency>
+    		<groupId>com.google.code.gson</groupId>
+    		<artifactId>gson</artifactId>
+    		<version>2.10.1</version>
+    		<type>jar</type>
+    	</dependency>
+    </dependencies>
+    </location>
+    <location includeDependencyDepth="none" includeDependencyScopes="compile" includeSource="true" missingManifest="error" type="Maven" label="bytebuddy">
+    <dependencies>
+    	<dependency>
+    		<groupId>net.bytebuddy</groupId>
+    		<artifactId>byte-buddy</artifactId>
+    		<version>1.14.7</version>
+    		<type>jar</type>
+    	</dependency>
+    	<dependency>
+    		<groupId>net.bytebuddy</groupId>
+    		<artifactId>byte-buddy-agent</artifactId>
+    		<version>1.14.7</version>
+    		<type>jar</type>
+    	</dependency>
+    </dependencies>
+    </location>
+    <location includeDependencyDepth="none" includeDependencyScopes="compile" includeSource="true" missingManifest="error" type="Maven" label="bouncycastle">
+    <dependencies>
+    	<dependency>
+    		<groupId>org.bouncycastle</groupId>
+    		<artifactId>bcpg-jdk18on</artifactId>
+    		<version>1.76</version>
+    		<type>jar</type>
+    	</dependency>
+    	<dependency>
+    		<groupId>org.bouncycastle</groupId>
+    		<artifactId>bcprov-jdk18on</artifactId>
+    		<version>1.76</version>
+    		<type>jar</type>
+    	</dependency>
+    	<dependency>
+    		<groupId>org.bouncycastle</groupId>
+    		<artifactId>bcpkix-jdk18on</artifactId>
+    		<version>1.76</version>
+    		<type>jar</type>
+    	</dependency>
+    	<dependency>
+    		<groupId>org.bouncycastle</groupId>
+    		<artifactId>bcutil-jdk18on</artifactId>
+    		<version>1.76</version>
+    		<type>jar</type>
+    	</dependency>
+    </dependencies>
+    </location>
+    <location includeDependencyDepth="none" includeDependencyScopes="compile" includeSource="true" missingManifest="error" type="Maven" label="assertj">
+    <dependencies>
+    	<dependency>
+    		<groupId>org.assertj</groupId>
+    		<artifactId>assertj-core</artifactId>
+    		<version>3.24.2</version>
+    		<type>jar</type>
+    	</dependency>
+    </dependencies>
+    </location>
+    <location includeDependencyDepth="none" includeDependencyScopes="compile" includeSource="true" missingManifest="error" type="Maven" label="args4j">
+    <dependencies>
+    	<dependency>
+    		<groupId>args4j</groupId>
+    		<artifactId>args4j</artifactId>
+    		<version>2.33</version>
+    		<type>jar</type>
+    	</dependency>
+    </dependencies>
+    </location>
+    <location includeDependencyDepth="none" includeDependencyScopes="compile" includeSource="true" missingManifest="error" type="Maven" label="apache">
+    <dependencies>
+    	<dependency>
+    		<groupId>commons-codec</groupId>
+    		<artifactId>commons-codec</artifactId>
+    		<version>1.16.0</version>
+    		<type>jar</type>
+    	</dependency>
+    	<dependency>
+    		<groupId>org.apache.commons</groupId>
+    		<artifactId>commons-compress</artifactId>
+    		<version>1.23.0</version>
+    		<type>jar</type>
+    	</dependency>
+    	<dependency>
+    		<groupId>commons-logging</groupId>
+    		<artifactId>commons-logging</artifactId>
+    		<version>1.2</version>
+    		<type>jar</type>
+    	</dependency>
+    </dependencies>
+    </location>
+  </locations>
+</target>
diff --git a/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.29.tpd b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.29.tpd
new file mode 100644
index 0000000..3318e4f
--- /dev/null
+++ b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.29.tpd
@@ -0,0 +1,8 @@
+target "jgit-4.29" with source configurePhase
+
+include "orbit/orbit-4.29.tpd"
+include "maven/dependencies.tpd"
+
+location "https://download.eclipse.org/releases/2023-09" {
+	org.eclipse.osgi lazy
+}
diff --git a/org.eclipse.jgit.packaging/org.eclipse.jgit.target/maven/dependencies.tpd b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/maven/dependencies.tpd
index cbb7d1e..ec4adf9 100644
--- a/org.eclipse.jgit.packaging/org.eclipse.jgit.target/maven/dependencies.tpd
+++ b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/maven/dependencies.tpd
@@ -10,7 +10,7 @@
 	dependency {
 		groupId = "commons-codec"
 		artifactId = "commons-codec"
-		version = "1.15"
+		version = "1.16.0"
 	}
 	dependency {
 		groupId = "org.apache.commons"
@@ -59,22 +59,22 @@
 	dependency {
 		groupId = "org.bouncycastle"
 		artifactId = "bcpg-jdk18on"
-		version = "1.73"
+		version = "1.76"
 	}
 	dependency {
 		groupId = "org.bouncycastle"
 		artifactId = "bcprov-jdk18on"
-		version = "1.73"
+		version = "1.76"
 	}
 	dependency {
 		groupId = "org.bouncycastle"
 		artifactId = "bcpkix-jdk18on"
-		version = "1.73"
+		version = "1.76"
 	}
 	dependency {
 		groupId = "org.bouncycastle"
 		artifactId = "bcutil-jdk18on"
-		version = "1.73"
+		version = "1.76"
 	}
 }
 
@@ -87,12 +87,12 @@
 	dependency {
 		groupId = "net.bytebuddy"
 		artifactId = "byte-buddy"
-		version = "1.12.18"
+		version = "1.14.7"
 	}
 	dependency {
 		groupId = "net.bytebuddy"
 		artifactId = "byte-buddy-agent"
-		version = "1.12.18"
+		version = "1.14.7"
 	}
 }
 
@@ -201,6 +201,19 @@
 	}
 }
 
+maven mockito
+	scope = compile
+	dependencyDepth = none
+	missingManifest = error
+	includeSources
+{
+	dependency {
+		groupId = "org.mockito"
+		artifactId = "mockito-core"
+		version = "5.5.0"
+	}
+}
+
 maven sshd
 	scope = compile
 	dependencyDepth = none
diff --git a/org.eclipse.jgit.packaging/org.eclipse.jgit.target/orbit/R20230531010532-2023-06.tpd b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/orbit/R20230531010532-2023-06.tpd
index 089981c..46055d3 100644
--- a/org.eclipse.jgit.packaging/org.eclipse.jgit.target/orbit/R20230531010532-2023-06.tpd
+++ b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/orbit/R20230531010532-2023-06.tpd
@@ -20,8 +20,6 @@
 	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.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]
 }
diff --git a/org.eclipse.jgit.packaging/org.eclipse.jgit.target/orbit/orbit-4.29.tpd b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/orbit/orbit-4.29.tpd
new file mode 100644
index 0000000..70a17a1
--- /dev/null
+++ b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/orbit/orbit-4.29.tpd
@@ -0,0 +1,27 @@
+target "orbit-4.29" with source configurePhase
+// see https://download.eclipse.org/tools/orbit/downloads/
+
+location "https://download.eclipse.org/tools/orbit/simrel/orbit-aggregation/release/4.29.0" {
+	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]
+	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.httpcomponents.httpclient [4.5.14,4.5.14]
+	org.apache.httpcomponents.httpclient.source [4.5.14,4.5.14]
+	org.apache.httpcomponents.httpcore [4.4.16,4.4.16]
+	org.apache.httpcomponents.httpcore.source [4.4.16,4.4.16]
+	org.hamcrest.core [1.3.0.v20230809-1000,1.3.0.v20230809-1000]
+	org.hamcrest.core.source [1.3.0.v20230809-1000,1.3.0.v20230809-1000]
+	org.hamcrest.library [1.3.0.v20230809-1000,1.3.0.v20230809-1000]
+	org.hamcrest.library.source [1.3.0.v20230809-1000,1.3.0.v20230809-1000]
+	org.junit [4.13.2.v20230809-1000,4.13.2.v20230809-1000]
+	org.junit.source [4.13.2.v20230809-1000,4.13.2.v20230809-1000]
+	org.objenesis [3.3,3.3]
+	org.objenesis.source [3.3,3.3]
+	org.osgi.service.cm [1.6.1.202109301733,1.6.1.202109301733]
+	org.osgi.service.cm.source [1.6.1.202109301733,1.6.1.202109301733]
+}
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 86d2cbb..666bca4 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.6.2-SNAPSHOT</version>
+    <version>6.7.1-SNAPSHOT</version>
   </parent>
 
   <artifactId>org.eclipse.jgit.target</artifactId>
diff --git a/org.eclipse.jgit.packaging/pom.xml b/org.eclipse.jgit.packaging/pom.xml
index 1e4d052..63c2e4c 100644
--- a/org.eclipse.jgit.packaging/pom.xml
+++ b/org.eclipse.jgit.packaging/pom.xml
@@ -16,14 +16,14 @@
 
   <groupId>org.eclipse.jgit</groupId>
   <artifactId>jgit.tycho.parent</artifactId>
-  <version>6.6.2-SNAPSHOT</version>
+  <version>6.7.1-SNAPSHOT</version>
   <packaging>pom</packaging>
 
   <name>JGit Tycho Parent</name>
 
   <properties>
     <java.version>11</java.version>
-    <tycho-version>4.0.1</tycho-version>
+    <tycho-version>4.0.2</tycho-version>
     <target-platform>jgit-4.17</target-platform>
   </properties>
 
@@ -32,14 +32,6 @@
       <id>repo.eclipse.org.cbi-releases</id>
       <url>https://repo.eclipse.org/content/repositories/cbi-releases/</url>
     </pluginRepository>
-    <pluginRepository>
-      <id>repo.eclipse.org.cbi-snapshots</id>
-      <url>https://repo.eclipse.org/content/repositories/cbi-snapshots/</url>
-    </pluginRepository>
-    <pluginRepository>
-      <id>tycho-snapshots</id>
-      <url>https://repo.eclipse.org/content/repositories/tycho-snapshots/</url>
-    </pluginRepository>
   </pluginRepositories>
 
   <modules>
@@ -298,7 +290,7 @@
         <plugin>
           <groupId>org.eclipse.cbi.maven.plugins</groupId>
           <artifactId>eclipse-jarsigner-plugin</artifactId>
-          <version>1.3.5</version>
+          <version>1.4.2</version>
         </plugin>
         <plugin>
           <groupId>org.codehaus.mojo</groupId>
diff --git a/org.eclipse.jgit.pgm.test/META-INF/MANIFEST.MF b/org.eclipse.jgit.pgm.test/META-INF/MANIFEST.MF
index 598aa02..dddf560 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.6.2.qualifier
+Bundle-Version: 6.7.1.qualifier
 Bundle-Vendor: %Bundle-Vendor
 Bundle-Localization: plugin
 Bundle-ActivationPolicy: lazy
 Bundle-RequiredExecutionEnvironment: JavaSE-11
-Import-Package: org.eclipse.jgit.api;version="[6.6.2,6.7.0)",
- org.eclipse.jgit.api.errors;version="[6.6.2,6.7.0)",
- org.eclipse.jgit.diff;version="[6.6.2,6.7.0)",
- org.eclipse.jgit.dircache;version="[6.6.2,6.7.0)",
- org.eclipse.jgit.internal.diffmergetool;version="6.6.2",
- org.eclipse.jgit.internal.storage.file;version="6.6.2",
- org.eclipse.jgit.junit;version="[6.6.2,6.7.0)",
- org.eclipse.jgit.lib;version="[6.6.2,6.7.0)",
- org.eclipse.jgit.lib.internal;version="[6.6.2,6.7.0)",
- org.eclipse.jgit.merge;version="[6.6.2,6.7.0)",
- org.eclipse.jgit.pgm;version="[6.6.2,6.7.0)",
- org.eclipse.jgit.pgm.internal;version="[6.6.2,6.7.0)",
- org.eclipse.jgit.pgm.opt;version="[6.6.2,6.7.0)",
- org.eclipse.jgit.revwalk;version="[6.6.2,6.7.0)",
- org.eclipse.jgit.storage.file;version="[6.6.2,6.7.0)",
- org.eclipse.jgit.transport;version="[6.6.2,6.7.0)",
- org.eclipse.jgit.treewalk;version="[6.6.2,6.7.0)",
- org.eclipse.jgit.util;version="[6.6.2,6.7.0)",
- org.eclipse.jgit.util.io;version="[6.6.2,6.7.0)",
+Import-Package: org.eclipse.jgit.api;version="[6.7.1,6.8.0)",
+ org.eclipse.jgit.api.errors;version="[6.7.1,6.8.0)",
+ org.eclipse.jgit.diff;version="[6.7.1,6.8.0)",
+ org.eclipse.jgit.dircache;version="[6.7.1,6.8.0)",
+ org.eclipse.jgit.internal.diffmergetool;version="6.7.1",
+ org.eclipse.jgit.internal.storage.file;version="6.7.1",
+ org.eclipse.jgit.junit;version="[6.7.1,6.8.0)",
+ org.eclipse.jgit.lib;version="[6.7.1,6.8.0)",
+ org.eclipse.jgit.lib.internal;version="[6.7.1,6.8.0)",
+ org.eclipse.jgit.merge;version="[6.7.1,6.8.0)",
+ org.eclipse.jgit.pgm;version="[6.7.1,6.8.0)",
+ org.eclipse.jgit.pgm.internal;version="[6.7.1,6.8.0)",
+ org.eclipse.jgit.pgm.opt;version="[6.7.1,6.8.0)",
+ org.eclipse.jgit.revwalk;version="[6.7.1,6.8.0)",
+ org.eclipse.jgit.storage.file;version="[6.7.1,6.8.0)",
+ org.eclipse.jgit.transport;version="[6.7.1,6.8.0)",
+ org.eclipse.jgit.treewalk;version="[6.7.1,6.8.0)",
+ org.eclipse.jgit.util;version="[6.7.1,6.8.0)",
+ org.eclipse.jgit.util.io;version="[6.7.1,6.8.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 84887fa..b19a7be 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.6.2-SNAPSHOT</version>
+    <version>6.7.1-SNAPSHOT</version>
   </parent>
 
   <artifactId>org.eclipse.jgit.pgm.test</artifactId>
diff --git a/org.eclipse.jgit.pgm/.settings/org.eclipse.jdt.core.prefs b/org.eclipse.jgit.pgm/.settings/org.eclipse.jdt.core.prefs
index 2abe952..b27b6c3 100644
--- a/org.eclipse.jgit.pgm/.settings/org.eclipse.jdt.core.prefs
+++ b/org.eclipse.jgit.pgm/.settings/org.eclipse.jdt.core.prefs
@@ -52,7 +52,7 @@
 org.eclipse.jdt.core.compiler.problem.missingJavadocComments=error
 org.eclipse.jdt.core.compiler.problem.missingJavadocCommentsOverriding=disabled
 org.eclipse.jdt.core.compiler.problem.missingJavadocCommentsVisibility=protected
-org.eclipse.jdt.core.compiler.problem.missingJavadocTagDescription=return_tag
+org.eclipse.jdt.core.compiler.problem.missingJavadocTagDescription=all_standard_tags
 org.eclipse.jdt.core.compiler.problem.missingJavadocTags=error
 org.eclipse.jdt.core.compiler.problem.missingJavadocTagsMethodTypeParameters=disabled
 org.eclipse.jdt.core.compiler.problem.missingJavadocTagsOverriding=disabled
diff --git a/org.eclipse.jgit.pgm/META-INF/MANIFEST.MF b/org.eclipse.jgit.pgm/META-INF/MANIFEST.MF
index 250acbb..235c2fc 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.6.2.qualifier
+Bundle-Version: 6.7.1.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.6.2,6.7.0)",
- org.eclipse.jgit.api.errors;version="[6.6.2,6.7.0)",
- org.eclipse.jgit.archive;version="[6.6.2,6.7.0)",
- org.eclipse.jgit.awtui;version="[6.6.2,6.7.0)",
- org.eclipse.jgit.blame;version="[6.6.2,6.7.0)",
- org.eclipse.jgit.diff;version="[6.6.2,6.7.0)",
- org.eclipse.jgit.dircache;version="[6.6.2,6.7.0)",
- org.eclipse.jgit.errors;version="[6.6.2,6.7.0)",
- org.eclipse.jgit.gitrepo;version="[6.6.2,6.7.0)",
- org.eclipse.jgit.internal.storage.file;version="[6.6.2,6.7.0)",
- org.eclipse.jgit.internal.diffmergetool;version="[6.6.2,6.7.0)",
- org.eclipse.jgit.internal.storage.io;version="[6.6.2,6.7.0)",
- org.eclipse.jgit.internal.storage.pack;version="[6.6.2,6.7.0)",
- org.eclipse.jgit.internal.storage.reftable;version="[6.6.2,6.7.0)",
- org.eclipse.jgit.lfs;version="[6.6.2,6.7.0)",
- org.eclipse.jgit.lfs.server;version="[6.6.2,6.7.0)",
- org.eclipse.jgit.lfs.server.fs;version="[6.6.2,6.7.0)",
- org.eclipse.jgit.lfs.server.s3;version="[6.6.2,6.7.0)",
- org.eclipse.jgit.lib;version="[6.6.2,6.7.0)",
- org.eclipse.jgit.merge;version="[6.6.2,6.7.0)",
- org.eclipse.jgit.lib.internal;version="[6.6.2,6.7.0)",
- org.eclipse.jgit.nls;version="[6.6.2,6.7.0)",
- org.eclipse.jgit.notes;version="[6.6.2,6.7.0)",
- org.eclipse.jgit.revplot;version="[6.6.2,6.7.0)",
- org.eclipse.jgit.revwalk;version="[6.6.2,6.7.0)",
- org.eclipse.jgit.revwalk.filter;version="[6.6.2,6.7.0)",
- org.eclipse.jgit.storage.file;version="[6.6.2,6.7.0)",
- org.eclipse.jgit.storage.pack;version="[6.6.2,6.7.0)",
- org.eclipse.jgit.transport;version="[6.6.2,6.7.0)",
- org.eclipse.jgit.transport.http.apache;version="[6.6.2,6.7.0)",
- org.eclipse.jgit.transport.resolver;version="[6.6.2,6.7.0)",
- org.eclipse.jgit.transport.ssh.jsch;version="[6.6.2,6.7.0)",
- org.eclipse.jgit.transport.sshd;version="[6.6.2,6.7.0)",
- org.eclipse.jgit.treewalk;version="[6.6.2,6.7.0)",
- org.eclipse.jgit.treewalk.filter;version="[6.6.2,6.7.0)",
- org.eclipse.jgit.util;version="[6.6.2,6.7.0)",
- org.eclipse.jgit.util.io;version="[6.6.2,6.7.0)",
+ org.eclipse.jgit.api;version="[6.7.1,6.8.0)",
+ org.eclipse.jgit.api.errors;version="[6.7.1,6.8.0)",
+ org.eclipse.jgit.archive;version="[6.7.1,6.8.0)",
+ org.eclipse.jgit.awtui;version="[6.7.1,6.8.0)",
+ org.eclipse.jgit.blame;version="[6.7.1,6.8.0)",
+ org.eclipse.jgit.diff;version="[6.7.1,6.8.0)",
+ org.eclipse.jgit.dircache;version="[6.7.1,6.8.0)",
+ org.eclipse.jgit.errors;version="[6.7.1,6.8.0)",
+ org.eclipse.jgit.gitrepo;version="[6.7.1,6.8.0)",
+ org.eclipse.jgit.internal.storage.file;version="[6.7.1,6.8.0)",
+ org.eclipse.jgit.internal.diffmergetool;version="[6.7.1,6.8.0)",
+ org.eclipse.jgit.internal.storage.io;version="[6.7.1,6.8.0)",
+ org.eclipse.jgit.internal.storage.pack;version="[6.7.1,6.8.0)",
+ org.eclipse.jgit.internal.storage.reftable;version="[6.7.1,6.8.0)",
+ org.eclipse.jgit.lfs;version="[6.7.1,6.8.0)",
+ org.eclipse.jgit.lfs.server;version="[6.7.1,6.8.0)",
+ org.eclipse.jgit.lfs.server.fs;version="[6.7.1,6.8.0)",
+ org.eclipse.jgit.lfs.server.s3;version="[6.7.1,6.8.0)",
+ org.eclipse.jgit.lib;version="[6.7.1,6.8.0)",
+ org.eclipse.jgit.merge;version="[6.7.1,6.8.0)",
+ org.eclipse.jgit.lib.internal;version="[6.7.1,6.8.0)",
+ org.eclipse.jgit.nls;version="[6.7.1,6.8.0)",
+ org.eclipse.jgit.notes;version="[6.7.1,6.8.0)",
+ org.eclipse.jgit.revplot;version="[6.7.1,6.8.0)",
+ org.eclipse.jgit.revwalk;version="[6.7.1,6.8.0)",
+ org.eclipse.jgit.revwalk.filter;version="[6.7.1,6.8.0)",
+ org.eclipse.jgit.storage.file;version="[6.7.1,6.8.0)",
+ org.eclipse.jgit.storage.pack;version="[6.7.1,6.8.0)",
+ org.eclipse.jgit.transport;version="[6.7.1,6.8.0)",
+ org.eclipse.jgit.transport.http.apache;version="[6.7.1,6.8.0)",
+ org.eclipse.jgit.transport.resolver;version="[6.7.1,6.8.0)",
+ org.eclipse.jgit.transport.ssh.jsch;version="[6.7.1,6.8.0)",
+ org.eclipse.jgit.transport.sshd;version="[6.7.1,6.8.0)",
+ org.eclipse.jgit.treewalk;version="[6.7.1,6.8.0)",
+ org.eclipse.jgit.treewalk.filter;version="[6.7.1,6.8.0)",
+ org.eclipse.jgit.util;version="[6.7.1,6.8.0)",
+ org.eclipse.jgit.util.io;version="[6.7.1,6.8.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.6.2";
+Export-Package: org.eclipse.jgit.console;version="6.7.1";
  uses:="org.eclipse.jgit.transport,
   org.eclipse.jgit.util",
- org.eclipse.jgit.pgm;version="6.6.2";
+ org.eclipse.jgit.pgm;version="6.7.1";
   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.6.2";
+ org.eclipse.jgit.pgm.debug;version="6.7.1";
   uses:="org.eclipse.jgit.util.io,
    org.eclipse.jgit.pgm,
    org.eclipse.jetty.servlet",
- org.eclipse.jgit.pgm.internal;version="6.6.2";
+ org.eclipse.jgit.pgm.internal;version="6.7.1";
   x-friends:="org.eclipse.jgit.pgm.test,
    org.eclipse.jgit.test",
- org.eclipse.jgit.pgm.opt;version="6.6.2";
+ org.eclipse.jgit.pgm.opt;version="6.7.1";
   uses:="org.kohsuke.args4j,
    org.eclipse.jgit.lib,
    org.eclipse.jgit.revwalk,
diff --git a/org.eclipse.jgit.pgm/META-INF/SOURCE-MANIFEST.MF b/org.eclipse.jgit.pgm/META-INF/SOURCE-MANIFEST.MF
index 3a3b108..0755ae5 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.6.2.qualifier
-Eclipse-SourceBundle: org.eclipse.jgit.pgm;version="6.6.2.qualifier";roots="."
+Bundle-Version: 6.7.1.qualifier
+Eclipse-SourceBundle: org.eclipse.jgit.pgm;version="6.7.1.qualifier";roots="."
diff --git a/org.eclipse.jgit.pgm/META-INF/services/org.eclipse.jgit.pgm.TextBuiltin b/org.eclipse.jgit.pgm/META-INF/services/org.eclipse.jgit.pgm.TextBuiltin
index ea1d1e3..08d3727 100644
--- a/org.eclipse.jgit.pgm/META-INF/services/org.eclipse.jgit.pgm.TextBuiltin
+++ b/org.eclipse.jgit.pgm/META-INF/services/org.eclipse.jgit.pgm.TextBuiltin
@@ -46,6 +46,7 @@
 org.eclipse.jgit.pgm.debug.DiffAlgorithms
 org.eclipse.jgit.pgm.debug.LfsStore
 org.eclipse.jgit.pgm.debug.MakeCacheTree
+org.eclipse.jgit.pgm.debug.ReadChangedPathFilter
 org.eclipse.jgit.pgm.debug.ReadDirCache
 org.eclipse.jgit.pgm.debug.ReadReftable
 org.eclipse.jgit.pgm.debug.RebuildCommitGraph
diff --git a/org.eclipse.jgit.pgm/pom.xml b/org.eclipse.jgit.pgm/pom.xml
index 06975ff..c1916ab 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.6.2-SNAPSHOT</version>
+    <version>6.7.1-SNAPSHOT</version>
   </parent>
 
   <artifactId>org.eclipse.jgit.pgm</artifactId>
diff --git a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/console/ConsoleAuthenticator.java b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/console/ConsoleAuthenticator.java
index 681cf5d..201fa3d 100644
--- a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/console/ConsoleAuthenticator.java
+++ b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/console/ConsoleAuthenticator.java
@@ -38,7 +38,6 @@
 
 	private final Console cons = System.console();
 
-	/** {@inheritDoc} */
 	@Override
 	protected PasswordAuthentication promptPasswordAuthentication() {
 		final String realm = formatRealm();
diff --git a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/console/ConsoleCredentialsProvider.java b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/console/ConsoleCredentialsProvider.java
index 63ce838..5bdfc7b 100644
--- a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/console/ConsoleCredentialsProvider.java
+++ b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/console/ConsoleCredentialsProvider.java
@@ -43,13 +43,11 @@
 
 	private final Console cons = System.console();
 
-	/** {@inheritDoc} */
 	@Override
 	public boolean isInteractive() {
 		return true;
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public boolean supports(CredentialItem... items) {
 		for (CredentialItem i : items) {
@@ -71,7 +69,6 @@
 		return true;
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public boolean get(URIish uri, CredentialItem... items)
 			throws UnsupportedCredentialItem {
diff --git a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/Add.java b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/Add.java
index ff0b55d..2ebab5e 100644
--- a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/Add.java
+++ b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/Add.java
@@ -31,7 +31,6 @@
 	@Argument(required = true, metaVar = "metaVar_filepattern", usage = "usage_filesToAddContentFrom")
 	private List<String> filepatterns = new ArrayList<>();
 
-	/** {@inheritDoc} */
 	@Override
 	protected void run() throws Exception {
 		try (Git git = new Git(db)) {
diff --git a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/AmazonS3Client.java b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/AmazonS3Client.java
index 0acad86..9c0915c 100644
--- a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/AmazonS3Client.java
+++ b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/AmazonS3Client.java
@@ -42,13 +42,11 @@
 	@Argument(index = 3, metaVar = "metaVar_KEY", required = true)
 	private String key;
 
-	/** {@inheritDoc} */
 	@Override
 	protected final boolean requiresRepository() {
 		return false;
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	protected void run() throws Exception {
 		final AmazonS3 s3 = new AmazonS3(properties());
diff --git a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/Archive.java b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/Archive.java
index 4028105..f98f8cb 100644
--- a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/Archive.java
+++ b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/Archive.java
@@ -41,7 +41,6 @@
 	@Option(name = "--output", aliases = { "-o" }, metaVar = "metaVar_file", usage = "usage_archiveOutput")
 	private String output;
 
-	/** {@inheritDoc} */
 	@Override
 	protected void run() throws Exception {
 		if (tree == null)
diff --git a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/Blame.java b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/Blame.java
index 1a3a2f6..93d02c1 100644
--- a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/Blame.java
+++ b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/Blame.java
@@ -104,7 +104,6 @@
 	/** Used to get a current time stamp for lines without commit. */
 	private final PersonIdent dummyDate = new PersonIdent("", ""); //$NON-NLS-1$ //$NON-NLS-2$
 
-	/** {@inheritDoc} */
 	@Override
 	protected void run() {
 		if (file == null) {
diff --git a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/Branch.java b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/Branch.java
index 27668b5..e680394 100644
--- a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/Branch.java
+++ b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/Branch.java
@@ -148,7 +148,6 @@
 
 	private int maxNameLength;
 
-	/** {@inheritDoc} */
 	@Override
 	protected void run() {
 		try {
diff --git a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/Checkout.java b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/Checkout.java
index 98724bf..229d54d 100644
--- a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/Checkout.java
+++ b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/Checkout.java
@@ -51,7 +51,6 @@
 	@Option(name = "--", metaVar = "metaVar_paths", handler = RestOfArgumentsHandler.class)
 	private List<String> paths = new ArrayList<>();
 
-	/** {@inheritDoc} */
 	@Override
 	protected void run() throws Exception {
 		if (createBranch) {
diff --git a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/Clean.java b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/Clean.java
index 6db73e6..348f2e7 100644
--- a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/Clean.java
+++ b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/Clean.java
@@ -32,7 +32,6 @@
 	@Option(name = "--dryRun", aliases = { "-n" })
 	private boolean dryRun = false;
 
-	/** {@inheritDoc} */
 	@Override
 	protected void run() {
 		try (Git git = new Git(db)) {
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 9f9fa8f..1efba55 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
@@ -72,13 +72,11 @@
 	@Argument(index = 1, metaVar = "metaVar_directory")
 	private String localName;
 
-	/** {@inheritDoc} */
 	@Override
 	protected final boolean requiresRepository() {
 		return false;
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	protected void run() throws Exception {
 		if (localName != null && gitdir != null)
@@ -148,7 +146,6 @@
 		}
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public void initializedSubmodules(Collection<String> submodules) {
 		try {
@@ -162,7 +159,6 @@
 		}
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public void cloningSubmodule(String path) {
 		try {
@@ -174,7 +170,6 @@
 		}
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public void checkingOut(AnyObjectId commit, String path) {
 		try {
diff --git a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/CommandRef.java b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/CommandRef.java
index 7a197a7..fb5a8ff 100644
--- a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/CommandRef.java
+++ b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/CommandRef.java
@@ -141,7 +141,6 @@
 		return r;
 	}
 
-	/** {@inheritDoc} */
 	@SuppressWarnings("nls")
 	@Override
 	public String toString() {
diff --git a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/Commit.java b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/Commit.java
index b0713f7..8df028d 100644
--- a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/Commit.java
+++ b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/Commit.java
@@ -84,7 +84,6 @@
 	@Argument(metaVar = "metaVar_commitPaths", usage = "usage_CommitPaths")
 	private List<String> paths = new ArrayList<>();
 
-	/** {@inheritDoc} */
 	@Override
 	protected void run() {
 		try (Git git = new Git(db)) {
diff --git a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/Config.java b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/Config.java
index 979c6fa..52f40c2 100644
--- a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/Config.java
+++ b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/Config.java
@@ -68,7 +68,6 @@
 	@Option(name = "--file", aliases = { "-f" }, metaVar = "metaVar_file", usage = "usage_configFile")
 	private File configFile;
 
-	/** {@inheritDoc} */
 	@Override
 	protected void run() {
 		if (!list) {
diff --git a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/ConvertRefStorage.java b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/ConvertRefStorage.java
index 47e4b6b..06e37da 100644
--- a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/ConvertRefStorage.java
+++ b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/ConvertRefStorage.java
@@ -28,7 +28,6 @@
 			"-r" }, usage = "usage_convertRefStorageRefLogs")
 	private boolean writeLogs = true;
 
-	/** {@inheritDoc} */
 	@Override
 	protected void run() throws Exception {
 		((FileRepository) db).convertRefStorage(format, writeLogs, backup);
diff --git a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/Daemon.java b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/Daemon.java
index f987f2c..ec201a5 100644
--- a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/Daemon.java
+++ b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/Daemon.java
@@ -64,13 +64,11 @@
 	@Argument(required = true, metaVar = "metaVar_directory", usage = "usage_directoriesToExport")
 	List<File> directory = new ArrayList<>();
 
-	/** {@inheritDoc} */
 	@Override
 	protected boolean requiresRepository() {
 		return false;
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	protected void run() throws Exception {
 		PackConfig packConfig = new PackConfig();
diff --git a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/Describe.java b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/Describe.java
index 116db03..913d7c7 100644
--- a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/Describe.java
+++ b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/Describe.java
@@ -47,7 +47,6 @@
 	@Option(name = "--abbrev", usage = "usage_Abbrev")
 	private Integer abbrev;
 
-	/** {@inheritDoc} */
 	@Override
 	protected void run() {
 		try (Git git = new Git(db)) {
diff --git a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/Diff.java b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/Diff.java
index 3152c44..61979d1 100644
--- a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/Diff.java
+++ b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/Diff.java
@@ -155,14 +155,12 @@
 
 	// END -- Options shared with Log
 
-	/** {@inheritDoc} */
 	@Override
 	protected void init(Repository repository, String gitDir) {
 		super.init(repository, gitDir);
 		diffFmt = new DiffFormatter(new BufferedOutputStream(outs));
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	protected void run() {
 		diffFmt.setRepository(db);
diff --git a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/DiffTree.java b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/DiffTree.java
index 9aaf3f5..352ffde 100644
--- a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/DiffTree.java
+++ b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/DiffTree.java
@@ -40,7 +40,6 @@
 	@Option(name = "--", metaVar = "metaVar_path", handler = PathTreeFilterHandler.class)
 	private TreeFilter pathFilter = TreeFilter.ALL;
 
-	/** {@inheritDoc} */
 	@Override
 	protected void run() {
 		try (TreeWalk walk = new TreeWalk(db)) {
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 2e0c36b..7a007e3 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
@@ -113,7 +113,6 @@
 	@Argument(index = 1, metaVar = "metaVar_refspec")
 	private List<RefSpec> toget;
 
-	/** {@inheritDoc} */
 	@Override
 	protected void run() {
 		try (Git git = new Git(db)) {
@@ -167,7 +166,6 @@
 		}
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public void fetchingSubmodule(String name) {
 		try {
diff --git a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/Glog.java b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/Glog.java
index 5318018..ce687c4 100644
--- a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/Glog.java
+++ b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/Glog.java
@@ -65,7 +65,6 @@
 		frame.getContentPane().add(world);
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	protected int walkLoop() throws Exception {
 		graphPane.getCommitList().source(walk);
@@ -77,13 +76,11 @@
 		return graphPane.getCommitList().size();
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	protected void show(RevCommit c) throws Exception {
 		throw new UnsupportedOperationException();
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	protected RevWalk createWalk() {
 		if (objects)
diff --git a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/IndexPack.java b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/IndexPack.java
index 9732335..b3808d6 100644
--- a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/IndexPack.java
+++ b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/IndexPack.java
@@ -28,7 +28,6 @@
 	@Option(name = "--index-version", usage = "usage_indexFileFormatToCreate")
 	private int indexVersion = -1;
 
-	/** {@inheritDoc} */
 	@Override
 	protected void run() {
 		BufferedInputStream in = new BufferedInputStream(ins);
diff --git a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/Init.java b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/Init.java
index 7a0d96d..9c4af81 100644
--- a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/Init.java
+++ b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/Init.java
@@ -40,13 +40,11 @@
 	@Argument(index = 0, metaVar = "metaVar_directory")
 	private String directory;
 
-	/** {@inheritDoc} */
 	@Override
 	protected final boolean requiresRepository() {
 		return false;
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	protected void run() {
 		InitCommand command = Git.init();
diff --git a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/Log.java b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/Log.java
index d693051..852a4b3 100644
--- a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/Log.java
+++ b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/Log.java
@@ -182,14 +182,12 @@
 		dateFormatter = new GitDateFormatter(Format.DEFAULT);
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	protected void init(Repository repository, String gitDir) {
 		super.init(repository, gitDir);
 		diffFmt = new DiffFormatter(new BufferedOutputStream(outs));
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	protected void run() {
 		config = new GpgConfig(db.getConfig());
@@ -244,7 +242,6 @@
 				NoteMap.read(argWalk.getObjectReader(), notesCommit));
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	protected void show(RevCommit c) throws Exception {
 		outw.print(CLIText.get().commitLabel);
@@ -314,10 +311,14 @@
 	}
 
 	/**
+	 * Show notes for given commit
+	 *
 	 * @param c
+	 *            given commit
 	 * @return <code>true</code> if at least one note was printed,
 	 *         <code>false</code> otherwise
 	 * @throws IOException
+	 *             if an IO error occurred
 	 */
 	private boolean showNotes(RevCommit c) throws IOException {
 		if (noteMaps == null)
@@ -344,12 +345,17 @@
 
 	/**
 	 * @param c
+	 *            given commit
 	 * @param map
+	 *            note map
 	 * @param label
+	 *            label
 	 * @param emptyLine
+	 *            whether to start with an empty line
 	 * @return <code>true</code> if note was printed, <code>false</code>
 	 *         otherwise
 	 * @throws IOException
+	 *             if an IO error occurred
 	 */
 	private boolean showNotes(RevCommit c, NoteMap map, String label,
 			boolean emptyLine)
diff --git a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/LsRemote.java b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/LsRemote.java
index 83446cc..89ceed2 100644
--- a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/LsRemote.java
+++ b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/LsRemote.java
@@ -40,7 +40,6 @@
 	@Argument(index = 0, metaVar = "metaVar_uriish", required = true)
 	private String remote;
 
-	/** {@inheritDoc} */
 	@Override
 	protected void run() {
 		LsRemoteCommand command = Git.lsRemoteRepository().setRemote(remote)
@@ -63,7 +62,6 @@
 		}
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	protected boolean requiresRepository() {
 		return false;
diff --git a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/LsTree.java b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/LsTree.java
index bb14001..34b48c1 100644
--- a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/LsTree.java
+++ b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/LsTree.java
@@ -38,7 +38,6 @@
 	@Option(name = "--", metaVar = "metaVar_paths", handler = StopOptionHandler.class)
 	private List<String> paths = new ArrayList<>();
 
-	/** {@inheritDoc} */
 	@Override
 	protected void run() {
 		try (TreeWalk walk = new TreeWalk(db)) {
diff --git a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/Main.java b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/Main.java
index 613fc5f..d059eff 100644
--- a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/Main.java
+++ b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/Main.java
@@ -97,6 +97,7 @@
 	 * @param argv
 	 *            arguments.
 	 * @throws java.lang.Exception
+	 *             if an error occurred
 	 */
 	public static void main(String[] argv) throws Exception {
 		// make sure built-in filters are registered
@@ -121,6 +122,7 @@
 	 * @param argv
 	 *            arguments.
 	 * @throws java.lang.Exception
+	 *             if an error occurred
 	 */
 	protected void run(String[] argv) throws Exception {
 		writer = createErrorWriter();
@@ -263,9 +265,11 @@
 
 	/**
 	 * @param status
+	 *            exit status code, nonzero value indicates an error
 	 * @param t
 	 *            can be {@code null}
 	 * @throws Exception
+	 *             if an IO error occurred
 	 */
 	void exit(int status, Exception t) throws Exception {
 		writer.flush();
diff --git a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/Merge.java b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/Merge.java
index 27a3d90..b78998d 100644
--- a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/Merge.java
+++ b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/Merge.java
@@ -86,7 +86,6 @@
 		}
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	protected void run() {
 		if (squash && ff == FastForwardMode.NO_FF) {
diff --git a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/MergeBase.java b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/MergeBase.java
index 68eeff7..aacde2f 100644
--- a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/MergeBase.java
+++ b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/MergeBase.java
@@ -33,7 +33,6 @@
 	@Argument(index = 1, metaVar = "metaVar_commitish", required = true)
 	private List<RevCommit> commits = new ArrayList<>();
 
-	/** {@inheritDoc} */
 	@Override
 	protected void run() {
 		try {
diff --git a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/Push.java b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/Push.java
index f2e3a16..6535d95 100644
--- a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/Push.java
+++ b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/Push.java
@@ -81,7 +81,6 @@
 
 	private boolean shownURI;
 
-	/** {@inheritDoc} */
 	@Override
 	protected void run() {
 		try (Git git = new Git(db)) {
diff --git a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/ReceivePack.java b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/ReceivePack.java
index f570f7f..f89a4d1 100644
--- a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/ReceivePack.java
+++ b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/ReceivePack.java
@@ -26,13 +26,11 @@
 	@Argument(index = 0, required = true, metaVar = "metaVar_directory", usage = "usage_RepositoryToReceiveInto")
 	File dstGitdir;
 
-	/** {@inheritDoc} */
 	@Override
 	protected final boolean requiresRepository() {
 		return false;
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	protected void run() {
 		final org.eclipse.jgit.transport.ReceivePack rp;
diff --git a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/Reflog.java b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/Reflog.java
index c63532d..46485cc 100644
--- a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/Reflog.java
+++ b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/Reflog.java
@@ -28,7 +28,6 @@
 	@Argument(metaVar = "metaVar_ref")
 	private String ref;
 
-	/** {@inheritDoc} */
 	@Override
 	protected void run() {
 		try (Git git = new Git(db)) {
diff --git a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/Remote.java b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/Remote.java
index 6d6feed..a3100ac 100644
--- a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/Remote.java
+++ b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/Remote.java
@@ -52,7 +52,6 @@
 	@Argument(index = 2, metaVar = "metaVar_uriish")
 	private String uri;
 
-	/** {@inheritDoc} */
 	@Override
 	protected void run() {
 		try (Git git = new Git(db)) {
@@ -114,7 +113,6 @@
 		}
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public void printUsage(String message, CmdLineParser clp)
 			throws IOException {
diff --git a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/Repo.java b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/Repo.java
index 0588a7c..da622e1 100644
--- a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/Repo.java
+++ b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/Repo.java
@@ -26,7 +26,6 @@
 	@Argument(required = true, metaVar = "metaVar_path", usage = "usage_pathToXml")
 	private String path;
 
-	/** {@inheritDoc} */
 	@Override
 	protected void run() {
 		try {
diff --git a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/Reset.java b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/Reset.java
index 3454cf2..f33cb6be 100644
--- a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/Reset.java
+++ b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/Reset.java
@@ -41,7 +41,6 @@
 	@Option(name = "--", metaVar = "metaVar_paths", handler = RestOfArgumentsHandler.class)
 	private List<String> paths = new ArrayList<>();
 
-	/** {@inheritDoc} */
 	@Override
 	protected void run() {
 		try (Git git = new Git(db)) {
diff --git a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/RevList.java b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/RevList.java
index e86ad01..59fc5f2 100644
--- a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/RevList.java
+++ b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/RevList.java
@@ -18,7 +18,6 @@
 
 @Command(usage = "usage_RevList")
 class RevList extends RevWalkTextBuiltin {
-	/** {@inheritDoc} */
 	@Override
 	protected void show(RevCommit c) throws Exception {
 		if (c.has(RevFlag.UNINTERESTING))
@@ -32,7 +31,6 @@
 		outw.println();
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	protected void show(ObjectWalk ow, RevObject obj)
 			throws Exception {
diff --git a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/RevParse.java b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/RevParse.java
index 9e4d1c9..b1fb07b 100644
--- a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/RevParse.java
+++ b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/RevParse.java
@@ -35,7 +35,6 @@
 	@Argument(index = 0, metaVar = "metaVar_commitish")
 	private List<ObjectId> commits = new ArrayList<>();
 
-	/** {@inheritDoc} */
 	@Override
 	protected void run() {
 		try {
diff --git a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/RevWalkTextBuiltin.java b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/RevWalkTextBuiltin.java
index 696a924..51e597c 100644
--- a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/RevWalkTextBuiltin.java
+++ b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/RevWalkTextBuiltin.java
@@ -114,7 +114,6 @@
 	@Option(name = "--max-count", aliases = "-n", metaVar = "metaVar_n")
 	private int maxCount = -1;
 
-	/** {@inheritDoc} */
 	@Override
 	protected void run() throws Exception {
 		walk = createWalk();
@@ -228,7 +227,8 @@
 	 *
 	 * @param c
 	 *            The current {@link org.eclipse.jgit.revwalk.RevCommit}
-	 * @throws java.lang.Exception
+	 * @throws Exception
+	 *             if an error occurred
 	 */
 	protected abstract void show(RevCommit c) throws Exception;
 
@@ -243,7 +243,8 @@
 	 *            {@link #walkLoop()}
 	 * @param currentObject
 	 *            The current {@link org.eclipse.jgit.revwalk.RevObject}
-	 * @throws java.lang.Exception
+	 * @throws Exception
+	 *             if an error occurred
 	 */
 	protected void show(final ObjectWalk objectWalk,
 			final RevObject currentObject) throws Exception {
diff --git a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/Rm.java b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/Rm.java
index 4a33798..234da1a 100644
--- a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/Rm.java
+++ b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/Rm.java
@@ -27,7 +27,6 @@
 	@Option(name = "--", handler = StopOptionHandler.class)
 	private List<String> paths = new ArrayList<>();
 
-	/** {@inheritDoc} */
 	@Override
 	protected void run() {
 		try (Git git = new Git(db)) {
diff --git a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/Show.java b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/Show.java
index c18d35a..4feb090 100644
--- a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/Show.java
+++ b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/Show.java
@@ -161,14 +161,12 @@
 		fmt = new SimpleDateFormat("EEE MMM dd HH:mm:ss yyyy ZZZZZ", Locale.US); //$NON-NLS-1$
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	protected void init(Repository repository, String gitDir) {
 		super.init(repository, gitDir);
 		diffFmt = new DiffFormatter(new BufferedOutputStream(outs));
 	}
 
-	/** {@inheritDoc} */
 	@SuppressWarnings("boxing")
 	@Override
 	protected void run() {
diff --git a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/ShowRef.java b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/ShowRef.java
index a58785f..64b182e 100644
--- a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/ShowRef.java
+++ b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/ShowRef.java
@@ -21,7 +21,6 @@
 
 @Command(usage = "usage_ShowRef")
 class ShowRef extends TextBuiltin {
-	/** {@inheritDoc} */
 	@Override
 	protected void run() {
 		try {
diff --git a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/Status.java b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/Status.java
index 141de0c..1ef39a1 100644
--- a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/Status.java
+++ b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/Status.java
@@ -55,7 +55,6 @@
 	@Option(name = "--", metaVar = "metaVar_paths", handler = RestOfArgumentsHandler.class)
 	protected List<String> filterPaths;
 
-	/** {@inheritDoc} */
 	@Override
 	protected void run() {
 		try (Git git = new Git(db)) {
@@ -239,10 +238,11 @@
 	 * Print section header
 	 *
 	 * @param pattern
-	 *            a {@link java.lang.String} object.
+	 *            a {@link String} object.
 	 * @param arguments
-	 *            a {@link java.lang.Object} object.
-	 * @throws java.io.IOException
+	 *            a {@link Object} object.
+	 * @throws IOException
+	 *             if an IO error occurred
 	 */
 	protected void printSectionHeader(String pattern, Object... arguments)
 			throws IOException {
@@ -259,9 +259,10 @@
 	 * Print String list
 	 *
 	 * @param list
-	 *            a {@link java.util.Collection} object.
-	 * @return a int.
-	 * @throws java.io.IOException
+	 *            a {@link Collection} object.
+	 * @return size of the list
+	 * @throws IOException
+	 *             if an IO error occurred
 	 */
 	protected int printList(Collection<String> list) throws IOException {
 		if (!list.isEmpty()) {
@@ -281,21 +282,22 @@
 	 * Print String list
 	 *
 	 * @param status1
-	 *            a {@link java.lang.String} object.
+	 *            a {@link String} object.
 	 * @param status2
-	 *            a {@link java.lang.String} object.
+	 *            a {@link String} object.
 	 * @param status3
-	 *            a {@link java.lang.String} object.
+	 *            a {@link String} object.
 	 * @param list
-	 *            a {@link java.util.Collection} object.
+	 *            a {@link Collection} object.
 	 * @param set1
-	 *            a {@link java.util.Collection} object.
+	 *            a {@link Collection} object.
 	 * @param set2
-	 *            a {@link java.util.Collection} object.
+	 *            a {@link Collection} object.
 	 * @param set3
-	 *            a {@link java.util.Collection} object.
+	 *            a {@link Collection} object.
 	 * @return a int.
-	 * @throws java.io.IOException
+	 * @throws IOException
+	 *             if an IO error occurred
 	 */
 	protected int printList(String status1, String status2, String status3,
 			Collection<String> list, Collection<String> set1,
diff --git a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/Tag.java b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/Tag.java
index 0603de1..4ea67ab 100644
--- a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/Tag.java
+++ b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/Tag.java
@@ -88,7 +88,6 @@
 	@Argument(index = 1, metaVar = "metaVar_object")
 	private ObjectId object;
 
-	/** {@inheritDoc} */
 	@Override
 	protected void run() {
 		try (Git git = new Git(db)) {
diff --git a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/TextBuiltin.java b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/TextBuiltin.java
index 6cfe93d..c572e3b 100644
--- a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/TextBuiltin.java
+++ b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/TextBuiltin.java
@@ -249,6 +249,7 @@
 	 * @param args
 	 *            the arguments supplied on the command line, if any.
 	 * @throws java.io.IOException
+	 *             if an IO error occurred
 	 */
 	protected void parseArguments(String[] args) throws IOException {
 		final CmdLineParser clp = new CmdLineParser(this);
@@ -277,6 +278,7 @@
 	 * @param clp
 	 *            a {@link org.eclipse.jgit.pgm.opt.CmdLineParser} object.
 	 * @throws java.io.IOException
+	 *             if an IO error occurred
 	 */
 	public void printUsageAndExit(CmdLineParser clp) throws IOException {
 		printUsageAndExit("", clp); //$NON-NLS-1$
@@ -290,6 +292,7 @@
 	 * @param clp
 	 *            a {@link org.eclipse.jgit.pgm.opt.CmdLineParser} object.
 	 * @throws java.io.IOException
+	 *             if an IO error occurred
 	 */
 	public void printUsageAndExit(String message, CmdLineParser clp) throws IOException {
 		printUsage(message, clp);
@@ -304,6 +307,7 @@
 	 * @param clp
 	 *            parser used to print options
 	 * @throws java.io.IOException
+	 *             if an IO error occurred
 	 * @since 4.2
 	 */
 	protected void printUsage(String message, CmdLineParser clp)
diff --git a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/UploadPack.java b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/UploadPack.java
index ac51643..db2c393 100644
--- a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/UploadPack.java
+++ b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/UploadPack.java
@@ -30,13 +30,11 @@
 	@Argument(index = 0, required = true, metaVar = "metaVar_directory", usage = "usage_RepositoryToReadFrom")
 	File srcGitdir;
 
-	/** {@inheritDoc} */
 	@Override
 	protected final boolean requiresRepository() {
 		return false;
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	protected void run() {
 		try {
diff --git a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/Version.java b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/Version.java
index d06f1e2..8546094 100644
--- a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/Version.java
+++ b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/Version.java
@@ -22,7 +22,6 @@
 
 @Command(common = true, usage = "usage_DisplayTheVersionOfJgit")
 class Version extends TextBuiltin {
-	/** {@inheritDoc} */
 	@Override
 	protected void run() {
 		// read the Implementation-Version from Manifest
@@ -48,7 +47,6 @@
 		}
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	protected final boolean requiresRepository() {
 		return false;
diff --git a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/debug/BenchmarkReftable.java b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/debug/BenchmarkReftable.java
index f23f4cf..f156b8c 100644
--- a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/debug/BenchmarkReftable.java
+++ b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/debug/BenchmarkReftable.java
@@ -70,7 +70,6 @@
 	@Argument(index = 1)
 	private String reftablePath;
 
-	/** {@inheritDoc} */
 	@Override
 	protected void run() throws Exception {
 		switch (test) {
diff --git a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/debug/DiffAlgorithms.java b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/debug/DiffAlgorithms.java
index a63387c..67300dc 100644
--- a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/debug/DiffAlgorithms.java
+++ b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/debug/DiffAlgorithms.java
@@ -96,13 +96,11 @@
 
 	private ThreadMXBean mxBean;
 
-	/** {@inheritDoc} */
 	@Override
 	protected boolean requiresRepository() {
 		return false;
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	protected void run() throws Exception {
 		mxBean = ManagementFactory.getThreadMXBean();
diff --git a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/debug/LfsStore.java b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/debug/LfsStore.java
index 9c0ced5..653530d 100644
--- a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/debug/LfsStore.java
+++ b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/debug/LfsStore.java
@@ -181,13 +181,11 @@
 
 	String secretKey;
 
-	/** {@inheritDoc} */
 	@Override
 	protected boolean requiresRepository() {
 		return false;
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	protected void run() throws Exception {
 		AppServer server = new AppServer(port);
diff --git a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/debug/MakeCacheTree.java b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/debug/MakeCacheTree.java
index 63897a3..5188336 100644
--- a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/debug/MakeCacheTree.java
+++ b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/debug/MakeCacheTree.java
@@ -24,7 +24,6 @@
 
 @Command(usage = "usage_MakeCacheTree")
 class MakeCacheTree extends TextBuiltin {
-	/** {@inheritDoc} */
 	@Override
 	protected void run() throws Exception {
 		final DirCache cache = db.readDirCache();
diff --git a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/debug/ReadChangedPathFilter.java b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/debug/ReadChangedPathFilter.java
new file mode 100644
index 0000000..1414165
--- /dev/null
+++ b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/debug/ReadChangedPathFilter.java
@@ -0,0 +1,83 @@
+/*
+ * Copyright (C) 2023, Google LLC
+ *
+ * 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.debug;
+
+import java.io.FileInputStream;
+import java.util.HashSet;
+
+import org.eclipse.jgit.pgm.Command;
+import org.eclipse.jgit.pgm.TextBuiltin;
+import org.eclipse.jgit.util.NB;
+import org.kohsuke.args4j.Argument;
+
+/**
+ * Prints the contents of the BDAT chunk from commit-graph file.
+ * <p>
+ * This is a debugging tool for changed path filter development.
+ */
+@Command
+class ReadChangedPathFilter extends TextBuiltin {
+
+	static final int CHUNK_ID_OID_FANOUT = 0x4f494446; /* "OIDF" */
+
+	static final int CHUNK_ID_BLOOM_FILTER_INDEX = 0x42494458; /* "BIDX" */
+
+	static final int CHUNK_ID_BLOOM_FILTER_DATA = 0x42444154; /* "BDAT" */
+
+	@Argument(index = 0)
+	private String input;
+
+	static HashSet<String> changedPathStrings(byte[] data) {
+		int oidf_offset = -1;
+		int bidx_offset = -1;
+		int bdat_offset = -1;
+		for (int i = 8; i < data.length - 4; i += 12) {
+			switch (NB.decodeInt32(data, i)) {
+			case CHUNK_ID_OID_FANOUT:
+				oidf_offset = (int) NB.decodeInt64(data, i + 4);
+				break;
+			case CHUNK_ID_BLOOM_FILTER_INDEX:
+				bidx_offset = (int) NB.decodeInt64(data, i + 4);
+				break;
+			case CHUNK_ID_BLOOM_FILTER_DATA:
+				bdat_offset = (int) NB.decodeInt64(data, i + 4);
+				break;
+			}
+		}
+		bdat_offset += 12; // skip version, hash count, bits per entry
+		int commit_count = NB.decodeInt32(data, oidf_offset + 255 * 4);
+		int[] changed_path_length_cumuls = new int[commit_count];
+		for (int i = 0; i < commit_count; i++) {
+			changed_path_length_cumuls[i] = NB.decodeInt32(data,
+					bidx_offset + i * 4);
+		}
+		HashSet<String> changed_paths = new HashSet<>();
+		for (int i = 0; i < commit_count; i++) {
+			int prior_cumul = i == 0 ? 0 : changed_path_length_cumuls[i - 1];
+			String changed_path = ""; //$NON-NLS-1$
+			for (int j = prior_cumul; j < changed_path_length_cumuls[i]; j++) {
+				changed_path += data[bdat_offset + j] + ","; //$NON-NLS-1$
+			}
+			changed_paths.add(changed_path);
+		}
+		return changed_paths;
+	}
+
+	/** {@inheritDoc} */
+	@Override
+	protected void run() throws Exception {
+		try (FileInputStream in = new FileInputStream(input)
+				) {
+				byte[] data = in.readAllBytes();
+				outw.println(changedPathStrings(data).toString());
+		}
+	}
+}
diff --git a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/debug/ReadDirCache.java b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/debug/ReadDirCache.java
index 33d1059..6e0f915 100644
--- a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/debug/ReadDirCache.java
+++ b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/debug/ReadDirCache.java
@@ -21,7 +21,6 @@
 
 @Command(usage = "usage_ReadDirCache")
 class ReadDirCache extends TextBuiltin {
-	/** {@inheritDoc} */
 	@Override
 	protected void run() throws Exception {
 		final int cnt = 100;
diff --git a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/debug/ReadReftable.java b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/debug/ReadReftable.java
index 6dace84..a2443d3 100644
--- a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/debug/ReadReftable.java
+++ b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/debug/ReadReftable.java
@@ -30,7 +30,6 @@
 	@Argument(index = 1, required = false)
 	private String ref;
 
-	/** {@inheritDoc} */
 	@Override
 	protected void run() throws Exception {
 		try (FileInputStream in = new FileInputStream(input);
diff --git a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/debug/RebuildCommitGraph.java b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/debug/RebuildCommitGraph.java
index 8d884c1..2f96ef7 100644
--- a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/debug/RebuildCommitGraph.java
+++ b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/debug/RebuildCommitGraph.java
@@ -81,7 +81,6 @@
 
 	private Map<ObjectId, ObjectId> rewrites = new HashMap<>();
 
-	/** {@inheritDoc} */
 	@Override
 	protected void run() throws Exception {
 		if (!really && db.getRefDatabase().hasRefs()) {
diff --git a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/debug/ShowCacheTree.java b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/debug/ShowCacheTree.java
index 28a8d86..057d20b 100644
--- a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/debug/ShowCacheTree.java
+++ b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/debug/ShowCacheTree.java
@@ -24,7 +24,6 @@
 
 @Command(usage = "usage_ShowCacheTree")
 class ShowCacheTree extends TextBuiltin {
-	/** {@inheritDoc} */
 	@Override
 	protected void run() throws Exception {
 		final DirCache cache = db.readDirCache();
diff --git a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/debug/ShowCommands.java b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/debug/ShowCommands.java
index 9e61357..daea1fb 100644
--- a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/debug/ShowCommands.java
+++ b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/debug/ShowCommands.java
@@ -26,7 +26,6 @@
 	@Option(name = "--pretty", metaVar = "metaVar_commandDetail", usage = "usage_alterTheDetailShown")
 	private Format pretty = Format.USAGE;
 
-	/** {@inheritDoc} */
 	@Override
 	protected void run() throws Exception {
 		final CommandRef[] list = CommandCatalog.all();
diff --git a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/debug/ShowDirCache.java b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/debug/ShowDirCache.java
index 1f4733f..3633d88 100644
--- a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/debug/ShowDirCache.java
+++ b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/debug/ShowDirCache.java
@@ -33,7 +33,6 @@
 	@Option(name = "--millis", aliases = { "-m" }, usage = "usage_showTimeInMilliseconds")
 	private boolean millis = false;
 
-	/** {@inheritDoc} */
 	@Override
 	protected void run() throws Exception {
 		final DateTimeFormatter fmt = DateTimeFormatter
diff --git a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/debug/ShowPackDelta.java b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/debug/ShowPackDelta.java
index 49f7ada..c95f138 100644
--- a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/debug/ShowPackDelta.java
+++ b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/debug/ShowPackDelta.java
@@ -39,7 +39,6 @@
 	@Argument(index = 0)
 	private ObjectId objectId;
 
-	/** {@inheritDoc} */
 	@Override
 	protected void run() throws Exception {
 		ObjectReader reader = db.newObjectReader();
diff --git a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/debug/TextHashFunctions.java b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/debug/TextHashFunctions.java
index 1ca3034..d7d31bd 100644
--- a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/debug/TextHashFunctions.java
+++ b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/debug/TextHashFunctions.java
@@ -228,13 +228,11 @@
 	@Option(name = "--repository", aliases = { "-r" }, metaVar = "GIT_DIR", usage = "Repository to scan")
 	List<File> gitDirs = new ArrayList<>();
 
-	/** {@inheritDoc} */
 	@Override
 	protected boolean requiresRepository() {
 		return false;
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	protected void run() throws Exception {
 		if (gitDirs.isEmpty()) {
diff --git a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/debug/VerifyReftable.java b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/debug/VerifyReftable.java
index 16a4c9f..aa1b81f 100644
--- a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/debug/VerifyReftable.java
+++ b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/debug/VerifyReftable.java
@@ -42,7 +42,6 @@
 	@Argument(index = 1)
 	private String reftablePath;
 
-	/** {@inheritDoc} */
 	@Override
 	protected void run() throws Exception {
 		List<Ref> refs = WriteReftable.readRefs(lsRemotePath);
diff --git a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/debug/WriteDirCache.java b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/debug/WriteDirCache.java
index 44836ec..d367f02 100644
--- a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/debug/WriteDirCache.java
+++ b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/debug/WriteDirCache.java
@@ -18,7 +18,6 @@
 
 @Command(usage = "usage_WriteDirCache")
 class WriteDirCache extends TextBuiltin {
-	/** {@inheritDoc} */
 	@Override
 	protected void run() throws Exception {
 		final DirCache cache = db.readDirCache();
diff --git a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/debug/WriteReftable.java b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/debug/WriteReftable.java
index 80d2f76..faa2bce 100644
--- a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/debug/WriteReftable.java
+++ b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/debug/WriteReftable.java
@@ -71,7 +71,6 @@
 	@Argument(index = 1)
 	private String out;
 
-	/** {@inheritDoc} */
 	@SuppressWarnings({ "nls", "boxing" })
 	@Override
 	protected void run() throws Exception {
diff --git a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/opt/AbstractTreeIteratorHandler.java b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/opt/AbstractTreeIteratorHandler.java
index d860472..cea2309 100644
--- a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/opt/AbstractTreeIteratorHandler.java
+++ b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/opt/AbstractTreeIteratorHandler.java
@@ -63,7 +63,6 @@
 		clp = (org.eclipse.jgit.pgm.opt.CmdLineParser) parser;
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public int parseArguments(Parameters params) throws CmdLineException {
 		final String name = params.getParameter(0);
@@ -115,7 +114,6 @@
 		return 1;
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public String getDefaultMetaVariable() {
 		return CLIText.get().metaVar_treeish;
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 df0b39b..463213d 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
@@ -110,7 +110,6 @@
 		this.db = repo;
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public void parseArgument(String... args) throws CmdLineException {
 		final ArrayList<String> tmp = new ArrayList<>(args.length);
@@ -265,7 +264,6 @@
 		}
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	protected OptionHandler createOptionHandler(OptionDef o, Setter setter) {
 		if (o instanceof NamedOptionDef) {
@@ -275,7 +273,6 @@
 
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public void printSingleLineUsage(Writer w, ResourceBundle rb) {
 		List<OptionHandler> options = getOptions();
diff --git a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/opt/GpgSignHandler.java b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/opt/GpgSignHandler.java
index af90b83..56423ad 100644
--- a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/opt/GpgSignHandler.java
+++ b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/opt/GpgSignHandler.java
@@ -53,7 +53,6 @@
 		super(parser, option, setter);
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public int parseArguments(Parameters params) throws CmdLineException {
 		String alias = params.getParameter(-1);
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
index feee78e..9c54169 100644
--- 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
@@ -44,7 +44,6 @@
 		super(parser, option, setter);
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public int parseArguments(Parameters params) throws CmdLineException {
 		Instant instant = Instant.parse(params.getParameter(0));
@@ -52,7 +51,6 @@
 		return 1;
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public String getDefaultMetaVariable() {
 		return CLIText.get().metaVar_instant;
diff --git a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/opt/ObjectIdHandler.java b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/opt/ObjectIdHandler.java
index 6cd36c3..b50df90 100644
--- a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/opt/ObjectIdHandler.java
+++ b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/opt/ObjectIdHandler.java
@@ -49,7 +49,6 @@
 		clp = (org.eclipse.jgit.pgm.opt.CmdLineParser) parser;
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public int parseArguments(Parameters params) throws CmdLineException {
 		final String name = params.getParameter(0);
@@ -68,7 +67,6 @@
 				CLIText.format(CLIText.get().notAnObject), name);
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public String getDefaultMetaVariable() {
 		return CLIText.get().metaVar_object;
diff --git a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/opt/OptionWithValuesListHandler.java b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/opt/OptionWithValuesListHandler.java
index 7d7c806..7bb2766 100644
--- a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/opt/OptionWithValuesListHandler.java
+++ b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/opt/OptionWithValuesListHandler.java
@@ -33,7 +33,6 @@
 		super(parser, option, setter);
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public int parseArguments(Parameters params) throws CmdLineException {
 		final List<String> list = new ArrayList<>();
@@ -50,7 +49,6 @@
 		return list.size();
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public String getDefaultMetaVariable() {
 		return CLIText.get().metaVar_values;
diff --git a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/opt/PathTreeFilterHandler.java b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/opt/PathTreeFilterHandler.java
index 6535119..f215040 100644
--- a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/opt/PathTreeFilterHandler.java
+++ b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/opt/PathTreeFilterHandler.java
@@ -49,7 +49,6 @@
 		super(parser, option, setter);
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public int parseArguments(Parameters params) throws CmdLineException {
 		final List<PathFilter> filters = new ArrayList<>();
@@ -73,7 +72,6 @@
 		return filters.size();
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public String getDefaultMetaVariable() {
 		return CLIText.get().metaVar_paths;
diff --git a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/opt/RefSpecHandler.java b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/opt/RefSpecHandler.java
index effa22a..0491445 100644
--- a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/opt/RefSpecHandler.java
+++ b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/opt/RefSpecHandler.java
@@ -43,14 +43,12 @@
 		super(parser, option, setter);
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public int parseArguments(Parameters params) throws CmdLineException {
 		setter.addValue(new RefSpec(params.getParameter(0)));
 		return 1;
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public String getDefaultMetaVariable() {
 		return CLIText.get().metaVar_refspec;
diff --git a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/opt/RevCommitHandler.java b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/opt/RevCommitHandler.java
index 8b2bed36..a095a28 100644
--- a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/opt/RevCommitHandler.java
+++ b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/opt/RevCommitHandler.java
@@ -53,7 +53,6 @@
 		clp = (org.eclipse.jgit.pgm.opt.CmdLineParser) parser;
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public int parseArguments(Parameters params) throws CmdLineException {
 		String name = params.getParameter(0);
@@ -116,7 +115,6 @@
 		setter.addValue(c);
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public String getDefaultMetaVariable() {
 		return CLIText.get().metaVar_commitish;
diff --git a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/opt/RevTreeHandler.java b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/opt/RevTreeHandler.java
index 357886d..08f1d28 100644
--- a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/opt/RevTreeHandler.java
+++ b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/opt/RevTreeHandler.java
@@ -52,7 +52,6 @@
 		clp = (org.eclipse.jgit.pgm.opt.CmdLineParser) parser;
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public int parseArguments(Parameters params) throws CmdLineException {
 		final String name = params.getParameter(0);
@@ -83,7 +82,6 @@
 		return 1;
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public String getDefaultMetaVariable() {
 		return CLIText.get().metaVar_treeish;
diff --git a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/opt/SubcommandHandler.java b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/opt/SubcommandHandler.java
index e096203..e71ba90 100644
--- a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/opt/SubcommandHandler.java
+++ b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/opt/SubcommandHandler.java
@@ -49,7 +49,6 @@
 		clp = (org.eclipse.jgit.pgm.opt.CmdLineParser) parser;
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public int parseArguments(Parameters params) throws CmdLineException {
 		final String name = params.getParameter(0);
@@ -67,7 +66,6 @@
 		return 1;
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public String getDefaultMetaVariable() {
 		return CLIText.get().metaVar_command;
diff --git a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/opt/UntrackedFilesHandler.java b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/opt/UntrackedFilesHandler.java
index 3562754..2f99cff 100644
--- a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/opt/UntrackedFilesHandler.java
+++ b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/opt/UntrackedFilesHandler.java
@@ -52,7 +52,6 @@
 		super(parser, option, setter);
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public int parseArguments(Parameters params) throws CmdLineException {
 		String alias = params.getParameter(-1);
diff --git a/org.eclipse.jgit.ssh.apache.agent/.settings/org.eclipse.jdt.core.prefs b/org.eclipse.jgit.ssh.apache.agent/.settings/org.eclipse.jdt.core.prefs
index d1f54bb..d5c0e6c 100644
--- a/org.eclipse.jgit.ssh.apache.agent/.settings/org.eclipse.jdt.core.prefs
+++ b/org.eclipse.jgit.ssh.apache.agent/.settings/org.eclipse.jdt.core.prefs
@@ -52,7 +52,7 @@
 org.eclipse.jdt.core.compiler.problem.missingJavadocComments=error
 org.eclipse.jdt.core.compiler.problem.missingJavadocCommentsOverriding=disabled
 org.eclipse.jdt.core.compiler.problem.missingJavadocCommentsVisibility=protected
-org.eclipse.jdt.core.compiler.problem.missingJavadocTagDescription=return_tag
+org.eclipse.jdt.core.compiler.problem.missingJavadocTagDescription=all_standard_tags
 org.eclipse.jdt.core.compiler.problem.missingJavadocTags=error
 org.eclipse.jdt.core.compiler.problem.missingJavadocTagsMethodTypeParameters=disabled
 org.eclipse.jdt.core.compiler.problem.missingJavadocTagsOverriding=disabled
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 84d97e2..fd3e977 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.6.2.qualifier
+Bundle-Version: 6.7.1.qualifier
 Bundle-Localization: plugin
 Bundle-Vendor: %Bundle-Vendor
-Fragment-Host: org.eclipse.jgit.ssh.apache;bundle-version="[6.6.2,6.7.0)"
+Fragment-Host: org.eclipse.jgit.ssh.apache;bundle-version="[6.7.1,6.8.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.6.2,6.7.0)",
- org.eclipse.jgit.nls;version="[6.6.2,6.7.0)",
- org.eclipse.jgit.util;version="[6.6.2,6.7.0)"
+Import-Package: org.eclipse.jgit.transport.sshd;version="[6.7.1,6.8.0)",
+ org.eclipse.jgit.nls;version="[6.7.1,6.8.0)",
+ org.eclipse.jgit.util;version="[6.7.1,6.8.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.6.2";x-internal:=true
+Export-Package: org.eclipse.jgit.internal.transport.sshd.agent.connector;version="6.7.1";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 f0c3ec2..79f4f05 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.6.2.qualifier
-Eclipse-SourceBundle: org.eclipse.jgit.ssh.apache.agent;version="6.6.2.qualifier";roots="."
+Bundle-Version: 6.7.1.qualifier
+Eclipse-SourceBundle: org.eclipse.jgit.ssh.apache.agent;version="6.7.1.qualifier";roots="."
diff --git a/org.eclipse.jgit.ssh.apache.agent/pom.xml b/org.eclipse.jgit.ssh.apache.agent/pom.xml
index 5b1ea04..ef6262c 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.6.2-SNAPSHOT</version>
+    <version>6.7.1-SNAPSHOT</version>
   </parent>
 
   <artifactId>org.eclipse.jgit.ssh.apache.agent</artifactId>
diff --git a/org.eclipse.jgit.ssh.apache.agent/src/org/eclipse/jgit/internal/transport/sshd/agent/connector/UnixSockets.java b/org.eclipse.jgit.ssh.apache.agent/src/org/eclipse/jgit/internal/transport/sshd/agent/connector/UnixSockets.java
index 6f8153d..54e4e2a 100644
--- a/org.eclipse.jgit.ssh.apache.agent/src/org/eclipse/jgit/internal/transport/sshd/agent/connector/UnixSockets.java
+++ b/org.eclipse.jgit.ssh.apache.agent/src/org/eclipse/jgit/internal/transport/sshd/agent/connector/UnixSockets.java
@@ -67,6 +67,7 @@
 	 *            set it
 	 * @return -1 on error, otherwise a value >= 0
 	 * @throws LastErrorException
+	 *             represents non-zero error code for the last error
 	 */
 	int fcntl(int fd, int command, int flag) throws LastErrorException;
 
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 cf7edd2..567c3fe 100644
--- a/org.eclipse.jgit.ssh.apache.test/META-INF/MANIFEST.MF
+++ b/org.eclipse.jgit.ssh.apache.test/META-INF/MANIFEST.MF
@@ -3,10 +3,11 @@
 Bundle-Name: %Bundle-Name
 Automatic-Module-Name: org.eclipse.jgit.ssh.apache.test
 Bundle-SymbolicName: org.eclipse.jgit.ssh.apache.test
-Bundle-Version: 6.6.2.qualifier
+Bundle-Version: 6.7.1.qualifier
 Bundle-Vendor: %Bundle-Vendor
 Bundle-Localization: plugin
 Bundle-RequiredExecutionEnvironment: JavaSE-11
+Require-Bundle: org.hamcrest.core;bundle-version="[1.3.0,2.0.0)"
 Import-Package: org.apache.sshd.client.config.hosts;version="[2.10.0,2.11.0)",
  org.apache.sshd.common;version="[2.10.0,2.11.0)",
  org.apache.sshd.common.auth;version="[2.10.0,2.11.0)",
@@ -21,17 +22,16 @@
  org.apache.sshd.core;version="[2.10.0,2.11.0)",
  org.apache.sshd.server;version="[2.10.0,2.11.0)",
  org.apache.sshd.server.forward;version="[2.10.0,2.11.0)",
- org.eclipse.jgit.api;version="[6.6.2,6.7.0)",
- org.eclipse.jgit.api.errors;version="[6.6.2,6.7.0)",
- org.eclipse.jgit.internal.transport.sshd.proxy;version="[6.6.2,6.7.0)",
- org.eclipse.jgit.junit;version="[6.6.2,6.7.0)",
- org.eclipse.jgit.junit.ssh;version="[6.6.2,6.7.0)",
- org.eclipse.jgit.lib;version="[6.6.2,6.7.0)",
- org.eclipse.jgit.transport;version="[6.6.2,6.7.0)",
- org.eclipse.jgit.transport.sshd;version="[6.6.2,6.7.0)",
- org.eclipse.jgit.transport.sshd.agent;version="[6.6.2,6.7.0)",
- org.eclipse.jgit.util;version="[6.6.2,6.7.0)",
- org.hamcrest;version="[1.1.0,3.0.0)",
+ org.eclipse.jgit.api;version="[6.7.1,6.8.0)",
+ org.eclipse.jgit.api.errors;version="[6.7.1,6.8.0)",
+ org.eclipse.jgit.internal.transport.sshd.proxy;version="[6.7.1,6.8.0)",
+ org.eclipse.jgit.junit;version="[6.7.1,6.8.0)",
+ org.eclipse.jgit.junit.ssh;version="[6.7.1,6.8.0)",
+ org.eclipse.jgit.lib;version="[6.7.1,6.8.0)",
+ org.eclipse.jgit.transport;version="[6.7.1,6.8.0)",
+ org.eclipse.jgit.transport.sshd;version="[6.7.1,6.8.0)",
+ org.eclipse.jgit.transport.sshd.agent;version="[6.7.1,6.8.0)",
+ org.eclipse.jgit.util;version="[6.7.1,6.8.0)",
  org.junit;version="[4.13,5.0.0)",
  org.junit.experimental.theories;version="[4.13,5.0.0)",
  org.junit.runner;version="[4.13,5.0.0)"
diff --git a/org.eclipse.jgit.ssh.apache.test/pom.xml b/org.eclipse.jgit.ssh.apache.test/pom.xml
index 9e19ec4..bda4294 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.6.2-SNAPSHOT</version>
+    <version>6.7.1-SNAPSHOT</version>
   </parent>
 
   <artifactId>org.eclipse.jgit.ssh.apache.test</artifactId>
diff --git a/org.eclipse.jgit.ssh.apache/.settings/org.eclipse.jdt.core.prefs b/org.eclipse.jgit.ssh.apache/.settings/org.eclipse.jdt.core.prefs
index d1f54bb..d5c0e6c 100644
--- a/org.eclipse.jgit.ssh.apache/.settings/org.eclipse.jdt.core.prefs
+++ b/org.eclipse.jgit.ssh.apache/.settings/org.eclipse.jdt.core.prefs
@@ -52,7 +52,7 @@
 org.eclipse.jdt.core.compiler.problem.missingJavadocComments=error
 org.eclipse.jdt.core.compiler.problem.missingJavadocCommentsOverriding=disabled
 org.eclipse.jdt.core.compiler.problem.missingJavadocCommentsVisibility=protected
-org.eclipse.jdt.core.compiler.problem.missingJavadocTagDescription=return_tag
+org.eclipse.jdt.core.compiler.problem.missingJavadocTagDescription=all_standard_tags
 org.eclipse.jdt.core.compiler.problem.missingJavadocTags=error
 org.eclipse.jdt.core.compiler.problem.missingJavadocTagsMethodTypeParameters=disabled
 org.eclipse.jdt.core.compiler.problem.missingJavadocTagsOverriding=disabled
diff --git a/org.eclipse.jgit.ssh.apache/META-INF/MANIFEST.MF b/org.eclipse.jgit.ssh.apache/META-INF/MANIFEST.MF
index 22f07ad..fa51dfb 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.6.2.qualifier
+Bundle-Version: 6.7.1.qualifier
 Bundle-RequiredExecutionEnvironment: JavaSE-11
-Export-Package: org.eclipse.jgit.internal.transport.sshd;version="6.6.2";x-internal:=true;
+Export-Package: org.eclipse.jgit.internal.transport.sshd;version="6.7.1";x-internal:=true;
   uses:="org.apache.sshd.client,
    org.apache.sshd.client.auth,
    org.apache.sshd.client.auth.keyboard,
@@ -23,17 +23,18 @@
    org.apache.sshd.common.signature,
    org.apache.sshd.common.util.buffer,
    org.eclipse.jgit.transport",
- org.eclipse.jgit.internal.transport.sshd.agent;version="6.6.2";x-internal:=true,
- org.eclipse.jgit.internal.transport.sshd.auth;version="6.6.2";x-internal:=true,
- org.eclipse.jgit.internal.transport.sshd.proxy;version="6.6.2";x-friends:="org.eclipse.jgit.ssh.apache.test",
- org.eclipse.jgit.transport.sshd;version="6.6.2";
+ org.eclipse.jgit.internal.transport.sshd.agent;version="6.7.1";x-internal:=true,
+ org.eclipse.jgit.internal.transport.sshd.auth;version="6.7.1";x-internal:=true,
+ org.eclipse.jgit.internal.transport.sshd.pkcs11;version="6.7.1";x-internal:=true,
+ org.eclipse.jgit.internal.transport.sshd.proxy;version="6.7.1";x-friends:="org.eclipse.jgit.ssh.apache.test",
+ org.eclipse.jgit.transport.sshd;version="6.7.1";
   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.6.2"
+ org.eclipse.jgit.transport.sshd.agent;version="6.7.1"
 Import-Package: net.i2p.crypto.eddsa;version="[0.3.0,0.4.0)",
  org.apache.sshd.agent;version="[2.10.0,2.11.0)",
  org.apache.sshd.client;version="[2.10.0,2.11.0)",
@@ -86,12 +87,12 @@
  org.apache.sshd.sftp;version="[2.10.0,2.11.0)",
  org.apache.sshd.sftp.client;version="[2.10.0,2.11.0)",
  org.apache.sshd.sftp.common;version="[2.10.0,2.11.0)",
- org.eclipse.jgit.annotations;version="[6.6.2,6.7.0)",
- org.eclipse.jgit.errors;version="[6.6.2,6.7.0)",
- org.eclipse.jgit.fnmatch;version="[6.6.2,6.7.0)",
- org.eclipse.jgit.internal.storage.file;version="[6.6.2,6.7.0)",
- org.eclipse.jgit.internal.transport.ssh;version="[6.6.2,6.7.0)",
- org.eclipse.jgit.nls;version="[6.6.2,6.7.0)",
- org.eclipse.jgit.transport;version="[6.6.2,6.7.0)",
- org.eclipse.jgit.util;version="[6.6.2,6.7.0)",
+ org.eclipse.jgit.annotations;version="[6.7.1,6.8.0)",
+ org.eclipse.jgit.errors;version="[6.7.1,6.8.0)",
+ org.eclipse.jgit.fnmatch;version="[6.7.1,6.8.0)",
+ org.eclipse.jgit.internal.storage.file;version="[6.7.1,6.8.0)",
+ org.eclipse.jgit.internal.transport.ssh;version="[6.7.1,6.8.0)",
+ org.eclipse.jgit.nls;version="[6.7.1,6.8.0)",
+ org.eclipse.jgit.transport;version="[6.7.1,6.8.0)",
+ org.eclipse.jgit.util;version="[6.7.1,6.8.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 c51e94b..7a432fa 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.6.2.qualifier
-Eclipse-SourceBundle: org.eclipse.jgit.ssh.apache;version="6.6.2.qualifier";roots="."
+Bundle-Version: 6.7.1.qualifier
+Eclipse-SourceBundle: org.eclipse.jgit.ssh.apache;version="6.7.1.qualifier";roots="."
diff --git a/org.eclipse.jgit.ssh.apache/README.md b/org.eclipse.jgit.ssh.apache/README.md
index f06b2f6..b2911c6 100644
--- a/org.eclipse.jgit.ssh.apache/README.md
+++ b/org.eclipse.jgit.ssh.apache/README.md
@@ -73,7 +73,8 @@
 * **IdentityAgent** can be set to choose which SSH agent to use, if there are several running.
   It can also be set to `none` to explicitly switch off using an SSH agent at all.
 * **IdentitiesOnly** if set to `yes` and an SSH agent is used, only keys from the agent that are
-  also listed in an `IdentityFile` property will be considered. (It'll also switch off trying
+  also listed in an `IdentityFile` property and for which the public key is available in a
+  corresponding `*.pub` file will be considered. (It'll also switch off trying
   default key names, such as `~/.ssh/id_rsa` or `~/.ssh/id_ed25519`; only keys listed explicitly
   will be used.)
 
@@ -90,6 +91,57 @@
 not supported in JGit if its built-in SSH implementation is used. ed448 or other unsupported keys
 provided by an SSH agent are ignored.
 
+## PKCS#11 support
+
+JGit supports using PKCS#11 HSMs (Hardware Security Modules) such as YubiKey PIV for SSH
+authentication.
+
+Using such a PKCS#11 token for SSH authentication can be configured in `~/.ssh/config` with a
+configuration
+
+```
+  PCKS11Provider /absolute/path/to/vendor/library.so
+```
+
+instead of or in addition to `IdentityFile` or `IdentityAgent`. PKCS#11 keys are considered before
+keys from an SSH agent. If `IdentitiesOnly` is also set, only keys listed in `IdentityFile` for which
+the public key is available in a corresponding `*.pub` file are considered.
+
+If `PKCS11Provider` is not set, or is set to the value `none`, no PKCS#11 library is used.
+
+This is all as in OpenSSH.
+
+Keys from PKCS#11 tokens are never added to an SSH agent; the `AddKeysToAgent` configuration has
+no effect for PKCS#11 keys in JGit. It makes only sense if someone is using agent forwarding and
+it requires the SSH agent to understand the `SSH_AGENTC_ADD_SMARTCARD_KEY` command. It is unknown
+which SSH agents support this (OpenSSH does), the SSH library used by JGit has no API for it,
+and JGit doesn't do agent forwarding anyway. (To hop through servers to a git repository use
+`ProxyJump` instead.)
+
+JGit by default uses the first token (the default `slotListIndex` zero). The Java KeyStore or
+[Provider configuration](https://docs.oracle.com/en/java/javase/11/security/pkcs11-reference-guide1.html)
+does not seem to have any support for [RFC7512](https://www.rfc-editor.org/rfc/rfc7512) URIs
+to select the token. JGit provides a custom SSH configuration `PKCS11SlotListIndex` that can be
+set to the slot index of the token wanted. The value should be a non-negative integer. If not
+set or if negative, the first token (slot list index zero) is used. (Note that the value is the
+slot *index*, not the slot ID. Slot IDs are not necessarily stable.)
+
+If you *do* set `PKCS11SlotListIndex` anywhere in your configuration file, then you should also
+set at the very top of the `~/.ssh/config` file:
+
+```
+IgnoreUnknown PKCS11SlotListIndex
+```
+
+The `IgnoreUnknown` configuration tells OpenSSH to ignore configurations it doesn't know about.
+Without this option, OpenSSH will issue an error and exit if the config file contains
+`PKCS11SlotListIndex`. The `IgnoreUnknown` option is available in OpenSSH since version 6.3
+from 2013-09-13. See the [OpenSSH documentation](https://man.openbsd.org/ssh_config.5#IgnoreUnknown)
+for details.
+
+If a token has multiple certificates and keys, a specific one can be selected by exporting
+the public key to a file and then using `IdentitiesOnly` and an `IdentityFile` configuration.
+
 ## Using a different SSH implementation
 
 To use a different SSH implementation:
diff --git a/org.eclipse.jgit.ssh.apache/manual_tests.txt b/org.eclipse.jgit.ssh.apache/manual_tests.txt
new file mode 100644
index 0000000..ea3e59c
--- /dev/null
+++ b/org.eclipse.jgit.ssh.apache/manual_tests.txt
@@ -0,0 +1,45 @@
+Testing PKCS11 support
+----------------------
+
+# Install SoftHSM and OpenSC
+
+I got SoftHSM via MacPorts, and OpenSC from https://github.com/OpenSC/OpenSC#downloads
+
+You need both; softhsm2-util cannot import certificates.
+
+# Initialize SoftHSM
+
+$ softhsm2-util --init-token --slot 0 --label "TestToken" --pin 1234 --so-pin 4567
+The token has been initialized and is reassigned to slot 2006661923
+
+# Create a new RSA key and certificate
+
+$ openssl req -x509 -newkey rsa:4096 -keyout key.pem -out cert.pem -subj "/CN=MyCertTEST" -nodes
+
+# Import the RSA key pair into the SoftHSM token
+
+$ softhsm2-util --import key.pem --slot 2006661923 --label "testkey" --id 1212 --pin 1234
+
+# Convert the certificate to DER and import it into SoftHSM token
+
+$ openssl x509 -in cert.pem -out cert.der -outform DER
+$ pkcs11-tool --module /opt/local/lib/softhsm/libsofthsm2.so -l --id 1212 --label "testcert" -y cert -w cert.der --pin 1234
+
+# Export the RSA public key convert to PEM, and show in SSH format
+# (I'm sure this could be done simpler from the original key.pem, but what the heck.)
+
+pkcs11-tool --module /opt/local/lib/softhsm/libsofthsm2.so --slot 2006661923 --read-object --type pubkey --id 1212 -o key.der
+openssl rsa -pubin -inform DER -in key.der -outform PEM -out key.pub.pem
+ssh-keygen -f key.pub.pem -m pkcs8 -i
+
+# Install that public key at Gerrit (or your git server of choice)
+
+# Have an ~/.ssh/config with a host entry for your git server using the SoftHSM library as PKCS11 provider:
+
+Host gitserver
+Hostname git.eclipse.org
+Port 29418
+User ...
+PKCS11Provider /opt/local/lib/softhsm/libsofthsm2.so
+
+# Fetch from your git server! When asked for the PIN, enter 1234.
diff --git a/org.eclipse.jgit.ssh.apache/pom.xml b/org.eclipse.jgit.ssh.apache/pom.xml
index 47bda2e..9702f55 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.6.2-SNAPSHOT</version>
+    <version>6.7.1-SNAPSHOT</version>
   </parent>
 
   <artifactId>org.eclipse.jgit.ssh.apache</artifactId>
diff --git a/org.eclipse.jgit.ssh.apache/resources/org/eclipse/jgit/internal/transport/sshd/SshdText.properties b/org.eclipse.jgit.ssh.apache/resources/org/eclipse/jgit/internal/transport/sshd/SshdText.properties
index c676221..7da7181 100644
--- a/org.eclipse.jgit.ssh.apache/resources/org/eclipse/jgit/internal/transport/sshd/SshdText.properties
+++ b/org.eclipse.jgit.ssh.apache/resources/org/eclipse/jgit/internal/transport/sshd/SshdText.properties
@@ -32,17 +32,17 @@
 gssapiInitFailure=GSS-API initialization failure for mechanism {0}
 gssapiUnexpectedMechanism=Server {0} replied with unknown mechanism name ''{1}'' in {2} authentication
 gssapiUnexpectedMessage=Received unexpected ssh message {1} in {0} authentication
-identityFileCannotDecrypt=Given passphrase cannot decrypt identity {0}
+identityFileCannotDecrypt=Given passphrase cannot read identity {0}
 identityFileNoKey=No keys found in identity {0}
 identityFileMultipleKeys=Multiple key pairs found in identity {0}
 identityFileNotFound=Skipping identity ''{0}'': file not found
 identityFileUnsupportedFormat=Unsupported format in identity {0}
 invalidSignatureAlgorithm=Signature algorithm ''{0}'' is not valid for a key of type ''{1}''
 kexServerKeyInvalid=Server key did not validate
-keyEncryptedMsg=Key ''{0}'' is encrypted. Enter the passphrase to decrypt it.
+keyEncryptedMsg=''{0}'' needs a passphrase to be read.
 keyEncryptedPrompt=Passphrase
-keyEncryptedRetry=Encrypted key ''{0}'' could not be decrypted. Enter the passphrase again.
-keyLoadFailed=Could not load key ''{0}''
+keyEncryptedRetry=''{0}'' could not be read. Enter the passphrase again.
+keyLoadFailed=Could not load ''{0}''
 knownHostsCouldNotUpdate=Could not update known hosts file {0}
 knownHostsFileLockedUpdate=Could not update known hosts file (locked) {0}
 knownHostsFileReadFailed=Failed to read known hosts file {0}
@@ -69,6 +69,14 @@
 knownHostsUserAskCreationPrompt=Create file {0} ?
 loginDenied=Cannot log in at {0}:{1}
 passwordPrompt=Password
+pkcs11Error=ERROR: {0}
+pkcs11FailedInstantiation=HostConfig for host {0} (hostname {1}): could not instantiate {2} {3}
+pkcs11GeneralMessage=Java reported for PKCS#11 token {0}: {1}
+pkcs11NoKeys=HostConfig for host {0} (hostname {1}) {2} {3} did not provide any keys
+pkcs11NonExisting=HostConfig for host {0} (hostname {1}) {2} {3} does not exist or is not a file
+pkcs11NotAbsolute=HostConfig for host {0} (hostname {1}) {2} {3} is not an absolute path
+pkcs11Unsupported=HostConfig for host {0} (hostname {1}) {2} {3}: PKCS#11 is not supported
+pkcs11Warning=WARNING: {0}
 proxyCannotAuthenticate=Cannot authenticate to proxy {0}
 proxyHttpFailure=HTTP Proxy connection to {0} failed with code {1}: {2}
 proxyHttpInvalidUserName=HTTP proxy connection {0} with invalid user name; must not contain colons: {1}
diff --git a/org.eclipse.jgit.ssh.apache/src/org/eclipse/jgit/internal/transport/sshd/JGitClientSession.java b/org.eclipse.jgit.ssh.apache/src/org/eclipse/jgit/internal/transport/sshd/JGitClientSession.java
index 5100bc9..c19a04d 100644
--- a/org.eclipse.jgit.ssh.apache/src/org/eclipse/jgit/internal/transport/sshd/JGitClientSession.java
+++ b/org.eclipse.jgit.ssh.apache/src/org/eclipse/jgit/internal/transport/sshd/JGitClientSession.java
@@ -27,6 +27,7 @@
 import java.util.Map;
 import java.util.Objects;
 import java.util.Set;
+import java.util.function.Supplier;
 
 import org.apache.sshd.client.ClientBuilder;
 import org.apache.sshd.client.ClientFactoryManager;
@@ -55,6 +56,7 @@
 import org.eclipse.jgit.internal.transport.sshd.proxy.StatefulProxyConnector;
 import org.eclipse.jgit.transport.CredentialsProvider;
 import org.eclipse.jgit.transport.SshConstants;
+import org.eclipse.jgit.transport.sshd.KeyPasswordProvider;
 import org.eclipse.jgit.util.StringUtils;
 
 /**
@@ -69,6 +71,12 @@
 public class JGitClientSession extends ClientSessionImpl {
 
 	/**
+	 * Attribute set by {@link JGitSshClient} to make the
+	 * {@link KeyPasswordProvider} factory accessible via the session.
+	 */
+	public static final AttributeKey<Supplier<KeyPasswordProvider>> KEY_PASSWORD_PROVIDER_FACTORY = new AttributeKey<>();
+
+	/**
 	 * Default setting for the maximum number of bytes to read in the initial
 	 * protocol version exchange. 64kb is what OpenSSH &lt; 8.0 read; OpenSSH
 	 * 8.0 changed it to 8Mb, but that seems excessive for the purpose stated in
@@ -88,8 +96,11 @@
 
 	/**
 	 * @param manager
+	 *            client factory manager
 	 * @param session
+	 *            the session
 	 * @throws Exception
+	 *             an error occurred
 	 */
 	public JGitClientSession(ClientFactoryManager manager, IoSession session)
 			throws Exception {
diff --git a/org.eclipse.jgit.ssh.apache/src/org/eclipse/jgit/internal/transport/sshd/JGitPublicKeyAuthentication.java b/org.eclipse.jgit.ssh.apache/src/org/eclipse/jgit/internal/transport/sshd/JGitPublicKeyAuthentication.java
index e2da799..eb55ec0 100644
--- a/org.eclipse.jgit.ssh.apache/src/org/eclipse/jgit/internal/transport/sshd/JGitPublicKeyAuthentication.java
+++ b/org.eclipse.jgit.ssh.apache/src/org/eclipse/jgit/internal/transport/sshd/JGitPublicKeyAuthentication.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2018, 2022 Thomas Wolf <thomas.wolf@paranor.ch> and others
+ * Copyright (C) 2018, 2023 Thomas Wolf <twolf@apache.org> and others
  *
  * This program and the accompanying materials are made available under the
  * terms of the Eclipse Distribution License v. 1.0 which is available at
@@ -10,8 +10,12 @@
 package org.eclipse.jgit.internal.transport.sshd;
 
 import static java.text.MessageFormat.format;
+import static org.eclipse.jgit.transport.SshConstants.NONE;
+import static org.eclipse.jgit.transport.SshConstants.PKCS11_PROVIDER;
+import static org.eclipse.jgit.transport.SshConstants.PKCS11_SLOT_LIST_INDEX;
 import static org.eclipse.jgit.transport.SshConstants.PUBKEY_ACCEPTED_ALGORITHMS;
 
+import java.io.File;
 import java.io.IOException;
 import java.net.URISyntaxException;
 import java.nio.file.Files;
@@ -25,6 +29,7 @@
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.Collection;
+import java.util.Collections;
 import java.util.Iterator;
 import java.util.List;
 import java.util.Map;
@@ -49,19 +54,25 @@
 import org.apache.sshd.common.config.keys.u2f.SecurityKeyPublicKey;
 import org.apache.sshd.common.signature.Signature;
 import org.apache.sshd.common.signature.SignatureFactoriesManager;
+import org.apache.sshd.common.util.GenericUtils;
 import org.eclipse.jgit.internal.transport.ssh.OpenSshConfigFile;
+import org.eclipse.jgit.internal.transport.sshd.pkcs11.Pkcs11Provider;
 import org.eclipse.jgit.transport.CredentialItem;
 import org.eclipse.jgit.transport.CredentialsProvider;
 import org.eclipse.jgit.transport.SshConstants;
 import org.eclipse.jgit.transport.URIish;
+import org.eclipse.jgit.util.FS;
 import org.eclipse.jgit.util.StringUtils;
 
 /**
  * Custom {@link UserAuthPublicKey} implementation for handling SSH config
- * PubkeyAcceptedAlgorithms and interaction with the SSH agent.
+ * PubkeyAcceptedAlgorithms and interaction with the SSH agent and PKCS11
+ * providers.
  */
 public class JGitPublicKeyAuthentication extends UserAuthPublicKey {
 
+	private static final String LOG_FORMAT = "{}"; //$NON-NLS-1$
+
 	private SshAgent agent;
 
 	private HostConfigEntry hostConfig;
@@ -102,7 +113,7 @@
 				super.init(session, service);
 				return;
 			}
-			log.warn(format(SshdText.get().configNoKnownAlgorithms,
+			log.warn(LOG_FORMAT, format(SshdText.get().configNoKnownAlgorithms,
 					PUBKEY_ACCEPTED_ALGORITHMS, pubkeyAlgos));
 		}
 		// TODO: remove this once we're on an sshd version that has SSHD-1272
@@ -181,7 +192,7 @@
 				} catch (IOException e) {
 					// Do not re-throw: we don't want authentication to fail if
 					// we cannot add the key to the agent.
-					log.error(
+					log.error(LOG_FORMAT,
 							format(SshdText.get().pubkeyAuthAddKeyToAgentError,
 									keyType, fingerprint),
 							e);
@@ -303,13 +314,6 @@
 
 	private class KeyIterator extends UserAuthPublicKeyIterator {
 
-		private Iterable<? extends Map.Entry<PublicKey, String>> agentKeys;
-
-		// If non-null, all the public keys from explicitly given key files. Any
-		// agent key not matching one of these public keys will be ignored in
-		// getIdentities().
-		private Collection<PublicKey> identityFiles;
-
 		public KeyIterator(ClientSession session,
 				SignatureFactoriesManager manager)
 				throws Exception {
@@ -331,7 +335,8 @@
 					}
 				} catch (InvalidPathException | IOException
 						| GeneralSecurityException e) {
-					log.warn(format(SshdText.get().cannotReadPublicKey, s), e);
+					log.warn("{}", //$NON-NLS-1$
+							format(SshdText.get().cannotReadPublicKey, s), e);
 				}
 				return null;
 			}).filter(Objects::nonNull).collect(Collectors.toList());
@@ -340,36 +345,40 @@
 		@Override
 		protected Iterable<KeyAgentIdentity> initializeAgentIdentities(
 				ClientSession session) throws IOException {
-			if (agent == null) {
+			Iterable<KeyAgentIdentity> allAgentKeys = getAgentIdentities();
+			if (allAgentKeys == null) {
 				return null;
 			}
-			agentKeys = agent.getIdentities();
-			if (hostConfig != null && hostConfig.isIdentitiesOnly()) {
-				identityFiles = getExplicitKeys(hostConfig.getIdentities());
+			Collection<PublicKey> identityFiles = identitiesOnly();
+			if (GenericUtils.isEmpty(identityFiles)) {
+				return allAgentKeys;
 			}
+
+			// Only consider agent or PKCS11 keys that match a known public key
+			// file.
 			return () -> new Iterator<>() {
 
-				private final Iterator<? extends Map.Entry<PublicKey, String>> iter = agentKeys
+				private final Iterator<KeyAgentIdentity> identities = allAgentKeys
 						.iterator();
 
-				private Map.Entry<PublicKey, String> next;
+				private KeyAgentIdentity next;
 
 				@Override
 				public boolean hasNext() {
-					while (next == null && iter.hasNext()) {
-						Map.Entry<PublicKey, String> val = iter.next();
-						PublicKey pk = val.getKey();
+					while (next == null && identities.hasNext()) {
+						KeyAgentIdentity val = identities.next();
+						PublicKey pk = val.getKeyIdentity().getPublic();
 						// This checks against all explicit keys for any agent
 						// key, but since identityFiles.size() is typically 1,
 						// it should be fine.
-						if (identityFiles == null || identityFiles.stream()
+						if (identityFiles.stream()
 								.anyMatch(k -> KeyUtils.compareKeys(k, pk))) {
 							next = val;
 							return true;
 						}
 						if (log.isTraceEnabled()) {
 							log.trace(
-									"Ignoring SSH agent {} key not in explicit IdentityFile in SSH config: {}", //$NON-NLS-1$
+									"Ignoring SSH agent or PKCS11 {} key not in explicit IdentityFile in SSH config: {}", //$NON-NLS-1$
 									KeyUtils.getKeyType(pk),
 									KeyUtils.getFingerPrint(pk));
 						}
@@ -382,12 +391,157 @@
 					if (!hasNext()) {
 						throw new NoSuchElementException();
 					}
-					KeyAgentIdentity result = new KeyAgentIdentity(agent,
-							next.getKey(), next.getValue());
+					KeyAgentIdentity result = next;
 					next = null;
 					return result;
 				}
 			};
 		}
+
+		private Collection<PublicKey> identitiesOnly() {
+			if (hostConfig != null && hostConfig.isIdentitiesOnly()) {
+				return getExplicitKeys(hostConfig.getIdentities());
+			}
+			return Collections.emptyList();
+		}
+
+		private Iterable<KeyAgentIdentity> getAgentIdentities()
+				throws IOException {
+			Iterable<KeyAgentIdentity> pkcs11Keys = getPkcs11Keys();
+			if (agent == null) {
+				return pkcs11Keys;
+			}
+			Iterable<? extends Map.Entry<PublicKey, String>> agentKeys = agent
+					.getIdentities();
+			if (GenericUtils.isEmpty(agentKeys)) {
+				return pkcs11Keys;
+			}
+			Iterable<KeyAgentIdentity> fromAgent = () -> new Iterator<>() {
+
+				private final Iterator<? extends Map.Entry<PublicKey, String>> iter = agentKeys
+						.iterator();
+
+				@Override
+				public boolean hasNext() {
+					return iter.hasNext();
+				}
+
+				@Override
+				public KeyAgentIdentity next() {
+					Map.Entry<PublicKey, String> next = iter.next();
+					return new KeyAgentIdentity(agent, next.getKey(),
+							next.getValue());
+				}
+			};
+			if (GenericUtils.isEmpty(pkcs11Keys)) {
+				return fromAgent;
+			}
+			return () -> new Iterator<>() {
+
+				private final Iterator<Iterator<KeyAgentIdentity>> keyIter = List
+						.of(pkcs11Keys.iterator(), fromAgent.iterator())
+						.iterator();
+
+				private Iterator<KeyAgentIdentity> currentKeys;
+
+				private Boolean hasElement;
+
+				@Override
+				public boolean hasNext() {
+					if (hasElement != null) {
+						return hasElement.booleanValue();
+					}
+					while (currentKeys == null || !currentKeys.hasNext()) {
+						if (keyIter.hasNext()) {
+							currentKeys = keyIter.next();
+						} else {
+							currentKeys = null;
+							hasElement = Boolean.FALSE;
+							return false;
+						}
+					}
+					hasElement = Boolean.TRUE;
+					return true;
+				}
+
+				@Override
+				public KeyAgentIdentity next() {
+					if ((hasElement == null && !hasNext())
+							|| !hasElement.booleanValue()) {
+						throw new NoSuchElementException();
+					}
+					hasElement = null;
+					KeyAgentIdentity result;
+					try {
+						result = currentKeys.next();
+					} catch (NoSuchElementException e) {
+						result = null;
+					}
+					return result;
+				}
+			};
+		}
+
+		private Iterable<KeyAgentIdentity> getPkcs11Keys() throws IOException {
+			String value = hostConfig.getProperty(PKCS11_PROVIDER);
+			if (StringUtils.isEmptyOrNull(value) || NONE.equals(value)) {
+				return null;
+			}
+			if (value.startsWith("~/") //$NON-NLS-1$
+					|| value.startsWith('~' + File.separator)) {
+				value = new File(FS.DETECTED.userHome(), value.substring(2))
+						.toString();
+			}
+			Path library = Paths.get(value);
+			if (!library.isAbsolute()) {
+				throw new IOException(format(SshdText.get().pkcs11NotAbsolute,
+						hostConfig.getHost(), hostConfig.getHostName(),
+						PKCS11_PROVIDER, value));
+			}
+			if (!Files.isRegularFile(library)) {
+				throw new IOException(format(SshdText.get().pkcs11NonExisting,
+						hostConfig.getHost(), hostConfig.getHostName(),
+						PKCS11_PROVIDER, value));
+			}
+			try {
+				int slotListIndex = OpenSshConfigFile.positive(
+						hostConfig.getProperty(PKCS11_SLOT_LIST_INDEX));
+				Pkcs11Provider provider = Pkcs11Provider.getProvider(library,
+						slotListIndex);
+				if (provider == null) {
+					throw new UnsupportedOperationException();
+				}
+				Iterable<KeyAgentIdentity> pkcs11Identities = provider
+						.getKeys(getSession());
+				if (GenericUtils.isEmpty(pkcs11Identities)) {
+					log.warn(LOG_FORMAT, format(SshdText.get().pkcs11NoKeys,
+							hostConfig.getHost(), hostConfig.getHostName(),
+							PKCS11_PROVIDER, value));
+					return null;
+				}
+				return pkcs11Identities;
+			} catch (UnsupportedOperationException e) {
+				throw new UnsupportedOperationException(format(
+						SshdText.get().pkcs11Unsupported, hostConfig.getHost(),
+						hostConfig.getHostName(), PKCS11_PROVIDER, value), e);
+			} catch (Exception e) {
+				checkCancellation(e);
+				throw new IOException(
+						format(SshdText.get().pkcs11FailedInstantiation,
+								hostConfig.getHost(), hostConfig.getHostName(),
+								PKCS11_PROVIDER, value),
+						e);
+			}
+		}
+
+		private void checkCancellation(Throwable e) {
+			Throwable t = e;
+			while (t != null) {
+				if (t instanceof AuthenticationCanceledException) {
+					throw (AuthenticationCanceledException) t;
+				}
+				t = t.getCause();
+			}
+		}
 	}
 }
diff --git a/org.eclipse.jgit.ssh.apache/src/org/eclipse/jgit/internal/transport/sshd/JGitSshClient.java b/org.eclipse.jgit.ssh.apache/src/org/eclipse/jgit/internal/transport/sshd/JGitSshClient.java
index 311cf19..6e9bd62 100644
--- a/org.eclipse.jgit.ssh.apache/src/org/eclipse/jgit/internal/transport/sshd/JGitSshClient.java
+++ b/org.eclipse.jgit.ssh.apache/src/org/eclipse/jgit/internal/transport/sshd/JGitSshClient.java
@@ -32,6 +32,7 @@
 import java.util.Map;
 import java.util.NoSuchElementException;
 import java.util.Objects;
+import java.util.function.Supplier;
 import java.util.stream.Collectors;
 
 import org.apache.sshd.client.SshClient;
@@ -58,6 +59,7 @@
 import org.eclipse.jgit.transport.CredentialsProvider;
 import org.eclipse.jgit.transport.SshConstants;
 import org.eclipse.jgit.transport.sshd.KeyCache;
+import org.eclipse.jgit.transport.sshd.KeyPasswordProvider;
 import org.eclipse.jgit.transport.sshd.ProxyData;
 import org.eclipse.jgit.transport.sshd.ProxyDataFactory;
 import org.eclipse.jgit.util.StringUtils;
@@ -103,6 +105,8 @@
 
 	private CredentialsProvider credentialsProvider;
 
+	private Supplier<KeyPasswordProvider> keyPasswordProviderFactory;
+
 	private ProxyDataFactory proxyDatabase;
 
 	@Override
@@ -277,6 +281,8 @@
 		}
 		int numberOfPasswordPrompts = getNumberOfPasswordPrompts(hostConfig);
 		PASSWORD_PROMPTS.set(session, Integer.valueOf(numberOfPasswordPrompts));
+		session.setAttribute(JGitClientSession.KEY_PASSWORD_PROVIDER_FACTORY,
+				getKeyPasswordProviderFactory());
 		List<Path> identities = hostConfig.getIdentities().stream()
 				.map(s -> {
 					try {
@@ -374,6 +380,26 @@
 	}
 
 	/**
+	 * Sets a supplier for a {@link KeyPasswordProvider} for this client.
+	 *
+	 * @param factory
+	 *            to set
+	 */
+	public void setKeyPasswordProviderFactory(
+			Supplier<KeyPasswordProvider> factory) {
+		keyPasswordProviderFactory = factory;
+	}
+
+	/**
+	 * Retrieves the {@link KeyPasswordProvider} factory of this client.
+	 *
+	 * @return a factory to create {@link KeyPasswordProvider}s
+	 */
+	public Supplier<KeyPasswordProvider> getKeyPasswordProviderFactory() {
+		return keyPasswordProviderFactory;
+	}
+
+	/**
 	 * A {@link SessionFactory} to create our own specialized
 	 * {@link JGitClientSession}s.
 	 */
diff --git a/org.eclipse.jgit.ssh.apache/src/org/eclipse/jgit/internal/transport/sshd/KnownHostEntryReader.java b/org.eclipse.jgit.ssh.apache/src/org/eclipse/jgit/internal/transport/sshd/KnownHostEntryReader.java
index 7931c76..a00e5d9 100644
--- a/org.eclipse.jgit.ssh.apache/src/org/eclipse/jgit/internal/transport/sshd/KnownHostEntryReader.java
+++ b/org.eclipse.jgit.ssh.apache/src/org/eclipse/jgit/internal/transport/sshd/KnownHostEntryReader.java
@@ -34,9 +34,9 @@
 
 /**
  * Apache MINA sshd 2.0.0 KnownHostEntry cannot read a host entry line like
- * "host:port ssh-rsa <key>"; it complains about an illegal character in the
- * host name (correct would be "[host]:port"). The default known_hosts reader
- * also aborts reading on the first error.
+ * "host:port ssh-rsa &lt;key&gt;"; it complains about an illegal character in
+ * the host name (correct would be "[host]:port"). The default known_hosts
+ * reader also aborts reading on the first error.
  * <p>
  * This reader is a bit more robust and tries to handle this case if there is
  * only one colon (otherwise it might be an IPv6 address (without port)), and it
diff --git a/org.eclipse.jgit.ssh.apache/src/org/eclipse/jgit/internal/transport/sshd/OpenSshServerKeyDatabase.java b/org.eclipse.jgit.ssh.apache/src/org/eclipse/jgit/internal/transport/sshd/OpenSshServerKeyDatabase.java
index d8bf449..65ba5be 100644
--- a/org.eclipse.jgit.ssh.apache/src/org/eclipse/jgit/internal/transport/sshd/OpenSshServerKeyDatabase.java
+++ b/org.eclipse.jgit.ssh.apache/src/org/eclipse/jgit/internal/transport/sshd/OpenSshServerKeyDatabase.java
@@ -74,7 +74,6 @@
  * ignored.
  * <p>
  * {@code StrictHostKeyChecking} accepts the following values:
- * </p>
  * <dl>
  * <dt>ask</dt>
  * <dd>Ask the user whether new or changed keys shall be accepted and be added
@@ -91,7 +90,6 @@
  * <p>
  * If {@code StrictHostKeyChecking} is not set, or set to any other value, the
  * default value <b>ask</b> is active.
- * </p>
  * <p>
  * This implementation relies on the {@link ClientSession} being a
  * {@link JGitClientSession}. By default Apache MINA sshd does not forward the
@@ -100,23 +98,19 @@
  * used. If used with some other session type, the implementation assumes
  * "<b>ask</b>".
  * <p>
- * <p>
  * Asking the user is done via a {@link CredentialsProvider} obtained from the
  * session. If none is set, the implementation falls back to strict host key
  * checking ("<b>yes</b>").
- * </p>
  * <p>
  * Note that adding a key to the known hosts file may create the file. You can
  * specify in the constructor whether the user shall be asked about that, too.
  * If the user declines updating the file, but the key was otherwise
  * accepted (user confirmed for "<b>ask</b>", or "no" or "accept-new" are
  * active), the key is accepted for this session only.
- * </p>
  * <p>
  * If several known hosts files are specified, a new key is always added to the
  * first file (even if it doesn't exist yet; see the note about file creation
  * above).
- * </p>
  *
  * @see <a href="http://man.openbsd.org/OpenBSD-current/man5/ssh_config.5">man
  *      ssh-config</a>
diff --git a/org.eclipse.jgit.ssh.apache/src/org/eclipse/jgit/internal/transport/sshd/SshdText.java b/org.eclipse.jgit.ssh.apache/src/org/eclipse/jgit/internal/transport/sshd/SshdText.java
index 39332d9..34c73fc 100644
--- a/org.eclipse.jgit.ssh.apache/src/org/eclipse/jgit/internal/transport/sshd/SshdText.java
+++ b/org.eclipse.jgit.ssh.apache/src/org/eclipse/jgit/internal/transport/sshd/SshdText.java
@@ -90,6 +90,14 @@
 	/***/ public String knownHostsUserAskCreationPrompt;
 	/***/ public String loginDenied;
 	/***/ public String passwordPrompt;
+	/***/ public String pkcs11Error;
+	/***/ public String pkcs11FailedInstantiation;
+	/***/ public String pkcs11GeneralMessage;
+	/***/ public String pkcs11NoKeys;
+	/***/ public String pkcs11NonExisting;
+	/***/ public String pkcs11NotAbsolute;
+	/***/ public String pkcs11Unsupported;
+	/***/ public String pkcs11Warning;
 	/***/ public String proxyCannotAuthenticate;
 	/***/ public String proxyHttpFailure;
 	/***/ public String proxyHttpInvalidUserName;
diff --git a/org.eclipse.jgit.ssh.apache/src/org/eclipse/jgit/internal/transport/sshd/pkcs11/Pkcs11Provider.java b/org.eclipse.jgit.ssh.apache/src/org/eclipse/jgit/internal/transport/sshd/pkcs11/Pkcs11Provider.java
new file mode 100644
index 0000000..eefa3aa
--- /dev/null
+++ b/org.eclipse.jgit.ssh.apache/src/org/eclipse/jgit/internal/transport/sshd/pkcs11/Pkcs11Provider.java
@@ -0,0 +1,372 @@
+/*
+ * Copyright (C) 2023 Thomas Wolf <twolf@apache.org> and others
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Distribution License v. 1.0 which is available at
+ * https://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+package org.eclipse.jgit.internal.transport.sshd.pkcs11;
+
+import java.io.IOException;
+import java.nio.file.Path;
+import java.security.GeneralSecurityException;
+import java.security.KeyPair;
+import java.security.KeyStore;
+import java.security.PrivateKey;
+import java.security.Provider;
+import java.security.PublicKey;
+import java.security.Security;
+import java.security.Signature;
+import java.security.cert.Certificate;
+import java.security.cert.CertificateExpiredException;
+import java.security.cert.CertificateNotYetValidException;
+import java.security.cert.X509Certificate;
+import java.util.AbstractMap.SimpleImmutableEntry;
+import java.util.ArrayList;
+import java.util.Enumeration;
+import java.util.List;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.atomic.AtomicInteger;
+
+import javax.security.auth.login.FailedLoginException;
+
+import org.apache.sshd.agent.SshAgent;
+import org.apache.sshd.agent.SshAgentKeyConstraint;
+import org.apache.sshd.client.auth.pubkey.KeyAgentIdentity;
+import org.apache.sshd.common.session.SessionContext;
+import org.apache.sshd.common.signature.BuiltinSignatures;
+import org.eclipse.jgit.annotations.NonNull;
+import org.eclipse.jgit.transport.URIish;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Bridge for using a PKCS11 HSM (Hardware Security Module) for public-key
+ * authentication.
+ */
+public class Pkcs11Provider {
+
+	private static final Logger LOG = LoggerFactory
+			.getLogger(Pkcs11Provider.class);
+
+	/**
+	 * A dummy agent; exists only because
+	 * {@link KeyAgentIdentity#KeyAgentIdentity(SshAgent, PublicKey, String)} requires
+	 * a non-{@code null} {@link SshAgent}.
+	 */
+	private static final SshAgent NULL_AGENT = new SshAgent() {
+
+		@Override
+		public boolean isOpen() {
+			return true;
+		}
+
+		@Override
+		public void close() throws IOException {
+			// Nothing to do
+		}
+
+		@Override
+		public Iterable<? extends Entry<PublicKey, String>> getIdentities()
+				throws IOException {
+			throw new UnsupportedOperationException();
+		}
+
+		@Override
+		public Entry<String, byte[]> sign(SessionContext session, PublicKey key,
+				String algo, byte[] data) throws IOException {
+			throw new UnsupportedOperationException();
+		}
+
+		@Override
+		public void addIdentity(KeyPair key, String comment,
+				SshAgentKeyConstraint... constraints) throws IOException {
+			throw new UnsupportedOperationException();
+		}
+
+		@Override
+		public void removeIdentity(PublicKey key) throws IOException {
+			throw new UnsupportedOperationException();
+		}
+
+		@Override
+		public void removeAllIdentities() throws IOException {
+			throw new UnsupportedOperationException();
+		}
+
+	};
+
+	private static final Map<String, Pkcs11Provider> PROVIDERS = new ConcurrentHashMap<>();
+
+	private static final AtomicInteger COUNT = new AtomicInteger();
+
+	/**
+	 * Creates a new {@link Pkcs11Provider}.
+	 *
+	 * @param library
+	 *            {@link Path} to the library the SunPKCS11 provider shall use
+	 * @param slotListIndex
+	 *            index identifying the token; if &lt; 0, ignored and 0 is used
+	 * @return a new {@link Pkcs11Provider}, or {@code null} if SunPKCS11 is not
+	 *         available
+	 * @throws IOException
+	 *             if the configuration file cannot be created
+	 * @throws java.security.ProviderException
+	 *             if the Java {@link Provider} encounters a problem
+	 * @throws UnsupportedOperationException
+	 *             if PKCS#11 is unsupported
+	 */
+	public static Pkcs11Provider getProvider(@NonNull Path library,
+			int slotListIndex) throws IOException {
+		int slotIndex = slotListIndex < 0 ? 0 : slotListIndex;
+		Path libPath = library.toAbsolutePath();
+		String key = libPath.toString() + '/' + slotIndex;
+		return PROVIDERS.computeIfAbsent(key, sharedLib -> {
+			Provider pkcs11 = Security.getProvider("SunPKCS11"); //$NON-NLS-1$
+			if (pkcs11 == null) {
+				throw new UnsupportedOperationException();
+			}
+			// There must not be any spaces in the name.
+			String name = libPath.getFileName().toString().replaceAll("\\s", //$NON-NLS-1$
+					""); //$NON-NLS-1$
+			name = "JGit-" + slotIndex + '-' + name; //$NON-NLS-1$
+			// SunPKCS11 has a problem with paths containing multiple successive
+			// spaces; it collapses them to a single space.
+			//
+			// However, it also performs property expansion on these paths.
+			// (Seems to be an undocumented feature, though.) A reference like
+			// ${xyz} is replaced by system property "xyz". Use that to work
+			// around the rudimentary config parsing in SunPKCS11.
+			String property = "pkcs11-" + COUNT.incrementAndGet() + '-' + name; //$NON-NLS-1$
+			System.setProperty(property, libPath.toString());
+			// Undocumented feature of the SunPKCS11 provider: if the parameter
+			// to configure() starts with two dashes, it's not a file name but
+			// the configuration directly.
+			String config = "--" //$NON-NLS-1$
+					+ "name = " + name + '\n' //$NON-NLS-1$
+					+ "library = ${" + property + "}\n" //$NON-NLS-1$ //$NON-NLS-2$
+					+ "slotListIndex = " + slotIndex + '\n'; //$NON-NLS-1$
+			if (LOG.isDebugEnabled()) {
+				LOG.debug(
+						"{}: configuring provider with system property {}={} and config:{}{}", //$NON-NLS-1$
+						name, property, libPath, System.lineSeparator(),
+						config);
+			}
+			pkcs11 = pkcs11.configure(config);
+			// Produce an RFC7512 URI. Empty path, module-path must be in
+			// the query.
+			String path = "pkcs11:?module-path=" + libPath; //$NON-NLS-1$
+			if (slotListIndex > 0) {
+				// RFC7512 has nothing for the slot list index; pretend it
+				// was a vendor-specific query attribute.
+				path += "&slot-list-index=" + slotListIndex; //$NON-NLS-1$
+			}
+			SecurityCallback callback = new SecurityCallback(
+					new URIish().setPath(path));
+			return new Pkcs11Provider(pkcs11, callback);
+		});
+	}
+
+	private final Provider provider;
+
+	private final SecurityCallback prompter;
+
+	private final KeyStore.Builder builder;
+
+	private KeyStore keys;
+
+	private Pkcs11Provider(Provider pkcs11, SecurityCallback prompter) {
+		this.provider = pkcs11;
+		this.prompter = prompter;
+		this.builder = KeyStore.Builder.newInstance("PKCS11", provider, //$NON-NLS-1$
+				new KeyStore.CallbackHandlerProtection(prompter));
+	}
+
+	// Implementation note: With SoftHSM Java 11 asks for the PIN when the
+	// KeyStore is loaded, i.e., when the token is accessed. softhsm2-util,
+	// however, can list certificates and public keys without PIN entry, but
+	// needs a PIN to also list private keys. So it appears that different
+	// module libraries or possibly different KeyStore implementations may
+	// prompt either when accessing the token, or only when we try to actually
+	// sign something (i.e., when accessing a private key). It may also depend
+	// on the token itself; some tokens require early log-in.
+	//
+	// Therefore we initialize the prompter in both cases, even if it may be
+	// unused in one or the other operation.
+	//
+	// The price to pay is that sign() has to be synchronized, too, to avoid
+	// that different sessions step on each other's toes in the prompter.
+
+	private synchronized void load(SessionContext session)
+			throws GeneralSecurityException, IOException {
+		if (keys == null) {
+			int numberOfPrompts = prompter.init(session);
+			int attempt = 0;
+			while (attempt < numberOfPrompts) {
+				attempt++;
+				try {
+					if (LOG.isDebugEnabled()) {
+						LOG.debug(
+								"{}: Loading PKCS#11 KeyStore (attempt {})", //$NON-NLS-1$
+								getName(), Integer.toString(attempt));
+					}
+					keys = builder.getKeyStore();
+					prompter.passwordTried(null);
+					return;
+				} catch (GeneralSecurityException e) {
+					if (!prompter.passwordTried(e) || attempt >= numberOfPrompts
+							|| !isWrongPin(e)) {
+						throw e;
+					}
+				}
+			}
+		}
+	}
+
+	synchronized byte[] sign(SessionContext session, String algorithm,
+			String alias, byte[] data)
+			throws GeneralSecurityException, IOException {
+		int numberOfPrompts = prompter.init(session);
+		int attempt = 0;
+		while (attempt < numberOfPrompts) {
+			attempt++;
+			try {
+				if (LOG.isDebugEnabled()) {
+					LOG.debug(
+							"{}: Signing with PKCS#11 key {}, algorithm {} (attempt {})", //$NON-NLS-1$
+							getName(), alias, algorithm,
+							Integer.toString(attempt));
+				}
+				Signature signer = Signature.getInstance(algorithm, provider);
+				PrivateKey privKey = (PrivateKey) keys.getKey(alias, null);
+				signer.initSign(privKey);
+				signer.update(data);
+				byte[] signature = signer.sign();
+				prompter.passwordTried(null);
+				return signature;
+			} catch (GeneralSecurityException e) {
+				if (!prompter.passwordTried(e) || attempt >= numberOfPrompts
+						|| !isWrongPin(e)) {
+					throw e;
+				}
+			}
+		}
+		return null;
+	}
+
+	private boolean isWrongPin(Throwable e) {
+		Throwable t = e;
+		while (t != null) {
+			if (t instanceof FailedLoginException) {
+				return true;
+			}
+			t = t.getCause();
+		}
+		return false;
+	}
+
+	/**
+	 * Retrieves an identifying name of this {@link Pkcs11Provider}.
+	 *
+	 * @return the name
+	 */
+	public String getName() {
+		return provider.getName();
+	}
+
+	/**
+	 * Obtains the identities provided by the PKCS11 library.
+	 *
+	 * @param session
+	 *            in which we to load the identities
+	 * @return all the available identities
+	 * @throws IOException
+	 *             if keys cannot be accessed
+	 * @throws GeneralSecurityException
+	 *             if keys cannot be accessed
+	 */
+	public Iterable<KeyAgentIdentity> getKeys(SessionContext session)
+			throws IOException, GeneralSecurityException {
+		// Get all public keys from the KeyStore.
+		load(session);
+		List<KeyAgentIdentity> result = new ArrayList<>(2);
+		Enumeration<String> aliases = keys.aliases();
+		while (aliases.hasMoreElements()) {
+			String alias = aliases.nextElement();
+			Certificate certificate = keys.getCertificate(alias);
+			if (certificate == null) {
+				continue;
+			}
+			PublicKey pubKey = certificate.getPublicKey();
+			if (pubKey == null) {
+				// This should never happen
+				if (LOG.isDebugEnabled()) {
+					LOG.debug("{}: certificate {} has no public key??", //$NON-NLS-1$
+							getName(), alias);
+				}
+				continue;
+			}
+			if (LOG.isDebugEnabled()) {
+				if (certificate instanceof X509Certificate) {
+					X509Certificate x509 = (X509Certificate) certificate;
+					// OpenSSH does not seem to check certificate validity?
+					String msg;
+					try {
+						x509.checkValidity();
+						msg = "Certificate is valid"; //$NON-NLS-1$
+					} catch (CertificateExpiredException
+							| CertificateNotYetValidException e) {
+						msg = "Certificate is INVALID"; //$NON-NLS-1$
+					}
+					// OpenSSh explicitly also considers private keys not
+					// intended for signing, see
+					// https://bugzilla.mindrot.org/show_bug.cgi?id=1736 .
+					boolean[] usage = x509.getKeyUsage();
+					if (usage != null) {
+						// We have no access to the PKCS#11 flags on the key, so
+						// report the certificate flag, if present.
+						msg += ", signing " //$NON-NLS-1$
+								+ (usage[0] ? "allowed" : "NOT allowed"); //$NON-NLS-1$ //$NON-NLS-2$
+					}
+					LOG.debug(
+							"{}: Loaded X.509 certificate {}, key type {}. {}.", //$NON-NLS-1$
+							getName(), alias, pubKey.getAlgorithm(), msg);
+				} else {
+					LOG.debug("{}: Loaded certificate {}, key type {}.", //$NON-NLS-1$
+							getName(), alias, pubKey.getAlgorithm());
+				}
+			}
+			result.add(new Pkcs11Identity(pubKey, alias));
+		}
+		return result;
+	}
+
+	// We use a KeyAgentIdentity because we want to hide the private key.
+	//
+	// JGit doesn't do Agent forwarding, so there will never be any reason to
+	// add a PKCS11 key/token to an agent.
+	private class Pkcs11Identity extends KeyAgentIdentity {
+
+		Pkcs11Identity(PublicKey key, String alias) {
+			super(NULL_AGENT, key, alias);
+		}
+
+		@Override
+		public Entry<String, byte[]> sign(SessionContext session, String algo,
+				byte[] data) throws Exception {
+			// Find the built-in signature factory for the algorithm
+			BuiltinSignatures factory = BuiltinSignatures.fromFactoryName(algo);
+			// Get its Java signature algorithm name from that
+			String javaSignatureName = factory.create().getAlgorithm();
+			// We cannot use the Signature created by the factory -- we need a
+			// provider-specific Signature instance.
+			return new SimpleImmutableEntry<>(algo,
+					Pkcs11Provider.this.sign(session, javaSignatureName,
+							getComment(), data));
+		}
+	}
+}
diff --git a/org.eclipse.jgit.ssh.apache/src/org/eclipse/jgit/internal/transport/sshd/pkcs11/SecurityCallback.java b/org.eclipse.jgit.ssh.apache/src/org/eclipse/jgit/internal/transport/sshd/pkcs11/SecurityCallback.java
new file mode 100644
index 0000000..334a8ca
--- /dev/null
+++ b/org.eclipse.jgit.ssh.apache/src/org/eclipse/jgit/internal/transport/sshd/pkcs11/SecurityCallback.java
@@ -0,0 +1,246 @@
+/*
+ * Copyright (C) 2023 Thomas Wolf <twolf@apache.org> and others
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Distribution License v. 1.0 which is available at
+ * https://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+package org.eclipse.jgit.internal.transport.sshd.pkcs11;
+
+import static java.text.MessageFormat.format;
+import static org.apache.sshd.core.CoreModuleProperties.PASSWORD_PROMPTS;
+
+import java.io.IOException;
+import java.security.GeneralSecurityException;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+import java.util.Locale;
+import java.util.function.Supplier;
+
+import javax.security.auth.callback.Callback;
+import javax.security.auth.callback.CallbackHandler;
+import javax.security.auth.callback.ChoiceCallback;
+import javax.security.auth.callback.ConfirmationCallback;
+import javax.security.auth.callback.LanguageCallback;
+import javax.security.auth.callback.PasswordCallback;
+import javax.security.auth.callback.TextInputCallback;
+import javax.security.auth.callback.TextOutputCallback;
+import javax.security.auth.callback.UnsupportedCallbackException;
+
+import org.apache.sshd.common.session.SessionContext;
+import org.eclipse.jgit.internal.transport.sshd.AuthenticationCanceledException;
+import org.eclipse.jgit.internal.transport.sshd.JGitClientSession;
+import org.eclipse.jgit.internal.transport.sshd.SshdText;
+import org.eclipse.jgit.transport.CredentialItem;
+import org.eclipse.jgit.transport.CredentialsProvider;
+import org.eclipse.jgit.transport.URIish;
+import org.eclipse.jgit.transport.sshd.KeyPasswordProvider;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * A bridge to the JGit {@link CredentialsProvider}.
+ */
+public class SecurityCallback implements CallbackHandler {
+
+	private static final Logger LOG = LoggerFactory
+			.getLogger(SecurityCallback.class);
+
+	private final URIish uri;
+
+	private KeyPasswordProvider passwordProvider;
+
+	private CredentialsProvider credentialsProvider;
+
+	private int attempts = 0;
+
+	/**
+	 * Creates a new {@link SecurityCallback}.
+	 *
+	 * @param uri
+	 *            {@link URIish} identifying the item the interaction is about
+	 */
+	public SecurityCallback(URIish uri) {
+		this.uri = uri;
+	}
+
+	/**
+	 * Initializes this {@link SecurityCallback} for the given session.
+	 *
+	 * @param session
+	 *            {@link SessionContext} of the keystore access
+	 * @return the number of PIN prompts to try to log-in to the token
+	 */
+	public int init(SessionContext session) {
+		int numberOfAttempts = PASSWORD_PROMPTS.getRequired(session).intValue();
+		Supplier<KeyPasswordProvider> factory = session
+				.getAttribute(JGitClientSession.KEY_PASSWORD_PROVIDER_FACTORY);
+		if (factory == null) {
+			passwordProvider = null;
+		} else {
+			passwordProvider = factory.get();
+			passwordProvider.setAttempts(numberOfAttempts);
+		}
+		attempts = 0;
+		if (session instanceof JGitClientSession) {
+			credentialsProvider = ((JGitClientSession) session)
+					.getCredentialsProvider();
+		} else {
+			credentialsProvider = null;
+		}
+		return numberOfAttempts;
+	}
+
+	/**
+	 * Tells this {@link SecurityCallback} that an attempt to load something
+	 * from the key store has been made.
+	 *
+	 * @param error
+	 *            an {@link Exception} that may have occurred, or {@code null}
+	 *            on success
+	 * @return whether to try once more
+	 * @throws IOException
+	 *             on errors
+	 * @throws GeneralSecurityException
+	 *             on errors
+	 */
+	public boolean passwordTried(Exception error)
+			throws IOException, GeneralSecurityException {
+		if (attempts > 0 && passwordProvider != null) {
+			return passwordProvider.keyLoaded(uri, attempts, error);
+		}
+		return true;
+	}
+
+	@Override
+	public void handle(Callback[] callbacks)
+			throws IOException, UnsupportedCallbackException {
+		if (callbacks.length == 1 && callbacks[0] instanceof PasswordCallback
+				&& passwordProvider != null) {
+			PasswordCallback p = (PasswordCallback) callbacks[0];
+			char[] password = passwordProvider.getPassphrase(uri, attempts++);
+			if (password == null || password.length == 0) {
+				throw new AuthenticationCanceledException();
+			}
+			p.setPassword(password);
+			Arrays.fill(password, '\0');
+		} else {
+			handleGeneral(callbacks);
+		}
+	}
+
+	private void handleGeneral(Callback[] callbacks)
+			throws UnsupportedCallbackException {
+		List<CredentialItem> items = new ArrayList<>();
+		List<Runnable> updaters = new ArrayList<>();
+		for (int i = 0; i < callbacks.length; i++) {
+			Callback c = callbacks[i];
+			if (c instanceof TextOutputCallback) {
+				TextOutputCallback t = (TextOutputCallback) c;
+				String msg = getText(t.getMessageType(), t.getMessage());
+				if (credentialsProvider == null) {
+					LOG.warn("{}", format(SshdText.get().pkcs11GeneralMessage, //$NON-NLS-1$
+							uri, msg));
+				} else {
+					CredentialItem.InformationalMessage item =
+							new CredentialItem.InformationalMessage(msg);
+					items.add(item);
+				}
+			} else if (c instanceof TextInputCallback) {
+				if (credentialsProvider == null) {
+					throw new UnsupportedOperationException(
+							"No CredentialsProvider " + uri); //$NON-NLS-1$
+				}
+				TextInputCallback t = (TextInputCallback) c;
+				CredentialItem.StringType item = new CredentialItem.StringType(
+						t.getPrompt(), false);
+				String defaultValue = t.getDefaultText();
+				if (defaultValue != null) {
+					item.setValue(defaultValue);
+				}
+				items.add(item);
+				updaters.add(() -> t.setText(item.getValue()));
+			} else if (c instanceof PasswordCallback) {
+				if (credentialsProvider == null) {
+					throw new UnsupportedOperationException(
+							"No CredentialsProvider " + uri); //$NON-NLS-1$
+				}
+				// It appears that this is actually the only callback item we
+				// get from the KeyStore when it asks for the PIN.
+				PasswordCallback p = (PasswordCallback) c;
+				CredentialItem.Password item = new CredentialItem.Password(
+						p.getPrompt());
+				items.add(item);
+				updaters.add(() -> {
+					char[] password = item.getValue();
+					if (password == null || password.length == 0) {
+						throw new AuthenticationCanceledException();
+					}
+					p.setPassword(password);
+					item.clear();
+				});
+			} else if (c instanceof ConfirmationCallback) {
+				if (credentialsProvider == null) {
+					throw new UnsupportedOperationException(
+							"No CredentialsProvider " + uri); //$NON-NLS-1$
+				}
+				// JGit has only limited support for this
+				ConfirmationCallback conf = (ConfirmationCallback) c;
+				int options = conf.getOptionType();
+				int defaultOption = conf.getDefaultOption();
+				CredentialItem.YesNoType item = new CredentialItem.YesNoType(
+						getText(conf.getMessageType(), conf.getPrompt()));
+				switch (options) {
+				case ConfirmationCallback.YES_NO_OPTION:
+					if (defaultOption == ConfirmationCallback.YES) {
+						item.setValue(true);
+					}
+					updaters.add(() -> conf.setSelectedIndex(
+							item.getValue() ? ConfirmationCallback.YES
+									: ConfirmationCallback.NO));
+					break;
+				case ConfirmationCallback.OK_CANCEL_OPTION:
+					if (defaultOption == ConfirmationCallback.OK) {
+						item.setValue(true);
+					}
+					updaters.add(() -> conf.setSelectedIndex(
+							item.getValue() ? ConfirmationCallback.OK
+									: ConfirmationCallback.CANCEL));
+					break;
+				default:
+					throw new UnsupportedCallbackException(c);
+				}
+				items.add(item);
+			} else if (c instanceof ChoiceCallback) {
+				// TODO: implement? Information for the prompt, and individual
+				// YesNoItems for the choices? Might be better to hoist JGit
+				// onto the CallbackHandler interface directly, or add support
+				// for choices.
+				throw new UnsupportedCallbackException(c);
+			} else if (c instanceof LanguageCallback) {
+				((LanguageCallback) c).setLocale(Locale.getDefault());
+			} else {
+				throw new UnsupportedCallbackException(c);
+			}
+		}
+		if (!items.isEmpty()) {
+			if (credentialsProvider.get(uri, items)) {
+				updaters.forEach(Runnable::run);
+			} else {
+				throw new AuthenticationCanceledException();
+			}
+		}
+	}
+
+	private String getText(int messageType, String text) {
+		if (messageType == TextOutputCallback.WARNING) {
+			return format(SshdText.get().pkcs11Warning, text);
+		} else if (messageType == TextOutputCallback.ERROR) {
+			return format(SshdText.get().pkcs11Error, text);
+		}
+		return text;
+	}
+}
diff --git a/org.eclipse.jgit.ssh.apache/src/org/eclipse/jgit/transport/sshd/IdentityPasswordProvider.java b/org.eclipse.jgit.ssh.apache/src/org/eclipse/jgit/transport/sshd/IdentityPasswordProvider.java
index 807bda8..23f46d8 100644
--- a/org.eclipse.jgit.ssh.apache/src/org/eclipse/jgit/transport/sshd/IdentityPasswordProvider.java
+++ b/org.eclipse.jgit.ssh.apache/src/org/eclipse/jgit/transport/sshd/IdentityPasswordProvider.java
@@ -247,7 +247,9 @@
 	 *            the attempt result - {@code null} for success
 	 * @return how to proceed in case of error
 	 * @throws IOException
+	 *             if an IO error occurred
 	 * @throws GeneralSecurityException
+	 *             something went wrong
 	 */
 	protected boolean keyLoaded(URIish uri,
 			State state, char[] password, Exception err)
diff --git a/org.eclipse.jgit.ssh.apache/src/org/eclipse/jgit/transport/sshd/KeyPasswordProvider.java b/org.eclipse.jgit.ssh.apache/src/org/eclipse/jgit/transport/sshd/KeyPasswordProvider.java
index ed9fe37..a80a5d1 100644
--- a/org.eclipse.jgit.ssh.apache/src/org/eclipse/jgit/transport/sshd/KeyPasswordProvider.java
+++ b/org.eclipse.jgit.ssh.apache/src/org/eclipse/jgit/transport/sshd/KeyPasswordProvider.java
@@ -77,7 +77,9 @@
 	 *         {@code error} exception; Ignored if the key was loaded
 	 *         successfully, i.e., if {@code error == null}.
 	 * @throws IOException
+	 *             if an IO error occurred
 	 * @throws GeneralSecurityException
+	 *             something went wrong
 	 */
 	boolean keyLoaded(URIish uri, int attempt, Exception error)
 			throws IOException, GeneralSecurityException;
diff --git a/org.eclipse.jgit.ssh.apache/src/org/eclipse/jgit/transport/sshd/SshdSessionFactory.java b/org.eclipse.jgit.ssh.apache/src/org/eclipse/jgit/transport/sshd/SshdSessionFactory.java
index 7798b80..35c9be0 100644
--- a/org.eclipse.jgit.ssh.apache/src/org/eclipse/jgit/transport/sshd/SshdSessionFactory.java
+++ b/org.eclipse.jgit.ssh.apache/src/org/eclipse/jgit/transport/sshd/SshdSessionFactory.java
@@ -210,11 +210,12 @@
 						home, sshDir);
 				KeyIdentityProvider defaultKeysProvider = toKeyIdentityProvider(
 						getDefaultKeys(sshDir));
+				Supplier<KeyPasswordProvider> keyPasswordProvider = () -> createKeyPasswordProvider(
+						credentialsProvider);
 				SshClient client = ClientBuilder.builder()
 						.factory(JGitSshClient::new)
 						.filePasswordProvider(createFilePasswordProvider(
-								() -> createKeyPasswordProvider(
-										credentialsProvider)))
+								keyPasswordProvider))
 						.hostConfigEntryResolver(configFile)
 						.serverKeyVerifier(new JGitServerKeyVerifier(
 								getServerKeyDatabase(home, sshDir)))
@@ -236,6 +237,7 @@
 				jgitClient.setKeyCache(getKeyCache());
 				jgitClient.setCredentialsProvider(credentialsProvider);
 				jgitClient.setProxyDatabase(proxies);
+				jgitClient.setKeyPasswordProviderFactory(keyPasswordProvider);
 				String defaultAuths = getDefaultPreferredAuthentications();
 				if (defaultAuths != null) {
 					jgitClient.setAttribute(
@@ -386,7 +388,7 @@
 	}
 
 	/**
-	 * Obtains a {@link SshConfigStore}, or {@code null} if not SSH config is to
+	 * Obtains a {@link SshConfigStore}, or {@code null} if no SSH config is to
 	 * be used. The default implementation returns {@code null} if
 	 * {@code configFile == null} and otherwise an OpenSSH-compatible store
 	 * reading host entries from the given file.
@@ -471,6 +473,7 @@
 	 * {@code UserKnownHostsFile} overrides this default.
 	 *
 	 * @param sshDir
+	 *            directory containing ssh configurations
 	 * @return the possibly empty list of default known host file paths.
 	 */
 	@NonNull
diff --git a/org.eclipse.jgit.ssh.apache/src/org/eclipse/jgit/transport/sshd/agent/Connector.java b/org.eclipse.jgit.ssh.apache/src/org/eclipse/jgit/transport/sshd/agent/Connector.java
index d8dfbfc..b391cf4 100644
--- a/org.eclipse.jgit.ssh.apache/src/org/eclipse/jgit/transport/sshd/agent/Connector.java
+++ b/org.eclipse.jgit.ssh.apache/src/org/eclipse/jgit/transport/sshd/agent/Connector.java
@@ -26,7 +26,7 @@
 	 * connected just returns {@code true}.
 	 *
 	 * @return {@code true} if an SSH agent is available and connected,
-	 *         {@false} if no SSH agent is available
+	 *         {@code false} if no SSH agent is available
 	 * @throws IOException
 	 *             if connecting to the SSH agent failed
 	 */
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 095dbb1..46f5899 100644
--- a/org.eclipse.jgit.ssh.jsch.test/META-INF/MANIFEST.MF
+++ b/org.eclipse.jgit.ssh.jsch.test/META-INF/MANIFEST.MF
@@ -3,19 +3,19 @@
 Bundle-Name: %Bundle-Name
 Automatic-Module-Name: org.eclipse.jgit.ssh.jsch.test
 Bundle-SymbolicName: org.eclipse.jgit.ssh.jsch.test
-Bundle-Version: 6.6.2.qualifier
+Bundle-Version: 6.7.1.qualifier
 Bundle-Vendor: %Bundle-Vendor
 Bundle-Localization: plugin
 Bundle-RequiredExecutionEnvironment: JavaSE-11
+Require-Bundle: org.hamcrest.core;bundle-version="[1.3.0,2.0.0)"
 Import-Package: com.jcraft.jsch;version="[0.1.54,0.2.0)",
- org.eclipse.jgit.errors;version="[6.6.2,6.7.0)",
- org.eclipse.jgit.junit;version="[6.6.2,6.7.0)",
- org.eclipse.jgit.junit.ssh;version="[6.6.2,6.7.0)",
- org.eclipse.jgit.lib;version="[6.6.2,6.7.0)",
- org.eclipse.jgit.transport;version="[6.6.2,6.7.0)",
- org.eclipse.jgit.transport.ssh.jsch;version="[6.6.2,6.7.0)",
- org.eclipse.jgit.util;version="[6.6.2,6.7.0)",
- org.hamcrest;version="[1.1.0,3.0.0)",
+ org.eclipse.jgit.errors;version="[6.7.1,6.8.0)",
+ org.eclipse.jgit.junit;version="[6.7.1,6.8.0)",
+ org.eclipse.jgit.junit.ssh;version="[6.7.1,6.8.0)",
+ org.eclipse.jgit.lib;version="[6.7.1,6.8.0)",
+ org.eclipse.jgit.transport;version="[6.7.1,6.8.0)",
+ org.eclipse.jgit.transport.ssh.jsch;version="[6.7.1,6.8.0)",
+ org.eclipse.jgit.util;version="[6.7.1,6.8.0)",
  org.junit;version="[4.13,5.0.0)",
  org.junit.experimental.theories;version="[4.13,5.0.0)",
  org.junit.runner;version="[4.13,5.0.0)"
diff --git a/org.eclipse.jgit.ssh.jsch.test/pom.xml b/org.eclipse.jgit.ssh.jsch.test/pom.xml
index 34fb8e7..9632a1a 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.6.2-SNAPSHOT</version>
+    <version>6.7.1-SNAPSHOT</version>
   </parent>
 
   <artifactId>org.eclipse.jgit.ssh.jsch.test</artifactId>
diff --git a/org.eclipse.jgit.ssh.jsch/.settings/org.eclipse.jdt.core.prefs b/org.eclipse.jgit.ssh.jsch/.settings/org.eclipse.jdt.core.prefs
index d1f54bb..d5c0e6c 100644
--- a/org.eclipse.jgit.ssh.jsch/.settings/org.eclipse.jdt.core.prefs
+++ b/org.eclipse.jgit.ssh.jsch/.settings/org.eclipse.jdt.core.prefs
@@ -52,7 +52,7 @@
 org.eclipse.jdt.core.compiler.problem.missingJavadocComments=error
 org.eclipse.jdt.core.compiler.problem.missingJavadocCommentsOverriding=disabled
 org.eclipse.jdt.core.compiler.problem.missingJavadocCommentsVisibility=protected
-org.eclipse.jdt.core.compiler.problem.missingJavadocTagDescription=return_tag
+org.eclipse.jdt.core.compiler.problem.missingJavadocTagDescription=all_standard_tags
 org.eclipse.jdt.core.compiler.problem.missingJavadocTags=error
 org.eclipse.jdt.core.compiler.problem.missingJavadocTagsMethodTypeParameters=disabled
 org.eclipse.jdt.core.compiler.problem.missingJavadocTagsOverriding=disabled
diff --git a/org.eclipse.jgit.ssh.jsch/META-INF/MANIFEST.MF b/org.eclipse.jgit.ssh.jsch/META-INF/MANIFEST.MF
index 056af34..68b7f3f 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.6.2,6.7.0)"
+Fragment-Host: org.eclipse.jgit;bundle-version="[6.7.1,6.8.0)"
 Bundle-Vendor: %Bundle-Vendor
 Bundle-Localization: plugin
 Bundle-ActivationPolicy: lazy
-Bundle-Version: 6.6.2.qualifier
+Bundle-Version: 6.7.1.qualifier
 Bundle-RequiredExecutionEnvironment: JavaSE-11
-Export-Package: org.eclipse.jgit.transport.ssh.jsch;version="6.6.2"
+Export-Package: org.eclipse.jgit.transport.ssh.jsch;version="6.7.1"
 Import-Package: com.jcraft.jsch;version="[0.1.37,0.2.0)",
- org.eclipse.jgit.errors;version="[6.6.2,6.7.0)",
- org.eclipse.jgit.internal;version="[6.6.2,6.7.0)",
- org.eclipse.jgit.internal.transport.ssh;version="[6.6.2,6.7.0)",
- org.eclipse.jgit.nls;version="[6.6.2,6.7.0)",
- org.eclipse.jgit.transport;version="[6.6.2,6.7.0)",
- org.eclipse.jgit.util;version="[6.6.2,6.7.0)",
- org.eclipse.jgit.util.io;version="[6.6.2,6.7.0)",
+ org.eclipse.jgit.errors;version="[6.7.1,6.8.0)",
+ org.eclipse.jgit.internal;version="[6.7.1,6.8.0)",
+ org.eclipse.jgit.internal.transport.ssh;version="[6.7.1,6.8.0)",
+ org.eclipse.jgit.nls;version="[6.7.1,6.8.0)",
+ org.eclipse.jgit.transport;version="[6.7.1,6.8.0)",
+ org.eclipse.jgit.util;version="[6.7.1,6.8.0)",
+ org.eclipse.jgit.util.io;version="[6.7.1,6.8.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 81557f5..67cc394 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.6.2.qualifier
-Eclipse-SourceBundle: org.eclipse.jgit.ssh.jsch;version="6.6.2.qualifier";roots="."
+Bundle-Version: 6.7.1.qualifier
+Eclipse-SourceBundle: org.eclipse.jgit.ssh.jsch;version="6.7.1.qualifier";roots="."
diff --git a/org.eclipse.jgit.ssh.jsch/pom.xml b/org.eclipse.jgit.ssh.jsch/pom.xml
index 6be4eaa..8962d84 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.6.2-SNAPSHOT</version>
+    <version>6.7.1-SNAPSHOT</version>
   </parent>
 
   <artifactId>org.eclipse.jgit.ssh.jsch</artifactId>
diff --git a/org.eclipse.jgit.ssh.jsch/src/org/eclipse/jgit/internal/transport/ssh/jsch/CredentialsProviderUserInfo.java b/org.eclipse.jgit.ssh.jsch/src/org/eclipse/jgit/internal/transport/ssh/jsch/CredentialsProviderUserInfo.java
index 5053493..b40ff5a 100644
--- a/org.eclipse.jgit.ssh.jsch/src/org/eclipse/jgit/internal/transport/ssh/jsch/CredentialsProviderUserInfo.java
+++ b/org.eclipse.jgit.ssh.jsch/src/org/eclipse/jgit/internal/transport/ssh/jsch/CredentialsProviderUserInfo.java
@@ -59,19 +59,16 @@
 		return uri;
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public String getPassword() {
 		return password;
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public String getPassphrase() {
 		return passphrase;
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public boolean promptPassphrase(String msg) {
 		CredentialItem.StringType v = newPrompt(msg);
@@ -83,7 +80,6 @@
 		return false;
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public boolean promptPassword(String msg) {
 		CredentialItem.Password p = new CredentialItem.Password(msg);
@@ -99,20 +95,17 @@
 		return new CredentialItem.StringType(msg, true);
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public boolean promptYesNo(String msg) {
 		CredentialItem.YesNoType v = new CredentialItem.YesNoType(msg);
 		return provider.get(uri, v) && v.getValue();
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public void showMessage(String msg) {
 		provider.get(uri, new CredentialItem.InformationalMessage(msg));
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public String[] promptKeyboardInteractive(String destination, String name,
 			String instruction, String[] prompt, boolean[] echo) {
diff --git a/org.eclipse.jgit.ssh.jsch/src/org/eclipse/jgit/transport/ssh/jsch/JschConfigSessionFactory.java b/org.eclipse.jgit.ssh.jsch/src/org/eclipse/jgit/transport/ssh/jsch/JschConfigSessionFactory.java
index 77b68bb..325d054 100644
--- a/org.eclipse.jgit.ssh.jsch/src/org/eclipse/jgit/transport/ssh/jsch/JschConfigSessionFactory.java
+++ b/org.eclipse.jgit.ssh.jsch/src/org/eclipse/jgit/transport/ssh/jsch/JschConfigSessionFactory.java
@@ -92,7 +92,6 @@
 
 	private OpenSshConfig config;
 
-	/** {@inheritDoc} */
 	@Override
 	public synchronized RemoteSession getSession(URIish uri,
 			CredentialsProvider credentialsProvider, FS fs, int tms)
@@ -189,14 +188,22 @@
 	 * Use for tests only
 	 *
 	 * @param credentialsProvider
+	 *            credentials provide
 	 * @param fs
+	 *            FS object to use
 	 * @param user
+	 *            user
 	 * @param pass
+	 *            password
 	 * @param host
+	 *            host name
 	 * @param port
+	 *            port number
 	 * @param hc
-	 * @return session
+	 *            host config
+	 * @return session the session
 	 * @throws JSchException
+	 *             jsch failed
 	 */
 	public Session createSession(CredentialsProvider credentialsProvider,
 			FS fs, String user, final String pass, String host, int port,
diff --git a/org.eclipse.jgit.ssh.jsch/src/org/eclipse/jgit/transport/ssh/jsch/JschSession.java b/org.eclipse.jgit.ssh.jsch/src/org/eclipse/jgit/transport/ssh/jsch/JschSession.java
index 02cdf70..5f36dad 100644
--- a/org.eclipse.jgit.ssh.jsch/src/org/eclipse/jgit/transport/ssh/jsch/JschSession.java
+++ b/org.eclipse.jgit.ssh.jsch/src/org/eclipse/jgit/transport/ssh/jsch/JschSession.java
@@ -68,20 +68,17 @@
 		this.uri = uri;
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public Process exec(String command, int timeout) throws IOException {
 		return exec(command, Collections.emptyMap(), timeout);
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public Process exec(String command, Map<String, String> environment,
 			int timeout) throws IOException {
 		return new JschProcess(command, environment, timeout);
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public void disconnect() {
 		if (sock.isConnected())
diff --git a/org.eclipse.jgit.ssh.jsch/src/org/eclipse/jgit/transport/ssh/jsch/OpenSshConfig.java b/org.eclipse.jgit.ssh.jsch/src/org/eclipse/jgit/transport/ssh/jsch/OpenSshConfig.java
index 2873307..087e546 100644
--- a/org.eclipse.jgit.ssh.jsch/src/org/eclipse/jgit/transport/ssh/jsch/OpenSshConfig.java
+++ b/org.eclipse.jgit.ssh.jsch/src/org/eclipse/jgit/transport/ssh/jsch/OpenSshConfig.java
@@ -353,7 +353,6 @@
 		return host.getConfig();
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public String toString() {
 		return "OpenSshConfig [configFile=" + configFile + ']'; //$NON-NLS-1$
diff --git a/org.eclipse.jgit.test/BUILD b/org.eclipse.jgit.test/BUILD
index 5066808..bb15de0 100644
--- a/org.eclipse.jgit.test/BUILD
+++ b/org.eclipse.jgit.test/BUILD
@@ -29,6 +29,7 @@
     "transport/ObjectIdMatcher.java",
     "transport/RequestValidatorTestCase.java",
     "transport/SpiTransport.java",
+    "transport/InMemoryPack.java",
     "treewalk/filter/AlwaysCloneTreeFilter.java",
     "test/resources/SampleDataRepositoryTestCase.java",
     "util/CPUTimeStopWatch.java",
@@ -76,6 +77,7 @@
     resources = DATA,
     deps = [
         "//lib:assertj-core",
+        "//lib:commons-codec",
         "//lib:junit",
         "//lib:mockito",
         "//lib:slf4j-simple",
diff --git a/org.eclipse.jgit.test/META-INF/MANIFEST.MF b/org.eclipse.jgit.test/META-INF/MANIFEST.MF
index 06be2ae..f9ace51 100644
--- a/org.eclipse.jgit.test/META-INF/MANIFEST.MF
+++ b/org.eclipse.jgit.test/META-INF/MANIFEST.MF
@@ -3,11 +3,14 @@
 Bundle-Name: %Bundle-Name
 Automatic-Module-Name: org.eclipse.jgit.test
 Bundle-SymbolicName: org.eclipse.jgit.test
-Bundle-Version: 6.6.2.qualifier
+Bundle-Version: 6.7.1.qualifier
 Bundle-Localization: plugin
 Bundle-Vendor: %Bundle-Vendor
 Bundle-RequiredExecutionEnvironment: JavaSE-11
+Require-Bundle: org.hamcrest.core;bundle-version="[1.3.0,2.0.0)",
+ org.hamcrest.library;bundle-version="[1.3.0,2.0.0)"
 Import-Package: com.googlecode.javaewah;version="[1.1.6,2.0.0)",
+ net.bytebuddy.agent;version="[1.9.0,2.0.0)",
  net.bytebuddy.dynamic.loading;version="[1.9.0,2.0.0)",
  org.apache.commons.compress.archivers;version="[1.15.0,2.0)",
  org.apache.commons.compress.archivers.tar;version="[1.15.0,2.0)",
@@ -16,76 +19,74 @@
  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.6.2,6.7.0)",
- org.eclipse.jgit.api;version="[6.6.2,6.7.0)",
- org.eclipse.jgit.api.errors;version="[6.6.2,6.7.0)",
- org.eclipse.jgit.archive;version="[6.6.2,6.7.0)",
- org.eclipse.jgit.attributes;version="[6.6.2,6.7.0)",
- org.eclipse.jgit.awtui;version="[6.6.2,6.7.0)",
- org.eclipse.jgit.blame;version="[6.6.2,6.7.0)",
- org.eclipse.jgit.diff;version="[6.6.2,6.7.0)",
- org.eclipse.jgit.dircache;version="[6.6.2,6.7.0)",
- org.eclipse.jgit.errors;version="[6.6.2,6.7.0)",
- org.eclipse.jgit.events;version="[6.6.2,6.7.0)",
- org.eclipse.jgit.fnmatch;version="[6.6.2,6.7.0)",
- org.eclipse.jgit.gitrepo;version="[6.6.2,6.7.0)",
- org.eclipse.jgit.hooks;version="[6.6.2,6.7.0)",
- org.eclipse.jgit.ignore;version="[6.6.2,6.7.0)",
- org.eclipse.jgit.ignore.internal;version="[6.6.2,6.7.0)",
- org.eclipse.jgit.internal;version="[6.6.2,6.7.0)",
- org.eclipse.jgit.internal.diff;version="[6.6.2,6.7.0)",
- org.eclipse.jgit.internal.diffmergetool;version="[6.6.2,6.7.0)",
- org.eclipse.jgit.internal.fsck;version="[6.6.2,6.7.0)",
- org.eclipse.jgit.internal.revwalk;version="[6.6.2,6.7.0)",
- org.eclipse.jgit.internal.storage.commitgraph;version="6.6.2",
- org.eclipse.jgit.internal.storage.dfs;version="[6.6.2,6.7.0)",
- org.eclipse.jgit.internal.storage.file;version="[6.6.2,6.7.0)",
- org.eclipse.jgit.internal.storage.io;version="[6.6.2,6.7.0)",
- org.eclipse.jgit.internal.storage.memory;version="[6.6.2,6.7.0)",
- org.eclipse.jgit.internal.storage.pack;version="[6.6.2,6.7.0)",
- org.eclipse.jgit.internal.storage.reftable;version="[6.6.2,6.7.0)",
- org.eclipse.jgit.internal.transport.connectivity;version="[6.6.2,6.7.0)",
- org.eclipse.jgit.internal.transport.http;version="[6.6.2,6.7.0)",
- org.eclipse.jgit.internal.transport.parser;version="[6.6.2,6.7.0)",
- org.eclipse.jgit.internal.transport.ssh;version="[6.6.2,6.7.0)",
- org.eclipse.jgit.junit;version="[6.6.2,6.7.0)",
- org.eclipse.jgit.junit.time;version="[6.6.2,6.7.0)",
- org.eclipse.jgit.lfs;version="[6.6.2,6.7.0)",
- org.eclipse.jgit.lib;version="[6.6.2,6.7.0)",
- org.eclipse.jgit.lib.internal;version="[6.6.2,6.7.0)",
- org.eclipse.jgit.logging;version="[6.6.2,6.7.0)",
- org.eclipse.jgit.merge;version="[6.6.2,6.7.0)",
- org.eclipse.jgit.nls;version="[6.6.2,6.7.0)",
- org.eclipse.jgit.notes;version="[6.6.2,6.7.0)",
- org.eclipse.jgit.patch;version="[6.6.2,6.7.0)",
- org.eclipse.jgit.pgm;version="[6.6.2,6.7.0)",
- org.eclipse.jgit.pgm.internal;version="[6.6.2,6.7.0)",
- org.eclipse.jgit.revplot;version="[6.6.2,6.7.0)",
- org.eclipse.jgit.revwalk;version="[6.6.2,6.7.0)",
- org.eclipse.jgit.revwalk.filter;version="[6.6.2,6.7.0)",
- org.eclipse.jgit.storage.file;version="[6.6.2,6.7.0)",
- org.eclipse.jgit.storage.pack;version="[6.6.2,6.7.0)",
- org.eclipse.jgit.submodule;version="[6.6.2,6.7.0)",
- org.eclipse.jgit.transport;version="[6.6.2,6.7.0)",
- org.eclipse.jgit.transport.http;version="[6.6.2,6.7.0)",
- org.eclipse.jgit.transport.resolver;version="[6.6.2,6.7.0)",
- org.eclipse.jgit.treewalk;version="[6.6.2,6.7.0)",
- org.eclipse.jgit.treewalk.filter;version="[6.6.2,6.7.0)",
- org.eclipse.jgit.util;version="[6.6.2,6.7.0)",
- org.eclipse.jgit.util.io;version="[6.6.2,6.7.0)",
- org.eclipse.jgit.util.sha1;version="[6.6.2,6.7.0)",
- org.hamcrest;version="[1.1.0,3.0.0)",
- org.hamcrest.collection;version="[1.1.0,3.0.0)",
+ org.eclipse.jgit.annotations;version="[6.7.1,6.8.0)",
+ org.eclipse.jgit.api;version="[6.7.1,6.8.0)",
+ org.eclipse.jgit.api.errors;version="[6.7.1,6.8.0)",
+ org.eclipse.jgit.archive;version="[6.7.1,6.8.0)",
+ org.eclipse.jgit.attributes;version="[6.7.1,6.8.0)",
+ org.eclipse.jgit.awtui;version="[6.7.1,6.8.0)",
+ org.eclipse.jgit.blame;version="[6.7.1,6.8.0)",
+ org.eclipse.jgit.diff;version="[6.7.1,6.8.0)",
+ org.eclipse.jgit.dircache;version="[6.7.1,6.8.0)",
+ org.eclipse.jgit.errors;version="[6.7.1,6.8.0)",
+ org.eclipse.jgit.events;version="[6.7.1,6.8.0)",
+ org.eclipse.jgit.fnmatch;version="[6.7.1,6.8.0)",
+ org.eclipse.jgit.gitrepo;version="[6.7.1,6.8.0)",
+ org.eclipse.jgit.hooks;version="[6.7.1,6.8.0)",
+ org.eclipse.jgit.ignore;version="[6.7.1,6.8.0)",
+ org.eclipse.jgit.ignore.internal;version="[6.7.1,6.8.0)",
+ org.eclipse.jgit.internal;version="[6.7.1,6.8.0)",
+ org.eclipse.jgit.internal.diff;version="[6.7.1,6.8.0)",
+ org.eclipse.jgit.internal.diffmergetool;version="[6.7.1,6.8.0)",
+ org.eclipse.jgit.internal.fsck;version="[6.7.1,6.8.0)",
+ org.eclipse.jgit.internal.revwalk;version="[6.7.1,6.8.0)",
+ org.eclipse.jgit.internal.storage.commitgraph;version="6.7.1",
+ org.eclipse.jgit.internal.storage.dfs;version="[6.7.1,6.8.0)",
+ org.eclipse.jgit.internal.storage.file;version="[6.7.1,6.8.0)",
+ org.eclipse.jgit.internal.storage.io;version="[6.7.1,6.8.0)",
+ org.eclipse.jgit.internal.storage.memory;version="[6.7.1,6.8.0)",
+ org.eclipse.jgit.internal.storage.pack;version="[6.7.1,6.8.0)",
+ org.eclipse.jgit.internal.storage.reftable;version="[6.7.1,6.8.0)",
+ org.eclipse.jgit.internal.transport.connectivity;version="[6.7.1,6.8.0)",
+ org.eclipse.jgit.internal.transport.http;version="[6.7.1,6.8.0)",
+ org.eclipse.jgit.internal.transport.parser;version="[6.7.1,6.8.0)",
+ org.eclipse.jgit.internal.transport.ssh;version="[6.7.1,6.8.0)",
+ org.eclipse.jgit.junit;version="[6.7.1,6.8.0)",
+ org.eclipse.jgit.junit.time;version="[6.7.1,6.8.0)",
+ org.eclipse.jgit.lfs;version="[6.7.1,6.8.0)",
+ org.eclipse.jgit.lib;version="[6.7.1,6.8.0)",
+ org.eclipse.jgit.lib.internal;version="[6.7.1,6.8.0)",
+ org.eclipse.jgit.logging;version="[6.7.1,6.8.0)",
+ org.eclipse.jgit.merge;version="[6.7.1,6.8.0)",
+ org.eclipse.jgit.nls;version="[6.7.1,6.8.0)",
+ org.eclipse.jgit.notes;version="[6.7.1,6.8.0)",
+ org.eclipse.jgit.patch;version="[6.7.1,6.8.0)",
+ org.eclipse.jgit.pgm;version="[6.7.1,6.8.0)",
+ org.eclipse.jgit.pgm.internal;version="[6.7.1,6.8.0)",
+ org.eclipse.jgit.revplot;version="[6.7.1,6.8.0)",
+ org.eclipse.jgit.revwalk;version="[6.7.1,6.8.0)",
+ org.eclipse.jgit.revwalk.filter;version="[6.7.1,6.8.0)",
+ org.eclipse.jgit.storage.file;version="[6.7.1,6.8.0)",
+ org.eclipse.jgit.storage.pack;version="[6.7.1,6.8.0)",
+ org.eclipse.jgit.submodule;version="[6.7.1,6.8.0)",
+ org.eclipse.jgit.transport;version="[6.7.1,6.8.0)",
+ org.eclipse.jgit.transport.http;version="[6.7.1,6.8.0)",
+ org.eclipse.jgit.transport.resolver;version="[6.7.1,6.8.0)",
+ org.eclipse.jgit.treewalk;version="[6.7.1,6.8.0)",
+ org.eclipse.jgit.treewalk.filter;version="[6.7.1,6.8.0)",
+ org.eclipse.jgit.util;version="[6.7.1,6.8.0)",
+ org.eclipse.jgit.util.io;version="[6.7.1,6.8.0)",
+ org.eclipse.jgit.util.sha1;version="[6.7.1,6.8.0)",
  org.junit;version="[4.13,5.0.0)",
  org.junit.experimental.theories;version="[4.13,5.0.0)",
  org.junit.function;version="[4.13.0,5.0.0)",
  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.mockito;version="[4.8.0,5.0.0)",
- org.mockito.invocation;version="[4.8.0,5.0.0)",
- org.mockito.junit;version="[4.8.0,5.0.0)",
- org.mockito.stubbing;version="[4.8.0,5.0.0)",
+ org.mockito;version="[5.4.0,6.0.0)",
+ org.mockito.invocation;version="[5.4.0,6.0.0)",
+ org.mockito.junit;version="[5.4.0,6.0.0)",
+ org.mockito.stubbing;version="[5.4.0,6.0.0)",
  org.objenesis;version="[3.3.0,4.0.0)",
  org.slf4j;version="[1.7.0,2.0.0)",
  org.tukaani.xz
diff --git a/org.eclipse.jgit.test/pom.xml b/org.eclipse.jgit.test/pom.xml
index 2e64ccc..490f089 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.6.2-SNAPSHOT</version>
+    <version>6.7.1-SNAPSHOT</version>
   </parent>
 
   <artifactId>org.eclipse.jgit.test</artifactId>
@@ -73,7 +73,7 @@
     <dependency>
       <groupId>org.mockito</groupId>
       <artifactId>mockito-core</artifactId>
-      <version>4.8.1</version>
+      <version>5.5.0</version>
     </dependency>
 
     <dependency>
diff --git a/org.eclipse.jgit.test/tst-rsrc/org/eclipse/jgit/test/resources/pack-cbdeda40019ae0e6e789088ea0f51f164f489d14.corrupt.rev b/org.eclipse.jgit.test/tst-rsrc/org/eclipse/jgit/test/resources/pack-cbdeda40019ae0e6e789088ea0f51f164f489d14.corrupt.rev
new file mode 100644
index 0000000..74283a2
--- /dev/null
+++ b/org.eclipse.jgit.test/tst-rsrc/org/eclipse/jgit/test/resources/pack-cbdeda40019ae0e6e789088ea0f51f164f489d14.corrupt.rev
Binary files differ
diff --git a/org.eclipse.jgit.test/tst-rsrc/org/eclipse/jgit/test/resources/pack-cbdeda40019ae0e6e789088ea0f51f164f489d14.rev b/org.eclipse.jgit.test/tst-rsrc/org/eclipse/jgit/test/resources/pack-cbdeda40019ae0e6e789088ea0f51f164f489d14.rev
new file mode 100644
index 0000000..6ac7d65
--- /dev/null
+++ b/org.eclipse.jgit.test/tst-rsrc/org/eclipse/jgit/test/resources/pack-cbdeda40019ae0e6e789088ea0f51f164f489d14.rev
Binary files differ
diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/ArchiveCommandTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/ArchiveCommandTest.java
index 411eab3..3a4ea8e 100644
--- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/ArchiveCommandTest.java
+++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/ArchiveCommandTest.java
@@ -254,7 +254,7 @@
 		}
 	}
 
-	@SuppressWarnings({ "serial", "boxing" })
+	@SuppressWarnings({ "boxing" })
 	private void archiveHeadAllFilesWithCompression(String fmt) throws Exception {
 		try (Git git = new Git(db)) {
 			createLargeTestContent(git);
diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/PushCommandTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/PushCommandTest.java
index ff5f8b7..70e990d 100644
--- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/PushCommandTest.java
+++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/PushCommandTest.java
@@ -941,7 +941,7 @@
 	}
 
 	/**
-	 * Check that branch.<name>.pushRemote overrides anything else.
+	 * Check that branch.&lt;name&gt;.pushRemote overrides anything else.
 	 *
 	 * @throws Exception
 	 */
@@ -980,7 +980,7 @@
 	}
 
 	/**
-	 * Check that remote.pushDefault overrides branch.<name>.remote
+	 * Check that remote.pushDefault overrides branch.&lt;name&gt;.remote
 	 *
 	 * @throws Exception
 	 */
diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/ignore/IgnoreNodeTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/ignore/IgnoreNodeTest.java
index 05a953e..ab08c99 100644
--- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/ignore/IgnoreNodeTest.java
+++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/ignore/IgnoreNodeTest.java
@@ -20,14 +20,18 @@
 import java.io.File;
 import java.io.IOException;
 import java.io.InputStream;
+import java.nio.file.Files;
+import java.nio.file.Path;
 import java.util.ArrayList;
 import java.util.Arrays;
 
+import org.eclipse.jgit.junit.MockSystemReader;
 import org.eclipse.jgit.junit.RepositoryTestCase;
 import org.eclipse.jgit.lib.FileMode;
 import org.eclipse.jgit.treewalk.FileTreeIterator;
 import org.eclipse.jgit.treewalk.TreeWalk;
 import org.eclipse.jgit.treewalk.WorkingTreeIterator;
+import org.eclipse.jgit.util.FS;
 import org.eclipse.jgit.util.FileUtils;
 import org.eclipse.jgit.util.SystemReader;
 import org.junit.After;
@@ -698,6 +702,110 @@
 	}
 
 	@Test
+	public void testUserGitIgnoreFound() throws IOException {
+		File homeDir = FS.DETECTED.userHome();
+		Path userIgnore = homeDir.toPath().resolve(".config").resolve("git")
+				.resolve("ignore");
+		Files.createDirectories(userIgnore.getParent());
+		Files.writeString(userIgnore, "x");
+		try {
+			writeTrashFile(".foo", "");
+			writeTrashFile("a/x/file", "");
+			writeTrashFile("b/x", "");
+			writeTrashFile("x/file", "");
+
+			beginWalk();
+			assertEntry(F, tracked, ".foo");
+			assertEntry(D, tracked, "a");
+			assertEntry(D, ignored, "a/x");
+			assertEntry(F, ignored, "a/x/file");
+			assertEntry(D, tracked, "b");
+			assertEntry(F, ignored, "b/x");
+			assertEntry(D, ignored, "x");
+			assertEntry(F, ignored, "x/file");
+			endWalk();
+		} finally {
+			Files.deleteIfExists(userIgnore);
+		}
+	}
+
+	@Test
+	public void testXdgIgnoreFound() throws IOException {
+		File tmp = getTemporaryDirectory();
+		Path xdg = tmp.toPath().resolve("xdg");
+		Path userIgnore = xdg.resolve("git").resolve("ignore");
+		Files.createDirectories(userIgnore.getParent());
+		Files.writeString(userIgnore, "x");
+		SystemReader system = SystemReader.getInstance();
+		assertTrue(system instanceof MockSystemReader);
+		((MockSystemReader) system).setProperty("XDG_CONFIG_HOME",
+				xdg.toAbsolutePath().toString());
+		// Also create the one in the home directory -- it should not be active
+		File homeDir = FS.DETECTED.userHome();
+		Path userIgnore2 = homeDir.toPath().resolve(".config").resolve("git")
+				.resolve("ignore");
+		Files.createDirectories(userIgnore2.getParent());
+		Files.writeString(userIgnore2, "a");
+		try {
+			writeTrashFile(".foo", "");
+			writeTrashFile("a/x/file", "");
+			writeTrashFile("b/x", "");
+			writeTrashFile("x/file", "");
+
+			beginWalk();
+			assertEntry(F, tracked, ".foo");
+			assertEntry(D, tracked, "a");
+			assertEntry(D, ignored, "a/x");
+			assertEntry(F, ignored, "a/x/file");
+			assertEntry(D, tracked, "b");
+			assertEntry(F, ignored, "b/x");
+			assertEntry(D, ignored, "x");
+			assertEntry(F, ignored, "x/file");
+			endWalk();
+		} finally {
+			((MockSystemReader) system).setProperty("XDG_CONFIG_HOME", null);
+			Files.deleteIfExists(userIgnore2);
+		}
+	}
+
+	@Test
+	public void testXdgWrong() throws IOException {
+		File tmp = getTemporaryDirectory();
+		Path xdg = tmp.toPath().resolve("xdg");
+		SystemReader system = SystemReader.getInstance();
+		assertTrue(system instanceof MockSystemReader);
+		// Valid value, but the directory doesn't exist
+		((MockSystemReader) system).setProperty("XDG_CONFIG_HOME",
+				xdg.toAbsolutePath().toString());
+		// Also create the one in the home directory -- it should not be active
+		File homeDir = FS.DETECTED.userHome();
+		Path userIgnore2 = homeDir.toPath().resolve(".config").resolve("git")
+				.resolve("ignore");
+		Files.createDirectories(userIgnore2.getParent());
+		Files.writeString(userIgnore2, "x");
+		try {
+			writeTrashFile(".foo", "");
+			writeTrashFile("a/x/file", "");
+			writeTrashFile("b/x", "");
+			writeTrashFile("x/file", "");
+
+			beginWalk();
+			assertEntry(F, tracked, ".foo");
+			assertEntry(D, tracked, "a");
+			assertEntry(D, tracked, "a/x");
+			assertEntry(F, tracked, "a/x/file");
+			assertEntry(D, tracked, "b");
+			assertEntry(F, tracked, "b/x");
+			assertEntry(D, tracked, "x");
+			assertEntry(F, tracked, "x/file");
+			endWalk();
+		} finally {
+			((MockSystemReader) system).setProperty("XDG_CONFIG_HOME", null);
+			Files.deleteIfExists(userIgnore2);
+		}
+	}
+
+	@Test
 	public void testToString() throws Exception {
 		assertEquals(Arrays.asList("").toString(), new IgnoreNode().toString());
 		assertEquals(Arrays.asList("hello").toString(),
diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/revwalk/ObjectReachabilityTestCase.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/revwalk/ObjectReachabilityTestCase.java
index 37ff40b..0e73588 100644
--- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/revwalk/ObjectReachabilityTestCase.java
+++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/revwalk/ObjectReachabilityTestCase.java
@@ -51,7 +51,6 @@
 		}
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	@Before
 	public void setUp() throws Exception {
diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/revwalk/ReachabilityCheckerTestCase.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/revwalk/ReachabilityCheckerTestCase.java
index 7679c11..eeb13cc 100644
--- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/revwalk/ReachabilityCheckerTestCase.java
+++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/revwalk/ReachabilityCheckerTestCase.java
@@ -32,7 +32,6 @@
 
 	TestRepository<FileRepository> repo;
 
-	/** {@inheritDoc} */
 	@Override
 	@Before
 	public void setUp() throws Exception {
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
index 9797656..4d05360 100644
--- 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
@@ -10,24 +10,31 @@
 
 package org.eclipse.jgit.internal.storage.commitgraph;
 
+import static java.nio.charset.StandardCharsets.UTF_8;
 import static org.eclipse.jgit.lib.Constants.COMMIT_GENERATION_UNKNOWN;
 import static org.junit.Assert.assertArrayEquals;
 import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
 
 import java.io.ByteArrayInputStream;
 import java.io.ByteArrayOutputStream;
+import java.io.IOException;
 import java.io.InputStream;
 import java.util.Collections;
 import java.util.HashSet;
 import java.util.Set;
 
+import org.eclipse.jgit.errors.ConfigInvalidException;
 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.ConfigConstants;
 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.storage.file.FileBasedConfig;
 import org.junit.Before;
 import org.junit.Test;
 
@@ -45,6 +52,7 @@
 	public void setUp() throws Exception {
 		super.setUp();
 		tr = new TestRepository<>(db, new RevWalk(db), mockSystemReader);
+		mockSystemReader.setJGitConfig(new MockConfig());
 	}
 
 	@Test
@@ -196,11 +204,32 @@
 		assertEquals(getGenerationNumber(c8), 5);
 	}
 
+	@Test
+	public void testGraphComputeChangedPaths() throws Exception {
+		RevCommit a = tr.commit(tr.tree(tr.file("d/f", tr.blob("a"))));
+		RevCommit b = tr.commit(tr.tree(tr.file("d/f", tr.blob("a"))), a);
+		RevCommit c = tr.commit(tr.tree(tr.file("d/f", tr.blob("b"))), b);
+
+		writeAndReadCommitGraph(Collections.singleton(c));
+		ChangedPathFilter acpf = commitGraph
+				.getChangedPathFilter(commitGraph.findGraphPosition(a));
+		assertTrue(acpf.maybeContains("d".getBytes(UTF_8)));
+		assertTrue(acpf.maybeContains("d/f".getBytes(UTF_8)));
+		ChangedPathFilter bcpf = commitGraph
+				.getChangedPathFilter(commitGraph.findGraphPosition(b));
+		assertFalse(bcpf.maybeContains("d".getBytes(UTF_8)));
+		assertFalse(bcpf.maybeContains("d/f".getBytes(UTF_8)));
+		ChangedPathFilter ccpf = commitGraph
+				.getChangedPathFilter(commitGraph.findGraphPosition(c));
+		assertTrue(ccpf.maybeContains("d".getBytes(UTF_8)));
+		assertTrue(ccpf.maybeContains("d/f".getBytes(UTF_8)));
+	}
+
 	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));
+					GraphCommits.fromWalk(m, wants, walk), true);
 			ByteArrayOutputStream os = new ByteArrayOutputStream();
 			writer.write(m, os);
 			InputStream inputStream = new ByteArrayInputStream(
@@ -252,4 +281,41 @@
 	RevCommit commit(RevCommit... parents) throws Exception {
 		return tr.commit(parents);
 	}
+
+	private static final class MockConfig extends FileBasedConfig {
+		private MockConfig() {
+			super(null, null);
+		}
+
+		@Override
+		public void load() throws IOException, ConfigInvalidException {
+			// Do nothing
+		}
+
+		@Override
+		public void save() throws IOException {
+			// Do nothing
+		}
+
+		@Override
+		public boolean isOutdated() {
+			return false;
+		}
+
+		@Override
+		public String toString() {
+			return "MockConfig";
+		}
+
+		@Override
+		public boolean getBoolean(final String section, final String name,
+				final boolean defaultValue) {
+			if (section.equals(ConfigConstants.CONFIG_COMMIT_GRAPH_SECTION)
+					&& name.equals(
+							ConfigConstants.CONFIG_KEY_READ_CHANGED_PATHS)) {
+				return true;
+			}
+			return defaultValue;
+		}
+	}
 }
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
index 6c5e5e5..5040a3b 100644
--- 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
@@ -10,21 +10,31 @@
 
 package org.eclipse.jgit.internal.storage.commitgraph;
 
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.hamcrest.Matchers.containsInAnyOrder;
 import static org.junit.Assert.assertArrayEquals;
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertTrue;
 
 import java.io.ByteArrayOutputStream;
+import java.io.IOException;
 import java.util.Collections;
+import java.util.HashSet;
 import java.util.Set;
 
+import org.eclipse.jgit.dircache.DirCacheEntry;
+import org.eclipse.jgit.errors.ConfigInvalidException;
 import org.eclipse.jgit.internal.storage.file.FileRepository;
+import org.eclipse.jgit.internal.storage.file.GC;
 import org.eclipse.jgit.junit.RepositoryTestCase;
 import org.eclipse.jgit.junit.TestRepository;
+import org.eclipse.jgit.lib.ConfigConstants;
 import org.eclipse.jgit.lib.NullProgressMonitor;
 import org.eclipse.jgit.lib.ObjectId;
+import org.eclipse.jgit.revwalk.RevBlob;
 import org.eclipse.jgit.revwalk.RevCommit;
 import org.eclipse.jgit.revwalk.RevWalk;
+import org.eclipse.jgit.storage.file.FileBasedConfig;
 import org.eclipse.jgit.util.NB;
 import org.junit.Before;
 import org.junit.Test;
@@ -46,6 +56,7 @@
 		os = new ByteArrayOutputStream();
 		tr = new TestRepository<>(db, new RevWalk(db), mockSystemReader);
 		walk = new RevWalk(db);
+		mockSystemReader.setJGitConfig(new MockConfig());
 	}
 
 	@Test
@@ -68,7 +79,7 @@
 		Set<ObjectId> wants = Collections.singleton(tip);
 		NullProgressMonitor m = NullProgressMonitor.INSTANCE;
 		GraphCommits graphCommits = GraphCommits.fromWalk(m, wants, walk);
-		writer = new CommitGraphWriter(graphCommits);
+		writer = new CommitGraphWriter(graphCommits, true);
 		writer.write(m, os);
 
 		assertEquals(5, graphCommits.size());
@@ -76,11 +87,20 @@
 		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));
+		assertArrayEquals(new byte[] { 'C', 'G', 'P', 'H', 1, 1, 6, 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));
+		assertEquals(CommitGraphConstants.CHUNK_ID_BLOOM_FILTER_INDEX,
+				NB.decodeInt32(data, 56));
+		assertEquals(CommitGraphConstants.CHUNK_ID_BLOOM_FILTER_DATA,
+				NB.decodeInt32(data, 68));
 	}
 
 	@Test
@@ -93,7 +113,7 @@
 		Set<ObjectId> wants = Collections.singleton(tip);
 		NullProgressMonitor m = NullProgressMonitor.INSTANCE;
 		GraphCommits graphCommits = GraphCommits.fromWalk(m, wants, walk);
-		writer = new CommitGraphWriter(graphCommits);
+		writer = new CommitGraphWriter(graphCommits, true);
 		writer.write(m, os);
 
 		assertEquals(4, graphCommits.size());
@@ -101,13 +121,281 @@
 		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));
+		assertArrayEquals(new byte[] { 'C', 'G', 'P', 'H', 1, 1, 5, 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_BLOOM_FILTER_INDEX,
+				NB.decodeInt32(data, 44));
+		assertEquals(CommitGraphConstants.CHUNK_ID_BLOOM_FILTER_DATA,
+				NB.decodeInt32(data, 56));
+	}
+
+	static HashSet<String> changedPathStrings(byte[] data) {
+		int oidf_offset = -1;
+		int bidx_offset = -1;
+		int bdat_offset = -1;
+		for (int i = 8; i < data.length - 4; i += 12) {
+			switch (NB.decodeInt32(data, i)) {
+			case CommitGraphConstants.CHUNK_ID_OID_FANOUT:
+				oidf_offset = (int) NB.decodeInt64(data, i + 4);
+				break;
+			case CommitGraphConstants.CHUNK_ID_BLOOM_FILTER_INDEX:
+				bidx_offset = (int) NB.decodeInt64(data, i + 4);
+				break;
+			case CommitGraphConstants.CHUNK_ID_BLOOM_FILTER_DATA:
+				bdat_offset = (int) NB.decodeInt64(data, i + 4);
+				break;
+			}
+		}
+		assertTrue(oidf_offset > 0);
+		assertTrue(bidx_offset > 0);
+		assertTrue(bdat_offset > 0);
+		bdat_offset += 12; // skip version, hash count, bits per entry
+		int commit_count = NB.decodeInt32(data, oidf_offset + 255 * 4);
+		int[] changed_path_length_cumuls = new int[commit_count];
+		for (int i = 0; i < commit_count; i++) {
+			changed_path_length_cumuls[i] = NB.decodeInt32(data,
+					bidx_offset + i * 4);
+		}
+		HashSet<String> changed_paths = new HashSet<>();
+		for (int i = 0; i < commit_count; i++) {
+			int prior_cumul = i == 0 ? 0 : changed_path_length_cumuls[i - 1];
+			String changed_path = "";
+			for (int j = prior_cumul; j < changed_path_length_cumuls[i]; j++) {
+				changed_path += data[bdat_offset + j] + ",";
+			}
+			changed_paths.add(changed_path);
+		}
+		return changed_paths;
+	}
+
+	/**
+	 * Expected value generated using the following:
+	 *
+	 * <pre>
+	 * # apply into git-repo: https://lore.kernel.org/git/cover.1684790529.git.jonathantanmy@google.com/
+	 * (cd git-repo; make)
+	 * git-repo/bin-wrappers/git init tested
+	 * (cd tested; touch foo.txt; mkdir -p onedir/twodir; touch onedir/twodir/bar.txt)
+	 * git-repo/bin-wrappers/git -C tested add foo.txt onedir
+	 * git-repo/bin-wrappers/git -C tested commit -m first_commit
+	 * (cd tested; mv foo.txt foo-new.txt; mv onedir/twodir/bar.txt onedir/twodir/bar-new.txt)
+	 * git-repo/bin-wrappers/git -C tested add foo-new.txt onedir
+	 * git-repo/bin-wrappers/git -C tested commit -a -m second_commit
+	 * git-repo/bin-wrappers/git -C tested maintenance run
+	 * git-repo/bin-wrappers/git -C tested commit-graph write --changed-paths
+	 * (cd tested; $JGIT debug-read-changed-path-filter .git/objects/info/commit-graph)
+	 * </pre>
+	 *
+	 * @throws Exception
+	 */
+	@Test
+	public void testChangedPathFilterRootAndNested() throws Exception {
+		RevBlob emptyBlob = tr.blob(new byte[] {});
+		RevCommit root = tr.commit(tr.tree(tr.file("foo.txt", emptyBlob),
+				tr.file("onedir/twodir/bar.txt", emptyBlob)));
+		RevCommit tip = tr.commit(tr.tree(tr.file("foo-new.txt", emptyBlob),
+				tr.file("onedir/twodir/bar-new.txt", emptyBlob)), root);
+
+		Set<ObjectId> wants = Collections.singleton(tip);
+		NullProgressMonitor m = NullProgressMonitor.INSTANCE;
+		GraphCommits graphCommits = GraphCommits.fromWalk(m, wants, walk);
+		writer = new CommitGraphWriter(graphCommits, true);
+		writer.write(m, os);
+
+		HashSet<String> changedPaths = changedPathStrings(os.toByteArray());
+		assertThat(changedPaths, containsInAnyOrder(
+				"109,-33,2,60,20,79,-11,116,",
+				"119,69,63,-8,0,"));
+	}
+
+	/**
+	 * Expected value generated using the following:
+	 *
+	 * <pre>
+	 * git -C git-repo checkout todo get version number when it is merged
+	 * (cd git-repo; make)
+	 * git-repo/bin-wrappers/git init tested
+	 * (cd tested; mkdir -p onedir/twodir; touch onedir/twodir/a.txt; touch onedir/twodir/b.txt)
+	 * git-repo/bin-wrappers/git -C tested add onedir
+	 * git-repo/bin-wrappers/git -C tested commit -m first_commit
+	 * (cd tested; mv onedir/twodir/a.txt onedir/twodir/c.txt; mv onedir/twodir/b.txt onedir/twodir/d.txt)
+	 * git-repo/bin-wrappers/git -C tested add onedir
+	 * git-repo/bin-wrappers/git -C tested commit -a -m second_commit
+	 * git-repo/bin-wrappers/git -C tested maintenance run
+	 * git-repo/bin-wrappers/git -C tested commit-graph write --changed-paths
+	 * (cd tested; $JGIT debug-read-changed-path-filter .git/objects/info/commit-graph)
+	 * </pre>
+	 *
+	 * @throws Exception
+	 */
+	@Test
+	public void testChangedPathFilterOverlappingNested() throws Exception {
+		RevBlob emptyBlob = tr.blob(new byte[] {});
+		RevCommit root = tr
+				.commit(tr.tree(tr.file("onedir/twodir/a.txt", emptyBlob),
+						tr.file("onedir/twodir/b.txt", emptyBlob)));
+		RevCommit tip = tr
+				.commit(tr.tree(tr.file("onedir/twodir/c.txt", emptyBlob),
+						tr.file("onedir/twodir/d.txt", emptyBlob)), root);
+
+		Set<ObjectId> wants = Collections.singleton(tip);
+		NullProgressMonitor m = NullProgressMonitor.INSTANCE;
+		GraphCommits graphCommits = GraphCommits.fromWalk(m, wants, walk);
+		writer = new CommitGraphWriter(graphCommits, true);
+		writer.write(m, os);
+
+		HashSet<String> changedPaths = changedPathStrings(os.toByteArray());
+		assertThat(changedPaths, containsInAnyOrder("61,30,23,-24,1,",
+				"-58,-51,-46,60,29,-121,113,90,"));
+	}
+
+	/**
+	 * Expected value generated using the following:
+	 *
+	 * <pre>
+	 * git -C git-repo checkout todo get version number when it is merged
+	 * (cd git-repo; make)
+	 * git-repo/bin-wrappers/git init tested
+	 * (cd tested; touch 你好)
+	 * git-repo/bin-wrappers/git -C tested add 你好
+	 * git-repo/bin-wrappers/git -C tested commit -m first_commit
+	 * git-repo/bin-wrappers/git -C tested maintenance run
+	 * git-repo/bin-wrappers/git -C tested commit-graph write --changed-paths
+	 * (cd tested; $JGIT debug-read-changed-path-filter .git/objects/info/commit-graph)
+	 * </pre>
+	 *
+	 * @throws Exception
+	 */
+	@Test
+	public void testChangedPathFilterHighBit() throws Exception {
+		RevBlob emptyBlob = tr.blob(new byte[] {});
+		// tr.file encodes using UTF-8
+		RevCommit root = tr.commit(tr.tree(tr.file("你好", emptyBlob)));
+
+		Set<ObjectId> wants = Collections.singleton(root);
+		NullProgressMonitor m = NullProgressMonitor.INSTANCE;
+		GraphCommits graphCommits = GraphCommits.fromWalk(m, wants, walk);
+		writer = new CommitGraphWriter(graphCommits, true);
+		writer.write(m, os);
+
+		HashSet<String> changedPaths = changedPathStrings(os.toByteArray());
+		assertThat(changedPaths, containsInAnyOrder("16,16,"));
+	}
+
+	@Test
+	public void testChangedPathFilterEmptyChange() throws Exception {
+		RevCommit root = commit();
+
+		Set<ObjectId> wants = Collections.singleton(root);
+		NullProgressMonitor m = NullProgressMonitor.INSTANCE;
+		GraphCommits graphCommits = GraphCommits.fromWalk(m, wants, walk);
+		writer = new CommitGraphWriter(graphCommits, true);
+		writer.write(m, os);
+
+		HashSet<String> changedPaths = changedPathStrings(os.toByteArray());
+		assertThat(changedPaths, containsInAnyOrder("0,"));
+	}
+
+	@Test
+	public void testChangedPathFilterManyChanges() throws Exception {
+		RevBlob emptyBlob = tr.blob(new byte[] {});
+		DirCacheEntry[] entries = new DirCacheEntry[513];
+		for (int i = 0; i < entries.length; i++) {
+			entries[i] = tr.file(i + ".txt", emptyBlob);
+		}
+
+		RevCommit root = tr.commit(tr.tree(entries));
+
+		Set<ObjectId> wants = Collections.singleton(root);
+		NullProgressMonitor m = NullProgressMonitor.INSTANCE;
+		GraphCommits graphCommits = GraphCommits.fromWalk(m, wants, walk);
+		writer = new CommitGraphWriter(graphCommits, true);
+		writer.write(m, os);
+
+		HashSet<String> changedPaths = changedPathStrings(os.toByteArray());
+		assertThat(changedPaths, containsInAnyOrder("-1,"));
+	}
+
+	@Test
+	public void testReuseBloomFilters() throws Exception {
+		RevBlob emptyBlob = tr.blob(new byte[] {});
+		RevCommit root = tr.commit(tr.tree(tr.file("foo.txt", emptyBlob),
+				tr.file("onedir/twodir/bar.txt", emptyBlob)));
+		tr.branch("master").update(root);
+
+		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);
+		db.getConfig().setBoolean(ConfigConstants.CONFIG_GC_SECTION, null,
+				ConfigConstants.CONFIG_KEY_WRITE_CHANGED_PATHS, true);
+		GC gc = new GC(db);
+		gc.gc().get();
+
+		RevCommit tip = tr.commit(tr.tree(tr.file("foo-new.txt", emptyBlob),
+				tr.file("onedir/twodir/bar-new.txt", emptyBlob)), root);
+
+		Set<ObjectId> wants = Collections.singleton(tip);
+		NullProgressMonitor m = NullProgressMonitor.INSTANCE;
+		GraphCommits graphCommits = GraphCommits.fromWalk(m, wants, walk);
+		writer = new CommitGraphWriter(graphCommits, true);
+		CommitGraphWriter.Stats stats = writer.write(m, os);
+
+		assertEquals(1, stats.getChangedPathFiltersReused());
+		assertEquals(1, stats.getChangedPathFiltersComputed());
+
+		// Expected strings are the same as in
+		// #testChangedPathFilterRootAndNested
+		HashSet<String> changedPaths = changedPathStrings(os.toByteArray());
+		assertThat(changedPaths, containsInAnyOrder(
+				"109,-33,2,60,20,79,-11,116,",
+				"119,69,63,-8,0,"));
 	}
 
 	RevCommit commit(RevCommit... parents) throws Exception {
 		return tr.commit(parents);
 	}
-}
+
+	private static final class MockConfig extends FileBasedConfig {
+		private MockConfig() {
+			super(null, null);
+		}
+
+		@Override
+		public void load() throws IOException, ConfigInvalidException {
+			// Do nothing
+		}
+
+		@Override
+		public void save() throws IOException {
+			// Do nothing
+		}
+
+		@Override
+		public boolean isOutdated() {
+			return false;
+		}
+
+		@Override
+		public String toString() {
+			return "MockConfig";
+		}
+
+		@Override
+		public boolean getBoolean(final String section, final String name,
+				final boolean defaultValue) {
+			if (section.equals(ConfigConstants.CONFIG_COMMIT_GRAPH_SECTION)
+					&& name.equals(
+							ConfigConstants.CONFIG_KEY_READ_CHANGED_PATHS)) {
+				return true;
+			}
+			return defaultValue;
+		}
+	}
+}
\ No newline at end of file
diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/dfs/DfsGarbageCollectorTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/dfs/DfsGarbageCollectorTest.java
index ab99895..05360dc 100644
--- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/dfs/DfsGarbageCollectorTest.java
+++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/dfs/DfsGarbageCollectorTest.java
@@ -15,10 +15,12 @@
 import static org.junit.Assert.fail;
 
 import java.io.IOException;
+import java.util.Arrays;
 import java.util.Collections;
 import java.util.concurrent.TimeUnit;
 
 import org.eclipse.jgit.internal.storage.commitgraph.CommitGraph;
+import org.eclipse.jgit.internal.storage.commitgraph.CommitGraphWriter;
 import org.eclipse.jgit.internal.storage.dfs.DfsObjDatabase.PackSource;
 import org.eclipse.jgit.internal.storage.reftable.RefCursor;
 import org.eclipse.jgit.internal.storage.reftable.ReftableConfig;
@@ -978,7 +980,7 @@
 	}
 
 	@Test
-	public void produceCommitGraphAllRefsIncludedFromDisk() throws Exception {
+	public void produceCommitGraphOnlyHeadsAndTags() throws Exception {
 		String tag = "refs/tags/tag1";
 		String head = "refs/heads/head1";
 		String nonHead = "refs/something/nonHead";
@@ -1000,19 +1002,20 @@
 		CommitGraph cg = gcPack.getCommitGraph(reader);
 		assertNotNull(cg);
 
-		assertTrue("all commits in commit graph", cg.getCommitCnt() == 3);
+		assertTrue("Only heads and tags reachable commits in commit graph",
+				cg.getCommitCnt() == 2);
 		// GC packed
 		assertTrue("tag referenced commit is in graph",
 				cg.findGraphPosition(rootCommitTagged) != -1);
 		assertTrue("head referenced commit is in graph",
 				cg.findGraphPosition(headTip) != -1);
-		// GC_REST packed
-		assertTrue("nonHead referenced commit is in graph",
-				cg.findGraphPosition(nonHeadTip) != -1);
+		// GC_REST not in commit graph
+		assertEquals("nonHead referenced commit is NOT in graph",
+				-1, cg.findGraphPosition(nonHeadTip));
 	}
 
 	@Test
-	public void produceCommitGraphAllRefsIncludedFromCache() throws Exception {
+	public void produceCommitGraphOnlyHeadsAndTagsIncludedFromCache() throws Exception {
 		String tag = "refs/tags/tag1";
 		String head = "refs/heads/head1";
 		String nonHead = "refs/something/nonHead";
@@ -1042,15 +1045,16 @@
 		assertTrue("commit graph read time is recorded",
 				reader.stats.readCommitGraphMicros > 0);
 
-		assertTrue("all commits in commit graph", cachedCG.getCommitCnt() == 3);
+		assertTrue("Only heads and tags reachable commits in commit graph",
+				cachedCG.getCommitCnt() == 2);
 		// GC packed
 		assertTrue("tag referenced commit is in graph",
 				cachedCG.findGraphPosition(rootCommitTagged) != -1);
 		assertTrue("head referenced commit is in graph",
 				cachedCG.findGraphPosition(headTip) != -1);
-		// GC_REST packed
-		assertTrue("nonHead referenced commit is in graph",
-				cachedCG.findGraphPosition(nonHeadTip) != -1);
+		// GC_REST not in commit graph
+		assertEquals("nonHead referenced commit is not in graph",
+				-1, cachedCG.findGraphPosition(nonHeadTip));
 	}
 
 	@Test
@@ -1100,6 +1104,86 @@
 		}
 	}
 
+	@Test
+	public void produceCommitGraphAndBloomFilter() throws Exception {
+		String head = "refs/heads/head1";
+
+		git.branch(head).commit().message("0").noParents().create();
+
+		gcWithCommitGraphAndBloomFilter();
+
+		assertEquals(1, odb.getPacks().length);
+		DfsPackFile pack = odb.getPacks()[0];
+		DfsPackDescription desc = pack.getPackDescription();
+		CommitGraphWriter.Stats stats = desc.getCommitGraphStats();
+		assertNotNull(stats);
+		assertEquals(1, stats.getChangedPathFiltersComputed());
+	}
+
+	@Test
+	public void objectSizeIdx_reachableBlob_bigEnough_indexed() throws Exception {
+		String master = "refs/heads/master";
+		RevCommit root = git.branch(master).commit().message("root").noParents()
+				.create();
+		RevBlob headsBlob = git.blob("twelve bytes");
+		git.branch(master).commit()
+				.message("commit on head")
+				.add("file.txt", headsBlob)
+				.parent(root)
+				.create();
+
+		gcWithObjectSizeIndex(10);
+
+		DfsReader reader = odb.newReader();
+		DfsPackFile gcPack = findFirstBySource(odb.getPacks(), GC);
+		assertTrue(gcPack.hasObjectSizeIndex(reader));
+		assertEquals(12, gcPack.getIndexedObjectSize(reader, headsBlob));
+	}
+
+	@Test
+	public void objectSizeIdx_reachableBlob_tooSmall_notIndexed() throws Exception {
+		String master = "refs/heads/master";
+		RevCommit root = git.branch(master).commit().message("root").noParents()
+				.create();
+		RevBlob tooSmallBlob = git.blob("small");
+		git.branch(master).commit()
+				.message("commit on head")
+				.add("small.txt", tooSmallBlob)
+				.parent(root)
+				.create();
+
+		gcWithObjectSizeIndex(10);
+
+		DfsReader reader = odb.newReader();
+		DfsPackFile gcPack = findFirstBySource(odb.getPacks(), GC);
+		assertTrue(gcPack.hasObjectSizeIndex(reader));
+		assertEquals(-1, gcPack.getIndexedObjectSize(reader, tooSmallBlob));
+	}
+
+	@Test
+	public void objectSizeIndex_unreachableGarbage_noIdx() throws Exception {
+		String master = "refs/heads/master";
+		RevCommit root = git.branch(master).commit().message("root").noParents()
+				.create();
+		git.branch(master).commit()
+				.message("commit on head")
+				.add("file.txt", git.blob("a blob"))
+				.parent(root)
+				.create();
+		git.update(master, root); // blob is unreachable
+		gcWithObjectSizeIndex(0);
+
+		DfsReader reader = odb.newReader();
+		DfsPackFile gcRestPack = findFirstBySource(odb.getPacks(), UNREACHABLE_GARBAGE);
+		assertFalse(gcRestPack.hasObjectSizeIndex(reader));
+	}
+
+	private static DfsPackFile findFirstBySource(DfsPackFile[] packs, PackSource source) {
+		return Arrays.stream(packs)
+				.filter(p -> p.getPackDescription().getPackSource() == source)
+				.findFirst().get();
+	}
+
 	private TestRepository<InMemoryRepository>.CommitBuilder commit() {
 		return git.commit();
 	}
@@ -1110,6 +1194,19 @@
 		run(gc);
 	}
 
+	private void gcWithCommitGraphAndBloomFilter() throws IOException {
+		DfsGarbageCollector gc = new DfsGarbageCollector(repo);
+		gc.setWriteCommitGraph(true);
+		gc.setWriteBloomFilter(true);
+		run(gc);
+	}
+
+	private void gcWithObjectSizeIndex(int threshold) throws IOException {
+		DfsGarbageCollector gc = new DfsGarbageCollector(repo);
+		gc.getPackConfig().setMinBytesForObjSizeIndex(threshold);
+		run(gc);
+	}
+
 	private void gcNoTtl() throws IOException {
 		DfsGarbageCollector gc = new DfsGarbageCollector(repo);
 		gc.setGarbageTtl(0, TimeUnit.MILLISECONDS); // disable TTL
diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/dfs/DfsInserterTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/dfs/DfsInserterTest.java
index adf577b..b84a0b0 100644
--- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/dfs/DfsInserterTest.java
+++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/dfs/DfsInserterTest.java
@@ -10,6 +10,8 @@
 
 package org.eclipse.jgit.internal.storage.dfs;
 
+import static org.eclipse.jgit.lib.ConfigConstants.CONFIG_KEY_MIN_BYTES_OBJ_SIZE_INDEX;
+import static org.eclipse.jgit.lib.ConfigConstants.CONFIG_PACK_SECTION;
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertFalse;
 import static org.junit.Assert.assertSame;
@@ -29,11 +31,16 @@
 import org.eclipse.jgit.junit.JGitTestUtil;
 import org.eclipse.jgit.junit.TestRng;
 import org.eclipse.jgit.lib.AbbreviatedObjectId;
+import org.eclipse.jgit.lib.CommitBuilder;
 import org.eclipse.jgit.lib.Constants;
+import org.eclipse.jgit.lib.FileMode;
 import org.eclipse.jgit.lib.ObjectId;
 import org.eclipse.jgit.lib.ObjectInserter;
 import org.eclipse.jgit.lib.ObjectLoader;
 import org.eclipse.jgit.lib.ObjectReader;
+import org.eclipse.jgit.lib.PersonIdent;
+import org.eclipse.jgit.lib.TagBuilder;
+import org.eclipse.jgit.lib.TreeFormatter;
 import org.eclipse.jgit.util.IO;
 import org.eclipse.jgit.util.RawParseUtils;
 import org.junit.Before;
@@ -240,6 +247,71 @@
 		}
 	}
 
+	@Test
+	public void testObjectSizePopulated() throws IOException {
+		// Blob
+		byte[] contents = Constants.encode("foo");
+
+		// Commit
+		PersonIdent person = new PersonIdent("Committer a", "jgit@eclipse.org");
+		CommitBuilder c = new CommitBuilder();
+		c.setAuthor(person);
+		c.setCommitter(person);
+		c.setTreeId(ObjectId
+				.fromString("45c4c6767a3945815371a7016532751dd558be40"));
+		c.setMessage("commit message");
+
+		// Tree
+		TreeFormatter treeBuilder = new TreeFormatter(2);
+		treeBuilder.append("filea", FileMode.REGULAR_FILE, ObjectId
+				.fromString("45c4c6767a3945815371a7016532751dd558be40"));
+		treeBuilder.append("fileb", FileMode.GITLINK, ObjectId
+				.fromString("1c458e25ca624bb8d4735bec1379a4a29ba786d0"));
+
+		// Tag
+		TagBuilder tagBuilder = new TagBuilder();
+		tagBuilder.setObjectId(
+				ObjectId.fromString("c97fe131649e80de55bd153e9a8d8629f7ca6932"),
+				Constants.OBJ_COMMIT);
+		tagBuilder.setTag("short name");
+
+		try (DfsInserter ins = (DfsInserter) db.newObjectInserter()) {
+			ObjectId aBlob = ins.insert(Constants.OBJ_BLOB, contents);
+			assertEquals(contents.length,
+					ins.objectMap.get(aBlob).getFullSize());
+
+			ObjectId aCommit = ins.insert(c);
+			assertEquals(174, ins.objectMap.get(aCommit).getFullSize());
+
+			ObjectId tree = ins.insert(treeBuilder);
+			assertEquals(66, ins.objectMap.get(tree).getFullSize());
+
+			ObjectId tag = ins.insert(tagBuilder);
+			assertEquals(76, ins.objectMap.get(tag).getFullSize());
+		}
+	}
+
+	@Test
+	public void testObjectSizeIndexOnInsert() throws IOException {
+		db.getConfig().setInt(CONFIG_PACK_SECTION, null,
+				CONFIG_KEY_MIN_BYTES_OBJ_SIZE_INDEX, 0);
+
+		byte[] contents = Constants.encode("foo");
+		ObjectId fooId;
+		try (ObjectInserter ins = db.newObjectInserter()) {
+			fooId = ins.insert(Constants.OBJ_BLOB, contents);
+			ins.flush();
+		}
+
+		DfsReader reader = db.getObjectDatabase().newReader();
+		assertEquals(1, db.getObjectDatabase().listPacks().size());
+		DfsPackFile insertPack = db.getObjectDatabase().getPacks()[0];
+		assertEquals(PackSource.INSERT,
+				insertPack.getPackDescription().getPackSource());
+		assertTrue(insertPack.hasObjectSizeIndex(reader));
+		assertEquals(contents.length, insertPack.getIndexedObjectSize(reader, fooId));
+	}
+
 	private static String readString(ObjectLoader loader) throws IOException {
 		return RawParseUtils.decode(readStream(loader));
 	}
diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/dfs/DfsPackFileTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/dfs/DfsPackFileTest.java
index ea57873..77e5b7c 100644
--- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/dfs/DfsPackFileTest.java
+++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/dfs/DfsPackFileTest.java
@@ -10,12 +10,20 @@
 
 package org.eclipse.jgit.internal.storage.dfs;
 
+import static org.eclipse.jgit.lib.ConfigConstants.CONFIG_KEY_MIN_BYTES_OBJ_SIZE_INDEX;
+import static org.eclipse.jgit.lib.ConfigConstants.CONFIG_PACK_SECTION;
 import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
 
 import java.io.ByteArrayOutputStream;
 import java.io.IOException;
+import java.util.HashMap;
+import java.util.Map;
 import java.util.zip.Deflater;
 
+import org.eclipse.jgit.internal.storage.dfs.DfsObjDatabase.PackSource;
+import org.eclipse.jgit.internal.storage.dfs.DfsReader.PackLoadListener;
 import org.eclipse.jgit.internal.storage.pack.PackExt;
 import org.eclipse.jgit.internal.storage.pack.PackOutputStream;
 import org.eclipse.jgit.internal.storage.pack.PackWriter;
@@ -23,6 +31,7 @@
 import org.eclipse.jgit.junit.TestRng;
 import org.eclipse.jgit.lib.Constants;
 import org.eclipse.jgit.lib.NullProgressMonitor;
+import org.eclipse.jgit.lib.ObjectId;
 import org.junit.Before;
 import org.junit.Test;
 
@@ -100,7 +109,120 @@
 		assertPackSize();
 	}
 
-	private void setupPack(int bs, int ps) throws IOException {
+	@Test
+	public void testLoadObjectSizeIndex() throws IOException {
+		bypassCache = false;
+		clearCache = true;
+		setObjectSizeIndexMinBytes(0);
+		ObjectId blobId = setupPack(512, 800);
+
+		DfsReader reader = db.getObjectDatabase().newReader();
+		DfsPackFile pack = db.getObjectDatabase().getPacks()[0];
+		assertTrue(pack.hasObjectSizeIndex(reader));
+		assertEquals(800, pack.getIndexedObjectSize(reader, blobId));
+	}
+
+	@Test
+	public void testLoadObjectSizeIndex_noIndex() throws IOException {
+		bypassCache = false;
+		clearCache = true;
+		setObjectSizeIndexMinBytes(-1);
+		setupPack(512, 800);
+
+		DfsReader reader = db.getObjectDatabase().newReader();
+		DfsPackFile pack = db.getObjectDatabase().getPacks()[0];
+		assertFalse(pack.hasObjectSizeIndex(reader));
+	}
+
+	private static class TestPackLoadListener implements PackLoadListener {
+		final Map<PackExt, Integer> indexLoadCount = new HashMap<>();
+
+		int blockLoadCount;
+
+		@SuppressWarnings("boxing")
+		@Override
+		public void onIndexLoad(String packName, PackSource src, PackExt ext,
+				long size, Object loadedIdx) {
+			indexLoadCount.merge(ext, 1, Integer::sum);
+		}
+
+		@Override
+		public void onBlockLoad(String packName, PackSource src, PackExt ext, long position,
+				DfsBlockData dfsBlockData) {
+			blockLoadCount += 1;
+		}
+	}
+
+	@Test
+	public void testIndexLoadCallback_indexNotInCache() throws IOException {
+		bypassCache = false;
+		clearCache = true;
+		setObjectSizeIndexMinBytes(-1);
+		setupPack(512, 800);
+
+		TestPackLoadListener tal = new TestPackLoadListener();
+		DfsReader reader = db.getObjectDatabase().newReader();
+		reader.addPackLoadListener(tal);
+		DfsPackFile pack = db.getObjectDatabase().getPacks()[0];
+		pack.getPackIndex(reader);
+
+		assertEquals(1, tal.indexLoadCount.get(PackExt.INDEX).intValue());
+	}
+
+	@Test
+	public void testIndexLoadCallback_indexInCache() throws IOException {
+		bypassCache = false;
+		clearCache = false;
+		setObjectSizeIndexMinBytes(-1);
+		setupPack(512, 800);
+
+		TestPackLoadListener tal = new TestPackLoadListener();
+		DfsReader reader = db.getObjectDatabase().newReader();
+		reader.addPackLoadListener(tal);
+		DfsPackFile pack = db.getObjectDatabase().getPacks()[0];
+		pack.getPackIndex(reader);
+		pack.getPackIndex(reader);
+		pack.getPackIndex(reader);
+
+		assertEquals(1, tal.indexLoadCount.get(PackExt.INDEX).intValue());
+	}
+
+	@Test
+	public void testIndexLoadCallback_multipleReads() throws IOException {
+		bypassCache = false;
+		clearCache = true;
+		setObjectSizeIndexMinBytes(-1);
+		setupPack(512, 800);
+
+		TestPackLoadListener tal = new TestPackLoadListener();
+		DfsReader reader = db.getObjectDatabase().newReader();
+		reader.addPackLoadListener(tal);
+		DfsPackFile pack = db.getObjectDatabase().getPacks()[0];
+		pack.getPackIndex(reader);
+		pack.getPackIndex(reader);
+		pack.getPackIndex(reader);
+
+		assertEquals(1, tal.indexLoadCount.get(PackExt.INDEX).intValue());
+	}
+
+
+	@Test
+	public void testBlockLoadCallback_loadInCache() throws IOException {
+		bypassCache = false;
+		clearCache = true;
+		setObjectSizeIndexMinBytes(-1);
+		setupPack(512, 800);
+
+		TestPackLoadListener tal = new TestPackLoadListener();
+		DfsReader reader = db.getObjectDatabase().newReader();
+		reader.addPackLoadListener(tal);
+		DfsPackFile pack = db.getObjectDatabase().getPacks()[0];
+		ObjectId anObject = pack.getPackIndex(reader).getObjectId(0);
+		pack.get(reader, anObject).getBytes();
+		assertEquals(2, tal.blockLoadCount);
+	}
+
+	private ObjectId setupPack(int bs, int ps) throws IOException {
 		DfsBlockCacheConfig cfg = new DfsBlockCacheConfig().setBlockSize(bs)
 				.setBlockLimit(bs * 100).setStreamRatio(bypassCache ? 0F : 1F);
 		DfsBlockCache.reconfigure(cfg);
@@ -108,13 +230,14 @@
 		byte[] data = new TestRng(JGitTestUtil.getName()).nextBytes(ps);
 		DfsInserter ins = (DfsInserter) db.newObjectInserter();
 		ins.setCompressionLevel(Deflater.NO_COMPRESSION);
-		ins.insert(Constants.OBJ_BLOB, data);
+		ObjectId blobId = ins.insert(Constants.OBJ_BLOB, data);
 		ins.flush();
 
 		if (clearCache) {
 			DfsBlockCache.reconfigure(cfg);
 			db.getObjectDatabase().clearCache();
 		}
+		return blobId;
 	}
 
 	private void assertPackSize() throws IOException {
@@ -129,4 +252,9 @@
 			assertEquals(packSize - (12 + 20), os.size());
 		}
 	}
+
+	private void setObjectSizeIndexMinBytes(int threshold) {
+		db.getConfig().setInt(CONFIG_PACK_SECTION, null,
+				CONFIG_KEY_MIN_BYTES_OBJ_SIZE_INDEX, threshold);
+	}
 }
diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/dfs/DfsPackParserTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/dfs/DfsPackParserTest.java
new file mode 100644
index 0000000..845d5fc
--- /dev/null
+++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/dfs/DfsPackParserTest.java
@@ -0,0 +1,69 @@
+/*
+ * Copyright (C) 2023, Google LLC and others.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Distribution License v. 1.0 which is available at
+ * https://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+package org.eclipse.jgit.internal.storage.dfs;
+
+import static org.eclipse.jgit.lib.ConfigConstants.CONFIG_KEY_MIN_BYTES_OBJ_SIZE_INDEX;
+import static org.eclipse.jgit.lib.ConfigConstants.CONFIG_PACK_SECTION;
+import static org.junit.Assert.assertEquals;
+
+import java.io.IOException;
+
+import org.eclipse.jgit.internal.storage.dfs.DfsObjDatabase.PackList;
+import org.eclipse.jgit.lib.Constants;
+import org.eclipse.jgit.lib.NullProgressMonitor;
+import org.eclipse.jgit.lib.ObjectId;
+import org.eclipse.jgit.lib.ObjectInserter;
+import org.eclipse.jgit.transport.InMemoryPack;
+import org.eclipse.jgit.transport.PackParser;
+import org.junit.Before;
+import org.junit.Test;
+
+public class DfsPackParserTest {
+  private InMemoryRepository repo;
+
+
+	@Before
+	public void setUp() throws Exception {
+		DfsRepositoryDescription desc = new DfsRepositoryDescription("test");
+		repo = new InMemoryRepository(desc);
+		repo.getConfig().setInt(CONFIG_PACK_SECTION, null,
+				CONFIG_KEY_MIN_BYTES_OBJ_SIZE_INDEX, 0);
+	}
+
+	@Test
+	public void parse_writeObjSizeIdx() throws IOException {
+		InMemoryPack pack = new InMemoryPack();
+
+		// Sha1 of the blob "a"
+		ObjectId blobA = ObjectId
+				.fromString("2e65efe2a145dda7ee51d1741299f848e5bf752e");
+
+		pack.header(2);
+		pack.write((Constants.OBJ_BLOB) << 4 | 1);
+		pack.deflate(new byte[] { 'a' });
+
+		pack.write((Constants.OBJ_REF_DELTA) << 4 | 4);
+		pack.copyRaw(blobA);
+		pack.deflate(new byte[] { 0x1, 0x1, 0x1, 'b' });
+		pack.digest();
+
+		try (ObjectInserter ins = repo.newObjectInserter()) {
+			PackParser parser = ins.newPackParser(pack.toInputStream());
+			parser.parse(NullProgressMonitor.INSTANCE,
+					NullProgressMonitor.INSTANCE);
+			ins.flush();
+		}
+
+		DfsReader reader = repo.getObjectDatabase().newReader();
+		PackList packList = repo.getObjectDatabase().getPackList();
+		assertEquals(1, packList.packs.length);
+		assertEquals(1, packList.packs[0].getIndexedObjectSize(reader, blobA));
+	}
+}
diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/dfs/DfsReaderTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/dfs/DfsReaderTest.java
new file mode 100644
index 0000000..eb8ceec
--- /dev/null
+++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/dfs/DfsReaderTest.java
@@ -0,0 +1,262 @@
+/*
+ * Copyright (C) 2023, Google LLC. and others
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Distribution License v. 1.0 which is available at
+ * https://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+package org.eclipse.jgit.internal.storage.dfs;
+
+import static org.eclipse.jgit.lib.ConfigConstants.CONFIG_KEY_MIN_BYTES_OBJ_SIZE_INDEX;
+import static org.eclipse.jgit.lib.ConfigConstants.CONFIG_PACK_SECTION;
+import static org.eclipse.jgit.lib.Constants.OBJ_BLOB;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+
+import java.io.IOException;
+import java.util.HashMap;
+import java.util.Map;
+
+import org.eclipse.jgit.internal.storage.dfs.DfsObjDatabase.PackSource;
+import org.eclipse.jgit.internal.storage.dfs.DfsReader.PackLoadListener;
+import org.eclipse.jgit.internal.storage.pack.PackExt;
+import org.eclipse.jgit.junit.JGitTestUtil;
+import org.eclipse.jgit.junit.TestRng;
+import org.eclipse.jgit.lib.ObjectId;
+import org.eclipse.jgit.lib.ObjectInserter;
+import org.junit.Before;
+import org.junit.Test;
+
+public class DfsReaderTest {
+	InMemoryRepository db;
+
+	@Before
+	public void setUp() {
+		db = new InMemoryRepository(new DfsRepositoryDescription("test"));
+	}
+
+	@Test
+	public void isNotLargerThan_objAboveThreshold()
+			throws IOException {
+		setObjectSizeIndexMinBytes(100);
+		ObjectId obj = insertBlobWithSize(200);
+		try (DfsReader ctx = db.getObjectDatabase().newReader()) {
+			assertFalse("limit < threshold < obj",
+					ctx.isNotLargerThan(obj, OBJ_BLOB, 50));
+			assertEquals(1, ctx.stats.isNotLargerThanCallCount);
+			assertEquals(1, ctx.stats.objectSizeIndexHit);
+			assertEquals(0, ctx.stats.objectSizeIndexMiss);
+
+			assertFalse("limit = threshold < obj",
+					ctx.isNotLargerThan(obj, OBJ_BLOB, 100));
+			assertEquals(2, ctx.stats.isNotLargerThanCallCount);
+			assertEquals(2, ctx.stats.objectSizeIndexHit);
+			assertEquals(0, ctx.stats.objectSizeIndexMiss);
+
+			assertFalse("threshold < limit < obj",
+					ctx.isNotLargerThan(obj, OBJ_BLOB, 150));
+			assertEquals(3, ctx.stats.isNotLargerThanCallCount);
+			assertEquals(3, ctx.stats.objectSizeIndexHit);
+			assertEquals(0, ctx.stats.objectSizeIndexMiss);
+
+			assertTrue("threshold < limit = obj",
+					ctx.isNotLargerThan(obj, OBJ_BLOB, 200));
+			assertEquals(4, ctx.stats.isNotLargerThanCallCount);
+			assertEquals(4, ctx.stats.objectSizeIndexHit);
+			assertEquals(0, ctx.stats.objectSizeIndexMiss);
+
+			assertTrue("threshold < obj < limit",
+					ctx.isNotLargerThan(obj, OBJ_BLOB, 250));
+			assertEquals(5, ctx.stats.isNotLargerThanCallCount);
+			assertEquals(5, ctx.stats.objectSizeIndexHit);
+			assertEquals(0, ctx.stats.objectSizeIndexMiss);
+		}
+	}
+
+
+	@Test
+	public void isNotLargerThan_objBelowThreshold()
+			throws IOException {
+		setObjectSizeIndexMinBytes(100);
+		insertBlobWithSize(1000); // index not empty
+		ObjectId obj = insertBlobWithSize(50);
+		try (DfsReader ctx = db.getObjectDatabase().newReader()) {
+			assertFalse("limit < obj < threshold",
+					ctx.isNotLargerThan(obj, OBJ_BLOB, 10));
+			assertEquals(1, ctx.stats.isNotLargerThanCallCount);
+			assertEquals(0, ctx.stats.objectSizeIndexHit);
+			assertEquals(1, ctx.stats.objectSizeIndexMiss);
+
+			assertTrue("limit = obj < threshold",
+					ctx.isNotLargerThan(obj, OBJ_BLOB, 50));
+			assertEquals(2, ctx.stats.isNotLargerThanCallCount);
+			assertEquals(0, ctx.stats.objectSizeIndexHit);
+			assertEquals(2, ctx.stats.objectSizeIndexMiss);
+
+			assertTrue("obj < limit < threshold",
+					ctx.isNotLargerThan(obj, OBJ_BLOB, 80));
+			assertEquals(3, ctx.stats.isNotLargerThanCallCount);
+			assertEquals(0, ctx.stats.objectSizeIndexHit);
+			assertEquals(3, ctx.stats.objectSizeIndexMiss);
+
+			assertTrue("obj < limit = threshold",
+					ctx.isNotLargerThan(obj, OBJ_BLOB, 100));
+			assertEquals(4, ctx.stats.isNotLargerThanCallCount);
+			assertEquals(0, ctx.stats.objectSizeIndexHit);
+			assertEquals(4, ctx.stats.objectSizeIndexMiss);
+
+			assertTrue("obj < threshold < limit",
+					ctx.isNotLargerThan(obj, OBJ_BLOB, 120));
+			assertEquals(5, ctx.stats.isNotLargerThanCallCount);
+			assertEquals(0, ctx.stats.objectSizeIndexHit);
+			assertEquals(5, ctx.stats.objectSizeIndexMiss);
+		}
+	}
+
+	@Test
+	public void isNotLargerThan_emptyIdx() throws IOException {
+		setObjectSizeIndexMinBytes(100);
+		ObjectId obj = insertBlobWithSize(10);
+		try (DfsReader ctx = db.getObjectDatabase().newReader()) {
+			assertFalse(ctx.isNotLargerThan(obj, OBJ_BLOB, 0));
+			assertTrue(ctx.isNotLargerThan(obj, OBJ_BLOB, 10));
+			assertTrue(ctx.isNotLargerThan(obj, OBJ_BLOB, 40));
+			assertTrue(ctx.isNotLargerThan(obj, OBJ_BLOB, 50));
+			assertTrue(ctx.isNotLargerThan(obj, OBJ_BLOB, 100));
+
+			assertEquals(5, ctx.stats.isNotLargerThanCallCount);
+			assertEquals(5, ctx.stats.objectSizeIndexMiss);
+			assertEquals(0, ctx.stats.objectSizeIndexHit);
+		}
+	}
+
+	@Test
+	public void isNotLargerThan_noObjectSizeIndex() throws IOException {
+		setObjectSizeIndexMinBytes(-1);
+		ObjectId obj = insertBlobWithSize(10);
+		try (DfsReader ctx = db.getObjectDatabase().newReader()) {
+			assertFalse(ctx.isNotLargerThan(obj, OBJ_BLOB, 0));
+			assertTrue(ctx.isNotLargerThan(obj, OBJ_BLOB, 10));
+			assertTrue(ctx.isNotLargerThan(obj, OBJ_BLOB, 40));
+			assertTrue(ctx.isNotLargerThan(obj, OBJ_BLOB, 50));
+			assertTrue(ctx.isNotLargerThan(obj, OBJ_BLOB, 100));
+
+			assertEquals(5, ctx.stats.isNotLargerThanCallCount);
+			assertEquals(0, ctx.stats.objectSizeIndexMiss);
+			assertEquals(0, ctx.stats.objectSizeIndexHit);
+		}
+	}
+
+	@Test
+	public void packLoadListener_noInvocations() throws IOException {
+		insertBlobWithSize(100);
+		try (DfsReader ctx = db.getObjectDatabase().newReader()) {
+			CounterPackLoadListener listener = new CounterPackLoadListener();
+			ctx.addPackLoadListener(listener);
+			assertEquals(null, listener.callsPerExt.get(PackExt.INDEX));
+		}
+	}
+
+	@Test
+	public void packLoadListener_has_openIdx() throws IOException {
+		ObjectId obj = insertBlobWithSize(100);
+		try (DfsReader ctx = db.getObjectDatabase().newReader()) {
+			CounterPackLoadListener listener = new CounterPackLoadListener();
+			ctx.addPackLoadListener(listener);
+			boolean has = ctx.has(obj);
+			assertTrue(has);
+			assertEquals(Integer.valueOf(1), listener.callsPerExt.get(PackExt.INDEX));
+		}
+	}
+
+	@Test
+	public void packLoadListener_notLargerThan_openMultipleIndices() throws IOException {
+			setObjectSizeIndexMinBytes(100);
+			ObjectId obj = insertBlobWithSize(200);
+			try (DfsReader ctx = db.getObjectDatabase().newReader()) {
+				CounterPackLoadListener listener = new CounterPackLoadListener();
+				ctx.addPackLoadListener(listener);
+				boolean notLargerThan = ctx.isNotLargerThan(obj, OBJ_BLOB, 1000);
+				assertTrue(notLargerThan);
+				assertEquals(Integer.valueOf(1), listener.callsPerExt.get(PackExt.INDEX));
+				assertEquals(Integer.valueOf(1), listener.callsPerExt.get(PackExt.OBJECT_SIZE_INDEX));
+			}
+	}
+
+	@Test
+	public void packLoadListener_has_openMultipleIndices() throws IOException {
+		setObjectSizeIndexMinBytes(100);
+		insertBlobWithSize(200);
+		insertBlobWithSize(230);
+		insertBlobWithSize(100);
+		try (DfsReader ctx = db.getObjectDatabase().newReader()) {
+			CounterPackLoadListener listener = new CounterPackLoadListener();
+			ctx.addPackLoadListener(listener);
+			ObjectId oid = ObjectId.fromString("aa48de2aa61d9dffa8a05439dc115fe82f10f129");
+			boolean has = ctx.has(oid);
+			assertFalse(has);
+			// Open 3 indices trying to find the pack
+			assertEquals(Integer.valueOf(3), listener.callsPerExt.get(PackExt.INDEX));
+		}
+	}
+
+
+	@Test
+	public void packLoadListener_has_repeatedCalls_openMultipleIndices() throws IOException {
+		// Two objects NOT in the repo
+		ObjectId oid = ObjectId.fromString("aa48de2aa61d9dffa8a05439dc115fe82f10f129");
+		ObjectId oid2 = ObjectId.fromString("aa48de2aa61d9dffa8a05439dc115fe82f10f130");
+
+		setObjectSizeIndexMinBytes(100);
+		insertBlobWithSize(200);
+		insertBlobWithSize(230);
+		insertBlobWithSize(100);
+		CounterPackLoadListener listener = new CounterPackLoadListener();
+		try (DfsReader ctx = db.getObjectDatabase().newReader()) {
+			ctx.addPackLoadListener(listener);
+			boolean has = ctx.has(oid);
+			ctx.has(oid);
+			ctx.has(oid2);
+			assertFalse(has);
+			// The 3 indices were loaded only once each
+			assertEquals(Integer.valueOf(3), listener.callsPerExt.get(PackExt.INDEX));
+		}
+	}
+
+	private static class CounterPackLoadListener implements PackLoadListener {
+		final Map<PackExt, Integer> callsPerExt = new HashMap<>();
+
+		@SuppressWarnings("boxing")
+		@Override
+		public void onIndexLoad(String packName, PackSource src, PackExt ext, long size,
+				Object loadedIdx) {
+			callsPerExt.merge(ext, 1, Integer::sum);
+		}
+
+		@Override
+		public void onBlockLoad(String packName, PackSource src, PackExt ext,
+				long size, DfsBlockData dfsBlockData) {
+			// empty
+		}
+	}
+
+	private ObjectId insertBlobWithSize(int size)
+			throws IOException {
+		TestRng testRng = new TestRng(JGitTestUtil.getName());
+		ObjectId oid;
+		try (ObjectInserter ins = db.newObjectInserter()) {
+				oid = ins.insert(OBJ_BLOB,
+						testRng.nextBytes(size));
+			ins.flush();
+		}
+		return oid;
+	}
+
+	private void setObjectSizeIndexMinBytes(int threshold) {
+		db.getConfig().setInt(CONFIG_PACK_SECTION, null,
+				CONFIG_KEY_MIN_BYTES_OBJ_SIZE_INDEX, threshold);
+	}
+}
diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/file/FileRepositoryBuilderAfterOpenConfigTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/file/FileRepositoryBuilderAfterOpenConfigTest.java
index 100bd32..ed5a699 100644
--- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/file/FileRepositoryBuilderAfterOpenConfigTest.java
+++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/file/FileRepositoryBuilderAfterOpenConfigTest.java
@@ -18,7 +18,6 @@
 import org.junit.Before;
 
 public class FileRepositoryBuilderAfterOpenConfigTest extends FileRepositoryBuilderTest {
-	/** {@inheritDoc} */
 	@Before
 	@Override
 	public void setUp() throws Exception {
diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/file/GcReverseIndexTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/file/GcReverseIndexTest.java
new file mode 100644
index 0000000..cbb0943
--- /dev/null
+++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/file/GcReverseIndexTest.java
@@ -0,0 +1,116 @@
+/*
+ * Copyright (C) 2023, Google LLC and others
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Distribution License v. 1.0 which is available at
+ * 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.eclipse.jgit.internal.storage.pack.PackExt.REVERSE_INDEX;
+import static org.junit.Assert.assertArrayEquals;
+import static org.junit.Assert.assertEquals;
+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.revwalk.RevCommit;
+import org.eclipse.jgit.storage.pack.PackConfig;
+import org.eclipse.jgit.util.IO;
+import org.junit.Test;
+
+public class GcReverseIndexTest extends GcTestCase {
+
+	@Test
+	public void testWriteDefault() throws Exception {
+		PackConfig config = new PackConfig(repo);
+		gc.setPackConfig(config);
+
+		RevCommit tip = commitChain(10);
+		TestRepository.BranchBuilder bb = tr.branch("refs/heads/main");
+		bb.update(tip);
+
+		gc.gc().get();
+		assertRidxDoesNotExist(repo);
+	}
+
+	@Test
+	public void testWriteDisabled() throws Exception {
+		PackConfig config = new PackConfig(repo);
+		config.setWriteReverseIndex(false);
+		gc.setPackConfig(config);
+
+		RevCommit tip = commitChain(10);
+		TestRepository.BranchBuilder bb = tr.branch("refs/heads/main");
+		bb.update(tip);
+
+		gc.gc().get();
+		assertRidxDoesNotExist(repo);
+	}
+
+	@Test
+	public void testWriteEmptyRepo() throws Exception {
+		PackConfig config = new PackConfig(repo);
+		config.setWriteReverseIndex(true);
+		gc.setPackConfig(config);
+
+		gc.gc().get();
+		assertRidxDoesNotExist(repo);
+	}
+
+	@Test
+	public void testWriteShallowRepo() throws Exception {
+		PackConfig config = new PackConfig(repo);
+		config.setWriteReverseIndex(true);
+		gc.setPackConfig(config);
+
+		RevCommit tip = commitChain(2);
+		TestRepository.BranchBuilder bb = tr.branch("refs/heads/main");
+		bb.update(tip);
+		repo.getObjectDatabase().setShallowCommits(Collections.singleton(tip));
+
+		gc.gc().get();
+		assertValidRidxExists(repo);
+	}
+
+	@Test
+	public void testWriteEnabled() throws Exception {
+		PackConfig config = new PackConfig(repo);
+		config.setWriteReverseIndex(true);
+		gc.setPackConfig(config);
+
+		RevCommit tip = commitChain(10);
+		TestRepository.BranchBuilder bb = tr.branch("refs/heads/main");
+		bb.update(tip);
+
+		gc.gc().get();
+		assertValidRidxExists(repo);
+	}
+
+	private static void assertValidRidxExists(FileRepository repo)
+			throws Exception {
+		PackFile packFile = repo.getObjectDatabase().getPacks().iterator()
+				.next().getPackFile();
+		File file = packFile.create(REVERSE_INDEX);
+		assertTrue(file.exists());
+		try (InputStream os = new FileInputStream(file)) {
+			byte[] magic = new byte[4];
+			IO.readFully(os, magic, 0, 4);
+			assertArrayEquals(new byte[] { 'R', 'I', 'D', 'X' }, magic);
+		}
+	}
+
+	private static void assertRidxDoesNotExist(FileRepository repo) {
+		File packDir = repo.getObjectDatabase().getPackDirectory();
+		String[] reverseIndexFilenames = packDir.list(
+				(dir, name) -> name.endsWith(REVERSE_INDEX.getExtension()));
+		assertEquals(0, reverseIndexFilenames.length);
+	}
+}
diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/file/PackReverseIndexComputedTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/file/PackReverseIndexComputedTest.java
new file mode 100644
index 0000000..ea5aaf5
--- /dev/null
+++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/file/PackReverseIndexComputedTest.java
@@ -0,0 +1,108 @@
+/*
+ * Copyright (C) 2008, Imran M Yousuf <imyousuf@smartitengineering.com>
+ * Copyright (C) 2008, Marek Zawirski <marek.zawirski@gmail.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.file;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+
+import org.eclipse.jgit.errors.CorruptObjectException;
+import org.eclipse.jgit.errors.PackMismatchException;
+import org.eclipse.jgit.internal.storage.file.PackIndex.MutableEntry;
+import org.eclipse.jgit.junit.JGitTestUtil;
+import org.eclipse.jgit.junit.RepositoryTestCase;
+import org.junit.Before;
+import org.junit.Test;
+
+public class PackReverseIndexComputedTest extends RepositoryTestCase {
+
+	private PackIndex idx;
+
+	private PackReverseIndex reverseIdx;
+
+	/**
+	 * Set up tested class instance, test constructor by the way.
+	 */
+	@Override
+	@Before
+	public void setUp() throws Exception {
+		super.setUp();
+		// index with both small (< 2^31) and big offsets
+		idx = PackIndex.open(JGitTestUtil.getTestResourceFile("pack-huge.idx"));
+		reverseIdx = PackReverseIndexFactory.computeFromIndex(idx);
+	}
+
+	/**
+	 * Test findObject() for all index entries.
+	 */
+	@Test
+	public void testFindObject() {
+		for (MutableEntry me : idx)
+			assertEquals(me.toObjectId(), reverseIdx.findObject(me.getOffset()));
+	}
+
+	/**
+	 * Test findObject() with illegal argument.
+	 */
+	@Test
+	public void testFindObjectWrongOffset() {
+		assertNull(reverseIdx.findObject(0));
+	}
+
+	/**
+	 * Test findNextOffset() for all index entries.
+	 *
+	 * @throws CorruptObjectException
+	 */
+	@Test
+	public void testFindNextOffset() throws CorruptObjectException {
+		long offset = findFirstOffset();
+		assertTrue(offset > 0);
+		for (int i = 0; i < idx.getObjectCount(); i++) {
+			long newOffset = reverseIdx.findNextOffset(offset, Long.MAX_VALUE);
+			assertTrue(newOffset > offset);
+			if (i == idx.getObjectCount() - 1)
+				assertEquals(newOffset, Long.MAX_VALUE);
+			else
+				assertEquals(newOffset, idx.findOffset(reverseIdx
+						.findObject(newOffset)));
+			offset = newOffset;
+		}
+	}
+
+	/**
+	 * Test findNextOffset() with wrong illegal argument as offset.
+	 */
+	@Test
+	public void testFindNextOffsetWrongOffset() {
+		try {
+			reverseIdx.findNextOffset(0, Long.MAX_VALUE);
+			fail("findNextOffset() should throw exception");
+		} catch (CorruptObjectException x) {
+			// expected
+		}
+	}
+
+	@Test
+	public void testVerifyChecksum() throws PackMismatchException {
+		// ComputedReverseIndex doesn't have a file containing a checksum.
+		reverseIdx.verifyPackChecksum(null);
+	}
+
+	private long findFirstOffset() {
+		long min = Long.MAX_VALUE;
+		for (MutableEntry me : idx)
+			min = Math.min(min, me.getOffset());
+		return min;
+	}
+}
diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/file/PackReverseIndexTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/file/PackReverseIndexTest.java
index 292e3e7..f8fb4c1 100644
--- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/file/PackReverseIndexTest.java
+++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/file/PackReverseIndexTest.java
@@ -1,6 +1,5 @@
 /*
- * Copyright (C) 2008, Imran M Yousuf <imyousuf@smartitengineering.com>
- * Copyright (C) 2008, Marek Zawirski <marek.zawirski@gmail.com> and others
+ * Copyright (C) 2022, Google LLC and others
  *
  * This program and the accompanying materials are made available under the
  * terms of the Eclipse Distribution License v. 1.0 which is available at
@@ -8,95 +7,94 @@
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
-
 package org.eclipse.jgit.internal.storage.file;
 
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertThrows;
 import static org.junit.Assert.assertTrue;
-import static org.junit.Assert.fail;
 
-import org.eclipse.jgit.errors.CorruptObjectException;
-import org.eclipse.jgit.internal.storage.file.PackIndex.MutableEntry;
+import java.io.ByteArrayInputStream;
+import java.io.File;
+import java.io.IOException;
+
+import org.eclipse.jgit.internal.storage.pack.PackExt;
 import org.eclipse.jgit.junit.JGitTestUtil;
-import org.eclipse.jgit.junit.RepositoryTestCase;
-import org.junit.Before;
 import org.junit.Test;
 
-public class PackReverseIndexTest extends RepositoryTestCase {
+public class PackReverseIndexTest {
 
-	private PackIndex idx;
-
-	private PackReverseIndex reverseIdx;
-
-	/**
-	 * Set up tested class instance, test constructor by the way.
-	 */
-	@Override
-	@Before
-	public void setUp() throws Exception {
-		super.setUp();
-		// index with both small (< 2^31) and big offsets
-		idx = PackIndex.open(JGitTestUtil.getTestResourceFile(
-				"pack-huge.idx"));
-		reverseIdx = new PackReverseIndex(idx);
-	}
-
-	/**
-	 * Test findObject() for all index entries.
-	 */
 	@Test
-	public void testFindObject() {
-		for (MutableEntry me : idx)
-			assertEquals(me.toObjectId(), reverseIdx.findObject(me.getOffset()));
+	public void open_fallbackToComputed() throws IOException {
+		String noRevFilePrefix = "pack-3280af9c07ee18a87705ef50b0cc4cd20266cf12.";
+		PackReverseIndex computed = PackReverseIndexFactory.openOrCompute(
+				getResourceFileFor(noRevFilePrefix, PackExt.REVERSE_INDEX), 7,
+				() -> PackIndex.open(
+						getResourceFileFor(noRevFilePrefix, PackExt.INDEX)));
+
+		assertTrue(computed instanceof PackReverseIndexComputed);
 	}
 
-	/**
-	 * Test findObject() with illegal argument.
-	 */
 	@Test
-	public void testFindObjectWrongOffset() {
-		assertNull(reverseIdx.findObject(0));
+	public void open_readGoodFile() throws IOException {
+		String hasRevFilePrefix = "pack-cbdeda40019ae0e6e789088ea0f51f164f489d14.";
+		PackReverseIndex version1 = PackReverseIndexFactory.openOrCompute(
+				getResourceFileFor(hasRevFilePrefix, PackExt.REVERSE_INDEX), 6,
+				() -> PackIndex.open(
+						getResourceFileFor(hasRevFilePrefix, PackExt.INDEX)));
+
+		assertTrue(version1 instanceof PackReverseIndexV1);
 	}
 
-	/**
-	 * Test findNextOffset() for all index entries.
-	 *
-	 * @throws CorruptObjectException
-	 */
 	@Test
-	public void testFindNextOffset() throws CorruptObjectException {
-		long offset = findFirstOffset();
-		assertTrue(offset > 0);
-		for (int i = 0; i < idx.getObjectCount(); i++) {
-			long newOffset = reverseIdx.findNextOffset(offset, Long.MAX_VALUE);
-			assertTrue(newOffset > offset);
-			if (i == idx.getObjectCount() - 1)
-				assertEquals(newOffset, Long.MAX_VALUE);
-			else
-				assertEquals(newOffset, idx.findOffset(reverseIdx
-						.findObject(newOffset)));
-			offset = newOffset;
-		}
+	public void open_readCorruptFile() {
+		String hasRevFilePrefix = "pack-cbdeda40019ae0e6e789088ea0f51f164f489d14.";
+
+		assertThrows(IOException.class,
+				() -> PackReverseIndexFactory.openOrCompute(
+						getResourceFileFor(hasRevFilePrefix + "corrupt.",
+								PackExt.REVERSE_INDEX),
+						6, () -> PackIndex.open(getResourceFileFor(
+								hasRevFilePrefix, PackExt.INDEX))));
 	}
 
-	/**
-	 * Test findNextOffset() with wrong illegal argument as offset.
-	 */
 	@Test
-	public void testFindNextOffsetWrongOffset() {
-		try {
-			reverseIdx.findNextOffset(0, Long.MAX_VALUE);
-			fail("findNextOffset() should throw exception");
-		} catch (CorruptObjectException x) {
-			// expected
-		}
+	public void read_badMagic() {
+		byte[] badMagic = new byte[] { 'R', 'B', 'A', 'D', // magic
+				0x00, 0x00, 0x00, 0x01, // file version
+				0x00, 0x00, 0x00, 0x01, // oid version
+				// pack checksum
+				'P', 'A', 'C', 'K', 'C', 'H', 'E', 'C', 'K', 'S', 'U', 'M', '3',
+				'4', '5', '6', '7', '8', '9', '0',
+				// checksum
+				0x66, 0x01, (byte) 0xbc, (byte) 0xe8, 0x51, 0x4b, 0x2f,
+				(byte) 0xa1, (byte) 0xa9, (byte) 0xcd, (byte) 0xbe, (byte) 0xd6,
+				0x4f, (byte) 0xa8, 0x7d, (byte) 0xab, 0x50, (byte) 0xa3,
+				(byte) 0xf7, (byte) 0xcc, };
+		ByteArrayInputStream in = new ByteArrayInputStream(badMagic);
+
+		assertThrows(IOException.class,
+				() -> PackReverseIndexFactory.readFromFile(in, 0, () -> null));
 	}
 
-	private long findFirstOffset() {
-		long min = Long.MAX_VALUE;
-		for (MutableEntry me : idx)
-			min = Math.min(min, me.getOffset());
-		return min;
+	@Test
+	public void read_unsupportedVersion2() {
+		byte[] version2 = new byte[] { 'R', 'I', 'D', 'X', // magic
+				0x00, 0x00, 0x00, 0x02, // file version
+				0x00, 0x00, 0x00, 0x01, // oid version
+				// pack checksum
+				'P', 'A', 'C', 'K', 'C', 'H', 'E', 'C', 'K', 'S', 'U', 'M', '3',
+				'4', '5', '6', '7', '8', '9', '0',
+				// checksum
+				0x70, 0x17, 0x10, 0x51, (byte) 0xfe, (byte) 0xab, (byte) 0x9b,
+				0x68, (byte) 0xed, 0x3a, 0x3f, 0x27, 0x1d, (byte) 0xce,
+				(byte) 0xff, 0x38, 0x09, (byte) 0x9b, 0x29, 0x58, };
+		ByteArrayInputStream in = new ByteArrayInputStream(version2);
+
+		assertThrows(IOException.class,
+				() -> PackReverseIndexFactory.readFromFile(in, 0, () -> null));
+	}
+
+	private File getResourceFileFor(String packFilePrefix, PackExt ext) {
+		return JGitTestUtil
+				.getTestResourceFile(packFilePrefix + ext.getExtension());
 	}
 }
diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/file/PackReverseIndexV1Test.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/file/PackReverseIndexV1Test.java
new file mode 100644
index 0000000..38b28b5
--- /dev/null
+++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/file/PackReverseIndexV1Test.java
@@ -0,0 +1,289 @@
+/*
+ * Copyright (C) 2022, Google LLC and others
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Distribution License v. 1.0 which is available at
+ * 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.eclipse.jgit.lib.Constants.OBJ_BLOB;
+import static org.eclipse.jgit.lib.Constants.OBJ_COMMIT;
+import static org.eclipse.jgit.lib.Constants.OBJ_TREE;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertThrows;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+
+import org.eclipse.jgit.errors.CorruptObjectException;
+import org.eclipse.jgit.errors.PackMismatchException;
+import org.eclipse.jgit.junit.JGitTestUtil;
+import org.eclipse.jgit.lib.ObjectId;
+import org.eclipse.jgit.transport.PackedObjectInfo;
+import org.junit.Before;
+import org.junit.Test;
+
+public class PackReverseIndexV1Test {
+	private static final byte[] FAKE_PACK_CHECKSUM = new byte[] { 'P', 'A', 'C',
+			'K', 'C', 'H', 'E', 'C', 'K', 'S', 'U', 'M', '3', '4', '5', '6',
+			'7', '8', '9', '0', };
+
+	private static final byte[] NO_OBJECTS = new byte[] { 'R', 'I', 'D', 'X', // magic
+			0x00, 0x00, 0x00, 0x01, // file version
+			0x00, 0x00, 0x00, 0x01, // oid version
+			// pack checksum to copy into at byte 12
+			0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+			// checksum
+			(byte) 0xd1, 0x1d, 0x17, (byte) 0xd5, (byte) 0xa1, 0x5c,
+			(byte) 0x8f, 0x45, 0x7e, 0x06, (byte) 0x91, (byte) 0xf2, 0x7e, 0x20,
+			0x35, 0x2c, (byte) 0xdc, 0x4c, 0x46, (byte) 0xe4, };
+
+	private static final byte[] SMALL_PACK_CHECKSUM = new byte[] { (byte) 0xbb,
+			0x1d, 0x25, 0x3d, (byte) 0xd3, (byte) 0xf0, 0x08, 0x75, (byte) 0xc8,
+			0x04, (byte) 0xd0, 0x6f, 0x73, (byte) 0xe9, 0x00, (byte) 0x82,
+			(byte) 0xdb, 0x09, (byte) 0xc8, 0x13, };
+
+	private static final byte[] SMALL_CONTENTS = new byte[] { 'R', 'I', 'D',
+			'X', // magic
+			0x00, 0x00, 0x00, 0x01, // file version
+			0x00, 0x00, 0x00, 0x01, // oid version
+			0x00, 0x00, 0x00, 0x04, // offset 12: "68" -> index @ 4
+			0x00, 0x00, 0x00, 0x02, // offset 165: "5c" -> index @ 2
+			0x00, 0x00, 0x00, 0x03, // offset 257: "62" -> index @ 3
+			0x00, 0x00, 0x00, 0x01, // offset 450: "58" -> index @ 1
+			0x00, 0x00, 0x00, 0x05, // offset 556: "c5" -> index @ 5
+			0x00, 0x00, 0x00, 0x00, // offset 614: "2d" -> index @ 0
+			// pack checksum to copy into at byte 36
+			0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+			// checksum
+			(byte) 0xf0, 0x6d, 0x03, (byte) 0xd7, 0x6f, (byte) 0x9f,
+			(byte) 0xc1, 0x36, 0x26, (byte) 0xbc, (byte) 0xcb, 0x75, 0x36,
+			(byte) 0xa1, 0x26, 0x6a, 0x2b, (byte) 0x84, 0x16, (byte) 0x83, };
+
+	private PackReverseIndex emptyReverseIndex;
+
+	/**
+	 * Reverse index for the pack-cbdeda40019ae0e6e789088ea0f51f164f489d14.idx
+	 * with contents `SHA-1 type size size-in-packfile offset-in-packfile` as
+	 * shown by `verify-pack`:
+	 * 2d04ee74dba30078c2dcdb713ddb8be4bc084d76 blob   8 17 614
+	 * 58728c938a9a8b9970cc09236caf94ada4689923 blob   140 106 450
+	 * 5ce00008cf3fb8f194f52742020bd40d78f3f1b3 commit 81 92 165 1 68cb1f232964f3cd698afc1dafe583937203c587
+	 * 62299a7ae290d685196e948a2fcb7d8c07f95c7d tree   198 193 257
+	 * 68cb1f232964f3cd698afc1dafe583937203c587 commit 220 153 12
+	 * c5ab27309491cf641eb11bb4b7a78641f280b482 tree   46 58 556 1 62299a7ae290d685196e948a2fcb7d8c07f95c7d
+	 */
+	private PackReverseIndex smallReverseIndex;
+
+	private final PackedObjectInfo object614 = objectInfo(
+			"2d04ee74dba30078c2dcdb713ddb8be4bc084d76", OBJ_BLOB, 614);
+
+	private final PackedObjectInfo object450 = objectInfo(
+			"58728c938a9a8b9970cc09236caf94ada4689923", OBJ_BLOB, 450);
+
+	private final PackedObjectInfo object165 = objectInfo(
+			"5ce00008cf3fb8f194f52742020bd40d78f3f1b3", OBJ_COMMIT, 165);
+
+	private final PackedObjectInfo object257 = objectInfo(
+			"62299a7ae290d685196e948a2fcb7d8c07f95c7d", OBJ_TREE, 257);
+
+	private final PackedObjectInfo object12 = objectInfo(
+			"68cb1f232964f3cd698afc1dafe583937203c587", OBJ_COMMIT, 12);
+
+	private final PackedObjectInfo object556 = objectInfo(
+			"c5ab27309491cf641eb11bb4b7a78641f280b482", OBJ_TREE, 556);
+
+	// last object's offset + last object's length
+	private final long smallMaxOffset = 631;
+
+	@Before
+	public void setUp() throws Exception {
+		System.arraycopy(SMALL_PACK_CHECKSUM, 0, SMALL_CONTENTS, 36,
+				SMALL_PACK_CHECKSUM.length);
+		ByteArrayInputStream smallIn = new ByteArrayInputStream(SMALL_CONTENTS);
+		smallReverseIndex = PackReverseIndexFactory.readFromFile(smallIn, 6,
+				() -> PackIndex.open(JGitTestUtil.getTestResourceFile(
+						"pack-cbdeda40019ae0e6e789088ea0f51f164f489d14.idx")));
+
+		System.arraycopy(FAKE_PACK_CHECKSUM, 0, NO_OBJECTS, 12,
+				FAKE_PACK_CHECKSUM.length);
+		ByteArrayInputStream emptyIn = new ByteArrayInputStream(NO_OBJECTS);
+		emptyReverseIndex = PackReverseIndexFactory.readFromFile(emptyIn, 0,
+				() -> null);
+	}
+
+	@Test
+	public void read_unsupportedOidSHA256() {
+		byte[] version2 = new byte[] { 'R', 'I', 'D', 'X', // magic
+				0x00, 0x00, 0x00, 0x01, // file version
+				0x00, 0x00, 0x00, 0x02, // oid version
+				// pack checksum to copy into at byte 12
+				0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+				// checksum
+				0x6e, 0x78, 0x75, 0x67, (byte) 0x84, (byte) 0x89, (byte) 0xde,
+				(byte) 0xe3, (byte) 0x86, 0x6a, 0x3b, (byte) 0x98, 0x51,
+				(byte) 0xd8, (byte) 0x8c, (byte) 0xec, 0x50, (byte) 0xe7,
+				(byte) 0xfb, 0x22, };
+		System.arraycopy(FAKE_PACK_CHECKSUM, 0, version2, 12,
+				FAKE_PACK_CHECKSUM.length);
+		ByteArrayInputStream in = new ByteArrayInputStream(version2);
+
+		assertThrows(IOException.class,
+				() -> PackReverseIndexFactory.readFromFile(in, 0, () -> null));
+	}
+
+	@Test
+	public void read_objectCountTooLarge() {
+		ByteArrayInputStream dummyInput = new ByteArrayInputStream(NO_OBJECTS);
+		long biggerThanInt = ((long) Integer.MAX_VALUE) + 1;
+
+		assertThrows(IllegalArgumentException.class,
+				() -> PackReverseIndexFactory.readFromFile(dummyInput,
+						biggerThanInt,
+						() -> null));
+	}
+
+	@Test
+	public void read_incorrectChecksum() {
+		byte[] badChecksum = new byte[] { 'R', 'I', 'D', 'X', // magic
+				0x00, 0x00, 0x00, 0x01, // file version
+				0x00, 0x00, 0x00, 0x01, // oid version
+				// pack checksum to copy into at byte 12
+				0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+				// checksum
+				(byte) 0xf2, 0x1a, 0x1a, (byte) 0xaa, 0x32, 0x2d, (byte) 0xb9,
+				(byte) 0xfd, 0x0f, (byte) 0xa5, 0x4c, (byte) 0xea, (byte) 0xcf,
+				(byte) 0xbb, (byte) 0x99, (byte) 0xde, (byte) 0xd3, 0x4e,
+				(byte) 0xb1, (byte) 0xee, // would be 0x74 if correct
+		};
+		System.arraycopy(FAKE_PACK_CHECKSUM, 0, badChecksum, 12,
+				FAKE_PACK_CHECKSUM.length);
+		ByteArrayInputStream in = new ByteArrayInputStream(badChecksum);
+		assertThrows(CorruptObjectException.class,
+				() -> PackReverseIndexFactory.readFromFile(in, 0, () -> null));
+	}
+
+	@Test
+	public void findObject_noObjects() {
+		assertNull(emptyReverseIndex.findObject(0));
+	}
+
+	@Test
+	public void findObject_multipleObjects() {
+		assertEquals(object614, smallReverseIndex.findObject(614));
+		assertEquals(object450, smallReverseIndex.findObject(450));
+		assertEquals(object165, smallReverseIndex.findObject(165));
+		assertEquals(object257, smallReverseIndex.findObject(257));
+		assertEquals(object12, smallReverseIndex.findObject(12));
+		assertEquals(object556, smallReverseIndex.findObject(556));
+	}
+
+	@Test
+	public void findObject_badOffset() {
+		assertNull(smallReverseIndex.findObject(0));
+	}
+
+	@Test
+	public void findNextOffset_noObjects() {
+		assertThrows(IOException.class,
+				() -> emptyReverseIndex.findNextOffset(0, Long.MAX_VALUE));
+	}
+
+	@Test
+	public void findNextOffset_multipleObjects() throws CorruptObjectException {
+		assertEquals(smallMaxOffset,
+				smallReverseIndex.findNextOffset(614, smallMaxOffset));
+		assertEquals(614,
+				smallReverseIndex.findNextOffset(556, smallMaxOffset));
+		assertEquals(556,
+				smallReverseIndex.findNextOffset(450, smallMaxOffset));
+		assertEquals(450,
+				smallReverseIndex.findNextOffset(257, smallMaxOffset));
+		assertEquals(257,
+				smallReverseIndex.findNextOffset(165, smallMaxOffset));
+		assertEquals(165, smallReverseIndex.findNextOffset(12, smallMaxOffset));
+	}
+
+	@Test
+	public void findNextOffset_badOffset() {
+		assertThrows(IOException.class,
+				() -> smallReverseIndex.findNextOffset(0, Long.MAX_VALUE));
+	}
+
+	@Test
+	public void findPosition_noObjects() {
+		assertEquals(-1, emptyReverseIndex.findPosition(0));
+	}
+
+	@Test
+	public void findPosition_multipleObjects() {
+		assertEquals(0, smallReverseIndex.findPosition(12));
+		assertEquals(1, smallReverseIndex.findPosition(165));
+		assertEquals(2, smallReverseIndex.findPosition(257));
+		assertEquals(3, smallReverseIndex.findPosition(450));
+		assertEquals(4, smallReverseIndex.findPosition(556));
+		assertEquals(5, smallReverseIndex.findPosition(614));
+	}
+
+	@Test
+	public void findPosition_badOffset() {
+		assertEquals(-1, smallReverseIndex.findPosition(10));
+	}
+
+	@Test
+	public void findObjectByPosition_noObjects() {
+		assertThrows(AssertionError.class,
+				() -> emptyReverseIndex.findObjectByPosition(0));
+	}
+
+	@Test
+	public void findObjectByPosition_multipleObjects() {
+		assertEquals(object12, smallReverseIndex.findObjectByPosition(0));
+		assertEquals(object165, smallReverseIndex.findObjectByPosition(1));
+		assertEquals(object257, smallReverseIndex.findObjectByPosition(2));
+		assertEquals(object450, smallReverseIndex.findObjectByPosition(3));
+		assertEquals(object556, smallReverseIndex.findObjectByPosition(4));
+		assertEquals(object614, smallReverseIndex.findObjectByPosition(5));
+	}
+
+	@Test
+	public void findObjectByPosition_badOffset() {
+		assertThrows(AssertionError.class,
+				() -> smallReverseIndex.findObjectByPosition(10));
+	}
+
+	@Test
+	public void verifyChecksum_match() throws IOException {
+		smallReverseIndex.verifyPackChecksum("smallPackFilePath");
+	}
+
+	@Test
+	public void verifyChecksum_mismatch() throws IOException {
+		ByteArrayInputStream in = new ByteArrayInputStream(NO_OBJECTS);
+		PackIndex mockForwardIndex = mock(PackIndex.class);
+		when(mockForwardIndex.getChecksum()).thenReturn(
+				new byte[] { 'D', 'I', 'F', 'F', 'P', 'A', 'C', 'K', 'C', 'H',
+						'E', 'C', 'K', 'S', 'U', 'M', '7', '8', '9', '0', });
+		PackReverseIndex reverseIndex = PackReverseIndexFactory.readFromFile(in,
+				0,
+				() -> mockForwardIndex);
+
+		assertThrows(PackMismatchException.class,
+				() -> reverseIndex.verifyPackChecksum("packFilePath"));
+	}
+
+	private static PackedObjectInfo objectInfo(String objectId, int type,
+			long offset) {
+		PackedObjectInfo objectInfo = new PackedObjectInfo(
+				ObjectId.fromString(objectId));
+		objectInfo.setType(type);
+		objectInfo.setOffset(offset);
+		return objectInfo;
+	}
+}
diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/file/PackReverseIndexV1WriteReadTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/file/PackReverseIndexV1WriteReadTest.java
new file mode 100644
index 0000000..372a4c7
--- /dev/null
+++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/file/PackReverseIndexV1WriteReadTest.java
@@ -0,0 +1,119 @@
+/*
+ * Copyright (C) 2022, Google LLC and others
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Distribution License v. 1.0 which is available at
+ * 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.eclipse.jgit.lib.Constants.OBJECT_ID_STRING_LENGTH;
+import static org.eclipse.jgit.lib.Constants.OBJ_BLOB;
+import static org.eclipse.jgit.lib.Constants.OBJ_COMMIT;
+import static org.eclipse.jgit.lib.Constants.OBJ_TREE;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertThrows;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
+
+import org.eclipse.jgit.lib.ObjectId;
+import org.eclipse.jgit.transport.PackedObjectInfo;
+import org.junit.Test;
+
+public class PackReverseIndexV1WriteReadTest {
+
+	private static byte[] PACK_CHECKSUM = new byte[] { 'P', 'A', 'C', 'K', 'C',
+			'H', 'E', 'C', 'K', 'S', 'U', 'M', '3', '4', '5', '6', '7', '8',
+			'9', '0', };
+
+	@Test
+	public void writeThenRead_noObjects() throws IOException {
+		ByteArrayOutputStream out = new ByteArrayOutputStream();
+		PackReverseIndexWriter writer = PackReverseIndexWriter.createWriter(out,
+				1);
+		List<PackedObjectInfo> objectsSortedByName = new ArrayList<>();
+
+		// write
+		writer.write(objectsSortedByName, PACK_CHECKSUM);
+
+		ByteArrayInputStream in = new ByteArrayInputStream(out.toByteArray());
+
+		// read
+		PackReverseIndex noObjectsReverseIndex = PackReverseIndexFactory
+				.readFromFile(in, 0, () -> null);
+
+		// use
+		assertThrows(AssertionError.class,
+				() -> noObjectsReverseIndex.findObjectByPosition(0));
+	}
+
+	@Test
+	public void writeThenRead_oneObject() throws IOException {
+		ByteArrayOutputStream out = new ByteArrayOutputStream();
+		PackReverseIndexWriter writer = PackReverseIndexWriter.createWriter(out,
+				1);
+		PackedObjectInfo a = objectInfo("a", OBJ_COMMIT, 0);
+		List<PackedObjectInfo> objectsSortedByName = List.of(a);
+
+		// write
+		writer.write(objectsSortedByName, PACK_CHECKSUM);
+
+		ByteArrayInputStream in = new ByteArrayInputStream(out.toByteArray());
+		PackIndex mockForwardIndex = mock(PackIndex.class);
+		when(mockForwardIndex.getObjectId(0)).thenReturn(a);
+
+		// read
+		PackReverseIndex oneObjectReverseIndex = PackReverseIndexFactory
+				.readFromFile(in, 1, () -> mockForwardIndex);
+
+		// use
+		assertEquals(a, oneObjectReverseIndex.findObjectByPosition(0));
+	}
+
+	@Test
+	public void writeThenRead_multipleObjectsLargeOffsets() throws IOException {
+		ByteArrayOutputStream out = new ByteArrayOutputStream();
+		PackReverseIndexWriter writer = PackReverseIndexWriter.createWriter(out,
+				1);
+		PackedObjectInfo a = objectInfo("a", OBJ_BLOB, 200000000);
+		PackedObjectInfo b = objectInfo("b", OBJ_COMMIT, 0);
+		PackedObjectInfo c = objectInfo("c", OBJ_COMMIT, 52000000000L);
+		PackedObjectInfo d = objectInfo("d", OBJ_TREE, 7);
+		PackedObjectInfo e = objectInfo("e", OBJ_COMMIT, 38000000000L);
+		List<PackedObjectInfo> objectsSortedByName = List.of(a, b, c, d, e);
+
+		writer.write(objectsSortedByName, PACK_CHECKSUM);
+
+		// write
+		writer.write(objectsSortedByName, PACK_CHECKSUM);
+
+		ByteArrayInputStream in = new ByteArrayInputStream(out.toByteArray());
+		PackIndex mockForwardIndex = mock(PackIndex.class);
+		when(mockForwardIndex.getObjectId(4)).thenReturn(e);
+
+		// read
+		PackReverseIndex multipleObjectsReverseIndex = PackReverseIndexFactory
+				.readFromFile(in, 5, () -> mockForwardIndex);
+
+		// use with minimal mocked forward index use
+		assertEquals(e, multipleObjectsReverseIndex.findObjectByPosition(3));
+	}
+
+	private static PackedObjectInfo objectInfo(String objectId, int type,
+			long offset) {
+		assert (objectId.length() == 1);
+		PackedObjectInfo objectInfo = new PackedObjectInfo(
+				ObjectId.fromString(objectId.repeat(OBJECT_ID_STRING_LENGTH)));
+		objectInfo.setType(type);
+		objectInfo.setOffset(offset);
+		return objectInfo;
+	}
+}
diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/file/PackTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/file/PackTest.java
index a359654..e150945 100644
--- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/file/PackTest.java
+++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/file/PackTest.java
@@ -261,7 +261,7 @@
 				new PackIndexWriterV1(f).write(list, footer);
 			}
 
-			Pack pack = new Pack(packName, null);
+			Pack pack = new Pack(repo.getConfig(), packName, null);
 			try {
 				pack.get(wc, b);
 				fail("expected LargeObjectException.ExceedsByteArrayLimit");
diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/file/RefDirectoryAfterOpenConfigTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/file/RefDirectoryAfterOpenConfigTest.java
index 42304e2..3ea4a16 100644
--- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/file/RefDirectoryAfterOpenConfigTest.java
+++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/file/RefDirectoryAfterOpenConfigTest.java
@@ -17,7 +17,6 @@
 import org.eclipse.jgit.util.SystemReader;
 
 public class RefDirectoryAfterOpenConfigTest extends RefDirectoryTest {
-	/** {@inheritDoc} */
 	@Override
 	public void refDirectorySetup() throws Exception {
 		StoredConfig userConfig = SystemReader.getInstance().getUserConfig();
diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/file/SnapshottingRefDirectoryTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/file/SnapshottingRefDirectoryTest.java
index c3dafe4..90a2aa6 100644
--- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/file/SnapshottingRefDirectoryTest.java
+++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/file/SnapshottingRefDirectoryTest.java
@@ -23,7 +23,6 @@
 public class SnapshottingRefDirectoryTest extends RefDirectoryTest {
 	private RefDirectory originalRefDirectory;
 
-	/** {@inheritDoc} */
 	@Before
 	@Override
 	public void setUp() throws Exception {
diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/lib/CommitTemplateConfigTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/lib/CommitTemplateConfigTest.java
index 42bafb6..3ccd0ef 100644
--- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/lib/CommitTemplateConfigTest.java
+++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/lib/CommitTemplateConfigTest.java
@@ -17,7 +17,9 @@
 
 import org.eclipse.jgit.errors.ConfigInvalidException;
 import org.eclipse.jgit.junit.JGitTestUtil;
+import org.eclipse.jgit.junit.LocalDiskRepositoryTestCase;
 import org.eclipse.jgit.storage.file.FileRepositoryBuilder;
+import org.eclipse.jgit.util.FS;
 import org.junit.Rule;
 import org.junit.Test;
 import org.junit.rules.TemporaryFolder;
@@ -27,7 +29,7 @@
  * test using bazel which doesn't allow tests to create files in the home
  * directory
  */
-public class CommitTemplateConfigTest {
+public class CommitTemplateConfigTest extends LocalDiskRepositoryTestCase {
 
 	@Rule
 	public TemporaryFolder tmp = new TemporaryFolder();
@@ -42,9 +44,11 @@
 		String templateContent = "content of the template";
 		JGitTestUtil.write(tempFile, templateContent);
 		// proper evaluation of the ~/ directory
-		String homeDir = System.getProperty("user.home");
+		File homeDir = FS.DETECTED.userHome();
 		File tempFileInHomeDirectory = File.createTempFile("fileInHomeFolder",
-				".tmp", new File(homeDir));
+				".tmp", homeDir);
+		// The home directory should be a mocked temporary directory, but
+		// still...
 		tempFileInHomeDirectory.deleteOnExit();
 		JGitTestUtil.write(tempFileInHomeDirectory, templateContent);
 		String expectedTemplatePath = "~/" + tempFileInHomeDirectory.getName();
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 8f9d105..36cf77b 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
@@ -1482,7 +1482,9 @@
 
 		File workTree = tmp.newFolder("dummy-worktree");
 		File tempFile = tmp.newFile("testCommitTemplate-");
-		Repository repo = FileRepositoryBuilder.create(workTree);
+		Repository repo = FileRepositoryBuilder
+				.create(new File(workTree, ".git"));
+		repo.create();
 		String templateContent = "content of the template";
 		JGitTestUtil.write(tempFile, templateContent);
 		String expectedTemplatePath = tempFile.getPath();
@@ -1532,7 +1534,9 @@
 			throws ConfigInvalidException, IOException {
 		Config config = new Config(null);
 		File workTree = tmp.newFolder("dummy-worktree");
-		Repository repo = FileRepositoryBuilder.create(workTree);
+		Repository repo = FileRepositoryBuilder
+				.create(new File(workTree, ".git"));
+		repo.create();
 		File tempFile = tmp.newFile("testCommitTemplate-");
 		String templateContent = "content of the template";
 		JGitTestUtil.write(tempFile, templateContent);
@@ -1554,7 +1558,9 @@
 		Config config = new Config(null);
 		File workTree = tmp.newFolder("dummy-worktree");
 		File tempFile = tmp.newFile("testCommitTemplate-");
-		Repository repo = FileRepositoryBuilder.create(workTree);
+		Repository repo = FileRepositoryBuilder
+				.create(new File(workTree, ".git"));
+		repo.create();
 		String templateContent = "content of the template";
 		JGitTestUtil.write(tempFile, templateContent);
 		config = parse("[i18n]\n\tcommitEncoding = invalidEcoding\n"
@@ -1569,7 +1575,9 @@
 		Config config = new Config(null);
 		File workTree = tmp.newFolder("dummy-worktree");
 		File tempFile = tmp.newFile("testCommitTemplate-");
-		Repository repo = FileRepositoryBuilder.create(workTree);
+		Repository repo = FileRepositoryBuilder
+				.create(new File(workTree, ".git"));
+		repo.create();
 		String templateContent = "content of the template";
 		JGitTestUtil.write(tempFile, templateContent);
 		// commit message encoding
diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/merge/MergeAlgorithmTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/merge/MergeAlgorithmTest.java
index 5f4331b..680a2d5 100644
--- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/merge/MergeAlgorithmTest.java
+++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/merge/MergeAlgorithmTest.java
@@ -47,7 +47,10 @@
 	@Test
 	public void testTwoConflictingModifications() throws IOException {
 		assertEquals(t("a<b=Z>Zdefghij"),
-				merge("abcdefghij", "abZdefghij", "aZZdefghij"));
+				merge("abcdefghij", "abZdefghij", "aZZdefghij", false));
+
+		assertEquals(t("a<b|b=Z>Zdefghij"),
+				merge("abcdefghij", "abZdefghij", "aZZdefghij", true));
 	}
 
 	/**
@@ -60,7 +63,10 @@
 	@Test
 	public void testOneAgainstTwoConflictingModifications() throws IOException {
 		assertEquals(t("aZ<Z=c>Zefghij"),
-				merge("abcdefghij", "aZZZefghij", "aZcZefghij"));
+				merge("abcdefghij", "aZZZefghij", "aZcZefghij", false));
+
+		assertEquals(t("aZ<Z|c=c>Zefghij"),
+				merge("abcdefghij", "aZZZefghij", "aZcZefghij", true));
 	}
 
 	/**
@@ -72,7 +78,10 @@
 	@Test
 	public void testNoAgainstOneModification() throws IOException {
 		assertEquals(t("aZcZefghij"),
-				merge("abcdefghij", "abcdefghij", "aZcZefghij"));
+				merge("abcdefghij", "abcdefghij", "aZcZefghij", false));
+
+		assertEquals(t("aZcZefghij"),
+				merge("abcdefghij", "abcdefghij", "aZcZefghij", true));
 	}
 
 	/**
@@ -84,7 +93,10 @@
 	@Test
 	public void testTwoNonConflictingModifications() throws IOException {
 		assertEquals(t("YbZdefghij"),
-				merge("abcdefghij", "abZdefghij", "Ybcdefghij"));
+				merge("abcdefghij", "abZdefghij", "Ybcdefghij", false));
+
+		assertEquals(t("YbZdefghij"),
+				merge("abcdefghij", "abZdefghij", "Ybcdefghij", true));
 	}
 
 	/**
@@ -96,7 +108,10 @@
 	@Test
 	public void testTwoComplicatedModifications() throws IOException {
 		assertEquals(t("a<ZZZZfZhZj=bYdYYYYiY>"),
-				merge("abcdefghij", "aZZZZfZhZj", "abYdYYYYiY"));
+				merge("abcdefghij", "aZZZZfZhZj", "abYdYYYYiY", false));
+
+		assertEquals(t("a<ZZZZfZhZj|bcdefghij=bYdYYYYiY>"),
+				merge("abcdefghij", "aZZZZfZhZj", "abYdYYYYiY", true));
 	}
 
 	/**
@@ -109,7 +124,9 @@
 	@Test
 	public void testTwoModificationsWithSharedDelete() throws IOException {
 		assertEquals(t("Cb}n}"),
-				merge("ab}n}n}", "ab}n}", "Cb}n}"));
+				merge("ab}n}n}", "ab}n}", "Cb}n}", false));
+
+		assertEquals(t("Cb}n}"), merge("ab}n}n}", "ab}n}", "Cb}n}", true));
 	}
 
 	/**
@@ -122,7 +139,11 @@
 	@Test
 	public void testModificationsWithMiddleInsert() throws IOException {
 		assertEquals(t("aBcd123123uvwxPq"),
-				merge("abcd123uvwxpq", "aBcd123123uvwxPq", "abcd123123uvwxpq"));
+				merge("abcd123uvwxpq", "aBcd123123uvwxPq", "abcd123123uvwxpq",
+						false));
+
+		assertEquals(t("aBcd123123uvwxPq"), merge("abcd123uvwxpq",
+				"aBcd123123uvwxPq", "abcd123123uvwxpq", true));
 	}
 
 	/**
@@ -135,7 +156,10 @@
 	@Test
 	public void testModificationsWithMiddleDelete() throws IOException {
 		assertEquals(t("Abz}z123Q"),
-				merge("abz}z}z123q", "Abz}z123Q", "abz}z123q"));
+				merge("abz}z}z123q", "Abz}z123Q", "abz}z123q", false));
+
+		assertEquals(t("Abz}z123Q"),
+				merge("abz}z}z123q", "Abz}z123Q", "abz}z123q", true));
 	}
 
 	/**
@@ -146,7 +170,10 @@
 	@Test
 	public void testConflictAtStart() throws IOException {
 		assertEquals(t("<Z=Y>bcdefghij"),
-				merge("abcdefghij", "Zbcdefghij", "Ybcdefghij"));
+				merge("abcdefghij", "Zbcdefghij", "Ybcdefghij", false));
+
+		assertEquals(t("<Z|a=Y>bcdefghij"),
+				merge("abcdefghij", "Zbcdefghij", "Ybcdefghij", true));
 	}
 
 	/**
@@ -157,7 +184,10 @@
 	@Test
 	public void testConflictAtEnd() throws IOException {
 		assertEquals(t("abcdefghi<Z=Y>"),
-				merge("abcdefghij", "abcdefghiZ", "abcdefghiY"));
+				merge("abcdefghij", "abcdefghiZ", "abcdefghiY", false));
+
+		assertEquals(t("abcdefghi<Z|j=Y>"),
+				merge("abcdefghij", "abcdefghiZ", "abcdefghiY", true));
 	}
 
 	/**
@@ -169,7 +199,10 @@
 	@Test
 	public void testSameModification() throws IOException {
 		assertEquals(t("abZdefghij"),
-				merge("abcdefghij", "abZdefghij", "abZdefghij"));
+				merge("abcdefghij", "abZdefghij", "abZdefghij", false));
+
+		assertEquals(t("abZdefghij"),
+				merge("abcdefghij", "abZdefghij", "abZdefghij", true));
 	}
 
 	/**
@@ -181,27 +214,36 @@
 	@Test
 	public void testDeleteVsModify() throws IOException {
 		assertEquals(t("ab<=Z>defghij"),
-				merge("abcdefghij", "abdefghij", "abZdefghij"));
+				merge("abcdefghij", "abdefghij", "abZdefghij", false));
+
+		assertEquals(t("ab<|c=Z>defghij"),
+				merge("abcdefghij", "abdefghij", "abZdefghij", true));
 	}
 
 	@Test
 	public void testInsertVsModify() throws IOException {
-		assertEquals(t("a<bZ=XY>"), merge("ab", "abZ", "aXY"));
+		assertEquals(t("a<bZ=XY>"), merge("ab", "abZ", "aXY", false));
+		assertEquals(t("a<bZ|b=XY>"), merge("ab", "abZ", "aXY", true));
 	}
 
 	@Test
 	public void testAdjacentModifications() throws IOException {
-		assertEquals(t("a<Zc=bY>d"), merge("abcd", "aZcd", "abYd"));
+		assertEquals(t("a<Zc=bY>d"), merge("abcd", "aZcd", "abYd", false));
+		assertEquals(t("a<Zc|bc=bY>d"), merge("abcd", "aZcd", "abYd", true));
 	}
 
 	@Test
 	public void testSeparateModifications() throws IOException {
-		assertEquals(t("aZcYe"), merge("abcde", "aZcde", "abcYe"));
+		assertEquals(t("aZcYe"), merge("abcde", "aZcde", "abcYe", false));
+		assertEquals(t("aZcYe"), merge("abcde", "aZcde", "abcYe", true));
 	}
 
 	@Test
 	public void testBlankLines() throws IOException {
-		assertEquals(t("aZc\nYe"), merge("abc\nde", "aZc\nde", "abc\nYe"));
+		assertEquals(t("aZc\nYe"),
+				merge("abc\nde", "aZc\nde", "abc\nYe", false));
+		assertEquals(t("aZc\nYe"),
+				merge("abc\nde", "aZc\nde", "abc\nYe", true));
 	}
 
 	/**
@@ -214,11 +256,22 @@
 	 */
 	@Test
 	public void testTwoSimilarModsAndOneInsert() throws IOException {
-		assertEquals(t("aBcDde"), merge("abcde", "aBcde", "aBcDde"));
-		assertEquals(t("IAAAJCAB"), merge("iACAB", "IACAB", "IAAAJCAB"));
-		assertEquals(t("HIAAAJCAB"), merge("HiACAB", "HIACAB", "HIAAAJCAB"));
+		assertEquals(t("aBcDde"), merge("abcde", "aBcde", "aBcDde", false));
+		assertEquals(t("aBcDde"), merge("abcde", "aBcde", "aBcDde", true));
+
+		assertEquals(t("IAAAJCAB"), merge("iACAB", "IACAB", "IAAAJCAB", false));
+		assertEquals(t("IAAAJCAB"), merge("iACAB", "IACAB", "IAAAJCAB", true));
+
+		assertEquals(t("HIAAAJCAB"),
+				merge("HiACAB", "HIACAB", "HIAAAJCAB", false));
+		assertEquals(t("HIAAAJCAB"),
+				merge("HiACAB", "HIACAB", "HIAAAJCAB", true));
+
 		assertEquals(t("AGADEFHIAAAJCAB"),
-				merge("AGADEFHiACAB", "AGADEFHIACAB", "AGADEFHIAAAJCAB"));
+				merge("AGADEFHiACAB", "AGADEFHIACAB", "AGADEFHIAAAJCAB",
+						false));
+		assertEquals(t("AGADEFHIAAAJCAB"),
+				merge("AGADEFHiACAB", "AGADEFHIACAB", "AGADEFHIAAAJCAB", true));
 	}
 
 	/**
@@ -232,18 +285,28 @@
 	@Test
 	public void testTwoSimilarModsAndOneInsertAtEnd() throws IOException {
 		Assume.assumeTrue(newlineAtEnd);
-		assertEquals(t("IAAJ"), merge("iA", "IA", "IAAJ"));
-		assertEquals(t("IAJ"), merge("iA", "IA", "IAJ"));
-		assertEquals(t("IAAAJ"), merge("iA", "IA", "IAAAJ"));
+		assertEquals(t("IAAJ"), merge("iA", "IA", "IAAJ", false));
+		assertEquals(t("IAAJ"), merge("iA", "IA", "IAAJ", true));
+
+		assertEquals(t("IAJ"), merge("iA", "IA", "IAJ", false));
+		assertEquals(t("IAJ"), merge("iA", "IA", "IAJ", true));
+
+		assertEquals(t("IAAAJ"), merge("iA", "IA", "IAAAJ", false));
+		assertEquals(t("IAAAJ"), merge("iA", "IA", "IAAAJ", true));
 	}
 
 	@Test
 	public void testTwoSimilarModsAndOneInsertAtEndNoNewlineAtEnd()
 			throws IOException {
 		Assume.assumeFalse(newlineAtEnd);
-		assertEquals(t("I<A=AAJ>"), merge("iA", "IA", "IAAJ"));
-		assertEquals(t("I<A=AJ>"), merge("iA", "IA", "IAJ"));
-		assertEquals(t("I<A=AAAJ>"), merge("iA", "IA", "IAAAJ"));
+		assertEquals(t("I<A=AAJ>"), merge("iA", "IA", "IAAJ", false));
+		assertEquals(t("I<A|A=AAJ>"), merge("iA", "IA", "IAAJ", true));
+
+		assertEquals(t("I<A=AJ>"), merge("iA", "IA", "IAJ", false));
+		assertEquals(t("I<A|A=AJ>"), merge("iA", "IA", "IAJ", true));
+
+		assertEquals(t("I<A=AAAJ>"), merge("iA", "IA", "IAAAJ", false));
+		assertEquals(t("I<A|A=AAAJ>"), merge("iA", "IA", "IAAAJ", true));
 	}
 
 	/**
@@ -254,22 +317,34 @@
 	@Test
 	public void testEmptyTexts() throws IOException {
 		// test modification against deletion
-		assertEquals(t("<AB=>"), merge("A", "AB", ""));
-		assertEquals(t("<=AB>"), merge("A", "", "AB"));
+		assertEquals(t("<AB=>"), merge("A", "AB", "", false));
+		assertEquals(t("<AB|A=>"), merge("A", "AB", "", true));
+
+		assertEquals(t("<=AB>"), merge("A", "", "AB", false));
+		assertEquals(t("<|A=AB>"), merge("A", "", "AB", true));
 
 		// test unmodified against deletion
-		assertEquals(t(""), merge("AB", "AB", ""));
-		assertEquals(t(""), merge("AB", "", "AB"));
+		assertEquals(t(""), merge("AB", "AB", "", false));
+		assertEquals(t(""), merge("AB", "AB", "", true));
+
+		assertEquals(t(""), merge("AB", "", "AB", false));
+		assertEquals(t(""), merge("AB", "", "AB", true));
 
 		// test deletion against deletion
-		assertEquals(t(""), merge("AB", "", ""));
+		assertEquals(t(""), merge("AB", "", "", false));
+		assertEquals(t(""), merge("AB", "", "", true));
 	}
 
-	private String merge(String commonBase, String ours, String theirs) throws IOException {
+	private String merge(String commonBase, String ours, String theirs,
+			boolean diff3) throws IOException {
 		MergeResult r = new MergeAlgorithm().merge(RawTextComparator.DEFAULT,
 				T(commonBase), T(ours), T(theirs));
 		ByteArrayOutputStream bo=new ByteArrayOutputStream(50);
-		fmt.formatMerge(bo, r, "B", "O", "T", UTF_8);
+		if (diff3) {
+			fmt.formatMergeDiff3(bo, r, "B", "O", "T", UTF_8);
+		} else {
+			fmt.formatMerge(bo, r, "B", "O", "T", UTF_8);
+		}
 		return new String(bo.toByteArray(), UTF_8);
 	}
 
@@ -284,6 +359,9 @@
 			case '=':
 				r.append("=======\n");
 				break;
+			case '|':
+				r.append("||||||| B\n");
+				break;
 			case '>':
 				r.append(">>>>>>> T\n");
 				break;
diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/revwalk/FooterLineTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/revwalk/FooterLineTest.java
index 113f3be..01f6a3a 100644
--- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/revwalk/FooterLineTest.java
+++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/revwalk/FooterLineTest.java
@@ -16,76 +16,74 @@
 import static org.junit.Assert.assertNull;
 import static org.junit.Assert.assertTrue;
 
-import java.io.IOException;
 import java.util.List;
 
 import org.eclipse.jgit.junit.RepositoryTestCase;
-import org.eclipse.jgit.lib.Constants;
 import org.eclipse.jgit.lib.ObjectId;
 import org.junit.Test;
 
 public class FooterLineTest extends RepositoryTestCase {
 	@Test
-	public void testNoFooters_EmptyBody() throws IOException {
-		final RevCommit commit = parse("");
-		final List<FooterLine> footers = commit.getFooterLines();
+	public void testNoFooters_EmptyBody() {
+		String msg = buildMessage("");
+		List<FooterLine> footers = FooterLine.fromMessage(msg);
 		assertNotNull(footers);
 		assertEquals(0, footers.size());
 	}
 
 	@Test
-	public void testNoFooters_NewlineOnlyBody1() throws IOException {
-		final RevCommit commit = parse("\n");
-		final List<FooterLine> footers = commit.getFooterLines();
+	public void testNoFooters_NewlineOnlyBody1() {
+		String msg = buildMessage("\n");
+		List<FooterLine> footers = FooterLine.fromMessage(msg);
 		assertNotNull(footers);
 		assertEquals(0, footers.size());
 	}
 
 	@Test
-	public void testNoFooters_NewlineOnlyBody5() throws IOException {
-		final RevCommit commit = parse("\n\n\n\n\n");
-		final List<FooterLine> footers = commit.getFooterLines();
+	public void testNoFooters_NewlineOnlyBody5() {
+		String msg = buildMessage("\n\n\n\n\n");
+		List<FooterLine> footers = FooterLine.fromMessage(msg);
 		assertNotNull(footers);
 		assertEquals(0, footers.size());
 	}
 
 	@Test
-	public void testNoFooters_OneLineBodyNoLF() throws IOException {
-		final RevCommit commit = parse("this is a commit");
-		final List<FooterLine> footers = commit.getFooterLines();
+	public void testNoFooters_OneLineBodyNoLF() {
+		String msg = buildMessage("this is a commit");
+		List<FooterLine> footers = FooterLine.fromMessage(msg);
 		assertNotNull(footers);
 		assertEquals(0, footers.size());
 	}
 
 	@Test
-	public void testNoFooters_OneLineBodyWithLF() throws IOException {
-		final RevCommit commit = parse("this is a commit\n");
-		final List<FooterLine> footers = commit.getFooterLines();
+	public void testNoFooters_OneLineBodyWithLF() {
+		String msg = buildMessage("this is a commit\n");
+		List<FooterLine> footers = FooterLine.fromMessage(msg);
 		assertNotNull(footers);
 		assertEquals(0, footers.size());
 	}
 
 	@Test
-	public void testNoFooters_ShortBodyNoLF() throws IOException {
-		final RevCommit commit = parse("subject\n\nbody of commit");
-		final List<FooterLine> footers = commit.getFooterLines();
+	public void testNoFooters_ShortBodyNoLF() {
+		String msg = buildMessage("subject\n\nbody of commit");
+		List<FooterLine> footers = FooterLine.fromMessage(msg);
 		assertNotNull(footers);
 		assertEquals(0, footers.size());
 	}
 
 	@Test
-	public void testNoFooters_ShortBodyWithLF() throws IOException {
-		final RevCommit commit = parse("subject\n\nbody of commit\n");
-		final List<FooterLine> footers = commit.getFooterLines();
+	public void testNoFooters_ShortBodyWithLF() {
+		String msg = buildMessage("subject\n\nbody of commit\n");
+		List<FooterLine> footers = FooterLine.fromMessage(msg);
 		assertNotNull(footers);
 		assertEquals(0, footers.size());
 	}
 
 	@Test
-	public void testSignedOffBy_OneUserNoLF() throws IOException {
-		final RevCommit commit = parse("subject\n\nbody of commit\n" + "\n"
-				+ "Signed-off-by: A. U. Thor <a@example.com>");
-		final List<FooterLine> footers = commit.getFooterLines();
+	public void testSignedOffBy_OneUserNoLF() {
+		String msg = buildMessage("subject\n\nbody of commit\n" + "\n"
+			+ "Signed-off-by: A. U. Thor <a@example.com>");
+		List<FooterLine> footers = FooterLine.fromMessage(msg);
 		FooterLine f;
 
 		assertNotNull(footers);
@@ -98,10 +96,10 @@
 	}
 
 	@Test
-	public void testSignedOffBy_OneUserWithLF() throws IOException {
-		final RevCommit commit = parse("subject\n\nbody of commit\n" + "\n"
-				+ "Signed-off-by: A. U. Thor <a@example.com>\n");
-		final List<FooterLine> footers = commit.getFooterLines();
+	public void testSignedOffBy_OneUserWithLF() {
+		String msg = buildMessage("subject\n\nbody of commit\n" + "\n"
+			+ "Signed-off-by: A. U. Thor <a@example.com>\n");
+		List<FooterLine> footers = FooterLine.fromMessage(msg);
 		FooterLine f;
 
 		assertNotNull(footers);
@@ -114,14 +112,13 @@
 	}
 
 	@Test
-	public void testSignedOffBy_IgnoreWhitespace() throws IOException {
+	public void testSignedOffBy_IgnoreWhitespace() {
 		// We only ignore leading whitespace on the value, trailing
 		// is assumed part of the value.
 		//
-		final RevCommit commit = parse("subject\n\nbody of commit\n" + "\n"
-				+ "Signed-off-by:   A. U. Thor <a@example.com>  \n");
-		final List<FooterLine> footers = commit.getFooterLines();
-		FooterLine f;
+		String msg = buildMessage("subject\n\nbody of commit\n" + "\n"
+			+ "Signed-off-by:   A. U. Thor <a@example.com>  \n");
+		List<FooterLine> footers = FooterLine.fromMessage(msg);		FooterLine f;
 
 		assertNotNull(footers);
 		assertEquals(1, footers.size());
@@ -133,10 +130,10 @@
 	}
 
 	@Test
-	public void testEmptyValueNoLF() throws IOException {
-		final RevCommit commit = parse("subject\n\nbody of commit\n" + "\n"
-				+ "Signed-off-by:");
-		final List<FooterLine> footers = commit.getFooterLines();
+	public void testEmptyValueNoLF() {
+		String msg = buildMessage("subject\n\nbody of commit\n" + "\n"
+			+ "Signed-off-by:");
+		List<FooterLine> footers = FooterLine.fromMessage(msg);
 		FooterLine f;
 
 		assertNotNull(footers);
@@ -149,10 +146,10 @@
 	}
 
 	@Test
-	public void testEmptyValueWithLF() throws IOException {
-		final RevCommit commit = parse("subject\n\nbody of commit\n" + "\n"
-				+ "Signed-off-by:\n");
-		final List<FooterLine> footers = commit.getFooterLines();
+	public void testEmptyValueWithLF() {
+		String msg = buildMessage("subject\n\nbody of commit\n" + "\n"
+			+ "Signed-off-by:\n");
+		List<FooterLine> footers = FooterLine.fromMessage(msg);
 		FooterLine f;
 
 		assertNotNull(footers);
@@ -165,10 +162,10 @@
 	}
 
 	@Test
-	public void testShortKey() throws IOException {
-		final RevCommit commit = parse("subject\n\nbody of commit\n" + "\n"
-				+ "K:V\n");
-		final List<FooterLine> footers = commit.getFooterLines();
+	public void testShortKey() {
+		String msg = buildMessage("subject\n\nbody of commit\n" + "\n"
+			+ "K:V\n");
+		List<FooterLine> footers = FooterLine.fromMessage(msg);
 		FooterLine f;
 
 		assertNotNull(footers);
@@ -181,10 +178,10 @@
 	}
 
 	@Test
-	public void testNonDelimtedEmail() throws IOException {
-		final RevCommit commit = parse("subject\n\nbody of commit\n" + "\n"
-				+ "Acked-by: re@example.com\n");
-		final List<FooterLine> footers = commit.getFooterLines();
+	public void testNonDelimtedEmail() {
+		String msg = buildMessage("subject\n\nbody of commit\n" + "\n"
+			+ "Acked-by: re@example.com\n");
+		List<FooterLine> footers = FooterLine.fromMessage(msg);
 		FooterLine f;
 
 		assertNotNull(footers);
@@ -197,10 +194,10 @@
 	}
 
 	@Test
-	public void testNotEmail() throws IOException {
-		final RevCommit commit = parse("subject\n\nbody of commit\n" + "\n"
-				+ "Acked-by: Main Tain Er\n");
-		final List<FooterLine> footers = commit.getFooterLines();
+	public void testNotEmail() {
+		String msg = buildMessage("subject\n\nbody of commit\n" + "\n"
+			+ "Acked-by: Main Tain Er\n");
+		List<FooterLine> footers = FooterLine.fromMessage(msg);
 		FooterLine f;
 
 		assertNotNull(footers);
@@ -213,15 +210,15 @@
 	}
 
 	@Test
-	public void testSignedOffBy_ManyUsers() throws IOException {
-		final RevCommit commit = parse("subject\n\nbody of commit\n"
-				+ "Not-A-Footer-Line: this line must not be read as a footer\n"
-				+ "\n" // paragraph break, now footers appear in final block
-				+ "Signed-off-by: A. U. Thor <a@example.com>\n"
-				+ "CC:            <some.mailing.list@example.com>\n"
-				+ "Acked-by: Some Reviewer <sr@example.com>\n"
-				+ "Signed-off-by: Main Tain Er <mte@example.com>\n");
-		final List<FooterLine> footers = commit.getFooterLines();
+	public void testSignedOffBy_ManyUsers() {
+		String msg = buildMessage("subject\n\nbody of commit\n"
+			+ "Not-A-Footer-Line: this line must not be read as a footer\n"
+			+ "\n" // paragraph break, now footers appear in final block
+			+ "Signed-off-by: A. U. Thor <a@example.com>\n"
+			+ "CC:            <some.mailing.list@example.com>\n"
+			+ "Acked-by: Some Reviewer <sr@example.com>\n"
+			+ "Signed-off-by: Main Tain Er <mte@example.com>\n");
+		List<FooterLine> footers = FooterLine.fromMessage(msg);
 		FooterLine f;
 
 		assertNotNull(footers);
@@ -249,16 +246,16 @@
 	}
 
 	@Test
-	public void testSignedOffBy_SkipNonFooter() throws IOException {
-		final RevCommit commit = parse("subject\n\nbody of commit\n"
-				+ "Not-A-Footer-Line: this line must not be read as a footer\n"
-				+ "\n" // paragraph break, now footers appear in final block
-				+ "Signed-off-by: A. U. Thor <a@example.com>\n"
-				+ "CC:            <some.mailing.list@example.com>\n"
-				+ "not really a footer line but we'll skip it anyway\n"
-				+ "Acked-by: Some Reviewer <sr@example.com>\n"
-				+ "Signed-off-by: Main Tain Er <mte@example.com>\n");
-		final List<FooterLine> footers = commit.getFooterLines();
+	public void testSignedOffBy_SkipNonFooter() {
+		String msg = buildMessage("subject\n\nbody of commit\n"
+			+ "Not-A-Footer-Line: this line must not be read as a footer\n"
+			+ "\n" // paragraph break, now footers appear in final block
+			+ "Signed-off-by: A. U. Thor <a@example.com>\n"
+			+ "CC:            <some.mailing.list@example.com>\n"
+			+ "not really a footer line but we'll skip it anyway\n"
+			+ "Acked-by: Some Reviewer <sr@example.com>\n"
+			+ "Signed-off-by: Main Tain Er <mte@example.com>\n");
+		List<FooterLine> footers = FooterLine.fromMessage(msg);
 		FooterLine f;
 
 		assertNotNull(footers);
@@ -282,15 +279,16 @@
 	}
 
 	@Test
-	public void testFilterFootersIgnoreCase() throws IOException {
-		final RevCommit commit = parse("subject\n\nbody of commit\n"
-				+ "Not-A-Footer-Line: this line must not be read as a footer\n"
-				+ "\n" // paragraph break, now footers appear in final block
-				+ "Signed-Off-By: A. U. Thor <a@example.com>\n"
-				+ "CC:            <some.mailing.list@example.com>\n"
-				+ "Acked-by: Some Reviewer <sr@example.com>\n"
-				+ "signed-off-by: Main Tain Er <mte@example.com>\n");
-		final List<String> footers = commit.getFooterLines("signed-off-by");
+	public void testFilterFootersIgnoreCase() {
+		String msg = buildMessage("subject\n\nbody of commit\n"
+			+ "Not-A-Footer-Line: this line must not be read as a footer\n"
+			+ "\n" // paragraph break, now footers appear in final block
+			+ "Signed-Off-By: A. U. Thor <a@example.com>\n"
+			+ "CC:            <some.mailing.list@example.com>\n"
+			+ "Acked-by: Some Reviewer <sr@example.com>\n"
+			+ "signed-off-by: Main Tain Er <mte@example.com>\n");
+		List<String> footers = FooterLine.getValues(
+			FooterLine.fromMessage(msg), "signed-off-by");
 
 		assertNotNull(footers);
 		assertEquals(2, footers.size());
@@ -300,38 +298,33 @@
 	}
 
 	@Test
-	public void testMatchesBugId() throws IOException {
-		final RevCommit commit = parse("this is a commit subject for test\n"
-				+ "\n" // paragraph break, now footers appear in final block
-				+ "Simple-Bug-Id: 42\n");
-		final List<FooterLine> footers = commit.getFooterLines();
+	public void testMatchesBugId() {
+		String msg = buildMessage("this is a commit subject for test\n"
+			+ "\n" // paragraph break, now footers appear in final block
+			+ "Simple-Bug-Id: 42\n");
+		List<FooterLine> footers = FooterLine.fromMessage(msg);
 
 		assertNotNull(footers);
 		assertEquals(1, footers.size());
 
-		final FooterLine line = footers.get(0);
+		FooterLine line = footers.get(0);
 		assertNotNull(line);
 		assertEquals("Simple-Bug-Id", line.getKey());
 		assertEquals("42", line.getValue());
 
-		final FooterKey bugid = new FooterKey("Simple-Bug-Id");
+		FooterKey bugid = new FooterKey("Simple-Bug-Id");
 		assertTrue("matches Simple-Bug-Id", line.matches(bugid));
 		assertFalse("not Signed-off-by", line.matches(FooterKey.SIGNED_OFF_BY));
 		assertFalse("not CC", line.matches(FooterKey.CC));
 	}
 
-	private RevCommit parse(String msg) throws IOException {
-		final StringBuilder buf = new StringBuilder();
+	private String buildMessage(String msg) {
+		StringBuilder buf = new StringBuilder();
 		buf.append("tree " + ObjectId.zeroId().name() + "\n");
 		buf.append("author A. U. Thor <a@example.com> 1 +0000\n");
 		buf.append("committer A. U. Thor <a@example.com> 1 +0000\n");
 		buf.append("\n");
 		buf.append(msg);
-
-		try (RevWalk walk = new RevWalk(db)) {
-			RevCommit c = new RevCommit(ObjectId.zeroId());
-			c.parseCanonical(walk, Constants.encode(buf.toString()));
-			return c;
-		}
+		return buf.toString();
 	}
 }
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
index 3cc0368..8215a79 100644
--- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/revwalk/RevWalkCommitGraphTest.java
+++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/revwalk/RevWalkCommitGraphTest.java
@@ -26,6 +26,8 @@
 import java.util.List;
 
 import org.eclipse.jgit.api.Git;
+import org.eclipse.jgit.diff.DiffConfig;
+import org.eclipse.jgit.errors.ConfigInvalidException;
 import org.eclipse.jgit.internal.storage.file.GC;
 import org.eclipse.jgit.lib.AnyObjectId;
 import org.eclipse.jgit.lib.ConfigConstants;
@@ -33,6 +35,7 @@
 import org.eclipse.jgit.lib.Ref;
 import org.eclipse.jgit.revwalk.filter.MessageRevFilter;
 import org.eclipse.jgit.revwalk.filter.RevFilter;
+import org.eclipse.jgit.storage.file.FileBasedConfig;
 import org.eclipse.jgit.treewalk.filter.AndTreeFilter;
 import org.eclipse.jgit.treewalk.filter.PathFilter;
 import org.eclipse.jgit.treewalk.filter.TreeFilter;
@@ -46,6 +49,7 @@
 	public void setUp() throws Exception {
 		super.setUp();
 		rw = new RevWalk(db);
+		mockSystemReader.setJGitConfig(new MockConfig());
 	}
 
 	@Test
@@ -167,6 +171,72 @@
 	}
 
 	@Test
+	public void testChangedPathFilter() throws Exception {
+		RevCommit c1 = commitFile("file1", "1", "master");
+		commitFile("file2", "2", "master");
+		RevCommit c3 = commitFile("file1", "3", "master");
+		RevCommit c4 = commitFile("file2", "4", "master");
+
+		enableAndWriteCommitGraph();
+
+		TreeRevFilter trf = new TreeRevFilter(rw, PathFilter.create("file1"));
+		rw.markStart(rw.lookupCommit(c4));
+		rw.setRevFilter(trf);
+		assertEquals(c3, rw.next());
+		assertEquals(c1, rw.next());
+		assertNull(rw.next());
+
+		// 1 commit that has exactly one parent and matches path
+		assertEquals(1, trf.getChangedPathFilterTruePositive());
+
+		// No false positives
+		assertEquals(0, trf.getChangedPathFilterFalsePositive());
+
+		// 2 commits that have exactly one parent and don't match path
+		assertEquals(2, trf.getChangedPathFilterNegative());
+	}
+
+	@Test
+	public void testChangedPathFilterWithFollowFilter() throws Exception {
+		RevCommit c0 = commit(tree());
+		RevCommit c1 = commit(tree(file("file", blob("contents"))), c0);
+		RevCommit c2 = commit(tree(file("file", blob("contents")),
+				file("unrelated", blob("unrelated change"))), c1);
+		RevCommit c3 = commit(tree(file("renamed-file", blob("contents")),
+				file("unrelated", blob("unrelated change"))), c2);
+		RevCommit c4 = commit(
+				tree(file("renamed-file", blob("contents")),
+						file("unrelated", blob("another unrelated change"))),
+				c3);
+		branch(c4, "master");
+
+		enableAndWriteCommitGraph();
+
+		db.getConfig().setString(ConfigConstants.CONFIG_DIFF_SECTION, null,
+				ConfigConstants.CONFIG_KEY_RENAMES, "true");
+
+		TreeRevFilter trf = new TreeRevFilter(rw,
+				new FollowFilter(PathFilter.create("renamed-file"),
+						db.getConfig().get(DiffConfig.KEY)));
+		rw.markStart(rw.lookupCommit(c4));
+		rw.setRevFilter(trf);
+		assertEquals(c3, rw.next());
+		assertEquals(c1, rw.next());
+		assertNull(rw.next());
+
+		// Path "renamed-file" is in c3's bloom filter, and another path "file"
+		// is in c1's bloom filter (we know of "file" because the rev walk
+		// detected that "renamed-file" is a renaming of "file")
+		assertEquals(2, trf.getChangedPathFilterTruePositive());
+
+		// No false positives
+		assertEquals(0, trf.getChangedPathFilterFalsePositive());
+
+		// 2 commits that have exactly one parent and don't match path
+		assertEquals(2, trf.getChangedPathFilterNegative());
+	}
+
+	@Test
 	public void testWalkWithCommitMessageFilter() throws Exception {
 		RevCommit a = commit();
 		RevCommit b = commitBuilder().parent(a)
@@ -437,6 +507,8 @@
 				ConfigConstants.CONFIG_COMMIT_GRAPH, true);
 		db.getConfig().setBoolean(ConfigConstants.CONFIG_GC_SECTION, null,
 				ConfigConstants.CONFIG_KEY_WRITE_COMMIT_GRAPH, true);
+		db.getConfig().setBoolean(ConfigConstants.CONFIG_GC_SECTION, null,
+				ConfigConstants.CONFIG_KEY_WRITE_CHANGED_PATHS, true);
 		GC gc = new GC(db);
 		gc.gc().get();
 	}
@@ -445,4 +517,41 @@
 		rw.close();
 		rw = new RevWalk(db);
 	}
+
+	private static final class MockConfig extends FileBasedConfig {
+		private MockConfig() {
+			super(null, null);
+		}
+
+		@Override
+		public void load() throws IOException, ConfigInvalidException {
+			// Do nothing
+		}
+
+		@Override
+		public void save() throws IOException {
+			// Do nothing
+		}
+
+		@Override
+		public boolean isOutdated() {
+			return false;
+		}
+
+		@Override
+		public String toString() {
+			return "MockConfig";
+		}
+
+		@Override
+		public boolean getBoolean(final String section, final String name,
+				final boolean defaultValue) {
+			if (section.equals(ConfigConstants.CONFIG_COMMIT_GRAPH_SECTION)
+					&& name.equals(
+							ConfigConstants.CONFIG_KEY_READ_CHANGED_PATHS)) {
+				return true;
+			}
+			return defaultValue;
+		}
+	}
 }
diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/revwalk/RevWalkFollowFilterTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/revwalk/RevWalkFollowFilterTest.java
index c62136e..5203e3f 100644
--- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/revwalk/RevWalkFollowFilterTest.java
+++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/revwalk/RevWalkFollowFilterTest.java
@@ -27,9 +27,17 @@
 	private static class DiffCollector extends RenameCallback {
 		List<DiffEntry> diffs = new ArrayList<>();
 
+		List<RevCommit> commits = new ArrayList<>();
+
 		@Override
 		public void renamed(DiffEntry diff) {
+			throw new UnsupportedOperationException("unimplemented");
+		}
+
+		@Override
+		public void renamed(DiffEntry diff, RevCommit commit) {
 			diffs.add(diff);
+			commits.add(commit);
 		}
 	}
 
@@ -77,6 +85,7 @@
 		assertNull(rw.next());
 
 		assertRenames("a->b");
+		assertRenameCommits(renameCommit);
 	}
 
 	@Test
@@ -108,6 +117,7 @@
 		assertNull(rw.next());
 
 		assertRenames("c->a", "b->c", "a->b");
+		assertRenameCommits(renameCommit3, renameCommit2, renameCommit1);
 	}
 
 	/**
@@ -136,6 +146,20 @@
 		}
 	}
 
+	protected void assertRenameCommits(RevCommit... expectedCommits) {
+		Assert.assertEquals(
+				"Unexpected number of rename commits. Expected: "
+						+ expectedCommits.length + ", actual: "
+						+ diffCollector.diffs.size(),
+				expectedCommits.length, diffCollector.diffs.size());
+
+		for (int i = 0; i < expectedCommits.length; i++) {
+			RevCommit renameCommit = diffCollector.commits.get(i);
+			Assert.assertNotNull(renameCommit);
+			Assert.assertEquals(expectedCommits[i], renameCommit);
+		}
+	}
+
 	protected void assertNoRenames() {
 		Assert.assertEquals("Found unexpected rename/copy diff", 0,
 				diffCollector.diffs.size());
diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/storage/file/UserConfigFileTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/storage/file/UserConfigFileTest.java
new file mode 100644
index 0000000..7d212d5
--- /dev/null
+++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/storage/file/UserConfigFileTest.java
@@ -0,0 +1,301 @@
+/*
+ * Copyright (C) 2023, Thomas Wolf <twolf@apache.org> and others
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Distribution License v. 1.0 which is available at
+ * https://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+package org.eclipse.jgit.storage.file;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertTrue;
+
+import java.nio.file.Files;
+import java.nio.file.Path;
+
+import org.eclipse.jgit.util.FS;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.rules.TemporaryFolder;
+
+public class UserConfigFileTest {
+
+	@Rule
+	public TemporaryFolder tmp = new TemporaryFolder();
+
+	@Test
+	public void testParentOnlyLoad() throws Exception {
+		Path xdg = tmp.getRoot().toPath().resolve("xdg.cfg");
+		Files.writeString(xdg, "[user]\n\tname = Archibald Ulysses Thor");
+		Path user = tmp.getRoot().toPath().resolve("user.cfg");
+		UserConfigFile config = new UserConfigFile(null, user.toFile(),
+				xdg.toFile(), FS.DETECTED);
+		config.load();
+		assertEquals("Archibald Ulysses Thor",
+				config.getString("user", null, "name"));
+	}
+
+	@Test
+	public void testLoadBoth() throws Exception {
+		Path xdg = tmp.getRoot().toPath().resolve("xdg.cfg");
+		Files.writeString(xdg, "[user]\n\tname = Archibald Ulysses Thor");
+		Path user = tmp.getRoot().toPath().resolve("user.cfg");
+		Files.writeString(user, "[user]\n\temail = a.u.thor@example.com");
+		UserConfigFile config = new UserConfigFile(null, user.toFile(),
+				xdg.toFile(), FS.DETECTED);
+		config.load();
+		assertEquals("Archibald Ulysses Thor",
+				config.getString("user", null, "name"));
+		assertEquals("a.u.thor@example.com",
+				config.getString("user", null, "email"));
+	}
+
+	@Test
+	public void testOverwriteChild() throws Exception {
+		Path xdg = tmp.getRoot().toPath().resolve("xdg.cfg");
+		Files.writeString(xdg, "[user]\n\tname = Archibald Ulysses Thor");
+		Path user = tmp.getRoot().toPath().resolve("user.cfg");
+		Files.writeString(user, "[user]\n\temail = a.u.thor@example.com");
+		UserConfigFile config = new UserConfigFile(null, user.toFile(),
+				xdg.toFile(), FS.DETECTED);
+		config.load();
+		assertEquals("Archibald Ulysses Thor",
+				config.getString("user", null, "name"));
+		assertEquals("a.u.thor@example.com",
+				config.getString("user", null, "email"));
+		config.setString("user", null, "name", "A U Thor");
+		assertEquals("A U Thor", config.getString("user", null, "name"));
+		config.save();
+		UserConfigFile config2 = new UserConfigFile(null, user.toFile(),
+				xdg.toFile(), FS.DETECTED);
+		config2.load();
+		assertEquals("A U Thor", config2.getString("user", null, "name"));
+		assertEquals("a.u.thor@example.com",
+				config.getString("user", null, "email"));
+		FileBasedConfig cfg = new FileBasedConfig(null, xdg.toFile(),
+				FS.DETECTED);
+		cfg.load();
+		assertEquals("Archibald Ulysses Thor",
+				cfg.getString("user", null, "name"));
+		assertNull(cfg.getString("user", null, "email"));
+	}
+
+	@Test
+	public void testUnset() throws Exception {
+		Path xdg = tmp.getRoot().toPath().resolve("xdg.cfg");
+		Files.writeString(xdg, "[user]\n\tname = Archibald Ulysses Thor");
+		Path user = tmp.getRoot().toPath().resolve("user.cfg");
+		Files.writeString(user, "[user]\n\temail = a.u.thor@example.com");
+		UserConfigFile config = new UserConfigFile(null, user.toFile(),
+				xdg.toFile(), FS.DETECTED);
+		config.load();
+		assertEquals("Archibald Ulysses Thor",
+				config.getString("user", null, "name"));
+		assertEquals("a.u.thor@example.com",
+				config.getString("user", null, "email"));
+		config.setString("user", null, "name", "A U Thor");
+		assertEquals("A U Thor", config.getString("user", null, "name"));
+		config.unset("user", null, "name");
+		assertEquals("Archibald Ulysses Thor",
+				config.getString("user", null, "name"));
+		assertEquals("a.u.thor@example.com",
+				config.getString("user", null, "email"));
+		config.save();
+		UserConfigFile config2 = new UserConfigFile(null, user.toFile(),
+				xdg.toFile(), FS.DETECTED);
+		config2.load();
+		assertEquals("Archibald Ulysses Thor",
+				config2.getString("user", null, "name"));
+		assertEquals("a.u.thor@example.com",
+				config.getString("user", null, "email"));
+		FileBasedConfig cfg = new FileBasedConfig(null, user.toFile(),
+				FS.DETECTED);
+		cfg.load();
+		assertNull(cfg.getString("user", null, "name"));
+		assertEquals("a.u.thor@example.com",
+				cfg.getString("user", null, "email"));
+	}
+
+	@Test
+	public void testUnsetSection() throws Exception {
+		Path xdg = tmp.getRoot().toPath().resolve("xdg.cfg");
+		Files.writeString(xdg, "[user]\n\tname = Archibald Ulysses Thor");
+		Path user = tmp.getRoot().toPath().resolve("user.cfg");
+		Files.writeString(user, "[user]\n\temail = a.u.thor@example.com");
+		UserConfigFile config = new UserConfigFile(null, user.toFile(),
+				xdg.toFile(), FS.DETECTED);
+		config.load();
+		assertEquals("Archibald Ulysses Thor",
+				config.getString("user", null, "name"));
+		assertEquals("a.u.thor@example.com",
+				config.getString("user", null, "email"));
+		config.unsetSection("user", null);
+		assertEquals("Archibald Ulysses Thor",
+				config.getString("user", null, "name"));
+		config.save();
+		assertTrue(Files.readString(user).strip().isEmpty());
+	}
+
+	@Test
+	public void testNoChild() throws Exception {
+		Path xdg = tmp.getRoot().toPath().resolve("xdg.cfg");
+		Files.writeString(xdg, "[user]\n\tname = Archibald Ulysses Thor");
+		Path user = tmp.getRoot().toPath().resolve("user.cfg");
+		UserConfigFile config = new UserConfigFile(null, user.toFile(),
+				xdg.toFile(), FS.DETECTED);
+		config.load();
+		assertEquals("Archibald Ulysses Thor",
+				config.getString("user", null, "name"));
+		assertNull(config.getString("user", null, "email"));
+		config.setString("user", null, "email", "a.u.thor@example.com");
+		assertEquals("a.u.thor@example.com",
+				config.getString("user", null, "email"));
+		config.save();
+		assertFalse(Files.exists(user));
+		UserConfigFile config2 = new UserConfigFile(null, user.toFile(),
+				xdg.toFile(), FS.DETECTED);
+		config2.load();
+		assertEquals("Archibald Ulysses Thor",
+				config2.getString("user", null, "name"));
+		assertEquals("a.u.thor@example.com",
+				config2.getString("user", null, "email"));
+	}
+
+	@Test
+	public void testNoFiles() throws Exception {
+		Path xdg = tmp.getRoot().toPath().resolve("xdg.cfg");
+		Path user = tmp.getRoot().toPath().resolve("user.cfg");
+		UserConfigFile config = new UserConfigFile(null, user.toFile(),
+				xdg.toFile(), FS.DETECTED);
+		config.load();
+		assertNull(config.getString("user", null, "name"));
+		assertNull(config.getString("user", null, "email"));
+		config.setString("user", null, "name", "Archibald Ulysses Thor");
+		config.setString("user", null, "email", "a.u.thor@example.com");
+		assertEquals("Archibald Ulysses Thor",
+				config.getString("user", null, "name"));
+		assertEquals("a.u.thor@example.com",
+				config.getString("user", null, "email"));
+		config.save();
+		assertTrue(Files.exists(user));
+		assertFalse(Files.exists(xdg));
+		UserConfigFile config2 = new UserConfigFile(null, user.toFile(),
+				xdg.toFile(), FS.DETECTED);
+		config2.load();
+		assertEquals("Archibald Ulysses Thor",
+				config2.getString("user", null, "name"));
+		assertEquals("a.u.thor@example.com",
+				config2.getString("user", null, "email"));
+	}
+
+	@Test
+	public void testSetInXdg() throws Exception {
+		Path xdg = tmp.getRoot().toPath().resolve("xdg.cfg");
+		Files.writeString(xdg, "[user]\n\tname = Archibald Ulysses Thor");
+		Path user = tmp.getRoot().toPath().resolve("user.cfg");
+		UserConfigFile config = new UserConfigFile(null, user.toFile(),
+				xdg.toFile(), FS.DETECTED);
+		config.load();
+		assertEquals("Archibald Ulysses Thor",
+				config.getString("user", null, "name"));
+		config.setString("user", null, "email", "a.u.thor@example.com");
+		config.save();
+		assertFalse(Files.exists(user));
+		FileBasedConfig cfg = new FileBasedConfig(null, xdg.toFile(),
+				FS.DETECTED);
+		cfg.load();
+		assertEquals("Archibald Ulysses Thor",
+				cfg.getString("user", null, "name"));
+		assertEquals("a.u.thor@example.com",
+				cfg.getString("user", null, "email"));
+	}
+
+	@Test
+	public void testUserConfigCreated() throws Exception {
+		Path xdg = tmp.getRoot().toPath().resolve("xdg.cfg");
+		Files.writeString(xdg, "[user]\n\tname = Archibald Ulysses Thor");
+		Path user = tmp.getRoot().toPath().resolve("user.cfg");
+		Thread.sleep(3000); // Avoid racily clean isOutdated() below.
+		UserConfigFile config = new UserConfigFile(null, user.toFile(),
+				xdg.toFile(), FS.DETECTED);
+		config.load();
+		assertEquals("Archibald Ulysses Thor",
+				config.getString("user", null, "name"));
+		Files.writeString(user,
+				"[user]\n\temail = a.u.thor@example.com\n\tname = A U Thor");
+		assertEquals("Archibald Ulysses Thor",
+				config.getString("user", null, "name"));
+		assertTrue(config.isOutdated());
+		config.load();
+		assertEquals("A U Thor", config.getString("user", null, "name"));
+		assertEquals("a.u.thor@example.com",
+				config.getString("user", null, "email"));
+	}
+
+	@Test
+	public void testUserConfigDeleted() throws Exception {
+		Path xdg = tmp.getRoot().toPath().resolve("xdg.cfg");
+		Files.writeString(xdg, "[user]\n\tname = Archibald Ulysses Thor");
+		Path user = tmp.getRoot().toPath().resolve("user.cfg");
+		Files.writeString(user,
+				"[user]\n\temail = a.u.thor@example.com\n\tname = A U Thor");
+		Thread.sleep(3000); // Avoid racily clean isOutdated() below.
+		UserConfigFile config = new UserConfigFile(null, user.toFile(),
+				xdg.toFile(), FS.DETECTED);
+		config.load();
+		assertEquals("A U Thor", config.getString("user", null, "name"));
+		assertEquals("a.u.thor@example.com",
+				config.getString("user", null, "email"));
+		Files.delete(user);
+		assertEquals("A U Thor", config.getString("user", null, "name"));
+		assertEquals("a.u.thor@example.com",
+				config.getString("user", null, "email"));
+		assertTrue(config.isOutdated());
+		config.load();
+		assertEquals("Archibald Ulysses Thor",
+				config.getString("user", null, "name"));
+		assertNull(config.getString("user", null, "email"));
+	}
+
+	@Test
+	public void testXdgConfigDeleted() throws Exception {
+		Path xdg = tmp.getRoot().toPath().resolve("xdg.cfg");
+		Files.writeString(xdg, "[user]\n\tname = Archibald Ulysses Thor");
+		Path user = tmp.getRoot().toPath().resolve("user.cfg");
+		Thread.sleep(3000); // Avoid racily clean isOutdated() below.
+		UserConfigFile config = new UserConfigFile(null, user.toFile(),
+				xdg.toFile(), FS.DETECTED);
+		config.load();
+		assertEquals("Archibald Ulysses Thor",
+				config.getString("user", null, "name"));
+		Files.delete(xdg);
+		assertEquals("Archibald Ulysses Thor",
+				config.getString("user", null, "name"));
+		assertTrue(config.isOutdated());
+		config.load();
+		assertNull(config.getString("user", null, "name"));
+	}
+
+	@Test
+	public void testXdgConfigDeletedUserConfigExists() throws Exception {
+		Path xdg = tmp.getRoot().toPath().resolve("xdg.cfg");
+		Files.writeString(xdg, "[user]\n\tname = Archibald Ulysses Thor");
+		Path user = tmp.getRoot().toPath().resolve("user.cfg");
+		Files.writeString(user,
+				"[user]\n\temail = a.u.thor@example.com\n\tname = A U Thor");
+		Thread.sleep(3000); // Avoid racily clean isOutdated() below.
+		UserConfigFile config = new UserConfigFile(null, user.toFile(),
+				xdg.toFile(), FS.DETECTED);
+		config.load();
+		assertEquals("A U Thor", config.getString("user", null, "name"));
+		Files.delete(xdg);
+		assertTrue(config.isOutdated());
+		config.load();
+		assertEquals("A U Thor", config.getString("user", null, "name"));
+	}
+
+}
diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/transport/HttpAuthTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/transport/HttpAuthTest.java
index 947ca97..c1ab43e 100644
--- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/transport/HttpAuthTest.java
+++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/transport/HttpAuthTest.java
@@ -160,7 +160,7 @@
 				String value = header.substring(i + 1).trim();
 
 				if (!headerFields.containsKey(key))
-					headerFields.put(key, new ArrayList<String>());
+					headerFields.put(key, new ArrayList<>());
 
 				List<String> values = headerFields.get(key);
 				values.add(value);
diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/transport/InMemoryPack.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/transport/InMemoryPack.java
new file mode 100644
index 0000000..cad80ef
--- /dev/null
+++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/transport/InMemoryPack.java
@@ -0,0 +1,88 @@
+/*
+ * Copyright (C) 2023, Google LLC. and others
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Distribution License v. 1.0 which is available at
+ * https://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+package org.eclipse.jgit.transport;
+
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.security.MessageDigest;
+import java.util.zip.Deflater;
+
+import org.eclipse.jgit.lib.AnyObjectId;
+import org.eclipse.jgit.lib.Constants;
+import org.eclipse.jgit.util.NB;
+import org.eclipse.jgit.util.TemporaryBuffer;
+import org.eclipse.jgit.util.TemporaryBuffer.Heap;
+
+/**
+ * Helper class to create packs for tests.
+ */
+public class InMemoryPack {
+
+  private final Heap tinyPack;
+
+  public InMemoryPack() {
+    this(1024);
+  }
+
+  public InMemoryPack(int size) {
+    this.tinyPack = new TemporaryBuffer.Heap(size);
+  }
+
+  public InMemoryPack header(int cnt)
+      throws IOException {
+    final byte[] hdr = new byte[8];
+    NB.encodeInt32(hdr, 0, 2);
+    NB.encodeInt32(hdr, 4, cnt);
+
+    tinyPack.write(Constants.PACK_SIGNATURE);
+    tinyPack.write(hdr, 0, 8);
+    return this;
+  }
+
+  public InMemoryPack write(int i) throws IOException {
+    tinyPack.write(i);
+    return this;
+  }
+
+  public InMemoryPack deflate(byte[] content)
+      throws IOException {
+    Deflater deflater = new Deflater();
+    byte[] buf = new byte[128];
+    deflater.setInput(content, 0, content.length);
+    deflater.finish();
+    do {
+      final int n = deflater.deflate(buf, 0, buf.length);
+      if (n > 0)
+        tinyPack.write(buf, 0, n);
+    } while (!deflater.finished());
+    return this;
+  }
+
+  public InMemoryPack copyRaw(AnyObjectId o) throws IOException {
+    o.copyRawTo(tinyPack);
+    return this;
+  }
+
+  public InMemoryPack digest() throws IOException {
+    MessageDigest md = Constants.newMessageDigest();
+    md.update(tinyPack.toByteArray());
+    tinyPack.write(md.digest());
+    return this;
+  }
+
+  public InputStream toInputStream() throws IOException {
+    return new ByteArrayInputStream(tinyPack.toByteArray());
+  }
+
+  public byte[] toByteArray() throws IOException {
+    return tinyPack.toByteArray();
+  }
+}
diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/transport/PackParserTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/transport/PackParserTest.java
index f02428e..2fd82e7 100644
--- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/transport/PackParserTest.java
+++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/transport/PackParserTest.java
@@ -22,12 +22,10 @@
 import java.io.FileInputStream;
 import java.io.IOException;
 import java.io.InputStream;
-import java.security.MessageDigest;
 import java.text.MessageFormat;
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
-import java.util.zip.Deflater;
 
 import org.eclipse.jgit.errors.TooLargeObjectInPackException;
 import org.eclipse.jgit.internal.JGitText;
@@ -42,8 +40,6 @@
 import org.eclipse.jgit.lib.ObjectInserter;
 import org.eclipse.jgit.lib.Repository;
 import org.eclipse.jgit.revwalk.RevBlob;
-import org.eclipse.jgit.util.NB;
-import org.eclipse.jgit.util.TemporaryBuffer;
 import org.eclipse.jgit.util.io.UnionInputStream;
 import org.junit.After;
 import org.junit.Test;
@@ -193,17 +189,14 @@
 			a = d.blob("a");
 		}
 
-		TemporaryBuffer.Heap pack = new TemporaryBuffer.Heap(1024);
-
-		packHeader(pack, 1);
-
+		InMemoryPack pack = new InMemoryPack();
+		pack.header(1);
 		pack.write((Constants.OBJ_REF_DELTA) << 4 | 4);
-		a.copyRawTo(pack);
-		deflate(pack, new byte[] { 0x1, 0x1, 0x1, 'b' });
+		pack.copyRaw(a);
+		pack.deflate(new byte[] { 0x1, 0x1, 0x1, 'b' });
+		pack.digest();
 
-		digest(pack);
-
-		PackParser p = index(new ByteArrayInputStream(pack.toByteArray()));
+		PackParser p = index(pack.toInputStream());
 		p.setAllowThin(true);
 		p.parse(NullProgressMonitor.INSTANCE);
 	}
@@ -216,14 +209,14 @@
 			assertTrue(db.getObjectDatabase().has(d.blob(data)));
 		}
 
-		TemporaryBuffer.Heap pack = new TemporaryBuffer.Heap(1024);
-		packHeader(pack, 1);
+		InMemoryPack pack = new InMemoryPack();
+		pack.header(1);
 		pack.write((Constants.OBJ_BLOB) << 4 | 0x80 | 1);
 		pack.write(1);
-		deflate(pack, data);
-		digest(pack);
+		pack.deflate(data);
+		pack.digest();
 
-		PackParser p = index(new ByteArrayInputStream(pack.toByteArray()));
+		PackParser p = index(pack.toInputStream());
 		p.setAllowThin(false);
 		p.parse(NullProgressMonitor.INSTANCE);
 	}
@@ -236,16 +229,16 @@
 			assertTrue(db.getObjectDatabase().has(d.blob(data)));
 		}
 
-		TemporaryBuffer.Heap pack = new TemporaryBuffer.Heap(1024);
-		packHeader(pack, 2);
+		InMemoryPack pack = new InMemoryPack();
+		pack.header(2);
 		pack.write((Constants.OBJ_BLOB) << 4 | 10); // offset 12
-		deflate(pack, data);
+		pack.deflate(data);
 		pack.write((Constants.OBJ_OFS_DELTA) << 4 | 4); // offset 31
 		pack.write(19);
-		deflate(pack, new byte[] { 0xA, 0xB, 0x1, 'b' });
-		digest(pack);
+		pack.deflate(new byte[] { 0xA, 0xB, 0x1, 'b' });
+		pack.digest();
 
-		PackParser p = index(new ByteArrayInputStream(pack.toByteArray()));
+		PackParser p = index(pack.toInputStream());
 		p.parse(NullProgressMonitor.INSTANCE);
 
 		List<PackedObjectInfo> sortedObjectList = p.getSortedObjectList(null);
@@ -275,15 +268,15 @@
 			a = d.blob("a");
 		}
 
-		TemporaryBuffer.Heap pack = new TemporaryBuffer.Heap(1024);
-		packHeader(pack, 1);
+		InMemoryPack pack = new InMemoryPack();
+		pack.header(1);
 		pack.write((Constants.OBJ_REF_DELTA) << 4 | 4);
-		a.copyRawTo(pack);
-		deflate(pack, new byte[] { 0x1, 0x1, 0x1, 'b' });
-		digest(pack);
+		pack.copyRaw(a);
+		pack.deflate(new byte[] { 0x1, 0x1, 0x1, 'b' });
+		pack.digest();
 
 		PackParser p = index(new UnionInputStream(
-				new ByteArrayInputStream(pack.toByteArray()),
+				pack.toInputStream(),
 				new ByteArrayInputStream(new byte[] { 0x7e })));
 		p.setAllowThin(true);
 		p.setCheckEofAfterPackFooter(true);
@@ -305,22 +298,21 @@
 			d.blob(data);
 		}
 
-		TemporaryBuffer.Heap pack = new TemporaryBuffer.Heap(1024);
-
-		packHeader(pack, 1);
+		InMemoryPack pack = new InMemoryPack();
+		pack.header(1);
 		pack.write((Constants.OBJ_BLOB) << 4 | 10);
-		deflate(pack, data);
-		digest(pack);
+		pack.deflate(data);
+		pack.digest();
 
-		PackParser p = index(new ByteArrayInputStream(pack.toByteArray()));
+		PackParser p = index(pack.toInputStream());
 		p.setMaxObjectSizeLimit(11);
 		p.parse(NullProgressMonitor.INSTANCE);
 
-		p = index(new ByteArrayInputStream(pack.toByteArray()));
+		p = index(pack.toInputStream());
 		p.setMaxObjectSizeLimit(10);
 		p.parse(NullProgressMonitor.INSTANCE);
 
-		p = index(new ByteArrayInputStream(pack.toByteArray()));
+		p = index(pack.toInputStream());
 		p.setMaxObjectSizeLimit(9);
 		try {
 			p.parse(NullProgressMonitor.INSTANCE);
@@ -339,21 +331,20 @@
 			a = d.blob("a");
 		}
 
-		TemporaryBuffer.Heap pack = new TemporaryBuffer.Heap(1024);
-
-		packHeader(pack, 1);
+		InMemoryPack pack = new InMemoryPack();
+		pack.header(1);
 		pack.write((Constants.OBJ_REF_DELTA) << 4 | 14);
-		a.copyRawTo(pack);
-		deflate(pack, new byte[] { 1, 11, 11, 'a', '0', '1', '2', '3', '4',
+		pack.copyRaw(a);
+		pack.deflate(new byte[] { 1, 11, 11, 'a', '0', '1', '2', '3', '4',
 				'5', '6', '7', '8', '9' });
-		digest(pack);
+		pack.digest();
 
-		PackParser p = index(new ByteArrayInputStream(pack.toByteArray()));
+		PackParser p = index(pack.toInputStream());
 		p.setAllowThin(true);
 		p.setMaxObjectSizeLimit(14);
 		p.parse(NullProgressMonitor.INSTANCE);
 
-		p = index(new ByteArrayInputStream(pack.toByteArray()));
+		p = index(pack.toInputStream());
 		p.setAllowThin(true);
 		p.setMaxObjectSizeLimit(13);
 		try {
@@ -373,20 +364,19 @@
 			a = d.blob("0123456789");
 		}
 
-		TemporaryBuffer.Heap pack = new TemporaryBuffer.Heap(1024);
-
-		packHeader(pack, 1);
+		InMemoryPack pack = new InMemoryPack();
+		pack.header(1);
 		pack.write((Constants.OBJ_REF_DELTA) << 4 | 4);
-		a.copyRawTo(pack);
-		deflate(pack, new byte[] { 10, 11, 1, 'a' });
-		digest(pack);
+		pack.copyRaw(a);
+		pack.deflate(new byte[] { 10, 11, 1, 'a' });
+		pack.digest();
 
-		PackParser p = index(new ByteArrayInputStream(pack.toByteArray()));
+		PackParser p = index(pack.toInputStream());
 		p.setAllowThin(true);
 		p.setMaxObjectSizeLimit(11);
 		p.parse(NullProgressMonitor.INSTANCE);
 
-		p = index(new ByteArrayInputStream(pack.toByteArray()));
+		p = index(pack.toInputStream());
 		p.setAllowThin(true);
 		p.setMaxObjectSizeLimit(10);
 		try {
@@ -406,12 +396,12 @@
 			a = d.blob("a");
 		}
 
-		TemporaryBuffer.Heap pack = new TemporaryBuffer.Heap(1024);
-		packHeader(pack, 1);
+		InMemoryPack pack = new InMemoryPack();
+		pack.header(1);
 		pack.write((Constants.OBJ_REF_DELTA) << 4 | 4);
-		a.copyRawTo(pack);
-		deflate(pack, new byte[] { 0x1, 0x1, 0x1, 'b' });
-		digest(pack);
+		pack.copyRaw(a);
+		pack.deflate(new byte[] { 0x1, 0x1, 0x1, 'b' });
+		pack.digest();
 
 		InputStream in = new ByteArrayInputStream(pack.toByteArray()) {
 			@Override
@@ -447,12 +437,12 @@
 			a = d.blob("a");
 		}
 
-		TemporaryBuffer.Heap pack = new TemporaryBuffer.Heap(32*1024);
-		packHeader(pack, 1);
+		InMemoryPack pack = new InMemoryPack();
+		pack.header(1);
 		pack.write((Constants.OBJ_REF_DELTA) << 4 | 4);
-		a.copyRawTo(pack);
-		deflate(pack, new byte[] { 0x1, 0x1, 0x1, 'b' });
-		digest(pack);
+		pack.copyRaw(a);
+		pack.deflate(new byte[] { 0x1, 0x1, 0x1, 'b' });
+		pack.digest();
 
 		byte packData[] = pack.toByteArray();
 		byte streamData[] = new byte[packData.length + 1];
@@ -476,14 +466,14 @@
 
 		// Build a pack ~17k
 		int objects = 900;
-		TemporaryBuffer.Heap pack = new TemporaryBuffer.Heap(32 * 1024);
-		packHeader(pack, objects);
+		InMemoryPack pack = new InMemoryPack(32 * 1024);
+		pack.header(objects);
 
 		for (int i = 0; i < objects; i++) {
 			pack.write((Constants.OBJ_BLOB) << 4 | 10);
-			deflate(pack, data);
+			pack.deflate(data);
 		}
-		digest(pack);
+		pack.digest();
 
 		byte packData[] = pack.toByteArray();
 		byte streamData[] = new byte[packData.length + 1];
@@ -510,8 +500,9 @@
 		}
 
 		int objects = 248;
-		TemporaryBuffer.Heap pack = new TemporaryBuffer.Heap(32 * 1024);
-		packHeader(pack, objects + 1);
+		InMemoryPack pack = new InMemoryPack(32 * 1024);
+		pack.header(objects + 1);
+
 		int offset = 13;
 		StringBuilder sb = new StringBuilder();
 		for (int i = 0; i < offset; i++)
@@ -529,16 +520,16 @@
 				lenByte |= 1 << 7;
 			pack.write(lenByte);
 		}
-		deflate(pack, Constants.encode(sb.toString()));
+		pack.deflate(Constants.encode(sb.toString()));
 
 		for (int i = 0; i < objects; i++) {
 			// The last pack header written falls across the 8192 byte boundary
 			// between [8189:8210]
 			pack.write((Constants.OBJ_REF_DELTA) << 4 | 4);
-			b.copyRawTo(pack);
-			deflate(pack, new byte[] { 0x1, 0x1, 0x1, 'b' });
+			pack.copyRaw(b);
+			pack.deflate(new byte[] { 0x1, 0x1, 0x1, 'b' });
 		}
-		digest(pack);
+		pack.digest();
 
 		byte packData[] = pack.toByteArray();
 		byte streamData[] = new byte[packData.length + 1];
@@ -555,36 +546,6 @@
 		assertEquals(0x7e, in.read());
 	}
 
-	private static void packHeader(TemporaryBuffer.Heap tinyPack, int cnt)
-			throws IOException {
-		final byte[] hdr = new byte[8];
-		NB.encodeInt32(hdr, 0, 2);
-		NB.encodeInt32(hdr, 4, cnt);
-
-		tinyPack.write(Constants.PACK_SIGNATURE);
-		tinyPack.write(hdr, 0, 8);
-	}
-
-	private static void deflate(TemporaryBuffer.Heap tinyPack,
-			final byte[] content)
-			throws IOException {
-		final Deflater deflater = new Deflater();
-		final byte[] buf = new byte[128];
-		deflater.setInput(content, 0, content.length);
-		deflater.finish();
-		do {
-			final int n = deflater.deflate(buf, 0, buf.length);
-			if (n > 0)
-				tinyPack.write(buf, 0, n);
-		} while (!deflater.finished());
-	}
-
-	private static void digest(TemporaryBuffer.Heap buf) throws IOException {
-		MessageDigest md = Constants.newMessageDigest();
-		md.update(buf.toByteArray());
-		buf.write(md.digest());
-	}
-
 	private ObjectInserter inserter;
 
 	@After
diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/transport/UploadPackTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/transport/UploadPackTest.java
index 9755ed1..f9687f9 100644
--- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/transport/UploadPackTest.java
+++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/transport/UploadPackTest.java
@@ -2168,12 +2168,12 @@
 	/**
 	 * <pre>
 	 * remote:
-	 *    foo <- foofoo <-- branchFoo
-	 *    bar <- barbar <-- branchBar
+	 *    foo &lt;- foofoo &lt;-- branchFoo
+	 *    bar &lt;- barbar &lt;-- branchBar
 	 *
 	 * client:
-	 *    foo <-- branchFoo
-	 *    bar <-- branchBar
+	 *    foo &lt;-- branchFoo
+	 *    bar &lt;-- branchBar
 	 *
 	 * fetch(branchFoo) should send exactly 1 have (i.e. foo) from branchFoo
 	 * </pre>
diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/treewalk/filter/PathSuffixFilterTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/treewalk/filter/PathSuffixFilterTest.java
index 0b5a735..d6f4f18 100644
--- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/treewalk/filter/PathSuffixFilterTest.java
+++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/treewalk/filter/PathSuffixFilterTest.java
@@ -53,8 +53,8 @@
 	@Test
 	public void testEdgeCases() throws IOException {
 		ObjectId treeId = createTree("abc", "abcd", "bcd", "c");
-		assertEquals(new ArrayList<String>(), getMatchingPaths("xbcd", treeId));
-		assertEquals(new ArrayList<String>(), getMatchingPaths("abcx", treeId));
+		assertEquals(new ArrayList<>(), getMatchingPaths("xbcd", treeId));
+		assertEquals(new ArrayList<>(), getMatchingPaths("abcx", treeId));
 		assertEquals(Arrays.asList("abcd"), getMatchingPaths("abcd", treeId));
 		assertEquals(Arrays.asList("abcd", "bcd"), getMatchingPaths("bcd", treeId));
 		assertEquals(Arrays.asList("abc", "c"), getMatchingPaths("c", treeId));
diff --git a/org.eclipse.jgit.ui/.settings/org.eclipse.jdt.core.prefs b/org.eclipse.jgit.ui/.settings/org.eclipse.jdt.core.prefs
index 0857bc1..3a92f0c 100644
--- a/org.eclipse.jgit.ui/.settings/org.eclipse.jdt.core.prefs
+++ b/org.eclipse.jgit.ui/.settings/org.eclipse.jdt.core.prefs
@@ -52,7 +52,7 @@
 org.eclipse.jdt.core.compiler.problem.missingJavadocComments=error
 org.eclipse.jdt.core.compiler.problem.missingJavadocCommentsOverriding=disabled
 org.eclipse.jdt.core.compiler.problem.missingJavadocCommentsVisibility=protected
-org.eclipse.jdt.core.compiler.problem.missingJavadocTagDescription=return_tag
+org.eclipse.jdt.core.compiler.problem.missingJavadocTagDescription=all_standard_tags
 org.eclipse.jdt.core.compiler.problem.missingJavadocTags=error
 org.eclipse.jdt.core.compiler.problem.missingJavadocTagsMethodTypeParameters=disabled
 org.eclipse.jdt.core.compiler.problem.missingJavadocTagsOverriding=disabled
diff --git a/org.eclipse.jgit.ui/META-INF/MANIFEST.MF b/org.eclipse.jgit.ui/META-INF/MANIFEST.MF
index fd679f9..90fb486 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.6.2.qualifier
+Bundle-Version: 6.7.1.qualifier
 Bundle-Vendor: %Bundle-Vendor
 Bundle-RequiredExecutionEnvironment: JavaSE-11
-Export-Package: org.eclipse.jgit.awtui;version="6.6.2"
-Import-Package: org.eclipse.jgit.errors;version="[6.6.2,6.7.0)",
- org.eclipse.jgit.lib;version="[6.6.2,6.7.0)",
- org.eclipse.jgit.nls;version="[6.6.2,6.7.0)",
- org.eclipse.jgit.revplot;version="[6.6.2,6.7.0)",
- org.eclipse.jgit.revwalk;version="[6.6.2,6.7.0)",
- org.eclipse.jgit.transport;version="[6.6.2,6.7.0)",
- org.eclipse.jgit.util;version="[6.6.2,6.7.0)"
+Export-Package: org.eclipse.jgit.awtui;version="6.7.1"
+Import-Package: org.eclipse.jgit.errors;version="[6.7.1,6.8.0)",
+ org.eclipse.jgit.lib;version="[6.7.1,6.8.0)",
+ org.eclipse.jgit.nls;version="[6.7.1,6.8.0)",
+ org.eclipse.jgit.revplot;version="[6.7.1,6.8.0)",
+ org.eclipse.jgit.revwalk;version="[6.7.1,6.8.0)",
+ org.eclipse.jgit.transport;version="[6.7.1,6.8.0)",
+ org.eclipse.jgit.util;version="[6.7.1,6.8.0)"
diff --git a/org.eclipse.jgit.ui/META-INF/SOURCE-MANIFEST.MF b/org.eclipse.jgit.ui/META-INF/SOURCE-MANIFEST.MF
index be9bb5d..94b8bc5 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.6.2.qualifier
-Eclipse-SourceBundle: org.eclipse.jgit.ui;version="6.6.2.qualifier";roots="."
+Bundle-Version: 6.7.1.qualifier
+Eclipse-SourceBundle: org.eclipse.jgit.ui;version="6.7.1.qualifier";roots="."
diff --git a/org.eclipse.jgit.ui/pom.xml b/org.eclipse.jgit.ui/pom.xml
index cdb6f84..930fc73 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.6.2-SNAPSHOT</version>
+    <version>6.7.1-SNAPSHOT</version>
   </parent>
 
   <artifactId>org.eclipse.jgit.ui</artifactId>
diff --git a/org.eclipse.jgit.ui/src/org/eclipse/jgit/awtui/AwtAuthenticator.java b/org.eclipse.jgit.ui/src/org/eclipse/jgit/awtui/AwtAuthenticator.java
index 56655b3..2b078c1 100644
--- a/org.eclipse.jgit.ui/src/org/eclipse/jgit/awtui/AwtAuthenticator.java
+++ b/org.eclipse.jgit.ui/src/org/eclipse/jgit/awtui/AwtAuthenticator.java
@@ -36,7 +36,6 @@
 		setDefault(new AwtAuthenticator());
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	protected PasswordAuthentication promptPasswordAuthentication() {
 		final GridBagConstraints gbc = new GridBagConstraints(0, 0, 1, 1, 1, 1,
diff --git a/org.eclipse.jgit.ui/src/org/eclipse/jgit/awtui/AwtCredentialsProvider.java b/org.eclipse.jgit.ui/src/org/eclipse/jgit/awtui/AwtCredentialsProvider.java
index 0403957..729f4cb 100644
--- a/org.eclipse.jgit.ui/src/org/eclipse/jgit/awtui/AwtCredentialsProvider.java
+++ b/org.eclipse.jgit.ui/src/org/eclipse/jgit/awtui/AwtCredentialsProvider.java
@@ -43,13 +43,11 @@
 		CredentialsProvider.setDefault(cp);
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public boolean isInteractive() {
 		return true;
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public boolean supports(CredentialItem... items) {
 		for (CredentialItem i : items) {
@@ -71,7 +69,6 @@
 		return true;
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public boolean get(URIish uri, CredentialItem... items)
 			throws UnsupportedCredentialItem {
diff --git a/org.eclipse.jgit.ui/src/org/eclipse/jgit/awtui/CommitGraphPane.java b/org.eclipse.jgit.ui/src/org/eclipse/jgit/awtui/CommitGraphPane.java
index dcf3c1d..a266a2f 100644
--- a/org.eclipse.jgit.ui/src/org/eclipse/jgit/awtui/CommitGraphPane.java
+++ b/org.eclipse.jgit.ui/src/org/eclipse/jgit/awtui/CommitGraphPane.java
@@ -80,7 +80,6 @@
 		return allCommits;
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public void setModel(TableModel dataModel) {
 		if (dataModel != null && !(dataModel instanceof CommitTableModel))
@@ -88,7 +87,6 @@
 		super.setModel(dataModel);
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	protected TableModel createDefaultDataModel() {
 		return new CommitTableModel();
diff --git a/org.eclipse.jgit/.settings/.api_filters b/org.eclipse.jgit/.settings/.api_filters
index a6aff1b..277e9ce 100644
--- a/org.eclipse.jgit/.settings/.api_filters
+++ b/org.eclipse.jgit/.settings/.api_filters
@@ -16,29 +16,9 @@
             </message_arguments>
         </filter>
     </resource>
-    <resource path="src/org/eclipse/jgit/errors/PackMismatchException.java" type="org.eclipse.jgit.errors.PackMismatchException">
-        <filter id="1142947843">
-            <message_arguments>
-                <message_argument value="5.9.1"/>
-                <message_argument value="isPermanent()"/>
-            </message_arguments>
-        </filter>
-        <filter id="1142947843">
-            <message_arguments>
-                <message_argument value="5.9.1"/>
-                <message_argument value="setPermanent(boolean)"/>
-            </message_arguments>
-        </filter>
-    </resource>
     <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_SKIPHASH"/>
-            </message_arguments>
-        </filter>
-        <filter id="1142947843">
-            <message_arguments>
                 <message_argument value="5.13.3"/>
                 <message_argument value="CONFIG_KEY_PACK_KEPT_OBJECTS"/>
             </message_arguments>
@@ -50,6 +30,20 @@
             </message_arguments>
         </filter>
     </resource>
+    <resource path="src/org/eclipse/jgit/lib/Constants.java" type="org.eclipse.jgit.lib.Constants">
+        <filter id="388100214">
+            <message_arguments>
+                <message_argument value="org.eclipse.jgit.lib.Constants"/>
+                <message_argument value="COMMIT_GENERATION_NOT_COMPUTED"/>
+            </message_arguments>
+        </filter>
+        <filter id="388100214">
+            <message_arguments>
+                <message_argument value="org.eclipse.jgit.lib.Constants"/>
+                <message_argument value="COMMIT_GENERATION_UNKNOWN"/>
+            </message_arguments>
+        </filter>
+    </resource>
     <resource path="src/org/eclipse/jgit/lib/FileModeCache.java" type="org.eclipse.jgit.lib.FileModeCache">
         <filter id="1109393411">
             <message_arguments>
@@ -58,14 +52,6 @@
             </message_arguments>
         </filter>
     </resource>
-    <resource path="src/org/eclipse/jgit/revwalk/RevCommit.java" type="org.eclipse.jgit.revwalk.RevCommit">
-        <filter id="1193279491">
-            <message_arguments>
-                <message_argument value="6.5.1"/>
-                <message_argument value="buffer"/>
-            </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>
@@ -73,12 +59,6 @@
                 <message_argument value="DEFAULT_PACK_KEPT_OBJECTS"/>
             </message_arguments>
         </filter>
-        <filter id="336658481">
-            <message_arguments>
-                <message_argument value="org.eclipse.jgit.storage.pack.PackConfig"/>
-                <message_argument value="DEFAULT_WRITE_REVERSE_INDEX"/>
-            </message_arguments>
-        </filter>
         <filter id="1142947843">
             <message_arguments>
                 <message_argument value="5.13.3"/>
diff --git a/org.eclipse.jgit/.settings/org.eclipse.jdt.core.prefs b/org.eclipse.jgit/.settings/org.eclipse.jdt.core.prefs
index 2abe952..b27b6c3 100644
--- a/org.eclipse.jgit/.settings/org.eclipse.jdt.core.prefs
+++ b/org.eclipse.jgit/.settings/org.eclipse.jdt.core.prefs
@@ -52,7 +52,7 @@
 org.eclipse.jdt.core.compiler.problem.missingJavadocComments=error
 org.eclipse.jdt.core.compiler.problem.missingJavadocCommentsOverriding=disabled
 org.eclipse.jdt.core.compiler.problem.missingJavadocCommentsVisibility=protected
-org.eclipse.jdt.core.compiler.problem.missingJavadocTagDescription=return_tag
+org.eclipse.jdt.core.compiler.problem.missingJavadocTagDescription=all_standard_tags
 org.eclipse.jdt.core.compiler.problem.missingJavadocTags=error
 org.eclipse.jdt.core.compiler.problem.missingJavadocTagsMethodTypeParameters=disabled
 org.eclipse.jdt.core.compiler.problem.missingJavadocTagsOverriding=disabled
diff --git a/org.eclipse.jgit/BUILD b/org.eclipse.jgit/BUILD
index e806e7d..1e9b770 100644
--- a/org.eclipse.jgit/BUILD
+++ b/org.eclipse.jgit/BUILD
@@ -20,6 +20,7 @@
     resources = RESOURCES,
     deps = [
         ":insecure_cipher_factory",
+        "//lib:commons-codec",
         "//lib:javaewah",
         "//lib:slf4j-api",
     ],
diff --git a/org.eclipse.jgit/META-INF/MANIFEST.MF b/org.eclipse.jgit/META-INF/MANIFEST.MF
index bf40cfd..6f0debd 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.6.2.qualifier
+Bundle-Version: 6.7.1.qualifier
 Bundle-Localization: plugin
 Bundle-Vendor: %Bundle-Vendor
 Eclipse-ExtensibleAPI: true
-Export-Package: org.eclipse.jgit.annotations;version="6.6.2",
- org.eclipse.jgit.api;version="6.6.2";
+Export-Package: org.eclipse.jgit.annotations;version="6.7.1",
+ org.eclipse.jgit.api;version="6.7.1";
   uses:="org.eclipse.jgit.transport,
    org.eclipse.jgit.notes,
    org.eclipse.jgit.dircache,
@@ -23,18 +23,18 @@
    org.eclipse.jgit.revwalk.filter,
    org.eclipse.jgit.blame,
    org.eclipse.jgit.merge",
- org.eclipse.jgit.api.errors;version="6.6.2";
+ org.eclipse.jgit.api.errors;version="6.7.1";
   uses:="org.eclipse.jgit.lib,
    org.eclipse.jgit.errors",
- org.eclipse.jgit.attributes;version="6.6.2";
+ org.eclipse.jgit.attributes;version="6.7.1";
   uses:="org.eclipse.jgit.lib,
    org.eclipse.jgit.treewalk",
- org.eclipse.jgit.blame;version="6.6.2";
+ org.eclipse.jgit.blame;version="6.7.1";
   uses:="org.eclipse.jgit.lib,
    org.eclipse.jgit.revwalk,
    org.eclipse.jgit.treewalk.filter,
    org.eclipse.jgit.diff",
- org.eclipse.jgit.diff;version="6.6.2";
+ org.eclipse.jgit.diff;version="6.7.1";
   uses:="org.eclipse.jgit.lib,
    org.eclipse.jgit.attributes,
    org.eclipse.jgit.revwalk,
@@ -42,53 +42,53 @@
    org.eclipse.jgit.treewalk.filter,
    org.eclipse.jgit.treewalk,
    org.eclipse.jgit.util",
- org.eclipse.jgit.dircache;version="6.6.2";
+ org.eclipse.jgit.dircache;version="6.7.1";
   uses:="org.eclipse.jgit.events,
    org.eclipse.jgit.lib,
    org.eclipse.jgit.attributes,
    org.eclipse.jgit.treewalk,
    org.eclipse.jgit.util",
- org.eclipse.jgit.errors;version="6.6.2";
+ org.eclipse.jgit.errors;version="6.7.1";
   uses:="org.eclipse.jgit.transport,
    org.eclipse.jgit.dircache,
    org.eclipse.jgit.lib,
    org.eclipse.jgit.internal.storage.pack",
- org.eclipse.jgit.events;version="6.6.2";
+ org.eclipse.jgit.events;version="6.7.1";
   uses:="org.eclipse.jgit.lib",
- org.eclipse.jgit.fnmatch;version="6.6.2",
- org.eclipse.jgit.gitrepo;version="6.6.2";
+ org.eclipse.jgit.fnmatch;version="6.7.1",
+ org.eclipse.jgit.gitrepo;version="6.7.1";
   uses:="org.xml.sax.helpers,
    org.eclipse.jgit.api,
    org.eclipse.jgit.lib,
    org.eclipse.jgit.revwalk,
    org.xml.sax",
- org.eclipse.jgit.gitrepo.internal;version="6.6.2";x-internal:=true,
- org.eclipse.jgit.hooks;version="6.6.2";uses:="org.eclipse.jgit.lib",
- org.eclipse.jgit.ignore;version="6.6.2",
- org.eclipse.jgit.ignore.internal;version="6.6.2";
+ org.eclipse.jgit.gitrepo.internal;version="6.7.1";x-internal:=true,
+ org.eclipse.jgit.hooks;version="6.7.1";uses:="org.eclipse.jgit.lib",
+ org.eclipse.jgit.ignore;version="6.7.1",
+ org.eclipse.jgit.ignore.internal;version="6.7.1";
   x-friends:="org.eclipse.jgit.test",
- org.eclipse.jgit.internal;version="6.6.2";
+ org.eclipse.jgit.internal;version="6.7.1";
   x-friends:="org.eclipse.jgit.test,
    org.eclipse.jgit.http.test",
- org.eclipse.jgit.internal.diff;version="6.6.2";
+ org.eclipse.jgit.internal.diff;version="6.7.1";
   x-friends:="org.eclipse.jgit.test",
- org.eclipse.jgit.internal.diffmergetool;version="6.6.2";
+ org.eclipse.jgit.internal.diffmergetool;version="6.7.1";
   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.6.2";
+ org.eclipse.jgit.internal.fsck;version="6.7.1";
   x-friends:="org.eclipse.jgit.test",
- org.eclipse.jgit.internal.revwalk;version="6.6.2";
+ org.eclipse.jgit.internal.revwalk;version="6.7.1";
   x-friends:="org.eclipse.jgit.test",
- org.eclipse.jgit.internal.storage.commitgraph;version="6.6.2";
+ org.eclipse.jgit.internal.storage.commitgraph;version="6.7.1";
   x-friends:="org.eclipse.jgit.test",
- org.eclipse.jgit.internal.storage.dfs;version="6.6.2";
+ org.eclipse.jgit.internal.storage.dfs;version="6.7.1";
   x-friends:="org.eclipse.jgit.test,
    org.eclipse.jgit.http.server,
    org.eclipse.jgit.http.test,
    org.eclipse.jgit.lfs.test",
- org.eclipse.jgit.internal.storage.file;version="6.6.2";
+ org.eclipse.jgit.internal.storage.file;version="6.7.1";
   x-friends:="org.eclipse.jgit.test,
    org.eclipse.jgit.junit,
    org.eclipse.jgit.junit.http,
@@ -97,34 +97,35 @@
    org.eclipse.jgit.pgm,
    org.eclipse.jgit.pgm.test,
    org.eclipse.jgit.ssh.apache",
- org.eclipse.jgit.internal.storage.io;version="6.6.2";
+ org.eclipse.jgit.internal.storage.io;version="6.7.1";
   x-friends:="org.eclipse.jgit.junit,
    org.eclipse.jgit.test,
    org.eclipse.jgit.pgm",
- org.eclipse.jgit.internal.storage.memory;version="6.6.2";
+ org.eclipse.jgit.internal.storage.memory;version="6.7.1";
   x-friends:="org.eclipse.jgit.test",
- org.eclipse.jgit.internal.storage.pack;version="6.6.2";
+ org.eclipse.jgit.internal.storage.pack;version="6.7.1";
   x-friends:="org.eclipse.jgit.junit,
    org.eclipse.jgit.test,
    org.eclipse.jgit.pgm",
- org.eclipse.jgit.internal.storage.reftable;version="6.6.2";
+ org.eclipse.jgit.internal.storage.reftable;version="6.7.1";
   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.6.2";x-internal:=true,
- org.eclipse.jgit.internal.transport.connectivity;version="6.6.2";
+ org.eclipse.jgit.internal.submodule;version="6.7.1";x-internal:=true,
+ org.eclipse.jgit.internal.transport.connectivity;version="6.7.1";
   x-friends:="org.eclipse.jgit.test",
- org.eclipse.jgit.internal.transport.http;version="6.6.2";
+ org.eclipse.jgit.internal.transport.http;version="6.7.1";
   x-friends:="org.eclipse.jgit.test",
- org.eclipse.jgit.internal.transport.parser;version="6.6.2";
+ org.eclipse.jgit.internal.transport.parser;version="6.7.1";
   x-friends:="org.eclipse.jgit.http.server,
    org.eclipse.jgit.test",
- org.eclipse.jgit.internal.transport.ssh;version="6.6.2";
+ org.eclipse.jgit.internal.transport.ssh;version="6.7.1";
   x-friends:="org.eclipse.jgit.ssh.apache,
    org.eclipse.jgit.ssh.jsch,
    org.eclipse.jgit.test",
- org.eclipse.jgit.lib;version="6.6.2";
+ org.eclipse.jgit.internal.util;version="6.7.1";x-internal:=true,
+ org.eclipse.jgit.lib;version="6.7.1";
   uses:="org.eclipse.jgit.transport,
    org.eclipse.jgit.util.sha1,
    org.eclipse.jgit.dircache,
@@ -138,12 +139,12 @@
    org.eclipse.jgit.util,
    org.eclipse.jgit.submodule,
    org.eclipse.jgit.util.time",
- org.eclipse.jgit.lib.internal;version="6.6.2";
+ org.eclipse.jgit.lib.internal;version="6.7.1";
   x-friends:="org.eclipse.jgit.test,
    org.eclipse.jgit.pgm,
    org.eclipse.egit.ui",
- org.eclipse.jgit.logging;version="6.6.2",
- org.eclipse.jgit.merge;version="6.6.2";
+ org.eclipse.jgit.logging;version="6.7.1",
+ org.eclipse.jgit.merge;version="6.7.1";
   uses:="org.eclipse.jgit.dircache,
    org.eclipse.jgit.lib,
    org.eclipse.jgit.revwalk,
@@ -152,40 +153,40 @@
    org.eclipse.jgit.util,
    org.eclipse.jgit.api,
    org.eclipse.jgit.attributes",
- org.eclipse.jgit.nls;version="6.6.2",
- org.eclipse.jgit.notes;version="6.6.2";
+ org.eclipse.jgit.nls;version="6.7.1",
+ org.eclipse.jgit.notes;version="6.7.1";
   uses:="org.eclipse.jgit.lib,
    org.eclipse.jgit.revwalk,
    org.eclipse.jgit.treewalk,
    org.eclipse.jgit.merge",
- org.eclipse.jgit.patch;version="6.6.2";
+ org.eclipse.jgit.patch;version="6.7.1";
   uses:="org.eclipse.jgit.lib,
    org.eclipse.jgit.diff",
- org.eclipse.jgit.revplot;version="6.6.2";
+ org.eclipse.jgit.revplot;version="6.7.1";
   uses:="org.eclipse.jgit.lib,
    org.eclipse.jgit.revwalk",
- org.eclipse.jgit.revwalk;version="6.6.2";
+ org.eclipse.jgit.revwalk;version="6.7.1";
   uses:="org.eclipse.jgit.lib,
    org.eclipse.jgit.diff,
    org.eclipse.jgit.treewalk.filter,
    org.eclipse.jgit.revwalk.filter,
    org.eclipse.jgit.treewalk",
- org.eclipse.jgit.revwalk.filter;version="6.6.2";
+ org.eclipse.jgit.revwalk.filter;version="6.7.1";
   uses:="org.eclipse.jgit.revwalk,
    org.eclipse.jgit.lib,
    org.eclipse.jgit.util",
- org.eclipse.jgit.storage.file;version="6.6.2";
+ org.eclipse.jgit.storage.file;version="6.7.1";
   uses:="org.eclipse.jgit.lib,
    org.eclipse.jgit.util",
- org.eclipse.jgit.storage.pack;version="6.6.2";
+ org.eclipse.jgit.storage.pack;version="6.7.1";
   uses:="org.eclipse.jgit.lib",
- org.eclipse.jgit.submodule;version="6.6.2";
+ org.eclipse.jgit.submodule;version="6.7.1";
   uses:="org.eclipse.jgit.lib,
    org.eclipse.jgit.diff,
    org.eclipse.jgit.treewalk.filter,
    org.eclipse.jgit.treewalk,
    org.eclipse.jgit.util",
- org.eclipse.jgit.transport;version="6.6.2";
+ org.eclipse.jgit.transport;version="6.7.1";
   uses:="javax.crypto,
    org.eclipse.jgit.util.io,
    org.eclipse.jgit.lib,
@@ -198,21 +199,21 @@
    org.eclipse.jgit.transport.resolver,
    org.eclipse.jgit.storage.pack,
    org.eclipse.jgit.errors",
- org.eclipse.jgit.transport.http;version="6.6.2";
+ org.eclipse.jgit.transport.http;version="6.7.1";
   uses:="javax.net.ssl",
- org.eclipse.jgit.transport.resolver;version="6.6.2";
+ org.eclipse.jgit.transport.resolver;version="6.7.1";
   uses:="org.eclipse.jgit.transport,
    org.eclipse.jgit.lib",
- org.eclipse.jgit.treewalk;version="6.6.2";
+ org.eclipse.jgit.treewalk;version="6.7.1";
   uses:="org.eclipse.jgit.dircache,
    org.eclipse.jgit.lib,
    org.eclipse.jgit.attributes,
    org.eclipse.jgit.revwalk,
    org.eclipse.jgit.treewalk.filter,
    org.eclipse.jgit.util",
- org.eclipse.jgit.treewalk.filter;version="6.6.2";
+ org.eclipse.jgit.treewalk.filter;version="6.7.1";
   uses:="org.eclipse.jgit.treewalk",
- org.eclipse.jgit.util;version="6.6.2";
+ org.eclipse.jgit.util;version="6.7.1";
   uses:="org.eclipse.jgit.transport,
    org.eclipse.jgit.hooks,
    org.eclipse.jgit.revwalk,
@@ -225,17 +226,18 @@
    org.eclipse.jgit.treewalk,
    javax.net.ssl,
    org.eclipse.jgit.util.time",
- org.eclipse.jgit.util.io;version="6.6.2";
+ org.eclipse.jgit.util.io;version="6.7.1";
   uses:="org.eclipse.jgit.attributes,
    org.eclipse.jgit.lib,
    org.eclipse.jgit.treewalk",
- org.eclipse.jgit.util.sha1;version="6.6.2",
- org.eclipse.jgit.util.time;version="6.6.2"
+ org.eclipse.jgit.util.sha1;version="6.7.1",
+ org.eclipse.jgit.util.time;version="6.7.1"
 Bundle-RequiredExecutionEnvironment: JavaSE-11
 Import-Package: com.googlecode.javaewah;version="[1.1.6,2.0.0)",
  javax.crypto,
  javax.management,
  javax.net.ssl,
+ org.apache.commons.codec.digest;version="1.15.0",
  org.slf4j;version="[1.7.0,2.0.0)",
  org.xml.sax,
  org.xml.sax.helpers
diff --git a/org.eclipse.jgit/META-INF/SOURCE-MANIFEST.MF b/org.eclipse.jgit/META-INF/SOURCE-MANIFEST.MF
index 152ab2a..5c5f67e 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.6.2.qualifier
-Eclipse-SourceBundle: org.eclipse.jgit;version="6.6.2.qualifier";roots="."
+Bundle-Version: 6.7.1.qualifier
+Eclipse-SourceBundle: org.eclipse.jgit;version="6.7.1.qualifier";roots="."
diff --git a/org.eclipse.jgit/pom.xml b/org.eclipse.jgit/pom.xml
index 4d7336d..eb9e237 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.6.2-SNAPSHOT</version>
+    <version>6.7.1-SNAPSHOT</version>
   </parent>
 
   <artifactId>org.eclipse.jgit</artifactId>
@@ -46,6 +46,12 @@
       <artifactId>slf4j-api</artifactId>
     </dependency>
 
+    <dependency>
+      <groupId>commons-codec</groupId>
+      <artifactId>commons-codec</artifactId>
+      <version>1.16.0</version>
+    </dependency>
+
   </dependencies>
 
   <build>
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 45a6794..fe5fd4c 100644
--- a/org.eclipse.jgit/resources/org/eclipse/jgit/internal/JGitText.properties
+++ b/org.eclipse.jgit/resources/org/eclipse/jgit/internal/JGitText.properties
@@ -225,6 +225,7 @@
 corruptObjectTruncatedInName=truncated in name
 corruptObjectTruncatedInObjectId=truncated in object id
 corruptObjectZeroId=entry points to null SHA-1
+corruptReverseIndexChecksumIncorrect=Reverse index checksum incorrect: written as {0} but digest was {1}
 corruptUseCnt=close() called when useCnt is already zero for {0}
 couldNotGetAdvertisedRef=Remote {0} did not advertise Ref for branch {1}. This Ref may not exist in the remote or may be hidden by permission settings.
 couldNotGetRepoStatistics=Could not get repository statistics
@@ -569,7 +570,7 @@
 operationCanceled=Operation {0} was canceled
 outputHasAlreadyBeenStarted=Output has already been started.
 overflowedReftableBlock=Overflowed reftable block
-packChecksumMismatch=Pack checksum mismatch detected for pack file {0}: .pack has {1} whilst .idx has {2}
+packChecksumMismatch=Pack checksum mismatch detected for pack file {0}: {1} has {2} whilst {3} has {4}
 packCorruptedWhileWritingToFilesystem=Pack corrupted while writing to filesystem
 packedRefsHandleIsStale=packed-refs handle is stale, {0}. retry
 packetSizeMustBeAtLeast=packet size {0} must be >= {1}
@@ -692,6 +693,7 @@
 saveFileStoreAttributesFailed=Saving measured FileStore attributes to user config failed
 searchForReuse=Finding sources
 searchForReuseTimeout=Search for reuse timed out after {0} seconds
+unsupportedObjectIdVersion=Object id version {0} is not supported
 searchForSizes=Getting sizes
 secondsAgo={0} seconds ago
 selectingCommits=Selecting commits
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/api/AddNoteCommand.java b/org.eclipse.jgit/src/org/eclipse/jgit/api/AddNoteCommand.java
index ceb17fb..8805ea2 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/api/AddNoteCommand.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/api/AddNoteCommand.java
@@ -51,7 +51,6 @@
 		super(repo);
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public Note call() throws GitAPIException {
 		checkCallable();
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/api/ApplyCommand.java b/org.eclipse.jgit/src/org/eclipse/jgit/api/ApplyCommand.java
index e612924..df0f616 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/api/ApplyCommand.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/api/ApplyCommand.java
@@ -37,11 +37,12 @@
 	/**
 	 * Constructs the command.
 	 *
-	 * @param local
+	 * @param repo
+	 *            the repository this command will be used on
 	 */
-	ApplyCommand(Repository local) {
-		super(local);
-		if (local == null) {
+	ApplyCommand(Repository repo) {
+		super(repo);
+		if (repo == null) {
 			throw new NullPointerException(JGitText.get().repositoryIsRequired);
 		}
 	}
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/api/ArchiveCommand.java b/org.eclipse.jgit/src/org/eclipse/jgit/api/ArchiveCommand.java
index fdf8b80..4efc6a7 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/api/ArchiveCommand.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/api/ArchiveCommand.java
@@ -389,7 +389,6 @@
 		}
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public OutputStream call() throws GitAPIException {
 		checkCallable();
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/api/CheckoutCommand.java b/org.eclipse.jgit/src/org/eclipse/jgit/api/CheckoutCommand.java
index 8edae5a..2bc14ff 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/api/CheckoutCommand.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/api/CheckoutCommand.java
@@ -167,7 +167,6 @@
 		this.paths = new LinkedList<>();
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public Ref call() throws GitAPIException, RefAlreadyExistsException,
 			RefNotFoundException, InvalidRefNameException,
@@ -407,7 +406,9 @@
 	 *
 	 * @return this instance
 	 * @throws java.io.IOException
+	 *             if an IO error occurred
 	 * @throws org.eclipse.jgit.api.errors.RefNotFoundException
+	 *             if {@code Ref} couldn't be resolved
 	 */
 	protected CheckoutCommand checkoutPaths() throws IOException,
 			RefNotFoundException {
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/api/CherryPickCommand.java b/org.eclipse.jgit/src/org/eclipse/jgit/api/CherryPickCommand.java
index 5f8c2b7..38e795b 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/api/CherryPickCommand.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/api/CherryPickCommand.java
@@ -399,7 +399,6 @@
 		return headName;
 	}
 
-	/** {@inheritDoc} */
 	@SuppressWarnings("nls")
 	@Override
 	public String toString() {
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/api/CleanCommand.java b/org.eclipse.jgit/src/org/eclipse/jgit/api/CleanCommand.java
index 36ca97d..a4a0c49 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/api/CleanCommand.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/api/CleanCommand.java
@@ -113,24 +113,25 @@
 	}
 
 	/**
-	 * When dryRun is false, deletes the specified path from disk. If dryRun
-	 * is true, no paths are actually deleted. In both cases, the paths that
-	 * would have been deleted are added to inFiles and returned.
+	 * When dryRun is false, deletes the specified path from disk. If dryRun is
+	 * true, no paths are actually deleted. In both cases, the paths that would
+	 * have been deleted are added to inFiles and returned.
 	 *
 	 * Paths that are directories are recursively deleted when
-	 * {@link #directories} is true.
-	 * Paths that are git repositories are recursively deleted when
-	 * {@link #directories} and {@link #force} are both true.
+	 * {@link #directories} is true. Paths that are git repositories are
+	 * recursively deleted when {@link #directories} and {@link #force} are both
+	 * true.
 	 *
 	 * @param path
-	 * 			The path to be cleaned
+	 *            The path to be cleaned
 	 * @param inFiles
-	 * 			A set of strings representing the files that have been cleaned
-	 * 			already, the path to be cleaned will be added to this set
-	 * 			before being returned.
+	 *            A set of strings representing the files that have been cleaned
+	 *            already, the path to be cleaned will be added to this set
+	 *            before being returned.
 	 *
 	 * @return a set of strings with the cleaned path added to it
 	 * @throws IOException
+	 *             if an IO error occurred
 	 */
 	private Set<String> cleanPath(String path, Set<String> inFiles)
 			throws IOException {
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/api/CreateBranchCommand.java b/org.eclipse.jgit/src/org/eclipse/jgit/api/CreateBranchCommand.java
index 9e77dd7..e1efb86 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/api/CreateBranchCommand.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/api/CreateBranchCommand.java
@@ -82,7 +82,6 @@
 		super(repo);
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public Ref call() throws GitAPIException, RefAlreadyExistsException,
 			RefNotFoundException, InvalidRefNameException {
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/api/DeleteBranchCommand.java b/org.eclipse.jgit/src/org/eclipse/jgit/api/DeleteBranchCommand.java
index 3d3ee63..f1b5d62 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/api/DeleteBranchCommand.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/api/DeleteBranchCommand.java
@@ -61,7 +61,6 @@
 		super(repo);
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public List<String> call() throws GitAPIException,
 			NotMergedException, CannotDeleteCurrentBranchException {
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/api/DeleteTagCommand.java b/org.eclipse.jgit/src/org/eclipse/jgit/api/DeleteTagCommand.java
index 64d0d94..92d88aa 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/api/DeleteTagCommand.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/api/DeleteTagCommand.java
@@ -48,7 +48,6 @@
 		super(repo);
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public List<String> call() throws GitAPIException {
 		checkCallable();
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/api/GarbageCollectCommand.java b/org.eclipse.jgit/src/org/eclipse/jgit/api/GarbageCollectCommand.java
index ab8cd18..88d7e91 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/api/GarbageCollectCommand.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/api/GarbageCollectCommand.java
@@ -178,7 +178,6 @@
 		return this;
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public Properties call() throws GitAPIException {
 		checkCallable();
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/api/Git.java b/org.eclipse.jgit/src/org/eclipse/jgit/api/Git.java
index 3b3e10e..3dc53ec 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/api/Git.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/api/Git.java
@@ -68,6 +68,7 @@
 	 * @return a {@link org.eclipse.jgit.api.Git} object for the existing git
 	 *         repository
 	 * @throws java.io.IOException
+	 *             if an IO error occurred
 	 */
 	public static Git open(File dir) throws IOException {
 		return open(dir, FS.DETECTED);
@@ -84,6 +85,7 @@
 	 * @return a {@link org.eclipse.jgit.api.Git} object for the existing git
 	 *         repository. Closing this instance will close the repo.
 	 * @throws java.io.IOException
+	 *             if an IO error occurred
 	 */
 	public static Git open(File dir, FS fs) throws IOException {
 		RepositoryCache.FileKey key;
@@ -792,7 +794,6 @@
 		return repo;
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public String toString() {
 		return "Git[" + repo + "]"; //$NON-NLS-1$//$NON-NLS-2$
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/api/ListBranchCommand.java b/org.eclipse.jgit/src/org/eclipse/jgit/api/ListBranchCommand.java
index 4b7445f..e3c3c89 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/api/ListBranchCommand.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/api/ListBranchCommand.java
@@ -73,7 +73,6 @@
 		super(repo);
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public List<Ref> call() throws GitAPIException {
 		checkCallable();
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/api/ListNotesCommand.java b/org.eclipse.jgit/src/org/eclipse/jgit/api/ListNotesCommand.java
index 34955e8..9eb5286 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/api/ListNotesCommand.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/api/ListNotesCommand.java
@@ -44,7 +44,6 @@
 		super(repo);
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public List<Note> call() throws GitAPIException {
 		checkCallable();
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/api/ListTagCommand.java b/org.eclipse.jgit/src/org/eclipse/jgit/api/ListTagCommand.java
index 27a5288..9a4a822 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/api/ListTagCommand.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/api/ListTagCommand.java
@@ -54,8 +54,11 @@
 	 *            the specified commit
 	 * @return this command
 	 * @throws IOException
+	 *             if an IO error occurred
 	 * @throws IncorrectObjectTypeException
+	 *             if commit has an incorrect object type
 	 * @throws MissingObjectException
+	 *             if the commit is missing
 	 *
 	 * @since 6.6
 	 */
@@ -67,7 +70,6 @@
 		return this;
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public List<Ref> call() throws GitAPIException {
 		checkCallable();
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/api/LogCommand.java b/org.eclipse.jgit/src/org/eclipse/jgit/api/LogCommand.java
index fa40d93..555e351 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/api/LogCommand.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/api/LogCommand.java
@@ -53,13 +53,11 @@
  * </pre>
  * <p>
  *
- * <p>
  * Get commits only for a specific file:
  *
  * <pre>
  * git.log().add(head).addPath(&quot;dir/filename.txt&quot;).call();
  * </pre>
- * <p>
  *
  * @see <a href="http://www.kernel.org/pub/software/scm/git/docs/git-log.html"
  *      >Git documentation about Log</a>
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/api/MergeResult.java b/org.eclipse.jgit/src/org/eclipse/jgit/api/MergeResult.java
index 7347f63..ecc3b40 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/api/MergeResult.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/api/MergeResult.java
@@ -364,7 +364,6 @@
 		return base;
 	}
 
-	/** {@inheritDoc} */
 	@SuppressWarnings("nls")
 	@Override
 	public String toString() {
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/api/NameRevCommand.java b/org.eclipse.jgit/src/org/eclipse/jgit/api/NameRevCommand.java
index e6ab1e6..cd7c4e9 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/api/NameRevCommand.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/api/NameRevCommand.java
@@ -102,7 +102,6 @@
 		};
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public Map<ObjectId, String> call() throws GitAPIException {
 		try {
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/api/PullResult.java b/org.eclipse.jgit/src/org/eclipse/jgit/api/PullResult.java
index cbb9cc2..fdc7f3f 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/api/PullResult.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/api/PullResult.java
@@ -89,7 +89,6 @@
 		return true;
 	}
 
-	/** {@inheritDoc} */
 	@SuppressWarnings("nls")
 	@Override
 	public String toString() {
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/api/RebaseCommand.java b/org.eclipse.jgit/src/org/eclipse/jgit/api/RebaseCommand.java
index 19fd3bb..859bf93 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/api/RebaseCommand.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/api/RebaseCommand.java
@@ -86,7 +86,6 @@
  * supported options and arguments of this command and a {@link #call()} method
  * to finally execute the command. Each instance of this class should only be
  * used for one invocation of the command (means: one call to {@link #call()})
- * <p>
  *
  * @see <a
  *      href="http://www.kernel.org/pub/software/scm/git/docs/git-rebase.html"
@@ -1000,7 +999,9 @@
 	/**
 	 * @return the commit if we had to do a commit, otherwise null
 	 * @throws GitAPIException
+	 *             if JGit API failed
 	 * @throws IOException
+	 *             if an IO error occurred
 	 */
 	private RevCommit continueRebase() throws GitAPIException, IOException {
 		// if there are still conflicts, we throw a specific Exception
@@ -1102,7 +1103,9 @@
 	 * that can not be parsed as steps
 	 *
 	 * @param numSteps
+	 *            number of steps to remove
 	 * @throws IOException
+	 *             if an IO error occurred
 	 */
 	private void popSteps(int numSteps) throws IOException {
 		if (numSteps == 0)
@@ -1297,7 +1300,9 @@
 	 *            if we can fast-forward to.
 	 * @return the new head, or null
 	 * @throws java.io.IOException
+	 *             if an IO error occurred
 	 * @throws org.eclipse.jgit.api.errors.GitAPIException
+	 *             if a JGit API exception occurred
 	 */
 	public RevCommit tryFastForward(RevCommit newCommit) throws IOException,
 			GitAPIException {
@@ -1548,6 +1553,7 @@
 	 *            the name of the upstream branch
 	 * @return {@code this}
 	 * @throws org.eclipse.jgit.api.errors.RefNotFoundException
+	 *             if {@code upstream} Ref couldn't be resolved
 	 */
 	public RebaseCommand setUpstream(String upstream)
 			throws RefNotFoundException {
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/api/RebaseResult.java b/org.eclipse.jgit/src/org/eclipse/jgit/api/RebaseResult.java
index 826ea51..83c0dc2 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/api/RebaseResult.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/api/RebaseResult.java
@@ -194,6 +194,7 @@
 	 * Create <code>RebaseResult</code>
 	 *
 	 * @param status
+	 *            the overall rebase status
 	 * @param commit
 	 *            current commit
 	 * @return the RebaseResult
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/api/RemoveNoteCommand.java b/org.eclipse.jgit/src/org/eclipse/jgit/api/RemoveNoteCommand.java
index f4b60ad..c65cbf160 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/api/RemoveNoteCommand.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/api/RemoveNoteCommand.java
@@ -47,7 +47,6 @@
 		super(repo);
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public Note call() throws GitAPIException {
 		checkCallable();
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/api/RenameBranchCommand.java b/org.eclipse.jgit/src/org/eclipse/jgit/api/RenameBranchCommand.java
index 922cb53..029f9d0 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/api/RenameBranchCommand.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/api/RenameBranchCommand.java
@@ -55,7 +55,6 @@
 		super(repo);
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public Ref call() throws GitAPIException, RefNotFoundException, InvalidRefNameException,
 			RefAlreadyExistsException, DetachedHeadException {
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/api/ResetCommand.java b/org.eclipse.jgit/src/org/eclipse/jgit/api/ResetCommand.java
index 87b4acb..225c999 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/api/ResetCommand.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/api/ResetCommand.java
@@ -436,7 +436,6 @@
 		repo.writeMergeCommitMsg(null);
 	}
 
-	/** {@inheritDoc} */
 	@SuppressWarnings("nls")
 	@Override
 	public String toString() {
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/api/ShowNoteCommand.java b/org.eclipse.jgit/src/org/eclipse/jgit/api/ShowNoteCommand.java
index f64cb6b..7bb9de0 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/api/ShowNoteCommand.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/api/ShowNoteCommand.java
@@ -44,7 +44,6 @@
 		super(repo);
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public Note call() throws GitAPIException {
 		checkCallable();
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/api/StashListCommand.java b/org.eclipse.jgit/src/org/eclipse/jgit/api/StashListCommand.java
index 8171c4c..828a302 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/api/StashListCommand.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/api/StashListCommand.java
@@ -43,7 +43,6 @@
 		super(repo);
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public Collection<RevCommit> call() throws GitAPIException,
 			InvalidRefNameException {
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/api/SubmoduleAddCommand.java b/org.eclipse.jgit/src/org/eclipse/jgit/api/SubmoduleAddCommand.java
index 606d567..8fb5d60 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/api/SubmoduleAddCommand.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/api/SubmoduleAddCommand.java
@@ -66,6 +66,7 @@
 	 * Set the submodule name
 	 *
 	 * @param name
+	 *            name of the submodule
 	 * @return this command
 	 * @since 5.1
 	 */
@@ -117,6 +118,7 @@
 	 *
 	 * @return true if submodule exists in index, false otherwise
 	 * @throws java.io.IOException
+	 *             if an IO error occurred
 	 */
 	protected boolean submoduleExists() throws IOException {
 		TreeFilter filter = PathFilter.create(path);
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/api/SubmoduleDeinitCommand.java b/org.eclipse.jgit/src/org/eclipse/jgit/api/SubmoduleDeinitCommand.java
index f4b8ac2..0aa1515 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/api/SubmoduleDeinitCommand.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/api/SubmoduleDeinitCommand.java
@@ -61,6 +61,7 @@
 	 * Constructor of SubmoduleDeinitCommand
 	 *
 	 * @param repo
+	 *            repository this command works on
 	 */
 	public SubmoduleDeinitCommand(Repository repo) {
 		super(repo);
@@ -69,7 +70,6 @@
 
 	/**
 	 * {@inheritDoc}
-	 * <p>
 	 *
 	 * @return the set of repositories successfully deinitialized.
 	 * @throws NoSuchSubmoduleException
@@ -135,6 +135,7 @@
 	 * @param path
 	 *            the path to clean
 	 * @throws IOException
+	 *             if an IO error occurred
 	 */
 	private void deinit(String path) throws IOException {
 		File dir = new File(repo.getWorkTree(), path);
@@ -157,10 +158,14 @@
 	 * the parent repo's index or HEAD.
 	 *
 	 * @param revWalk
+	 *            used to walk commit graph
 	 * @param path
+	 *            path of the submodule
 	 * @return status of the command
 	 * @throws GitAPIException
+	 *             if JGit API failed
 	 * @throws IOException
+	 *             if an IO error occurred
 	 */
 	private SubmoduleDeinitStatus checkDirty(RevWalk revWalk, String path)
 			throws GitAPIException, IOException {
@@ -216,6 +221,7 @@
 	 * @return {@code true} if path exists and is a submodule in index,
 	 *         {@code false} otherwise
 	 * @throws IOException
+	 *             if an IO error occurred
 	 */
 	private boolean submoduleExists(String path) throws IOException {
 		TreeFilter filter = PathFilter.create(path);
@@ -241,6 +247,7 @@
 	 * else it will refuse to do so.
 	 *
 	 * @param force
+	 *            execute the command forcefully if there are local modifications
 	 * @return {@code this}
 	 */
 	public SubmoduleDeinitCommand setForce(boolean force) {
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/api/SubmoduleDeinitResult.java b/org.eclipse.jgit/src/org/eclipse/jgit/api/SubmoduleDeinitResult.java
index 8129be4..b7d7b66 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/api/SubmoduleDeinitResult.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/api/SubmoduleDeinitResult.java
@@ -25,6 +25,7 @@
 	 * @param path
 	 *            path of the submodule
 	 * @param status
+	 *            effect of a SubmoduleDeinitCommand's execution
 	 */
 	public SubmoduleDeinitResult(String path,
 			SubmoduleDeinitCommand.SubmoduleDeinitStatus status) {
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/api/SubmoduleInitCommand.java b/org.eclipse.jgit/src/org/eclipse/jgit/api/SubmoduleInitCommand.java
index bdceaba..03b4a00 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/api/SubmoduleInitCommand.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/api/SubmoduleInitCommand.java
@@ -61,7 +61,6 @@
 		return this;
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public Collection<String> call() throws GitAPIException {
 		checkCallable();
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/api/SubmoduleStatusCommand.java b/org.eclipse.jgit/src/org/eclipse/jgit/api/SubmoduleStatusCommand.java
index 196ef7b..d5bc0dd 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/api/SubmoduleStatusCommand.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/api/SubmoduleStatusCommand.java
@@ -61,7 +61,6 @@
 		return this;
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public Map<String, SubmoduleStatus> call() throws GitAPIException {
 		checkCallable();
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/api/SubmoduleSyncCommand.java b/org.eclipse.jgit/src/org/eclipse/jgit/api/SubmoduleSyncCommand.java
index b319a1b..4f3e851 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/api/SubmoduleSyncCommand.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/api/SubmoduleSyncCommand.java
@@ -70,6 +70,7 @@
 	 *            a {@link org.eclipse.jgit.lib.Repository} object.
 	 * @return shortened branch name, null on failures
 	 * @throws java.io.IOException
+	 *             if an IO error occurred
 	 */
 	protected String getHeadBranch(Repository subRepo) throws IOException {
 		Ref head = subRepo.exactRef(Constants.HEAD);
@@ -79,7 +80,6 @@
 		return null;
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public Map<String, String> call() throws GitAPIException {
 		checkCallable();
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/api/TagCommand.java b/org.eclipse.jgit/src/org/eclipse/jgit/api/TagCommand.java
index 58c18b3..dd4ba10 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/api/TagCommand.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/api/TagCommand.java
@@ -51,13 +51,11 @@
  * </pre>
  * <p>
  *
- * <p>
  * Create a new unannotated tag for the current commit:
  *
  * <pre>
  * git.tag().setName(&quot;v1.0&quot;).setAnnotated(false).call();
  * </pre>
- * <p>
  *
  * @see <a href="http://www.kernel.org/pub/software/scm/git/docs/git-tag.html"
  *      >Git documentation about Tag</a>
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/api/TransportCommand.java b/org.eclipse.jgit/src/org/eclipse/jgit/api/TransportCommand.java
index 1af880d..30f1bc9 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/api/TransportCommand.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/api/TransportCommand.java
@@ -22,7 +22,9 @@
  * {@link org.eclipse.jgit.api.TransportConfigCallback}.
  *
  * @param <C>
+ *            concrete type of this {@code GitCommand}
  * @param <T>
+ *            the return type of the {@code GitCommand}'s {@code call()} method
  */
 public abstract class TransportCommand<C extends GitCommand, T> extends
 		GitCommand<T> {
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/api/errors/CheckoutConflictException.java b/org.eclipse.jgit/src/org/eclipse/jgit/api/errors/CheckoutConflictException.java
index 3b71373..0224b3d 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/api/errors/CheckoutConflictException.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/api/errors/CheckoutConflictException.java
@@ -94,6 +94,7 @@
 	 * Adds a new conflicting path
 	 *
 	 * @param conflictingPath
+	 *            the new conflicting path
 	 * @return {@code this}
 	 */
 	CheckoutConflictException addConflictingPath(String conflictingPath) {
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/attributes/Attribute.java b/org.eclipse.jgit/src/org/eclipse/jgit/attributes/Attribute.java
index 470a92e..fe3e22a 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/attributes/Attribute.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/attributes/Attribute.java
@@ -97,7 +97,6 @@
 		this(key, State.CUSTOM, value);
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public boolean equals(Object obj) {
 		if (this == obj)
@@ -144,7 +143,6 @@
 		return value;
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public int hashCode() {
 		final int prime = 31;
@@ -155,7 +153,6 @@
 		return result;
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public String toString() {
 		switch (state) {
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/attributes/Attributes.java b/org.eclipse.jgit/src/org/eclipse/jgit/attributes/Attributes.java
index 125ee59..08bc1da 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/attributes/Attributes.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/attributes/Attributes.java
@@ -231,7 +231,6 @@
 		return true;
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public String toString() {
 		StringBuilder buf = new StringBuilder();
@@ -246,13 +245,11 @@
 		return buf.toString();
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public int hashCode() {
 		return map.hashCode();
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public boolean equals(Object obj) {
 		if (this == obj)
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/attributes/AttributesHandler.java b/org.eclipse.jgit/src/org/eclipse/jgit/attributes/AttributesHandler.java
index 7ec7859..d8857f5 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/attributes/AttributesHandler.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/attributes/AttributesHandler.java
@@ -69,6 +69,7 @@
 	 * @param treeWalk
 	 *            a {@link org.eclipse.jgit.treewalk.TreeWalk}
 	 * @throws java.io.IOException
+	 *             if an IO error occurred
 	 * @deprecated since 6.1, use {@link #AttributesHandler(TreeWalk, Supplier)}
 	 *             instead
 	 */
@@ -87,6 +88,7 @@
 	 * @param attributesTree
 	 *            the tree to read .gitattributes from
 	 * @throws java.io.IOException
+	 *             if an IO error occurred
 	 * @since 6.1
 	 */
 	public AttributesHandler(TreeWalk treeWalk,
@@ -128,6 +130,7 @@
 	 *         current path represented by the
 	 *         {@link org.eclipse.jgit.treewalk.TreeWalk}
 	 * @throws java.io.IOException
+	 *             if an IO error occurred
 	 */
 	public Attributes getAttributes() throws IOException {
 		String entryPath = treeWalk.getPathString();
@@ -206,12 +209,16 @@
 	 * @param isDirectory
 	 *            true if the target item is a directory.
 	 * @param workingTreeIterator
+	 *            the working tree iterator
 	 * @param dirCacheIterator
+	 *            the dircache iterator
 	 * @param otherTree
+	 *            another tree
 	 * @param result
 	 *            that will hold the attributes matching this entry path. This
 	 *            method will NOT override any existing entry in attributes.
 	 * @throws IOException
+	 *             if an IO error occurred
 	 */
 	private void mergePerDirectoryEntryAttributes(String entryPath,
 			int nameRoot, boolean isDirectory,
@@ -357,9 +364,13 @@
 	 * </p>
 	 *
 	 * @param treeWalk
+	 *            used to walk trees
 	 * @param workingTreeIterator
+	 *            used to walk the working tree
 	 * @param dirCacheIterator
+	 *            used to walk the dircache
 	 * @param otherTree
+	 *            another tree
 	 * @return a {@link AttributesNode} of the current entry,
 	 *         {@link NullPointerException} otherwise.
 	 * @throws IOException
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/attributes/AttributesRule.java b/org.eclipse.jgit/src/org/eclipse/jgit/attributes/AttributesRule.java
index 73fd587..2039191 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/attributes/AttributesRule.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/attributes/AttributesRule.java
@@ -187,7 +187,6 @@
 		return match;
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public String toString() {
 		StringBuilder sb = new StringBuilder();
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/attributes/FilterCommandRegistry.java b/org.eclipse.jgit/src/org/eclipse/jgit/attributes/FilterCommandRegistry.java
index 1c9e9d7..bbbb437 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/attributes/FilterCommandRegistry.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/attributes/FilterCommandRegistry.java
@@ -41,8 +41,8 @@
 	 *            the factory responsible for creating
 	 *            {@link org.eclipse.jgit.attributes.FilterCommand}s for the
 	 *            specified name
-	 * @return the previous factory associated with <tt>commandName</tt>, or
-	 *         <tt>null</tt> if there was no mapping for <tt>commandName</tt>
+	 * @return the previous factory associated with {@code commandName}, or
+	 *         {@code null} if there was no mapping for {@code commandName}
 	 */
 	public static FilterCommandFactory register(String filterCommandName,
 			FilterCommandFactory factory) {
@@ -55,8 +55,8 @@
 	 *
 	 * @param filterCommandName
 	 *            the FilterCommandFactory's filter command name
-	 * @return the previous factory associated with <tt>filterCommandName</tt>,
-	 *         or <tt>null</tt> if there was no mapping for <tt>commandName</tt>
+	 * @return the previous factory associated with {@code filterCommandName},
+	 *         or {@code null} if there was no mapping for {@code commandName}
 	 */
 	public static FilterCommandFactory unregister(String filterCommandName) {
 		return filterCommandRegistry.remove(filterCommandName);
@@ -69,7 +69,7 @@
 	 *
 	 * @param filterCommandName
 	 *            the name for which the registry should be checked
-	 * @return <code>true</code> if any factory was registered for the name
+	 * @return {@code true} if any factory was registered for the name
 	 */
 	public static boolean isRegistered(String filterCommandName) {
 		return filterCommandRegistry.containsKey(filterCommandName);
@@ -107,6 +107,7 @@
 	 * @return the command if a command could be created or <code>null</code> if
 	 *         there was no factory registered for that name
 	 * @throws java.io.IOException
+	 *             if an IO error occurred
 	 */
 	public static FilterCommand createFilterCommand(String filterCommandName,
 			Repository db, InputStream in, OutputStream out)
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/blame/BlameResult.java b/org.eclipse.jgit/src/org/eclipse/jgit/blame/BlameResult.java
index c854b37..5e2746c 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/blame/BlameResult.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/blame/BlameResult.java
@@ -303,7 +303,6 @@
 		}
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public String toString() {
 		StringBuilder r = new StringBuilder();
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/blame/Candidate.java b/org.eclipse.jgit/src/org/eclipse/jgit/blame/Candidate.java
index ccf99ff..8e2aaec 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/blame/Candidate.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/blame/Candidate.java
@@ -305,7 +305,6 @@
 		}
 	}
 
-	/** {@inheritDoc} */
 	@SuppressWarnings("nls")
 	@Override
 	public String toString() {
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/blame/Region.java b/org.eclipse.jgit/src/org/eclipse/jgit/blame/Region.java
index 2236eec..c481eb1 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/blame/Region.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/blame/Region.java
@@ -83,7 +83,6 @@
 		return head;
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public String toString() {
 		StringBuilder buf = new StringBuilder();
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/blame/ReverseWalk.java b/org.eclipse.jgit/src/org/eclipse/jgit/blame/ReverseWalk.java
index e8f3f38..fafc4fb 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/blame/ReverseWalk.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/blame/ReverseWalk.java
@@ -24,7 +24,6 @@
 		super(repo);
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public ReverseCommit next() throws MissingObjectException,
 			IncorrectObjectTypeException, IOException {
@@ -36,7 +35,6 @@
 		return c;
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	protected RevCommit createCommit(AnyObjectId id) {
 		return new ReverseCommit(id);
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/diff/DiffAlgorithm.java b/org.eclipse.jgit/src/org/eclipse/jgit/diff/DiffAlgorithm.java
index 2526cbf..7821efd 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/diff/DiffAlgorithm.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/diff/DiffAlgorithm.java
@@ -58,6 +58,8 @@
 	/**
 	 * Compare two sequences and identify a list of edits between them.
 	 *
+	 * @param <S>
+	 *            type of sequence being compared.
 	 * @param cmp
 	 *            the comparator supplying the element equivalence function.
 	 * @param a
@@ -217,6 +219,8 @@
 	 * method, which invokes this method using
 	 * {@link org.eclipse.jgit.diff.Subsequence}s.
 	 *
+	 * @param <S>
+	 *            type of sequence being compared.
 	 * @param cmp
 	 *            the comparator supplying the element equivalence function.
 	 * @param a
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/diff/DiffEntry.java b/org.eclipse.jgit/src/org/eclipse/jgit/diff/DiffEntry.java
index f0ce121..717d898 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/diff/DiffEntry.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/diff/DiffEntry.java
@@ -457,7 +457,6 @@
 	/**
 	 * Whether the mark tree filter with the specified index matched during scan
 	 * or not, see {@link #scan(TreeWalk, boolean, TreeFilter...)}. Example:
-	 * <p>
 	 *
 	 * <pre>
 	 * TreeFilter filterA = ...;
@@ -506,7 +505,6 @@
 		return side == Side.OLD ? getOldId() : getNewId();
 	}
 
-	/** {@inheritDoc} */
 	@SuppressWarnings("nls")
 	@Override
 	public String toString() {
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/diff/DiffFormatter.java b/org.eclipse.jgit/src/org/eclipse/jgit/diff/DiffFormatter.java
index 1a5f74f..2f472b5 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/diff/DiffFormatter.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/diff/DiffFormatter.java
@@ -777,6 +777,7 @@
 	 * @param b
 	 *            the text B which was compared
 	 * @throws java.io.IOException
+	 *             if an IO error occurred
 	 */
 	public void format(EditList edits, RawText a, RawText b)
 			throws IOException {
@@ -825,6 +826,7 @@
 	 * @param line
 	 *            the line number within text
 	 * @throws java.io.IOException
+	 *             if an IO error occurred
 	 */
 	protected void writeContextLine(RawText text, int line)
 			throws IOException {
@@ -843,6 +845,7 @@
 	 * @param line
 	 *            the line number within text
 	 * @throws java.io.IOException
+	 *             if an IO error occurred
 	 */
 	protected void writeAddedLine(RawText text, int line)
 			throws IOException {
@@ -857,6 +860,7 @@
 	 * @param line
 	 *            the line number within text
 	 * @throws java.io.IOException
+	 *             if an IO error occurred
 	 */
 	protected void writeRemovedLine(RawText text, int line)
 			throws IOException {
@@ -875,6 +879,7 @@
 	 * @param bEndLine
 	 *            within second source
 	 * @throws java.io.IOException
+	 *             if an IO error occurred
 	 */
 	protected void writeHunkHeader(int aStartLine, int aEndLine,
 			int bStartLine, int bEndLine) throws IOException {
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/diff/Edit.java b/org.eclipse.jgit/src/org/eclipse/jgit/diff/Edit.java
index 219a187..2968dba 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/diff/Edit.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/diff/Edit.java
@@ -238,13 +238,11 @@
 		endB = sEnd;
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public int hashCode() {
 		return beginA ^ endA;
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public boolean equals(Object o) {
 		if (o instanceof Edit) {
@@ -255,7 +253,6 @@
 		return false;
 	}
 
-	/** {@inheritDoc} */
 	@SuppressWarnings("nls")
 	@Override
 	public String toString() {
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/diff/EditList.java b/org.eclipse.jgit/src/org/eclipse/jgit/diff/EditList.java
index d40a640..85e23e9 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/diff/EditList.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/diff/EditList.java
@@ -49,7 +49,6 @@
 		super(capacity);
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public String toString() {
 		return "EditList" + super.toString(); //$NON-NLS-1$
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/diff/HashedSequence.java b/org.eclipse.jgit/src/org/eclipse/jgit/diff/HashedSequence.java
index 9cb8e73..82ab21c 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/diff/HashedSequence.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/diff/HashedSequence.java
@@ -34,7 +34,6 @@
 		this.hashes = hashes;
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public int size() {
 		return base.size();
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/diff/HashedSequenceComparator.java b/org.eclipse.jgit/src/org/eclipse/jgit/diff/HashedSequenceComparator.java
index 0380208..c7dfd9a 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/diff/HashedSequenceComparator.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/diff/HashedSequenceComparator.java
@@ -33,7 +33,6 @@
 		this.cmp = cmp;
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public boolean equals(HashedSequence<S> a, int ai, //
 			HashedSequence<S> b, int bi) {
@@ -41,7 +40,6 @@
 				&& cmp.equals(a.base, ai, b.base, bi);
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public int hash(HashedSequence<S> seq, int ptr) {
 		return seq.hashes[ptr];
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/diff/HistogramDiff.java b/org.eclipse.jgit/src/org/eclipse/jgit/diff/HistogramDiff.java
index 4035a1e..bb72e1f 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/diff/HistogramDiff.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/diff/HistogramDiff.java
@@ -98,7 +98,6 @@
 		maxChainLength = maxLen;
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public <S extends Sequence> void diffNonCommon(EditList edits,
 			HashedSequenceComparator<S> cmp, HashedSequence<S> a,
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/diff/LowLevelDiffAlgorithm.java b/org.eclipse.jgit/src/org/eclipse/jgit/diff/LowLevelDiffAlgorithm.java
index 7f3c251..39be43d 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/diff/LowLevelDiffAlgorithm.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/diff/LowLevelDiffAlgorithm.java
@@ -14,7 +14,6 @@
  * Compares two sequences primarily based upon hash codes.
  */
 public abstract class LowLevelDiffAlgorithm extends DiffAlgorithm {
-	/** {@inheritDoc} */
 	@Override
 	public <S extends Sequence> EditList diffNonCommon(
 			SequenceComparator<? super S> cmp, S a, S b) {
@@ -40,6 +39,8 @@
 	 * method, which invokes this method using
 	 * {@link org.eclipse.jgit.diff.Subsequence}s.
 	 *
+	 * @param <S>
+	 *            type of Sequence compared
 	 * @param edits
 	 *            result list to append the region's edits onto.
 	 * @param cmp
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/diff/PatchIdDiffFormatter.java b/org.eclipse.jgit/src/org/eclipse/jgit/diff/PatchIdDiffFormatter.java
index 53cd2ea..4343642 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/diff/PatchIdDiffFormatter.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/diff/PatchIdDiffFormatter.java
@@ -43,14 +43,12 @@
 		return ObjectId.fromRaw(digest.digest());
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	protected void writeHunkHeader(int aStartLine, int aEndLine,
 			int bStartLine, int bEndLine) throws IOException {
 		// The hunk header is not taken into account for patch id calculation
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	protected void formatIndexLine(OutputStream o, DiffEntry ent)
 			throws IOException {
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/diff/RawText.java b/org.eclipse.jgit/src/org/eclipse/jgit/diff/RawText.java
index b528035..7835582 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/diff/RawText.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/diff/RawText.java
@@ -114,7 +114,6 @@
 	}
 
 	/** @return total number of items in the sequence. */
-	/** {@inheritDoc} */
 	@Override
 	public int size() {
 		// The line map is always 2 entries larger than the number of lines in
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/diff/RawTextComparator.java b/org.eclipse.jgit/src/org/eclipse/jgit/diff/RawTextComparator.java
index 0c41b85..e06e2f8 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/diff/RawTextComparator.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/diff/RawTextComparator.java
@@ -227,7 +227,6 @@
 		return hashRegion(seq.content, begin, end);
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public Edit reduceCommonStartEnd(RawText a, RawText b, Edit e) {
 		// This is a faster exact match based form that tries to improve
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/diff/RenameDetector.java b/org.eclipse.jgit/src/org/eclipse/jgit/diff/RenameDetector.java
index c33f53a..fd84bc6 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/diff/RenameDetector.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/diff/RenameDetector.java
@@ -713,15 +713,16 @@
 
 	/**
 	 * Find the best match by file path for a given DiffEntry from a list of
-	 * DiffEntrys. The returned DiffEntry will be of the same type as <src>. If
-	 * no DiffEntry can be found that has the same type, this method will return
-	 * null.
+	 * DiffEntrys. The returned DiffEntry will be of the same type as
+	 * &lt;src&gt;. If no DiffEntry can be found that has the same type, this
+	 * method will return null.
 	 *
 	 * @param src
 	 *            the DiffEntry to try to find a match for
 	 * @param list
 	 *            a list of DiffEntrys to search through
-	 * @return the DiffEntry from <list> who's file path best matches <src>
+	 * @return the DiffEntry from &lt;list&gt; who's file path best matches
+	 *         &lt;src&gt;
 	 */
 	private static DiffEntry bestPathMatch(DiffEntry src, List<DiffEntry> list) {
 		DiffEntry best = null;
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/diff/Subsequence.java b/org.eclipse.jgit/src/org/eclipse/jgit/diff/Subsequence.java
index 61f133c..878c66b 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/diff/Subsequence.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/diff/Subsequence.java
@@ -25,6 +25,8 @@
 	/**
 	 * Construct a subsequence around the A region/base sequence.
 	 *
+	 * @param <S>
+	 *            type of returned Sequence
 	 * @param a
 	 *            the A sequence.
 	 * @param region
@@ -38,6 +40,8 @@
 	/**
 	 * Construct a subsequence around the B region/base sequence.
 	 *
+	 * @param <S>
+	 *            type of returned Sequence
 	 * @param b
 	 *            the B sequence.
 	 * @param region
@@ -51,6 +55,8 @@
 	/**
 	 * Adjust the Edit to reflect positions in the base sequence.
 	 *
+	 * @param <S>
+	 *            type of returned Sequence
 	 * @param e
 	 *            edit to adjust in-place. Prior to invocation the indexes are
 	 *            in terms of the two subsequences; after invocation the indexes
@@ -72,6 +78,8 @@
 	/**
 	 * Adjust the Edits to reflect positions in the base sequence.
 	 *
+	 * @param <S>
+	 *            type of returned Sequence
 	 * @param edits
 	 *            edits to adjust in-place. Prior to invocation the indexes are
 	 *            in terms of the two subsequences; after invocation the indexes
@@ -116,7 +124,6 @@
 		this.size = end - begin;
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public int size() {
 		return size;
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/diff/SubsequenceComparator.java b/org.eclipse.jgit/src/org/eclipse/jgit/diff/SubsequenceComparator.java
index c609453..707df59 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/diff/SubsequenceComparator.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/diff/SubsequenceComparator.java
@@ -36,13 +36,11 @@
 		this.cmp = cmp;
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public boolean equals(Subsequence<S> a, int ai, Subsequence<S> b, int bi) {
 		return cmp.equals(a.base, ai + a.begin, b.base, bi + b.begin);
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public int hash(Subsequence<S> seq, int ptr) {
 		return cmp.hash(seq.base, ptr + seq.begin);
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/dircache/BaseDirCacheEditor.java b/org.eclipse.jgit/src/org/eclipse/jgit/dircache/BaseDirCacheEditor.java
index 86e60e5..68296ef 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/dircache/BaseDirCacheEditor.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/dircache/BaseDirCacheEditor.java
@@ -25,9 +25,11 @@
  * services to applications.
  */
 abstract class BaseDirCacheEditor {
+	@SuppressWarnings("doclint:missing")
 	/** The cache instance this editor updates during {@link #finish()}. */
 	protected DirCache cache;
 
+	@SuppressWarnings("doclint:missing")
 	/**
 	 * Entry table this builder will eventually replace into {@link #cache}.
 	 * <p>
@@ -40,7 +42,7 @@
 	 */
 	protected DirCacheEntry[] entries;
 
-	/** Total number of valid entries in {@link #entries}. */
+	/** Total number of valid entries in {@link BaseDirCacheEditor#entries}. */
 	protected int entryCnt;
 
 	/**
@@ -137,7 +139,8 @@
 	public abstract void finish();
 
 	/**
-	 * Update the DirCache with the contents of {@link #entries}.
+	 * Update the DirCache with the contents of
+	 * {@link BaseDirCacheEditor#entries}.
 	 * <p>
 	 * This method should be invoked only during an implementation of
 	 * {@link #finish()}, and only after {@link #entries} is sorted.
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/dircache/DirCache.java b/org.eclipse.jgit/src/org/eclipse/jgit/dircache/DirCache.java
index e560612..34dba0b 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/dircache/DirCache.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/dircache/DirCache.java
@@ -429,6 +429,7 @@
 	 *
 	 * @return {@code true} if the memory state differs from the index file
 	 * @throws java.io.IOException
+	 *             if an IO error occurred
 	 */
 	public boolean isOutdated() throws IOException {
 		if (liveFile == null || !liveFile.exists())
@@ -1001,6 +1002,7 @@
 	 * Update any smudged entries with information from the working tree.
 	 *
 	 * @throws IOException
+	 *             if an IO error occurred
 	 */
 	private void updateSmudgedEntries() throws IOException {
 		List<String> paths = new ArrayList<>(128);
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/dircache/DirCacheBuildIterator.java b/org.eclipse.jgit/src/org/eclipse/jgit/dircache/DirCacheBuildIterator.java
index f6e4d36..befd806 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/dircache/DirCacheBuildIterator.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/dircache/DirCacheBuildIterator.java
@@ -74,7 +74,6 @@
 		builder = p.builder;
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public AbstractTreeIterator createSubtreeIterator(ObjectReader reader)
 			throws IncorrectObjectTypeException, IOException {
@@ -84,7 +83,6 @@
 		return new DirCacheBuildIterator(this, currentSubtree);
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public void skip() throws CorruptObjectException {
 		if (currentSubtree != null)
@@ -94,7 +92,6 @@
 		next(1);
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public void stopWalk() {
 		final int cur = ptr;
@@ -103,7 +100,6 @@
 			builder.keep(cur, cnt - cur);
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	protected boolean needsStopWalk() {
 		return ptr < cache.getEntryCount();
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/dircache/DirCacheBuilder.java b/org.eclipse.jgit/src/org/eclipse/jgit/dircache/DirCacheBuilder.java
index 9fe77f3..28d2502 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/dircache/DirCacheBuilder.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/dircache/DirCacheBuilder.java
@@ -186,7 +186,6 @@
 		return e;
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public void finish() {
 		if (!sorted)
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/dircache/DirCacheCheckout.java b/org.eclipse.jgit/src/org/eclipse/jgit/dircache/DirCacheCheckout.java
index d54df8d..6ae5153 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/dircache/DirCacheCheckout.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/dircache/DirCacheCheckout.java
@@ -95,7 +95,9 @@
 
 		/**
 		 * @param eolStreamType
+		 *            how to convert EOL characters during stream conversion
 		 * @param smudgeFilterCommand
+		 *            command used as smudge filter during checkout
 		 */
 		public CheckoutMetadata(EolStreamType eolStreamType,
 				String smudgeFilterCommand) {
@@ -201,6 +203,7 @@
 	 * @param workingTree
 	 *            an iterator over the repositories Working Tree
 	 * @throws java.io.IOException
+	 *             if an IO error occurred
 	 */
 	public DirCacheCheckout(Repository repo, ObjectId headCommitTree, DirCache dc,
 			ObjectId mergeCommitTree, WorkingTreeIterator workingTree)
@@ -228,6 +231,7 @@
 	 * @param mergeCommitTree
 	 *            the id of the tree we want to fast-forward to
 	 * @throws java.io.IOException
+	 *             if an IO error occurred
 	 */
 	public DirCacheCheckout(Repository repo, ObjectId headCommitTree,
 			DirCache dc, ObjectId mergeCommitTree) throws IOException {
@@ -247,6 +251,7 @@
 	 * @param workingTree
 	 *            an iterator over the repositories Working Tree
 	 * @throws java.io.IOException
+	 *             if an IO error occurred
 	 */
 	public DirCacheCheckout(Repository repo, DirCache dc,
 			ObjectId mergeCommitTree, WorkingTreeIterator workingTree)
@@ -266,6 +271,7 @@
 	 * @param mergeCommitTree
 	 *            the id of the tree of the
 	 * @throws java.io.IOException
+	 *             if an IO error occurred
 	 */
 	public DirCacheCheckout(Repository repo, DirCache dc,
 			ObjectId mergeCommitTree) throws IOException {
@@ -289,7 +295,9 @@
 	 * operations.
 	 *
 	 * @throws org.eclipse.jgit.errors.CorruptObjectException
+	 *             if a corrupt object was found
 	 * @throws java.io.IOException
+	 *             if an IO error occurred
 	 */
 	public void preScanTwoTrees() throws CorruptObjectException, IOException {
 		removed.clear();
@@ -319,9 +327,13 @@
 	 * there is no head yet.
 	 *
 	 * @throws org.eclipse.jgit.errors.MissingObjectException
+	 *             if an object was found missing
 	 * @throws org.eclipse.jgit.errors.IncorrectObjectTypeException
+	 *             if an object didn't have the expected type
 	 * @throws org.eclipse.jgit.errors.CorruptObjectException
+	 *             if an object is corrupt
 	 * @throws java.io.IOException
+	 *             if an IO error occurred
 	 */
 	public void prescanOneTree()
 			throws MissingObjectException, IncorrectObjectTypeException,
@@ -367,6 +379,7 @@
 	 * @param f
 	 *            the working tree
 	 * @throws IOException
+	 *             if an IO error occurred
 	 */
 	void processEntry(CanonicalTreeParser m, DirCacheBuildIterator i,
 			WorkingTreeIterator f) throws IOException {
@@ -460,6 +473,7 @@
 	 *         successful and the working tree was updated for all other files.
 	 *         <code>true</code> is returned when no such problem occurred
 	 * @throws java.io.IOException
+	 *             if an IO error occurred
 	 */
 	public boolean checkout() throws IOException {
 		try {
@@ -669,9 +683,13 @@
 	 * Compares whether two pairs of ObjectId and FileMode are equal.
 	 *
 	 * @param id1
+	 *            id of first object
 	 * @param mode1
+	 *            mode of first object
 	 * @param id2
+	 *            id of second object
 	 * @param mode2
+	 *            mode of second object
 	 * @return <code>true</code> if FileModes and ObjectIds are equal.
 	 *         <code>false</code> otherwise
 	 */
@@ -697,6 +715,7 @@
 	 * @param f
 	 *            the file in the working tree
 	 * @throws IOException
+	 *             if an IO error occurred
 	 */
 
 	void processEntry(CanonicalTreeParser h, CanonicalTreeParser m,
@@ -1281,6 +1300,7 @@
 	 * {@link #failOnConflict} is false
 	 *
 	 * @throws CheckoutConflictException
+	 *             if a conflict occurred during merge checkout
 	 */
 	private void cleanUpConflicts() throws CheckoutConflictException {
 		// TODO: couldn't we delete unsaved worktree content here?
@@ -1294,13 +1314,16 @@
 	}
 
 	/**
-	 * Checks whether the subtree starting at a given path differs between Index and
-	 * workingtree.
+	 * Checks whether the subtree starting at a given path differs between Index
+	 * and workingtree.
 	 *
 	 * @param path
+	 *            given subtree path
 	 * @return true if the subtrees differ
 	 * @throws CorruptObjectException
+	 *             if a corrupt object was found
 	 * @throws IOException
+	 *             if an IO error occurred
 	 */
 	private boolean isModifiedSubtree_IndexWorkingtree(String path)
 			throws CorruptObjectException, IOException {
@@ -1341,15 +1364,18 @@
 	}
 
 	/**
-	 * Checks whether the subtree starting at a given path differs between Index and
-	 * some tree.
+	 * Checks whether the subtree starting at a given path differs between Index
+	 * and some tree.
 	 *
 	 * @param path
+	 *            given path
 	 * @param tree
 	 *            the tree to compare
 	 * @return true if the subtrees differ
 	 * @throws CorruptObjectException
+	 *             if a corrupt object was found
 	 * @throws IOException
+	 *             if an IO error occurred
 	 */
 	private boolean isModifiedSubtree_IndexTree(String path, ObjectId tree)
 			throws CorruptObjectException, IOException {
@@ -1394,6 +1420,7 @@
 	 * @param or
 	 *            object reader to use for checkout
 	 * @throws java.io.IOException
+	 *             if an IO error occurred
 	 * @since 3.6
 	 * @deprecated since 5.1, use
 	 *             {@link #checkoutEntry(Repository, DirCacheEntry, ObjectReader, boolean, CheckoutMetadata, WorkingTreeOptions)}
@@ -1435,6 +1462,7 @@
 	 *            <li>eolStreamType used for stream conversion</li>
 	 *            </ul>
 	 * @throws java.io.IOException
+	 *             if an IO error occurred
 	 * @since 4.2
 	 * @deprecated since 6.3, use
 	 *             {@link #checkoutEntry(Repository, DirCacheEntry, ObjectReader, boolean, CheckoutMetadata, WorkingTreeOptions)}
@@ -1479,6 +1507,7 @@
 	 *            {@link WorkingTreeOptions} that are effective; if {@code null}
 	 *            they are loaded from the repository config
 	 * @throws java.io.IOException
+	 *             if an IO error occurred
 	 * @since 6.3
 	 * @deprecated since 6.6.1; use {@link Checkout} instead
 	 */
@@ -1518,6 +1547,7 @@
 	 *            the output stream the filtered content is written to. The
 	 *            caller is responsible to close the stream.
 	 * @throws IOException
+	 *             if an IO error occurred
 	 *
 	 * @since 5.7
 	 */
@@ -1573,6 +1603,7 @@
 	 *            the output stream the filtered content is written to. The
 	 *            caller is responsible to close the stream.
 	 * @throws IOException
+	 *             if an IO error occurred
 	 * @since 6.3
 	 */
 	public static void getContent(Repository repo, String path,
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/dircache/DirCacheEditor.java b/org.eclipse.jgit/src/org/eclipse/jgit/dircache/DirCacheEditor.java
index 8c342e2..b1f4e7d 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/dircache/DirCacheEditor.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/dircache/DirCacheEditor.java
@@ -37,7 +37,6 @@
  * have the editor compute the proper entry indexes necessary to perform an
  * efficient in-order update of the index records. This can be easier to use
  * than {@link org.eclipse.jgit.dircache.DirCacheBuilder}.
- * <p>
  *
  * @see DirCacheBuilder
  */
@@ -80,7 +79,6 @@
 		edits.add(edit);
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public boolean commit() throws IOException {
 		if (edits.isEmpty()) {
@@ -92,7 +90,6 @@
 		return super.commit();
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public void finish() {
 		if (!edits.isEmpty()) {
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/dircache/DirCacheIterator.java b/org.eclipse.jgit/src/org/eclipse/jgit/dircache/DirCacheIterator.java
index aed1c34..9cc34a0 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/dircache/DirCacheIterator.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/dircache/DirCacheIterator.java
@@ -104,7 +104,6 @@
 		parseEntry();
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public AbstractTreeIterator createSubtreeIterator(ObjectReader reader)
 			throws IncorrectObjectTypeException, IOException {
@@ -114,7 +113,6 @@
 		return new DirCacheIterator(this, currentSubtree);
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public EmptyTreeIterator createEmptyTreeIterator() {
 		final byte[] n = new byte[Math.max(pathLen + 1, DEFAULT_PATH_SIZE)];
@@ -123,7 +121,6 @@
 		return new EmptyTreeIterator(this, n, pathLen + 1);
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public boolean hasId() {
 		if (currentSubtree != null)
@@ -131,7 +128,6 @@
 		return currentEntry != null;
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public byte[] idBuffer() {
 		if (currentSubtree != null)
@@ -141,7 +137,6 @@
 		return zeroid;
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public int idOffset() {
 		if (currentSubtree != null)
@@ -151,7 +146,6 @@
 		return 0;
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public void reset() {
 		if (!first()) {
@@ -164,19 +158,16 @@
 		}
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public boolean first() {
 		return ptr == treeStart;
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public boolean eof() {
 		return ptr == treeEnd;
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public void next(int delta) {
 		while (--delta >= 0) {
@@ -190,7 +181,6 @@
 		}
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public void back(int delta) {
 		while (--delta >= 0) {
@@ -271,6 +261,7 @@
 	 * @return {@link org.eclipse.jgit.attributes.AttributesNode} for the
 	 *         current entry.
 	 * @throws java.io.IOException
+	 *             if an IO error occurred
 	 * @since 3.7
 	 */
 	public AttributesNode getEntryAttributesNode(ObjectReader reader)
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/dircache/DirCacheTree.java b/org.eclipse.jgit/src/org/eclipse/jgit/dircache/DirCacheTree.java
index e0c1e93..2561ae9 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/dircache/DirCacheTree.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/dircache/DirCacheTree.java
@@ -534,7 +534,6 @@
 		return -1;
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public String toString() {
 		return getNameString();
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/errors/LargeObjectException.java b/org.eclipse.jgit/src/org/eclipse/jgit/errors/LargeObjectException.java
index 4a53561..40aa1c3 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/errors/LargeObjectException.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/errors/LargeObjectException.java
@@ -84,7 +84,6 @@
 			objectId = id.copy();
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public String getMessage() {
 		return MessageFormat.format(JGitText.get().largeObjectException,
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/errors/RevisionSyntaxException.java b/org.eclipse.jgit/src/org/eclipse/jgit/errors/RevisionSyntaxException.java
index 084d67c..83876ef 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/errors/RevisionSyntaxException.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/errors/RevisionSyntaxException.java
@@ -44,7 +44,6 @@
 		this.revstr = revstr;
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public String toString() {
 		return super.toString() + ":" + revstr; //$NON-NLS-1$
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/events/ConfigChangedEvent.java b/org.eclipse.jgit/src/org/eclipse/jgit/events/ConfigChangedEvent.java
index e634254..0c2aa46 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/events/ConfigChangedEvent.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/events/ConfigChangedEvent.java
@@ -14,13 +14,11 @@
  * Describes a change to one or more keys in the configuration.
  */
 public class ConfigChangedEvent extends RepositoryEvent<ConfigChangedListener> {
-	/** {@inheritDoc} */
 	@Override
 	public Class<ConfigChangedListener> getListenerType() {
 		return ConfigChangedListener.class;
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public void dispatch(ConfigChangedListener listener) {
 		listener.onConfigChanged(this);
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/events/IndexChangedEvent.java b/org.eclipse.jgit/src/org/eclipse/jgit/events/IndexChangedEvent.java
index f5a6d64..64d285a 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/events/IndexChangedEvent.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/events/IndexChangedEvent.java
@@ -36,13 +36,11 @@
 		return internal;
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public Class<IndexChangedListener> getListenerType() {
 		return IndexChangedListener.class;
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public void dispatch(IndexChangedListener listener) {
 		listener.onIndexChanged(this);
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/events/ListenerHandle.java b/org.eclipse.jgit/src/org/eclipse/jgit/events/ListenerHandle.java
index 4489760..94d49fd 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/events/ListenerHandle.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/events/ListenerHandle.java
@@ -35,7 +35,6 @@
 		parent.remove(this);
 	}
 
-	/** {@inheritDoc} */
 	@SuppressWarnings("nls")
 	@Override
 	public String toString() {
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/events/ListenerList.java b/org.eclipse.jgit/src/org/eclipse/jgit/events/ListenerList.java
index 476c37c..92a2277 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/events/ListenerList.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/events/ListenerList.java
@@ -71,6 +71,8 @@
 	/**
 	 * Add a listener to the list.
 	 *
+	 * @param <T>
+	 *            type of {@code RepositoryListener}
 	 * @param type
 	 *            type of listener being registered.
 	 * @param listener
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/events/RefsChangedEvent.java b/org.eclipse.jgit/src/org/eclipse/jgit/events/RefsChangedEvent.java
index 6f1e8d5..9bd1ef0 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/events/RefsChangedEvent.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/events/RefsChangedEvent.java
@@ -14,13 +14,11 @@
  * Describes a change to one or more references of a repository.
  */
 public class RefsChangedEvent extends RepositoryEvent<RefsChangedListener> {
-	/** {@inheritDoc} */
 	@Override
 	public Class<RefsChangedListener> getListenerType() {
 		return RefsChangedListener.class;
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public void dispatch(RefsChangedListener listener) {
 		listener.onRefsChanged(this);
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/events/RepositoryEvent.java b/org.eclipse.jgit/src/org/eclipse/jgit/events/RepositoryEvent.java
index 81f2e73..288074e 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/events/RepositoryEvent.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/events/RepositoryEvent.java
@@ -61,7 +61,6 @@
 	 */
 	public abstract void dispatch(T listener);
 
-	/** {@inheritDoc} */
 	@SuppressWarnings("nls")
 	@Override
 	public String toString() {
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/events/WorkingTreeModifiedEvent.java b/org.eclipse.jgit/src/org/eclipse/jgit/events/WorkingTreeModifiedEvent.java
index f9888ea..c327515 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/events/WorkingTreeModifiedEvent.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/events/WorkingTreeModifiedEvent.java
@@ -87,13 +87,11 @@
 		return result;
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public Class<WorkingTreeModifiedListener> getListenerType() {
 		return WorkingTreeModifiedListener.class;
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public void dispatch(WorkingTreeModifiedListener listener) {
 		listener.onWorkingTreeModified(this);
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/fnmatch/AbstractHead.java b/org.eclipse.jgit/src/org/eclipse/jgit/fnmatch/AbstractHead.java
index d54bf65..8668ea9 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/fnmatch/AbstractHead.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/fnmatch/AbstractHead.java
@@ -45,7 +45,6 @@
 		this.newHeads = newHeads;
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public List<Head> getNextHeads(char c) {
 		if (matches(c)) {
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/fnmatch/CharacterHead.java b/org.eclipse.jgit/src/org/eclipse/jgit/fnmatch/CharacterHead.java
index faf4ee6..92fee62 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/fnmatch/CharacterHead.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/fnmatch/CharacterHead.java
@@ -24,13 +24,11 @@
 		this.expectedCharacter = expectedCharacter;
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	protected final boolean matches(char c) {
 		return c == expectedCharacter;
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public String toString() {
 		return String.valueOf(expectedCharacter);
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/fnmatch/GroupHead.java b/org.eclipse.jgit/src/org/eclipse/jgit/fnmatch/GroupHead.java
index 5ffcafc..3b240c3 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/fnmatch/GroupHead.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/fnmatch/GroupHead.java
@@ -96,7 +96,6 @@
 		}
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	protected final boolean matches(char c) {
 		for (CharacterPattern pattern : characterClasses) {
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/fnmatch/LastHead.java b/org.eclipse.jgit/src/org/eclipse/jgit/fnmatch/LastHead.java
index 6aac3fa..d4cc850 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/fnmatch/LastHead.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/fnmatch/LastHead.java
@@ -22,7 +22,6 @@
 		// defined because of javadoc and visibility modifier.
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public List<Head> getNextHeads(char c) {
 		return FileNameMatcher.EMPTY_HEAD_LIST;
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/fnmatch/RestrictedWildCardHead.java b/org.eclipse.jgit/src/org/eclipse/jgit/fnmatch/RestrictedWildCardHead.java
index 14b6038..6b4526f 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/fnmatch/RestrictedWildCardHead.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/fnmatch/RestrictedWildCardHead.java
@@ -18,13 +18,11 @@
 		this.excludedCharacter = excludedCharacter;
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	protected final boolean matches(char c) {
 		return c != excludedCharacter;
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public String toString() {
 		return isStar() ? "*" : "?"; //$NON-NLS-1$ //$NON-NLS-2$
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/fnmatch/WildCardHead.java b/org.eclipse.jgit/src/org/eclipse/jgit/fnmatch/WildCardHead.java
index 3665a70..62b6f42 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/fnmatch/WildCardHead.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/fnmatch/WildCardHead.java
@@ -15,7 +15,6 @@
 		super(star);
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	protected final boolean matches(char c) {
 		return true;
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/gitrepo/ManifestParser.java b/org.eclipse.jgit/src/org/eclipse/jgit/gitrepo/ManifestParser.java
index aa69a05..957b386 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/gitrepo/ManifestParser.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/gitrepo/ManifestParser.java
@@ -75,7 +75,9 @@
 		 *            The relative path to the file to read
 		 * @return the {@code InputStream} of the file.
 		 * @throws GitAPIException
+		 *             a JGit API exception
 		 * @throws IOException
+		 *             if an IO error occurred
 		 */
 		public InputStream readIncludeFile(String path)
 				throws GitAPIException, IOException;
@@ -134,6 +136,7 @@
 	 * @param inputStream
 	 *            a {@link java.io.InputStream} object.
 	 * @throws java.io.IOException
+	 *             if an IO error occurred
 	 */
 	public void read(InputStream inputStream) throws IOException {
 		xmlInRead++;
@@ -151,7 +154,6 @@
 		}
 	}
 
-	/** {@inheritDoc} */
 	@SuppressWarnings("nls")
 	@Override
 	public void startElement(
@@ -239,7 +241,6 @@
 		}
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public void endElement(
 			String uri,
@@ -251,7 +252,6 @@
 		}
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public void endDocument() throws SAXException {
 		xmlInRead--;
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/gitrepo/RepoCommand.java b/org.eclipse.jgit/src/org/eclipse/jgit/gitrepo/RepoCommand.java
index 6e943e5..1ca3ce4 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/gitrepo/RepoCommand.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/gitrepo/RepoCommand.java
@@ -105,6 +105,7 @@
 		 * @return the sha1 of the remote repository, or null if the ref does
 		 *         not exist.
 		 * @throws GitAPIException
+		 *             a JGit API exception
 		 */
 		@Nullable
 		public ObjectId sha1(String uri, String ref) throws GitAPIException;
@@ -120,7 +121,10 @@
 		 *            The relative path (inside the repo) to the file to read
 		 * @return the file content.
 		 * @throws GitAPIException
+		 *             If the ref have an invalid or ambiguous name, or it does
+		 *             not exist in the repository,
 		 * @throws IOException
+		 *             If the object does not exist or is too large
 		 * @since 3.5
 		 *
 		 * @deprecated Use {@link #readFileWithMode(String, String, String)}
@@ -528,7 +532,6 @@
 		return this;
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public RevCommit call() throws GitAPIException {
 		checkCallable();
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/gitrepo/RepoProject.java b/org.eclipse.jgit/src/org/eclipse/jgit/gitrepo/RepoProject.java
index c5ead09..8deb738 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/gitrepo/RepoProject.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/gitrepo/RepoProject.java
@@ -93,6 +93,7 @@
 		 * Do the copy file action.
 		 *
 		 * @throws IOException
+		 *             if an IO error occurred
 		 */
 		public void copy() throws IOException {
 			File srcFile = new File(repo.getWorkTree(),
@@ -180,7 +181,7 @@
 	 */
 	public RepoProject(String name, String path, String revision,
 			String remote, String groupsParam) {
-		this(name, path, revision, remote, new HashSet<String>(), null);
+		this(name, path, revision, remote, new HashSet<>(), null);
 		if (groupsParam != null && groupsParam.length() > 0)
 			this.setGroups(groupsParam);
 	}
@@ -418,7 +419,6 @@
 		return thatPath.startsWith(getPathWithSlash());
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public boolean equals(Object o) {
 		if (o instanceof RepoProject) {
@@ -428,13 +428,11 @@
 		return false;
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public int hashCode() {
 		return this.getPathWithSlash().hashCode();
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public int compareTo(RepoProject that) {
 		return this.getPathWithSlash().compareTo(that.getPathWithSlash());
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/hooks/CommitMsgHook.java b/org.eclipse.jgit/src/org/eclipse/jgit/hooks/CommitMsgHook.java
index 023aef1..17fdd7e 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/hooks/CommitMsgHook.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/hooks/CommitMsgHook.java
@@ -71,7 +71,6 @@
 		super(repo, outputStream, errorStream);
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public String call() throws IOException, AbortedByHookException {
 		if (commitMessage == null) {
@@ -94,7 +93,6 @@
 		return getCommitEditMessageFilePath() != null && commitMessage != null;
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public String getHookName() {
 		return NAME;
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/hooks/PostCommitHook.java b/org.eclipse.jgit/src/org/eclipse/jgit/hooks/PostCommitHook.java
index b9dafcc..3988ee0 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/hooks/PostCommitHook.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/hooks/PostCommitHook.java
@@ -61,14 +61,12 @@
 		super(repo, outputStream, errorStream);
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public Void call() throws IOException, AbortedByHookException {
 		doRun();
 		return null;
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public String getHookName() {
 		return NAME;
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/hooks/PreCommitHook.java b/org.eclipse.jgit/src/org/eclipse/jgit/hooks/PreCommitHook.java
index 321f476..b12ea83 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/hooks/PreCommitHook.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/hooks/PreCommitHook.java
@@ -60,14 +60,12 @@
 		super(repo, outputStream, errorStream);
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public Void call() throws IOException, AbortedByHookException {
 		doRun();
 		return null;
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public String getHookName() {
 		return NAME;
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/hooks/PrePushHook.java b/org.eclipse.jgit/src/org/eclipse/jgit/hooks/PrePushHook.java
index 43dbc37..e36312b 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/hooks/PrePushHook.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/hooks/PrePushHook.java
@@ -74,13 +74,11 @@
 		super(repo, outputStream, errorStream);
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	protected String getStdinArgs() {
 		return refs;
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public String call() throws IOException, AbortedByHookException {
 		if (canRun()) {
@@ -96,7 +94,6 @@
 		return true;
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public String getHookName() {
 		return NAME;
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/ignore/FastIgnoreRule.java b/org.eclipse.jgit/src/org/eclipse/jgit/ignore/FastIgnoreRule.java
index 9dd565f..b041729 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/ignore/FastIgnoreRule.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/ignore/FastIgnoreRule.java
@@ -208,7 +208,6 @@
 		return matcher == NO_MATCH;
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public String toString() {
 		StringBuilder sb = new StringBuilder();
@@ -221,7 +220,6 @@
 
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public int hashCode() {
 		final int prime = 31;
@@ -232,7 +230,6 @@
 		return result;
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public boolean equals(Object obj) {
 		if (this == obj)
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/ignore/IgnoreNode.java b/org.eclipse.jgit/src/org/eclipse/jgit/ignore/IgnoreNode.java
index 4e7f126..33dceb0 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/ignore/IgnoreNode.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/ignore/IgnoreNode.java
@@ -190,7 +190,6 @@
 		return null;
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public String toString() {
 		return rules.toString();
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/ignore/internal/AbstractMatcher.java b/org.eclipse.jgit/src/org/eclipse/jgit/ignore/internal/AbstractMatcher.java
index 0737ed8..a3f365e 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/ignore/internal/AbstractMatcher.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/ignore/internal/AbstractMatcher.java
@@ -33,19 +33,16 @@
 		this.dirOnly = dirOnly;
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public String toString() {
 		return pattern;
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public int hashCode() {
 		return pattern.hashCode();
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public boolean equals(Object obj) {
 		if (this == obj)
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/ignore/internal/LeadingAsteriskMatcher.java b/org.eclipse.jgit/src/org/eclipse/jgit/ignore/internal/LeadingAsteriskMatcher.java
index 73e2ad3..84376be 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/ignore/internal/LeadingAsteriskMatcher.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/ignore/internal/LeadingAsteriskMatcher.java
@@ -22,7 +22,6 @@
 					"Pattern must have leading asterisk: " + pattern); //$NON-NLS-1$
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public boolean matches(String segment, int startIncl, int endExcl) {
 		// faster local access, same as in string.indexOf()
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/ignore/internal/NameMatcher.java b/org.eclipse.jgit/src/org/eclipse/jgit/ignore/internal/NameMatcher.java
index 39fa74f..4f8e149 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/ignore/internal/NameMatcher.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/ignore/internal/NameMatcher.java
@@ -38,7 +38,6 @@
 		}
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public boolean matches(String path, boolean assumeDirectory,
 			boolean pathMatch) {
@@ -88,7 +87,6 @@
 		return false;
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public boolean matches(String segment, int startIncl, int endExcl) {
 		// faster local access, same as in string.indexOf()
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/ignore/internal/PathMatcher.java b/org.eclipse.jgit/src/org/eclipse/jgit/ignore/internal/PathMatcher.java
index ba77b3d..a40568d 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/ignore/internal/PathMatcher.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/ignore/internal/PathMatcher.java
@@ -91,6 +91,7 @@
 	 *            a boolean.
 	 * @return never null
 	 * @throws org.eclipse.jgit.errors.InvalidPatternException
+	 *             if pattern is invalid
 	 */
 	public static IMatcher createPathMatcher(String pattern,
 			Character pathSeparator, boolean dirOnly)
@@ -149,7 +150,6 @@
 		}
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public boolean matches(String path, boolean assumeDirectory,
 			boolean pathMatch) {
@@ -192,7 +192,6 @@
 		return false;
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public boolean matches(String segment, int startIncl, int endExcl) {
 		throw new UnsupportedOperationException(
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/ignore/internal/Strings.java b/org.eclipse.jgit/src/org/eclipse/jgit/ignore/internal/Strings.java
index fbce08a..3305a74 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/ignore/internal/Strings.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/ignore/internal/Strings.java
@@ -232,16 +232,19 @@
 			.compile("\\[\\[[.=]\\w+[.=]\\]\\]"); //$NON-NLS-1$
 
 	/**
-	 * Conversion from glob to Java regex following two sources: <li>
-	 * http://man7.org/linux/man-pages/man7/glob.7.html <li>
-	 * org.eclipse.jgit.fnmatch.FileNameMatcher.java Seems that there are
+	 * Conversion from glob to Java regex following two sources:
+	 * <ul>
+	 * <li>http://man7.org/linux/man-pages/man7/glob.7.html
+	 * <li>org.eclipse.jgit.fnmatch.FileNameMatcher.java Seems that there are
 	 * various ways to define what "glob" can be.
+	 * </ul>
 	 *
 	 * @param pattern
 	 *            non null pattern
 	 *
 	 * @return Java regex pattern corresponding to given glob pattern
 	 * @throws InvalidPatternException
+	 *             if pattern is invalid
 	 */
 	static Pattern convertGlob(String pattern) throws InvalidPatternException {
 		if (UNSUPPORTED.matcher(pattern).find())
@@ -419,6 +422,7 @@
 
 	/**
 	 * @param buffer
+	 *            buffer
 	 * @return zero of the buffer is empty, otherwise the last character from
 	 *         buffer
 	 */
@@ -427,10 +431,13 @@
 	}
 
 	/**
+	 * Lookahead next character after given index in pattern
+	 *
 	 * @param pattern
+	 *            the pattern
 	 * @param i
 	 *            current pointer in the pattern
-	 * @return zero of the index is out of range, otherwise the next character
+	 * @return zero if the index is out of range, otherwise the next character
 	 *         from given position
 	 */
 	private static char lookAhead(String pattern, int i) {
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/ignore/internal/TrailingAsteriskMatcher.java b/org.eclipse.jgit/src/org/eclipse/jgit/ignore/internal/TrailingAsteriskMatcher.java
index 7fa076b..1f1c223 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/ignore/internal/TrailingAsteriskMatcher.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/ignore/internal/TrailingAsteriskMatcher.java
@@ -22,7 +22,6 @@
 					"Pattern must have trailing asterisk: " + pattern); //$NON-NLS-1$
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public boolean matches(String segment, int startIncl, int endExcl) {
 		// faster local access, same as in string.indexOf()
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/ignore/internal/WildCardMatcher.java b/org.eclipse.jgit/src/org/eclipse/jgit/ignore/internal/WildCardMatcher.java
index 76a8864..d976f6e 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/ignore/internal/WildCardMatcher.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/ignore/internal/WildCardMatcher.java
@@ -31,7 +31,6 @@
 		p = convertGlob(subPattern);
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public boolean matches(String segment, int startIncl, int endExcl) {
 		return p.matcher(segment.substring(startIncl, endExcl)).matches();
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/ignore/internal/WildMatcher.java b/org.eclipse.jgit/src/org/eclipse/jgit/ignore/internal/WildMatcher.java
index 1baa9ab..606b585 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/ignore/internal/WildMatcher.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/ignore/internal/WildMatcher.java
@@ -26,7 +26,6 @@
 		super(WILDMATCH, dirOnly);
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public final boolean matches(String path, boolean assumeDirectory,
 			boolean pathMatch) {
@@ -34,7 +33,6 @@
 				|| (!pathMatch && isSubdirectory(path));
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public final boolean matches(String segment, int startIncl, int endExcl) {
 		return true;
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 c7cad43..cdad7cc 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/internal/JGitText.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/internal/JGitText.java
@@ -254,6 +254,7 @@
 	/***/ public String corruptObjectTruncatedInName;
 	/***/ public String corruptObjectTruncatedInObjectId;
 	/***/ public String corruptObjectZeroId;
+	/***/ public String corruptReverseIndexChecksumIncorrect;
 	/***/ public String corruptPack;
 	/***/ public String corruptUseCnt;
 	/***/ public String couldNotFindTabInLine;
@@ -869,6 +870,7 @@
 	/***/ public String unsupportedEncryptionVersion;
 	/***/ public String unsupportedGC;
 	/***/ public String unsupportedMark;
+	/***/ public String unsupportedObjectIdVersion;
 	/***/ public String unsupportedOperationNotAddAtEnd;
 	/***/ public String unsupportedPackIndexVersion;
 	/***/ public String unsupportedPackReverseIndexVersion;
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/internal/diff/FilteredRenameDetector.java b/org.eclipse.jgit/src/org/eclipse/jgit/internal/diff/FilteredRenameDetector.java
index d65624f..ec4049a 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/internal/diff/FilteredRenameDetector.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/internal/diff/FilteredRenameDetector.java
@@ -54,6 +54,7 @@
 	 *            Filter out changes that didn't affect this path.
 	 * @return The subset of changes that affect only the filtered path.
 	 * @throws IOException
+	 *             if an IO error occurred
 	 */
 	public List<DiffEntry> compute(List<DiffEntry> diffs,
 			PathFilter pathFilter) throws IOException {
@@ -73,6 +74,7 @@
 	 *            Filter out changes that didn't affect these paths.
 	 * @return The subset of changes that affect only the filtered paths.
 	 * @throws IOException
+	 *             if an IO error occurred
 	 * @see RenameDetector#compute()
 	 */
 	public List<DiffEntry> compute(List<DiffEntry> changes,
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/internal/diffmergetool/CommandExecutor.java b/org.eclipse.jgit/src/org/eclipse/jgit/internal/diffmergetool/CommandExecutor.java
index ebef524..3a729fb 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/internal/diffmergetool/CommandExecutor.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/internal/diffmergetool/CommandExecutor.java
@@ -62,8 +62,11 @@
 	 *            the environment
 	 * @return the execution result
 	 * @throws ToolException
+	 *             if a tool raised an error
 	 * @throws InterruptedException
+	 *             if thread was interrupted
 	 * @throws IOException
+	 *             if an IO error occurred
 	 */
 	public ExecutionResult run(String command, File workingDir,
 			Map<String, String> env)
@@ -109,8 +112,11 @@
 	 *            the environment
 	 * @return the execution result
 	 * @throws ToolException
+	 *             if a tool raised an error
 	 * @throws InterruptedException
+	 *             if thread was interrupted
 	 * @throws IOException
+	 *             if an IO error occurred
 	 */
 	public boolean checkExecutable(String path, File workingDir,
 			Map<String, String> env)
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/internal/diffmergetool/DiffTools.java b/org.eclipse.jgit/src/org/eclipse/jgit/internal/diffmergetool/DiffTools.java
index d0034df..6a67bf3 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/internal/diffmergetool/DiffTools.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/internal/diffmergetool/DiffTools.java
@@ -172,6 +172,7 @@
 	 *            the "trust exit code" option
 	 * @return the execution result from tool
 	 * @throws ToolException
+	 *             when the tool fails
 	 */
 	public ExecutionResult compare(FileElement localFile,
 			FileElement remoteFile, ExternalDiffTool tool,
@@ -244,6 +245,7 @@
 	 *            path to the node in repository to parse git attributes for
 	 * @return name of the difftool if set
 	 * @throws ToolException
+	 *             when the tool failed
 	 */
 	public Optional<String> getExternalToolFromAttributes(final String path)
 			throws ToolException {
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/internal/diffmergetool/ExternalToolUtils.java b/org.eclipse.jgit/src/org/eclipse/jgit/internal/diffmergetool/ExternalToolUtils.java
index b2dd846..367107d 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/internal/diffmergetool/ExternalToolUtils.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/internal/diffmergetool/ExternalToolUtils.java
@@ -57,6 +57,7 @@
 	 *            the base file (can be null)
 	 * @return the prepared (with replaced variables) command string
 	 * @throws IOException
+	 *             if an IO error occurred
 	 */
 	public static String prepareCommand(String command, FileElement localFile,
 			FileElement remoteFile, FileElement mergedFile,
@@ -91,6 +92,7 @@
 	 *            the base file (can be null)
 	 * @return the environment map with variables and values (file paths)
 	 * @throws IOException
+	 *             if an IO error occurred
 	 */
 	public static Map<String, String> prepareEnvironment(File gitDir,
 			FileElement localFile, FileElement remoteFile,
@@ -209,6 +211,7 @@
 	 *            config key name for the tool
 	 * @return attribute value for the given tool key if set
 	 * @throws ToolException
+	 *             if the tool failed
 	 */
 	public static Optional<String> getExternalToolFromAttributes(
 			final Repository repository, final String path,
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/internal/diffmergetool/FileElement.java b/org.eclipse.jgit/src/org/eclipse/jgit/internal/diffmergetool/FileElement.java
index ba8ca54..0061e3f 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/internal/diffmergetool/FileElement.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/internal/diffmergetool/FileElement.java
@@ -138,6 +138,7 @@
 	 *
 	 * @return the object stream
 	 * @throws IOException
+	 *             if an IO error occurred
 	 */
 	public File getFile() throws IOException {
 		// if we have already temp file and no stream
@@ -179,6 +180,7 @@
 	 *            temporary directory is used
 	 * @return temporary file in directory or in the system temporary directory
 	 * @throws IOException
+	 *             if an IO error occurred
 	 */
 	public File createTempFile(File directory) throws IOException {
 		if (tempFile == null) {
@@ -204,6 +206,7 @@
 	 *            the input string
 	 * @return the replaced input string
 	 * @throws IOException
+	 *             if an IO error occurred
 	 */
 	public String replaceVariable(String input) throws IOException {
 		return input.replace("$" + type.name(), getFile().getPath()); //$NON-NLS-1$
@@ -215,6 +218,7 @@
 	 * @param env
 	 *            the environment where this element should be added
 	 * @throws IOException
+	 *             if an IO error occurred
 	 */
 	public void addToEnv(Map<String, String> env) throws IOException {
 		env.put(type.name(), getFile().getPath());
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/internal/diffmergetool/MergeTools.java b/org.eclipse.jgit/src/org/eclipse/jgit/internal/diffmergetool/MergeTools.java
index b903201..0da58e4 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/internal/diffmergetool/MergeTools.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/internal/diffmergetool/MergeTools.java
@@ -184,6 +184,7 @@
 	 *            the selected tool
 	 * @return the execution result from tool
 	 * @throws ToolException
+	 *             if the tool failed
 	 */
 	public ExecutionResult merge(FileElement localFile, FileElement remoteFile,
 			FileElement mergedFile, FileElement baseFile, File tempDir,
@@ -254,6 +255,7 @@
 	 * @return the created temporary directory if (mergetol.writeToTemp == true)
 	 *         or null if not configured or false.
 	 * @throws IOException
+	 *             if an IO error occurred
 	 */
 	public File createTempDirectory() throws IOException {
 		return config.isWriteToTemp()
@@ -305,6 +307,7 @@
 	 *            path to the node in repository to parse git attributes for
 	 * @return name of the difftool if set
 	 * @throws ToolException
+	 *             if the tool failed
 	 */
 	public Optional<String> getExternalToolFromAttributes(final String path)
 			throws ToolException {
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/internal/diffmergetool/PreDefinedDiffTool.java b/org.eclipse.jgit/src/org/eclipse/jgit/internal/diffmergetool/PreDefinedDiffTool.java
index e1169a2..c1d69b4 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/internal/diffmergetool/PreDefinedDiffTool.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/internal/diffmergetool/PreDefinedDiffTool.java
@@ -43,6 +43,7 @@
 
 	/**
 	 * @param path
+	 *            path string
 	 */
 	@Override
 	public void setPath(String path) {
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/internal/diffmergetool/UserDefinedMergeTool.java b/org.eclipse.jgit/src/org/eclipse/jgit/internal/diffmergetool/UserDefinedMergeTool.java
index 1dd2f0d..17d5b0b 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/internal/diffmergetool/UserDefinedMergeTool.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/internal/diffmergetool/UserDefinedMergeTool.java
@@ -59,7 +59,7 @@
 	/**
 	 * @param withBase
 	 *            not used, because user-defined merge tool can only define one
-	 *            cmd -> it must handle with and without base present (empty)
+	 *            cmd -&gt; it must handle with and without base present (empty)
 	 * @return the tool command
 	 */
 	@Override
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/internal/fsck/FsckPackParser.java b/org.eclipse.jgit/src/org/eclipse/jgit/internal/fsck/FsckPackParser.java
index 3b94984..795f440 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/internal/fsck/FsckPackParser.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/internal/fsck/FsckPackParser.java
@@ -66,7 +66,6 @@
 		this.blockSize = channel.blockSize() > 0 ? channel.blockSize() : 65536;
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	protected void onPackHeader(long objCnt) throws IOException {
 		if (expectedObjectCount >= 0) {
@@ -78,48 +77,41 @@
 		}
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	protected void onBeginWholeObject(long streamPosition, int type,
 			long inflatedSize) throws IOException {
 		crc.reset();
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	protected void onObjectHeader(Source src, byte[] raw, int pos, int len)
 			throws IOException {
 		crc.update(raw, pos, len);
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	protected void onObjectData(Source src, byte[] raw, int pos, int len)
 			throws IOException {
 		crc.update(raw, pos, len);
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	protected void onEndWholeObject(PackedObjectInfo info) throws IOException {
 		info.setCRC((int) crc.getValue());
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	protected void onBeginOfsDelta(long deltaStreamPosition,
 			long baseStreamPosition, long inflatedSize) throws IOException {
 		crc.reset();
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	protected void onBeginRefDelta(long deltaStreamPosition, AnyObjectId baseId,
 			long inflatedSize) throws IOException {
 		crc.reset();
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	protected UnresolvedDelta onEndDelta() throws IOException {
 		UnresolvedDelta delta = new UnresolvedDelta();
@@ -127,14 +119,12 @@
 		return delta;
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	protected void onInflatedObjectData(PackedObjectInfo obj, int typeCode,
 			byte[] data) throws IOException {
 		// FsckPackParser ignores this event.
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	protected void verifySafeObject(final AnyObjectId id, final int type,
 			final byte[] data) {
@@ -146,13 +136,11 @@
 		}
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	protected void onPackFooter(byte[] hash) throws IOException {
 		// Do nothing.
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	protected boolean onAppendBase(int typeCode, byte[] data,
 			PackedObjectInfo info) throws IOException {
@@ -160,13 +148,11 @@
 		return false;
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	protected void onEndThinPack() throws IOException {
 		// Do nothing.
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	protected ObjectTypeAndSize seekDatabase(PackedObjectInfo obj,
 			ObjectTypeAndSize info) throws IOException {
@@ -175,7 +161,6 @@
 		return readObjectHeader(info);
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	protected ObjectTypeAndSize seekDatabase(UnresolvedDelta delta,
 			ObjectTypeAndSize info) throws IOException {
@@ -184,7 +169,6 @@
 		return readObjectHeader(info);
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	protected int readDatabase(byte[] dst, int pos, int cnt)
 			throws IOException {
@@ -229,13 +213,11 @@
 		return buf.array();
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	protected boolean checkCRC(int oldCRC) {
 		return oldCRC == (int) crc.getValue();
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	protected void onStoreStream(byte[] raw, int pos, int len)
 			throws IOException {
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/internal/revwalk/AddToBitmapFilter.java b/org.eclipse.jgit/src/org/eclipse/jgit/internal/revwalk/AddToBitmapFilter.java
index 86d4722..84f1cb9 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/internal/revwalk/AddToBitmapFilter.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/internal/revwalk/AddToBitmapFilter.java
@@ -40,7 +40,6 @@
 		this.bitmap = bitmap;
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public final boolean include(RevWalk walker, RevCommit cmit) {
 		Bitmap visitedBitmap;
@@ -61,13 +60,11 @@
 		return false;
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public final RevFilter clone() {
 		throw new UnsupportedOperationException();
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public final boolean requiresCommitBody() {
 		return false;
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/internal/revwalk/AddToBitmapWithCacheFilter.java b/org.eclipse.jgit/src/org/eclipse/jgit/internal/revwalk/AddToBitmapWithCacheFilter.java
index d7ccadf..a95432c 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/internal/revwalk/AddToBitmapWithCacheFilter.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/internal/revwalk/AddToBitmapWithCacheFilter.java
@@ -53,7 +53,6 @@
 		this.bitmap = bitmap;
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public final boolean include(RevWalk rw, RevCommit c) {
 		Bitmap visitedBitmap;
@@ -76,13 +75,11 @@
 		return false;
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public final RevFilter clone() {
 		throw new UnsupportedOperationException();
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public final boolean requiresCommitBody() {
 		return false;
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/internal/revwalk/AddUnseenToBitmapFilter.java b/org.eclipse.jgit/src/org/eclipse/jgit/internal/revwalk/AddUnseenToBitmapFilter.java
index da9f9d0..5ac267e 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/internal/revwalk/AddUnseenToBitmapFilter.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/internal/revwalk/AddUnseenToBitmapFilter.java
@@ -48,7 +48,6 @@
 		this.bitmap = bitmap;
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public final boolean include(RevWalk walker, RevCommit cmit) {
 		Bitmap visitedBitmap;
@@ -69,13 +68,11 @@
 		return false;
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public final RevFilter clone() {
 		throw new UnsupportedOperationException();
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public final boolean requiresCommitBody() {
 		return false;
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/internal/revwalk/BitmappedReachabilityChecker.java b/org.eclipse.jgit/src/org/eclipse/jgit/internal/revwalk/BitmappedReachabilityChecker.java
index 37721ad..f5f51e4 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/internal/revwalk/BitmappedReachabilityChecker.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/internal/revwalk/BitmappedReachabilityChecker.java
@@ -119,7 +119,6 @@
 			this.reached = repoBitmaps.newBitmapBuilder();
 		}
 
-		/** {@inheritDoc} */
 		@Override
 		public final boolean include(RevWalk walker, RevCommit cmit) {
 			Bitmap commitBitmap;
@@ -149,13 +148,11 @@
 			}
 		}
 
-		/** {@inheritDoc} */
 		@Override
 		public final RevFilter clone() {
 			throw new UnsupportedOperationException();
 		}
 
-		/** {@inheritDoc} */
 		@Override
 		public final boolean requiresCommitBody() {
 			return false;
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/commitgraph/ChangedPathFilter.java b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/commitgraph/ChangedPathFilter.java
new file mode 100644
index 0000000..53d921e
--- /dev/null
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/commitgraph/ChangedPathFilter.java
@@ -0,0 +1,163 @@
+/*
+ * Copyright (C) 2023, Google LLC
+ *
+ * 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.ByteArrayOutputStream;
+import java.nio.ByteBuffer;
+import java.util.Set;
+
+import org.apache.commons.codec.digest.MurmurHash3;
+
+/**
+ * A changed path filter for a commit.
+ *
+ * @since 6.7
+ */
+public class ChangedPathFilter {
+	/**
+	 * The number of times a path is hashed, as described in man
+	 * gitformat-commit-graph(5). The value of this constant is the only value
+	 * JGit currently supports.
+	 */
+	public static final int PATH_HASH_COUNT = 7;
+
+	/**
+	 * The minimum bits per entry, as described in man
+	 * gitformat-commit-graph(5). The value of this constant is the only value
+	 * JGit currently supports.
+	 */
+	public static final int BITS_PER_ENTRY = 10;
+
+	/**
+	 * Seed value as described in man gitformat-commit-graph(5).
+	 */
+	private static final int SEED1 = 0x293ae76f;
+
+	/**
+	 * Seed value as described in man gitformat-commit-graph(5).
+	 */
+	private static final int SEED2 = 0x7e646e2c;
+
+	/**
+	 * A filter that matches every path.
+	 */
+	public static final ChangedPathFilter FULL = new ChangedPathFilter(
+			new byte[] { (byte) 0xff }, 0, 1);
+
+	private static final ChangedPathFilter EMPTY = new ChangedPathFilter(
+			new byte[] { (byte) 0 }, 0, 1);
+
+	private final byte[] data;
+
+	private final int offset;
+
+	private final int length;
+
+	/**
+	 * Constructs a changed path filter.
+	 *
+	 * @param data
+	 *            data (possibly read from a commit graph file)
+	 * @param offset
+	 *            offset into data
+	 * @param length
+	 *            length of data
+	 */
+	private ChangedPathFilter(byte[] data, int offset, int length) {
+		this.data = data;
+		this.offset = offset;
+		this.length = length;
+	}
+
+	/**
+	 * Returns a filter that matches all given paths.
+	 * <p>
+	 * Because of the nature of Bloom filters, this filter may also match paths
+	 * not in the given set.
+	 *
+	 * @param paths
+	 *            the paths that the filter must match
+	 * @return the corresponding filter
+	 */
+	public static ChangedPathFilter fromPaths(Set<ByteBuffer> paths) {
+		if (paths.isEmpty()) {
+			return EMPTY;
+		}
+		byte[] bloom = new byte[-Math
+				.floorDiv(-paths.size() * ChangedPathFilter.BITS_PER_ENTRY, 8)];
+		for (ByteBuffer path : paths) {
+			add(bloom, path.array(), path.position(),
+					path.limit() - path.position());
+		}
+		return new ChangedPathFilter(bloom, 0, bloom.length);
+	}
+
+	/**
+	 * Returns a filter read from a file.
+	 *
+	 * @param data
+	 *            data (read from a commit graph file)
+	 * @param offset
+	 *            offset into data
+	 * @param length
+	 *            length of data
+	 *
+	 * @return the corresponding filter
+	 */
+	public static ChangedPathFilter fromFile(byte[] data, int offset,
+			int length) {
+		return new ChangedPathFilter(data, offset, length);
+	}
+
+	private static void add(byte[] changedPathFilterData, byte[] path,
+			int offset, int length) {
+
+		int hash0 = MurmurHash3.hash32x86(path, offset, length, SEED1);
+		int hash1 = MurmurHash3.hash32x86(path, offset, length, SEED2);
+		for (int i = 0; i < PATH_HASH_COUNT; i++) {
+			int pos = Integer.remainderUnsigned(hash0 + i * hash1,
+					changedPathFilterData.length * 8);
+			changedPathFilterData[pos / 8] |= (byte) (1 << (pos % 8));
+		}
+	}
+
+	/**
+	 * Checks if this changed path filter could contain path.
+	 *
+	 * @param path
+	 *            path to check existence of
+	 * @return true if the filter could contain path, false if the filter
+	 *         definitely does not contain path
+	 */
+	public boolean maybeContains(byte[] path) {
+		int hash0 = MurmurHash3.hash32x86(path, 0, path.length, SEED1);
+		int hash1 = MurmurHash3.hash32x86(path, 0, path.length, SEED2);
+		int bloomFilterBits = length * 8;
+		for (int i = 0; i < PATH_HASH_COUNT; i++) {
+			int pos = Integer.remainderUnsigned(hash0 + i * hash1,
+					bloomFilterBits);
+			if ((data[offset + (pos / 8)] & (byte) (1 << (pos % 8))) == 0) {
+				return false;
+			}
+		}
+		return true;
+	}
+
+	/**
+	 * Writes this filter to the given stream.
+	 *
+	 * @param s
+	 *            stream to write to
+	 */
+	public void writeTo(ByteArrayOutputStream s) {
+		s.write(data, offset, length);
+	}
+}
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
index 0796293..d1178c2 100644
--- 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
@@ -32,25 +32,26 @@
 
 	/** 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 ChangedPathFilter getChangedPathFilter(int graphPos) {
+			return null;
+		}
+
 		@Override
 		public long getCommitCnt() {
 			return 0;
@@ -97,6 +98,15 @@
 	ObjectId getObjectId(int graphPos);
 
 	/**
+	 * Get the changed path filter of the object at the commit-graph position.
+	 *
+	 * @param graphPos
+	 *            the position in the commit-graph of the object.
+	 * @return the bloom filter or null if it's not found.
+	 */
+	ChangedPathFilter getChangedPathFilter(int graphPos);
+
+	/**
 	 * Obtain the total number of commits described by this commit-graph.
 	 *
 	 * @return number of commits in this commit-graph.
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
index a6af3bc..8f02770 100644
--- 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
@@ -10,6 +10,8 @@
 
 package org.eclipse.jgit.internal.storage.commitgraph;
 
+import static org.eclipse.jgit.internal.storage.commitgraph.CommitGraphConstants.CHUNK_ID_BLOOM_FILTER_DATA;
+import static org.eclipse.jgit.internal.storage.commitgraph.CommitGraphConstants.CHUNK_ID_BLOOM_FILTER_INDEX;
 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;
@@ -35,6 +37,10 @@
 
 	private byte[] extraList;
 
+	private byte[] bloomFilterIndex;
+
+	private byte[] bloomFilterData;
+
 	/** @return A builder of {@link CommitGraph}. */
 	static CommitGraphBuilder builder() {
 		return new CommitGraphBuilder(OBJECT_ID_LENGTH);
@@ -72,6 +78,20 @@
 		return this;
 	}
 
+	CommitGraphBuilder addBloomFilterIndex(byte[] buffer)
+			throws CommitGraphFormatException {
+		assertChunkNotSeenYet(bloomFilterIndex, CHUNK_ID_BLOOM_FILTER_INDEX);
+		bloomFilterIndex = buffer;
+		return this;
+	}
+
+	CommitGraphBuilder addBloomFilterData(byte[] buffer)
+			throws CommitGraphFormatException {
+		assertChunkNotSeenYet(bloomFilterData, CHUNK_ID_BLOOM_FILTER_DATA);
+		bloomFilterData = buffer;
+		return this;
+	}
+
 	CommitGraph build() throws CommitGraphFormatException {
 		assertChunkNotNull(oidFanout, CHUNK_ID_OID_FANOUT);
 		assertChunkNotNull(oidLookup, CHUNK_ID_OID_LOOKUP);
@@ -81,7 +101,9 @@
 				oidLookup);
 		GraphCommitData commitDataChunk = new GraphCommitData(hashLength,
 				commitData, extraList);
-		return new CommitGraphV1(index, commitDataChunk);
+		GraphChangedPathFilterData cpfData = new GraphChangedPathFilterData(
+				bloomFilterIndex, bloomFilterData);
+		return new CommitGraphV1(index, commitDataChunk, cpfData);
 	}
 
 	private void assertChunkNotNull(Object object, int 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
index a074833..8d2789c 100644
--- 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
@@ -25,6 +25,10 @@
 
 	static final int CHUNK_ID_EXTRA_EDGE_LIST = 0x45444745; /* "EDGE" */
 
+	static final int CHUNK_ID_BLOOM_FILTER_INDEX = 0x42494458; /* "BIDX" */
+
+	static final int CHUNK_ID_BLOOM_FILTER_DATA = 0x42444154; /* "BDAT" */
+
 	/**
 	 * 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.
@@ -41,15 +45,15 @@
 	/** 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 */
+	/** EdgeValue &amp; 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
+	 * EdgeValue &amp; 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/CommitGraphLoader.java b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/commitgraph/CommitGraphLoader.java
index 571f5f4..867d522 100644
--- 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
@@ -10,6 +10,8 @@
 
 package org.eclipse.jgit.internal.storage.commitgraph;
 
+import static org.eclipse.jgit.internal.storage.commitgraph.CommitGraphConstants.CHUNK_ID_BLOOM_FILTER_DATA;
+import static org.eclipse.jgit.internal.storage.commitgraph.CommitGraphConstants.CHUNK_ID_BLOOM_FILTER_INDEX;
 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;
@@ -25,9 +27,12 @@
 import java.util.ArrayList;
 import java.util.List;
 
+import org.eclipse.jgit.errors.ConfigInvalidException;
 import org.eclipse.jgit.internal.JGitText;
+import org.eclipse.jgit.lib.ConfigConstants;
 import org.eclipse.jgit.util.IO;
 import org.eclipse.jgit.util.NB;
+import org.eclipse.jgit.util.SystemReader;
 import org.eclipse.jgit.util.io.SilentFileInputStream;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -137,6 +142,17 @@
 			chunks.add(new ChunkSegment(id, offset));
 		}
 
+		boolean readChangedPathFilters;
+		try {
+			readChangedPathFilters = SystemReader.getInstance()
+					.getJGitConfig()
+					.getBoolean(ConfigConstants.CONFIG_COMMIT_GRAPH_SECTION,
+						ConfigConstants.CONFIG_KEY_READ_CHANGED_PATHS, false);
+		} catch (ConfigInvalidException e) {
+			// Use the default value if, for some reason, the config couldn't be read.
+			readChangedPathFilters = false;
+		}
+
 		CommitGraphBuilder builder = CommitGraphBuilder.builder();
 		for (int i = 0; i < numberOfChunks; i++) {
 			long chunkOffset = chunks.get(i).offset;
@@ -164,6 +180,16 @@
 			case CHUNK_ID_EXTRA_EDGE_LIST:
 				builder.addExtraList(buffer);
 				break;
+			case CHUNK_ID_BLOOM_FILTER_INDEX:
+				if (readChangedPathFilters) {
+					builder.addBloomFilterIndex(buffer);
+				}
+				break;
+			case CHUNK_ID_BLOOM_FILTER_DATA:
+				if (readChangedPathFilters) {
+					builder.addBloomFilterData(buffer);
+				}
+				break;
 			default:
 				LOG.warn(MessageFormat.format(
 						JGitText.get().commitGraphChunkUnknown,
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
index da17219..b0a9c83 100644
--- 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
@@ -24,18 +24,20 @@
 
 	private final GraphCommitData commitData;
 
-	CommitGraphV1(GraphObjectIndex index, GraphCommitData commitData) {
+	private final GraphChangedPathFilterData cpfData;
+
+	CommitGraphV1(GraphObjectIndex index, GraphCommitData commitData,
+			GraphChangedPathFilterData cpfData) {
 		this.idx = index;
 		this.commitData = commitData;
+		this.cpfData = cpfData;
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public int findGraphPosition(AnyObjectId commit) {
 		return idx.findGraphPosition(commit);
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public CommitData getCommitData(int graphPos) {
 		if (graphPos < 0 || graphPos >= getCommitCnt()) {
@@ -44,13 +46,16 @@
 		return commitData.getCommitData(graphPos);
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public ObjectId getObjectId(int graphPos) {
 		return idx.getObjectId(graphPos);
 	}
 
-	/** {@inheritDoc} */
+	@Override
+	public ChangedPathFilter getChangedPathFilter(int graphPos) {
+		return cpfData.getChangedPathFilter(graphPos);
+	}
+
 	@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
index a58a9eb..bab2622 100644
--- 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
@@ -10,6 +10,8 @@
 
 package org.eclipse.jgit.internal.storage.commitgraph;
 
+import static org.eclipse.jgit.internal.storage.commitgraph.CommitGraphConstants.CHUNK_ID_BLOOM_FILTER_DATA;
+import static org.eclipse.jgit.internal.storage.commitgraph.CommitGraphConstants.CHUNK_ID_BLOOM_FILTER_INDEX;
 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;
@@ -24,21 +26,31 @@
 import static org.eclipse.jgit.lib.Constants.COMMIT_GENERATION_UNKNOWN;
 import static org.eclipse.jgit.lib.Constants.OBJECT_ID_LENGTH;
 
+import java.io.ByteArrayOutputStream;
 import java.io.IOException;
 import java.io.InterruptedIOException;
 import java.io.OutputStream;
+import java.nio.ByteBuffer;
 import java.text.MessageFormat;
 import java.util.ArrayList;
+import java.util.HashSet;
 import java.util.List;
+import java.util.Optional;
 import java.util.Stack;
 
 import org.eclipse.jgit.annotations.NonNull;
+import org.eclipse.jgit.errors.CorruptObjectException;
+import org.eclipse.jgit.errors.IncorrectObjectTypeException;
 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.ObjectReader;
 import org.eclipse.jgit.lib.ProgressMonitor;
 import org.eclipse.jgit.revwalk.RevCommit;
+import org.eclipse.jgit.revwalk.RevWalk;
+import org.eclipse.jgit.treewalk.EmptyTreeIterator;
+import org.eclipse.jgit.treewalk.TreeWalk;
 import org.eclipse.jgit.util.NB;
 
 /**
@@ -56,10 +68,14 @@
 
 	private static final int GENERATION_NUMBER_MAX = 0x3FFFFFFF;
 
+	private static final int MAX_CHANGED_PATHS = 512;
+
 	private final int hashsz;
 
 	private final GraphCommits graphCommits;
 
+	private final boolean generateChangedPathFilters;
+
 	/**
 	 * Create commit-graph writer for these commits.
 	 *
@@ -67,8 +83,22 @@
 	 *            the commits which will be writen to the commit-graph.
 	 */
 	public CommitGraphWriter(@NonNull GraphCommits graphCommits) {
+		this(graphCommits, false);
+	}
+
+	/**
+	 * Create commit-graph writer for these commits.
+	 *
+	 * @param graphCommits
+	 *            the commits which will be writen to the commit-graph.
+	 * @param generateChangedPathFilters
+	 *            whether changed path filters are generated
+	 */
+	public CommitGraphWriter(@NonNull GraphCommits graphCommits,
+			boolean generateChangedPathFilters) {
 		this.graphCommits = graphCommits;
 		this.hashsz = OBJECT_ID_LENGTH;
+		this.generateChangedPathFilters = generateChangedPathFilters;
 	}
 
 	/**
@@ -80,15 +110,18 @@
 	 *            output stream of commit-graph data. The stream should be
 	 *            buffered by the caller. The caller is responsible for closing
 	 *            the stream.
+	 * @return statistics gathered during the run
 	 * @throws IOException
+	 *             if an error occurred
 	 */
-	public void write(@NonNull ProgressMonitor monitor,
+	public Stats write(@NonNull ProgressMonitor monitor,
 			@NonNull OutputStream commitGraphStream) throws IOException {
+		Stats stats = new Stats();
 		if (graphCommits.size() == 0) {
-			return;
+			return stats;
 		}
 
-		List<ChunkHeader> chunks = createChunks();
+		List<ChunkHeader> chunks = createChunks(stats);
 		long writeCount = 256 + 2 * graphCommits.size()
 				+ graphCommits.getExtraEdgeCnt();
 		monitor.beginTask(
@@ -108,9 +141,12 @@
 		} finally {
 			monitor.endTask();
 		}
+		return stats;
 	}
 
-	private List<ChunkHeader> createChunks() {
+	private List<ChunkHeader> createChunks(Stats stats)
+			throws MissingObjectException,
+			IncorrectObjectTypeException, CorruptObjectException, IOException {
 		List<ChunkHeader> chunks = new ArrayList<>();
 		chunks.add(new ChunkHeader(CHUNK_ID_OID_FANOUT, GRAPH_FANOUT_SIZE));
 		chunks.add(new ChunkHeader(CHUNK_ID_OID_LOOKUP,
@@ -121,6 +157,14 @@
 			chunks.add(new ChunkHeader(CHUNK_ID_EXTRA_EDGE_LIST,
 					graphCommits.getExtraEdgeCnt() * 4));
 		}
+		if (generateChangedPathFilters) {
+			BloomFilterChunks bloomFilterChunks = computeBloomFilterChunks(
+					stats);
+			chunks.add(new ChunkHeader(CHUNK_ID_BLOOM_FILTER_INDEX,
+					bloomFilterChunks.index));
+			chunks.add(new ChunkHeader(CHUNK_ID_BLOOM_FILTER_DATA,
+					bloomFilterChunks.data));
+		}
 		return chunks;
 	}
 
@@ -170,6 +214,17 @@
 			case CHUNK_ID_EXTRA_EDGE_LIST:
 				writeExtraEdges(out);
 				break;
+			case CHUNK_ID_BLOOM_FILTER_INDEX:
+			case CHUNK_ID_BLOOM_FILTER_DATA:
+				if (!chunk.data.isPresent()) {
+					throw new IllegalStateException(
+							"data for this chunk must be precomputed"); //$NON-NLS-1$
+				}
+				chunk.data.get().writeTo(out);
+				break;
+			default:
+				throw new IllegalStateException(
+						"Don't know how to write chunk " + chunkId); //$NON-NLS-1$
 			}
 		}
 	}
@@ -304,6 +359,79 @@
 		return generations;
 	}
 
+	private static Optional<HashSet<ByteBuffer>> computeBloomFilterPaths(
+			ObjectReader or, RevCommit cmit) throws MissingObjectException,
+			IncorrectObjectTypeException, CorruptObjectException, IOException {
+		HashSet<ByteBuffer> paths = new HashSet<>();
+		try (TreeWalk walk = new TreeWalk(null, or)) {
+			walk.setRecursive(true);
+			if (cmit.getParentCount() == 0) {
+				walk.addTree(new EmptyTreeIterator());
+			} else {
+				walk.addTree(cmit.getParent(0).getTree());
+			}
+			walk.addTree(cmit.getTree());
+			while (walk.next()) {
+				if (walk.idEqual(0, 1)) {
+					continue;
+				}
+				byte[] rawPath = walk.getRawPath();
+				paths.add(ByteBuffer.wrap(rawPath));
+				for (int i = 0; i < rawPath.length; i++) {
+					if (rawPath[i] == '/') {
+						paths.add(ByteBuffer.wrap(rawPath, 0, i));
+					}
+					if (paths.size() > MAX_CHANGED_PATHS) {
+						return Optional.empty();
+					}
+				}
+			}
+		}
+		return Optional.of(paths);
+	}
+
+	private BloomFilterChunks computeBloomFilterChunks(Stats stats)
+			throws MissingObjectException, IncorrectObjectTypeException,
+			CorruptObjectException, IOException {
+
+		ByteArrayOutputStream index = new ByteArrayOutputStream();
+		ByteArrayOutputStream data = new ByteArrayOutputStream();
+
+		// Allocate scratch buffer for converting integers into
+		// big-endian bytes.
+		byte[] scratch = new byte[4];
+
+		NB.encodeInt32(scratch, 0, 1); // version 1
+		data.write(scratch);
+		NB.encodeInt32(scratch, 0, ChangedPathFilter.PATH_HASH_COUNT);
+		data.write(scratch);
+		NB.encodeInt32(scratch, 0, ChangedPathFilter.BITS_PER_ENTRY);
+		data.write(scratch);
+		int dataHeaderSize = data.size();
+
+		try (RevWalk rw = new RevWalk(graphCommits.getObjectReader())) {
+			for (RevCommit cmit : graphCommits) {
+				ChangedPathFilter cpf = cmit.getChangedPathFilter(rw);
+				if (cpf != null) {
+					stats.changedPathFiltersReused++;
+				} else {
+					stats.changedPathFiltersComputed++;
+					Optional<HashSet<ByteBuffer>> paths = computeBloomFilterPaths(
+							graphCommits.getObjectReader(), cmit);
+					if (paths.isEmpty()) {
+						cpf = ChangedPathFilter.FULL;
+					} else {
+						cpf = ChangedPathFilter.fromPaths(paths.get());
+					}
+				}
+				cpf.writeTo(data);
+				NB.encodeInt32(scratch, 0, data.size() - dataHeaderSize);
+				index.write(scratch);
+			}
+			return new BloomFilterChunks(index, data);
+		}
+	}
+
 	private void writeExtraEdges(CancellableDigestOutputStream out)
 			throws IOException {
 		byte[] tmp = new byte[4];
@@ -330,9 +458,60 @@
 
 		final long size;
 
+		final Optional<ByteArrayOutputStream> data;
+
 		public ChunkHeader(int id, long size) {
 			this.id = id;
 			this.size = size;
+			this.data = Optional.empty();
+		}
+
+		ChunkHeader(int id, ByteArrayOutputStream data) {
+			this.id = id;
+			this.size = data.size();
+			this.data = Optional.of(data);
+		}
+	}
+
+	private static class BloomFilterChunks {
+		final ByteArrayOutputStream index;
+
+		final ByteArrayOutputStream data;
+
+		BloomFilterChunks(ByteArrayOutputStream index,
+				ByteArrayOutputStream data) {
+			this.index = index;
+			this.data = data;
+		}
+	}
+
+	/**
+	 * Statistics collected during a single commit graph write.
+	 */
+	public static class Stats {
+
+		private long changedPathFiltersReused = 0;
+
+		private long changedPathFiltersComputed = 0;
+
+		/**
+		 * Returns the number of existing changed path filters that were reused
+		 * when writing, for statistical purposes.
+		 *
+		 * @return count of changed path filters
+		 */
+		public long getChangedPathFiltersReused() {
+			return changedPathFiltersReused;
+		}
+
+		/**
+		 * Returns the number of changed path filters that were computed from
+		 * scratch, for statistical purposes.
+		 *
+		 * @return count of changed path filters
+		 */
+		public long getChangedPathFiltersComputed() {
+			return changedPathFiltersComputed;
 		}
 	}
 }
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/commitgraph/GraphChangedPathFilterData.java b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/commitgraph/GraphChangedPathFilterData.java
new file mode 100644
index 0000000..738a42a
--- /dev/null
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/commitgraph/GraphChangedPathFilterData.java
@@ -0,0 +1,68 @@
+/*
+ * Copyright (C) 2023, Google LLC.
+ *
+ * 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.util.NB;
+
+/**
+ * Represents the BIDX and BDAT data found in a commit graph file.
+ */
+class GraphChangedPathFilterData {
+
+	private static final int BIDX_BYTES_PER_ENTRY = 4;
+
+	private static final int BDAT_HEADER_BYTES = 12;
+
+	private final byte[] bloomFilterIndex;
+
+	private final byte[] bloomFilterData;
+
+	/**
+	 * Initialize the GraphChangedPathFilterData.
+	 *
+	 * @param bloomFilterIndex
+	 *            content of BIDX chunk, if it exists
+	 * @param bloomFilterData
+	 *            content of BDAT chunk, if it exists
+	 */
+	GraphChangedPathFilterData(byte[] bloomFilterIndex,
+			byte[] bloomFilterData) {
+
+		if ((bloomFilterIndex == null) != (bloomFilterData == null)) {
+			bloomFilterIndex = null;
+			bloomFilterData = null;
+		}
+		if (bloomFilterData != null
+				&& (NB.decodeUInt32(bloomFilterData,
+						4) != ChangedPathFilter.PATH_HASH_COUNT
+						|| NB.decodeUInt32(bloomFilterData,
+								8) != ChangedPathFilter.BITS_PER_ENTRY)) {
+			bloomFilterIndex = null;
+			bloomFilterData = null;
+		}
+
+		this.bloomFilterIndex = bloomFilterIndex;
+		this.bloomFilterData = bloomFilterData;
+	}
+
+	ChangedPathFilter getChangedPathFilter(int graphPos) {
+		if (bloomFilterIndex == null) {
+			return null;
+		}
+		int priorCumul = graphPos == 0 ? 0
+				: NB.decodeInt32(bloomFilterIndex,
+						graphPos * BIDX_BYTES_PER_ENTRY - BIDX_BYTES_PER_ENTRY);
+		int cumul = NB.decodeInt32(bloomFilterIndex, graphPos * BIDX_BYTES_PER_ENTRY);
+		return ChangedPathFilter.fromFile(bloomFilterData,
+				priorCumul + BDAT_HEADER_BYTES,
+				cumul - priorCumul);
+	}
+}
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
index ccf6d0e..c77d950 100644
--- 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
@@ -23,6 +23,7 @@
 import org.eclipse.jgit.lib.Constants;
 import org.eclipse.jgit.lib.ObjectId;
 import org.eclipse.jgit.lib.ObjectIdOwnerMap;
+import org.eclipse.jgit.lib.ObjectReader;
 import org.eclipse.jgit.lib.ProgressMonitor;
 import org.eclipse.jgit.revwalk.RevCommit;
 import org.eclipse.jgit.revwalk.RevObject;
@@ -56,6 +57,7 @@
 	 * @return the commits' collection which are used by the commit-graph
 	 *         writer. Never null.
 	 * @throws IOException
+	 *             if an error occurred
 	 */
 	public static GraphCommits fromWalk(ProgressMonitor pm,
 			@NonNull Set<? extends ObjectId> wants, @NonNull RevWalk walk)
@@ -78,7 +80,7 @@
 			commits.add(c);
 		}
 		pm.endTask();
-		return new GraphCommits(commits);
+		return new GraphCommits(commits, walk.getObjectReader());
 	}
 
 	private final List<RevCommit> sortedCommits;
@@ -87,13 +89,17 @@
 
 	private final int extraEdgeCnt;
 
+	private final ObjectReader objectReader;
+
 	/**
 	 * Initialize the GraphCommits.
 	 *
 	 * @param commits
 	 *            list of commits with their headers already parsed.
+	 * @param objectReader
+	 *            object reader
 	 */
-	private GraphCommits(List<RevCommit> commits) {
+	private GraphCommits(List<RevCommit> commits, ObjectReader objectReader) {
 		Collections.sort(commits); // sorted by name
 		sortedCommits = commits;
 		commitPosMap = new ObjectIdOwnerMap<>();
@@ -106,6 +112,7 @@
 			commitPosMap.add(new CommitWithPosition(c, i));
 		}
 		this.extraEdgeCnt = cnt;
+		this.objectReader = objectReader;
 	}
 
 	int getOidPosition(RevCommit c) throws MissingObjectException {
@@ -124,7 +131,10 @@
 		return sortedCommits.size();
 	}
 
-	/** {@inheritDoc} */
+	ObjectReader getObjectReader() {
+		return objectReader;
+	}
+
 	@Override
 	public Iterator<RevCommit> iterator() {
 		return sortedCommits.iterator();
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/dfs/BeforeDfsPackIndexLoadedEvent.java b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/dfs/BeforeDfsPackIndexLoadedEvent.java
index cdfd3e9..68fc296 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/dfs/BeforeDfsPackIndexLoadedEvent.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/dfs/BeforeDfsPackIndexLoadedEvent.java
@@ -41,13 +41,11 @@
 		return pack;
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public Class<BeforeDfsPackIndexLoadedListener> getListenerType() {
 		return BeforeDfsPackIndexLoadedListener.class;
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public void dispatch(BeforeDfsPackIndexLoadedListener listener) {
 		listener.onBeforeDfsPackIndexLoaded(this);
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/dfs/BlockBasedFile.java b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/dfs/BlockBasedFile.java
index b1b09ba..ab07475 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/dfs/BlockBasedFile.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/dfs/BlockBasedFile.java
@@ -100,7 +100,9 @@
 
 	DfsBlock getOrLoadBlock(long pos, DfsReader ctx) throws IOException {
 		try (LazyChannel c = new LazyChannel(ctx, desc, ext)) {
-			return cache.getOrLoad(this, pos, ctx, c);
+			DfsBlock block = cache.getOrLoad(this, pos, ctx, c);
+			ctx.emitBlockLoad(this, pos, block);
+			return block;
 		}
 	}
 
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/dfs/DfsBlockCache.java b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/dfs/DfsBlockCache.java
index 0a02180..99b9d55 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/dfs/DfsBlockCache.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/dfs/DfsBlockCache.java
@@ -847,6 +847,7 @@
 		/**
 		 * @return ReadableChannel
 		 * @throws IOException
+		 *             if an IO error occurred
 		 */
 		ReadableChannel get() throws IOException;
 	}
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/dfs/DfsCachedPack.java b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/dfs/DfsCachedPack.java
index 22959e9..d6d3fbf 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/dfs/DfsCachedPack.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/dfs/DfsCachedPack.java
@@ -43,19 +43,16 @@
 		return pack.getPackDescription();
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public long getObjectCount() throws IOException {
 		return getPackDescription().getObjectCount();
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public long getDeltaCount() throws IOException {
 		return getPackDescription().getDeltaCount();
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public boolean hasObject(ObjectToPack obj, StoredObjectRepresentation rep) {
 		return ((DfsObjectRepresentation) rep).pack == pack;
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/dfs/DfsConfig.java b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/dfs/DfsConfig.java
index 2ee23f8..4f0e4a5 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/dfs/DfsConfig.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/dfs/DfsConfig.java
@@ -22,13 +22,11 @@
  * simply clears the config, and saving does nothing.
  */
 public final class DfsConfig extends StoredConfig {
-	/** {@inheritDoc} */
 	@Override
 	public void load() throws IOException, ConfigInvalidException {
 		clear();
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public void save() throws IOException {
 		// TODO actually store this configuration.
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/dfs/DfsGarbageCollector.java b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/dfs/DfsGarbageCollector.java
index 92e23b8..62b55d4 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/dfs/DfsGarbageCollector.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/dfs/DfsGarbageCollector.java
@@ -20,6 +20,7 @@
 import static org.eclipse.jgit.internal.storage.pack.PackExt.BITMAP_INDEX;
 import static org.eclipse.jgit.internal.storage.pack.PackExt.COMMIT_GRAPH;
 import static org.eclipse.jgit.internal.storage.pack.PackExt.INDEX;
+import static org.eclipse.jgit.internal.storage.pack.PackExt.OBJECT_SIZE_INDEX;
 import static org.eclipse.jgit.internal.storage.pack.PackExt.PACK;
 import static org.eclipse.jgit.internal.storage.pack.PackExt.REFTABLE;
 import static org.eclipse.jgit.internal.storage.pack.PackWriter.NONE;
@@ -35,7 +36,6 @@
 import java.util.List;
 import java.util.Set;
 import java.util.concurrent.TimeUnit;
-import java.util.stream.Collectors;
 
 import org.eclipse.jgit.internal.JGitText;
 import org.eclipse.jgit.internal.storage.commitgraph.CommitGraphWriter;
@@ -80,6 +80,8 @@
 	private ReftableConfig reftableConfig;
 	private boolean convertToReftable = true;
 	private boolean writeCommitGraph;
+
+	private boolean writeBloomFilter;
 	private boolean includeDeletes;
 	private long reftableInitialMinUpdateIndex = 1;
 	private long reftableInitialMaxUpdateIndex = 1;
@@ -298,6 +300,20 @@
 	}
 
 	/**
+	 * Toggle bloom filter generation.
+	 * <p>
+	 * False by default.
+	 *
+	 * @param enable
+	 *            Whether bloom filter generation is enabled
+	 * @return {@code this}
+	 */
+	public DfsGarbageCollector setWriteBloomFilter(boolean enable) {
+		writeBloomFilter = enable;
+		return this;
+	}
+
+	/**
 	 * Create a single new pack file containing all of the live objects.
 	 * <p>
 	 * This method safely decides which packs can be expired after the new pack
@@ -681,6 +697,17 @@
 			pack.setIndexVersion(pw.getIndexVersion());
 		}
 
+		if (source != UNREACHABLE_GARBAGE && packConfig.getMinBytesForObjSizeIndex() >= 0) {
+			try (DfsOutputStream out = objdb.writeFile(pack,
+					OBJECT_SIZE_INDEX)) {
+				CountingOutputStream cnt = new CountingOutputStream(out);
+				pw.writeObjectSizeIndex(cnt);
+				pack.addFileExt(OBJECT_SIZE_INDEX);
+				pack.setFileSize(OBJECT_SIZE_INDEX, cnt.getCount());
+				pack.setBlockSize(OBJECT_SIZE_INDEX, out.blockSize());
+			}
+		}
+
 		if (pw.prepareBitmapIndex(pm)) {
 			try (DfsOutputStream out = objdb.writeFile(pack, BITMAP_INDEX)) {
 				CountingOutputStream cnt = new CountingOutputStream(out);
@@ -755,18 +782,17 @@
 			return;
 		}
 
-		Set<ObjectId> allTips = refsBefore.stream().map(Ref::getObjectId)
-				.collect(Collectors.toUnmodifiableSet());
-
 		try (DfsOutputStream out = objdb.writeFile(pack, COMMIT_GRAPH);
 				RevWalk pool = new RevWalk(ctx)) {
-			GraphCommits gcs = GraphCommits.fromWalk(pm, allTips, pool);
+			GraphCommits gcs = GraphCommits.fromWalk(pm, allHeadsAndTags, pool);
 			CountingOutputStream cnt = new CountingOutputStream(out);
-			CommitGraphWriter writer = new CommitGraphWriter(gcs);
-			writer.write(pm, cnt);
+			CommitGraphWriter writer = new CommitGraphWriter(gcs,
+					writeBloomFilter);
+			CommitGraphWriter.Stats stats = writer.write(pm, cnt);
 			pack.addFileExt(COMMIT_GRAPH);
 			pack.setFileSize(COMMIT_GRAPH, cnt.getCount());
 			pack.setBlockSize(COMMIT_GRAPH, out.blockSize());
+			pack.setCommitGraphStats(stats);
 		}
 	}
 }
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/dfs/DfsInserter.java b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/dfs/DfsInserter.java
index a2fb67f..2f8d964 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/dfs/DfsInserter.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/dfs/DfsInserter.java
@@ -11,6 +11,7 @@
 package org.eclipse.jgit.internal.storage.dfs;
 
 import static org.eclipse.jgit.internal.storage.pack.PackExt.INDEX;
+import static org.eclipse.jgit.internal.storage.pack.PackExt.OBJECT_SIZE_INDEX;
 import static org.eclipse.jgit.internal.storage.pack.PackExt.PACK;
 import static org.eclipse.jgit.lib.Constants.OBJ_OFS_DELTA;
 import static org.eclipse.jgit.lib.Constants.OBJ_REF_DELTA;
@@ -42,6 +43,7 @@
 import org.eclipse.jgit.internal.JGitText;
 import org.eclipse.jgit.internal.storage.file.PackIndex;
 import org.eclipse.jgit.internal.storage.file.PackIndexWriter;
+import org.eclipse.jgit.internal.storage.file.PackObjectSizeIndexWriter;
 import org.eclipse.jgit.internal.storage.pack.PackExt;
 import org.eclipse.jgit.lib.AbbreviatedObjectId;
 import org.eclipse.jgit.lib.AnyObjectId;
@@ -52,6 +54,7 @@
 import org.eclipse.jgit.lib.ObjectLoader;
 import org.eclipse.jgit.lib.ObjectReader;
 import org.eclipse.jgit.lib.ObjectStream;
+import org.eclipse.jgit.storage.pack.PackConfig;
 import org.eclipse.jgit.transport.PackedObjectInfo;
 import org.eclipse.jgit.util.BlockList;
 import org.eclipse.jgit.util.IO;
@@ -106,19 +109,16 @@
 		this.compression = compression;
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public DfsPackParser newPackParser(InputStream in) throws IOException {
 		return new DfsPackParser(db, this, in);
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public ObjectReader newReader() {
 		return new Reader();
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public ObjectId insert(int type, byte[] data, int off, int len)
 			throws IOException {
@@ -132,10 +132,9 @@
 		long offset = beginObject(type, len);
 		packOut.compress.write(data, off, len);
 		packOut.compress.finish();
-		return endObject(id, offset);
+		return endObject(id, offset, len, type);
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public ObjectId insert(int type, long len, InputStream in)
 			throws IOException {
@@ -152,16 +151,17 @@
 		md.update(Constants.encodeASCII(len));
 		md.update((byte) 0);
 
-		while (0 < len) {
-			int n = in.read(buf, 0, (int) Math.min(buf.length, len));
+		long inLength = len;
+		while (0 < inLength) {
+			int n = in.read(buf, 0, (int) Math.min(buf.length, inLength));
 			if (n <= 0)
 				throw new EOFException();
 			md.update(buf, 0, n);
 			packOut.compress.write(buf, 0, n);
-			len -= n;
+			inLength -= n;
 		}
 		packOut.compress.finish();
-		return endObject(md.toObjectId(), offset);
+		return endObject(md.toObjectId(), offset, len, type);
 	}
 
 	private byte[] insertBuffer(long len) {
@@ -178,7 +178,6 @@
 		return buf;
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public void flush() throws IOException {
 		if (packDsc == null)
@@ -196,6 +195,11 @@
 		sortObjectsById();
 
 		PackIndex index = writePackIndex(packDsc, packHash, objectList);
+		PackConfig pConfig = new PackConfig(db.getRepository().getConfig());
+		if (pConfig.isWriteObjSizeIndex()) {
+			writeObjectSizeIndex(packDsc, objectList,
+					pConfig.getMinBytesForObjSizeIndex());
+		}
 		db.commitPack(Collections.singletonList(packDsc), null);
 		rollback = false;
 
@@ -206,7 +210,6 @@
 		clear();
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public void close() {
 		if (packOut != null) {
@@ -244,10 +247,12 @@
 		return offset;
 	}
 
-	private ObjectId endObject(ObjectId id, long offset) {
+	private ObjectId endObject(ObjectId id, long offset, long inflatedSize, int type) {
 		PackedObjectInfo obj = new PackedObjectInfo(id);
+		obj.setType(type);
 		obj.setOffset(offset);
 		obj.setCRC((int) packOut.crc32.getValue());
+		obj.setFullSize(inflatedSize);
 		objectList.add(obj);
 		objectMap.addIfAbsent(obj);
 		return id;
@@ -317,6 +322,18 @@
 		PackIndexWriter.createVersion(out, INDEX_VERSION).write(list, packHash);
 	}
 
+	void writeObjectSizeIndex(DfsPackDescription pack,
+			List<PackedObjectInfo> packedObjs, int minSize) throws IOException {
+		try (DfsOutputStream os = db.writeFile(pack, PackExt.OBJECT_SIZE_INDEX);
+				CountingOutputStream cnt = new CountingOutputStream(os)) {
+			PackObjectSizeIndexWriter.createWriter(os, minSize)
+					.write(packedObjs);
+			pack.addFileExt(OBJECT_SIZE_INDEX);
+			pack.setBlockSize(OBJECT_SIZE_INDEX, os.blockSize());
+			pack.setFileSize(OBJECT_SIZE_INDEX, cnt.getCount());
+		}
+	}
+
 	private class PackStream extends OutputStream {
 		private final DfsOutputStream out;
 		private final MessageDigest md;
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/dfs/DfsObjDatabase.java b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/dfs/DfsObjDatabase.java
index 46ec87d..faeafce 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/dfs/DfsObjDatabase.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/dfs/DfsObjDatabase.java
@@ -241,13 +241,11 @@
 		this.packComparator = packComparator;
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public DfsReader newReader() {
 		return new DfsReader(this);
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public ObjectInserter newInserter() {
 		return new DfsInserter(this);
@@ -657,7 +655,6 @@
 		packList.set(NO_PACKS);
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public void close() {
 		packList.set(NO_PACKS);
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/dfs/DfsObjectRepresentation.java b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/dfs/DfsObjectRepresentation.java
index 8e124e3..885582f 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/dfs/DfsObjectRepresentation.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/dfs/DfsObjectRepresentation.java
@@ -24,25 +24,21 @@
 		this.pack = pack;
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public int getFormat() {
 		return format;
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public int getWeight() {
 		return (int) Math.min(length, Integer.MAX_VALUE);
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public ObjectId getDeltaBase() {
 		return baseId;
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public boolean wasDeltaAttempted() {
 		switch (pack.getPackDescription().getPackSource()) {
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/dfs/DfsObjectToPack.java b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/dfs/DfsObjectToPack.java
index 10fa236..c2feab8 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/dfs/DfsObjectToPack.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/dfs/DfsObjectToPack.java
@@ -39,14 +39,12 @@
 		setExtendedFlag(FLAG_FOUND);
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	protected void clearReuseAsIs() {
 		super.clearReuseAsIs();
 		pack = null;
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public void select(StoredObjectRepresentation ref) {
 		DfsObjectRepresentation ptr = (DfsObjectRepresentation) ref;
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/dfs/DfsOutputStream.java b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/dfs/DfsOutputStream.java
index 7cf91a4..c74a1e1 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/dfs/DfsOutputStream.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/dfs/DfsOutputStream.java
@@ -39,13 +39,11 @@
 		return 0;
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public void write(int b) throws IOException {
 		write(new byte[] { (byte) b });
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public abstract void write(byte[] buf, int off, int len) throws IOException;
 
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/dfs/DfsPackDescription.java b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/dfs/DfsPackDescription.java
index 4f418ab..663190a 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/dfs/DfsPackDescription.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/dfs/DfsPackDescription.java
@@ -17,6 +17,7 @@
 import java.util.Comparator;
 
 import org.eclipse.jgit.annotations.NonNull;
+import org.eclipse.jgit.internal.storage.commitgraph.CommitGraphWriter;
 import org.eclipse.jgit.internal.storage.dfs.DfsObjDatabase.PackSource;
 import org.eclipse.jgit.internal.storage.pack.PackExt;
 import org.eclipse.jgit.internal.storage.reftable.ReftableWriter;
@@ -144,6 +145,7 @@
 
 	private PackStatistics packStats;
 	private ReftableWriter.Stats refStats;
+	private CommitGraphWriter.Stats commitGraphStats;
 	private int extensions;
 	private int indexVersion;
 	private long estimatedPackSize;
@@ -481,6 +483,19 @@
 	}
 
 	/**
+	 * Get stats from the sibling commit graph, if created.
+	 *
+	 * @return stats from the sibling commit graph, if created.
+	 */
+	public CommitGraphWriter.Stats getCommitGraphStats() {
+		return commitGraphStats;
+	}
+
+	void setCommitGraphStats(CommitGraphWriter.Stats stats) {
+		this.commitGraphStats = stats;
+	}
+
+	/**
 	 * Discard the pack statistics, if it was populated.
 	 *
 	 * @return {@code this}
@@ -512,13 +527,11 @@
 		return this;
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public int hashCode() {
 		return packName.hashCode();
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public boolean equals(Object b) {
 		if (b instanceof DfsPackDescription) {
@@ -539,7 +552,6 @@
 		}
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public String toString() {
 		return getFileName(PackExt.PACK);
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/dfs/DfsPackFile.java b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/dfs/DfsPackFile.java
index c745b8e..ecbfa74 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/dfs/DfsPackFile.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/dfs/DfsPackFile.java
@@ -16,6 +16,7 @@
 import static org.eclipse.jgit.internal.storage.pack.PackExt.BITMAP_INDEX;
 import static org.eclipse.jgit.internal.storage.pack.PackExt.COMMIT_GRAPH;
 import static org.eclipse.jgit.internal.storage.pack.PackExt.INDEX;
+import static org.eclipse.jgit.internal.storage.pack.PackExt.OBJECT_SIZE_INDEX;
 import static org.eclipse.jgit.internal.storage.pack.PackExt.PACK;
 import static org.eclipse.jgit.internal.storage.pack.PackExt.REVERSE_INDEX;
 
@@ -42,7 +43,10 @@
 import org.eclipse.jgit.internal.storage.commitgraph.CommitGraphLoader;
 import org.eclipse.jgit.internal.storage.file.PackBitmapIndex;
 import org.eclipse.jgit.internal.storage.file.PackIndex;
+import org.eclipse.jgit.internal.storage.file.PackObjectSizeIndex;
+import org.eclipse.jgit.internal.storage.file.PackObjectSizeIndexLoader;
 import org.eclipse.jgit.internal.storage.file.PackReverseIndex;
+import org.eclipse.jgit.internal.storage.file.PackReverseIndexFactory;
 import org.eclipse.jgit.internal.storage.pack.BinaryDelta;
 import org.eclipse.jgit.internal.storage.pack.PackOutputStream;
 import org.eclipse.jgit.internal.storage.pack.StoredObjectRepresentation;
@@ -75,6 +79,11 @@
 	/** Index of compressed commit graph mapping entire object graph. */
 	private volatile CommitGraph commitGraph;
 
+	/** Index by size */
+	private boolean objectSizeIndexLoadAttempted;
+
+	private volatile PackObjectSizeIndex objectSizeIndex;
+
 	/**
 	 * Objects we have tried to read, and discovered to be corrupt.
 	 * <p>
@@ -147,6 +156,7 @@
 		return idx(ctx);
 	}
 
+	@SuppressWarnings("boxing")
 	private PackIndex idx(DfsReader ctx) throws IOException {
 		if (index != null) {
 			return index;
@@ -172,6 +182,7 @@
 			PackIndex idx = idxref.get();
 			if (index == null && idx != null) {
 				index = idx;
+				ctx.emitIndexLoad(desc, INDEX, System.identityHashCode(idx));
 			}
 			return index;
 		} catch (IOException e) {
@@ -195,6 +206,7 @@
 	 * @throws java.io.IOException
 	 *             the bitmap index is not available, or is corrupt.
 	 */
+	@SuppressWarnings("boxing")
 	public PackBitmapIndex getBitmapIndex(DfsReader ctx) throws IOException {
 		if (invalid || isGarbage() || !desc.hasFileExt(BITMAP_INDEX)) {
 			return null;
@@ -217,6 +229,7 @@
 		PackBitmapIndex bmidx = idxref.get();
 		if (bitmapIndex == null && bmidx != null) {
 			bitmapIndex = bmidx;
+			ctx.emitIndexLoad(desc, BITMAP_INDEX, System.identityHashCode(bmidx));
 		}
 		return bitmapIndex;
 	}
@@ -232,6 +245,7 @@
 	 * @throws java.io.IOException
 	 *             the Commit Graph is not available, or is corrupt.
 	 */
+	@SuppressWarnings("boxing")
 	public CommitGraph getCommitGraph(DfsReader ctx) throws IOException {
 		if (invalid || isGarbage() || !desc.hasFileExt(COMMIT_GRAPH)) {
 			return null;
@@ -254,11 +268,23 @@
 		CommitGraph cg = cgref.get();
 		if (commitGraph == null && cg != null) {
 			commitGraph = cg;
+			ctx.emitIndexLoad(desc, COMMIT_GRAPH, System.identityHashCode(cg));
 		}
 		return commitGraph;
 	}
 
-	PackReverseIndex getReverseIdx(DfsReader ctx) throws IOException {
+	/**
+	 * Get the PackReverseIndex for this PackFile.
+	 *
+	 * @param ctx
+	 *            reader context to support reading from the backing store if
+	 *            the index is not already loaded in memory
+	 * @return the PackReverseIndex
+	 * @throws java.io.IOException
+	 *             the pack index is not available, or is corrupt
+	 */
+	@SuppressWarnings("boxing")
+	public PackReverseIndex getReverseIdx(DfsReader ctx) throws IOException {
 		if (reverseIndex != null) {
 			return reverseIndex;
 		}
@@ -277,10 +303,46 @@
 		PackReverseIndex revidx = revref.get();
 		if (reverseIndex == null && revidx != null) {
 			reverseIndex = revidx;
+			ctx.emitIndexLoad(desc, REVERSE_INDEX, System.identityHashCode(revidx));
 		}
 		return reverseIndex;
 	}
 
+	@SuppressWarnings("boxing")
+	private PackObjectSizeIndex getObjectSizeIndex(DfsReader ctx)
+			throws IOException {
+		if (objectSizeIndex != null) {
+			return objectSizeIndex;
+		}
+
+		if (objectSizeIndexLoadAttempted) {
+			// Pack doesn't have object size index
+			return null;
+		}
+
+		DfsStreamKey objSizeKey = desc.getStreamKey(OBJECT_SIZE_INDEX);
+		AtomicBoolean cacheHit = new AtomicBoolean(true);
+		try {
+			DfsBlockCache.Ref<PackObjectSizeIndex> sizeIdxRef = cache
+					.getOrLoadRef(objSizeKey, REF_POSITION, () -> {
+						cacheHit.set(false);
+						return loadObjectSizeIndex(ctx, objSizeKey);
+					});
+			if (cacheHit.get()) {
+				ctx.stats.objectSizeIndexCacheHit++;
+			}
+			PackObjectSizeIndex sizeIdx = sizeIdxRef.get();
+			if (objectSizeIndex == null && sizeIdx != null) {
+				objectSizeIndex = sizeIdx;
+				ctx.emitIndexLoad(desc, OBJECT_SIZE_INDEX, System.identityHashCode(sizeIdx));
+			}
+		} finally {
+			objectSizeIndexLoadAttempted = true;
+		}
+
+		return objectSizeIndex;
+	}
+
 	/**
 	 * Check if an object is stored within this pack.
 	 *
@@ -374,6 +436,7 @@
 			if (sz > 0) {
 				rc.setReadAheadBytes(sz);
 			}
+			//TODO(ifrade): report ctx.emitBlockLoaded for this copy
 			if (cache.shouldCopyThroughCache(length)) {
 				copyPackThroughCache(out, ctx, rc);
 			} else {
@@ -957,6 +1020,81 @@
 		}
 	}
 
+	/**
+	 * Return if this packfile has an object size index attached.
+	 *
+	 * This loads the index if it is not already in memory.
+	 *
+	 * @param ctx
+	 *            reader context to support reading from the backing store if
+	 *            the object size index is not already loaded in memory.
+	 * @return true if the packfile has an object size index.
+	 * @throws IOException
+	 *             a problem accessing storage while looking for the index
+	 */
+	boolean hasObjectSizeIndex(DfsReader ctx) throws IOException {
+			return getObjectSizeIndex(ctx) != null;
+	}
+
+	/**
+	 * Return minimum size for an object to be included in the object size
+	 * index.
+	 *
+	 * Caller must make sure the pack has an object size index with
+	 * {@link #hasObjectSizeIndex} before calling this method.
+	 *
+	 * @param ctx
+	 *            reader context to support reading from the backing store if
+	 *            the object size index is not already loaded in memory.
+	 * @return minimum size for indexing in bytes
+	 * @throws IOException
+	 *             no object size index or a problem loading it.
+	 */
+	int getObjectSizeIndexThreshold(DfsReader ctx) throws IOException {
+		PackObjectSizeIndex idx = getObjectSizeIndex(ctx);
+		if (idx == null) {
+			throw new IOException("Asking threshold of non-existing obj-size"); //$NON-NLS-1$
+		}
+		return idx.getThreshold();
+	}
+
+	/**
+	 * Return the size of the object from the object-size index. The object
+	 * should be a blob. Any other type is not indexed and returns -1.
+	 *
+	 * Caller MUST be sure that the object is in the pack (e.g. with
+	 * {@link #hasObject(DfsReader, AnyObjectId)}) and the pack has object size
+	 * index (e.g. with {@link #hasObjectSizeIndex(DfsReader)}) before asking
+	 * the indexed size.
+	 *
+	 * @param ctx
+	 *            reader context to support reading from the backing store if
+	 *            the object size index is not already loaded in memory.
+	 * @param id
+	 *            object id of an object in the pack
+	 * @return size of the object from the index. Negative if object is not in
+	 *         the index (below threshold or not a blob)
+	 * @throws IOException
+	 *             could not read the object size index. IO problem or the pack
+	 *             doesn't have it.
+	 */
+	long getIndexedObjectSize(DfsReader ctx, AnyObjectId id)
+			throws IOException {
+		int idxPosition = idx(ctx).findPosition(id);
+		if (idxPosition < 0) {
+			throw new IllegalArgumentException(
+					"Cannot get size from index since object is not in pack"); //$NON-NLS-1$
+		}
+
+		PackObjectSizeIndex sizeIdx = getObjectSizeIndex(ctx);
+		if (sizeIdx == null) {
+			throw new IllegalStateException(
+					"Asking indexed size from a pack without object size index"); //$NON-NLS-1$
+		}
+
+		return sizeIdx.getSize(idxPosition);
+	}
+
 	void representation(DfsObjectRepresentation r, final long pos,
 			DfsReader ctx, PackReverseIndex rev)
 			throws IOException {
@@ -1036,6 +1174,7 @@
 		}
 	}
 
+	@SuppressWarnings("boxing")
 	private DfsBlockCache.Ref<PackIndex> loadPackIndex(
 			DfsReader ctx, DfsStreamKey idxKey) throws IOException {
 		try {
@@ -1044,6 +1183,7 @@
 			try (ReadableChannel rc = ctx.db.openFile(desc, INDEX)) {
 				PackIndex idx = PackIndex.read(alignTo8kBlocks(rc));
 				ctx.stats.readIdxBytes += rc.position();
+				ctx.emitIndexLoad(desc, INDEX, System.identityHashCode(idx));
 				index = idx;
 				return new DfsBlockCache.Ref<>(
 						idxKey,
@@ -1064,12 +1204,14 @@
 		}
 	}
 
+	@SuppressWarnings("boxing")
 	private DfsBlockCache.Ref<PackReverseIndex> loadReverseIdx(
 			DfsReader ctx, DfsStreamKey revKey, PackIndex idx) {
 		ctx.stats.readReverseIdx++;
 		long start = System.nanoTime();
-		PackReverseIndex revidx = new PackReverseIndex(idx);
+		PackReverseIndex revidx = PackReverseIndexFactory.computeFromIndex(idx);
 		reverseIndex = revidx;
+		ctx.emitIndexLoad(desc, REVERSE_INDEX, System.identityHashCode(revidx));
 		ctx.stats.readReverseIdxMicros += elapsedMicros(start);
 		return new DfsBlockCache.Ref<>(
 				revKey,
@@ -1078,6 +1220,41 @@
 				revidx);
 	}
 
+	@SuppressWarnings("boxing")
+	private DfsBlockCache.Ref<PackObjectSizeIndex> loadObjectSizeIndex(
+			DfsReader ctx, DfsStreamKey objectSizeIndexKey) throws IOException {
+		ctx.stats.readObjectSizeIndex++;
+		long start = System.nanoTime();
+		long size = 0;
+		Exception parsingError = null;
+		try (ReadableChannel rc = ctx.db.openFile(desc, OBJECT_SIZE_INDEX)) {
+			try {
+				objectSizeIndex = PackObjectSizeIndexLoader
+						.load(Channels.newInputStream(rc));
+				size = rc.position();
+				ctx.emitIndexLoad(desc, OBJECT_SIZE_INDEX, System.identityHashCode(objectSizeIndex));
+			} catch (IOException e) {
+				parsingError = e;
+			}
+		} catch (IOException e) {
+			// No object size index in this pack
+			return new DfsBlockCache.Ref<>(objectSizeIndexKey, REF_POSITION, 0,
+					null);
+		}
+
+		if (parsingError != null) {
+			throw new IOException(
+					MessageFormat.format(DfsText.get().shortReadOfIndex,
+							desc.getFileName(OBJECT_SIZE_INDEX)),
+					parsingError);
+		}
+
+		ctx.stats.readObjectSizeIndexBytes += size;
+		ctx.stats.readObjectSizeIndexMicros += elapsedMicros(start);
+		return new DfsBlockCache.Ref<>(objectSizeIndexKey, REF_POSITION, size,
+				objectSizeIndex);
+	}
+
 	private DfsBlockCache.Ref<PackBitmapIndex> loadBitmapIndex(DfsReader ctx,
 			DfsStreamKey bitmapKey) throws IOException {
 		ctx.stats.readBitmap++;
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/dfs/DfsPackParser.java b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/dfs/DfsPackParser.java
index d8e191c..8c7b0ec 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/dfs/DfsPackParser.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/dfs/DfsPackParser.java
@@ -26,6 +26,7 @@
 import org.eclipse.jgit.lib.AnyObjectId;
 import org.eclipse.jgit.lib.Constants;
 import org.eclipse.jgit.lib.ProgressMonitor;
+import org.eclipse.jgit.storage.pack.PackConfig;
 import org.eclipse.jgit.transport.PackLock;
 import org.eclipse.jgit.transport.PackParser;
 import org.eclipse.jgit.transport.PackedObjectInfo;
@@ -101,7 +102,6 @@
 		this.packDigest = Constants.newMessageDigest();
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public PackLock parse(ProgressMonitor receiving, ProgressMonitor resolving)
 			throws IOException {
@@ -123,6 +123,11 @@
 			packDsc.setBlockSize(PACK, blockSize);
 
 			writePackIndex();
+			PackConfig pConfig = new PackConfig(objdb.getRepository().getConfig());
+			if (pConfig.isWriteObjSizeIndex()) {
+				objins.writeObjectSizeIndex(packDsc, getSortedObjectList(null),
+						pConfig.getMinBytesForObjSizeIndex());
+			}
 			objdb.commitPack(Collections.singletonList(packDsc), null);
 			rollback = false;
 
@@ -172,7 +177,6 @@
 		return packDsc;
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	protected void onPackHeader(long objectCount) throws IOException {
 		if (objectCount == 0) {
@@ -194,34 +198,29 @@
 		currBuf = new byte[blockSize];
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	protected void onBeginWholeObject(long streamPosition, int type,
 			long inflatedSize) throws IOException {
 		crc.reset();
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	protected void onEndWholeObject(PackedObjectInfo info) throws IOException {
 		info.setCRC((int) crc.getValue());
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	protected void onBeginOfsDelta(long streamPosition,
 			long baseStreamPosition, long inflatedSize) throws IOException {
 		crc.reset();
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	protected void onBeginRefDelta(long streamPosition, AnyObjectId baseId,
 			long inflatedSize) throws IOException {
 		crc.reset();
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	protected UnresolvedDelta onEndDelta() throws IOException {
 		UnresolvedDelta delta = new UnresolvedDelta();
@@ -229,28 +228,24 @@
 		return delta;
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	protected void onInflatedObjectData(PackedObjectInfo obj, int typeCode,
 			byte[] data) throws IOException {
 		// DfsPackParser ignores this event.
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	protected void onObjectHeader(Source src, byte[] raw, int pos, int len)
 			throws IOException {
 		crc.update(raw, pos, len);
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	protected void onObjectData(Source src, byte[] raw, int pos, int len)
 			throws IOException {
 		crc.update(raw, pos, len);
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	protected void onStoreStream(byte[] raw, int pos, int len)
 			throws IOException {
@@ -297,7 +292,6 @@
 		return v;
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	protected void onPackFooter(byte[] hash) throws IOException {
 		// The base class will validate the original hash matches
@@ -307,7 +301,6 @@
 		packHash = hash;
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	protected ObjectTypeAndSize seekDatabase(PackedObjectInfo obj,
 			ObjectTypeAndSize info) throws IOException {
@@ -316,7 +309,6 @@
 		return readObjectHeader(info);
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	protected ObjectTypeAndSize seekDatabase(UnresolvedDelta delta,
 			ObjectTypeAndSize info) throws IOException {
@@ -325,7 +317,6 @@
 		return readObjectHeader(info);
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	protected int readDatabase(byte[] dst, int pos, int cnt) throws IOException {
 		if (cnt == 0)
@@ -381,13 +372,11 @@
 		return (pos / blockSize) * blockSize;
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	protected boolean checkCRC(int oldCRC) {
 		return oldCRC == (int) crc.getValue();
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	protected boolean onAppendBase(final int typeCode, final byte[] data,
 			final PackedObjectInfo info) throws IOException {
@@ -427,7 +416,6 @@
 		return true;
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	protected void onEndThinPack() throws IOException {
 		// Normally when a thin pack is closed the pack header gets
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/dfs/DfsPacksChangedEvent.java b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/dfs/DfsPacksChangedEvent.java
index 750c118..f4e863d 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/dfs/DfsPacksChangedEvent.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/dfs/DfsPacksChangedEvent.java
@@ -18,13 +18,11 @@
  */
 public class DfsPacksChangedEvent
 		extends RepositoryEvent<DfsPacksChangedListener> {
-	/** {@inheritDoc} */
 	@Override
 	public Class<DfsPacksChangedListener> getListenerType() {
 		return DfsPacksChangedListener.class;
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public void dispatch(DfsPacksChangedListener listener) {
 		listener.onPacksChanged(this);
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/dfs/DfsReader.java b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/dfs/DfsReader.java
index 8d8a766..3f0adcb 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/dfs/DfsReader.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/dfs/DfsReader.java
@@ -34,6 +34,8 @@
 import org.eclipse.jgit.internal.JGitText;
 import org.eclipse.jgit.internal.storage.commitgraph.CommitGraph;
 import org.eclipse.jgit.internal.storage.dfs.DfsObjDatabase.PackList;
+import org.eclipse.jgit.internal.storage.dfs.DfsObjDatabase.PackSource;
+import org.eclipse.jgit.internal.storage.dfs.DfsReader.PackLoadListener.DfsBlockData;
 import org.eclipse.jgit.internal.storage.file.BitmapIndexImpl;
 import org.eclipse.jgit.internal.storage.file.PackBitmapIndex;
 import org.eclipse.jgit.internal.storage.file.PackIndex;
@@ -41,6 +43,7 @@
 import org.eclipse.jgit.internal.storage.pack.CachedPack;
 import org.eclipse.jgit.internal.storage.pack.ObjectReuseAsIs;
 import org.eclipse.jgit.internal.storage.pack.ObjectToPack;
+import org.eclipse.jgit.internal.storage.pack.PackExt;
 import org.eclipse.jgit.internal.storage.pack.PackOutputStream;
 import org.eclipse.jgit.internal.storage.pack.PackWriter;
 import org.eclipse.jgit.lib.AbbreviatedObjectId;
@@ -49,6 +52,7 @@
 import org.eclipse.jgit.lib.AsyncObjectSizeQueue;
 import org.eclipse.jgit.lib.BitmapIndex;
 import org.eclipse.jgit.lib.BitmapIndex.BitmapBuilder;
+import org.eclipse.jgit.lib.Constants;
 import org.eclipse.jgit.lib.InflaterCache;
 import org.eclipse.jgit.lib.ObjectId;
 import org.eclipse.jgit.lib.ObjectLoader;
@@ -78,6 +82,7 @@
 	private DeltaBaseCache baseCache;
 	private DfsPackFile last;
 	private boolean avoidUnreachable;
+	private List<PackLoadListener> packLoadListeners = new ArrayList<>();
 
 	/**
 	 * Initialize a new DfsReader
@@ -100,19 +105,16 @@
 		return baseCache;
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public ObjectReader newReader() {
 		return db.newReader();
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public void setAvoidUnreachableObjects(boolean avoid) {
 		avoidUnreachable = avoid;
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public BitmapIndex getBitmapIndex() throws IOException {
 		for (DfsPackFile pack : db.getPacks()) {
@@ -123,7 +125,6 @@
 		return null;
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public Optional<CommitGraph> getCommitGraph() throws IOException {
 		for (DfsPackFile pack : db.getPacks()) {
@@ -135,7 +136,6 @@
 		return Optional.empty();
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public Collection<CachedPack> getCachedPacksAndUpdate(
 		BitmapBuilder needBitmap) throws IOException {
@@ -148,7 +148,6 @@
 		return Collections.emptyList();
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public Collection<ObjectId> resolve(AbbreviatedObjectId id)
 			throws IOException {
@@ -177,7 +176,6 @@
 		}
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public boolean has(AnyObjectId objectId) throws IOException {
 		if (last != null
@@ -207,7 +205,6 @@
 		return false;
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public ObjectLoader open(AnyObjectId objectId, int typeHint)
 			throws MissingObjectException, IncorrectObjectTypeException,
@@ -262,7 +259,6 @@
 		return null;
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public Set<ObjectId> getShallowCommits() {
 		return Collections.emptySet();
@@ -370,7 +366,6 @@
 		return avoidUnreachable && pack.isGarbage();
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public <T extends ObjectId> AsyncObjectLoaderQueue<T> open(
 			Iterable<T> objectIds, final boolean reportMissing) {
@@ -430,7 +425,6 @@
 		};
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public <T extends ObjectId> AsyncObjectSizeQueue<T> getObjectSize(
 			Iterable<T> objectIds, final boolean reportMissing) {
@@ -492,7 +486,6 @@
 		};
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public long getObjectSize(AnyObjectId objectId, int typeHint)
 			throws MissingObjectException, IncorrectObjectTypeException,
@@ -523,6 +516,59 @@
 		throw new MissingObjectException(objectId.copy(), typeHint);
 	}
 
+
+	@Override
+	public boolean isNotLargerThan(AnyObjectId objectId, int typeHint,
+			long limit) throws MissingObjectException,
+			IncorrectObjectTypeException, IOException {
+		DfsPackFile pack = findPackWithObject(objectId);
+		if (pack == null) {
+			if (typeHint == OBJ_ANY) {
+				throw new MissingObjectException(objectId.copy(),
+						JGitText.get().unknownObjectType2);
+			}
+			throw new MissingObjectException(objectId.copy(), typeHint);
+		}
+
+		stats.isNotLargerThanCallCount += 1;
+		if (typeHint != Constants.OBJ_BLOB || !pack.hasObjectSizeIndex(this)) {
+			return pack.getObjectSize(this, objectId) <= limit;
+		}
+
+		long sz = pack.getIndexedObjectSize(this, objectId);
+		if (sz < 0) {
+			stats.objectSizeIndexMiss += 1;
+		} else {
+			stats.objectSizeIndexHit += 1;
+		}
+
+		// Got size from index or we didn't but we are sure it should be there.
+		if (sz >= 0 || pack.getObjectSizeIndexThreshold(this) <= limit) {
+			return sz <= limit;
+		}
+
+		return pack.getObjectSize(this, objectId) <= limit;
+	}
+
+	private DfsPackFile findPackWithObject(AnyObjectId objectId)
+			throws IOException {
+		if (last != null && !skipGarbagePack(last)
+				&& last.hasObject(this, objectId)) {
+			return last;
+		}
+		PackList packList = db.getPackList();
+		// hasImpl doesn't check "last", but leaves "last" pointing to the pack
+		// with the object
+		if (hasImpl(packList, objectId)) {
+			return last;
+		} else if (packList.dirty()) {
+			if (hasImpl(db.getPackList(), objectId)) {
+				return last;
+			}
+		}
+		return null;
+	}
+
 	private long getObjectSizeImpl(PackList packList, AnyObjectId objectId)
 			throws IOException {
 		for (DfsPackFile pack : packList.packs) {
@@ -538,7 +584,6 @@
 		return -1;
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public DfsObjectToPack newObjectToPack(AnyObjectId objectId, int type) {
 		return new DfsObjectToPack(objectId, type);
@@ -642,7 +687,6 @@
 		return tmp;
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public void copyObjectAsIs(PackOutputStream out, ObjectToPack otp,
 			boolean validate) throws IOException,
@@ -651,7 +695,6 @@
 		src.pack.copyAsIs(out, src, validate, this);
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public void writeObjects(PackOutputStream out, List<ObjectToPack> list)
 			throws IOException {
@@ -659,7 +702,6 @@
 			out.writeObject(otp);
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public void copyPackAsIs(PackOutputStream out, CachedPack pack)
 			throws IOException {
@@ -796,6 +838,100 @@
 		return new DfsReaderIoStats(stats);
 	}
 
+	/** Announces when data is loaded by reader */
+	protected interface PackLoadListener {
+		/**
+		 * Immutable copy of a DFS block metadata
+		 */
+		class DfsBlockData {
+			private final int identityHash;
+			private final int size;
+
+			static DfsBlockData of(DfsBlock src) {
+				return new DfsBlockData(src);
+			}
+
+			private DfsBlockData(DfsBlock src) {
+				this.identityHash = System.identityHashCode(src);
+				this.size = src.size();
+			}
+
+			public int getIdentityHash() {
+				return identityHash;
+			}
+
+			public int getSize() {
+				return size;
+			}
+		}
+
+		/**
+		 * This is called when an index reference (e.g. primary index, reverse
+		 * index, ...) is set in the reader, regarless if loaded from scratch or
+		 * copied from cache.
+		 *
+		 * During the lifetime of the reader, the reference for an index should
+		 * be set only once.
+		 *
+		 * @param packName
+		 *            Name of the pack
+		 * @param src
+		 *            Source of the pack (e.g. GC, COMPACT, ...)
+		 * @param ext
+		 *            Extension in the pack (e.g. IDX, RIDX, ...)
+		 * @param size
+		 *            Size of the data loaded (usually as bytes in disk)
+		 * @param loadedIdx
+		 *            reference to the loaded index
+		 */
+		void onIndexLoad(String packName, PackSource src, PackExt ext, long size,
+				Object loadedIdx);
+
+		/**
+		 * This is called when a dfs block is loaded into the reader.
+		 *
+		 * The reader keeps only one block at a time in memory, so during a
+		 * request the same block could be loaded multiple times.
+		 *
+		 * @param packName
+		 *            Name of the pack this block belongs to
+		 * @param src
+		 *            Source of the pack (e.g. GC, COMPACT, ...)
+		 * @param ext
+		 *            Extension in the pack (e.g. PACK or REFTABLE)
+		 * @param position
+		 *            Offset in the file requested by caller
+		 * @param dfsBlockData
+		 *            Metadata of the block
+		 */
+		void onBlockLoad(String packName, PackSource src, PackExt ext,
+				long position, DfsBlockData dfsBlockData);
+	}
+
+	void emitIndexLoad(DfsPackDescription packDescription, PackExt ext,
+			Object loadedIdx) {
+		packLoadListeners.forEach(
+				listener -> listener.onIndexLoad(packDescription.getFileName(ext),
+						packDescription.getPackSource(), ext,
+						packDescription.getFileSize(ext), loadedIdx));
+	}
+
+	void emitBlockLoad(BlockBasedFile file, long position, DfsBlock dfsBlock) {
+		packLoadListeners
+				.forEach(listener -> listener.onBlockLoad(file.getFileName(),
+						file.desc.getPackSource(), file.ext, position,
+						DfsBlockData.of(dfsBlock)));
+	}
+
+	/**
+	 * Add listener to record loads by this reader
+	 *
+	 * @param listener a listener
+	 */
+	protected void addPackLoadListener(PackLoadListener listener) {
+		packLoadListeners.add(listener);
+	}
+
 	/**
 	 * {@inheritDoc}
 	 * <p>
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/dfs/DfsReaderIoStats.java b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/dfs/DfsReaderIoStats.java
index 5ac7985..adb4673 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/dfs/DfsReaderIoStats.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/dfs/DfsReaderIoStats.java
@@ -10,12 +10,15 @@
 
 package org.eclipse.jgit.internal.storage.dfs;
 
+import org.eclipse.jgit.lib.AnyObjectId;
+
 /**
  * IO statistics for a {@link org.eclipse.jgit.internal.storage.dfs.DfsReader}.
  */
 public class DfsReaderIoStats {
 	/** POJO to accumulate IO statistics. */
 	public static class Accumulator {
+
 		/** Number of times the reader explicitly called scanPacks. */
 		long scanPacks;
 
@@ -31,6 +34,9 @@
 		/** Total number of cache hits for commit graphs. */
 		long commitGraphCacheHit;
 
+		/** Total number of cache hits for object size indexes. */
+		long objectSizeIndexCacheHit;
+
 		/** Total number of complete pack indexes read into memory. */
 		long readIdx;
 
@@ -43,12 +49,18 @@
 		/** Total number of complete commit graphs read into memory. */
 		long readCommitGraph;
 
+		/** Total number of object size indexes added into memory. */
+		long readObjectSizeIndex;
+
 		/** Total number of bytes read from pack indexes. */
 		long readIdxBytes;
 
 		/** Total number of bytes read from commit graphs. */
 		long readCommitGraphBytes;
 
+		/** Total numer of bytes read from object size index */
+		long readObjectSizeIndexBytes;
+
 		/** Total microseconds spent reading pack indexes. */
 		long readIdxMicros;
 
@@ -58,6 +70,9 @@
 		/** Total microseconds spent creating commit graphs. */
 		long readCommitGraphMicros;
 
+		/** Total microseconds spent creating object size indexes */
+		long readObjectSizeIndexMicros;
+
 		/** Total number of bytes read from bitmap indexes. */
 		long readBitmapIdxBytes;
 
@@ -88,6 +103,15 @@
 		/** Total microseconds spent inflating compressed bytes. */
 		long inflationMicros;
 
+		/** Count of queries for the size of an object via #isNotLargerThan */
+		long isNotLargerThanCallCount;
+
+		/** Object was below threshold in the object size index */
+		long objectSizeIndexMiss;
+
+		/** Object size found in the object size index */
+		long objectSizeIndexHit;
+
 		Accumulator() {
 		}
 	}
@@ -144,6 +168,15 @@
 	}
 
 	/**
+	 * Get total number of object size index cache hits.
+	 *
+	 * @return total number of object size index cache hits.
+	 */
+	public long getObjectSizeIndexCacheHits() {
+		return stats.objectSizeIndexCacheHit;
+	}
+
+	/**
 	 * Get total number of complete pack indexes read into memory.
 	 *
 	 * @return total number of complete pack indexes read into memory.
@@ -180,6 +213,15 @@
 	}
 
 	/**
+	 * Get total number of complete object size indexes read into memory.
+	 *
+	 * @return total number of complete object size indexes read into memory.
+	 */
+	public long getReadObjectSizeIndexCount() {
+		return stats.readObjectSizeIndex;
+	}
+
+	/**
 	 * Get total number of bytes read from pack indexes.
 	 *
 	 * @return total number of bytes read from pack indexes.
@@ -297,4 +339,41 @@
 	public long getInflationMicros() {
 		return stats.inflationMicros;
 	}
+
+	/**
+	 * Get count of invocations to
+	 * {@link DfsReader#isNotLargerThan(AnyObjectId, int, long)}
+	 * <p>
+	 * Each call could use the object-size index or not.
+	 *
+	 * @return how many times the size of an object was checked with
+	 *         {@link DfsReader#isNotLargerThan(AnyObjectId, int, long)}
+	 */
+	public long getIsNotLargerThanCallCount() {
+		return stats.isNotLargerThanCallCount;
+	}
+
+	/**
+	 * Get number of times the size of a blob was found in the object size
+	 * index.
+	 * <p>
+	 * This counts only queries for blobs on packs with object size index.
+	 *
+	 * @return count of object size index hits
+	 */
+	public long getObjectSizeIndexHits() {
+		return stats.objectSizeIndexHit;
+	}
+
+	/**
+	 * Get number of times the size of an object was not found in the object
+	 * size index. This usually means it was below the threshold.
+	 * <p>
+	 * This counts only queries for blobs on packs with object size index.
+	 *
+	 * @return count of object size index misses.
+	 */
+	public long getObjectSizeIndexMisses() {
+		return stats.objectSizeIndexMiss;
+	}
 }
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/dfs/DfsRefDatabase.java b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/dfs/DfsRefDatabase.java
index ae65670..b524562 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/dfs/DfsRefDatabase.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/dfs/DfsRefDatabase.java
@@ -65,7 +65,6 @@
 		return 0 < read().size();
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public Ref exactRef(String name) throws IOException {
 		RefCache curr = read();
@@ -73,13 +72,11 @@
 		return ref != null ? resolve(ref, 0, curr.ids) : null;
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public List<Ref> getAdditionalRefs() {
 		return Collections.emptyList();
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public Map<String, Ref> getRefs(String prefix) throws IOException {
 		RefCache curr = read();
@@ -126,7 +123,6 @@
 		return new SymbolicRef(ref.getName(), dst);
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public Ref peel(Ref ref) throws IOException {
 		final Ref oldLeaf = ref.getLeaf();
@@ -176,7 +172,6 @@
 		return leaf;
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public RefUpdate newUpdate(String refName, boolean detach)
 			throws IOException {
@@ -193,7 +188,6 @@
 		return update;
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public RefRename newRename(String fromName, String toName)
 			throws IOException {
@@ -202,7 +196,6 @@
 		return new DfsRefRename(src, dst);
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public boolean isNameConflicting(String refName) throws IOException {
 		RefList<Ref> all = read().ids;
@@ -224,19 +217,16 @@
 		return false;
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public void create() {
 		// Nothing to do.
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public void refresh() {
 		clearCache();
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public void close() {
 		clearCache();
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/dfs/DfsRefRename.java b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/dfs/DfsRefRename.java
index 5698035..e76b0bc 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/dfs/DfsRefRename.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/dfs/DfsRefRename.java
@@ -22,7 +22,6 @@
 		super(src, dst);
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	protected Result doRename() throws IOException {
 		// TODO Correctly handle renaming foo/bar to foo.
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/dfs/DfsRefUpdate.java b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/dfs/DfsRefUpdate.java
index 28331a0..f327034 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/dfs/DfsRefUpdate.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/dfs/DfsRefUpdate.java
@@ -33,19 +33,16 @@
 		this.refdb = refdb;
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	protected DfsRefDatabase getRefDatabase() {
 		return refdb;
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	protected DfsRepository getRepository() {
 		return refdb.getRepository();
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	protected boolean tryLock(boolean deref) throws IOException {
 		dstRef = getRef();
@@ -60,13 +57,11 @@
 		return true;
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	protected void unlock() {
 		// No state is held while "locked".
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public Result update(RevWalk walk) throws IOException {
 		try {
@@ -77,7 +72,6 @@
 		}
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	protected Result doUpdate(Result desiredResult) throws IOException {
 		ObjectIdRef newRef;
@@ -102,7 +96,6 @@
 		return Result.LOCK_FAILURE;
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	protected Result doDelete(Result desiredResult) throws IOException {
 		if (getRefDatabase().compareAndRemove(dstRef)) {
@@ -112,7 +105,6 @@
 		return Result.LOCK_FAILURE;
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	protected Result doLink(String target) throws IOException {
 		final SymbolicRef newRef = new SymbolicRef(
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/dfs/DfsReftableDatabase.java b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/dfs/DfsReftableDatabase.java
index 6c3b056..3ba74b2 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/dfs/DfsReftableDatabase.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/dfs/DfsReftableDatabase.java
@@ -75,19 +75,16 @@
 		stack = null;
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public boolean hasVersioning() {
 		return true;
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public boolean performsAtomicTransactions() {
 		return true;
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public BatchRefUpdate newBatchUpdate() {
 		DfsObjDatabase odb = getRepository().getObjectDatabase();
@@ -151,13 +148,11 @@
 		return reftableDatabase.isNameConflicting(refName, new TreeSet<>(), new HashSet<>());
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public Ref exactRef(String name) throws IOException {
 		return reftableDatabase.exactRef(name);
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public Map<String, Ref> getRefs(String prefix) throws IOException {
 		List<Ref> refs = reftableDatabase.getRefsByPrefix(prefix);
@@ -169,21 +164,18 @@
 			RefList.emptyList());
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public List<Ref> getRefsByPrefix(String prefix) throws IOException {
 
 		return reftableDatabase.getRefsByPrefix(prefix);
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public List<Ref> getRefsByPrefixWithExclusions(String include, Set<String> excludes)
 			throws IOException {
 		return reftableDatabase.getRefsByPrefixWithExclusions(include, excludes);
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public Set<Ref> getTipsWithSha1(ObjectId id) throws IOException {
 		if (!getReftableConfig().isIndexObjects()) {
@@ -192,13 +184,11 @@
 		return reftableDatabase.getTipsWithSha1(id);
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public boolean hasFastTipsWithSha1() throws IOException {
 		return reftableDatabase.hasFastTipsWithSha1();
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public Ref peel(Ref ref) throws IOException {
 		Ref oldLeaf = ref.getLeaf();
@@ -233,7 +223,6 @@
 		}
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	protected boolean compareAndPut(Ref oldRef, @Nullable Ref newRef)
 			throws IOException {
@@ -254,13 +243,11 @@
 		}
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	protected boolean compareAndRemove(Ref oldRef) throws IOException {
 		return compareAndPut(oldRef, null);
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	protected RefCache scanAllRefs() throws IOException {
 		throw new UnsupportedOperationException();
@@ -276,7 +263,6 @@
 		// Unnecessary; DfsReftableBatchRefUpdate calls clearCache().
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	protected void cachePeeledState(Ref oldLeaf, Ref newLeaf) {
 		// Do not cache peeled state in reftable.
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/dfs/DfsReftableStack.java b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/dfs/DfsReftableStack.java
index 27b0329..97ba4d5 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/dfs/DfsReftableStack.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/dfs/DfsReftableStack.java
@@ -80,7 +80,6 @@
 		return Collections.unmodifiableList(tables);
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public void close() {
 		for (ReftableReader t : tables) {
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/dfs/DfsRepository.java b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/dfs/DfsRepository.java
index 32c0ccd..218f1e9 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/dfs/DfsRepository.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/dfs/DfsRepository.java
@@ -45,7 +45,6 @@
 		this.description = builder.getRepositoryDescription();
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public abstract DfsObjDatabase getObjectDatabase();
 
@@ -72,7 +71,6 @@
 		return true;
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public void create(boolean bare) throws IOException {
 		if (exists())
@@ -85,39 +83,33 @@
 			throw new IOException(result.name());
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public StoredConfig getConfig() {
 		return config;
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public String getIdentifier() {
 		return getDescription().getRepositoryName();
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public void scanForRepoChanges() throws IOException {
 		getRefDatabase().refresh();
 		getObjectDatabase().clearCache();
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public void notifyIndexChanged(boolean internal) {
 		// Do not send notifications.
 		// There is no index, as there is no working tree.
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public ReflogReader getReflogReader(String refName) throws IOException {
 		throw new UnsupportedOperationException();
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public AttributesNodeProvider createAttributesNodeProvider() {
 		// TODO Check if the implementation used in FileRepository can be used
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/dfs/DfsRepositoryBuilder.java b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/dfs/DfsRepositoryBuilder.java
index 943d926..ab5f7fe 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/dfs/DfsRepositoryBuilder.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/dfs/DfsRepositoryBuilder.java
@@ -72,7 +72,6 @@
 		return self();
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public B setup() throws IllegalArgumentException, IOException {
 		super.setup();
@@ -97,7 +96,6 @@
 
 	// We don't support local file IO and thus shouldn't permit these to set.
 
-	/** {@inheritDoc} */
 	@Override
 	public B setGitDir(File gitDir) {
 		if (gitDir != null)
@@ -105,7 +103,6 @@
 		return self();
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public B setObjectDirectory(File objectDirectory) {
 		if (objectDirectory != null)
@@ -113,14 +110,12 @@
 		return self();
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public B addAlternateObjectDirectory(File other) {
 		throw new UnsupportedOperationException(
 				JGitText.get().unsupportedAlternates);
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public B setWorkTree(File workTree) {
 		if (workTree != null)
@@ -128,7 +123,6 @@
 		return self();
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public B setIndexFile(File indexFile) {
 		if (indexFile != null)
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/dfs/DfsRepositoryDescription.java b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/dfs/DfsRepositoryDescription.java
index 069956b..e949085 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/dfs/DfsRepositoryDescription.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/dfs/DfsRepositoryDescription.java
@@ -42,7 +42,6 @@
 		return repositoryName;
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public int hashCode() {
 		if (getRepositoryName() != null)
@@ -50,7 +49,6 @@
 		return System.identityHashCode(this);
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public boolean equals(Object b) {
 		if (b instanceof DfsRepositoryDescription){
@@ -61,7 +59,6 @@
 		return false;
 	}
 
-	/** {@inheritDoc} */
 	@SuppressWarnings("nls")
 	@Override
 	public String toString() {
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/dfs/DfsStreamKey.java b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/dfs/DfsStreamKey.java
index f3f3091..8983c2d 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/dfs/DfsStreamKey.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/dfs/DfsStreamKey.java
@@ -56,17 +56,14 @@
 		this.packExtPos = ext == null ? 0 : ext.getPosition();
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public int hashCode() {
 		return hash;
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public abstract boolean equals(Object o);
 
-	/** {@inheritDoc} */
 	@SuppressWarnings("boxing")
 	@Override
 	public String toString() {
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/dfs/InMemoryRepository.java b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/dfs/InMemoryRepository.java
index 583b8b3..734a5fc 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/dfs/InMemoryRepository.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/dfs/InMemoryRepository.java
@@ -78,13 +78,11 @@
 		return new MemRefDatabase();
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public MemObjDatabase getObjectDatabase() {
 		return objdb;
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public RefDatabase getRefDatabase() {
 		return refdb;
@@ -102,14 +100,12 @@
 		refdb.performsAtomicTransactions = atomic;
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	@Nullable
 	public String getGitwebDescription() {
 		return gitwebDescription;
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public void setGitwebDescription(@Nullable String d) {
 		gitwebDescription = d;
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/dfs/LargePackedWholeObject.java b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/dfs/LargePackedWholeObject.java
index cd4f168..89a3afb 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/dfs/LargePackedWholeObject.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/dfs/LargePackedWholeObject.java
@@ -44,31 +44,26 @@
 		this.db = db;
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public int getType() {
 		return type;
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public long getSize() {
 		return size;
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public boolean isLarge() {
 		return true;
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public byte[] getCachedBytes() throws LargeObjectException {
 		throw new LargeObjectException();
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public ObjectStream openStream() throws MissingObjectException, IOException {
 		PackInputStream packIn;
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/dfs/PackInputStream.java b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/dfs/PackInputStream.java
index 6ff8164..3d07660 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/dfs/PackInputStream.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/dfs/PackInputStream.java
@@ -31,7 +31,6 @@
 		ctx.pin(pack, pos);
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public int read(byte[] b, int off, int len) throws IOException {
 		int n = ctx.copy(pack, pos, b, off, len);
@@ -39,7 +38,6 @@
 		return n;
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public int read() throws IOException {
 		byte[] buf = new byte[1];
@@ -47,7 +45,6 @@
 		return n == 1 ? buf[0] & 0xff : -1;
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public void close() {
 		ctx.close();
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/BasePackBitmapIndex.java b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/BasePackBitmapIndex.java
index ec53818..53e3695 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/BasePackBitmapIndex.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/BasePackBitmapIndex.java
@@ -25,7 +25,6 @@
 		this.bitmaps = bitmaps;
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public EWAHCompressedBitmap getBitmap(AnyObjectId objectId) {
 		StoredBitmap sb = bitmaps.get(objectId);
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/BitmapIndexImpl.java b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/BitmapIndexImpl.java
index 9aa1417..55c05ef 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/BitmapIndexImpl.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/BitmapIndexImpl.java
@@ -54,7 +54,6 @@
 		return packIndex;
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public CompressedBitmap getBitmap(AnyObjectId objectId) {
 		EWAHCompressedBitmap compressed = packIndex.getBitmap(objectId);
@@ -63,7 +62,6 @@
 		return new CompressedBitmap(compressed, this);
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public CompressedBitmapBuilder newBitmapBuilder() {
 		return new CompressedBitmapBuilder(this);
@@ -291,7 +289,9 @@
 		 * Construct compressed bitmap for given bitmap and bitmap index
 		 *
 		 * @param bitmap
+		 *            the bitmap
 		 * @param bitmapIndex
+		 *            the bitmap index
 		 */
 		public CompressedBitmap(EWAHCompressedBitmap bitmap, BitmapIndexImpl bitmapIndex) {
 			this.bitmap = bitmap;
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/ByteArrayWindow.java b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/ByteArrayWindow.java
index 1036535..ef1392e 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/ByteArrayWindow.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/ByteArrayWindow.java
@@ -30,7 +30,6 @@
 		array = b;
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	protected int copy(int p, byte[] b, int o, int n) {
 		n = Math.min(array.length - p, n);
@@ -38,7 +37,6 @@
 		return n;
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	protected int setInput(int pos, Inflater inf)
 			throws DataFormatException {
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/ByteBufferWindow.java b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/ByteBufferWindow.java
index b687757..4094f13 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/ByteBufferWindow.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/ByteBufferWindow.java
@@ -32,7 +32,6 @@
 		buffer = b;
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	protected int copy(int p, byte[] b, int o, int n) {
 		final ByteBuffer s = buffer.slice();
@@ -57,7 +56,6 @@
 		}
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	protected int setInput(int pos, Inflater inf)
 			throws DataFormatException {
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 2e19580..129d2e0 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
@@ -86,13 +86,11 @@
 		return m;
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public void close() {
 		// Don't close anything.
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public ObjectDatabase newCachedDatabase() {
 		return this;
@@ -153,7 +151,6 @@
 		wrapped.resolve(matches, id);
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public boolean has(AnyObjectId objectId) throws IOException {
 		return has(objectId, null);
@@ -261,7 +258,6 @@
 		return wrapped.getPacks();
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public Optional<CommitGraph> getCommitGraph() {
 		return wrapped.getCommitGraph();
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/CheckoutEntryImpl.java b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/CheckoutEntryImpl.java
index 2b8779f..d641da5 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/CheckoutEntryImpl.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/CheckoutEntryImpl.java
@@ -32,13 +32,11 @@
 		to = comment.substring(p2 + " to ".length(), p3); //$NON-NLS-1$
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public String getFromBranch() {
 		return from;
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public String getToBranch() {
 		return to;
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
index 44429a7..5172963 100644
--- 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
@@ -108,7 +108,8 @@
 				// commit-graph file was not modified
 				return this;
 			}
-			return new GraphSnapshot(file, FileSnapshot.save(file), open(file));
+			return new GraphSnapshot(file, FileSnapshot.save(file),
+					open(file));
 		}
 
 		private static CommitGraph open(File file) {
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 aa578d3..e8f532f 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
@@ -33,13 +33,11 @@
 		INSERTED, EXISTS_PACKED, EXISTS_LOOSE, FAILURE;
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public ObjectReader newReader() {
 		return new WindowCursor(this);
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public ObjectDirectoryInserter newInserter() {
 		return new ObjectDirectoryInserter(this, getConfig());
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/FileReftableDatabase.java b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/FileReftableDatabase.java
index e9e17c0..3abd71a 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/FileReftableDatabase.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/FileReftableDatabase.java
@@ -93,13 +93,13 @@
 
 	/**
 	 * @param repoDir
+	 *            the repository's metadata directory
 	 * @return whether the given repo uses reftable for refdb storage.
 	 */
 	public static boolean isReftable(File repoDir) {
 		return new File(repoDir, Constants.REFTABLE).isDirectory();
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public boolean hasFastTipsWithSha1() throws IOException {
 		return reftableDatabase.hasFastTipsWithSha1();
@@ -124,20 +124,17 @@
 		return reftableDatabase.getLock();
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public boolean performsAtomicTransactions() {
 		return true;
 	}
 
-	/** {@inheritDoc} */
 	@NonNull
 	@Override
 	public BatchRefUpdate newBatchUpdate() {
 		return new FileReftableBatchRefUpdate(this, fileRepository);
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public RefUpdate newUpdate(String refName, boolean detach)
 			throws IOException {
@@ -157,19 +154,16 @@
 		return update;
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public Ref exactRef(String name) throws IOException {
 		return reftableDatabase.exactRef(name);
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public List<Ref> getRefs() throws IOException {
 		return super.getRefs();
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public Map<String, Ref> getRefs(String prefix) throws IOException {
 		List<Ref> refs = reftableDatabase.getRefsByPrefix(prefix);
@@ -181,20 +175,17 @@
 				RefList.emptyList());
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public List<Ref> getRefsByPrefixWithExclusions(String include, Set<String> excludes)
 			throws IOException {
 		return reftableDatabase.getRefsByPrefixWithExclusions(include, excludes);
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public List<Ref> getAdditionalRefs() throws IOException {
 		return Collections.emptyList();
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public Ref peel(Ref ref) throws IOException {
 		Ref oldLeaf = ref.getLeaf();
@@ -303,7 +294,6 @@
 		}
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public RefRename newRename(String fromName, String toName)
 			throws IOException {
@@ -312,20 +302,17 @@
 		return new FileRefRename(src, dst);
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public boolean isNameConflicting(String name) throws IOException {
 		return reftableDatabase.isNameConflicting(name, new TreeSet<>(),
 				new HashSet<>());
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public void close() {
 		reftableStack.close();
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public void create() throws IOException {
 		FileUtils.mkdir(
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/FileReftableStack.java b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/FileReftableStack.java
index 5152367..c74a298 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/FileReftableStack.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/FileReftableStack.java
@@ -264,6 +264,7 @@
 		 * @param w
 		 *            writer to use
 		 * @throws IOException
+		 *             if an IO error occurred
 		 */
 		void call(ReftableWriter w) throws IOException;
 	}
@@ -559,6 +560,7 @@
 	 * Calculate an approximate log2.
 	 *
 	 * @param sz
+	 *            the number to compute an approximate log2 for
 	 * @return log2
 	 */
 	static int log(long sz) {
@@ -688,6 +690,7 @@
 	 * shape.
 	 *
 	 * @throws IOException
+	 *             if an IO error occurred
 	 */
 	private void autoCompact() throws IOException {
 		Optional<Segment> cand = autoCompactCandidate(tableSizes());
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/FileRepository.java b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/FileRepository.java
index 3e92cdd..e5a00d3 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/FileRepository.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/FileRepository.java
@@ -321,19 +321,16 @@
 		return objectDatabase.getDirectory();
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public ObjectDirectory getObjectDatabase() {
 		return objectDatabase;
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public RefDatabase getRefDatabase() {
 		return refs;
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public String getIdentifier() {
 		File directory = getDirectory();
@@ -343,7 +340,6 @@
 		throw new IllegalStateException();
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public FileBasedConfig getConfig() {
 		try {
@@ -357,7 +353,6 @@
 		return repoConfig;
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	@Nullable
 	public String getGitwebDescription() throws IOException {
@@ -376,7 +371,6 @@
 		return d;
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public void setGitwebDescription(@Nullable String description)
 			throws IOException {
@@ -423,6 +417,7 @@
 	 * client trying to push changes avoid pushing more than it needs to.
 	 *
 	 * @throws IOException
+	 *             if an IO error occurred
 	 */
 	@Override
 	public Set<ObjectId> getAdditionalHaves() throws IOException {
@@ -478,7 +473,6 @@
 		objectDatabase.openPack(pack);
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public void scanForRepoChanges() throws IOException {
 		getRefDatabase().getRefs(); // This will look for changes to refs
@@ -504,7 +498,6 @@
 		notifyIndexChanged(false);
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public void notifyIndexChanged(boolean internal) {
 		synchronized (snapshotLock) {
@@ -513,7 +506,6 @@
 		fireEvent(new IndexChangedEvent(internal));
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public ReflogReader getReflogReader(String refName) throws IOException {
 		if (refs instanceof FileReftableDatabase) {
@@ -537,7 +529,6 @@
 		return new ReflogReaderImpl(this, ref.getName());
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public AttributesNodeProvider createAttributesNodeProvider() {
 		return new AttributesNodeProviderImpl(this);
@@ -600,7 +591,6 @@
 				ConfigConstants.CONFIG_KEY_AUTODETACH, true);
 	}
 
-	/** {@inheritDoc} */
 	@SuppressWarnings("FutureReturnValueIgnored")
 	@Override
 	public void autoGC(ProgressMonitor monitor) {
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/FileSnapshot.java b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/FileSnapshot.java
index 6088c15..9a85752 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/FileSnapshot.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/FileSnapshot.java
@@ -404,7 +404,6 @@
 				&& Objects.equals(fileKey, other.fileKey);
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public boolean equals(Object obj) {
 		if (this == obj) {
@@ -420,7 +419,6 @@
 		return equals(other);
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public int hashCode() {
 		return Objects.hash(lastModified, Long.valueOf(size), fileKey);
@@ -474,7 +472,6 @@
 		return racyThreshold;
 	}
 
-	/** {@inheritDoc} */
 	@SuppressWarnings({ "nls", "ReferenceEquality" })
 	@Override
 	public String toString() {
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 8d624bc..40323aa 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
@@ -135,6 +135,8 @@
 
 	private static final int DEFAULT_AUTOLIMIT = 6700;
 
+	private static final boolean DEFAULT_WRITE_BLOOM_FILTER = false;
+
 	private static final boolean DEFAULT_WRITE_COMMIT_GRAPH = false;
 
 	private static volatile ExecutorService executor;
@@ -224,9 +226,10 @@
 	 * gc.log.
 	 *
 	 * @return the collection of
-	 *         {@link org.eclipse.jgit.internal.storage.file.Pack}'s which
-	 *         are newly created
+	 *         {@link org.eclipse.jgit.internal.storage.file.Pack}'s which are
+	 *         newly created
 	 * @throws java.io.IOException
+	 *             if an IO error occurred
 	 * @throws java.text.ParseException
 	 *             If the configuration parameter "gc.pruneexpire" couldn't be
 	 *             parsed
@@ -300,10 +303,15 @@
 	 * pack files.
 	 *
 	 * @param inserter
+	 *            used to insert objects
 	 * @param reader
+	 *            used to read objects
 	 * @param pack
+	 *            the pack file to loosen objects for
 	 * @param existing
+	 *            existing objects
 	 * @throws IOException
+	 *             if an IO error occurred
 	 */
 	private void loosen(ObjectDirectoryInserter inserter, ObjectReader reader, Pack pack, HashSet<ObjectId> existing)
 			throws IOException {
@@ -329,13 +337,17 @@
 	 * directory. If an expirationDate is set then pack files which are younger
 	 * than the expirationDate will not be deleted nor preserved.
 	 * <p>
-	 * If we're not immediately expiring loose objects, loosen any objects
-	 * in the old pack files which aren't in the new pack files.
+	 * If we're not immediately expiring loose objects, loosen any objects in
+	 * the old pack files which aren't in the new pack files.
 	 *
 	 * @param oldPacks
+	 *            old pack files
 	 * @param newPacks
+	 *            new pack files
 	 * @throws ParseException
+	 *             if an error occurred during parsing
 	 * @throws IOException
+	 *             if an IO error occurred
 	 */
 	private void deleteOldPacks(Collection<Pack> oldPacks,
 			Collection<Pack> newPacks) throws ParseException, IOException {
@@ -382,12 +394,15 @@
 	}
 
 	/**
-	 * Deletes old pack file, unless 'preserve-oldpacks' is set, in which case it
-	 * moves the pack file to the preserved directory
+	 * Deletes old pack file, unless 'preserve-oldpacks' is set, in which case
+	 * it moves the pack file to the preserved directory
 	 *
 	 * @param packFile
+	 *            the packfile to delete
 	 * @param deleteOptions
+	 *            delete option flags
 	 * @throws IOException
+	 *             if an IO error occurred
 	 */
 	private void removeOldPack(PackFile packFile, int deleteOptions)
 			throws IOException {
@@ -426,6 +441,7 @@
 	 * with a ".pack" file without a ".index" file.
 	 *
 	 * @param packFile
+	 *            the pack file to prune files for
 	 */
 	private void prunePack(PackFile packFile) {
 		try {
@@ -453,6 +469,7 @@
 	 * because the filesystem delete operation fails) this is silently ignored.
 	 *
 	 * @throws java.io.IOException
+	 *             if an IO error occurred
 	 */
 	public void prunePacked() throws IOException {
 		ObjectDirectory objdb = repo.getObjectDatabase();
@@ -511,6 +528,7 @@
 	 * @param objectsToKeep
 	 *            a set of objects which should explicitly not be pruned
 	 * @throws java.io.IOException
+	 *             if an IO error occurred
 	 * @throws java.text.ParseException
 	 *             If the configuration parameter "gc.pruneexpire" couldn't be
 	 *             parsed
@@ -718,10 +736,15 @@
 	 * by the given ObjectWalk
 	 *
 	 * @param id2File
+	 *            mapping objectIds to files
 	 * @param w
+	 *            used to walk objects
 	 * @throws MissingObjectException
+	 *             if an object is missing
 	 * @throws IncorrectObjectTypeException
+	 *             if an object has an unexpected tyoe
 	 * @throws IOException
+	 *             if an IO error occurred
 	 */
 	private void removeReferenced(Map<ObjectId, File> id2File,
 			ObjectWalk w) throws MissingObjectException,
@@ -762,6 +785,7 @@
 	 * is compacted into a single table.
 	 *
 	 * @throws java.io.IOException
+	 *             if an IO error occurred
 	 */
 	public void packRefs() throws IOException {
 		RefDatabase refDb = repo.getRefDatabase();
@@ -816,7 +840,6 @@
 		Set<ObjectId> allHeads = new HashSet<>();
 		Set<ObjectId> allTags = new HashSet<>();
 		Set<ObjectId> nonHeads = new HashSet<>();
-		Set<ObjectId> txnHeads = new HashSet<>();
 		Set<ObjectId> tagTargets = new HashSet<>();
 		Set<ObjectId> indexObjects = listNonHEADIndexObjects();
 
@@ -881,12 +904,6 @@
 			if (rest != null)
 				ret.add(rest);
 		}
-		if (!txnHeads.isEmpty()) {
-			Pack txn = writePack(txnHeads, PackWriter.NONE, PackWriter.NONE,
-					PackWriter.NONE, null, excluded, false);
-			if (txn != null)
-				ret.add(txn);
-		}
 		try {
 			deleteOldPacks(toBeDeleted, ret);
 		} catch (ParseException e) {
@@ -932,6 +949,7 @@
 	 *            the list of wanted objects, writer walks commits starting at
 	 *            these. Must not be {@code null}.
 	 * @throws IOException
+	 *             if an IO error occurred
 	 */
 	void writeCommitGraph(@NonNull Set<? extends ObjectId> wants)
 			throws IOException {
@@ -948,7 +966,8 @@
 		File tmpFile = null;
 		try (RevWalk walk = new RevWalk(repo)) {
 			CommitGraphWriter writer = new CommitGraphWriter(
-					GraphCommits.fromWalk(pm, wants, walk));
+					GraphCommits.fromWalk(pm, wants, walk),
+					shouldWriteBloomFilter());
 			tmpFile = File.createTempFile("commit_", //$NON-NLS-1$
 					COMMIT_GRAPH.getTmpExtension(),
 					repo.getObjectDatabase().getInfoDirectory());
@@ -1000,7 +1019,7 @@
 	/**
 	 * 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}.
+	 * @return true if commit-graph should be written. Default is {@code false}.
 	 */
 	boolean shouldWriteCommitGraphWhenGc() {
 		return repo.getConfig().getBoolean(ConfigConstants.CONFIG_GC_SECTION,
@@ -1008,6 +1027,17 @@
 				DEFAULT_WRITE_COMMIT_GRAPH);
 	}
 
+	/**
+	 * If {@code true}, generates bloom filter in the commit-graph file.
+	 *
+	 * @return true if bloom filter should be written. Default is {@code false}.
+	 */
+	boolean shouldWriteBloomFilter() {
+		return repo.getConfig().getBoolean(ConfigConstants.CONFIG_GC_SECTION,
+				ConfigConstants.CONFIG_KEY_WRITE_CHANGED_PATHS,
+				DEFAULT_WRITE_BLOOM_FILTER);
+	}
+
 	private static boolean isHead(Ref ref) {
 		return ref.getName().startsWith(Constants.R_HEADS);
 	}
@@ -1148,9 +1178,11 @@
 	/**
 	 * @param ref
 	 *            the ref which log should be inspected
-	 * @param minTime only reflog entries not older then this time are processed
+	 * @param minTime
+	 *            only reflog entries not older then this time are processed
 	 * @return the {@link ObjectId}s contained in the reflog
 	 * @throws IOException
+	 *             if an IO error occurred
 	 */
 	private Set<ObjectId> listRefLogObjects(Ref ref, long minTime) throws IOException {
 		ReflogReader reflogReader = repo.getReflogReader(ref);
@@ -1182,6 +1214,7 @@
 	 *
 	 * @return a collection of refs pointing to live objects.
 	 * @throws IOException
+	 *             if an IO error occurred
 	 */
 	private Collection<Ref> getAllRefs() throws IOException {
 		RefDatabase refdb = repo.getRefDatabase();
@@ -1208,8 +1241,11 @@
 	 *
 	 * @return a set of ObjectIds of changed objects in the index
 	 * @throws IOException
+	 *             if an IO error occurred
 	 * @throws CorruptObjectException
+	 *             if an object is corrupt
 	 * @throws NoWorkTreeException
+	 *             if the repository has no working directory
 	 */
 	private Set<ObjectId> listNonHEADIndexObjects()
 			throws CorruptObjectException, IOException {
@@ -1329,6 +1365,25 @@
 				idxChannel.force(true);
 			}
 
+			if (pw.isReverseIndexEnabled()) {
+				File tmpReverseIndexFile = new File(packdir,
+						tmpBase + REVERSE_INDEX.getTmpExtension());
+				tmpExts.put(REVERSE_INDEX, tmpReverseIndexFile);
+				if (!tmpReverseIndexFile.createNewFile()) {
+					throw new IOException(MessageFormat.format(
+							JGitText.get().cannotCreateIndexfile,
+							tmpReverseIndexFile.getPath()));
+				}
+				try (FileOutputStream fos = new FileOutputStream(
+						tmpReverseIndexFile);
+						FileChannel channel = fos.getChannel();
+						OutputStream stream = Channels
+								.newOutputStream(channel)) {
+					pw.writeReverseIndex(stream);
+					channel.force(true);
+				}
+			}
+
 			if (pw.prepareBitmapIndex(pm)) {
 				File tmpBitmapIdx = new File(packdir,
 						tmpBase + BITMAP_INDEX.getTmpExtension());
@@ -1503,6 +1558,7 @@
 	 *
 	 * @return information about objects and pack files for a FileRepository
 	 * @throws java.io.IOException
+	 *             if an IO error occurred
 	 */
 	public RepoStatistics getStatistics() throws IOException {
 		RepoStatistics ret = new RepoStatistics();
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/GcLog.java b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/GcLog.java
index 86994a9..628bf5d 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/GcLog.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/GcLog.java
@@ -132,6 +132,7 @@
 	 * @param content
 	 *            The content to write
 	 * @throws IOException
+	 *             if an IO error occurred
 	 */
 	void write(String content) throws IOException {
 		if (content.length() > 0) {
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/GlobalAttributesNode.java b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/GlobalAttributesNode.java
index 254557c..bbb7476 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/GlobalAttributesNode.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/GlobalAttributesNode.java
@@ -39,6 +39,7 @@
 	 *
 	 * @return the attributes node
 	 * @throws java.io.IOException
+	 *             if an IO error occurred
 	 */
 	public AttributesNode load() throws IOException {
 		AttributesNode r = new AttributesNode();
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/InfoAttributesNode.java b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/InfoAttributesNode.java
index a22cd3f..11d842b 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/InfoAttributesNode.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/InfoAttributesNode.java
@@ -39,6 +39,7 @@
 	 *
 	 * @return the attributes node
 	 * @throws java.io.IOException
+	 *             if an IO error occurred
 	 */
 	public AttributesNode load() throws IOException {
 		AttributesNode r = new AttributesNode();
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/LargePackedWholeObject.java b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/LargePackedWholeObject.java
index e2fbd7a..15223ad 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/LargePackedWholeObject.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/LargePackedWholeObject.java
@@ -44,25 +44,21 @@
 		this.db = db;
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public int getType() {
 		return type;
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public long getSize() {
 		return size;
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public boolean isLarge() {
 		return true;
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public byte[] getCachedBytes() throws LargeObjectException {
 		try {
@@ -72,7 +68,6 @@
 		}
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public ObjectStream openStream() throws MissingObjectException, IOException {
 		WindowCursor wc = new WindowCursor(db);
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/LazyObjectIdSetFile.java b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/LazyObjectIdSetFile.java
index 2d73f9b..d0d320b 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/LazyObjectIdSetFile.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/LazyObjectIdSetFile.java
@@ -41,7 +41,6 @@
 		this.src = src;
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public boolean contains(AnyObjectId objectId) {
 		if (set == null) {
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/LocalCachedPack.java b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/LocalCachedPack.java
index f112947..22eef94 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/LocalCachedPack.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/LocalCachedPack.java
@@ -39,7 +39,6 @@
 		this.packs = packs.toArray(new Pack[0]);
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public long getObjectCount() throws IOException {
 		long cnt = 0;
@@ -54,7 +53,6 @@
 			pack.copyPackAsIs(out, wc);
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public boolean hasObject(ObjectToPack obj, StoredObjectRepresentation rep) {
 		try {
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/LocalObjectRepresentation.java b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/LocalObjectRepresentation.java
index 559718a..3f3d78c 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/LocalObjectRepresentation.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/LocalObjectRepresentation.java
@@ -59,13 +59,11 @@
 
 	private ObjectId baseId;
 
-	/** {@inheritDoc} */
 	@Override
 	public int getWeight() {
 		return (int) Math.min(length, Integer.MAX_VALUE);
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public ObjectId getDeltaBase() {
 		if (baseId == null && getFormat() == PACK_DELTA) {
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/LocalObjectToPack.java b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/LocalObjectToPack.java
index ac6cd21..ca25212 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/LocalObjectToPack.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/LocalObjectToPack.java
@@ -29,14 +29,12 @@
 		super(src, type);
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	protected void clearReuseAsIs() {
 		super.clearReuseAsIs();
 		pack = null;
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public void select(StoredObjectRepresentation ref) {
 		LocalObjectRepresentation ptr = (LocalObjectRepresentation) ref;
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/LockFile.java b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/LockFile.java
index d06b5a7..8ada0a9 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/LockFile.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/LockFile.java
@@ -79,6 +79,7 @@
 	 * Get the lock file corresponding to the given file.
 	 *
 	 * @param file
+	 *            given file
 	 * @return lock file
 	 */
 	static File getLockFile(File file) {
@@ -575,7 +576,6 @@
 		written = false;
 	}
 
-	/** {@inheritDoc} */
 	@SuppressWarnings("nls")
 	@Override
 	public String toString() {
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/LooseObjects.java b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/LooseObjects.java
index 326c5f6..278c846 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/LooseObjects.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/LooseObjects.java
@@ -90,7 +90,6 @@
 		unpackedObjectCache().clear();
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public String toString() {
 		return "LooseObjects[" + directory + "]"; //$NON-NLS-1$ //$NON-NLS-2$
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 f27daad..579f931 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
@@ -145,7 +145,6 @@
 		}
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public final File getDirectory() {
 		return loose.getDirectory();
@@ -169,13 +168,11 @@
 		return preserved.getDirectory();
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public boolean exists() {
 		return fs.exists(objects);
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public void create() throws IOException {
 		loose.create();
@@ -183,7 +180,6 @@
 		packed.create();
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public ObjectDirectoryInserter newInserter() {
 		return new ObjectDirectoryInserter(this, config);
@@ -199,7 +195,6 @@
 		return new PackInserter(this);
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public void close() {
 		loose.close();
@@ -214,13 +209,11 @@
 		}
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public Collection<Pack> getPacks() {
 		return packed.getPacks();
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public long getApproximateObjectCount() {
 		long count = 0;
@@ -234,7 +227,6 @@
 		return count;
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public Optional<CommitGraph> getCommitGraph() {
 		if (config.get(CoreConfig.KEY).enableCommitGraph()) {
@@ -244,7 +236,6 @@
 	}
 
 	/**
-	 * {@inheritDoc}
 	 * <p>
 	 * Add a single existing pack to the list of available pack files.
 	 */
@@ -268,18 +259,16 @@
 		}
 
 		PackFile bitmapIdx = pf.create(BITMAP_INDEX);
-		Pack res = new Pack(pack, bitmapIdx.exists() ? bitmapIdx : null);
+		Pack res = new Pack(config, pack, bitmapIdx.exists() ? bitmapIdx : null);
 		packed.insert(res);
 		return res;
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public String toString() {
 		return "ObjectDirectory[" + getDirectory() + "]"; //$NON-NLS-1$ //$NON-NLS-2$
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public boolean has(AnyObjectId objectId) {
 		return loose.hasCached(objectId)
@@ -811,7 +800,6 @@
 		}
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public ObjectDatabase newCachedDatabase() {
 		return newCachedFileObjectDatabase();
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/ObjectDirectoryInserter.java b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/ObjectDirectoryInserter.java
index e6b2cc1..2f30a97 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/ObjectDirectoryInserter.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/ObjectDirectoryInserter.java
@@ -49,7 +49,6 @@
 		config = cfg.get(WriteConfig.KEY);
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public ObjectId insert(int type, byte[] data, int off, int len)
 			throws IOException {
@@ -62,12 +61,19 @@
 	 * ODB.
 	 *
 	 * @param type
+	 *            object type
 	 * @param data
+	 *            object data
 	 * @param off
+	 *            first position within @{code data}
 	 * @param len
+	 *            length number of bytes to copy
 	 * @param createDuplicate
-	 * @return ObjectId
+	 *            whether to insert a duplicate if an object with this id
+	 *            already exists
+	 * @return ObjectId the name of the object
 	 * @throws IOException
+	 *             if an IO error occurred
 	 */
 	private ObjectId insert(
 			int type, byte[] data, int off, int len, boolean createDuplicate)
@@ -80,7 +86,6 @@
 		return insertOneObject(tmp, id, createDuplicate);
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public ObjectId insert(int type, long len, InputStream is)
 			throws IOException {
@@ -93,11 +98,17 @@
 	 * ODB.
 	 *
 	 * @param type
+	 *            object type
 	 * @param len
+	 *            number of bytes to copy
 	 * @param is
+	 *            input stream
 	 * @param createDuplicate
-	 * @return ObjectId
+	 *            whether to insert a duplicate if an object with this id
+	 *            already exists
+	 * @return ObjectId the name of the object
 	 * @throws IOException
+	 *             if an IO error occurred
 	 */
 	ObjectId insert(int type, long len, InputStream is, boolean createDuplicate)
 			throws IOException {
@@ -132,25 +143,21 @@
 				.format(JGitText.get().unableToCreateNewObject, dst));
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public PackParser newPackParser(InputStream in) throws IOException {
 		return new ObjectDirectoryPackParser(db, in);
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public ObjectReader newReader() {
 		return new WindowCursor(db, this);
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public void flush() throws IOException {
 		// Do nothing. Loose objects are immediately visible.
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public void close() {
 		if (deflate != null) {
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/ObjectDirectoryPackParser.java b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/ObjectDirectoryPackParser.java
index 55b2646..9f27f4b 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/ObjectDirectoryPackParser.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/ObjectDirectoryPackParser.java
@@ -142,7 +142,6 @@
 		return newPack;
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public long getPackSize() {
 		if (newPack == null)
@@ -158,7 +157,6 @@
 		return size;
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public PackLock parse(ProgressMonitor receiving, ProgressMonitor resolving)
 			throws IOException {
@@ -193,40 +191,34 @@
 		}
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	protected void onPackHeader(long objectCount) throws IOException {
 		// Ignored, the count is not required.
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	protected void onBeginWholeObject(long streamPosition, int type,
 			long inflatedSize) throws IOException {
 		crc.reset();
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	protected void onEndWholeObject(PackedObjectInfo info) throws IOException {
 		info.setCRC((int) crc.getValue());
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	protected void onBeginOfsDelta(long streamPosition,
 			long baseStreamPosition, long inflatedSize) throws IOException {
 		crc.reset();
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	protected void onBeginRefDelta(long streamPosition, AnyObjectId baseId,
 			long inflatedSize) throws IOException {
 		crc.reset();
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	protected UnresolvedDelta onEndDelta() throws IOException {
 		UnresolvedDelta delta = new UnresolvedDelta();
@@ -234,35 +226,30 @@
 		return delta;
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	protected void onInflatedObjectData(PackedObjectInfo obj, int typeCode,
 			byte[] data) throws IOException {
 		// ObjectDirectory ignores this event.
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	protected void onObjectHeader(Source src, byte[] raw, int pos, int len)
 			throws IOException {
 		crc.update(raw, pos, len);
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	protected void onObjectData(Source src, byte[] raw, int pos, int len)
 			throws IOException {
 		crc.update(raw, pos, len);
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	protected void onStoreStream(byte[] raw, int pos, int len)
 			throws IOException {
 		out.write(raw, pos, len);
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	protected void onPackFooter(byte[] hash) throws IOException {
 		packEnd = out.getFilePointer();
@@ -271,7 +258,6 @@
 		packHash = hash;
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	protected ObjectTypeAndSize seekDatabase(UnresolvedDelta delta,
 			ObjectTypeAndSize info) throws IOException {
@@ -280,7 +266,6 @@
 		return readObjectHeader(info);
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	protected ObjectTypeAndSize seekDatabase(PackedObjectInfo obj,
 			ObjectTypeAndSize info) throws IOException {
@@ -289,13 +274,11 @@
 		return readObjectHeader(info);
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	protected int readDatabase(byte[] dst, int pos, int cnt) throws IOException {
 		return out.read(dst, pos, cnt);
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	protected boolean checkCRC(int oldCRC) {
 		return oldCRC == (int) crc.getValue();
@@ -313,7 +296,6 @@
 			tmpPack.deleteOnExit();
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	protected boolean onAppendBase(final int typeCode, final byte[] data,
 			final PackedObjectInfo info) throws IOException {
@@ -356,7 +338,6 @@
 		return true;
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	protected void onEndThinPack() throws IOException {
 		final byte[] buf = buffer();
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/Pack.java b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/Pack.java
index 6e74136..90f9811 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/Pack.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/Pack.java
@@ -14,6 +14,9 @@
 
 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.REVERSE_INDEX;
+import static org.eclipse.jgit.lib.ConfigConstants.CONFIG_CORE_SECTION;
+import static org.eclipse.jgit.lib.ConfigConstants.CONFIG_KEY_PACKED_INDEX_GIT_USE_STRONGREFS;
 
 import java.io.EOFException;
 import java.io.File;
@@ -31,6 +34,7 @@
 import java.util.Collections;
 import java.util.Comparator;
 import java.util.Iterator;
+import java.util.Optional;
 import java.util.Set;
 import java.util.concurrent.atomic.AtomicInteger;
 import java.util.zip.CRC32;
@@ -50,12 +54,16 @@
 import org.eclipse.jgit.errors.UnsupportedPackVersionException;
 import org.eclipse.jgit.internal.JGitText;
 import org.eclipse.jgit.internal.storage.pack.BinaryDelta;
+import org.eclipse.jgit.internal.storage.pack.PackExt;
 import org.eclipse.jgit.internal.storage.pack.PackOutputStream;
+import org.eclipse.jgit.internal.util.Optionally;
 import org.eclipse.jgit.lib.AbbreviatedObjectId;
 import org.eclipse.jgit.lib.AnyObjectId;
+import org.eclipse.jgit.lib.Config;
 import org.eclipse.jgit.lib.Constants;
 import org.eclipse.jgit.lib.ObjectId;
 import org.eclipse.jgit.lib.ObjectLoader;
+import org.eclipse.jgit.util.Hex;
 import org.eclipse.jgit.util.LongList;
 import org.eclipse.jgit.util.NB;
 import org.eclipse.jgit.util.RawParseUtils;
@@ -76,6 +84,8 @@
 	public static final Comparator<Pack> SORT = (a, b) -> b.packLastModified
 			.compareTo(a.packLastModified);
 
+	private boolean useStrongRefs;
+
 	private final PackFile packFile;
 
 	private PackFile keepFile;
@@ -108,11 +118,11 @@
 
 	private byte[] packChecksum;
 
-	private volatile PackIndex loadedIdx;
+	private volatile Optionally<PackIndex> loadedIdx = Optionally.empty();
 
-	private PackReverseIndex reverseIdx;
+	private Optionally<PackReverseIndex> reverseIdx = Optionally.empty();
 
-	private PackBitmapIndex bitmapIdx;
+	private Optionally<PackBitmapIndex> bitmapIdx = Optionally.empty();
 
 	/**
 	 * Objects we have tried to read, and discovered to be corrupt.
@@ -126,12 +136,16 @@
 	/**
 	 * Construct a reader for an existing, pre-indexed packfile.
 	 *
+	 * @param cfg
+	 *            configuration this directory consults for write settings.
 	 * @param packFile
 	 *            path of the <code>.pack</code> file holding the data.
 	 * @param bitmapIdxFile
 	 *            existing bitmap index file with the same base as the pack
 	 */
-	public Pack(File packFile, @Nullable PackFile bitmapIdxFile) {
+	public Pack(Config cfg, File packFile, @Nullable PackFile bitmapIdxFile) {
+		useStrongRefs = cfg.getBoolean(CONFIG_CORE_SECTION,
+				CONFIG_KEY_PACKED_INDEX_GIT_USE_STRONGREFS, WindowCache.getInstance().isPackedIndexGitUseStrongRefs());
 		this.packFile = new PackFile(packFile);
 		this.fileSnapshot = PackFileSnapshot.save(packFile);
 		this.packLastModified = fileSnapshot.lastModifiedInstant();
@@ -145,57 +159,58 @@
 	}
 
 	private PackIndex idx() throws IOException {
-		PackIndex idx = loadedIdx;
-		if (idx == null) {
-			synchronized (this) {
-				idx = loadedIdx;
-				if (idx == null) {
-					if (invalid) {
-						throw new PackInvalidException(packFile,
-								invalidatingCause);
-					}
-					try {
-						long start = System.currentTimeMillis();
-						PackFile idxFile = packFile.create(INDEX);
-						idx = PackIndex.open(idxFile);
-						if (LOG.isDebugEnabled()) {
-							LOG.debug(String.format(
-									"Opening pack index %s, size %.3f MB took %d ms", //$NON-NLS-1$
-									idxFile.getAbsolutePath(),
-									Float.valueOf(idxFile.length()
-											/ (1024f * 1024)),
-									Long.valueOf(System.currentTimeMillis()
-											- start)));
-						}
-
-						if (packChecksum == null) {
-							packChecksum = idx.packChecksum;
-							fileSnapshot.setChecksum(
-									ObjectId.fromRaw(packChecksum));
-						} else if (!Arrays.equals(packChecksum,
-								idx.packChecksum)) {
-							throw new PackMismatchException(MessageFormat
-									.format(JGitText.get().packChecksumMismatch,
-											packFile.getPath(),
-											ObjectId.fromRaw(packChecksum)
-													.name(),
-											ObjectId.fromRaw(idx.packChecksum)
-													.name()));
-						}
-						loadedIdx = idx;
-					} catch (InterruptedIOException e) {
-						// don't invalidate the pack, we are interrupted from
-						// another thread
-						throw e;
-					} catch (IOException e) {
-						invalid = true;
-						invalidatingCause = e;
-						throw e;
-					}
+		Optional<PackIndex> optional = loadedIdx.getOptional();
+		if (optional.isPresent()) {
+			return optional.get();
+		}
+		synchronized (this) {
+			optional = loadedIdx.getOptional();
+			if (optional.isPresent()) {
+				return optional.get();
+			}
+			if (invalid) {
+				throw new PackInvalidException(packFile, invalidatingCause);
+			}
+			try {
+				long start = System.currentTimeMillis();
+				PackFile idxFile = packFile.create(INDEX);
+				PackIndex idx = PackIndex.open(idxFile);
+				if (LOG.isDebugEnabled()) {
+					LOG.debug(String.format(
+							"Opening pack index %s, size %.3f MB took %d ms", //$NON-NLS-1$
+							idxFile.getAbsolutePath(),
+							Float.valueOf(idxFile.length()
+									/ (1024f * 1024)),
+							Long.valueOf(System.currentTimeMillis()
+									- start)));
 				}
+
+				if (packChecksum == null) {
+					packChecksum = idx.packChecksum;
+					fileSnapshot.setChecksum(
+							ObjectId.fromRaw(packChecksum));
+				} else if (!Arrays.equals(packChecksum,
+						idx.packChecksum)) {
+					throw new PackMismatchException(MessageFormat
+							.format(JGitText.get().packChecksumMismatch,
+									packFile.getPath(),
+									PackExt.PACK.getExtension(),
+									Hex.toHexString(packChecksum),
+									PackExt.INDEX.getExtension(),
+									Hex.toHexString(idx.packChecksum)));
+				}
+				loadedIdx = optionally(idx);
+				return idx;
+			} catch (InterruptedIOException e) {
+				// don't invalidate the pack, we are interrupted from
+				// another thread
+				throw e;
+			} catch (IOException e) {
+				invalid = true;
+				invalidatingCause = e;
+				throw e;
 			}
 		}
-		return idx;
 	}
 	/**
 	 * Get the File object which locates this pack on disk.
@@ -211,6 +226,7 @@
 	 *
 	 * @return the index for this pack file.
 	 * @throws java.io.IOException
+	 *             if an IO error occurred
 	 */
 	public PackIndex getIndex() throws IOException {
 		return idx();
@@ -284,8 +300,9 @@
 	public void close() {
 		WindowCache.purge(this);
 		synchronized (this) {
-			loadedIdx = null;
-			reverseIdx = null;
+			loadedIdx.clear();
+			reverseIdx.clear();
+			bitmapIdx.clear();
 		}
 	}
 
@@ -764,11 +781,11 @@
 		fd.seek(length - 20);
 		fd.readFully(buf, 0, 20);
 		if (!Arrays.equals(buf, packChecksum)) {
-			throw new PackMismatchException(MessageFormat.format(
-					JGitText.get().packChecksumMismatch,
-					getPackFile(),
-					ObjectId.fromRaw(buf).name(),
-					ObjectId.fromRaw(idx.packChecksum).name()));
+			throw new PackMismatchException(
+					MessageFormat.format(JGitText.get().packChecksumMismatch,
+							getPackFile(), PackExt.PACK.getExtension(),
+							Hex.toHexString(buf), PackExt.INDEX.getExtension(),
+							Hex.toHexString(idx.packChecksum)));
 		}
 	}
 
@@ -1123,33 +1140,41 @@
 		if (invalid || bitmapIdxFile == null) {
 			return null;
 		}
-		if (bitmapIdx == null) {
-			final PackBitmapIndex idx;
-			try {
-				idx = PackBitmapIndex.open(bitmapIdxFile, idx(),
-						getReverseIdx());
-			} catch (FileNotFoundException e) {
-				// Once upon a time this bitmap file existed. Now it
-				// has been removed. Most likely an external gc  has
-				// removed this packfile and the bitmap
-				bitmapIdxFile = null;
-				return null;
-			}
-
+		Optional<PackBitmapIndex> optional = bitmapIdx.getOptional();
+		if (optional.isPresent()) {
+			return optional.get();
+		}
+		try {
+			PackBitmapIndex idx = PackBitmapIndex.open(bitmapIdxFile, idx(),
+					getReverseIdx());
 			// At this point, idx() will have set packChecksum.
 			if (Arrays.equals(packChecksum, idx.packChecksum)) {
-				bitmapIdx = idx;
-			} else {
-				bitmapIdxFile = null;
+				bitmapIdx = optionally(idx);
+				return idx;
 			}
+		} catch (FileNotFoundException e) {
+			// Once upon a time this bitmap file existed. Now it
+			// has been removed. Most likely an external gc  has
+			// removed this packfile and the bitmap
 		}
-		return bitmapIdx;
+		bitmapIdxFile = null;
+		return null;
 	}
 
 	private synchronized PackReverseIndex getReverseIdx() throws IOException {
-		if (reverseIdx == null)
-			reverseIdx = new PackReverseIndex(idx());
-		return reverseIdx;
+		if (invalid) {
+			throw new PackInvalidException(packFile, invalidatingCause);
+		}
+		Optional<PackReverseIndex> optional = reverseIdx.getOptional();
+		if (optional.isPresent()) {
+			return optional.get();
+		}
+		PackFile reverseIndexFile = packFile.create(REVERSE_INDEX);
+		PackReverseIndex revIdx = PackReverseIndexFactory.openOrCompute(reverseIndexFile,
+					getObjectCount(), () -> getIndex());
+		revIdx.verifyPackChecksum(getPackFile().getPath());
+		reverseIdx = optionally(revIdx);
+		return revIdx;
 	}
 
 	private boolean isCorrupt(long offset) {
@@ -1184,4 +1209,8 @@
 				+ packFile.length() + ", packChecksum="
 				+ ObjectId.fromRaw(packChecksum).name() + "]";
 	}
+
+	private <T> Optionally<T> optionally(T element) {
+		return useStrongRefs ? new Optionally.Hard<>(element) : new Optionally.Soft<>(element);
+	}
 }
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/PackBitmapIndex.java b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/PackBitmapIndex.java
index 8fb17fc..0c3e724 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/PackBitmapIndex.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/PackBitmapIndex.java
@@ -205,6 +205,7 @@
 		/**
 		 * @return result
 		 * @throws IOException
+		 *             if an IO error occurred
 		 */
 		T get() throws IOException;
 	}
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/PackBitmapIndexBuilder.java b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/PackBitmapIndexBuilder.java
index 5666b57..1d1ad98 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/PackBitmapIndexBuilder.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/PackBitmapIndexBuilder.java
@@ -58,7 +58,7 @@
 	 *            ObjectId (name); it will be resorted in place.
 	 */
 	public PackBitmapIndexBuilder(List<ObjectToPack> objects) {
-		super(new ObjectIdOwnerMap<StoredBitmap>());
+		super(new ObjectIdOwnerMap<>());
 		byOffset = new BlockList<>(objects.size());
 		sortByOffsetAndIndex(byOffset, positionEntries, objects);
 
@@ -214,7 +214,6 @@
 		getBitmaps().add(result);
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public EWAHCompressedBitmap ofObjectType(
 			EWAHCompressedBitmap bitmap, int type) {
@@ -231,7 +230,6 @@
 		throw new IllegalArgumentException();
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public int findPosition(AnyObjectId objectId) {
 		PositionEntry entry = positionEntries.get(objectId);
@@ -240,7 +238,6 @@
 		return entry.offsetPosition;
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public ObjectId getObject(int position) throws IllegalArgumentException {
 		ObjectId objectId = byOffset.get(position);
@@ -294,7 +291,6 @@
 		return PackBitmapIndexV1.OPT_FULL;
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public int getBitmapCount() {
 		return bitmapsToWriteXorBuffer.size() + bitmapsToWrite.size();
@@ -311,7 +307,6 @@
 		bitmapsToWrite = new ArrayList<>(size);
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public int getObjectCount() {
 		return byOffset.size();
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/PackBitmapIndexRemapper.java b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/PackBitmapIndexRemapper.java
index e1b6f78..c97d9f0 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/PackBitmapIndexRemapper.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/PackBitmapIndexRemapper.java
@@ -79,32 +79,27 @@
 					oldPackIndex.getObject(pos));
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public int findPosition(AnyObjectId objectId) {
 		return newPackIndex.findPosition(objectId);
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public ObjectId getObject(int position) throws IllegalArgumentException {
 		return newPackIndex.getObject(position);
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public int getObjectCount() {
 		return newPackIndex.getObjectCount();
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public EWAHCompressedBitmap ofObjectType(
 			EWAHCompressedBitmap bitmap, int type) {
 		return newPackIndex.ofObjectType(bitmap, type);
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public Iterator<Entry> iterator() {
 		if (oldPackIndex == null)
@@ -141,7 +136,6 @@
 		};
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public EWAHCompressedBitmap getBitmap(AnyObjectId objectId) {
 		EWAHCompressedBitmap bitmap = newPackIndex.getBitmap(objectId);
@@ -179,7 +173,6 @@
 		}
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public int getBitmapCount() {
 		// The count is only useful for the end index, not the remapper.
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 988dc6c..f2f24b3 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
@@ -84,7 +84,7 @@
 			throws IOException {
 		// An entry is object id, xor offset, flag byte, and a length encoded
 		// bitmap. The object id is an int32 of the nth position sorted by name.
-		super(new ObjectIdOwnerMap<StoredBitmap>());
+		super(new ObjectIdOwnerMap<>());
 		this.bitmaps = getBitmaps();
 
 		// Optionally start loading reverse index in parallel to loading bitmap
@@ -214,7 +214,6 @@
 		this.reverseIndex = computedReverseIndex;
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public int findPosition(AnyObjectId objectId) {
 		long offset = packIndex.findOffset(objectId);
@@ -223,7 +222,6 @@
 		return reverseIndex.findPosition(offset);
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public ObjectId getObject(int position) throws IllegalArgumentException {
 		ObjectId objectId = reverseIndex.findObjectByPosition(position);
@@ -232,13 +230,11 @@
 		return objectId;
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public int getObjectCount() {
 		return (int) packIndex.getObjectCount();
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public EWAHCompressedBitmap ofObjectType(
 			EWAHCompressedBitmap bitmap, int type) {
@@ -255,13 +251,11 @@
 		throw new IllegalArgumentException();
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public int getBitmapCount() {
 		return bitmaps.size();
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public boolean equals(Object o) {
 		// TODO(cranger): compare the pack checksum?
@@ -270,7 +264,6 @@
 		return false;
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public int hashCode() {
 		return getPackIndex().hashCode();
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/PackDirectory.java b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/PackDirectory.java
index 6a99cb3..28f6250 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/PackDirectory.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/PackDirectory.java
@@ -65,6 +65,8 @@
 	private static final PackList NO_PACKS = new PackList(FileSnapshot.DIRTY,
 			new Pack[0]);
 
+	private final Config config;
+
 	private final File directory;
 
 	private final AtomicReference<PackList> packList;
@@ -80,6 +82,7 @@
 	 *            the location of the {@code pack} directory.
 	 */
 	PackDirectory(Config config, File directory) {
+		this.config = config;
 		this.directory = directory;
 		packList = new AtomicReference<>(NO_PACKS);
 
@@ -123,7 +126,6 @@
 		return Collections.unmodifiableCollection(Arrays.asList(packs));
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public String toString() {
 		return "PackDirectory[" + getDirectory() + "]"; //$NON-NLS-1$ //$NON-NLS-2$
@@ -350,7 +352,7 @@
 	/**
 	 * @param n
 	 *            count of consecutive failures
-	 * @return @{code true} if i is a power of 2
+	 * @return {@code true} if i is a power of 2
 	 */
 	private boolean doLogExponentialBackoff(int n) {
 		return (n & (n - 1)) == 0;
@@ -458,7 +460,7 @@
 				continue;
 			}
 
-			list.add(new Pack(packFile, packFilesByExt.get(BITMAP_INDEX)));
+			list.add(new Pack(config, packFile, packFilesByExt.get(BITMAP_INDEX)));
 			foundNew = true;
 		}
 
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/PackFileSnapshot.java b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/PackFileSnapshot.java
index a784af8..dbf7d8a 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/PackFileSnapshot.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/PackFileSnapshot.java
@@ -48,7 +48,6 @@
 		this.checksum = checksum;
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public boolean isModified(File packFile) {
 		if (!super.isModified(packFile)) {
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/PackIndex.java b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/PackIndex.java
index f4f62d4..7778cb5 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/PackIndex.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/PackIndex.java
@@ -128,7 +128,6 @@
 		return findOffset(id) != -1;
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public boolean contains(AnyObjectId id) {
 		return findOffset(id) != -1;
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/PackIndexV1.java b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/PackIndexV1.java
index fff410b..860ebae 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/PackIndexV1.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/PackIndexV1.java
@@ -72,13 +72,11 @@
 		IO.readFully(fd, packChecksum, 0, packChecksum.length);
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public long getObjectCount() {
 		return objectCnt;
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public long getOffset64Count() {
 		long n64 = 0;
@@ -111,7 +109,6 @@
 		return (int) (nthPosition - base);
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public ObjectId getObjectId(long nthPosition) {
 		final int levelOne = findLevelOne(nthPosition);
@@ -128,7 +125,6 @@
 		return NB.decodeUInt32(idxdata[levelOne], p);
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public long findOffset(AnyObjectId objId) {
 		final int levelOne = objId.getFirstByte();
@@ -145,7 +141,6 @@
 		return (((long) b0) << 24) | (b1 << 16) | (b2 << 8) | (b3);
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public int findPosition(AnyObjectId objId) {
 		int levelOne = objId.getFirstByte();
@@ -193,25 +188,21 @@
 		return -1;
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public long findCRC32(AnyObjectId objId) {
 		throw new UnsupportedOperationException();
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public boolean hasCRC32Support() {
 		return false;
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public Iterator<MutableEntry> iterator() {
 		return new IndexV1Iterator();
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public void resolve(Set<ObjectId> matches, AbbreviatedObjectId id,
 			int matchLimit) throws IOException {
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/PackIndexV2.java b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/PackIndexV2.java
index 7a39006..751b62d 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/PackIndexV2.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/PackIndexV2.java
@@ -131,13 +131,11 @@
 		IO.readFully(fd, packChecksum, 0, packChecksum.length);
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public long getObjectCount() {
 		return objectCnt;
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public long getOffset64Count() {
 		return offset64.length / 8;
@@ -165,7 +163,6 @@
 		return (int) (nthPosition - base);
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public ObjectId getObjectId(long nthPosition) {
 		final int levelOne = findLevelOne(nthPosition);
@@ -174,7 +171,6 @@
 		return ObjectId.fromRaw(names[levelOne], p4 + p); // p * 5
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public long getOffset(long nthPosition) {
 		final int levelOne = findLevelOne(nthPosition);
@@ -182,7 +178,6 @@
 		return getOffset(levelOne, levelTwo);
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public long findOffset(AnyObjectId objId) {
 		final int levelOne = objId.getFirstByte();
@@ -192,7 +187,6 @@
 		return getOffset(levelOne, levelTwo);
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public int findPosition(AnyObjectId objId) {
 		int levelOne = objId.getFirstByte();
@@ -211,7 +205,6 @@
 		return p;
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public long findCRC32(AnyObjectId objId) throws MissingObjectException {
 		final int levelOne = objId.getFirstByte();
@@ -221,19 +214,16 @@
 		return NB.decodeUInt32(crc32[levelOne], levelTwo << 2);
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public boolean hasCRC32Support() {
 		return true;
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public Iterator<MutableEntry> iterator() {
 		return new EntriesIteratorV2();
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public void resolve(Set<ObjectId> matches, AbbreviatedObjectId id,
 			int matchLimit) throws IOException {
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/PackIndexWriterV1.java b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/PackIndexWriterV1.java
index e1612bb..7e28b5e 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/PackIndexWriterV1.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/PackIndexWriterV1.java
@@ -35,7 +35,6 @@
 		super(dst);
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	protected void writeImpl() throws IOException {
 		writeFanOutTable();
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/PackIndexWriterV2.java b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/PackIndexWriterV2.java
index 7adabad..fc5ef61 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/PackIndexWriterV2.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/PackIndexWriterV2.java
@@ -30,7 +30,6 @@
 		super(dst);
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	protected void writeImpl() throws IOException {
 		writeTOC(2);
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/PackInputStream.java b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/PackInputStream.java
index 0bceca7..fdc2f80 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/PackInputStream.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/PackInputStream.java
@@ -31,7 +31,6 @@
 		wc.pin(pack, pos);
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public int read(byte[] b, int off, int len) throws IOException {
 		int n = wc.copy(pack, pos, b, off, len);
@@ -39,7 +38,6 @@
 		return n;
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public int read() throws IOException {
 		byte[] buf = new byte[1];
@@ -47,7 +45,6 @@
 		return n == 1 ? buf[0] & 0xff : -1;
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public void close() {
 		wc.close();
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/PackInserter.java b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/PackInserter.java
index d6209c4..1b092a3 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/PackInserter.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/PackInserter.java
@@ -150,7 +150,6 @@
 		return buffer().length;
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public ObjectId insert(int type, byte[] data, int off, int len)
 			throws IOException {
@@ -169,7 +168,6 @@
 		return endObject(id, offset);
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public ObjectId insert(int type, long len, InputStream in)
 			throws IOException {
@@ -243,19 +241,16 @@
 		return 12;
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public PackParser newPackParser(InputStream in) {
 		throw new UnsupportedOperationException();
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public ObjectReader newReader() {
 		return new Reader();
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public void flush() throws IOException {
 		if (tmpPack == null) {
@@ -340,7 +335,6 @@
 		return ObjectId.fromRaw(md.digest());
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public void close() {
 		try {
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/PackObjectSizeIndexWriter.java b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/PackObjectSizeIndexWriter.java
index 65a065d..3286436 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/PackObjectSizeIndexWriter.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/PackObjectSizeIndexWriter.java
@@ -72,11 +72,13 @@
 	 *
 	 * Store position (in the main index) to size as parallel arrays.
 	 *
-	 * <p>Positions in the main index fit well in unsigned 24 bits (16M) for most
+	 * <p>
+	 * Positions in the main index fit well in unsigned 24 bits (16M) for most
 	 * repositories, but some outliers have even more objects, so we need to
 	 * store also 32 bits positions.
 	 *
-	 * <p>Sizes are stored as a first array parallel to positions. If a size
+	 * <p>
+	 * Sizes are stored as a first array parallel to positions. If a size
 	 * doesn't fit in an element of that array, then we encode there a position
 	 * on the next-size array. This "overflow" array doesn't have entries for
 	 * all positions.
@@ -85,30 +87,36 @@
 	 *
 	 *      positions       [10, 500, 1000, 1001]
 	 *      sizes (32bits)  [15MB, -1, 6MB, -2]
-   *                          ___/  ______/
+	*                          ___/  ______/
 	 *                        /     /
 	 *      sizes (64 bits) [3GB, 6GB]
 	 * </pre>
 	 *
-	 * <p>For sizes we use 32 bits as the first level and 64 for the rare objects
+	 * <p>
+	 * For sizes we use 32 bits as the first level and 64 for the rare objects
 	 * over 2GB.
 	 *
-	 * <p>A 24/32/64 bits hierarchy of arrays saves space if we have a lot of small
-	 * objects, but wastes space if we have only big ones. The min size to index is
-	 * controlled by conf and in principle we want to index only rather
-	 * big objects (e.g. > 10MB). We could support more dynamics read/write of sizes
+	 * <p>
+	 * A 24/32/64 bits hierarchy of arrays saves space if we have a lot of small
+	 * objects, but wastes space if we have only big ones. The min size to index
+	 * is controlled by conf and in principle we want to index only rather big
+	 * objects (e.g. > 10MB). We could support more dynamics read/write of sizes
 	 * (e.g. 24 only if the threshold will include many of those objects) but it
-	 * complicates a lot code and spec. If needed it could go for a v2 of the protocol.
+	 * complicates a lot code and spec. If needed it could go for a v2 of the
+	 * protocol.
 	 *
-	 * <p>Format:
-	 *
+	 * <p>
+	 * Format:
+	 * <ul>
 	 * <li>A header with the magic number (4 bytes)
 	 * <li>The index version (1 byte)
 	 * <li>The minimum object size (4 bytes)
 	 * <li>Total count of objects indexed (C, 4 bytes)
+	 * </ul>
 	 * (if count == 0, stop here)
-	 *
+	 * <p>
 	 * Blocks of
+	 * <ul>
 	 * <li>Size per entry in bits (1 byte, either 24 (0x18) or 32 (0x20))
 	 * <li>Count of entries (4 bytes) (c, as a signed int)
 	 * <li>positions encoded in s bytes each (i.e s*c bytes)
@@ -120,6 +128,7 @@
 	 * <li>Count of 64 bit sizes (s64) (or 0 if no more indirections)
 	 * <li>64 bit sizes (s64 * 8 bytes)
 	 * <li>0 (end)
+	 * </ul>
 	 */
 	static class PackObjectSizeWriterV1 extends PackObjectSizeIndexWriter {
 
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 1a5adb4..ef9753c 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
@@ -10,11 +10,8 @@
 
 package org.eclipse.jgit.internal.storage.file;
 
-import java.text.MessageFormat;
-
 import org.eclipse.jgit.errors.CorruptObjectException;
-import org.eclipse.jgit.internal.JGitText;
-import org.eclipse.jgit.internal.storage.file.PackIndex.MutableEntry;
+import org.eclipse.jgit.errors.PackMismatchException;
 import org.eclipse.jgit.lib.ObjectId;
 
 /**
@@ -27,92 +24,27 @@
  * @see PackIndex
  * @see Pack
  */
-public class PackReverseIndex {
-	/** Index we were created from, and that has our ObjectId data. */
-	private final PackIndex index;
-
-	/** The number of bytes per entry in the offsetIndex. */
-	private final long bucketSize;
+public interface PackReverseIndex {
+	/**
+	 * Magic bytes that uniquely identify git reverse index files.
+	 */
+	byte[] MAGIC = { 'R', 'I', 'D', 'X' };
 
 	/**
-	 * An index into the nth mapping, where the value is the position after the
-	 * the last index that contains the values of the bucket. For example given
-	 * offset o (and bucket = o / bucketSize), the offset will be contained in
-	 * the range nth[offsetIndex[bucket - 1]] inclusive to
-	 * nth[offsetIndex[bucket]] exclusive.
-	 *
-	 * See {@link #binarySearch}
+	 * The first reverse index file version.
 	 */
-	private final int[] offsetIndex;
-
-	/** Mapping from indices in offset order to indices in SHA-1 order. */
-	private final int[] nth;
+	int VERSION_1 = 1;
 
 	/**
-	 * Create reverse index from straight/forward pack index, by indexing all
-	 * its entries.
+	 * Verify that the pack checksum found in the reverse index matches that
+	 * from the pack file.
 	 *
-	 * @param packIndex
-	 *            forward index - entries to (reverse) index.
+	 * @param packFilePath
+	 *            the path to display in event of a mismatch
+	 * @throws PackMismatchException
+	 *             if the checksums do not match
 	 */
-	public PackReverseIndex(PackIndex packIndex) {
-		index = packIndex;
-
-		final long cnt = index.getObjectCount();
-		if (cnt + 1 > Integer.MAX_VALUE)
-			throw new IllegalArgumentException(
-					JGitText.get().hugeIndexesAreNotSupportedByJgitYet);
-
-		if (cnt == 0) {
-			bucketSize = Long.MAX_VALUE;
-			offsetIndex = new int[1];
-			nth = new int[0];
-			return;
-		}
-
-		final long[] offsetsBySha1 = new long[(int) cnt];
-
-		long maxOffset = 0;
-		int ith = 0;
-		for (MutableEntry me : index) {
-			final long o = me.getOffset();
-			offsetsBySha1[ith++] = o;
-			if (o > maxOffset)
-				maxOffset = o;
-		}
-
-		bucketSize = maxOffset / cnt + 1;
-		int[] bucketIndex = new int[(int) cnt];
-		int[] bucketValues = new int[(int) cnt + 1];
-		for (int oi = 0; oi < offsetsBySha1.length; oi++) {
-			final long o = offsetsBySha1[oi];
-			final int bucket = (int) (o / bucketSize);
-			final int bucketValuesPos = oi + 1;
-			final int current = bucketIndex[bucket];
-			bucketIndex[bucket] = bucketValuesPos;
-			bucketValues[bucketValuesPos] = current;
-		}
-
-		int nthByOffset = 0;
-		nth = new int[offsetsBySha1.length];
-		offsetIndex = bucketIndex; // Reuse the allocation
-		for (int bi = 0; bi < bucketIndex.length; bi++) {
-			final int start = nthByOffset;
-			// Insertion sort of the values in the bucket.
-			for (int vi = bucketIndex[bi]; vi > 0; vi = bucketValues[vi]) {
-				final int nthBySha1 = vi - 1;
-				final long o = offsetsBySha1[nthBySha1];
-				int insertion = nthByOffset++;
-				for (; start < insertion; insertion--) {
-					if (o > offsetsBySha1[nth[insertion - 1]])
-						break;
-					nth[insertion] = nth[insertion - 1];
-				}
-				nth[insertion] = nthBySha1;
-			}
-			offsetIndex[bi] = nthByOffset;
-		}
-	}
+	void verifyPackChecksum(String packFilePath) throws PackMismatchException;
 
 	/**
 	 * Search for object id with the specified start offset in this pack
@@ -122,12 +54,7 @@
 	 *            start offset of object to find.
 	 * @return object id for this offset, or null if no object was found.
 	 */
-	public ObjectId findObject(long offset) {
-		final int ith = binarySearch(offset);
-		if (ith < 0)
-			return null;
-		return index.getObjectId(nth[ith]);
-	}
+	ObjectId findObject(long offset);
 
 	/**
 	 * Search for the next offset to the specified offset in this pack (reverse)
@@ -144,42 +71,25 @@
 	 * @throws org.eclipse.jgit.errors.CorruptObjectException
 	 *             when there is no object with the provided offset.
 	 */
-	public long findNextOffset(long offset, long maxOffset)
-			throws CorruptObjectException {
-		final int ith = binarySearch(offset);
-		if (ith < 0)
-			throw new CorruptObjectException(
-					MessageFormat.format(
-							JGitText.get().cantFindObjectInReversePackIndexForTheSpecifiedOffset,
-							Long.valueOf(offset)));
+	long findNextOffset(long offset, long maxOffset)
+			throws CorruptObjectException;
 
-		if (ith + 1 == nth.length)
-			return maxOffset;
-		return index.getOffset(nth[ith + 1]);
-	}
+	/**
+	 * Find the position in the primary index of the object at the given pack
+	 * offset.
+	 *
+	 * @param offset
+	 *            the pack offset of the object
+	 * @return the position in the primary index of the object
+	 */
+	int findPosition(long offset);
 
-	int findPosition(long offset) {
-		return binarySearch(offset);
-	}
-
-	private int binarySearch(long offset) {
-		int bucket = (int) (offset / bucketSize);
-		int low = bucket == 0 ? 0 : offsetIndex[bucket - 1];
-		int high = offsetIndex[bucket];
-		while (low < high) {
-			final int mid = (low + high) >>> 1;
-			final long o = index.getOffset(nth[mid]);
-			if (offset < o)
-				high = mid;
-			else if (offset == o)
-				return mid;
-			else
-				low = mid + 1;
-		}
-		return -1;
-	}
-
-	ObjectId findObjectByPosition(int nthPosition) {
-		return index.getObjectId(nth[nthPosition]);
-	}
+	/**
+	 * Find the object that is in the given position in the primary index.
+	 *
+	 * @param nthPosition
+	 *            the position of the object in the primary index
+	 * @return the object in that position
+	 */
+	ObjectId findObjectByPosition(int nthPosition);
 }
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/PackReverseIndexComputed.java b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/PackReverseIndexComputed.java
new file mode 100644
index 0000000..0b487a2
--- /dev/null
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/PackReverseIndexComputed.java
@@ -0,0 +1,205 @@
+/*
+ * Copyright (C) 2023, Google LLC and others
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Distribution License v. 1.0 which is available at
+ * https://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+package org.eclipse.jgit.internal.storage.file;
+
+import java.text.MessageFormat;
+
+import org.eclipse.jgit.errors.CorruptObjectException;
+import org.eclipse.jgit.errors.PackMismatchException;
+import org.eclipse.jgit.internal.JGitText;
+import org.eclipse.jgit.internal.storage.file.PackIndex.MutableEntry;
+import org.eclipse.jgit.lib.ObjectId;
+
+/**
+ * Reverse index for forward pack index which is computed from the forward pack
+ * index.
+ * <p>
+ * Creating an instance uses an insertion sort of the entries in the forward
+ * index, so it runs in quadratic time on average.
+ */
+final class PackReverseIndexComputed implements PackReverseIndex {
+	/**
+	 * Index we were created from, and that has our ObjectId data.
+	 */
+	private final PackIndex index;
+
+	/**
+	 * The difference in offset between the start of an offset bucket and the
+	 * start of its succeeding bucket.
+	 */
+	private final long bucketSize;
+
+	/**
+	 * The indexes into indexPosInOffsetOrder at which the next bucket starts.
+	 * <p>
+	 * For example, given offset o (and therefore bucket = o / bucketSize), the
+	 * indexPos corresponding to o will be contained in the range
+	 * indexPosInOffsetOrder[nextBucketStart[bucket - 1]] inclusive to
+	 * indexPosInOffsetOrder[nextBucketStart[bucket]] exclusive.
+	 * <p>
+	 * This range information can speed up #binarySearch by identifying the
+	 * relevant bucket and only searching within its range.
+	 * <p>
+	 * See {@link #binarySearch}
+	 */
+	private final int[] nextBucketStart;
+
+	/**
+	 * Mapping from indices in offset order to indices in SHA-1 order.
+	 */
+	private final int[] indexPosInOffsetOrder;
+
+	/**
+	 * Create reverse index from straight/forward pack index, by indexing all
+	 * its entries.
+	 *
+	 * @param packIndex
+	 *            forward index - entries to (reverse) index.
+	 */
+	PackReverseIndexComputed(PackIndex packIndex) {
+		index = packIndex;
+
+		long rawCnt = index.getObjectCount();
+		if (rawCnt + 1 > Integer.MAX_VALUE) {
+			throw new IllegalArgumentException(
+					JGitText.get().hugeIndexesAreNotSupportedByJgitYet);
+		}
+		int cnt = (int) rawCnt;
+
+		if (cnt == 0) {
+			bucketSize = Long.MAX_VALUE;
+			nextBucketStart = new int[1];
+			indexPosInOffsetOrder = new int[0];
+			return;
+		}
+
+		// Sort the index positions according to the corresponding pack offsets.
+		// Use bucket sort since the offsets are somewhat uniformly distributed
+		// over the range (0, pack size).
+		long[] offsetsInIndexOrder = new long[cnt];
+		long maxOffset = 0;
+		int i = 0;
+		for (MutableEntry entry : index) {
+			long offset = entry.getOffset();
+			offsetsInIndexOrder[i++] = offset;
+			if (offset > maxOffset) {
+				maxOffset = offset;
+			}
+		}
+
+		bucketSize = maxOffset / cnt + 1;
+		// The values in each bucket, stored as a linked list. Given a bucket,
+		// headValues[bucket] contains the first value,
+		// furtherValues[headValues[bucket]] contains the second,
+		// furtherValues[furtherValues[headValues[bucket]]] the third, and so
+		// on. The linked list stops when a value is 0. The values themselves
+		// are shifted index positions. There won't be any
+		// collisions because every index position is unique.
+		int[] headValues = new int[cnt];
+		int[] furtherValues = new int[cnt + 1];
+		for (int indexPos = 0; indexPos < cnt; indexPos++) {
+			// The offset determines which bucket this index position falls
+			// into, since the goal is sort into offset order.
+			long offset = offsetsInIndexOrder[indexPos];
+			int bucket = (int) (offset / bucketSize);
+			// Store the index positions as 1-indexed so that default
+			// initialized value 0 can be interpreted as the end of the bucket
+			// values.
+			int asBucketValue = indexPos + 1;
+			// If there is an existing value in this bucket, push the value to
+			// the front of the linked list.
+			int current = headValues[bucket];
+			headValues[bucket] = asBucketValue;
+			furtherValues[asBucketValue] = current;
+		}
+
+		int nthByOffset = 0;
+		indexPosInOffsetOrder = new int[cnt];
+		nextBucketStart = headValues; // Reuse the allocation
+		for (int bi = 0; bi < headValues.length; bi++) {
+			// Insertion sort of the values in the bucket.
+			int start = nthByOffset;
+			for (int vi = headValues[bi]; vi > 0; vi = furtherValues[vi]) {
+				int nthBySha1 = vi - 1;
+				long o = offsetsInIndexOrder[nthBySha1];
+				int insertion = nthByOffset++;
+				for (; start < insertion; insertion--) {
+					if (o > offsetsInIndexOrder[indexPosInOffsetOrder[insertion
+							- 1]]) {
+						break;
+					}
+					indexPosInOffsetOrder[insertion] = indexPosInOffsetOrder[insertion
+							- 1];
+				}
+				indexPosInOffsetOrder[insertion] = nthBySha1;
+			}
+			nextBucketStart[bi] = nthByOffset;
+		}
+	}
+
+	@Override
+	public void verifyPackChecksum(String packFilePath)
+			throws PackMismatchException {
+		// There is no file with a checksum.
+	}
+
+	@Override
+	public ObjectId findObject(long offset) {
+		final int ith = binarySearch(offset);
+		if (ith < 0) {
+			return null;
+		}
+		return index.getObjectId(indexPosInOffsetOrder[ith]);
+	}
+
+	@Override
+	public long findNextOffset(long offset, long maxOffset)
+			throws CorruptObjectException {
+		final int ith = binarySearch(offset);
+		if (ith < 0) {
+			throw new CorruptObjectException(MessageFormat.format(JGitText
+					.get().cantFindObjectInReversePackIndexForTheSpecifiedOffset,
+					Long.valueOf(offset)));
+		}
+
+		if (ith + 1 == indexPosInOffsetOrder.length) {
+			return maxOffset;
+		}
+		return index.getOffset(indexPosInOffsetOrder[ith + 1]);
+	}
+
+	@Override
+	public int findPosition(long offset) {
+		return binarySearch(offset);
+	}
+
+	private int binarySearch(long offset) {
+		int bucket = (int) (offset / bucketSize);
+		int low = bucket == 0 ? 0 : nextBucketStart[bucket - 1];
+		int high = nextBucketStart[bucket];
+		while (low < high) {
+			final int mid = (low + high) >>> 1;
+			final long o = index.getOffset(indexPosInOffsetOrder[mid]);
+			if (offset < o) {
+				high = mid;
+			} else if (offset == o) {
+				return mid;
+			} else {
+				low = mid + 1;
+			}
+		}
+		return -1;
+	}
+
+	@Override
+	public ObjectId findObjectByPosition(int nthPosition) {
+		return index.getObjectId(indexPosInOffsetOrder[nthPosition]);
+	}
+}
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/PackReverseIndexFactory.java b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/PackReverseIndexFactory.java
new file mode 100644
index 0000000..32830c3
--- /dev/null
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/PackReverseIndexFactory.java
@@ -0,0 +1,117 @@
+/*
+ * Copyright (C) 2023, Google LLC and others
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Distribution License v. 1.0 which is available at
+ * 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.eclipse.jgit.internal.storage.file.PackReverseIndex.MAGIC;
+import static org.eclipse.jgit.internal.storage.file.PackReverseIndex.VERSION_1;
+
+import java.io.DataInput;
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.io.InputStream;
+import java.security.DigestInputStream;
+import java.text.MessageFormat;
+import java.util.Arrays;
+
+import org.eclipse.jgit.internal.JGitText;
+import org.eclipse.jgit.lib.Constants;
+import org.eclipse.jgit.util.IO;
+import org.eclipse.jgit.util.io.SilentFileInputStream;
+
+/**
+ * Factory for creating instances of {@link PackReverseIndex}.
+ */
+public final class PackReverseIndexFactory {
+	/**
+	 * Create an in-memory pack reverse index by reading it from the given file
+	 * if the file exists, or computing it from the given pack index if the file
+	 * doesn't exist.
+	 *
+	 * @param idxFile
+	 *            the file to read the pack file from, if it exists
+	 * @param objectCount
+	 *            the number of objects in the corresponding pack
+	 * @param packIndexSupplier
+	 *            a function to lazily get the corresponding forward index
+	 * @return the reverse index instance
+	 * @throws IOException
+	 *             if reading from the file fails
+	 */
+	static PackReverseIndex openOrCompute(File idxFile, long objectCount,
+			PackBitmapIndex.SupplierWithIOException<PackIndex> packIndexSupplier)
+			throws IOException {
+		try (SilentFileInputStream fd = new SilentFileInputStream(idxFile)) {
+			return readFromFile(fd, objectCount, packIndexSupplier);
+		} catch (FileNotFoundException e) {
+			return computeFromIndex(packIndexSupplier.get());
+		} catch (IOException e) {
+			throw new IOException(
+					MessageFormat.format(JGitText.get().unreadablePackIndex,
+							idxFile.getAbsolutePath()),
+					e);
+		}
+	}
+
+	/**
+	 * Compute an in-memory pack reverse index from the in-memory pack forward
+	 * index. This computation uses insertion sort, which has a quadratic
+	 * runtime on average.
+	 *
+	 * @param packIndex
+	 *            the forward index to compute from
+	 * @return the reverse index instance
+	 */
+	public static PackReverseIndex computeFromIndex(PackIndex packIndex) {
+		return new PackReverseIndexComputed(packIndex);
+	}
+
+	/**
+	 * Read an in-memory pack reverse index from the given input stream. This
+	 * has a linear runtime.
+	 *
+	 * @param src
+	 *            the input stream to read the contents from
+	 * @param objectCount
+	 *            the number of objects in the corresponding pack
+	 * @param packIndexSupplier
+	 *            a function to lazily get the corresponding forward index
+	 * @return the reverse index instance
+	 * @throws IOException
+	 *             if reading from the input stream fails
+	 */
+	static PackReverseIndex readFromFile(InputStream src, long objectCount,
+			PackBitmapIndex.SupplierWithIOException<PackIndex> packIndexSupplier)
+			throws IOException {
+		final DigestInputStream digestIn = new DigestInputStream(src,
+				Constants.newMessageDigest());
+
+		final byte[] magic = new byte[MAGIC.length];
+		IO.readFully(digestIn, magic);
+		if (!Arrays.equals(magic, MAGIC)) {
+			throw new IOException(
+					MessageFormat.format(JGitText.get().expectedGot,
+							Arrays.toString(MAGIC), Arrays.toString(magic)));
+		}
+
+		DataInput dataIn = new SimpleDataInput(digestIn);
+		int version = dataIn.readInt();
+		switch (version) {
+		case VERSION_1:
+			return new PackReverseIndexV1(digestIn, objectCount,
+					packIndexSupplier);
+		default:
+			throw new IOException(MessageFormat.format(
+					JGitText.get().unsupportedPackReverseIndexVersion,
+					String.valueOf(version)));
+		}
+	}
+}
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/PackReverseIndexV1.java b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/PackReverseIndexV1.java
new file mode 100644
index 0000000..c77a8eb
--- /dev/null
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/PackReverseIndexV1.java
@@ -0,0 +1,208 @@
+/*
+ * Copyright (C) 2022, Google LLC and others
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Distribution License v. 1.0 which is available at
+ * 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.eclipse.jgit.lib.Constants.OBJECT_ID_LENGTH;
+
+import java.io.DataInput;
+import java.io.IOException;
+import java.io.UncheckedIOException;
+import java.security.DigestInputStream;
+import java.text.MessageFormat;
+import java.util.Arrays;
+
+import org.eclipse.jgit.errors.CorruptObjectException;
+import org.eclipse.jgit.errors.PackMismatchException;
+import org.eclipse.jgit.internal.JGitText;
+import org.eclipse.jgit.internal.storage.pack.PackExt;
+import org.eclipse.jgit.lib.ObjectId;
+import org.eclipse.jgit.util.Hex;
+import org.eclipse.jgit.util.IO;
+
+/**
+ * Reverse index for forward pack index which is parsed from a version 1 file.
+ * <p>
+ * The file format is specified at
+ * https://git-scm.com/docs/pack-format#_pack_rev_files_have_the_format.
+ */
+final class PackReverseIndexV1 implements PackReverseIndex {
+	static final int OID_VERSION_SHA1 = 1;
+
+	static final int OID_VERSION_SHA256 = 2;
+
+	private static final int SHA1_BYTES = OBJECT_ID_LENGTH;
+
+	private final DigestInputStream inputStream;
+
+	private final DataInput dataIn;
+
+	/**
+	 * A lazy supplier for the corresponding PackIndex. The PackIndex is not
+	 * needed during instantiation and parsing, only later when querying the
+	 * reverse index. Allow lazy loading so that the parsing of the forward and
+	 * reverse indices could happen in parallel.
+	 */
+	private final PackBitmapIndex.SupplierWithIOException<PackIndex> packIndexSupplier;
+
+	private int objectCount;
+
+	private byte[] packChecksum;
+
+	private int[] indexPositionsSortedByOffset;
+
+	private PackIndex packIndex;
+
+	PackReverseIndexV1(DigestInputStream inputStream, long objectCount,
+			PackBitmapIndex.SupplierWithIOException<PackIndex> packIndexSupplier)
+			throws IOException {
+		try {
+			this.objectCount = Math.toIntExact(objectCount);
+		} catch (ArithmeticException e) {
+			throw new IllegalArgumentException(
+					JGitText.get().hugeIndexesAreNotSupportedByJgitYet);
+		}
+
+		this.inputStream = inputStream;
+		dataIn = new SimpleDataInput(inputStream);
+
+		int oid_version = dataIn.readInt();
+		switch (oid_version) {
+		case OID_VERSION_SHA1:
+			// JGit Pack only supports AnyObjectId, which represents SHA1.
+			break;
+		case OID_VERSION_SHA256:
+			throw new IOException(MessageFormat.format(
+					JGitText.get().unsupportedObjectIdVersion, "SHA256")); //$NON-NLS-1$
+		default:
+			throw new IOException(MessageFormat.format(
+					JGitText.get().unsupportedObjectIdVersion,
+					String.valueOf(oid_version)));
+		}
+
+		indexPositionsSortedByOffset = new int[this.objectCount];
+		this.packIndexSupplier = packIndexSupplier;
+
+		parseBody();
+		parseChecksums();
+	}
+
+	@Override
+	public void verifyPackChecksum(String packFilePath)
+			throws PackMismatchException {
+		if (!Arrays.equals(packChecksum, getPackIndex().getChecksum())) {
+			throw new PackMismatchException(
+					MessageFormat.format(JGitText.get().packChecksumMismatch,
+							packFilePath, PackExt.INDEX.getExtension(),
+							Hex.toHexString(getPackIndex().getChecksum()),
+							PackExt.REVERSE_INDEX.getExtension(),
+							Hex.toHexString(packChecksum)));
+		}
+	}
+
+		private void parseBody() throws IOException {
+		for (int i = 0; i < objectCount; i++) {
+			indexPositionsSortedByOffset[i] = dataIn.readInt();
+		}
+	}
+
+	private void parseChecksums() throws IOException {
+		packChecksum = new byte[SHA1_BYTES];
+		IO.readFully(inputStream, packChecksum);
+
+		// Take digest before reading the self checksum changes it.
+		byte[] observedSelfChecksum = inputStream.getMessageDigest().digest();
+
+		byte[] readSelfChecksum = new byte[SHA1_BYTES];
+		IO.readFully(inputStream, readSelfChecksum);
+
+		if (!Arrays.equals(readSelfChecksum, observedSelfChecksum)) {
+			throw new CorruptObjectException(MessageFormat.format(
+					JGitText.get().corruptReverseIndexChecksumIncorrect,
+					Hex.toHexString(readSelfChecksum),
+					Hex.toHexString(observedSelfChecksum)));
+		}
+	}
+
+	@Override
+	public ObjectId findObject(long offset) {
+		int reversePosition = findPosition(offset);
+		if (reversePosition < 0) {
+			return null;
+		}
+		int forwardPosition = findForwardPositionByReversePosition(
+				reversePosition);
+		return getPackIndex().getObjectId(forwardPosition);
+	}
+
+	@Override
+	public long findNextOffset(long offset, long maxOffset)
+			throws CorruptObjectException {
+		int position = findPosition(offset);
+		if (position < 0) {
+			throw new CorruptObjectException(MessageFormat.format(JGitText
+					.get().cantFindObjectInReversePackIndexForTheSpecifiedOffset,
+					Long.valueOf(offset)));
+		}
+		if (position + 1 == objectCount) {
+			return maxOffset;
+		}
+		return findOffsetByReversePosition(position + 1);
+	}
+
+	@Override
+	public int findPosition(long offset) {
+		return binarySearchByOffset(offset);
+	}
+
+	@Override
+	public ObjectId findObjectByPosition(int position) {
+		return getPackIndex()
+				.getObjectId(findForwardPositionByReversePosition(position));
+	}
+
+	private long findOffsetByReversePosition(int position) {
+		return getPackIndex()
+				.getOffset(findForwardPositionByReversePosition(position));
+	}
+
+	private int findForwardPositionByReversePosition(int reversePosition) {
+		assert (reversePosition >= 0);
+		assert (reversePosition < indexPositionsSortedByOffset.length);
+		return indexPositionsSortedByOffset[reversePosition];
+	}
+
+	private int binarySearchByOffset(long wantedOffset) {
+		int low = 0;
+		int high = objectCount - 1;
+		while (low <= high) {
+			int mid = (low + high) >>> 1;
+			long offsetAtMid = findOffsetByReversePosition(mid);
+			if (offsetAtMid == wantedOffset) {
+				return mid;
+			} else if (offsetAtMid > wantedOffset) {
+				high = mid - 1;
+			} else {
+				low = mid + 1;
+			}
+		}
+		return -1;
+	}
+
+	private PackIndex getPackIndex() {
+		if (packIndex == null) {
+			try {
+				packIndex = packIndexSupplier.get();
+			} catch (IOException e) {
+				throw new UncheckedIOException(e);
+			}
+		}
+		return packIndex;
+	}
+}
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/PackReverseIndexWriter.java b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/PackReverseIndexWriter.java
index 4c8417b..94a4e9c 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/PackReverseIndexWriter.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/PackReverseIndexWriter.java
@@ -9,6 +9,8 @@
  */
 package org.eclipse.jgit.internal.storage.file;
 
+import static org.eclipse.jgit.internal.storage.file.PackReverseIndex.VERSION_1;
+
 import java.io.BufferedOutputStream;
 import java.io.DataOutput;
 import java.io.IOException;
@@ -29,16 +31,6 @@
  */
 public abstract class PackReverseIndexWriter {
 	/**
-	 * Magic bytes that uniquely identify git reverse index files.
-	 */
-	protected static byte[] MAGIC = { 'R', 'I', 'D', 'X' };
-
-	/**
-	 * The first reverse index file version.
-	 */
-	protected static final int VERSION_1 = 1;
-
-	/**
 	 * Stream to write contents to while maintaining a checksum.
 	 */
 	protected final DigestOutputStream out;
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/PackReverseIndexWriterV1.java b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/PackReverseIndexWriterV1.java
index 7630724..ff1809f 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/PackReverseIndexWriterV1.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/PackReverseIndexWriterV1.java
@@ -9,6 +9,10 @@
  */
 package org.eclipse.jgit.internal.storage.file;
 
+import static org.eclipse.jgit.internal.storage.file.PackReverseIndex.MAGIC;
+import static org.eclipse.jgit.internal.storage.file.PackReverseIndex.VERSION_1;
+import static org.eclipse.jgit.internal.storage.file.PackReverseIndexV1.OID_VERSION_SHA1;
+
 import java.io.IOException;
 import java.io.OutputStream;
 import java.util.List;
@@ -24,8 +28,6 @@
  * https://git-scm.com/docs/pack-format#_pack_rev_files_have_the_format.
  */
 final class PackReverseIndexWriterV1 extends PackReverseIndexWriter {
-	private static final int OID_VERSION_SHA1 = 1;
-
 	private static final int DEFAULT_OID_VERSION = OID_VERSION_SHA1;
 
 	PackReverseIndexWriterV1(final OutputStream dst) {
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/PackedBatchRefUpdate.java b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/PackedBatchRefUpdate.java
index 106313d..5584f13 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/PackedBatchRefUpdate.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/PackedBatchRefUpdate.java
@@ -98,7 +98,6 @@
 	  this.shouldLockLooseRefs = shouldLockLooseRefs;
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public void execute(RevWalk walk, ProgressMonitor monitor,
 			List<String> options) throws IOException {
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 9f31e68..8bf6c67 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
@@ -247,7 +247,6 @@
 		return new SnapshottingRefDirectory(this);
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public void create() throws IOException {
 		FileUtils.mkdir(refsDir);
@@ -256,7 +255,6 @@
 		newLogWriter(false).create();
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public void close() {
 		clearReferences();
@@ -267,14 +265,12 @@
 		packedRefs.set(NO_PACKED_REFS);
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public void refresh() {
 		super.refresh();
 		clearReferences();
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public boolean isNameConflicting(String name) throws IOException {
 		// Cannot be nested within an existing reference.
@@ -312,7 +308,6 @@
 		}
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public Ref exactRef(String name) throws IOException {
 		try {
@@ -322,7 +317,6 @@
 		}
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	@NonNull
 	public Map<String, Ref> exactRef(String... refs) throws IOException {
@@ -341,7 +335,6 @@
 		}
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	@Nullable
 	public Ref firstExactRef(String... refs) throws IOException {
@@ -359,7 +352,6 @@
 		}
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public Map<String, Ref> getRefs(String prefix) throws IOException {
 		final RefList<LooseRef> oldLoose = looseRefs.get();
@@ -399,7 +391,6 @@
 		return new RefMap(prefix, packed, upcast(loose), symbolic.toRefList());
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public List<Ref> getAdditionalRefs() throws IOException {
 		List<Ref> ret = new LinkedList<>();
@@ -534,7 +525,6 @@
 		}
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public Ref peel(Ref ref) throws IOException {
 		final Ref leaf = ref.getLeaf();
@@ -585,7 +575,6 @@
 		fireRefsChanged();
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public RefDirectoryUpdate newUpdate(String name, boolean detach)
 			throws IOException {
@@ -609,7 +598,6 @@
 		return new RefDirectoryUpdate(this, ref);
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public RefDirectoryRename newRename(String fromName, String toName)
 			throws IOException {
@@ -622,7 +610,6 @@
 		return new RefDirectoryRename(from, to);
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public PackedBatchRefUpdate newBatchUpdate() {
 		return new PackedBatchRefUpdate(this);
@@ -643,7 +630,6 @@
 		return new PackedBatchRefUpdate(this, shouldLockLooseRefs);
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public boolean performsAtomicTransactions() {
 		return true;
@@ -724,6 +710,7 @@
 	 * @param refs
 	 *            the refs to be added. Must be fully qualified.
 	 * @throws java.io.IOException
+	 *             if an IO error occurred
 	 */
 	public void pack(List<String> refs) throws IOException {
 		pack(refs, Collections.emptyMap());
@@ -868,26 +855,29 @@
 	 * has this attributes simply return it. Otherwise create a new peeled
 	 * {@link ObjectIdRef} where Storage is set to PACKED.
 	 *
-	 * @param f
+	 * @param ref
+	 *            given ref
 	 * @return a ref for Storage PACKED having the same name, id, peeledId as f
 	 * @throws MissingObjectException
+	 *             if an object is missing
 	 * @throws IOException
+	 *             if an IO error occurred
 	 */
-	private Ref peeledPackedRef(Ref f)
+	private Ref peeledPackedRef(Ref ref)
 			throws MissingObjectException, IOException {
-		if (f.getStorage().isPacked() && f.isPeeled()) {
-			return f;
+		if (ref.getStorage().isPacked() && ref.isPeeled()) {
+			return ref;
 		}
-		if (!f.isPeeled()) {
-			f = peel(f);
+		if (!ref.isPeeled()) {
+			ref = peel(ref);
 		}
-		ObjectId peeledObjectId = f.getPeeledObjectId();
+		ObjectId peeledObjectId = ref.getPeeledObjectId();
 		if (peeledObjectId != null) {
-			return new ObjectIdRef.PeeledTag(PACKED, f.getName(),
-					f.getObjectId(), peeledObjectId);
+			return new ObjectIdRef.PeeledTag(PACKED, ref.getName(),
+					ref.getObjectId(), peeledObjectId);
 		}
-		return new ObjectIdRef.PeeledNonTag(PACKED, f.getName(),
-				f.getObjectId());
+		return new ObjectIdRef.PeeledNonTag(PACKED, ref.getName(),
+				ref.getObjectId());
 	}
 
 	void log(boolean force, RefUpdate update, String msg, boolean deref)
@@ -1236,6 +1226,7 @@
 	 *
 	 * @return {@code true} if we are currently cloning a repository
 	 * @throws IOException
+	 *             if an IO error occurred
 	 */
 	boolean isInClone() throws IOException {
 		return hasDanglingHead() && !packedRefsFile.exists() && !hasLooseRef();
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/RefDirectoryRename.java b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/RefDirectoryRename.java
index d07299e..1c5c48a 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/RefDirectoryRename.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/RefDirectoryRename.java
@@ -68,7 +68,6 @@
 		return refdb;
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	protected Result doRename() throws IOException {
 		if (source.getRef().isSymbolic())
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/RefDirectoryUpdate.java b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/RefDirectoryUpdate.java
index 0dcb319..1dc4e30 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/RefDirectoryUpdate.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/RefDirectoryUpdate.java
@@ -32,19 +32,16 @@
 		database = r;
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	protected RefDirectory getRefDatabase() {
 		return database;
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	protected Repository getRepository() {
 		return database.getRepository();
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	protected boolean tryLock(boolean deref) throws IOException {
 		shouldDeref = deref;
@@ -61,7 +58,6 @@
 		return false;
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	protected void unlock() {
 		if (lock != null) {
@@ -70,7 +66,6 @@
 		}
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	protected Result doUpdate(Result status) throws IOException {
 		WriteConfig wc = database.getRepository().getConfig()
@@ -112,7 +107,6 @@
 		}
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	protected Result doDelete(Result status) throws IOException {
 		if (getRef().getStorage() != Ref.Storage.NEW)
@@ -120,7 +114,6 @@
 		return status;
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	protected Result doLink(String target) throws IOException {
 		WriteConfig wc = database.getRepository().getConfig()
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/ReflogEntryImpl.java b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/ReflogEntryImpl.java
index cb80043..6870d76 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/ReflogEntryImpl.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/ReflogEntryImpl.java
@@ -60,7 +60,6 @@
 	/* (non-Javadoc)
 	 * @see org.eclipse.jgit.internal.storage.file.ReflogEntry#getOldId()
 	 */
-	/** {@inheritDoc} */
 	@Override
 	public ObjectId getOldId() {
 		return oldId;
@@ -69,7 +68,6 @@
 	/* (non-Javadoc)
 	 * @see org.eclipse.jgit.internal.storage.file.ReflogEntry#getNewId()
 	 */
-	/** {@inheritDoc} */
 	@Override
 	public ObjectId getNewId() {
 		return newId;
@@ -78,7 +76,6 @@
 	/* (non-Javadoc)
 	 * @see org.eclipse.jgit.internal.storage.file.ReflogEntry#getWho()
 	 */
-	/** {@inheritDoc} */
 	@Override
 	public PersonIdent getWho() {
 		return who;
@@ -87,13 +84,11 @@
 	/* (non-Javadoc)
 	 * @see org.eclipse.jgit.internal.storage.file.ReflogEntry#getComment()
 	 */
-	/** {@inheritDoc} */
 	@Override
 	public String getComment() {
 		return comment;
 	}
 
-	/** {@inheritDoc} */
 	@SuppressWarnings("nls")
 	@Override
 	public String toString() {
@@ -104,7 +99,6 @@
 	/* (non-Javadoc)
 	 * @see org.eclipse.jgit.internal.storage.file.ReflogEntry#parseCheckout()
 	 */
-	/** {@inheritDoc} */
 	@Override
 	public CheckoutEntry parseCheckout() {
 		if (getComment().startsWith(CheckoutEntryImpl.CHECKOUT_MOVING_FROM)) {
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/ReflogReaderImpl.java b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/ReflogReaderImpl.java
index 99a9e09..21b5a54 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/ReflogReaderImpl.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/ReflogReaderImpl.java
@@ -32,7 +32,9 @@
 
 	/**
 	 * @param db
+	 *            repository to read reflogs from
 	 * @param refname
+	 *            {@code Ref} name
 	 */
 	ReflogReaderImpl(Repository db, String refname) {
 		logName = new File(db.getDirectory(), Constants.LOGS + '/' + refname);
@@ -41,7 +43,6 @@
 	/* (non-Javadoc)
 	 * @see org.eclipse.jgit.internal.storage.file.ReflogReaader#getLastEntry()
 	 */
-	/** {@inheritDoc} */
 	@Override
 	public ReflogEntry getLastEntry() throws IOException {
 		return getReverseEntry(0);
@@ -50,7 +51,6 @@
 	/* (non-Javadoc)
 	 * @see org.eclipse.jgit.internal.storage.file.ReflogReaader#getReverseEntries()
 	 */
-	/** {@inheritDoc} */
 	@Override
 	public List<ReflogEntry> getReverseEntries() throws IOException {
 		return getReverseEntries(Integer.MAX_VALUE);
@@ -59,7 +59,6 @@
 	/* (non-Javadoc)
 	 * @see org.eclipse.jgit.internal.storage.file.ReflogReaader#getReverseEntry(int)
 	 */
-	/** {@inheritDoc} */
 	@Override
 	public ReflogEntry getReverseEntry(int number) throws IOException {
 		if (number < 0)
@@ -89,7 +88,6 @@
 	/* (non-Javadoc)
 	 * @see org.eclipse.jgit.internal.storage.file.ReflogReaader#getReverseEntries(int)
 	 */
-	/** {@inheritDoc} */
 	@Override
 	public List<ReflogEntry> getReverseEntries(int max) throws IOException {
 		final byte[] log;
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/ReflogWriter.java b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/ReflogWriter.java
index 7032083..b1ceb14 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/ReflogWriter.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/ReflogWriter.java
@@ -91,6 +91,7 @@
 	 * Create the log directories.
 	 *
 	 * @throws java.io.IOException
+	 *             if an IO error occurred
 	 * @return this writer.
 	 */
 	public ReflogWriter create() throws IOException {
@@ -110,6 +111,7 @@
 	 *            a {@link org.eclipse.jgit.lib.ReflogEntry} object.
 	 * @return this writer
 	 * @throws java.io.IOException
+	 *             if an IO error occurred
 	 */
 	public ReflogWriter log(String refName, ReflogEntry entry)
 			throws IOException {
@@ -132,6 +134,7 @@
 	 *            reflog message
 	 * @return this writer
 	 * @throws java.io.IOException
+	 *             if an IO error occurred
 	 */
 	public ReflogWriter log(String refName, ObjectId oldId,
 			ObjectId newId, PersonIdent ident, String message) throws IOException {
@@ -150,6 +153,7 @@
 	 *            whether to dereference symbolic refs
 	 * @return this writer
 	 * @throws java.io.IOException
+	 *             if an IO error occurred
 	 */
 	public ReflogWriter log(RefUpdate update, String msg,
 			boolean deref) throws IOException {
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/SimpleDataInput.java b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/SimpleDataInput.java
index 6a80519..7a564cc 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/SimpleDataInput.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/SimpleDataInput.java
@@ -31,14 +31,12 @@
 		this.fd = fd;
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public int readInt() throws IOException {
 		readFully(buf, 0, 4);
 		return NB.decodeInt32(buf, 0);
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public long readLong() throws IOException {
 		readFully(buf, 0, 8);
@@ -57,79 +55,66 @@
 		return NB.decodeUInt32(buf, 0);
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public void readFully(byte[] b) throws IOException {
 		readFully(b, 0, b.length);
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public void readFully(byte[] b, int off, int len) throws IOException {
 		IO.readFully(fd, b, off, len);
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public int skipBytes(int n) throws IOException {
 		throw new UnsupportedOperationException();
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public boolean readBoolean() throws IOException {
 		throw new UnsupportedOperationException();
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public byte readByte() throws IOException {
 		throw new UnsupportedOperationException();
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public int readUnsignedByte() throws IOException {
 		throw new UnsupportedOperationException();
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public short readShort() throws IOException {
 		throw new UnsupportedOperationException();
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public int readUnsignedShort() throws IOException {
 		throw new UnsupportedOperationException();
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public char readChar() throws IOException {
 		throw new UnsupportedOperationException();
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public float readFloat() throws IOException {
 		throw new UnsupportedOperationException();
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public double readDouble() throws IOException {
 		throw new UnsupportedOperationException();
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public String readLine() throws IOException {
 		throw new UnsupportedOperationException();
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public String readUTF() throws IOException {
 		throw new UnsupportedOperationException();
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/SimpleDataOutput.java b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/SimpleDataOutput.java
index d01f6b4..7484088 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/SimpleDataOutput.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/SimpleDataOutput.java
@@ -31,88 +31,74 @@
 		this.fd = fd;
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public void writeShort(int v) throws IOException {
 		NB.encodeInt16(buf, 0, v);
 		fd.write(buf, 0, 2);
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public void writeInt(int v) throws IOException {
 		NB.encodeInt32(buf, 0, v);
 		fd.write(buf, 0, 4);
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public void writeLong(long v) throws IOException {
 		NB.encodeInt64(buf, 0, v);
 		fd.write(buf, 0, 8);
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public void write(int b) throws IOException {
 		throw new UnsupportedOperationException();
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public void write(byte[] b) throws IOException {
 		throw new UnsupportedOperationException();
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public void write(byte[] b, int off, int len) throws IOException {
 		throw new UnsupportedOperationException();
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public void writeBoolean(boolean v) throws IOException {
 		throw new UnsupportedOperationException();
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public void writeByte(int v) throws IOException {
 		throw new UnsupportedOperationException();
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public void writeChar(int v) throws IOException {
 		throw new UnsupportedOperationException();
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public void writeFloat(float v) throws IOException {
 		throw new UnsupportedOperationException();
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public void writeDouble(double v) throws IOException {
 		throw new UnsupportedOperationException();
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public void writeBytes(String s) throws IOException {
 		throw new UnsupportedOperationException();
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public void writeChars(String s) throws IOException {
 		throw new UnsupportedOperationException();
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public void writeUTF(String s) throws IOException {
 		throw new UnsupportedOperationException();
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/SnapshottingRefDirectory.java b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/SnapshottingRefDirectory.java
index 0b97480..767084a 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/SnapshottingRefDirectory.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/SnapshottingRefDirectory.java
@@ -67,14 +67,12 @@
 		return packedRefs.get();
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	void delete(RefDirectoryUpdate update) throws IOException {
 		refreshSnapshot();
 		super.delete(update);
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public RefDirectoryUpdate newUpdate(String name, boolean detach)
 			throws IOException {
@@ -82,19 +80,16 @@
 		return super.newUpdate(name, detach);
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public PackedBatchRefUpdate newBatchUpdate() {
 		return new SnapshotPackedBatchRefUpdate(this);
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public PackedBatchRefUpdate newBatchUpdate(boolean shouldLockLooseRefs) {
 		return new SnapshotPackedBatchRefUpdate(this, shouldLockLooseRefs);
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	RefDirectoryUpdate newTemporaryUpdate() throws IOException {
 		refreshSnapshot();
@@ -126,6 +121,7 @@
 	 * threads use this snapshot.
 	 *
 	 * @throws IOException
+	 *             if an IO error occurred
 	 */
 	private synchronized void refreshSnapshot() throws IOException {
 		compareAndSetPackedRefs(packedRefs.get(), refDb.getPackedRefs());
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/WindowCache.java b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/WindowCache.java
index 25653b3..81537dd 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/WindowCache.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/WindowCache.java
@@ -435,7 +435,9 @@
 
 	private final AtomicBoolean publishMBean = new AtomicBoolean();
 
-	private boolean useStrongRefs;
+	private final boolean useStrongRefs;
+
+	private final boolean useStrongIndexRefs;
 
 	private WindowCache(WindowCacheConfig cfg) {
 		tableSize = tableSize(cfg);
@@ -467,6 +469,7 @@
 		windowSizeShift = bits(cfg.getPackedGitWindowSize());
 		windowSize = 1 << windowSizeShift;
 		useStrongRefs = cfg.isPackedGitUseStrongRefs();
+		useStrongIndexRefs = cfg.isPackedIndexGitUseStrongRefs();
 		queue = useStrongRefs ? new StrongCleanupQueue(this)
 				: new SoftCleanupQueue(this);
 
@@ -751,6 +754,10 @@
 		return n == top.next ? top : new Entry(n, top.ref);
 	}
 
+	boolean isPackedIndexGitUseStrongRefs() {
+		return useStrongIndexRefs;
+	}
+
 	private static class Entry {
 		/** Next entry in the hash table's chain list. */
 		final Entry next;
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 fa743ba..01f514b 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
@@ -79,13 +79,11 @@
 		return baseCache;
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public ObjectReader newReader() {
 		return new WindowCursor(db);
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public BitmapIndex getBitmapIndex() throws IOException {
 		for (Pack pack : db.getPacks()) {
@@ -96,13 +94,11 @@
 		return null;
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public Optional<CommitGraph> getCommitGraph() {
 		return db.getCommitGraph();
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public Collection<CachedPack> getCachedPacksAndUpdate(
 			BitmapBuilder needBitmap) throws IOException {
@@ -115,7 +111,6 @@
 		return Collections.emptyList();
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public Collection<ObjectId> resolve(AbbreviatedObjectId id)
 			throws IOException {
@@ -126,13 +121,11 @@
 		return matches;
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public boolean has(AnyObjectId objectId) throws IOException {
 		return db.has(objectId);
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public ObjectLoader open(AnyObjectId objectId, int typeHint)
 			throws MissingObjectException, IncorrectObjectTypeException,
@@ -149,13 +142,11 @@
 		return ldr;
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public Set<ObjectId> getShallowCommits() throws IOException {
 		return db.getShallowCommits();
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public long getObjectSize(AnyObjectId objectId, int typeHint)
 			throws MissingObjectException, IncorrectObjectTypeException,
@@ -170,13 +161,11 @@
 		return sz;
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public LocalObjectToPack newObjectToPack(AnyObjectId objectId, int type) {
 		return new LocalObjectToPack(objectId, type);
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public void selectObjectRepresentation(PackWriter packer,
 			ProgressMonitor monitor, Iterable<ObjectToPack> objects)
@@ -187,7 +176,6 @@
 		}
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public void copyObjectAsIs(PackOutputStream out, ObjectToPack otp,
 			boolean validate) throws IOException,
@@ -196,7 +184,6 @@
 		src.pack.copyAsIs(out, src, validate, this);
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public void writeObjects(PackOutputStream out, List<ObjectToPack> list)
 			throws IOException {
@@ -240,7 +227,6 @@
 		return cnt - need;
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public void copyPackAsIs(PackOutputStream out, CachedPack pack)
 			throws IOException {
@@ -336,7 +322,6 @@
 		}
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	@Nullable
 	public ObjectInserter getCreatedFromInserter() {
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/io/BlockSource.java b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/io/BlockSource.java
index 82d07e6..58695fc 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/io/BlockSource.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/io/BlockSource.java
@@ -147,7 +147,6 @@
 		// Do nothing by default.
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public abstract void close();
 }
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/io/CancellableDigestOutputStream.java b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/io/CancellableDigestOutputStream.java
index ca2095f..ce86eab 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/io/CancellableDigestOutputStream.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/io/CancellableDigestOutputStream.java
@@ -80,7 +80,6 @@
 		return count;
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public final void write(int b) throws IOException {
 		if (checkCancelAt <= count) {
@@ -95,7 +94,6 @@
 		count++;
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public final void write(byte[] b, int off, int len) throws IOException {
 		while (0 < len) {
@@ -116,7 +114,6 @@
 		}
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public void flush() throws IOException {
 		out.flush();
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
index 1ac6627..acc1c83 100644
--- 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
@@ -300,6 +300,7 @@
 	 * Find the key which is the longest prefix of the given query string.
 	 *
 	 * @param query
+	 *            the query string
 	 * @return the key which is the longest prefix of the given query string or
 	 *         {@code null} if none exists.
 	 */
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/pack/DeltaIndex.java b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/pack/DeltaIndex.java
index 7ed5def..b86ff7f 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/pack/DeltaIndex.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/pack/DeltaIndex.java
@@ -393,7 +393,6 @@
 		return start - resPtr;
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	@SuppressWarnings("nls")
 	public String toString() {
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/pack/DeltaTask.java b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/pack/DeltaTask.java
index 132eb50..9a3f4b0 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/pack/DeltaTask.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/pack/DeltaTask.java
@@ -254,7 +254,6 @@
 		slices.add(s);
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public Object call() throws Exception {
 		or = block.templateReader.newReader();
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/pack/ObjectToPack.java b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/pack/ObjectToPack.java
index d9013bf..ea5b946 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/pack/ObjectToPack.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/pack/ObjectToPack.java
@@ -156,7 +156,6 @@
 		return 1 < getOffset(); // markWantWrite sets 1.
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public final int getType() {
 		return (flags >> TYPE_SHIFT) & 0x7;
@@ -357,7 +356,6 @@
 		// Empty by default.
 	}
 
-	/** {@inheritDoc} */
 	@SuppressWarnings("nls")
 	@Override
 	public String toString() {
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 d580083..e6daaea 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
@@ -80,7 +80,6 @@
 		return String.format(".%s_tmp", ext); //$NON-NLS-1$
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public String toString() {
 		return String.format("PackExt[%s, bit=0x%s]", getExtension(), //$NON-NLS-1$
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 9f8ab35..dcd360d 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
@@ -2008,8 +2008,10 @@
 		final long countingStart = System.currentTimeMillis();
 		beginPhase(PackingPhase.COUNTING, countingMonitor, ProgressMonitor.UNKNOWN);
 
-		stats.interestingObjects = Collections.unmodifiableSet(new HashSet<ObjectId>(want));
-		stats.uninterestingObjects = Collections.unmodifiableSet(new HashSet<ObjectId>(have));
+		stats.interestingObjects = Collections
+				.unmodifiableSet(new HashSet<>(want));
+		stats.uninterestingObjects = Collections
+				.unmodifiableSet(new HashSet<>(have));
 		excludeFromBitmapSelection = noBitmaps;
 
 		canBuildBitmaps = config.isBuildBitmaps()
@@ -2308,7 +2310,7 @@
 
 	/**
 	 * Determines if the object should be omitted from the pack as a result of
-	 * its depth (probably because of the tree:<depth> filter).
+	 * its depth (probably because of the tree:&lt;depth&gt; filter).
 	 * <p>
 	 * Causes {@code walker} to skip traversing the current tree, which ought to
 	 * have just started traversal, assuming this method is called as soon as a
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/reftable/EmptyLogCursor.java b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/reftable/EmptyLogCursor.java
index 7c06be8..8700556 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/reftable/EmptyLogCursor.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/reftable/EmptyLogCursor.java
@@ -16,31 +16,26 @@
 
 /** Empty {@link LogCursor} with no results. */
 class EmptyLogCursor extends LogCursor {
-	/** {@inheritDoc} */
 	@Override
 	public boolean next() throws IOException {
 		return false;
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public String getRefName() {
 		return null;
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public long getUpdateIndex() {
 		return 0;
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public ReflogEntry getReflogEntry() {
 		return null;
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public void close() {
 		// Do nothing.
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/reftable/LogCursor.java b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/reftable/LogCursor.java
index f78975a..f9c701e 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/reftable/LogCursor.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/reftable/LogCursor.java
@@ -51,7 +51,6 @@
 	@Nullable
 	public abstract ReflogEntry getReflogEntry();
 
-	/** {@inheritDoc} */
 	@Override
 	public abstract void close();
 }
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/reftable/MergedReftable.java b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/reftable/MergedReftable.java
index e210acf..aeaf241 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/reftable/MergedReftable.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/reftable/MergedReftable.java
@@ -39,7 +39,6 @@
 
 	/**
 	 * Initialize a merged table reader.
-	 * <p>
 	 *
 	 * @param tableStack
 	 *            stack of tables to read from. The base of the stack is at
@@ -91,7 +90,6 @@
 		return minUpdateIndex;
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public boolean hasObjectMap() throws IOException {
 		boolean has = true;
@@ -101,7 +99,6 @@
 		return has;
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public RefCursor allRefs() throws IOException {
 		MergedRefCursor m = new MergedRefCursor();
@@ -111,7 +108,6 @@
 		return m;
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public RefCursor seekRef(String name) throws IOException {
 		MergedRefCursor m = new MergedRefCursor();
@@ -121,7 +117,6 @@
 		return m;
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public RefCursor seekRefsWithPrefix(String prefix) throws IOException {
 		MergedRefCursor m = new MergedRefCursor();
@@ -131,7 +126,6 @@
 		return m;
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public RefCursor byObjectId(AnyObjectId name) throws IOException {
 		MergedRefCursor m = new FilteringMergedRefCursor(name);
@@ -141,7 +135,6 @@
 		return m;
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public LogCursor allLogs() throws IOException {
 		MergedLogCursor m = new MergedLogCursor();
@@ -151,7 +144,6 @@
 		return m;
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public LogCursor seekLog(String refName, long updateIdx)
 			throws IOException {
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/reftable/RefCursor.java b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/reftable/RefCursor.java
index 5e2c350..6cd4f6c 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/reftable/RefCursor.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/reftable/RefCursor.java
@@ -58,7 +58,6 @@
 		return r.getStorage() == Ref.Storage.NEW && r.getObjectId() == null;
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public abstract void close();
 }
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/reftable/Reftable.java b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/reftable/Reftable.java
index 63786dc..6e83778 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/reftable/Reftable.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/reftable/Reftable.java
@@ -138,7 +138,7 @@
 	public abstract RefCursor byObjectId(AnyObjectId id) throws IOException;
 
 	/**
-	 * @return whether this reftable can do a fast SHA1 => ref lookup.
+	 * @return whether this reftable can do a fast SHA1 =&gt; ref lookup.
 	 * @throws IOException on I/O problems.
 	 */
 	public abstract boolean hasObjectMap() throws IOException;
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/reftable/ReftableBatchRefUpdate.java b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/reftable/ReftableBatchRefUpdate.java
index dbc2ec7..38c17e3 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/reftable/ReftableBatchRefUpdate.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/reftable/ReftableBatchRefUpdate.java
@@ -81,7 +81,6 @@
 		this.repository = repository;
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public void execute(RevWalk rw, ProgressMonitor pm, List<String> options) {
 		List<ReceiveCommand> pending = getPending();
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/reftable/ReftableOutputStream.java b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/reftable/ReftableOutputStream.java
index aa3aba5..86e16ec 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/reftable/ReftableOutputStream.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/reftable/ReftableOutputStream.java
@@ -59,14 +59,12 @@
 		blockSize = bs;
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public void write(int b) {
 		ensureBytesAvailableInBlockBuf(1);
 		blockBuf[cur++] = (byte) b;
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public void write(byte[] b, int off, int cnt) {
 		ensureBytesAvailableInBlockBuf(cnt);
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/reftable/ReftableReader.java b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/reftable/ReftableReader.java
index cabb2e1..2a73efd 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/reftable/ReftableReader.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/reftable/ReftableReader.java
@@ -127,7 +127,6 @@
 		return maxUpdateIndex;
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public RefCursor allRefs() throws IOException {
 		if (blockSize == -1) {
@@ -144,7 +143,6 @@
 		return i;
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public RefCursor seekRef(String refName) throws IOException {
 		initRefIndex();
@@ -155,7 +153,6 @@
 		return i;
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public RefCursor seekRefsWithPrefix(String prefix) throws IOException {
 		initRefIndex();
@@ -166,7 +163,6 @@
 		return i;
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public RefCursor byObjectId(AnyObjectId id) throws IOException {
 		initObjIndex();
@@ -179,7 +175,6 @@
 		return i;
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public LogCursor allLogs() throws IOException {
 		initLogIndex();
@@ -192,7 +187,6 @@
 		return new EmptyLogCursor();
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public LogCursor seekLog(String refName, long updateIndex)
 			throws IOException {
@@ -460,7 +454,6 @@
 		return src.size();
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public void close() throws IOException {
 		src.close();
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/reftable/ReftableReflogReader.java b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/reftable/ReftableReflogReader.java
index f9f1def..5973033 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/reftable/ReftableReflogReader.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/reftable/ReftableReflogReader.java
@@ -34,7 +34,6 @@
 		this.refname = refname;
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public ReflogEntry getLastEntry() throws IOException {
 		lock.lock();
@@ -46,13 +45,11 @@
 		}
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public List<ReflogEntry> getReverseEntries() throws IOException {
 		return getReverseEntries(Integer.MAX_VALUE);
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public ReflogEntry getReverseEntry(int number) throws IOException {
 		lock.lock();
@@ -72,7 +69,6 @@
 		}
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public List<ReflogEntry> getReverseEntries(int max) throws IOException {
 		lock.lock();
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/internal/submodule/SubmoduleValidator.java b/org.eclipse.jgit/src/org/eclipse/jgit/internal/submodule/SubmoduleValidator.java
index d0e2441..ff8308d 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/internal/submodule/SubmoduleValidator.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/internal/submodule/SubmoduleValidator.java
@@ -45,8 +45,8 @@
 		 * @param message
 		 *            Description of the problem
 		 * @param fsckMessageId
-		 *            Error identifier, following the git fsck fsck.<msg-id>
-		 *            format
+		 *            Error identifier, following the git fsck
+		 *            fsck.&lt;msg-id&gt; format
 		 */
 		SubmoduleValidationException(String message,
 				ObjectChecker.ErrorType fsckMessageId) {
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/internal/transport/ssh/OpenSshConfigFile.java b/org.eclipse.jgit/src/org/eclipse/jgit/internal/transport/ssh/OpenSshConfigFile.java
index 659ccb8..29a2922 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/internal/transport/ssh/OpenSshConfigFile.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/internal/transport/ssh/OpenSshConfigFile.java
@@ -1154,7 +1154,6 @@
 		}
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	@SuppressWarnings("nls")
 	public String toString() {
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/internal/util/Optionally.java b/org.eclipse.jgit/src/org/eclipse/jgit/internal/util/Optionally.java
new file mode 100644
index 0000000..987584f
--- /dev/null
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/internal/util/Optionally.java
@@ -0,0 +1,126 @@
+/*
+ * Copyright (c) 2023 Qualcomm Innovation Center, Inc.
+ * and other copyright owners as documented in the project's IP log.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Distribution License 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.util;
+
+import java.lang.ref.SoftReference;
+import java.util.Optional;
+
+/**
+ * Interface representing a reference to a potentially mutable optional object.
+ *
+ * @param <T>
+ *            type of the mutable optional object
+ *
+ * @since 6.7
+ */
+public interface Optionally<T> {
+	/**
+	 * A permanently empty Optionally
+	 *
+	 * @param <T>
+	 *            type of the mutable optional object
+	 *
+	 */
+	public class Empty<T> implements Optionally<T> {
+		@Override
+		public void clear() {
+			// empty
+		}
+
+		@Override
+		public Optional<T> getOptional() {
+			return Optional.empty();
+		}
+	}
+
+	/**
+	 * A permanent(hard) reference to an object
+	 *
+	 * @param <T>
+	 *            type of the mutable optional object
+	 *
+	 */
+	public class Hard<T> implements Optionally<T> {
+		/**
+		 * The mutable optional object
+		 */
+		protected T element;
+
+		/**
+		 * @param element
+		 *            the mutable optional object
+		 */
+		public Hard(T element) {
+			this.element = element;
+		}
+
+		@Override
+		public void clear() {
+			element = null;
+		}
+
+		@Override
+		public Optional<T> getOptional() {
+			return Optional.ofNullable(element);
+		}
+	}
+
+	/**
+	 * A SoftReference Optionally
+	 *
+	 * @param <T>
+	 *            type of the mutable optional object
+	 *
+	 */
+	public class Soft<T> extends SoftReference<T> implements Optionally<T> {
+		/**
+		 * @param t
+		 *            the mutable optional object
+		 */
+		public Soft(T t) {
+			super(t);
+		}
+
+		@Override
+		public Optional<T> getOptional() {
+			return Optional.ofNullable(get());
+		}
+	}
+
+	/**
+	 * The empty Optionally
+	 */
+	public static final Optionally<?> EMPTY = new Empty<>();
+
+	/**
+	 * @param <T>
+	 *            type of the empty Optionally
+	 * @return the empty Optionally
+	 */
+	@SuppressWarnings("unchecked")
+	public static <T> Optionally<T> empty() {
+		return (Optionally<T>) EMPTY;
+	}
+
+	/**
+	 * Clear the object
+	 *
+	 */
+	void clear();
+
+	/**
+	 * Get an Optional representing the current state of the object
+	 *
+	 * @return the mutable optional object
+	 */
+	Optional<T> getOptional();
+}
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/lib/AbbrevConfig.java b/org.eclipse.jgit/src/org/eclipse/jgit/lib/AbbrevConfig.java
index 9109cfd..c3dffdf 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/lib/AbbrevConfig.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/lib/AbbrevConfig.java
@@ -19,7 +19,7 @@
 
 /**
  * Git configuration option <a
- * href=https://git-scm.com/docs/git-config#Documentation/git-config.txt-coreabbrev">
+ * href="https://git-scm.com/docs/git-config#Documentation/git-config.txt-coreabbrev">
  * core.abbrev</a>
  *
  * @since 6.1
@@ -100,6 +100,7 @@
 	 * object names to stay unique for some time.
 	 *
 	 * @param repo
+	 *            the repository the AbbrevConfig shall be computed for
 	 * @return appropriate value computed based on the approximate number of
 	 *         packed objects in a repository
 	 */
@@ -128,7 +129,10 @@
 	private int abbrev;
 
 	/**
+	 * Create an {@code AbbrevConfig}
+	 *
 	 * @param abbrev
+	 *            abbreviation length
 	 */
 	private AbbrevConfig(int abbrev) {
 		this.abbrev = capAbbrev(abbrev);
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/lib/AbbreviatedObjectId.java b/org.eclipse.jgit/src/org/eclipse/jgit/lib/AbbreviatedObjectId.java
index dc5e5cc..a13136b 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/lib/AbbreviatedObjectId.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/lib/AbbreviatedObjectId.java
@@ -321,13 +321,11 @@
 		return mask(nibbles, word, v);
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public int hashCode() {
 		return w1;
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public boolean equals(Object o) {
 		if (o instanceof AbbreviatedObjectId) {
@@ -366,7 +364,6 @@
 		return new String(b, 0, nibbles);
 	}
 
-	/** {@inheritDoc} */
 	@SuppressWarnings("nls")
 	@Override
 	public String toString() {
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/lib/AnyObjectId.java b/org.eclipse.jgit/src/org/eclipse/jgit/lib/AnyObjectId.java
index 7685b30..c58133a 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/lib/AnyObjectId.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/lib/AnyObjectId.java
@@ -248,7 +248,6 @@
 		return abbr.prefixCompare(this) == 0;
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public final int hashCode() {
 		return w2;
@@ -266,7 +265,6 @@
 		return other != null ? isEqual(this, other) : false;
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public final boolean equals(Object o) {
 		if (o instanceof AnyObjectId) {
@@ -477,7 +475,6 @@
 			dst[o--] = '0';
 	}
 
-	/** {@inheritDoc} */
 	@SuppressWarnings("nls")
 	@Override
 	public String toString() {
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 d2367cc..f995250 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/lib/BatchRefUpdate.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/lib/BatchRefUpdate.java
@@ -716,7 +716,6 @@
 				: isForceRefLog();
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public String toString() {
 		StringBuilder r = new StringBuilder();
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/lib/BatchingProgressMonitor.java b/org.eclipse.jgit/src/org/eclipse/jgit/lib/BatchingProgressMonitor.java
index f826057..8e92f20 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/lib/BatchingProgressMonitor.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/lib/BatchingProgressMonitor.java
@@ -47,13 +47,11 @@
 		delayStartUnit = unit;
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public void start(int totalTasks) {
 		// Ignore the number of tasks.
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public void beginTask(String title, int work) {
 		endTask();
@@ -62,14 +60,12 @@
 			task.delay(delayStartTime, delayStartUnit);
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public void update(int completed) {
 		if (task != null)
 			task.update(this, completed);
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public void endTask() {
 		if (task != null) {
@@ -78,7 +74,6 @@
 		}
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public boolean isCancelled() {
 		return false;
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/lib/BranchTrackingStatus.java b/org.eclipse.jgit/src/org/eclipse/jgit/lib/BranchTrackingStatus.java
index 6c625bb..39fc566 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/lib/BranchTrackingStatus.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/lib/BranchTrackingStatus.java
@@ -33,6 +33,7 @@
 	 *            the local branch
 	 * @return the tracking status, or null if it is not known
 	 * @throws java.io.IOException
+	 *             if an IO error occurred
 	 */
 	public static BranchTrackingStatus of(Repository repository, String branchName)
 			throws IOException {
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/lib/CommitBuilder.java b/org.eclipse.jgit/src/org/eclipse/jgit/lib/CommitBuilder.java
index 1665f05..ea33082 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/lib/CommitBuilder.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/lib/CommitBuilder.java
@@ -275,7 +275,6 @@
 		return build();
 	}
 
-	/** {@inheritDoc} */
 	@SuppressWarnings("nls")
 	@Override
 	public String toString() {
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/lib/Config.java b/org.eclipse.jgit/src/org/eclipse/jgit/lib/Config.java
index d1d66d2..7e2c5b5 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/lib/Config.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/lib/Config.java
@@ -399,6 +399,8 @@
 	/**
 	 * Parse an enumeration from the configuration.
 	 *
+	 * @param <T>
+	 *            type of the returned enum
 	 * @param section
 	 *            section the key is grouped within.
 	 * @param subsection
@@ -431,6 +433,8 @@
 	/**
 	 * Parse an enumeration from the configuration.
 	 *
+	 * @param <T>
+	 *            type of the returned enum
 	 * @param all
 	 *            all possible values in the enumeration which should be
 	 *            recognized. Typically {@code EnumType.values()}.
@@ -722,7 +726,7 @@
 	 * responsible for issuing {@link #fireConfigChangedEvent()} calls
 	 * themselves.
 	 *
-	 * @return <code></code>
+	 * @return whether to issue change events for transient changes
 	 */
 	protected boolean notifyUponTransientChanges() {
 		return true;
@@ -735,7 +739,7 @@
 		listeners.dispatch(new ConfigChangedEvent());
 	}
 
-	String getRawString(final String section, final String subsection,
+	private String getRawString(final String section, final String subsection,
 			final String name) {
 		String[] lst = getRawStringList(section, subsection, name);
 		if (lst != null) {
@@ -847,6 +851,8 @@
 	 *         name = value
 	 * </pre>
 	 *
+	 * @param <T>
+	 *            type of the enum to set
 	 * @param section
 	 *            section name, e.g "branch"
 	 * @param subsection
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 056861d..9852ae3 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/lib/ConfigConstants.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/lib/ConfigConstants.java
@@ -60,7 +60,8 @@
 	public static final String CONFIG_KEY_PROMPT = "prompt";
 
 	/**
-	 * The "trustExitCode" key within "difftool" or "mergetool.<name>." section
+	 * The "trustExitCode" key within "difftool" or "mergetool.&lt;name&gt;."
+	 * section
 	 *
 	 * @since 6.1
 	 */
@@ -114,6 +115,7 @@
 
 	/**
 	 * The "fetch" section
+	 *
 	 * @since 3.3
 	 */
 	public static final String CONFIG_FETCH_SECTION = "fetch";
@@ -368,6 +370,12 @@
 	 */
 	public static final String CONFIG_KEY_PACKED_GIT_USE_STRONGREFS = "packedgitusestrongrefs";
 
+	/**
+	 * The "packedIndexGitUseStrongRefs" key
+	 * @since 6.7
+	 */
+	public static final String CONFIG_KEY_PACKED_INDEX_GIT_USE_STRONGREFS = "packedindexgitusestrongrefs";
+
 	/** The "remote" key */
 	public static final String CONFIG_KEY_REMOTE = "remote";
 
@@ -959,4 +967,25 @@
 	 * @since 5.13.2
 	 */
 	public static final String CONFIG_KEY_PRUNE_PRESERVED = "prunepreserved";
+
+	/**
+	 * The "commitGraph" section
+	 *
+	 * @since 6.7
+	 */
+	public static final String CONFIG_COMMIT_GRAPH_SECTION = "commitGraph";
+
+	/**
+	 * The "writeChangedPaths" key
+	 *
+	 * @since 6.7
+	 */
+	public static final String CONFIG_KEY_WRITE_CHANGED_PATHS = "writeChangedPaths";
+
+	/**
+	 * The "readChangedPaths" key
+	 *
+	 * @since 6.7
+	 */
+	public static final String CONFIG_KEY_READ_CHANGED_PATHS = "readChangedPaths";
 }
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/lib/ConfigLine.java b/org.eclipse.jgit/src/org/eclipse/jgit/lib/ConfigLine.java
index a9235eb..e9a8b44 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/lib/ConfigLine.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/lib/ConfigLine.java
@@ -83,7 +83,6 @@
 		return a.equals(b);
 	}
 
-	/** {@inheritDoc} */
 	@SuppressWarnings("nls")
 	@Override
 	public String toString() {
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 0b8bf8c..60a23dd 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/lib/Constants.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/lib/Constants.java
@@ -337,9 +337,9 @@
 	public static final String GIT_CONFIG_NOSYSTEM_KEY = "GIT_CONFIG_NOSYSTEM";
 
 	/**
-	 * The key of the XDG_CONFIG_HOME directory defined in the XDG base
-	 * directory specification, see
-	 * {@link "https://wiki.archlinux.org/index.php/XDG_Base_Directory"}
+	 * The key of the XDG_CONFIG_HOME directory defined in the
+	 * <a href="https://wiki.archlinux.org/index.php/XDG_Base_Directory">
+	 * XDG Base Directory specification</a>.
 	 *
 	 * @since 5.5.2
 	 */
@@ -766,7 +766,7 @@
 	 *
 	 * @since 6.5
 	 */
-	public static int COMMIT_GENERATION_UNKNOWN = Integer.MAX_VALUE;
+	public static final int COMMIT_GENERATION_UNKNOWN = Integer.MAX_VALUE;
 
 	/**
 	 * If a commit-graph file was written by a version of Git that did not
@@ -775,7 +775,7 @@
 	 *
 	 * @since 6.5
 	 */
-	public static int COMMIT_GENERATION_NOT_COMPUTED = 0;
+	public static final int COMMIT_GENERATION_NOT_COMPUTED = 0;
 
 	private Constants() {
 		// Hide the default constructor
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/lib/DefaultTypedConfigGetter.java b/org.eclipse.jgit/src/org/eclipse/jgit/lib/DefaultTypedConfigGetter.java
index 8640940..a71549c 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/lib/DefaultTypedConfigGetter.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/lib/DefaultTypedConfigGetter.java
@@ -31,11 +31,10 @@
  */
 public class DefaultTypedConfigGetter implements TypedConfigGetter {
 
-	/** {@inheritDoc} */
 	@Override
 	public boolean getBoolean(Config config, String section, String subsection,
 			String name, boolean defaultValue) {
-		String n = config.getRawString(section, subsection, name);
+		String n = config.getString(section, subsection, name);
 		if (n == null) {
 			return defaultValue;
 		}
@@ -50,7 +49,6 @@
 		}
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public <T extends Enum<?>> T getEnum(Config config, T[] all, String section,
 			String subsection, String name, T defaultValue) {
@@ -106,7 +104,6 @@
 				JGitText.get().enumValueNotSupported2, section, name, value));
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public int getInt(Config config, String section, String subsection,
 			String name, int defaultValue) {
@@ -118,7 +115,6 @@
 				.format(JGitText.get().integerValueOutOfRange, section, name));
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public int getIntInRange(Config config, String section, String subsection,
 			String name, int minValue, int maxValue, int defaultValue) {
@@ -138,7 +134,6 @@
 				Integer.valueOf(minValue), Integer.valueOf(maxValue)));
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public long getLong(Config config, String section, String subsection,
 			String name, long defaultValue) {
@@ -158,7 +153,6 @@
 		}
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public long getTimeUnit(Config config, String section, String subsection,
 			String name, long defaultValue, TimeUnit wantUnit) {
@@ -269,7 +263,6 @@
 						section, name, valueString));
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	@NonNull
 	public List<RefSpec> getRefSpecs(Config config, String section,
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/lib/EmptyProgressMonitor.java b/org.eclipse.jgit/src/org/eclipse/jgit/lib/EmptyProgressMonitor.java
index 94d28eb..a5410b7 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/lib/EmptyProgressMonitor.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/lib/EmptyProgressMonitor.java
@@ -18,31 +18,26 @@
  */
 public abstract class EmptyProgressMonitor implements ProgressMonitor {
 
-	/** {@inheritDoc} */
 	@Override
 	public void start(int totalTasks) {
 		// empty
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public void beginTask(String title, int totalWork) {
 		// empty
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public void update(int completed) {
 		// empty
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public void endTask() {
 		// empty
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public boolean isCancelled() {
 		return false;
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/lib/GpgSignature.java b/org.eclipse.jgit/src/org/eclipse/jgit/lib/GpgSignature.java
index e78cf16..4018dab 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/lib/GpgSignature.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/lib/GpgSignature.java
@@ -49,7 +49,6 @@
 		return new String(signature, US_ASCII);
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	@SuppressWarnings("nls")
 	public String toString() {
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/lib/IndexDiff.java b/org.eclipse.jgit/src/org/eclipse/jgit/lib/IndexDiff.java
index df9fd47..b009ea1 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/lib/IndexDiff.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/lib/IndexDiff.java
@@ -265,6 +265,7 @@
 	 * @param workingTreeIterator
 	 *            iterator for working directory
 	 * @throws java.io.IOException
+	 *             if an IO error occurred
 	 */
 	public IndexDiff(Repository repository, String revstr,
 			WorkingTreeIterator workingTreeIterator) throws IOException {
@@ -281,6 +282,7 @@
 	 * @param workingTreeIterator
 	 *            iterator for working directory
 	 * @throws java.io.IOException
+	 *             if an IO error occurred
 	 */
 	public IndexDiff(Repository repository, ObjectId objectId,
 			WorkingTreeIterator workingTreeIterator) throws IOException {
@@ -325,6 +327,7 @@
 	 * Allows higher layers to set the factory for WorkingTreeIterators.
 	 *
 	 * @param wTreeIt
+	 *            working tree iterator factory
 	 * @since 3.6
 	 */
 	public void setWorkingTreeItFactory(WorkingTreeIteratorFactory wTreeIt) {
@@ -349,6 +352,7 @@
 	 *
 	 * @return if anything is different between index, tree, and workdir
 	 * @throws java.io.IOException
+	 *             if an IO error occurred
 	 */
 	public boolean diff() throws IOException {
 		return diff(null);
@@ -372,6 +376,7 @@
 	 *            {@link RepositoryBuilder}.
 	 * @return if anything is different between index, tree, and workdir
 	 * @throws java.io.IOException
+	 *             if an IO error occurred
 	 * @since 5.6
 	 */
 	public boolean diff(RepositoryBuilderFactory factory)
@@ -395,9 +400,11 @@
 	 *            number or estimated files in the working tree
 	 * @param estIndexSize
 	 *            number of estimated entries in the cache
-	 * @param title a {@link java.lang.String} object.
+	 * @param title
+	 *            a {@link java.lang.String} object.
 	 * @return if anything is different between index, tree, and workdir
 	 * @throws java.io.IOException
+	 *             if an IO error occurred
 	 */
 	public boolean diff(final ProgressMonitor monitor, int estWorkTreeSize,
 			int estIndexSize, final String title)
@@ -436,6 +443,7 @@
 	 *            {@link RepositoryBuilder}.
 	 * @return if anything is different between index, tree, and workdir
 	 * @throws java.io.IOException
+	 *             if an IO error occurred
 	 * @since 5.6
 	 */
 	public boolean diff(ProgressMonitor monitor, int estWorkTreeSize,
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/lib/MutableObjectId.java b/org.eclipse.jgit/src/org/eclipse/jgit/lib/MutableObjectId.java
index 4a712ba..6a35ded 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/lib/MutableObjectId.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/lib/MutableObjectId.java
@@ -242,7 +242,6 @@
 		}
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public ObjectId toObjectId() {
 		return new ObjectId(this);
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/lib/NullProgressMonitor.java b/org.eclipse.jgit/src/org/eclipse/jgit/lib/NullProgressMonitor.java
index 127cca9..0a4db2a 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/lib/NullProgressMonitor.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/lib/NullProgressMonitor.java
@@ -23,31 +23,26 @@
 		// Do not let others instantiate
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public void start(int totalTasks) {
 		// Do not report.
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public void beginTask(String title, int totalWork) {
 		// Do not report.
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public void update(int completed) {
 		// Do not report.
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public boolean isCancelled() {
 		return false;
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public void endTask() {
 		// Do not report.
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/lib/ObjectBuilder.java b/org.eclipse.jgit/src/org/eclipse/jgit/lib/ObjectBuilder.java
index 4b7054f..064d89e 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/lib/ObjectBuilder.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/lib/ObjectBuilder.java
@@ -72,7 +72,6 @@
 	 * <li>create {@link GpgSignature} from payload</li>
 	 * <li>set {@link GpgSignature}</li>
 	 * </ol>
-	 * </p>
 	 *
 	 * @param gpgSignature
 	 *            the signature to set or {@code null} to unset
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/lib/ObjectChecker.java b/org.eclipse.jgit/src/org/eclipse/jgit/lib/ObjectChecker.java
index 9e9ef88..a1d6d92 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/lib/ObjectChecker.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/lib/ObjectChecker.java
@@ -1065,6 +1065,7 @@
 	 *
 	 * @return true if the filename in buf could be a ".gitmodules" file
 	 * @throws CorruptObjectException
+	 *             if an object is corrupt
 	 */
 	private boolean isGitmodules(byte[] buf, int start, int end, @Nullable AnyObjectId id)
 			throws CorruptObjectException {
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/lib/ObjectId.java b/org.eclipse.jgit/src/org/eclipse/jgit/lib/ObjectId.java
index 269049f..1c31263 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/lib/ObjectId.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/lib/ObjectId.java
@@ -262,7 +262,6 @@
 		w5 = src.w5;
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public ObjectId toObjectId() {
 		return this;
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/lib/ObjectIdOwnerMap.java b/org.eclipse.jgit/src/org/eclipse/jgit/lib/ObjectIdOwnerMap.java
index 2903909..a74fddf 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/lib/ObjectIdOwnerMap.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/lib/ObjectIdOwnerMap.java
@@ -128,8 +128,11 @@
 	 * <p>
 	 * An existing mapping for <b>must not</b> be in this map. Callers must
 	 * first call {@link #get(AnyObjectId)} to verify there is no current
-	 * mapping prior to adding a new mapping, or use {@link #addIfAbsent(Entry)}.
+	 * mapping prior to adding a new mapping, or use
+	 * {@link #addIfAbsent(Entry)}.
 	 *
+	 * @param <Q>
+	 *            type of values
 	 * @param newValue
 	 *            the object to store.
 	 */
@@ -157,6 +160,8 @@
 	 * boolean wasNew = map.addIfAbsent(obj) == obj;
 	 * </pre>
 	 *
+	 * @param <Q>
+	 *            type of values
 	 * @param newValue
 	 *            the object to store.
 	 * @return {@code newValue} if stored, or the prior value already stored and
@@ -199,7 +204,6 @@
 		return size == 0;
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public Iterator<V> iterator() {
 		return new Iterator<>() {
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/lib/ObjectIdRef.java b/org.eclipse.jgit/src/org/eclipse/jgit/lib/ObjectIdRef.java
index a04ca68..c3c5837 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/lib/ObjectIdRef.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/lib/ObjectIdRef.java
@@ -204,41 +204,35 @@
 		this.updateIndex = updateIndex;
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	@NonNull
 	public String getName() {
 		return name;
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public boolean isSymbolic() {
 		return false;
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	@NonNull
 	public Ref getLeaf() {
 		return this;
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	@NonNull
 	public Ref getTarget() {
 		return this;
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	@Nullable
 	public ObjectId getObjectId() {
 		return objectId;
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	@NonNull
 	public Storage getStorage() {
@@ -257,7 +251,6 @@
 		return updateIndex;
 	}
 
-	/** {@inheritDoc} */
 	@NonNull
 	@Override
 	public String toString() {
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/lib/ObjectIdSubclassMap.java b/org.eclipse.jgit/src/org/eclipse/jgit/lib/ObjectIdSubclassMap.java
index 0e015b6..d4acfd4 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/lib/ObjectIdSubclassMap.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/lib/ObjectIdSubclassMap.java
@@ -96,6 +96,8 @@
 	 * mapping prior to adding a new mapping, or use
 	 * {@link #addIfAbsent(ObjectId)}.
 	 *
+	 * @param <Q>
+	 *            type of values
 	 * @param newValue
 	 *            the object to store.
 	 */
@@ -117,6 +119,8 @@
 	 * boolean wasNew = map.addIfAbsent(obj) == obj;
 	 * </pre>
 	 *
+	 * @param <Q>
+	 *            type of values
 	 * @param newValue
 	 *            the object to store.
 	 * @return {@code newValue} if stored, or the prior value already stored and
@@ -162,7 +166,6 @@
 		return size == 0;
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public Iterator<V> iterator() {
 		return new Iterator<>() {
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 69b2b51..3e29985 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/lib/ObjectReader.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/lib/ObjectReader.java
@@ -245,12 +245,15 @@
 	 *
 	 * @return IDs of shallow commits
 	 * @throws java.io.IOException
+	 *             if an error occurred
 	 */
 	public abstract Set<ObjectId> getShallowCommits() throws IOException;
 
 	/**
 	 * Asynchronous object opening.
 	 *
+	 * @param <T>
+	 *            type of {@code ObjectId}
 	 * @param objectIds
 	 *            objects to open from the object store. The supplied collection
 	 *            must not be modified until the queue has finished.
@@ -370,6 +373,8 @@
 	/**
 	 * Asynchronous object size lookup.
 	 *
+	 * @param <T>
+	 *            type of {@code ObjectId}
 	 * @param objectIds
 	 *            objects to get the size of from the object store. The supplied
 	 *            collection must not be modified until the queue has finished.
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/lib/PersonIdent.java b/org.eclipse.jgit/src/org/eclipse/jgit/lib/PersonIdent.java
index 9371029..3ba055a 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/lib/PersonIdent.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/lib/PersonIdent.java
@@ -392,7 +392,6 @@
 		return hc;
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public boolean equals(Object o) {
 		if (o instanceof PersonIdent) {
@@ -421,7 +420,6 @@
 		return r.toString();
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	@SuppressWarnings("nls")
 	public String toString() {
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/lib/RebaseTodoFile.java b/org.eclipse.jgit/src/org/eclipse/jgit/lib/RebaseTodoFile.java
index a4cd1d6..c716f46 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/lib/RebaseTodoFile.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/lib/RebaseTodoFile.java
@@ -55,6 +55,7 @@
 	 *            <code>true</code> if also comments should be reported
 	 * @return the list of steps
 	 * @throws java.io.IOException
+	 *             if an IO error occurred
 	 */
 	public List<RebaseTodoLine> readRebaseTodo(String path,
 			boolean includeComments) throws IOException {
@@ -126,8 +127,11 @@
 	 * Skip leading space, tab, CR and LF characters
 	 *
 	 * @param buf
+	 *            byte buffer
 	 * @param tokenBegin
+	 *            index of token begin
 	 * @param lineEnd
+	 *            index of line end
 	 * @return the token within the range of the given {@code buf} that doesn't
 	 *         need to be skipped, {@code -1} if no such token found within the
 	 *         range (i.e. empty line)
@@ -193,6 +197,7 @@
 	 * @param append
 	 *            whether to append to an existing file or to write a new file
 	 * @throws java.io.IOException
+	 *             if an IO error occurred
 	 */
 	public void writeRebaseTodoFile(String path, List<RebaseTodoLine> steps,
 			boolean append) throws IOException {
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/lib/RebaseTodoLine.java b/org.eclipse.jgit/src/org/eclipse/jgit/lib/RebaseTodoLine.java
index 8b77849..878cfc8 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/lib/RebaseTodoLine.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/lib/RebaseTodoLine.java
@@ -70,6 +70,7 @@
 
 		/**
 		 * @param token
+		 *            token to parse
 		 * @return the Action
 		 */
 		public static Action parse(String token) {
@@ -245,7 +246,6 @@
 		return comment;
 	}
 
-	/** {@inheritDoc} */
 	@SuppressWarnings("nls")
 	@Override
 	public String toString() {
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/lib/RefComparator.java b/org.eclipse.jgit/src/org/eclipse/jgit/lib/RefComparator.java
index 3ab64934..c4c0001 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/lib/RefComparator.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/lib/RefComparator.java
@@ -27,7 +27,6 @@
 	/** Singleton instance of RefComparator */
 	public static final RefComparator INSTANCE = new RefComparator();
 
-	/** {@inheritDoc} */
 	@Override
 	public int compare(Ref o1, Ref o2) {
 		return compareTo(o1, o2);
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 98089fb..82dcc6b 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/lib/RefDatabase.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/lib/RefDatabase.java
@@ -136,6 +136,7 @@
 	 *         with the passed ref name; empty collection when there are no
 	 *         conflicts
 	 * @throws java.io.IOException
+	 *             if an error occurred
 	 * @since 2.3
 	 * @see #isNameConflicting(String)
 	 */
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/lib/RefRename.java b/org.eclipse.jgit/src/org/eclipse/jgit/lib/RefRename.java
index cdd4e4b..e8821d0 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/lib/RefRename.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/lib/RefRename.java
@@ -122,6 +122,7 @@
 	 *
 	 * @return the result of the new ref update
 	 * @throws java.io.IOException
+	 *             if an IO error occurred
 	 */
 	public Result rename() throws IOException {
 		try {
@@ -138,6 +139,7 @@
 	 *
 	 * @return the result of the rename operation.
 	 * @throws java.io.IOException
+	 *             if an IO error occurred
 	 */
 	protected abstract Result doRename() throws IOException;
 
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/lib/RefUpdate.java b/org.eclipse.jgit/src/org/eclipse/jgit/lib/RefUpdate.java
index d1be63b..d113243 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/lib/RefUpdate.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/lib/RefUpdate.java
@@ -115,7 +115,6 @@
 
 		/**
 		 * The ref was renamed from another name
-		 * <p>
 		 */
 		RENAMED,
 
@@ -245,6 +244,7 @@
 	 *            a {@link org.eclipse.jgit.lib.RefUpdate.Result} object.
 	 * @return {@code result}
 	 * @throws java.io.IOException
+	 *             if an IO error occurred
 	 */
 	protected abstract Result doUpdate(Result desiredResult) throws IOException;
 
@@ -255,6 +255,7 @@
 	 *            a {@link org.eclipse.jgit.lib.RefUpdate.Result} object.
 	 * @return {@code result}
 	 * @throws java.io.IOException
+	 *             if an IO error occurred
 	 */
 	protected abstract Result doDelete(Result desiredResult) throws IOException;
 
@@ -265,6 +266,7 @@
 	 *            a {@link java.lang.String} object.
 	 * @return {@link org.eclipse.jgit.lib.RefUpdate.Result#NEW} on success.
 	 * @throws java.io.IOException
+	 *             if an IO error occurred
 	 */
 	protected abstract Result doLink(String target) throws IOException;
 
@@ -612,6 +614,7 @@
 	 *
 	 * @return the result status of the delete.
 	 * @throws java.io.IOException
+	 *             if an IO error occurred
 	 */
 	public Result delete() throws IOException {
 		try (RevWalk rw = new RevWalk(getRepository())) {
@@ -628,6 +631,7 @@
 	 *            the merge test. The walk will be reset to perform the test.
 	 * @return the result status of the delete.
 	 * @throws java.io.IOException
+	 *             if an IO error occurred
 	 */
 	public Result delete(RevWalk walk) throws IOException {
 		final String myName = detachingSymbolicRef
@@ -668,6 +672,7 @@
 	 * @return {@link org.eclipse.jgit.lib.RefUpdate.Result#NEW} or
 	 *         {@link org.eclipse.jgit.lib.RefUpdate.Result#FORCED} on success.
 	 * @throws java.io.IOException
+	 *             if an IO error occurred
 	 */
 	public Result link(String target) throws IOException {
 		if (!target.startsWith(Constants.R_REFS))
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 d2c3f9d..41917f8 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/lib/RefWriter.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/lib/RefWriter.java
@@ -177,6 +177,7 @@
 	 * @param content
 	 *            byte content of file to be written.
 	 * @throws java.io.IOException
+	 *             if an IO error occurred
 	 */
 	protected abstract void writeFile(String file, byte[] content)
 			throws IOException;
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/lib/ReflogReader.java b/org.eclipse.jgit/src/org/eclipse/jgit/lib/ReflogReader.java
index 1e6a661..5233bfc 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/lib/ReflogReader.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/lib/ReflogReader.java
@@ -25,6 +25,7 @@
 	 *
 	 * @return the latest reflog entry, or null if no log
 	 * @throws java.io.IOException
+	 *             if an IO error occurred
 	 */
 	ReflogEntry getLastEntry() throws IOException;
 
@@ -33,6 +34,7 @@
 	 *
 	 * @return all reflog entries in reverse order
 	 * @throws java.io.IOException
+	 *             if an IO error occurred
 	 */
 	List<ReflogEntry> getReverseEntries() throws IOException;
 
@@ -40,9 +42,11 @@
 	 * Get specific entry in the reflog relative to the last entry which is
 	 * considered entry zero.
 	 *
-	 * @param number a int.
+	 * @param number
+	 *            a int.
 	 * @return reflog entry or null if not found
 	 * @throws java.io.IOException
+	 *             if an IO error occurred
 	 */
 	ReflogEntry getReverseEntry(int number) throws IOException;
 
@@ -53,6 +57,7 @@
 	 *            max number of entries to read
 	 * @return all reflog entries in reverse order
 	 * @throws java.io.IOException
+	 *             if an IO error occurred
 	 */
 	List<ReflogEntry> getReverseEntries(int max) throws IOException;
 }
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/lib/Repository.java b/org.eclipse.jgit/src/org/eclipse/jgit/lib/Repository.java
index db2571c..d446a1c 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/lib/Repository.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/lib/Repository.java
@@ -175,6 +175,7 @@
 	 * the same as {@code create(false)}.
 	 *
 	 * @throws java.io.IOException
+	 *             if an IO error occurred
 	 * @see #create(boolean)
 	 */
 	public void create() throws IOException {
@@ -484,11 +485,14 @@
 	 * Thus this method can be used to process an expression to a method that
 	 * expects a branch or revision id.
 	 *
-	 * @param revstr a {@link java.lang.String} object.
+	 * @param revstr
+	 *            a {@link java.lang.String} object.
 	 * @return object id or ref name from resolved expression or {@code null} if
 	 *         given expression cannot be resolved
 	 * @throws org.eclipse.jgit.errors.AmbiguousObjectException
+	 *             if a shortened ObjectId was ambiguous
 	 * @throws java.io.IOException
+	 *             if an IO error occurred
 	 */
 	@Nullable
 	public String simplify(String revstr)
@@ -968,7 +972,6 @@
 		getRefDatabase().close();
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	@NonNull
 	public String toString() {
@@ -999,6 +1002,7 @@
 	 *         {@code null} if the repository is corrupt and has no HEAD
 	 *         reference.
 	 * @throws java.io.IOException
+	 *             if an IO error occurred
 	 */
 	@Nullable
 	public String getFullBranch() throws IOException {
@@ -1027,6 +1031,7 @@
 	 *         in hex format if the current branch is detached, or {@code null}
 	 *         if the repository is corrupt and has no HEAD reference.
 	 * @throws java.io.IOException
+	 *             if an IO error occurred
 	 */
 	@Nullable
 	public String getBranch() throws IOException {
@@ -1056,6 +1061,7 @@
 	 *
 	 * @return unmodifiable collection of other known objects.
 	 * @throws IOException
+	 *             if an IO error occurred
 	 */
 	@NonNull
 	public Set<ObjectId> getAdditionalHaves() throws IOException {
@@ -1066,11 +1072,12 @@
 	 * Get a ref by name.
 	 *
 	 * @param name
-	 *            the name of the ref to lookup. Must not be a short-hand
-	 *            form; e.g., "master" is not automatically expanded to
+	 *            the name of the ref to lookup. Must not be a short-hand form;
+	 *            e.g., "master" is not automatically expanded to
 	 *            "refs/heads/master".
 	 * @return the Ref with the given name, or {@code null} if it does not exist
 	 * @throws java.io.IOException
+	 *             if an IO error occurred
 	 * @since 4.2
 	 */
 	@Nullable
@@ -1087,6 +1094,7 @@
 	 *            "refs/heads/master" if "refs/heads/master" already exists.
 	 * @return the Ref with the given name, or {@code null} if it does not exist
 	 * @throws java.io.IOException
+	 *             if an IO error occurred
 	 * @since 4.2
 	 */
 	@Nullable
@@ -1162,6 +1170,7 @@
 	 *
 	 * @return a map with all objects referenced by a peeled ref.
 	 * @throws IOException
+	 *             if an IO error occurred
 	 */
 	@NonNull
 	public Map<AnyObjectId, Set<Ref>> getAllRefsByPeeledObjectId()
@@ -1579,6 +1588,7 @@
 	 * changes are detected.
 	 *
 	 * @throws java.io.IOException
+	 *             if an IO error occurred
 	 */
 	public abstract void scanForRepoChanges() throws IOException;
 
@@ -1703,6 +1713,7 @@
 	 * @return a {@link org.eclipse.jgit.lib.ReflogReader} for the supplied ref,
 	 *         or {@code null} if the ref does not exist.
 	 * @throws IOException
+	 *             if an IO error occurred
 	 * @since 5.13.2
 	 */
 	public @Nullable ReflogReader getReflogReader(@NonNull	Ref ref)
@@ -1718,6 +1729,7 @@
 	 * @return a String containing the content of the MERGE_MSG file or
 	 *         {@code null} if this file doesn't exist
 	 * @throws java.io.IOException
+	 *             if an IO error occurred
 	 * @throws org.eclipse.jgit.errors.NoWorkTreeException
 	 *             if this is bare, which implies it has no working directory.
 	 *             See {@link #isBare()}.
@@ -1737,6 +1749,7 @@
 	 *            the message which should be written or <code>null</code> to
 	 *            delete the file
 	 * @throws java.io.IOException
+	 *             if an IO error occurred
 	 */
 	public void writeMergeCommitMsg(String msg) throws IOException {
 		File mergeMsgFile = new File(gitDir, Constants.MERGE_MSG);
@@ -1751,6 +1764,7 @@
 	 * @return a String containing the content of the COMMIT_EDITMSG file or
 	 *         {@code null} if this file doesn't exist
 	 * @throws java.io.IOException
+	 *             if an IO error occurred
 	 * @throws org.eclipse.jgit.errors.NoWorkTreeException
 	 *             if this is bare, which implies it has no working directory.
 	 *             See {@link #isBare()}.
@@ -1770,6 +1784,7 @@
 	 *            the message which should be written or {@code null} to delete
 	 *            the file
 	 * @throws java.io.IOException
+	 *             if an IO error occurred
 	 * @since 4.0
 	 */
 	public void writeCommitEditMsg(String msg) throws IOException {
@@ -1786,6 +1801,7 @@
 	 *         {@code null} if this file doesn't exist. Also if the file exists
 	 *         but is empty {@code null} will be returned
 	 * @throws java.io.IOException
+	 *             if an IO error occurred
 	 * @throws org.eclipse.jgit.errors.NoWorkTreeException
 	 *             if this is bare, which implies it has no working directory.
 	 *             See {@link #isBare()}.
@@ -1818,6 +1834,7 @@
 	 *            a list of commits which IDs should be written to
 	 *            $GIT_DIR/MERGE_HEAD or <code>null</code> to delete the file
 	 * @throws java.io.IOException
+	 *             if an IO error occurred
 	 */
 	public void writeMergeHeads(List<? extends ObjectId> heads) throws IOException {
 		writeHeadsFile(heads, Constants.MERGE_HEAD);
@@ -1830,6 +1847,7 @@
 	 *         doesn't exist. Also if the file exists but is empty {@code null}
 	 *         will be returned
 	 * @throws java.io.IOException
+	 *             if an IO error occurred
 	 * @throws org.eclipse.jgit.errors.NoWorkTreeException
 	 *             if this is bare, which implies it has no working directory.
 	 *             See {@link #isBare()}.
@@ -1854,6 +1872,7 @@
 	 *         doesn't exist. Also if the file exists but is empty {@code null}
 	 *         will be returned
 	 * @throws java.io.IOException
+	 *             if an IO error occurred
 	 * @throws org.eclipse.jgit.errors.NoWorkTreeException
 	 *             if this is bare, which implies it has no working directory.
 	 *             See {@link #isBare()}.
@@ -1877,6 +1896,7 @@
 	 *            an object id of the cherry commit or <code>null</code> to
 	 *            delete the file
 	 * @throws java.io.IOException
+	 *             if an IO error occurred
 	 */
 	public void writeCherryPickHead(ObjectId head) throws IOException {
 		List<ObjectId> heads = (head != null) ? Collections.singletonList(head)
@@ -1892,6 +1912,7 @@
 	 *            an object id of the revert commit or <code>null</code> to
 	 *            delete the file
 	 * @throws java.io.IOException
+	 *             if an IO error occurred
 	 */
 	public void writeRevertHead(ObjectId head) throws IOException {
 		List<ObjectId> heads = (head != null) ? Collections.singletonList(head)
@@ -1906,6 +1927,7 @@
 	 *            an object id of the original HEAD commit or <code>null</code>
 	 *            to delete the file
 	 * @throws java.io.IOException
+	 *             if an IO error occurred
 	 */
 	public void writeOrigHead(ObjectId head) throws IOException {
 		List<ObjectId> heads = head != null ? Collections.singletonList(head)
@@ -1920,6 +1942,7 @@
 	 *         doesn't exist. Also if the file exists but is empty {@code null}
 	 *         will be returned
 	 * @throws java.io.IOException
+	 *             if an IO error occurred
 	 * @throws org.eclipse.jgit.errors.NoWorkTreeException
 	 *             if this is bare, which implies it has no working directory.
 	 *             See {@link #isBare()}.
@@ -1941,6 +1964,7 @@
 	 * @return a String containing the content of the SQUASH_MSG file or
 	 *         {@code null} if this file doesn't exist
 	 * @throws java.io.IOException
+	 *             if an IO error occurred
 	 * @throws NoWorkTreeException
 	 *             if this is bare, which implies it has no working directory.
 	 *             See {@link #isBare()}.
@@ -1960,6 +1984,7 @@
 	 *            the message which should be written or <code>null</code> to
 	 *            delete the file
 	 * @throws java.io.IOException
+	 *             if an IO error occurred
 	 */
 	public void writeSquashCommitMsg(String msg) throws IOException {
 		File squashMsgFile = new File(gitDir, Constants.SQUASH_MSG);
@@ -1997,9 +2022,11 @@
 	 * Read a file from the git directory.
 	 *
 	 * @param filename
+	 *            the file to read
 	 * @return the raw contents or {@code null} if the file doesn't exist or is
 	 *         empty
 	 * @throws IOException
+	 *             if an IO error occurred
 	 */
 	private byte[] readGitDirectoryFile(String filename) throws IOException {
 		File file = new File(getDirectory(), filename);
@@ -2021,8 +2048,11 @@
 	 *            a list of object ids to write or null if the file should be
 	 *            deleted.
 	 * @param filename
+	 *            name of the file to write heads to
 	 * @throws FileNotFoundException
+	 *             if the heads file couldn't be found
 	 * @throws IOException
+	 *             if an IO error occurred
 	 */
 	private void writeHeadsFile(List<? extends ObjectId> heads, String filename)
 			throws FileNotFoundException, IOException {
@@ -2052,6 +2082,7 @@
 	 *            <code>true</code> if also comments should be reported
 	 * @return the list of steps
 	 * @throws java.io.IOException
+	 *             if an IO error occurred
 	 * @since 3.2
 	 */
 	@NonNull
@@ -2072,6 +2103,7 @@
 	 * @param append
 	 *            whether to append to an existing file or to write a new file
 	 * @throws java.io.IOException
+	 *             if an IO error occurred
 	 * @since 3.2
 	 */
 	public void writeRebaseTodoFile(String path, List<RebaseTodoLine> steps,
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/lib/StoredConfig.java b/org.eclipse.jgit/src/org/eclipse/jgit/lib/StoredConfig.java
index 9ddfd59..a10eb0c 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/lib/StoredConfig.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/lib/StoredConfig.java
@@ -57,7 +57,6 @@
 	 */
 	public abstract void save() throws IOException;
 
-	/** {@inheritDoc} */
 	@Override
 	public void clear() {
 		super.clear();
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/lib/SymbolicRef.java b/org.eclipse.jgit/src/org/eclipse/jgit/lib/SymbolicRef.java
index 3ba3342..6fb8f32 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/lib/SymbolicRef.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/lib/SymbolicRef.java
@@ -59,20 +59,17 @@
 		this.updateIndex = updateIndex;
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	@NonNull
 	public String getName() {
 		return name;
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public boolean isSymbolic() {
 		return true;
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	@NonNull
 	public Ref getLeaf() {
@@ -82,35 +79,30 @@
 		return dst;
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	@NonNull
 	public Ref getTarget() {
 		return target;
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	@Nullable
 	public ObjectId getObjectId() {
 		return getLeaf().getObjectId();
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	@NonNull
 	public Storage getStorage() {
 		return Storage.LOOSE;
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	@Nullable
 	public ObjectId getPeeledObjectId() {
 		return getLeaf().getPeeledObjectId();
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public boolean isPeeled() {
 		return getLeaf().isPeeled();
@@ -128,7 +120,6 @@
 		return updateIndex;
 	}
 
-	/** {@inheritDoc} */
 	@SuppressWarnings("nls")
 	@Override
 	public String toString() {
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/lib/TagBuilder.java b/org.eclipse.jgit/src/org/eclipse/jgit/lib/TagBuilder.java
index facb4a5..bbc6144 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/lib/TagBuilder.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/lib/TagBuilder.java
@@ -223,7 +223,6 @@
 		}
 	}
 
-	/** {@inheritDoc} */
 	@SuppressWarnings("nls")
 	@Override
 	public String toString() {
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/lib/TextProgressMonitor.java b/org.eclipse.jgit/src/org/eclipse/jgit/lib/TextProgressMonitor.java
index 85aa0b6..98ea2f9 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/lib/TextProgressMonitor.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/lib/TextProgressMonitor.java
@@ -45,7 +45,6 @@
 		this.write = true;
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	protected void onUpdate(String taskName, int workCurr, Duration duration) {
 		StringBuilder s = new StringBuilder();
@@ -53,7 +52,6 @@
 		send(s);
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	protected void onEndTask(String taskName, int workCurr, Duration duration) {
 		StringBuilder s = new StringBuilder();
@@ -73,7 +71,6 @@
 		appendDuration(s, duration);
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	protected void onUpdate(String taskName, int cmp, int totalWork, int pcnt,
 			Duration duration) {
@@ -82,7 +79,6 @@
 		send(s);
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	protected void onEndTask(String taskName, int cmp, int totalWork, int pcnt,
 			Duration duration) {
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/lib/ThreadSafeProgressMonitor.java b/org.eclipse.jgit/src/org/eclipse/jgit/lib/ThreadSafeProgressMonitor.java
index e553955..05eacdc 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/lib/ThreadSafeProgressMonitor.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/lib/ThreadSafeProgressMonitor.java
@@ -55,7 +55,6 @@
 		this.process = new Semaphore(0);
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public void start(int totalTasks) {
 		if (!isMainThread())
@@ -63,7 +62,6 @@
 		pm.start(totalTasks);
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public void beginTask(String title, int totalWork) {
 		if (!isMainThread())
@@ -132,14 +130,12 @@
 			pm.update(cnt);
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public void update(int completed) {
 		if (0 == pendingUpdates.getAndAdd(completed))
 			process.release();
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public boolean isCancelled() {
 		lock.lock();
@@ -150,7 +146,6 @@
 		}
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public void endTask() {
 		if (!isMainThread())
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/lib/TreeFormatter.java b/org.eclipse.jgit/src/org/eclipse/jgit/lib/TreeFormatter.java
index e1f8684..c3c170a 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/lib/TreeFormatter.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/lib/TreeFormatter.java
@@ -332,7 +332,6 @@
 		}
 	}
 
-	/** {@inheritDoc} */
 	@SuppressWarnings("nls")
 	@Override
 	public String toString() {
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/lib/TypedConfigGetter.java b/org.eclipse.jgit/src/org/eclipse/jgit/lib/TypedConfigGetter.java
index c4eb8f1..0c03adc 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/lib/TypedConfigGetter.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/lib/TypedConfigGetter.java
@@ -57,6 +57,8 @@
 	/**
 	 * Parse an enumeration from a git {@link Config}.
 	 *
+	 * @param <T>
+	 *            type of the enum
 	 * @param config
 	 *            to get the value from
 	 * @param all
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/merge/EolAwareOutputStream.java b/org.eclipse.jgit/src/org/eclipse/jgit/merge/EolAwareOutputStream.java
index e44970a..1ddac18 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/merge/EolAwareOutputStream.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/merge/EolAwareOutputStream.java
@@ -79,14 +79,12 @@
 		return bol;
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public void write(int val) throws IOException {
 		out.write(val);
 		bol = (val == '\n');
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public void write(byte[] buf, int pos, int cnt) throws IOException {
 		if (cnt > 0) {
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/merge/MergeAlgorithm.java b/org.eclipse.jgit/src/org/eclipse/jgit/merge/MergeAlgorithm.java
index 8060735..b902492 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/merge/MergeAlgorithm.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/merge/MergeAlgorithm.java
@@ -90,10 +90,16 @@
 	/**
 	 * Does the three way merge between a common base and two sequences.
 	 *
-	 * @param cmp comparison method for this execution.
-	 * @param base the common base sequence
-	 * @param ours the first sequence to be merged
-	 * @param theirs the second sequence to be merged
+	 * @param <S>
+	 *            type of the sequences
+	 * @param cmp
+	 *            comparison method for this execution.
+	 * @param base
+	 *            the common base sequence
+	 * @param ours
+	 *            the first sequence to be merged
+	 * @param theirs
+	 *            the second sequence to be merged
 	 * @return the resulting content
 	 */
 	public <S extends Sequence> MergeResult<S> merge(
@@ -121,6 +127,8 @@
 						// Let their complete content conflict with empty text
 						result.add(1, 0, 0,
 								ConflictState.FIRST_CONFLICTING_RANGE);
+						result.add(0, 0, base.size(),
+								ConflictState.BASE_CONFLICTING_RANGE);
 						result.add(2, 0, theirs.size(),
 								ConflictState.NEXT_CONFLICTING_RANGE);
 						break;
@@ -149,6 +157,8 @@
 					// Let our complete content conflict with empty text
 					result.add(1, 0, ours.size(),
 							ConflictState.FIRST_CONFLICTING_RANGE);
+					result.add(0, 0, base.size(),
+						ConflictState.BASE_CONFLICTING_RANGE);
 					result.add(2, 0, 0, ConflictState.NEXT_CONFLICTING_RANGE);
 					break;
 				}
@@ -318,6 +328,14 @@
 						result.add(1, oursBeginB + commonPrefix,
 								oursEndB - commonSuffix,
 								ConflictState.FIRST_CONFLICTING_RANGE);
+
+						int baseBegin = Math.min(oursBeginB, theirsBeginB)
+								+ commonPrefix;
+						int baseEnd = Math.min(base.size(),
+								Math.max(oursEndB, theirsEndB)) - commonSuffix;
+						result.add(0, baseBegin, baseEnd,
+								ConflictState.BASE_CONFLICTING_RANGE);
+
 						result.add(2, theirsBeginB + commonPrefix,
 								theirsEndB - commonSuffix,
 								ConflictState.NEXT_CONFLICTING_RANGE);
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/merge/MergeChunk.java b/org.eclipse.jgit/src/org/eclipse/jgit/merge/MergeChunk.java
index ca998e3..7102aa6 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/merge/MergeChunk.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/merge/MergeChunk.java
@@ -29,14 +29,22 @@
 		NO_CONFLICT,
 
 		/**
-		 * This chunk does belong to a conflict and is the first one of the
+		 * This chunk does belong to a conflict and is the ours section of the
 		 * conflicting chunks
 		 */
 		FIRST_CONFLICTING_RANGE,
 
 		/**
-		 * This chunk does belong to a conflict but is not the first one of the
-		 * conflicting chunks. It's a subsequent one.
+		 * This chunk does belong to a conflict and is the base section of the
+		 * conflicting chunks
+		 *
+		 * @since 6.7
+		 */
+		BASE_CONFLICTING_RANGE,
+
+		/**
+		 * This chunk does belong to a conflict and is the theirs section of
+		 * the conflicting chunks. It's a subsequent one.
 		 */
 		NEXT_CONFLICTING_RANGE
 	}
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/merge/MergeFormatter.java b/org.eclipse.jgit/src/org/eclipse/jgit/merge/MergeFormatter.java
index 18b0ad9..a35b30e 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/merge/MergeFormatter.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/merge/MergeFormatter.java
@@ -43,6 +43,7 @@
 	 *            the name of the character set used when writing conflict
 	 *            metadata
 	 * @throws java.io.IOException
+	 *             if an IO error occurred
 	 * @deprecated Use
 	 *             {@link #formatMerge(OutputStream, MergeResult, List, Charset)}
 	 *             instead.
@@ -73,6 +74,7 @@
 	 * @param charset
 	 *            the character set used when writing conflict metadata
 	 * @throws java.io.IOException
+	 *             if an IO error occurred
 	 * @since 5.2
 	 */
 	public void formatMerge(OutputStream out, MergeResult<RawText> res,
@@ -81,6 +83,35 @@
 	}
 
 	/**
+	 * Formats the results of a merge of {@link org.eclipse.jgit.diff.RawText}
+	 * objects in a Git conformant way using diff3 style. This method also
+	 * assumes that the {@link org.eclipse.jgit.diff.RawText} objects being
+	 * merged are line oriented files which use LF as delimiter. This method
+	 * will also use LF to separate chunks and conflict metadata, therefore it
+	 * fits only to texts that are LF-separated lines.
+	 *
+	 * @param out
+	 *            the output stream where to write the textual presentation
+	 * @param res
+	 *            the merge result which should be presented
+	 * @param seqName
+	 *            When a conflict is reported each conflicting range will get a
+	 *            name. This name is following the "&lt;&lt;&lt;&lt;&lt;&lt;&lt;
+	 *            ", "|||||||" or "&gt;&gt;&gt;&gt;&gt;&gt;&gt; " conflict
+	 *            markers. The names for the sequences are given in this list
+	 * @param charset
+	 *            the character set used when writing conflict metadata
+	 * @throws java.io.IOException
+	 *            if an IO error occurred
+	 * @since 6.7
+	 */
+	public void formatMergeDiff3(OutputStream out,
+			MergeResult<RawText> res, List<String> seqName, Charset charset)
+			throws IOException {
+		new MergeFormatterPass(out, res, seqName, charset, true).formatMerge();
+	}
+
+	/**
 	 * Formats the results of a merge of exactly two
 	 * {@link org.eclipse.jgit.diff.RawText} objects in a Git conformant way.
 	 * This convenience method accepts the names for the three sequences (base
@@ -102,6 +133,7 @@
 	 *            the name of the character set used when writing conflict
 	 *            metadata
 	 * @throws java.io.IOException
+	 *             if an IO error occurred
 	 * @deprecated use
 	 *             {@link #formatMerge(OutputStream, MergeResult, String, String, String, Charset)}
 	 *             instead.
@@ -134,6 +166,7 @@
 	 * @param charset
 	 *            the character set used when writing conflict metadata
 	 * @throws java.io.IOException
+	 *             if an IO error occurred
 	 * @since 5.2
 	 */
 	@SuppressWarnings("unchecked")
@@ -146,4 +179,39 @@
 		names.add(theirsName);
 		formatMerge(out, res, names, charset);
 	}
+
+	/**
+	 * Formats the results of a merge of three
+	 * {@link org.eclipse.jgit.diff.RawText} objects in a Git conformant way,
+	 * using diff-3 style. This convenience method accepts the names for the
+	 * three sequences (base and the two merged sequences) as explicit
+	 * parameters and doesn't require the caller to specify a List
+	 *
+	 * @param out
+	 *            the {@link java.io.OutputStream} where to write the textual
+	 *            presentation
+	 * @param res
+	 *            the merge result which should be presented
+	 * @param baseName
+	 *            the name ranges from the base should get
+	 * @param oursName
+	 *            the name ranges from ours should get
+	 * @param theirsName
+	 *            the name ranges from theirs should get
+	 * @param charset
+	 *            the character set used when writing conflict metadata
+	 * @throws java.io.IOException
+	 *            if an IO error occurred
+	 * @since 6.7
+	 */
+	@SuppressWarnings("unchecked")
+	public void formatMergeDiff3(OutputStream out,
+			MergeResult res, String baseName, String oursName,
+			String theirsName, Charset charset) throws IOException {
+		List<String> names = new ArrayList<>(3);
+		names.add(baseName);
+		names.add(oursName);
+		names.add(theirsName);
+		formatMergeDiff3(out, res, names, charset);
+	}
 }
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/merge/MergeFormatterPass.java b/org.eclipse.jgit/src/org/eclipse/jgit/merge/MergeFormatterPass.java
index f09b343..5e80b5f 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/merge/MergeFormatterPass.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/merge/MergeFormatterPass.java
@@ -31,6 +31,8 @@
 
 	private final boolean threeWayMerge;
 
+	private final boolean writeBase; // diff3-style requested
+
 	private String lastConflictingName; // is set to non-null whenever we are in
 										// a conflict
 
@@ -50,22 +52,47 @@
 	 */
 	MergeFormatterPass(OutputStream out, MergeResult<RawText> res,
 			List<String> seqName, Charset charset) {
+		this(out, res, seqName, charset, false);
+	}
+
+	/**
+	 * @param out
+	 *            the {@link java.io.OutputStream} where to write the textual
+	 *            presentation
+	 * @param res
+	 *            the merge result which should be presented
+	 * @param seqName
+	 *            When a conflict is reported each conflicting range will get a
+	 *            name. This name is following the "&lt;&lt;&lt;&lt;&lt;&lt;&lt;
+	 *            ", "|||||||" or "&gt;&gt;&gt;&gt;&gt;&gt;&gt; " conflict
+	 *            markers. The names for the sequences are given in this list
+	 * @param charset
+	 *            the character set used when writing conflict metadata
+	 * @param writeBase
+	 *            base's contribution should be written in conflicts
+	 */
+	MergeFormatterPass(OutputStream out, MergeResult<RawText> res,
+			List<String> seqName, Charset charset, boolean writeBase) {
 		this.out = new EolAwareOutputStream(out);
 		this.res = res;
 		this.seqName = seqName;
 		this.charset = charset;
 		this.threeWayMerge = (res.getSequences().size() == 3);
+		this.writeBase = writeBase;
 	}
 
 	void formatMerge() throws IOException {
 		boolean missingNewlineAtEnd = false;
 		for (MergeChunk chunk : res) {
-			RawText seq = res.getSequences().get(chunk.getSequenceIndex());
-			writeConflictMetadata(chunk);
-			// the lines with conflict-metadata are written. Now write the chunk
-			for (int i = chunk.getBegin(); i < chunk.getEnd(); i++)
-				writeLine(seq, i);
-			missingNewlineAtEnd = seq.isMissingNewlineAtEnd();
+			if (!isBase(chunk) || writeBase) {
+				RawText seq = res.getSequences().get(chunk.getSequenceIndex());
+				writeConflictMetadata(chunk);
+				// the lines with conflict-metadata are written. Now write the
+				// chunk
+				for (int i = chunk.getBegin(); i < chunk.getEnd(); i++)
+					writeLine(seq, i);
+				missingNewlineAtEnd = seq.isMissingNewlineAtEnd();
+			}
 		}
 		// one possible leftover: if the merge result ended with a conflict we
 		// have to close the last conflict here
@@ -77,16 +104,19 @@
 
 	private void writeConflictMetadata(MergeChunk chunk) throws IOException {
 		if (lastConflictingName != null
-				&& chunk.getConflictState() != ConflictState.NEXT_CONFLICTING_RANGE) {
-			// found the end of an conflict
+				&& !isTheirs(chunk) && !isBase(chunk)) {
+			// found the end of a conflict
 			writeConflictEnd();
 		}
-		if (chunk.getConflictState() == ConflictState.FIRST_CONFLICTING_RANGE) {
-			// found the start of an conflict
+		if (isOurs(chunk)) {
+			// found the start of a conflict
 			writeConflictStart(chunk);
-		} else if (chunk.getConflictState() == ConflictState.NEXT_CONFLICTING_RANGE) {
-			// found another conflicting chunk
+		} else if (isTheirs(chunk)) {
+			// found the theirs conflicting chunk
 			writeConflictChange(chunk);
+		} else if (isBase(chunk)) {
+			// found the base conflicting chunk
+			writeConflictBase(chunk);
 		}
 	}
 
@@ -113,6 +143,11 @@
 				+ lastConflictingName);
 	}
 
+	private void writeConflictBase(MergeChunk chunk) throws IOException {
+		lastConflictingName = seqName.get(chunk.getSequenceIndex());
+		writeln("||||||| " + lastConflictingName); //$NON-NLS-1$
+	}
+
 	private void writeln(String s) throws IOException {
 		out.beginln();
 		out.write((s + "\n").getBytes(charset)); //$NON-NLS-1$
@@ -125,4 +160,17 @@
 		if (out.isBeginln())
 			out.write('\n');
 	}
+
+	private boolean isBase(MergeChunk chunk) {
+		return chunk.getConflictState() == ConflictState.BASE_CONFLICTING_RANGE;
+	}
+
+	private boolean isOurs(MergeChunk chunk) {
+		return chunk
+				.getConflictState() == ConflictState.FIRST_CONFLICTING_RANGE;
+	}
+
+	private boolean isTheirs(MergeChunk chunk) {
+		return chunk.getConflictState() == ConflictState.NEXT_CONFLICTING_RANGE;
+	}
 }
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/merge/MergeResult.java b/org.eclipse.jgit/src/org/eclipse/jgit/merge/MergeResult.java
index 20fc3c3..acf9553 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/merge/MergeResult.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/merge/MergeResult.java
@@ -97,7 +97,6 @@
 
 	static final ConflictState[] states = ConflictState.values();
 
-	/** {@inheritDoc} */
 	@Override
 	public Iterator<MergeChunk> iterator() {
 		return new Iterator<>() {
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/merge/RecursiveMerger.java b/org.eclipse.jgit/src/org/eclipse/jgit/merge/RecursiveMerger.java
index df60689..1162a61 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/merge/RecursiveMerger.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/merge/RecursiveMerger.java
@@ -123,6 +123,7 @@
 	 *         synthetic merge base this commit is visible only the merger's
 	 *         RevWalk and will not be in the repository.
 	 * @throws java.io.IOException
+	 *             if an IO error occurred
 	 * @throws IncorrectObjectTypeException
 	 *             one of the input objects is not a commit.
 	 * @throws NoMergeBaseException
@@ -213,6 +214,7 @@
 	 *            the list of parent commits
 	 * @return a new commit visible only within this merger's RevWalk.
 	 * @throws IOException
+	 *             if an IO error occurred
 	 */
 	private RevCommit createCommitForTree(ObjectId tree, List<RevCommit> parents)
 			throws IOException {
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/merge/ResolveMerger.java b/org.eclipse.jgit/src/org/eclipse/jgit/merge/ResolveMerger.java
index 04c17be..6eea7b8 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/merge/ResolveMerger.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/merge/ResolveMerger.java
@@ -472,7 +472,6 @@
 		/**
 		 * Detects if CRLF conversion has been configured.
 		 * <p>
-		 * </p>
 		 * See {@link EolStreamTypeUtil#detectStreamType} for more info.
 		 *
 		 * @param attributes
@@ -911,7 +910,6 @@
 				: strategy;
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	protected boolean mergeImpl() throws IOException {
 		return mergeTrees(mergeBase(), sourceTrees[0], sourceTrees[1],
@@ -922,18 +920,23 @@
 	 * adds a new path with the specified stage to the index builder
 	 *
 	 * @param path
+	 *            the new path
 	 * @param p
+	 *            canonical tree parser
 	 * @param stage
-	 * @param lastMod
+	 *            the stage
+	 * @param lastModified
+	 *            lastModified attribute of the file
 	 * @param len
+	 *            file length
 	 * @return the entry which was added to the index
 	 */
 	private DirCacheEntry add(byte[] path, CanonicalTreeParser p, int stage,
-			Instant lastMod, long len) {
+			Instant lastModified, long len) {
 		if (p != null && !p.getEntryFileMode().equals(FileMode.TREE)) {
 			return workTreeUpdater.addExistingToIndex(p.getEntryObjectId(), path,
 					p.getEntryFileMode(), stage,
-					lastMod, (int) len);
+					lastModified, (int) len);
 		}
 		return null;
 	}
@@ -1063,6 +1066,7 @@
 	 *         didn't match ours or the working-dir file was dirty and a
 	 *         conflict occurred
 	 * @throws java.io.IOException
+	 *             if an IO error occurred
 	 * @since 6.1
 	 */
 	protected boolean processEntry(CanonicalTreeParser base,
@@ -1439,15 +1443,21 @@
 	 * specified as <code>null</code> then an empty text will be used instead.
 	 *
 	 * @param base
+	 *            used to parse base tree
 	 * @param ours
+	 *            used to parse ours tree
 	 * @param theirs
+	 *            used to parse theirs tree
 	 * @param attributes
+	 *            attributes for the different stages
 	 * @param strategy
+	 *            merge strategy
 	 *
 	 * @return the result of the content merge
 	 * @throws BinaryBlobException
 	 *             if any of the blobs looks like a binary blob
 	 * @throws IOException
+	 *             if an IO error occurred
 	 */
 	private MergeResult<RawText> contentMerge(CanonicalTreeParser base,
 			CanonicalTreeParser ours, CanonicalTreeParser theirs,
@@ -1523,11 +1533,17 @@
 	 * correct stages to the index.
 	 *
 	 * @param base
+	 *            used to parse base tree
 	 * @param ours
+	 *            used to parse ours tree
 	 * @param theirs
+	 *            used to parse theirs tree
 	 * @param result
+	 *            merge result
 	 * @param attributes
+	 *            the file's attributes
 	 * @throws IOException
+	 *             if an IO error occurred
 	 */
 	private void updateIndex(CanonicalTreeParser base,
 			CanonicalTreeParser ours, CanonicalTreeParser theirs,
@@ -1578,6 +1594,7 @@
 	 *            the files .gitattributes entries
 	 * @return the working tree file to which the merged content was written.
 	 * @throws IOException
+	 *             if an IO error occurred
 	 */
 	private File writeMergedFile(TemporaryBuffer rawMerged,
 			Attributes attributes)
@@ -1662,7 +1679,6 @@
 		return FileMode.GITLINK.equals(mode);
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public ObjectId getResultTreeId() {
 		return (resultTree == null) ? null : resultTree.toObjectId();
@@ -1822,6 +1838,7 @@
 	 *            content-merge conflicts.
 	 * @return whether the trees merged cleanly
 	 * @throws java.io.IOException
+	 *             if an IO error occurred
 	 * @since 3.5
 	 */
 	protected boolean mergeTrees(AbstractTreeIterator baseTree,
@@ -1881,6 +1898,7 @@
 	 *            {@link org.eclipse.jgit.merge.ResolveMerger#mergeTrees(AbstractTreeIterator, RevTree, RevTree, boolean)}
 	 * @return Whether the trees merged cleanly.
 	 * @throws java.io.IOException
+	 *             if an IO error occurred
 	 * @since 3.5
 	 */
 	protected boolean mergeTreeWalk(TreeWalk treeWalk, boolean ignoreConflicts)
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/merge/StrategyOneSided.java b/org.eclipse.jgit/src/org/eclipse/jgit/merge/StrategyOneSided.java
index 7055ccd..6064ebe 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/merge/StrategyOneSided.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/merge/StrategyOneSided.java
@@ -43,25 +43,21 @@
 		treeIndex = index;
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public String getName() {
 		return strategyName;
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public Merger newMerger(Repository db) {
 		return new OneSide(db, treeIndex);
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public Merger newMerger(Repository db, boolean inCore) {
 		return new OneSide(db, treeIndex);
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public Merger newMerger(ObjectInserter inserter, Config config) {
 		return new OneSide(inserter, treeIndex);
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/merge/StrategyRecursive.java b/org.eclipse.jgit/src/org/eclipse/jgit/merge/StrategyRecursive.java
index c9512ed..a74bfc0 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/merge/StrategyRecursive.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/merge/StrategyRecursive.java
@@ -21,25 +21,21 @@
  */
 public class StrategyRecursive extends StrategyResolve {
 
-	/** {@inheritDoc} */
 	@Override
 	public ThreeWayMerger newMerger(Repository db) {
 		return new RecursiveMerger(db, false);
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public ThreeWayMerger newMerger(Repository db, boolean inCore) {
 		return new RecursiveMerger(db, inCore);
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public ThreeWayMerger newMerger(ObjectInserter inserter, Config config) {
 		return new RecursiveMerger(inserter, config);
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public String getName() {
 		return "recursive"; //$NON-NLS-1$
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/merge/StrategyResolve.java b/org.eclipse.jgit/src/org/eclipse/jgit/merge/StrategyResolve.java
index 5991ef6..a686fd0 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/merge/StrategyResolve.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/merge/StrategyResolve.java
@@ -19,25 +19,21 @@
  */
 public class StrategyResolve extends ThreeWayMergeStrategy {
 
-	/** {@inheritDoc} */
 	@Override
 	public ThreeWayMerger newMerger(Repository db) {
 		return new ResolveMerger(db, false);
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public ThreeWayMerger newMerger(Repository db, boolean inCore) {
 		return new ResolveMerger(db, inCore);
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public ThreeWayMerger newMerger(ObjectInserter inserter, Config config) {
 		return new ResolveMerger(inserter, config);
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public String getName() {
 		return "resolve"; //$NON-NLS-1$
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/merge/StrategySimpleTwoWayInCore.java b/org.eclipse.jgit/src/org/eclipse/jgit/merge/StrategySimpleTwoWayInCore.java
index ff40fc1..c3180ab 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/merge/StrategySimpleTwoWayInCore.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/merge/StrategySimpleTwoWayInCore.java
@@ -43,26 +43,22 @@
 		//
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public String getName() {
 		return "simple-two-way-in-core"; //$NON-NLS-1$
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public ThreeWayMerger newMerger(Repository db) {
 		return new InCoreMerger(db);
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public ThreeWayMerger newMerger(Repository db, boolean inCore) {
 		// This class is always inCore, so ignore the parameter
 		return newMerger(db);
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public ThreeWayMerger newMerger(ObjectInserter inserter, Config config) {
 		return new InCoreMerger(inserter);
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/merge/ThreeWayMergeStrategy.java b/org.eclipse.jgit/src/org/eclipse/jgit/merge/ThreeWayMergeStrategy.java
index 411789f..8cefa65 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/merge/ThreeWayMergeStrategy.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/merge/ThreeWayMergeStrategy.java
@@ -16,11 +16,9 @@
  * A merge strategy to merge 2 trees, using a common base ancestor tree.
  */
 public abstract class ThreeWayMergeStrategy extends MergeStrategy {
-	/** {@inheritDoc} */
 	@Override
 	public abstract ThreeWayMerger newMerger(Repository db);
 
-	/** {@inheritDoc} */
 	@Override
 	public abstract ThreeWayMerger newMerger(Repository db, boolean inCore);
 }
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/merge/ThreeWayMerger.java b/org.eclipse.jgit/src/org/eclipse/jgit/merge/ThreeWayMerger.java
index f283ede..68a1b5e 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/merge/ThreeWayMerger.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/merge/ThreeWayMerger.java
@@ -88,7 +88,6 @@
 		}
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public boolean merge(AnyObjectId... tips) throws IOException {
 		if (tips.length != 2)
@@ -96,7 +95,6 @@
 		return super.merge(tips);
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public ObjectId getBaseCommitId() {
 		return baseCommitId;
@@ -108,6 +106,7 @@
 	 * @return an iterator over the caller-specified merge base, or the natural
 	 *         merge base of the two input commits.
 	 * @throws java.io.IOException
+	 *             if an IO error occurred
 	 */
 	protected AbstractTreeIterator mergeBase() throws IOException {
 		if (baseTree != null) {
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/nls/NLS.java b/org.eclipse.jgit/src/org/eclipse/jgit/nls/NLS.java
index 881873d..16d1763 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/nls/NLS.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/nls/NLS.java
@@ -83,6 +83,8 @@
 	 * injected as described in the
 	 * {@link org.eclipse.jgit.nls.TranslationBundle}.
 	 *
+	 * @param <T>
+	 *            type of the translation bundle
 	 * @param type
 	 *            required bundle type
 	 * @return an instance of the required bundle type
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/notes/DefaultNoteMerger.java b/org.eclipse.jgit/src/org/eclipse/jgit/notes/DefaultNoteMerger.java
index bde0b9e..b65f28c 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/notes/DefaultNoteMerger.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/notes/DefaultNoteMerger.java
@@ -34,7 +34,6 @@
  */
 public class DefaultNoteMerger implements NoteMerger {
 
-	/** {@inheritDoc} */
 	@Override
 	public Note merge(Note base, Note ours, Note theirs, ObjectReader reader,
 			ObjectInserter inserter) throws IOException {
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/notes/Note.java b/org.eclipse.jgit/src/org/eclipse/jgit/notes/Note.java
index c356963..2f719bf 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/notes/Note.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/notes/Note.java
@@ -45,7 +45,6 @@
 		data = newData;
 	}
 
-	/** {@inheritDoc} */
 	@SuppressWarnings("nls")
 	@Override
 	public String toString() {
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/notes/NoteMap.java b/org.eclipse.jgit/src/org/eclipse/jgit/notes/NoteMap.java
index 93adf36..b872750 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/notes/NoteMap.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/notes/NoteMap.java
@@ -166,7 +166,6 @@
 		this.reader = reader;
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public Iterator<Note> iterator() {
 		try {
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/notes/NoteMapMerger.java b/org.eclipse.jgit/src/org/eclipse/jgit/notes/NoteMapMerger.java
index a6ea523..79ceb13 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/notes/NoteMapMerger.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/notes/NoteMapMerger.java
@@ -94,6 +94,7 @@
 	 *            theirs version of the note tree
 	 * @return merge result as a new NoteMap
 	 * @throws java.io.IOException
+	 *             if an IO error occurred
 	 */
 	public NoteMap merge(NoteMap base, NoteMap ours, NoteMap theirs)
 			throws IOException {
@@ -113,11 +114,16 @@
 	 * between base, ours and theirs.
 	 *
 	 * @param treeDepth
+	 *            depth of the tree
 	 * @param base
+	 *            base version
 	 * @param ours
+	 *            ours version
 	 * @param theirs
+	 *            theirs version
 	 * @return merge result as an InMemoryBucket
 	 * @throws IOException
+	 *             if an IO error occurred
 	 */
 	private InMemoryNoteBucket merge(int treeDepth, InMemoryNoteBucket base,
 			InMemoryNoteBucket ours, InMemoryNoteBucket theirs)
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/patch/CombinedFileHeader.java b/org.eclipse.jgit/src/org/eclipse/jgit/patch/CombinedFileHeader.java
index 4ba7cca..e29af61 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/patch/CombinedFileHeader.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/patch/CombinedFileHeader.java
@@ -40,7 +40,6 @@
 		super(b, offset);
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	@SuppressWarnings("unchecked")
 	public List<? extends CombinedHunkHeader> getHunks() {
@@ -48,9 +47,6 @@
 	}
 
 	/**
-	 * {@inheritDoc}
-	 * <p>
-	 *
 	 * @return number of ancestor revisions mentioned in this diff.
 	 */
 	@Override
@@ -60,7 +56,7 @@
 
 	/**
 	 * {@inheritDoc}
-	 * <p>
+	 *
 	 * @return get the file mode of the first parent.
 	 */
 	@Override
@@ -81,7 +77,6 @@
 
 	/**
 	 * {@inheritDoc}
-	 * <p>
 	 *
 	 * @return get the object id of the first parent.
 	 */
@@ -101,7 +96,6 @@
 		return oldIds[nthParent];
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public String getScriptText(Charset ocs, Charset ncs) {
 		final Charset[] cs = new Charset[getParentCount() + 1];
@@ -110,11 +104,6 @@
 		return getScriptText(cs);
 	}
 
-	/**
-	 * {@inheritDoc}
-	 * <p>
-	 * Convert the patch script for this file into a string.
-	 */
 	@Override
 	public String getScriptText(Charset[] charsetGuess) {
 		return super.getScriptText(charsetGuess);
@@ -156,7 +145,6 @@
 		return ptr;
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	protected void parseIndexLine(int ptr, int eol) {
 		// "index $asha1,$bsha1..$csha1"
@@ -178,7 +166,6 @@
 		oldModes = new FileMode[oldIds.length];
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	protected void parseNewFileMode(int ptr, int eol) {
 		for (int i = 0; i < oldModes.length; i++)
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/patch/CombinedHunkHeader.java b/org.eclipse.jgit/src/org/eclipse/jgit/patch/CombinedHunkHeader.java
index 263b1b9..49cf499 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/patch/CombinedHunkHeader.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/patch/CombinedHunkHeader.java
@@ -45,13 +45,11 @@
 		}
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public CombinedFileHeader getFileHeader() {
 		return (CombinedFileHeader) super.getFileHeader();
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public OldImage getOldImage() {
 		return getOldImage(0);
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/patch/FileHeader.java b/org.eclipse.jgit/src/org/eclipse/jgit/patch/FileHeader.java
index 1e6fb78..a47b73d 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/patch/FileHeader.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/patch/FileHeader.java
@@ -187,6 +187,13 @@
 		return getScriptText(new Charset[] { oldCharset, newCharset });
 	}
 
+	/**
+	 * Convert the patch script for this file into a string.
+	 *
+	 * @param charsetGuess
+	 *            hint which charset is used
+	 * @return the patch script, as a Unicode string.
+	 */
 	String getScriptText(Charset[] charsetGuess) {
 		if (getHunks().isEmpty()) {
 			// If we have no hunks then we can safely assume the entire
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/patch/FormatError.java b/org.eclipse.jgit/src/org/eclipse/jgit/patch/FormatError.java
index 5618a71..8d21b6d 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/patch/FormatError.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/patch/FormatError.java
@@ -91,7 +91,6 @@
 		return RawParseUtils.decode(UTF_8, buf, offset, eol);
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public String toString() {
 		final StringBuilder r = new StringBuilder();
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/patch/HunkHeader.java b/org.eclipse.jgit/src/org/eclipse/jgit/patch/HunkHeader.java
index 4b59fcf..1359f66 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/patch/HunkHeader.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/patch/HunkHeader.java
@@ -409,7 +409,6 @@
 		offsets[fileIdx] = end < 0 ? s.length() : end + 1;
 	}
 
-	/** {@inheritDoc} */
 	@SuppressWarnings("nls")
 	@Override
 	public String toString() {
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 04300a9..7cfc162 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/patch/PatchApplier.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/patch/PatchApplier.java
@@ -254,6 +254,7 @@
 	 *            the patch to apply.
 	 * @return the result of the patch
 	 * @throws IOException
+	 *             if an IO error occurred
 	 * @since 6.6
 	 */
 	public Result applyPatch(Patch p) throws IOException {
@@ -448,6 +449,7 @@
 	 * @param result
 	 *            The patch application result.
 	 * @throws IOException
+	 *             if an IO error occurred
 	 */
 	private void apply(String pathWithOriginalContent, DirCache dirCache,
 			DirCacheBuilder dirCacheBuilder, @Nullable File f, FileHeader fh, Result result)
@@ -802,7 +804,9 @@
 	 *            The patch application result
 	 * @return a loader for the new content, or null if invalid.
 	 * @throws IOException
+	 *             if an IO error occurred
 	 * @throws UnsupportedOperationException
+	 *             if an operation isn't supported
 	 */
 	private @Nullable ContentStreamLoader applyBinary(String path, File f, FileHeader fh,
 			StreamSupplier inputSupplier, ObjectId id, Result result)
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/revplot/PlotCommit.java b/org.eclipse.jgit/src/org/eclipse/jgit/revplot/PlotCommit.java
index c11fca1..fa109e8 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/revplot/PlotCommit.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/revplot/PlotCommit.java
@@ -179,7 +179,6 @@
 		return (L) lane;
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public void reset() {
 		forkingOffLanes = NO_LANES;
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/revplot/PlotCommitList.java b/org.eclipse.jgit/src/org/eclipse/jgit/revplot/PlotCommitList.java
index 458f240..3177de1 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/revplot/PlotCommitList.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/revplot/PlotCommitList.java
@@ -49,7 +49,6 @@
 	private final HashMap<PlotLane, Integer> laneLength = new HashMap<>(
 			32);
 
-	/** {@inheritDoc} */
 	@Override
 	public void clear() {
 		super.clear();
@@ -59,7 +58,6 @@
 		laneLength.clear();
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public void source(RevWalk w) {
 		if (!(w instanceof PlotWalk))
@@ -91,7 +89,6 @@
 			result.add((L) p);
 	}
 
-	/** {@inheritDoc} */
 	@SuppressWarnings("ReferenceEquality")
 	@Override
 	protected void enter(int index, PlotCommit<L> currCommit) {
@@ -184,6 +181,7 @@
 	 * @param index
 	 *            the index of <code>currCommit</code> in the list
 	 * @param currCommit
+	 *            the current commit
 	 * @param childOnLane
 	 *            the direct child on the same lane as <code>currCommit</code>,
 	 *            may be null if <code>currCommit</code> is the first commit on
@@ -287,8 +285,11 @@
 	 * All blockades on the lane must be resolved before calling this method.
 	 *
 	 * @param commitIndex
+	 *            commit index
 	 * @param child
+	 *            child to connect
 	 * @param laneToContinue
+	 *            lane to continue
 	 */
 	@SuppressWarnings("ReferenceEquality")
 	private void drawLaneToChild(final int commitIndex, PlotCommit child,
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/revplot/PlotWalk.java b/org.eclipse.jgit/src/org/eclipse/jgit/revplot/PlotWalk.java
index 0582338..0f6bd2d 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/revplot/PlotWalk.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/revplot/PlotWalk.java
@@ -49,7 +49,6 @@
 
 	private Repository repository;
 
-	/** {@inheritDoc} */
 	@Override
 	public void dispose() {
 		super.dispose();
@@ -83,6 +82,7 @@
 	 * @param refs
 	 *            additional refs
 	 * @throws java.io.IOException
+	 *             if an IO error occurred
 	 */
 	public void addAdditionalRefs(Iterable<Ref> refs) throws IOException {
 		for (Ref ref : refs) {
@@ -97,7 +97,6 @@
 		}
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public void sort(RevSort s, boolean use) {
 		if (s == RevSort.TOPO && !use)
@@ -105,13 +104,11 @@
 		super.sort(s, use);
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	protected RevCommit createCommit(AnyObjectId id) {
 		return new PlotCommit(id);
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public RevCommit next() throws MissingObjectException,
 			IncorrectObjectTypeException, IOException {
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/AbstractRevQueue.java b/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/AbstractRevQueue.java
index dda108b..73ae62a 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/AbstractRevQueue.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/AbstractRevQueue.java
@@ -79,8 +79,6 @@
 	}
 
 	/**
-	 * {@inheritDoc}
-	 * <p>
 	 * Remove the first commit from the queue.
 	 */
 	@Override
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/BlockRevQueue.java b/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/BlockRevQueue.java
index cdd8073..e855d8f 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/BlockRevQueue.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/BlockRevQueue.java
@@ -45,8 +45,6 @@
 	}
 
 	/**
-	 * {@inheritDoc}
-	 * <p>
 	 * Reconfigure this queue to share the same free list as another.
 	 * <p>
 	 * Multiple revision queues can be connected to the same free list, making
@@ -56,6 +54,11 @@
 	 * <p>
 	 * Free lists are not thread-safe. Applications must ensure that all queues
 	 * sharing the same free list are doing so from only a single thread.
+	 *
+	 * @param q
+	 *            another FIFO queue that wants to share our queue's free list.
+	 *
+	 * @see Generator#shareFreeList
 	 */
 	@Override
 	public void shareFreeList(BlockRevQueue q) {
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/DepthGenerator.java b/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/DepthGenerator.java
index ec0824c..664f8fa 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/DepthGenerator.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/DepthGenerator.java
@@ -55,10 +55,15 @@
 
 	/**
 	 * @param w
-	 * @param s Parent generator
+	 *            walk used for depth filtering
+	 * @param s
+	 *            Parent generator
 	 * @throws MissingObjectException
+	 *             if an object is missing
 	 * @throws IncorrectObjectTypeException
+	 *             if an object has an unexpected type
 	 * @throws IOException
+	 *             if an IO error occurred
 	 */
 	DepthGenerator(DepthWalk w, Generator s) throws MissingObjectException,
 			IncorrectObjectTypeException, IOException {
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/DepthWalk.java b/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/DepthWalk.java
index 5277563..f74666b 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/DepthWalk.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/DepthWalk.java
@@ -159,8 +159,11 @@
 		 * @param c
 		 *            Commit to mark
 		 * @throws IOException
+		 *             if an IO error occurred
 		 * @throws IncorrectObjectTypeException
+		 *             if object has an unexpected type
 		 * @throws MissingObjectException
+		 *             if object is missing
 		 */
 		public void markRoot(RevCommit c) throws MissingObjectException,
 				IncorrectObjectTypeException, IOException {
@@ -289,8 +292,11 @@
 		 * @param o
 		 *            Commit to mark
 		 * @throws IOException
+		 *             if an IO error occurred
 		 * @throws IncorrectObjectTypeException
+		 *             if object has an unexpected type
 		 * @throws MissingObjectException
+		 *             if object is missing
 		 */
 		public void markRoot(RevObject o) throws MissingObjectException,
 				IncorrectObjectTypeException, IOException {
@@ -313,8 +319,11 @@
 		 * @param c
 		 *            Commit to mark
 		 * @throws MissingObjectException
+		 *             if object is missing
 		 * @throws IncorrectObjectTypeException
+		 *             if object has an unexpected type
 		 * @throws IOException
+		 *             if an IO error occurred
 		 */
 		public void markUnshallow(RevObject c) throws MissingObjectException,
 				IncorrectObjectTypeException, IOException {
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/FIFORevQueue.java b/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/FIFORevQueue.java
index 0f8eddd..996745c 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/FIFORevQueue.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/FIFORevQueue.java
@@ -37,7 +37,6 @@
 		super(s);
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public void add(RevCommit c) {
 		Block b = tail;
@@ -82,7 +81,6 @@
 		head = b;
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public RevCommit next() {
 		final Block b = head;
@@ -99,7 +97,6 @@
 		return c;
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public void clear() {
 		head = null;
@@ -135,7 +132,6 @@
 		}
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public String toString() {
 		final StringBuilder s = new StringBuilder();
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/FollowFilter.java b/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/FollowFilter.java
index 3b54123..35ef51f 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/FollowFilter.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/FollowFilter.java
@@ -11,6 +11,8 @@
 package org.eclipse.jgit.revwalk;
 
 import java.io.IOException;
+import java.util.Optional;
+import java.util.Set;
 
 import org.eclipse.jgit.diff.DiffConfig;
 import org.eclipse.jgit.errors.IncorrectObjectTypeException;
@@ -77,7 +79,6 @@
 		return path.getPath();
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public boolean include(TreeWalk walker)
 			throws MissingObjectException, IncorrectObjectTypeException,
@@ -85,19 +86,22 @@
 		return path.include(walker) && ANY_DIFF.include(walker);
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public boolean shouldBeRecursive() {
 		return path.shouldBeRecursive() || ANY_DIFF.shouldBeRecursive();
 	}
 
+	@Override
+	public Optional<Set<byte[]>> getPathsBestEffort() {
+		return path.getPathsBestEffort();
+	}
+
 	/** {@inheritDoc} */
 	@Override
 	public TreeFilter clone() {
 		return new FollowFilter(path.clone(), cfg);
 	}
 
-	/** {@inheritDoc} */
 	@SuppressWarnings("nls")
 	@Override
 	public String toString() {
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/FooterKey.java b/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/FooterKey.java
index 74e4c1e..af50794 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/FooterKey.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/FooterKey.java
@@ -51,7 +51,6 @@
 		return name;
 	}
 
-	/** {@inheritDoc} */
 	@SuppressWarnings("nls")
 	@Override
 	public String toString() {
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/FooterLine.java b/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/FooterLine.java
index 3d128a6..2d396d5 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/FooterLine.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/FooterLine.java
@@ -11,6 +11,9 @@
 package org.eclipse.jgit.revwalk;
 
 import java.nio.charset.Charset;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
 
 import org.eclipse.jgit.util.RawParseUtils;
 
@@ -47,6 +50,112 @@
 	}
 
 	/**
+	 * Extract the footer lines from the given message.
+	 *
+	 * @param str
+	 *            the message to extract footers from.
+	 * @return ordered list of footer lines; empty list if no footers found.
+	 * @see RevCommit#getFooterLines()
+	 * @since 6.7
+	 */
+	public static List<FooterLine> fromMessage(
+			String str) {
+		return fromMessage(str.getBytes());
+	}
+
+	/**
+	 * Extract the footer lines from the given message.
+	 *
+	 * @param raw
+	 *            the raw message to extract footers from.
+	 * @return ordered list of footer lines; empty list if no footers found.
+	 * @see RevCommit#getFooterLines()
+	 * @since 6.7
+	 */
+	public static List<FooterLine> fromMessage(
+			byte[] raw) {
+		int ptr = raw.length - 1;
+		while (raw[ptr] == '\n') // trim any trailing LFs, not interesting
+			ptr--;
+
+		int msgB = RawParseUtils.commitMessage(raw, 0);
+		ArrayList<FooterLine> r = new ArrayList<>(4);
+		Charset enc = RawParseUtils.guessEncoding(raw);
+		for (;;) {
+			ptr = RawParseUtils.prevLF(raw, ptr);
+			if (ptr <= msgB)
+				break; // Don't parse commit headers as footer lines.
+
+			int keyStart = ptr + 2;
+			if (raw[keyStart] == '\n')
+				break; // Stop at first paragraph break, no footers above it.
+
+			int keyEnd = RawParseUtils.endOfFooterLineKey(raw, keyStart);
+			if (keyEnd < 0)
+				continue; // Not a well formed footer line, skip it.
+
+			// Skip over the ': *' at the end of the key before the value.
+			//
+			int valStart = keyEnd + 1;
+			while (valStart < raw.length && raw[valStart] == ' ')
+				valStart++;
+
+			// Value ends at the LF, and does not include it.
+			//
+			int valEnd = RawParseUtils.nextLF(raw, valStart);
+			if (raw[valEnd - 1] == '\n')
+				valEnd--;
+
+			r.add(new FooterLine(raw, enc, keyStart, keyEnd, valStart, valEnd));
+		}
+		Collections.reverse(r);
+		return r;
+	}
+
+	/**
+	 * Get the values of all footer lines with the given key.
+	 *
+	 * @param footers
+	 *            list of footers to find the values in.
+	 * @param keyName
+	 *            footer key to find values of, case-insensitive.
+	 * @return values of footers with key of {@code keyName}, ordered by their
+	 *         order of appearance. Duplicates may be returned if the same
+	 *         footer appeared more than once. Empty list if no footers appear
+	 *         with the specified key, or there are no footers at all.
+	 * @see #fromMessage
+	 * @since 6.7
+	 */
+	public static List<String> getValues(List<FooterLine> footers, String keyName) {
+		return getValues(footers, new FooterKey(keyName));
+	}
+
+	/**
+	 * Get the values of all footer lines with the given key.
+	 *
+	 * @param footers
+	 *            list of footers to find the values in.
+	 * @param key
+	 *            footer key to find values of, case-insensitive.
+	 * @return values of footers with key of {@code keyName}, ordered by their
+	 *         order of appearance. Duplicates may be returned if the same
+	 *         footer appeared more than once. Empty list if no footers appear
+	 *         with the specified key, or there are no footers at all.
+	 * @see #fromMessage
+	 * @since 6.7
+	 */
+	public static List<String> getValues(List<FooterLine> footers, FooterKey key) {
+		if (footers.isEmpty())
+			return Collections.emptyList();
+		ArrayList<String> r = new ArrayList<>(footers.size());
+		for (FooterLine f : footers) {
+			if (f.matches(key))
+				r.add(f.getValue());
+		}
+		return r;
+	}
+
+	/**
 	 * Whether keys match
 	 *
 	 * @param key
@@ -117,7 +226,6 @@
 		return RawParseUtils.decode(enc, buffer, lt, gt - 1);
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public String toString() {
 		return getKey() + ": " + getValue(); //$NON-NLS-1$
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/Generator.java b/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/Generator.java
index 3493dcf..d97812f 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/Generator.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/Generator.java
@@ -71,8 +71,11 @@
 	 *
 	 * @return next available commit; null if no more are to be returned.
 	 * @throws MissingObjectException
+	 *             if an object is missing
 	 * @throws IncorrectObjectTypeException
+	 *             if an object has an unexpected type
 	 * @throws IOException
+	 *             if an IO error occurred
 	 */
 	abstract RevCommit next() throws MissingObjectException,
 			IncorrectObjectTypeException, IOException;
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/LIFORevQueue.java b/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/LIFORevQueue.java
index 4773ca8..ae67ca7 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/LIFORevQueue.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/LIFORevQueue.java
@@ -34,7 +34,6 @@
 		super(s);
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public void add(RevCommit c) {
 		Block b = head;
@@ -47,7 +46,6 @@
 		b.unpop(c);
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public RevCommit next() {
 		final Block b = head;
@@ -62,7 +60,6 @@
 		return c;
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public void clear() {
 		head = null;
@@ -89,7 +86,6 @@
 		return false;
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public String toString() {
 		final StringBuilder s = new StringBuilder();
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/ObjectWalk.java b/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/ObjectWalk.java
index 4e48a5c..64b2fcd 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/ObjectWalk.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/ObjectWalk.java
@@ -300,14 +300,12 @@
 			addObject(o);
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public void sort(RevSort s) {
 		super.sort(s);
 		boundary = hasRevSort(RevSort.BOUNDARY);
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public void sort(RevSort s, boolean use) {
 		super.sort(s, use);
@@ -357,7 +355,6 @@
 		visitationPolicy = requireNonNull(policy);
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public RevCommit next() throws MissingObjectException,
 			IncorrectObjectTypeException, IOException {
@@ -762,7 +759,6 @@
 		pathBuf = newBuf;
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public void dispose() {
 		super.dispose();
@@ -771,7 +767,6 @@
 		freeVisit = null;
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	protected void reset(int retainFlags) {
 		super.reset(retainFlags);
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/RenameCallback.java b/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/RenameCallback.java
index ba3399c..9856f2c 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/RenameCallback.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/RenameCallback.java
@@ -23,8 +23,30 @@
 	 * Called whenever a diff was found that is actually a rename or copy of a
 	 * file.
 	 *
+	 * <p>Subclass of this class have to override this to receive diffEntry for
+	 * the rename.
+	 *
 	 * @param entry
 	 *            the entry representing the rename/copy
 	 */
 	public abstract void renamed(DiffEntry entry);
+
+	/**
+	 * Called whenever a diff was found that is actually a rename or copy of a
+	 * file along with the commit that caused it.
+	 *
+	 * <p>Subclass of this class have an option to override this if it wants to
+	 * know what commit generated the diffEntry. Otherwise defaults to the
+	 * {@link RenameCallback#renamed(DiffEntry)} function.
+	 *
+	 * @param entry
+	 *            the entry representing the rename/copy
+	 * @param commit
+	 *            commit at which callback occurred
+	 *
+	 * @since 6.7
+	 */
+	public void renamed(DiffEntry entry, RevCommit commit) {
+		renamed(entry);
+	}
 }
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/RevBlob.java b/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/RevBlob.java
index f5abbb8..1f81b6a 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/RevBlob.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/RevBlob.java
@@ -33,7 +33,6 @@
 		super(id);
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public final int getType() {
 		return Constants.OBJ_BLOB;
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 b64c9ce..0392ea4 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/RevCommit.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/RevCommit.java
@@ -11,20 +11,19 @@
 
 package org.eclipse.jgit.revwalk;
 
-import static java.nio.charset.StandardCharsets.UTF_8;
+import static org.eclipse.jgit.util.RawParseUtils.guessEncoding;
 
 import java.io.IOException;
 import java.nio.charset.Charset;
 import java.nio.charset.IllegalCharsetNameException;
 import java.nio.charset.UnsupportedCharsetException;
-import java.util.ArrayList;
 import java.util.Arrays;
-import java.util.Collections;
 import java.util.List;
 
 import org.eclipse.jgit.annotations.Nullable;
 import org.eclipse.jgit.errors.IncorrectObjectTypeException;
 import org.eclipse.jgit.errors.MissingObjectException;
+import org.eclipse.jgit.internal.storage.commitgraph.ChangedPathFilter;
 import org.eclipse.jgit.lib.AnyObjectId;
 import org.eclipse.jgit.lib.Constants;
 import org.eclipse.jgit.lib.MutableObjectId;
@@ -222,7 +221,6 @@
 		flags |= PARSED;
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public final int getType() {
 		return Constants.OBJ_COMMIT;
@@ -484,7 +482,8 @@
 		if (msgB < 0) {
 			return ""; //$NON-NLS-1$
 		}
-		return RawParseUtils.decode(guessEncoding(), raw, msgB, raw.length);
+		return RawParseUtils.decode(guessEncoding(buffer), raw, msgB,
+				raw.length);
 	}
 
 	/**
@@ -510,7 +509,8 @@
 		}
 
 		int msgE = RawParseUtils.endOfParagraph(raw, msgB);
-		String str = RawParseUtils.decode(guessEncoding(), raw, msgB, msgE);
+		String str = RawParseUtils.decode(guessEncoding(buffer), raw, msgB,
+				msgE);
 		if (hasLF(raw, msgB, msgE)) {
 			str = StringUtils.replaceLineBreaksWithSpace(str);
 		}
@@ -562,14 +562,6 @@
 		return RawParseUtils.parseEncoding(buffer);
 	}
 
-	private Charset guessEncoding() {
-		try {
-			return getEncoding();
-		} catch (IllegalCharsetNameException | UnsupportedCharsetException e) {
-			return UTF_8;
-		}
-	}
-
 	/**
 	 * Parse the footer lines (e.g. "Signed-off-by") for machine processing.
 	 * <p>
@@ -592,50 +584,14 @@
 	 * @return ordered list of footer lines; empty list if no footers found.
 	 */
 	public final List<FooterLine> getFooterLines() {
-		final byte[] raw = buffer;
-		int ptr = raw.length - 1;
-		while (raw[ptr] == '\n') // trim any trailing LFs, not interesting
-			ptr--;
-
-		final int msgB = RawParseUtils.commitMessage(raw, 0);
-		final ArrayList<FooterLine> r = new ArrayList<>(4);
-		final Charset enc = guessEncoding();
-		for (;;) {
-			ptr = RawParseUtils.prevLF(raw, ptr);
-			if (ptr <= msgB)
-				break; // Don't parse commit headers as footer lines.
-
-			final int keyStart = ptr + 2;
-			if (raw[keyStart] == '\n')
-				break; // Stop at first paragraph break, no footers above it.
-
-			final int keyEnd = RawParseUtils.endOfFooterLineKey(raw, keyStart);
-			if (keyEnd < 0)
-				continue; // Not a well formed footer line, skip it.
-
-			// Skip over the ': *' at the end of the key before the value.
-			//
-			int valStart = keyEnd + 1;
-			while (valStart < raw.length && raw[valStart] == ' ')
-				valStart++;
-
-			// Value ends at the LF, and does not include it.
-			//
-			int valEnd = RawParseUtils.nextLF(raw, valStart);
-			if (raw[valEnd - 1] == '\n')
-				valEnd--;
-
-			r.add(new FooterLine(raw, enc, keyStart, keyEnd, valStart, valEnd));
-		}
-		Collections.reverse(r);
-		return r;
+		return FooterLine.fromMessage(buffer);
 	}
 
 	/**
 	 * Get the values of all footer lines with the given key.
 	 *
 	 * @param keyName
-	 *            footer key to find values of, case insensitive.
+	 *            footer key to find values of, case-insensitive.
 	 * @return values of footers with key of {@code keyName}, ordered by their
 	 *         order of appearance. Duplicates may be returned if the same
 	 *         footer appeared more than once. Empty list if no footers appear
@@ -643,30 +599,22 @@
 	 * @see #getFooterLines()
 	 */
 	public final List<String> getFooterLines(String keyName) {
-		return getFooterLines(new FooterKey(keyName));
+		return FooterLine.getValues(getFooterLines(), keyName);
 	}
 
 	/**
 	 * Get the values of all footer lines with the given key.
 	 *
-	 * @param keyName
-	 *            footer key to find values of, case insensitive.
+	 * @param key
+	 *            footer key to find values of, case-insensitive.
 	 * @return values of footers with key of {@code keyName}, ordered by their
 	 *         order of appearance. Duplicates may be returned if the same
 	 *         footer appeared more than once. Empty list if no footers appear
 	 *         with the specified key, or there are no footers at all.
 	 * @see #getFooterLines()
 	 */
-	public final List<String> getFooterLines(FooterKey keyName) {
-		final List<FooterLine> src = getFooterLines();
-		if (src.isEmpty())
-			return Collections.emptyList();
-		final ArrayList<String> r = new ArrayList<>(src.size());
-		for (FooterLine f : src) {
-			if (f.matches(keyName))
-				r.add(f.getValue());
-		}
-		return r;
+	public final List<String> getFooterLines(FooterKey key) {
+		return FooterLine.getValues(getFooterLines(), key);
 	}
 
 	/**
@@ -688,6 +636,21 @@
 	}
 
 	/**
+	 * Get the changed path filter of the commit.
+	 * <p>
+	 * This is null when there is no commit graph file, the commit is not in the
+	 * commit graph file, or the commit graph file was generated without changed
+	 * path filters.
+	 *
+	 * @param rw A revwalk to load the commit graph (if available)
+	 * @return the changed path filter
+	 * @since 6.7
+	 */
+	public ChangedPathFilter getChangedPathFilter(RevWalk rw) {
+		return null;
+	}
+
+	/**
 	 * Reset this commit to allow another RevWalk with the same instances.
 	 * <p>
 	 * Subclasses <b>must</b> call <code>super.reset()</code> to ensure the
@@ -713,7 +676,6 @@
 		buffer = null;
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public String toString() {
 		final StringBuilder s = new StringBuilder();
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/RevCommitCG.java b/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/RevCommitCG.java
index 4d3664d..c7a0399 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/RevCommitCG.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/RevCommitCG.java
@@ -14,6 +14,7 @@
 
 import org.eclipse.jgit.errors.IncorrectObjectTypeException;
 import org.eclipse.jgit.errors.MissingObjectException;
+import org.eclipse.jgit.internal.storage.commitgraph.ChangedPathFilter;
 import org.eclipse.jgit.internal.storage.commitgraph.CommitGraph;
 import org.eclipse.jgit.lib.AnyObjectId;
 import org.eclipse.jgit.lib.Constants;
@@ -44,7 +45,6 @@
 		this.graphPosition = graphPosition;
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	void parseCanonical(RevWalk walk, byte[] raw) throws IOException {
 		if (walk.isRetainBody()) {
@@ -53,7 +53,6 @@
 		parseInGraph(walk);
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	void parseHeaders(RevWalk walk) throws MissingObjectException,
 			IncorrectObjectTypeException, IOException {
@@ -98,9 +97,14 @@
 		flags |= PARSED;
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	int getGeneration() {
 		return generation;
 	}
+
+	/** {@inheritDoc} */
+	@Override
+	public ChangedPathFilter getChangedPathFilter(RevWalk rw) {
+		return rw.commitGraph().getChangedPathFilter(graphPosition);
+	}
 }
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/RevCommitList.java b/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/RevCommitList.java
index 59213a8..58f5d42 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/RevCommitList.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/RevCommitList.java
@@ -25,7 +25,6 @@
 public class RevCommitList<E extends RevCommit> extends RevObjectList<E> {
 	private RevWalk walker;
 
-	/** {@inheritDoc} */
 	@Override
 	public void clear() {
 		super.clear();
@@ -313,7 +312,6 @@
 	 * walker specified by {@link #source(RevWalk)} is pumped until the
 	 * specified commit is loaded. Callers can test the final size of the list
 	 * by {@link #size()} to determine if the high water mark specified was met.
-	 * <p>
 	 *
 	 * @param commitToLoad
 	 *            commit the caller wants this list to contain when the fill
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/RevFlag.java b/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/RevFlag.java
index a0160dd..3221bf6 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/RevFlag.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/RevFlag.java
@@ -67,7 +67,6 @@
 		return walker;
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public String toString() {
 		return name;
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/RevObject.java b/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/RevObject.java
index 4d2684a..55ea30d 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/RevObject.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/RevObject.java
@@ -132,7 +132,6 @@
 		flags &= ~set.mask;
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public String toString() {
 		final StringBuilder s = new StringBuilder();
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/RevObjectList.java b/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/RevObjectList.java
index 0393f55..ad8aeed 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/RevObjectList.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/RevObjectList.java
@@ -47,7 +47,6 @@
 		// Initialized above.
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public void add(int index, E element) {
 		if (index != size)
@@ -58,7 +57,6 @@
 		size++;
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	@SuppressWarnings("unchecked")
 	public E set(int index, E element) {
@@ -80,7 +78,6 @@
 		return (E) old;
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	@SuppressWarnings("unchecked")
 	public E get(int index) {
@@ -95,13 +92,11 @@
 		return s != null ? (E) s.contents[index] : null;
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public int size() {
 		return size;
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public void clear() {
 		contents = new Block(0);
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/RevTag.java b/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/RevTag.java
index b9d1450..75dbd57 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/RevTag.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/RevTag.java
@@ -149,7 +149,6 @@
 		flags |= PARSED;
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public final int getType() {
 		return Constants.OBJ_TAG;
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/RevTree.java b/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/RevTree.java
index 8119af4..d81af0c 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/RevTree.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/RevTree.java
@@ -33,7 +33,6 @@
 		super(id);
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public final int getType() {
 		return Constants.OBJ_TREE;
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 2fb3a60..0319684 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/RevWalk.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/RevWalk.java
@@ -221,7 +221,6 @@
 
 	/**
 	 * Create a new revision walker for a given repository.
-	 * <p>
 	 *
 	 * @param or
 	 *            the reader the walker will obtain data from. The reader is not
@@ -479,7 +478,6 @@
 	 * <p>
 	 * A commit is merged into a ref if we can find a path of commits that leads
 	 * from that specific ref and ends at <code>commit</code>.
-	 * <p>
 	 *
 	 * @param commit
 	 *            commit the caller thinks is reachable from <code>refs</code>.
@@ -501,7 +499,6 @@
 	 * <p>
 	 * A commit is merged into a ref if we can find a path of commits that leads
 	 * from that specific ref and ends at <code>commit</code>.
-	 * <p>
 	 *
 	 * @param commit
 	 *            commit the caller thinks is reachable from <code>refs</code>.
@@ -1222,6 +1219,8 @@
 	/**
 	 * Asynchronous object parsing.
 	 *
+	 * @param <T>
+	 *            Type of returned {@code ObjectId}
 	 * @param objectIds
 	 *            objects to open from the object store. The supplied collection
 	 *            must not be modified until the queue has finished.
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/RevWalkUtils.java b/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/RevWalkUtils.java
index e52e916..4bfe2fd 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/RevWalkUtils.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/RevWalkUtils.java
@@ -51,8 +51,11 @@
 	 *            should be done until there are no more commits
 	 * @return the number of commits
 	 * @throws org.eclipse.jgit.errors.MissingObjectException
+	 *             if object is missing
 	 * @throws org.eclipse.jgit.errors.IncorrectObjectTypeException
+	 *             if object has unexpected type
 	 * @throws java.io.IOException
+	 *             if an IO error occurred
 	 */
 	public static int count(final RevWalk walk, final RevCommit start,
 			final RevCommit end) throws MissingObjectException,
@@ -80,8 +83,11 @@
 	 *            should be done until there are no more commits
 	 * @return the commits found
 	 * @throws org.eclipse.jgit.errors.MissingObjectException
+	 *             if object is missing
 	 * @throws org.eclipse.jgit.errors.IncorrectObjectTypeException
+	 *             if object has unexpected type
 	 * @throws java.io.IOException
+	 *             if an IO error occurred
 	 */
 	public static List<RevCommit> find(final RevWalk walk,
 			final RevCommit start, final RevCommit end)
@@ -116,8 +122,11 @@
 	 *            the set of branches we want to see reachability from
 	 * @return the list of branches a given commit is reachable from
 	 * @throws org.eclipse.jgit.errors.MissingObjectException
+	 *             if object is missing
 	 * @throws org.eclipse.jgit.errors.IncorrectObjectTypeException
+	 *             if object has unexpected type
 	 * @throws java.io.IOException
+	 *             if an IO error occurred
 	 */
 	public static List<Ref> findBranchesReachableFrom(RevCommit commit,
 			RevWalk revWalk, Collection<Ref> refs)
@@ -147,8 +156,11 @@
 	 *            the callback for progress and cancellation
 	 * @return the list of branches a given commit is reachable from
 	 * @throws org.eclipse.jgit.errors.MissingObjectException
+	 *             if object is missing
 	 * @throws org.eclipse.jgit.errors.IncorrectObjectTypeException
+	 *             if object has unexpected type
 	 * @throws java.io.IOException
+	 *             if an IO error occurred
 	 * @since 5.4
 	 */
 	public static List<Ref> findBranchesReachableFrom(RevCommit commit,
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/RewriteGenerator.java b/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/RewriteGenerator.java
index 2c88bb8..4a93f4d 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/RewriteGenerator.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/RewriteGenerator.java
@@ -101,9 +101,13 @@
 	 * of this commit by the previous {@link PendingGenerator}.
 	 *
 	 * @param c
+	 *            given commit
 	 * @throws MissingObjectException
+	 *             if an object is missing
 	 * @throws IncorrectObjectTypeException
+	 *             if an object has an unexpected type
 	 * @throws IOException
+	 *             if an IO error occurred
 	 */
 	private void applyFilterToParents(RevCommit c)
 			throws MissingObjectException, IncorrectObjectTypeException,
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/TopoNonIntermixSortGenerator.java b/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/TopoNonIntermixSortGenerator.java
index 452545a..c9d8ff9 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/TopoNonIntermixSortGenerator.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/TopoNonIntermixSortGenerator.java
@@ -33,8 +33,11 @@
 	 * @param s
 	 *            generator to pull all commits out of, and into this buffer.
 	 * @throws MissingObjectException
+	 *             if an object is missing
 	 * @throws IncorrectObjectTypeException
+	 *             if an object has an unexpected type
 	 * @throws IOException
+	 *             if an IO error occurred
 	 */
 	TopoNonIntermixSortGenerator(Generator s) throws MissingObjectException,
 			IncorrectObjectTypeException, IOException {
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/TopoSortGenerator.java b/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/TopoSortGenerator.java
index 4739f78..950b0a4 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/TopoSortGenerator.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/TopoSortGenerator.java
@@ -33,8 +33,11 @@
 	 * @param s
 	 *            generator to pull all commits out of, and into this buffer.
 	 * @throws MissingObjectException
+	 *             if an object is missing
 	 * @throws IncorrectObjectTypeException
+	 *             if an object has an unexpected type
 	 * @throws IOException
+	 *             if an IO error occurred
 	 */
 	TopoSortGenerator(Generator s) throws MissingObjectException,
 			IncorrectObjectTypeException, IOException {
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/TreeRevFilter.java b/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/TreeRevFilter.java
index f921449..43571a6 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/TreeRevFilter.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/TreeRevFilter.java
@@ -12,7 +12,10 @@
 
 import java.io.IOException;
 import java.util.List;
+import java.util.Optional;
+import java.util.Set;
 
+import org.eclipse.jgit.internal.storage.commitgraph.ChangedPathFilter;
 import org.eclipse.jgit.diff.DiffConfig;
 import org.eclipse.jgit.diff.DiffEntry;
 import org.eclipse.jgit.diff.DiffEntry.ChangeType;
@@ -47,6 +50,12 @@
 
 	private final TreeWalk pathFilter;
 
+	private long changedPathFilterTruePositive = 0;
+
+	private long changedPathFilterFalsePositive = 0;
+
+	private long changedPathFilterNegative = 0;
+
 	/**
 	 * Create a {@link org.eclipse.jgit.revwalk.filter.RevFilter} from a
 	 * {@link org.eclipse.jgit.treewalk.filter.TreeFilter}.
@@ -92,13 +101,11 @@
 		this.rewriteFlag = rewriteFlag;
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public RevFilter clone() {
 		throw new UnsupportedOperationException();
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public boolean include(RevWalk walker, RevCommit c)
 			throws StopWalkException, MissingObjectException,
@@ -124,12 +131,41 @@
 			// We have exactly one parent. This is a very common case.
 			//
 			int chgs = 0, adds = 0;
-			while (tw.next()) {
-				chgs++;
-				if (tw.getRawMode(0) == 0 && tw.getRawMode(1) != 0) {
-					adds++;
-				} else {
-					break; // no point in looking at this further.
+			boolean changedPathFilterUsed = false;
+			boolean mustCalculateChgs = true;
+			ChangedPathFilter cpf = c.getChangedPathFilter(walker);
+			if (cpf != null) {
+				Optional<Set<byte[]>> paths = pathFilter.getFilter()
+						.getPathsBestEffort();
+				if (paths.isPresent()) {
+					changedPathFilterUsed = true;
+					for (byte[] path : paths.get()) {
+						if (!cpf.maybeContains(path)) {
+							mustCalculateChgs = false;
+							break;
+						}
+					}
+				}
+			}
+			if (mustCalculateChgs) {
+				while (tw.next()) {
+					chgs++;
+					if (tw.getRawMode(0) == 0 && tw.getRawMode(1) != 0) {
+						adds++;
+					} else {
+						break; // no point in looking at this further.
+					}
+				}
+				if (changedPathFilterUsed) {
+					if (chgs > 0) {
+						changedPathFilterTruePositive++;
+					} else {
+						changedPathFilterFalsePositive++;
+					}
+				}
+			} else {
+				if (changedPathFilterUsed) {
+					changedPathFilterNegative++;
 				}
 			}
 
@@ -149,7 +185,8 @@
 				// commit. We need to update our filter to its older
 				// name, if we can discover it. Find out what that is.
 				//
-				updateFollowFilter(trees, ((FollowFilter) tw.getFilter()).cfg);
+				updateFollowFilter(trees, ((FollowFilter) tw.getFilter()).cfg,
+						c);
 			}
 			return true;
 		} else if (nParents == 0) {
@@ -241,13 +278,47 @@
 		return false;
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public boolean requiresCommitBody() {
 		return false;
 	}
 
-	private void updateFollowFilter(ObjectId[] trees, DiffConfig cfg)
+	/**
+	 * Return how many times a changed path filter correctly predicted that a
+	 * path was changed in a commit, for statistics gathering purposes.
+	 *
+	 * @return count of true positives
+	 * @since 6.7
+	 */
+	public long getChangedPathFilterTruePositive() {
+		return changedPathFilterTruePositive;
+	}
+
+	/**
+	 * Return how many times a changed path filter wrongly predicted that a path
+	 * was changed in a commit, for statistics gathering purposes.
+	 *
+	 * @return count of false positives
+	 * @since 6.7
+	 */
+	public long getChangedPathFilterFalsePositive() {
+		return changedPathFilterFalsePositive;
+	}
+
+	/**
+	 * Return how many times a changed path filter predicted that a path was not
+	 * changed in a commit (allowing that commit to be skipped), for statistics
+	 * gathering purposes.
+	 *
+	 * @return count of negatives
+	 * @since 6.7
+	 */
+	public long getChangedPathFilterNegative() {
+		return changedPathFilterNegative;
+	}
+
+	private void updateFollowFilter(ObjectId[] trees, DiffConfig cfg,
+			RevCommit commit)
 			throws MissingObjectException, IncorrectObjectTypeException,
 			CorruptObjectException, IOException {
 		TreeWalk tw = pathFilter;
@@ -266,7 +337,7 @@
 				newFilter = FollowFilter.create(ent.getOldPath(), cfg);
 				RenameCallback callback = oldFilter.getRenameCallback();
 				if (callback != null) {
-					callback.renamed(ent);
+					callback.renamed(ent, commit);
 					// forward the callback to the new follow filter
 					((FollowFilter) newFilter).setRenameCallback(callback);
 				}
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/filter/CommitTimeRevFilter.java b/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/filter/CommitTimeRevFilter.java
index 6ac490a..4100e87 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/filter/CommitTimeRevFilter.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/filter/CommitTimeRevFilter.java
@@ -98,13 +98,11 @@
 		when = (int) (ts / 1000);
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public RevFilter clone() {
 		return this;
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public boolean requiresCommitBody() {
 		return false;
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/filter/MaxCountRevFilter.java b/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/filter/MaxCountRevFilter.java
index 0e3a803..09bcb33 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/filter/MaxCountRevFilter.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/filter/MaxCountRevFilter.java
@@ -46,7 +46,6 @@
 		this.maxCount = maxCount;
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public boolean include(RevWalk walker, RevCommit cmit)
 			throws StopWalkException, MissingObjectException,
@@ -57,7 +56,6 @@
 		return true;
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public RevFilter clone() {
 		return new MaxCountRevFilter(maxCount);
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/filter/NotRevFilter.java b/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/filter/NotRevFilter.java
index 1482c51..8fcebc9 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/filter/NotRevFilter.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/filter/NotRevFilter.java
@@ -38,13 +38,11 @@
 		a = one;
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public RevFilter negate() {
 		return a;
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public boolean include(RevWalk walker, RevCommit c)
 			throws MissingObjectException, IncorrectObjectTypeException,
@@ -52,19 +50,16 @@
 		return !a.include(walker, c);
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public boolean requiresCommitBody() {
 		return a.requiresCommitBody();
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public RevFilter clone() {
 		return new NotRevFilter(a.clone());
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public String toString() {
 		return "NOT " + a.toString(); //$NON-NLS-1$
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/filter/RevFilter.java b/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/filter/RevFilter.java
index 256e479..8430646 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/filter/RevFilter.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/filter/RevFilter.java
@@ -264,7 +264,6 @@
 	@Override
 	public abstract RevFilter clone();
 
-	/** {@inheritDoc} */
 	@Override
 	public String toString() {
 		String n = getClass().getName();
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/filter/RevFlagFilter.java b/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/filter/RevFlagFilter.java
index 16d9f76..f9ee632 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/filter/RevFlagFilter.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/filter/RevFlagFilter.java
@@ -91,13 +91,11 @@
 		flags = m;
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public RevFilter clone() {
 		return this;
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public String toString() {
 		return super.toString() + flags;
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/filter/SkipRevFilter.java b/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/filter/SkipRevFilter.java
index 84df36a..bf93b7b 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/filter/SkipRevFilter.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/filter/SkipRevFilter.java
@@ -45,7 +45,6 @@
 		this.skip = skip;
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public boolean include(RevWalk walker, RevCommit cmit)
 			throws StopWalkException, MissingObjectException,
@@ -55,7 +54,6 @@
 		return true;
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public RevFilter clone() {
 		return new SkipRevFilter(skip);
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/filter/SubStringRevFilter.java b/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/filter/SubStringRevFilter.java
index 7f00dfd..ff1fea2 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/filter/SubStringRevFilter.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/filter/SubStringRevFilter.java
@@ -67,7 +67,6 @@
 		pattern = new RawSubStringPattern(patternText);
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public boolean include(RevWalk walker, RevCommit cmit)
 			throws MissingObjectException, IncorrectObjectTypeException,
@@ -75,7 +74,6 @@
 		return pattern.match(text(cmit)) >= 0;
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public boolean requiresCommitBody() {
 		return true;
@@ -90,13 +88,11 @@
 	 */
 	protected abstract RawCharSequence text(RevCommit cmit);
 
-	/** {@inheritDoc} */
 	@Override
 	public RevFilter clone() {
 		return this; // Typically we are actually thread-safe.
 	}
 
-	/** {@inheritDoc} */
 	@SuppressWarnings("nls")
 	@Override
 	public String toString() {
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/storage/file/FileBasedConfig.java b/org.eclipse.jgit/src/org/eclipse/jgit/storage/file/FileBasedConfig.java
index cba5e16..7fdcc4d 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/storage/file/FileBasedConfig.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/storage/file/FileBasedConfig.java
@@ -22,6 +22,8 @@
 import java.io.File;
 import java.io.IOException;
 import java.text.MessageFormat;
+import java.util.List;
+import java.util.concurrent.atomic.AtomicBoolean;
 
 import org.eclipse.jgit.errors.ConfigInvalidException;
 import org.eclipse.jgit.errors.LockFailedException;
@@ -52,6 +54,8 @@
 
 	private volatile ObjectId hash;
 
+	private AtomicBoolean exists = new AtomicBoolean();
+
 	/**
 	 * Create a configuration with no default fallback.
 	 *
@@ -84,7 +88,6 @@
 		this.hash = ObjectId.zeroId();
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	protected boolean notifyUponTransientChanges() {
 		// we will notify listeners upon save()
@@ -100,6 +103,21 @@
 		return configFile;
 	}
 
+	boolean exists() {
+		return exists.get();
+	}
+
+	@Override
+	public void setStringList(String section, String subsection, String name,
+			List<String> values) {
+		super.setStringList(section, subsection, name, values);
+	}
+
+	@Override
+	public void unsetSection(String section, String subsection) {
+		super.unsetSection(section, subsection);
+	}
+
 	/**
 	 * {@inheritDoc}
 	 * <p>
@@ -145,6 +163,7 @@
 				clear();
 				snapshot = lastSnapshot[0];
 			}
+			exists.set(wasRead != null);
 		} catch (IOException e) {
 			throw e;
 		} catch (Exception e) {
@@ -197,7 +216,6 @@
 		fireConfigChangedEvent();
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public void clear() {
 		hash = hash(new byte[0]);
@@ -208,7 +226,6 @@
 		return ObjectId.fromRaw(Constants.newMessageDigest().digest(rawText));
 	}
 
-	/** {@inheritDoc} */
 	@SuppressWarnings("nls")
 	@Override
 	public String toString() {
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/storage/file/UserConfigFile.java b/org.eclipse.jgit/src/org/eclipse/jgit/storage/file/UserConfigFile.java
new file mode 100644
index 0000000..2ad74c2
--- /dev/null
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/storage/file/UserConfigFile.java
@@ -0,0 +1,110 @@
+/*
+ * Copyright (C) 2023, Thomas Wolf <twolf@apache.org> and others
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Distribution License v. 1.0 which is available at
+ * https://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+package org.eclipse.jgit.storage.file;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.List;
+
+import org.eclipse.jgit.annotations.NonNull;
+import org.eclipse.jgit.errors.ConfigInvalidException;
+import org.eclipse.jgit.lib.Config;
+import org.eclipse.jgit.util.FS;
+
+/**
+ * User (global) git config based on two possible locations,
+ * {@code ~/.gitconfig} and {@code $XDG_CONFIG_HOME/git/config}.
+ * <p>
+ * For reading, both locations are considered, first the XDG file, then the file
+ * in the home directory. All updates occur in the last file read that exists,
+ * or in the home directory file if neither exists. In other words: if only the
+ * XDG file exists, it is updated, otherwise the home directory file is updated.
+ * </p>
+ *
+ * @since 6.7
+ */
+public class UserConfigFile extends FileBasedConfig {
+
+	private final FileBasedConfig parent;
+
+	/**
+	 * Creates a new {@link UserConfigFile}.
+	 *
+	 * @param parent
+	 *            parent {@link Config}; may be {@code null}
+	 * @param config
+	 *            {@link File} for {@code ~/.gitconfig}
+	 * @param xdgConfig
+	 *            {@link File} for {@code $XDG_CONFIG_HOME/.gitconfig}
+	 * @param fileSystem
+	 *            {@link FS} to use for the two files; normally
+	 *            {@link FS#DETECTED}
+	 */
+	public UserConfigFile(Config parent, @NonNull File config,
+			@NonNull File xdgConfig, @NonNull FS fileSystem) {
+		super(new FileBasedConfig(parent, xdgConfig, fileSystem), config,
+				fileSystem);
+		this.parent = (FileBasedConfig) getBaseConfig();
+	}
+
+	@Override
+	public void setStringList(String section, String subsection, String name,
+			List<String> values) {
+		if (exists() || !parent.exists()) {
+			super.setStringList(section, subsection, name, values);
+		} else {
+			parent.setStringList(section, subsection, name, values);
+		}
+	}
+
+	@Override
+	public void unset(String section, String subsection, String name) {
+		if (exists() || !parent.exists()) {
+			super.unset(section, subsection, name);
+		} else {
+			parent.unset(section, subsection, name);
+		}
+	}
+
+	@Override
+	public void unsetSection(String section, String subsection) {
+		if (exists() || !parent.exists()) {
+			super.unsetSection(section, subsection);
+		} else {
+			parent.unsetSection(section, subsection);
+		}
+	}
+
+	@Override
+	public boolean isOutdated() {
+		return super.isOutdated() || parent.isOutdated();
+	}
+
+	@Override
+	public void load() throws IOException, ConfigInvalidException {
+		if (super.isOutdated()) {
+			super.load();
+		}
+		if (parent.isOutdated()) {
+			parent.load();
+		}
+	}
+
+	@Override
+	public void save() throws IOException {
+		if (exists() || !parent.exists()) {
+			if (exists() || !toText().strip().isEmpty()) {
+				super.save();
+			}
+		} else {
+			parent.save();
+		}
+	}
+}
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/storage/file/WindowCacheConfig.java b/org.eclipse.jgit/src/org/eclipse/jgit/storage/file/WindowCacheConfig.java
index a12f652..27795ab 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/storage/file/WindowCacheConfig.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/storage/file/WindowCacheConfig.java
@@ -18,6 +18,7 @@
 import static org.eclipse.jgit.lib.ConfigConstants.CONFIG_KEY_PACKED_GIT_WINDOWSIZE;
 import static org.eclipse.jgit.lib.ConfigConstants.CONFIG_KEY_STREAM_FILE_TRESHOLD;
 import static org.eclipse.jgit.lib.ConfigConstants.CONFIG_KEY_PACKED_GIT_USE_STRONGREFS;
+import static org.eclipse.jgit.lib.ConfigConstants.CONFIG_KEY_PACKED_INDEX_GIT_USE_STRONGREFS;
 
 import org.eclipse.jgit.internal.storage.file.WindowCache;
 import org.eclipse.jgit.lib.Config;
@@ -39,6 +40,8 @@
 
 	private boolean useStrongRefs;
 
+	private boolean useStrongIndexRefs;
+
 	private int packedGitWindowSize;
 
 	private boolean packedGitMMAP;
@@ -56,6 +59,7 @@
 		packedGitOpenFiles = 128;
 		packedGitLimit = 10 * MB;
 		useStrongRefs = false;
+		useStrongIndexRefs = true;
 		packedGitWindowSize = 8 * KB;
 		packedGitMMAP = false;
 		deltaBaseCacheLimit = 10 * MB;
@@ -133,6 +137,31 @@
 	}
 
 	/**
+	 * Get whether the Pack indices cache should use strong references or
+	 * SoftReferences
+	 *
+	 * @return {@code true} if the cached Pack indices should use strong references,
+	 *         otherwise it will use {@link java.lang.ref.SoftReference}s
+	 * @since 6.7
+	 */
+	public boolean isPackedIndexGitUseStrongRefs() {
+		return useStrongIndexRefs;
+	}
+
+	/**
+	 * Set if the Pack indices cache should use strong refs or soft refs
+	 *
+	 * @param useStrongRefs
+	 *            if @{code true} the Pack strongly references cached indices
+	 *            otherwise it uses {@link java.lang.ref.SoftReference}s which
+	 *            can be evicted by the Java gc if heap is almost full
+	 * @since 6.7
+	 */
+	public void setPackedIndexGitUseStrongRefs(boolean useStrongRefs) {
+		this.useStrongIndexRefs = useStrongRefs;
+	}
+
+	/**
 	 * Get size in bytes of a single window mapped or read in from the pack
 	 * file.
 	 *
@@ -270,6 +299,8 @@
 		setPackedGitUseStrongRefs(rc.getBoolean(CONFIG_CORE_SECTION,
 				CONFIG_KEY_PACKED_GIT_USE_STRONGREFS,
 				isPackedGitUseStrongRefs()));
+		setPackedIndexGitUseStrongRefs(rc.getBoolean(CONFIG_CORE_SECTION,
+				CONFIG_KEY_PACKED_INDEX_GIT_USE_STRONGREFS, isPackedIndexGitUseStrongRefs()));
 		setPackedGitOpenFiles(rc.getInt(CONFIG_CORE_SECTION, null,
 				CONFIG_KEY_PACKED_GIT_OPENFILES, getPackedGitOpenFiles()));
 		setPackedGitLimit(rc.getLong(CONFIG_CORE_SECTION, null,
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/storage/pack/PackConfig.java b/org.eclipse.jgit/src/org/eclipse/jgit/storage/pack/PackConfig.java
index be87e07..d524524 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/storage/pack/PackConfig.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/storage/pack/PackConfig.java
@@ -268,8 +268,9 @@
 	public static final int DEFAULT_MIN_BYTES_FOR_OBJ_SIZE_INDEX = -1;
 
 	/**
-	 * Default max time to spend during the search for reuse phase. This
-	 * optimization is disabled by default: {@value}
+	 * Default max time to spend during the search for reuse phase.
+	 *
+	 * This optimization is disabled by default: {@link Integer#MAX_VALUE} seconds.
 	 *
 	 * @see #setSearchForReuseTimeout(Duration)
 	 * @since 5.13
@@ -1228,7 +1229,7 @@
 	/**
 	 * Get the max time to spend during the search for reuse phase.
 	 *
-	 * Default setting: {@value #DEFAULT_SEARCH_FOR_REUSE_TIMEOUT}
+	 * Default setting: {@link #DEFAULT_SEARCH_FOR_REUSE_TIMEOUT}
 	 *
 	 * @return the maximum time to spend during the search for reuse phase.
 	 * @since 5.13
@@ -1240,7 +1241,7 @@
 	/**
 	 * Set the age in days that marks a branch as "inactive".
 	 *
-	 * Default setting: {@value #DEFAULT_BITMAP_INACTIVE_BRANCH_AGE_IN_DAYS}
+	 * Default setting: {@link #DEFAULT_BITMAP_INACTIVE_BRANCH_AGE_IN_DAYS}
 	 *
 	 * @param ageInDays
 	 *            the age in days that marks a branch as "inactive"
@@ -1277,7 +1278,7 @@
 	 * @param timeout
 	 *            max time allowed during the search for reuse phase
 	 *
-	 *            Default setting: {@value #DEFAULT_SEARCH_FOR_REUSE_TIMEOUT}
+	 *            Default setting: {@link #DEFAULT_SEARCH_FOR_REUSE_TIMEOUT}
 	 * @since 5.13
 	 */
 	public void setSearchForReuseTimeout(Duration timeout) {
@@ -1416,7 +1417,6 @@
 				CONFIG_KEY_PRUNE_PRESERVED, DEFAULT_PRUNE_PRESERVED));
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public String toString() {
 		final StringBuilder b = new StringBuilder();
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/submodule/SubmoduleConflict.java b/org.eclipse.jgit/src/org/eclipse/jgit/submodule/SubmoduleConflict.java
index 856eb72..f09e1a5 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/submodule/SubmoduleConflict.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/submodule/SubmoduleConflict.java
@@ -55,9 +55,11 @@
     private final ObjectId objectId;
 
     /**
-     * Create a SubmoduleConflict for the given submodule object id
-     * @param objectId
-     */
+	 * Create a SubmoduleConflict for the given submodule object id
+	 *
+	 * @param objectId
+	 *            the id of the object to create a submodule conflict for
+	 */
     public SubmoduleConflict(ObjectId objectId) {
         super();
         this.objectId = objectId;
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/submodule/SubmoduleWalk.java b/org.eclipse.jgit/src/org/eclipse/jgit/submodule/SubmoduleWalk.java
index bf77021..7d5836e 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/submodule/SubmoduleWalk.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/submodule/SubmoduleWalk.java
@@ -87,6 +87,7 @@
 	 * @return generator over submodule index entries. The caller is responsible
 	 *         for calling {@link #close()}.
 	 * @throws java.io.IOException
+	 *             if an IO error occurred
 	 */
 	public static SubmoduleWalk forIndex(Repository repository)
 			throws IOException {
@@ -116,6 +117,7 @@
 	 * @return generator at given path. The caller is responsible for calling
 	 *         {@link #close()}. Null if no submodule at given path.
 	 * @throws java.io.IOException
+	 *             if an IO error occurred
 	 */
 	public static SubmoduleWalk forPath(Repository repository,
 			AnyObjectId treeId, String path) throws IOException {
@@ -150,6 +152,7 @@
 	 * @return generator at given path. The caller is responsible for calling
 	 *         {@link #close()}. Null if no submodule at given path.
 	 * @throws java.io.IOException
+	 *             if an IO error occurred
 	 */
 	public static SubmoduleWalk forPath(Repository repository,
 			AbstractTreeIterator iterator, String path) throws IOException {
@@ -193,6 +196,7 @@
 	 *            submodule path
 	 * @return repository or null if repository doesn't exist
 	 * @throws java.io.IOException
+	 *             if an IO error occurred
 	 */
 	public static Repository getSubmoduleRepository(final Repository parent,
 			final String path) throws IOException {
@@ -209,6 +213,7 @@
 	 *            submodule path
 	 * @return repository or null if repository doesn't exist
 	 * @throws java.io.IOException
+	 *             if an IO error occurred
 	 */
 	public static Repository getSubmoduleRepository(final File parent,
 			final String path) throws IOException {
@@ -220,11 +225,14 @@
 	 * abstraction
 	 *
 	 * @param parent
+	 *            {@link Repository} that contains the submodule
 	 * @param path
+	 *            of the working tree of the submodule
 	 * @param fs
 	 *            the file system abstraction to be used
 	 * @return repository or null if repository doesn't exist
 	 * @throws IOException
+	 *             if an IO error occurred
 	 * @since 4.10
 	 */
 	public static Repository getSubmoduleRepository(final File parent,
@@ -249,7 +257,7 @@
 	 * @return the {@link Repository} of the submodule, or {@code null} if it
 	 *         doesn't exist
 	 * @throws IOException
-	 *             on errors
+	 *             if an IO error occurred
 	 * @since 5.6
 	 */
 	public static Repository getSubmoduleRepository(File parent, String path,
@@ -286,6 +294,7 @@
 	 *            absolute or relative URL of the submodule repository
 	 * @return resolved URL
 	 * @throws java.io.IOException
+	 *             if an IO error occurred
 	 */
 	public static String getSubmoduleRemoteUrl(final Repository parent,
 			final String url) throws IOException {
@@ -369,6 +378,7 @@
 	 * @param repository
 	 *            the {@link org.eclipse.jgit.lib.Repository}.
 	 * @throws java.io.IOException
+	 *             if an IO error occurred
 	 */
 	public SubmoduleWalk(Repository repository) throws IOException {
 		this.repository = repository;
@@ -419,13 +429,14 @@
 	 * The root tree is not read until the first submodule is encountered by the
 	 * walk.
 	 * <p>
-	 * This method need only be called if constructing a walk manually instead of
-	 * with one of the static factory methods above.
+	 * This method need only be called if constructing a walk manually instead
+	 * of with one of the static factory methods above.
 	 *
 	 * @param id
 	 *            ID of a tree containing .gitmodules
 	 * @return this generator
 	 * @throws java.io.IOException
+	 *             if an IO error occurred
 	 */
 	public SubmoduleWalk setRootTree(AnyObjectId id) throws IOException {
 		final CanonicalTreeParser p = new CanonicalTreeParser();
@@ -448,6 +459,7 @@
 	 * @throws java.io.IOException
 	 *             if an error occurred, or if the repository is bare
 	 * @throws org.eclipse.jgit.errors.ConfigInvalidException
+	 *             if .gitmodules config is invalid
 	 */
 	public SubmoduleWalk loadModulesConfig() throws IOException, ConfigInvalidException {
 		if (rootTree == null) {
@@ -512,11 +524,13 @@
 	 *
 	 * @param repository
 	 *            the repository to check
-	 * @return <code>true</code> if the working tree contains a .gitmodules file,
-	 *         <code>false</code> otherwise. Always returns <code>false</code>
-	 *         for bare repositories.
+	 * @return <code>true</code> if the working tree contains a .gitmodules
+	 *         file, <code>false</code> otherwise. Always returns
+	 *         <code>false</code> for bare repositories.
 	 * @throws java.io.IOException
-	 * @throws CorruptObjectException if any.
+	 *             if an IO error occurred
+	 * @throws CorruptObjectException
+	 *             if a corrupt object was found
 	 * @since 3.6
 	 */
 	public static boolean containsGitModulesFile(Repository repository)
@@ -560,6 +574,7 @@
 	 *            object.
 	 * @return this generator
 	 * @throws org.eclipse.jgit.errors.CorruptObjectException
+	 *             if a corrupt object was found
 	 */
 	public SubmoduleWalk setTree(AbstractTreeIterator iterator)
 			throws CorruptObjectException {
@@ -574,10 +589,11 @@
 	 *            an {@link org.eclipse.jgit.lib.AnyObjectId} object.
 	 * @return this generator
 	 * @throws java.io.IOException
+	 *             if an IO error occurred
 	 * @throws IncorrectObjectTypeException
-	 *             if any.
+	 *             if object has unexpected type
 	 * @throws MissingObjectException
-	 *             if any.
+	 *             if object is missing
 	 */
 	public SubmoduleWalk setTree(AnyObjectId treeId) throws IOException {
 		walk.addTree(treeId);
@@ -614,6 +630,7 @@
 	 *
 	 * @return true if entry found, false otherwise
 	 * @throws java.io.IOException
+	 *             if an IO error occurred
 	 */
 	public boolean next() throws IOException {
 		while (walk.next()) {
@@ -656,9 +673,11 @@
 	 * name of .git/config)
 	 *
 	 * @since 4.10
-	 * @return name
+	 * @return name of the submodule
 	 * @throws ConfigInvalidException
+	 *             if the .gitmodules config is invalid
 	 * @throws IOException
+	 *             if an IO error occurred
 	 */
 	public String getModuleName() throws IOException, ConfigInvalidException {
 		lazyLoadModulesConfig();
@@ -680,7 +699,9 @@
 	 *
 	 * @return configured path
 	 * @throws org.eclipse.jgit.errors.ConfigInvalidException
+	 *             if .gitmodules config is invalid
 	 * @throws java.io.IOException
+	 *             if an IO error occurred
 	 */
 	public String getModulesPath() throws IOException, ConfigInvalidException {
 		lazyLoadModulesConfig();
@@ -694,7 +715,9 @@
 	 *
 	 * @return configured URL
 	 * @throws org.eclipse.jgit.errors.ConfigInvalidException
+	 *             if .gitmodules config is invalid
 	 * @throws java.io.IOException
+	 *             if an IO error occurred
 	 */
 	public String getConfigUrl() throws IOException, ConfigInvalidException {
 		return repoConfig.getString(ConfigConstants.CONFIG_SUBMODULE_SECTION,
@@ -707,7 +730,9 @@
 	 *
 	 * @return configured URL
 	 * @throws org.eclipse.jgit.errors.ConfigInvalidException
+	 *             if .gitmodules config is invalid
 	 * @throws java.io.IOException
+	 *             if an IO error occurred
 	 */
 	public String getModulesUrl() throws IOException, ConfigInvalidException {
 		lazyLoadModulesConfig();
@@ -721,7 +746,9 @@
 	 *
 	 * @return update value
 	 * @throws org.eclipse.jgit.errors.ConfigInvalidException
+	 *             if .gitmodules config is invalid
 	 * @throws java.io.IOException
+	 *             if an IO error occurred
 	 */
 	public String getConfigUpdate() throws IOException, ConfigInvalidException {
 		return repoConfig.getString(ConfigConstants.CONFIG_SUBMODULE_SECTION,
@@ -734,7 +761,9 @@
 	 *
 	 * @return update value
 	 * @throws org.eclipse.jgit.errors.ConfigInvalidException
+	 *             if .gitmodules config is invalid
 	 * @throws java.io.IOException
+	 *             if an IO error occurred
 	 */
 	public String getModulesUpdate() throws IOException, ConfigInvalidException {
 		lazyLoadModulesConfig();
@@ -748,7 +777,9 @@
 	 *
 	 * @return ignore value
 	 * @throws org.eclipse.jgit.errors.ConfigInvalidException
+	 *             if .gitmodules config is invalid
 	 * @throws java.io.IOException
+	 *             if an IO error occurred
 	 * @since 3.6
 	 */
 	public IgnoreSubmoduleMode getModulesIgnore() throws IOException,
@@ -771,6 +802,7 @@
 	 *
 	 * @return repository or null if non-existent
 	 * @throws java.io.IOException
+	 *             if an IO error occurred
 	 */
 	public Repository getRepository() throws IOException {
 		return getSubmoduleRepository(repository.getWorkTree(), path,
@@ -782,6 +814,7 @@
 	 *
 	 * @return object id of HEAD reference
 	 * @throws java.io.IOException
+	 *             if an IO error occurred
 	 */
 	public ObjectId getHead() throws IOException {
 		try (Repository subRepo = getRepository()) {
@@ -797,6 +830,7 @@
 	 *
 	 * @return ref name, null on failures
 	 * @throws java.io.IOException
+	 *             if an IO error occurred
 	 */
 	public String getHeadRef() throws IOException {
 		try (Repository subRepo = getRepository()) {
@@ -816,7 +850,9 @@
 	 *
 	 * @return resolved remote URL
 	 * @throws java.io.IOException
+	 *             if an IO error occurred
 	 * @throws org.eclipse.jgit.errors.ConfigInvalidException
+	 *             if .gitmodules config is invalid
 	 */
 	public String getRemoteUrl() throws IOException, ConfigInvalidException {
 		String url = getModulesUrl();
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/transport/AbstractAdvertiseRefsHook.java b/org.eclipse.jgit/src/org/eclipse/jgit/transport/AbstractAdvertiseRefsHook.java
index fb9c145..260a85e 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/transport/AbstractAdvertiseRefsHook.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/transport/AbstractAdvertiseRefsHook.java
@@ -58,7 +58,6 @@
  * @since 2.0
  */
 public abstract class AbstractAdvertiseRefsHook implements AdvertiseRefsHook {
-	/** {@inheritDoc} */
 	@Override
 	public void advertiseRefs(UploadPack uploadPack)
 			throws ServiceMayNotContinueException {
@@ -67,7 +66,6 @@
 	}
 
 	/**
-	 * {@inheritDoc}
 	 */
 	@Override
 	public void advertiseRefs(ReceivePack receivePack)
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/transport/AdvertiseRefsHook.java b/org.eclipse.jgit/src/org/eclipse/jgit/transport/AdvertiseRefsHook.java
index 84c3691..6381f1e 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/transport/AdvertiseRefsHook.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/transport/AdvertiseRefsHook.java
@@ -92,6 +92,7 @@
 	 * @throws org.eclipse.jgit.transport.ServiceMayNotContinueException
 	 *             abort; the message will be sent to the user.
 	 * @throws IOException
+	 *             if an IO error occurred
 	 * @since 5.6
 	 */
 	void advertiseRefs(ReceivePack receivePack)
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/transport/AdvertiseRefsHookChain.java b/org.eclipse.jgit/src/org/eclipse/jgit/transport/AdvertiseRefsHookChain.java
index eb9c673..6db0775 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/transport/AdvertiseRefsHookChain.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/transport/AdvertiseRefsHookChain.java
@@ -50,9 +50,6 @@
 		}
 	}
 
-	/**
-	 * {@inheritDoc}
-	 */
 	@Override
 	public void advertiseRefs(ReceivePack rp)
 			throws IOException {
@@ -60,7 +57,6 @@
 			hooks[i].advertiseRefs(rp);
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public void advertiseRefs(UploadPack rp)
 			throws ServiceMayNotContinueException {
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/transport/BaseConnection.java b/org.eclipse.jgit/src/org/eclipse/jgit/transport/BaseConnection.java
index 9e229a1..3ac9f59 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/transport/BaseConnection.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/transport/BaseConnection.java
@@ -38,25 +38,21 @@
 
 	private Writer messageWriter;
 
-	/** {@inheritDoc} */
 	@Override
 	public Map<String, Ref> getRefsMap() {
 		return advertisedRefs;
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public final Collection<Ref> getRefs() {
 		return advertisedRefs.values();
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public final Ref getRef(String name) {
 		return advertisedRefs.get(name);
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public String getMessages() {
 		return messageWriter != null ? messageWriter.toString() : ""; //$NON-NLS-1$
@@ -84,7 +80,6 @@
 		peerUserAgent = agent;
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public abstract void close();
 
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/transport/BaseFetchConnection.java b/org.eclipse.jgit/src/org/eclipse/jgit/transport/BaseFetchConnection.java
index 6954bd9..48992f3 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/transport/BaseFetchConnection.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/transport/BaseFetchConnection.java
@@ -31,7 +31,6 @@
  */
 abstract class BaseFetchConnection extends BaseConnection implements
 		FetchConnection {
-	/** {@inheritDoc} */
 	@Override
 	public final void fetch(final ProgressMonitor monitor,
 			final Collection<Ref> want, final Set<ObjectId> have)
@@ -39,7 +38,6 @@
 		fetch(monitor, want, have, null);
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public final void fetch(final ProgressMonitor monitor,
 			final Collection<Ref> want, final Set<ObjectId> have,
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/transport/BasePackConnection.java b/org.eclipse.jgit/src/org/eclipse/jgit/transport/BasePackConnection.java
index 09c559d..bac5025 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/transport/BasePackConnection.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/transport/BasePackConnection.java
@@ -64,6 +64,7 @@
  */
 abstract class BasePackConnection extends BaseConnection {
 
+	/** The capability prefix for a symlink */
 	protected static final String CAPABILITY_SYMREF_PREFIX = "symref="; //$NON-NLS-1$
 
 	/** The repository this transport fetches into, or pushes out of. */
@@ -72,7 +73,7 @@
 	/** Remote repository location. */
 	protected final URIish uri;
 
-	/** A transport connected to {@link #uri}. */
+	/** A transport connected to {@link BasePackConnection#uri}. */
 	protected final Transport transport;
 
 	/** Low-level input stream, if a timeout was configured. */
@@ -81,7 +82,10 @@
 	/** Low-level output stream, if a timeout was configured. */
 	protected TimeoutOutputStream timeoutOut;
 
-	/** Timer to manage {@link #timeoutIn} and {@link #timeoutOut}. */
+	/**
+	 * Timer to manage {@link #timeoutIn} and
+	 * {@link BasePackConnection#timeoutOut}.
+	 */
 	private InterruptTimer myTimer;
 
 	/** Input stream reading from the remote. */
@@ -90,13 +94,16 @@
 	/** Output stream sending to the remote. */
 	protected OutputStream out;
 
-	/** Packet line decoder around {@link #in}. */
+	/** Packet line decoder around {@link BasePackConnection#in}. */
 	protected PacketLineIn pckIn;
 
-	/** Packet line encoder around {@link #out}. */
+	/** Packet line encoder around {@link BasePackConnection#out}. */
 	protected PacketLineOut pckOut;
 
-	/** Send {@link PacketLineOut#end()} before closing {@link #out}? */
+	/**
+	 * Send {@link PacketLineOut#end()} before closing
+	 * {@link BasePackConnection#out}?
+	 */
 	protected boolean outNeedsEnd;
 
 	/** True if this is a stateless RPC connection. */
@@ -486,7 +493,6 @@
 	 * <p>
 	 * If refMap already contains an entry for symRef.key, it is replaced.
 	 * </p>
-	 * </p>
 	 * <p>
 	 * For example, given:
 	 * </p>
@@ -627,7 +633,6 @@
 		}
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public String getPeerUserAgent() {
 		String agent = remoteCapabilities.get(OPTION_AGENT);
@@ -642,7 +647,6 @@
 		return new PackProtocolException(uri, MessageFormat.format(JGitText.get().invalidRefAdvertisementLine, line));
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public void close() {
 		if (out != null) {
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/transport/BasePackFetchConnection.java b/org.eclipse.jgit/src/org/eclipse/jgit/transport/BasePackFetchConnection.java
index 8909380..cdda3c0 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/transport/BasePackFetchConnection.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/transport/BasePackFetchConnection.java
@@ -334,7 +334,6 @@
 		}
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public final void fetch(final ProgressMonitor monitor,
 			final Collection<Ref> want, final Set<ObjectId> have)
@@ -342,7 +341,6 @@
 		fetch(monitor, want, have, null);
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public final void fetch(final ProgressMonitor monitor,
 			final Collection<Ref> want, final Set<ObjectId> have,
@@ -351,25 +349,21 @@
 		doFetch(monitor, want, have, outputStream);
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public boolean didFetchIncludeTags() {
 		return false;
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public boolean didFetchTestConnectivity() {
 		return false;
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public void setPackLockMessage(String message) {
 		lockMessage = message;
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public Collection<PackLock> getPackLocks() {
 		if (packLock != null)
@@ -659,7 +653,6 @@
 		return gotReady;
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public void close() {
 		if (walk != null)
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/transport/BasePackPushConnection.java b/org.eclipse.jgit/src/org/eclipse/jgit/transport/BasePackPushConnection.java
index adc1c98..9a96fdc 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/transport/BasePackPushConnection.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/transport/BasePackPushConnection.java
@@ -122,7 +122,6 @@
 		useBitmaps = transport.isPushUseBitmaps();
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public void push(final ProgressMonitor monitor,
 			final Map<String, RemoteRefUpdate> refUpdates)
@@ -130,7 +129,6 @@
 		push(monitor, refUpdates, null);
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public void push(final ProgressMonitor monitor,
 			final Map<String, RemoteRefUpdate> refUpdates, OutputStream outputStream)
@@ -139,7 +137,6 @@
 		doPush(monitor, refUpdates, outputStream);
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	protected TransportException noRepository(Throwable cause) {
 		// Sadly we cannot tell the "invalid URI" case from "push not allowed".
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/transport/BundleFetchConnection.java b/org.eclipse.jgit/src/org/eclipse/jgit/transport/BundleFetchConnection.java
index f04e573..5299dfa 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/transport/BundleFetchConnection.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/transport/BundleFetchConnection.java
@@ -147,13 +147,11 @@
 		return line.toString();
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public boolean didFetchTestConnectivity() {
 		return false;
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	protected void doFetch(final ProgressMonitor monitor,
 			final Collection<Ref> want, final Set<ObjectId> have)
@@ -174,13 +172,11 @@
 		}
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public void setPackLockMessage(String message) {
 		lockMessage = message;
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public Collection<PackLock> getPackLocks() {
 		if (packLock != null)
@@ -258,7 +254,6 @@
 		}
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public void close() {
 		if (bin != null) {
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/transport/ChainingCredentialsProvider.java b/org.eclipse.jgit/src/org/eclipse/jgit/transport/ChainingCredentialsProvider.java
index 6a4cfca..3bae0ea 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/transport/ChainingCredentialsProvider.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/transport/ChainingCredentialsProvider.java
@@ -39,7 +39,6 @@
 				Arrays.asList(providers));
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public boolean isInteractive() {
 		for (CredentialsProvider p : credentialProviders)
@@ -48,7 +47,6 @@
 		return false;
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public boolean supports(CredentialItem... items) {
 		for (CredentialsProvider p : credentialProviders)
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/transport/CredentialItem.java b/org.eclipse.jgit/src/org/eclipse/jgit/transport/CredentialItem.java
index 2b09424..78c5c63 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/transport/CredentialItem.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/transport/CredentialItem.java
@@ -115,8 +115,8 @@
 		}
 
 		/**
-		 *
 		 * @param newValue
+		 *            the new value
 		 */
 		public void setValue(String newValue) {
 			value = newValue;
@@ -223,6 +223,7 @@
 		 * Set the new value.
 		 *
 		 * @param newValue
+		 *            the new value
 		 */
 		public void setValue(boolean newValue) {
 			value = newValue;
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/transport/FilterSpec.java b/org.eclipse.jgit/src/org/eclipse/jgit/transport/FilterSpec.java
index a8cf849..12a7dd3 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/transport/FilterSpec.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/transport/FilterSpec.java
@@ -55,7 +55,6 @@
 			return val.testBit(type);
 		}
 
-		/** {@inheritDoc} */
 		@Override
 		public boolean equals(Object obj) {
 			if (!(obj instanceof ObjectTypes)) {
@@ -66,7 +65,6 @@
 			return other.val.equals(val);
 		}
 
-		/** {@inheritDoc} */
 		@Override
 		public int hashCode() {
 			return val.hashCode();
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/transport/FtpChannel.java b/org.eclipse.jgit/src/org/eclipse/jgit/transport/FtpChannel.java
index 44656c1..6d5b5e6 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/transport/FtpChannel.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/transport/FtpChannel.java
@@ -71,6 +71,7 @@
 	 * @param unit
 	 *            of the {@code timeout}
 	 * @throws IOException
+	 *             if an IO error occurred
 	 */
 	void connect(int timeout, TimeUnit unit) throws IOException;
 
@@ -97,6 +98,7 @@
 	/**
 	 * @return the current remote directory path
 	 * @throws IOException
+	 *             if an IO error occurred
 	 */
 	String pwd() throws IOException;
 
@@ -118,6 +120,7 @@
 	 *            of the directory to list
 	 * @return the directory entries
 	 * @throws IOException
+	 *             if an IO error occurred
 	 */
 	Collection<DirEntry> ls(String path) throws IOException;
 
@@ -128,6 +131,7 @@
 	 * @param path
 	 *            to delete
 	 * @throws IOException
+	 *             if an IO error occurred
 	 */
 	void rmdir(String path) throws IOException;
 
@@ -137,6 +141,7 @@
 	 * @param path
 	 *            to create
 	 * @throws IOException
+	 *             if an IO error occurred
 	 */
 	void mkdir(String path) throws IOException;
 
@@ -148,6 +153,7 @@
 	 *
 	 * @return the stream to read from
 	 * @throws IOException
+	 *             if an IO error occurred
 	 */
 	InputStream get(String path) throws IOException;
 
@@ -160,6 +166,7 @@
 	 *
 	 * @return the stream to read from
 	 * @throws IOException
+	 *             if an IO error occurred
 	 */
 	OutputStream put(String path) throws IOException;
 
@@ -204,6 +211,7 @@
 	 * @param to
 	 *            new name of the file
 	 * @throws IOException
+	 *             if an IO error occurred
 	 * @see <a href=
 	 *      "http://pubs.opengroup.org/onlinepubs/9699919799/functions/rename.html">stdio.h:
 	 *      rename()</a>
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/transport/HMACSHA1NonceGenerator.java b/org.eclipse.jgit/src/org/eclipse/jgit/transport/HMACSHA1NonceGenerator.java
index 14d6c1e..655b460 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/transport/HMACSHA1NonceGenerator.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/transport/HMACSHA1NonceGenerator.java
@@ -35,9 +35,8 @@
 	 *
 	 * @param seed
 	 *            seed the generator
-	 * @throws java.lang.IllegalStateException
 	 */
-	public HMACSHA1NonceGenerator(String seed) throws IllegalStateException {
+	public HMACSHA1NonceGenerator(String seed) {
 		try {
 			byte[] keyBytes = seed.getBytes(ISO_8859_1);
 			SecretKeySpec signingKey = new SecretKeySpec(keyBytes, "HmacSHA1"); //$NON-NLS-1$
@@ -48,16 +47,13 @@
 		}
 	}
 
-	/** {@inheritDoc} */
 	@Override
-	public synchronized String createNonce(Repository repo, long timestamp)
-			throws IllegalStateException {
+	public synchronized String createNonce(Repository repo, long timestamp) {
 		String input = repo.getIdentifier() + ":" + String.valueOf(timestamp); //$NON-NLS-1$
 		byte[] rawHmac = mac.doFinal(input.getBytes(UTF_8));
 		return Long.toString(timestamp) + "-" + toHex(rawHmac); //$NON-NLS-1$
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public NonceStatus verify(String received, String sent,
 			Repository db, boolean allowSlop, int slop) {
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/transport/HttpAuthMethod.java b/org.eclipse.jgit/src/org/eclipse/jgit/transport/HttpAuthMethod.java
index aec5b89..3db0421 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/transport/HttpAuthMethod.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/transport/HttpAuthMethod.java
@@ -224,7 +224,9 @@
 	 * Update this method with the given username and password pair.
 	 *
 	 * @param user
+	 *            username
 	 * @param pass
+	 *            password
 	 */
 	abstract void authorize(String user, String pass);
 
@@ -232,7 +234,9 @@
 	 * Update connection properties based on this authentication method.
 	 *
 	 * @param conn
+	 *            the connection to configure
 	 * @throws IOException
+	 *             if an IO error occurred
 	 */
 	abstract void configureRequest(HttpConnection conn) throws IOException;
 
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/transport/InternalFetchConnection.java b/org.eclipse.jgit/src/org/eclipse/jgit/transport/InternalFetchConnection.java
index 18dc792..9a699a8 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/transport/InternalFetchConnection.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/transport/InternalFetchConnection.java
@@ -103,7 +103,6 @@
 		readAdvertisedRefs();
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public void close() {
 		super.close();
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/transport/InternalPushConnection.java b/org.eclipse.jgit/src/org/eclipse/jgit/transport/InternalPushConnection.java
index d2b0ef4..a23fdc9 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/transport/InternalPushConnection.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/transport/InternalPushConnection.java
@@ -99,7 +99,6 @@
 		readAdvertisedRefs();
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public void close() {
 		super.close();
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/transport/LsRefsV2Request.java b/org.eclipse.jgit/src/org/eclipse/jgit/transport/LsRefsV2Request.java
index 856047e..b2799e1 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/transport/LsRefsV2Request.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/transport/LsRefsV2Request.java
@@ -130,6 +130,7 @@
 
 		/**
 		 * @param value
+		 *            ref prefix values
 		 * @return the Builder
 		 */
 		public Builder setRefPrefixes(List<String> value) {
@@ -139,6 +140,7 @@
 
 		/**
 		 * @param value
+		 *            of symrefs
 		 * @return the Builder
 		 */
 		public Builder setSymrefs(boolean value) {
@@ -148,6 +150,7 @@
 
 		/**
 		 * @param value
+		 *            of peel
 		 * @return the Builder
 		 */
 		public Builder setPeel(boolean value) {
@@ -203,7 +206,11 @@
 			return this;
 		}
 
-		/** @return LsRefsV2Request */
+		/**
+		 * Builds the request
+		 *
+		 * @return LsRefsV2Request the request
+		 */
 		public LsRefsV2Request build() {
 			return new LsRefsV2Request(
 					Collections.unmodifiableList(refPrefixes), symrefs, peel,
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/transport/NetRCCredentialsProvider.java b/org.eclipse.jgit/src/org/eclipse/jgit/transport/NetRCCredentialsProvider.java
index 6531b17..e32530c 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/transport/NetRCCredentialsProvider.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/transport/NetRCCredentialsProvider.java
@@ -67,7 +67,6 @@
 		CredentialsProvider.setDefault(new NetRCCredentialsProvider());
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public boolean supports(CredentialItem... items) {
 		for (CredentialItem i : items) {
@@ -81,7 +80,6 @@
 		return true;
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public boolean get(URIish uri, CredentialItem... items)
 			throws UnsupportedCredentialItem {
@@ -112,7 +110,6 @@
 		return !isAnyNull(items);
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public boolean isInteractive() {
 		return false;
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/transport/NonceGenerator.java b/org.eclipse.jgit/src/org/eclipse/jgit/transport/NonceGenerator.java
index 2541ff1..30e80e0 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/transport/NonceGenerator.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/transport/NonceGenerator.java
@@ -31,10 +31,8 @@
 	 * @param timestamp
 	 *            The current time in seconds.
 	 * @return The nonce to be signed by the pusher
-	 * @throws java.lang.IllegalStateException
 	 */
-	String createNonce(Repository db, long timestamp)
-			throws IllegalStateException;
+	String createNonce(Repository db, long timestamp);
 
 	/**
 	 * Verify trustworthiness of the received nonce.
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/transport/ObjectInfoRequest.java b/org.eclipse.jgit/src/org/eclipse/jgit/transport/ObjectInfoRequest.java
index 86a2716..2a52d7f 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/transport/ObjectInfoRequest.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/transport/ObjectInfoRequest.java
@@ -53,6 +53,7 @@
 
 		/**
 		 * @param value
+		 *            of objectIds
 		 * @return the Builder
 		 */
 		public Builder setObjectIDs(List<ObjectId> value) {
@@ -60,7 +61,11 @@
 			return this;
 		}
 
-		/** @return ObjectInfoRequest */
+		/**
+		 * Build the request
+		 *
+		 * @return ObjectInfoRequest the request
+		 */
 		public ObjectInfoRequest build() {
 			return new ObjectInfoRequest(
 					Collections.unmodifiableList(objectIDs));
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/transport/PackParser.java b/org.eclipse.jgit/src/org/eclipse/jgit/transport/PackParser.java
index d966904..fe9ddab 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/transport/PackParser.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/transport/PackParser.java
@@ -1102,6 +1102,7 @@
 	 * @param data
 	 *            raw content of the object.
 	 * @throws org.eclipse.jgit.errors.CorruptObjectException
+	 *             if a corrupt object was found
 	 * @since 4.9
 	 */
 	protected void verifySafeObject(final AnyObjectId id, final int type,
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/transport/PackedObjectInfo.java b/org.eclipse.jgit/src/org/eclipse/jgit/transport/PackedObjectInfo.java
index bf7997e..d7ef4f8 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/transport/PackedObjectInfo.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/transport/PackedObjectInfo.java
@@ -117,6 +117,7 @@
 	 * Size in storage
 	 *
 	 * @param sizeBeforeInflating
+	 *            size before inflating
 	 */
 	void setSize(long sizeBeforeInflating) {
 		this.sizeBeforeInflating = sizeBeforeInflating;
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/transport/PostReceiveHookChain.java b/org.eclipse.jgit/src/org/eclipse/jgit/transport/PostReceiveHookChain.java
index 4d53e1b..f9d2c38 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/transport/PostReceiveHookChain.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/transport/PostReceiveHookChain.java
@@ -47,7 +47,6 @@
 		}
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public void onPostReceive(ReceivePack rp,
 			Collection<ReceiveCommand> commands) {
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/transport/PostUploadHookChain.java b/org.eclipse.jgit/src/org/eclipse/jgit/transport/PostUploadHookChain.java
index 4334888..072f43f 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/transport/PostUploadHookChain.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/transport/PostUploadHookChain.java
@@ -80,7 +80,6 @@
 		}
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public void onPostUpload(PackStatistics stats) {
 		for (PostUploadHook hook : hooks) {
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/transport/PreReceiveHookChain.java b/org.eclipse.jgit/src/org/eclipse/jgit/transport/PreReceiveHookChain.java
index dffa30d..2a5522b 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/transport/PreReceiveHookChain.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/transport/PreReceiveHookChain.java
@@ -46,7 +46,6 @@
 		}
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public void onPreReceive(ReceivePack rp,
 			Collection<ReceiveCommand> commands) {
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/transport/PreUploadHookChain.java b/org.eclipse.jgit/src/org/eclipse/jgit/transport/PreUploadHookChain.java
index 9c28abe..dc703d0 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/transport/PreUploadHookChain.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/transport/PreUploadHookChain.java
@@ -48,7 +48,6 @@
 		}
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public void onBeginNegotiateRound(UploadPack up,
 			Collection<? extends ObjectId> wants, int cntOffered)
@@ -58,7 +57,6 @@
 		}
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public void onEndNegotiateRound(UploadPack up,
 			Collection<? extends ObjectId> wants, int cntCommon,
@@ -69,7 +67,6 @@
 		}
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public void onSendPack(UploadPack up,
 			Collection<? extends ObjectId> wants,
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/transport/ProtocolV0Parser.java b/org.eclipse.jgit/src/org/eclipse/jgit/transport/ProtocolV0Parser.java
index 9d05551..f1afeab 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/transport/ProtocolV0Parser.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/transport/ProtocolV0Parser.java
@@ -51,7 +51,9 @@
 	 *            incoming lines. This method will read until an END line.
 	 * @return a FetchV0Request with the data received in the wire.
 	 * @throws PackProtocolException
+	 *             if a protocol occurred
 	 * @throws IOException
+	 *             if an IO error occurred
 	 */
 	FetchV0Request recvWants(PacketLineIn pckIn)
 			throws PackProtocolException, IOException {
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/transport/PushCertificate.java b/org.eclipse.jgit/src/org/eclipse/jgit/transport/PushCertificate.java
index d9831c7..437abb0 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/transport/PushCertificate.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/transport/PushCertificate.java
@@ -222,13 +222,11 @@
 		return sb;
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public int hashCode() {
 		return signature.hashCode();
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public boolean equals(Object o) {
 		if (!(o instanceof PushCertificate)) {
@@ -259,7 +257,6 @@
 		return true;
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public String toString() {
 		return getClass().getSimpleName() + '['
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/transport/PushCertificateIdent.java b/org.eclipse.jgit/src/org/eclipse/jgit/transport/PushCertificateIdent.java
index 94d1169..bd76b34 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/transport/PushCertificateIdent.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/transport/PushCertificateIdent.java
@@ -228,20 +228,17 @@
 		return tzOffset;
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public boolean equals(Object o) {
 		return (o instanceof PushCertificateIdent)
 			&& raw.equals(((PushCertificateIdent) o).raw);
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public int hashCode() {
 		return raw.hashCode();
 	}
 
-	/** {@inheritDoc} */
 	@SuppressWarnings("nls")
 	@Override
 	public String toString() {
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/transport/PushConnection.java b/org.eclipse.jgit/src/org/eclipse/jgit/transport/PushConnection.java
index 51c8558..32c443f 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/transport/PushConnection.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/transport/PushConnection.java
@@ -43,17 +43,14 @@
 	 * and sending objects that remote repository need to have a consistent
 	 * objects graph from new refs.
 	 * <p>
-	 * <p>
 	 * Only one call per connection is allowed. Subsequent calls will result in
 	 * {@link org.eclipse.jgit.errors.TransportException}.
-	 * </p>
 	 * <p>
 	 * Implementation may use local repository to send a minimum set of objects
 	 * needed by remote repository in efficient way.
 	 * {@link org.eclipse.jgit.transport.Transport#isPushThin()} should be
 	 * honored if applicable. refUpdates should be filled with information about
 	 * status of each update.
-	 * </p>
 	 *
 	 * @param monitor
 	 *            progress monitor to update the end-user about the amount of
@@ -90,17 +87,14 @@
 	 * and sending objects that remote repository need to have a consistent
 	 * objects graph from new refs.
 	 * <p>
-	 * <p>
 	 * Only one call per connection is allowed. Subsequent calls will result in
 	 * {@link org.eclipse.jgit.errors.TransportException}.
-	 * </p>
 	 * <p>
 	 * Implementation may use local repository to send a minimum set of objects
 	 * needed by remote repository in efficient way.
 	 * {@link org.eclipse.jgit.transport.Transport#isPushThin()} should be
 	 * honored if applicable. refUpdates should be filled with information about
 	 * status of each update.
-	 * </p>
 	 *
 	 * @param monitor
 	 *            progress monitor to update the end-user about the amount of
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/transport/PushProcess.java b/org.eclipse.jgit/src/org/eclipse/jgit/transport/PushProcess.java
index b59ae0c..8f90f32 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/transport/PushProcess.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/transport/PushProcess.java
@@ -76,6 +76,7 @@
 	 *            {@link PrePushHook} to run after the remote advertisement has
 	 *            been gotten
 	 * @throws TransportException
+	 *             if a protocol error occurred during push/fetch
 	 */
 	PushProcess(Transport transport, Collection<RemoteRefUpdate> toPush,
 			PrePushHook prePush) throws TransportException {
@@ -96,6 +97,7 @@
 	 * @param out
 	 *            OutputStream to write messages to
 	 * @throws TransportException
+	 *             if a protocol error occurred during push/fetch
 	 */
 	PushProcess(Transport transport, Collection<RemoteRefUpdate> toPush,
 			PrePushHook prePush, OutputStream out) throws TransportException {
@@ -272,6 +274,7 @@
 	 *            {@link ObjectId} of the new commit
 	 * @return {@code true} if the update fast-forwards, {@code false} otherwise
 	 * @throws TransportException
+	 *             if a protocol error occurred during push/fetch
 	 */
 	private boolean isFastForward(ObjectId oldOid, ObjectId newOid)
 			throws TransportException {
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/transport/ReceiveCommand.java b/org.eclipse.jgit/src/org/eclipse/jgit/transport/ReceiveCommand.java
index ab41160..bfc75f0 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/transport/ReceiveCommand.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/transport/ReceiveCommand.java
@@ -849,7 +849,6 @@
 				JGitText.get().lockError, err.getMessage()));
 	}
 
-	/** {@inheritDoc} */
 	@SuppressWarnings("nls")
 	@Override
 	public String toString() {
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/transport/ReceivePack.java b/org.eclipse.jgit/src/org/eclipse/jgit/transport/ReceivePack.java
index 816cec8..9a61774 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/transport/ReceivePack.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/transport/ReceivePack.java
@@ -460,6 +460,7 @@
 	 *            null, assumes the default set of additional haves from the
 	 *            repository.
 	 * @throws IOException
+	 *             if an IO error occurred
 	 */
 	public void setAdvertisedRefs(Map<String, Ref> allRefs,
 			Set<ObjectId> additionalHaves) throws IOException {
@@ -1024,6 +1025,7 @@
 	 * Set an error handler for {@link ReceiveCommand}.
 	 *
 	 * @param receiveCommandErrorHandler
+	 *            the error handler
 	 * @since 5.7
 	 */
 	public void setReceiveCommandErrorHandler(
@@ -1212,6 +1214,7 @@
 	 *
 	 * @return advertised refs, or the default if not explicitly advertised.
 	 * @throws IOException
+	 *             if an IO error occurred
 	 */
 	private Map<String, Ref> getAdvertisedOrDefaultRefs() throws IOException {
 		if (refs == null)
@@ -1348,7 +1351,8 @@
 	/**
 	 * Receive a list of commands from the input.
 	 *
-	 * @throws java.io.IOException
+	 * @throws IOException
+	 *             if an IO error occurred
 	 */
 	private void recvCommands() throws IOException {
 		PacketLineIn pck = maxCommandBytes > 0
@@ -1936,7 +1940,8 @@
 	/**
 	 * Close and flush (if necessary) the underlying streams.
 	 *
-	 * @throws java.io.IOException
+	 * @throws IOException
+	 *             if an IO error occurred
 	 */
 	private void close() throws IOException {
 		if (sideBand) {
@@ -2174,6 +2179,7 @@
 	 *            standard error channel of the command execution. For most
 	 *            other network connections this should be null.
 	 * @throws java.io.IOException
+	 *             if an IO error occurred
 	 */
 	public void receive(final InputStream input, final OutputStream output,
 			final OutputStream messages) throws IOException {
@@ -2217,6 +2223,7 @@
 	 *            standard error channel of the command execution. For most
 	 *            other network connections this should be null.
 	 * @throws java.io.IOException
+	 *             if an IO error occurred
 	 * @since 5.7
 	 */
 	public void receiveWithExceptionPropagation(InputStream input,
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/transport/RefAdvertiser.java b/org.eclipse.jgit/src/org/eclipse/jgit/transport/RefAdvertiser.java
index c525e66..6b022ea 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/transport/RefAdvertiser.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/transport/RefAdvertiser.java
@@ -173,7 +173,7 @@
 	/**
 	 * Toggle tag peeling.
 	 * <p>
-	 * <p>
+	 *
 	 * This method must be invoked prior to any of the following:
 	 * <ul>
 	 * <li>{@link #send(Map)}</li>
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/transport/RefLeaseSpec.java b/org.eclipse.jgit/src/org/eclipse/jgit/transport/RefLeaseSpec.java
index 1af3fad..8a131c8 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/transport/RefLeaseSpec.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/transport/RefLeaseSpec.java
@@ -58,7 +58,6 @@
 		return expected;
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public String toString() {
 		final StringBuilder r = new StringBuilder();
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/transport/RefSpec.java b/org.eclipse.jgit/src/org/eclipse/jgit/transport/RefSpec.java
index 61d1935..0466085 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/transport/RefSpec.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/transport/RefSpec.java
@@ -616,7 +616,6 @@
 		return true;
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public int hashCode() {
 		int hc = 0;
@@ -627,7 +626,6 @@
 		return hc;
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public boolean equals(Object obj) {
 		if (!(obj instanceof RefSpec))
@@ -649,7 +647,6 @@
 				&& Objects.equals(getDestination(), b.getDestination());
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public String toString() {
 		final StringBuilder r = new StringBuilder();
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/transport/RemoteRefUpdate.java b/org.eclipse.jgit/src/org/eclipse/jgit/transport/RemoteRefUpdate.java
index 218e62c..fb3cd21 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/transport/RemoteRefUpdate.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/transport/RemoteRefUpdate.java
@@ -541,7 +541,6 @@
 			trackingRefUpdate.setResult(localUpdate.update(walk));
 	}
 
-	/** {@inheritDoc} */
 	@SuppressWarnings("nls")
 	@Override
 	public String toString() {
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/transport/SideBandInputStream.java b/org.eclipse.jgit/src/org/eclipse/jgit/transport/SideBandInputStream.java
index 96c7be5..1f96be8 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/transport/SideBandInputStream.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/transport/SideBandInputStream.java
@@ -94,7 +94,6 @@
 		out = outputStream;
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public int read() throws IOException {
 		needDataPacket();
@@ -104,7 +103,6 @@
 		return rawIn.read();
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public int read(byte[] b, int off, int len) throws IOException {
 		int r = 0;
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/transport/SideBandOutputStream.java b/org.eclipse.jgit/src/org/eclipse/jgit/transport/SideBandOutputStream.java
index bb80299..b6d840d 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/transport/SideBandOutputStream.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/transport/SideBandOutputStream.java
@@ -94,14 +94,12 @@
 			writeBuffer();
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public void flush() throws IOException {
 		flushBuffer();
 		out.flush();
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public void write(byte[] b, int off, int len) throws IOException {
 		while (0 < len) {
@@ -128,7 +126,6 @@
 		}
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public void write(int b) throws IOException {
 		if (cnt == buffer.length)
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/transport/SideBandProgressMonitor.java b/org.eclipse.jgit/src/org/eclipse/jgit/transport/SideBandProgressMonitor.java
index 3330860..1e85d81 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/transport/SideBandProgressMonitor.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/transport/SideBandProgressMonitor.java
@@ -28,7 +28,6 @@
 		write = true;
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	protected void onUpdate(String taskName, int workCurr, Duration duration) {
 		StringBuilder s = new StringBuilder();
@@ -37,7 +36,6 @@
 		send(s);
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	protected void onEndTask(String taskName, int workCurr, Duration duration) {
 		StringBuilder s = new StringBuilder();
@@ -54,7 +52,6 @@
 		appendDuration(s, duration);
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	protected void onUpdate(String taskName, int cmp, int totalWork, int pcnt,
 			Duration duration) {
@@ -64,7 +61,6 @@
 		send(s);
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	protected void onEndTask(String taskName, int cmp, int totalWork, int pcnt,
 			Duration duration) {
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/transport/SshConfigStore.java b/org.eclipse.jgit/src/org/eclipse/jgit/transport/SshConfigStore.java
index 1226a6b..b2e2549 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/transport/SshConfigStore.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/transport/SshConfigStore.java
@@ -43,6 +43,7 @@
 	 * {@link SshConstants#CONNECTION_ATTEMPTS}, fill those values with defaults
 	 * from the arguments:
 	 * <table>
+	 * <caption>Description of arguments</caption>
 	 * <tr>
 	 * <th>ssh config key</th>
 	 * <th>value from argument</th>
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/transport/SshConstants.java b/org.eclipse.jgit/src/org/eclipse/jgit/transport/SshConstants.java
index 48cacf0..41dbdca 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/transport/SshConstants.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/transport/SshConstants.java
@@ -125,6 +125,25 @@
 	/** Key in an ssh config file. */
 	public static final String NUMBER_OF_PASSWORD_PROMPTS = "NumberOfPasswordPrompts";
 
+	/**
+	 * Path to a shared library of a PKCS11 key provider, or "none".
+	 * <p>
+	 * If set and not "none", the provider's keys should be used.
+	 * </p>
+	 *
+	 * @since 6.7
+	 */
+	public static final String PKCS11_PROVIDER = "PKCS11Provider";
+
+	/**
+	 * Non-standard JGit addition: specify the PKCS#11 slot list index of the
+	 * token to use. A positive number; defaults to zero; ignored if negative
+	 * (in which case zero is used, too).
+	 *
+	 * @since 6.7
+	 */
+	public static final String PKCS11_SLOT_LIST_INDEX = "PKCS11SlotListIndex";
+
 	/** Key in an ssh config file. */
 	public static final String PORT = "Port";
 
@@ -146,8 +165,8 @@
 	 * Comma-separated list of jump hosts, defining a jump host chain <em>in
 	 * reverse order</em>. Each jump host is a SSH URI or "[user@]host[:port]".
 	 * <p>
-	 * Reverse order means: to connect A->B->target, one can do in
-	 * {@code ~/.ssh/config} either of:
+	 * Reverse order means: to connect {@literal A -> B -> target}, one can do
+	 * in {@code ~/.ssh/config} either of:
 	 * </p>
 	 *
 	 * <pre>
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/transport/SshTransport.java b/org.eclipse.jgit/src/org/eclipse/jgit/transport/SshTransport.java
index 28ec92c..8d93977 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/transport/SshTransport.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/transport/SshTransport.java
@@ -108,7 +108,6 @@
 		return sock;
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public void close() {
 		if (sock != null) {
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/transport/TestProtocol.java b/org.eclipse.jgit/src/org/eclipse/jgit/transport/TestProtocol.java
index 1985b66..77ab0f6 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/transport/TestProtocol.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/transport/TestProtocol.java
@@ -81,19 +81,16 @@
 		this.handles = new HashMap<>();
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public String getName() {
 		return JGitText.get().transportProtoTest;
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public Set<String> getSchemes() {
 		return Collections.singleton(SCHEME);
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public Transport open(URIish uri, Repository local, String remoteName)
 			throws NotSupportedException, TransportException {
@@ -105,13 +102,11 @@
 		return new TransportInternal(local, uri, h);
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public Set<URIishField> getRequiredFields() {
 		return EnumSet.of(URIishField.HOST, URIishField.PATH);
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public Set<URIishField> getOptionalFields() {
 		return Collections.emptySet();
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/transport/TrackingRefUpdate.java b/org.eclipse.jgit/src/org/eclipse/jgit/transport/TrackingRefUpdate.java
index 51bc07c..26045a2 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/transport/TrackingRefUpdate.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/transport/TrackingRefUpdate.java
@@ -174,7 +174,6 @@
 		}
 	}
 
-	/** {@inheritDoc} */
 	@SuppressWarnings("nls")
 	@Override
 	public String toString() {
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/transport/Transport.java b/org.eclipse.jgit/src/org/eclipse/jgit/transport/Transport.java
index ee35f48..4d2f4a9 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/transport/Transport.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/transport/Transport.java
@@ -533,10 +533,13 @@
 	 * Note that the resulting transport instance can not be used for fetching
 	 * or pushing, but only for reading remote refs.
 	 *
-	 * @param uri a {@link org.eclipse.jgit.transport.URIish} object.
+	 * @param uri
+	 *            a {@link org.eclipse.jgit.transport.URIish} object.
 	 * @return new Transport instance
 	 * @throws org.eclipse.jgit.errors.NotSupportedException
+	 *             case that is not supported by JGit
 	 * @throws org.eclipse.jgit.errors.TransportException
+	 *             if transport failed
 	 */
 	public static Transport open(URIish uri) throws NotSupportedException, TransportException {
 		for (WeakReference<TransportProtocol> ref : protocols) {
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/transport/TransportAmazonS3.java b/org.eclipse.jgit/src/org/eclipse/jgit/transport/TransportAmazonS3.java
index 784f566..58232a7 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/transport/TransportAmazonS3.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/transport/TransportAmazonS3.java
@@ -170,7 +170,6 @@
 		}
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public FetchConnection openFetch() throws TransportException {
 		final DatabaseS3 c = new DatabaseS3(bucket, keyPrefix + "/objects"); //$NON-NLS-1$
@@ -179,7 +178,6 @@
 		return r;
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public PushConnection openPush() throws TransportException {
 		final DatabaseS3 c = new DatabaseS3(bucket, keyPrefix + "/objects"); //$NON-NLS-1$
@@ -188,7 +186,6 @@
 		return r;
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public void close() {
 		// No explicit connections are maintained.
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/transport/TransportBundleFile.java b/org.eclipse.jgit/src/org/eclipse/jgit/transport/TransportBundleFile.java
index 04ebddb..0f84f7e 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/transport/TransportBundleFile.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/transport/TransportBundleFile.java
@@ -105,7 +105,6 @@
 		bundle = bundlePath;
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public FetchConnection openFetch() throws NotSupportedException,
 			TransportException {
@@ -121,14 +120,12 @@
 		return new BundleFetchConnection(this, src);
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public PushConnection openPush() throws NotSupportedException {
 		throw new NotSupportedException(
 				JGitText.get().pushIsNotSupportedForBundleTransport);
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public void close() {
 		// Resources must be established per-connection.
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/transport/TransportBundleStream.java b/org.eclipse.jgit/src/org/eclipse/jgit/transport/TransportBundleStream.java
index eac9208..0366bf3 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/transport/TransportBundleStream.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/transport/TransportBundleStream.java
@@ -57,7 +57,6 @@
 		src = in;
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public FetchConnection openFetch() throws TransportException {
 		if (src == null)
@@ -69,14 +68,12 @@
 		}
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public PushConnection openPush() throws NotSupportedException {
 		throw new NotSupportedException(
 				JGitText.get().pushIsNotSupportedForBundleTransport);
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public void close() {
 		if (src != null) {
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/transport/TransportGitAnon.java b/org.eclipse.jgit/src/org/eclipse/jgit/transport/TransportGitAnon.java
index a1914b6..43b3f6c 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/transport/TransportGitAnon.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/transport/TransportGitAnon.java
@@ -89,7 +89,6 @@
 		super(uri);
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public FetchConnection openFetch() throws TransportException {
 		return new TcpFetchConnection();
@@ -102,13 +101,11 @@
 		return new TcpFetchConnection(refSpecs, additionalPatterns);
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public PushConnection openPush() throws TransportException {
 		return new TcpPushConnection();
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public void close() {
 		// Resources must be established per-connection.
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/transport/TransportGitSsh.java b/org.eclipse.jgit/src/org/eclipse/jgit/transport/TransportGitSsh.java
index 19ed4fb..a2273b2 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/transport/TransportGitSsh.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/transport/TransportGitSsh.java
@@ -140,7 +140,6 @@
 		}
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public FetchConnection openFetch() throws TransportException {
 		return new SshFetchConnection();
@@ -153,7 +152,6 @@
 		return new SshFetchConnection(refSpecs, additionalPatterns);
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public PushConnection openPush() throws TransportException {
 		return new SshPushConnection();
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/transport/TransportHttp.java b/org.eclipse.jgit/src/org/eclipse/jgit/transport/TransportHttp.java
index df034bd..c08b7fa 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/transport/TransportHttp.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/transport/TransportHttp.java
@@ -311,6 +311,7 @@
 	 * @param uri
 	 *            a {@link org.eclipse.jgit.transport.URIish} object.
 	 * @throws org.eclipse.jgit.errors.NotSupportedException
+	 *             if URI is not supported by JGit
 	 * @since 4.9
 	 */
 	protected void setURI(URIish uri) throws NotSupportedException {
@@ -327,7 +328,9 @@
 	 * Create a minimal HTTP transport with default configuration values.
 	 *
 	 * @param uri
+	 *            URI to create a HTTP transport for
 	 * @throws NotSupportedException
+	 *             if URI is not supported by JGit
 	 */
 	TransportHttp(URIish uri) throws NotSupportedException {
 		super(uri);
@@ -445,7 +448,6 @@
 		}
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public FetchConnection openFetch() throws TransportException,
 			NotSupportedException {
@@ -532,7 +534,6 @@
 		return new BufferedReader(new InputStreamReader(in, UTF_8));
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public PushConnection openPush() throws NotSupportedException,
 			TransportException {
@@ -567,7 +568,6 @@
 		return p;
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public void close() {
 		if (gitSession != null) {
@@ -822,7 +822,7 @@
 		/**
 		 * Trust the server for all git operations from this repository; may be
 		 * {@code null} if the transport was created via
-		 * {@link #TransportHttp(URIish)}.
+		 * {@link TransportHttp#TransportHttp(URIish)}.
 		 */
 		CredentialItem.YesNoType forRepo;
 
@@ -1035,11 +1035,15 @@
 	/**
 	 * Open an HTTP connection.
 	 *
-	 * @param method HTTP request method
-	 * @param u url of the HTTP connection
-	 * @param acceptEncoding accept-encoding header option
+	 * @param method
+	 *            HTTP request method
+	 * @param u
+	 *            url of the HTTP connection
+	 * @param acceptEncoding
+	 *            accept-encoding header option
 	 * @return the HTTP connection
 	 * @throws java.io.IOException
+	 *             if an IO error occurred
 	 * @since 4.6
 	 */
 	protected HttpConnection httpOpen(String method, URL u,
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/transport/TransportLocal.java b/org.eclipse.jgit/src/org/eclipse/jgit/transport/TransportLocal.java
index 77d1419..3a06ce5 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/transport/TransportLocal.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/transport/TransportLocal.java
@@ -151,7 +151,6 @@
 		}
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public FetchConnection openFetch() throws TransportException {
 		return openFetch(Collections.emptyList());
@@ -170,7 +169,6 @@
 		return new InternalFetchConnection<>(this, upf, null, openRepo());
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public PushConnection openPush() throws TransportException {
 		final String rp = getOptionReceivePack();
@@ -183,7 +181,6 @@
 		return new InternalPushConnection<>(this, rpf, null, openRepo());
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public void close() {
 		// Resources must be established per-connection.
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/transport/TransportProtocol.java b/org.eclipse.jgit/src/org/eclipse/jgit/transport/TransportProtocol.java
index 912a90a..bfb840d 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/transport/TransportProtocol.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/transport/TransportProtocol.java
@@ -251,7 +251,9 @@
 	 *            a {@link org.eclipse.jgit.transport.URIish} object.
 	 * @return new Transport
 	 * @throws org.eclipse.jgit.errors.NotSupportedException
+	 *             this protocol does not support the URI.
 	 * @throws org.eclipse.jgit.errors.TransportException
+	 *             the transport cannot open this URI.
 	 */
 	public Transport open(URIish uri)
 			throws NotSupportedException, TransportException {
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/transport/TransportSftp.java b/org.eclipse.jgit/src/org/eclipse/jgit/transport/TransportSftp.java
index b9feeb9..a59d352 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/transport/TransportSftp.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/transport/TransportSftp.java
@@ -104,7 +104,6 @@
 		super(local, uri);
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public FetchConnection openFetch() throws TransportException {
 		final SftpObjectDB c = new SftpObjectDB(uri.getPath());
@@ -113,7 +112,6 @@
 		return r;
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public PushConnection openPush() throws TransportException {
 		final SftpObjectDB c = new SftpObjectDB(uri.getPath());
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/transport/URIish.java b/org.eclipse.jgit/src/org/eclipse/jgit/transport/URIish.java
index c9bb89a..4de6ff8 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/transport/URIish.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/transport/URIish.java
@@ -94,7 +94,7 @@
 	private static final long serialVersionUID = 1L;
 
 	/**
-	 * A pattern matching standard URI: </br>
+	 * A pattern matching standard URI: <br>
 	 * <code>scheme "://" user_password? hostname? portnumber? path</code>
 	 */
 	private static final Pattern FULL_URI = Pattern.compile("^" // //$NON-NLS-1$
@@ -175,6 +175,7 @@
 	 * @param s
 	 *            a {@link java.lang.String} object.
 	 * @throws java.net.URISyntaxException
+	 *             if {@code s} was null or couldn't be parsed
 	 */
 	public URIish(String s) throws URISyntaxException {
 		if (StringUtils.isEmptyOrNull(s)) {
@@ -477,6 +478,7 @@
 	 *            the new value for path.
 	 * @return a new URI with the updated value.
 	 * @throws java.net.URISyntaxException
+	 *             if URI couldn't be parsed from String
 	 */
 	public URIish setRawPath(String n) throws URISyntaxException {
 		final URIish r = new URIish(this);
@@ -551,7 +553,6 @@
 		return r;
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public int hashCode() {
 		int hc = 0;
@@ -570,7 +571,6 @@
 		return hc;
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public boolean equals(Object obj) {
 		if (!(obj instanceof URIish))
@@ -611,7 +611,6 @@
 		return format(true, false);
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public String toString() {
 		return format(false, false);
@@ -683,7 +682,8 @@
 	/**
 	 * Get the "humanish" part of the path. Some examples of a 'humanish' part
 	 * for a full path:
-	 * <table summary="path vs humanish path" border="1">
+	 * <table border="1">
+	 * <caption>path vs. humanish path</caption>
 	 * <tr>
 	 * <th>Path</th>
 	 * <th>Humanish part</th>
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/transport/UploadPack.java b/org.eclipse.jgit/src/org/eclipse/jgit/transport/UploadPack.java
index 3264f55..78e9110 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/transport/UploadPack.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/transport/UploadPack.java
@@ -771,9 +771,13 @@
 	 * its own error handling mechanism.
 	 *
 	 * @param input
+	 *            input stream
 	 * @param output
+	 *            output stream
 	 * @param messages
+	 *            stream for messages
 	 * @throws java.io.IOException
+	 *             if an IO error occurred
 	 */
 	public void upload(InputStream input, OutputStream output,
 			@Nullable OutputStream messages) throws IOException {
@@ -2266,7 +2270,8 @@
 	 *            request in process
 	 * @param allTags
 	 *            refs to search for annotated tags to include in the pack if
-	 *            the {@link #OPTION_INCLUDE_TAG} capability was requested.
+	 *            the {@link GitProtocolConstants#OPTION_INCLUDE_TAG} capability
+	 *            was requested.
 	 * @param unshallowCommits
 	 *            shallow commits on the client that are now becoming unshallow
 	 * @param deepenNots
@@ -2327,7 +2332,8 @@
 	 *            where to write statistics about the content of the pack.
 	 * @param allTags
 	 *            refs to search for annotated tags to include in the pack if
-	 *            the {@link #OPTION_INCLUDE_TAG} capability was requested.
+	 *            the {@link GitProtocolConstants#OPTION_INCLUDE_TAG} capability
+	 *            was requested.
 	 * @param unshallowCommits
 	 *            shallow commits on the client that are now becoming unshallow
 	 * @param deepenNots
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/transport/UserAgent.java b/org.eclipse.jgit/src/org/eclipse/jgit/transport/UserAgent.java
index df98d0c..7b052ad 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/transport/UserAgent.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/transport/UserAgent.java
@@ -94,10 +94,12 @@
 	/**
 	 *
 	 * @param options
+	 *            options
 	 * @param transportAgent
+	 *            name of transport agent
 	 * @return The transport agent.
-	 * @deprecated Capabilities with <key>=<value> shape are now parsed
-	 *             alongside other capabilities in the ReceivePack flow.
+	 * @deprecated Capabilities with &lt;key&gt;=&lt;value&gt; shape are now
+	 *             parsed alongside other capabilities in the ReceivePack flow.
 	 */
 	@Deprecated
 	static String getAgent(Set<String> options, String transportAgent) {
@@ -117,9 +119,10 @@
 	/**
 	 *
 	 * @param options
+	 *            options
 	 * @return True if the transport agent is set. False otherwise.
-	 * @deprecated Capabilities with <key>=<value> shape are now parsed
-	 *             alongside other capabilities in the ReceivePack flow.
+	 * @deprecated Capabilities with &lt;key&gt;=&lt;value&gt; shape are now
+	 *             parsed alongside other capabilities in the ReceivePack flow.
 	 */
 	@Deprecated
 	static boolean hasAgent(Set<String> options) {
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/transport/UsernamePasswordCredentialsProvider.java b/org.eclipse.jgit/src/org/eclipse/jgit/transport/UsernamePasswordCredentialsProvider.java
index c0de42c..da8af5a 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/transport/UsernamePasswordCredentialsProvider.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/transport/UsernamePasswordCredentialsProvider.java
@@ -48,13 +48,11 @@
 		this.password = password;
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public boolean isInteractive() {
 		return false;
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public boolean supports(CredentialItem... items) {
 		for (CredentialItem i : items) {
@@ -77,7 +75,6 @@
 		return true;
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public boolean get(URIish uri, CredentialItem... items)
 			throws UnsupportedCredentialItem {
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/transport/WalkEncryption.java b/org.eclipse.jgit/src/org/eclipse/jgit/transport/WalkEncryption.java
index c8cdb5a..3bfc523 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/transport/WalkEncryption.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/transport/WalkEncryption.java
@@ -130,6 +130,7 @@
 	 * EncryptionUtil.java</a>
 	 * <p>
 	 * Note: EncryptionUtil is inadequate:
+	 * <ul>
 	 * <li>EncryptionUtil.isCipherAvailableForUse checks encryption only which
 	 * "always works", but in JetS3t both encryption and decryption use non-IV
 	 * aware algorithm parameters for all PBE specs, which breaks in case of AES
@@ -137,6 +138,7 @@
 	 * JetS3t, such as PBEWithMD5AndDES and PBEWithSHAAndTwofish-CBC
 	 * <li>any AES based algorithms such as "PBE...With...And...AES" will not
 	 * work, since they need proper IV setup
+	 * </ul>
 	 */
 	static class JetS3tV2 extends WalkEncryption {
 
@@ -516,8 +518,10 @@
 	 * Encryption factory.
 	 *
 	 * @param props
-	 * @return instance
+	 *            configuration properties
+	 * @return instance this object
 	 * @throws GeneralSecurityException
+	 *             if generic security failure occurred
 	 */
 	static WalkEncryption instance(Properties props)
 			throws GeneralSecurityException {
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/transport/WalkFetchConnection.java b/org.eclipse.jgit/src/org/eclipse/jgit/transport/WalkFetchConnection.java
index cc6c252..8d89107 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/transport/WalkFetchConnection.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/transport/WalkFetchConnection.java
@@ -186,13 +186,11 @@
 		workQueue = new LinkedList<>();
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public boolean didFetchTestConnectivity() {
 		return true;
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	protected void doFetch(final ProgressMonitor monitor,
 			final Collection<Ref> want, final Set<ObjectId> have)
@@ -214,19 +212,16 @@
 		}
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public Collection<PackLock> getPackLocks() {
 		return packLocks;
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public void setPackLockMessage(String message) {
 		lockMessage = message;
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public void close() {
 		inserter.close();
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 a54fd8e..464017a 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/transport/WalkPushConnection.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/transport/WalkPushConnection.java
@@ -104,7 +104,6 @@
 		dest = w;
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public void push(final ProgressMonitor monitor,
 			final Map<String, RemoteRefUpdate> refUpdates)
@@ -112,7 +111,6 @@
 		push(monitor, refUpdates, null);
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public void push(final ProgressMonitor monitor,
 			final Map<String, RemoteRefUpdate> refUpdates, OutputStream out)
@@ -184,7 +182,6 @@
 		}
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public void close() {
 		dest.close();
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/transport/http/HttpConnection.java b/org.eclipse.jgit/src/org/eclipse/jgit/transport/http/HttpConnection.java
index 98c231a..125ee6c 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/transport/http/HttpConnection.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/transport/http/HttpConnection.java
@@ -105,6 +105,7 @@
 	 * @see HttpURLConnection#getResponseCode()
 	 * @return the HTTP Status-Code, or -1
 	 * @throws java.io.IOException
+	 *             if an IO error occurred
 	 */
 	int getResponseCode() throws IOException;
 
@@ -122,6 +123,7 @@
 	 * @see HttpURLConnection#getResponseMessage()
 	 * @return the HTTP response message, or <code>null</code>
 	 * @throws java.io.IOException
+	 *             if an IO error occurred
 	 */
 	String getResponseMessage() throws IOException;
 
@@ -207,14 +209,14 @@
 	 * @exception IOException
 	 *                if an I/O error occurs while creating the input stream.
 	 * @throws java.io.IOException
-	 *             if any.
+	 *             if an IO error occurred
 	 */
 	InputStream getInputStream() throws IOException;
 
 	/**
 	 * Get header field. According to
-	 * {@link <a href="https://tools.ietf.org/html/rfc2616#section-4.2">RFC
-	 * 2616</a>} header field names are case insensitive. Header fields defined
+	 * <a href="https://tools.ietf.org/html/rfc2616#section-4.2">RFC 2616</a>
+	 * header field names are case insensitive. Header fields defined
 	 * as a comma separated list can have multiple header fields with the same
 	 * field name. This method only returns one of these header fields. If you
 	 * want the union of all values of all multiple header fields with the same
@@ -230,8 +232,8 @@
 
 	/**
 	 * Get all values of given header field. According to
-	 * {@link <a href="https://tools.ietf.org/html/rfc2616#section-4.2">RFC
-	 * 2616</a>} header field names are case insensitive. Header fields defined
+	 * <a href="https://tools.ietf.org/html/rfc2616#section-4.2">RFC 2616</a>
+	 * header field names are case insensitive. Header fields defined
 	 * as a comma separated list can have multiple header fields with the same
 	 * field name. This method does not validate if the given header field is
 	 * defined as a comma separated list.
@@ -287,6 +289,7 @@
 	 * @see HttpURLConnection#getOutputStream()
 	 * @return an output stream that writes to this connection.
 	 * @throws java.io.IOException
+	 *             if an IO error occurred
 	 */
 	OutputStream getOutputStream() throws IOException;
 
@@ -321,6 +324,7 @@
 	 *
 	 * @see HttpURLConnection#connect()
 	 * @throws java.io.IOException
+	 *             if an IO error occurred
 	 */
 	void connect() throws IOException;
 
@@ -338,7 +342,9 @@
 	 *            the source of randomness for this generator or null. See
 	 *            {@link javax.net.ssl.SSLContext#init(KeyManager[], TrustManager[], SecureRandom)}
 	 * @throws java.security.NoSuchAlgorithmException
+	 *             if algorithm isn't available
 	 * @throws java.security.KeyManagementException
+	 *             if key management failed
 	 */
 	void configure(KeyManager[] km, TrustManager[] tm,
 			SecureRandom random) throws NoSuchAlgorithmException,
@@ -351,7 +357,9 @@
 	 * @param hostnameverifier
 	 *            a {@link javax.net.ssl.HostnameVerifier} object.
 	 * @throws java.security.NoSuchAlgorithmException
+	 *             if algorithm isn't available
 	 * @throws java.security.KeyManagementException
+	 *             if key management failed
 	 */
 	void setHostnameVerifier(HostnameVerifier hostnameverifier)
 			throws NoSuchAlgorithmException, KeyManagementException;
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/transport/http/HttpConnectionFactory.java b/org.eclipse.jgit/src/org/eclipse/jgit/transport/http/HttpConnectionFactory.java
index bd0aa3f..b50eaa4 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/transport/http/HttpConnectionFactory.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/transport/http/HttpConnectionFactory.java
@@ -28,6 +28,7 @@
 	 *            a {@link java.net.URL} object.
 	 * @return a {@link org.eclipse.jgit.transport.http.HttpConnection}
 	 * @throws java.io.IOException
+	 *             if an IO error occurred
 	 */
 	HttpConnection create(URL url) throws IOException;
 
@@ -41,6 +42,7 @@
 	 *            the proxy to be used
 	 * @return a {@link org.eclipse.jgit.transport.http.HttpConnection}
 	 * @throws java.io.IOException
+	 *             if an IO error occurred
 	 */
 	HttpConnection create(URL url, Proxy proxy)
 			throws IOException;
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/transport/http/HttpConnectionFactory2.java b/org.eclipse.jgit/src/org/eclipse/jgit/transport/http/HttpConnectionFactory2.java
index 88abc60..71d5c1b 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/transport/http/HttpConnectionFactory2.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/transport/http/HttpConnectionFactory2.java
@@ -48,7 +48,7 @@
 		 *            {@link HttpConnectionFactory} instance
 		 * @param sslVerify
 		 *            whether SSL is to be verified
-		 * @return the configured {@connection}
+		 * @return the configured {@code connection}
 		 * @throws IOException
 		 *             if the connection cannot be configured
 		 * @throws GeneralSecurityException
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/transport/http/JDKHttpConnection.java b/org.eclipse.jgit/src/org/eclipse/jgit/transport/http/JDKHttpConnection.java
index 3b0bae2..8e9be1d 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/transport/http/JDKHttpConnection.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/transport/http/JDKHttpConnection.java
@@ -55,7 +55,9 @@
 	 * @param url
 	 *            a {@link java.net.URL} object.
 	 * @throws java.net.MalformedURLException
+	 *             if URL is malformed
 	 * @throws java.io.IOException
+	 *             if an IO error occurred
 	 */
 	protected JDKHttpConnection(URL url)
 			throws MalformedURLException,
@@ -71,7 +73,9 @@
 	 * @param proxy
 	 *            a {@link java.net.Proxy} object.
 	 * @throws java.net.MalformedURLException
+	 *             if URL is malformed
 	 * @throws java.io.IOException
+	 *             if an IO error occurred
 	 */
 	protected JDKHttpConnection(URL url, Proxy proxy)
 			throws MalformedURLException, IOException {
@@ -79,73 +83,61 @@
 				.openConnection(proxy);
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public int getResponseCode() throws IOException {
 		return wrappedUrlConnection.getResponseCode();
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public URL getURL() {
 		return wrappedUrlConnection.getURL();
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public String getResponseMessage() throws IOException {
 		return wrappedUrlConnection.getResponseMessage();
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public Map<String, List<String>> getHeaderFields() {
 		return wrappedUrlConnection.getHeaderFields();
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public void setRequestProperty(String key, String value) {
 		wrappedUrlConnection.setRequestProperty(key, value);
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public void setRequestMethod(String method) throws ProtocolException {
 		wrappedUrlConnection.setRequestMethod(method);
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public void setUseCaches(boolean usecaches) {
 		wrappedUrlConnection.setUseCaches(usecaches);
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public void setConnectTimeout(int timeout) {
 		wrappedUrlConnection.setConnectTimeout(timeout);
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public void setReadTimeout(int timeout) {
 		wrappedUrlConnection.setReadTimeout(timeout);
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public String getContentType() {
 		return wrappedUrlConnection.getContentType();
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public InputStream getInputStream() throws IOException {
 		return wrappedUrlConnection.getInputStream();
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public String getHeaderField(@NonNull String name) {
 		return wrappedUrlConnection.getHeaderField(name);
@@ -167,68 +159,57 @@
 		return fields;
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public int getContentLength() {
 		return wrappedUrlConnection.getContentLength();
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public void setInstanceFollowRedirects(boolean followRedirects) {
 		wrappedUrlConnection.setInstanceFollowRedirects(followRedirects);
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public void setDoOutput(boolean dooutput) {
 		wrappedUrlConnection.setDoOutput(dooutput);
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public void setFixedLengthStreamingMode(int contentLength) {
 		wrappedUrlConnection.setFixedLengthStreamingMode(contentLength);
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public OutputStream getOutputStream() throws IOException {
 		return wrappedUrlConnection.getOutputStream();
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public void setChunkedStreamingMode(int chunklen) {
 		wrappedUrlConnection.setChunkedStreamingMode(chunklen);
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public String getRequestMethod() {
 		return wrappedUrlConnection.getRequestMethod();
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public boolean usingProxy() {
 		return wrappedUrlConnection.usingProxy();
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public void connect() throws IOException {
 		wrappedUrlConnection.connect();
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public void setHostnameVerifier(HostnameVerifier hostnameverifier) {
 		((HttpsURLConnection) wrappedUrlConnection)
 				.setHostnameVerifier(hostnameverifier);
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public void configure(KeyManager[] km, TrustManager[] tm,
 			SecureRandom random) throws NoSuchAlgorithmException,
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/transport/resolver/FileResolver.java b/org.eclipse.jgit/src/org/eclipse/jgit/transport/resolver/FileResolver.java
index 046f395..36731a5 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/transport/resolver/FileResolver.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/transport/resolver/FileResolver.java
@@ -60,7 +60,6 @@
 		setExportAll(exportAll);
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public Repository open(C req, String name)
 			throws RepositoryNotFoundException, ServiceNotEnabledException {
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/treewalk/AbstractTreeIterator.java b/org.eclipse.jgit/src/org/eclipse/jgit/treewalk/AbstractTreeIterator.java
index 3ef5b29..65b1808 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/treewalk/AbstractTreeIterator.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/treewalk/AbstractTreeIterator.java
@@ -718,7 +718,6 @@
 		System.arraycopy(path, pathOffset, buffer, offset, pathLen - pathOffset);
 	}
 
-	/** {@inheritDoc} */
 	@SuppressWarnings("nls")
 	@Override
 	public String toString() {
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/treewalk/CanonicalTreeParser.java b/org.eclipse.jgit/src/org/eclipse/jgit/treewalk/CanonicalTreeParser.java
index 5c3f6ae..c6d50d3 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/treewalk/CanonicalTreeParser.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/treewalk/CanonicalTreeParser.java
@@ -191,7 +191,6 @@
 		reset(reader.open(id, OBJ_TREE).getCachedBytes());
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public CanonicalTreeParser createSubtreeIterator(final ObjectReader reader,
 			final MutableObjectId idBuffer)
@@ -227,51 +226,43 @@
 		return p;
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public CanonicalTreeParser createSubtreeIterator(ObjectReader reader)
 			throws IncorrectObjectTypeException, IOException {
 		return createSubtreeIterator(reader, new MutableObjectId());
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public boolean hasId() {
 		return true;
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public byte[] idBuffer() {
 		return raw;
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public int idOffset() {
 		return nextPtr - OBJECT_ID_LENGTH;
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public void reset() {
 		if (!first())
 			reset(raw);
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public boolean first() {
 		return currPtr == 0;
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public boolean eof() {
 		return currPtr == raw.length;
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public void next(int delta) {
 		if (delta == 1) {
@@ -301,7 +292,6 @@
 			parseEntry();
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public void back(int delta) {
 		if (delta == 1 && 0 <= prevPtr) {
@@ -376,6 +366,7 @@
 	 * @return {@link org.eclipse.jgit.attributes.AttributesNode} for the
 	 *         current entry.
 	 * @throws java.io.IOException
+	 *             if an IO error occurred
 	 * @since 4.2
 	 */
 	public AttributesNode getEntryAttributesNode(ObjectReader reader)
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/treewalk/EmptyTreeIterator.java b/org.eclipse.jgit/src/org/eclipse/jgit/treewalk/EmptyTreeIterator.java
index 0661c90..32368dc 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/treewalk/EmptyTreeIterator.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/treewalk/EmptyTreeIterator.java
@@ -57,75 +57,63 @@
 		pathLen = childPathOffset - 1;
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public AbstractTreeIterator createSubtreeIterator(ObjectReader reader)
 			throws IncorrectObjectTypeException, IOException {
 		return new EmptyTreeIterator(this);
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public boolean hasId() {
 		return false;
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public ObjectId getEntryObjectId() {
 		return ObjectId.zeroId();
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public byte[] idBuffer() {
 		return zeroid;
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public int idOffset() {
 		return 0;
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public void reset() {
 		// Do nothing.
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public boolean first() {
 		return true;
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public boolean eof() {
 		return true;
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public void next(int delta) throws CorruptObjectException {
 		// Do nothing.
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public void back(int delta) throws CorruptObjectException {
 		// Do nothing.
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public void stopWalk() {
 		if (parent != null)
 			parent.stopWalk();
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	protected boolean needsStopWalk() {
 		return parent != null && parent.needsStopWalk();
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/treewalk/FileTreeIterator.java b/org.eclipse.jgit/src/org/eclipse/jgit/treewalk/FileTreeIterator.java
index 60b92d7..36fa720 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/treewalk/FileTreeIterator.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/treewalk/FileTreeIterator.java
@@ -175,7 +175,6 @@
 		init(entries());
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public AbstractTreeIterator createSubtreeIterator(ObjectReader reader)
 			throws IncorrectObjectTypeException, IOException {
@@ -425,13 +424,11 @@
 		return ((FileEntry) current()).getFile();
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	protected byte[] idSubmodule(Entry e) {
 		return idSubmodule(getDirectory(), e);
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	protected String readSymlinkTarget(Entry entry) throws IOException {
 		return fs.readSymLink(getEntryFile());
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/treewalk/TreeWalk.java b/org.eclipse.jgit/src/org/eclipse/jgit/treewalk/TreeWalk.java
index ece9452..e0a8af1 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/treewalk/TreeWalk.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/treewalk/TreeWalk.java
@@ -548,7 +548,7 @@
 	 * <p>
 	 * Retrieve the git attributes for the current entry.
 	 *
-	 * <h3>Git attribute computation</h3>
+	 * <h4>Git attribute computation</h4>
 	 *
 	 * <ul>
 	 * <li>Get the attributes matching the current path entry from the info file
@@ -563,11 +563,10 @@
 	 * <li>In the end, completes the list of matching attributes using the
 	 * global attribute file define in the configuration (see
 	 * {@link AttributesNodeProvider#getGlobalAttributesNode()})</li>
-	 *
 	 * </ul>
 	 *
 	 *
-	 * <h3>Iterator constraints</h3>
+	 * <h4>Iterator constraints</h4>
 	 *
 	 * <p>
 	 * In order to have a correct list of attributes for the current entry, this
@@ -960,6 +959,8 @@
 	 * iterators to manage only one list of items, with the diving handled by
 	 * recursive trees.
 	 *
+	 * @param <T>
+	 *            Type of returned {@code AbstractTreeIterator}
 	 * @param nth
 	 *            tree to obtain the current iterator of.
 	 * @param clazz
@@ -1376,12 +1377,14 @@
 	}
 
 	/**
-	 * Returns an AbstractTreeIterator from {@code trees} with the smallest name, and sets its
-	 * {@code matches} field. This may clobber {@code matches} in other {@code tree}s. Other iterators
-	 * at the same name will have their {@code matches} pointing to the same {@code min()} value.
+	 * Returns an AbstractTreeIterator from {@code trees} with the smallest
+	 * name, and sets its {@code matches} field. This may clobber
+	 * {@code matches} in other {@code tree}s. Other iterators at the same name
+	 * will have their {@code matches} pointing to the same {@code min()} value.
 	 *
 	 * @return the smallest tree iterator available.
 	 * @throws CorruptObjectException
+	 *             if an object is corrupt
 	 */
 	@SuppressWarnings("unused")
 	AbstractTreeIterator min() throws CorruptObjectException {
@@ -1488,6 +1491,7 @@
 	 *            {{@link #getSmudgeCommand(int)} instead.
 	 * @return a filter command
 	 * @throws java.io.IOException
+	 *             if an IO error occurred
 	 * @since 4.2
 	 */
 	public String getFilterCommand(String filterCommandType)
@@ -1521,6 +1525,7 @@
 	 *            of the tree the item to be smudged is in
 	 * @return a filter command
 	 * @throws java.io.IOException
+	 *             if an IO error occurred
 	 * @since 6.1
 	 */
 	public String getSmudgeCommand(int index)
@@ -1536,6 +1541,7 @@
 	 *            to use
 	 * @return a filter command
 	 * @throws java.io.IOException
+	 *             if an IO error occurred
 	 * @since 6.1
 	 */
 	public String getSmudgeCommand(Attributes attributes) throws IOException {
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/treewalk/WorkingTreeIterator.java b/org.eclipse.jgit/src/org/eclipse/jgit/treewalk/WorkingTreeIterator.java
index b5d6610..98d08466 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/treewalk/WorkingTreeIterator.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/treewalk/WorkingTreeIterator.java
@@ -25,6 +25,7 @@
 import java.nio.CharBuffer;
 import java.nio.charset.CharacterCodingException;
 import java.nio.charset.CharsetEncoder;
+import java.nio.file.Files;
 import java.nio.file.Path;
 import java.text.MessageFormat;
 import java.time.Instant;
@@ -68,6 +69,7 @@
 import org.eclipse.jgit.util.IO;
 import org.eclipse.jgit.util.Paths;
 import org.eclipse.jgit.util.RawParseUtils;
+import org.eclipse.jgit.util.SystemReader;
 import org.eclipse.jgit.util.TemporaryBuffer;
 import org.eclipse.jgit.util.TemporaryBuffer.LocalFile;
 import org.eclipse.jgit.util.io.EolStreamTypeUtil;
@@ -270,7 +272,6 @@
 		return state.walkIgnored;
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public boolean hasId() {
 		if (contentIdFromPtr == ptr)
@@ -278,7 +279,6 @@
 		return (mode & FileMode.TYPE_MASK) == FileMode.TYPE_FILE;
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public byte[] idBuffer() {
 		if (contentIdFromPtr == ptr)
@@ -316,7 +316,6 @@
 		return zeroid;
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public boolean isWorkTree() {
 		return true;
@@ -549,13 +548,11 @@
 		return repository;
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public int idOffset() {
 		return contentIdOffset;
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public void reset() {
 		if (!first()) {
@@ -565,19 +562,16 @@
 		}
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public boolean first() {
 		return ptr == 0;
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public boolean eof() {
 		return ptr == entryCnt;
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public void next(int delta) throws CorruptObjectException {
 		ptr += delta;
@@ -586,7 +580,6 @@
 		}
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public void back(int delta) throws CorruptObjectException {
 		ptr -= delta;
@@ -620,6 +613,7 @@
 	 *
 	 * @return size of the content, in bytes
 	 * @throws java.io.IOException
+	 *             if an IO error occurred
 	 */
 	public long getEntryContentLength() throws IOException {
 		if (canonLen == -1) {
@@ -772,6 +766,7 @@
 	 * @return the {@link org.eclipse.jgit.attributes.AttributesNode} for the
 	 *         current entry.
 	 * @throws IOException
+	 *             if an IO error occurred
 	 */
 	public AttributesNode getEntryAttributesNode() throws IOException {
 		if (attributesNode instanceof PerDirectoryAttributesNode)
@@ -964,6 +959,7 @@
 	 *            access to repository objects if necessary. Should not be null.
 	 * @return true if content is most likely different.
 	 * @throws java.io.IOException
+	 *             if an IO error occurred
 	 * @since 3.3
 	 */
 	public boolean isModified(DirCacheEntry entry, boolean forceContentCheck,
@@ -1070,6 +1066,7 @@
 	 * @return <code>true</code> if the content doesn't match,
 	 *         <code>false</code> if it matches
 	 * @throws IOException
+	 *             if an IO error occurred
 	 */
 	private boolean contentCheck(DirCacheEntry entry, ObjectReader reader)
 			throws IOException {
@@ -1334,7 +1331,11 @@
 					ConfigConstants.CONFIG_CORE_SECTION, null,
 					ConfigConstants.CONFIG_KEY_EXCLUDESFILE, fs, null, null);
 			if (path != null) {
-				loadRulesFromFile(coreExclude, path.toFile());
+				if (Files.exists(path)) {
+					loadRulesFromFile(coreExclude, path.toFile());
+				}
+			} else {
+				loadRulesFromDefaultFile(coreExclude, fs);
 			}
 			if (coreExclude.getRules().isEmpty()) {
 				coreExclude = parent;
@@ -1344,7 +1345,9 @@
 					coreExclude);
 			File exclude = fs.resolve(repository.getDirectory(),
 					Constants.INFO_EXCLUDE);
-			loadRulesFromFile(infoExclude, exclude);
+			if (fs.exists(exclude)) {
+				loadRulesFromFile(infoExclude, exclude);
+			}
 			if (infoExclude.getRules().isEmpty()) {
 				infoExclude = null;
 			}
@@ -1366,9 +1369,19 @@
 
 		private static void loadRulesFromFile(IgnoreNode r, File exclude)
 				throws FileNotFoundException, IOException {
-			if (FS.DETECTED.exists(exclude)) {
-				try (FileInputStream in = new FileInputStream(exclude)) {
-					r.parse(exclude.getAbsolutePath(), in);
+			try (FileInputStream in = new FileInputStream(exclude)) {
+				r.parse(exclude.getAbsolutePath(), in);
+			}
+		}
+
+		private static void loadRulesFromDefaultFile(IgnoreNode r,
+				FS fileSystem) throws FileNotFoundException, IOException {
+			Path cfg = SystemReader.getInstance()
+					.getXdgConfigDirectory(fileSystem);
+			if (cfg != null) {
+				Path cfgPath = cfg.resolve("git").resolve("ignore"); //$NON-NLS-1$ //$NON-NLS-2$
+				if (Files.exists(cfgPath)) {
+					loadRulesFromFile(r, cfgPath.toFile());
 				}
 			}
 		}
@@ -1450,6 +1463,7 @@
 	 * @return the clean filter command for the current entry or
 	 *         <code>null</code> if no such command is defined
 	 * @throws java.io.IOException
+	 *             if an IO error occurred
 	 * @since 4.2
 	 */
 	public String getCleanFilterCommand() throws IOException {
@@ -1472,6 +1486,7 @@
 	 *         {@link org.eclipse.jgit.treewalk.TreeWalk} is not based on a
 	 *         {@link org.eclipse.jgit.lib.Repository} then null is returned.
 	 * @throws java.io.IOException
+	 *             if an IO error occurred
 	 * @since 4.3
 	 */
 	public EolStreamType getEolStreamType() throws IOException {
@@ -1486,6 +1501,7 @@
 	 *         {@link TreeWalk} is not based on a {@link Repository} then null
 	 *         is returned.
 	 * @throws IOException
+	 *             if an IO error occurred
 	 */
 	private EolStreamType getEolStreamType(OperationType opType)
 			throws IOException {
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/treewalk/filter/ByteArraySet.java b/org.eclipse.jgit/src/org/eclipse/jgit/treewalk/filter/ByteArraySet.java
index cafa926..c941601 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/treewalk/filter/ByteArraySet.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/treewalk/filter/ByteArraySet.java
@@ -39,6 +39,7 @@
 	 * Create an empty set.
 	 *
 	 * @param capacity
+	 *            initial capacity of the set
 	 */
 	ByteArraySet(int capacity) {
 		initTable(1 << Integer.highestOneBit((capacity * 2) - 1));
@@ -180,7 +181,6 @@
 		table = new byte[sz][];
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public String toString() {
 		StringBuilder sb = new StringBuilder();
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/treewalk/filter/IndexDiffFilter.java b/org.eclipse.jgit/src/org/eclipse/jgit/treewalk/filter/IndexDiffFilter.java
index 4731f34..699ff6b 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/treewalk/filter/IndexDiffFilter.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/treewalk/filter/IndexDiffFilter.java
@@ -106,7 +106,6 @@
 		this.honorIgnores = honorIgnores;
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public boolean include(TreeWalk tw) throws MissingObjectException,
 			IncorrectObjectTypeException, IOException {
@@ -234,7 +233,6 @@
 		return tw.getTree(workingTree, WorkingTreeIterator.class);
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public boolean shouldBeRecursive() {
 		// We cannot compare subtrees in the working tree, so encourage
@@ -242,13 +240,11 @@
 		return true;
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public TreeFilter clone() {
 		return this;
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public String toString() {
 		return "INDEX_DIFF_FILTER"; //$NON-NLS-1$
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/treewalk/filter/InterIndexDiffFilter.java b/org.eclipse.jgit/src/org/eclipse/jgit/treewalk/filter/InterIndexDiffFilter.java
index 163dc71..0c0b09e 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/treewalk/filter/InterIndexDiffFilter.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/treewalk/filter/InterIndexDiffFilter.java
@@ -28,7 +28,6 @@
 	 */
 	public static final TreeFilter INSTANCE = new InterIndexDiffFilter();
 
-	/** {@inheritDoc} */
 	@Override
 	public boolean include(TreeWalk walker) {
 		final int n = walker.getTreeCount();
@@ -57,19 +56,16 @@
 		return false;
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public boolean shouldBeRecursive() {
 		return false;
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public TreeFilter clone() {
 		return this;
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public String toString() {
 		return "INTERINDEX_DIFF"; //$NON-NLS-1$
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/treewalk/filter/NotIgnoredFilter.java b/org.eclipse.jgit/src/org/eclipse/jgit/treewalk/filter/NotIgnoredFilter.java
index 7d04f27..25947da 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/treewalk/filter/NotIgnoredFilter.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/treewalk/filter/NotIgnoredFilter.java
@@ -33,7 +33,6 @@
 		this.index = workdirTreeIndex;
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public boolean include(TreeWalk tw) throws MissingObjectException,
 			IncorrectObjectTypeException, IOException {
@@ -41,20 +40,17 @@
 		return i == null || !i.isEntryIgnored();
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public boolean shouldBeRecursive() {
 		return false;
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public TreeFilter clone() {
 		// immutable
 		return this;
 	}
 
-	/** {@inheritDoc} */
 	@SuppressWarnings("nls")
 	@Override
 	public String toString() {
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/treewalk/filter/NotTreeFilter.java b/org.eclipse.jgit/src/org/eclipse/jgit/treewalk/filter/NotTreeFilter.java
index 4fb6153..e9cd83c 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/treewalk/filter/NotTreeFilter.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/treewalk/filter/NotTreeFilter.java
@@ -38,13 +38,11 @@
 		a = one;
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public TreeFilter negate() {
 		return a;
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public boolean include(TreeWalk walker)
 			throws MissingObjectException, IncorrectObjectTypeException,
@@ -52,7 +50,6 @@
 		return matchFilter(walker) == 0;
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public int matchFilter(TreeWalk walker)
 			throws MissingObjectException, IncorrectObjectTypeException,
@@ -69,20 +66,17 @@
 		return -1;
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public boolean shouldBeRecursive() {
 		return a.shouldBeRecursive();
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public TreeFilter clone() {
 		final TreeFilter n = a.clone();
 		return n == a ? this : new NotTreeFilter(n);
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public String toString() {
 		return "NOT " + a.toString(); //$NON-NLS-1$
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/treewalk/filter/PathFilter.java b/org.eclipse.jgit/src/org/eclipse/jgit/treewalk/filter/PathFilter.java
index c94215f..66ab8bb 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/treewalk/filter/PathFilter.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/treewalk/filter/PathFilter.java
@@ -11,6 +11,9 @@
 
 package org.eclipse.jgit.treewalk.filter;
 
+import java.util.Optional;
+import java.util.Set;
+import java.util.HashSet;
 import org.eclipse.jgit.internal.JGitText;
 import org.eclipse.jgit.lib.Constants;
 import org.eclipse.jgit.treewalk.TreeWalk;
@@ -45,7 +48,8 @@
 		while (path.endsWith("/")) //$NON-NLS-1$
 			path = path.substring(0, path.length() - 1);
 		if (path.length() == 0)
-			throw new IllegalArgumentException(JGitText.get().emptyPathNotPermitted);
+			throw new IllegalArgumentException(
+					JGitText.get().emptyPathNotPermitted);
 		return new PathFilter(path);
 	}
 
@@ -67,19 +71,16 @@
 		return pathStr;
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public boolean include(TreeWalk walker) {
 		return matchFilter(walker) <= 0;
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public int matchFilter(TreeWalk walker) {
 		return walker.isPathMatch(pathRaw, pathRaw.length);
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public boolean shouldBeRecursive() {
 		for (byte b : pathRaw)
@@ -88,13 +89,19 @@
 		return false;
 	}
 
+	@Override
+	public Optional<Set<byte[]>> getPathsBestEffort() {
+		HashSet<byte[]> s = new HashSet<>();
+		s.add(pathRaw);
+		return Optional.of(s);
+	}
+
 	/** {@inheritDoc} */
 	@Override
 	public PathFilter clone() {
 		return this;
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	@SuppressWarnings("nls")
 	public String toString() {
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/treewalk/filter/PathSuffixFilter.java b/org.eclipse.jgit/src/org/eclipse/jgit/treewalk/filter/PathSuffixFilter.java
index 3816d5e..ec25903 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/treewalk/filter/PathSuffixFilter.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/treewalk/filter/PathSuffixFilter.java
@@ -56,13 +56,11 @@
 		pathRaw = Constants.encode(pathStr);
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public TreeFilter clone() {
 		return this;
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public boolean include(TreeWalk walker) throws MissingObjectException,
 			IncorrectObjectTypeException, IOException {
@@ -82,7 +80,6 @@
 		return super.matchFilter(walker);
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public boolean shouldBeRecursive() {
 		return true;
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/treewalk/filter/SkipWorkTreeFilter.java b/org.eclipse.jgit/src/org/eclipse/jgit/treewalk/filter/SkipWorkTreeFilter.java
index 1ed2ef3..e311523 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/treewalk/filter/SkipWorkTreeFilter.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/treewalk/filter/SkipWorkTreeFilter.java
@@ -36,7 +36,6 @@
 		this.treeIdx = treeIdx;
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public boolean include(TreeWalk walker) {
 		DirCacheIterator i = walker.getTree(treeIdx, DirCacheIterator.class);
@@ -47,19 +46,16 @@
 		return e == null || !e.isSkipWorkTree();
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public boolean shouldBeRecursive() {
 		return false;
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public TreeFilter clone() {
 		return this;
 	}
 
-	/** {@inheritDoc} */
 	@SuppressWarnings("nls")
 	@Override
 	public String toString() {
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/treewalk/filter/TreeFilter.java b/org.eclipse.jgit/src/org/eclipse/jgit/treewalk/filter/TreeFilter.java
index 6dbd508..22d430b 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/treewalk/filter/TreeFilter.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/treewalk/filter/TreeFilter.java
@@ -11,6 +11,8 @@
 package org.eclipse.jgit.treewalk.filter;
 
 import java.io.IOException;
+import java.util.Optional;
+import java.util.Set;
 
 import org.eclipse.jgit.dircache.DirCacheIterator;
 import org.eclipse.jgit.errors.IncorrectObjectTypeException;
@@ -188,10 +190,8 @@
 	 *             as thrown by {@link #include(TreeWalk)}
 	 * @since 4.7
 	 */
-	public int matchFilter(TreeWalk walker)
-			throws MissingObjectException, IncorrectObjectTypeException,
-			IOException
-	{
+	public int matchFilter(TreeWalk walker) throws MissingObjectException,
+			IncorrectObjectTypeException, IOException {
 		return include(walker) ? 0 : 1;
 	}
 
@@ -210,6 +210,19 @@
 	public abstract boolean shouldBeRecursive();
 
 	/**
+	 * If this filter checks that a specific set of paths have all been
+	 * modified, returns that set of paths to be checked against a changed path
+	 * filter. Otherwise, returns empty.
+	 *
+	 * @return a set of paths, or empty
+	 *
+	 * @since 6.7
+	 */
+	public Optional<Set<byte[]>> getPathsBestEffort() {
+		return Optional.empty();
+	}
+
+	/**
 	 * {@inheritDoc}
 	 *
 	 * Clone this tree filter, including its parameters.
@@ -220,7 +233,6 @@
 	@Override
 	public abstract TreeFilter clone();
 
-	/** {@inheritDoc} */
 	@Override
 	public String toString() {
 		String n = getClass().getName();
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/util/BlockList.java b/org.eclipse.jgit/src/org/eclipse/jgit/util/BlockList.java
index 527c5a6..557e2cd 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/util/BlockList.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/util/BlockList.java
@@ -75,13 +75,11 @@
 		tailBlock = directory[0];
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public int size() {
 		return size;
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public void clear() {
 		for (T[] block : directory) {
@@ -94,7 +92,6 @@
 		tailBlock = directory[0];
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public T get(int index) {
 		if (index < 0 || size <= index)
@@ -102,7 +99,6 @@
 		return directory[toDirectoryIndex(index)][toBlockIndex(index)];
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public T set(int index, T element) {
 		if (index < 0 || size <= index)
@@ -160,7 +156,6 @@
 		}
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public boolean add(T element) {
 		int i = tailBlkIdx;
@@ -191,7 +186,6 @@
 		return true;
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public void add(int index, T element) {
 		if (index == size) {
@@ -213,7 +207,6 @@
 		}
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public T remove(int index) {
 		if (index == size - 1) {
@@ -253,7 +246,6 @@
 		tailBlock = directory[tailDirIdx];
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public Iterator<T> iterator() {
 		return new MyIterator();
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/util/CachedAuthenticator.java b/org.eclipse.jgit/src/org/eclipse/jgit/util/CachedAuthenticator.java
index 5815c62..d8183eb 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/util/CachedAuthenticator.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/util/CachedAuthenticator.java
@@ -32,7 +32,6 @@
 		cached.add(ca);
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	protected final PasswordAuthentication getPasswordAuthentication() {
 		final String host = getRequestingHost();
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/util/Equality.java b/org.eclipse.jgit/src/org/eclipse/jgit/util/Equality.java
index da16846..ff136f7 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/util/Equality.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/util/Equality.java
@@ -13,22 +13,24 @@
 /**
  * Equality utilities.
  *
- * @since: 6.2
+ * @since 6.2
  */
 public class Equality {
 
     /**
-     * Compare by reference
-     *
-     * @param a
-     *            First object to compare
-     * @param b
-     *            Second object to compare
-     * @return {@code true} if the objects are identical, {@code false}
-     *         otherwise
-     *
-     * @since 6.2
-     */
+	 * Compare by reference
+	 *
+	 * @param <T>
+	 *            type of the objects to compare
+	 * @param a
+	 *            First object to compare
+	 * @param b
+	 *            Second object to compare
+	 * @return {@code true} if the objects are identical, {@code false}
+	 *         otherwise
+	 *
+	 * @since 6.2
+	 */
     @SuppressWarnings("ReferenceEquality")
     public static <T> boolean isSameInstance(T a, T b) {
         return a == b;
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/util/FS.java b/org.eclipse.jgit/src/org/eclipse/jgit/util/FS.java
index aef9e64..b8fc4fc 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/util/FS.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/util/FS.java
@@ -31,8 +31,6 @@
 import java.nio.file.attribute.BasicFileAttributes;
 import java.nio.file.attribute.FileTime;
 import java.security.AccessControlException;
-import java.security.AccessController;
-import java.security.PrivilegedAction;
 import java.text.MessageFormat;
 import java.time.Duration;
 import java.time.Instant;
@@ -118,6 +116,7 @@
 		 * Detect the file system
 		 *
 		 * @param cygwinUsed
+		 *            whether cygwin is used
 		 * @return FS instance
 		 */
 		public FS detect(Boolean cygwinUsed) {
@@ -149,8 +148,11 @@
 
 		/**
 		 * @param stdout
+		 *            stdout stream
 		 * @param stderr
+		 *            stderr stream
 		 * @param rc
+		 *            return code
 		 */
 		public ExecutionResult(TemporaryBuffer stdout, TemporaryBuffer stderr,
 				int rc) {
@@ -263,7 +265,7 @@
 		 */
 		private static final ExecutorService FUTURE_RUNNER = new ThreadPoolExecutor(
 				0, 5, 30L, TimeUnit.SECONDS,
-				new LinkedBlockingQueue<Runnable>(),
+				new LinkedBlockingQueue<>(),
 				runnable -> {
 					Thread t = new Thread(runnable,
 							"JGit-FileStoreAttributeReader-" //$NON-NLS-1$
@@ -287,7 +289,7 @@
 		 */
 		private static final ExecutorService SAVE_RUNNER = new ThreadPoolExecutor(
 				0, 1, 1L, TimeUnit.MILLISECONDS,
-				new LinkedBlockingQueue<Runnable>(),
+				new LinkedBlockingQueue<>(),
 				runnable -> {
 					Thread t = new Thread(runnable,
 							"JGit-FileStoreAttributeWriter-" //$NON-NLS-1$
@@ -849,6 +851,7 @@
 		 * timestamp resolution
 		 *
 		 * @param fsTimestampResolution
+		 *            resolution of filesystem timestamps
 		 */
 		public FileStoreAttributes(
 				@NonNull Duration fsTimestampResolution) {
@@ -1074,6 +1077,7 @@
 	 *            a {@link java.io.File} object.
 	 * @return last modified time of f
 	 * @throws java.io.IOException
+	 *             if an IO error occurred
 	 * @since 3.0
 	 * @deprecated use {@link #lastModifiedInstant(Path)} instead
 	 */
@@ -1120,6 +1124,7 @@
 	 * @param time
 	 *            last modified time
 	 * @throws java.io.IOException
+	 *             if an IO error occurred
 	 * @since 3.0
 	 * @deprecated use {@link #setLastModified(Path, Instant)} instead
 	 */
@@ -1138,6 +1143,7 @@
 	 * @param time
 	 *            last modified time
 	 * @throws java.io.IOException
+	 *             if an IO error occurred
 	 * @since 5.1.9
 	 */
 	public void setLastModified(Path p, Instant time) throws IOException {
@@ -1152,6 +1158,7 @@
 	 *            a {@link java.io.File} object.
 	 * @return length of a file
 	 * @throws java.io.IOException
+	 *             if an IO error occurred
 	 * @since 3.0
 	 */
 	public long length(File path) throws IOException {
@@ -1164,7 +1171,7 @@
 	 * @param f
 	 *            a {@link java.io.File} object.
 	 * @throws java.io.IOException
-	 *             this may be a Java7 subclass with detailed information
+	 *             if an IO error occurred
 	 * @since 3.3
 	 */
 	public void delete(File f) throws IOException {
@@ -1264,8 +1271,10 @@
 	 * Return all the attributes of a file, without following symbolic links.
 	 *
 	 * @param file
+	 *            the file
 	 * @return {@link BasicFileAttributes} of the file
-	 * @throws IOException in case of any I/O errors accessing the file
+	 * @throws IOException
+	 *             in case of any I/O errors accessing the file
 	 *
 	 * @since 4.5.6
 	 */
@@ -1283,11 +1292,10 @@
 	}
 
 	private File defaultUserHomeImpl() {
-		String home = AccessController.doPrivileged(
-				(PrivilegedAction<String>) () -> System.getProperty("user.home") //$NON-NLS-1$
-		);
-		if (home == null || home.length() == 0)
+		String home = SystemReader.getInstance().getProperty("user.home"); //$NON-NLS-1$
+		if (StringUtils.isEmptyOrNull(home)) {
 			return null;
+		}
 		return new File(home).getAbsoluteFile();
 	}
 
@@ -1671,6 +1679,7 @@
 	 *            a {@link java.io.File} object.
 	 * @return target of link or null
 	 * @throws java.io.IOException
+	 *             if an IO error occurred
 	 * @since 3.0
 	 */
 	public String readSymLink(File path) throws IOException {
@@ -1684,6 +1693,7 @@
 	 *            a {@link java.io.File} object.
 	 * @return true if the path is a symbolic link (and we support these)
 	 * @throws java.io.IOException
+	 *             if an IO error occurred
 	 * @since 3.0
 	 */
 	public boolean isSymLink(File path) throws IOException {
@@ -1738,6 +1748,7 @@
 	 * @return true if path is hidden, either starts with . on unix or has the
 	 *         hidden attribute in windows
 	 * @throws java.io.IOException
+	 *             if an IO error occurred
 	 * @since 3.0
 	 */
 	public boolean isHidden(File path) throws IOException {
@@ -1752,6 +1763,7 @@
 	 * @param hidden
 	 *            whether to set the file hidden
 	 * @throws java.io.IOException
+	 *             if an IO error occurred
 	 * @since 3.0
 	 */
 	public void setHidden(File path, boolean hidden) throws IOException {
@@ -1766,6 +1778,7 @@
 	 * @param target
 	 *            target path of the symlink
 	 * @throws java.io.IOException
+	 *             if an IO error occurred
 	 * @since 3.0
 	 */
 	public void createSymLink(File path, String target) throws IOException {
@@ -1782,6 +1795,7 @@
 	 * @return <code>true</code> if the file was created, <code>false</code> if
 	 *         the file already existed
 	 * @throws java.io.IOException
+	 *             if an IO error occurred
 	 * @deprecated use {@link #createNewFileAtomic(File)} instead
 	 * @since 4.5
 	 */
@@ -1852,6 +1866,7 @@
 	 * @return LockToken this token must be closed after the created file was
 	 *         deleted
 	 * @throws IOException
+	 *             if an IO error occurred
 	 * @since 4.7
 	 */
 	public LockToken createNewFileAtomic(File path) throws IOException {
@@ -2317,7 +2332,9 @@
 	 *            The standard input stream passed to the process
 	 * @return The result of the executed command
 	 * @throws java.lang.InterruptedException
+	 *             if thread was interrupted
 	 * @throws java.io.IOException
+	 *             if an IO error occurred
 	 * @since 4.2
 	 */
 	public ExecutionResult execute(ProcessBuilder pb, InputStream in)
@@ -2441,8 +2458,10 @@
 		 * Constructor when there are issues with reading. All attributes except
 		 * given will be set to the default values.
 		 *
-		 * @param fs
 		 * @param path
+		 *            file path
+		 * @param fs
+		 *            FS to use
 		 */
 		public Attributes(File path, FS fs) {
 			this(fs, path, false, false, false, false, false, 0L, EPOCH, 0L);
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/util/FS_POSIX.java b/org.eclipse.jgit/src/org/eclipse/jgit/util/FS_POSIX.java
index 1c11361..6f31847 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/util/FS_POSIX.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/util/FS_POSIX.java
@@ -418,6 +418,7 @@
 	 * @return LockToken this lock token must be held until the file is no
 	 *         longer needed
 	 * @throws IOException
+	 *             if an IO error occurred
 	 * @since 5.0
 	 */
 	@Override
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/util/FS_Win32.java b/org.eclipse.jgit/src/org/eclipse/jgit/util/FS_Win32.java
index ae73d3f..5926655 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/util/FS_Win32.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/util/FS_Win32.java
@@ -58,43 +58,36 @@
 		super(src);
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public FS newInstance() {
 		return new FS_Win32(this);
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public boolean supportsExecute() {
 		return false;
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public boolean canExecute(File f) {
 		return false;
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public boolean setExecute(File f, boolean canExec) {
 		return false;
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public boolean isCaseSensitive() {
 		return false;
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public boolean retryFailedLockFileCommit() {
 		return true;
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public Entry[] list(File directory, FileModeStrategy fileModeStrategy) {
 		if (!Files.isDirectory(directory.toPath(), LinkOption.NOFOLLOW_LINKS)) {
@@ -140,7 +133,6 @@
 		return result.toArray(new Entry[0]);
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	protected File discoverGitExe() {
 		String path = SystemReader.getInstance().getenv("PATH"); //$NON-NLS-1$
@@ -171,7 +163,6 @@
 		return gitExe;
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	protected File userHomeImpl() {
 		String home = SystemReader.getInstance().getenv("HOME"); //$NON-NLS-1$
@@ -194,7 +185,6 @@
 		return super.userHomeImpl();
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public ProcessBuilder runInShell(String cmd, String[] args) {
 		List<String> argv = new ArrayList<>(3 + args.length);
@@ -207,7 +197,6 @@
 		return proc;
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public Attributes getAttributes(File path) {
 		return FileUtils.getFileAttributesBasic(this, path);
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/util/FS_Win32_Cygwin.java b/org.eclipse.jgit/src/org/eclipse/jgit/util/FS_Win32_Cygwin.java
index add5498..635351a 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/util/FS_Win32_Cygwin.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/util/FS_Win32_Cygwin.java
@@ -72,13 +72,11 @@
 		super(src);
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public FS newInstance() {
 		return new FS_Win32_Cygwin(this);
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public File resolve(File dir, String pn) {
 		String useCygPath = System.getProperty("jgit.usecygpath"); //$NON-NLS-1$
@@ -99,7 +97,6 @@
 		return super.resolve(dir, pn);
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	protected File userHomeImpl() {
 		final String home = AccessController.doPrivileged(
@@ -110,7 +107,6 @@
 		return resolve(new File("."), home); //$NON-NLS-1$
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public ProcessBuilder runInShell(String cmd, String[] args) {
 		List<String> argv = new ArrayList<>(4 + args.length);
@@ -129,14 +125,12 @@
 		return QuotedString.BOURNE.quote(cmd.replace(File.separatorChar, '/'));
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public String relativize(String base, String other) {
 		final String relativized = super.relativize(base, other);
 		return relativized.replace(File.separatorChar, '/');
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public ProcessResult runHookIfPresent(Repository repository, String hookName,
 			String[] args, OutputStream outRedirect, OutputStream errRedirect,
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/util/FileUtils.java b/org.eclipse.jgit/src/org/eclipse/jgit/util/FileUtils.java
index f013e7e..9d052d1 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/util/FileUtils.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/util/FileUtils.java
@@ -288,6 +288,7 @@
 	 * @throws java.nio.file.AtomicMoveNotSupportedException
 	 *             if file cannot be moved as an atomic file system operation
 	 * @throws java.io.IOException
+	 *             if an IO error occurred
 	 * @since 4.1
 	 */
 	public static void rename(final File src, final File dst,
@@ -446,6 +447,7 @@
 	 *            the target of the symbolic link
 	 * @return the path to the symbolic link
 	 * @throws java.io.IOException
+	 *             if an IO error occurred
 	 * @since 4.2
 	 */
 	public static Path createSymLink(File path, String target)
@@ -474,6 +476,7 @@
 	 *            a {@link java.io.File} object.
 	 * @return target path of the symlink, or null if it is not a symbolic link
 	 * @throws java.io.IOException
+	 *             if an IO error occurred
 	 * @since 3.0
 	 */
 	public static String readSymLink(File path) throws IOException {
@@ -499,6 +502,7 @@
 	 *            The parent dir, can be null to use system default temp dir.
 	 * @return the temp dir created.
 	 * @throws java.io.IOException
+	 *             if an IO error occurred
 	 * @since 3.4
 	 */
 	public static File createTempDir(String prefix, String suffix, File dir)
@@ -749,7 +753,10 @@
 	}
 
 	/**
+	 * Check if file is a symlink
+	 *
 	 * @param file
+	 *            the file to be checked if it is a symbolic link
 	 * @return {@code true} if the passed file is a symbolic link
 	 */
 	static boolean isSymlink(File file) {
@@ -757,10 +764,14 @@
 	}
 
 	/**
+	 * Get the lastModified attribute for a given file
+	 *
 	 * @param file
+	 *            the file
 	 * @return lastModified attribute for given file, not following symbolic
 	 *         links
 	 * @throws IOException
+	 *             if an IO error occurred
 	 * @deprecated use {@link #lastModifiedInstant(Path)} instead which returns
 	 *             FileTime
 	 */
@@ -771,7 +782,10 @@
 	}
 
 	/**
+	 * Get last modified timestamp of a file
+	 *
 	 * @param path
+	 *            file path
 	 * @return lastModified attribute for given file, not following symbolic
 	 *         links
 	 */
@@ -795,8 +809,10 @@
 	 * Return all the attributes of a file, without following symbolic links.
 	 *
 	 * @param file
+	 *            the file
 	 * @return {@link BasicFileAttributes} of the file
-	 * @throws IOException in case of any I/O errors accessing the file
+	 * @throws IOException
+	 *             in case of any I/O errors accessing the file
 	 *
 	 * @since 4.5.6
 	 */
@@ -808,8 +824,11 @@
 	 * Set the last modified time of a file system object.
 	 *
 	 * @param file
+	 *            the file
 	 * @param time
+	 *            last modified timestamp
 	 * @throws IOException
+	 *             if an IO error occurred
 	 */
 	@Deprecated
 	static void setLastModified(File file, long time) throws IOException {
@@ -820,8 +839,11 @@
 	 * Set the last modified time of a file system object.
 	 *
 	 * @param path
+	 *            file path
 	 * @param time
+	 *            last modified timestamp of the file
 	 * @throws IOException
+	 *             if an IO error occurred
 	 */
 	static void setLastModified(Path path, Instant time)
 			throws IOException {
@@ -830,6 +852,7 @@
 
 	/**
 	 * @param file
+	 *            the file
 	 * @return {@code true} if the given file exists, not following symbolic
 	 *         links
 	 */
@@ -838,9 +861,13 @@
 	}
 
 	/**
+	 * Check if file is hidden (on Windows)
+	 *
 	 * @param file
+	 *            the file
 	 * @return {@code true} if the given file is hidden
 	 * @throws IOException
+	 *             if an IO error occurred
 	 */
 	static boolean isHidden(File file) throws IOException {
 		return Files.isHidden(toPath(file));
@@ -854,6 +881,7 @@
 	 * @param hidden
 	 *            a boolean.
 	 * @throws java.io.IOException
+	 *             if an IO error occurred
 	 * @since 4.1
 	 */
 	public static void setHidden(File file, boolean hidden) throws IOException {
@@ -868,6 +896,7 @@
 	 *            a {@link java.io.File}.
 	 * @return length of the given file
 	 * @throws java.io.IOException
+	 *             if an IO error occurred
 	 * @since 4.1
 	 */
 	public static long getLength(File file) throws IOException {
@@ -879,7 +908,10 @@
 	}
 
 	/**
+	 * Check if file is directory
+	 *
 	 * @param file
+	 *            the file
 	 * @return {@code true} if the given file is a directory, not following
 	 *         symbolic links
 	 */
@@ -888,7 +920,10 @@
 	}
 
 	/**
+	 * Check if File is a file
+	 *
 	 * @param file
+	 *            the file
 	 * @return {@code true} if the given file is a file, not following symbolic
 	 *         links
 	 */
@@ -930,7 +965,9 @@
 
 	/**
 	 * @param fs
+	 *            a {@link org.eclipse.jgit.util.FS} object.
 	 * @param file
+	 *            the file
 	 * @return non null attributes object
 	 */
 	static Attributes getFileAttributesBasic(FS fs, File file) {
@@ -1079,6 +1116,7 @@
 	 * @param f
 	 *            the file to touch
 	 * @throws IOException
+	 *             if an IO error occurred
 	 * @since 5.1.8
 	 */
 	public static void touch(Path f) throws IOException {
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/util/HttpSupport.java b/org.eclipse.jgit/src/org/eclipse/jgit/util/HttpSupport.java
index e3ba606..1942342 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/util/HttpSupport.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/util/HttpSupport.java
@@ -321,6 +321,7 @@
 	 *            a {@link org.eclipse.jgit.transport.http.HttpConnection}
 	 *            object.
 	 * @throws java.io.IOException
+	 *             if an IO error occurred
 	 * @since 4.3
 	 */
 	public static void disableSslVerify(HttpConnection conn)
@@ -346,7 +347,9 @@
 	 * that have all available protocols enabled already, up to the one
 	 * specified.
 	 * <p>
+	 * <br>
 	 * <table>
+	 * <caption>TLS versions</caption>
 	 * <tr>
 	 * <td>SSLContext.getInstance()</td>
 	 * <td>OpenJDK</td>
@@ -354,16 +357,16 @@
 	 * </tr>
 	 * <tr>
 	 * <td>"TLS"</td>
-	 * <td>Supported: TLSv1, TLSV1.1, TLSv1.2 (+ TLSv1.3)<br />
+	 * <td>Supported: TLSv1, TLSV1.1, TLSv1.2 (+ TLSv1.3)<br>
 	 * Enabled: TLSv1, TLSV1.1, TLSv1.2 (+ TLSv1.3)</td>
-	 * <td>Supported: TLSv1, TLSV1.1, TLSv1.2<br />
+	 * <td>Supported: TLSv1, TLSV1.1, TLSv1.2<br>
 	 * Enabled: TLSv1</td>
 	 * </tr>
 	 * <tr>
 	 * <td>"TLSv1.2"</td>
-	 * <td>Supported: TLSv1, TLSV1.1, TLSv1.2<br />
+	 * <td>Supported: TLSv1, TLSV1.1, TLSv1.2<br>
 	 * Enabled: TLSv1, TLSV1.1, TLSv1.2</td>
-	 * <td>Supported: TLSv1, TLSV1.1, TLSv1.2<br />
+	 * <td>Supported: TLSv1, TLSV1.1, TLSv1.2<br>
 	 * Enabled: TLSv1.2</td>
 	 * </tr>
 	 * </table>
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 80877bb..8cc5316 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/util/IO.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/util/IO.java
@@ -66,19 +66,7 @@
 	public static final byte[] readSome(File path, int limit)
 			throws FileNotFoundException, IOException {
 		try (SilentFileInputStream in = new SilentFileInputStream(path)) {
-			byte[] buf = new byte[limit];
-			int cnt = 0;
-			for (;;) {
-				int n = in.read(buf, cnt, buf.length - cnt);
-				if (n <= 0)
-					break;
-				cnt += n;
-			}
-			if (cnt == buf.length)
-				return buf;
-			byte[] res = new byte[cnt];
-			System.arraycopy(buf, 0, res, 0, cnt);
-			return res;
+			return in.readNBytes(limit);
 		}
 	}
 
@@ -99,37 +87,10 @@
 	public static final byte[] readFully(File path, int max)
 			throws FileNotFoundException, IOException {
 		try (SilentFileInputStream in = new SilentFileInputStream(path)) {
-			long sz = Math.max(path.length(), 1);
-			if (sz > max)
+			byte[] buf = in.readNBytes(max);
+			if (in.read() != -1) {
 				throw new IOException(MessageFormat.format(
 						JGitText.get().fileIsTooLarge, path));
-
-			byte[] buf = new byte[(int) sz];
-			int valid = 0;
-			for (;;) {
-				if (buf.length == valid) {
-					if (buf.length == max) {
-						int next = in.read();
-						if (next < 0)
-							break;
-
-						throw new IOException(MessageFormat.format(
-								JGitText.get().fileIsTooLarge, path));
-					}
-
-					byte[] nb = new byte[Math.min(buf.length * 2, max)];
-					System.arraycopy(buf, 0, nb, 0, valid);
-					buf = nb;
-				}
-				int n = in.read(buf, valid, buf.length - valid);
-				if (n < 0)
-					break;
-				valid += n;
-			}
-			if (valid < buf.length) {
-				byte[] nb = new byte[valid];
-				System.arraycopy(buf, 0, nb, 0, valid);
-				buf = nb;
 			}
 			return buf;
 		}
@@ -157,26 +118,7 @@
 	 */
 	public static ByteBuffer readWholeStream(InputStream in, int sizeHint)
 			throws IOException {
-		byte[] out = new byte[sizeHint];
-		int pos = 0;
-		while (pos < out.length) {
-			int read = in.read(out, pos, out.length - pos);
-			if (read < 0)
-				return ByteBuffer.wrap(out, 0, pos);
-			pos += read;
-		}
-
-		int last = in.read();
-		if (last < 0)
-			return ByteBuffer.wrap(out, 0, pos);
-
-		try (TemporaryBuffer.Heap tmp = new TemporaryBuffer.Heap(
-				Integer.MAX_VALUE)) {
-			tmp.write(out);
-			tmp.write(last);
-			tmp.copy(in);
-			return ByteBuffer.wrap(tmp.toByteArray());
-		}
+		return ByteBuffer.wrap(in.readAllBytes());
 	}
 
 	/**
@@ -197,13 +139,9 @@
 	 */
 	public static void readFully(final InputStream fd, final byte[] dst,
 			int off, int len) throws IOException {
-		while (len > 0) {
-			final int r = fd.read(dst, off, len);
-			if (r <= 0)
-				throw new EOFException(JGitText.get().shortReadOfBlock);
-			off += r;
-			len -= r;
-		}
+		int read = fd.readNBytes(dst, off, len);
+		if (read != len)
+			throw new EOFException(JGitText.get().shortReadOfBlock);
 	}
 
 	/**
@@ -271,14 +209,7 @@
 	 */
 	public static int readFully(InputStream fd, byte[] dst, int off)
 			throws IOException {
-		int r;
-		int len = 0;
-		while (off < dst.length
-				&& (r = fd.read(dst, off, dst.length - off)) >= 0) {
-			off += r;
-			len += r;
-		}
-		return len;
+		return fd.readNBytes(dst, off, dst.length - off);
 	}
 
 	/**
@@ -300,6 +231,7 @@
 	 */
 	public static void skipFully(InputStream fd, long toSkip)
 			throws IOException {
+		// same as fd.skipNBytes(toSkip) of JDK 12;
 		while (toSkip > 0) {
 			final long r = fd.skip(toSkip);
 			if (r <= 0)
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/util/IntList.java b/org.eclipse.jgit/src/org/eclipse/jgit/util/IntList.java
index 635dd6a..6a5190c 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/util/IntList.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/util/IntList.java
@@ -204,7 +204,6 @@
 		entries = n;
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public String toString() {
 		final StringBuilder r = new StringBuilder();
@@ -232,8 +231,8 @@
 		 *            the first int to compare
 		 * @param second
 		 *            the second int to compare
-		 * @return a negative number if first < second, 0 if first == second, or
-		 *         a positive number if first > second
+		 * @return a negative number if first &lt; second, 0 if first == second, or
+		 *         a positive number if first &gt; second
 		 */
 		int compare(int first, int second);
 	}
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/util/LfsFactory.java b/org.eclipse.jgit/src/org/eclipse/jgit/util/LfsFactory.java
index 7456c71..d0b7b9f 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/util/LfsFactory.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/util/LfsFactory.java
@@ -105,6 +105,7 @@
 	 * @return a loader for the actual data of a blob, or the original loader in
 	 *         case LFS is not applicable.
 	 * @throws IOException
+	 *             if an IO error occurred
 	 */
 	public ObjectLoader applySmudgeFilter(Repository db,
 			ObjectLoader loader, Attribute attribute) throws IOException {
@@ -117,6 +118,7 @@
 	 * @param repo
 	 *            the {@link Repository} the hook is applied to.
 	 * @param outputStream
+	 *            output stream
 	 * @return a {@link PrePushHook} implementation or <code>null</code>
 	 */
 	@Nullable
@@ -131,7 +133,9 @@
 	 * @param repo
 	 *            the {@link Repository} the hook is applied to.
 	 * @param outputStream
+	 *            output stream
 	 * @param errorStream
+	 *            error stream
 	 * @return a {@link PrePushHook} implementation or <code>null</code>
 	 * @since 5.6
 	 */
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/util/LongList.java b/org.eclipse.jgit/src/org/eclipse/jgit/util/LongList.java
index b2bdfc1..47f38f4 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/util/LongList.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/util/LongList.java
@@ -140,7 +140,6 @@
 		entries = n;
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public String toString() {
 		final StringBuilder r = new StringBuilder();
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/util/RawCharSequence.java b/org.eclipse.jgit/src/org/eclipse/jgit/util/RawCharSequence.java
index 3de7a15..be4bd9e 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/util/RawCharSequence.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/util/RawCharSequence.java
@@ -41,25 +41,21 @@
 		endPtr = end;
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public char charAt(int index) {
 		return (char) (buffer[startPtr + index] & 0xff);
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public int length() {
 		return endPtr - startPtr;
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public CharSequence subSequence(int start, int end) {
 		return new RawCharSequence(buffer, startPtr + start, startPtr + end);
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public String toString() {
 		final int n = length();
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/util/RawParseUtils.java b/org.eclipse.jgit/src/org/eclipse/jgit/util/RawParseUtils.java
index 0e8e9b3..00e55f5 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/util/RawParseUtils.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/util/RawParseUtils.java
@@ -868,6 +868,26 @@
 	}
 
 	/**
+	 * Parse the "encoding " header into a character set reference.
+	 * <p>
+	 * If unsuccessful, return UTF-8.
+	 *
+	 * @param buffer
+	 *            buffer to scan.
+	 * @return the Java character set representation. Never null. Default to
+	 *         UTF-8.
+	 * @see #parseEncoding(byte[])
+	 * @since 6.7
+	 */
+	public static Charset guessEncoding(byte[] buffer) {
+		try {
+			return parseEncoding(buffer);
+		} catch (IllegalCharsetNameException | UnsupportedCharsetException e) {
+			return UTF_8;
+		}
+	}
+
+	/**
 	 * Parse a name string (e.g. author, committer, tagger) into a PersonIdent.
 	 * <p>
 	 * Leading spaces won't be trimmed from the string, i.e. will show up in the
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/util/RawSubStringPattern.java b/org.eclipse.jgit/src/org/eclipse/jgit/util/RawSubStringPattern.java
index 57464f3..04fdcd0 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/util/RawSubStringPattern.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/util/RawSubStringPattern.java
@@ -98,7 +98,6 @@
 		return needleString;
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public String toString() {
 		return pattern();
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/util/RefList.java b/org.eclipse.jgit/src/org/eclipse/jgit/util/RefList.java
index 462bab0..2a287cf 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/util/RefList.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/util/RefList.java
@@ -43,6 +43,8 @@
 	/**
 	 * Create an empty unmodifiable reference list.
 	 *
+	 * @param <T>
+	 *            type of reference being stored.
 	 * @return an empty unmodifiable reference list.
 	 */
 	@SuppressWarnings("unchecked")
@@ -70,7 +72,6 @@
 		this.cnt = src.cnt;
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public Iterator<Ref> iterator() {
 		return new Iterator<>() {
@@ -286,7 +287,6 @@
 		return add(idx, ref);
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public String toString() {
 		StringBuilder r = new StringBuilder();
@@ -305,6 +305,8 @@
 	/**
 	 * Create a {@link Collector} for {@link Ref}.
 	 *
+	 * @param <T>
+	 *            type of reference being stored.
 	 * @param mergeFunction
 	 *            if specified the result will be sorted and deduped.
 	 * @return {@link Collector} for {@link Ref}
@@ -390,6 +392,7 @@
 		 * after additions are complete using {@link #sort()}.
 		 *
 		 * @param ref
+		 *            reference to add
 		 */
 		public void add(T ref) {
 			if (list.length == size) {
@@ -404,6 +407,7 @@
 		 * Add all items from another builder.
 		 *
 		 * @param other
+		 *            another builder
 		 * @since 5.4
 		 */
 		public void addAll(Builder other) {
@@ -454,6 +458,7 @@
 		 * Dedupe the refs in place. Must be called after {@link #sort}.
 		 *
 		 * @param mergeFunction
+		 *            function used for de-duplication
 		 */
 		@SuppressWarnings("unchecked")
 		void dedupe(BinaryOperator<T> mergeFunction) {
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/util/RefMap.java b/org.eclipse.jgit/src/org/eclipse/jgit/util/RefMap.java
index c68a76c..a4d1fd5 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/util/RefMap.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/util/RefMap.java
@@ -119,13 +119,11 @@
 		this.resolved = (RefList<Ref>) resolved;
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public boolean containsKey(Object name) {
 		return get(name) != null;
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public Ref get(Object key) {
 		String name = toRefName((String) key);
@@ -137,7 +135,6 @@
 		return ref;
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public Ref put(String keyName, Ref value) {
 		String name = toRefName(keyName);
@@ -165,7 +162,6 @@
 		return prior;
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public Ref remove(Object key) {
 		String name = toRefName((String) key);
@@ -189,13 +185,11 @@
 		return res;
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public boolean isEmpty() {
 		return entrySet().isEmpty();
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public Set<Entry<String, Ref>> entrySet() {
 		if (entrySet == null) {
@@ -238,7 +232,6 @@
 		return entrySet;
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public String toString() {
 		StringBuilder r = new StringBuilder();
@@ -259,6 +252,7 @@
 	 * Create a {@link Collector} for {@link Ref}.
 	 *
 	 * @param mergeFunction
+	 *            merge function
 	 * @return {@link Collector} for {@link Ref}
 	 * @since 5.4
 	 */
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/util/SshSupport.java b/org.eclipse.jgit/src/org/eclipse/jgit/util/SshSupport.java
index e297041..42a76b5 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/util/SshSupport.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/util/SshSupport.java
@@ -48,6 +48,7 @@
 	 *            cases.
 	 * @return The entire output read from stdout.
 	 * @throws IOException
+	 *             if an IO error occurred
 	 * @throws CommandFailedException
 	 *             if the ssh command execution failed, error message contains
 	 *             the content of stderr.
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/util/StringUtils.java b/org.eclipse.jgit/src/org/eclipse/jgit/util/StringUtils.java
index 917add3..2747060 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/util/StringUtils.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/util/StringUtils.java
@@ -181,9 +181,9 @@
 	 *
 	 * @param stringValue
 	 *            the string to parse.
-	 * @return the boolean interpretation of {@code value}.
+	 * @return the boolean interpretation of {@code stringValue}.
 	 * @throws java.lang.IllegalArgumentException
-	 *             if {@code value} is not recognized as one of the standard
+	 *             if {@code stringValue} is not recognized as one of the standard
 	 *             boolean names.
 	 */
 	public static boolean toBoolean(String stringValue) {
@@ -346,7 +346,7 @@
 	 *            allow negative numbers, too
 	 * @return the value parsed
 	 * @throws NumberFormatException
-	 *             if the {@value} is not parseable, or beyond the range of
+	 *             if the {@code value} is not parseable, or beyond the range of
 	 *             {@link Long}
 	 * @throws StringIndexOutOfBoundsException
 	 *             if the string is empty or contains only whitespace, or
@@ -420,7 +420,7 @@
 	 *            allow negative numbers, too
 	 * @return the value parsed
 	 * @throws NumberFormatException
-	 *             if the {@value} is not parseable or beyond the range of
+	 *             if the {@code value} is not parseable or beyond the range of
 	 *             {@link Integer}
 	 * @throws StringIndexOutOfBoundsException
 	 *             if the string is empty or contains only whitespace, or
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/util/SystemReader.java b/org.eclipse.jgit/src/org/eclipse/jgit/util/SystemReader.java
index a8a7790..4a48762 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/util/SystemReader.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/util/SystemReader.java
@@ -39,6 +39,7 @@
 import org.eclipse.jgit.lib.ObjectChecker;
 import org.eclipse.jgit.lib.StoredConfig;
 import org.eclipse.jgit.storage.file.FileBasedConfig;
+import org.eclipse.jgit.storage.file.UserConfigFile;
 import org.eclipse.jgit.util.time.MonotonicClock;
 import org.eclipse.jgit.util.time.MonotonicSystemClock;
 import org.slf4j.Logger;
@@ -124,28 +125,20 @@
 
 		@Override
 		public FileBasedConfig openUserConfig(Config parent, FS fs) {
-			return new FileBasedConfig(parent, new File(fs.userHome(), ".gitconfig"), //$NON-NLS-1$
-					fs);
-		}
-
-		private Path getXDGConfigHome(FS fs) {
-			String configHomePath = getenv(Constants.XDG_CONFIG_HOME);
-			if (StringUtils.isEmptyOrNull(configHomePath)) {
-				configHomePath = new File(fs.userHome(), ".config") //$NON-NLS-1$
-						.getAbsolutePath();
+			File homeFile = new File(fs.userHome(), ".gitconfig"); //$NON-NLS-1$
+			Path xdgPath = getXdgConfigDirectory(fs);
+			if (xdgPath != null) {
+				Path configPath = xdgPath.resolve("git") //$NON-NLS-1$
+						.resolve(Constants.CONFIG);
+				return new UserConfigFile(parent, homeFile, configPath.toFile(),
+						fs);
 			}
-			try {
-				return Paths.get(configHomePath);
-			} catch (InvalidPathException e) {
-				LOG.error(JGitText.get().logXDGConfigHomeInvalid,
-						configHomePath, e);
-			}
-			return null;
+			return new FileBasedConfig(parent, homeFile, fs);
 		}
 
 		@Override
 		public FileBasedConfig openJGitConfig(Config parent, FS fs) {
-			Path xdgPath = getXDGConfigHome(fs);
+			Path xdgPath = getXdgConfigDirectory(fs);
 			if (xdgPath != null) {
 				Path configPath = xdgPath.resolve("jgit") //$NON-NLS-1$
 						.resolve(Constants.CONFIG);
@@ -391,6 +384,36 @@
 	}
 
 	/**
+	 * Gets the directory denoted by environment variable XDG_CONFIG_HOME. If
+	 * the variable is not set or empty, return a path for
+	 * {@code $HOME/.config}.
+	 *
+	 * @param fileSystem
+	 *            {@link FS} to get the user's home directory
+	 * @return a {@link Path} denoting the directory, which may exist or not, or
+	 *         {@code null} if the environment variable is not set and there is
+	 *         no home directory, or the path is invalid.
+	 * @since 6.7
+	 */
+	public Path getXdgConfigDirectory(FS fileSystem) {
+		String configHomePath = getenv(Constants.XDG_CONFIG_HOME);
+		if (StringUtils.isEmptyOrNull(configHomePath)) {
+			File home = fileSystem.userHome();
+			if (home == null) {
+				return null;
+			}
+			configHomePath = new File(home, ".config").getAbsolutePath(); //$NON-NLS-1$
+		}
+		try {
+			return Paths.get(configHomePath);
+		} catch (InvalidPathException e) {
+			LOG.error(JGitText.get().logXDGConfigHomeInvalid, configHomePath,
+					e);
+		}
+		return null;
+	}
+
+	/**
 	 * Update config and its parents if they seem modified
 	 *
 	 * @param config
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/util/io/AutoCRLFInputStream.java b/org.eclipse.jgit/src/org/eclipse/jgit/util/io/AutoCRLFInputStream.java
index cedb159..ccc1969 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/util/io/AutoCRLFInputStream.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/util/io/AutoCRLFInputStream.java
@@ -57,14 +57,12 @@
 		this.detectBinary = detectBinary;
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public int read() throws IOException {
 		final int read = read(single, 0, 1);
 		return read == 1 ? single[0] & 0xff : -1;
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public int read(byte[] bs, int off, int len) throws IOException {
 		if (len == 0)
@@ -103,7 +101,6 @@
 		return n;
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public void close() throws IOException {
 		in.close();
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/util/io/AutoCRLFOutputStream.java b/org.eclipse.jgit/src/org/eclipse/jgit/util/io/AutoCRLFOutputStream.java
index 305ccbd..9fb316f 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/util/io/AutoCRLFOutputStream.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/util/io/AutoCRLFOutputStream.java
@@ -65,14 +65,12 @@
 		this.detectBinary = detectBinary;
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public void write(int b) throws IOException {
 		onebytebuf[0] = (byte) b;
 		write(onebytebuf, 0, 1);
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public void write(byte[] b) throws IOException {
 		int overflow = buffer(b, 0, b.length);
@@ -80,7 +78,6 @@
 			write(b, b.length - overflow, overflow);
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public void write(byte[] b, int startOff, int startLen)
 			throws IOException {
@@ -151,7 +148,6 @@
 		write(binbuf, 0, cachedLen);
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public void flush() throws IOException {
 		if (binbufcnt <= binbuf.length) {
@@ -161,7 +157,6 @@
 		out.flush();
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public void close() throws IOException {
 		flush();
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/util/io/AutoLFInputStream.java b/org.eclipse.jgit/src/org/eclipse/jgit/util/io/AutoLFInputStream.java
index 7db882c..2385865 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/util/io/AutoLFInputStream.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/util/io/AutoLFInputStream.java
@@ -185,14 +185,12 @@
 		this.forCheckout = false;
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public int read() throws IOException {
 		final int read = read(single, 0, 1);
 		return read == 1 ? single[0] & 0xff : -1;
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public int read(byte[] bs, int off, int len)
 			throws IOException {
@@ -242,7 +240,6 @@
 		return isBinary;
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public void close() throws IOException {
 		in.close();
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/util/io/AutoLFOutputStream.java b/org.eclipse.jgit/src/org/eclipse/jgit/util/io/AutoLFOutputStream.java
index a0e9fb6..e56991d 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/util/io/AutoLFOutputStream.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/util/io/AutoLFOutputStream.java
@@ -69,14 +69,12 @@
 		this.detectBinary = detectBinary;
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public void write(int b) throws IOException {
 		onebytebuf[0] = (byte) b;
 		write(onebytebuf, 0, 1);
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public void write(byte[] b) throws IOException {
 		int overflow = buffer(b, 0, b.length);
@@ -85,7 +83,6 @@
 		}
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public void write(byte[] b, int startOff, int startLen)
 			throws IOException {
@@ -164,7 +161,6 @@
 		write(binbuf, 0, cachedLen);
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public void flush() throws IOException {
 		if (binbufcnt <= binbuf.length) {
@@ -173,7 +169,6 @@
 		out.flush();
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public void close() throws IOException {
 		flush();
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/util/io/CountingOutputStream.java b/org.eclipse.jgit/src/org/eclipse/jgit/util/io/CountingOutputStream.java
index 782f3f4..d0049d2 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/util/io/CountingOutputStream.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/util/io/CountingOutputStream.java
@@ -39,27 +39,23 @@
 		return cnt;
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public void write(int val) throws IOException {
 		out.write(val);
 		cnt++;
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public void write(byte[] buf, int off, int len) throws IOException {
 		out.write(buf, off, len);
 		cnt += len;
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public void flush() throws IOException {
 		out.flush();
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public void close() throws IOException {
 		out.close();
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/util/io/DisabledOutputStream.java b/org.eclipse.jgit/src/org/eclipse/jgit/util/io/DisabledOutputStream.java
index f1bfbe2..03c25bb 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/util/io/DisabledOutputStream.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/util/io/DisabledOutputStream.java
@@ -27,7 +27,6 @@
 		// more than one instance from being created.
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public void write(int b) throws IOException {
 		// We shouldn't be writing output at this stage, there
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/util/io/IsolatedOutputStream.java b/org.eclipse.jgit/src/org/eclipse/jgit/util/io/IsolatedOutputStream.java
index 2bbdbef..1faf6ea 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/util/io/IsolatedOutputStream.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/util/io/IsolatedOutputStream.java
@@ -58,13 +58,11 @@
 				new ArrayBlockingQueue<>(1), new NamedThreadFactory());
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public void write(int ch) throws IOException {
 		write(new byte[] { (byte) ch }, 0, 1);
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public void write(byte[] buf, int pos, int cnt)
 			throws IOException {
@@ -75,7 +73,6 @@
 		});
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public void flush() throws IOException {
 		checkClosed();
@@ -85,7 +82,6 @@
 		});
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public void close() throws IOException {
 		if (!copier.isShutdown()) {
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/util/io/LimitedInputStream.java b/org.eclipse.jgit/src/org/eclipse/jgit/util/io/LimitedInputStream.java
index 8800624..681a529 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/util/io/LimitedInputStream.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/util/io/LimitedInputStream.java
@@ -47,21 +47,18 @@
 		this.limit = limit;
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public int available() throws IOException {
 		return (int) Math.min(in.available(), left);
 	}
 
 	// it's okay to mark even if mark isn't supported, as reset won't work
-	/** {@inheritDoc} */
 	@Override
 	public synchronized void mark(int readLimit) {
 		in.mark(readLimit);
 		mark = left;
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public int read() throws IOException {
 		if (left == 0) {
@@ -78,7 +75,6 @@
 		return result;
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public int read(byte[] b, int off, int len) throws IOException {
 		if (left == 0) {
@@ -96,7 +92,6 @@
 		return result;
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public synchronized void reset() throws IOException {
 		if (!in.markSupported())
@@ -109,7 +104,6 @@
 		left = mark;
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public long skip(long n) throws IOException {
 		n = Math.min(n, left);
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/util/io/MessageWriter.java b/org.eclipse.jgit/src/org/eclipse/jgit/util/io/MessageWriter.java
index 2637766..8d5b8fd 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/util/io/MessageWriter.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/util/io/MessageWriter.java
@@ -51,7 +51,6 @@
 		enc = new OutputStreamWriter(getRawStream(), UTF_8);
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public void write(char[] cbuf, int off, int len) throws IOException {
 		synchronized (buf) {
@@ -71,20 +70,17 @@
 		return buf;
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public void close() throws IOException {
 		// Do nothing, we are buffered with no resources.
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public void flush() throws IOException {
 		// Do nothing, we are buffered with no resources.
 	}
 
 	/** @return string version of all buffered data. */
-	/** {@inheritDoc} */
 	@Override
 	public String toString() {
 		return RawParseUtils.decode(buf.toByteArray());
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/util/io/StreamCopyThread.java b/org.eclipse.jgit/src/org/eclipse/jgit/util/io/StreamCopyThread.java
index c0724e4..ed412fa 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/util/io/StreamCopyThread.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/util/io/StreamCopyThread.java
@@ -67,7 +67,6 @@
 		}
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public void run() {
 		try {
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/util/io/TeeInputStream.java b/org.eclipse.jgit/src/org/eclipse/jgit/util/io/TeeInputStream.java
index 56d0169..96376bf 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/util/io/TeeInputStream.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/util/io/TeeInputStream.java
@@ -46,7 +46,6 @@
 		this.dst = dst;
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public int read() throws IOException {
 		byte[] b = skipBuffer();
@@ -54,7 +53,6 @@
 		return n == 1 ? b[0] & 0xff : -1;
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public long skip(long count) throws IOException {
 		long skipped = 0;
@@ -71,7 +69,6 @@
 		return skipped;
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public int read(byte[] b, int off, int len) throws IOException {
 		if (len == 0)
@@ -83,7 +80,6 @@
 		return n;
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public void close() throws IOException {
 		byte[] b = skipBuffer();
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/util/io/TeeOutputStream.java b/org.eclipse.jgit/src/org/eclipse/jgit/util/io/TeeOutputStream.java
index e6fdd70..ab084a6 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/util/io/TeeOutputStream.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/util/io/TeeOutputStream.java
@@ -34,35 +34,30 @@
 		this.stream2 = stream2;
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public void write(byte[] buf) throws IOException {
 		this.stream1.write(buf);
 		this.stream2.write(buf);
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public void write(byte[] buf, int off, int len) throws IOException {
 		this.stream1.write(buf, off, len);
 		this.stream2.write(buf, off, len);
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public void write(int b) throws IOException {
 		this.stream1.write(b);
 		this.stream2.write(b);
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public void flush() throws IOException {
 		this.stream1.flush();
 		this.stream2.flush();
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public void close() throws IOException {
 		try {
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/util/io/ThrowingPrintWriter.java b/org.eclipse.jgit/src/org/eclipse/jgit/util/io/ThrowingPrintWriter.java
index 3bc92d5..4764676 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/util/io/ThrowingPrintWriter.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/util/io/ThrowingPrintWriter.java
@@ -41,19 +41,16 @@
 				);
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public void write(char[] cbuf, int off, int len) throws IOException {
 		out.write(cbuf, off, len);
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public void flush() throws IOException {
 		out.flush();
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public void close() throws IOException {
 		out.close();
@@ -62,8 +59,10 @@
 	/**
 	 * Print a string and terminate with a line feed.
 	 *
-	 * @param s a {@link java.lang.String} object.
+	 * @param s
+	 *            a {@link java.lang.String} object.
 	 * @throws java.io.IOException
+	 *             if an IO error occurred
 	 */
 	public void println(String s) throws IOException {
 		print(s + LF);
@@ -73,6 +72,7 @@
 	 * Print a platform dependent new line
 	 *
 	 * @throws java.io.IOException
+	 *             if an IO error occurred
 	 */
 	public void println() throws IOException {
 		print(LF);
@@ -81,8 +81,10 @@
 	/**
 	 * Print a char
 	 *
-	 * @param value a char.
+	 * @param value
+	 *            a char.
 	 * @throws java.io.IOException
+	 *             if an IO error occurred
 	 */
 	public void print(char value) throws IOException {
 		print(String.valueOf(value));
@@ -94,6 +96,7 @@
 	 * @param value
 	 *            an int.
 	 * @throws java.io.IOException
+	 *             if an IO error occurred
 	 */
 	public void print(int value) throws IOException {
 		print(String.valueOf(value));
@@ -102,8 +105,10 @@
 	/**
 	 * Print a long as string
 	 *
-	 * @param value a long.
+	 * @param value
+	 *            a long.
 	 * @throws java.io.IOException
+	 *             if an IO error occurred
 	 */
 	public void print(long value) throws IOException {
 		print(String.valueOf(value));
@@ -112,8 +117,10 @@
 	/**
 	 * Print a short as string
 	 *
-	 * @param value a short.
+	 * @param value
+	 *            a short.
 	 * @throws java.io.IOException
+	 *             if an IO error occurred
 	 */
 	public void print(short value) throws IOException {
 		print(String.valueOf(value));
@@ -128,6 +135,7 @@
 	 * @param args
 	 *            objects.
 	 * @throws java.io.IOException
+	 *             if an IO error occurred
 	 */
 	public void format(String fmt, Object... args) throws IOException {
 		print(String.format(fmt, args));
@@ -139,6 +147,7 @@
 	 * @param any
 	 *            an object.
 	 * @throws java.io.IOException
+	 *             if an IO error occurred
 	 */
 	public void print(Object any) throws IOException {
 		out.write(String.valueOf(any));
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/util/io/TimeoutInputStream.java b/org.eclipse.jgit/src/org/eclipse/jgit/util/io/TimeoutInputStream.java
index 1947b3b..4d9f83d 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/util/io/TimeoutInputStream.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/util/io/TimeoutInputStream.java
@@ -63,7 +63,6 @@
 		timeout = millis;
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public int read() throws IOException {
 		try {
@@ -76,13 +75,11 @@
 		}
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public int read(byte[] buf) throws IOException {
 		return read(buf, 0, buf.length);
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public int read(byte[] buf, int off, int cnt) throws IOException {
 		try {
@@ -95,7 +92,6 @@
 		}
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public long skip(long cnt) throws IOException {
 		try {
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/util/io/TimeoutOutputStream.java b/org.eclipse.jgit/src/org/eclipse/jgit/util/io/TimeoutOutputStream.java
index 3fbf6ff..afd798a 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/util/io/TimeoutOutputStream.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/util/io/TimeoutOutputStream.java
@@ -65,7 +65,6 @@
 		timeout = millis;
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public void write(int b) throws IOException {
 		try {
@@ -78,13 +77,11 @@
 		}
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public void write(byte[] buf) throws IOException {
 		write(buf, 0, buf.length);
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public void write(byte[] buf, int off, int len) throws IOException {
 		try {
@@ -97,7 +94,6 @@
 		}
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public void flush() throws IOException {
 		try {
@@ -110,7 +106,6 @@
 		}
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public void close() throws IOException {
 		try {
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/util/io/UnionInputStream.java b/org.eclipse.jgit/src/org/eclipse/jgit/util/io/UnionInputStream.java
index 4598881..b37f28b 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/util/io/UnionInputStream.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/util/io/UnionInputStream.java
@@ -91,7 +91,6 @@
 		return streams.isEmpty();
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public int read() throws IOException {
 		for (;;) {
@@ -106,7 +105,6 @@
 		}
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public int read(byte[] b, int off, int len) throws IOException {
 		if (len == 0)
@@ -123,13 +121,11 @@
 		}
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public int available() throws IOException {
 		return head().available();
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public long skip(long count) throws IOException {
 		long skipped = 0;
@@ -163,7 +159,6 @@
 		return skipped;
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public void close() throws IOException {
 		IOException err = null;
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/util/sha1/SHA1.java b/org.eclipse.jgit/src/org/eclipse/jgit/util/sha1/SHA1.java
index 56e90d0..0a56c83 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/util/sha1/SHA1.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/util/sha1/SHA1.java
@@ -193,7 +193,6 @@
 	 * <p>
 	 * Implementations not supporting collision detection always return
 	 * {@code false}.
-	 * <p>
 	 *
 	 * @return {@code true} if a likely collision was detected.
 	 */
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/util/time/MonotonicSystemClock.java b/org.eclipse.jgit/src/org/eclipse/jgit/util/time/MonotonicSystemClock.java
index 66857b5..4e079f0 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/util/time/MonotonicSystemClock.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/util/time/MonotonicSystemClock.java
@@ -37,7 +37,6 @@
 		}
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public ProposedTimestamp propose() {
 		final long u = nowMicros();
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/util/time/ProposedTimestamp.java b/org.eclipse.jgit/src/org/eclipse/jgit/util/time/ProposedTimestamp.java
index 8c20423..a5ee107 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/util/time/ProposedTimestamp.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/util/time/ProposedTimestamp.java
@@ -162,7 +162,6 @@
 		// Do nothing by default.
 	}
 
-	/** {@inheritDoc} */
 	@Override
 	public String toString() {
 		return instant().toString();
diff --git a/pom.xml b/pom.xml
index 873958c..3304587 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.6.2-SNAPSHOT</version>
+  <version>6.7.1-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.5.0.202303070854-r</jgit-last-release-version>
+    <jgit-last-release-version>6.6.0.202305301015-r</jgit-last-release-version>
     <ant-version>1.10.12</ant-version>
     <apache-sshd-version>2.10.0</apache-sshd-version>
     <jsch-version>0.1.55</jsch-version>
@@ -169,7 +169,7 @@
     <slf4j-version>1.7.36</slf4j-version>
     <maven-javadoc-plugin-version>3.5.0</maven-javadoc-plugin-version>
     <gson-version>2.10.1</gson-version>
-    <bouncycastle-version>1.73</bouncycastle-version>
+    <bouncycastle-version>1.76</bouncycastle-version>
     <spotbugs-maven-plugin-version>4.7.3.4</spotbugs-maven-plugin-version>
     <maven-project-info-reports-plugin-version>3.4.3</maven-project-info-reports-plugin-version>
     <maven-jxr-plugin-version>3.3.0</maven-jxr-plugin-version>
@@ -204,10 +204,6 @@
       <url>https://repo.eclipse.org/content/repositories/cbi-releases/</url>
     </pluginRepository>
     <pluginRepository>
-      <id>repo.eclipse.org.cbi-snapshots</id>
-      <url>https://repo.eclipse.org/content/repositories/cbi-snapshots/</url>
-    </pluginRepository>
-    <pluginRepository>
       <id>repo.eclipse.org.dash-releases</id>
       <url>https://repo.eclipse.org/content/repositories/dash-licenses-releases/</url>
     </pluginRepository>
@@ -262,7 +258,7 @@
         <plugin>
           <groupId>org.apache.maven.plugins</groupId>
           <artifactId>maven-source-plugin</artifactId>
-          <version>3.2.1</version>
+          <version>3.3.0</version>
         </plugin>
 
         <plugin>
@@ -285,7 +281,7 @@
         <plugin>
           <groupId>org.codehaus.mojo</groupId>
           <artifactId>build-helper-maven-plugin</artifactId>
-          <version>3.3.0</version>
+          <version>3.4.0</version>
         </plugin>
 
         <plugin>
@@ -331,7 +327,7 @@
         <plugin>
           <groupId>org.eclipse.cbi.maven.plugins</groupId>
           <artifactId>eclipse-jarsigner-plugin</artifactId>
-          <version>1.3.5</version>
+          <version>1.4.2</version>
         </plugin>
         <plugin>
           <groupId>org.jacoco</groupId>
@@ -341,7 +337,7 @@
         <plugin>
           <groupId>org.apache.maven.plugins</groupId>
           <artifactId>maven-site-plugin</artifactId>
-          <version>3.12.1</version>
+          <version>4.0.0-M9</version>
           <dependencies>
             <dependency><!-- add support for ssh/scp -->
               <groupId>org.apache.maven.wagon</groupId>
@@ -388,7 +384,7 @@
         <plugin>
           <groupId>org.springframework.boot</groupId>
           <artifactId>spring-boot-maven-plugin</artifactId>
-          <version>2.7.11</version>
+          <version>2.7.13</version>
         </plugin>
         <plugin>
           <groupId>org.eclipse.dash</groupId>
@@ -465,13 +461,38 @@
         <groupId>org.apache.maven.plugins</groupId>
         <artifactId>maven-javadoc-plugin</artifactId>
         <configuration>
-          <additionalJOption>-Xdoclint:-missing</additionalJOption>
+          <!-- We check javadoc when compiling with ecj (option -Pecj) and configurations
+          set in .settings/org.eclipse.jdt.core.prefs. This allows more fine grained
+          configuration and fails the build on missing javadoc for protected and
+          public but not for private classes, methods and fields. We don't want
+          to check javadoc on tests. We can reconsider to configure this on javadoc
+          when it starts supporting access specifiers so that we can set
+          -Xdoclint:all,-missing/private -->
+          <additionalJOption>-Xdoclint:none</additionalJOption>
           <encoding>${project.build.sourceEncoding}</encoding>
           <quiet>true</quiet>
+          <failOnWarnings>true</failOnWarnings>
           <excludePackageNames>org.eclipse.jgit.http.test</excludePackageNames>
           <links>
             <link>https://docs.oracle.com/en/java/javase/11/docs/api</link>
           </links>
+          <tags>
+            <tag>
+              <name>apiNote</name>
+              <placement>a</placement>
+              <head>API Note:</head>
+            </tag>
+            <tag>
+              <name>implSpec</name>
+              <placement>a</placement>
+              <head>Implementation Requirements:</head>
+            </tag>
+            <tag>
+              <name>implNote</name>
+              <placement>a</placement>
+              <head>Implementation Note:</head>
+            </tag>
+          </tags>
         </configuration>
         <executions>
           <execution>
@@ -589,7 +610,32 @@
           </reportSet>
         </reportSets>
         <configuration>
-          <additionalJOption>-Xdoclint:-missing</additionalJOption>
+          <failOnWarnings>false</failOnWarnings>
+          <additionalJOption>-Xdoclint:none</additionalJOption>
+          <encoding>${project.build.sourceEncoding}</encoding>
+          <quiet>true</quiet>
+          <failOnWarnings>false</failOnWarnings>
+          <excludePackageNames>org.eclipse.jgit.http.test</excludePackageNames>
+          <links>
+            <link>https://docs.oracle.com/en/java/javase/11/docs/api</link>
+          </links>
+          <tags>
+            <tag>
+              <name>apiNote</name>
+              <placement>a</placement>
+              <head>API Note:</head>
+            </tag>
+            <tag>
+              <name>implSpec</name>
+              <placement>a</placement>
+              <head>Implementation Requirements:</head>
+            </tag>
+            <tag>
+              <name>implNote</name>
+              <placement>a</placement>
+              <head>Implementation Note:</head>
+            </tag>
+          </tags>
         </configuration>
       </plugin>
       <plugin>
@@ -890,7 +936,7 @@
               <dependency>
                 <groupId>org.eclipse.jdt</groupId>
                 <artifactId>ecj</artifactId>
-                <version>3.33.0</version>
+                <version>3.34.0</version>
               </dependency>
             </dependencies>
           </plugin>