Merge branch 'stable-6.1' into stable-6.2

* stable-6.1:
  HTTP Smart: set correct HTTP status on error

Change-Id: I792d6cdfe9e76a3d2e6d1e01ec1dc96805ed2900
diff --git a/DEPENDENCIES b/DEPENDENCIES
index 93fa850..59c456e 100644
--- a/DEPENDENCIES
+++ b/DEPENDENCIES
@@ -2,7 +2,7 @@
 maven/mavencentral/com.google.code.gson/gson/2.8.9, Apache-2.0, approved, CQ23496
 maven/mavencentral/com.googlecode.javaewah/JavaEWAH/1.1.13, Apache-2.0, approved, CQ11658
 maven/mavencentral/com.jcraft/jsch/0.1.55, BSD-3-Clause, approved, CQ19435
-maven/mavencentral/com.jcraft/jzlib/1.1.1, BSD-2-Clause, approved, CQ6218
+maven/mavencentral/com.jcraft/jzlib/1.1.3, BSD-2-Clause, approved, CQ6218
 maven/mavencentral/commons-codec/commons-codec/1.11, Apache-2.0 AND BSD-3-Clause, approved, CQ15971
 maven/mavencentral/commons-logging/commons-logging/1.2, Apache-2.0, approved, CQ10162
 maven/mavencentral/javax.servlet/javax.servlet-api/4.0.0, , approved, CQ16125
@@ -19,6 +19,8 @@
 maven/mavencentral/org.apache.commons/commons-math3/3.2, Apache-2.0, approved, clearlydefined
 maven/mavencentral/org.apache.httpcomponents/httpclient/4.5.13, Apache-2.0 AND LicenseRef-Public-Domain, approved, CQ23527
 maven/mavencentral/org.apache.httpcomponents/httpcore/4.4.14, Apache-2.0, approved, CQ23528
+maven/mavencentral/org.apache.sshd/sshd-common/2.8.0, Apache-2.0 AND ISC, approved, #2349
+maven/mavencentral/org.apache.sshd/sshd-core/2.8.0, Apache-2.0, approved, #2331
 maven/mavencentral/org.apache.sshd/sshd-osgi/2.8.0, Apache-2.0, approved, CQ23892
 maven/mavencentral/org.apache.sshd/sshd-sftp/2.8.0, Apache-2.0, approved, CQ23893
 maven/mavencentral/org.assertj/assertj-core/3.20.2, Apache-2.0, approved, clearlydefined
@@ -33,29 +35,29 @@
 maven/mavencentral/org.eclipse.jetty/jetty-server/10.0.6, EPL-2.0 OR Apache-2.0, approved, rt.jetty
 maven/mavencentral/org.eclipse.jetty/jetty-servlet/10.0.6, EPL-2.0 OR Apache-2.0, approved, rt.jetty
 maven/mavencentral/org.eclipse.jetty/jetty-util/10.0.6, EPL-2.0 OR Apache-2.0, approved, rt.jetty
-maven/mavencentral/org.eclipse.jgit/org.eclipse.jgit.ant.test/6.1.0-SNAPSHOT, BSD-3-Clause, approved, technology.jgit
-maven/mavencentral/org.eclipse.jgit/org.eclipse.jgit.ant/6.1.0-SNAPSHOT, BSD-3-Clause, approved, technology.jgit
-maven/mavencentral/org.eclipse.jgit/org.eclipse.jgit.archive/6.1.0-SNAPSHOT, BSD-3-Clause, approved, technology.jgit
-maven/mavencentral/org.eclipse.jgit/org.eclipse.jgit.gpg.bc/6.1.0-SNAPSHOT, BSD-3-Clause, approved, technology.jgit
-maven/mavencentral/org.eclipse.jgit/org.eclipse.jgit.http.apache/6.1.0-SNAPSHOT, BSD-3-Clause, approved, technology.jgit
-maven/mavencentral/org.eclipse.jgit/org.eclipse.jgit.http.server/6.1.0-SNAPSHOT, BSD-3-Clause, approved, technology.jgit
-maven/mavencentral/org.eclipse.jgit/org.eclipse.jgit.http.test/6.1.0-SNAPSHOT, BSD-3-Clause, approved, technology.jgit
-maven/mavencentral/org.eclipse.jgit/org.eclipse.jgit.junit.http/6.1.0-SNAPSHOT, BSD-3-Clause, approved, technology.jgit
-maven/mavencentral/org.eclipse.jgit/org.eclipse.jgit.junit.ssh/6.1.0-SNAPSHOT, BSD-3-Clause, approved, technology.jgit
-maven/mavencentral/org.eclipse.jgit/org.eclipse.jgit.junit/6.1.0-SNAPSHOT, BSD-3-Clause, approved, technology.jgit
-maven/mavencentral/org.eclipse.jgit/org.eclipse.jgit.lfs.server.test/6.1.0-SNAPSHOT, BSD-3-Clause, approved, technology.jgit
-maven/mavencentral/org.eclipse.jgit/org.eclipse.jgit.lfs.server/6.1.0-SNAPSHOT, BSD-3-Clause, approved, technology.jgit
-maven/mavencentral/org.eclipse.jgit/org.eclipse.jgit.lfs.test/6.1.0-SNAPSHOT, BSD-3-Clause, approved, technology.jgit
-maven/mavencentral/org.eclipse.jgit/org.eclipse.jgit.lfs/6.1.0-SNAPSHOT, BSD-3-Clause, approved, technology.jgit
-maven/mavencentral/org.eclipse.jgit/org.eclipse.jgit.pgm.test/6.1.0-SNAPSHOT, BSD-3-Clause, approved, technology.jgit
-maven/mavencentral/org.eclipse.jgit/org.eclipse.jgit.pgm/6.1.0-SNAPSHOT, BSD-3-Clause, approved, technology.jgit
-maven/mavencentral/org.eclipse.jgit/org.eclipse.jgit.ssh.apache.agent/6.1.0-SNAPSHOT, BSD-3-Clause, approved, technology.jgit
-maven/mavencentral/org.eclipse.jgit/org.eclipse.jgit.ssh.apache.test/6.1.0-SNAPSHOT, BSD-3-Clause, approved, technology.jgit
-maven/mavencentral/org.eclipse.jgit/org.eclipse.jgit.ssh.apache/6.1.0-SNAPSHOT, BSD-3-Clause, approved, technology.jgit
-maven/mavencentral/org.eclipse.jgit/org.eclipse.jgit.ssh.jsch/6.1.0-SNAPSHOT, BSD-3-Clause, approved, technology.jgit
-maven/mavencentral/org.eclipse.jgit/org.eclipse.jgit.test/6.1.0-SNAPSHOT, BSD-3-Clause, approved, technology.jgit
-maven/mavencentral/org.eclipse.jgit/org.eclipse.jgit.ui/6.1.0-SNAPSHOT, BSD-3-Clause, approved, technology.jgit
-maven/mavencentral/org.eclipse.jgit/org.eclipse.jgit/6.1.0-SNAPSHOT, BSD-3-Clause, approved, technology.jgit
+maven/mavencentral/org.eclipse.jgit/org.eclipse.jgit.ant.test/6.2.0-SNAPSHOT, BSD-3-Clause, approved, technology.jgit
+maven/mavencentral/org.eclipse.jgit/org.eclipse.jgit.ant/6.2.0-SNAPSHOT, BSD-3-Clause, approved, technology.jgit
+maven/mavencentral/org.eclipse.jgit/org.eclipse.jgit.archive/6.2.0-SNAPSHOT, BSD-3-Clause, approved, technology.jgit
+maven/mavencentral/org.eclipse.jgit/org.eclipse.jgit.gpg.bc/6.2.0-SNAPSHOT, BSD-3-Clause, approved, technology.jgit
+maven/mavencentral/org.eclipse.jgit/org.eclipse.jgit.http.apache/6.2.0-SNAPSHOT, BSD-3-Clause, approved, technology.jgit
+maven/mavencentral/org.eclipse.jgit/org.eclipse.jgit.http.server/6.2.0-SNAPSHOT, BSD-3-Clause, approved, technology.jgit
+maven/mavencentral/org.eclipse.jgit/org.eclipse.jgit.http.test/6.2.0-SNAPSHOT, BSD-3-Clause, approved, technology.jgit
+maven/mavencentral/org.eclipse.jgit/org.eclipse.jgit.junit.http/6.2.0-SNAPSHOT, BSD-3-Clause, approved, technology.jgit
+maven/mavencentral/org.eclipse.jgit/org.eclipse.jgit.junit.ssh/6.2.0-SNAPSHOT, BSD-3-Clause, approved, technology.jgit
+maven/mavencentral/org.eclipse.jgit/org.eclipse.jgit.junit/6.2.0-SNAPSHOT, BSD-3-Clause, approved, technology.jgit
+maven/mavencentral/org.eclipse.jgit/org.eclipse.jgit.lfs.server.test/6.2.0-SNAPSHOT, BSD-3-Clause, approved, technology.jgit
+maven/mavencentral/org.eclipse.jgit/org.eclipse.jgit.lfs.server/6.2.0-SNAPSHOT, BSD-3-Clause, approved, technology.jgit
+maven/mavencentral/org.eclipse.jgit/org.eclipse.jgit.lfs.test/6.2.0-SNAPSHOT, BSD-3-Clause, approved, technology.jgit
+maven/mavencentral/org.eclipse.jgit/org.eclipse.jgit.lfs/6.2.0-SNAPSHOT, BSD-3-Clause, approved, technology.jgit
+maven/mavencentral/org.eclipse.jgit/org.eclipse.jgit.pgm.test/6.2.0-SNAPSHOT, BSD-3-Clause, approved, technology.jgit
+maven/mavencentral/org.eclipse.jgit/org.eclipse.jgit.pgm/6.2.0-SNAPSHOT, BSD-3-Clause, approved, technology.jgit
+maven/mavencentral/org.eclipse.jgit/org.eclipse.jgit.ssh.apache.agent/6.2.0-SNAPSHOT, BSD-3-Clause, approved, technology.jgit
+maven/mavencentral/org.eclipse.jgit/org.eclipse.jgit.ssh.apache.test/6.2.0-SNAPSHOT, BSD-3-Clause, approved, technology.jgit
+maven/mavencentral/org.eclipse.jgit/org.eclipse.jgit.ssh.apache/6.2.0-SNAPSHOT, BSD-3-Clause, approved, technology.jgit
+maven/mavencentral/org.eclipse.jgit/org.eclipse.jgit.ssh.jsch/6.2.0-SNAPSHOT, BSD-3-Clause, approved, technology.jgit
+maven/mavencentral/org.eclipse.jgit/org.eclipse.jgit.test/6.2.0-SNAPSHOT, BSD-3-Clause, approved, technology.jgit
+maven/mavencentral/org.eclipse.jgit/org.eclipse.jgit.ui/6.2.0-SNAPSHOT, BSD-3-Clause, approved, technology.jgit
+maven/mavencentral/org.eclipse.jgit/org.eclipse.jgit/6.2.0-SNAPSHOT, BSD-3-Clause, approved, technology.jgit
 maven/mavencentral/org.hamcrest/hamcrest-core/1.3, BSD-2-Clause, approved, CQ11429
 maven/mavencentral/org.mockito/mockito-core/2.23.0, Apache-2.0 AND MIT, approved, #958
 maven/mavencentral/org.objenesis/objenesis/2.6, Apache-2.0, approved, CQ15478
diff --git a/WORKSPACE b/WORKSPACE
index 040617e..cce1316 100644
--- a/WORKSPACE
+++ b/WORKSPACE
@@ -68,8 +68,8 @@
 
 maven_jar(
     name = "jzlib",
-    artifact = "com.jcraft:jzlib:1.1.1",
-    sha1 = "a1551373315ffc2f96130a0e5704f74e151777ba",
+    artifact = "com.jcraft:jzlib:1.1.3",
+    sha1 = "c01428efa717624f7aabf4df319939dda9646b2d",
 )
 
 maven_jar(
diff --git a/org.eclipse.jgit.ant.test/META-INF/MANIFEST.MF b/org.eclipse.jgit.ant.test/META-INF/MANIFEST.MF
index 0997570..e4d990c 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.1.1.qualifier
+Bundle-Version: 6.2.0.qualifier
 Bundle-ActivationPolicy: lazy
 Bundle-RequiredExecutionEnvironment: JavaSE-11
 Import-Package: org.apache.tools.ant,
- org.eclipse.jgit.ant.tasks;version="[6.1.1,6.2.0)",
- org.eclipse.jgit.junit;version="[6.1.1,6.2.0)",
- org.eclipse.jgit.lib;version="[6.1.1,6.2.0)",
- org.eclipse.jgit.util;version="[6.1.1,6.2.0)",
+ org.eclipse.jgit.ant.tasks;version="[6.2.0,6.3.0)",
+ org.eclipse.jgit.junit;version="[6.2.0,6.3.0)",
+ org.eclipse.jgit.lib;version="[6.2.0,6.3.0)",
+ org.eclipse.jgit.util;version="[6.2.0,6.3.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 ba473ef..7247086 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.1.1-SNAPSHOT</version>
+    <version>6.2.0-SNAPSHOT</version>
   </parent>
 
   <artifactId>org.eclipse.jgit.ant.test</artifactId>
diff --git a/org.eclipse.jgit.ant/META-INF/MANIFEST.MF b/org.eclipse.jgit.ant/META-INF/MANIFEST.MF
index 6003a31..066da07 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.1.1.qualifier
+Bundle-Version: 6.2.0.qualifier
 Bundle-RequiredExecutionEnvironment: JavaSE-11
 Import-Package: org.apache.tools.ant,
-  org.eclipse.jgit.storage.file;version="[6.1.1,6.2.0)"
+  org.eclipse.jgit.storage.file;version="[6.2.0,6.3.0)"
 Bundle-Localization: plugin
 Bundle-Vendor: %Bundle-Vendor
-Export-Package: org.eclipse.jgit.ant;version="6.1.1",
- org.eclipse.jgit.ant.tasks;version="6.1.1";
+Export-Package: org.eclipse.jgit.ant;version="6.2.0",
+ org.eclipse.jgit.ant.tasks;version="6.2.0";
   uses:="org.apache.tools.ant,
    org.apache.tools.ant.types"
diff --git a/org.eclipse.jgit.ant/META-INF/SOURCE-MANIFEST.MF b/org.eclipse.jgit.ant/META-INF/SOURCE-MANIFEST.MF
index d0dc5c8..3cde592 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.1.1.qualifier
-Eclipse-SourceBundle: org.eclipse.jgit.ant;version="6.1.1.qualifier";roots="."
+Bundle-Version: 6.2.0.qualifier
+Eclipse-SourceBundle: org.eclipse.jgit.ant;version="6.2.0.qualifier";roots="."
diff --git a/org.eclipse.jgit.ant/pom.xml b/org.eclipse.jgit.ant/pom.xml
index a7f258b..75b1717 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.1.1-SNAPSHOT</version>
+    <version>6.2.0-SNAPSHOT</version>
   </parent>
 
   <artifactId>org.eclipse.jgit.ant</artifactId>
diff --git a/org.eclipse.jgit.archive/META-INF/MANIFEST.MF b/org.eclipse.jgit.archive/META-INF/MANIFEST.MF
index 3fc8df1..f5125de 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.1.1.qualifier
+Bundle-Version: 6.2.0.qualifier
 Bundle-Vendor: %Bundle-Vendor
 Bundle-Localization: plugin
 Bundle-RequiredExecutionEnvironment: JavaSE-11
@@ -13,17 +13,17 @@
  org.apache.commons.compress.compressors.bzip2;version="[1.4,2.0)",
  org.apache.commons.compress.compressors.gzip;version="[1.4,2.0)",
  org.apache.commons.compress.compressors.xz;version="[1.4,2.0)",
- org.eclipse.jgit.api;version="[6.1.1,6.2.0)",
- org.eclipse.jgit.lib;version="[6.1.1,6.2.0)",
- org.eclipse.jgit.nls;version="[6.1.1,6.2.0)",
- org.eclipse.jgit.revwalk;version="[6.1.1,6.2.0)",
- org.eclipse.jgit.util;version="[6.1.1,6.2.0)",
+ org.eclipse.jgit.api;version="[6.2.0,6.3.0)",
+ org.eclipse.jgit.lib;version="[6.2.0,6.3.0)",
+ org.eclipse.jgit.nls;version="[6.2.0,6.3.0)",
+ org.eclipse.jgit.revwalk;version="[6.2.0,6.3.0)",
+ org.eclipse.jgit.util;version="[6.2.0,6.3.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.1.1";
+Export-Package: org.eclipse.jgit.archive;version="6.2.0";
   uses:="org.eclipse.jgit.lib,
    org.eclipse.jgit.api,
    org.apache.commons.compress.archivers,
    org.osgi.framework",
- org.eclipse.jgit.archive.internal;version="6.1.1";x-internal:=true
+ org.eclipse.jgit.archive.internal;version="6.2.0";x-internal:=true
diff --git a/org.eclipse.jgit.archive/META-INF/SOURCE-MANIFEST.MF b/org.eclipse.jgit.archive/META-INF/SOURCE-MANIFEST.MF
index 8c7fd07..5dfc659 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.1.1.qualifier
-Eclipse-SourceBundle: org.eclipse.jgit.archive;version="6.1.1.qualifier";roots="."
+Bundle-Version: 6.2.0.qualifier
+Eclipse-SourceBundle: org.eclipse.jgit.archive;version="6.2.0.qualifier";roots="."
diff --git a/org.eclipse.jgit.archive/pom.xml b/org.eclipse.jgit.archive/pom.xml
index 12f3e68..e4f2d67 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.1.1-SNAPSHOT</version>
+    <version>6.2.0-SNAPSHOT</version>
   </parent>
 
   <artifactId>org.eclipse.jgit.archive</artifactId>
diff --git a/org.eclipse.jgit.benchmarks/pom.xml b/org.eclipse.jgit.benchmarks/pom.xml
index 0f72f64..c8b0887 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.1.1-SNAPSHOT</version>
+  <version>6.2.0-SNAPSHOT</version>
   <artifactId>org.eclipse.jgit.benchmarks</artifactId>
   <packaging>jar</packaging>
 
diff --git a/org.eclipse.jgit.benchmarks/src/org/eclipse/jgit/benchmarks/GetRefsBenchmark.java b/org.eclipse.jgit.benchmarks/src/org/eclipse/jgit/benchmarks/GetRefsBenchmark.java
new file mode 100644
index 0000000..62627e6
--- /dev/null
+++ b/org.eclipse.jgit.benchmarks/src/org/eclipse/jgit/benchmarks/GetRefsBenchmark.java
@@ -0,0 +1,181 @@
+/*
+ * Copyright (C) 2021, Luca Milanesio <luca.milanesio@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.benchmarks;
+
+import java.io.IOException;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.concurrent.ThreadLocalRandom;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.atomic.AtomicInteger;
+import java.util.stream.Collectors;
+import java.util.stream.IntStream;
+
+import org.eclipse.jgit.api.Git;
+import org.eclipse.jgit.api.errors.GitAPIException;
+import org.eclipse.jgit.internal.storage.dfs.DfsRepositoryDescription;
+import org.eclipse.jgit.internal.storage.dfs.InMemoryRepository;
+import org.eclipse.jgit.internal.storage.file.FileRepository;
+import org.eclipse.jgit.lib.*;
+import org.eclipse.jgit.revwalk.RevCommit;
+import org.eclipse.jgit.revwalk.RevWalk;
+import org.eclipse.jgit.transport.ReceiveCommand;
+import org.eclipse.jgit.util.FS;
+import org.eclipse.jgit.util.FileUtils;
+import org.openjdk.jmh.annotations.Benchmark;
+import org.openjdk.jmh.annotations.BenchmarkMode;
+import org.openjdk.jmh.annotations.Measurement;
+import org.openjdk.jmh.annotations.Mode;
+import org.openjdk.jmh.annotations.OutputTimeUnit;
+import org.openjdk.jmh.annotations.Param;
+import org.openjdk.jmh.annotations.Scope;
+import org.openjdk.jmh.annotations.Setup;
+import org.openjdk.jmh.annotations.State;
+import org.openjdk.jmh.annotations.TearDown;
+import org.openjdk.jmh.annotations.Warmup;
+import org.openjdk.jmh.infra.Blackhole;
+import org.openjdk.jmh.runner.Runner;
+import org.openjdk.jmh.runner.RunnerException;
+import org.openjdk.jmh.runner.options.Options;
+import org.openjdk.jmh.runner.options.OptionsBuilder;
+
+import static org.eclipse.jgit.transport.ReceiveCommand.Type.CREATE;
+import static org.eclipse.jgit.transport.ReceiveCommand.Type.UPDATE;
+
+@State(Scope.Thread)
+public class GetRefsBenchmark {
+
+	ThreadLocalRandom branchIndex = ThreadLocalRandom.current();
+
+	@State(Scope.Benchmark)
+	public static class BenchmarkState {
+
+		@Param({ "true", "false" })
+		boolean useRefTable;
+
+		@Param({ "100", "2500", "10000", "50000" })
+		int numBranches;
+
+		@Param({ "true", "false" })
+		boolean trustFolderStat;
+
+		List<String> branches = new ArrayList<>(numBranches);
+
+		Path testDir;
+
+		Repository repo;
+
+		@Setup
+		@SuppressWarnings("boxing")
+		public void setupBenchmark() throws IOException, GitAPIException {
+			String firstBranch = "firstbranch";
+			testDir = Files.createDirectory(Paths.get("testrepos"));
+			String repoName = "branches-" + numBranches + "-trustFolderStat-"
+					+ trustFolderStat + "-" + refDatabaseType();
+			Path workDir = testDir.resolve(repoName);
+			Path repoPath = workDir.resolve(".git");
+			Git git = Git.init().setDirectory(workDir.toFile()).call();
+			RevCommit firstCommit = git.commit().setMessage("First commit")
+					.call();
+			git.branchCreate().setName(firstBranch).call();
+
+			StoredConfig cfg = git.getRepository().getConfig();
+			if (useRefTable) {
+				((FileRepository) git.getRepository()).convertRefStorage(
+						ConfigConstants.CONFIG_REF_STORAGE_REFTABLE, false,
+						false);
+			} else {
+				cfg.setBoolean(ConfigConstants.CONFIG_CORE_SECTION, null,
+						ConfigConstants.CONFIG_KEY_TRUSTFOLDERSTAT,
+						trustFolderStat);
+			}
+			cfg.setInt(ConfigConstants.CONFIG_RECEIVE_SECTION, null,
+					"maxCommandBytes", Integer.MAX_VALUE);
+			cfg.save();
+
+			repo = RepositoryCache.open(RepositoryCache.FileKey
+					.lenient(repoPath.toFile(), FS.DETECTED));
+
+			System.out.println("Preparing test");
+			System.out.println("- repository: \t\t" + repoPath);
+			System.out.println("- refDatabase: \t\t" + refDatabaseType());
+			System.out.println("- trustFolderStat: \t" + trustFolderStat);
+			System.out.println("- branches: \t\t" + numBranches);
+
+			BatchRefUpdate u = repo.getRefDatabase().newBatchUpdate();
+
+			branches = IntStream.range(0, numBranches)
+					.mapToObj(i -> "branch/" + i % 100 + "/" + i)
+					.collect(Collectors.toList());
+			for (String branch : branches) {
+				u.addCommand(new ReceiveCommand(ObjectId.zeroId(),
+						firstCommit.toObjectId(), Constants.R_HEADS + branch,
+						CREATE));
+			}
+
+			System.out.println();
+			System.out.print(
+					String.format("Creating %d branches ... ", numBranches));
+
+			try (RevWalk rw = new RevWalk(repo)) {
+				u.execute(rw, new TextProgressMonitor());
+			}
+			System.out.println("DONE");
+		}
+
+		private String refDatabaseType() {
+			return useRefTable ? "reftable" : "refdir";
+		}
+
+		@TearDown
+		public void teardown() throws IOException {
+			repo.close();
+			FileUtils.delete(testDir.toFile(),
+					FileUtils.RECURSIVE | FileUtils.RETRY);
+		}
+	}
+
+	@Benchmark
+	@BenchmarkMode({ Mode.AverageTime })
+	@OutputTimeUnit(TimeUnit.MICROSECONDS)
+	@Warmup(iterations = 2, time = 100, timeUnit = TimeUnit.MILLISECONDS)
+	@Measurement(iterations = 2, time = 10, timeUnit = TimeUnit.SECONDS)
+	public void testGetExactRef(Blackhole blackhole, BenchmarkState state)
+			throws IOException {
+		String branchName = state.branches
+				.get(branchIndex.nextInt(state.numBranches));
+		blackhole.consume(state.repo.exactRef(branchName));
+	}
+
+	@Benchmark
+	@BenchmarkMode({ Mode.AverageTime })
+	@OutputTimeUnit(TimeUnit.MICROSECONDS)
+	@Warmup(iterations = 2, time = 100, timeUnit = TimeUnit.MILLISECONDS)
+	@Measurement(iterations = 2, time = 10, timeUnit = TimeUnit.SECONDS)
+	public void testGetRefsByPrefix(Blackhole blackhole, BenchmarkState state)
+			throws IOException {
+		String branchPrefix = "refs/heads/branch/" + branchIndex.nextInt(100)
+				+ "/";
+		blackhole.consume(
+				state.repo.getRefDatabase().getRefsByPrefix(branchPrefix));
+	}
+
+	public static void main(String[] args) throws RunnerException {
+		Options opt = new OptionsBuilder()
+				.include(GetRefsBenchmark.class.getSimpleName())
+				// .addProfiler(StackProfiler.class)
+				// .addProfiler(GCProfiler.class)
+				.forks(1).jvmArgs("-ea").build();
+		new Runner(opt).run();
+	}
+}
diff --git a/org.eclipse.jgit.coverage/pom.xml b/org.eclipse.jgit.coverage/pom.xml
index abc37ec..a99e23e 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.1.1-SNAPSHOT</version>
+    <version>6.2.0-SNAPSHOT</version>
   </parent>
   <modelVersion>4.0.0</modelVersion>
 
@@ -27,88 +27,88 @@
     <dependency>
       <groupId>org.eclipse.jgit</groupId>
       <artifactId>org.eclipse.jgit</artifactId>
-      <version>6.1.1-SNAPSHOT</version>
+      <version>6.2.0-SNAPSHOT</version>
     </dependency>
     <dependency>
       <groupId>org.eclipse.jgit</groupId>
       <artifactId>org.eclipse.jgit.ant</artifactId>
-      <version>6.1.1-SNAPSHOT</version>
+      <version>6.2.0-SNAPSHOT</version>
     </dependency>
     <dependency>
       <groupId>org.eclipse.jgit</groupId>
       <artifactId>org.eclipse.jgit.archive</artifactId>
-      <version>6.1.1-SNAPSHOT</version>
+      <version>6.2.0-SNAPSHOT</version>
     </dependency>
     <dependency>
       <groupId>org.eclipse.jgit</groupId>
       <artifactId>org.eclipse.jgit.http.apache</artifactId>
-      <version>6.1.1-SNAPSHOT</version>
+      <version>6.2.0-SNAPSHOT</version>
     </dependency>
     <dependency>
       <groupId>org.eclipse.jgit</groupId>
       <artifactId>org.eclipse.jgit.http.server</artifactId>
-      <version>6.1.1-SNAPSHOT</version>
+      <version>6.2.0-SNAPSHOT</version>
     </dependency>
     <dependency>
       <groupId>org.eclipse.jgit</groupId>
       <artifactId>org.eclipse.jgit.lfs</artifactId>
-      <version>6.1.1-SNAPSHOT</version>
+      <version>6.2.0-SNAPSHOT</version>
     </dependency>
     <dependency>
       <groupId>org.eclipse.jgit</groupId>
       <artifactId>org.eclipse.jgit.lfs.server</artifactId>
-      <version>6.1.1-SNAPSHOT</version>
+      <version>6.2.0-SNAPSHOT</version>
     </dependency>
     <dependency>
       <groupId>org.eclipse.jgit</groupId>
       <artifactId>org.eclipse.jgit.pgm</artifactId>
-      <version>6.1.1-SNAPSHOT</version>
+      <version>6.2.0-SNAPSHOT</version>
     </dependency>
     <dependency>
       <groupId>org.eclipse.jgit</groupId>
       <artifactId>org.eclipse.jgit.ui</artifactId>
-      <version>6.1.1-SNAPSHOT</version>
+      <version>6.2.0-SNAPSHOT</version>
     </dependency>
     <dependency>
       <groupId>org.eclipse.jgit</groupId>
       <artifactId>org.eclipse.jgit.ssh.apache</artifactId>
-      <version>6.1.1-SNAPSHOT</version>
+      <version>6.2.0-SNAPSHOT</version>
     </dependency>
 
     <dependency>
       <groupId>org.eclipse.jgit</groupId>
       <artifactId>org.eclipse.jgit.test</artifactId>
-      <version>6.1.1-SNAPSHOT</version>
+      <version>6.2.0-SNAPSHOT</version>
     </dependency>
     <dependency>
       <groupId>org.eclipse.jgit</groupId>
       <artifactId>org.eclipse.jgit.ant.test</artifactId>
-      <version>6.1.1-SNAPSHOT</version>
+      <version>6.2.0-SNAPSHOT</version>
     </dependency>
     <dependency>
       <groupId>org.eclipse.jgit</groupId>
       <artifactId>org.eclipse.jgit.http.test</artifactId>
-      <version>6.1.1-SNAPSHOT</version>
+      <version>6.2.0-SNAPSHOT</version>
     </dependency>
     <dependency>
       <groupId>org.eclipse.jgit</groupId>
       <artifactId>org.eclipse.jgit.pgm.test</artifactId>
-      <version>6.1.1-SNAPSHOT</version>
+      <version>6.2.0-SNAPSHOT</version>
     </dependency>
     <dependency>
       <groupId>org.eclipse.jgit</groupId>
       <artifactId>org.eclipse.jgit.lfs.test</artifactId>
-      <version>6.1.1-SNAPSHOT</version>
+      <version>6.2.0-SNAPSHOT</version>
     </dependency>
     <dependency>
       <groupId>org.eclipse.jgit</groupId>
       <artifactId>org.eclipse.jgit.lfs.server.test</artifactId>
-      <version>6.1.1-SNAPSHOT</version>
+      <version>6.2.0-SNAPSHOT</version>
     </dependency>
     <dependency>
       <groupId>org.eclipse.jgit</groupId>
       <artifactId>org.eclipse.jgit.ssh.apache.test</artifactId>
-      <version>6.1.1-SNAPSHOT</version>
+      <version>6.2.0-SNAPSHOT</version>
     </dependency>
   </dependencies>
 
diff --git a/org.eclipse.jgit.gpg.bc.test/META-INF/MANIFEST.MF b/org.eclipse.jgit.gpg.bc.test/META-INF/MANIFEST.MF
index bb9b393..c92fd3e 100644
--- a/org.eclipse.jgit.gpg.bc.test/META-INF/MANIFEST.MF
+++ b/org.eclipse.jgit.gpg.bc.test/META-INF/MANIFEST.MF
@@ -3,7 +3,7 @@
 Bundle-Name: %Bundle-Name
 Automatic-Module-Name: org.eclipse.jgit.gpg.bc.test
 Bundle-SymbolicName: org.eclipse.jgit.gpg.bc.test
-Bundle-Version: 6.1.1.qualifier
+Bundle-Version: 6.2.0.qualifier
 Bundle-Vendor: %Bundle-Vendor
 Bundle-Localization: plugin
 Bundle-RequiredExecutionEnvironment: JavaSE-11
@@ -12,9 +12,9 @@
  org.bouncycastle.openpgp.operator;version="[1.65.0,2.0.0)",
  org.bouncycastle.openpgp.operator.jcajce;version="[1.65.0,2.0.0)",
  org.bouncycastle.util.encoders;version="[1.65.0,2.0.0)",
- org.eclipse.jgit.gpg.bc.internal;version="[6.1.1,6.2.0)",
- org.eclipse.jgit.gpg.bc.internal.keys;version="[6.1.1,6.2.0)",
- org.eclipse.jgit.util.sha1;version="[6.1.1,6.2.0)",
+ org.eclipse.jgit.gpg.bc.internal;version="[6.2.0,6.3.0)",
+ org.eclipse.jgit.gpg.bc.internal.keys;version="[6.2.0,6.3.0)",
+ org.eclipse.jgit.util.sha1;version="[6.2.0,6.3.0)",
  org.hamcrest;version="[1.1.0,3.0.0)",
  org.junit;version="[4.13,5.0.0)",
  org.junit.runner;version="[4.13,5.0.0)",
diff --git a/org.eclipse.jgit.gpg.bc.test/pom.xml b/org.eclipse.jgit.gpg.bc.test/pom.xml
index 9568c68..2556889 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.1.1-SNAPSHOT</version>
+    <version>6.2.0-SNAPSHOT</version>
   </parent>
 
   <artifactId>org.eclipse.jgit.gpg.bc.test</artifactId>
diff --git a/org.eclipse.jgit.gpg.bc/META-INF/MANIFEST.MF b/org.eclipse.jgit.gpg.bc/META-INF/MANIFEST.MF
index 534568d..fb45761 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.1.1,6.2.0)"
+Fragment-Host: org.eclipse.jgit;bundle-version="[6.2.0,6.3.0)"
 Bundle-Vendor: %Bundle-Vendor
 Bundle-Localization: plugin
-Bundle-Version: 6.1.1.qualifier
+Bundle-Version: 6.2.0.qualifier
 Bundle-RequiredExecutionEnvironment: JavaSE-11
 Import-Package: org.bouncycastle.asn1;version="[1.69.0,2.0.0)",
  org.bouncycastle.asn1.cryptlib;version="[1.69.0,2.0.0)",
@@ -29,9 +29,9 @@
  org.bouncycastle.util;version="[1.69.0,2.0.0)",
  org.bouncycastle.util.encoders;version="[1.69.0,2.0.0)",
  org.bouncycastle.util.io;version="[1.69.0,2.0.0)",
- org.eclipse.jgit.annotations;version="[6.1.1,6.2.0)",
- org.eclipse.jgit.api.errors;version="[6.1.1,6.2.0)",
+ org.eclipse.jgit.annotations;version="[6.2.0,6.3.0)",
+ org.eclipse.jgit.api.errors;version="[6.2.0,6.3.0)",
  org.slf4j;version="[1.7.0,2.0.0)"
-Export-Package: org.eclipse.jgit.gpg.bc;version="6.1.1",
- org.eclipse.jgit.gpg.bc.internal;version="6.1.1";x-friends:="org.eclipse.jgit.gpg.bc.test",
- org.eclipse.jgit.gpg.bc.internal.keys;version="6.1.1";x-friends:="org.eclipse.jgit.gpg.bc.test"
+Export-Package: org.eclipse.jgit.gpg.bc;version="6.2.0",
+ org.eclipse.jgit.gpg.bc.internal;version="6.2.0";x-friends:="org.eclipse.jgit.gpg.bc.test",
+ org.eclipse.jgit.gpg.bc.internal.keys;version="6.2.0";x-friends:="org.eclipse.jgit.gpg.bc.test"
diff --git a/org.eclipse.jgit.gpg.bc/META-INF/SOURCE-MANIFEST.MF b/org.eclipse.jgit.gpg.bc/META-INF/SOURCE-MANIFEST.MF
index 20e2d01..b62a2a6 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.1.1.qualifier
-Eclipse-SourceBundle: org.eclipse.jgit.gpg.bc;version="6.1.1.qualifier";roots="."
+Bundle-Version: 6.2.0.qualifier
+Eclipse-SourceBundle: org.eclipse.jgit.gpg.bc;version="6.2.0.qualifier";roots="."
diff --git a/org.eclipse.jgit.gpg.bc/pom.xml b/org.eclipse.jgit.gpg.bc/pom.xml
index 138f4e8..69465d0 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.1.1-SNAPSHOT</version>
+    <version>6.2.0-SNAPSHOT</version>
   </parent>
 
   <artifactId>org.eclipse.jgit.gpg.bc</artifactId>
diff --git a/org.eclipse.jgit.http.apache/META-INF/MANIFEST.MF b/org.eclipse.jgit.http.apache/META-INF/MANIFEST.MF
index afcaa78..df60729 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.1.1.qualifier
+Bundle-Version: 6.2.0.qualifier
 Bundle-RequiredExecutionEnvironment: JavaSE-11
 Bundle-Localization: plugin
 Bundle-Vendor: %Bundle-Vendor
@@ -25,11 +25,11 @@
  org.apache.http.impl.conn;version="[4.4.0,5.0.0)",
  org.apache.http.params;version="[4.3.0,5.0.0)",
  org.apache.http.ssl;version="[4.3.0,5.0.0)",
- org.eclipse.jgit.annotations;version="[6.1.1,6.2.0)",
- org.eclipse.jgit.nls;version="[6.1.1,6.2.0)",
- org.eclipse.jgit.transport.http;version="[6.1.1,6.2.0)",
- org.eclipse.jgit.util;version="[6.1.1,6.2.0)"
-Export-Package: org.eclipse.jgit.transport.http.apache;version="6.1.1";
+ org.eclipse.jgit.annotations;version="[6.2.0,6.3.0)",
+ org.eclipse.jgit.nls;version="[6.2.0,6.3.0)",
+ org.eclipse.jgit.transport.http;version="[6.2.0,6.3.0)",
+ org.eclipse.jgit.util;version="[6.2.0,6.3.0)"
+Export-Package: org.eclipse.jgit.transport.http.apache;version="6.2.0";
   uses:="org.apache.http.client,
    org.eclipse.jgit.transport.http,
    org.apache.http.entity,
diff --git a/org.eclipse.jgit.http.apache/META-INF/SOURCE-MANIFEST.MF b/org.eclipse.jgit.http.apache/META-INF/SOURCE-MANIFEST.MF
index 7b8e149..ead7256 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.1.1.qualifier
-Eclipse-SourceBundle: org.eclipse.jgit.http.apache;version="6.1.1.qualifier";roots="."
+Bundle-Version: 6.2.0.qualifier
+Eclipse-SourceBundle: org.eclipse.jgit.http.apache;version="6.2.0.qualifier";roots="."
diff --git a/org.eclipse.jgit.http.apache/pom.xml b/org.eclipse.jgit.http.apache/pom.xml
index bd35589..0bd899f 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.1.1-SNAPSHOT</version>
+    <version>6.2.0-SNAPSHOT</version>
   </parent>
 
   <artifactId>org.eclipse.jgit.http.apache</artifactId>
diff --git a/org.eclipse.jgit.http.server/META-INF/MANIFEST.MF b/org.eclipse.jgit.http.server/META-INF/MANIFEST.MF
index 4bf66a2..cd7db79 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.1.1.qualifier
+Bundle-Version: 6.2.0.qualifier
 Bundle-Localization: plugin
 Bundle-Vendor: %Bundle-Vendor
-Export-Package: org.eclipse.jgit.http.server;version="6.1.1",
- org.eclipse.jgit.http.server.glue;version="6.1.1";
+Export-Package: org.eclipse.jgit.http.server;version="6.2.0",
+ org.eclipse.jgit.http.server.glue;version="6.2.0";
   uses:="javax.servlet,javax.servlet.http",
- org.eclipse.jgit.http.server.resolver;version="6.1.1";
+ org.eclipse.jgit.http.server.resolver;version="6.2.0";
   uses:="org.eclipse.jgit.transport.resolver,
    org.eclipse.jgit.lib,
    org.eclipse.jgit.transport,
@@ -18,14 +18,14 @@
 Bundle-RequiredExecutionEnvironment: JavaSE-11
 Import-Package: javax.servlet;version="[2.5.0,5.0.0)",
  javax.servlet.http;version="[2.5.0,5.0.0)",
- org.eclipse.jgit.annotations;version="[6.1.1,6.2.0)",
- org.eclipse.jgit.errors;version="[6.1.1,6.2.0)",
- org.eclipse.jgit.internal.storage.dfs;version="[6.1.1,6.2.0)",
- org.eclipse.jgit.internal.storage.file;version="[6.1.1,6.2.0)",
- org.eclipse.jgit.internal.transport.parser;version="[6.1.1,6.2.0)",
- org.eclipse.jgit.lib;version="[6.1.1,6.2.0)",
- org.eclipse.jgit.nls;version="[6.1.1,6.2.0)",
- org.eclipse.jgit.revwalk;version="[6.1.1,6.2.0)",
- org.eclipse.jgit.transport;version="[6.1.1,6.2.0)",
- org.eclipse.jgit.transport.resolver;version="[6.1.1,6.2.0)",
- org.eclipse.jgit.util;version="[6.1.1,6.2.0)"
+ org.eclipse.jgit.annotations;version="[6.2.0,6.3.0)",
+ org.eclipse.jgit.errors;version="[6.2.0,6.3.0)",
+ org.eclipse.jgit.internal.storage.dfs;version="[6.2.0,6.3.0)",
+ org.eclipse.jgit.internal.storage.file;version="[6.2.0,6.3.0)",
+ org.eclipse.jgit.internal.transport.parser;version="[6.2.0,6.3.0)",
+ org.eclipse.jgit.lib;version="[6.2.0,6.3.0)",
+ org.eclipse.jgit.nls;version="[6.2.0,6.3.0)",
+ org.eclipse.jgit.revwalk;version="[6.2.0,6.3.0)",
+ org.eclipse.jgit.transport;version="[6.2.0,6.3.0)",
+ org.eclipse.jgit.transport.resolver;version="[6.2.0,6.3.0)",
+ org.eclipse.jgit.util;version="[6.2.0,6.3.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 2b47055..b86561a 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.1.1.qualifier
-Eclipse-SourceBundle: org.eclipse.jgit.http.server;version="6.1.1.qualifier";roots="."
+Bundle-Version: 6.2.0.qualifier
+Eclipse-SourceBundle: org.eclipse.jgit.http.server;version="6.2.0.qualifier";roots="."
diff --git a/org.eclipse.jgit.http.server/pom.xml b/org.eclipse.jgit.http.server/pom.xml
index 6a788e2..2ea4c6a 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.1.1-SNAPSHOT</version>
+    <version>6.2.0-SNAPSHOT</version>
   </parent>
 
   <artifactId>org.eclipse.jgit.http.server</artifactId>
diff --git a/org.eclipse.jgit.http.test/META-INF/MANIFEST.MF b/org.eclipse.jgit.http.test/META-INF/MANIFEST.MF
index 4150bdb..1b8caed 100644
--- a/org.eclipse.jgit.http.test/META-INF/MANIFEST.MF
+++ b/org.eclipse.jgit.http.test/META-INF/MANIFEST.MF
@@ -3,7 +3,7 @@
 Bundle-Name: %Bundle-Name
 Automatic-Module-Name: org.eclipse.jgit.http.test
 Bundle-SymbolicName: org.eclipse.jgit.http.test
-Bundle-Version: 6.1.1.qualifier
+Bundle-Version: 6.2.0.qualifier
 Bundle-Vendor: %Bundle-Vendor
 Bundle-Localization: plugin
 Bundle-RequiredExecutionEnvironment: JavaSE-11
@@ -26,26 +26,26 @@
  org.eclipse.jetty.util.log;version="[10.0.0,11.0.0)",
  org.eclipse.jetty.util.security;version="[10.0.0,11.0.0)",
  org.eclipse.jetty.util.thread;version="[10.0.0,11.0.0)",
- org.eclipse.jgit.api;version="[6.1.1,6.2.0)",
- org.eclipse.jgit.errors;version="[6.1.1,6.2.0)",
- org.eclipse.jgit.http.server;version="[6.1.1,6.2.0)",
- org.eclipse.jgit.http.server.glue;version="[6.1.1,6.2.0)",
- org.eclipse.jgit.http.server.resolver;version="[6.1.1,6.2.0)",
- org.eclipse.jgit.internal;version="[6.1.1,6.2.0)",
- org.eclipse.jgit.internal.storage.dfs;version="[6.1.1,6.2.0)",
- org.eclipse.jgit.internal.storage.file;version="[6.1.1,6.2.0)",
- org.eclipse.jgit.internal.storage.reftable;version="[6.1.1,6.2.0)",
- org.eclipse.jgit.junit;version="[6.1.1,6.2.0)",
- org.eclipse.jgit.junit.http;version="[6.1.1,6.2.0)",
- org.eclipse.jgit.lib;version="[6.1.1,6.2.0)",
- org.eclipse.jgit.nls;version="[6.1.1,6.2.0)",
- org.eclipse.jgit.revwalk;version="[6.1.1,6.2.0)",
- org.eclipse.jgit.storage.file;version="[6.1.1,6.2.0)",
- org.eclipse.jgit.transport;version="[6.1.1,6.2.0)",
- org.eclipse.jgit.transport.http;version="[6.1.1,6.2.0)",
- org.eclipse.jgit.transport.http.apache;version="[6.1.1,6.2.0)",
- org.eclipse.jgit.transport.resolver;version="[6.1.1,6.2.0)",
- org.eclipse.jgit.util;version="[6.1.1,6.2.0)",
+ org.eclipse.jgit.api;version="[6.2.0,6.3.0)",
+ org.eclipse.jgit.errors;version="[6.2.0,6.3.0)",
+ org.eclipse.jgit.http.server;version="[6.2.0,6.3.0)",
+ org.eclipse.jgit.http.server.glue;version="[6.2.0,6.3.0)",
+ org.eclipse.jgit.http.server.resolver;version="[6.2.0,6.3.0)",
+ org.eclipse.jgit.internal;version="[6.2.0,6.3.0)",
+ org.eclipse.jgit.internal.storage.dfs;version="[6.2.0,6.3.0)",
+ org.eclipse.jgit.internal.storage.file;version="[6.2.0,6.3.0)",
+ org.eclipse.jgit.internal.storage.reftable;version="[6.2.0,6.3.0)",
+ org.eclipse.jgit.junit;version="[6.2.0,6.3.0)",
+ org.eclipse.jgit.junit.http;version="[6.2.0,6.3.0)",
+ org.eclipse.jgit.lib;version="[6.2.0,6.3.0)",
+ org.eclipse.jgit.nls;version="[6.2.0,6.3.0)",
+ org.eclipse.jgit.revwalk;version="[6.2.0,6.3.0)",
+ org.eclipse.jgit.storage.file;version="[6.2.0,6.3.0)",
+ org.eclipse.jgit.transport;version="[6.2.0,6.3.0)",
+ org.eclipse.jgit.transport.http;version="[6.2.0,6.3.0)",
+ org.eclipse.jgit.transport.http.apache;version="[6.2.0,6.3.0)",
+ org.eclipse.jgit.transport.resolver;version="[6.2.0,6.3.0)",
+ org.eclipse.jgit.util;version="[6.2.0,6.3.0)",
  org.hamcrest;version="[1.1.0,3.0.0)",
  org.hamcrest.core;version="[1.1.0,3.0.0)",
  org.junit;version="[4.13,5.0.0)",
diff --git a/org.eclipse.jgit.http.test/pom.xml b/org.eclipse.jgit.http.test/pom.xml
index 336f43b..7a7b409 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.1.1-SNAPSHOT</version>
+    <version>6.2.0-SNAPSHOT</version>
   </parent>
 
   <artifactId>org.eclipse.jgit.http.test</artifactId>
diff --git a/org.eclipse.jgit.junit.http/META-INF/MANIFEST.MF b/org.eclipse.jgit.junit.http/META-INF/MANIFEST.MF
index d035072..50e814b 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.1.1.qualifier
+Bundle-Version: 6.2.0.qualifier
 Bundle-Localization: plugin
 Bundle-Vendor: %Bundle-Vendor
 Bundle-ActivationPolicy: lazy
@@ -21,17 +21,17 @@
  org.eclipse.jetty.util.log;version="[10.0.0,11.0.0)",
  org.eclipse.jetty.util.security;version="[10.0.0,11.0.0)",
  org.eclipse.jetty.util.ssl;version="[10.0.0,11.0.0)",
- org.eclipse.jgit.errors;version="[6.1.1,6.2.0)",
- org.eclipse.jgit.http.server;version="[6.1.1,6.2.0)",
- org.eclipse.jgit.internal.storage.file;version="[6.1.1,6.2.0)",
- org.eclipse.jgit.junit;version="[6.1.1,6.2.0)",
- org.eclipse.jgit.lib;version="[6.1.1,6.2.0)",
- org.eclipse.jgit.revwalk;version="[6.1.1,6.2.0)",
- org.eclipse.jgit.transport;version="[6.1.1,6.2.0)",
- org.eclipse.jgit.transport.resolver;version="[6.1.1,6.2.0)",
+ org.eclipse.jgit.errors;version="[6.2.0,6.3.0)",
+ org.eclipse.jgit.http.server;version="[6.2.0,6.3.0)",
+ org.eclipse.jgit.internal.storage.file;version="[6.2.0,6.3.0)",
+ org.eclipse.jgit.junit;version="[6.2.0,6.3.0)",
+ org.eclipse.jgit.lib;version="[6.2.0,6.3.0)",
+ org.eclipse.jgit.revwalk;version="[6.2.0,6.3.0)",
+ org.eclipse.jgit.transport;version="[6.2.0,6.3.0)",
+ org.eclipse.jgit.transport.resolver;version="[6.2.0,6.3.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.1.1";
+Export-Package: org.eclipse.jgit.junit.http;version="6.2.0";
   uses:="org.eclipse.jgit.transport,
    org.eclipse.jgit.junit,
    javax.servlet.http,
diff --git a/org.eclipse.jgit.junit.http/META-INF/SOURCE-MANIFEST.MF b/org.eclipse.jgit.junit.http/META-INF/SOURCE-MANIFEST.MF
index 19142c5..da17142 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.1.1.qualifier
-Eclipse-SourceBundle: org.eclipse.jgit.junit.http;version="6.1.1.qualifier";roots="."
+Bundle-Version: 6.2.0.qualifier
+Eclipse-SourceBundle: org.eclipse.jgit.junit.http;version="6.2.0.qualifier";roots="."
diff --git a/org.eclipse.jgit.junit.http/pom.xml b/org.eclipse.jgit.junit.http/pom.xml
index d883e03..440a06c 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.1.1-SNAPSHOT</version>
+    <version>6.2.0-SNAPSHOT</version>
   </parent>
 
   <artifactId>org.eclipse.jgit.junit.http</artifactId>
diff --git a/org.eclipse.jgit.junit.ssh/META-INF/MANIFEST.MF b/org.eclipse.jgit.junit.ssh/META-INF/MANIFEST.MF
index 60858d8..8caf93a 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.1.1.qualifier
+Bundle-Version: 6.2.0.qualifier
 Bundle-Localization: plugin
 Bundle-Vendor: %Bundle-Vendor
 Bundle-ActivationPolicy: lazy
@@ -33,16 +33,16 @@
  org.apache.sshd.server.subsystem;version="[2.8.0,2.9.0)",
  org.apache.sshd.sftp;version="[2.8.0,2.9.0)",
  org.apache.sshd.sftp.server;version="[2.8.0,2.9.0)",
- org.eclipse.jgit.annotations;version="[6.1.1,6.2.0)",
- org.eclipse.jgit.api;version="[6.1.1,6.2.0)",
- org.eclipse.jgit.api.errors;version="[6.1.1,6.2.0)",
- org.eclipse.jgit.errors;version="[6.1.1,6.2.0)",
- org.eclipse.jgit.junit;version="[6.1.1,6.2.0)",
- org.eclipse.jgit.lib;version="[6.1.1,6.2.0)",
- org.eclipse.jgit.revwalk;version="[6.1.1,6.2.0)",
- org.eclipse.jgit.transport;version="[6.1.1,6.2.0)",
- org.eclipse.jgit.util;version="[6.1.1,6.2.0)",
+ org.eclipse.jgit.annotations;version="[6.2.0,6.3.0)",
+ org.eclipse.jgit.api;version="[6.2.0,6.3.0)",
+ org.eclipse.jgit.api.errors;version="[6.2.0,6.3.0)",
+ org.eclipse.jgit.errors;version="[6.2.0,6.3.0)",
+ org.eclipse.jgit.junit;version="[6.2.0,6.3.0)",
+ org.eclipse.jgit.lib;version="[6.2.0,6.3.0)",
+ org.eclipse.jgit.revwalk;version="[6.2.0,6.3.0)",
+ org.eclipse.jgit.transport;version="[6.2.0,6.3.0)",
+ org.eclipse.jgit.util;version="[6.2.0,6.3.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.1.1"
+Export-Package: org.eclipse.jgit.junit.ssh;version="6.2.0"
diff --git a/org.eclipse.jgit.junit.ssh/META-INF/SOURCE-MANIFEST.MF b/org.eclipse.jgit.junit.ssh/META-INF/SOURCE-MANIFEST.MF
index 41246bc..f6f2c2d 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.1.1.qualifier
-Eclipse-SourceBundle: org.eclipse.jgit.junit.ssh;version="6.1.1.qualifier";roots="."
+Bundle-Version: 6.2.0.qualifier
+Eclipse-SourceBundle: org.eclipse.jgit.junit.ssh;version="6.2.0.qualifier";roots="."
diff --git a/org.eclipse.jgit.junit.ssh/pom.xml b/org.eclipse.jgit.junit.ssh/pom.xml
index 07d0218..395b14b 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.1.1-SNAPSHOT</version>
+    <version>6.2.0-SNAPSHOT</version>
   </parent>
 
   <artifactId>org.eclipse.jgit.junit.ssh</artifactId>
diff --git a/org.eclipse.jgit.junit/META-INF/MANIFEST.MF b/org.eclipse.jgit.junit/META-INF/MANIFEST.MF
index 7a3b200..209b232 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.1.1.qualifier
+Bundle-Version: 6.2.0.qualifier
 Bundle-Localization: plugin
 Bundle-Vendor: %Bundle-Vendor
 Bundle-ActivationPolicy: lazy
 Bundle-RequiredExecutionEnvironment: JavaSE-11
-Import-Package: org.eclipse.jgit.annotations;version="[6.1.1,6.2.0)",
- org.eclipse.jgit.api;version="[6.1.1,6.2.0)",
- org.eclipse.jgit.api.errors;version="[6.1.1,6.2.0)",
- org.eclipse.jgit.dircache;version="[6.1.1,6.2.0)",
- org.eclipse.jgit.errors;version="[6.1.1,6.2.0)",
- org.eclipse.jgit.internal.storage.file;version="[6.1.1,6.2.0)",
- org.eclipse.jgit.internal.storage.pack;version="[6.1.1,6.2.0)",
- org.eclipse.jgit.lib;version="[6.1.1,6.2.0)",
- org.eclipse.jgit.merge;version="[6.1.1,6.2.0)",
- org.eclipse.jgit.revwalk;version="[6.1.1,6.2.0)",
- org.eclipse.jgit.storage.file;version="[6.1.1,6.2.0)",
- org.eclipse.jgit.transport;version="6.1.1",
- org.eclipse.jgit.treewalk;version="[6.1.1,6.2.0)",
- org.eclipse.jgit.treewalk.filter;version="[6.1.1,6.2.0)",
- org.eclipse.jgit.util;version="[6.1.1,6.2.0)",
- org.eclipse.jgit.util.io;version="[6.1.1,6.2.0)",
- org.eclipse.jgit.util.time;version="[6.1.1,6.2.0)",
+Import-Package: org.eclipse.jgit.annotations;version="[6.2.0,6.3.0)",
+ org.eclipse.jgit.api;version="[6.2.0,6.3.0)",
+ org.eclipse.jgit.api.errors;version="[6.2.0,6.3.0)",
+ org.eclipse.jgit.dircache;version="[6.2.0,6.3.0)",
+ org.eclipse.jgit.errors;version="[6.2.0,6.3.0)",
+ org.eclipse.jgit.internal.storage.file;version="[6.2.0,6.3.0)",
+ org.eclipse.jgit.internal.storage.pack;version="[6.2.0,6.3.0)",
+ org.eclipse.jgit.lib;version="[6.2.0,6.3.0)",
+ org.eclipse.jgit.merge;version="[6.2.0,6.3.0)",
+ org.eclipse.jgit.revwalk;version="[6.2.0,6.3.0)",
+ org.eclipse.jgit.storage.file;version="[6.2.0,6.3.0)",
+ org.eclipse.jgit.transport;version="6.2.0",
+ org.eclipse.jgit.treewalk;version="[6.2.0,6.3.0)",
+ org.eclipse.jgit.treewalk.filter;version="[6.2.0,6.3.0)",
+ org.eclipse.jgit.util;version="[6.2.0,6.3.0)",
+ org.eclipse.jgit.util.io;version="[6.2.0,6.3.0)",
+ org.eclipse.jgit.util.time;version="[6.2.0,6.3.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.1.1";
+Export-Package: org.eclipse.jgit.junit;version="6.2.0";
   uses:="org.eclipse.jgit.dircache,
    org.eclipse.jgit.lib,
    org.eclipse.jgit.revwalk,
@@ -44,4 +44,4 @@
    org.junit.runners.model,
    org.junit.runner,
    org.eclipse.jgit.util.time",
- org.eclipse.jgit.junit.time;version="6.1.1";uses:="org.eclipse.jgit.util.time"
+ org.eclipse.jgit.junit.time;version="6.2.0";uses:="org.eclipse.jgit.util.time"
diff --git a/org.eclipse.jgit.junit/META-INF/SOURCE-MANIFEST.MF b/org.eclipse.jgit.junit/META-INF/SOURCE-MANIFEST.MF
index 25876c7..f1dad6a 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.1.1.qualifier
-Eclipse-SourceBundle: org.eclipse.jgit.junit;version="6.1.1.qualifier";roots="."
+Bundle-Version: 6.2.0.qualifier
+Eclipse-SourceBundle: org.eclipse.jgit.junit;version="6.2.0.qualifier";roots="."
diff --git a/org.eclipse.jgit.junit/pom.xml b/org.eclipse.jgit.junit/pom.xml
index 2c260e2..13bb6a7 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.1.1-SNAPSHOT</version>
+    <version>6.2.0-SNAPSHOT</version>
   </parent>
 
   <artifactId>org.eclipse.jgit.junit</artifactId>
diff --git a/org.eclipse.jgit.lfs.server.test/META-INF/MANIFEST.MF b/org.eclipse.jgit.lfs.server.test/META-INF/MANIFEST.MF
index cbb8135..23078bd 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.1.1.qualifier
+Bundle-Version: 6.2.0.qualifier
 Bundle-Vendor: %Bundle-Vendor
 Bundle-Localization: plugin
 Bundle-RequiredExecutionEnvironment: JavaSE-11
@@ -26,24 +26,24 @@
  org.eclipse.jetty.util.log;version="[10.0.0,11.0.0)",
  org.eclipse.jetty.util.security;version="[10.0.0,11.0.0)",
  org.eclipse.jetty.util.thread;version="[10.0.0,11.0.0)",
- org.eclipse.jgit.api;version="[6.1.1,6.2.0)",
- org.eclipse.jgit.api.errors;version="[6.1.1,6.2.0)",
- org.eclipse.jgit.internal.storage.file;version="[6.1.1,6.2.0)",
- org.eclipse.jgit.junit;version="[6.1.1,6.2.0)",
- org.eclipse.jgit.junit.http;version="[6.1.1,6.2.0)",
- org.eclipse.jgit.lfs;version="[6.1.1,6.2.0)",
- org.eclipse.jgit.lfs.errors;version="[6.1.1,6.2.0)",
- org.eclipse.jgit.lfs.lib;version="[6.1.1,6.2.0)",
- org.eclipse.jgit.lfs.server;version="[6.1.1,6.2.0)",
- org.eclipse.jgit.lfs.server.fs;version="[6.1.1,6.2.0)",
- org.eclipse.jgit.lfs.test;version="[6.1.1,6.2.0)",
- org.eclipse.jgit.lib;version="[6.1.1,6.2.0)",
- org.eclipse.jgit.revwalk;version="[6.1.1,6.2.0)",
- org.eclipse.jgit.storage.file;version="[6.1.1,6.2.0)",
- org.eclipse.jgit.transport;version="[6.1.1,6.2.0)",
- org.eclipse.jgit.treewalk;version="[6.1.1,6.2.0)",
- org.eclipse.jgit.treewalk.filter;version="[6.1.1,6.2.0)",
- org.eclipse.jgit.util;version="[6.1.1,6.2.0)",
+ org.eclipse.jgit.api;version="[6.2.0,6.3.0)",
+ org.eclipse.jgit.api.errors;version="[6.2.0,6.3.0)",
+ org.eclipse.jgit.internal.storage.file;version="[6.2.0,6.3.0)",
+ org.eclipse.jgit.junit;version="[6.2.0,6.3.0)",
+ org.eclipse.jgit.junit.http;version="[6.2.0,6.3.0)",
+ org.eclipse.jgit.lfs;version="[6.2.0,6.3.0)",
+ org.eclipse.jgit.lfs.errors;version="[6.2.0,6.3.0)",
+ org.eclipse.jgit.lfs.lib;version="[6.2.0,6.3.0)",
+ org.eclipse.jgit.lfs.server;version="[6.2.0,6.3.0)",
+ org.eclipse.jgit.lfs.server.fs;version="[6.2.0,6.3.0)",
+ org.eclipse.jgit.lfs.test;version="[6.2.0,6.3.0)",
+ org.eclipse.jgit.lib;version="[6.2.0,6.3.0)",
+ org.eclipse.jgit.revwalk;version="[6.2.0,6.3.0)",
+ org.eclipse.jgit.storage.file;version="[6.2.0,6.3.0)",
+ org.eclipse.jgit.transport;version="[6.2.0,6.3.0)",
+ org.eclipse.jgit.treewalk;version="[6.2.0,6.3.0)",
+ org.eclipse.jgit.treewalk.filter;version="[6.2.0,6.3.0)",
+ org.eclipse.jgit.util;version="[6.2.0,6.3.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 1bab620..abc5594 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.1.1-SNAPSHOT</version>
+    <version>6.2.0-SNAPSHOT</version>
   </parent>
 
   <artifactId>org.eclipse.jgit.lfs.server.test</artifactId>
diff --git a/org.eclipse.jgit.lfs.server/META-INF/MANIFEST.MF b/org.eclipse.jgit.lfs.server/META-INF/MANIFEST.MF
index cd8bde3..067559f 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.1.1.qualifier
+Bundle-Version: 6.2.0.qualifier
 Bundle-Localization: plugin
 Bundle-Vendor: %Bundle-Vendor
-Export-Package: org.eclipse.jgit.lfs.server;version="6.1.1";
+Export-Package: org.eclipse.jgit.lfs.server;version="6.2.0";
   uses:="javax.servlet.http,
    org.eclipse.jgit.lfs.lib",
- org.eclipse.jgit.lfs.server.fs;version="6.1.1";
+ org.eclipse.jgit.lfs.server.fs;version="6.2.0";
   uses:="javax.servlet,
    javax.servlet.http,
    org.eclipse.jgit.lfs.server,
    org.eclipse.jgit.lfs.lib",
- org.eclipse.jgit.lfs.server.internal;version="6.1.1";x-internal:=true,
- org.eclipse.jgit.lfs.server.s3;version="6.1.1";
+ org.eclipse.jgit.lfs.server.internal;version="6.2.0";x-internal:=true,
+ org.eclipse.jgit.lfs.server.s3;version="6.2.0";
   uses:="org.eclipse.jgit.lfs.server,
    org.eclipse.jgit.lfs.lib"
 Bundle-RequiredExecutionEnvironment: JavaSE-11
@@ -24,15 +24,15 @@
  javax.servlet.annotation;version="[3.1.0,5.0.0)",
  javax.servlet.http;version="[3.1.0,5.0.0)",
  org.apache.http;version="[4.3.0,5.0.0)",
- org.eclipse.jgit.annotations;version="[6.1.1,6.2.0)",
- org.eclipse.jgit.internal;version="[6.1.1,6.2.0)",
- org.eclipse.jgit.internal.storage.file;version="[6.1.1,6.2.0)",
- org.eclipse.jgit.lfs.errors;version="[6.1.1,6.2.0)",
- org.eclipse.jgit.lfs.internal;version="[6.1.1,6.2.0)",
- org.eclipse.jgit.lfs.lib;version="[6.1.1,6.2.0)",
- org.eclipse.jgit.lib;version="[6.1.1,6.2.0)",
- org.eclipse.jgit.nls;version="[6.1.1,6.2.0)",
- org.eclipse.jgit.transport.http;version="[6.1.1,6.2.0)",
- org.eclipse.jgit.transport.http.apache;version="[6.1.1,6.2.0)",
- org.eclipse.jgit.util;version="[6.1.1,6.2.0)",
+ org.eclipse.jgit.annotations;version="[6.2.0,6.3.0)",
+ org.eclipse.jgit.internal;version="[6.2.0,6.3.0)",
+ org.eclipse.jgit.internal.storage.file;version="[6.2.0,6.3.0)",
+ org.eclipse.jgit.lfs.errors;version="[6.2.0,6.3.0)",
+ org.eclipse.jgit.lfs.internal;version="[6.2.0,6.3.0)",
+ org.eclipse.jgit.lfs.lib;version="[6.2.0,6.3.0)",
+ org.eclipse.jgit.lib;version="[6.2.0,6.3.0)",
+ org.eclipse.jgit.nls;version="[6.2.0,6.3.0)",
+ org.eclipse.jgit.transport.http;version="[6.2.0,6.3.0)",
+ org.eclipse.jgit.transport.http.apache;version="[6.2.0,6.3.0)",
+ org.eclipse.jgit.util;version="[6.2.0,6.3.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 5a5b23a..a640bf3 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.1.1.qualifier
-Eclipse-SourceBundle: org.eclipse.jgit.lfs.server;version="6.1.1.qualifier";roots="."
+Bundle-Version: 6.2.0.qualifier
+Eclipse-SourceBundle: org.eclipse.jgit.lfs.server;version="6.2.0.qualifier";roots="."
diff --git a/org.eclipse.jgit.lfs.server/pom.xml b/org.eclipse.jgit.lfs.server/pom.xml
index ae27153..354ed59 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.1.1-SNAPSHOT</version>
+    <version>6.2.0-SNAPSHOT</version>
   </parent>
 
   <artifactId>org.eclipse.jgit.lfs.server</artifactId>
diff --git a/org.eclipse.jgit.lfs.test/META-INF/MANIFEST.MF b/org.eclipse.jgit.lfs.test/META-INF/MANIFEST.MF
index e3c0af8..19f852b 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.1.1.qualifier
+Bundle-Version: 6.2.0.qualifier
 Bundle-Vendor: %Bundle-Vendor
 Bundle-Localization: plugin
 Bundle-RequiredExecutionEnvironment: JavaSE-11
-Import-Package: org.eclipse.jgit.api;version="[6.1.1,6.2.0)",
- org.eclipse.jgit.attributes;version="[6.1.1,6.2.0)",
- org.eclipse.jgit.internal.storage.dfs;version="[6.1.1,6.2.0)",
- org.eclipse.jgit.junit;version="[6.1.1,6.2.0)",
- org.eclipse.jgit.lfs;version="[6.1.1,6.2.0)",
- org.eclipse.jgit.lfs.errors;version="[6.1.1,6.2.0)",
- org.eclipse.jgit.lfs.internal;version="[6.1.1,6.2.0)",
- org.eclipse.jgit.lfs.lib;version="[6.1.1,6.2.0)",
- org.eclipse.jgit.lib;version="[6.1.1,6.2.0)",
- org.eclipse.jgit.revwalk;version="[6.1.1,6.2.0)",
- org.eclipse.jgit.transport;version="[6.1.1,6.2.0)",
- org.eclipse.jgit.transport.http;version="[6.1.1,6.2.0)",
- org.eclipse.jgit.treewalk;version="[6.1.1,6.2.0)",
- org.eclipse.jgit.treewalk.filter;version="[6.1.1,6.2.0)",
- org.eclipse.jgit.util;version="[6.1.1,6.2.0)",
+Import-Package: org.eclipse.jgit.api;version="[6.2.0,6.3.0)",
+ org.eclipse.jgit.attributes;version="[6.2.0,6.3.0)",
+ org.eclipse.jgit.internal.storage.dfs;version="[6.2.0,6.3.0)",
+ org.eclipse.jgit.junit;version="[6.2.0,6.3.0)",
+ org.eclipse.jgit.lfs;version="[6.2.0,6.3.0)",
+ org.eclipse.jgit.lfs.errors;version="[6.2.0,6.3.0)",
+ org.eclipse.jgit.lfs.internal;version="[6.2.0,6.3.0)",
+ org.eclipse.jgit.lfs.lib;version="[6.2.0,6.3.0)",
+ org.eclipse.jgit.lib;version="[6.2.0,6.3.0)",
+ org.eclipse.jgit.revwalk;version="[6.2.0,6.3.0)",
+ org.eclipse.jgit.transport;version="[6.2.0,6.3.0)",
+ org.eclipse.jgit.transport.http;version="[6.2.0,6.3.0)",
+ org.eclipse.jgit.treewalk;version="[6.2.0,6.3.0)",
+ org.eclipse.jgit.treewalk.filter;version="[6.2.0,6.3.0)",
+ org.eclipse.jgit.util;version="[6.2.0,6.3.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.1.1";x-friends:="org.eclipse.jgit.lfs.server.test"
+Export-Package: org.eclipse.jgit.lfs.test;version="6.2.0";x-friends:="org.eclipse.jgit.lfs.server.test"
diff --git a/org.eclipse.jgit.lfs.test/pom.xml b/org.eclipse.jgit.lfs.test/pom.xml
index 1d782e6..5b401ad 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.1.1-SNAPSHOT</version>
+    <version>6.2.0-SNAPSHOT</version>
   </parent>
 
   <artifactId>org.eclipse.jgit.lfs.test</artifactId>
diff --git a/org.eclipse.jgit.lfs.test/tst/org/eclipse/jgit/lfs/LfsConfigGitTest.java b/org.eclipse.jgit.lfs.test/tst/org/eclipse/jgit/lfs/LfsConfigGitTest.java
index 98a0712..3ac4157 100644
--- a/org.eclipse.jgit.lfs.test/tst/org/eclipse/jgit/lfs/LfsConfigGitTest.java
+++ b/org.eclipse.jgit.lfs.test/tst/org/eclipse/jgit/lfs/LfsConfigGitTest.java
@@ -142,14 +142,6 @@
 	File gitAttributesFile;
 
 	private void createLfsFiles(String lfsPointer) throws Exception {
-		/*
-		 * FileNames ".aaa.txt" and "zzz.txt" seem to be sufficient to get the
-		 * desired checkout order before and after ".lfsconfig", at least in a
-		 * number of manual tries. Since the files to checkout are contained in
-		 * a set (see DirCacheCheckout::doCheckout) the order cannot be
-		 * guaranteed.
-		 */
-
 		//File to be checked out before lfs config
 		String fileNameBefore = ".aaa.txt";
 		fileBefore = writeTrashFile(fileNameBefore, lfsPointer);
diff --git a/org.eclipse.jgit.lfs/META-INF/MANIFEST.MF b/org.eclipse.jgit.lfs/META-INF/MANIFEST.MF
index 09ffffb..7a9b5b9 100644
--- a/org.eclipse.jgit.lfs/META-INF/MANIFEST.MF
+++ b/org.eclipse.jgit.lfs/META-INF/MANIFEST.MF
@@ -3,33 +3,32 @@
 Bundle-Name: %Bundle-Name
 Automatic-Module-Name: org.eclipse.jgit.lfs
 Bundle-SymbolicName: org.eclipse.jgit.lfs
-Bundle-Version: 6.1.1.qualifier
+Bundle-Version: 6.2.0.qualifier
 Bundle-Localization: plugin
 Bundle-Vendor: %Bundle-Vendor
-Export-Package: org.eclipse.jgit.lfs;version="6.1.1",
- org.eclipse.jgit.lfs.errors;version="6.1.1",
- org.eclipse.jgit.lfs.internal;version="6.1.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.1.1"
+Export-Package: org.eclipse.jgit.lfs;version="6.2.0",
+ org.eclipse.jgit.lfs.errors;version="6.2.0",
+ org.eclipse.jgit.lfs.internal;version="6.2.0";x-friends:="org.eclipse.jgit.lfs.test,org.eclipse.jgit.lfs.server.fs,org.eclipse.jgit.lfs.server",
+ org.eclipse.jgit.lfs.lib;version="6.2.0"
 Bundle-RequiredExecutionEnvironment: JavaSE-11
 Import-Package: com.google.gson;version="[2.8.2,3.0.0)",
  com.google.gson.stream;version="[2.8.2,3.0.0)",
- org.eclipse.jgit.annotations;version="[6.1.1,6.2.0)";resolution:=optional,
- org.eclipse.jgit.api.errors;version="[6.1.1,6.2.0)",
- org.eclipse.jgit.attributes;version="[6.1.1,6.2.0)",
- org.eclipse.jgit.diff;version="[6.1.1,6.2.0)",
- org.eclipse.jgit.dircache;version="[6.1.1,6.2.0)",
- org.eclipse.jgit.errors;version="[6.1.1,6.2.0)",
- org.eclipse.jgit.hooks;version="[6.1.1,6.2.0)",
- org.eclipse.jgit.internal.storage.file;version="[6.1.1,6.2.0)",
- org.eclipse.jgit.lib;version="[6.1.1,6.2.0)",
- org.eclipse.jgit.nls;version="[6.1.1,6.2.0)",
- org.eclipse.jgit.revwalk;version="[6.1.1,6.2.0)",
- org.eclipse.jgit.storage.file;version="[6.1.1,6.2.0)",
- org.eclipse.jgit.storage.pack;version="[6.1.1,6.2.0)",
- org.eclipse.jgit.transport;version="[6.1.1,6.2.0)",
- org.eclipse.jgit.transport.http;version="[6.1.1,6.2.0)",
- org.eclipse.jgit.treewalk;version="[6.1.1,6.2.0)",
- org.eclipse.jgit.treewalk.filter;version="[6.1.1,6.2.0)",
- org.eclipse.jgit.util;version="[6.1.1,6.2.0)",
- org.eclipse.jgit.util.io;version="[6.1.1,6.2.0)",
- org.slf4j;version="[1.7.0,2.0.0)"
+ org.eclipse.jgit.annotations;version="[6.2.0,6.3.0)";resolution:=optional,
+ org.eclipse.jgit.api.errors;version="[6.2.0,6.3.0)",
+ org.eclipse.jgit.attributes;version="[6.2.0,6.3.0)",
+ org.eclipse.jgit.diff;version="[6.2.0,6.3.0)",
+ org.eclipse.jgit.dircache;version="[6.2.0,6.3.0)",
+ org.eclipse.jgit.errors;version="[6.2.0,6.3.0)",
+ org.eclipse.jgit.hooks;version="[6.2.0,6.3.0)",
+ org.eclipse.jgit.internal.storage.file;version="[6.2.0,6.3.0)",
+ org.eclipse.jgit.lib;version="[6.2.0,6.3.0)",
+ org.eclipse.jgit.nls;version="[6.2.0,6.3.0)",
+ org.eclipse.jgit.revwalk;version="[6.2.0,6.3.0)",
+ org.eclipse.jgit.storage.file;version="[6.2.0,6.3.0)",
+ org.eclipse.jgit.storage.pack;version="[6.2.0,6.3.0)",
+ org.eclipse.jgit.transport;version="[6.2.0,6.3.0)",
+ org.eclipse.jgit.transport.http;version="[6.2.0,6.3.0)",
+ org.eclipse.jgit.treewalk;version="[6.2.0,6.3.0)",
+ org.eclipse.jgit.treewalk.filter;version="[6.2.0,6.3.0)",
+ org.eclipse.jgit.util;version="[6.2.0,6.3.0)",
+ org.eclipse.jgit.util.io;version="[6.2.0,6.3.0)"
diff --git a/org.eclipse.jgit.lfs/META-INF/SOURCE-MANIFEST.MF b/org.eclipse.jgit.lfs/META-INF/SOURCE-MANIFEST.MF
index 7a2a446..2eef821 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.1.1.qualifier
-Eclipse-SourceBundle: org.eclipse.jgit.lfs;version="6.1.1.qualifier";roots="."
+Bundle-Version: 6.2.0.qualifier
+Eclipse-SourceBundle: org.eclipse.jgit.lfs;version="6.2.0.qualifier";roots="."
diff --git a/org.eclipse.jgit.lfs/pom.xml b/org.eclipse.jgit.lfs/pom.xml
index 949c568..4d2766e 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.1.1-SNAPSHOT</version>
+    <version>6.2.0-SNAPSHOT</version>
   </parent>
 
   <artifactId>org.eclipse.jgit.lfs</artifactId>
diff --git a/org.eclipse.jgit.lfs/resources/org/eclipse/jgit/lfs/internal/LfsText.properties b/org.eclipse.jgit.lfs/resources/org/eclipse/jgit/lfs/internal/LfsText.properties
index 642b83d..c4c0dac 100644
--- a/org.eclipse.jgit.lfs/resources/org/eclipse/jgit/lfs/internal/LfsText.properties
+++ b/org.eclipse.jgit.lfs/resources/org/eclipse/jgit/lfs/internal/LfsText.properties
@@ -6,14 +6,13 @@
 invalidLongId=Invalid id: {0}
 invalidLongIdLength=Invalid id length {0}; should be {1}
 lfsFailedToGetRepository=failed to get repository {0}
-lfsNoDownloadUrl="Need to download object from LFS server but couldn't determine LFS server URL"
+lfsNoDownloadUrl=Need to download object from LFS server but couldn't determine LFS server URL
 lfsUnauthorized=Not authorized to perform operation {0} on repository {1}
 lfsUnavailable=LFS is not available for repository {0}
-missingLocalObject="Local Object {0} is missing"
+missingLocalObject=Local Object {0} is missing
 protocolError=LFS Protocol Error {0}: {1}
 repositoryNotFound=Repository {0} not found
 repositoryReadOnly=Repository {0} is read-only
 requiredHashFunctionNotAvailable=Required hash function {0} not available.
 serverFailure=When trying to open a connection to {0} the server responded with an error code. rc={1}
-userConfigInvalid="User config file {0} invalid {1}"
 wrongAmountOfDataReceived=While downloading data from the content server {0} {1} bytes have been received while {2} have been expected
\ No newline at end of file
diff --git a/org.eclipse.jgit.lfs/src/org/eclipse/jgit/lfs/LfsPrePushHook.java b/org.eclipse.jgit.lfs/src/org/eclipse/jgit/lfs/LfsPrePushHook.java
index ebf46e0..9b3d608 100644
--- a/org.eclipse.jgit.lfs/src/org/eclipse/jgit/lfs/LfsPrePushHook.java
+++ b/org.eclipse.jgit.lfs/src/org/eclipse/jgit/lfs/LfsPrePushHook.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2017, Markus Duft <markus.duft@ssi-schaefer.com> and others
+ * Copyright (C) 2017, 2022 Markus Duft <markus.duft@ssi-schaefer.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
@@ -101,8 +101,10 @@
 		}
 		HttpConnection api = LfsConnectionFactory.getLfsConnection(
 				getRepository(), METHOD_POST, OPERATION_UPLOAD);
-		Map<String, LfsPointer> oid2ptr = requestBatchUpload(api, toPush);
-		uploadContents(api, oid2ptr);
+		if (!isDryRun()) {
+			Map<String, LfsPointer> oid2ptr = requestBatchUpload(api, toPush);
+			uploadContents(api, oid2ptr);
+		}
 		return EMPTY;
 
 	}
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 71d395c..857ccbe 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
@@ -30,21 +30,26 @@
 import static org.eclipse.jgit.lib.Constants.HEAD;
 
 /**
- * Encapsulate access to the .lfsconfig.
+ * Encapsulate access to the {@code .lfsconfig}.
+ * <p>
+ * According to the git lfs documentation the order to find the
+ * {@code .lfsconfig} file is:
+ * </p>
+ * <ol>
+ * <li>in the root of the working tree</li>
+ * <li>in the index</li>
+ * <li>in the HEAD; for bare repositories this is the only place that is
+ * searched</li>
+ * </ol>
+ * <p>
+ * Values from the {@code .lfsconfig} are used only if not specified in another
+ * git config file to allow local override without modifiction of a committed
+ * file.
+ * </p>
  *
- * According to the document
- * https://github.com/git-lfs/git-lfs/blob/main/docs/man/git-lfs-config.5.ronn
- * the order to find the .lfsconfig file is:
- *
- * <pre>
- *   1. in the root of the working tree
- *   2. in the index
- *   3. in the HEAD, for bare repositories this is the only place
- *      that is searched
- * </pre>
- *
- * Values from the .lfsconfig are used only if not specified in another git
- * config file to allow local override without modifiction of a committed file.
+ * @see <a href=
+ *      "https://github.com/git-lfs/git-lfs/blob/main/docs/man/git-lfs-config.5.ronn">Configuration
+ *      options for git-lfs</a>
  */
 public class LfsConfig {
 	private Repository db;
@@ -55,17 +60,30 @@
 	 *
 	 * @param db
 	 *            the associated repo
+	 */
+	public LfsConfig(Repository db) {
+		this.db = db;
+	}
+
+	/**
+	 * Getter for the delegate to allow lazy initialization.
+	 *
+	 * @return the delegate {@link Config}
 	 * @throws IOException
 	 */
-	public LfsConfig(Repository db) throws IOException {
-		this.db = db;
-		delegate = this.load();
+	private Config getDelegate() throws IOException {
+		if (delegate == null) {
+			delegate = this.load();
+		}
+		return delegate;
 	}
 
 	/**
 	 * Read the .lfsconfig file from the repository
 	 *
-	 * @return The loaded lfs config or null if it does not exist
+	 * An empty config is returned be empty if no lfs config exists.
+	 *
+	 * @return The loaded lfs config
 	 *
 	 * @throws IOException
 	 */
@@ -102,7 +120,7 @@
 			throws IOException {
 		File lfsConfig = db.getFS().resolve(db.getWorkTree(),
 				Constants.DOT_LFS_CONFIG);
-		if (lfsConfig.exists() && lfsConfig.isFile()) {
+		if (lfsConfig.isFile()) {
 			FileBasedConfig config = new FileBasedConfig(lfsConfig, db.getFS());
 			try {
 				config.load();
@@ -188,12 +206,14 @@
 	 * @param name
 	 *            the key name
 	 * @return a String value from the config, <code>null</code> if not found
+	 * @throws IOException
 	 */
+	@Nullable
 	public String getString(final String section, final String subsection,
-			final String name) {
+			final String name) throws IOException {
 		String result = db.getConfig().getString(section, subsection, name);
 		if (result == null) {
-			result = delegate.getString(section, subsection, name);
+			result = getDelegate().getString(section, subsection, name);
 		}
 		return result;
 	}
diff --git a/org.eclipse.jgit.lfs/src/org/eclipse/jgit/lfs/internal/LfsText.java b/org.eclipse.jgit.lfs/src/org/eclipse/jgit/lfs/internal/LfsText.java
index 06234c1..8ef8f59 100644
--- a/org.eclipse.jgit.lfs/src/org/eclipse/jgit/lfs/internal/LfsText.java
+++ b/org.eclipse.jgit.lfs/src/org/eclipse/jgit/lfs/internal/LfsText.java
@@ -44,6 +44,5 @@
 	/***/ public String repositoryReadOnly;
 	/***/ public String requiredHashFunctionNotAvailable;
 	/***/ public String serverFailure;
-	/***/ public String userConfigInvalid;
 	/***/ public String wrongAmountOfDataReceived;
 }
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 cd22e24..2d52eed 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.1.1.qualifier"
+      version="6.2.0.qualifier"
       provider-name="%providerName">
 
    <description url="http://www.eclipse.org/jgit/">
diff --git a/org.eclipse.jgit.packaging/org.eclipse.jgit.feature/pom.xml b/org.eclipse.jgit.packaging/org.eclipse.jgit.feature/pom.xml
index 54feb9d..7d591ed 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.1.1-SNAPSHOT</version>
+    <version>6.2.0-SNAPSHOT</version>
   </parent>
 
   <groupId>org.eclipse.jgit.feature</groupId>
diff --git a/org.eclipse.jgit.packaging/org.eclipse.jgit.gpg.bc.feature/feature.xml b/org.eclipse.jgit.packaging/org.eclipse.jgit.gpg.bc.feature/feature.xml
index 2061948..cd6746b 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.1.1.qualifier"
+      version="6.2.0.qualifier"
       provider-name="%providerName">
 
    <description url="http://www.eclipse.org/jgit/">
@@ -23,7 +23,7 @@
    </url>
 
    <requires>
-      <import plugin="org.eclipse.jgit" version="6.1.1" match="equivalent"/>
+      <import plugin="org.eclipse.jgit" version="6.2.0" match="equivalent"/>
    </requires>
 
    <plugin
diff --git a/org.eclipse.jgit.packaging/org.eclipse.jgit.gpg.bc.feature/pom.xml b/org.eclipse.jgit.packaging/org.eclipse.jgit.gpg.bc.feature/pom.xml
index 760903e..17ead4e 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.1.1-SNAPSHOT</version>
+    <version>6.2.0-SNAPSHOT</version>
   </parent>
 
   <groupId>org.eclipse.jgit.feature</groupId>
diff --git a/org.eclipse.jgit.packaging/org.eclipse.jgit.http.apache.feature/feature.xml b/org.eclipse.jgit.packaging/org.eclipse.jgit.http.apache.feature/feature.xml
index e899ad5..3081201 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.1.1.qualifier"
+      version="6.2.0.qualifier"
       provider-name="%providerName">
 
    <description url="http://www.eclipse.org/jgit/">
@@ -23,7 +23,7 @@
    </url>
 
    <requires>
-      <import plugin="org.eclipse.jgit" version="6.1.1" match="equivalent"/>
+      <import plugin="org.eclipse.jgit" version="6.2.0" match="equivalent"/>
    </requires>
 
    <plugin
diff --git a/org.eclipse.jgit.packaging/org.eclipse.jgit.http.apache.feature/pom.xml b/org.eclipse.jgit.packaging/org.eclipse.jgit.http.apache.feature/pom.xml
index b725dff..cf091c3 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.1.1-SNAPSHOT</version>
+    <version>6.2.0-SNAPSHOT</version>
   </parent>
 
   <groupId>org.eclipse.jgit.feature</groupId>
diff --git a/org.eclipse.jgit.packaging/org.eclipse.jgit.junit.feature/feature.xml b/org.eclipse.jgit.packaging/org.eclipse.jgit.junit.feature/feature.xml
index 99073e4..9d5839e 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.1.1.qualifier"
+      version="6.2.0.qualifier"
       provider-name="%providerName">
 
    <description url="http://www.eclipse.org/jgit/">
@@ -24,7 +24,7 @@
 
    <requires>
       <import plugin="com.jcraft.jsch"/>
-      <import plugin="org.eclipse.jgit" version="6.1.1" match="equivalent"/>
+      <import plugin="org.eclipse.jgit" version="6.2.0" match="equivalent"/>
    </requires>
 
    <plugin
diff --git a/org.eclipse.jgit.packaging/org.eclipse.jgit.junit.feature/pom.xml b/org.eclipse.jgit.packaging/org.eclipse.jgit.junit.feature/pom.xml
index 3566dbb..938edc8 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.1.1-SNAPSHOT</version>
+    <version>6.2.0-SNAPSHOT</version>
   </parent>
 
   <groupId>org.eclipse.jgit.feature</groupId>
diff --git a/org.eclipse.jgit.packaging/org.eclipse.jgit.lfs.feature/feature.xml b/org.eclipse.jgit.packaging/org.eclipse.jgit.lfs.feature/feature.xml
index c04051b..23159ec 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.1.1.qualifier"
+      version="6.2.0.qualifier"
       provider-name="%providerName">
 
    <description url="http://www.eclipse.org/jgit/">
@@ -23,7 +23,7 @@
    </url>
 
    <requires>
-      <import feature="org.eclipse.jgit" version="6.1.1" match="equivalent"/>
+      <import feature="org.eclipse.jgit" version="6.2.0" match="equivalent"/>
    </requires>
 
    <plugin
diff --git a/org.eclipse.jgit.packaging/org.eclipse.jgit.lfs.feature/pom.xml b/org.eclipse.jgit.packaging/org.eclipse.jgit.lfs.feature/pom.xml
index 50338a6..b416432 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.1.1-SNAPSHOT</version>
+    <version>6.2.0-SNAPSHOT</version>
   </parent>
 
   <groupId>org.eclipse.jgit.feature</groupId>
diff --git a/org.eclipse.jgit.packaging/org.eclipse.jgit.pgm.feature/feature.xml b/org.eclipse.jgit.packaging/org.eclipse.jgit.pgm.feature/feature.xml
index 3939f51..985233b 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.1.1.qualifier"
+      version="6.2.0.qualifier"
       provider-name="%providerName">
 
    <description url="http://www.eclipse.org/jgit/">
@@ -35,9 +35,9 @@
          version="0.0.0"/>
 
    <requires>
-      <import feature="org.eclipse.jgit" version="6.1.1" match="equivalent"/>
-      <import feature="org.eclipse.jgit.lfs" version="6.1.1" match="equivalent"/>
-      <import feature="org.eclipse.jgit.ssh.apache" version="6.1.1" match="equivalent"/>
+      <import feature="org.eclipse.jgit" version="6.2.0" match="equivalent"/>
+      <import feature="org.eclipse.jgit.lfs" version="6.2.0" match="equivalent"/>
+      <import feature="org.eclipse.jgit.ssh.apache" version="6.2.0" match="equivalent"/>
    </requires>
 
    <plugin
diff --git a/org.eclipse.jgit.packaging/org.eclipse.jgit.pgm.feature/pom.xml b/org.eclipse.jgit.packaging/org.eclipse.jgit.pgm.feature/pom.xml
index 4b0e26a..bf8e938 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.1.1-SNAPSHOT</version>
+    <version>6.2.0-SNAPSHOT</version>
   </parent>
 
   <groupId>org.eclipse.jgit.feature</groupId>
diff --git a/org.eclipse.jgit.packaging/org.eclipse.jgit.repository/pom.xml b/org.eclipse.jgit.packaging/org.eclipse.jgit.repository/pom.xml
index 9ccf39e..b38d113 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.1.1-SNAPSHOT</version>
+    <version>6.2.0-SNAPSHOT</version>
   </parent>
 
   <artifactId>org.eclipse.jgit.repository</artifactId>
diff --git a/org.eclipse.jgit.packaging/org.eclipse.jgit.source.feature/feature.xml b/org.eclipse.jgit.packaging/org.eclipse.jgit.source.feature/feature.xml
index d3e662b..f64898d 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.1.1.qualifier"
+      version="6.2.0.qualifier"
       provider-name="%providerName">
 
    <description url="http://www.eclipse.org/jgit/">
@@ -23,7 +23,7 @@
    </url>
 
    <requires>
-      <import feature="org.eclipse.jgit" version="6.1.1" match="equivalent"/>
+      <import feature="org.eclipse.jgit" version="6.2.0" match="equivalent"/>
    </requires>
 
    <plugin
diff --git a/org.eclipse.jgit.packaging/org.eclipse.jgit.source.feature/pom.xml b/org.eclipse.jgit.packaging/org.eclipse.jgit.source.feature/pom.xml
index d8b5de2..fe36483 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.1.1-SNAPSHOT</version>
+    <version>6.2.0-SNAPSHOT</version>
   </parent>
 
   <groupId>org.eclipse.jgit.feature</groupId>
@@ -30,7 +30,7 @@
     <dependency>
       <groupId>org.eclipse.jgit.feature</groupId>
       <artifactId>org.eclipse.jgit</artifactId>
-      <version>6.1.1-SNAPSHOT</version>
+      <version>6.2.0-SNAPSHOT</version>
     </dependency>
   </dependencies>
 
diff --git a/org.eclipse.jgit.packaging/org.eclipse.jgit.ssh.apache.feature/feature.xml b/org.eclipse.jgit.packaging/org.eclipse.jgit.ssh.apache.feature/feature.xml
index e039647..503ce01 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.1.1.qualifier"
+      version="6.2.0.qualifier"
       provider-name="%providerName">
 
    <description url="http://www.eclipse.org/jgit/">
@@ -23,7 +23,7 @@
    </url>
 
    <requires>
-      <import feature="org.eclipse.jgit" version="6.1.1" match="equivalent"/>
+      <import feature="org.eclipse.jgit" version="6.2.0" match="equivalent"/>
    </requires>
 
    <plugin
diff --git a/org.eclipse.jgit.packaging/org.eclipse.jgit.ssh.apache.feature/pom.xml b/org.eclipse.jgit.packaging/org.eclipse.jgit.ssh.apache.feature/pom.xml
index 591b448..ab1f5d3 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.1.1-SNAPSHOT</version>
+    <version>6.2.0-SNAPSHOT</version>
   </parent>
 
   <groupId>org.eclipse.jgit.feature</groupId>
diff --git a/org.eclipse.jgit.packaging/org.eclipse.jgit.ssh.jsch.feature/feature.xml b/org.eclipse.jgit.packaging/org.eclipse.jgit.ssh.jsch.feature/feature.xml
index 3df4a92..94485a2 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.1.1.qualifier"
+      version="6.2.0.qualifier"
       provider-name="%providerName">
 
    <description url="http://www.eclipse.org/jgit/">
@@ -23,7 +23,7 @@
    </url>
 
    <requires>
-      <import plugin="org.eclipse.jgit" version="6.1.1" match="equivalent"/>
+      <import plugin="org.eclipse.jgit" version="6.2.0" match="equivalent"/>
    </requires>
 
    <plugin
diff --git a/org.eclipse.jgit.packaging/org.eclipse.jgit.ssh.jsch.feature/pom.xml b/org.eclipse.jgit.packaging/org.eclipse.jgit.ssh.jsch.feature/pom.xml
index e461bff..a93c70d 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.1.1-SNAPSHOT</version>
+    <version>6.2.0-SNAPSHOT</version>
   </parent>
 
   <groupId>org.eclipse.jgit.feature</groupId>
diff --git a/org.eclipse.jgit.packaging/org.eclipse.jgit.target/META-INF/MANIFEST.MF b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/META-INF/MANIFEST.MF
index 5d61eef..a72e385 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.1.1.qualifier
+Bundle-Version: 6.2.0.qualifier
diff --git a/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.17.target b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.17.target
index 4e40232..117ad0a 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="1646256653">
+<target name="jgit-4.17" sequenceNumber="1651525068">
   <locations>
     <location includeMode="slicer" includeAllPlatforms="false" includeSource="true" includeConfigurePhase="true" type="InstallableUnit">
       <unit id="jakarta.servlet-api" version="4.0.0"/>
@@ -27,8 +27,8 @@
       <unit id="com.google.gson.source" version="2.8.9.v20220111-1409"/>
       <unit id="com.jcraft.jsch" version="0.1.55.v20190404-1902"/>
       <unit id="com.jcraft.jsch.source" version="0.1.55.v20190404-1902"/>
-      <unit id="com.jcraft.jzlib" version="1.1.1.v201205102305"/>
-      <unit id="com.jcraft.jzlib.source" version="1.1.1.v201205102305"/>
+      <unit id="com.jcraft.jzlib" version="1.1.3.v20220502-1820"/>
+      <unit id="com.jcraft.jzlib.source" version="1.1.3.v20220502-1820"/>
       <unit id="com.sun.jna" version="5.8.0.v20210503-0343"/>
       <unit id="com.sun.jna.source" version="5.8.0.v20210503-0343"/>
       <unit id="com.sun.jna.platform" version="5.8.0.v20210406-1004"/>
@@ -87,7 +87,7 @@
       <unit id="org.slf4j.binding.simple.source" version="1.7.30.v20200204-2150"/>
       <unit id="org.tukaani.xz" version="1.9.0.v20210624-1259"/>
       <unit id="org.tukaani.xz.source" version="1.9.0.v20210624-1259"/>
-      <repository location="https://download.eclipse.org/tools/orbit/downloads/drops/R20220302172233/repository"/>
+      <repository location="https://download.eclipse.org/tools/orbit/downloads/drops/I20220502200629/repository"/>
     </location>
     <location includeMode="slicer" includeAllPlatforms="false" includeSource="true" includeConfigurePhase="true" type="InstallableUnit">
       <unit id="org.eclipse.osgi" version="0.0.0"/>
diff --git a/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.17.tpd b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.17.tpd
index dbb450a..c78908b 100644
--- a/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.17.tpd
+++ b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.17.tpd
@@ -1,7 +1,7 @@
 target "jgit-4.17" with source configurePhase
 
 include "projects/jetty-10.0.x.tpd"
-include "orbit/R20220302172233-2022-03.tpd"
+include "orbit/staging-2022-06.tpd"
 
 location "https://download.eclipse.org/releases/2020-09/" {
 	org.eclipse.osgi lazy
diff --git a/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.18.target b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.18.target
index 1628217..adc5aa0 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="1646256653">
+<target name="jgit-4.18" sequenceNumber="1651525068">
   <locations>
     <location includeMode="slicer" includeAllPlatforms="false" includeSource="true" includeConfigurePhase="true" type="InstallableUnit">
       <unit id="jakarta.servlet-api" version="4.0.0"/>
@@ -27,8 +27,8 @@
       <unit id="com.google.gson.source" version="2.8.9.v20220111-1409"/>
       <unit id="com.jcraft.jsch" version="0.1.55.v20190404-1902"/>
       <unit id="com.jcraft.jsch.source" version="0.1.55.v20190404-1902"/>
-      <unit id="com.jcraft.jzlib" version="1.1.1.v201205102305"/>
-      <unit id="com.jcraft.jzlib.source" version="1.1.1.v201205102305"/>
+      <unit id="com.jcraft.jzlib" version="1.1.3.v20220502-1820"/>
+      <unit id="com.jcraft.jzlib.source" version="1.1.3.v20220502-1820"/>
       <unit id="com.sun.jna" version="5.8.0.v20210503-0343"/>
       <unit id="com.sun.jna.source" version="5.8.0.v20210503-0343"/>
       <unit id="com.sun.jna.platform" version="5.8.0.v20210406-1004"/>
@@ -87,7 +87,7 @@
       <unit id="org.slf4j.binding.simple.source" version="1.7.30.v20200204-2150"/>
       <unit id="org.tukaani.xz" version="1.9.0.v20210624-1259"/>
       <unit id="org.tukaani.xz.source" version="1.9.0.v20210624-1259"/>
-      <repository location="https://download.eclipse.org/tools/orbit/downloads/drops/R20220302172233/repository"/>
+      <repository location="https://download.eclipse.org/tools/orbit/downloads/drops/I20220502200629/repository"/>
     </location>
     <location includeMode="slicer" includeAllPlatforms="false" includeSource="true" includeConfigurePhase="true" type="InstallableUnit">
       <unit id="org.eclipse.osgi" version="0.0.0"/>
diff --git a/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.18.tpd b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.18.tpd
index 911c67c..bb94110 100644
--- a/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.18.tpd
+++ b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.18.tpd
@@ -1,7 +1,7 @@
 target "jgit-4.18" with source configurePhase
 
 include "projects/jetty-10.0.x.tpd"
-include "orbit/R20220302172233-2022-03.tpd"
+include "orbit/staging-2022-06.tpd"
 
 location "https://download.eclipse.org/releases/2020-12/" {
 	org.eclipse.osgi lazy
diff --git a/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.19.target b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.19.target
index ab18f7b..5842995 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="1646256653">
+<target name="jgit-4.19-staging" sequenceNumber="1651525065">
   <locations>
     <location includeMode="slicer" includeAllPlatforms="false" includeSource="true" includeConfigurePhase="true" type="InstallableUnit">
       <unit id="jakarta.servlet-api" version="4.0.0"/>
@@ -27,8 +27,8 @@
       <unit id="com.google.gson.source" version="2.8.9.v20220111-1409"/>
       <unit id="com.jcraft.jsch" version="0.1.55.v20190404-1902"/>
       <unit id="com.jcraft.jsch.source" version="0.1.55.v20190404-1902"/>
-      <unit id="com.jcraft.jzlib" version="1.1.1.v201205102305"/>
-      <unit id="com.jcraft.jzlib.source" version="1.1.1.v201205102305"/>
+      <unit id="com.jcraft.jzlib" version="1.1.3.v20220502-1820"/>
+      <unit id="com.jcraft.jzlib.source" version="1.1.3.v20220502-1820"/>
       <unit id="com.sun.jna" version="5.8.0.v20210503-0343"/>
       <unit id="com.sun.jna.source" version="5.8.0.v20210503-0343"/>
       <unit id="com.sun.jna.platform" version="5.8.0.v20210406-1004"/>
@@ -87,7 +87,7 @@
       <unit id="org.slf4j.binding.simple.source" version="1.7.30.v20200204-2150"/>
       <unit id="org.tukaani.xz" version="1.9.0.v20210624-1259"/>
       <unit id="org.tukaani.xz.source" version="1.9.0.v20210624-1259"/>
-      <repository location="https://download.eclipse.org/tools/orbit/downloads/drops/R20220302172233/repository"/>
+      <repository location="https://download.eclipse.org/tools/orbit/downloads/drops/I20220502200629/repository"/>
     </location>
     <location includeMode="slicer" includeAllPlatforms="false" includeSource="true" includeConfigurePhase="true" type="InstallableUnit">
       <unit id="org.eclipse.osgi" version="0.0.0"/>
diff --git a/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.19.tpd b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.19.tpd
index fdb8b11..86d5550 100644
--- a/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.19.tpd
+++ b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.19.tpd
@@ -1,7 +1,7 @@
 target "jgit-4.19-staging" with source configurePhase
 
 include "projects/jetty-10.0.x.tpd"
-include "orbit/R20220302172233-2022-03.tpd"
+include "orbit/staging-2022-06.tpd"
 
 location "https://download.eclipse.org/staging/2021-03/" {
 	org.eclipse.osgi lazy
diff --git a/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.20.target b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.20.target
index 4c840dc..f8f7f3c 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="1646256653">
+<target name="jgit-4.20" sequenceNumber="1651525067">
   <locations>
     <location includeMode="slicer" includeAllPlatforms="false" includeSource="true" includeConfigurePhase="true" type="InstallableUnit">
       <unit id="jakarta.servlet-api" version="4.0.0"/>
@@ -27,8 +27,8 @@
       <unit id="com.google.gson.source" version="2.8.9.v20220111-1409"/>
       <unit id="com.jcraft.jsch" version="0.1.55.v20190404-1902"/>
       <unit id="com.jcraft.jsch.source" version="0.1.55.v20190404-1902"/>
-      <unit id="com.jcraft.jzlib" version="1.1.1.v201205102305"/>
-      <unit id="com.jcraft.jzlib.source" version="1.1.1.v201205102305"/>
+      <unit id="com.jcraft.jzlib" version="1.1.3.v20220502-1820"/>
+      <unit id="com.jcraft.jzlib.source" version="1.1.3.v20220502-1820"/>
       <unit id="com.sun.jna" version="5.8.0.v20210503-0343"/>
       <unit id="com.sun.jna.source" version="5.8.0.v20210503-0343"/>
       <unit id="com.sun.jna.platform" version="5.8.0.v20210406-1004"/>
@@ -87,7 +87,7 @@
       <unit id="org.slf4j.binding.simple.source" version="1.7.30.v20200204-2150"/>
       <unit id="org.tukaani.xz" version="1.9.0.v20210624-1259"/>
       <unit id="org.tukaani.xz.source" version="1.9.0.v20210624-1259"/>
-      <repository location="https://download.eclipse.org/tools/orbit/downloads/drops/R20220302172233/repository"/>
+      <repository location="https://download.eclipse.org/tools/orbit/downloads/drops/I20220502200629/repository"/>
     </location>
     <location includeMode="slicer" includeAllPlatforms="false" includeSource="true" includeConfigurePhase="true" type="InstallableUnit">
       <unit id="org.eclipse.osgi" version="0.0.0"/>
diff --git a/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.20.tpd b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.20.tpd
index 120ee64..55fc7fb 100644
--- a/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.20.tpd
+++ b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.20.tpd
@@ -1,7 +1,7 @@
 target "jgit-4.20" with source configurePhase
 
 include "projects/jetty-10.0.x.tpd"
-include "orbit/R20220302172233-2022-03.tpd"
+include "orbit/staging-2022-06.tpd"
 
 location "https://download.eclipse.org/releases/2021-06/" {
 	org.eclipse.osgi lazy
diff --git a/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.21.target b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.21.target
index 7e8cd91..503f653 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="1646256653">
+<target name="jgit-4.21" sequenceNumber="1651525068">
   <locations>
     <location includeMode="slicer" includeAllPlatforms="false" includeSource="true" includeConfigurePhase="true" type="InstallableUnit">
       <unit id="jakarta.servlet-api" version="4.0.0"/>
@@ -27,8 +27,8 @@
       <unit id="com.google.gson.source" version="2.8.9.v20220111-1409"/>
       <unit id="com.jcraft.jsch" version="0.1.55.v20190404-1902"/>
       <unit id="com.jcraft.jsch.source" version="0.1.55.v20190404-1902"/>
-      <unit id="com.jcraft.jzlib" version="1.1.1.v201205102305"/>
-      <unit id="com.jcraft.jzlib.source" version="1.1.1.v201205102305"/>
+      <unit id="com.jcraft.jzlib" version="1.1.3.v20220502-1820"/>
+      <unit id="com.jcraft.jzlib.source" version="1.1.3.v20220502-1820"/>
       <unit id="com.sun.jna" version="5.8.0.v20210503-0343"/>
       <unit id="com.sun.jna.source" version="5.8.0.v20210503-0343"/>
       <unit id="com.sun.jna.platform" version="5.8.0.v20210406-1004"/>
@@ -87,7 +87,7 @@
       <unit id="org.slf4j.binding.simple.source" version="1.7.30.v20200204-2150"/>
       <unit id="org.tukaani.xz" version="1.9.0.v20210624-1259"/>
       <unit id="org.tukaani.xz.source" version="1.9.0.v20210624-1259"/>
-      <repository location="https://download.eclipse.org/tools/orbit/downloads/drops/R20220302172233/repository"/>
+      <repository location="https://download.eclipse.org/tools/orbit/downloads/drops/I20220502200629/repository"/>
     </location>
     <location includeMode="slicer" includeAllPlatforms="false" includeSource="true" includeConfigurePhase="true" type="InstallableUnit">
       <unit id="org.eclipse.osgi" version="0.0.0"/>
diff --git a/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.21.tpd b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.21.tpd
index 0ec2a52..10acb68 100644
--- a/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.21.tpd
+++ b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.21.tpd
@@ -1,7 +1,7 @@
 target "jgit-4.21" with source configurePhase
 
 include "projects/jetty-10.0.x.tpd"
-include "orbit/R20220302172233-2022-03.tpd"
+include "orbit/staging-2022-06.tpd"
 
 location "https://download.eclipse.org/releases/2021-09/" {
 	org.eclipse.osgi lazy
diff --git a/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.22.target b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.22.target
index b229da1..c40cde3 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="1646256653">
+<target name="jgit-4.22" sequenceNumber="1651525008">
   <locations>
     <location includeMode="slicer" includeAllPlatforms="false" includeSource="true" includeConfigurePhase="true" type="InstallableUnit">
       <unit id="jakarta.servlet-api" version="4.0.0"/>
@@ -27,8 +27,8 @@
       <unit id="com.google.gson.source" version="2.8.9.v20220111-1409"/>
       <unit id="com.jcraft.jsch" version="0.1.55.v20190404-1902"/>
       <unit id="com.jcraft.jsch.source" version="0.1.55.v20190404-1902"/>
-      <unit id="com.jcraft.jzlib" version="1.1.1.v201205102305"/>
-      <unit id="com.jcraft.jzlib.source" version="1.1.1.v201205102305"/>
+      <unit id="com.jcraft.jzlib" version="1.1.3.v20220502-1820"/>
+      <unit id="com.jcraft.jzlib.source" version="1.1.3.v20220502-1820"/>
       <unit id="com.sun.jna" version="5.8.0.v20210503-0343"/>
       <unit id="com.sun.jna.source" version="5.8.0.v20210503-0343"/>
       <unit id="com.sun.jna.platform" version="5.8.0.v20210406-1004"/>
@@ -87,7 +87,7 @@
       <unit id="org.slf4j.binding.simple.source" version="1.7.30.v20200204-2150"/>
       <unit id="org.tukaani.xz" version="1.9.0.v20210624-1259"/>
       <unit id="org.tukaani.xz.source" version="1.9.0.v20210624-1259"/>
-      <repository location="https://download.eclipse.org/tools/orbit/downloads/drops/R20220302172233/repository"/>
+      <repository location="https://download.eclipse.org/tools/orbit/downloads/drops/I20220502200629/repository"/>
     </location>
     <location includeMode="slicer" includeAllPlatforms="false" includeSource="true" includeConfigurePhase="true" type="InstallableUnit">
       <unit id="org.eclipse.osgi" version="0.0.0"/>
diff --git a/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.22.tpd b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.22.tpd
index eb1723c..9b2533b 100644
--- a/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.22.tpd
+++ b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.22.tpd
@@ -1,7 +1,7 @@
 target "jgit-4.22" with source configurePhase
 
 include "projects/jetty-10.0.x.tpd"
-include "orbit/R20220302172233-2022-03.tpd"
+include "orbit/staging-2022-06.tpd"
 
 location "https://download.eclipse.org/releases/2021-12/" {
 	org.eclipse.osgi lazy
diff --git a/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.23.target b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.23.target
new file mode 100644
index 0000000..78456d4
--- /dev/null
+++ b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.23.target
@@ -0,0 +1,97 @@
+<?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="1651531554">
+  <locations>
+    <location includeMode="slicer" includeAllPlatforms="false" includeSource="true" includeConfigurePhase="true" type="InstallableUnit">
+      <unit id="jakarta.servlet-api" version="4.0.0"/>
+      <unit id="jakarta.servlet-api.source" version="4.0.0"/>
+      <unit id="org.eclipse.jetty.http" version="10.0.6"/>
+      <unit id="org.eclipse.jetty.http.source" version="10.0.6"/>
+      <unit id="org.eclipse.jetty.io" version="10.0.6"/>
+      <unit id="org.eclipse.jetty.io.source" version="10.0.6"/>
+      <unit id="org.eclipse.jetty.security" version="10.0.6"/>
+      <unit id="org.eclipse.jetty.security.source" version="10.0.6"/>
+      <unit id="org.eclipse.jetty.server" version="10.0.6"/>
+      <unit id="org.eclipse.jetty.server.source" version="10.0.6"/>
+      <unit id="org.eclipse.jetty.servlet" version="10.0.6"/>
+      <unit id="org.eclipse.jetty.servlet.source" version="10.0.6"/>
+      <unit id="org.eclipse.jetty.util" version="10.0.6"/>
+      <unit id="org.eclipse.jetty.util.source" version="10.0.6"/>
+      <unit id="org.eclipse.jetty.util.ajax" version="10.0.6"/>
+      <unit id="org.eclipse.jetty.util.ajax.source" version="10.0.6"/>
+      <repository id="jetty-10.0.x" location="https://download.eclipse.org/eclipse/jetty/10.0.6/"/>
+    </location>
+    <location includeMode="slicer" includeAllPlatforms="false" includeSource="true" includeConfigurePhase="true" type="InstallableUnit">
+      <unit id="com.google.gson" version="2.8.9.v20220111-1409"/>
+      <unit id="com.google.gson.source" version="2.8.9.v20220111-1409"/>
+      <unit id="com.jcraft.jsch" version="0.1.55.v20190404-1902"/>
+      <unit id="com.jcraft.jsch.source" version="0.1.55.v20190404-1902"/>
+      <unit id="com.jcraft.jzlib" version="1.1.3.v20220502-1820"/>
+      <unit id="com.jcraft.jzlib.source" version="1.1.3.v20220502-1820"/>
+      <unit id="com.sun.jna" version="5.8.0.v20210503-0343"/>
+      <unit id="com.sun.jna.source" version="5.8.0.v20210503-0343"/>
+      <unit id="com.sun.jna.platform" version="5.8.0.v20210406-1004"/>
+      <unit id="com.sun.jna.platform.source" version="5.8.0.v20210406-1004"/>
+      <unit id="javaewah" version="1.1.13.v20211029-0839"/>
+      <unit id="javaewah.source" version="1.1.13.v20211029-0839"/>
+      <unit id="net.bytebuddy.byte-buddy" version="1.9.0.v20181107-1410"/>
+      <unit id="net.bytebuddy.byte-buddy-agent" version="1.9.0.v20181106-1534"/>
+      <unit id="net.bytebuddy.byte-buddy-agent.source" version="1.9.0.v20181106-1534"/>
+      <unit id="net.bytebuddy.byte-buddy.source" version="1.9.0.v20181107-1410"/>
+      <unit id="net.i2p.crypto.eddsa" version="0.3.0.v20210923-1401"/>
+      <unit id="net.i2p.crypto.eddsa.source" version="0.3.0.v20210923-1401"/>
+      <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.commons.codec" version="1.14.0.v20200818-1422"/>
+      <unit id="org.apache.commons.codec.source" version="1.14.0.v20200818-1422"/>
+      <unit id="org.apache.commons.compress" version="1.21.0.v20211103-2100"/>
+      <unit id="org.apache.commons.compress.source" version="1.21.0.v20211103-2100"/>
+      <unit id="org.apache.commons.logging" version="1.2.0.v20180409-1502"/>
+      <unit id="org.apache.commons.logging.source" version="1.2.0.v20180409-1502"/>
+      <unit id="org.apache.httpcomponents.httpclient" version="4.5.13.v20210128-2225"/>
+      <unit id="org.apache.httpcomponents.httpclient.source" version="4.5.13.v20210128-2225"/>
+      <unit id="org.apache.httpcomponents.httpcore" version="4.4.15.v20220209-2345"/>
+      <unit id="org.apache.httpcomponents.httpcore.source" version="4.4.15.v20220209-2345"/>
+      <unit id="org.apache.sshd.osgi" version="2.8.0.v20211227-1750"/>
+      <unit id="org.apache.sshd.osgi.source" version="2.8.0.v20211227-1750"/>
+      <unit id="org.apache.sshd.sftp" version="2.8.0.v20211227-1750"/>
+      <unit id="org.apache.sshd.sftp.source" version="2.8.0.v20211227-1750"/>
+      <unit id="org.assertj" version="3.20.2.v20210706-1104"/>
+      <unit id="org.assertj.source" version="3.20.2.v20210706-1104"/>
+      <unit id="org.bouncycastle.bcpg" version="1.70.0.v20220105-1522"/>
+      <unit id="org.bouncycastle.bcpg.source" version="1.70.0.v20220105-1522"/>
+      <unit id="org.bouncycastle.bcpkix" version="1.70.0.v20220105-1522"/>
+      <unit id="org.bouncycastle.bcpkix.source" version="1.70.0.v20220105-1522"/>
+      <unit id="org.bouncycastle.bcprov" version="1.70.0.v20220105-1522"/>
+      <unit id="org.bouncycastle.bcprov.source" version="1.70.0.v20220105-1522"/>
+      <unit id="org.bouncycastle.bcutil" version="1.70.0.v20220105-1522"/>
+      <unit id="org.bouncycastle.bcutil.source" version="1.70.0.v20220105-1522"/>
+      <unit id="org.hamcrest" version="2.2.0.v20210711-0821"/>
+      <unit id="org.hamcrest.source" version="2.2.0.v20210711-0821"/>
+      <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.kohsuke.args4j" version="2.33.0.v20160323-2218"/>
+      <unit id="org.kohsuke.args4j.source" version="2.33.0.v20160323-2218"/>
+      <unit id="org.mockito" version="2.23.0.v20200310-1642"/>
+      <unit id="org.mockito.source" version="2.23.0.v20200310-1642"/>
+      <unit id="org.objenesis" version="2.6.0.v20180420-1519"/>
+      <unit id="org.objenesis.source" version="2.6.0.v20180420-1519"/>
+      <unit id="org.slf4j.api" version="1.7.30.v20200204-2150"/>
+      <unit id="org.slf4j.api.source" version="1.7.30.v20200204-2150"/>
+      <unit id="org.slf4j.binding.simple" version="1.7.30.v20200204-2150"/>
+      <unit id="org.slf4j.binding.simple.source" version="1.7.30.v20200204-2150"/>
+      <unit id="org.tukaani.xz" version="1.9.0.v20210624-1259"/>
+      <unit id="org.tukaani.xz.source" version="1.9.0.v20210624-1259"/>
+      <repository location="https://download.eclipse.org/tools/orbit/downloads/drops/I20220502200629/repository"/>
+    </location>
+    <location includeMode="slicer" includeAllPlatforms="false" includeSource="true" includeConfigurePhase="true" type="InstallableUnit">
+      <unit id="org.eclipse.osgi" version="0.0.0"/>
+      <repository location="https://download.eclipse.org/releases/2022-03/"/>
+    </location>
+  </locations>
+</target>
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
new file mode 100644
index 0000000..69c9a11
--- /dev/null
+++ b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.23.tpd
@@ -0,0 +1,8 @@
+target "jgit-4.23" with source configurePhase
+
+include "projects/jetty-10.0.x.tpd"
+include "orbit/staging-2022-06.tpd"
+
+location "https://download.eclipse.org/releases/2022-03/" {
+	org.eclipse.osgi lazy
+}
diff --git a/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.24.target b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.24.target
new file mode 100644
index 0000000..12b5ea8
--- /dev/null
+++ b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.24.target
@@ -0,0 +1,97 @@
+<?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="1651531556">
+  <locations>
+    <location includeMode="slicer" includeAllPlatforms="false" includeSource="true" includeConfigurePhase="true" type="InstallableUnit">
+      <unit id="jakarta.servlet-api" version="4.0.0"/>
+      <unit id="jakarta.servlet-api.source" version="4.0.0"/>
+      <unit id="org.eclipse.jetty.http" version="10.0.6"/>
+      <unit id="org.eclipse.jetty.http.source" version="10.0.6"/>
+      <unit id="org.eclipse.jetty.io" version="10.0.6"/>
+      <unit id="org.eclipse.jetty.io.source" version="10.0.6"/>
+      <unit id="org.eclipse.jetty.security" version="10.0.6"/>
+      <unit id="org.eclipse.jetty.security.source" version="10.0.6"/>
+      <unit id="org.eclipse.jetty.server" version="10.0.6"/>
+      <unit id="org.eclipse.jetty.server.source" version="10.0.6"/>
+      <unit id="org.eclipse.jetty.servlet" version="10.0.6"/>
+      <unit id="org.eclipse.jetty.servlet.source" version="10.0.6"/>
+      <unit id="org.eclipse.jetty.util" version="10.0.6"/>
+      <unit id="org.eclipse.jetty.util.source" version="10.0.6"/>
+      <unit id="org.eclipse.jetty.util.ajax" version="10.0.6"/>
+      <unit id="org.eclipse.jetty.util.ajax.source" version="10.0.6"/>
+      <repository id="jetty-10.0.x" location="https://download.eclipse.org/eclipse/jetty/10.0.6/"/>
+    </location>
+    <location includeMode="slicer" includeAllPlatforms="false" includeSource="true" includeConfigurePhase="true" type="InstallableUnit">
+      <unit id="com.google.gson" version="2.8.9.v20220111-1409"/>
+      <unit id="com.google.gson.source" version="2.8.9.v20220111-1409"/>
+      <unit id="com.jcraft.jsch" version="0.1.55.v20190404-1902"/>
+      <unit id="com.jcraft.jsch.source" version="0.1.55.v20190404-1902"/>
+      <unit id="com.jcraft.jzlib" version="1.1.3.v20220502-1820"/>
+      <unit id="com.jcraft.jzlib.source" version="1.1.3.v20220502-1820"/>
+      <unit id="com.sun.jna" version="5.8.0.v20210503-0343"/>
+      <unit id="com.sun.jna.source" version="5.8.0.v20210503-0343"/>
+      <unit id="com.sun.jna.platform" version="5.8.0.v20210406-1004"/>
+      <unit id="com.sun.jna.platform.source" version="5.8.0.v20210406-1004"/>
+      <unit id="javaewah" version="1.1.13.v20211029-0839"/>
+      <unit id="javaewah.source" version="1.1.13.v20211029-0839"/>
+      <unit id="net.bytebuddy.byte-buddy" version="1.9.0.v20181107-1410"/>
+      <unit id="net.bytebuddy.byte-buddy-agent" version="1.9.0.v20181106-1534"/>
+      <unit id="net.bytebuddy.byte-buddy-agent.source" version="1.9.0.v20181106-1534"/>
+      <unit id="net.bytebuddy.byte-buddy.source" version="1.9.0.v20181107-1410"/>
+      <unit id="net.i2p.crypto.eddsa" version="0.3.0.v20210923-1401"/>
+      <unit id="net.i2p.crypto.eddsa.source" version="0.3.0.v20210923-1401"/>
+      <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.commons.codec" version="1.14.0.v20200818-1422"/>
+      <unit id="org.apache.commons.codec.source" version="1.14.0.v20200818-1422"/>
+      <unit id="org.apache.commons.compress" version="1.21.0.v20211103-2100"/>
+      <unit id="org.apache.commons.compress.source" version="1.21.0.v20211103-2100"/>
+      <unit id="org.apache.commons.logging" version="1.2.0.v20180409-1502"/>
+      <unit id="org.apache.commons.logging.source" version="1.2.0.v20180409-1502"/>
+      <unit id="org.apache.httpcomponents.httpclient" version="4.5.13.v20210128-2225"/>
+      <unit id="org.apache.httpcomponents.httpclient.source" version="4.5.13.v20210128-2225"/>
+      <unit id="org.apache.httpcomponents.httpcore" version="4.4.15.v20220209-2345"/>
+      <unit id="org.apache.httpcomponents.httpcore.source" version="4.4.15.v20220209-2345"/>
+      <unit id="org.apache.sshd.osgi" version="2.8.0.v20211227-1750"/>
+      <unit id="org.apache.sshd.osgi.source" version="2.8.0.v20211227-1750"/>
+      <unit id="org.apache.sshd.sftp" version="2.8.0.v20211227-1750"/>
+      <unit id="org.apache.sshd.sftp.source" version="2.8.0.v20211227-1750"/>
+      <unit id="org.assertj" version="3.20.2.v20210706-1104"/>
+      <unit id="org.assertj.source" version="3.20.2.v20210706-1104"/>
+      <unit id="org.bouncycastle.bcpg" version="1.70.0.v20220105-1522"/>
+      <unit id="org.bouncycastle.bcpg.source" version="1.70.0.v20220105-1522"/>
+      <unit id="org.bouncycastle.bcpkix" version="1.70.0.v20220105-1522"/>
+      <unit id="org.bouncycastle.bcpkix.source" version="1.70.0.v20220105-1522"/>
+      <unit id="org.bouncycastle.bcprov" version="1.70.0.v20220105-1522"/>
+      <unit id="org.bouncycastle.bcprov.source" version="1.70.0.v20220105-1522"/>
+      <unit id="org.bouncycastle.bcutil" version="1.70.0.v20220105-1522"/>
+      <unit id="org.bouncycastle.bcutil.source" version="1.70.0.v20220105-1522"/>
+      <unit id="org.hamcrest" version="2.2.0.v20210711-0821"/>
+      <unit id="org.hamcrest.source" version="2.2.0.v20210711-0821"/>
+      <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.kohsuke.args4j" version="2.33.0.v20160323-2218"/>
+      <unit id="org.kohsuke.args4j.source" version="2.33.0.v20160323-2218"/>
+      <unit id="org.mockito" version="2.23.0.v20200310-1642"/>
+      <unit id="org.mockito.source" version="2.23.0.v20200310-1642"/>
+      <unit id="org.objenesis" version="2.6.0.v20180420-1519"/>
+      <unit id="org.objenesis.source" version="2.6.0.v20180420-1519"/>
+      <unit id="org.slf4j.api" version="1.7.30.v20200204-2150"/>
+      <unit id="org.slf4j.api.source" version="1.7.30.v20200204-2150"/>
+      <unit id="org.slf4j.binding.simple" version="1.7.30.v20200204-2150"/>
+      <unit id="org.slf4j.binding.simple.source" version="1.7.30.v20200204-2150"/>
+      <unit id="org.tukaani.xz" version="1.9.0.v20210624-1259"/>
+      <unit id="org.tukaani.xz.source" version="1.9.0.v20210624-1259"/>
+      <repository location="https://download.eclipse.org/tools/orbit/downloads/drops/I20220502200629/repository"/>
+    </location>
+    <location includeMode="slicer" includeAllPlatforms="false" includeSource="true" includeConfigurePhase="true" type="InstallableUnit">
+      <unit id="org.eclipse.osgi" version="0.0.0"/>
+      <repository location="https://download.eclipse.org/staging/2022-06/"/>
+    </location>
+  </locations>
+</target>
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
new file mode 100644
index 0000000..9b8e6f8
--- /dev/null
+++ b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.24.tpd
@@ -0,0 +1,8 @@
+target "jgit-4.24" with source configurePhase
+
+include "projects/jetty-10.0.x.tpd"
+include "orbit/staging-2022-06.tpd"
+
+location "https://download.eclipse.org/staging/2022-06/" {
+	org.eclipse.osgi lazy
+}
diff --git a/org.eclipse.jgit.packaging/org.eclipse.jgit.target/orbit/staging-2022-06.tpd b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/orbit/staging-2022-06.tpd
new file mode 100644
index 0000000..9e32ba4
--- /dev/null
+++ b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/orbit/staging-2022-06.tpd
@@ -0,0 +1,69 @@
+target "staging-2022-06" with source configurePhase
+// see https://download.eclipse.org/tools/orbit/downloads/
+
+location "https://download.eclipse.org/tools/orbit/downloads/drops/I20220502200629/repository" {
+	com.google.gson [2.8.9.v20220111-1409,2.8.9.v20220111-1409]
+	com.google.gson.source [2.8.9.v20220111-1409,2.8.9.v20220111-1409]
+	com.jcraft.jsch [0.1.55.v20190404-1902,0.1.55.v20190404-1902]
+	com.jcraft.jsch.source [0.1.55.v20190404-1902,0.1.55.v20190404-1902]
+	com.jcraft.jzlib [1.1.3.v20220502-1820,1.1.3.v20220502-1820]
+	com.jcraft.jzlib.source [1.1.3.v20220502-1820,1.1.3.v20220502-1820]
+	com.sun.jna [5.8.0.v20210503-0343,5.8.0.v20210503-0343]
+	com.sun.jna.source [5.8.0.v20210503-0343,5.8.0.v20210503-0343]
+	com.sun.jna.platform [5.8.0.v20210406-1004,5.8.0.v20210406-1004]
+	com.sun.jna.platform.source [5.8.0.v20210406-1004,5.8.0.v20210406-1004]
+	javaewah [1.1.13.v20211029-0839,1.1.13.v20211029-0839]
+	javaewah.source [1.1.13.v20211029-0839,1.1.13.v20211029-0839]
+	net.bytebuddy.byte-buddy [1.9.0.v20181107-1410,1.9.0.v20181107-1410]
+	net.bytebuddy.byte-buddy-agent [1.9.0.v20181106-1534,1.9.0.v20181106-1534]
+	net.bytebuddy.byte-buddy-agent.source [1.9.0.v20181106-1534,1.9.0.v20181106-1534]
+	net.bytebuddy.byte-buddy.source [1.9.0.v20181107-1410,1.9.0.v20181107-1410]
+	net.i2p.crypto.eddsa [0.3.0.v20210923-1401,0.3.0.v20210923-1401]
+	net.i2p.crypto.eddsa.source [0.3.0.v20210923-1401,0.3.0.v20210923-1401]
+	org.apache.ant [1.10.12.v20211102-1452,1.10.12.v20211102-1452]
+	org.apache.ant.source [1.10.12.v20211102-1452,1.10.12.v20211102-1452]
+	org.apache.commons.codec [1.14.0.v20200818-1422,1.14.0.v20200818-1422]
+	org.apache.commons.codec.source [1.14.0.v20200818-1422,1.14.0.v20200818-1422]
+	org.apache.commons.compress [1.21.0.v20211103-2100,1.21.0.v20211103-2100]
+	org.apache.commons.compress.source [1.21.0.v20211103-2100,1.21.0.v20211103-2100]
+	org.apache.commons.logging [1.2.0.v20180409-1502,1.2.0.v20180409-1502]
+	org.apache.commons.logging.source [1.2.0.v20180409-1502,1.2.0.v20180409-1502]
+	org.apache.httpcomponents.httpclient [4.5.13.v20210128-2225,4.5.13.v20210128-2225]
+	org.apache.httpcomponents.httpclient.source [4.5.13.v20210128-2225,4.5.13.v20210128-2225]
+	org.apache.httpcomponents.httpcore [4.4.15.v20220209-2345,4.4.15.v20220209-2345]
+	org.apache.httpcomponents.httpcore.source [4.4.15.v20220209-2345,4.4.15.v20220209-2345]
+	org.apache.sshd.osgi [2.8.0.v20211227-1750,2.8.0.v20211227-1750]
+	org.apache.sshd.osgi.source [2.8.0.v20211227-1750,2.8.0.v20211227-1750]
+	org.apache.sshd.sftp [2.8.0.v20211227-1750,2.8.0.v20211227-1750]
+	org.apache.sshd.sftp.source [2.8.0.v20211227-1750,2.8.0.v20211227-1750]
+	org.assertj [3.20.2.v20210706-1104,3.20.2.v20210706-1104]
+	org.assertj.source [3.20.2.v20210706-1104,3.20.2.v20210706-1104]
+	org.bouncycastle.bcpg [1.70.0.v20220105-1522,1.70.0.v20220105-1522]
+	org.bouncycastle.bcpg.source [1.70.0.v20220105-1522,1.70.0.v20220105-1522]
+	org.bouncycastle.bcpkix [1.70.0.v20220105-1522,1.70.0.v20220105-1522]
+	org.bouncycastle.bcpkix.source [1.70.0.v20220105-1522,1.70.0.v20220105-1522]
+	org.bouncycastle.bcprov [1.70.0.v20220105-1522,1.70.0.v20220105-1522]
+	org.bouncycastle.bcprov.source [1.70.0.v20220105-1522,1.70.0.v20220105-1522]
+	org.bouncycastle.bcutil [1.70.0.v20220105-1522,1.70.0.v20220105-1522]
+	org.bouncycastle.bcutil.source [1.70.0.v20220105-1522,1.70.0.v20220105-1522]
+	org.hamcrest [2.2.0.v20210711-0821,2.2.0.v20210711-0821]
+	org.hamcrest.source [2.2.0.v20210711-0821,2.2.0.v20210711-0821]
+	org.hamcrest.core [1.3.0.v20180420-1519,1.3.0.v20180420-1519]
+	org.hamcrest.core.source [1.3.0.v20180420-1519,1.3.0.v20180420-1519]
+	org.hamcrest.library [1.3.0.v20180524-2246,1.3.0.v20180524-2246]
+	org.hamcrest.library.source [1.3.0.v20180524-2246,1.3.0.v20180524-2246]
+	org.junit [4.13.2.v20211018-1956,4.13.2.v20211018-1956]
+	org.junit.source [4.13.2.v20211018-1956,4.13.2.v20211018-1956]
+	org.kohsuke.args4j [2.33.0.v20160323-2218,2.33.0.v20160323-2218]
+	org.kohsuke.args4j.source [2.33.0.v20160323-2218,2.33.0.v20160323-2218]
+	org.mockito [2.23.0.v20200310-1642,2.23.0.v20200310-1642]
+	org.mockito.source [2.23.0.v20200310-1642,2.23.0.v20200310-1642]
+	org.objenesis [2.6.0.v20180420-1519,2.6.0.v20180420-1519]
+	org.objenesis.source [2.6.0.v20180420-1519,2.6.0.v20180420-1519]
+	org.slf4j.api [1.7.30.v20200204-2150,1.7.30.v20200204-2150]
+	org.slf4j.api.source [1.7.30.v20200204-2150,1.7.30.v20200204-2150]
+	org.slf4j.binding.simple [1.7.30.v20200204-2150,1.7.30.v20200204-2150]
+	org.slf4j.binding.simple.source [1.7.30.v20200204-2150,1.7.30.v20200204-2150]
+	org.tukaani.xz [1.9.0.v20210624-1259,1.9.0.v20210624-1259]
+	org.tukaani.xz.source [1.9.0.v20210624-1259,1.9.0.v20210624-1259]
+}
diff --git a/org.eclipse.jgit.packaging/org.eclipse.jgit.target/pom.xml b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/pom.xml
index 2a95042..2296e95 100644
--- a/org.eclipse.jgit.packaging/org.eclipse.jgit.target/pom.xml
+++ b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/pom.xml
@@ -16,37 +16,10 @@
   <parent>
     <groupId>org.eclipse.jgit</groupId>
     <artifactId>jgit.tycho.parent</artifactId>
-    <version>6.1.1-SNAPSHOT</version>
+    <version>6.2.0-SNAPSHOT</version>
   </parent>
 
   <artifactId>org.eclipse.jgit.target</artifactId>
   <packaging>pom</packaging>
   <name>JGit Target Platform</name>
-
-  <build>
-    <plugins>
-      <plugin>
-        <groupId>org.codehaus.mojo</groupId>
-        <artifactId>build-helper-maven-plugin</artifactId>
-        <executions>
-          <execution>
-            <id>attach-artifacts</id>
-            <phase>package</phase>
-            <goals>
-              <goal>attach-artifact</goal>
-            </goals>
-            <configuration>
-              <artifacts>
-                <artifact>
-                  <file>${target-platform}.target</file>
-                  <type>target</type>
-                  <classifier>${target-platform}</classifier>
-                </artifact>
-              </artifacts>
-            </configuration>
-          </execution>
-        </executions>
-      </plugin>
-    </plugins>
-  </build>
 </project>
\ No newline at end of file
diff --git a/org.eclipse.jgit.packaging/pom.xml b/org.eclipse.jgit.packaging/pom.xml
index b650598..bfcfd65 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.1.1-SNAPSHOT</version>
+  <version>6.2.0-SNAPSHOT</version>
   <packaging>pom</packaging>
 
   <name>JGit Tycho Parent</name>
 
   <properties>
     <java.version>11</java.version>
-    <tycho-version>2.5.0</tycho-version>
+    <tycho-version>2.6.0</tycho-version>
     <tycho-extras-version>${tycho-version}</tycho-extras-version>
     <target-platform>jgit-4.17</target-platform>
   </properties>
@@ -231,12 +231,7 @@
             <resolver>p2</resolver>
             <pomDependencies>consider</pomDependencies>
             <target>
-              <artifact>
-                <groupId>org.eclipse.jgit</groupId>
-                <artifactId>org.eclipse.jgit.target</artifactId>
-                <version>${project.version}</version>
-                <classifier>${target-platform}</classifier>
-              </artifact>
+              <file>${project.basedir}/../org.eclipse.jgit.target/${target-platform}.target</file>
             </target>
             <environments>
               <environment>
diff --git a/org.eclipse.jgit.pgm.test/META-INF/MANIFEST.MF b/org.eclipse.jgit.pgm.test/META-INF/MANIFEST.MF
index f5c4de4..c1b6ae6 100644
--- a/org.eclipse.jgit.pgm.test/META-INF/MANIFEST.MF
+++ b/org.eclipse.jgit.pgm.test/META-INF/MANIFEST.MF
@@ -3,31 +3,31 @@
 Bundle-Name: %Bundle-Name
 Automatic-Module-Name: org.eclipse.jgit.pgm.test
 Bundle-SymbolicName: org.eclipse.jgit.pgm.test
-Bundle-Version: 6.1.1.qualifier
+Bundle-Version: 6.2.0.qualifier
 Bundle-Vendor: %Bundle-Vendor
 Bundle-Localization: plugin
 Bundle-ActivationPolicy: lazy
 Bundle-RequiredExecutionEnvironment: JavaSE-11
-Import-Package: org.eclipse.jgit.api;version="[6.1.1,6.2.0)",
- org.eclipse.jgit.api.errors;version="[6.1.1,6.2.0)",
- org.eclipse.jgit.diff;version="[6.1.1,6.2.0)",
- org.eclipse.jgit.dircache;version="[6.1.1,6.2.0)",
- org.eclipse.jgit.internal.diffmergetool;version="6.1.1",
- org.eclipse.jgit.internal.storage.file;version="6.1.1",
- org.eclipse.jgit.junit;version="[6.1.1,6.2.0)",
- org.eclipse.jgit.lib;version="[6.1.1,6.2.0)",
- org.eclipse.jgit.lib.internal;version="[6.1.1,6.2.0)",
- org.eclipse.jgit.merge;version="[6.1.1,6.2.0)",
- org.eclipse.jgit.pgm;version="[6.1.1,6.2.0)",
- org.eclipse.jgit.pgm.internal;version="[6.1.1,6.2.0)",
- org.eclipse.jgit.pgm.opt;version="[6.1.1,6.2.0)",
- org.eclipse.jgit.revwalk;version="[6.1.1,6.2.0)",
- org.eclipse.jgit.storage.file;version="[6.1.1,6.2.0)",
- org.eclipse.jgit.transport;version="[6.1.1,6.2.0)",
- org.eclipse.jgit.treewalk;version="[6.1.1,6.2.0)",
- org.eclipse.jgit.util;version="[6.1.1,6.2.0)",
- org.eclipse.jgit.util.io;version="[6.1.1,6.2.0)",
- org.hamcrest.core;bundle-version="[2.2.0,3.0.0)",
+Import-Package: org.eclipse.jgit.api;version="[6.2.0,6.3.0)",
+ org.eclipse.jgit.api.errors;version="[6.2.0,6.3.0)",
+ org.eclipse.jgit.diff;version="[6.2.0,6.3.0)",
+ org.eclipse.jgit.dircache;version="[6.2.0,6.3.0)",
+ org.eclipse.jgit.internal.diffmergetool;version="6.2.0",
+ org.eclipse.jgit.internal.storage.file;version="6.2.0",
+ org.eclipse.jgit.junit;version="[6.2.0,6.3.0)",
+ org.eclipse.jgit.lib;version="[6.2.0,6.3.0)",
+ org.eclipse.jgit.lib.internal;version="[6.2.0,6.3.0)",
+ org.eclipse.jgit.merge;version="[6.2.0,6.3.0)",
+ org.eclipse.jgit.pgm;version="[6.2.0,6.3.0)",
+ org.eclipse.jgit.pgm.internal;version="[6.2.0,6.3.0)",
+ org.eclipse.jgit.pgm.opt;version="[6.2.0,6.3.0)",
+ org.eclipse.jgit.revwalk;version="[6.2.0,6.3.0)",
+ org.eclipse.jgit.storage.file;version="[6.2.0,6.3.0)",
+ org.eclipse.jgit.transport;version="[6.2.0,6.3.0)",
+ org.eclipse.jgit.treewalk;version="[6.2.0,6.3.0)",
+ org.eclipse.jgit.util;version="[6.2.0,6.3.0)",
+ org.eclipse.jgit.util.io;version="[6.2.0,6.3.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)",
  org.kohsuke.args4j;version="[2.33.0,3.0.0)"
diff --git a/org.eclipse.jgit.pgm.test/pom.xml b/org.eclipse.jgit.pgm.test/pom.xml
index c824788..d26919a 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.1.1-SNAPSHOT</version>
+    <version>6.2.0-SNAPSHOT</version>
   </parent>
 
   <artifactId>org.eclipse.jgit.pgm.test</artifactId>
diff --git a/org.eclipse.jgit.pgm/META-INF/MANIFEST.MF b/org.eclipse.jgit.pgm/META-INF/MANIFEST.MF
index ed980b5..2ef2cd2 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.1.1.qualifier
+Bundle-Version: 6.2.0.qualifier
 Bundle-Vendor: %Bundle-Vendor
 Bundle-Localization: plugin
 Bundle-RequiredExecutionEnvironment: JavaSE-11
@@ -14,49 +14,49 @@
  org.eclipse.jetty.servlet;version="[10.0.0,11.0.0)",
  org.eclipse.jetty.util;version="[10.0.0,11.0.0)",
  org.eclipse.jetty.util.component;version="[10.0.0,11.0.0)",
- org.eclipse.jgit.api;version="[6.1.1,6.2.0)",
- org.eclipse.jgit.api.errors;version="[6.1.1,6.2.0)",
- org.eclipse.jgit.archive;version="[6.1.1,6.2.0)",
- org.eclipse.jgit.awtui;version="[6.1.1,6.2.0)",
- org.eclipse.jgit.blame;version="[6.1.1,6.2.0)",
- org.eclipse.jgit.diff;version="[6.1.1,6.2.0)",
- org.eclipse.jgit.dircache;version="[6.1.1,6.2.0)",
- org.eclipse.jgit.errors;version="[6.1.1,6.2.0)",
- org.eclipse.jgit.gitrepo;version="[6.1.1,6.2.0)",
- org.eclipse.jgit.internal.storage.file;version="[6.1.1,6.2.0)",
- org.eclipse.jgit.internal.diffmergetool;version="[6.1.1,6.2.0)",
- org.eclipse.jgit.internal.storage.io;version="[6.1.1,6.2.0)",
- org.eclipse.jgit.internal.storage.pack;version="[6.1.1,6.2.0)",
- org.eclipse.jgit.internal.storage.reftable;version="[6.1.1,6.2.0)",
- org.eclipse.jgit.lfs;version="[6.1.1,6.2.0)",
- org.eclipse.jgit.lfs.server;version="[6.1.1,6.2.0)",
- org.eclipse.jgit.lfs.server.fs;version="[6.1.1,6.2.0)",
- org.eclipse.jgit.lfs.server.s3;version="[6.1.1,6.2.0)",
- org.eclipse.jgit.lib;version="[6.1.1,6.2.0)",
- org.eclipse.jgit.merge;version="[6.1.1,6.2.0)",
- org.eclipse.jgit.lib.internal;version="[6.1.1,6.2.0)",
- org.eclipse.jgit.nls;version="[6.1.1,6.2.0)",
- org.eclipse.jgit.notes;version="[6.1.1,6.2.0)",
- org.eclipse.jgit.revplot;version="[6.1.1,6.2.0)",
- org.eclipse.jgit.revwalk;version="[6.1.1,6.2.0)",
- org.eclipse.jgit.revwalk.filter;version="[6.1.1,6.2.0)",
- org.eclipse.jgit.storage.file;version="[6.1.1,6.2.0)",
- org.eclipse.jgit.storage.pack;version="[6.1.1,6.2.0)",
- org.eclipse.jgit.transport;version="[6.1.1,6.2.0)",
- org.eclipse.jgit.transport.http.apache;version="[6.1.1,6.2.0)",
- org.eclipse.jgit.transport.resolver;version="[6.1.1,6.2.0)",
- org.eclipse.jgit.transport.ssh.jsch;version="[6.1.1,6.2.0)",
- org.eclipse.jgit.transport.sshd;version="[6.1.1,6.2.0)",
- org.eclipse.jgit.treewalk;version="[6.1.1,6.2.0)",
- org.eclipse.jgit.treewalk.filter;version="[6.1.1,6.2.0)",
- org.eclipse.jgit.util;version="[6.1.1,6.2.0)",
- org.eclipse.jgit.util.io;version="[6.1.1,6.2.0)",
+ org.eclipse.jgit.api;version="[6.2.0,6.3.0)",
+ org.eclipse.jgit.api.errors;version="[6.2.0,6.3.0)",
+ org.eclipse.jgit.archive;version="[6.2.0,6.3.0)",
+ org.eclipse.jgit.awtui;version="[6.2.0,6.3.0)",
+ org.eclipse.jgit.blame;version="[6.2.0,6.3.0)",
+ org.eclipse.jgit.diff;version="[6.2.0,6.3.0)",
+ org.eclipse.jgit.dircache;version="[6.2.0,6.3.0)",
+ org.eclipse.jgit.errors;version="[6.2.0,6.3.0)",
+ org.eclipse.jgit.gitrepo;version="[6.2.0,6.3.0)",
+ org.eclipse.jgit.internal.storage.file;version="[6.2.0,6.3.0)",
+ org.eclipse.jgit.internal.diffmergetool;version="[6.2.0,6.3.0)",
+ org.eclipse.jgit.internal.storage.io;version="[6.2.0,6.3.0)",
+ org.eclipse.jgit.internal.storage.pack;version="[6.2.0,6.3.0)",
+ org.eclipse.jgit.internal.storage.reftable;version="[6.2.0,6.3.0)",
+ org.eclipse.jgit.lfs;version="[6.2.0,6.3.0)",
+ org.eclipse.jgit.lfs.server;version="[6.2.0,6.3.0)",
+ org.eclipse.jgit.lfs.server.fs;version="[6.2.0,6.3.0)",
+ org.eclipse.jgit.lfs.server.s3;version="[6.2.0,6.3.0)",
+ org.eclipse.jgit.lib;version="[6.2.0,6.3.0)",
+ org.eclipse.jgit.merge;version="[6.2.0,6.3.0)",
+ org.eclipse.jgit.lib.internal;version="[6.2.0,6.3.0)",
+ org.eclipse.jgit.nls;version="[6.2.0,6.3.0)",
+ org.eclipse.jgit.notes;version="[6.2.0,6.3.0)",
+ org.eclipse.jgit.revplot;version="[6.2.0,6.3.0)",
+ org.eclipse.jgit.revwalk;version="[6.2.0,6.3.0)",
+ org.eclipse.jgit.revwalk.filter;version="[6.2.0,6.3.0)",
+ org.eclipse.jgit.storage.file;version="[6.2.0,6.3.0)",
+ org.eclipse.jgit.storage.pack;version="[6.2.0,6.3.0)",
+ org.eclipse.jgit.transport;version="[6.2.0,6.3.0)",
+ org.eclipse.jgit.transport.http.apache;version="[6.2.0,6.3.0)",
+ org.eclipse.jgit.transport.resolver;version="[6.2.0,6.3.0)",
+ org.eclipse.jgit.transport.ssh.jsch;version="[6.2.0,6.3.0)",
+ org.eclipse.jgit.transport.sshd;version="[6.2.0,6.3.0)",
+ org.eclipse.jgit.treewalk;version="[6.2.0,6.3.0)",
+ org.eclipse.jgit.treewalk.filter;version="[6.2.0,6.3.0)",
+ org.eclipse.jgit.util;version="[6.2.0,6.3.0)",
+ org.eclipse.jgit.util.io;version="[6.2.0,6.3.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.1.1";
+Export-Package: org.eclipse.jgit.console;version="6.2.0";
  uses:="org.eclipse.jgit.transport,
   org.eclipse.jgit.util",
- org.eclipse.jgit.pgm;version="6.1.1";
+ org.eclipse.jgit.pgm;version="6.2.0";
   uses:="org.eclipse.jgit.transport,
    org.eclipse.jgit.util.io,
    org.eclipse.jgit.awtui,
@@ -68,14 +68,14 @@
    org.eclipse.jgit.treewalk,
    org.eclipse.jgit.api,
    javax.swing",
- org.eclipse.jgit.pgm.debug;version="6.1.1";
+ org.eclipse.jgit.pgm.debug;version="6.2.0";
   uses:="org.eclipse.jgit.util.io,
    org.eclipse.jgit.pgm,
    org.eclipse.jetty.servlet",
- org.eclipse.jgit.pgm.internal;version="6.1.1";
+ org.eclipse.jgit.pgm.internal;version="6.2.0";
   x-friends:="org.eclipse.jgit.pgm.test,
    org.eclipse.jgit.test",
- org.eclipse.jgit.pgm.opt;version="6.1.1";
+ org.eclipse.jgit.pgm.opt;version="6.2.0";
   uses:="org.kohsuke.args4j,
    org.eclipse.jgit.lib,
    org.eclipse.jgit.revwalk,
diff --git a/org.eclipse.jgit.pgm/META-INF/SOURCE-MANIFEST.MF b/org.eclipse.jgit.pgm/META-INF/SOURCE-MANIFEST.MF
index 0a5dd88..fd88286 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.1.1.qualifier
-Eclipse-SourceBundle: org.eclipse.jgit.pgm;version="6.1.1.qualifier";roots="."
+Bundle-Version: 6.2.0.qualifier
+Eclipse-SourceBundle: org.eclipse.jgit.pgm;version="6.2.0.qualifier";roots="."
diff --git a/org.eclipse.jgit.pgm/pom.xml b/org.eclipse.jgit.pgm/pom.xml
index c189dc7..c06304d 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.1.1-SNAPSHOT</version>
+    <version>6.2.0-SNAPSHOT</version>
   </parent>
 
   <artifactId>org.eclipse.jgit.pgm</artifactId>
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 1a5746d..596a8dd 100644
--- a/org.eclipse.jgit.ssh.apache.agent/META-INF/MANIFEST.MF
+++ b/org.eclipse.jgit.ssh.apache.agent/META-INF/MANIFEST.MF
@@ -2,15 +2,15 @@
 Bundle-ManifestVersion: 2
 Bundle-Name: %Bundle-Name
 Bundle-SymbolicName: org.eclipse.jgit.ssh.apache.agent;singleton:=true
-Bundle-Version: 6.1.1.qualifier
+Bundle-Version: 6.2.0.qualifier
 Bundle-Vendor: %Bundle-Vendor
-Fragment-Host: org.eclipse.jgit.ssh.apache;bundle-version="[6.1.1,6.2.0)"
+Fragment-Host: org.eclipse.jgit.ssh.apache;bundle-version="[6.2.0,6.3.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.1.1,6.2.0)",
- org.eclipse.jgit.nls;version="[6.1.1,6.2.0)",
- org.eclipse.jgit.util;version="[6.1.1,6.2.0)"
+Import-Package: org.eclipse.jgit.transport.sshd;version="[6.2.0,6.3.0)",
+ org.eclipse.jgit.nls;version="[6.2.0,6.3.0)",
+ org.eclipse.jgit.util;version="[6.2.0,6.3.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.1.1";x-internal:=true
+Export-Package: org.eclipse.jgit.internal.transport.sshd.agent.connector;version="6.2.0";x-internal:=true
diff --git a/org.eclipse.jgit.ssh.apache.agent/META-INF/SOURCE-MANIFEST.MF b/org.eclipse.jgit.ssh.apache.agent/META-INF/SOURCE-MANIFEST.MF
index d06e6b1..57f00a9 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.1.1.qualifier
-Eclipse-SourceBundle: org.eclipse.jgit.ssh.apache.agent;version="6.1.1.qualifier";roots="."
+Bundle-Version: 6.2.0.qualifier
+Eclipse-SourceBundle: org.eclipse.jgit.ssh.apache.agent;version="6.2.0.qualifier";roots="."
diff --git a/org.eclipse.jgit.ssh.apache.agent/pom.xml b/org.eclipse.jgit.ssh.apache.agent/pom.xml
index 77b9c95..262b9c6 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.1.1-SNAPSHOT</version>
+    <version>6.2.0-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/WinPipeConnector.java b/org.eclipse.jgit.ssh.apache.agent/src/org/eclipse/jgit/internal/transport/sshd/agent/connector/WinPipeConnector.java
index 7bad90f..81c6537 100644
--- a/org.eclipse.jgit.ssh.apache.agent/src/org/eclipse/jgit/internal/transport/sshd/agent/connector/WinPipeConnector.java
+++ b/org.eclipse.jgit.ssh.apache.agent/src/org/eclipse/jgit/internal/transport/sshd/agent/connector/WinPipeConnector.java
@@ -90,7 +90,7 @@
 			file = libs.kernel.CreateFile(pipeName,
 					WinNT.GENERIC_READ | WinNT.GENERIC_WRITE, FILE_SHARE_NONE,
 					null, WinNT.OPEN_EXISTING, FILE_ATTRIBUTE_NONE, null);
-			if (file == null || file == WinBase.INVALID_HANDLE_VALUE) {
+			if (file == null || WinBase.INVALID_HANDLE_VALUE.equals(file)) {
 				int errorCode = libs.kernel.GetLastError();
 				if (errorCode == WinError.ERROR_FILE_NOT_FOUND
 						&& CANONICAL_PIPE_NAME.equalsIgnoreCase(pipeName)) {
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 411d43c..794a585 100644
--- a/org.eclipse.jgit.ssh.apache.test/META-INF/MANIFEST.MF
+++ b/org.eclipse.jgit.ssh.apache.test/META-INF/MANIFEST.MF
@@ -3,7 +3,7 @@
 Bundle-Name: %Bundle-Name
 Automatic-Module-Name: org.eclipse.jgit.ssh.apache.test
 Bundle-SymbolicName: org.eclipse.jgit.ssh.apache.test
-Bundle-Version: 6.1.1.qualifier
+Bundle-Version: 6.2.0.qualifier
 Bundle-Vendor: %Bundle-Vendor
 Bundle-Localization: plugin
 Bundle-RequiredExecutionEnvironment: JavaSE-11
@@ -21,16 +21,16 @@
  org.apache.sshd.core;version="[2.8.0,2.9.0)",
  org.apache.sshd.server;version="[2.8.0,2.9.0)",
  org.apache.sshd.server.forward;version="[2.8.0,2.9.0)",
- org.eclipse.jgit.api;version="[6.1.1,6.2.0)",
- org.eclipse.jgit.api.errors;version="[6.1.1,6.2.0)",
- org.eclipse.jgit.internal.transport.sshd.proxy;version="[6.1.1,6.2.0)",
- org.eclipse.jgit.junit;version="[6.1.1,6.2.0)",
- org.eclipse.jgit.junit.ssh;version="[6.1.1,6.2.0)",
- org.eclipse.jgit.lib;version="[6.1.1,6.2.0)",
- org.eclipse.jgit.transport;version="[6.1.1,6.2.0)",
- org.eclipse.jgit.transport.sshd;version="[6.1.1,6.2.0)",
- org.eclipse.jgit.transport.sshd.agent;version="[6.1.1,6.2.0)",
- org.eclipse.jgit.util;version="[6.1.1,6.2.0)",
+ org.eclipse.jgit.api;version="[6.2.0,6.3.0)",
+ org.eclipse.jgit.api.errors;version="[6.2.0,6.3.0)",
+ org.eclipse.jgit.internal.transport.sshd.proxy;version="[6.2.0,6.3.0)",
+ org.eclipse.jgit.junit;version="[6.2.0,6.3.0)",
+ org.eclipse.jgit.junit.ssh;version="[6.2.0,6.3.0)",
+ org.eclipse.jgit.lib;version="[6.2.0,6.3.0)",
+ org.eclipse.jgit.transport;version="[6.2.0,6.3.0)",
+ org.eclipse.jgit.transport.sshd;version="[6.2.0,6.3.0)",
+ org.eclipse.jgit.transport.sshd.agent;version="[6.2.0,6.3.0)",
+ org.eclipse.jgit.util;version="[6.2.0,6.3.0)",
  org.hamcrest;version="[1.1.0,3.0.0)",
  org.junit;version="[4.13,5.0.0)",
  org.junit.experimental.theories;version="[4.13,5.0.0)",
diff --git a/org.eclipse.jgit.ssh.apache.test/pom.xml b/org.eclipse.jgit.ssh.apache.test/pom.xml
index 3e98e33..6f9dcac 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.1.1-SNAPSHOT</version>
+    <version>6.2.0-SNAPSHOT</version>
   </parent>
 
   <artifactId>org.eclipse.jgit.ssh.apache.test</artifactId>
diff --git a/org.eclipse.jgit.ssh.apache.test/tst/org/eclipse/jgit/transport/sshd/ApacheSshTest.java b/org.eclipse.jgit.ssh.apache.test/tst/org/eclipse/jgit/transport/sshd/ApacheSshTest.java
index 3d7c765..a8fcca7 100644
--- a/org.eclipse.jgit.ssh.apache.test/tst/org/eclipse/jgit/transport/sshd/ApacheSshTest.java
+++ b/org.eclipse.jgit.ssh.apache.test/tst/org/eclipse/jgit/transport/sshd/ApacheSshTest.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2018, 2020 Thomas Wolf <thomas.wolf@paranor.ch> and others
+ * Copyright (C) 2018, 2022 Thomas Wolf <thomas.wolf@paranor.ch> and others
  *
  * This program and the accompanying materials are made available under the
  * terms of the Eclipse Distribution License v. 1.0 which is available at
@@ -789,4 +789,76 @@
 			session.disconnect();
 		}
 	}
+
+	private void verifyAuthLog(String message, String first) {
+		assertTrue(message.contains(System.lineSeparator()));
+		String[] lines = message.split(System.lineSeparator());
+		int pubkeyIndex = -1;
+		int passwordIndex = -1;
+		for (int i = 0; i < lines.length; i++) {
+			String line = lines[i];
+			if (i == 0) {
+				assertTrue(line.contains(first));
+			}
+			if (line.contains("publickey:")) {
+				if (pubkeyIndex < 0) {
+					pubkeyIndex = i;
+					assertTrue(line.contains("/userkey"));
+				}
+			} else if (line.contains("password:")) {
+				if (passwordIndex < 0) {
+					passwordIndex = i;
+					assertTrue(line.contains("attempt 1"));
+				}
+			}
+		}
+		assertTrue(pubkeyIndex > 0 && passwordIndex > 0);
+		assertTrue(pubkeyIndex < passwordIndex);
+	}
+
+	@Test
+	public void testAuthFailureMessageCancel() throws Exception {
+		File userKey = new File(getTemporaryDirectory(), "userkey");
+		copyTestResource("id_ed25519", userKey);
+		File publicKey = new File(getTemporaryDirectory(), "userkey.pub");
+		copyTestResource("id_ed25519.pub", publicKey);
+		// Don't set this as the user's key; we do want to try with a wrong key.
+		server.enablePasswordAuthentication();
+		TestCredentialsProvider provider = new TestCredentialsProvider(
+				"wrongpass");
+		TransportException e = assertThrows(TransportException.class,
+				() -> cloneWith("ssh://git/doesntmatter", defaultCloneDir,
+						provider, //
+						"Host git", //
+						"HostName localhost", //
+						"Port " + testPort, //
+						"User " + TEST_USER, //
+						"IdentityFile " + userKey.getAbsolutePath(), //
+						"PreferredAuthentications publickey,password"));
+		verifyAuthLog(e.getMessage(), "canceled");
+	}
+
+	@Test
+	public void testAuthFailureMessage() throws Exception {
+		File userKey = new File(getTemporaryDirectory(), "userkey");
+		copyTestResource("id_ed25519", userKey);
+		File publicKey = new File(getTemporaryDirectory(), "userkey.pub");
+		copyTestResource("id_ed25519.pub", publicKey);
+		// Don't set this as the user's key; we do want to try with a wrong key.
+		server.enablePasswordAuthentication();
+		// Enough passwords not to cancel authentication
+		TestCredentialsProvider provider = new TestCredentialsProvider(
+				"wrongpass", "wrongpass", "wrongpass");
+		TransportException e = assertThrows(TransportException.class,
+				() -> cloneWith("ssh://git/doesntmatter", defaultCloneDir,
+						provider, //
+						"Host git", //
+						"HostName localhost", //
+						"Port " + testPort, //
+						"User " + TEST_USER, //
+						"IdentityFile " + userKey.getAbsolutePath(), //
+						"PreferredAuthentications publickey,password"));
+		verifyAuthLog(e.getMessage(), "log in");
+	}
+
 }
diff --git a/org.eclipse.jgit.ssh.apache/META-INF/MANIFEST.MF b/org.eclipse.jgit.ssh.apache/META-INF/MANIFEST.MF
index 73feaec..041f0ce 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.1.1.qualifier
+Bundle-Version: 6.2.0.qualifier
 Bundle-RequiredExecutionEnvironment: JavaSE-11
-Export-Package: org.eclipse.jgit.internal.transport.sshd;version="6.1.1";x-internal:=true;
+Export-Package: org.eclipse.jgit.internal.transport.sshd;version="6.2.0";x-internal:=true;
   uses:="org.apache.sshd.client,
    org.apache.sshd.client.auth,
    org.apache.sshd.client.auth.keyboard,
@@ -23,17 +23,17 @@
    org.apache.sshd.common.signature,
    org.apache.sshd.common.util.buffer,
    org.eclipse.jgit.transport",
- org.eclipse.jgit.internal.transport.sshd.agent;version="6.1.1";x-internal:=true,
- org.eclipse.jgit.internal.transport.sshd.auth;version="6.1.1";x-internal:=true,
- org.eclipse.jgit.internal.transport.sshd.proxy;version="6.1.1";x-friends:="org.eclipse.jgit.ssh.apache.test",
- org.eclipse.jgit.transport.sshd;version="6.1.1";
+ org.eclipse.jgit.internal.transport.sshd.agent;version="6.2.0";x-internal:=true,
+ org.eclipse.jgit.internal.transport.sshd.auth;version="6.2.0";x-internal:=true,
+ org.eclipse.jgit.internal.transport.sshd.proxy;version="6.2.0";x-friends:="org.eclipse.jgit.ssh.apache.test",
+ org.eclipse.jgit.transport.sshd;version="6.2.0";
   uses:="org.eclipse.jgit.transport,
    org.apache.sshd.client.config.hosts,
    org.apache.sshd.common.keyprovider,
    org.eclipse.jgit.util,
    org.apache.sshd.client.session,
    org.apache.sshd.client.keyverifier",
- org.eclipse.jgit.transport.sshd.agent;version="6.1.1"
+ org.eclipse.jgit.transport.sshd.agent;version="6.2.0"
 Import-Package: net.i2p.crypto.eddsa;version="[0.3.0,0.4.0)",
  org.apache.sshd.agent;version="[2.8.0,2.9.0)",
  org.apache.sshd.client;version="[2.8.0,2.9.0)",
@@ -86,12 +86,12 @@
  org.apache.sshd.sftp;version="[2.8.0,2.9.0)",
  org.apache.sshd.sftp.client;version="[2.8.0,2.9.0)",
  org.apache.sshd.sftp.common;version="[2.8.0,2.9.0)",
- org.eclipse.jgit.annotations;version="[6.1.1,6.2.0)",
- org.eclipse.jgit.errors;version="[6.1.1,6.2.0)",
- org.eclipse.jgit.fnmatch;version="[6.1.1,6.2.0)",
- org.eclipse.jgit.internal.storage.file;version="[6.1.1,6.2.0)",
- org.eclipse.jgit.internal.transport.ssh;version="[6.1.1,6.2.0)",
- org.eclipse.jgit.nls;version="[6.1.1,6.2.0)",
- org.eclipse.jgit.transport;version="[6.1.1,6.2.0)",
- org.eclipse.jgit.util;version="[6.1.1,6.2.0)",
+ org.eclipse.jgit.annotations;version="[6.2.0,6.3.0)",
+ org.eclipse.jgit.errors;version="[6.2.0,6.3.0)",
+ org.eclipse.jgit.fnmatch;version="[6.2.0,6.3.0)",
+ org.eclipse.jgit.internal.storage.file;version="[6.2.0,6.3.0)",
+ org.eclipse.jgit.internal.transport.ssh;version="[6.2.0,6.3.0)",
+ org.eclipse.jgit.nls;version="[6.2.0,6.3.0)",
+ org.eclipse.jgit.transport;version="[6.2.0,6.3.0)",
+ org.eclipse.jgit.util;version="[6.2.0,6.3.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 9fefa6e..76a9fd5 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.1.1.qualifier
-Eclipse-SourceBundle: org.eclipse.jgit.ssh.apache;version="6.1.1.qualifier";roots="."
+Bundle-Version: 6.2.0.qualifier
+Eclipse-SourceBundle: org.eclipse.jgit.ssh.apache;version="6.2.0.qualifier";roots="."
diff --git a/org.eclipse.jgit.ssh.apache/pom.xml b/org.eclipse.jgit.ssh.apache/pom.xml
index 674c7a4..106bc38 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.1.1-SNAPSHOT</version>
+    <version>6.2.0-SNAPSHOT</version>
   </parent>
 
   <artifactId>org.eclipse.jgit.ssh.apache</artifactId>
@@ -50,16 +50,6 @@
       <groupId>org.apache.sshd</groupId>
       <artifactId>sshd-sftp</artifactId>
       <version>${apache-sshd-version}</version>
-      <exclusions>
-          <exclusion>
-              <groupId>org.apache.sshd</groupId>
-              <artifactId>sshd-core</artifactId>
-          </exclusion>
-          <exclusion>
-              <groupId>org.apache.sshd</groupId>
-              <artifactId>sshd-common</artifactId>
-          </exclusion>
-      </exclusions>
     </dependency>
 
     <dependency>
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 4f735ba..c676221 100644
--- a/org.eclipse.jgit.ssh.apache/resources/org/eclipse/jgit/internal/transport/sshd/SshdText.properties
+++ b/org.eclipse.jgit.ssh.apache/resources/org/eclipse/jgit/internal/transport/sshd/SshdText.properties
@@ -1,5 +1,22 @@
 authenticationCanceled=SSH authentication canceled: no password given
 authenticationOnClosedSession=Authentication canceled: session is already closing or closed
+authGssApiAttempt={0}: trying mechanism OID {1}
+authGssApiExhausted={0}: no more mechanisms to try
+authGssApiFailure={0}: server refused authentication; mechanism {1}
+authGssApiNotTried={0}: not tried
+authGssApiPartialSuccess={0}: partial success with mechanism OID {1}, continue with authentication methods {2}
+authPasswordAttempt={0}: attempt {1}
+authPasswordChangeAttempt={0}: attempt {1} with password change
+authPasswordExhausted={0}: no more attempts
+authPasswordFailure={0}: server refused (wrong password)
+authPasswordNotTried={0}: not tried
+authPasswordPartialSuccess={0}: partial success, continue with authentication methods {1}
+authPubkeyAttempt={0}: trying {1} key {2} with signature type {3}
+authPubkeyAttemptAgent={0}: trying {1} key {2} from SSH agent with signature type {3}
+authPubkeyExhausted={0}: no more keys to try
+authPubkeyFailure={0}: server refused {1} key {2}
+authPubkeyNoKeys={0}: no keys to try
+authPubkeyPartialSuccess={0}: partial success for {1} key {2}, continue with authentication methods {3}
 cannotReadPublicKey=Cannot read public key from file {0}
 closeListenerFailed=Ssh session close listener failed
 configInvalidPath=Invalid path in ssh config key {0}: {1}
diff --git a/org.eclipse.jgit.ssh.apache/src/org/eclipse/jgit/internal/transport/sshd/AuthenticationLogger.java b/org.eclipse.jgit.ssh.apache/src/org/eclipse/jgit/internal/transport/sshd/AuthenticationLogger.java
new file mode 100644
index 0000000..add79b3
--- /dev/null
+++ b/org.eclipse.jgit.ssh.apache/src/org/eclipse/jgit/internal/transport/sshd/AuthenticationLogger.java
@@ -0,0 +1,238 @@
+/*
+ * Copyright (C) 2022 Thomas Wolf <thomas.wolf@paranor.ch> and others
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Distribution License v. 1.0 which is available at
+ * https://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+package org.eclipse.jgit.internal.transport.sshd;
+
+import static org.eclipse.jgit.internal.transport.sshd.CachingKeyPairProvider.getKeyId;
+
+import java.security.KeyPair;
+import java.text.MessageFormat;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
+import org.apache.sshd.client.auth.password.PasswordAuthenticationReporter;
+import org.apache.sshd.client.auth.password.UserAuthPassword;
+import org.apache.sshd.client.auth.pubkey.PublicKeyAuthenticationReporter;
+import org.apache.sshd.client.auth.pubkey.UserAuthPublicKey;
+import org.apache.sshd.client.session.ClientSession;
+import org.apache.sshd.common.config.keys.KeyUtils;
+
+/**
+ * Provides a log of authentication attempts for a {@link ClientSession}.
+ */
+public class AuthenticationLogger {
+
+	private final List<String> messages = new ArrayList<>();
+
+	// We're interested in this log only in the failure case, so we don't need
+	// to log authentication success.
+
+	private final PublicKeyAuthenticationReporter pubkeyLogger = new PublicKeyAuthenticationReporter() {
+
+		private boolean hasAttempts;
+
+		@Override
+		public void signalAuthenticationAttempt(ClientSession session,
+				String service, KeyPair identity, String signature)
+				throws Exception {
+			hasAttempts = true;
+			String message;
+			if (identity.getPrivate() == null) {
+				// SSH agent key
+				message = MessageFormat.format(
+						SshdText.get().authPubkeyAttemptAgent,
+						UserAuthPublicKey.NAME, KeyUtils.getKeyType(identity),
+						getKeyId(session, identity), signature);
+			} else {
+				message = MessageFormat.format(
+						SshdText.get().authPubkeyAttempt,
+						UserAuthPublicKey.NAME, KeyUtils.getKeyType(identity),
+						getKeyId(session, identity), signature);
+			}
+			messages.add(message);
+		}
+
+		@Override
+		public void signalAuthenticationExhausted(ClientSession session,
+				String service) throws Exception {
+			String message;
+			if (hasAttempts) {
+				message = MessageFormat.format(
+						SshdText.get().authPubkeyExhausted,
+						UserAuthPublicKey.NAME);
+			} else {
+				message = MessageFormat.format(SshdText.get().authPubkeyNoKeys,
+						UserAuthPublicKey.NAME);
+			}
+			messages.add(message);
+			hasAttempts = false;
+		}
+
+		@Override
+		public void signalAuthenticationFailure(ClientSession session,
+				String service, KeyPair identity, boolean partial,
+				List<String> serverMethods) throws Exception {
+			String message;
+			if (partial) {
+				message = MessageFormat.format(
+						SshdText.get().authPubkeyPartialSuccess,
+						UserAuthPublicKey.NAME, KeyUtils.getKeyType(identity),
+						getKeyId(session, identity), serverMethods);
+			} else {
+				message = MessageFormat.format(
+						SshdText.get().authPubkeyFailure,
+						UserAuthPublicKey.NAME, KeyUtils.getKeyType(identity),
+						getKeyId(session, identity));
+			}
+			messages.add(message);
+		}
+	};
+
+	private final PasswordAuthenticationReporter passwordLogger = new PasswordAuthenticationReporter() {
+
+		private int attempts;
+
+		@Override
+		public void signalAuthenticationAttempt(ClientSession session,
+				String service, String oldPassword, boolean modified,
+				String newPassword) throws Exception {
+			attempts++;
+			String message;
+			if (modified) {
+				message = MessageFormat.format(
+						SshdText.get().authPasswordChangeAttempt,
+						UserAuthPassword.NAME, Integer.valueOf(attempts));
+			} else {
+				message = MessageFormat.format(
+						SshdText.get().authPasswordAttempt,
+						UserAuthPassword.NAME, Integer.valueOf(attempts));
+			}
+			messages.add(message);
+		}
+
+		@Override
+		public void signalAuthenticationExhausted(ClientSession session,
+				String service) throws Exception {
+			String message;
+			if (attempts > 0) {
+				message = MessageFormat.format(
+						SshdText.get().authPasswordExhausted,
+						UserAuthPassword.NAME);
+			} else {
+				message = MessageFormat.format(
+						SshdText.get().authPasswordNotTried,
+						UserAuthPassword.NAME);
+			}
+			messages.add(message);
+			attempts = 0;
+		}
+
+		@Override
+		public void signalAuthenticationFailure(ClientSession session,
+				String service, String password, boolean partial,
+				List<String> serverMethods) throws Exception {
+			String message;
+			if (partial) {
+				message = MessageFormat.format(
+						SshdText.get().authPasswordPartialSuccess,
+						UserAuthPassword.NAME, serverMethods);
+			} else {
+				message = MessageFormat.format(
+						SshdText.get().authPasswordFailure,
+						UserAuthPassword.NAME);
+			}
+			messages.add(message);
+		}
+	};
+
+	private final GssApiWithMicAuthenticationReporter gssLogger = new GssApiWithMicAuthenticationReporter() {
+
+		private boolean hasAttempts;
+
+		@Override
+		public void signalAuthenticationAttempt(ClientSession session,
+				String service, String mechanism) {
+			hasAttempts = true;
+			String message = MessageFormat.format(
+					SshdText.get().authGssApiAttempt,
+					GssApiWithMicAuthFactory.NAME, mechanism);
+			messages.add(message);
+		}
+
+		@Override
+		public void signalAuthenticationExhausted(ClientSession session,
+				String service) {
+			String message;
+			if (hasAttempts) {
+				message = MessageFormat.format(
+						SshdText.get().authGssApiExhausted,
+						GssApiWithMicAuthFactory.NAME);
+			} else {
+				message = MessageFormat.format(
+						SshdText.get().authGssApiNotTried,
+						GssApiWithMicAuthFactory.NAME);
+			}
+			messages.add(message);
+			hasAttempts = false;
+		}
+
+		@Override
+		public void signalAuthenticationFailure(ClientSession session,
+				String service, String mechanism, boolean partial,
+				List<String> serverMethods) {
+			String message;
+			if (partial) {
+				message = MessageFormat.format(
+						SshdText.get().authGssApiPartialSuccess,
+						GssApiWithMicAuthFactory.NAME, mechanism,
+						serverMethods);
+			} else {
+				message = MessageFormat.format(
+						SshdText.get().authGssApiFailure,
+						GssApiWithMicAuthFactory.NAME, mechanism);
+			}
+			messages.add(message);
+		}
+	};
+
+	/**
+	 * Creates a new {@link AuthenticationLogger} and configures the
+	 * {@link ClientSession} to report authentication attempts through this
+	 * instance.
+	 *
+	 * @param session
+	 *            to configure
+	 */
+	public AuthenticationLogger(ClientSession session) {
+		session.setPublicKeyAuthenticationReporter(pubkeyLogger);
+		session.setPasswordAuthenticationReporter(passwordLogger);
+		session.setAttribute(
+				GssApiWithMicAuthenticationReporter.GSS_AUTHENTICATION_REPORTER,
+				gssLogger);
+		// TODO: keyboard-interactive? sshd 2.8.0 has no callback
+		// interface for it.
+	}
+
+	/**
+	 * Retrieves the log messages for the authentication attempts.
+	 *
+	 * @return the messages as an unmodifiable list
+	 */
+	public List<String> getLog() {
+		return Collections.unmodifiableList(messages);
+	}
+
+	/**
+	 * Drops all previously recorded log messages.
+	 */
+	public void clear() {
+		messages.clear();
+	}
+}
diff --git a/org.eclipse.jgit.ssh.apache/src/org/eclipse/jgit/internal/transport/sshd/CachingKeyPairProvider.java b/org.eclipse.jgit.ssh.apache/src/org/eclipse/jgit/internal/transport/sshd/CachingKeyPairProvider.java
index 79b3637..cbd6a64 100644
--- a/org.eclipse.jgit.ssh.apache/src/org/eclipse/jgit/internal/transport/sshd/CachingKeyPairProvider.java
+++ b/org.eclipse.jgit.ssh.apache/src/org/eclipse/jgit/internal/transport/sshd/CachingKeyPairProvider.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2018, Thomas Wolf <thomas.wolf@paranor.ch> and others
+ * Copyright (C) 2018, 2022 Thomas Wolf <thomas.wolf@paranor.ch> and others
  *
  * This program and the accompanying materials are made available under the
  * terms of the Eclipse Distribution License v. 1.0 which is available at
@@ -11,6 +11,7 @@
 
 import static java.text.MessageFormat.format;
 
+import java.io.File;
 import java.io.IOException;
 import java.io.InputStream;
 import java.nio.file.Files;
@@ -19,18 +20,24 @@
 import java.security.InvalidKeyException;
 import java.security.KeyPair;
 import java.security.PrivateKey;
+import java.security.PublicKey;
 import java.util.ArrayList;
 import java.util.Collection;
 import java.util.Collections;
+import java.util.HashMap;
 import java.util.Iterator;
 import java.util.List;
+import java.util.Map;
 import java.util.NoSuchElementException;
 import java.util.concurrent.CancellationException;
 
 import javax.security.auth.DestroyFailedException;
 
+import org.apache.sshd.common.AttributeRepository.AttributeKey;
+import org.apache.sshd.client.session.ClientSession;
 import org.apache.sshd.common.NamedResource;
 import org.apache.sshd.common.config.keys.FilePasswordProvider;
+import org.apache.sshd.common.config.keys.KeyUtils;
 import org.apache.sshd.common.keyprovider.FileKeyPairProvider;
 import org.apache.sshd.common.session.SessionContext;
 import org.apache.sshd.common.util.io.resource.IoResource;
@@ -43,6 +50,14 @@
 public class CachingKeyPairProvider extends FileKeyPairProvider
 		implements Iterable<KeyPair> {
 
+	/**
+	 * An attribute set on the {@link SessionContext} recording loaded keys by
+	 * fingerprint. This enables us to provide nicer output by showing key
+	 * paths, if possible. Users can identify key identities used easier by
+	 * filename than by fingerprint.
+	 */
+	public static final AttributeKey<Map<String, Path>> KEY_PATHS_BY_FINGERPRINT = new AttributeKey<>();
+
 	private final KeyCache cache;
 
 	/**
@@ -78,6 +93,33 @@
 		return () -> iterator(session);
 	}
 
+	static String getKeyId(ClientSession session, KeyPair identity) {
+		String fingerprint = KeyUtils.getFingerPrint(identity.getPublic());
+		Map<String, Path> registered = session
+				.getAttribute(KEY_PATHS_BY_FINGERPRINT);
+		if (registered != null) {
+			Path path = registered.get(fingerprint);
+			if (path != null) {
+				Path home = session
+						.resolveAttribute(JGitSshClient.HOME_DIRECTORY);
+				if (home != null && path.startsWith(home)) {
+					try {
+						path = home.relativize(path);
+						String pathString = path.toString();
+						if (!pathString.isEmpty()) {
+							return "~" + File.separator + pathString; //$NON-NLS-1$
+						}
+					} catch (IllegalArgumentException e) {
+						// Cannot be relativized. Ignore, and work with the
+						// original path
+					}
+				}
+				return path.toString();
+			}
+		}
+		return fingerprint;
+	}
+
 	private KeyPair loadKey(SessionContext session, Path path)
 			throws IOException, GeneralSecurityException {
 		if (!Files.exists(path)) {
@@ -123,13 +165,23 @@
 						SshdText.get().identityFileUnsupportedFormat, path));
 			}
 			KeyPair result = keys.next();
+			PublicKey pk = result.getPublic();
+			if (pk != null) {
+				Map<String, Path> registered = session
+						.getAttribute(KEY_PATHS_BY_FINGERPRINT);
+				if (registered == null) {
+					registered = new HashMap<>();
+					session.setAttribute(KEY_PATHS_BY_FINGERPRINT, registered);
+				}
+				registered.put(KeyUtils.getFingerPrint(pk), path);
+			}
 			if (keys.hasNext()) {
 				log.warn(format(SshdText.get().identityFileMultipleKeys, path));
 				keys.forEachRemaining(k -> {
-					PrivateKey pk = k.getPrivate();
-					if (pk != null) {
+					PrivateKey priv = k.getPrivate();
+					if (priv != null) {
 						try {
-							pk.destroy();
+							priv.destroy();
 						} catch (DestroyFailedException e) {
 							// Ignore
 						}
diff --git a/org.eclipse.jgit.ssh.apache/src/org/eclipse/jgit/internal/transport/sshd/GssApiWithMicAuthentication.java b/org.eclipse.jgit.ssh.apache/src/org/eclipse/jgit/internal/transport/sshd/GssApiWithMicAuthentication.java
index c3cac0c..df01db3 100644
--- a/org.eclipse.jgit.ssh.apache/src/org/eclipse/jgit/internal/transport/sshd/GssApiWithMicAuthentication.java
+++ b/org.eclipse.jgit.ssh.apache/src/org/eclipse/jgit/internal/transport/sshd/GssApiWithMicAuthentication.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2018, Thomas Wolf <thomas.wolf@paranor.ch> and others
+ * Copyright (C) 2018, 2022 Thomas Wolf <thomas.wolf@paranor.ch> and others
  *
  * This program and the accompanying materials are made available under the
  * terms of the Eclipse Distribution License v. 1.0 which is available at
@@ -18,6 +18,7 @@
 import java.net.UnknownHostException;
 import java.util.Collection;
 import java.util.Iterator;
+import java.util.List;
 
 import org.apache.sshd.client.auth.AbstractUserAuth;
 import org.apache.sshd.client.session.ClientSession;
@@ -71,7 +72,10 @@
 		if (context != null) {
 			close(false);
 		}
+		GssApiWithMicAuthenticationReporter reporter = session.getAttribute(
+				GssApiWithMicAuthenticationReporter.GSS_AUTHENTICATION_REPORTER);
 		if (!nextMechanism.hasNext()) {
+			reporter.signalAuthenticationExhausted(session, service);
 			return false;
 		}
 		state = ProtocolState.STARTED;
@@ -79,6 +83,7 @@
 		// RFC 4462 states that SPNEGO must not be used with ssh
 		while (GssApiMechanisms.SPNEGO.equals(currentMechanism)) {
 			if (!nextMechanism.hasNext()) {
+				reporter.signalAuthenticationExhausted(session, service);
 				return false;
 			}
 			currentMechanism = nextMechanism.next();
@@ -102,6 +107,10 @@
 			state = ProtocolState.FAILED;
 			return false;
 		}
+		if (reporter != null) {
+			reporter.signalAuthenticationAttempt(session, service,
+					currentMechanism.toString());
+		}
 		Buffer buffer = session
 				.createBuffer(SshConstants.SSH_MSG_USERAUTH_REQUEST);
 		buffer.putString(session.getUsername());
@@ -246,4 +255,26 @@
 		return false;
 	}
 
+	@Override
+	public void signalAuthMethodSuccess(ClientSession session, String service,
+			Buffer buffer) throws Exception {
+		GssApiWithMicAuthenticationReporter reporter = session.getAttribute(
+				GssApiWithMicAuthenticationReporter.GSS_AUTHENTICATION_REPORTER);
+		if (reporter != null) {
+			reporter.signalAuthenticationSuccess(session, service,
+					currentMechanism.toString());
+		}
+	}
+
+	@Override
+	public void signalAuthMethodFailure(ClientSession session, String service,
+			boolean partial, List<String> serverMethods, Buffer buffer)
+			throws Exception {
+		GssApiWithMicAuthenticationReporter reporter = session.getAttribute(
+				GssApiWithMicAuthenticationReporter.GSS_AUTHENTICATION_REPORTER);
+		if (reporter != null) {
+			reporter.signalAuthenticationFailure(session, service,
+					currentMechanism.toString(), partial, serverMethods);
+		}
+	}
 }
diff --git a/org.eclipse.jgit.ssh.apache/src/org/eclipse/jgit/internal/transport/sshd/GssApiWithMicAuthenticationReporter.java b/org.eclipse.jgit.ssh.apache/src/org/eclipse/jgit/internal/transport/sshd/GssApiWithMicAuthenticationReporter.java
new file mode 100644
index 0000000..201a131
--- /dev/null
+++ b/org.eclipse.jgit.ssh.apache/src/org/eclipse/jgit/internal/transport/sshd/GssApiWithMicAuthenticationReporter.java
@@ -0,0 +1,93 @@
+/*
+ * Copyright (C) 2022 Thomas Wolf <thomas.wolf@paranor.ch> and others
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Distribution License v. 1.0 which is available at
+ * https://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+package org.eclipse.jgit.internal.transport.sshd;
+
+import java.util.List;
+
+import org.apache.sshd.client.session.ClientSession;
+import org.apache.sshd.common.AttributeRepository.AttributeKey;
+
+/**
+ * Callback interface for recording authentication state in
+ * {@link GssApiWithMicAuthentication}.
+ */
+public interface GssApiWithMicAuthenticationReporter {
+
+	/**
+	 * An {@link AttributeKey} for a {@link ClientSession} holding the
+	 * {@link GssApiWithMicAuthenticationReporter}.
+	 */
+	static final AttributeKey<GssApiWithMicAuthenticationReporter> GSS_AUTHENTICATION_REPORTER = new AttributeKey<>();
+
+	/**
+	 * Called when a new authentication attempt is made.
+	 *
+	 * @param session
+	 *            the {@link ClientSession}
+	 * @param service
+	 *            the name of the requesting SSH service name
+	 * @param mechanism
+	 *            the OID of the mechanism used
+	 */
+	default void signalAuthenticationAttempt(ClientSession session,
+			String service, String mechanism) {
+		// nothing
+	}
+
+	/**
+	 * Called when there are no more mechanisms to try.
+	 *
+	 * @param session
+	 *            the {@link ClientSession}
+	 * @param service
+	 *            the name of the requesting SSH service name
+	 */
+	default void signalAuthenticationExhausted(ClientSession session,
+			String service) {
+		// nothing
+	}
+
+	/**
+	 * Called when authentication was succeessful.
+	 *
+	 * @param session
+	 *            the {@link ClientSession}
+	 * @param service
+	 *            the name of the requesting SSH service name
+	 * @param mechanism
+	 *            the OID of the mechanism used
+	 */
+	default void signalAuthenticationSuccess(ClientSession session,
+			String service, String mechanism) {
+		// nothing
+	}
+
+	/**
+	 * Called when the authentication was not successful.
+	 *
+	 * @param session
+	 *            the {@link ClientSession}
+	 * @param service
+	 *            the name of the requesting SSH service name
+	 * @param mechanism
+	 *            the OID of the mechanism used
+	 * @param partial
+	 *            {@code true} if authentication was partially successful,
+	 *            meaning one continues with additional authentication methods
+	 *            given by {@code serverMethods}
+	 * @param serverMethods
+	 *            the {@link List} of authentication methods that can continue
+	 */
+	default void signalAuthenticationFailure(ClientSession session,
+			String service, String mechanism, boolean partial,
+			List<String> serverMethods) {
+		// nothing
+	}
+}
diff --git a/org.eclipse.jgit.ssh.apache/src/org/eclipse/jgit/internal/transport/sshd/JGitPasswordAuthentication.java b/org.eclipse.jgit.ssh.apache/src/org/eclipse/jgit/internal/transport/sshd/JGitPasswordAuthentication.java
index ff8caaa..33c3c60 100644
--- a/org.eclipse.jgit.ssh.apache/src/org/eclipse/jgit/internal/transport/sshd/JGitPasswordAuthentication.java
+++ b/org.eclipse.jgit.ssh.apache/src/org/eclipse/jgit/internal/transport/sshd/JGitPasswordAuthentication.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2018, Thomas Wolf <thomas.wolf@paranor.ch> and others
+ * Copyright (C) 2018, 2022 Thomas Wolf <thomas.wolf@paranor.ch> and others
  *
  * This program and the accompanying materials are made available under the
  * terms of the Eclipse Distribution License v. 1.0 which is available at
@@ -11,13 +11,11 @@
 
 import static org.apache.sshd.core.CoreModuleProperties.PASSWORD_PROMPTS;
 
-import org.apache.sshd.client.auth.keyboard.UserInteraction;
 import org.apache.sshd.client.auth.password.UserAuthPassword;
 import org.apache.sshd.client.session.ClientSession;
 
 /**
- * A password authentication handler that uses the {@link JGitUserInteraction}
- * to ask the user for the password. It also respects the
+ * A password authentication handler that respects the
  * {@code NumberOfPasswordPrompts} ssh config.
  */
 public class JGitPasswordAuthentication extends UserAuthPassword {
@@ -35,30 +33,11 @@
 	}
 
 	@Override
-	protected boolean sendAuthDataRequest(ClientSession session, String service)
-			throws Exception {
+	protected String resolveAttemptedPassword(ClientSession session,
+			String service) throws Exception {
 		if (++attempts > maxAttempts) {
-			return false;
+			return null;
 		}
-		UserInteraction interaction = session.getUserInteraction();
-		if (!interaction.isInteractionAllowed(session)) {
-			return false;
-		}
-		String password = getPassword(session, interaction);
-		if (password == null) {
-			throw new AuthenticationCanceledException();
-		}
-		// sendPassword takes a buffer as first argument, but actually doesn't
-		// use it and creates its own buffer...
-		sendPassword(null, session, password, password);
-		return true;
-	}
-
-	private String getPassword(ClientSession session,
-			UserInteraction interaction) {
-		String[] results = interaction.interactive(session, null, null, "", //$NON-NLS-1$
-				new String[] { SshdText.get().passwordPrompt },
-				new boolean[] { false });
-		return (results == null || results.length == 0) ? null : results[0];
+		return super.resolveAttemptedPassword(session, service);
 	}
 }
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 71e8e61..72f0bdb 100644
--- a/org.eclipse.jgit.ssh.apache/src/org/eclipse/jgit/internal/transport/sshd/JGitSshClient.java
+++ b/org.eclipse.jgit.ssh.apache/src/org/eclipse/jgit/internal/transport/sshd/JGitSshClient.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2018, 2021 Thomas Wolf <thomas.wolf@paranor.ch> and others
+ * Copyright (C) 2018, 2022 Thomas Wolf <thomas.wolf@paranor.ch> and others
  *
  * This program and the accompanying materials are made available under the
  * terms of the Eclipse Distribution License v. 1.0 which is available at
@@ -87,6 +87,11 @@
 	public static final AttributeKey<String> PREFERRED_AUTHENTICATIONS = new AttributeKey<>();
 
 	/**
+	 * An attribute key for the home directory.
+	 */
+	public static final AttributeKey<Path> HOME_DIRECTORY = new AttributeKey<>();
+
+	/**
 	 * An attribute key for storing an alternate local address to connect to if
 	 * a local forward from a ProxyJump ssh config is present. If set,
 	 * {@link #connect(HostConfigEntry, AttributeRepository, SocketAddress)}
diff --git a/org.eclipse.jgit.ssh.apache/src/org/eclipse/jgit/internal/transport/sshd/JGitUserInteraction.java b/org.eclipse.jgit.ssh.apache/src/org/eclipse/jgit/internal/transport/sshd/JGitUserInteraction.java
index c51a75b..2a725ea 100644
--- a/org.eclipse.jgit.ssh.apache/src/org/eclipse/jgit/internal/transport/sshd/JGitUserInteraction.java
+++ b/org.eclipse.jgit.ssh.apache/src/org/eclipse/jgit/internal/transport/sshd/JGitUserInteraction.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2018, Thomas Wolf <thomas.wolf@paranor.ch> and others
+ * Copyright (C) 2018, 2022 Thomas Wolf <thomas.wolf@paranor.ch> and others
  *
  * This program and the accompanying materials are made available under the
  * terms of the Eclipse Distribution License v. 1.0 which is available at
@@ -120,15 +120,16 @@
 				return null;
 			}).filter(s -> s != null).toArray(String[]::new);
 		}
-		// TODO What to throw to abort the connection/authentication process?
-		// In UserAuthKeyboardInteractive.getUserResponses() it's clear that
-		// returning null is valid and signifies "an error"; we'll try the
-		// next authentication method. But if the user explicitly canceled,
-		// then we don't want to try the next methods...
-		//
-		// Probably not a serious issue with the typical order of public-key,
-		// keyboard-interactive, password.
-		return null;
+		throw new AuthenticationCanceledException();
+	}
+
+	@Override
+	public String resolveAuthPasswordAttempt(ClientSession session)
+			throws Exception {
+		String[] results = interactive(session, null, null, "", //$NON-NLS-1$
+				new String[] { SshdText.get().passwordPrompt },
+				new boolean[] { false });
+		return (results == null || results.length == 0) ? null : results[0];
 	}
 
 	@Override
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 19ad85c..39332d9 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
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2018, 2021 Thomas Wolf <thomas.wolf@paranor.ch> and others
+ * Copyright (C) 2018, 2022 Thomas Wolf <thomas.wolf@paranor.ch> and others
  *
  * This program and the accompanying materials are made available under the
  * terms of the Eclipse Distribution License v. 1.0 which is available at
@@ -29,6 +29,23 @@
 	// @formatter:off
 	/***/ public String authenticationCanceled;
 	/***/ public String authenticationOnClosedSession;
+	/***/ public String authGssApiAttempt;
+	/***/ public String authGssApiExhausted;
+	/***/ public String authGssApiFailure;
+	/***/ public String authGssApiNotTried;
+	/***/ public String authGssApiPartialSuccess;
+	/***/ public String authPasswordAttempt;
+	/***/ public String authPasswordChangeAttempt;
+	/***/ public String authPasswordExhausted;
+	/***/ public String authPasswordFailure;
+	/***/ public String authPasswordNotTried;
+	/***/ public String authPasswordPartialSuccess;
+	/***/ public String authPubkeyAttempt;
+	/***/ public String authPubkeyAttemptAgent;
+	/***/ public String authPubkeyExhausted;
+	/***/ public String authPubkeyFailure;
+	/***/ public String authPubkeyNoKeys;
+	/***/ public String authPubkeyPartialSuccess;
 	/***/ public String closeListenerFailed;
 	/***/ public String cannotReadPublicKey;
 	/***/ public String configInvalidPath;
diff --git a/org.eclipse.jgit.ssh.apache/src/org/eclipse/jgit/transport/sshd/SshdSession.java b/org.eclipse.jgit.ssh.apache/src/org/eclipse/jgit/transport/sshd/SshdSession.java
index b742f5e..b94ccc6 100644
--- a/org.eclipse.jgit.ssh.apache/src/org/eclipse/jgit/transport/sshd/SshdSession.java
+++ b/org.eclipse.jgit.ssh.apache/src/org/eclipse/jgit/transport/sshd/SshdSession.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2018, 2021 Thomas Wolf <thomas.wolf@paranor.ch> and others
+ * Copyright (C) 2018, 2022 Thomas Wolf <thomas.wolf@paranor.ch> and others
  *
  * This program and the accompanying materials are made available under the
  * terms of the Eclipse Distribution License v. 1.0 which is available at
@@ -52,6 +52,8 @@
 import org.eclipse.jgit.annotations.NonNull;
 import org.eclipse.jgit.errors.TransportException;
 import org.eclipse.jgit.internal.transport.ssh.OpenSshConfigFile;
+import org.eclipse.jgit.internal.transport.sshd.AuthenticationCanceledException;
+import org.eclipse.jgit.internal.transport.sshd.AuthenticationLogger;
 import org.eclipse.jgit.internal.transport.sshd.JGitSshClient;
 import org.eclipse.jgit.internal.transport.sshd.SshdText;
 import org.eclipse.jgit.transport.FtpChannel;
@@ -119,6 +121,7 @@
 		ClientSession resultSession = null;
 		ClientSession proxySession = null;
 		PortForwardingTracker portForward = null;
+		AuthenticationLogger authLog = null;
 		try {
 			if (!hops.isEmpty()) {
 				URIish hop = hops.remove(0);
@@ -165,6 +168,7 @@
 				resultSession.addCloseFutureListener(listener);
 			}
 			// Authentication timeout is by default 2 minutes.
+			authLog = new AuthenticationLogger(resultSession);
 			resultSession.auth().verify(resultSession.getAuthTimeout());
 			return resultSession;
 		} catch (IOException e) {
@@ -173,17 +177,34 @@
 			close(resultSession, e);
 			if (e instanceof SshException && ((SshException) e)
 					.getDisconnectCode() == SSH2_DISCONNECT_NO_MORE_AUTH_METHODS_AVAILABLE) {
-				// Ensure the user gets to know on which URI the authentication
-				// was denied.
+				String message = format(SshdText.get().loginDenied, host,
+						Integer.toString(port));
 				throw new TransportException(target,
-						format(SshdText.get().loginDenied, host,
-								Integer.toString(port)),
-						e);
+						withAuthLog(message, authLog), e);
+			} else if (e instanceof SshException && e
+					.getCause() instanceof AuthenticationCanceledException) {
+				String message = e.getCause().getMessage();
+				throw new TransportException(target,
+						withAuthLog(message, authLog), e.getCause());
 			}
 			throw e;
+		} finally {
+			if (authLog != null) {
+				authLog.clear();
+			}
 		}
 	}
 
+	private String withAuthLog(String message, AuthenticationLogger authLog) {
+		if (authLog != null) {
+			String log = String.join(System.lineSeparator(), authLog.getLog());
+			if (!log.isEmpty()) {
+				return message + System.lineSeparator() + log;
+			}
+		}
+		return message;
+	}
+
 	private ClientSession connect(HostConfigEntry config,
 			AttributeRepository context, Duration timeout)
 			throws IOException {
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 58cf8e1..c792c18 100644
--- a/org.eclipse.jgit.ssh.apache/src/org/eclipse/jgit/transport/sshd/SshdSessionFactory.java
+++ b/org.eclipse.jgit.ssh.apache/src/org/eclipse/jgit/transport/sshd/SshdSessionFactory.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2018, 2021 Thomas Wolf <thomas.wolf@paranor.ch> and others
+ * Copyright (C) 2018, 2022 Thomas Wolf <thomas.wolf@paranor.ch> and others
  *
  * This program and the accompanying materials are made available under the
  * terms of the Eclipse Distribution License v. 1.0 which is available at
@@ -13,6 +13,7 @@
 import java.io.File;
 import java.io.IOException;
 import java.nio.file.Files;
+import java.nio.file.InvalidPathException;
 import java.nio.file.Path;
 import java.security.KeyPair;
 import java.time.Duration;
@@ -34,7 +35,6 @@
 import org.apache.sshd.client.auth.keyboard.UserAuthKeyboardInteractiveFactory;
 import org.apache.sshd.client.config.hosts.HostConfigEntryResolver;
 import org.apache.sshd.common.NamedFactory;
-import org.apache.sshd.common.SshException;
 import org.apache.sshd.common.compression.BuiltinCompressions;
 import org.apache.sshd.common.config.keys.FilePasswordProvider;
 import org.apache.sshd.common.config.keys.loader.openssh.kdf.BCryptKdfOptions;
@@ -44,7 +44,6 @@
 import org.eclipse.jgit.annotations.NonNull;
 import org.eclipse.jgit.errors.TransportException;
 import org.eclipse.jgit.internal.transport.ssh.OpenSshConfigFile;
-import org.eclipse.jgit.internal.transport.sshd.AuthenticationCanceledException;
 import org.eclipse.jgit.internal.transport.sshd.CachingKeyPairProvider;
 import org.eclipse.jgit.internal.transport.sshd.GssApiWithMicAuthFactory;
 import org.eclipse.jgit.internal.transport.sshd.JGitPasswordAuthFactory;
@@ -243,6 +242,12 @@
 							JGitSshClient.PREFERRED_AUTHENTICATIONS,
 							defaultAuths);
 				}
+				try {
+					jgitClient.setAttribute(JGitSshClient.HOME_DIRECTORY,
+							home.getAbsoluteFile().toPath());
+				} catch (SecurityException | InvalidPathException e) {
+					// Ignore
+				}
 				// Other things?
 				return client;
 			});
@@ -255,13 +260,7 @@
 			if (e instanceof TransportException) {
 				throw (TransportException) e;
 			}
-			Throwable cause = e;
-			if (e instanceof SshException && e
-					.getCause() instanceof AuthenticationCanceledException) {
-				// Results in a nicer error message
-				cause = e.getCause();
-			}
-			throw new TransportException(uri, cause.getMessage(), cause);
+			throw new TransportException(uri, e.getMessage(), e);
 		}
 	}
 
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 4a08940..f48b926 100644
--- a/org.eclipse.jgit.ssh.jsch.test/META-INF/MANIFEST.MF
+++ b/org.eclipse.jgit.ssh.jsch.test/META-INF/MANIFEST.MF
@@ -3,18 +3,18 @@
 Bundle-Name: %Bundle-Name
 Automatic-Module-Name: org.eclipse.jgit.ssh.jsch.test
 Bundle-SymbolicName: org.eclipse.jgit.ssh.jsch.test
-Bundle-Version: 6.1.1.qualifier
+Bundle-Version: 6.2.0.qualifier
 Bundle-Vendor: %Bundle-Vendor
 Bundle-Localization: plugin
 Bundle-RequiredExecutionEnvironment: JavaSE-11
 Import-Package: com.jcraft.jsch;version="[0.1.54,0.2.0)",
- org.eclipse.jgit.errors;version="[6.1.1,6.2.0)",
- org.eclipse.jgit.junit;version="[6.1.1,6.2.0)",
- org.eclipse.jgit.junit.ssh;version="[6.1.1,6.2.0)",
- org.eclipse.jgit.lib;version="[6.1.1,6.2.0)",
- org.eclipse.jgit.transport;version="[6.1.1,6.2.0)",
- org.eclipse.jgit.transport.ssh.jsch;version="[6.1.1,6.2.0)",
- org.eclipse.jgit.util;version="[6.1.1,6.2.0)",
+ org.eclipse.jgit.errors;version="[6.2.0,6.3.0)",
+ org.eclipse.jgit.junit;version="[6.2.0,6.3.0)",
+ org.eclipse.jgit.junit.ssh;version="[6.2.0,6.3.0)",
+ org.eclipse.jgit.lib;version="[6.2.0,6.3.0)",
+ org.eclipse.jgit.transport;version="[6.2.0,6.3.0)",
+ org.eclipse.jgit.transport.ssh.jsch;version="[6.2.0,6.3.0)",
+ org.eclipse.jgit.util;version="[6.2.0,6.3.0)",
  org.hamcrest;version="[1.1.0,3.0.0)",
  org.junit;version="[4.13,5.0.0)",
  org.junit.experimental.theories;version="[4.13,5.0.0)",
diff --git a/org.eclipse.jgit.ssh.jsch.test/pom.xml b/org.eclipse.jgit.ssh.jsch.test/pom.xml
index ca1e742..9a3a847 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.1.1-SNAPSHOT</version>
+    <version>6.2.0-SNAPSHOT</version>
   </parent>
 
   <artifactId>org.eclipse.jgit.ssh.jsch.test</artifactId>
diff --git a/org.eclipse.jgit.ssh.jsch/META-INF/MANIFEST.MF b/org.eclipse.jgit.ssh.jsch/META-INF/MANIFEST.MF
index 332d981..4238239 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.1.1,6.2.0)"
+Fragment-Host: org.eclipse.jgit;bundle-version="[6.2.0,6.3.0)"
 Bundle-Vendor: %Bundle-Vendor
 Bundle-Localization: plugin
 Bundle-ActivationPolicy: lazy
-Bundle-Version: 6.1.1.qualifier
+Bundle-Version: 6.2.0.qualifier
 Bundle-RequiredExecutionEnvironment: JavaSE-11
-Export-Package: org.eclipse.jgit.transport.ssh.jsch;version="6.1.1"
+Export-Package: org.eclipse.jgit.transport.ssh.jsch;version="6.2.0"
 Import-Package: com.jcraft.jsch;version="[0.1.37,0.2.0)",
- org.eclipse.jgit.errors;version="[6.1.1,6.2.0)",
- org.eclipse.jgit.internal;version="[6.1.1,6.2.0)",
- org.eclipse.jgit.internal.transport.ssh;version="[6.1.1,6.2.0)",
- org.eclipse.jgit.nls;version="[6.1.1,6.2.0)",
- org.eclipse.jgit.transport;version="[6.1.1,6.2.0)",
- org.eclipse.jgit.util;version="[6.1.1,6.2.0)",
- org.eclipse.jgit.util.io;version="[6.1.1,6.2.0)",
+ org.eclipse.jgit.errors;version="[6.2.0,6.3.0)",
+ org.eclipse.jgit.internal;version="[6.2.0,6.3.0)",
+ org.eclipse.jgit.internal.transport.ssh;version="[6.2.0,6.3.0)",
+ org.eclipse.jgit.nls;version="[6.2.0,6.3.0)",
+ org.eclipse.jgit.transport;version="[6.2.0,6.3.0)",
+ org.eclipse.jgit.util;version="[6.2.0,6.3.0)",
+ org.eclipse.jgit.util.io;version="[6.2.0,6.3.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 b56bb7c..edb6b19 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.1.1.qualifier
-Eclipse-SourceBundle: org.eclipse.jgit.ssh.jsch;version="6.1.1.qualifier";roots="."
+Bundle-Version: 6.2.0.qualifier
+Eclipse-SourceBundle: org.eclipse.jgit.ssh.jsch;version="6.2.0.qualifier";roots="."
diff --git a/org.eclipse.jgit.ssh.jsch/pom.xml b/org.eclipse.jgit.ssh.jsch/pom.xml
index 3b6d66c..1ff971f 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.1.1-SNAPSHOT</version>
+    <version>6.2.0-SNAPSHOT</version>
   </parent>
 
   <artifactId>org.eclipse.jgit.ssh.jsch</artifactId>
diff --git a/org.eclipse.jgit.test/META-INF/MANIFEST.MF b/org.eclipse.jgit.test/META-INF/MANIFEST.MF
index 581395d..85d93a9 100644
--- a/org.eclipse.jgit.test/META-INF/MANIFEST.MF
+++ b/org.eclipse.jgit.test/META-INF/MANIFEST.MF
@@ -3,7 +3,7 @@
 Bundle-Name: %Bundle-Name
 Automatic-Module-Name: org.eclipse.jgit.test
 Bundle-SymbolicName: org.eclipse.jgit.test
-Bundle-Version: 6.1.1.qualifier
+Bundle-Version: 6.2.0.qualifier
 Bundle-Localization: plugin
 Bundle-Vendor: %Bundle-Vendor
 Bundle-RequiredExecutionEnvironment: JavaSE-11
@@ -16,61 +16,61 @@
  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.1.1,6.2.0)",
- org.eclipse.jgit.api;version="[6.1.1,6.2.0)",
- org.eclipse.jgit.api.errors;version="[6.1.1,6.2.0)",
- org.eclipse.jgit.archive;version="[6.1.1,6.2.0)",
- org.eclipse.jgit.attributes;version="[6.1.1,6.2.0)",
- org.eclipse.jgit.awtui;version="[6.1.1,6.2.0)",
- org.eclipse.jgit.blame;version="[6.1.1,6.2.0)",
- org.eclipse.jgit.diff;version="[6.1.1,6.2.0)",
- org.eclipse.jgit.dircache;version="[6.1.1,6.2.0)",
- org.eclipse.jgit.errors;version="[6.1.1,6.2.0)",
- org.eclipse.jgit.events;version="[6.1.1,6.2.0)",
- org.eclipse.jgit.fnmatch;version="[6.1.1,6.2.0)",
- org.eclipse.jgit.gitrepo;version="[6.1.1,6.2.0)",
- org.eclipse.jgit.hooks;version="[6.1.1,6.2.0)",
- org.eclipse.jgit.ignore;version="[6.1.1,6.2.0)",
- org.eclipse.jgit.ignore.internal;version="[6.1.1,6.2.0)",
- org.eclipse.jgit.internal;version="[6.1.1,6.2.0)",
- org.eclipse.jgit.internal.diffmergetool;version="[6.1.1,6.2.0)",
- org.eclipse.jgit.internal.fsck;version="[6.1.1,6.2.0)",
- org.eclipse.jgit.internal.revwalk;version="[6.1.1,6.2.0)",
- org.eclipse.jgit.internal.storage.dfs;version="[6.1.1,6.2.0)",
- org.eclipse.jgit.internal.storage.file;version="[6.1.1,6.2.0)",
- org.eclipse.jgit.internal.storage.io;version="[6.1.1,6.2.0)",
- org.eclipse.jgit.internal.storage.pack;version="[6.1.1,6.2.0)",
- org.eclipse.jgit.internal.storage.reftable;version="[6.1.1,6.2.0)",
- org.eclipse.jgit.internal.transport.connectivity;version="[6.1.1,6.2.0)",
- org.eclipse.jgit.internal.transport.http;version="[6.1.1,6.2.0)",
- org.eclipse.jgit.internal.transport.parser;version="[6.1.1,6.2.0)",
- org.eclipse.jgit.internal.transport.ssh;version="[6.1.1,6.2.0)",
- org.eclipse.jgit.junit;version="[6.1.1,6.2.0)",
- org.eclipse.jgit.junit.time;version="[6.1.1,6.2.0)",
- org.eclipse.jgit.lfs;version="[6.1.1,6.2.0)",
- org.eclipse.jgit.lib;version="[6.1.1,6.2.0)",
- org.eclipse.jgit.lib.internal;version="[6.1.1,6.2.0)",
- org.eclipse.jgit.logging;version="[6.1.1,6.2.0)",
- org.eclipse.jgit.merge;version="[6.1.1,6.2.0)",
- org.eclipse.jgit.nls;version="[6.1.1,6.2.0)",
- org.eclipse.jgit.notes;version="[6.1.1,6.2.0)",
- org.eclipse.jgit.patch;version="[6.1.1,6.2.0)",
- org.eclipse.jgit.pgm;version="[6.1.1,6.2.0)",
- org.eclipse.jgit.pgm.internal;version="[6.1.1,6.2.0)",
- org.eclipse.jgit.revplot;version="[6.1.1,6.2.0)",
- org.eclipse.jgit.revwalk;version="[6.1.1,6.2.0)",
- org.eclipse.jgit.revwalk.filter;version="[6.1.1,6.2.0)",
- org.eclipse.jgit.storage.file;version="[6.1.1,6.2.0)",
- org.eclipse.jgit.storage.pack;version="[6.1.1,6.2.0)",
- org.eclipse.jgit.submodule;version="[6.1.1,6.2.0)",
- org.eclipse.jgit.transport;version="[6.1.1,6.2.0)",
- org.eclipse.jgit.transport.http;version="[6.1.1,6.2.0)",
- org.eclipse.jgit.transport.resolver;version="[6.1.1,6.2.0)",
- org.eclipse.jgit.treewalk;version="[6.1.1,6.2.0)",
- org.eclipse.jgit.treewalk.filter;version="[6.1.1,6.2.0)",
- org.eclipse.jgit.util;version="[6.1.1,6.2.0)",
- org.eclipse.jgit.util.io;version="[6.1.1,6.2.0)",
- org.eclipse.jgit.util.sha1;version="[6.1.1,6.2.0)",
+ org.eclipse.jgit.annotations;version="[6.2.0,6.3.0)",
+ org.eclipse.jgit.api;version="[6.2.0,6.3.0)",
+ org.eclipse.jgit.api.errors;version="[6.2.0,6.3.0)",
+ org.eclipse.jgit.archive;version="[6.2.0,6.3.0)",
+ org.eclipse.jgit.attributes;version="[6.2.0,6.3.0)",
+ org.eclipse.jgit.awtui;version="[6.2.0,6.3.0)",
+ org.eclipse.jgit.blame;version="[6.2.0,6.3.0)",
+ org.eclipse.jgit.diff;version="[6.2.0,6.3.0)",
+ org.eclipse.jgit.dircache;version="[6.2.0,6.3.0)",
+ org.eclipse.jgit.errors;version="[6.2.0,6.3.0)",
+ org.eclipse.jgit.events;version="[6.2.0,6.3.0)",
+ org.eclipse.jgit.fnmatch;version="[6.2.0,6.3.0)",
+ org.eclipse.jgit.gitrepo;version="[6.2.0,6.3.0)",
+ org.eclipse.jgit.hooks;version="[6.2.0,6.3.0)",
+ org.eclipse.jgit.ignore;version="[6.2.0,6.3.0)",
+ org.eclipse.jgit.ignore.internal;version="[6.2.0,6.3.0)",
+ org.eclipse.jgit.internal;version="[6.2.0,6.3.0)",
+ org.eclipse.jgit.internal.diffmergetool;version="[6.2.0,6.3.0)",
+ org.eclipse.jgit.internal.fsck;version="[6.2.0,6.3.0)",
+ org.eclipse.jgit.internal.revwalk;version="[6.2.0,6.3.0)",
+ org.eclipse.jgit.internal.storage.dfs;version="[6.2.0,6.3.0)",
+ org.eclipse.jgit.internal.storage.file;version="[6.2.0,6.3.0)",
+ org.eclipse.jgit.internal.storage.io;version="[6.2.0,6.3.0)",
+ org.eclipse.jgit.internal.storage.pack;version="[6.2.0,6.3.0)",
+ org.eclipse.jgit.internal.storage.reftable;version="[6.2.0,6.3.0)",
+ org.eclipse.jgit.internal.transport.connectivity;version="[6.2.0,6.3.0)",
+ org.eclipse.jgit.internal.transport.http;version="[6.2.0,6.3.0)",
+ org.eclipse.jgit.internal.transport.parser;version="[6.2.0,6.3.0)",
+ org.eclipse.jgit.internal.transport.ssh;version="[6.2.0,6.3.0)",
+ org.eclipse.jgit.junit;version="[6.2.0,6.3.0)",
+ org.eclipse.jgit.junit.time;version="[6.2.0,6.3.0)",
+ org.eclipse.jgit.lfs;version="[6.2.0,6.3.0)",
+ org.eclipse.jgit.lib;version="[6.2.0,6.3.0)",
+ org.eclipse.jgit.lib.internal;version="[6.2.0,6.3.0)",
+ org.eclipse.jgit.logging;version="[6.2.0,6.3.0)",
+ org.eclipse.jgit.merge;version="[6.2.0,6.3.0)",
+ org.eclipse.jgit.nls;version="[6.2.0,6.3.0)",
+ org.eclipse.jgit.notes;version="[6.2.0,6.3.0)",
+ org.eclipse.jgit.patch;version="[6.2.0,6.3.0)",
+ org.eclipse.jgit.pgm;version="[6.2.0,6.3.0)",
+ org.eclipse.jgit.pgm.internal;version="[6.2.0,6.3.0)",
+ org.eclipse.jgit.revplot;version="[6.2.0,6.3.0)",
+ org.eclipse.jgit.revwalk;version="[6.2.0,6.3.0)",
+ org.eclipse.jgit.revwalk.filter;version="[6.2.0,6.3.0)",
+ org.eclipse.jgit.storage.file;version="[6.2.0,6.3.0)",
+ org.eclipse.jgit.storage.pack;version="[6.2.0,6.3.0)",
+ org.eclipse.jgit.submodule;version="[6.2.0,6.3.0)",
+ org.eclipse.jgit.transport;version="[6.2.0,6.3.0)",
+ org.eclipse.jgit.transport.http;version="[6.2.0,6.3.0)",
+ org.eclipse.jgit.transport.resolver;version="[6.2.0,6.3.0)",
+ org.eclipse.jgit.treewalk;version="[6.2.0,6.3.0)",
+ org.eclipse.jgit.treewalk.filter;version="[6.2.0,6.3.0)",
+ org.eclipse.jgit.util;version="[6.2.0,6.3.0)",
+ org.eclipse.jgit.util.io;version="[6.2.0,6.3.0)",
+ org.eclipse.jgit.util.sha1;version="[6.2.0,6.3.0)",
  org.hamcrest;version="[1.1.0,3.0.0)",
  org.hamcrest.collection;version="[1.1.0,3.0.0)",
  org.junit;version="[4.13,5.0.0)",
diff --git a/org.eclipse.jgit.test/pom.xml b/org.eclipse.jgit.test/pom.xml
index 6b66919..0d1e545 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.1.1-SNAPSHOT</version>
+    <version>6.2.0-SNAPSHOT</version>
   </parent>
 
   <artifactId>org.eclipse.jgit.test</artifactId>
diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/FetchCommandTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/FetchCommandTest.java
index 6479d15..0884d72 100644
--- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/FetchCommandTest.java
+++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/FetchCommandTest.java
@@ -96,6 +96,53 @@
 	}
 
 	@Test
+	public void testFetchSimpleNegativeRefSpec() throws Exception {
+		remoteGit.commit().setMessage("commit").call();
+
+		FetchResult res = git.fetch().setRemote("test")
+				.setRefSpecs("refs/heads/master:refs/heads/test",
+						"^:refs/heads/test")
+				.call();
+		assertNull(res.getTrackingRefUpdate("refs/heads/test"));
+
+		res = git.fetch().setRemote("test")
+				.setRefSpecs("refs/heads/master:refs/heads/test",
+						"^refs/heads/master")
+				.call();
+		assertNull(res.getTrackingRefUpdate("refs/heads/test"));
+	}
+
+	@Test
+	public void negativeRefSpecFilterBySource() throws Exception {
+		remoteGit.commit().setMessage("commit").call();
+		remoteGit.branchCreate().setName("test").call();
+		remoteGit.commit().setMessage("commit1").call();
+		remoteGit.branchCreate().setName("dev").call();
+
+		FetchResult res = git.fetch().setRemote("test")
+				.setRefSpecs("refs/*:refs/origins/*", "^refs/*/test")
+				.call();
+		assertNotNull(res.getTrackingRefUpdate("refs/origins/heads/master"));
+		assertNull(res.getTrackingRefUpdate("refs/origins/heads/test"));
+		assertNotNull(res.getTrackingRefUpdate("refs/origins/heads/dev"));
+	}
+
+	@Test
+	public void negativeRefSpecFilterByDestination() throws Exception {
+		remoteGit.commit().setMessage("commit").call();
+		remoteGit.branchCreate().setName("meta").call();
+		remoteGit.commit().setMessage("commit1").call();
+		remoteGit.branchCreate().setName("data").call();
+
+		FetchResult res = git.fetch().setRemote("test")
+				.setRefSpecs("refs/*:refs/secret/*", "^:refs/secret/*/meta")
+				.call();
+		assertNotNull(res.getTrackingRefUpdate("refs/secret/heads/master"));
+		assertNull(res.getTrackingRefUpdate("refs/secret/heads/meta"));
+		assertNotNull(res.getTrackingRefUpdate("refs/secret/heads/data"));
+	}
+
+	@Test
 	public void fetchAddsBranches() throws Exception {
 		final String branch1 = "b1";
 		final String branch2 = "b2";
diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/LsRemoteCommandTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/LsRemoteCommandTest.java
index 12ec2aa..05af175 100644
--- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/LsRemoteCommandTest.java
+++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/LsRemoteCommandTest.java
@@ -21,6 +21,8 @@
 import org.eclipse.jgit.lib.Constants;
 import org.eclipse.jgit.lib.Ref;
 import org.eclipse.jgit.lib.RefUpdate;
+import org.eclipse.jgit.lib.StoredConfig;
+import org.eclipse.jgit.util.SystemReader;
 import org.junit.Test;
 
 public class LsRemoteCommandTest extends RepositoryTestCase {
@@ -107,6 +109,20 @@
 	}
 
 	@Test
+	public void testLsRemoteWithoutLocalRepositoryUrlInsteadOf()
+			throws Exception {
+		String uri = fileUri();
+		StoredConfig userConfig = SystemReader.getInstance().getUserConfig();
+		userConfig.load();
+		userConfig.setString("url", uri, "insteadOf", "file:///foo");
+		userConfig.save();
+		Collection<Ref> refs = Git.lsRemoteRepository().setRemote("file:///foo")
+				.setHeads(true).call();
+		assertNotNull(refs);
+		assertEquals(2, refs.size());
+	}
+
+	@Test
 	public void testLsRemoteWithSymRefs() throws Exception {
 		File directory = createTempDirectory("testRepository");
 		CloneCommand command = Git.cloneRepository();
diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/MergeCommandTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/MergeCommandTest.java
index 64475f5..917b6c3 100644
--- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/MergeCommandTest.java
+++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/MergeCommandTest.java
@@ -36,6 +36,7 @@
 import org.eclipse.jgit.lib.Repository;
 import org.eclipse.jgit.lib.RepositoryState;
 import org.eclipse.jgit.lib.Sets;
+import org.eclipse.jgit.lib.StoredConfig;
 import org.eclipse.jgit.merge.ContentMergeStrategy;
 import org.eclipse.jgit.merge.MergeStrategy;
 import org.eclipse.jgit.merge.ResolveMerger.MergeFailureReason;
@@ -2018,6 +2019,73 @@
 		}
 	}
 
+	@Test
+	public void testMergeConflictWithMessageAndCommentChar() throws Exception {
+		try (Git git = new Git(db)) {
+			writeTrashFile("a", "1\na\n3\n");
+			git.add().addFilepattern("a").call();
+			RevCommit initialCommit = git.commit().setMessage("initial").call();
+
+			createBranch(initialCommit, "refs/heads/side");
+			checkoutBranch("refs/heads/side");
+
+			writeTrashFile("a", "1\na(side)\n3\n");
+			git.add().addFilepattern("a").call();
+			git.commit().setMessage("side").call();
+
+			checkoutBranch("refs/heads/master");
+
+			writeTrashFile("a", "1\na(main)\n3\n");
+			git.add().addFilepattern("a").call();
+			git.commit().setMessage("main").call();
+
+			StoredConfig config = db.getConfig();
+			config.setString("core", null, "commentChar", "^");
+
+			Ref sideBranch = db.exactRef("refs/heads/side");
+
+			git.merge().include(sideBranch).setStrategy(MergeStrategy.RESOLVE)
+					.setMessage("user message").call();
+
+			assertEquals("user message\n\n^ Conflicts:\n^\ta\n",
+					db.readMergeCommitMsg());
+		}
+	}
+
+	@Test
+	public void testMergeConflictWithMessageAndCommentCharAuto()
+			throws Exception {
+		try (Git git = new Git(db)) {
+			writeTrashFile("a", "1\na\n3\n");
+			git.add().addFilepattern("a").call();
+			RevCommit initialCommit = git.commit().setMessage("initial").call();
+
+			createBranch(initialCommit, "refs/heads/side");
+			checkoutBranch("refs/heads/side");
+
+			writeTrashFile("a", "1\na(side)\n3\n");
+			git.add().addFilepattern("a").call();
+			git.commit().setMessage("side").call();
+
+			checkoutBranch("refs/heads/master");
+
+			writeTrashFile("a", "1\na(main)\n3\n");
+			git.add().addFilepattern("a").call();
+			git.commit().setMessage("main").call();
+
+			StoredConfig config = db.getConfig();
+			config.setString("core", null, "commentChar", "auto");
+
+			Ref sideBranch = db.exactRef("refs/heads/side");
+
+			git.merge().include(sideBranch).setStrategy(MergeStrategy.RESOLVE)
+					.setMessage("#user message").call();
+
+			assertEquals("#user message\n\n; Conflicts:\n;\ta\n",
+					db.readMergeCommitMsg());
+		}
+	}
+
 	private static void setExecutable(Git git, String path, boolean executable) {
 		FS.DETECTED.setExecute(
 				new File(git.getRepository().getWorkTree(), path), executable);
diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/RebaseCommandTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/RebaseCommandTest.java
index c64ff0b..d574e45 100644
--- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/RebaseCommandTest.java
+++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/RebaseCommandTest.java
@@ -30,6 +30,7 @@
 
 import org.eclipse.jgit.api.MergeResult.MergeStatus;
 import org.eclipse.jgit.api.RebaseCommand.InteractiveHandler;
+import org.eclipse.jgit.api.RebaseCommand.InteractiveHandler2;
 import org.eclipse.jgit.api.RebaseCommand.Operation;
 import org.eclipse.jgit.api.RebaseResult.Status;
 import org.eclipse.jgit.api.errors.InvalidRebaseStepException;
@@ -46,6 +47,7 @@
 import org.eclipse.jgit.events.ListenerHandle;
 import org.eclipse.jgit.junit.RepositoryTestCase;
 import org.eclipse.jgit.lib.AbbreviatedObjectId;
+import org.eclipse.jgit.lib.CommitConfig.CleanupMode;
 import org.eclipse.jgit.lib.ConfigConstants;
 import org.eclipse.jgit.lib.Constants;
 import org.eclipse.jgit.lib.ObjectId;
@@ -56,6 +58,7 @@
 import org.eclipse.jgit.lib.RefUpdate;
 import org.eclipse.jgit.lib.ReflogEntry;
 import org.eclipse.jgit.lib.RepositoryState;
+import org.eclipse.jgit.lib.StoredConfig;
 import org.eclipse.jgit.merge.MergeStrategy;
 import org.eclipse.jgit.revwalk.RevCommit;
 import org.eclipse.jgit.revwalk.RevSort;
@@ -3410,6 +3413,99 @@
 
 	}
 
+	@Test
+	public void testInteractiveRebaseSquashFixupSequence() throws Exception {
+		// create file1, add and commit
+		writeTrashFile(FILE1, "file1");
+		git.add().addFilepattern(FILE1).call();
+		git.commit().setMessage("commit1").call();
+
+		// modify file1, add and commit
+		writeTrashFile(FILE1, "modified file1");
+		git.add().addFilepattern(FILE1).call();
+		git.commit().setMessage("commit2").call();
+
+		// modify file1, add and commit
+		writeTrashFile(FILE1, "modified file1 a second time");
+		git.add().addFilepattern(FILE1).call();
+		// Make it difficult; use git standard comment characters in the commit
+		// messages
+		git.commit().setMessage("#commit3").call();
+
+		// modify file1, add and commit
+		writeTrashFile(FILE1, "modified file1 a third time");
+		git.add().addFilepattern(FILE1).call();
+		git.commit().setMessage("@commit4").call();
+
+		// modify file1, add and commit
+		writeTrashFile(FILE1, "modified file1 a fourth time");
+		git.add().addFilepattern(FILE1).call();
+		git.commit().setMessage(";commit5").call();
+
+		StoredConfig config = git.getRepository().getConfig();
+		config.setString("core", null, "commentChar", "auto");
+		// With "auto", we should end up with '@' being used as comment
+		// character (commit4 is skipped, so it should not advance the
+		// character).
+		RebaseResult result = git.rebase().setUpstream("HEAD~4")
+				.runInteractively(new InteractiveHandler2() {
+
+					@Override
+					public void prepareSteps(List<RebaseTodoLine> steps) {
+						try {
+							steps.get(0).setAction(Action.PICK);
+							steps.get(1).setAction(Action.SQUASH);
+							steps.get(2).setAction(Action.FIXUP);
+							steps.get(3).setAction(Action.SQUASH);
+						} catch (IllegalTodoFileModification e) {
+							fail("unexpected exception: " + e);
+						}
+					}
+
+					@Override
+					public String modifyCommitMessage(String commit) {
+						fail("should not be called");
+						return commit;
+					}
+
+					@Override
+					public ModifyResult editCommitMessage(String message,
+							CleanupMode mode, char commentChar) {
+						assertEquals('@', commentChar);
+						assertEquals("@ This is a combination of 4 commits.\n"
+								+ "@ The first commit's message is:\n"
+								+ "commit2\n"
+								+ "@ This is the 2nd commit message:\n"
+								+ "#commit3\n"
+								+ "@ The 3rd commit message will be skipped:\n"
+								+ "@ @commit4\n"
+								+ "@ This is the 4th commit message:\n"
+								+ ";commit5", message);
+						return new ModifyResult() {
+
+							@Override
+							public String getMessage() {
+								return message;
+							}
+
+							@Override
+							public CleanupMode getCleanupMode() {
+								return mode;
+							}
+
+							@Override
+							public boolean shouldAddChangeId() {
+								return false;
+							}
+						};
+					}
+				}).call();
+		assertEquals(Status.OK, result.getStatus());
+		Iterator<RevCommit> logIterator = git.log().all().call().iterator();
+		String actualCommitMsg = logIterator.next().getFullMessage();
+		assertEquals("commit2\n#commit3\n;commit5", actualCommitMsg);
+	}
+
 	private File getTodoFile() {
 		File todoFile = new File(db.getDirectory(), GIT_REBASE_TODO);
 		return todoFile;
diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/lib/CommitConfigTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/lib/CommitConfigTest.java
index d95d781..7066f9d 100644
--- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/lib/CommitConfigTest.java
+++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/lib/CommitConfigTest.java
@@ -11,7 +11,10 @@
 package org.eclipse.jgit.lib;
 
 import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotEquals;
 import static org.junit.Assert.assertThrows;
+import static org.junit.Assert.assertTrue;
 
 import org.eclipse.jgit.errors.ConfigInvalidException;
 import org.eclipse.jgit.lib.CommitConfig.CleanupMode;
@@ -169,6 +172,82 @@
 				CommitConfig.cleanText(message, CleanupMode.SCISSORS, '#'));
 	}
 
+	@Test
+	public void testCommentCharDefault() throws Exception {
+		CommitConfig cfg = parse("");
+		assertEquals('#', cfg.getCommentChar());
+		assertFalse(cfg.isAutoCommentChar());
+	}
+
+	@Test
+	public void testCommentCharAuto() throws Exception {
+		CommitConfig cfg = parse("[core]\n\tcommentChar = auto\n");
+		assertEquals('#', cfg.getCommentChar());
+		assertTrue(cfg.isAutoCommentChar());
+	}
+
+	@Test
+	public void testCommentCharEmpty() throws Exception {
+		CommitConfig cfg = parse("[core]\n\tcommentChar =\n");
+		assertEquals('#', cfg.getCommentChar());
+	}
+
+	@Test
+	public void testCommentCharInvalid() throws Exception {
+		CommitConfig cfg = parse("[core]\n\tcommentChar = \" \"\n");
+		assertEquals('#', cfg.getCommentChar());
+	}
+
+	@Test
+	public void testCommentCharNonAscii() throws Exception {
+		CommitConfig cfg = parse("[core]\n\tcommentChar = ö\n");
+		assertEquals('#', cfg.getCommentChar());
+	}
+
+	@Test
+	public void testCommentChar() throws Exception {
+		CommitConfig cfg = parse("[core]\n\tcommentChar = _\n");
+		assertEquals('_', cfg.getCommentChar());
+	}
+
+	@Test
+	public void testDetermineCommentChar() throws Exception {
+		String text = "A commit message\n\nBody\n";
+		assertEquals('#', CommitConfig.determineCommentChar(text));
+	}
+
+	@Test
+	public void testDetermineCommentChar2() throws Exception {
+		String text = "A commit message\n\nBody\n\n# Conflicts:\n#\tfoo.txt\n";
+		char ch = CommitConfig.determineCommentChar(text);
+		assertNotEquals('#', ch);
+		assertTrue(ch > ' ' && ch < 127);
+	}
+
+	@Test
+	public void testDetermineCommentChar3() throws Exception {
+		String text = "A commit message\n\n;Body\n\n# Conflicts:\n#\tfoo.txt\n";
+		char ch = CommitConfig.determineCommentChar(text);
+		assertNotEquals('#', ch);
+		assertNotEquals(';', ch);
+		assertTrue(ch > ' ' && ch < 127);
+	}
+
+	@Test
+	public void testDetermineCommentChar4() throws Exception {
+		String text = "A commit message\n\nBody\n\n  # Conflicts:\n\t #\tfoo.txt\n";
+		char ch = CommitConfig.determineCommentChar(text);
+		assertNotEquals('#', ch);
+		assertTrue(ch > ' ' && ch < 127);
+	}
+
+	@Test
+	public void testDetermineCommentChar5() throws Exception {
+		String text = "A commit message\n\nBody\n\n#a\n;b\n@c\n!d\n$\n%\n^\n&\n|\n:";
+		char ch = CommitConfig.determineCommentChar(text);
+		assertEquals(0, ch);
+	}
+
 	private static CommitConfig parse(String content)
 			throws ConfigInvalidException {
 		Config c = new Config();
diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/transport/RefSpecTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/transport/RefSpecTest.java
index b56308c..ef0817a 100644
--- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/transport/RefSpecTest.java
+++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/transport/RefSpecTest.java
@@ -443,6 +443,26 @@
 		a.setDestination("refs/remotes/origin/*/*");
 	}
 
+	@Test(expected = IllegalArgumentException.class)
+	public void invalidNegativeAndForce() {
+		assertNotNull(new RefSpec("^+refs/heads/master"));
+	}
+
+	@Test(expected = IllegalArgumentException.class)
+	public void invalidForceAndNegative() {
+		assertNotNull(new RefSpec("+^refs/heads/master"));
+	}
+
+	@Test(expected = IllegalArgumentException.class)
+	public void invalidNegativeNoSrcDest() {
+		assertNotNull(new RefSpec("^"));
+	}
+
+	@Test(expected = IllegalArgumentException.class)
+	public void invalidNegativeBothSrcDest() {
+		assertNotNull(new RefSpec("^refs/heads/*:refs/heads/*"));
+	}
+
 	@Test
 	public void sourceOnlywithWildcard() {
 		RefSpec a = new RefSpec("refs/heads/*",
@@ -480,4 +500,32 @@
 		assertTrue(a.isMatching());
 		assertTrue(a.isForceUpdate());
 	}
+
+	@Test
+	public void negativeRefSpecWithDest() {
+		RefSpec a = new RefSpec("^:refs/readonly/*");
+		assertTrue(a.isNegative());
+		assertNull(a.getSource());
+		assertEquals(a.getDestination(), "refs/readonly/*");
+	}
+
+	// Because of some of the API's existing behavior, without a colon at the
+	// end of the refspec, dest will be null.
+	@Test
+	public void negativeRefSpecWithSrcAndNullDest() {
+		RefSpec a = new RefSpec("^refs/testdata/*");
+		assertTrue(a.isNegative());
+		assertNull(a.getDestination());
+		assertEquals(a.getSource(), "refs/testdata/*");
+	}
+
+	// Because of some of the API's existing behavior, with a colon at the end
+	// of the refspec, dest will be empty.
+	@Test
+	public void negativeRefSpecWithSrcAndEmptyDest() {
+		RefSpec a = new RefSpec("^refs/testdata/*:");
+		assertTrue(a.isNegative());
+		assertTrue(a.getDestination().isEmpty());
+		assertEquals(a.getSource(), "refs/testdata/*");
+	}
 }
diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/transport/SideBandInputStreamTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/transport/SideBandInputStreamTest.java
new file mode 100644
index 0000000..7ac8319
--- /dev/null
+++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/transport/SideBandInputStreamTest.java
@@ -0,0 +1,229 @@
+/*
+ * Copyright (C) 2022 Thomas Wolf <thomas.wolf@paranor.ch> and others
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Distribution License v. 1.0 which is available at
+ * https://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+package org.eclipse.jgit.transport;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.StringWriter;
+import java.nio.charset.StandardCharsets;
+
+import org.junit.Before;
+import org.junit.Test;
+
+public class SideBandInputStreamTest {
+
+	private StringWriter messages;
+
+	private SideBandInputStream sideband;
+
+	@Before
+	public void setup() {
+		messages = new StringWriter();
+	}
+
+	@Test
+	public void progressSingleCR() throws IOException {
+		init(packet("message\r"));
+		assertTrue(sideband.read() < 0);
+		assertEquals("message\r", messages.toString());
+	}
+
+	@Test
+	public void progressSingleLF() throws IOException {
+		init(packet("message\n"));
+		assertTrue(sideband.read() < 0);
+		assertEquals("message\n", messages.toString());
+	}
+
+	@Test
+	public void progressSingleCRLF() throws IOException {
+		init(packet("message\r\n"));
+		assertTrue(sideband.read() < 0);
+		assertEquals("message\r\n", messages.toString());
+	}
+
+	@Test
+	public void progressMultiCR() throws IOException {
+		init(packet("message   0%\rmessage 100%\r"));
+		assertTrue(sideband.read() < 0);
+		assertEquals("message   0%\rmessage 100%\r", messages.toString());
+	}
+
+	@Test
+	public void progressMultiLF() throws IOException {
+		init(packet("message   0%\nmessage 100%\n"));
+		assertTrue(sideband.read() < 0);
+		assertEquals("message   0%\nmessage 100%\n", messages.toString());
+	}
+
+	@Test
+	public void progressMultiCRLF() throws IOException {
+		init(packet("message   0%\r\nmessage 100%\r\n"));
+		assertTrue(sideband.read() < 0);
+		assertEquals("message   0%\r\nmessage 100%\r\n", messages.toString());
+	}
+
+	@Test
+	public void progressPartial() throws IOException {
+		init(packet("message"));
+		assertTrue(sideband.read() < 0);
+		assertEquals("", messages.toString());
+		sideband.drainMessages();
+		assertEquals("message\n", messages.toString());
+	}
+
+	@Test
+	public void progressPartialTwoCR() throws IOException {
+		init(packet("message") + packet("message\r"));
+		assertTrue(sideband.read() < 0);
+		assertEquals("messagemessage\r", messages.toString());
+	}
+
+	@Test
+	public void progressPartialTwoLF() throws IOException {
+		init(packet("message") + packet("message\n"));
+		assertTrue(sideband.read() < 0);
+		assertEquals("messagemessage\n", messages.toString());
+	}
+
+	@Test
+	public void progressPartialTwoCRLF() throws IOException {
+		init(packet("message") + packet("message\r\n"));
+		assertTrue(sideband.read() < 0);
+		assertEquals("messagemessage\r\n", messages.toString());
+	}
+
+	@Test
+	public void progressPartialThreeCR() throws IOException {
+		init(packet("message") + packet("message") + packet("message\r"));
+		assertTrue(sideband.read() < 0);
+		assertEquals("messagemessagemessage\r", messages.toString());
+	}
+
+	@Test
+	public void progressPartialThreeLF() throws IOException {
+		init(packet("message") + packet("message") + packet("message\n"));
+		assertTrue(sideband.read() < 0);
+		assertEquals("messagemessagemessage\n", messages.toString());
+	}
+
+	@Test
+	public void progressPartialThreeCRLF() throws IOException {
+		init(packet("message") + packet("message") + packet("message\r\n"));
+		assertTrue(sideband.read() < 0);
+		assertEquals("messagemessagemessage\r\n", messages.toString());
+	}
+
+	@Test
+	public void progressPartialCR() throws IOException {
+		init(packet("message   0%\rmessage 100%"));
+		assertTrue(sideband.read() < 0);
+		assertEquals("message   0%\r", messages.toString());
+		sideband.drainMessages();
+		assertEquals("message   0%\rmessage 100%\n", messages.toString());
+	}
+
+	@Test
+	public void progressPartialLF() throws IOException {
+		init(packet("message   0%\nmessage 100%"));
+		assertTrue(sideband.read() < 0);
+		assertEquals("message   0%\n", messages.toString());
+		sideband.drainMessages();
+		assertEquals("message   0%\nmessage 100%\n", messages.toString());
+	}
+
+	@Test
+	public void progressPartialCRLF() throws IOException {
+		init(packet("message   0%\r\nmessage 100%"));
+		assertTrue(sideband.read() < 0);
+		assertEquals("message   0%\r\n", messages.toString());
+		sideband.drainMessages();
+		assertEquals("message   0%\r\nmessage 100%\n", messages.toString());
+	}
+
+	@Test
+	public void progressPartialSplitCR() throws IOException {
+		init(packet("message") + "0006\001a" + packet("   0%\rmessa")
+				+ packet("ge 100%"));
+		assertEquals('a', sideband.read());
+		assertEquals("", messages.toString());
+		assertTrue(sideband.read() < 0);
+		assertEquals("message   0%\r", messages.toString());
+		sideband.drainMessages();
+		assertEquals("message   0%\rmessage 100%\n", messages.toString());
+	}
+
+	@Test
+	public void progressPartialSplitLF() throws IOException {
+		init(packet("message") + "0006\001a" + packet("   0%\nmessa")
+				+ packet("ge 100%"));
+		assertEquals('a', sideband.read());
+		assertEquals("", messages.toString());
+		assertTrue(sideband.read() < 0);
+		assertEquals("message   0%\n", messages.toString());
+		sideband.drainMessages();
+		assertEquals("message   0%\nmessage 100%\n", messages.toString());
+	}
+
+	@Test
+	public void progressPartialSplitCRLF() throws IOException {
+		init(packet("message") + "0006\001a" + packet("   0%\r\nmessa")
+				+ packet("ge 100%"));
+		assertEquals('a', sideband.read());
+		assertEquals("", messages.toString());
+		assertTrue(sideband.read() < 0);
+		assertEquals("message   0%\r\n", messages.toString());
+		sideband.drainMessages();
+		assertEquals("message   0%\r\nmessage 100%\n", messages.toString());
+	}
+
+	@Test
+	public void progressInterleaved() throws IOException {
+		init(packet("message   0%\r") + "0006\001a" + packet("message  10%")
+				+ "0006\001b" + packet("\rmessage 100%\n"));
+		assertEquals('a', sideband.read());
+		assertEquals("message   0%\r", messages.toString());
+		assertEquals('b', sideband.read());
+		assertEquals("message   0%\r", messages.toString());
+		assertTrue(sideband.read() < 0);
+		assertEquals("message   0%\rmessage  10%\rmessage 100%\n",
+				messages.toString());
+	}
+
+	@Test
+	public void progressInterleavedPartial() throws IOException {
+		init(packet("message   0%\r") + "0006\001a" + packet("message  10%")
+				+ "0006\001b" + packet("\rmessage 100%"));
+		assertEquals('a', sideband.read());
+		assertEquals("message   0%\r", messages.toString());
+		assertEquals('b', sideband.read());
+		assertEquals("message   0%\r", messages.toString());
+		assertTrue(sideband.read() < 0);
+		assertEquals("message   0%\rmessage  10%\r", messages.toString());
+		sideband.drainMessages();
+		assertEquals("message   0%\rmessage  10%\rmessage 100%\n",
+				messages.toString());
+	}
+
+	private String packet(String data) {
+		return String.format("%04x\002%s", Integer.valueOf(data.length() + 5),
+				data);
+	}
+
+	private void init(String packets) {
+		InputStream rawIn = new ByteArrayInputStream(
+				(packets + "0000").getBytes(StandardCharsets.UTF_8));
+		sideband = new SideBandInputStream(rawIn, null, messages, null);
+	}
+}
diff --git a/org.eclipse.jgit.ui/META-INF/MANIFEST.MF b/org.eclipse.jgit.ui/META-INF/MANIFEST.MF
index 7baa215..e9c5879 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.1.1.qualifier
+Bundle-Version: 6.2.0.qualifier
 Bundle-Vendor: %Bundle-Vendor
 Bundle-RequiredExecutionEnvironment: JavaSE-11
-Export-Package: org.eclipse.jgit.awtui;version="6.1.1"
-Import-Package: org.eclipse.jgit.errors;version="[6.1.1,6.2.0)",
- org.eclipse.jgit.lib;version="[6.1.1,6.2.0)",
- org.eclipse.jgit.nls;version="[6.1.1,6.2.0)",
- org.eclipse.jgit.revplot;version="[6.1.1,6.2.0)",
- org.eclipse.jgit.revwalk;version="[6.1.1,6.2.0)",
- org.eclipse.jgit.transport;version="[6.1.1,6.2.0)",
- org.eclipse.jgit.util;version="[6.1.1,6.2.0)"
+Export-Package: org.eclipse.jgit.awtui;version="6.2.0"
+Import-Package: org.eclipse.jgit.errors;version="[6.2.0,6.3.0)",
+ org.eclipse.jgit.lib;version="[6.2.0,6.3.0)",
+ org.eclipse.jgit.nls;version="[6.2.0,6.3.0)",
+ org.eclipse.jgit.revplot;version="[6.2.0,6.3.0)",
+ org.eclipse.jgit.revwalk;version="[6.2.0,6.3.0)",
+ org.eclipse.jgit.transport;version="[6.2.0,6.3.0)",
+ org.eclipse.jgit.util;version="[6.2.0,6.3.0)"
diff --git a/org.eclipse.jgit.ui/META-INF/SOURCE-MANIFEST.MF b/org.eclipse.jgit.ui/META-INF/SOURCE-MANIFEST.MF
index 75f3d21..df93dc2 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.1.1.qualifier
-Eclipse-SourceBundle: org.eclipse.jgit.ui;version="6.1.1.qualifier";roots="."
+Bundle-Version: 6.2.0.qualifier
+Eclipse-SourceBundle: org.eclipse.jgit.ui;version="6.2.0.qualifier";roots="."
diff --git a/org.eclipse.jgit.ui/pom.xml b/org.eclipse.jgit.ui/pom.xml
index 125e120..31c7149 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.1.1-SNAPSHOT</version>
+    <version>6.2.0-SNAPSHOT</version>
   </parent>
 
   <artifactId>org.eclipse.jgit.ui</artifactId>
diff --git a/org.eclipse.jgit/META-INF/MANIFEST.MF b/org.eclipse.jgit/META-INF/MANIFEST.MF
index eb8eb8b..e72f00f 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.1.1.qualifier
+Bundle-Version: 6.2.0.qualifier
 Bundle-Localization: plugin
 Bundle-Vendor: %Bundle-Vendor
 Eclipse-ExtensibleAPI: true
-Export-Package: org.eclipse.jgit.annotations;version="6.1.1",
- org.eclipse.jgit.api;version="6.1.1";
+Export-Package: org.eclipse.jgit.annotations;version="6.2.0",
+ org.eclipse.jgit.api;version="6.2.0";
   uses:="org.eclipse.jgit.transport,
    org.eclipse.jgit.notes,
    org.eclipse.jgit.dircache,
@@ -23,18 +23,18 @@
    org.eclipse.jgit.revwalk.filter,
    org.eclipse.jgit.blame,
    org.eclipse.jgit.merge",
- org.eclipse.jgit.api.errors;version="6.1.1";
+ org.eclipse.jgit.api.errors;version="6.2.0";
   uses:="org.eclipse.jgit.lib,
    org.eclipse.jgit.errors",
- org.eclipse.jgit.attributes;version="6.1.1";
+ org.eclipse.jgit.attributes;version="6.2.0";
   uses:="org.eclipse.jgit.lib,
    org.eclipse.jgit.treewalk",
- org.eclipse.jgit.blame;version="6.1.1";
+ org.eclipse.jgit.blame;version="6.2.0";
   uses:="org.eclipse.jgit.lib,
    org.eclipse.jgit.revwalk,
    org.eclipse.jgit.treewalk.filter,
    org.eclipse.jgit.diff",
- org.eclipse.jgit.diff;version="6.1.1";
+ org.eclipse.jgit.diff;version="6.2.0";
   uses:="org.eclipse.jgit.lib,
    org.eclipse.jgit.attributes,
    org.eclipse.jgit.revwalk,
@@ -42,48 +42,48 @@
    org.eclipse.jgit.treewalk.filter,
    org.eclipse.jgit.treewalk,
    org.eclipse.jgit.util",
- org.eclipse.jgit.dircache;version="6.1.1";
+ org.eclipse.jgit.dircache;version="6.2.0";
   uses:="org.eclipse.jgit.events,
    org.eclipse.jgit.lib,
    org.eclipse.jgit.attributes,
    org.eclipse.jgit.treewalk,
    org.eclipse.jgit.util",
- org.eclipse.jgit.errors;version="6.1.1";
+ org.eclipse.jgit.errors;version="6.2.0";
   uses:="org.eclipse.jgit.transport,
    org.eclipse.jgit.dircache,
    org.eclipse.jgit.lib,
    org.eclipse.jgit.internal.storage.pack",
- org.eclipse.jgit.events;version="6.1.1";
+ org.eclipse.jgit.events;version="6.2.0";
   uses:="org.eclipse.jgit.lib",
- org.eclipse.jgit.fnmatch;version="6.1.1",
- org.eclipse.jgit.gitrepo;version="6.1.1";
+ org.eclipse.jgit.fnmatch;version="6.2.0",
+ org.eclipse.jgit.gitrepo;version="6.2.0";
   uses:="org.xml.sax.helpers,
    org.eclipse.jgit.api,
    org.eclipse.jgit.lib,
    org.eclipse.jgit.revwalk,
    org.xml.sax",
- org.eclipse.jgit.gitrepo.internal;version="6.1.1";x-internal:=true,
- org.eclipse.jgit.hooks;version="6.1.1";uses:="org.eclipse.jgit.lib",
- org.eclipse.jgit.ignore;version="6.1.1",
- org.eclipse.jgit.ignore.internal;version="6.1.1";
+ org.eclipse.jgit.gitrepo.internal;version="6.2.0";x-internal:=true,
+ org.eclipse.jgit.hooks;version="6.2.0";uses:="org.eclipse.jgit.lib",
+ org.eclipse.jgit.ignore;version="6.2.0",
+ org.eclipse.jgit.ignore.internal;version="6.2.0";
   x-friends:="org.eclipse.jgit.test",
- org.eclipse.jgit.internal;version="6.1.1";
+ org.eclipse.jgit.internal;version="6.2.0";
   x-friends:="org.eclipse.jgit.test,
    org.eclipse.jgit.http.test",
- org.eclipse.jgit.internal.diffmergetool;version="6.1.1";
+ org.eclipse.jgit.internal.diffmergetool;version="6.2.0";
   x-friends:="org.eclipse.jgit.test,
    org.eclipse.jgit.pgm.test,
    org.eclipse.jgit.pgm",
- org.eclipse.jgit.internal.fsck;version="6.1.1";
+ org.eclipse.jgit.internal.fsck;version="6.2.0";
   x-friends:="org.eclipse.jgit.test",
- org.eclipse.jgit.internal.revwalk;version="6.1.1";
+ org.eclipse.jgit.internal.revwalk;version="6.2.0";
   x-friends:="org.eclipse.jgit.test",
- org.eclipse.jgit.internal.storage.dfs;version="6.1.1";
+ org.eclipse.jgit.internal.storage.dfs;version="6.2.0";
   x-friends:="org.eclipse.jgit.test,
    org.eclipse.jgit.http.server,
    org.eclipse.jgit.http.test,
    org.eclipse.jgit.lfs.test",
- org.eclipse.jgit.internal.storage.file;version="6.1.1";
+ org.eclipse.jgit.internal.storage.file;version="6.2.0";
   x-friends:="org.eclipse.jgit.test,
    org.eclipse.jgit.junit,
    org.eclipse.jgit.junit.http,
@@ -92,32 +92,32 @@
    org.eclipse.jgit.pgm,
    org.eclipse.jgit.pgm.test,
    org.eclipse.jgit.ssh.apache",
- org.eclipse.jgit.internal.storage.io;version="6.1.1";
+ org.eclipse.jgit.internal.storage.io;version="6.2.0";
   x-friends:="org.eclipse.jgit.junit,
    org.eclipse.jgit.test,
    org.eclipse.jgit.pgm",
- org.eclipse.jgit.internal.storage.pack;version="6.1.1";
+ org.eclipse.jgit.internal.storage.pack;version="6.2.0";
   x-friends:="org.eclipse.jgit.junit,
    org.eclipse.jgit.test,
    org.eclipse.jgit.pgm",
- org.eclipse.jgit.internal.storage.reftable;version="6.1.1";
+ org.eclipse.jgit.internal.storage.reftable;version="6.2.0";
   x-friends:="org.eclipse.jgit.http.test,
    org.eclipse.jgit.junit,
    org.eclipse.jgit.test,
    org.eclipse.jgit.pgm",
- org.eclipse.jgit.internal.submodule;version="6.1.1";x-internal:=true,
- org.eclipse.jgit.internal.transport.connectivity;version="6.1.1";
+ org.eclipse.jgit.internal.submodule;version="6.2.0";x-internal:=true,
+ org.eclipse.jgit.internal.transport.connectivity;version="6.2.0";
   x-friends:="org.eclipse.jgit.test",
- org.eclipse.jgit.internal.transport.http;version="6.1.1";
+ org.eclipse.jgit.internal.transport.http;version="6.2.0";
   x-friends:="org.eclipse.jgit.test",
- org.eclipse.jgit.internal.transport.parser;version="6.1.1";
+ org.eclipse.jgit.internal.transport.parser;version="6.2.0";
   x-friends:="org.eclipse.jgit.http.server,
    org.eclipse.jgit.test",
- org.eclipse.jgit.internal.transport.ssh;version="6.1.1";
+ org.eclipse.jgit.internal.transport.ssh;version="6.2.0";
   x-friends:="org.eclipse.jgit.ssh.apache,
    org.eclipse.jgit.ssh.jsch,
    org.eclipse.jgit.test",
- org.eclipse.jgit.lib;version="6.1.1";
+ org.eclipse.jgit.lib;version="6.2.0";
   uses:="org.eclipse.jgit.transport,
    org.eclipse.jgit.util.sha1,
    org.eclipse.jgit.dircache,
@@ -131,11 +131,11 @@
    org.eclipse.jgit.util,
    org.eclipse.jgit.submodule,
    org.eclipse.jgit.util.time",
- org.eclipse.jgit.lib.internal;version="6.1.1";
+ org.eclipse.jgit.lib.internal;version="6.2.0";
   x-friends:="org.eclipse.jgit.test,
    org.eclipse.jgit.pgm",
- org.eclipse.jgit.logging;version="6.1.1",
- org.eclipse.jgit.merge;version="6.1.1";
+ org.eclipse.jgit.logging;version="6.2.0",
+ org.eclipse.jgit.merge;version="6.2.0";
   uses:="org.eclipse.jgit.dircache,
    org.eclipse.jgit.lib,
    org.eclipse.jgit.revwalk,
@@ -144,40 +144,40 @@
    org.eclipse.jgit.util,
    org.eclipse.jgit.api,
    org.eclipse.jgit.attributes",
- org.eclipse.jgit.nls;version="6.1.1",
- org.eclipse.jgit.notes;version="6.1.1";
+ org.eclipse.jgit.nls;version="6.2.0",
+ org.eclipse.jgit.notes;version="6.2.0";
   uses:="org.eclipse.jgit.lib,
    org.eclipse.jgit.revwalk,
    org.eclipse.jgit.treewalk,
    org.eclipse.jgit.merge",
- org.eclipse.jgit.patch;version="6.1.1";
+ org.eclipse.jgit.patch;version="6.2.0";
   uses:="org.eclipse.jgit.lib,
    org.eclipse.jgit.diff",
- org.eclipse.jgit.revplot;version="6.1.1";
+ org.eclipse.jgit.revplot;version="6.2.0";
   uses:="org.eclipse.jgit.lib,
    org.eclipse.jgit.revwalk",
- org.eclipse.jgit.revwalk;version="6.1.1";
+ org.eclipse.jgit.revwalk;version="6.2.0";
   uses:="org.eclipse.jgit.lib,
    org.eclipse.jgit.diff,
    org.eclipse.jgit.treewalk.filter,
    org.eclipse.jgit.revwalk.filter,
    org.eclipse.jgit.treewalk",
- org.eclipse.jgit.revwalk.filter;version="6.1.1";
+ org.eclipse.jgit.revwalk.filter;version="6.2.0";
   uses:="org.eclipse.jgit.revwalk,
    org.eclipse.jgit.lib,
    org.eclipse.jgit.util",
- org.eclipse.jgit.storage.file;version="6.1.1";
+ org.eclipse.jgit.storage.file;version="6.2.0";
   uses:="org.eclipse.jgit.lib,
    org.eclipse.jgit.util",
- org.eclipse.jgit.storage.pack;version="6.1.1";
+ org.eclipse.jgit.storage.pack;version="6.2.0";
   uses:="org.eclipse.jgit.lib",
- org.eclipse.jgit.submodule;version="6.1.1";
+ org.eclipse.jgit.submodule;version="6.2.0";
   uses:="org.eclipse.jgit.lib,
    org.eclipse.jgit.diff,
    org.eclipse.jgit.treewalk.filter,
    org.eclipse.jgit.treewalk,
    org.eclipse.jgit.util",
- org.eclipse.jgit.transport;version="6.1.1";
+ org.eclipse.jgit.transport;version="6.2.0";
   uses:="javax.crypto,
    org.eclipse.jgit.util.io,
    org.eclipse.jgit.lib,
@@ -190,21 +190,21 @@
    org.eclipse.jgit.transport.resolver,
    org.eclipse.jgit.storage.pack,
    org.eclipse.jgit.errors",
- org.eclipse.jgit.transport.http;version="6.1.1";
+ org.eclipse.jgit.transport.http;version="6.2.0";
   uses:="javax.net.ssl",
- org.eclipse.jgit.transport.resolver;version="6.1.1";
+ org.eclipse.jgit.transport.resolver;version="6.2.0";
   uses:="org.eclipse.jgit.transport,
    org.eclipse.jgit.lib",
- org.eclipse.jgit.treewalk;version="6.1.1";
+ org.eclipse.jgit.treewalk;version="6.2.0";
   uses:="org.eclipse.jgit.dircache,
    org.eclipse.jgit.lib,
    org.eclipse.jgit.attributes,
    org.eclipse.jgit.revwalk,
    org.eclipse.jgit.treewalk.filter,
    org.eclipse.jgit.util",
- org.eclipse.jgit.treewalk.filter;version="6.1.1";
+ org.eclipse.jgit.treewalk.filter;version="6.2.0";
   uses:="org.eclipse.jgit.treewalk",
- org.eclipse.jgit.util;version="6.1.1";
+ org.eclipse.jgit.util;version="6.2.0";
   uses:="org.eclipse.jgit.transport,
    org.eclipse.jgit.hooks,
    org.eclipse.jgit.revwalk,
@@ -217,12 +217,12 @@
    org.eclipse.jgit.treewalk,
    javax.net.ssl,
    org.eclipse.jgit.util.time",
- org.eclipse.jgit.util.io;version="6.1.1";
+ org.eclipse.jgit.util.io;version="6.2.0";
   uses:="org.eclipse.jgit.attributes,
    org.eclipse.jgit.lib,
    org.eclipse.jgit.treewalk",
- org.eclipse.jgit.util.sha1;version="6.1.1",
- org.eclipse.jgit.util.time;version="6.1.1"
+ org.eclipse.jgit.util.sha1;version="6.2.0",
+ org.eclipse.jgit.util.time;version="6.2.0"
 Bundle-RequiredExecutionEnvironment: JavaSE-11
 Import-Package: com.googlecode.javaewah;version="[1.1.6,2.0.0)",
  javax.crypto,
diff --git a/org.eclipse.jgit/META-INF/SOURCE-MANIFEST.MF b/org.eclipse.jgit/META-INF/SOURCE-MANIFEST.MF
index 33e6156..a418bc3 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.1.1.qualifier
-Eclipse-SourceBundle: org.eclipse.jgit;version="6.1.1.qualifier";roots="."
+Bundle-Version: 6.2.0.qualifier
+Eclipse-SourceBundle: org.eclipse.jgit;version="6.2.0.qualifier";roots="."
diff --git a/org.eclipse.jgit/pom.xml b/org.eclipse.jgit/pom.xml
index f0e92b3..2fbec2f 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.1.1-SNAPSHOT</version>
+    <version>6.2.0-SNAPSHOT</version>
   </parent>
 
   <artifactId>org.eclipse.jgit</artifactId>
diff --git a/org.eclipse.jgit/resources/org/eclipse/jgit/internal/JGitText.properties b/org.eclipse.jgit/resources/org/eclipse/jgit/internal/JGitText.properties
index e6f4e65..9f264fc 100644
--- a/org.eclipse.jgit/resources/org/eclipse/jgit/internal/JGitText.properties
+++ b/org.eclipse.jgit/resources/org/eclipse/jgit/internal/JGitText.properties
@@ -393,6 +393,7 @@
 invalidModeFor=Invalid mode {0} for {1} {2} in {3}.
 invalidModeForPath=Invalid mode {0} for path {1}
 invalidNameContainsDotDot=Invalid name (contains ".."): {0}
+invalidNegativeAndForce= RefSpec can't be negative and forceful.
 invalidObject=Invalid {0} {1}: {2}
 invalidOldIdSent=invalid old id sent
 invalidPacketLineHeader=Invalid packet line header: {0}
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 f88179a..ceba89d 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/api/CherryPickCommand.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/api/CherryPickCommand.java
@@ -30,6 +30,7 @@
 import org.eclipse.jgit.events.WorkingTreeModifiedEvent;
 import org.eclipse.jgit.internal.JGitText;
 import org.eclipse.jgit.lib.AnyObjectId;
+import org.eclipse.jgit.lib.CommitConfig;
 import org.eclipse.jgit.lib.Constants;
 import org.eclipse.jgit.lib.NullProgressMonitor;
 import org.eclipse.jgit.lib.ObjectId;
@@ -183,9 +184,13 @@
 
 					String message;
 					if (unmergedPaths != null) {
+						CommitConfig cfg = repo.getConfig()
+								.get(CommitConfig.KEY);
+						message = srcCommit.getFullMessage();
+						char commentChar = cfg.getCommentChar(message);
 						message = new MergeMessageFormatter()
-							.formatWithConflicts(srcCommit.getFullMessage(),
-										unmergedPaths, '#');
+								.formatWithConflicts(message, unmergedPaths,
+										commentChar);
 					} else {
 						message = srcCommit.getFullMessage();
 					}
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/api/CommitCommand.java b/org.eclipse.jgit/src/org/eclipse/jgit/api/CommitCommand.java
index 7a591aa..3b3baf5 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/api/CommitCommand.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/api/CommitCommand.java
@@ -233,11 +233,25 @@
 				config = repo.getConfig().get(CommitConfig.KEY);
 				cleanupMode = config.resolve(cleanupMode, cleanDefaultIsStrip);
 			}
-			char comments;
-			if (commentChar == null) {
-				comments = '#'; // TODO use git config core.commentChar
-			} else {
-				comments = commentChar.charValue();
+			char comments = (char) 0;
+			if (CleanupMode.STRIP.equals(cleanupMode)
+					|| CleanupMode.SCISSORS.equals(cleanupMode)) {
+				if (commentChar == null) {
+					if (config == null) {
+						config = repo.getConfig().get(CommitConfig.KEY);
+					}
+					if (config.isAutoCommentChar()) {
+						// We're supposed to pick a character that isn't used,
+						// but then cleaning up won't remove any lines. So don't
+						// bother.
+						comments = (char) 0;
+						cleanupMode = CleanupMode.WHITESPACE;
+					} else {
+						comments = config.getCommentChar();
+					}
+				} else {
+					comments = commentChar.charValue();
+				}
 			}
 			message = CommitConfig.cleanText(message, cleanupMode, comments);
 
@@ -309,8 +323,14 @@
 	private void sign(CommitBuilder commit) throws ServiceUnavailableException,
 			CanceledException, UnsupportedSigningFormatException {
 		if (gpgSigner == null) {
-			throw new ServiceUnavailableException(
-					JGitText.get().signingServiceUnavailable);
+			gpgSigner = GpgSigner.getDefault();
+			if (gpgSigner == null) {
+				throw new ServiceUnavailableException(
+						JGitText.get().signingServiceUnavailable);
+			}
+		}
+		if (signingKey == null) {
+			signingKey = gpgConfig.getSigningKey();
 		}
 		if (gpgSigner instanceof GpgObjectSigner) {
 			((GpgObjectSigner) gpgSigner).signObject(commit,
@@ -645,12 +665,6 @@
 			signCommit = gpgConfig.isSignCommits() ? Boolean.TRUE
 					: Boolean.FALSE;
 		}
-		if (signingKey == null) {
-			signingKey = gpgConfig.getSigningKey();
-		}
-		if (gpgSigner == null) {
-			gpgSigner = GpgSigner.getDefault();
-		}
 	}
 
 	private boolean isMergeDuringRebase(RepositoryState state) {
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/api/LsRemoteCommand.java b/org.eclipse.jgit/src/org/eclipse/jgit/api/LsRemoteCommand.java
index 0c69106..c341558 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/api/LsRemoteCommand.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/api/LsRemoteCommand.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2011, 2020 Christoph Brill <egore911@egore911.de> and others
+ * Copyright (C) 2011, 2022 Christoph Brill <egore911@egore911.de> and others
  *
  * This program and the accompanying materials are made available under the
  * terms of the Eclipse Distribution License v. 1.0 which is available at
@@ -9,6 +9,7 @@
  */
 package org.eclipse.jgit.api;
 
+import java.io.IOException;
 import java.net.URISyntaxException;
 import java.text.MessageFormat;
 import java.util.ArrayList;
@@ -20,8 +21,8 @@
 import org.eclipse.jgit.api.errors.GitAPIException;
 import org.eclipse.jgit.api.errors.InvalidRemoteException;
 import org.eclipse.jgit.api.errors.JGitInternalException;
+import org.eclipse.jgit.errors.ConfigInvalidException;
 import org.eclipse.jgit.errors.NotSupportedException;
-import org.eclipse.jgit.errors.TransportException;
 import org.eclipse.jgit.internal.JGitText;
 import org.eclipse.jgit.lib.Constants;
 import org.eclipse.jgit.lib.Ref;
@@ -30,6 +31,8 @@
 import org.eclipse.jgit.transport.RefSpec;
 import org.eclipse.jgit.transport.Transport;
 import org.eclipse.jgit.transport.URIish;
+import org.eclipse.jgit.transport.UrlConfig;
+import org.eclipse.jgit.util.SystemReader;
 
 /**
  * The ls-remote command
@@ -153,7 +156,7 @@
 
 		try (Transport transport = repo != null
 				? Transport.open(repo, remote)
-				: Transport.open(new URIish(remote))) {
+				: Transport.open(new URIish(translate(remote)))) {
 			transport.setOptionUploadPack(uploadPack);
 			configure(transport);
 			Collection<RefSpec> refSpecs = new ArrayList<>(1);
@@ -185,11 +188,16 @@
 			throw new JGitInternalException(
 					JGitText.get().exceptionCaughtDuringExecutionOfLsRemoteCommand,
 					e);
-		} catch (TransportException e) {
+		} catch (IOException | ConfigInvalidException e) {
 			throw new org.eclipse.jgit.api.errors.TransportException(
-					e.getMessage(),
-					e);
+					e.getMessage(), e);
 		}
 	}
 
+	private String translate(String uri)
+			throws IOException, ConfigInvalidException {
+		UrlConfig urls = new UrlConfig(
+				SystemReader.getInstance().getUserConfig());
+		return urls.replace(uri);
+	}
 }
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/api/MergeCommand.java b/org.eclipse.jgit/src/org/eclipse/jgit/api/MergeCommand.java
index ce068b6..ed4a534 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/api/MergeCommand.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/api/MergeCommand.java
@@ -34,6 +34,7 @@
 import org.eclipse.jgit.events.WorkingTreeModifiedEvent;
 import org.eclipse.jgit.internal.JGitText;
 import org.eclipse.jgit.lib.AnyObjectId;
+import org.eclipse.jgit.lib.CommitConfig;
 import org.eclipse.jgit.lib.Config.ConfigEnum;
 import org.eclipse.jgit.lib.Constants;
 import org.eclipse.jgit.lib.NullProgressMonitor;
@@ -404,8 +405,11 @@
 							MergeStatus.FAILED, mergeStrategy, lowLevelResults,
 							failingPaths, null);
 				}
+				CommitConfig cfg = repo.getConfig().get(CommitConfig.KEY);
+				char commentChar = cfg.getCommentChar(message);
 				String mergeMessageWithConflicts = new MergeMessageFormatter()
-						.formatWithConflicts(mergeMessage, unmergedPaths, '#');
+						.formatWithConflicts(mergeMessage, unmergedPaths,
+								commentChar);
 				repo.writeMergeCommitMsg(mergeMessageWithConflicts);
 				return new MergeResult(null, merger.getBaseCommitId(),
 						new ObjectId[] { headCommit.getId(),
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 2b0d8ce..4e0d9d7 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/api/RebaseCommand.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/api/RebaseCommand.java
@@ -449,7 +449,8 @@
 			String oldMessage = commitToPick.getFullMessage();
 			CleanupMode mode = commitConfig.resolve(CleanupMode.DEFAULT, true);
 			boolean[] doChangeId = { false };
-			String newMessage = editCommitMessage(doChangeId, oldMessage, mode);
+			String newMessage = editCommitMessage(doChangeId, oldMessage, mode,
+					commitConfig.getCommentChar(oldMessage));
 			try (Git git = new Git(repo)) {
 				newHead = git.commit()
 						.setMessage(newMessage)
@@ -494,12 +495,12 @@
 	}
 
 	private String editCommitMessage(boolean[] doChangeId, String message,
-			@NonNull CleanupMode mode) {
+			@NonNull CleanupMode mode, char commentChar) {
 		String newMessage;
 		CommitConfig.CleanupMode cleanup;
 		if (interactiveHandler instanceof InteractiveHandler2) {
 			InteractiveHandler2.ModifyResult modification = ((InteractiveHandler2) interactiveHandler)
-					.editCommitMessage(message, mode, '#');
+					.editCommitMessage(message, mode, commentChar);
 			newMessage = modification.getMessage();
 			cleanup = modification.getCleanupMode();
 			if (CleanupMode.DEFAULT.equals(cleanup)) {
@@ -511,7 +512,7 @@
 			cleanup = CommitConfig.CleanupMode.STRIP;
 			doChangeId[0] = false;
 		}
-		return CommitConfig.cleanText(newMessage, cleanup, '#');
+		return CommitConfig.cleanText(newMessage, cleanup, commentChar);
 	}
 
 	private RebaseResult cherryPickCommit(RevCommit commitToPick)
@@ -808,8 +809,9 @@
 			if (isLast) {
 				boolean[] doChangeId = { false };
 				if (sequenceContainsSquash) {
+					char commentChar = commitMessage.charAt(0);
 					commitMessage = editCommitMessage(doChangeId, commitMessage,
-							CleanupMode.STRIP);
+							CleanupMode.STRIP, commentChar);
 				}
 				retNewHead = git.commit()
 						.setMessage(commitMessage)
@@ -829,30 +831,60 @@
 	}
 
 	@SuppressWarnings("nls")
-	private static String composeSquashMessage(boolean isSquash,
+	private String composeSquashMessage(boolean isSquash,
 			RevCommit commitToPick, String currSquashMessage, int count) {
 		StringBuilder sb = new StringBuilder();
 		String ordinal = getOrdinal(count);
-		sb.setLength(0);
-		sb.append("# This is a combination of ").append(count)
-				.append(" commits.\n");
-		// Add the previous message without header (i.e first line)
-		sb.append(currSquashMessage
-				.substring(currSquashMessage.indexOf('\n') + 1));
-		sb.append("\n");
-		if (isSquash) {
-			sb.append("# This is the ").append(count).append(ordinal)
-					.append(" commit message:\n");
-			sb.append(commitToPick.getFullMessage());
+		// currSquashMessage is always non-empty here, and the first character
+		// is the comment character used so far.
+		char commentChar = currSquashMessage.charAt(0);
+		String newMessage = commitToPick.getFullMessage();
+		if (!isSquash) {
+			sb.append(commentChar).append(" This is a combination of ")
+					.append(count).append(" commits.\n");
+			// Add the previous message without header (i.e first line)
+			sb.append(currSquashMessage
+					.substring(currSquashMessage.indexOf('\n') + 1));
+			sb.append('\n');
+			sb.append(commentChar).append(" The ").append(count).append(ordinal)
+					.append(" commit message will be skipped:\n")
+					.append(commentChar).append(' ');
+			sb.append(newMessage.replaceAll("([\n\r])",
+					"$1" + commentChar + ' '));
 		} else {
-			sb.append("# The ").append(count).append(ordinal)
-					.append(" commit message will be skipped:\n# ");
-			sb.append(commitToPick.getFullMessage().replaceAll("([\n\r])",
-					"$1# "));
+			String currentMessage = currSquashMessage;
+			if (commitConfig.isAutoCommentChar()) {
+				// Figure out a new comment character taking into account the
+				// new message
+				String cleaned = CommitConfig.cleanText(currentMessage,
+						CommitConfig.CleanupMode.STRIP, commentChar) + '\n'
+						+ newMessage;
+				char newCommentChar = commitConfig.getCommentChar(cleaned);
+				if (newCommentChar != commentChar) {
+					currentMessage = replaceCommentChar(currentMessage,
+							commentChar, newCommentChar);
+					commentChar = newCommentChar;
+				}
+			}
+			sb.append(commentChar).append(" This is a combination of ")
+					.append(count).append(" commits.\n");
+			// Add the previous message without header (i.e first line)
+			sb.append(
+					currentMessage.substring(currentMessage.indexOf('\n') + 1));
+			sb.append('\n');
+			sb.append(commentChar).append(" This is the ").append(count)
+					.append(ordinal).append(" commit message:\n");
+			sb.append(newMessage);
 		}
 		return sb.toString();
 	}
 
+	private String replaceCommentChar(String message, char oldChar,
+			char newChar) {
+		// (?m) - Switch on multi-line matching; \h - horizontal whitespace
+		return message.replaceAll("(?m)^(\\h*)" + oldChar, "$1" + newChar); //$NON-NLS-1$ //$NON-NLS-2$
+	}
+
 	private static String getOrdinal(int count) {
 		switch (count % 10) {
 		case 1:
@@ -886,10 +918,11 @@
 
 	private void initializeSquashFixupFile(String messageFile,
 			String fullMessage) throws IOException {
-		rebaseState
-				.createFile(
-						messageFile,
-						"# This is a combination of 1 commits.\n# The first commit's message is:\n" + fullMessage); //$NON-NLS-1$);
+		char commentChar = commitConfig.getCommentChar(fullMessage);
+		rebaseState.createFile(messageFile,
+				commentChar + " This is a combination of 1 commits.\n" //$NON-NLS-1$
+						+ commentChar + " The first commit's message is:\n" //$NON-NLS-1$
+						+ fullMessage);
 	}
 
 	private String getOurCommitName() {
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/api/RevertCommand.java b/org.eclipse.jgit/src/org/eclipse/jgit/api/RevertCommand.java
index db88ad8..513f579 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/api/RevertCommand.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/api/RevertCommand.java
@@ -30,6 +30,7 @@
 import org.eclipse.jgit.events.WorkingTreeModifiedEvent;
 import org.eclipse.jgit.internal.JGitText;
 import org.eclipse.jgit.lib.AnyObjectId;
+import org.eclipse.jgit.lib.CommitConfig;
 import org.eclipse.jgit.lib.Constants;
 import org.eclipse.jgit.lib.NullProgressMonitor;
 import org.eclipse.jgit.lib.ObjectId;
@@ -185,9 +186,12 @@
 								MergeStatus.CONFLICTING, strategy,
 								merger.getMergeResults(), failingPaths, null);
 					if (!merger.failed() && !unmergedPaths.isEmpty()) {
+						CommitConfig config = repo.getConfig()
+								.get(CommitConfig.KEY);
+						char commentChar = config.getCommentChar(newMessage);
 						String message = new MergeMessageFormatter()
 								.formatWithConflicts(newMessage,
-										merger.getUnmergedPaths(), '#');
+										merger.getUnmergedPaths(), commentChar);
 						repo.writeRevertHead(srcCommit.getId());
 						repo.writeMergeCommitMsg(message);
 					}
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 3d50a82..f6fc393 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/dircache/DirCacheCheckout.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/dircache/DirCacheCheckout.java
@@ -26,9 +26,9 @@
 import java.text.MessageFormat;
 import java.time.Instant;
 import java.util.ArrayList;
-import java.util.HashMap;
 import java.util.HashSet;
 import java.util.Iterator;
+import java.util.LinkedHashMap;
 import java.util.List;
 import java.util.Map;
 import java.util.Set;
@@ -113,7 +113,7 @@
 
 	private Repository repo;
 
-	private HashMap<String, CheckoutMetadata> updated = new HashMap<>();
+	private Map<String, CheckoutMetadata> updated = new LinkedHashMap<>();
 
 	private ArrayList<String> conflicts = new ArrayList<>();
 
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 535c6b9..43dbc37 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/hooks/PrePushHook.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/hooks/PrePushHook.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2015 Obeo. and others
+ * Copyright (C) 2015, 2022 Obeo 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
@@ -38,6 +38,8 @@
 
 	private String refs;
 
+	private boolean dryRun;
+
 	/**
 	 * Constructor for PrePushHook
 	 * <p>
@@ -145,6 +147,27 @@
 	}
 
 	/**
+	 * Sets whether the push is a dry run.
+	 *
+	 * @param dryRun
+	 *            {@code true} if the push is a dry run, {@code false} otherwise
+	 * @since 6.2
+	 */
+	public void setDryRun(boolean dryRun) {
+		this.dryRun = dryRun;
+	}
+
+	/**
+	 * Tells whether the push is a dry run.
+	 *
+	 * @return {@code true} if the push is a dry run, {@code false} otherwise
+	 * @since 6.2
+	 */
+	protected boolean isDryRun() {
+		return dryRun;
+	}
+
+	/**
 	 * Set Refs
 	 *
 	 * @param toRefs
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 16b3f37..b81e605 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/internal/JGitText.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/internal/JGitText.java
@@ -421,6 +421,7 @@
 	/***/ public String invalidModeFor;
 	/***/ public String invalidModeForPath;
 	/***/ public String invalidNameContainsDotDot;
+	/***/ public String invalidNegativeAndForce;
 	/***/ public String invalidObject;
 	/***/ public String invalidOldIdSent;
 	/***/ public String invalidPacketLineHeader;
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 07e3814..4aa2edf 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
@@ -28,7 +28,6 @@
 import java.io.BufferedReader;
 import java.io.File;
 import java.io.FileInputStream;
-import java.io.FileNotFoundException;
 import java.io.IOException;
 import java.io.InputStreamReader;
 import java.io.InterruptedIOException;
@@ -892,38 +891,27 @@
 	}
 
 	private PackedRefList readPackedRefs() throws IOException {
-		int maxStaleRetries = 5;
-		int retries = 0;
-		while (true) {
-			final FileSnapshot snapshot = FileSnapshot.save(packedRefsFile);
-			final MessageDigest digest = Constants.newMessageDigest();
-			try (BufferedReader br = new BufferedReader(new InputStreamReader(
-					new DigestInputStream(new FileInputStream(packedRefsFile),
-							digest),
-					UTF_8))) {
-				try {
-					return new PackedRefList(parsePackedRefs(br), snapshot,
-							ObjectId.fromRaw(digest.digest()));
-				} catch (IOException e) {
-					if (FileUtils.isStaleFileHandleInCausalChain(e)
-							&& retries < maxStaleRetries) {
-						if (LOG.isDebugEnabled()) {
-							LOG.debug(MessageFormat.format(
-									JGitText.get().packedRefsHandleIsStale,
-									Integer.valueOf(retries)), e);
+		try {
+			PackedRefList result = FileUtils.readWithRetries(packedRefsFile,
+					f -> {
+						FileSnapshot snapshot = FileSnapshot.save(f);
+						MessageDigest digest = Constants.newMessageDigest();
+						try (BufferedReader br = new BufferedReader(
+								new InputStreamReader(
+										new DigestInputStream(
+												new FileInputStream(f), digest),
+										UTF_8))) {
+							return new PackedRefList(parsePackedRefs(br),
+									snapshot,
+									ObjectId.fromRaw(digest.digest()));
 						}
-						retries++;
-						continue;
-					}
-					throw e;
-				}
-			} catch (FileNotFoundException noPackedRefs) {
-				if (packedRefsFile.exists()) {
-					throw noPackedRefs;
-				}
-				// Ignore it and leave the new list empty.
-				return NO_PACKED_REFS;
-			}
+					});
+			return result != null ? result : NO_PACKED_REFS;
+		} catch (IOException e) {
+			throw e;
+		} catch (Exception e) {
+			throw new IOException(MessageFormat
+					.format(JGitText.get().cannotReadFile, packedRefsFile), e);
 		}
 	}
 
@@ -1090,40 +1078,55 @@
 		}
 
 		final int limit = 4096;
-		final byte[] buf;
-		FileSnapshot otherSnapshot = FileSnapshot.save(path);
-		try {
-			buf = IO.readSome(path, limit);
-		} catch (FileNotFoundException noFile) {
-			if (path.isFile()) {
-				throw noFile;
-			}
-			return null; // doesn't exist or no file; not a reference.
-		}
 
-		int n = buf.length;
+		class LooseItems {
+			final FileSnapshot snapshot;
+
+			final byte[] buf;
+
+			LooseItems(FileSnapshot snapshot, byte[] buf) {
+				this.snapshot = snapshot;
+				this.buf = buf;
+			}
+		}
+		LooseItems loose = null;
+		try {
+			loose = FileUtils.readWithRetries(path,
+					f -> new LooseItems(FileSnapshot.save(f),
+							IO.readSome(f, limit)));
+		} catch (IOException e) {
+			throw e;
+		} catch (Exception e) {
+			throw new IOException(
+					MessageFormat.format(JGitText.get().cannotReadFile, path),
+					e);
+		}
+		if (loose == null) {
+			return null;
+		}
+		int n = loose.buf.length;
 		if (n == 0)
 			return null; // empty file; not a reference.
 
-		if (isSymRef(buf, n)) {
+		if (isSymRef(loose.buf, n)) {
 			if (n == limit)
 				return null; // possibly truncated ref
 
 			// trim trailing whitespace
-			while (0 < n && Character.isWhitespace(buf[n - 1]))
+			while (0 < n && Character.isWhitespace(loose.buf[n - 1]))
 				n--;
 			if (n < 6) {
-				String content = RawParseUtils.decode(buf, 0, n);
+				String content = RawParseUtils.decode(loose.buf, 0, n);
 				throw new IOException(MessageFormat.format(JGitText.get().notARef, name, content));
 			}
-			final String target = RawParseUtils.decode(buf, 5, n);
+			final String target = RawParseUtils.decode(loose.buf, 5, n);
 			if (ref != null && ref.isSymbolic()
 					&& ref.getTarget().getName().equals(target)) {
 				assert(currentSnapshot != null);
-				currentSnapshot.setClean(otherSnapshot);
+				currentSnapshot.setClean(loose.snapshot);
 				return ref;
 			}
-			return newSymbolicRef(otherSnapshot, name, target);
+			return newSymbolicRef(loose.snapshot, name, target);
 		}
 
 		if (n < OBJECT_ID_STRING_LENGTH)
@@ -1131,23 +1134,23 @@
 
 		final ObjectId id;
 		try {
-			id = ObjectId.fromString(buf, 0);
+			id = ObjectId.fromString(loose.buf, 0);
 			if (ref != null && !ref.isSymbolic()
 					&& id.equals(ref.getTarget().getObjectId())) {
 				assert(currentSnapshot != null);
-				currentSnapshot.setClean(otherSnapshot);
+				currentSnapshot.setClean(loose.snapshot);
 				return ref;
 			}
 
 		} catch (IllegalArgumentException notRef) {
-			while (0 < n && Character.isWhitespace(buf[n - 1]))
+			while (0 < n && Character.isWhitespace(loose.buf[n - 1]))
 				n--;
-			String content = RawParseUtils.decode(buf, 0, n);
+			String content = RawParseUtils.decode(loose.buf, 0, n);
 
 			throw new IOException(MessageFormat.format(JGitText.get().notARef,
 					name, content), notRef);
 		}
-		return new LooseUnpeeled(otherSnapshot, name, id);
+		return new LooseUnpeeled(loose.snapshot, name, id);
 	}
 
 	private static boolean isSymRef(byte[] buf, int n) {
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/pack/BaseSearch.java b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/pack/BaseSearch.java
index 1c24aff..cda456c 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/pack/BaseSearch.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/pack/BaseSearch.java
@@ -142,6 +142,7 @@
 		return ptr;
 	}
 
+	@SuppressWarnings("ReferenceEquality")
 	private void add(AnyObjectId id, int objectType, int pathHash) {
 		ObjectToPack obj = new ObjectToPack(id, objectType);
 		obj.setEdge();
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/lib/CommitConfig.java b/org.eclipse.jgit/src/org/eclipse/jgit/lib/CommitConfig.java
index 55cc026..6a9b45b 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/lib/CommitConfig.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/lib/CommitConfig.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2020 Julian Ruppel <julian.ruppel@sap.com>
+ * Copyright (c) 2020, 2022 Julian Ruppel <julian.ruppel@sap.com> and others
  *
  * This program and the accompanying materials are made available under the
  * terms of the Eclipse Distribution License v. 1.0 which is available at
@@ -29,6 +29,7 @@
 import org.eclipse.jgit.util.FS;
 import org.eclipse.jgit.util.IO;
 import org.eclipse.jgit.util.RawParseUtils;
+import org.eclipse.jgit.util.StringUtils;
 
 /**
  * The standard "commit" configuration parameters.
@@ -44,6 +45,9 @@
 
 	private static final String CUT = " ------------------------ >8 ------------------------\n"; //$NON-NLS-1$
 
+	private static final char[] COMMENT_CHARS = { '#', ';', '@', '!', '$', '%',
+			'^', '&', '|', ':' };
+
 	/**
 	 * How to clean up commit messages when committing.
 	 *
@@ -99,6 +103,10 @@
 
 	private CleanupMode cleanupMode;
 
+	private char commentCharacter = '#';
+
+	private boolean autoCommentChar = false;
+
 	private CommitConfig(Config rc) {
 		commitTemplatePath = rc.getString(ConfigConstants.CONFIG_COMMIT_SECTION,
 				null, ConfigConstants.CONFIG_KEY_COMMIT_TEMPLATE);
@@ -106,6 +114,18 @@
 				null, ConfigConstants.CONFIG_KEY_COMMIT_ENCODING);
 		cleanupMode = rc.getEnum(ConfigConstants.CONFIG_COMMIT_SECTION, null,
 				ConfigConstants.CONFIG_KEY_CLEANUP, CleanupMode.DEFAULT);
+		String comment = rc.getString(ConfigConstants.CONFIG_CORE_SECTION, null,
+				ConfigConstants.CONFIG_KEY_COMMENT_CHAR);
+		if (!StringUtils.isEmptyOrNull(comment)) {
+			if ("auto".equalsIgnoreCase(comment)) { //$NON-NLS-1$
+				autoCommentChar = true;
+			} else {
+				char first = comment.charAt(0);
+				if (first > ' ' && first < 127) {
+					commentCharacter = first;
+				}
+			}
+		}
 	}
 
 	/**
@@ -131,6 +151,51 @@
 	}
 
 	/**
+	 * Retrieves the comment character set by git config
+	 * {@code core.commentChar}.
+	 *
+	 * @return the character to use for comments in commit messages
+	 * @since 6.2
+	 */
+	public char getCommentChar() {
+		return commentCharacter;
+	}
+
+	/**
+	 * Determines the comment character to use for a particular text. If
+	 * {@code core.commentChar} is "auto", tries to determine an unused
+	 * character; if none is found, falls back to '#'. Otherwise returns the
+	 * character given by {@code core.commentChar}.
+	 *
+	 * @param text
+	 *            existing text
+	 *
+	 * @return the character to use
+	 * @since 6.2
+	 */
+	public char getCommentChar(String text) {
+		if (isAutoCommentChar()) {
+			char toUse = determineCommentChar(text);
+			if (toUse > 0) {
+				return toUse;
+			}
+			return '#';
+		}
+		return getCommentChar();
+	}
+
+	/**
+	 * Tells whether the comment character should be determined by choosing a
+	 * character not occurring in a commit message.
+	 *
+	 * @return {@code true} if git config {@code core.commentChar} is "auto"
+	 * @since 6.2
+	 */
+	public boolean isAutoCommentChar() {
+		return autoCommentChar;
+	}
+
+	/**
 	 * Retrieves the {@link CleanupMode} as given by git config
 	 * {@code commit.cleanup}.
 	 *
@@ -315,4 +380,41 @@
 		}
 		return false;
 	}
+
+	/**
+	 * Determines a comment character by choosing one from a limited set of
+	 * 7-bit ASCII characters that do not occur in the given text at the
+	 * beginning of any line. If none can be determined, {@code (char) 0} is
+	 * returned.
+	 *
+	 * @param text
+	 *            to get a comment character for
+	 * @return the comment character, or {@code (char) 0} if none could be
+	 *         determined
+	 * @since 6.2
+	 */
+	public static char determineCommentChar(String text) {
+		if (StringUtils.isEmptyOrNull(text)) {
+			return '#';
+		}
+		final boolean[] inUse = new boolean[127];
+		for (String line : text.split("\n")) { //$NON-NLS-1$
+			int len = line.length();
+			for (int i = 0; i < len; i++) {
+				char ch = line.charAt(i);
+				if (!Character.isWhitespace(ch)) {
+					if (ch >= 0 && ch < inUse.length) {
+						inUse[ch] = true;
+					}
+					break;
+				}
+			}
+		}
+		for (char candidate : COMMENT_CHARS) {
+			if (!inUse[candidate]) {
+				return candidate;
+			}
+		}
+		return (char) 0;
+	}
 }
\ No newline at end of file
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 80d720a..8ad32d4 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/lib/ConfigConstants.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/lib/ConfigConstants.java
@@ -2,7 +2,7 @@
  * Copyright (C) 2010, Mathias Kinzler <mathias.kinzler@sap.com>
  * Copyright (C) 2010, Chris Aniszczyk <caniszczyk@gmail.com>
  * Copyright (C) 2012-2013, Robin Rosenberg
- * Copyright (C) 2018-2021, Andre Bossert <andre.bossert@siemens.com> and others
+ * Copyright (C) 2018-2022, Andre Bossert <andre.bossert@siemens.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
@@ -203,6 +203,13 @@
 	public static final String CONFIG_KEY_FORCE_SIGN_ANNOTATED = "forceSignAnnotated";
 
 	/**
+	 * The "commentChar" key.
+	 *
+	 * @since 6.2
+	 */
+	public static final String CONFIG_KEY_COMMENT_CHAR = "commentChar";
+
+	/**
 	 * The "hooksPath" key.
 	 *
 	 * @since 5.6
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/lib/GpgSignatureVerifierFactory.java b/org.eclipse.jgit/src/org/eclipse/jgit/lib/GpgSignatureVerifierFactory.java
index 4b1dbed..59775c4 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/lib/GpgSignatureVerifierFactory.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/lib/GpgSignatureVerifierFactory.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2021, Thomas Wolf <thomas.wolf@paranor.ch> and others
+ * Copyright (C) 2021, 2022 Thomas Wolf <thomas.wolf@paranor.ch> and others
  *
  * This program and the accompanying materials are made available under the
  * terms of the Eclipse Distribution License v. 1.0 which is available at
@@ -26,20 +26,41 @@
 	private static final Logger LOG = LoggerFactory
 			.getLogger(GpgSignatureVerifierFactory.class);
 
-	private static volatile GpgSignatureVerifierFactory defaultFactory = loadDefault();
+	private static class DefaultFactory {
 
-	private static GpgSignatureVerifierFactory loadDefault() {
-		try {
-			ServiceLoader<GpgSignatureVerifierFactory> loader = ServiceLoader
-					.load(GpgSignatureVerifierFactory.class);
-			Iterator<GpgSignatureVerifierFactory> iter = loader.iterator();
-			if (iter.hasNext()) {
-				return iter.next();
+		private static volatile GpgSignatureVerifierFactory defaultFactory = loadDefault();
+
+		private static GpgSignatureVerifierFactory loadDefault() {
+			try {
+				ServiceLoader<GpgSignatureVerifierFactory> loader = ServiceLoader
+						.load(GpgSignatureVerifierFactory.class);
+				Iterator<GpgSignatureVerifierFactory> iter = loader.iterator();
+				if (iter.hasNext()) {
+					return iter.next();
+				}
+			} catch (ServiceConfigurationError e) {
+				LOG.error(e.getMessage(), e);
 			}
-		} catch (ServiceConfigurationError e) {
-			LOG.error(e.getMessage(), e);
+			return null;
 		}
-		return null;
+
+		private DefaultFactory() {
+			// No instantiation
+		}
+
+		public static GpgSignatureVerifierFactory getDefault() {
+			return defaultFactory;
+		}
+
+		/**
+		 * Sets the default factory.
+		 *
+		 * @param factory
+		 *            the new default factory
+		 */
+		public static void setDefault(GpgSignatureVerifierFactory factory) {
+			defaultFactory = factory;
+		}
 	}
 
 	/**
@@ -48,7 +69,7 @@
 	 * @return the default factory or {@code null} if none set
 	 */
 	public static GpgSignatureVerifierFactory getDefault() {
-		return defaultFactory;
+		return DefaultFactory.getDefault();
 	}
 
 	/**
@@ -58,7 +79,7 @@
 	 *            the new default factory
 	 */
 	public static void setDefault(GpgSignatureVerifierFactory factory) {
-		defaultFactory = factory;
+		DefaultFactory.setDefault(factory);
 	}
 
 	/**
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/lib/GpgSigner.java b/org.eclipse.jgit/src/org/eclipse/jgit/lib/GpgSigner.java
index 5b32cf0..b25a61b 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/lib/GpgSigner.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/lib/GpgSigner.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2018, Salesforce. and others
+ * Copyright (C) 2018, 2022 Salesforce and others
  *
  * This program and the accompanying materials are made available under the
  * terms of the Eclipse Distribution License v. 1.0 which is available at
@@ -26,22 +26,38 @@
  * @since 5.3
  */
 public abstract class GpgSigner {
+
 	private static final Logger LOG = LoggerFactory.getLogger(GpgSigner.class);
 
-	private static GpgSigner defaultSigner = loadGpgSigner();
+	private static class DefaultSigner {
 
-	private static GpgSigner loadGpgSigner() {
-		try {
-			ServiceLoader<GpgSigner> loader = ServiceLoader
-					.load(GpgSigner.class);
-			Iterator<GpgSigner> iter = loader.iterator();
-			if (iter.hasNext()) {
-				return iter.next();
+		private static volatile GpgSigner defaultSigner = loadGpgSigner();
+
+		private static GpgSigner loadGpgSigner() {
+			try {
+				ServiceLoader<GpgSigner> loader = ServiceLoader
+						.load(GpgSigner.class);
+				Iterator<GpgSigner> iter = loader.iterator();
+				if (iter.hasNext()) {
+					return iter.next();
+				}
+			} catch (ServiceConfigurationError e) {
+				LOG.error(e.getMessage(), e);
 			}
-		} catch (ServiceConfigurationError e) {
-			LOG.error(e.getMessage(), e);
+			return null;
 		}
-		return null;
+
+		private DefaultSigner() {
+			// No instantiation
+		}
+
+		public static GpgSigner getDefault() {
+			return defaultSigner;
+		}
+
+		public static void setDefault(GpgSigner signer) {
+			defaultSigner = signer;
+		}
 	}
 
 	/**
@@ -50,7 +66,7 @@
 	 * @return the default signer, or <code>null</code>.
 	 */
 	public static GpgSigner getDefault() {
-		return defaultSigner;
+		return DefaultSigner.getDefault();
 	}
 
 	/**
@@ -61,7 +77,7 @@
 	 *            default.
 	 */
 	public static void setDefault(GpgSigner signer) {
-		GpgSigner.defaultSigner = signer;
+		DefaultSigner.setDefault(signer);
 	}
 
 	/**
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 94e7c53..c11fca1 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/revplot/PlotCommit.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/revplot/PlotCommit.java
@@ -138,6 +138,7 @@
 	 *            the commit to test.
 	 * @return true if the given commit built on top of this commit.
 	 */
+	@SuppressWarnings("ReferenceEquality")
 	public final boolean isChild(PlotCommit c) {
 		for (PlotCommit a : children)
 			if (a == c)
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 18ea756..458f240 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/revplot/PlotCommitList.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/revplot/PlotCommitList.java
@@ -92,6 +92,7 @@
 	}
 
 	/** {@inheritDoc} */
+	@SuppressWarnings("ReferenceEquality")
 	@Override
 	protected void enter(int index, PlotCommit<L> currCommit) {
 		setupChildren(currCommit);
@@ -188,6 +189,7 @@
 	 *            may be null if <code>currCommit</code> is the first commit on
 	 *            the lane
 	 */
+	@SuppressWarnings("ReferenceEquality")
 	private void handleBlockedLanes(final int index, final PlotCommit currCommit,
 			final PlotCommit childOnLane) {
 		for (PlotCommit child : currCommit.children) {
@@ -214,6 +216,7 @@
 	}
 
 	// Handles the case where currCommit is a non-first parent of the child
+	@SuppressWarnings("ReferenceEquality")
 	private PlotLane handleMerge(final int index, final PlotCommit currCommit,
 			final PlotCommit childOnLane, PlotCommit child, PlotLane laneToUse) {
 
@@ -287,6 +290,7 @@
 	 * @param child
 	 * @param laneToContinue
 	 */
+	@SuppressWarnings("ReferenceEquality")
 	private void drawLaneToChild(final int commitIndex, PlotCommit child,
 			PlotLane laneToContinue) {
 		for (int r = commitIndex - 1; r >= 0; r--) {
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 a928c2e..4565a4b 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/RewriteGenerator.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/RewriteGenerator.java
@@ -58,6 +58,7 @@
 		return source.outputType() & ~NEEDS_REWRITE;
 	}
 
+	@SuppressWarnings("ReferenceEquality")
 	@Override
 	RevCommit next() throws MissingObjectException,
 			IncorrectObjectTypeException, IOException {
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 7b5f00e..567e409 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
@@ -20,7 +20,6 @@
 
 import java.io.ByteArrayOutputStream;
 import java.io.File;
-import java.io.FileNotFoundException;
 import java.io.IOException;
 import java.text.MessageFormat;
 
@@ -37,15 +36,11 @@
 import org.eclipse.jgit.util.FileUtils;
 import org.eclipse.jgit.util.IO;
 import org.eclipse.jgit.util.RawParseUtils;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
 
 /**
  * The configuration file that is stored in the file of the file system.
  */
 public class FileBasedConfig extends StoredConfig {
-	private static final Logger LOG = LoggerFactory
-			.getLogger(FileBasedConfig.class);
 
 	private final File configFile;
 
@@ -115,16 +110,15 @@
 	 */
 	@Override
 	public void load() throws IOException, ConfigInvalidException {
-		final int maxRetries = 5;
-		int retryDelayMillis = 20;
-		int retries = 0;
-		while (true) {
-			final FileSnapshot oldSnapshot = snapshot;
-			final FileSnapshot newSnapshot;
-			// don't use config in this snapshot to avoid endless recursion
-			newSnapshot = FileSnapshot.saveNoConfig(getFile());
-			try {
-				final byte[] in = IO.readFully(getFile());
+		try {
+			FileSnapshot[] lastSnapshot = { null };
+			Boolean wasRead = FileUtils.readWithRetries(getFile(), f -> {
+				final FileSnapshot oldSnapshot = snapshot;
+				final FileSnapshot newSnapshot;
+				// don't use config in this snapshot to avoid endless recursion
+				newSnapshot = FileSnapshot.saveNoConfig(f);
+				lastSnapshot[0] = newSnapshot;
+				final byte[] in = IO.readFully(f);
 				final ObjectId newHash = hash(in);
 				if (hash.equals(newHash)) {
 					if (oldSnapshot.equals(newSnapshot)) {
@@ -145,47 +139,17 @@
 					snapshot = newSnapshot;
 					hash = newHash;
 				}
-				return;
-			} catch (FileNotFoundException noFile) {
-				// might be locked by another process (see exception Javadoc)
-				if (retries < maxRetries && configFile.exists()) {
-					if (LOG.isDebugEnabled()) {
-						LOG.debug(MessageFormat.format(
-								JGitText.get().configHandleMayBeLocked,
-								Integer.valueOf(retries)), noFile);
-					}
-					try {
-						Thread.sleep(retryDelayMillis);
-					} catch (InterruptedException e) {
-						Thread.currentThread().interrupt();
-					}
-					retries++;
-					retryDelayMillis *= 2; // max wait 1260 ms
-					continue;
-				}
-				if (configFile.exists()) {
-					throw noFile;
-				}
+				return Boolean.TRUE;
+			});
+			if (wasRead == null) {
 				clear();
-				snapshot = newSnapshot;
-				return;
-			} catch (IOException e) {
-				if (FileUtils.isStaleFileHandle(e)
-						&& retries < maxRetries) {
-					if (LOG.isDebugEnabled()) {
-						LOG.debug(MessageFormat.format(
-								JGitText.get().configHandleIsStale,
-								Integer.valueOf(retries)), e);
-					}
-					retries++;
-					continue;
-				}
-				throw new IOException(MessageFormat
-						.format(JGitText.get().cannotReadFile, getFile()), e);
-			} catch (ConfigInvalidException e) {
-				throw new ConfigInvalidException(MessageFormat
-						.format(JGitText.get().cannotReadFile, getFile()), e);
+				snapshot = lastSnapshot[0];
 			}
+		} catch (IOException e) {
+			throw e;
+		} catch (Exception e) {
+			throw new ConfigInvalidException(MessageFormat
+					.format(JGitText.get().cannotReadFile, getFile()), e);
 		}
 	}
 
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 f48e1e6..3f167cc 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/transport/BasePackFetchConnection.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/transport/BasePackFetchConnection.java
@@ -1,7 +1,7 @@
 /*
  * Copyright (C) 2008, 2010 Google Inc.
  * Copyright (C) 2008, Robin Rosenberg <robin.rosenberg@dewire.com>
- * Copyright (C) 2008, 2020 Shawn O. Pearce <spearce@spearce.org> and others
+ * Copyright (C) 2008, 2022 Shawn O. Pearce <spearce@spearce.org> and others
  *
  * This program and the accompanying materials are made available under the
  * terms of the Eclipse Distribution License v. 1.0 which is available at
@@ -1004,9 +1004,12 @@
 			OutputStream outputStream) throws IOException {
 		onReceivePack();
 		InputStream input = in;
-		if (sideband)
-			input = new SideBandInputStream(input, monitor, getMessageWriter(),
-					outputStream);
+		SideBandInputStream sidebandIn = null;
+		if (sideband) {
+			sidebandIn = new SideBandInputStream(input, monitor,
+					getMessageWriter(), outputStream);
+			input = sidebandIn;
+		}
 
 		try (ObjectInserter ins = local.newObjectInserter()) {
 			PackParser parser = ins.newPackParser(input);
@@ -1015,6 +1018,10 @@
 			parser.setLockMessage(lockMessage);
 			packLock = parser.parse(monitor);
 			ins.flush();
+		} finally {
+			if (sidebandIn != null) {
+				sidebandIn.drainMessages();
+			}
 		}
 	}
 
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 b87a85d..b7be59d 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/transport/BasePackPushConnection.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/transport/BasePackPushConnection.java
@@ -1,6 +1,6 @@
 /*
  * Copyright (C) 2008, Marek Zawirski <marek.zawirski@gmail.com>
- * Copyright (C) 2008, Shawn O. Pearce <spearce@spearce.org> and others
+ * Copyright (C) 2008, 2022 Shawn O. Pearce <spearce@spearce.org> and others
  *
  * This program and the accompanying materials are made available under the
  * terms of the Eclipse Distribution License v. 1.0 which is available at
@@ -194,10 +194,11 @@
 					// the other data channels.
 					//
 					int b = in.read();
-					if (0 <= b)
+					if (0 <= b) {
 						throw new TransportException(uri, MessageFormat.format(
 								JGitText.get().expectedEOFReceived,
 								Character.valueOf((char) b)));
+					}
 				}
 			}
 		} catch (TransportException e) {
@@ -205,6 +206,9 @@
 		} catch (Exception e) {
 			throw new TransportException(uri, e.getMessage(), e);
 		} finally {
+			if (in instanceof SideBandInputStream) {
+				((SideBandInputStream) in).drainMessages();
+			}
 			close();
 		}
 	}
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/transport/FetchProcess.java b/org.eclipse.jgit/src/org/eclipse/jgit/transport/FetchProcess.java
index 7d7b3ee..87e5476 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/transport/FetchProcess.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/transport/FetchProcess.java
@@ -31,6 +31,7 @@
 import java.util.Map;
 import java.util.Set;
 import java.util.concurrent.TimeUnit;
+import java.util.stream.Collectors;
 
 import org.eclipse.jgit.errors.MissingObjectException;
 import org.eclipse.jgit.errors.NotSupportedException;
@@ -56,6 +57,12 @@
 	/** List of things we want to fetch from the remote repository. */
 	private final Collection<RefSpec> toFetch;
 
+	/**
+	 * List of things we don't want to fetch from the remote repository or to
+	 * the local repository.
+	 */
+	private final Collection<RefSpec> negativeRefSpecs;
+
 	/** Set of refs we will actually wind up asking to obtain. */
 	private final HashMap<ObjectId, Ref> askFor = new HashMap<>();
 
@@ -74,9 +81,12 @@
 
 	private Map<String, Ref> localRefs;
 
-	FetchProcess(Transport t, Collection<RefSpec> f) {
+	FetchProcess(Transport t, Collection<RefSpec> refSpecs) {
 		transport = t;
-		toFetch = f;
+		toFetch = refSpecs.stream().filter(refSpec -> !refSpec.isNegative())
+				.collect(Collectors.toList());
+		negativeRefSpecs = refSpecs.stream().filter(RefSpec::isNegative)
+				.collect(Collectors.toList());
 	}
 
 	void execute(ProgressMonitor monitor, FetchResult result,
@@ -389,8 +399,13 @@
 	private void expandWildcard(RefSpec spec, Set<Ref> matched)
 			throws TransportException {
 		for (Ref src : conn.getRefs()) {
-			if (spec.matchSource(src) && matched.add(src))
-				want(src, spec.expandFromSource(src));
+			if (spec.matchSource(src)) {
+				RefSpec expandedRefSpec = spec.expandFromSource(src);
+				if (!matchNegativeRefSpec(expandedRefSpec)
+						&& matched.add(src)) {
+					want(src, expandedRefSpec);
+				}
+			}
 		}
 	}
 
@@ -406,11 +421,27 @@
 		if (src == null) {
 			throw new TransportException(MessageFormat.format(JGitText.get().remoteDoesNotHaveSpec, want));
 		}
-		if (matched.add(src)) {
+		if (!matchNegativeRefSpec(spec) && matched.add(src)) {
 			want(src, spec);
 		}
 	}
 
+	private boolean matchNegativeRefSpec(RefSpec spec) {
+		for (RefSpec negativeRefSpec : negativeRefSpecs) {
+			if (negativeRefSpec.getSource() != null && spec.getSource() != null
+					&& negativeRefSpec.matchSource(spec.getSource())) {
+				return true;
+			}
+
+			if (negativeRefSpec.getDestination() != null
+					&& spec.getDestination() != null && negativeRefSpec
+							.matchDestination(spec.getDestination())) {
+				return true;
+			}
+		}
+		return false;
+	}
+
 	private boolean localHasObject(ObjectId id) throws TransportException {
 		try {
 			return transport.local.getObjectDatabase().has(id);
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 942dad4..b59ae0c 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/transport/PushProcess.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/transport/PushProcess.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2008, Marek Zawirski <marek.zawirski@gmail.com> and others
+ * Copyright (C) 2008, 2022 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
@@ -166,6 +166,7 @@
 					if (prePush != null) {
 						try {
 							prePush.setRefs(willBeAttempted);
+							prePush.setDryRun(transport.isDryRun());
 							prePush.call();
 						} catch (AbortedByHookException | IOException e) {
 							throw new TransportException(e.getMessage(), e);
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 56d0036..e36eecc 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/transport/RefSpec.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/transport/RefSpec.java
@@ -53,6 +53,9 @@
 	/** Is this the special ":" RefSpec? */
 	private boolean matching;
 
+	/** Is this a negative refspec. */
+	private boolean negative;
+
 	/**
 	 * How strict to be about wildcards.
 	 *
@@ -96,12 +99,23 @@
 		wildcard = false;
 		srcName = Constants.HEAD;
 		dstName = null;
+		negative =false;
 		allowMismatchedWildcards = WildcardMode.REQUIRE_MATCH;
 	}
 
 	/**
 	 * Parse a ref specification for use during transport operations.
 	 * <p>
+	 * {@link RefSpec}s can be regular or negative, regular RefSpecs indicate
+	 * what to include in transport operations while negative RefSpecs indicate
+	 * what to exclude in fetch.
+	 * <p>
+	 * Negative {@link RefSpec}s can't be force, must have only source or
+	 * destination. Wildcard patterns are also supported in negative RefSpecs
+	 * but they can not go with {@code WildcardMode.REQUIRE_MATCH} because they
+	 * are natually one to many mappings.
+	 *
+	 * <p>
 	 * Specifications are typically one of the following forms:
 	 * <ul>
 	 * <li><code>refs/heads/master</code></li>
@@ -121,6 +135,12 @@
 	 * <li><code>refs/heads/*:refs/heads/master</code></li>
 	 * </ul>
 	 *
+	 * Negative specifications are usually like:
+	 * <ul>
+	 * <li><code>^:refs/heads/master</code></li>
+	 * <li><code>^refs/heads/*</code></li>
+	 * </ul>
+	 *
 	 * @param spec
 	 *            string describing the specification.
 	 * @param mode
@@ -133,11 +153,22 @@
 	public RefSpec(String spec, WildcardMode mode) {
 		this.allowMismatchedWildcards = mode;
 		String s = spec;
+
+		if (s.startsWith("^+") || s.startsWith("+^")) {
+			throw new IllegalArgumentException(
+					JGitText.get().invalidNegativeAndForce);
+		}
+
 		if (s.startsWith("+")) { //$NON-NLS-1$
 			force = true;
 			s = s.substring(1);
 		}
 
+		if(s.startsWith("^")) {
+			negative = true;
+			s = s.substring(1);
+		}
+
 		boolean matchPushSpec = false;
 		final int c = s.lastIndexOf(':');
 		if (c == 0) {
@@ -181,6 +212,21 @@
 			}
 			srcName = checkValid(s);
 		}
+
+		// Negative refspecs must only have dstName or srcName.
+		if (isNegative()) {
+			if (isNullOrEmpty(srcName) && isNullOrEmpty(dstName)) {
+				throw new IllegalArgumentException(MessageFormat
+						.format(JGitText.get().invalidRefSpec, spec));
+			}
+			if (!isNullOrEmpty(srcName) && !isNullOrEmpty(dstName)) {
+				throw new IllegalArgumentException(MessageFormat
+						.format(JGitText.get().invalidRefSpec, spec));
+			}
+			if(wildcard && mode == WildcardMode.REQUIRE_MATCH) {
+				throw new IllegalArgumentException(MessageFormat
+						.format(JGitText.get().invalidRefSpec, spec));}
+		}
 		matching = matchPushSpec;
 	}
 
@@ -205,13 +251,15 @@
 	 *             the specification is invalid.
 	 */
 	public RefSpec(String spec) {
-		this(spec, WildcardMode.REQUIRE_MATCH);
+		this(spec, spec.startsWith("^") ? WildcardMode.ALLOW_MISMATCH
+				: WildcardMode.REQUIRE_MATCH);
 	}
 
 	private RefSpec(RefSpec p) {
 		matching = false;
 		force = p.isForceUpdate();
 		wildcard = p.isWildcard();
+		negative = p.isNegative();
 		srcName = p.getSource();
 		dstName = p.getDestination();
 		allowMismatchedWildcards = p.allowMismatchedWildcards;
@@ -246,6 +294,10 @@
 	 */
 	public RefSpec setForceUpdate(boolean forceUpdate) {
 		final RefSpec r = new RefSpec(this);
+		if (forceUpdate && isNegative()) {
+			throw new IllegalArgumentException(
+					JGitText.get().invalidNegativeAndForce);
+		}
 		r.matching = matching;
 		r.force = forceUpdate;
 		return r;
@@ -265,6 +317,16 @@
 	}
 
 	/**
+	 * Check if this specification is a negative one.
+	 *
+	 * @return true if this specification is negative.
+	 * @since 6.2
+	 */
+	public boolean isNegative() {
+		return negative;
+	}
+
+	/**
 	 * Get the source ref description.
 	 * <p>
 	 * During a fetch this is the name of the ref on the remote repository we
@@ -435,6 +497,10 @@
 		return this;
 	}
 
+	private static boolean isNullOrEmpty(String refName) {
+		return refName == null || refName.isEmpty();
+	}
+
 	/**
 	 * Expand this specification to exactly match a ref.
 	 * <p>
@@ -570,6 +636,9 @@
 		if (isForceUpdate() != b.isForceUpdate()) {
 			return false;
 		}
+		if(isNegative() != b.isNegative()) {
+			return false;
+		}
 		if (isMatching()) {
 			return b.isMatching();
 		} else if (b.isMatching()) {
@@ -587,6 +656,9 @@
 		if (isForceUpdate()) {
 			r.append('+');
 		}
+		if(isNegative()) {
+			r.append('^');
+		}
 		if (isMatching()) {
 			r.append(':');
 		} else {
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/transport/RemoteConfig.java b/org.eclipse.jgit/src/org/eclipse/jgit/transport/RemoteConfig.java
index 2f3160b..c4e105e 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/transport/RemoteConfig.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/transport/RemoteConfig.java
@@ -16,10 +16,7 @@
 import java.net.URISyntaxException;
 import java.util.ArrayList;
 import java.util.Collections;
-import java.util.HashMap;
 import java.util.List;
-import java.util.Map;
-import java.util.Map.Entry;
 
 import org.eclipse.jgit.lib.Config;
 
@@ -54,10 +51,6 @@
 
 	private static final String KEY_TIMEOUT = "timeout"; //$NON-NLS-1$
 
-	private static final String KEY_INSTEADOF = "insteadof"; //$NON-NLS-1$
-
-	private static final String KEY_PUSHINSTEADOF = "pushinsteadof"; //$NON-NLS-1$
-
 	private static final boolean DEFAULT_MIRROR = false;
 
 	/** Default value for {@link #getUploadPack()} if not specified. */
@@ -135,10 +128,10 @@
 		String val;
 
 		vlst = rc.getStringList(SECTION, name, KEY_URL);
-		Map<String, String> insteadOf = getReplacements(rc, KEY_INSTEADOF);
+		UrlConfig urls = new UrlConfig(rc);
 		uris = new ArrayList<>(vlst.length);
 		for (String s : vlst) {
-			uris.add(new URIish(replaceUri(s, insteadOf)));
+			uris.add(new URIish(urls.replace(s)));
 		}
 		String[] plst = rc.getStringList(SECTION, name, KEY_PUSHURL);
 		pushURIs = new ArrayList<>(plst.length);
@@ -148,11 +141,9 @@
 		if (pushURIs.isEmpty()) {
 			// Would default to the uris. If we have pushinsteadof, we must
 			// supply rewritten push uris.
-			Map<String, String> pushInsteadOf = getReplacements(rc,
-					KEY_PUSHINSTEADOF);
-			if (!pushInsteadOf.isEmpty()) {
+			if (urls.hasPushReplacements()) {
 				for (String s : vlst) {
-					String replaced = replaceUri(s, pushInsteadOf);
+					String replaced = urls.replacePush(s);
 					if (!s.equals(replaced)) {
 						pushURIs.add(new URIish(replaced));
 					}
@@ -248,39 +239,6 @@
 		rc.unset(SECTION, getName(), key);
 	}
 
-	private Map<String, String> getReplacements(final Config config,
-			final String keyName) {
-		final Map<String, String> replacements = new HashMap<>();
-		for (String url : config.getSubsections(KEY_URL))
-			for (String insteadOf : config.getStringList(KEY_URL, url, keyName))
-				replacements.put(insteadOf, url);
-		return replacements;
-	}
-
-	private String replaceUri(final String uri,
-			final Map<String, String> replacements) {
-		if (replacements.isEmpty()) {
-			return uri;
-		}
-		Entry<String, String> match = null;
-		for (Entry<String, String> replacement : replacements.entrySet()) {
-			// Ignore current entry if not longer than previous match
-			if (match != null
-					&& match.getKey().length() > replacement.getKey()
-							.length()) {
-				continue;
-			}
-			if (!uri.startsWith(replacement.getKey())) {
-				continue;
-			}
-			match = replacement;
-		}
-		if (match != null) {
-			return match.getValue() + uri.substring(match.getKey().length());
-		}
-		return uri;
-	}
-
 	/**
 	 * Get the local name this remote configuration is recognized as.
 	 *
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 8a8d977..96c7be5 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/transport/SideBandInputStream.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/transport/SideBandInputStream.java
@@ -1,6 +1,6 @@
 /*
  * Copyright (C) 2008, Robin Rosenberg <robin.rosenberg@dewire.com>
- * Copyright (C) 2008, Shawn O. Pearce <spearce@spearce.org> and others
+ * Copyright (C) 2008, 2022 Shawn O. Pearce <spearce@spearce.org> and others
  *
  * This program and the accompanying materials are made available under the
  * terms of the Eclipse Distribution License v. 1.0 which is available at
@@ -28,6 +28,8 @@
 import org.eclipse.jgit.lib.ProgressMonitor;
 import org.eclipse.jgit.util.IO;
 import org.eclipse.jgit.util.RawParseUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 
 /**
  * Unmultiplexes the data portion of a side-band channel.
@@ -46,6 +48,10 @@
  * @since 4.11
  */
 public class SideBandInputStream extends InputStream {
+
+	private static final Logger LOG = LoggerFactory
+			.getLogger(SideBandInputStream.class);
+
 	static final int CH_DATA = 1;
 	static final int CH_PROGRESS = 2;
 	static final int CH_ERROR = 3;
@@ -210,6 +216,21 @@
 		monitor.beginTask(remote(currentTask), totalWorkUnits);
 	}
 
+	/**
+	 * Forces any buffered progress messages to be written.
+	 */
+	void drainMessages() {
+		if (!progressBuffer.isEmpty()) {
+			try {
+				progress("\n"); //$NON-NLS-1$
+			} catch (IOException e) {
+				// Just log; otherwise this IOException might hide a real
+				// TransportException
+				LOG.error(e.getMessage(), e);
+			}
+		}
+	}
+
 	private static String remote(String msg) {
 		String prefix = JGitText.get().prefixRemote;
 		StringBuilder r = new StringBuilder(prefix.length() + msg.length() + 1);
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/transport/SshSessionFactory.java b/org.eclipse.jgit/src/org/eclipse/jgit/transport/SshSessionFactory.java
index 1e98a56..a0194ea 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/transport/SshSessionFactory.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/transport/SshSessionFactory.java
@@ -1,6 +1,6 @@
 /*
  * Copyright (C) 2008, Robin Rosenberg <robin.rosenberg@dewire.com>
- * Copyright (C) 2008, 2020 Shawn O. Pearce <spearce@spearce.org> and others
+ * Copyright (C) 2008, 2022 Shawn O. Pearce <spearce@spearce.org> and others
  *
  * This program and the accompanying materials are made available under the
  * terms of the Eclipse Distribution License v. 1.0 which is available at
@@ -36,15 +36,35 @@
  */
 public abstract class SshSessionFactory {
 
-	private static volatile SshSessionFactory INSTANCE = loadSshSessionFactory();
+	private static class DefaultFactory {
 
-	private static SshSessionFactory loadSshSessionFactory() {
-		ServiceLoader<SshSessionFactory> loader = ServiceLoader.load(SshSessionFactory.class);
-		Iterator<SshSessionFactory> iter = loader.iterator();
-		if(iter.hasNext()) {
-			return iter.next();
+		private static volatile SshSessionFactory INSTANCE = loadSshSessionFactory();
+
+		private static SshSessionFactory loadSshSessionFactory() {
+			ServiceLoader<SshSessionFactory> loader = ServiceLoader
+					.load(SshSessionFactory.class);
+			Iterator<SshSessionFactory> iter = loader.iterator();
+			if (iter.hasNext()) {
+				return iter.next();
+			}
+			return null;
 		}
-		return null;
+
+		private DefaultFactory() {
+			// No instantiation
+		}
+
+		public static SshSessionFactory getInstance() {
+			return INSTANCE;
+		}
+
+		public static void setInstance(SshSessionFactory newFactory) {
+			if (newFactory != null) {
+				INSTANCE = newFactory;
+			} else {
+				INSTANCE = loadSshSessionFactory();
+			}
+		}
 	}
 
 	/**
@@ -57,7 +77,7 @@
 	 * @return factory the current factory for this JVM.
 	 */
 	public static SshSessionFactory getInstance() {
-		return INSTANCE;
+		return DefaultFactory.getInstance();
 	}
 
 	/**
@@ -68,11 +88,7 @@
 	 *            {@code null} the default factory will be restored.
 	 */
 	public static void setInstance(SshSessionFactory newFactory) {
-		if (newFactory != null) {
-			INSTANCE = newFactory;
-		} else {
-			INSTANCE = loadSshSessionFactory();
-		}
+		DefaultFactory.setInstance(newFactory);
 	}
 
 	/**
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 0eab443..3222d63 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/transport/Transport.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/transport/Transport.java
@@ -1230,7 +1230,9 @@
 	 * @param toFetch
 	 *            specification of refs to fetch locally. May be null or the
 	 *            empty collection to use the specifications from the
-	 *            RemoteConfig. Source for each RefSpec can't be null.
+	 *            RemoteConfig. May contains regular and negative 
+	 *            {@link RefSpec}s. Source for each regular RefSpec can't
+	 *            be null.
 	 * @return information describing the tracking refs updated.
 	 * @throws org.eclipse.jgit.errors.NotSupportedException
 	 *             this transport implementation does not support fetching
@@ -1264,7 +1266,9 @@
 	 * @param toFetch
 	 *            specification of refs to fetch locally. May be null or the
 	 *            empty collection to use the specifications from the
-	 *            RemoteConfig. Source for each RefSpec can't be null.
+	 *            RemoteConfig. May contains regular and negative 
+	 *            {@link RefSpec}s. Source for each regular RefSpec can't
+	 *            be null.
 	 * @param branch
 	 *            the initial branch to check out when cloning the repository.
 	 *            Can be specified as ref name (<code>refs/heads/master</code>),
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/transport/UrlConfig.java b/org.eclipse.jgit/src/org/eclipse/jgit/transport/UrlConfig.java
new file mode 100644
index 0000000..574fcf8
--- /dev/null
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/transport/UrlConfig.java
@@ -0,0 +1,120 @@
+/*
+ * Copyright (C) 2022 Thomas Wolf <thomas.wolf@paranor.ch> and others
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Distribution License v. 1.0 which is available at
+ * https://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+package org.eclipse.jgit.transport;
+
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Map.Entry;
+
+import org.eclipse.jgit.lib.Config;
+
+/**
+ * Support for URL translations via git configs {@code url.<base>.insteadOf} and
+ * {@code url.<base>.pushInsteadOf}.
+ *
+ * @since 6.2
+ */
+public class UrlConfig {
+
+	private static final String KEY_INSTEADOF = "insteadof"; //$NON-NLS-1$
+
+	private static final String KEY_PUSHINSTEADOF = "pushinsteadof"; //$NON-NLS-1$
+
+	private static final String SECTION_URL = "url"; //$NON-NLS-1$
+
+	private final Config config;
+
+	private Map<String, String> insteadOf;
+
+	private Map<String, String> pushInsteadOf;
+
+	/**
+	 * Creates a new {@link UrlConfig} instance.
+	 *
+	 * @param config
+	 *            {@link Config} to read values from
+	 */
+	public UrlConfig(Config config) {
+		this.config = config;
+	}
+
+	/**
+	 * Performs replacements as defined by git config
+	 * {@code url.<base>.insteadOf}. If there is no match, the input is returned
+	 * unchanged.
+	 *
+	 * @param url
+	 *            to substitute
+	 * @return the {@code url} with substitution applied
+	 */
+	public String replace(String url) {
+		if (insteadOf == null) {
+			insteadOf = load(KEY_INSTEADOF);
+		}
+		return replace(url, insteadOf);
+	}
+
+	/**
+	 * Tells whether there are push replacements.
+	 *
+	 * @return {@code true} if there are push replacements, {@code false}
+	 *         otherwise
+	 */
+	public boolean hasPushReplacements() {
+		if (pushInsteadOf == null) {
+			pushInsteadOf = load(KEY_PUSHINSTEADOF);
+		}
+		return !pushInsteadOf.isEmpty();
+	}
+
+	/**
+	 * Performs replacements as defined by git config
+	 * {@code url.<base>.pushInsteadOf}. If there is no match, the input is
+	 * returned unchanged.
+	 *
+	 * @param url
+	 *            to substitute
+	 * @return the {@code url} with substitution applied
+	 */
+	public String replacePush(String url) {
+		if (pushInsteadOf == null) {
+			pushInsteadOf = load(KEY_PUSHINSTEADOF);
+		}
+		return replace(url, pushInsteadOf);
+	}
+
+	private Map<String, String> load(String key) {
+		Map<String, String> replacements = new HashMap<>();
+		for (String url : config.getSubsections(SECTION_URL)) {
+			for (String prefix : config.getStringList(SECTION_URL, url, key)) {
+				replacements.put(prefix, url);
+			}
+		}
+		return replacements;
+	}
+
+	private String replace(String uri, Map<String, String> replacements) {
+		Entry<String, String> match = null;
+		for (Entry<String, String> replacement : replacements.entrySet()) {
+			// Ignore current entry if not longer than previous match
+			if (match != null && match.getKey().length() > replacement.getKey()
+					.length()) {
+				continue;
+			}
+			if (uri.startsWith(replacement.getKey())) {
+				match = replacement;
+			}
+		}
+		if (match != null) {
+			return match.getValue() + uri.substring(match.getKey().length());
+		}
+		return uri;
+	}
+}
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 b9dd9ba..f013e7e 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/util/FileUtils.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/util/FileUtils.java
@@ -17,6 +17,7 @@
 import java.io.File;
 import java.io.FileNotFoundException;
 import java.io.IOException;
+import java.io.InterruptedIOException;
 import java.nio.channels.FileChannel;
 import java.nio.file.AtomicMoveNotSupportedException;
 import java.nio.file.CopyOption;
@@ -655,6 +656,99 @@
 	}
 
 	/**
+	 * Like a {@link java.util.function.Function} but throwing an
+	 * {@link Exception}.
+	 *
+	 * @param <A>
+	 *            input type
+	 * @param <B>
+	 *            output type
+	 * @since 6.2
+	 */
+	@FunctionalInterface
+	public interface IOFunction<A, B> {
+
+		/**
+		 * Performs the function.
+		 *
+		 * @param t
+		 *            input to operate on
+		 * @return the output
+		 * @throws Exception
+		 *             if a problem occurs
+		 */
+		B apply(A t) throws Exception;
+	}
+
+	private static void backOff(long delay, IOException cause)
+			throws IOException {
+		try {
+			Thread.sleep(delay);
+		} catch (InterruptedException e) {
+			IOException interruption = new InterruptedIOException();
+			interruption.initCause(e);
+			interruption.addSuppressed(cause);
+			Thread.currentThread().interrupt(); // Re-set flag
+			throw interruption;
+		}
+	}
+
+	/**
+	 * Invokes the given {@link IOFunction}, performing a limited number of
+	 * re-tries if exceptions occur that indicate either a stale NFS file handle
+	 * or that indicate that the file may be written concurrently.
+	 *
+	 * @param <T>
+	 *            result type
+	 * @param file
+	 *            to read
+	 * @param reader
+	 *            for reading the file and creating an instance of {@code T}
+	 * @return the result of the {@code reader}, or {@code null} if the file
+	 *         does not exist
+	 * @throws Exception
+	 *             if a problem occurs
+	 * @since 6.2
+	 */
+	public static <T> T readWithRetries(File file,
+			IOFunction<File, ? extends T> reader)
+			throws Exception {
+		int maxStaleRetries = 5;
+		int retries = 0;
+		long backoff = 50;
+		while (true) {
+			try {
+				try {
+					return reader.apply(file);
+				} catch (IOException e) {
+					if (FileUtils.isStaleFileHandleInCausalChain(e)
+							&& retries < maxStaleRetries) {
+						if (LOG.isDebugEnabled()) {
+							LOG.debug(MessageFormat.format(
+									JGitText.get().packedRefsHandleIsStale,
+									Integer.valueOf(retries)), e);
+						}
+						retries++;
+						continue;
+					}
+					throw e;
+				}
+			} catch (FileNotFoundException noFile) {
+				if (!file.isFile()) {
+					return null;
+				}
+				// Probably Windows and some other thread is writing the file
+				// concurrently.
+				if (backoff > 1000) {
+					throw noFile;
+				}
+				backOff(backoff, noFile);
+				backoff *= 2; // 50, 100, 200, 400, 800 ms
+			}
+		}
+	}
+
+	/**
 	 * @param file
 	 * @return {@code true} if the passed file is a symbolic link
 	 */
diff --git a/pom.xml b/pom.xml
index 81093c0..53afbbe 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.1.1-SNAPSHOT</version>
+  <version>6.2.0-SNAPSHOT</version>
 
   <name>JGit - Parent</name>
   <url>${jgit-url}</url>
@@ -150,11 +150,11 @@
     <java.version>11</java.version>
     <bundle-manifest>${project.build.directory}/META-INF/MANIFEST.MF</bundle-manifest>
 
-    <jgit-last-release-version>6.0.0.202111291000-r</jgit-last-release-version>
+    <jgit-last-release-version>6.1.0.202203080745-r</jgit-last-release-version>
     <ant-version>1.10.12</ant-version>
     <apache-sshd-version>2.8.0</apache-sshd-version>
     <jsch-version>0.1.55</jsch-version>
-    <jzlib-version>1.1.1</jzlib-version>
+    <jzlib-version>1.1.3</jzlib-version>
     <javaewah-version>1.1.13</javaewah-version>
     <junit-version>4.13.2</junit-version>
     <test-fork-count>1C</test-fork-count>
@@ -168,7 +168,7 @@
     <httpcore-version>4.4.14</httpcore-version>
     <slf4j-version>1.7.30</slf4j-version>
     <maven-javadoc-plugin-version>3.3.1</maven-javadoc-plugin-version>
-    <tycho-extras-version>2.5.0</tycho-extras-version>
+    <tycho-extras-version>2.6.0</tycho-extras-version>
     <gson-version>2.8.9</gson-version>
     <bouncycastle-version>1.70</bouncycastle-version>
     <spotbugs-maven-plugin-version>4.3.0</spotbugs-maven-plugin-version>