Merge branch 'stable-7.2' into stable-7.3

* stable-7.2:
  Shortcut PackWriter reuse selection when possible
  Don't use Yoda style conditions to improve readability

Change-Id: I58a1b25260d883b92ea768dc36da0cf3db07e310
diff --git a/.bazelrc b/.bazelrc
index 70322dd..0006880 100644
--- a/.bazelrc
+++ b/.bazelrc
@@ -1,7 +1,3 @@
-# TODO(davido): Migrate all dependencies from WORKSPACE to MODULE.bazel
-# https://issues.gerritcodereview.com/issues/303819949
-common --noenable_bzlmod
-
 build --workspace_status_command="python3 ./tools/workspace_status.py"
 build --repository_cache=~/.gerritcodereview/bazel-cache/repository
 build --incompatible_strict_action_env
diff --git a/.bazelversion b/.bazelversion
index 21c8c7b..2b0aa21 100644
--- a/.bazelversion
+++ b/.bazelversion
@@ -1 +1 @@
-7.1.1
+8.2.1
diff --git a/MODULE.bazel b/MODULE.bazel
index 0b932b8..dc2bfbc 100644
--- a/MODULE.bazel
+++ b/MODULE.bazel
@@ -1,2 +1,101 @@
-# TODO(davido): Migrate all dependencies from WORKSPACE to MODULE.bazel
-# https://issues.gerritcodereview.com/issues/303819949
+module(name = "jgit")
+
+bazel_dep(name = "rules_java", version = "8.11.0")
+bazel_dep(name = "rules_jvm_external", version = "6.7")
+
+register_toolchains("//tools:error_prone_warnings_toolchain_java17_definition")
+
+register_toolchains("//tools:error_prone_warnings_toolchain_java21_definition")
+
+git_repository = use_repo_rule("@bazel_tools//tools/build_defs/repo:git.bzl", "git_repository")
+
+git_repository(
+    name = "com_googlesource_gerrit_bazlets",
+    commit = "f9c119e45d9a241bee720b7fbd6c7fdbc952da5f",
+    remote = "https://gerrit.googlesource.com/bazlets",
+)
+
+http_archive = use_repo_rule("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive")
+
+http_archive(
+    name = "ubuntu2204_jdk17",
+    sha256 = "8ea82b81c9707e535ff93ef5349d11e55b2a23c62bcc3b0faaec052144aed87d",
+    strip_prefix = "rbe_autoconfig-5.1.0",
+    urls = [
+        "https://gerrit-bazel.storage.googleapis.com/rbe_autoconfig/v5.1.0.tar.gz",
+        "https://github.com/davido/rbe_autoconfig/releases/download/v5.1.0/v5.1.0.tar.gz",
+    ],
+)
+
+BOUNCYCASTLE_VERSION = "1.80"
+
+BYTE_BUDDY_VERSION = "1.17.5"
+
+JETTY_VERSION = "12.0.21"
+
+JMH_VERSION = "1.37"
+
+JNA_VERSION = "5.17.0"
+
+SLF4J_VERSION = "1.7.36"
+
+SSHD_VERSION = "2.15.0"
+
+maven = use_extension("@rules_jvm_external//:extensions.bzl", "maven")
+maven.install(
+    name = "jgit_deps",
+    artifacts = [
+        "args4j:args4j:2.37",
+        "com.google.code.gson:gson:2.13.1",
+        "com.google.errorprone:error_prone_type_annotations:2.38.0",
+        "com.googlecode.javaewah:JavaEWAH:1.2.3",
+        "com.jcraft:jsch:0.1.55",
+        "com.jcraft:jzlib:1.1.3",
+        "commons-codec:commons-codec:1.18.0",
+        "commons-io:commons-io:2.19.0",
+        "commons-logging:commons-logging:1.3.5",
+        "jakarta.servlet:jakarta.servlet-api:6.1.0",
+        "junit:junit:4.13.2",
+        "net.bytebuddy:byte-buddy-agent:" + BYTE_BUDDY_VERSION,
+        "net.bytebuddy:byte-buddy:" + BYTE_BUDDY_VERSION,
+        "net.java.dev.jna:jna-platform:" + JNA_VERSION,
+        "net.java.dev.jna:jna:" + JNA_VERSION,
+        "net.sf.jopt-simple:jopt-simple:5.0.4",
+        "org.apache.commons:commons-compress:1.27.1",
+        "org.apache.commons:commons-lang3:3.17.0",
+        "org.apache.commons:commons-math3:3.6.1",
+        "org.apache.httpcomponents:httpclient:4.5.14",
+        "org.apache.httpcomponents:httpcore:4.4.16",
+        "org.apache.sshd:sshd-osgi:" + SSHD_VERSION,
+        "org.apache.sshd:sshd-sftp:" + SSHD_VERSION,
+        "org.assertj:assertj-core:3.27.3",
+        "org.bouncycastle:bcpg-jdk18on:" + BOUNCYCASTLE_VERSION,
+        "org.bouncycastle:bcpkix-jdk18on:" + BOUNCYCASTLE_VERSION,
+        "org.bouncycastle:bcprov-jdk18on:" + BOUNCYCASTLE_VERSION,
+        "org.bouncycastle:bcutil-jdk18on:" + BOUNCYCASTLE_VERSION,
+        "org.eclipse.jetty.ee10:jetty-ee10-servlet:" + JETTY_VERSION,
+        "org.eclipse.jetty:jetty-http:" + JETTY_VERSION,
+        "org.eclipse.jetty:jetty-io:" + JETTY_VERSION,
+        "org.eclipse.jetty:jetty-security:" + JETTY_VERSION,
+        "org.eclipse.jetty:jetty-server:" + JETTY_VERSION,
+        "org.eclipse.jetty:jetty-session:" + JETTY_VERSION,
+        "org.eclipse.jetty:jetty-util-ajax:" + JETTY_VERSION,
+        "org.eclipse.jetty:jetty-util:" + JETTY_VERSION,
+        "org.hamcrest:hamcrest:2.2",
+        "org.mockito:mockito-core:5.18.0",
+        "org.objenesis:objenesis:3.4",
+        "org.openjdk.jmh:jmh-core:" + JMH_VERSION,
+        "org.openjdk.jmh:jmh-generator-annprocess:" + JMH_VERSION,
+        "org.slf4j:slf4j-api:" + SLF4J_VERSION,
+        "org.slf4j:slf4j-simple:" + SLF4J_VERSION,
+        "org.tukaani:xz:1.10",
+    ],
+    duplicate_version_warning = "error",
+    fail_on_missing_checksum = True,
+    fetch_sources = True,
+    repositories = [
+        "https://repo1.maven.org/maven2",
+    ],
+    strict_visibility = True,
+)
+use_repo(maven, "jgit_deps")
diff --git a/MODULE.bazel.lock b/MODULE.bazel.lock
new file mode 100644
index 0000000..bdc8104
--- /dev/null
+++ b/MODULE.bazel.lock
@@ -0,0 +1,221 @@
+{
+  "lockFileVersion": 18,
+  "registryFileHashes": {
+    "https://bcr.bazel.build/bazel_registry.json": "8a28e4aff06ee60aed2a8c281907fb8bcbf3b753c91fb5a5c57da3215d5b3497",
+    "https://bcr.bazel.build/modules/abseil-cpp/20210324.2/MODULE.bazel": "7cd0312e064fde87c8d1cd79ba06c876bd23630c83466e9500321be55c96ace2",
+    "https://bcr.bazel.build/modules/abseil-cpp/20211102.0/MODULE.bazel": "70390338f7a5106231d20620712f7cccb659cd0e9d073d1991c038eb9fc57589",
+    "https://bcr.bazel.build/modules/abseil-cpp/20230125.1/MODULE.bazel": "89047429cb0207707b2dface14ba7f8df85273d484c2572755be4bab7ce9c3a0",
+    "https://bcr.bazel.build/modules/abseil-cpp/20230802.0.bcr.1/MODULE.bazel": "1c8cec495288dccd14fdae6e3f95f772c1c91857047a098fad772034264cc8cb",
+    "https://bcr.bazel.build/modules/abseil-cpp/20230802.0/MODULE.bazel": "d253ae36a8bd9ee3c5955384096ccb6baf16a1b1e93e858370da0a3b94f77c16",
+    "https://bcr.bazel.build/modules/abseil-cpp/20230802.1/MODULE.bazel": "fa92e2eb41a04df73cdabeec37107316f7e5272650f81d6cc096418fe647b915",
+    "https://bcr.bazel.build/modules/abseil-cpp/20240116.1/MODULE.bazel": "37bcdb4440fbb61df6a1c296ae01b327f19e9bb521f9b8e26ec854b6f97309ed",
+    "https://bcr.bazel.build/modules/abseil-cpp/20240116.1/source.json": "9be551b8d4e3ef76875c0d744b5d6a504a27e3ae67bc6b28f46415fd2d2957da",
+    "https://bcr.bazel.build/modules/bazel_features/1.1.1/MODULE.bazel": "27b8c79ef57efe08efccbd9dd6ef70d61b4798320b8d3c134fd571f78963dbcd",
+    "https://bcr.bazel.build/modules/bazel_features/1.11.0/MODULE.bazel": "f9382337dd5a474c3b7d334c2f83e50b6eaedc284253334cf823044a26de03e8",
+    "https://bcr.bazel.build/modules/bazel_features/1.15.0/MODULE.bazel": "d38ff6e517149dc509406aca0db3ad1efdd890a85e049585b7234d04238e2a4d",
+    "https://bcr.bazel.build/modules/bazel_features/1.17.0/MODULE.bazel": "039de32d21b816b47bd42c778e0454217e9c9caac4a3cf8e15c7231ee3ddee4d",
+    "https://bcr.bazel.build/modules/bazel_features/1.18.0/MODULE.bazel": "1be0ae2557ab3a72a57aeb31b29be347bcdc5d2b1eb1e70f39e3851a7e97041a",
+    "https://bcr.bazel.build/modules/bazel_features/1.19.0/MODULE.bazel": "59adcdf28230d220f0067b1f435b8537dd033bfff8db21335ef9217919c7fb58",
+    "https://bcr.bazel.build/modules/bazel_features/1.21.0/MODULE.bazel": "675642261665d8eea09989aa3b8afb5c37627f1be178382c320d1b46afba5e3b",
+    "https://bcr.bazel.build/modules/bazel_features/1.21.0/source.json": "3e8379efaaef53ce35b7b8ba419df829315a880cb0a030e5bb45c96d6d5ecb5f",
+    "https://bcr.bazel.build/modules/bazel_features/1.4.1/MODULE.bazel": "e45b6bb2350aff3e442ae1111c555e27eac1d915e77775f6fdc4b351b758b5d7",
+    "https://bcr.bazel.build/modules/bazel_features/1.9.1/MODULE.bazel": "8f679097876a9b609ad1f60249c49d68bfab783dd9be012faf9d82547b14815a",
+    "https://bcr.bazel.build/modules/bazel_skylib/1.0.3/MODULE.bazel": "bcb0fd896384802d1ad283b4e4eb4d718eebd8cb820b0a2c3a347fb971afd9d8",
+    "https://bcr.bazel.build/modules/bazel_skylib/1.1.1/MODULE.bazel": "1add3e7d93ff2e6998f9e118022c84d163917d912f5afafb3058e3d2f1545b5e",
+    "https://bcr.bazel.build/modules/bazel_skylib/1.2.0/MODULE.bazel": "44fe84260e454ed94ad326352a698422dbe372b21a1ac9f3eab76eb531223686",
+    "https://bcr.bazel.build/modules/bazel_skylib/1.2.1/MODULE.bazel": "f35baf9da0efe45fa3da1696ae906eea3d615ad41e2e3def4aeb4e8bc0ef9a7a",
+    "https://bcr.bazel.build/modules/bazel_skylib/1.3.0/MODULE.bazel": "20228b92868bf5cfc41bda7afc8a8ba2a543201851de39d990ec957b513579c5",
+    "https://bcr.bazel.build/modules/bazel_skylib/1.4.1/MODULE.bazel": "a0dcb779424be33100dcae821e9e27e4f2901d9dfd5333efe5ac6a8d7ab75e1d",
+    "https://bcr.bazel.build/modules/bazel_skylib/1.4.2/MODULE.bazel": "3bd40978e7a1fac911d5989e6b09d8f64921865a45822d8b09e815eaa726a651",
+    "https://bcr.bazel.build/modules/bazel_skylib/1.5.0/MODULE.bazel": "32880f5e2945ce6a03d1fbd588e9198c0a959bb42297b2cfaf1685b7bc32e138",
+    "https://bcr.bazel.build/modules/bazel_skylib/1.6.1/MODULE.bazel": "8fdee2dbaace6c252131c00e1de4b165dc65af02ea278476187765e1a617b917",
+    "https://bcr.bazel.build/modules/bazel_skylib/1.7.0/MODULE.bazel": "0db596f4563de7938de764cc8deeabec291f55e8ec15299718b93c4423e9796d",
+    "https://bcr.bazel.build/modules/bazel_skylib/1.7.1/MODULE.bazel": "3120d80c5861aa616222ec015332e5f8d3171e062e3e804a2a0253e1be26e59b",
+    "https://bcr.bazel.build/modules/bazel_skylib/1.7.1/source.json": "f121b43eeefc7c29efbd51b83d08631e2347297c95aac9764a701f2a6a2bb953",
+    "https://bcr.bazel.build/modules/buildozer/7.1.2/MODULE.bazel": "2e8dd40ede9c454042645fd8d8d0cd1527966aa5c919de86661e62953cd73d84",
+    "https://bcr.bazel.build/modules/buildozer/7.1.2/source.json": "c9028a501d2db85793a6996205c8de120944f50a0d570438fcae0457a5f9d1f8",
+    "https://bcr.bazel.build/modules/google_benchmark/1.8.2/MODULE.bazel": "a70cf1bba851000ba93b58ae2f6d76490a9feb74192e57ab8e8ff13c34ec50cb",
+    "https://bcr.bazel.build/modules/googletest/1.11.0/MODULE.bazel": "3a83f095183f66345ca86aa13c58b59f9f94a2f81999c093d4eeaa2d262d12f4",
+    "https://bcr.bazel.build/modules/googletest/1.14.0.bcr.1/MODULE.bazel": "22c31a561553727960057361aa33bf20fb2e98584bc4fec007906e27053f80c6",
+    "https://bcr.bazel.build/modules/googletest/1.14.0.bcr.1/source.json": "41e9e129f80d8c8bf103a7acc337b76e54fad1214ac0a7084bf24f4cd924b8b4",
+    "https://bcr.bazel.build/modules/googletest/1.14.0/MODULE.bazel": "cfbcbf3e6eac06ef9d85900f64424708cc08687d1b527f0ef65aa7517af8118f",
+    "https://bcr.bazel.build/modules/jsoncpp/1.9.5/MODULE.bazel": "31271aedc59e815656f5736f282bb7509a97c7ecb43e927ac1a37966e0578075",
+    "https://bcr.bazel.build/modules/jsoncpp/1.9.5/source.json": "4108ee5085dd2885a341c7fab149429db457b3169b86eb081fa245eadf69169d",
+    "https://bcr.bazel.build/modules/libpfm/4.11.0/MODULE.bazel": "45061ff025b301940f1e30d2c16bea596c25b176c8b6b3087e92615adbd52902",
+    "https://bcr.bazel.build/modules/platforms/0.0.10/MODULE.bazel": "8cb8efaf200bdeb2150d93e162c40f388529a25852b332cec879373771e48ed5",
+    "https://bcr.bazel.build/modules/platforms/0.0.10/source.json": "f22828ff4cf021a6b577f1bf6341cb9dcd7965092a439f64fc1bb3b7a5ae4bd5",
+    "https://bcr.bazel.build/modules/platforms/0.0.4/MODULE.bazel": "9b328e31ee156f53f3c416a64f8491f7eb731742655a47c9eec4703a71644aee",
+    "https://bcr.bazel.build/modules/platforms/0.0.5/MODULE.bazel": "5733b54ea419d5eaf7997054bb55f6a1d0b5ff8aedf0176fef9eea44f3acda37",
+    "https://bcr.bazel.build/modules/platforms/0.0.6/MODULE.bazel": "ad6eeef431dc52aefd2d77ed20a4b353f8ebf0f4ecdd26a807d2da5aa8cd0615",
+    "https://bcr.bazel.build/modules/platforms/0.0.7/MODULE.bazel": "72fd4a0ede9ee5c021f6a8dd92b503e089f46c227ba2813ff183b71616034814",
+    "https://bcr.bazel.build/modules/platforms/0.0.8/MODULE.bazel": "9f142c03e348f6d263719f5074b21ef3adf0b139ee4c5133e2aa35664da9eb2d",
+    "https://bcr.bazel.build/modules/protobuf/21.7/MODULE.bazel": "a5a29bb89544f9b97edce05642fac225a808b5b7be74038ea3640fae2f8e66a7",
+    "https://bcr.bazel.build/modules/protobuf/27.0/MODULE.bazel": "7873b60be88844a0a1d8f80b9d5d20cfbd8495a689b8763e76c6372998d3f64c",
+    "https://bcr.bazel.build/modules/protobuf/27.1/MODULE.bazel": "703a7b614728bb06647f965264967a8ef1c39e09e8f167b3ca0bb1fd80449c0d",
+    "https://bcr.bazel.build/modules/protobuf/29.0-rc2/MODULE.bazel": "6241d35983510143049943fc0d57937937122baf1b287862f9dc8590fc4c37df",
+    "https://bcr.bazel.build/modules/protobuf/29.0/MODULE.bazel": "319dc8bf4c679ff87e71b1ccfb5a6e90a6dbc4693501d471f48662ac46d04e4e",
+    "https://bcr.bazel.build/modules/protobuf/29.0/source.json": "b857f93c796750eef95f0d61ee378f3420d00ee1dd38627b27193aa482f4f981",
+    "https://bcr.bazel.build/modules/protobuf/3.19.0/MODULE.bazel": "6b5fbb433f760a99a22b18b6850ed5784ef0e9928a72668b66e4d7ccd47db9b0",
+    "https://bcr.bazel.build/modules/pybind11_bazel/2.11.1/MODULE.bazel": "88af1c246226d87e65be78ed49ecd1e6f5e98648558c14ce99176da041dc378e",
+    "https://bcr.bazel.build/modules/pybind11_bazel/2.11.1/source.json": "be4789e951dd5301282729fe3d4938995dc4c1a81c2ff150afc9f1b0504c6022",
+    "https://bcr.bazel.build/modules/re2/2023-09-01/MODULE.bazel": "cb3d511531b16cfc78a225a9e2136007a48cf8a677e4264baeab57fe78a80206",
+    "https://bcr.bazel.build/modules/re2/2023-09-01/source.json": "e044ce89c2883cd957a2969a43e79f7752f9656f6b20050b62f90ede21ec6eb4",
+    "https://bcr.bazel.build/modules/rules_android/0.1.1/MODULE.bazel": "48809ab0091b07ad0182defb787c4c5328bd3a278938415c00a7b69b50c4d3a8",
+    "https://bcr.bazel.build/modules/rules_android/0.1.1/source.json": "e6986b41626ee10bdc864937ffb6d6bf275bb5b9c65120e6137d56e6331f089e",
+    "https://bcr.bazel.build/modules/rules_cc/0.0.1/MODULE.bazel": "cb2aa0747f84c6c3a78dad4e2049c154f08ab9d166b1273835a8174940365647",
+    "https://bcr.bazel.build/modules/rules_cc/0.0.10/MODULE.bazel": "ec1705118f7eaedd6e118508d3d26deba2a4e76476ada7e0e3965211be012002",
+    "https://bcr.bazel.build/modules/rules_cc/0.0.13/MODULE.bazel": "0e8529ed7b323dad0775ff924d2ae5af7640b23553dfcd4d34344c7e7a867191",
+    "https://bcr.bazel.build/modules/rules_cc/0.0.14/MODULE.bazel": "5e343a3aac88b8d7af3b1b6d2093b55c347b8eefc2e7d1442f7a02dc8fea48ac",
+    "https://bcr.bazel.build/modules/rules_cc/0.0.15/MODULE.bazel": "6704c35f7b4a72502ee81f61bf88706b54f06b3cbe5558ac17e2e14666cd5dcc",
+    "https://bcr.bazel.build/modules/rules_cc/0.0.16/MODULE.bazel": "7661303b8fc1b4d7f532e54e9d6565771fea666fbdf839e0a86affcd02defe87",
+    "https://bcr.bazel.build/modules/rules_cc/0.0.17/MODULE.bazel": "2ae1d8f4238ec67d7185d8861cb0a2cdf4bc608697c331b95bf990e69b62e64a",
+    "https://bcr.bazel.build/modules/rules_cc/0.0.17/source.json": "4db99b3f55c90ab28d14552aa0632533e3e8e5e9aea0f5c24ac0014282c2a7c5",
+    "https://bcr.bazel.build/modules/rules_cc/0.0.2/MODULE.bazel": "6915987c90970493ab97393024c156ea8fb9f3bea953b2f3ec05c34f19b5695c",
+    "https://bcr.bazel.build/modules/rules_cc/0.0.6/MODULE.bazel": "abf360251023dfe3efcef65ab9d56beefa8394d4176dd29529750e1c57eaa33f",
+    "https://bcr.bazel.build/modules/rules_cc/0.0.8/MODULE.bazel": "964c85c82cfeb6f3855e6a07054fdb159aced38e99a5eecf7bce9d53990afa3e",
+    "https://bcr.bazel.build/modules/rules_cc/0.0.9/MODULE.bazel": "836e76439f354b89afe6a911a7adf59a6b2518fafb174483ad78a2a2fde7b1c5",
+    "https://bcr.bazel.build/modules/rules_foreign_cc/0.9.0/MODULE.bazel": "c9e8c682bf75b0e7c704166d79b599f93b72cfca5ad7477df596947891feeef6",
+    "https://bcr.bazel.build/modules/rules_fuzzing/0.5.2/MODULE.bazel": "40c97d1144356f52905566c55811f13b299453a14ac7769dfba2ac38192337a8",
+    "https://bcr.bazel.build/modules/rules_fuzzing/0.5.2/source.json": "c8b1e2c717646f1702290959a3302a178fb639d987ab61d548105019f11e527e",
+    "https://bcr.bazel.build/modules/rules_java/4.0.0/MODULE.bazel": "5a78a7ae82cd1a33cef56dc578c7d2a46ed0dca12643ee45edbb8417899e6f74",
+    "https://bcr.bazel.build/modules/rules_java/5.3.5/MODULE.bazel": "a4ec4f2db570171e3e5eb753276ee4b389bae16b96207e9d3230895c99644b86",
+    "https://bcr.bazel.build/modules/rules_java/6.0.0/MODULE.bazel": "8a43b7df601a7ec1af61d79345c17b31ea1fedc6711fd4abfd013ea612978e39",
+    "https://bcr.bazel.build/modules/rules_java/6.4.0/MODULE.bazel": "e986a9fe25aeaa84ac17ca093ef13a4637f6107375f64667a15999f77db6c8f6",
+    "https://bcr.bazel.build/modules/rules_java/6.5.2/MODULE.bazel": "1d440d262d0e08453fa0c4d8f699ba81609ed0e9a9a0f02cd10b3e7942e61e31",
+    "https://bcr.bazel.build/modules/rules_java/7.10.0/MODULE.bazel": "530c3beb3067e870561739f1144329a21c851ff771cd752a49e06e3dc9c2e71a",
+    "https://bcr.bazel.build/modules/rules_java/7.12.2/MODULE.bazel": "579c505165ee757a4280ef83cda0150eea193eed3bef50b1004ba88b99da6de6",
+    "https://bcr.bazel.build/modules/rules_java/7.2.0/MODULE.bazel": "06c0334c9be61e6cef2c8c84a7800cef502063269a5af25ceb100b192453d4ab",
+    "https://bcr.bazel.build/modules/rules_java/7.3.2/MODULE.bazel": "50dece891cfdf1741ea230d001aa9c14398062f2b7c066470accace78e412bc2",
+    "https://bcr.bazel.build/modules/rules_java/7.6.1/MODULE.bazel": "2f14b7e8a1aa2f67ae92bc69d1ec0fa8d9f827c4e17ff5e5f02e91caa3b2d0fe",
+    "https://bcr.bazel.build/modules/rules_java/8.11.0/MODULE.bazel": "c3d280bc5ff1038dcb3bacb95d3f6b83da8dd27bba57820ec89ea4085da767ad",
+    "https://bcr.bazel.build/modules/rules_java/8.11.0/source.json": "302b52a39259a85aa06ca3addb9787864ca3e03b432a5f964ea68244397e7544",
+    "https://bcr.bazel.build/modules/rules_jvm_external/4.4.2/MODULE.bazel": "a56b85e418c83eb1839819f0b515c431010160383306d13ec21959ac412d2fe7",
+    "https://bcr.bazel.build/modules/rules_jvm_external/5.1/MODULE.bazel": "33f6f999e03183f7d088c9be518a63467dfd0be94a11d0055fe2d210f89aa909",
+    "https://bcr.bazel.build/modules/rules_jvm_external/5.2/MODULE.bazel": "d9351ba35217ad0de03816ef3ed63f89d411349353077348a45348b096615036",
+    "https://bcr.bazel.build/modules/rules_jvm_external/5.3/MODULE.bazel": "bf93870767689637164657731849fb887ad086739bd5d360d90007a581d5527d",
+    "https://bcr.bazel.build/modules/rules_jvm_external/6.1/MODULE.bazel": "75b5fec090dbd46cf9b7d8ea08cf84a0472d92ba3585b476f44c326eda8059c4",
+    "https://bcr.bazel.build/modules/rules_jvm_external/6.3/MODULE.bazel": "c998e060b85f71e00de5ec552019347c8bca255062c990ac02d051bb80a38df0",
+    "https://bcr.bazel.build/modules/rules_jvm_external/6.7/MODULE.bazel": "e717beabc4d091ecb2c803c2d341b88590e9116b8bf7947915eeb33aab4f96dd",
+    "https://bcr.bazel.build/modules/rules_jvm_external/6.7/source.json": "5426f412d0a7fc6b611643376c7e4a82dec991491b9ce5cb1cfdd25fe2e92be4",
+    "https://bcr.bazel.build/modules/rules_kotlin/1.9.0/MODULE.bazel": "ef85697305025e5a61f395d4eaede272a5393cee479ace6686dba707de804d59",
+    "https://bcr.bazel.build/modules/rules_kotlin/1.9.6/MODULE.bazel": "d269a01a18ee74d0335450b10f62c9ed81f2321d7958a2934e44272fe82dcef3",
+    "https://bcr.bazel.build/modules/rules_kotlin/1.9.6/source.json": "2faa4794364282db7c06600b7e5e34867a564ae91bda7cae7c29c64e9466b7d5",
+    "https://bcr.bazel.build/modules/rules_license/0.0.3/MODULE.bazel": "627e9ab0247f7d1e05736b59dbb1b6871373de5ad31c3011880b4133cafd4bd0",
+    "https://bcr.bazel.build/modules/rules_license/0.0.7/MODULE.bazel": "088fbeb0b6a419005b89cf93fe62d9517c0a2b8bb56af3244af65ecfe37e7d5d",
+    "https://bcr.bazel.build/modules/rules_license/1.0.0/MODULE.bazel": "a7fda60eefdf3d8c827262ba499957e4df06f659330bbe6cdbdb975b768bb65c",
+    "https://bcr.bazel.build/modules/rules_license/1.0.0/source.json": "a52c89e54cc311196e478f8382df91c15f7a2bfdf4c6cd0e2675cc2ff0b56efb",
+    "https://bcr.bazel.build/modules/rules_pkg/0.7.0/MODULE.bazel": "df99f03fc7934a4737122518bb87e667e62d780b610910f0447665a7e2be62dc",
+    "https://bcr.bazel.build/modules/rules_pkg/1.0.1/MODULE.bazel": "5b1df97dbc29623bccdf2b0dcd0f5cb08e2f2c9050aab1092fd39a41e82686ff",
+    "https://bcr.bazel.build/modules/rules_pkg/1.0.1/source.json": "bd82e5d7b9ce2d31e380dd9f50c111d678c3bdaca190cb76b0e1c71b05e1ba8a",
+    "https://bcr.bazel.build/modules/rules_proto/4.0.0/MODULE.bazel": "a7a7b6ce9bee418c1a760b3d84f83a299ad6952f9903c67f19e4edd964894e06",
+    "https://bcr.bazel.build/modules/rules_proto/5.3.0-21.7/MODULE.bazel": "e8dff86b0971688790ae75528fe1813f71809b5afd57facb44dad9e8eca631b7",
+    "https://bcr.bazel.build/modules/rules_proto/6.0.2/MODULE.bazel": "ce916b775a62b90b61888052a416ccdda405212b6aaeb39522f7dc53431a5e73",
+    "https://bcr.bazel.build/modules/rules_proto/7.0.2/MODULE.bazel": "bf81793bd6d2ad89a37a40693e56c61b0ee30f7a7fdbaf3eabbf5f39de47dea2",
+    "https://bcr.bazel.build/modules/rules_proto/7.0.2/source.json": "1e5e7260ae32ef4f2b52fd1d0de8d03b606a44c91b694d2f1afb1d3b28a48ce1",
+    "https://bcr.bazel.build/modules/rules_python/0.10.2/MODULE.bazel": "cc82bc96f2997baa545ab3ce73f196d040ffb8756fd2d66125a530031cd90e5f",
+    "https://bcr.bazel.build/modules/rules_python/0.23.1/MODULE.bazel": "49ffccf0511cb8414de28321f5fcf2a31312b47c40cc21577144b7447f2bf300",
+    "https://bcr.bazel.build/modules/rules_python/0.25.0/MODULE.bazel": "72f1506841c920a1afec76975b35312410eea3aa7b63267436bfb1dd91d2d382",
+    "https://bcr.bazel.build/modules/rules_python/0.28.0/MODULE.bazel": "cba2573d870babc976664a912539b320cbaa7114cd3e8f053c720171cde331ed",
+    "https://bcr.bazel.build/modules/rules_python/0.31.0/MODULE.bazel": "93a43dc47ee570e6ec9f5779b2e64c1476a6ce921c48cc9a1678a91dd5f8fd58",
+    "https://bcr.bazel.build/modules/rules_python/0.4.0/MODULE.bazel": "9208ee05fd48bf09ac60ed269791cf17fb343db56c8226a720fbb1cdf467166c",
+    "https://bcr.bazel.build/modules/rules_python/0.40.0/MODULE.bazel": "9d1a3cd88ed7d8e39583d9ffe56ae8a244f67783ae89b60caafc9f5cf318ada7",
+    "https://bcr.bazel.build/modules/rules_python/0.40.0/source.json": "939d4bd2e3110f27bfb360292986bb79fd8dcefb874358ccd6cdaa7bda029320",
+    "https://bcr.bazel.build/modules/rules_shell/0.2.0/MODULE.bazel": "fda8a652ab3c7d8fee214de05e7a9916d8b28082234e8d2c0094505c5268ed3c",
+    "https://bcr.bazel.build/modules/rules_shell/0.3.0/MODULE.bazel": "de4402cd12f4cc8fda2354fce179fdb068c0b9ca1ec2d2b17b3e21b24c1a937b",
+    "https://bcr.bazel.build/modules/rules_shell/0.3.0/source.json": "c55ed591aa5009401ddf80ded9762ac32c358d2517ee7820be981e2de9756cf3",
+    "https://bcr.bazel.build/modules/stardoc/0.5.1/MODULE.bazel": "1a05d92974d0c122f5ccf09291442580317cdd859f07a8655f1db9a60374f9f8",
+    "https://bcr.bazel.build/modules/stardoc/0.5.3/MODULE.bazel": "c7f6948dae6999bf0db32c1858ae345f112cacf98f174c7a8bb707e41b974f1c",
+    "https://bcr.bazel.build/modules/stardoc/0.5.6/MODULE.bazel": "c43dabc564990eeab55e25ed61c07a1aadafe9ece96a4efabb3f8bf9063b71ef",
+    "https://bcr.bazel.build/modules/stardoc/0.7.0/MODULE.bazel": "05e3d6d30c099b6770e97da986c53bd31844d7f13d41412480ea265ac9e8079c",
+    "https://bcr.bazel.build/modules/stardoc/0.7.1/MODULE.bazel": "3548faea4ee5dda5580f9af150e79d0f6aea934fc60c1cc50f4efdd9420759e7",
+    "https://bcr.bazel.build/modules/stardoc/0.7.1/source.json": "b6500ffcd7b48cd72c29bb67bcac781e12701cc0d6d55d266a652583cfcdab01",
+    "https://bcr.bazel.build/modules/upb/0.0.0-20220923-a547704/MODULE.bazel": "7298990c00040a0e2f121f6c32544bab27d4452f80d9ce51349b1a28f3005c43",
+    "https://bcr.bazel.build/modules/zlib/1.2.11/MODULE.bazel": "07b389abc85fdbca459b69e2ec656ae5622873af3f845e1c9d80fe179f3effa0",
+    "https://bcr.bazel.build/modules/zlib/1.3.1.bcr.3/MODULE.bazel": "af322bc08976524477c79d1e45e241b6efbeb918c497e8840b8ab116802dda79",
+    "https://bcr.bazel.build/modules/zlib/1.3.1.bcr.3/source.json": "2be409ac3c7601245958cd4fcdff4288be79ed23bd690b4b951f500d54ee6e7d",
+    "https://bcr.bazel.build/modules/zlib/1.3.1/MODULE.bazel": "751c9940dcfe869f5f7274e1295422a34623555916eb98c174c1e945594bf198"
+  },
+  "selectedYankedVersions": {},
+  "moduleExtensions": {
+    "@@platforms//host:extension.bzl%host_platform": {
+      "general": {
+        "bzlTransitiveDigest": "xelQcPZH8+tmuOHVjL9vDxMnnQNMlwj0SlvgoqBkm4U=",
+        "usagesDigest": "SeQiIN/f8/Qt9vYQk7qcXp4I4wJeEC0RnQDiaaJ4tb8=",
+        "recordedFileInputs": {},
+        "recordedDirentsInputs": {},
+        "envVariables": {},
+        "generatedRepoSpecs": {
+          "host_platform": {
+            "repoRuleId": "@@platforms//host:extension.bzl%host_platform_repo",
+            "attributes": {}
+          }
+        },
+        "recordedRepoMappingEntries": []
+      }
+    },
+    "@@rules_kotlin+//src/main/starlark/core/repositories:bzlmod_setup.bzl%rules_kotlin_extensions": {
+      "general": {
+        "bzlTransitiveDigest": "sFhcgPbDQehmbD1EOXzX4H1q/CD5df8zwG4kp4jbvr8=",
+        "usagesDigest": "QI2z8ZUR+mqtbwsf2fLqYdJAkPOHdOV+tF2yVAUgRzw=",
+        "recordedFileInputs": {},
+        "recordedDirentsInputs": {},
+        "envVariables": {},
+        "generatedRepoSpecs": {
+          "com_github_jetbrains_kotlin_git": {
+            "repoRuleId": "@@rules_kotlin+//src/main/starlark/core/repositories:compiler.bzl%kotlin_compiler_git_repository",
+            "attributes": {
+              "urls": [
+                "https://github.com/JetBrains/kotlin/releases/download/v1.9.23/kotlin-compiler-1.9.23.zip"
+              ],
+              "sha256": "93137d3aab9afa9b27cb06a824c2324195c6b6f6179d8a8653f440f5bd58be88"
+            }
+          },
+          "com_github_jetbrains_kotlin": {
+            "repoRuleId": "@@rules_kotlin+//src/main/starlark/core/repositories:compiler.bzl%kotlin_capabilities_repository",
+            "attributes": {
+              "git_repository_name": "com_github_jetbrains_kotlin_git",
+              "compiler_version": "1.9.23"
+            }
+          },
+          "com_github_google_ksp": {
+            "repoRuleId": "@@rules_kotlin+//src/main/starlark/core/repositories:ksp.bzl%ksp_compiler_plugin_repository",
+            "attributes": {
+              "urls": [
+                "https://github.com/google/ksp/releases/download/1.9.23-1.0.20/artifacts.zip"
+              ],
+              "sha256": "ee0618755913ef7fd6511288a232e8fad24838b9af6ea73972a76e81053c8c2d",
+              "strip_version": "1.9.23-1.0.20"
+            }
+          },
+          "com_github_pinterest_ktlint": {
+            "repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_file",
+            "attributes": {
+              "sha256": "01b2e0ef893383a50dbeb13970fe7fa3be36ca3e83259e01649945b09d736985",
+              "urls": [
+                "https://github.com/pinterest/ktlint/releases/download/1.3.0/ktlint"
+              ],
+              "executable": true
+            }
+          },
+          "rules_android": {
+            "repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_archive",
+            "attributes": {
+              "sha256": "cd06d15dd8bb59926e4d65f9003bfc20f9da4b2519985c27e190cddc8b7a7806",
+              "strip_prefix": "rules_android-0.1.1",
+              "urls": [
+                "https://github.com/bazelbuild/rules_android/archive/v0.1.1.zip"
+              ]
+            }
+          }
+        },
+        "recordedRepoMappingEntries": [
+          [
+            "rules_kotlin+",
+            "bazel_tools",
+            "bazel_tools"
+          ]
+        ]
+      }
+    }
+  }
+}
diff --git a/WORKSPACE b/WORKSPACE
index 505141c..6ba4a02 100644
--- a/WORKSPACE
+++ b/WORKSPACE
@@ -1,317 +1,2 @@
-workspace(name = "jgit")
-
-load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive")
-load("//tools:bazlets.bzl", "load_bazlets")
-
-load_bazlets(commit = "f9c119e45d9a241bee720b7fbd6c7fdbc952da5f")
-
-load(
-    "@com_googlesource_gerrit_bazlets//tools:maven_jar.bzl",
-    "maven_jar",
-)
-
-http_archive(
-    name = "rules_java",
-    sha256 = "4da3761f6855ad916568e2bfe86213ba6d2637f56b8360538a7fb6125abf6518",
-    urls = [
-        "https://github.com/bazelbuild/rules_java/releases/download/7.5.0/rules_java-7.5.0.tar.gz",
-    ],
-)
-
-load("@rules_java//java:repositories.bzl", "rules_java_dependencies", "rules_java_toolchains")
-
-rules_java_dependencies()
-
-http_archive(
-    name = "ubuntu2204_jdk17",
-    sha256 = "8ea82b81c9707e535ff93ef5349d11e55b2a23c62bcc3b0faaec052144aed87d",
-    strip_prefix = "rbe_autoconfig-5.1.0",
-    urls = [
-        "https://gerrit-bazel.storage.googleapis.com/rbe_autoconfig/v5.1.0.tar.gz",
-        "https://github.com/davido/rbe_autoconfig/releases/download/v5.1.0/v5.1.0.tar.gz",
-    ],
-)
-
-register_toolchains("//tools:error_prone_warnings_toolchain_java17_definition")
-
-register_toolchains("//tools:error_prone_warnings_toolchain_java21_definition")
-
-# Order of registering toolchains matters. rules_java toolchains take precedence
-# over the custom toolchains, so the default jdk21 toolchain gets picked
-# (one without custom package_config). That's why the `rules_java_toolchains()`
-# must be called after the `register_toolchain()` invocation.
-rules_java_toolchains()
-
-JMH_VERS = "1.37"
-
-maven_jar(
-    name = "jmh-core",
-    artifact = "org.openjdk.jmh:jmh-core:" + JMH_VERS,
-    attach_source = False,
-    sha1 = "896f27e49105b35ea1964319c83d12082e7a79ef",
-)
-
-maven_jar(
-    name = "jmh-annotations",
-    artifact = "org.openjdk.jmh:jmh-generator-annprocess:" + JMH_VERS,
-    attach_source = False,
-    sha1 = "da93888682df163144edf9b13d2b78e54166063a",
-)
-
-maven_jar(
-    name = "jopt",
-    artifact = "net.sf.jopt-simple:jopt-simple:5.0.4",
-    attach_source = False,
-    sha1 = "4fdac2fbe92dfad86aa6e9301736f6b4342a3f5c",
-)
-
-maven_jar(
-    name = "math3",
-    artifact = "org.apache.commons:commons-math3:3.6.1",
-    attach_source = False,
-    sha1 = "e4ba98f1d4b3c80ec46392f25e094a6a2e58fcbf",
-)
-
-maven_jar(
-    name = "jsch",
-    artifact = "com.jcraft:jsch:0.1.55",
-    sha1 = "bbd40e5aa7aa3cfad5db34965456cee738a42a50",
-)
-
-maven_jar(
-    name = "jzlib",
-    artifact = "com.jcraft:jzlib:1.1.3",
-    sha1 = "c01428efa717624f7aabf4df319939dda9646b2d",
-)
-
-maven_jar(
-    name = "javaewah",
-    artifact = "com.googlecode.javaewah:JavaEWAH:1.2.3",
-    sha1 = "13a27c856e0c8808cee9a64032c58eee11c3adc9",
-)
-
-maven_jar(
-    name = "httpclient",
-    artifact = "org.apache.httpcomponents:httpclient:4.5.14",
-    sha1 = "1194890e6f56ec29177673f2f12d0b8e627dec98",
-)
-
-maven_jar(
-    name = "httpcore",
-    artifact = "org.apache.httpcomponents:httpcore:4.4.16",
-    sha1 = "51cf043c87253c9f58b539c9f7e44c8894223850",
-)
-
-SSHD_VERS = "2.15.0"
-
-maven_jar(
-    name = "sshd-osgi",
-    artifact = "org.apache.sshd:sshd-osgi:" + SSHD_VERS,
-    sha1 = "aa76898fe47eab7da0878dd60e6f3be5631e076c",
-)
-
-maven_jar(
-    name = "sshd-sftp",
-    artifact = "org.apache.sshd:sshd-sftp:" + SSHD_VERS,
-    sha1 = "2e226055ed060c64ed76256a9c45de6d0109eef8",
-)
-
-JNA_VERS = "5.16.0"
-
-maven_jar(
-    name = "jna",
-    artifact = "net.java.dev.jna:jna:" + JNA_VERS,
-    sha1 = "ebea09f91dc9f7048099f963fb8d6f919f0a4d9c",
-)
-
-maven_jar(
-    name = "jna-platform",
-    artifact = "net.java.dev.jna:jna-platform:" + JNA_VERS,
-    sha1 = "b2a9065f97c166893d504b164706512338e3bbc2",
-)
-
-maven_jar(
-    name = "commons-codec",
-    artifact = "commons-codec:commons-codec:1.18.0",
-    sha1 = "ee45d1cf6ec2cc2b809ff04b4dc7aec858e0df8f",
-)
-
-maven_jar(
-    name = "commons-logging",
-    artifact = "commons-logging:commons-logging:1.3.5",
-    sha1 = "a3fcc5d3c29b2b03433aa2d2f2d2c1b1638924a1",
-)
-
-maven_jar(
-    name = "log-api",
-    artifact = "org.slf4j:slf4j-api:1.7.36",
-    sha1 = "6c62681a2f655b49963a5983b8b0950a6120ae14",
-)
-
-maven_jar(
-    name = "slf4j-simple",
-    artifact = "org.slf4j:slf4j-simple:1.7.36",
-    sha1 = "a41f9cfe6faafb2eb83a1c7dd2d0dfd844e2a936",
-)
-
-maven_jar(
-    name = "servlet-api",
-    artifact = "jakarta.servlet:jakarta.servlet-api:6.1.0",
-    sha1 = "1169a246913fe3823782af7943e7a103634867c5",
-)
-
-maven_jar(
-    name = "commons-compress",
-    artifact = "org.apache.commons:commons-compress:1.27.1",
-    sha1 = "a19151084758e2fbb6b41eddaa88e7b8ff4e6599",
-)
-
-maven_jar(
-    name = "commons-lang3",
-    artifact = "org.apache.commons:commons-lang3:3.17.0",
-    sha1 = "b17d2136f0460dcc0d2016ceefca8723bdf4ee70",
-)
-
-maven_jar(
-    name = "commons-io",
-    artifact = "commons-io:commons-io:2.18.0",
-    sha1 = "44084ef756763795b31c578403dd028ff4a22950",
-)
-
-maven_jar(
-    name = "tukaani-xz",
-    artifact = "org.tukaani:xz:1.10",
-    sha1 = "1be8166f89e035a56c6bfc67dbc423996fe577e2",
-)
-
-maven_jar(
-    name = "args4j",
-    artifact = "args4j:args4j:2.37",
-    sha1 = "244f60c057d72a785227c0562d3560f42a7ea54b",
-)
-
-maven_jar(
-    name = "junit",
-    artifact = "junit:junit:4.13.2",
-    sha1 = "8ac9e16d933b6fb43bc7f576336b8f4d7eb5ba12",
-)
-
-maven_jar(
-    name = "hamcrest",
-    artifact = "org.hamcrest:hamcrest:2.2",
-    sha1 = "1820c0968dba3a11a1b30669bb1f01978a91dedc",
-)
-
-maven_jar(
-    name = "mockito",
-    artifact = "org.mockito:mockito-core:5.15.2",
-    sha1 = "87be4b1e0cc5febc07ab3197a8ff3ede56b37a79",
-)
-
-maven_jar(
-    name = "assertj-core",
-    artifact = "org.assertj:assertj-core:3.27.3",
-    sha1 = "31f5d58a202bd5df4993fb10fa2cffd610c20d6f",
-)
-
-BYTE_BUDDY_VERSION = "1.17.1"
-
-maven_jar(
-    name = "bytebuddy",
-    artifact = "net.bytebuddy:byte-buddy:" + BYTE_BUDDY_VERSION,
-    sha1 = "8b5205fad48196a88d3d66dddff5a7417bce3596",
-)
-
-maven_jar(
-    name = "bytebuddy-agent",
-    artifact = "net.bytebuddy:byte-buddy-agent:" + BYTE_BUDDY_VERSION,
-    sha1 = "0669a13b59d5ffd8198a79e4dc99018a9278e457",
-)
-
-maven_jar(
-    name = "objenesis",
-    artifact = "org.objenesis:objenesis:3.4",
-    sha1 = "675cbe121a68019235d27f6c34b4f0ac30e07418",
-)
-
-maven_jar(
-    name = "gson",
-    artifact = "com.google.code.gson:gson:2.12.1",
-    sha1 = "4e773a317740b83b43cfc3d652962856041697cb",
-)
-
-JETTY_VER = "12.0.16"
-
-maven_jar(
-    name = "jetty-servlet",
-    artifact = "org.eclipse.jetty.ee10:jetty-ee10-servlet:" + JETTY_VER,
-    sha1 = "022a746c00b1ac5c790fee65a398c707160a46d8",
-)
-
-maven_jar(
-    name = "jetty-security",
-    artifact = "org.eclipse.jetty:jetty-security:" + JETTY_VER,
-    sha1 = "23b1a3abecf9d6f5498064a32d9145ae1d8330f9",
-)
-
-maven_jar(
-    name = "jetty-server",
-    artifact = "org.eclipse.jetty:jetty-server:" + JETTY_VER,
-    sha1 = "3e3638b4bfbee04c27b3ae68e4949fc43b40a042",
-)
-
-maven_jar(
-    name = "jetty-session",
-    artifact = "org.eclipse.jetty:jetty-session:" + JETTY_VER,
-    sha1 = "79cdedc7afebbdba4453f603dfe2f970baa35cc3",
-)
-
-maven_jar(
-    name = "jetty-http",
-    artifact = "org.eclipse.jetty:jetty-http:" + JETTY_VER,
-    sha1 = "68019fa90e8420ae15c109bd8c8611cacbaf43e5",
-)
-
-maven_jar(
-    name = "jetty-io",
-    artifact = "org.eclipse.jetty:jetty-io:" + JETTY_VER,
-    sha1 = "7a162c537a99bbaf35a074fec9a50815e6c81d9d",
-)
-
-maven_jar(
-    name = "jetty-util",
-    artifact = "org.eclipse.jetty:jetty-util:" + JETTY_VER,
-    sha1 = "e262e505363e5925df15618622d9888aefc1b0d0",
-)
-
-maven_jar(
-    name = "jetty-util-ajax",
-    artifact = "org.eclipse.jetty:jetty-util-ajax:" + JETTY_VER,
-    sha1 = "60225034131e3f771b40bc75c15bd9cc4952302b",
-)
-
-BOUNCYCASTLE_VER = "1.80"
-
-maven_jar(
-    name = "bcpg",
-    artifact = "org.bouncycastle:bcpg-jdk18on:" + BOUNCYCASTLE_VER,
-    sha1 = "163889a825393854dbe7dc52f1a8667e715e9859",
-)
-
-maven_jar(
-    name = "bcprov",
-    artifact = "org.bouncycastle:bcprov-jdk18on:" + BOUNCYCASTLE_VER,
-    sha1 = "e22100b41042decf09cab914a5af8d2c57b5ac4a",
-)
-
-maven_jar(
-    name = "bcutil",
-    artifact = "org.bouncycastle:bcutil-jdk18on:" + BOUNCYCASTLE_VER,
-    sha1 = "b95726d1d49a0c65010c59a3e6640311d951bfd1",
-)
-
-maven_jar(
-    name = "bcpkix",
-    artifact = "org.bouncycastle:bcpkix-jdk18on:" + BOUNCYCASTLE_VER,
-    sha1 = "5277dfaaef2e92ce1d802499599a0ca7488f86e6",
-)
+# This file marks the root of the Bazel workspace.
+# See MODULE.bazel for external dependencies setup.
diff --git a/lib/BUILD b/lib/BUILD
index d236b3a..cd96abd 100644
--- a/lib/BUILD
+++ b/lib/BUILD
@@ -6,7 +6,7 @@
         "//org.eclipse.jgit.pgm:__pkg__",
         "//org.eclipse.jgit.pgm.test:__pkg__",
     ],
-    exports = ["@args4j//jar"],
+    exports = ["@jgit_deps//:args4j_args4j"],
 )
 
 java_library(
@@ -16,7 +16,7 @@
         "//org.eclipse.jgit.pgm.test:__pkg__",
         "//org.eclipse.jgit.test:__pkg__",
     ],
-    exports = ["@commons-compress//jar"],
+    exports = ["@jgit_deps//:org_apache_commons_commons_compress"],
 )
 
 java_library(
@@ -26,7 +26,7 @@
         "//org.eclipse.jgit.pgm.test:__pkg__",
         "//org.eclipse.jgit.test:__pkg__",
     ],
-    exports = ["@commons-lang3//jar"],
+    exports = ["@jgit_deps//:org_apache_commons_commons_lang3"],
 )
 
 java_library(
@@ -36,7 +36,7 @@
         "//org.eclipse.jgit.pgm.test:__pkg__",
         "//org.eclipse.jgit.test:__pkg__",
     ],
-    exports = ["@commons-io//jar"],
+    exports = ["@jgit_deps//:commons_io_commons_io"],
 )
 
 java_library(
@@ -45,13 +45,13 @@
         "//org.eclipse.jgit:__pkg__",
         "//org.eclipse.jgit.test:__pkg__",
     ],
-    exports = ["@commons-codec//jar"],
+    exports = ["@jgit_deps//:commons_codec_commons_codec"],
 )
 
 java_library(
     name = "commons-logging",
     visibility = ["//visibility:public"],
-    exports = ["@commons-logging//jar"],
+    exports = ["@jgit_deps//:commons_logging_commons_logging"],
 )
 
 java_library(
@@ -60,7 +60,7 @@
         "//org.eclipse.jgit.lfs:__pkg__",
         "//org.eclipse.jgit.lfs.server:__pkg__",
     ],
-    exports = ["@gson//jar"],
+    exports = ["@jgit_deps//:com_google_code_gson_gson"],
 )
 
 java_library(
@@ -70,7 +70,7 @@
         "//org.eclipse.jgit.lfs.server.test:__pkg__",
         "//org.eclipse.jgit.pgm:__pkg__",
     ],
-    exports = ["@httpclient//jar"],
+    exports = ["@jgit_deps//:org_apache_httpcomponents_httpclient"],
 )
 
 java_library(
@@ -82,7 +82,7 @@
         "//org.eclipse.jgit.lfs.server.test:__pkg__",
         "//org.eclipse.jgit.pgm:__pkg__",
     ],
-    exports = ["@httpcore//jar"],
+    exports = ["@jgit_deps//:org_apache_httpcomponents_httpcore"],
 )
 
 java_library(
@@ -94,7 +94,7 @@
         "//org.eclipse.jgit.ssh.apache.test:__pkg__",
         "//org.eclipse.jgit.test:__pkg__",
     ],
-    exports = ["@sshd-osgi//jar"],
+    exports = ["@jgit_deps//:org_apache_sshd_sshd_osgi"],
 )
 
 java_library(
@@ -105,7 +105,7 @@
         "//org.eclipse.jgit.ssh.apache.test:__pkg__",
         "//org.eclipse.jgit.test:__pkg__",
     ],
-    exports = ["@sshd-sftp//jar"],
+    exports = ["@jgit_deps//:org_apache_sshd_sshd_sftp"],
 )
 
 java_library(
@@ -113,7 +113,7 @@
     visibility = [
         "//org.eclipse.jgit.ssh.apache.agent:__pkg__",
     ],
-    exports = ["@jna//jar"],
+    exports = ["@jgit_deps//:net_java_dev_jna_jna"],
 )
 
 java_library(
@@ -121,20 +121,20 @@
     visibility = [
         "//org.eclipse.jgit.ssh.apache.agent:__pkg__",
     ],
-    exports = ["@jna-platform//jar"],
+    exports = ["@jgit_deps//:net_java_dev_jna_jna_platform"],
 )
 
 java_library(
     name = "javaewah",
     visibility = ["//visibility:public"],
-    exports = ["@javaewah//jar"],
+    exports = ["@jgit_deps//:com_googlecode_javaewah_JavaEWAH"],
 )
 
 java_library(
     name = "jetty-http",
     # TODO: This should be testonly but org.eclipse.jgit.pgm depends on it.
     visibility = ["//visibility:public"],
-    exports = ["@jetty-http//jar"],
+    exports = ["@jgit_deps//:org_eclipse_jetty_jetty_http"],
     runtime_deps = [":commons-codec"],
 )
 
@@ -142,28 +142,28 @@
     name = "jetty-io",
     # TODO: This should be testonly but org.eclipse.jgit.pgm depends on it.
     visibility = ["//visibility:public"],
-    exports = ["@jetty-io//jar"],
+    exports = ["@jgit_deps//:org_eclipse_jetty_jetty_io"],
 )
 
 java_library(
     name = "jetty-security",
     # TODO: This should be testonly but org.eclipse.jgit.pgm depends on it.
     visibility = ["//visibility:public"],
-    exports = ["@jetty-security//jar"],
+    exports = ["@jgit_deps//:org_eclipse_jetty_jetty_security"],
 )
 
 java_library(
     name = "jetty-session",
     # TODO: This should be testonly but org.eclipse.jgit.pgm depends on it.
     visibility = ["//visibility:public"],
-    exports = ["@jetty-session//jar"],
+    exports = ["@jgit_deps//:org_eclipse_jetty_jetty_session"],
 )
 
 java_library(
     name = "jetty-server",
     # TODO: This should be testonly but org.eclipse.jgit.pgm depends on it.
     visibility = ["//visibility:public"],
-    exports = ["@jetty-server//jar"],
+    exports = ["@jgit_deps//:org_eclipse_jetty_jetty_server"],
 )
 
 java_library(
@@ -171,8 +171,8 @@
     # TODO: This should be testonly but org.eclipse.jgit.pgm depends on it.
     visibility = ["//visibility:public"],
     exports = [
-        "@jetty-servlet//jar",
-        "@jetty-util-ajax//jar",
+        "@jgit_deps//:org_eclipse_jetty_ee10_jetty_ee10_servlet",
+        "@jgit_deps//:org_eclipse_jetty_jetty_util_ajax",
     ],
 )
 
@@ -180,7 +180,7 @@
     name = "jetty-util",
     # TODO: This should be testonly but org.eclipse.jgit.pgm depends on it.
     visibility = ["//visibility:public"],
-    exports = ["@jetty-util//jar"],
+    exports = ["@jgit_deps//:org_eclipse_jetty_jetty_util"],
 )
 
 java_library(
@@ -190,7 +190,7 @@
         "//org.eclipse.jgit.ssh.jsch:__pkg__",
         "//org.eclipse.jgit.ssh.jsch.test:__pkg__",
     ],
-    exports = ["@jsch//jar"],
+    exports = ["@jgit_deps//:com_jcraft_jsch"],
 )
 
 java_library(
@@ -198,9 +198,11 @@
     visibility = [
         "//org.eclipse.jgit.gpg.bc:__pkg__",
         "//org.eclipse.jgit.gpg.bc.test:__pkg__",
+        "//org.eclipse.jgit.ssh.apache:__pkg__",
+        "//org.eclipse.jgit.ssh.apache.test:__pkg__",
         "//org.eclipse.jgit.test:__pkg__",
     ],
-    exports = ["@bcpg//jar"],
+    exports = ["@jgit_deps//:org_bouncycastle_bcpg_jdk18on"],
 )
 
 java_library(
@@ -208,11 +210,12 @@
     visibility = [
         "//org.eclipse.jgit.gpg.bc:__pkg__",
         "//org.eclipse.jgit.gpg.bc.test:__pkg__",
+        "//org.eclipse.jgit.ssh.apache:__pkg__",
         "//org.eclipse.jgit.ssh.apache.test:__pkg__",
         "//org.eclipse.jgit.ssh.jsch.test:__pkg__",
         "//org.eclipse.jgit.test:__pkg__",
     ],
-    exports = ["@bcprov//jar"],
+    exports = ["@jgit_deps//:org_bouncycastle_bcprov_jdk18on"],
 )
 
 java_library(
@@ -220,22 +223,24 @@
     visibility = [
         "//org.eclipse.jgit.gpg.bc:__pkg__",
         "//org.eclipse.jgit.gpg.bc.test:__pkg__",
+        "//org.eclipse.jgit.ssh.apache:__pkg__",
         "//org.eclipse.jgit.ssh.apache.test:__pkg__",
         "//org.eclipse.jgit.ssh.jsch.test:__pkg__",
         "//org.eclipse.jgit.test:__pkg__",
     ],
-    exports = ["@bcutil//jar"],
+    exports = ["@jgit_deps//:org_bouncycastle_bcutil_jdk18on"],
 )
 
 java_library(
     name = "bcpkix",
     visibility = [
         "//org.eclipse.jgit.gpg.bc:__pkg__",
+        "//org.eclipse.jgit.ssh.apache:__pkg__",
         "//org.eclipse.jgit.ssh.apache.test:__pkg__",
         "//org.eclipse.jgit.ssh.jsch.test:__pkg__",
         "//org.eclipse.jgit.test:__pkg__",
     ],
-    exports = ["@bcpkix//jar"],
+    exports = ["@jgit_deps//:org_bouncycastle_bcpkix_jdk18on"],
 )
 
 java_library(
@@ -244,7 +249,7 @@
         "//org.eclipse.jgit.ssh.jsch:__pkg__",
         "//org.eclipse.jgit.test:__pkg__",
     ],
-    exports = ["@jzlib//jar"],
+    exports = ["@jgit_deps//:com_jcraft_jzlib"],
 )
 
 java_library(
@@ -252,12 +257,12 @@
     testonly = 1,
     visibility = ["//visibility:public"],
     exports = [
-        "@bytebuddy-agent//jar",
-        "@bytebuddy//jar",
-        "@hamcrest//jar",
-        "@junit//jar",
-        "@mockito//jar",
-        "@objenesis//jar",
+        "@jgit_deps//:net_bytebuddy_byte_buddy_agent",
+        "@jgit_deps//:net_bytebuddy_byte_buddy",
+        "@jgit_deps//:org_hamcrest_hamcrest",
+        "@jgit_deps//:junit_junit",
+        "@jgit_deps//:org_mockito_mockito_core",
+        "@jgit_deps//:org_objenesis_objenesis",
     ],
 )
 
@@ -266,10 +271,10 @@
     testonly = 1,
     visibility = ["//visibility:public"],
     exports = [
-        "@bytebuddy-agent//jar",
-        "@bytebuddy//jar",
-        "@mockito//jar",
-        "@objenesis//jar",
+        "@jgit_deps//:net_bytebuddy_byte_buddy_agent",
+        "@jgit_deps//:net_bytebuddy_byte_buddy",
+        "@jgit_deps//:org_mockito_mockito_core",
+        "@jgit_deps//:org_objenesis_objenesis",
     ],
 )
 
@@ -278,7 +283,7 @@
     testonly = 1,
     visibility = ["//visibility:public"],
     exports = [
-        "@assertj-core//jar",
+        "@jgit_deps//:org_assertj_assertj_core",
     ],
 )
 
@@ -293,24 +298,24 @@
         "//org.eclipse.jgit.lfs.server.test:__pkg__",
         "//org.eclipse.jgit.pgm:__pkg__",
     ],
-    exports = ["@servlet-api//jar"],
+    exports = ["@jgit_deps//:jakarta_servlet_jakarta_servlet_api_6_1_0"],
 )
 
 java_library(
     name = "slf4j-api",
     visibility = ["//visibility:public"],
-    exports = ["@log-api//jar"],
+    exports = ["@jgit_deps//:org_slf4j_slf4j_api"],
 )
 
 java_library(
     name = "slf4j-simple",
     visibility = ["//visibility:public"],
-    exports = ["@slf4j-simple//jar"],
+    exports = ["@jgit_deps//:org_slf4j_slf4j_simple"],
 )
 
 java_library(
     name = "xz",
     testonly = 1,
     visibility = ["//visibility:public"],
-    exports = ["@tukaani-xz//jar"],
+    exports = ["@jgit_deps//:org_tukaani_xz"],
 )
diff --git a/lib/jmh/BUILD b/lib/jmh/BUILD
index b15e66c..1bba1a5 100644
--- a/lib/jmh/BUILD
+++ b/lib/jmh/BUILD
@@ -4,9 +4,9 @@
     name = "jmh",
     visibility = ["//visibility:public"],
     exports = [
-        "@jmh-annotations//jar",
-        "@jmh-core//jar",
-        "@jopt//jar",
-        "@math3//jar",
+        "@jgit_deps//:org_openjdk_jmh_jmh_generator_annprocess",
+        "@jgit_deps//:org_openjdk_jmh_jmh_core",
+        "@jgit_deps//:net_sf_jopt_simple_jopt_simple",
+        "@jgit_deps//:org_apache_commons_commons_math3",
     ],
 )
diff --git a/org.eclipse.jgit.ant.test/META-INF/MANIFEST.MF b/org.eclipse.jgit.ant.test/META-INF/MANIFEST.MF
index 025335e..20cd365 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: 7.2.2.qualifier
+Bundle-Version: 7.3.1.qualifier
 Bundle-ActivationPolicy: lazy
 Bundle-RequiredExecutionEnvironment: JavaSE-17
 Import-Package: org.apache.tools.ant,
- org.eclipse.jgit.ant.tasks;version="[7.2.2,7.3.0)",
- org.eclipse.jgit.junit;version="[7.2.2,7.3.0)",
- org.eclipse.jgit.lib;version="[7.2.2,7.3.0)",
- org.eclipse.jgit.util;version="[7.2.2,7.3.0)",
+ org.eclipse.jgit.ant.tasks;version="[7.3.1,7.4.0)",
+ org.eclipse.jgit.junit;version="[7.3.1,7.4.0)",
+ org.eclipse.jgit.lib;version="[7.3.1,7.4.0)",
+ org.eclipse.jgit.util;version="[7.3.1,7.4.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 bce6d43..1f0e535 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>7.2.2-SNAPSHOT</version>
+    <version>7.3.1-SNAPSHOT</version>
   </parent>
 
   <artifactId>org.eclipse.jgit.ant.test</artifactId>
diff --git a/org.eclipse.jgit.ant/META-INF/MANIFEST.MF b/org.eclipse.jgit.ant/META-INF/MANIFEST.MF
index d6fa5e2..ce101a7 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: 7.2.2.qualifier
+Bundle-Version: 7.3.1.qualifier
 Bundle-RequiredExecutionEnvironment: JavaSE-17
 Import-Package: org.apache.tools.ant,
-  org.eclipse.jgit.storage.file;version="[7.2.2,7.3.0)"
+  org.eclipse.jgit.storage.file;version="[7.3.1,7.4.0)"
 Bundle-Localization: OSGI-INF/l10n/plugin
 Bundle-Vendor: %Bundle-Vendor
-Export-Package: org.eclipse.jgit.ant;version="7.2.2",
- org.eclipse.jgit.ant.tasks;version="7.2.2";
+Export-Package: org.eclipse.jgit.ant;version="7.3.1",
+ org.eclipse.jgit.ant.tasks;version="7.3.1";
   uses:="org.apache.tools.ant,
    org.apache.tools.ant.types"
diff --git a/org.eclipse.jgit.ant/META-INF/SOURCE-MANIFEST.MF b/org.eclipse.jgit.ant/META-INF/SOURCE-MANIFEST.MF
index c07a051..4f1e9e6 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: 7.2.2.qualifier
-Eclipse-SourceBundle: org.eclipse.jgit.ant;version="7.2.2.qualifier";roots="."
+Bundle-Version: 7.3.1.qualifier
+Eclipse-SourceBundle: org.eclipse.jgit.ant;version="7.3.1.qualifier";roots="."
diff --git a/org.eclipse.jgit.ant/pom.xml b/org.eclipse.jgit.ant/pom.xml
index 38e9dce..cd4ec00 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>7.2.2-SNAPSHOT</version>
+    <version>7.3.1-SNAPSHOT</version>
   </parent>
 
   <artifactId>org.eclipse.jgit.ant</artifactId>
diff --git a/org.eclipse.jgit.archive/META-INF/MANIFEST.MF b/org.eclipse.jgit.archive/META-INF/MANIFEST.MF
index e2b4b8c..cf6e68e 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: 7.2.2.qualifier
+Bundle-Version: 7.3.1.qualifier
 Bundle-Vendor: %Bundle-Vendor
 Bundle-Localization: OSGI-INF/l10n/plugin
 Bundle-RequiredExecutionEnvironment: JavaSE-17
@@ -13,18 +13,18 @@
  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="[7.2.2,7.3.0)",
- org.eclipse.jgit.lib;version="[7.2.2,7.3.0)",
- org.eclipse.jgit.nls;version="[7.2.2,7.3.0)",
- org.eclipse.jgit.revwalk;version="[7.2.2,7.3.0)",
- org.eclipse.jgit.util;version="[7.2.2,7.3.0)",
+ org.eclipse.jgit.api;version="[7.3.1,7.4.0)",
+ org.eclipse.jgit.lib;version="[7.3.1,7.4.0)",
+ org.eclipse.jgit.nls;version="[7.3.1,7.4.0)",
+ org.eclipse.jgit.revwalk;version="[7.3.1,7.4.0)",
+ org.eclipse.jgit.util;version="[7.3.1,7.4.0)",
  org.osgi.framework;version="[1.3.0,2.0.0)",
  org.tukaani.xz
 Bundle-ActivationPolicy: lazy
 Bundle-Activator: org.eclipse.jgit.archive.FormatActivator
-Export-Package: org.eclipse.jgit.archive;version="7.2.2";
+Export-Package: org.eclipse.jgit.archive;version="7.3.1";
   uses:="org.apache.commons.compress.archivers,
    org.osgi.framework,
    org.eclipse.jgit.api,
    org.eclipse.jgit.lib",
- org.eclipse.jgit.archive.internal;version="7.2.2";x-internal:=true
+ org.eclipse.jgit.archive.internal;version="7.3.1";x-internal:=true
diff --git a/org.eclipse.jgit.archive/META-INF/SOURCE-MANIFEST.MF b/org.eclipse.jgit.archive/META-INF/SOURCE-MANIFEST.MF
index 91164e8..116cde1 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: 7.2.2.qualifier
-Eclipse-SourceBundle: org.eclipse.jgit.archive;version="7.2.2.qualifier";roots="."
+Bundle-Version: 7.3.1.qualifier
+Eclipse-SourceBundle: org.eclipse.jgit.archive;version="7.3.1.qualifier";roots="."
diff --git a/org.eclipse.jgit.archive/pom.xml b/org.eclipse.jgit.archive/pom.xml
index c7ea62c..f4dc1a4 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>7.2.2-SNAPSHOT</version>
+    <version>7.3.1-SNAPSHOT</version>
   </parent>
 
   <artifactId>org.eclipse.jgit.archive</artifactId>
diff --git a/org.eclipse.jgit.benchmarks/BUILD b/org.eclipse.jgit.benchmarks/BUILD
index 6198e4d..7c311e7 100644
--- a/org.eclipse.jgit.benchmarks/BUILD
+++ b/org.eclipse.jgit.benchmarks/BUILD
@@ -10,6 +10,7 @@
     testonly = 1,
     deps = [
         "//lib:javaewah",
+        "//lib:junit",
         "//lib:slf4j-api",
         "//org.eclipse.jgit:jgit",
         "//org.eclipse.jgit.junit:junit",
diff --git a/org.eclipse.jgit.benchmarks/pom.xml b/org.eclipse.jgit.benchmarks/pom.xml
index bd5d904..a611696 100644
--- a/org.eclipse.jgit.benchmarks/pom.xml
+++ b/org.eclipse.jgit.benchmarks/pom.xml
@@ -16,7 +16,7 @@
   <parent>
     <groupId>org.eclipse.jgit</groupId>
     <artifactId>org.eclipse.jgit-parent</artifactId>
-    <version>7.2.2-SNAPSHOT</version>
+    <version>7.3.1-SNAPSHOT</version>
   </parent>
 
   <artifactId>org.eclipse.jgit.benchmarks</artifactId>
diff --git a/org.eclipse.jgit.coverage/pom.xml b/org.eclipse.jgit.coverage/pom.xml
index 448d19f..6ed16b4 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>7.2.2-SNAPSHOT</version>
+    <version>7.3.1-SNAPSHOT</version>
   </parent>
   <modelVersion>4.0.0</modelVersion>
 
@@ -27,88 +27,88 @@
     <dependency>
       <groupId>org.eclipse.jgit</groupId>
       <artifactId>org.eclipse.jgit</artifactId>
-      <version>7.2.2-SNAPSHOT</version>
+      <version>7.3.1-SNAPSHOT</version>
     </dependency>
     <dependency>
       <groupId>org.eclipse.jgit</groupId>
       <artifactId>org.eclipse.jgit.ant</artifactId>
-      <version>7.2.2-SNAPSHOT</version>
+      <version>7.3.1-SNAPSHOT</version>
     </dependency>
     <dependency>
       <groupId>org.eclipse.jgit</groupId>
       <artifactId>org.eclipse.jgit.archive</artifactId>
-      <version>7.2.2-SNAPSHOT</version>
+      <version>7.3.1-SNAPSHOT</version>
     </dependency>
     <dependency>
       <groupId>org.eclipse.jgit</groupId>
       <artifactId>org.eclipse.jgit.http.apache</artifactId>
-      <version>7.2.2-SNAPSHOT</version>
+      <version>7.3.1-SNAPSHOT</version>
     </dependency>
     <dependency>
       <groupId>org.eclipse.jgit</groupId>
       <artifactId>org.eclipse.jgit.http.server</artifactId>
-      <version>7.2.2-SNAPSHOT</version>
+      <version>7.3.1-SNAPSHOT</version>
     </dependency>
     <dependency>
       <groupId>org.eclipse.jgit</groupId>
       <artifactId>org.eclipse.jgit.lfs</artifactId>
-      <version>7.2.2-SNAPSHOT</version>
+      <version>7.3.1-SNAPSHOT</version>
     </dependency>
     <dependency>
       <groupId>org.eclipse.jgit</groupId>
       <artifactId>org.eclipse.jgit.lfs.server</artifactId>
-      <version>7.2.2-SNAPSHOT</version>
+      <version>7.3.1-SNAPSHOT</version>
     </dependency>
     <dependency>
       <groupId>org.eclipse.jgit</groupId>
       <artifactId>org.eclipse.jgit.pgm</artifactId>
-      <version>7.2.2-SNAPSHOT</version>
+      <version>7.3.1-SNAPSHOT</version>
     </dependency>
     <dependency>
       <groupId>org.eclipse.jgit</groupId>
       <artifactId>org.eclipse.jgit.ui</artifactId>
-      <version>7.2.2-SNAPSHOT</version>
+      <version>7.3.1-SNAPSHOT</version>
     </dependency>
     <dependency>
       <groupId>org.eclipse.jgit</groupId>
       <artifactId>org.eclipse.jgit.ssh.apache</artifactId>
-      <version>7.2.2-SNAPSHOT</version>
+      <version>7.3.1-SNAPSHOT</version>
     </dependency>
 
     <dependency>
       <groupId>org.eclipse.jgit</groupId>
       <artifactId>org.eclipse.jgit.test</artifactId>
-      <version>7.2.2-SNAPSHOT</version>
+      <version>7.3.1-SNAPSHOT</version>
     </dependency>
     <dependency>
       <groupId>org.eclipse.jgit</groupId>
       <artifactId>org.eclipse.jgit.ant.test</artifactId>
-      <version>7.2.2-SNAPSHOT</version>
+      <version>7.3.1-SNAPSHOT</version>
     </dependency>
     <dependency>
       <groupId>org.eclipse.jgit</groupId>
       <artifactId>org.eclipse.jgit.http.test</artifactId>
-      <version>7.2.2-SNAPSHOT</version>
+      <version>7.3.1-SNAPSHOT</version>
     </dependency>
     <dependency>
       <groupId>org.eclipse.jgit</groupId>
       <artifactId>org.eclipse.jgit.pgm.test</artifactId>
-      <version>7.2.2-SNAPSHOT</version>
+      <version>7.3.1-SNAPSHOT</version>
     </dependency>
     <dependency>
       <groupId>org.eclipse.jgit</groupId>
       <artifactId>org.eclipse.jgit.lfs.test</artifactId>
-      <version>7.2.2-SNAPSHOT</version>
+      <version>7.3.1-SNAPSHOT</version>
     </dependency>
     <dependency>
       <groupId>org.eclipse.jgit</groupId>
       <artifactId>org.eclipse.jgit.lfs.server.test</artifactId>
-      <version>7.2.2-SNAPSHOT</version>
+      <version>7.3.1-SNAPSHOT</version>
     </dependency>
     <dependency>
       <groupId>org.eclipse.jgit</groupId>
       <artifactId>org.eclipse.jgit.ssh.apache.test</artifactId>
-      <version>7.2.2-SNAPSHOT</version>
+      <version>7.3.1-SNAPSHOT</version>
     </dependency>
   </dependencies>
 
diff --git a/org.eclipse.jgit.gpg.bc.test/META-INF/MANIFEST.MF b/org.eclipse.jgit.gpg.bc.test/META-INF/MANIFEST.MF
index 6ef6065..7607871 100644
--- a/org.eclipse.jgit.gpg.bc.test/META-INF/MANIFEST.MF
+++ b/org.eclipse.jgit.gpg.bc.test/META-INF/MANIFEST.MF
@@ -3,20 +3,20 @@
 Bundle-Name: %Bundle-Name
 Automatic-Module-Name: org.eclipse.jgit.gpg.bc.test
 Bundle-SymbolicName: org.eclipse.jgit.gpg.bc.test
-Bundle-Version: 7.2.2.qualifier
+Bundle-Version: 7.3.1.qualifier
 Bundle-Vendor: %Bundle-Vendor
 Bundle-Localization: plugin
 Bundle-RequiredExecutionEnvironment: JavaSE-17
 Require-Bundle: org.hamcrest.core;bundle-version="[1.3.0,2.0.0)"
-Import-Package: org.bouncycastle.asn1.cryptlib;version="[1.79.0,2.0.0)",
- org.bouncycastle.jce.provider;version="[1.79.0,2.0.0)",
- org.bouncycastle.openpgp;version="[1.79.0,2.0.0)",
- org.bouncycastle.openpgp.operator;version="[1.79.0,2.0.0)",
- org.bouncycastle.openpgp.operator.jcajce;version="[1.79.0,2.0.0)",
- org.bouncycastle.util.encoders;version="[1.79.0,2.0.0)",
- org.eclipse.jgit.gpg.bc.internal;version="[7.2.2,7.3.0)",
- org.eclipse.jgit.gpg.bc.internal.keys;version="[7.2.2,7.3.0)",
- org.eclipse.jgit.util.sha1;version="[7.2.2,7.3.0)",
+Import-Package: org.bouncycastle.asn1.cryptlib;version="[1.80.0,2.0.0)",
+ org.bouncycastle.jce.provider;version="[1.80.0,2.0.0)",
+ org.bouncycastle.openpgp;version="[1.80.0,2.0.0)",
+ org.bouncycastle.openpgp.operator;version="[1.80.0,2.0.0)",
+ org.bouncycastle.openpgp.operator.jcajce;version="[1.80.0,2.0.0)",
+ org.bouncycastle.util.encoders;version="[1.80.0,2.0.0)",
+ org.eclipse.jgit.gpg.bc.internal;version="[7.3.1,7.4.0)",
+ org.eclipse.jgit.gpg.bc.internal.keys;version="[7.3.1,7.4.0)",
+ org.eclipse.jgit.util.sha1;version="[7.3.1,7.4.0)",
  org.junit;version="[4.13,5.0.0)",
  org.junit.runner;version="[4.13,5.0.0)",
  org.junit.runners;version="[4.13,5.0.0)"
diff --git a/org.eclipse.jgit.gpg.bc.test/pom.xml b/org.eclipse.jgit.gpg.bc.test/pom.xml
index 5b71a6e..55dd23f 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>7.2.2-SNAPSHOT</version>
+    <version>7.3.1-SNAPSHOT</version>
   </parent>
 
   <artifactId>org.eclipse.jgit.gpg.bc.test</artifactId>
diff --git a/org.eclipse.jgit.gpg.bc/META-INF/MANIFEST.MF b/org.eclipse.jgit.gpg.bc/META-INF/MANIFEST.MF
index 7fb9ca2..4624847 100644
--- a/org.eclipse.jgit.gpg.bc/META-INF/MANIFEST.MF
+++ b/org.eclipse.jgit.gpg.bc/META-INF/MANIFEST.MF
@@ -3,28 +3,28 @@
 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="[7.2.2,7.3.0)"
+Fragment-Host: org.eclipse.jgit;bundle-version="[7.3.1,7.4.0)"
 Bundle-Vendor: %Bundle-Vendor
 Bundle-Localization: OSGI-INF/l10n/gpg_bc
-Bundle-Version: 7.2.2.qualifier
+Bundle-Version: 7.3.1.qualifier
 Bundle-RequiredExecutionEnvironment: JavaSE-17
-Import-Package: org.bouncycastle.asn1;version="[1.79.0,2.0.0)",
- org.bouncycastle.asn1.x9;version="[1.79.0,2.0.0)",
- org.bouncycastle.bcpg;version="[1.79.0,2.0.0)",
- org.bouncycastle.bcpg.sig;version="[1.79.0,2.0.0)",
- org.bouncycastle.crypto.ec;version="[1.79.0,2.0.0)",
- org.bouncycastle.gpg;version="[1.79.0,2.0.0)",
- org.bouncycastle.gpg.keybox;version="[1.79.0,2.0.0)",
- org.bouncycastle.gpg.keybox.jcajce;version="[1.79.0,2.0.0)",
- org.bouncycastle.jcajce.interfaces;version="[1.79.0,2.0.0)",
- org.bouncycastle.jcajce.util;version="[1.79.0,2.0.0)",
- org.bouncycastle.math.ec;version="[1.79.0,2.0.0)",
- org.bouncycastle.math.field;version="[1.79.0,2.0.0)",
- org.bouncycastle.openpgp;version="[1.79.0,2.0.0)",
- org.bouncycastle.openpgp.jcajce;version="[1.79.0,2.0.0)",
- org.bouncycastle.openpgp.operator;version="[1.79.0,2.0.0)",
- org.bouncycastle.openpgp.operator.jcajce;version="[1.79.0,2.0.0)",
- org.bouncycastle.util.encoders;version="[1.79.0,2.0.0)",
+Import-Package: org.bouncycastle.asn1;version="[1.80.0,2.0.0)",
+ org.bouncycastle.asn1.x9;version="[1.80.0,2.0.0)",
+ org.bouncycastle.bcpg;version="[1.80.0,2.0.0)",
+ org.bouncycastle.bcpg.sig;version="[1.80.0,2.0.0)",
+ org.bouncycastle.crypto.ec;version="[1.80.0,2.0.0)",
+ org.bouncycastle.gpg;version="[1.80.0,2.0.0)",
+ org.bouncycastle.gpg.keybox;version="[1.80.0,2.0.0)",
+ org.bouncycastle.gpg.keybox.jcajce;version="[1.80.0,2.0.0)",
+ org.bouncycastle.jcajce.interfaces;version="[1.80.0,2.0.0)",
+ org.bouncycastle.jcajce.util;version="[1.80.0,2.0.0)",
+ org.bouncycastle.math.ec;version="[1.80.0,2.0.0)",
+ org.bouncycastle.math.field;version="[1.80.0,2.0.0)",
+ org.bouncycastle.openpgp;version="[1.80.0,2.0.0)",
+ org.bouncycastle.openpgp.jcajce;version="[1.80.0,2.0.0)",
+ org.bouncycastle.openpgp.operator;version="[1.80.0,2.0.0)",
+ org.bouncycastle.openpgp.operator.jcajce;version="[1.80.0,2.0.0)",
+ org.bouncycastle.util.encoders;version="[1.80.0,2.0.0)",
  org.slf4j;version="[1.7.0,3.0.0)"
-Export-Package: org.eclipse.jgit.gpg.bc.internal;version="7.2.2";x-friends:="org.eclipse.jgit.gpg.bc.test",
- org.eclipse.jgit.gpg.bc.internal.keys;version="7.2.2";x-friends:="org.eclipse.jgit.gpg.bc.test"
+Export-Package: org.eclipse.jgit.gpg.bc.internal;version="7.3.1";x-friends:="org.eclipse.jgit.gpg.bc.test",
+ org.eclipse.jgit.gpg.bc.internal.keys;version="7.3.1";x-friends:="org.eclipse.jgit.gpg.bc.test"
diff --git a/org.eclipse.jgit.gpg.bc/META-INF/SOURCE-MANIFEST.MF b/org.eclipse.jgit.gpg.bc/META-INF/SOURCE-MANIFEST.MF
index b8f19ca..9b1441e 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: 7.2.2.qualifier
-Eclipse-SourceBundle: org.eclipse.jgit.gpg.bc;version="7.2.2.qualifier";roots="."
+Bundle-Version: 7.3.1.qualifier
+Eclipse-SourceBundle: org.eclipse.jgit.gpg.bc;version="7.3.1.qualifier";roots="."
diff --git a/org.eclipse.jgit.gpg.bc/pom.xml b/org.eclipse.jgit.gpg.bc/pom.xml
index 4b3a713..d88e0c0 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>7.2.2-SNAPSHOT</version>
+    <version>7.3.1-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 18db66c..e51847e 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: 7.2.2.qualifier
+Bundle-Version: 7.3.1.qualifier
 Bundle-RequiredExecutionEnvironment: JavaSE-17
 Bundle-Localization: OSGI-INF/l10n/plugin
 Bundle-Vendor: %Bundle-Vendor
@@ -26,11 +26,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="[7.2.2,7.3.0)",
- org.eclipse.jgit.nls;version="[7.2.2,7.3.0)",
- org.eclipse.jgit.transport.http;version="[7.2.2,7.3.0)",
- org.eclipse.jgit.util;version="[7.2.2,7.3.0)"
-Export-Package: org.eclipse.jgit.transport.http.apache;version="7.2.2";
+ org.eclipse.jgit.annotations;version="[7.3.1,7.4.0)",
+ org.eclipse.jgit.nls;version="[7.3.1,7.4.0)",
+ org.eclipse.jgit.transport.http;version="[7.3.1,7.4.0)",
+ org.eclipse.jgit.util;version="[7.3.1,7.4.0)"
+Export-Package: org.eclipse.jgit.transport.http.apache;version="7.3.1";
   uses:="org.apache.http.client,
    org.eclipse.jgit.transport.http,
    org.apache.http.entity,
diff --git a/org.eclipse.jgit.http.apache/META-INF/SOURCE-MANIFEST.MF b/org.eclipse.jgit.http.apache/META-INF/SOURCE-MANIFEST.MF
index a4ec86e..7ab118c 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: 7.2.2.qualifier
-Eclipse-SourceBundle: org.eclipse.jgit.http.apache;version="7.2.2.qualifier";roots="."
+Bundle-Version: 7.3.1.qualifier
+Eclipse-SourceBundle: org.eclipse.jgit.http.apache;version="7.3.1.qualifier";roots="."
diff --git a/org.eclipse.jgit.http.apache/pom.xml b/org.eclipse.jgit.http.apache/pom.xml
index 963f5a4..15d1cbf 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>7.2.2-SNAPSHOT</version>
+    <version>7.3.1-SNAPSHOT</version>
   </parent>
 
   <artifactId>org.eclipse.jgit.http.apache</artifactId>
diff --git a/org.eclipse.jgit.http.server/META-INF/MANIFEST.MF b/org.eclipse.jgit.http.server/META-INF/MANIFEST.MF
index 418c2cb..5aef53f 100644
--- a/org.eclipse.jgit.http.server/META-INF/MANIFEST.MF
+++ b/org.eclipse.jgit.http.server/META-INF/MANIFEST.MF
@@ -3,14 +3,14 @@
 Bundle-Name: %Bundle-Name
 Automatic-Module-Name: org.eclipse.jgit.http.server
 Bundle-SymbolicName: org.eclipse.jgit.http.server
-Bundle-Version: 7.2.2.qualifier
+Bundle-Version: 7.3.1.qualifier
 Bundle-Localization: OSGI-INF/l10n/plugin
 Bundle-Vendor: %Bundle-Vendor
-Export-Package: org.eclipse.jgit.http.server;version="7.2.2",
- org.eclipse.jgit.http.server.glue;version="7.2.2";
+Export-Package: org.eclipse.jgit.http.server;version="7.3.1",
+ org.eclipse.jgit.http.server.glue;version="7.3.1";
   uses:="jakarta.servlet,
   	jakarta.servlet.http",
- org.eclipse.jgit.http.server.resolver;version="7.2.2";
+ org.eclipse.jgit.http.server.resolver;version="7.3.1";
   uses:="jakarta.servlet.http
    org.eclipse.jgit.transport.resolver,
    org.eclipse.jgit.lib,
@@ -19,14 +19,14 @@
 Bundle-RequiredExecutionEnvironment: JavaSE-17
 Import-Package: jakarta.servlet;version="[6.0.0,7.0.0)",
  jakarta.servlet.http;version="[6.0.0,7.0.0)",
- org.eclipse.jgit.annotations;version="[7.2.2,7.3.0)",
- org.eclipse.jgit.errors;version="[7.2.2,7.3.0)",
- org.eclipse.jgit.internal.storage.dfs;version="[7.2.2,7.3.0)",
- org.eclipse.jgit.internal.storage.file;version="[7.2.2,7.3.0)",
- org.eclipse.jgit.internal.transport.parser;version="[7.2.2,7.3.0)",
- org.eclipse.jgit.lib;version="[7.2.2,7.3.0)",
- org.eclipse.jgit.nls;version="[7.2.2,7.3.0)",
- org.eclipse.jgit.revwalk;version="[7.2.2,7.3.0)",
- org.eclipse.jgit.transport;version="[7.2.2,7.3.0)",
- org.eclipse.jgit.transport.resolver;version="[7.2.2,7.3.0)",
- org.eclipse.jgit.util;version="[7.2.2,7.3.0)"
+ org.eclipse.jgit.annotations;version="[7.3.1,7.4.0)",
+ org.eclipse.jgit.errors;version="[7.3.1,7.4.0)",
+ org.eclipse.jgit.internal.storage.dfs;version="[7.3.1,7.4.0)",
+ org.eclipse.jgit.internal.storage.file;version="[7.3.1,7.4.0)",
+ org.eclipse.jgit.internal.transport.parser;version="[7.3.1,7.4.0)",
+ org.eclipse.jgit.lib;version="[7.3.1,7.4.0)",
+ org.eclipse.jgit.nls;version="[7.3.1,7.4.0)",
+ org.eclipse.jgit.revwalk;version="[7.3.1,7.4.0)",
+ org.eclipse.jgit.transport;version="[7.3.1,7.4.0)",
+ org.eclipse.jgit.transport.resolver;version="[7.3.1,7.4.0)",
+ org.eclipse.jgit.util;version="[7.3.1,7.4.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 d1efc55..bac00c8 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: 7.2.2.qualifier
-Eclipse-SourceBundle: org.eclipse.jgit.http.server;version="7.2.2.qualifier";roots="."
+Bundle-Version: 7.3.1.qualifier
+Eclipse-SourceBundle: org.eclipse.jgit.http.server;version="7.3.1.qualifier";roots="."
diff --git a/org.eclipse.jgit.http.server/pom.xml b/org.eclipse.jgit.http.server/pom.xml
index a3f91b2..d5c7c3c 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>7.2.2-SNAPSHOT</version>
+    <version>7.3.1-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 618686f..5bc281e 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: 7.2.2.qualifier
+Bundle-Version: 7.3.1.qualifier
 Bundle-Vendor: %Bundle-Vendor
 Bundle-Localization: plugin
 Bundle-RequiredExecutionEnvironment: JavaSE-17
@@ -29,26 +29,26 @@
  org.eclipse.jetty.util.component;version="[12.0.0,13.0.0)",
  org.eclipse.jetty.util.security;version="[12.0.0,13.0.0)",
  org.eclipse.jetty.util.thread;version="[12.0.0,13.0.0)",
- org.eclipse.jgit.api;version="[7.2.2,7.3.0)",
- org.eclipse.jgit.errors;version="[7.2.2,7.3.0)",
- org.eclipse.jgit.http.server;version="[7.2.2,7.3.0)",
- org.eclipse.jgit.http.server.glue;version="[7.2.2,7.3.0)",
- org.eclipse.jgit.http.server.resolver;version="[7.2.2,7.3.0)",
- org.eclipse.jgit.internal;version="[7.2.2,7.3.0)",
- org.eclipse.jgit.internal.storage.dfs;version="[7.2.2,7.3.0)",
- org.eclipse.jgit.internal.storage.file;version="[7.2.2,7.3.0)",
- org.eclipse.jgit.internal.storage.reftable;version="[7.2.2,7.3.0)",
- org.eclipse.jgit.junit;version="[7.2.2,7.3.0)",
- org.eclipse.jgit.junit.http;version="[7.2.2,7.3.0)",
- org.eclipse.jgit.lib;version="[7.2.2,7.3.0)",
- org.eclipse.jgit.nls;version="[7.2.2,7.3.0)",
- org.eclipse.jgit.revwalk;version="[7.2.2,7.3.0)",
- org.eclipse.jgit.storage.file;version="[7.2.2,7.3.0)",
- org.eclipse.jgit.transport;version="[7.2.2,7.3.0)",
- org.eclipse.jgit.transport.http;version="[7.2.2,7.3.0)",
- org.eclipse.jgit.transport.http.apache;version="[7.2.2,7.3.0)",
- org.eclipse.jgit.transport.resolver;version="[7.2.2,7.3.0)",
- org.eclipse.jgit.util;version="[7.2.2,7.3.0)",
+ org.eclipse.jgit.api;version="[7.3.1,7.4.0)",
+ org.eclipse.jgit.errors;version="[7.3.1,7.4.0)",
+ org.eclipse.jgit.http.server;version="[7.3.1,7.4.0)",
+ org.eclipse.jgit.http.server.glue;version="[7.3.1,7.4.0)",
+ org.eclipse.jgit.http.server.resolver;version="[7.3.1,7.4.0)",
+ org.eclipse.jgit.internal;version="[7.3.1,7.4.0)",
+ org.eclipse.jgit.internal.storage.dfs;version="[7.3.1,7.4.0)",
+ org.eclipse.jgit.internal.storage.file;version="[7.3.1,7.4.0)",
+ org.eclipse.jgit.internal.storage.reftable;version="[7.3.1,7.4.0)",
+ org.eclipse.jgit.junit;version="[7.3.1,7.4.0)",
+ org.eclipse.jgit.junit.http;version="[7.3.1,7.4.0)",
+ org.eclipse.jgit.lib;version="[7.3.1,7.4.0)",
+ org.eclipse.jgit.nls;version="[7.3.1,7.4.0)",
+ org.eclipse.jgit.revwalk;version="[7.3.1,7.4.0)",
+ org.eclipse.jgit.storage.file;version="[7.3.1,7.4.0)",
+ org.eclipse.jgit.transport;version="[7.3.1,7.4.0)",
+ org.eclipse.jgit.transport.http;version="[7.3.1,7.4.0)",
+ org.eclipse.jgit.transport.http.apache;version="[7.3.1,7.4.0)",
+ org.eclipse.jgit.transport.resolver;version="[7.3.1,7.4.0)",
+ org.eclipse.jgit.util;version="[7.3.1,7.4.0)",
  org.junit;version="[4.13,5.0.0)",
  org.junit.rules;version="[4.13,5.0.0)",
  org.junit.runner;version="[4.13,5.0.0)",
diff --git a/org.eclipse.jgit.http.test/pom.xml b/org.eclipse.jgit.http.test/pom.xml
index fd9dbb8..2d9d074 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>7.2.2-SNAPSHOT</version>
+    <version>7.3.1-SNAPSHOT</version>
   </parent>
 
   <artifactId>org.eclipse.jgit.http.test</artifactId>
diff --git a/org.eclipse.jgit.junit.http/BUILD b/org.eclipse.jgit.junit.http/BUILD
index 5ddd0c8..66620ce 100644
--- a/org.eclipse.jgit.junit.http/BUILD
+++ b/org.eclipse.jgit.junit.http/BUILD
@@ -6,7 +6,7 @@
     name = "junit-http",
     testonly = 1,
     srcs = glob(["src/**/*.java"]),
-    resources = glob(["resources/**"]),
+    resources = glob(["resources/**"], allow_empty=True),
     # TODO(davido): we want here provided deps
     deps = [
         "//lib:jetty-http",
diff --git a/org.eclipse.jgit.junit.http/META-INF/MANIFEST.MF b/org.eclipse.jgit.junit.http/META-INF/MANIFEST.MF
index 09008d5..a8f49f4 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: 7.2.2.qualifier
+Bundle-Version: 7.3.1.qualifier
 Bundle-Localization: OSGI-INF/l10n/plugin
 Bundle-Vendor: %Bundle-Vendor
 Bundle-ActivationPolicy: lazy
@@ -22,17 +22,17 @@
  org.eclipse.jetty.util.component;version="[12.0.0,13.0.0)",
  org.eclipse.jetty.util.security;version="[12.0.0,13.0.0)",
  org.eclipse.jetty.util.ssl;version="[12.0.0,13.0.0)",
- org.eclipse.jgit.errors;version="[7.2.2,7.3.0)",
- org.eclipse.jgit.http.server;version="[7.2.2,7.3.0)",
- org.eclipse.jgit.internal.storage.file;version="[7.2.2,7.3.0)",
- org.eclipse.jgit.junit;version="[7.2.2,7.3.0)",
- org.eclipse.jgit.lib;version="[7.2.2,7.3.0)",
- org.eclipse.jgit.revwalk;version="[7.2.2,7.3.0)",
- org.eclipse.jgit.transport;version="[7.2.2,7.3.0)",
- org.eclipse.jgit.transport.resolver;version="[7.2.2,7.3.0)",
+ org.eclipse.jgit.errors;version="[7.3.1,7.4.0)",
+ org.eclipse.jgit.http.server;version="[7.3.1,7.4.0)",
+ org.eclipse.jgit.internal.storage.file;version="[7.3.1,7.4.0)",
+ org.eclipse.jgit.junit;version="[7.3.1,7.4.0)",
+ org.eclipse.jgit.lib;version="[7.3.1,7.4.0)",
+ org.eclipse.jgit.revwalk;version="[7.3.1,7.4.0)",
+ org.eclipse.jgit.transport;version="[7.3.1,7.4.0)",
+ org.eclipse.jgit.transport.resolver;version="[7.3.1,7.4.0)",
  org.junit;version="[4.13,5.0.0)",
  org.slf4j.helpers;version="[1.7.0,3.0.0)"
-Export-Package: org.eclipse.jgit.junit.http;version="7.2.2";
+Export-Package: org.eclipse.jgit.junit.http;version="7.3.1";
   uses:="org.eclipse.jgit.transport,
    jakarta.servlet,
    jakarta.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 c9b0ae7..361b249 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: 7.2.2.qualifier
-Eclipse-SourceBundle: org.eclipse.jgit.junit.http;version="7.2.2.qualifier";roots="."
+Bundle-Version: 7.3.1.qualifier
+Eclipse-SourceBundle: org.eclipse.jgit.junit.http;version="7.3.1.qualifier";roots="."
diff --git a/org.eclipse.jgit.junit.http/pom.xml b/org.eclipse.jgit.junit.http/pom.xml
index aab32f4..2cb8d3d 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>7.2.2-SNAPSHOT</version>
+    <version>7.3.1-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 7f255d7..f9321fa 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: 7.2.2.qualifier
+Bundle-Version: 7.3.1.qualifier
 Bundle-Localization: OSGI-INF/l10n/plugin
 Bundle-Vendor: %Bundle-Vendor
 Bundle-ActivationPolicy: lazy
@@ -33,16 +33,16 @@
  org.apache.sshd.server.subsystem;version="[2.15.0,2.16.0)",
  org.apache.sshd.sftp;version="[2.15.0,2.16.0)",
  org.apache.sshd.sftp.server;version="[2.15.0,2.16.0)",
- org.eclipse.jgit.annotations;version="[7.2.2,7.3.0)",
- org.eclipse.jgit.api;version="[7.2.2,7.3.0)",
- org.eclipse.jgit.api.errors;version="[7.2.2,7.3.0)",
- org.eclipse.jgit.errors;version="[7.2.2,7.3.0)",
- org.eclipse.jgit.junit;version="[7.2.2,7.3.0)",
- org.eclipse.jgit.lib;version="[7.2.2,7.3.0)",
- org.eclipse.jgit.revwalk;version="[7.2.2,7.3.0)",
- org.eclipse.jgit.transport;version="[7.2.2,7.3.0)",
- org.eclipse.jgit.util;version="[7.2.2,7.3.0)",
+ org.eclipse.jgit.annotations;version="[7.3.1,7.4.0)",
+ org.eclipse.jgit.api;version="[7.3.1,7.4.0)",
+ org.eclipse.jgit.api.errors;version="[7.3.1,7.4.0)",
+ org.eclipse.jgit.errors;version="[7.3.1,7.4.0)",
+ org.eclipse.jgit.junit;version="[7.3.1,7.4.0)",
+ org.eclipse.jgit.lib;version="[7.3.1,7.4.0)",
+ org.eclipse.jgit.revwalk;version="[7.3.1,7.4.0)",
+ org.eclipse.jgit.transport;version="[7.3.1,7.4.0)",
+ org.eclipse.jgit.util;version="[7.3.1,7.4.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,3.0.0)"
-Export-Package: org.eclipse.jgit.junit.ssh;version="7.2.2"
+Export-Package: org.eclipse.jgit.junit.ssh;version="7.3.1"
diff --git a/org.eclipse.jgit.junit.ssh/META-INF/SOURCE-MANIFEST.MF b/org.eclipse.jgit.junit.ssh/META-INF/SOURCE-MANIFEST.MF
index eea35bc..dd502ee 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: 7.2.2.qualifier
-Eclipse-SourceBundle: org.eclipse.jgit.junit.ssh;version="7.2.2.qualifier";roots="."
+Bundle-Version: 7.3.1.qualifier
+Eclipse-SourceBundle: org.eclipse.jgit.junit.ssh;version="7.3.1.qualifier";roots="."
diff --git a/org.eclipse.jgit.junit.ssh/pom.xml b/org.eclipse.jgit.junit.ssh/pom.xml
index 78afd40..cf4e5fc 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>7.2.2-SNAPSHOT</version>
+    <version>7.3.1-SNAPSHOT</version>
   </parent>
 
   <artifactId>org.eclipse.jgit.junit.ssh</artifactId>
diff --git a/org.eclipse.jgit.junit/BUILD b/org.eclipse.jgit.junit/BUILD
index 623c5be..f4a7165 100644
--- a/org.eclipse.jgit.junit/BUILD
+++ b/org.eclipse.jgit.junit/BUILD
@@ -7,7 +7,7 @@
     testonly = 1,
     srcs = glob(["src/**/*.java"]),
     resource_strip_prefix = "org.eclipse.jgit.junit/resources",
-    resources = glob(["resources/**"]),
+    resources = glob(["resources/**"], allow_empty=True),
     deps = [
         "//lib:junit",
         # We want these deps to be provided_deps
diff --git a/org.eclipse.jgit.junit/META-INF/MANIFEST.MF b/org.eclipse.jgit.junit/META-INF/MANIFEST.MF
index 2a84d0c..a2f10a1 100644
--- a/org.eclipse.jgit.junit/META-INF/MANIFEST.MF
+++ b/org.eclipse.jgit.junit/META-INF/MANIFEST.MF
@@ -3,36 +3,36 @@
 Bundle-Name: %Bundle-Name
 Automatic-Module-Name: org.eclipse.jgit.junit
 Bundle-SymbolicName: org.eclipse.jgit.junit
-Bundle-Version: 7.2.2.qualifier
+Bundle-Version: 7.3.1.qualifier
 Bundle-Localization: OSGI-INF/l10n/plugin
 Bundle-Vendor: %Bundle-Vendor
 Bundle-ActivationPolicy: lazy
 Bundle-RequiredExecutionEnvironment: JavaSE-17
-Import-Package: org.eclipse.jgit.annotations;version="[7.2.2,7.3.0)",
- org.eclipse.jgit.api;version="[7.2.2,7.3.0)",
- org.eclipse.jgit.api.errors;version="[7.2.2,7.3.0)",
- org.eclipse.jgit.dircache;version="[7.2.2,7.3.0)",
- org.eclipse.jgit.errors;version="[7.2.2,7.3.0)",
- org.eclipse.jgit.internal.storage.file;version="[7.2.2,7.3.0)",
- org.eclipse.jgit.internal.storage.pack;version="[7.2.2,7.3.0)",
- org.eclipse.jgit.internal.util;version="[7.2.2,7.3.0)",
- org.eclipse.jgit.lib;version="[7.2.2,7.3.0)",
- org.eclipse.jgit.merge;version="[7.2.2,7.3.0)",
- org.eclipse.jgit.revwalk;version="[7.2.2,7.3.0)",
- org.eclipse.jgit.storage.file;version="[7.2.2,7.3.0)",
- org.eclipse.jgit.transport;version="7.2.2",
- org.eclipse.jgit.treewalk;version="[7.2.2,7.3.0)",
- org.eclipse.jgit.treewalk.filter;version="[7.2.2,7.3.0)",
- org.eclipse.jgit.util;version="[7.2.2,7.3.0)",
- org.eclipse.jgit.util.io;version="[7.2.2,7.3.0)",
- org.eclipse.jgit.util.time;version="[7.2.2,7.3.0)",
+Import-Package: org.eclipse.jgit.annotations;version="[7.3.1,7.4.0)",
+ org.eclipse.jgit.api;version="[7.3.1,7.4.0)",
+ org.eclipse.jgit.api.errors;version="[7.3.1,7.4.0)",
+ org.eclipse.jgit.dircache;version="[7.3.1,7.4.0)",
+ org.eclipse.jgit.errors;version="[7.3.1,7.4.0)",
+ org.eclipse.jgit.internal.storage.file;version="[7.3.1,7.4.0)",
+ org.eclipse.jgit.internal.storage.pack;version="[7.3.1,7.4.0)",
+ org.eclipse.jgit.internal.util;version="[7.3.1,7.4.0)",
+ org.eclipse.jgit.lib;version="[7.3.1,7.4.0)",
+ org.eclipse.jgit.merge;version="[7.3.1,7.4.0)",
+ org.eclipse.jgit.revwalk;version="[7.3.1,7.4.0)",
+ org.eclipse.jgit.storage.file;version="[7.3.1,7.4.0)",
+ org.eclipse.jgit.transport;version="7.3.1",
+ org.eclipse.jgit.treewalk;version="[7.3.1,7.4.0)",
+ org.eclipse.jgit.treewalk.filter;version="[7.3.1,7.4.0)",
+ org.eclipse.jgit.util;version="[7.3.1,7.4.0)",
+ org.eclipse.jgit.util.io;version="[7.3.1,7.4.0)",
+ org.eclipse.jgit.util.time;version="[7.3.1,7.4.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,3.0.0)"
-Export-Package: org.eclipse.jgit.junit;version="7.2.2";
+Export-Package: org.eclipse.jgit.junit;version="7.3.1";
   uses:="org.eclipse.jgit.dircache,
    org.eclipse.jgit.lib,
    org.eclipse.jgit.revwalk,
@@ -45,4 +45,4 @@
    org.junit.runners.model,
    org.junit.runner,
    org.eclipse.jgit.util.time",
- org.eclipse.jgit.junit.time;version="7.2.2";uses:="org.eclipse.jgit.util.time"
+ org.eclipse.jgit.junit.time;version="7.3.1";uses:="org.eclipse.jgit.util.time"
diff --git a/org.eclipse.jgit.junit/META-INF/SOURCE-MANIFEST.MF b/org.eclipse.jgit.junit/META-INF/SOURCE-MANIFEST.MF
index ccf55a1..816c831 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: 7.2.2.qualifier
-Eclipse-SourceBundle: org.eclipse.jgit.junit;version="7.2.2.qualifier";roots="."
+Bundle-Version: 7.3.1.qualifier
+Eclipse-SourceBundle: org.eclipse.jgit.junit;version="7.3.1.qualifier";roots="."
diff --git a/org.eclipse.jgit.junit/pom.xml b/org.eclipse.jgit.junit/pom.xml
index be2e8bd..3841077 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>7.2.2-SNAPSHOT</version>
+    <version>7.3.1-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 f182089..5fd90b0 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: 7.2.2.qualifier
+Bundle-Version: 7.3.1.qualifier
 Bundle-Vendor: %Bundle-Vendor
 Bundle-Localization: plugin
 Bundle-RequiredExecutionEnvironment: JavaSE-17
@@ -26,24 +26,24 @@
  org.eclipse.jetty.util.component;version="[12.0.0,13.0.0)",
  org.eclipse.jetty.util.security;version="[12.0.0,13.0.0)",
  org.eclipse.jetty.util.thread;version="[12.0.0,13.0.0)",
- org.eclipse.jgit.api;version="[7.2.2,7.3.0)",
- org.eclipse.jgit.api.errors;version="[7.2.2,7.3.0)",
- org.eclipse.jgit.internal.storage.file;version="[7.2.2,7.3.0)",
- org.eclipse.jgit.junit;version="[7.2.2,7.3.0)",
- org.eclipse.jgit.junit.http;version="[7.2.2,7.3.0)",
- org.eclipse.jgit.lfs;version="[7.2.2,7.3.0)",
- org.eclipse.jgit.lfs.errors;version="[7.2.2,7.3.0)",
- org.eclipse.jgit.lfs.lib;version="[7.2.2,7.3.0)",
- org.eclipse.jgit.lfs.server;version="[7.2.2,7.3.0)",
- org.eclipse.jgit.lfs.server.fs;version="[7.2.2,7.3.0)",
- org.eclipse.jgit.lfs.test;version="[7.2.2,7.3.0)",
- org.eclipse.jgit.lib;version="[7.2.2,7.3.0)",
- org.eclipse.jgit.revwalk;version="[7.2.2,7.3.0)",
- org.eclipse.jgit.storage.file;version="[7.2.2,7.3.0)",
- org.eclipse.jgit.transport;version="[7.2.2,7.3.0)",
- org.eclipse.jgit.treewalk;version="[7.2.2,7.3.0)",
- org.eclipse.jgit.treewalk.filter;version="[7.2.2,7.3.0)",
- org.eclipse.jgit.util;version="[7.2.2,7.3.0)",
+ org.eclipse.jgit.api;version="[7.3.1,7.4.0)",
+ org.eclipse.jgit.api.errors;version="[7.3.1,7.4.0)",
+ org.eclipse.jgit.internal.storage.file;version="[7.3.1,7.4.0)",
+ org.eclipse.jgit.junit;version="[7.3.1,7.4.0)",
+ org.eclipse.jgit.junit.http;version="[7.3.1,7.4.0)",
+ org.eclipse.jgit.lfs;version="[7.3.1,7.4.0)",
+ org.eclipse.jgit.lfs.errors;version="[7.3.1,7.4.0)",
+ org.eclipse.jgit.lfs.lib;version="[7.3.1,7.4.0)",
+ org.eclipse.jgit.lfs.server;version="[7.3.1,7.4.0)",
+ org.eclipse.jgit.lfs.server.fs;version="[7.3.1,7.4.0)",
+ org.eclipse.jgit.lfs.test;version="[7.3.1,7.4.0)",
+ org.eclipse.jgit.lib;version="[7.3.1,7.4.0)",
+ org.eclipse.jgit.revwalk;version="[7.3.1,7.4.0)",
+ org.eclipse.jgit.storage.file;version="[7.3.1,7.4.0)",
+ org.eclipse.jgit.transport;version="[7.3.1,7.4.0)",
+ org.eclipse.jgit.treewalk;version="[7.3.1,7.4.0)",
+ org.eclipse.jgit.treewalk.filter;version="[7.3.1,7.4.0)",
+ org.eclipse.jgit.util;version="[7.3.1,7.4.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 d06a23f..5eafde3 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>7.2.2-SNAPSHOT</version>
+    <version>7.3.1-SNAPSHOT</version>
   </parent>
 
   <artifactId>org.eclipse.jgit.lfs.server.test</artifactId>
diff --git a/org.eclipse.jgit.lfs.server/META-INF/MANIFEST.MF b/org.eclipse.jgit.lfs.server/META-INF/MANIFEST.MF
index 54bdb66..8bb770d 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: 7.2.2.qualifier
+Bundle-Version: 7.3.1.qualifier
 Bundle-Localization: OSGI-INF/l10n/plugin
 Bundle-Vendor: %Bundle-Vendor
-Export-Package: org.eclipse.jgit.lfs.server;version="7.2.2";
+Export-Package: org.eclipse.jgit.lfs.server;version="7.3.1";
   uses:="jakarta.servlet.http,
    org.eclipse.jgit.lfs.lib",
- org.eclipse.jgit.lfs.server.fs;version="7.2.2";
+ org.eclipse.jgit.lfs.server.fs;version="7.3.1";
   uses:="jakarta.servlet,
    jakarta.servlet.http,
    org.eclipse.jgit.lfs.server,
    org.eclipse.jgit.lfs.lib",
- org.eclipse.jgit.lfs.server.internal;version="7.2.2";x-internal:=true,
- org.eclipse.jgit.lfs.server.s3;version="7.2.2";
+ org.eclipse.jgit.lfs.server.internal;version="7.3.1";x-internal:=true,
+ org.eclipse.jgit.lfs.server.s3;version="7.3.1";
   uses:="org.eclipse.jgit.lfs.server,
    org.eclipse.jgit.lfs.lib"
 Bundle-RequiredExecutionEnvironment: JavaSE-17
@@ -24,15 +24,15 @@
  jakarta.servlet.annotation;version="[6.0.0,7.0.0)",
  jakarta.servlet.http;version="[6.0.0,7.0.0)",
  org.apache.http;version="[4.3.0,5.0.0)",
- org.eclipse.jgit.annotations;version="[7.2.2,7.3.0)",
- org.eclipse.jgit.internal;version="[7.2.2,7.3.0)",
- org.eclipse.jgit.internal.storage.file;version="[7.2.2,7.3.0)",
- org.eclipse.jgit.lfs.errors;version="[7.2.2,7.3.0)",
- org.eclipse.jgit.lfs.internal;version="[7.2.2,7.3.0)",
- org.eclipse.jgit.lfs.lib;version="[7.2.2,7.3.0)",
- org.eclipse.jgit.lib;version="[7.2.2,7.3.0)",
- org.eclipse.jgit.nls;version="[7.2.2,7.3.0)",
- org.eclipse.jgit.transport.http;version="[7.2.2,7.3.0)",
- org.eclipse.jgit.transport.http.apache;version="[7.2.2,7.3.0)",
- org.eclipse.jgit.util;version="[7.2.2,7.3.0)",
+ org.eclipse.jgit.annotations;version="[7.3.1,7.4.0)",
+ org.eclipse.jgit.internal;version="[7.3.1,7.4.0)",
+ org.eclipse.jgit.internal.storage.file;version="[7.3.1,7.4.0)",
+ org.eclipse.jgit.lfs.errors;version="[7.3.1,7.4.0)",
+ org.eclipse.jgit.lfs.internal;version="[7.3.1,7.4.0)",
+ org.eclipse.jgit.lfs.lib;version="[7.3.1,7.4.0)",
+ org.eclipse.jgit.lib;version="[7.3.1,7.4.0)",
+ org.eclipse.jgit.nls;version="[7.3.1,7.4.0)",
+ org.eclipse.jgit.transport.http;version="[7.3.1,7.4.0)",
+ org.eclipse.jgit.transport.http.apache;version="[7.3.1,7.4.0)",
+ org.eclipse.jgit.util;version="[7.3.1,7.4.0)",
  org.slf4j;version="[1.7.0,3.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 6b1e70f..718c569 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: 7.2.2.qualifier
-Eclipse-SourceBundle: org.eclipse.jgit.lfs.server;version="7.2.2.qualifier";roots="."
+Bundle-Version: 7.3.1.qualifier
+Eclipse-SourceBundle: org.eclipse.jgit.lfs.server;version="7.3.1.qualifier";roots="."
diff --git a/org.eclipse.jgit.lfs.server/pom.xml b/org.eclipse.jgit.lfs.server/pom.xml
index af5af36..784b24a 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>7.2.2-SNAPSHOT</version>
+    <version>7.3.1-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 ac4c493..c0bde2f 100644
--- a/org.eclipse.jgit.lfs.test/META-INF/MANIFEST.MF
+++ b/org.eclipse.jgit.lfs.test/META-INF/MANIFEST.MF
@@ -3,28 +3,28 @@
 Bundle-Name: %Bundle-Name
 Automatic-Module-Name: org.eclipse.jgit.lfs.test
 Bundle-SymbolicName: org.eclipse.jgit.lfs.test
-Bundle-Version: 7.2.2.qualifier
+Bundle-Version: 7.3.1.qualifier
 Bundle-Vendor: %Bundle-Vendor
 Bundle-Localization: plugin
 Bundle-RequiredExecutionEnvironment: JavaSE-17
-Import-Package: org.eclipse.jgit.api;version="[7.2.2,7.3.0)",
- org.eclipse.jgit.attributes;version="[7.2.2,7.3.0)",
- org.eclipse.jgit.internal.storage.dfs;version="[7.2.2,7.3.0)",
- org.eclipse.jgit.internal.storage.file;version="[7.2.2,7.3.0)",
- org.eclipse.jgit.junit;version="[7.2.2,7.3.0)",
- org.eclipse.jgit.lfs;version="[7.2.2,7.3.0)",
- org.eclipse.jgit.lfs.errors;version="[7.2.2,7.3.0)",
- org.eclipse.jgit.lfs.internal;version="[7.2.2,7.3.0)",
- org.eclipse.jgit.lfs.lib;version="[7.2.2,7.3.0)",
- org.eclipse.jgit.lib;version="[7.2.2,7.3.0)",
- org.eclipse.jgit.revwalk;version="[7.2.2,7.3.0)",
- org.eclipse.jgit.transport;version="[7.2.2,7.3.0)",
- org.eclipse.jgit.transport.http;version="[7.2.2,7.3.0)",
- org.eclipse.jgit.treewalk;version="[7.2.2,7.3.0)",
- org.eclipse.jgit.treewalk.filter;version="[7.2.2,7.3.0)",
- org.eclipse.jgit.util;version="[7.2.2,7.3.0)",
+Import-Package: org.eclipse.jgit.api;version="[7.3.1,7.4.0)",
+ org.eclipse.jgit.attributes;version="[7.3.1,7.4.0)",
+ org.eclipse.jgit.internal.storage.dfs;version="[7.3.1,7.4.0)",
+ org.eclipse.jgit.internal.storage.file;version="[7.3.1,7.4.0)",
+ org.eclipse.jgit.junit;version="[7.3.1,7.4.0)",
+ org.eclipse.jgit.lfs;version="[7.3.1,7.4.0)",
+ org.eclipse.jgit.lfs.errors;version="[7.3.1,7.4.0)",
+ org.eclipse.jgit.lfs.internal;version="[7.3.1,7.4.0)",
+ org.eclipse.jgit.lfs.lib;version="[7.3.1,7.4.0)",
+ org.eclipse.jgit.lib;version="[7.3.1,7.4.0)",
+ org.eclipse.jgit.revwalk;version="[7.3.1,7.4.0)",
+ org.eclipse.jgit.transport;version="[7.3.1,7.4.0)",
+ org.eclipse.jgit.transport.http;version="[7.3.1,7.4.0)",
+ org.eclipse.jgit.treewalk;version="[7.3.1,7.4.0)",
+ org.eclipse.jgit.treewalk.filter;version="[7.3.1,7.4.0)",
+ org.eclipse.jgit.util;version="[7.3.1,7.4.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="7.2.2";x-friends:="org.eclipse.jgit.lfs.server.test"
+Export-Package: org.eclipse.jgit.lfs.test;version="7.3.1";x-friends:="org.eclipse.jgit.lfs.server.test"
diff --git a/org.eclipse.jgit.lfs.test/pom.xml b/org.eclipse.jgit.lfs.test/pom.xml
index 087caa4..e0e997e 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>7.2.2-SNAPSHOT</version>
+    <version>7.3.1-SNAPSHOT</version>
   </parent>
 
   <artifactId>org.eclipse.jgit.lfs.test</artifactId>
diff --git a/org.eclipse.jgit.lfs/META-INF/MANIFEST.MF b/org.eclipse.jgit.lfs/META-INF/MANIFEST.MF
index fdcde49..ad6a252 100644
--- a/org.eclipse.jgit.lfs/META-INF/MANIFEST.MF
+++ b/org.eclipse.jgit.lfs/META-INF/MANIFEST.MF
@@ -3,32 +3,32 @@
 Bundle-Name: %Bundle-Name
 Automatic-Module-Name: org.eclipse.jgit.lfs
 Bundle-SymbolicName: org.eclipse.jgit.lfs
-Bundle-Version: 7.2.2.qualifier
+Bundle-Version: 7.3.1.qualifier
 Bundle-Localization: OSGI-INF/l10n/plugin
 Bundle-Vendor: %Bundle-Vendor
-Export-Package: org.eclipse.jgit.lfs;version="7.2.2",
- org.eclipse.jgit.lfs.errors;version="7.2.2",
- org.eclipse.jgit.lfs.internal;version="7.2.2";x-friends:="org.eclipse.jgit.lfs.test,org.eclipse.jgit.lfs.server.fs,org.eclipse.jgit.lfs.server",
- org.eclipse.jgit.lfs.lib;version="7.2.2"
+Export-Package: org.eclipse.jgit.lfs;version="7.3.1",
+ org.eclipse.jgit.lfs.errors;version="7.3.1",
+ org.eclipse.jgit.lfs.internal;version="7.3.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="7.3.1"
 Bundle-RequiredExecutionEnvironment: JavaSE-17
 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="[7.2.2,7.3.0)";resolution:=optional,
- org.eclipse.jgit.api.errors;version="[7.2.2,7.3.0)",
- org.eclipse.jgit.attributes;version="[7.2.2,7.3.0)",
- org.eclipse.jgit.diff;version="[7.2.2,7.3.0)",
- org.eclipse.jgit.dircache;version="[7.2.2,7.3.0)",
- org.eclipse.jgit.errors;version="[7.2.2,7.3.0)",
- org.eclipse.jgit.hooks;version="[7.2.2,7.3.0)",
- org.eclipse.jgit.internal.storage.file;version="[7.2.2,7.3.0)",
- org.eclipse.jgit.lib;version="[7.2.2,7.3.0)",
- org.eclipse.jgit.nls;version="[7.2.2,7.3.0)",
- org.eclipse.jgit.revwalk;version="[7.2.2,7.3.0)",
- org.eclipse.jgit.storage.file;version="[7.2.2,7.3.0)",
- org.eclipse.jgit.storage.pack;version="[7.2.2,7.3.0)",
- org.eclipse.jgit.transport;version="[7.2.2,7.3.0)",
- org.eclipse.jgit.transport.http;version="[7.2.2,7.3.0)",
- org.eclipse.jgit.treewalk;version="[7.2.2,7.3.0)",
- org.eclipse.jgit.treewalk.filter;version="[7.2.2,7.3.0)",
- org.eclipse.jgit.util;version="[7.2.2,7.3.0)",
- org.eclipse.jgit.util.io;version="[7.2.2,7.3.0)"
+ org.eclipse.jgit.annotations;version="[7.3.1,7.4.0)";resolution:=optional,
+ org.eclipse.jgit.api.errors;version="[7.3.1,7.4.0)",
+ org.eclipse.jgit.attributes;version="[7.3.1,7.4.0)",
+ org.eclipse.jgit.diff;version="[7.3.1,7.4.0)",
+ org.eclipse.jgit.dircache;version="[7.3.1,7.4.0)",
+ org.eclipse.jgit.errors;version="[7.3.1,7.4.0)",
+ org.eclipse.jgit.hooks;version="[7.3.1,7.4.0)",
+ org.eclipse.jgit.internal.storage.file;version="[7.3.1,7.4.0)",
+ org.eclipse.jgit.lib;version="[7.3.1,7.4.0)",
+ org.eclipse.jgit.nls;version="[7.3.1,7.4.0)",
+ org.eclipse.jgit.revwalk;version="[7.3.1,7.4.0)",
+ org.eclipse.jgit.storage.file;version="[7.3.1,7.4.0)",
+ org.eclipse.jgit.storage.pack;version="[7.3.1,7.4.0)",
+ org.eclipse.jgit.transport;version="[7.3.1,7.4.0)",
+ org.eclipse.jgit.transport.http;version="[7.3.1,7.4.0)",
+ org.eclipse.jgit.treewalk;version="[7.3.1,7.4.0)",
+ org.eclipse.jgit.treewalk.filter;version="[7.3.1,7.4.0)",
+ org.eclipse.jgit.util;version="[7.3.1,7.4.0)",
+ org.eclipse.jgit.util.io;version="[7.3.1,7.4.0)"
diff --git a/org.eclipse.jgit.lfs/META-INF/SOURCE-MANIFEST.MF b/org.eclipse.jgit.lfs/META-INF/SOURCE-MANIFEST.MF
index 630559d..3d1bcb2 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: 7.2.2.qualifier
-Eclipse-SourceBundle: org.eclipse.jgit.lfs;version="7.2.2.qualifier";roots="."
+Bundle-Version: 7.3.1.qualifier
+Eclipse-SourceBundle: org.eclipse.jgit.lfs;version="7.3.1.qualifier";roots="."
diff --git a/org.eclipse.jgit.lfs/pom.xml b/org.eclipse.jgit.lfs/pom.xml
index 2eb7774..14a24c7 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>7.2.2-SNAPSHOT</version>
+    <version>7.3.1-SNAPSHOT</version>
   </parent>
 
   <artifactId>org.eclipse.jgit.lfs</artifactId>
diff --git a/org.eclipse.jgit.packaging/org.eclipse.jgit.feature/feature.xml b/org.eclipse.jgit.packaging/org.eclipse.jgit.feature/feature.xml
index 462274a..cfc31f8 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="7.2.2.qualifier"
+      version="7.3.1.qualifier"
       provider-name="%providerName">
 
    <description url="http://www.eclipse.org/jgit/">
diff --git a/org.eclipse.jgit.packaging/org.eclipse.jgit.feature/pom.xml b/org.eclipse.jgit.packaging/org.eclipse.jgit.feature/pom.xml
index 3635bb2..5eecfc3 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>7.2.2-SNAPSHOT</version>
+    <version>7.3.1-SNAPSHOT</version>
   </parent>
 
   <groupId>org.eclipse.jgit.feature</groupId>
diff --git a/org.eclipse.jgit.packaging/org.eclipse.jgit.gpg.bc.feature/feature.xml b/org.eclipse.jgit.packaging/org.eclipse.jgit.gpg.bc.feature/feature.xml
index bbe0ad8..42d065a 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="7.2.2.qualifier"
+      version="7.3.1.qualifier"
       provider-name="%providerName">
 
    <description url="http://www.eclipse.org/jgit/">
@@ -23,7 +23,7 @@
    </url>
 
    <requires>
-      <import plugin="org.eclipse.jgit" version="7.2.2" match="equivalent"/>
+      <import plugin="org.eclipse.jgit" version="7.3.1" match="equivalent"/>
    </requires>
 
    <plugin
diff --git a/org.eclipse.jgit.packaging/org.eclipse.jgit.gpg.bc.feature/pom.xml b/org.eclipse.jgit.packaging/org.eclipse.jgit.gpg.bc.feature/pom.xml
index 0ec9ab7..b31ed31 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>7.2.2-SNAPSHOT</version>
+    <version>7.3.1-SNAPSHOT</version>
   </parent>
 
   <groupId>org.eclipse.jgit.feature</groupId>
diff --git a/org.eclipse.jgit.packaging/org.eclipse.jgit.http.apache.feature/feature.xml b/org.eclipse.jgit.packaging/org.eclipse.jgit.http.apache.feature/feature.xml
index a3d06d9..7833d7d 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="7.2.2.qualifier"
+      version="7.3.1.qualifier"
       provider-name="%providerName">
 
    <description url="http://www.eclipse.org/jgit/">
@@ -23,7 +23,7 @@
    </url>
 
    <requires>
-      <import plugin="org.eclipse.jgit" version="7.2.2" match="equivalent"/>
+      <import plugin="org.eclipse.jgit" version="7.3.1" match="equivalent"/>
    </requires>
 
    <plugin
diff --git a/org.eclipse.jgit.packaging/org.eclipse.jgit.http.apache.feature/pom.xml b/org.eclipse.jgit.packaging/org.eclipse.jgit.http.apache.feature/pom.xml
index ca96a64..e288ea6 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>7.2.2-SNAPSHOT</version>
+    <version>7.3.1-SNAPSHOT</version>
   </parent>
 
   <groupId>org.eclipse.jgit.feature</groupId>
diff --git a/org.eclipse.jgit.packaging/org.eclipse.jgit.junit.feature/feature.xml b/org.eclipse.jgit.packaging/org.eclipse.jgit.junit.feature/feature.xml
index 54051cd..a5a1d3d 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="7.2.2.qualifier"
+      version="7.3.1.qualifier"
       provider-name="%providerName">
 
    <description url="http://www.eclipse.org/jgit/">
@@ -24,7 +24,7 @@
 
    <requires>
       <import plugin="com.jcraft.jsch"/>
-      <import plugin="org.eclipse.jgit" version="7.2.2" match="equivalent"/>
+      <import plugin="org.eclipse.jgit" version="7.3.1" match="equivalent"/>
    </requires>
 
    <plugin
diff --git a/org.eclipse.jgit.packaging/org.eclipse.jgit.junit.feature/pom.xml b/org.eclipse.jgit.packaging/org.eclipse.jgit.junit.feature/pom.xml
index bd15173..d2ab65b 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>7.2.2-SNAPSHOT</version>
+    <version>7.3.1-SNAPSHOT</version>
   </parent>
 
   <groupId>org.eclipse.jgit.feature</groupId>
diff --git a/org.eclipse.jgit.packaging/org.eclipse.jgit.lfs.feature/feature.xml b/org.eclipse.jgit.packaging/org.eclipse.jgit.lfs.feature/feature.xml
index 1e4fd55..765bf38 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="7.2.2.qualifier"
+      version="7.3.1.qualifier"
       provider-name="%providerName">
 
    <description url="http://www.eclipse.org/jgit/">
@@ -23,7 +23,7 @@
    </url>
 
    <requires>
-      <import feature="org.eclipse.jgit" version="7.2.2" match="equivalent"/>
+      <import feature="org.eclipse.jgit" version="7.3.1" match="equivalent"/>
    </requires>
 
    <plugin
diff --git a/org.eclipse.jgit.packaging/org.eclipse.jgit.lfs.feature/pom.xml b/org.eclipse.jgit.packaging/org.eclipse.jgit.lfs.feature/pom.xml
index 794932d..3904873 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>7.2.2-SNAPSHOT</version>
+    <version>7.3.1-SNAPSHOT</version>
   </parent>
 
   <groupId>org.eclipse.jgit.feature</groupId>
diff --git a/org.eclipse.jgit.packaging/org.eclipse.jgit.pgm.feature/feature.xml b/org.eclipse.jgit.packaging/org.eclipse.jgit.pgm.feature/feature.xml
index 30e92cb..1a204f7 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="7.2.2.qualifier"
+      version="7.3.1.qualifier"
       provider-name="%providerName">
 
    <description url="http://www.eclipse.org/jgit/">
@@ -35,9 +35,9 @@
          version="0.0.0"/>
 
    <requires>
-      <import feature="org.eclipse.jgit" version="7.2.2" match="equivalent"/>
-      <import feature="org.eclipse.jgit.lfs" version="7.2.2" match="equivalent"/>
-      <import feature="org.eclipse.jgit.ssh.apache" version="7.2.2" match="equivalent"/>
+      <import feature="org.eclipse.jgit" version="7.3.1" match="equivalent"/>
+      <import feature="org.eclipse.jgit.lfs" version="7.3.1" match="equivalent"/>
+      <import feature="org.eclipse.jgit.ssh.apache" version="7.3.1" match="equivalent"/>
    </requires>
 
    <plugin
diff --git a/org.eclipse.jgit.packaging/org.eclipse.jgit.pgm.feature/pom.xml b/org.eclipse.jgit.packaging/org.eclipse.jgit.pgm.feature/pom.xml
index 04c0550..f28b697 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>7.2.2-SNAPSHOT</version>
+    <version>7.3.1-SNAPSHOT</version>
   </parent>
 
   <groupId>org.eclipse.jgit.feature</groupId>
diff --git a/org.eclipse.jgit.packaging/org.eclipse.jgit.repository/pom.xml b/org.eclipse.jgit.packaging/org.eclipse.jgit.repository/pom.xml
index 6c36c39..d03b30b 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>7.2.2-SNAPSHOT</version>
+    <version>7.3.1-SNAPSHOT</version>
   </parent>
 
   <artifactId>org.eclipse.jgit.repository</artifactId>
diff --git a/org.eclipse.jgit.packaging/org.eclipse.jgit.source.feature/feature.xml b/org.eclipse.jgit.packaging/org.eclipse.jgit.source.feature/feature.xml
index bd49058..02d07da 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="7.2.2.qualifier"
+      version="7.3.1.qualifier"
       provider-name="%providerName">
 
    <description url="http://www.eclipse.org/jgit/">
@@ -23,7 +23,7 @@
    </url>
 
    <requires>
-      <import feature="org.eclipse.jgit" version="7.2.2" match="equivalent"/>
+      <import feature="org.eclipse.jgit" version="7.3.1" match="equivalent"/>
    </requires>
 
    <plugin
diff --git a/org.eclipse.jgit.packaging/org.eclipse.jgit.source.feature/pom.xml b/org.eclipse.jgit.packaging/org.eclipse.jgit.source.feature/pom.xml
index 7ffa079..508dc4b 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>7.2.2-SNAPSHOT</version>
+    <version>7.3.1-SNAPSHOT</version>
   </parent>
 
   <groupId>org.eclipse.jgit.feature</groupId>
@@ -30,7 +30,7 @@
     <dependency>
       <groupId>org.eclipse.jgit.feature</groupId>
       <artifactId>org.eclipse.jgit</artifactId>
-      <version>7.2.2-SNAPSHOT</version>
+      <version>7.3.1-SNAPSHOT</version>
     </dependency>
   </dependencies>
 
diff --git a/org.eclipse.jgit.packaging/org.eclipse.jgit.ssh.apache.feature/feature.xml b/org.eclipse.jgit.packaging/org.eclipse.jgit.ssh.apache.feature/feature.xml
index 1b3d932..4cc7919 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="7.2.2.qualifier"
+      version="7.3.1.qualifier"
       provider-name="%providerName">
 
    <description url="http://www.eclipse.org/jgit/">
@@ -23,7 +23,7 @@
    </url>
 
    <requires>
-      <import feature="org.eclipse.jgit" version="7.2.2" match="equivalent"/>
+      <import feature="org.eclipse.jgit" version="7.3.1" match="equivalent"/>
    </requires>
 
    <plugin
diff --git a/org.eclipse.jgit.packaging/org.eclipse.jgit.ssh.apache.feature/pom.xml b/org.eclipse.jgit.packaging/org.eclipse.jgit.ssh.apache.feature/pom.xml
index 7e4fb07..f4e1f93 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>7.2.2-SNAPSHOT</version>
+    <version>7.3.1-SNAPSHOT</version>
   </parent>
 
   <groupId>org.eclipse.jgit.feature</groupId>
diff --git a/org.eclipse.jgit.packaging/org.eclipse.jgit.ssh.jsch.feature/feature.xml b/org.eclipse.jgit.packaging/org.eclipse.jgit.ssh.jsch.feature/feature.xml
index ccac152..ab958ff 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="7.2.2.qualifier"
+      version="7.3.1.qualifier"
       provider-name="%providerName">
 
    <description url="http://www.eclipse.org/jgit/">
@@ -23,7 +23,7 @@
    </url>
 
    <requires>
-      <import plugin="org.eclipse.jgit" version="7.2.2" match="equivalent"/>
+      <import plugin="org.eclipse.jgit" version="7.3.1" match="equivalent"/>
    </requires>
 
    <plugin
diff --git a/org.eclipse.jgit.packaging/org.eclipse.jgit.ssh.jsch.feature/pom.xml b/org.eclipse.jgit.packaging/org.eclipse.jgit.ssh.jsch.feature/pom.xml
index d661464..e8df5e4 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>7.2.2-SNAPSHOT</version>
+    <version>7.3.1-SNAPSHOT</version>
   </parent>
 
   <groupId>org.eclipse.jgit.feature</groupId>
diff --git a/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.32.target b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.32.target
index 60baf0b..58c0834 100644
--- a/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.32.target
+++ b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.32.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.32" sequenceNumber="1740521280">
+<target name="jgit-4.32" sequenceNumber="1747840563">
   <locations>
     <location includeMode="slicer" includeAllPlatforms="false" includeSource="true" includeConfigurePhase="true" type="InstallableUnit">
       <unit id="com.jcraft.jsch" version="0.1.55.v20230916-1400"/>
@@ -77,7 +77,7 @@
         <dependency>
           <groupId>org.mockito</groupId>
           <artifactId>mockito-core</artifactId>
-          <version>5.15.2</version>
+          <version>5.18.0</version>
           <type>jar</type>
         </dependency>
       </dependencies>
@@ -87,13 +87,13 @@
         <dependency>
           <groupId>net.java.dev.jna</groupId>
           <artifactId>jna</artifactId>
-          <version>5.16.0</version>
+          <version>5.17.0</version>
           <type>jar</type>
         </dependency>
         <dependency>
           <groupId>net.java.dev.jna</groupId>
           <artifactId>jna-platform</artifactId>
-          <version>5.16.0</version>
+          <version>5.17.0</version>
           <type>jar</type>
         </dependency>
       </dependencies>
@@ -103,49 +103,49 @@
         <dependency>
           <groupId>org.eclipse.jetty.ee10</groupId>
           <artifactId>jetty-ee10-servlet</artifactId>
-          <version>12.0.16</version>
+          <version>12.0.21</version>
           <type>jar</type>
         </dependency>
         <dependency>
           <groupId>org.eclipse.jetty</groupId>
           <artifactId>jetty-http</artifactId>
-          <version>12.0.16</version>
+          <version>12.0.21</version>
           <type>jar</type>
         </dependency>
         <dependency>
           <groupId>org.eclipse.jetty</groupId>
           <artifactId>jetty-io</artifactId>
-          <version>12.0.16</version>
+          <version>12.0.21</version>
           <type>jar</type>
         </dependency>
         <dependency>
           <groupId>org.eclipse.jetty</groupId>
           <artifactId>jetty-security</artifactId>
-          <version>12.0.16</version>
+          <version>12.0.21</version>
           <type>jar</type>
         </dependency>
         <dependency>
           <groupId>org.eclipse.jetty</groupId>
           <artifactId>jetty-server</artifactId>
-          <version>12.0.16</version>
+          <version>12.0.21</version>
           <type>jar</type>
         </dependency>
         <dependency>
           <groupId>org.eclipse.jetty</groupId>
           <artifactId>jetty-session</artifactId>
-          <version>12.0.16</version>
+          <version>12.0.21</version>
           <type>jar</type>
         </dependency>
         <dependency>
           <groupId>org.eclipse.jetty</groupId>
           <artifactId>jetty-util</artifactId>
-          <version>12.0.16</version>
+          <version>12.0.21</version>
           <type>jar</type>
         </dependency>
         <dependency>
           <groupId>org.eclipse.jetty</groupId>
           <artifactId>jetty-util-ajax</artifactId>
-          <version>12.0.16</version>
+          <version>12.0.21</version>
           <type>jar</type>
         </dependency>
         <dependency>
@@ -181,7 +181,7 @@
         <dependency>
           <groupId>com.google.code.gson</groupId>
           <artifactId>gson</artifactId>
-          <version>2.12.1</version>
+          <version>2.13.1</version>
           <type>jar</type>
         </dependency>
       </dependencies>
@@ -191,13 +191,13 @@
         <dependency>
           <groupId>net.bytebuddy</groupId>
           <artifactId>byte-buddy</artifactId>
-          <version>1.17.1</version>
+          <version>1.17.5</version>
           <type>jar</type>
         </dependency>
         <dependency>
           <groupId>net.bytebuddy</groupId>
           <artifactId>byte-buddy-agent</artifactId>
-          <version>1.17.1</version>
+          <version>1.17.5</version>
           <type>jar</type>
         </dependency>
       </dependencies>
@@ -273,7 +273,7 @@
         <dependency>
           <groupId>commons-io</groupId>
           <artifactId>commons-io</artifactId>
-          <version>2.18.0</version>
+          <version>2.19.0</version>
           <type>jar</type>
         </dependency>
         <dependency>
diff --git a/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.33.target b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.33.target
index 1558ad6..41d2027 100644
--- a/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.33.target
+++ b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.33.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.33" sequenceNumber="1740521283">
+<target name="jgit-4.33" sequenceNumber="1747840563">
   <locations>
     <location includeMode="slicer" includeAllPlatforms="false" includeSource="true" includeConfigurePhase="true" type="InstallableUnit">
       <unit id="com.jcraft.jsch" version="0.1.55.v20230916-1400"/>
@@ -77,7 +77,7 @@
         <dependency>
           <groupId>org.mockito</groupId>
           <artifactId>mockito-core</artifactId>
-          <version>5.15.2</version>
+          <version>5.18.0</version>
           <type>jar</type>
         </dependency>
       </dependencies>
@@ -87,13 +87,13 @@
         <dependency>
           <groupId>net.java.dev.jna</groupId>
           <artifactId>jna</artifactId>
-          <version>5.16.0</version>
+          <version>5.17.0</version>
           <type>jar</type>
         </dependency>
         <dependency>
           <groupId>net.java.dev.jna</groupId>
           <artifactId>jna-platform</artifactId>
-          <version>5.16.0</version>
+          <version>5.17.0</version>
           <type>jar</type>
         </dependency>
       </dependencies>
@@ -103,49 +103,49 @@
         <dependency>
           <groupId>org.eclipse.jetty.ee10</groupId>
           <artifactId>jetty-ee10-servlet</artifactId>
-          <version>12.0.16</version>
+          <version>12.0.21</version>
           <type>jar</type>
         </dependency>
         <dependency>
           <groupId>org.eclipse.jetty</groupId>
           <artifactId>jetty-http</artifactId>
-          <version>12.0.16</version>
+          <version>12.0.21</version>
           <type>jar</type>
         </dependency>
         <dependency>
           <groupId>org.eclipse.jetty</groupId>
           <artifactId>jetty-io</artifactId>
-          <version>12.0.16</version>
+          <version>12.0.21</version>
           <type>jar</type>
         </dependency>
         <dependency>
           <groupId>org.eclipse.jetty</groupId>
           <artifactId>jetty-security</artifactId>
-          <version>12.0.16</version>
+          <version>12.0.21</version>
           <type>jar</type>
         </dependency>
         <dependency>
           <groupId>org.eclipse.jetty</groupId>
           <artifactId>jetty-server</artifactId>
-          <version>12.0.16</version>
+          <version>12.0.21</version>
           <type>jar</type>
         </dependency>
         <dependency>
           <groupId>org.eclipse.jetty</groupId>
           <artifactId>jetty-session</artifactId>
-          <version>12.0.16</version>
+          <version>12.0.21</version>
           <type>jar</type>
         </dependency>
         <dependency>
           <groupId>org.eclipse.jetty</groupId>
           <artifactId>jetty-util</artifactId>
-          <version>12.0.16</version>
+          <version>12.0.21</version>
           <type>jar</type>
         </dependency>
         <dependency>
           <groupId>org.eclipse.jetty</groupId>
           <artifactId>jetty-util-ajax</artifactId>
-          <version>12.0.16</version>
+          <version>12.0.21</version>
           <type>jar</type>
         </dependency>
         <dependency>
@@ -181,7 +181,7 @@
         <dependency>
           <groupId>com.google.code.gson</groupId>
           <artifactId>gson</artifactId>
-          <version>2.12.1</version>
+          <version>2.13.1</version>
           <type>jar</type>
         </dependency>
       </dependencies>
@@ -191,13 +191,13 @@
         <dependency>
           <groupId>net.bytebuddy</groupId>
           <artifactId>byte-buddy</artifactId>
-          <version>1.17.1</version>
+          <version>1.17.5</version>
           <type>jar</type>
         </dependency>
         <dependency>
           <groupId>net.bytebuddy</groupId>
           <artifactId>byte-buddy-agent</artifactId>
-          <version>1.17.1</version>
+          <version>1.17.5</version>
           <type>jar</type>
         </dependency>
       </dependencies>
@@ -273,7 +273,7 @@
         <dependency>
           <groupId>commons-io</groupId>
           <artifactId>commons-io</artifactId>
-          <version>2.18.0</version>
+          <version>2.19.0</version>
           <type>jar</type>
         </dependency>
         <dependency>
diff --git a/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.34.target b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.34.target
index bc35d2c..8914402 100644
--- a/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.34.target
+++ b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.34.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.34" sequenceNumber="1740521284">
+<target name="jgit-4.34" sequenceNumber="1747840563">
   <locations>
     <location includeMode="slicer" includeAllPlatforms="false" includeSource="true" includeConfigurePhase="true" type="InstallableUnit">
       <unit id="com.jcraft.jsch" version="0.1.55.v20230916-1400"/>
@@ -77,7 +77,7 @@
         <dependency>
           <groupId>org.mockito</groupId>
           <artifactId>mockito-core</artifactId>
-          <version>5.15.2</version>
+          <version>5.18.0</version>
           <type>jar</type>
         </dependency>
       </dependencies>
@@ -87,13 +87,13 @@
         <dependency>
           <groupId>net.java.dev.jna</groupId>
           <artifactId>jna</artifactId>
-          <version>5.16.0</version>
+          <version>5.17.0</version>
           <type>jar</type>
         </dependency>
         <dependency>
           <groupId>net.java.dev.jna</groupId>
           <artifactId>jna-platform</artifactId>
-          <version>5.16.0</version>
+          <version>5.17.0</version>
           <type>jar</type>
         </dependency>
       </dependencies>
@@ -103,49 +103,49 @@
         <dependency>
           <groupId>org.eclipse.jetty.ee10</groupId>
           <artifactId>jetty-ee10-servlet</artifactId>
-          <version>12.0.16</version>
+          <version>12.0.21</version>
           <type>jar</type>
         </dependency>
         <dependency>
           <groupId>org.eclipse.jetty</groupId>
           <artifactId>jetty-http</artifactId>
-          <version>12.0.16</version>
+          <version>12.0.21</version>
           <type>jar</type>
         </dependency>
         <dependency>
           <groupId>org.eclipse.jetty</groupId>
           <artifactId>jetty-io</artifactId>
-          <version>12.0.16</version>
+          <version>12.0.21</version>
           <type>jar</type>
         </dependency>
         <dependency>
           <groupId>org.eclipse.jetty</groupId>
           <artifactId>jetty-security</artifactId>
-          <version>12.0.16</version>
+          <version>12.0.21</version>
           <type>jar</type>
         </dependency>
         <dependency>
           <groupId>org.eclipse.jetty</groupId>
           <artifactId>jetty-server</artifactId>
-          <version>12.0.16</version>
+          <version>12.0.21</version>
           <type>jar</type>
         </dependency>
         <dependency>
           <groupId>org.eclipse.jetty</groupId>
           <artifactId>jetty-session</artifactId>
-          <version>12.0.16</version>
+          <version>12.0.21</version>
           <type>jar</type>
         </dependency>
         <dependency>
           <groupId>org.eclipse.jetty</groupId>
           <artifactId>jetty-util</artifactId>
-          <version>12.0.16</version>
+          <version>12.0.21</version>
           <type>jar</type>
         </dependency>
         <dependency>
           <groupId>org.eclipse.jetty</groupId>
           <artifactId>jetty-util-ajax</artifactId>
-          <version>12.0.16</version>
+          <version>12.0.21</version>
           <type>jar</type>
         </dependency>
         <dependency>
@@ -181,7 +181,7 @@
         <dependency>
           <groupId>com.google.code.gson</groupId>
           <artifactId>gson</artifactId>
-          <version>2.12.1</version>
+          <version>2.13.1</version>
           <type>jar</type>
         </dependency>
       </dependencies>
@@ -191,13 +191,13 @@
         <dependency>
           <groupId>net.bytebuddy</groupId>
           <artifactId>byte-buddy</artifactId>
-          <version>1.17.1</version>
+          <version>1.17.5</version>
           <type>jar</type>
         </dependency>
         <dependency>
           <groupId>net.bytebuddy</groupId>
           <artifactId>byte-buddy-agent</artifactId>
-          <version>1.17.1</version>
+          <version>1.17.5</version>
           <type>jar</type>
         </dependency>
       </dependencies>
@@ -273,7 +273,7 @@
         <dependency>
           <groupId>commons-io</groupId>
           <artifactId>commons-io</artifactId>
-          <version>2.18.0</version>
+          <version>2.19.0</version>
           <type>jar</type>
         </dependency>
         <dependency>
diff --git a/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.35.target b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.35.target
index 15cabc3..1e7a8df 100644
--- a/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.35.target
+++ b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.35.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.35" sequenceNumber="1740521286">
+<target name="jgit-4.35" sequenceNumber="1747840563">
   <locations>
     <location includeMode="slicer" includeAllPlatforms="false" includeSource="true" includeConfigurePhase="true" type="InstallableUnit">
       <unit id="com.jcraft.jsch" version="0.1.55.v20230916-1400"/>
@@ -77,7 +77,7 @@
         <dependency>
           <groupId>org.mockito</groupId>
           <artifactId>mockito-core</artifactId>
-          <version>5.15.2</version>
+          <version>5.18.0</version>
           <type>jar</type>
         </dependency>
       </dependencies>
@@ -87,13 +87,13 @@
         <dependency>
           <groupId>net.java.dev.jna</groupId>
           <artifactId>jna</artifactId>
-          <version>5.16.0</version>
+          <version>5.17.0</version>
           <type>jar</type>
         </dependency>
         <dependency>
           <groupId>net.java.dev.jna</groupId>
           <artifactId>jna-platform</artifactId>
-          <version>5.16.0</version>
+          <version>5.17.0</version>
           <type>jar</type>
         </dependency>
       </dependencies>
@@ -103,49 +103,49 @@
         <dependency>
           <groupId>org.eclipse.jetty.ee10</groupId>
           <artifactId>jetty-ee10-servlet</artifactId>
-          <version>12.0.16</version>
+          <version>12.0.21</version>
           <type>jar</type>
         </dependency>
         <dependency>
           <groupId>org.eclipse.jetty</groupId>
           <artifactId>jetty-http</artifactId>
-          <version>12.0.16</version>
+          <version>12.0.21</version>
           <type>jar</type>
         </dependency>
         <dependency>
           <groupId>org.eclipse.jetty</groupId>
           <artifactId>jetty-io</artifactId>
-          <version>12.0.16</version>
+          <version>12.0.21</version>
           <type>jar</type>
         </dependency>
         <dependency>
           <groupId>org.eclipse.jetty</groupId>
           <artifactId>jetty-security</artifactId>
-          <version>12.0.16</version>
+          <version>12.0.21</version>
           <type>jar</type>
         </dependency>
         <dependency>
           <groupId>org.eclipse.jetty</groupId>
           <artifactId>jetty-server</artifactId>
-          <version>12.0.16</version>
+          <version>12.0.21</version>
           <type>jar</type>
         </dependency>
         <dependency>
           <groupId>org.eclipse.jetty</groupId>
           <artifactId>jetty-session</artifactId>
-          <version>12.0.16</version>
+          <version>12.0.21</version>
           <type>jar</type>
         </dependency>
         <dependency>
           <groupId>org.eclipse.jetty</groupId>
           <artifactId>jetty-util</artifactId>
-          <version>12.0.16</version>
+          <version>12.0.21</version>
           <type>jar</type>
         </dependency>
         <dependency>
           <groupId>org.eclipse.jetty</groupId>
           <artifactId>jetty-util-ajax</artifactId>
-          <version>12.0.16</version>
+          <version>12.0.21</version>
           <type>jar</type>
         </dependency>
         <dependency>
@@ -181,7 +181,7 @@
         <dependency>
           <groupId>com.google.code.gson</groupId>
           <artifactId>gson</artifactId>
-          <version>2.12.1</version>
+          <version>2.13.1</version>
           <type>jar</type>
         </dependency>
       </dependencies>
@@ -191,13 +191,13 @@
         <dependency>
           <groupId>net.bytebuddy</groupId>
           <artifactId>byte-buddy</artifactId>
-          <version>1.17.1</version>
+          <version>1.17.5</version>
           <type>jar</type>
         </dependency>
         <dependency>
           <groupId>net.bytebuddy</groupId>
           <artifactId>byte-buddy-agent</artifactId>
-          <version>1.17.1</version>
+          <version>1.17.5</version>
           <type>jar</type>
         </dependency>
       </dependencies>
@@ -273,7 +273,7 @@
         <dependency>
           <groupId>commons-io</groupId>
           <artifactId>commons-io</artifactId>
-          <version>2.18.0</version>
+          <version>2.19.0</version>
           <type>jar</type>
         </dependency>
         <dependency>
diff --git a/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.36.target b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.36.target
new file mode 100644
index 0000000..9e3c33b
--- /dev/null
+++ b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.36.target
@@ -0,0 +1,288 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<?pde?>
+<!-- generated with https://github.com/eclipse-cbi/targetplatform-dsl -->
+<target name="jgit-4.36" sequenceNumber="1747840563">
+  <locations>
+    <location includeMode="slicer" includeAllPlatforms="false" includeSource="true" includeConfigurePhase="true" type="InstallableUnit">
+      <unit id="com.jcraft.jsch" version="0.1.55.v20230916-1400"/>
+      <unit id="com.jcraft.jsch.source" version="0.1.55.v20230916-1400"/>
+      <unit id="com.jcraft.jzlib" version="1.1.3.v20230916-1400"/>
+      <unit id="com.jcraft.jzlib.source" version="1.1.3.v20230916-1400"/>
+      <unit id="org.apache.ant" version="1.10.15.v20240901-1000"/>
+      <unit id="org.apache.ant.source" version="1.10.15.v20240901-1000"/>
+      <unit id="org.apache.httpcomponents.httpclient" version="4.5.14"/>
+      <unit id="org.apache.httpcomponents.httpclient.source" version="4.5.14"/>
+      <unit id="org.apache.httpcomponents.httpcore" version="4.4.16"/>
+      <unit id="org.apache.httpcomponents.httpcore.source" version="4.4.16"/>
+      <unit id="org.hamcrest.core" version="1.3.0.v20230809-1000"/>
+      <unit id="org.hamcrest.core.source" version="1.3.0.v20230809-1000"/>
+      <unit id="org.hamcrest.library" version="1.3.0.v20230809-1000"/>
+      <unit id="org.hamcrest.library.source" version="1.3.0.v20230809-1000"/>
+      <unit id="org.junit" version="4.13.2.v20240929-1000"/>
+      <unit id="org.junit.source" version="4.13.2.v20240929-1000"/>
+      <unit id="org.objenesis" version="3.4.0"/>
+      <unit id="org.objenesis.source" version="3.4.0"/>
+      <unit id="org.osgi.service.cm" version="1.6.1.202109301733"/>
+      <unit id="org.osgi.service.cm.source" version="1.6.1.202109301733"/>
+      <repository location="https://download.eclipse.org/tools/orbit/simrel/orbit-aggregation/2025-06"/>
+    </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/2025-06/"/>
+    </location>
+    <location includeDependencyDepth="none" includeDependencyScopes="compile" includeSource="true" missingManifest="error" type="Maven" label="xz">
+      <dependencies>
+        <dependency>
+          <groupId>org.tukaani</groupId>
+          <artifactId>xz</artifactId>
+          <version>1.10</version>
+          <type>jar</type>
+        </dependency>
+      </dependencies>
+    </location>
+    <location includeDependencyDepth="none" includeDependencyScopes="compile" includeSource="true" missingManifest="error" type="Maven" label="slf4j">
+      <dependencies>
+        <dependency>
+          <groupId>org.slf4j</groupId>
+          <artifactId>slf4j-api</artifactId>
+          <version>1.7.36</version>
+          <type>jar</type>
+        </dependency>
+        <dependency>
+          <groupId>org.slf4j</groupId>
+          <artifactId>slf4j-simple</artifactId>
+          <version>1.7.36</version>
+          <type>jar</type>
+        </dependency>
+      </dependencies>
+    </location>
+    <location includeDependencyDepth="none" includeDependencyScopes="compile" includeSource="true" missingManifest="error" type="Maven" label="sshd">
+      <dependencies>
+        <dependency>
+          <groupId>org.apache.sshd</groupId>
+          <artifactId>sshd-osgi</artifactId>
+          <version>2.15.0</version>
+          <type>jar</type>
+        </dependency>
+        <dependency>
+          <groupId>org.apache.sshd</groupId>
+          <artifactId>sshd-sftp</artifactId>
+          <version>2.15.0</version>
+          <type>jar</type>
+        </dependency>
+      </dependencies>
+    </location>
+    <location includeDependencyDepth="none" includeDependencyScopes="compile" includeSource="true" missingManifest="error" type="Maven" label="mockito">
+      <dependencies>
+        <dependency>
+          <groupId>org.mockito</groupId>
+          <artifactId>mockito-core</artifactId>
+          <version>5.18.0</version>
+          <type>jar</type>
+        </dependency>
+      </dependencies>
+    </location>
+    <location includeDependencyDepth="none" includeDependencyScopes="compile" includeSource="true" missingManifest="error" type="Maven" label="jna">
+      <dependencies>
+        <dependency>
+          <groupId>net.java.dev.jna</groupId>
+          <artifactId>jna</artifactId>
+          <version>5.17.0</version>
+          <type>jar</type>
+        </dependency>
+        <dependency>
+          <groupId>net.java.dev.jna</groupId>
+          <artifactId>jna-platform</artifactId>
+          <version>5.17.0</version>
+          <type>jar</type>
+        </dependency>
+      </dependencies>
+    </location>
+    <location includeDependencyDepth="none" includeDependencyScopes="compile" includeSource="true" missingManifest="error" type="Maven" label="jetty">
+      <dependencies>
+        <dependency>
+          <groupId>org.eclipse.jetty.ee10</groupId>
+          <artifactId>jetty-ee10-servlet</artifactId>
+          <version>12.0.21</version>
+          <type>jar</type>
+        </dependency>
+        <dependency>
+          <groupId>org.eclipse.jetty</groupId>
+          <artifactId>jetty-http</artifactId>
+          <version>12.0.21</version>
+          <type>jar</type>
+        </dependency>
+        <dependency>
+          <groupId>org.eclipse.jetty</groupId>
+          <artifactId>jetty-io</artifactId>
+          <version>12.0.21</version>
+          <type>jar</type>
+        </dependency>
+        <dependency>
+          <groupId>org.eclipse.jetty</groupId>
+          <artifactId>jetty-security</artifactId>
+          <version>12.0.21</version>
+          <type>jar</type>
+        </dependency>
+        <dependency>
+          <groupId>org.eclipse.jetty</groupId>
+          <artifactId>jetty-server</artifactId>
+          <version>12.0.21</version>
+          <type>jar</type>
+        </dependency>
+        <dependency>
+          <groupId>org.eclipse.jetty</groupId>
+          <artifactId>jetty-session</artifactId>
+          <version>12.0.21</version>
+          <type>jar</type>
+        </dependency>
+        <dependency>
+          <groupId>org.eclipse.jetty</groupId>
+          <artifactId>jetty-util</artifactId>
+          <version>12.0.21</version>
+          <type>jar</type>
+        </dependency>
+        <dependency>
+          <groupId>org.eclipse.jetty</groupId>
+          <artifactId>jetty-util-ajax</artifactId>
+          <version>12.0.21</version>
+          <type>jar</type>
+        </dependency>
+        <dependency>
+          <groupId>jakarta.servlet</groupId>
+          <artifactId>jakarta.servlet-api</artifactId>
+          <version>6.1.0</version>
+          <type>jar</type>
+        </dependency>
+      </dependencies>
+    </location>
+    <location includeDependencyDepth="none" includeDependencyScopes="compile" includeSource="true" missingManifest="error" type="Maven" label="javaewah">
+      <dependencies>
+        <dependency>
+          <groupId>com.googlecode.javaewah</groupId>
+          <artifactId>JavaEWAH</artifactId>
+          <version>1.2.3</version>
+          <type>jar</type>
+        </dependency>
+      </dependencies>
+    </location>
+    <location includeDependencyDepth="none" includeDependencyScopes="compile" includeSource="true" missingManifest="error" type="Maven" label="hamcrest">
+      <dependencies>
+        <dependency>
+          <groupId>org.hamcrest</groupId>
+          <artifactId>hamcrest</artifactId>
+          <version>2.2</version>
+          <type>jar</type>
+        </dependency>
+      </dependencies>
+    </location>
+    <location includeDependencyDepth="none" includeDependencyScopes="compile" includeSource="true" missingManifest="error" type="Maven" label="gson">
+      <dependencies>
+        <dependency>
+          <groupId>com.google.code.gson</groupId>
+          <artifactId>gson</artifactId>
+          <version>2.13.1</version>
+          <type>jar</type>
+        </dependency>
+      </dependencies>
+    </location>
+    <location includeDependencyDepth="none" includeDependencyScopes="compile" includeSource="true" missingManifest="error" type="Maven" label="bytebuddy">
+      <dependencies>
+        <dependency>
+          <groupId>net.bytebuddy</groupId>
+          <artifactId>byte-buddy</artifactId>
+          <version>1.17.5</version>
+          <type>jar</type>
+        </dependency>
+        <dependency>
+          <groupId>net.bytebuddy</groupId>
+          <artifactId>byte-buddy-agent</artifactId>
+          <version>1.17.5</version>
+          <type>jar</type>
+        </dependency>
+      </dependencies>
+    </location>
+    <location includeDependencyDepth="none" includeDependencyScopes="compile" includeSource="true" missingManifest="error" type="Maven" label="bouncycastle">
+      <dependencies>
+        <dependency>
+          <groupId>org.bouncycastle</groupId>
+          <artifactId>bcpg-jdk18on</artifactId>
+          <version>1.80</version>
+          <type>jar</type>
+        </dependency>
+        <dependency>
+          <groupId>org.bouncycastle</groupId>
+          <artifactId>bcprov-jdk18on</artifactId>
+          <version>1.80</version>
+          <type>jar</type>
+        </dependency>
+        <dependency>
+          <groupId>org.bouncycastle</groupId>
+          <artifactId>bcpkix-jdk18on</artifactId>
+          <version>1.80</version>
+          <type>jar</type>
+        </dependency>
+        <dependency>
+          <groupId>org.bouncycastle</groupId>
+          <artifactId>bcutil-jdk18on</artifactId>
+          <version>1.80</version>
+          <type>jar</type>
+        </dependency>
+      </dependencies>
+    </location>
+    <location includeDependencyDepth="none" includeDependencyScopes="compile" includeSource="true" missingManifest="error" type="Maven" label="assertj">
+      <dependencies>
+        <dependency>
+          <groupId>org.assertj</groupId>
+          <artifactId>assertj-core</artifactId>
+          <version>3.27.3</version>
+          <type>jar</type>
+        </dependency>
+      </dependencies>
+    </location>
+    <location includeDependencyDepth="none" includeDependencyScopes="compile" includeSource="true" missingManifest="error" type="Maven" label="args4j">
+      <dependencies>
+        <dependency>
+          <groupId>args4j</groupId>
+          <artifactId>args4j</artifactId>
+          <version>2.37</version>
+          <type>jar</type>
+        </dependency>
+      </dependencies>
+    </location>
+    <location includeDependencyDepth="none" includeDependencyScopes="compile" includeSource="true" missingManifest="error" type="Maven" label="apache">
+      <dependencies>
+        <dependency>
+          <groupId>commons-codec</groupId>
+          <artifactId>commons-codec</artifactId>
+          <version>1.18.0</version>
+          <type>jar</type>
+        </dependency>
+        <dependency>
+          <groupId>org.apache.commons</groupId>
+          <artifactId>commons-compress</artifactId>
+          <version>1.27.1</version>
+          <type>jar</type>
+        </dependency>
+        <dependency>
+          <groupId>org.apache.commons</groupId>
+          <artifactId>commons-lang3</artifactId>
+          <version>3.17.0</version>
+          <type>jar</type>
+        </dependency>
+        <dependency>
+          <groupId>commons-io</groupId>
+          <artifactId>commons-io</artifactId>
+          <version>2.19.0</version>
+          <type>jar</type>
+        </dependency>
+        <dependency>
+          <groupId>commons-logging</groupId>
+          <artifactId>commons-logging</artifactId>
+          <version>1.3.5</version>
+          <type>jar</type>
+        </dependency>
+      </dependencies>
+    </location>
+  </locations>
+</target>
diff --git a/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.36.tpd b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.36.tpd
new file mode 100644
index 0000000..053929f
--- /dev/null
+++ b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.36.tpd
@@ -0,0 +1,8 @@
+target "jgit-4.36" with source configurePhase
+
+include "orbit/orbit-4.36.tpd"
+include "maven/dependencies.tpd"
+
+location "https://download.eclipse.org/staging/2025-06/" {
+	org.eclipse.osgi lazy
+}
diff --git a/org.eclipse.jgit.packaging/org.eclipse.jgit.target/maven/dependencies.tpd b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/maven/dependencies.tpd
index b292cf5..03f1c0e 100644
--- a/org.eclipse.jgit.packaging/org.eclipse.jgit.target/maven/dependencies.tpd
+++ b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/maven/dependencies.tpd
@@ -25,7 +25,7 @@
 	dependency {
 		groupId = "commons-io"
 		artifactId = "commons-io"
-		version = "2.18.0"
+		version = "2.19.0"
 	}
 	dependency {
 		groupId = "commons-logging"
@@ -97,12 +97,12 @@
 	dependency {
 		groupId = "net.bytebuddy"
 		artifactId = "byte-buddy"
-		version = "1.17.1"
+		version = "1.17.5"
 	}
 	dependency {
 		groupId = "net.bytebuddy"
 		artifactId = "byte-buddy-agent"
-		version = "1.17.1"
+		version = "1.17.5"
 	}
 }
 
@@ -115,7 +115,7 @@
 	dependency {
 		groupId = "com.google.code.gson"
 		artifactId = "gson"
-		version = "2.12.1"
+		version = "2.13.1"
 	}
 }
 
@@ -154,42 +154,42 @@
 	dependency {
 		groupId = "org.eclipse.jetty.ee10"
 		artifactId = "jetty-ee10-servlet"
-		version = "12.0.16"
+		version = "12.0.21"
 	}
 	dependency {
 		groupId = "org.eclipse.jetty"
 		artifactId = "jetty-http"
-		version = "12.0.16"
+		version = "12.0.21"
 	}
 	dependency {
 		groupId = "org.eclipse.jetty"
 		artifactId = "jetty-io"
-		version = "12.0.16"
+		version = "12.0.21"
 	}
 	dependency {
 		groupId = "org.eclipse.jetty"
 		artifactId = "jetty-security"
-		version = "12.0.16"
+		version = "12.0.21"
 	}
 	dependency {
 		groupId = "org.eclipse.jetty"
 		artifactId = "jetty-server"
-		version = "12.0.16"
+		version = "12.0.21"
 	}
 	dependency {
 		groupId = "org.eclipse.jetty"
 		artifactId = "jetty-session"
-		version = "12.0.16"
+		version = "12.0.21"
 	}
 	dependency {
 		groupId = "org.eclipse.jetty"
 		artifactId = "jetty-util"
-		version = "12.0.16"
+		version = "12.0.21"
 	}
 	dependency {
 		groupId = "org.eclipse.jetty"
 		artifactId = "jetty-util-ajax"
-		version = "12.0.16"
+		version = "12.0.21"
 	}
 	dependency {
 		groupId = "jakarta.servlet"
@@ -207,12 +207,12 @@
 	dependency {
 		groupId = "net.java.dev.jna"
 		artifactId = "jna"
-		version = "5.16.0"
+		version = "5.17.0"
 	}
 	dependency {
 		groupId = "net.java.dev.jna"
 		artifactId = "jna-platform"
-		version = "5.16.0"
+		version = "5.17.0"
 	}
 }
 
@@ -225,7 +225,7 @@
 	dependency {
 		groupId = "org.mockito"
 		artifactId = "mockito-core"
-		version = "5.15.2"
+		version = "5.18.0"
 	}
 }
 
diff --git a/org.eclipse.jgit.packaging/org.eclipse.jgit.target/orbit/orbit-4.36.tpd b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/orbit/orbit-4.36.tpd
new file mode 100644
index 0000000..4f46583
--- /dev/null
+++ b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/orbit/orbit-4.36.tpd
@@ -0,0 +1,25 @@
+target "orbit-4.36" with source configurePhase
+// see https://download.eclipse.org/tools/orbit/downloads/
+
+location "https://download.eclipse.org/tools/orbit/simrel/orbit-aggregation/2025-06" {
+	com.jcraft.jsch [0.1.55.v20230916-1400,0.1.55.v20230916-1400]
+	com.jcraft.jsch.source [0.1.55.v20230916-1400,0.1.55.v20230916-1400]
+	com.jcraft.jzlib [1.1.3.v20230916-1400,1.1.3.v20230916-1400]
+	com.jcraft.jzlib.source [1.1.3.v20230916-1400,1.1.3.v20230916-1400]
+	org.apache.ant [1.10.15.v20240901-1000,1.10.15.v20240901-1000]
+	org.apache.ant.source [1.10.15.v20240901-1000,1.10.15.v20240901-1000]
+	org.apache.httpcomponents.httpclient [4.5.14,4.5.14]
+	org.apache.httpcomponents.httpclient.source [4.5.14,4.5.14]
+	org.apache.httpcomponents.httpcore [4.4.16,4.4.16]
+	org.apache.httpcomponents.httpcore.source [4.4.16,4.4.16]
+	org.hamcrest.core [1.3.0.v20230809-1000,1.3.0.v20230809-1000]
+	org.hamcrest.core.source [1.3.0.v20230809-1000,1.3.0.v20230809-1000]
+	org.hamcrest.library [1.3.0.v20230809-1000,1.3.0.v20230809-1000]
+	org.hamcrest.library.source [1.3.0.v20230809-1000,1.3.0.v20230809-1000]
+	org.junit [4.13.2.v20240929-1000,4.13.2.v20240929-1000]
+	org.junit.source [4.13.2.v20240929-1000,4.13.2.v20240929-1000]
+	org.objenesis [3.4,3.4]
+	org.objenesis.source [3.4,3.4]
+	org.osgi.service.cm [1.6.1.202109301733,1.6.1.202109301733]
+	org.osgi.service.cm.source [1.6.1.202109301733,1.6.1.202109301733]
+}
diff --git a/org.eclipse.jgit.packaging/pom.xml b/org.eclipse.jgit.packaging/pom.xml
index 9a13ec8..0687128 100644
--- a/org.eclipse.jgit.packaging/pom.xml
+++ b/org.eclipse.jgit.packaging/pom.xml
@@ -16,7 +16,7 @@
 
   <groupId>org.eclipse.jgit</groupId>
   <artifactId>jgit.tycho.parent</artifactId>
-  <version>7.2.2-SNAPSHOT</version>
+  <version>7.3.1-SNAPSHOT</version>
   <packaging>pom</packaging>
 
   <name>JGit Tycho Parent</name>
@@ -246,7 +246,7 @@
       <plugin>
         <groupId>io.github.git-commit-id</groupId>
         <artifactId>git-commit-id-maven-plugin</artifactId>
-        <version>9.0.1</version>
+        <version>9.0.2</version>
         <executions>
           <execution>
             <id>get-the-git-infos</id>
@@ -408,12 +408,12 @@
         <plugin>
           <groupId>org.apache.maven.plugins</groupId>
           <artifactId>maven-deploy-plugin</artifactId>
-          <version>3.1.3</version>
+          <version>3.1.4</version>
         </plugin>
         <plugin>
           <groupId>org.apache.maven.plugins</groupId>
           <artifactId>maven-install-plugin</artifactId>
-          <version>3.1.3</version>
+          <version>3.1.4</version>
         </plugin>
         <plugin>
           <groupId>org.apache.maven.plugins</groupId>
diff --git a/org.eclipse.jgit.pgm.test/META-INF/MANIFEST.MF b/org.eclipse.jgit.pgm.test/META-INF/MANIFEST.MF
index a787574..514fe71 100644
--- a/org.eclipse.jgit.pgm.test/META-INF/MANIFEST.MF
+++ b/org.eclipse.jgit.pgm.test/META-INF/MANIFEST.MF
@@ -3,30 +3,30 @@
 Bundle-Name: %Bundle-Name
 Automatic-Module-Name: org.eclipse.jgit.pgm.test
 Bundle-SymbolicName: org.eclipse.jgit.pgm.test
-Bundle-Version: 7.2.2.qualifier
+Bundle-Version: 7.3.1.qualifier
 Bundle-Vendor: %Bundle-Vendor
 Bundle-Localization: plugin
 Bundle-ActivationPolicy: lazy
 Bundle-RequiredExecutionEnvironment: JavaSE-17
-Import-Package: org.eclipse.jgit.api;version="[7.2.2,7.3.0)",
- org.eclipse.jgit.api.errors;version="[7.2.2,7.3.0)",
- org.eclipse.jgit.diff;version="[7.2.2,7.3.0)",
- org.eclipse.jgit.dircache;version="[7.2.2,7.3.0)",
- org.eclipse.jgit.internal.diffmergetool;version="[7.2.2,7.3.0)",
- org.eclipse.jgit.internal.storage.file;version="[7.2.2,7.3.0)",
- org.eclipse.jgit.junit;version="[7.2.2,7.3.0)",
- org.eclipse.jgit.lib;version="[7.2.2,7.3.0)",
- org.eclipse.jgit.lib.internal;version="[7.2.2,7.3.0)",
- org.eclipse.jgit.merge;version="[7.2.2,7.3.0)",
- org.eclipse.jgit.pgm;version="[7.2.2,7.3.0)",
- org.eclipse.jgit.pgm.internal;version="[7.2.2,7.3.0)",
- org.eclipse.jgit.pgm.opt;version="[7.2.2,7.3.0)",
- org.eclipse.jgit.revwalk;version="[7.2.2,7.3.0)",
- org.eclipse.jgit.storage.file;version="[7.2.2,7.3.0)",
- org.eclipse.jgit.transport;version="[7.2.2,7.3.0)",
- org.eclipse.jgit.treewalk;version="[7.2.2,7.3.0)",
- org.eclipse.jgit.util;version="[7.2.2,7.3.0)",
- org.eclipse.jgit.util.io;version="[7.2.2,7.3.0)",
+Import-Package: org.eclipse.jgit.api;version="[7.3.1,7.4.0)",
+ org.eclipse.jgit.api.errors;version="[7.3.1,7.4.0)",
+ org.eclipse.jgit.diff;version="[7.3.1,7.4.0)",
+ org.eclipse.jgit.dircache;version="[7.3.1,7.4.0)",
+ org.eclipse.jgit.internal.diffmergetool;version="[7.3.1,7.4.0)",
+ org.eclipse.jgit.internal.storage.file;version="[7.3.1,7.4.0)",
+ org.eclipse.jgit.junit;version="[7.3.1,7.4.0)",
+ org.eclipse.jgit.lib;version="[7.3.1,7.4.0)",
+ org.eclipse.jgit.lib.internal;version="[7.3.1,7.4.0)",
+ org.eclipse.jgit.merge;version="[7.3.1,7.4.0)",
+ org.eclipse.jgit.pgm;version="[7.3.1,7.4.0)",
+ org.eclipse.jgit.pgm.internal;version="[7.3.1,7.4.0)",
+ org.eclipse.jgit.pgm.opt;version="[7.3.1,7.4.0)",
+ org.eclipse.jgit.revwalk;version="[7.3.1,7.4.0)",
+ org.eclipse.jgit.storage.file;version="[7.3.1,7.4.0)",
+ org.eclipse.jgit.transport;version="[7.3.1,7.4.0)",
+ org.eclipse.jgit.treewalk;version="[7.3.1,7.4.0)",
+ org.eclipse.jgit.util;version="[7.3.1,7.4.0)",
+ org.eclipse.jgit.util.io;version="[7.3.1,7.4.0)",
  org.hamcrest.core;bundle-version="[1.1.0,3.0.0)",
  org.junit;version="[4.13,5.0.0)",
  org.junit.rules;version="[4.13,5.0.0)",
diff --git a/org.eclipse.jgit.pgm.test/pom.xml b/org.eclipse.jgit.pgm.test/pom.xml
index 87ca920..6a138a0 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>7.2.2-SNAPSHOT</version>
+    <version>7.3.1-SNAPSHOT</version>
   </parent>
 
   <artifactId>org.eclipse.jgit.pgm.test</artifactId>
diff --git a/org.eclipse.jgit.pgm.test/tst/org/eclipse/jgit/pgm/CheckoutTest.java b/org.eclipse.jgit.pgm.test/tst/org/eclipse/jgit/pgm/CheckoutTest.java
index 999bf43..d533829 100644
--- a/org.eclipse.jgit.pgm.test/tst/org/eclipse/jgit/pgm/CheckoutTest.java
+++ b/org.eclipse.jgit.pgm.test/tst/org/eclipse/jgit/pgm/CheckoutTest.java
@@ -96,6 +96,20 @@ public void testCheckoutNonExistingBranch() throws Exception {
 	}
 
 	@Test
+	public void testCheckoutWithNoRef() throws Exception {
+		assertStringArrayEquals(
+				"a valid ref is expected",
+				executeExpectingException("git checkout"));
+	}
+
+	@Test
+	public void testCheckoutWithInvalidRef() throws Exception {
+		assertStringArrayEquals(
+				".feature is not a valid ref name",
+				executeExpectingException("git checkout .feature"));
+	}
+
+	@Test
 	public void testCheckoutNewBranchThatAlreadyExists() throws Exception {
 		try (Git git = new Git(db)) {
 			git.commit().setMessage("initial commit").call();
diff --git a/org.eclipse.jgit.pgm/META-INF/MANIFEST.MF b/org.eclipse.jgit.pgm/META-INF/MANIFEST.MF
index 4fc96e9..c8750a8 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: 7.2.2.qualifier
+Bundle-Version: 7.3.1.qualifier
 Bundle-Vendor: %Bundle-Vendor
 Bundle-Localization: OSGI-INF/l10n/plugin
 Bundle-RequiredExecutionEnvironment: JavaSE-17
@@ -14,50 +14,50 @@
  org.eclipse.jetty.server.handler;version="[12.0.0,13.0.0)",
  org.eclipse.jetty.util;version="[12.0.0,13.0.0)",
  org.eclipse.jetty.util.component;version="[12.0.0,13.0.0)",
- org.eclipse.jgit.api;version="[7.2.2,7.3.0)",
- org.eclipse.jgit.api.errors;version="[7.2.2,7.3.0)",
- org.eclipse.jgit.archive;version="[7.2.2,7.3.0)",
- org.eclipse.jgit.awtui;version="[7.2.2,7.3.0)",
- org.eclipse.jgit.blame;version="[7.2.2,7.3.0)",
- org.eclipse.jgit.diff;version="[7.2.2,7.3.0)",
- org.eclipse.jgit.dircache;version="[7.2.2,7.3.0)",
- org.eclipse.jgit.errors;version="[7.2.2,7.3.0)",
- org.eclipse.jgit.gitrepo;version="[7.2.2,7.3.0)",
- org.eclipse.jgit.internal.diffmergetool;version="[7.2.2,7.3.0)",
- org.eclipse.jgit.internal.storage.file;version="[7.2.2,7.3.0)",
- org.eclipse.jgit.internal.storage.io;version="[7.2.2,7.3.0)",
- org.eclipse.jgit.internal.storage.midx;version="[7.2.2,7.3.0)",
- org.eclipse.jgit.internal.storage.pack;version="[7.2.2,7.3.0)",
- org.eclipse.jgit.internal.storage.reftable;version="[7.2.2,7.3.0)",
- org.eclipse.jgit.lfs;version="[7.2.2,7.3.0)",
- org.eclipse.jgit.lfs.server;version="[7.2.2,7.3.0)",
- org.eclipse.jgit.lfs.server.fs;version="[7.2.2,7.3.0)",
- org.eclipse.jgit.lfs.server.s3;version="[7.2.2,7.3.0)",
- org.eclipse.jgit.lib;version="[7.2.2,7.3.0)",
- org.eclipse.jgit.lib.internal;version="[7.2.2,7.3.0)",
- org.eclipse.jgit.merge;version="[7.2.2,7.3.0)",
- org.eclipse.jgit.nls;version="[7.2.2,7.3.0)",
- org.eclipse.jgit.notes;version="[7.2.2,7.3.0)",
- org.eclipse.jgit.revplot;version="[7.2.2,7.3.0)",
- org.eclipse.jgit.revwalk;version="[7.2.2,7.3.0)",
- org.eclipse.jgit.revwalk.filter;version="[7.2.2,7.3.0)",
- org.eclipse.jgit.storage.file;version="[7.2.2,7.3.0)",
- org.eclipse.jgit.storage.pack;version="[7.2.2,7.3.0)",
- org.eclipse.jgit.transport;version="[7.2.2,7.3.0)",
- org.eclipse.jgit.transport.http.apache;version="[7.2.2,7.3.0)",
- org.eclipse.jgit.transport.resolver;version="[7.2.2,7.3.0)",
- org.eclipse.jgit.transport.ssh.jsch;version="[7.2.2,7.3.0)",
- org.eclipse.jgit.transport.sshd;version="[7.2.2,7.3.0)",
- org.eclipse.jgit.treewalk;version="[7.2.2,7.3.0)",
- org.eclipse.jgit.treewalk.filter;version="[7.2.2,7.3.0)",
- org.eclipse.jgit.util;version="[7.2.2,7.3.0)",
- org.eclipse.jgit.util.io;version="[7.2.2,7.3.0)",
+ org.eclipse.jgit.api;version="[7.3.1,7.4.0)",
+ org.eclipse.jgit.api.errors;version="[7.3.1,7.4.0)",
+ org.eclipse.jgit.archive;version="[7.3.1,7.4.0)",
+ org.eclipse.jgit.awtui;version="[7.3.1,7.4.0)",
+ org.eclipse.jgit.blame;version="[7.3.1,7.4.0)",
+ org.eclipse.jgit.diff;version="[7.3.1,7.4.0)",
+ org.eclipse.jgit.dircache;version="[7.3.1,7.4.0)",
+ org.eclipse.jgit.errors;version="[7.3.1,7.4.0)",
+ org.eclipse.jgit.gitrepo;version="[7.3.1,7.4.0)",
+ org.eclipse.jgit.internal.diffmergetool;version="[7.3.1,7.4.0)",
+ org.eclipse.jgit.internal.storage.file;version="[7.3.1,7.4.0)",
+ org.eclipse.jgit.internal.storage.io;version="[7.3.1,7.4.0)",
+ org.eclipse.jgit.internal.storage.midx;version="[7.3.1,7.4.0)",
+ org.eclipse.jgit.internal.storage.pack;version="[7.3.1,7.4.0)",
+ org.eclipse.jgit.internal.storage.reftable;version="[7.3.1,7.4.0)",
+ org.eclipse.jgit.lfs;version="[7.3.1,7.4.0)",
+ org.eclipse.jgit.lfs.server;version="[7.3.1,7.4.0)",
+ org.eclipse.jgit.lfs.server.fs;version="[7.3.1,7.4.0)",
+ org.eclipse.jgit.lfs.server.s3;version="[7.3.1,7.4.0)",
+ org.eclipse.jgit.lib;version="[7.3.1,7.4.0)",
+ org.eclipse.jgit.lib.internal;version="[7.3.1,7.4.0)",
+ org.eclipse.jgit.merge;version="[7.3.1,7.4.0)",
+ org.eclipse.jgit.nls;version="[7.3.1,7.4.0)",
+ org.eclipse.jgit.notes;version="[7.3.1,7.4.0)",
+ org.eclipse.jgit.revplot;version="[7.3.1,7.4.0)",
+ org.eclipse.jgit.revwalk;version="[7.3.1,7.4.0)",
+ org.eclipse.jgit.revwalk.filter;version="[7.3.1,7.4.0)",
+ org.eclipse.jgit.storage.file;version="[7.3.1,7.4.0)",
+ org.eclipse.jgit.storage.pack;version="[7.3.1,7.4.0)",
+ org.eclipse.jgit.transport;version="[7.3.1,7.4.0)",
+ org.eclipse.jgit.transport.http.apache;version="[7.3.1,7.4.0)",
+ org.eclipse.jgit.transport.resolver;version="[7.3.1,7.4.0)",
+ org.eclipse.jgit.transport.ssh.jsch;version="[7.3.1,7.4.0)",
+ org.eclipse.jgit.transport.sshd;version="[7.3.1,7.4.0)",
+ org.eclipse.jgit.treewalk;version="[7.3.1,7.4.0)",
+ org.eclipse.jgit.treewalk.filter;version="[7.3.1,7.4.0)",
+ org.eclipse.jgit.util;version="[7.3.1,7.4.0)",
+ org.eclipse.jgit.util.io;version="[7.3.1,7.4.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="7.2.2";
+Export-Package: org.eclipse.jgit.console;version="7.3.1";
  uses:="org.eclipse.jgit.transport,
   org.eclipse.jgit.util",
- org.eclipse.jgit.pgm;version="7.2.2";
+ org.eclipse.jgit.pgm;version="7.3.1";
   uses:="org.eclipse.jgit.transport,
    org.eclipse.jgit.util.io,
    org.eclipse.jgit.awtui,
@@ -69,14 +69,14 @@
    org.eclipse.jgit.treewalk,
    org.eclipse.jgit.api,
    javax.swing",
- org.eclipse.jgit.pgm.debug;version="7.2.2";
+ org.eclipse.jgit.pgm.debug;version="7.3.1";
   uses:="org.eclipse.jgit.util.io,
    org.eclipse.jgit.pgm,
    org.eclipse.jetty.servlet",
- org.eclipse.jgit.pgm.internal;version="7.2.2";
+ org.eclipse.jgit.pgm.internal;version="7.3.1";
   x-friends:="org.eclipse.jgit.pgm.test,
    org.eclipse.jgit.test",
- org.eclipse.jgit.pgm.opt;version="7.2.2";
+ org.eclipse.jgit.pgm.opt;version="7.3.1";
   uses:="org.kohsuke.args4j,
    org.eclipse.jgit.lib,
    org.eclipse.jgit.revwalk,
diff --git a/org.eclipse.jgit.pgm/META-INF/SOURCE-MANIFEST.MF b/org.eclipse.jgit.pgm/META-INF/SOURCE-MANIFEST.MF
index 7491846..3560cf9 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: 7.2.2.qualifier
-Eclipse-SourceBundle: org.eclipse.jgit.pgm;version="7.2.2.qualifier";roots="."
+Bundle-Version: 7.3.1.qualifier
+Eclipse-SourceBundle: org.eclipse.jgit.pgm;version="7.3.1.qualifier";roots="."
diff --git a/org.eclipse.jgit.pgm/pom.xml b/org.eclipse.jgit.pgm/pom.xml
index 4585433..681735d 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>7.2.2-SNAPSHOT</version>
+    <version>7.3.1-SNAPSHOT</version>
   </parent>
 
   <artifactId>org.eclipse.jgit.pgm</artifactId>
diff --git a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/Checkout.java b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/Checkout.java
index 229d54d..7a218ec 100644
--- a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/Checkout.java
+++ b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/Checkout.java
@@ -18,6 +18,7 @@
 import org.eclipse.jgit.api.CheckoutCommand;
 import org.eclipse.jgit.api.Git;
 import org.eclipse.jgit.api.errors.CheckoutConflictException;
+import org.eclipse.jgit.api.errors.InvalidRefNameException;
 import org.eclipse.jgit.api.errors.RefAlreadyExistsException;
 import org.eclipse.jgit.api.errors.RefNotFoundException;
 import org.eclipse.jgit.lib.Constants;
@@ -94,7 +95,16 @@ protected void run() throws Exception {
 					outw.println(MessageFormat.format(
 							CLIText.get().switchedToBranch,
 							Repository.shortenRefName(ref.getName())));
-			} catch (RefNotFoundException e) {
+			} catch (InvalidRefNameException e){
+				if (name == null){
+					throw die(MessageFormat
+							.format("a valid ref is expected",e));
+				} else {
+					throw die(MessageFormat
+							.format(CLIText.get().notAValidRefName, name, e));
+				}
+			}
+			catch (RefNotFoundException e) {
 				throw die(MessageFormat
 						.format(CLIText.get().pathspecDidNotMatch, name), e);
 			} catch (RefAlreadyExistsException e) {
diff --git a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/debug/BenchmarkReftable.java b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/debug/BenchmarkReftable.java
index f156b8c..b7a7ec2 100644
--- a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/debug/BenchmarkReftable.java
+++ b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/debug/BenchmarkReftable.java
@@ -107,13 +107,12 @@ private void printf(String fmt, Object... args) throws IOException {
 	@SuppressWarnings({ "nls", "boxing" })
 	private void writeStack() throws Exception {
 		File dir = new File(reftablePath);
-		File stackFile = new File(reftablePath + ".stack");
 
 		dir.mkdirs();
 
 		long start = System.currentTimeMillis();
-		try (FileReftableStack stack = new FileReftableStack(stackFile, dir,
-				null, () -> new Config())) {
+		try (FileReftableStack stack = new FileReftableStack(dir, null,
+				() -> new Config())) {
 
 			List<Ref> refs = readLsRemote().asList();
 			for (Ref r : refs) {
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 2e7c78d..8310f43 100644
--- a/org.eclipse.jgit.ssh.apache.agent/META-INF/MANIFEST.MF
+++ b/org.eclipse.jgit.ssh.apache.agent/META-INF/MANIFEST.MF
@@ -2,16 +2,16 @@
 Bundle-ManifestVersion: 2
 Bundle-Name: %Bundle-Name
 Bundle-SymbolicName: org.eclipse.jgit.ssh.apache.agent;singleton:=true
-Bundle-Version: 7.2.2.qualifier
+Bundle-Version: 7.3.1.qualifier
 Bundle-Localization: OSGI-INF/l10n/agent
 Bundle-Vendor: %Bundle-Vendor
-Fragment-Host: org.eclipse.jgit.ssh.apache;bundle-version="[7.2.2,7.3.0)"
+Fragment-Host: org.eclipse.jgit.ssh.apache;bundle-version="[7.3.1,7.4.0)"
 Bundle-ActivationPolicy: lazy
 Automatic-Module-Name: org.eclipse.jgit.ssh.apache.agent
 Bundle-RequiredExecutionEnvironment: JavaSE-17
-Import-Package: org.eclipse.jgit.transport.sshd;version="[7.2.2,7.3.0)",
- org.eclipse.jgit.nls;version="[7.2.2,7.3.0)",
- org.eclipse.jgit.util;version="[7.2.2,7.3.0)"
+Import-Package: org.eclipse.jgit.transport.sshd;version="[7.3.1,7.4.0)",
+ org.eclipse.jgit.nls;version="[7.3.1,7.4.0)",
+ org.eclipse.jgit.util;version="[7.3.1,7.4.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="7.2.2";x-internal:=true
+Export-Package: org.eclipse.jgit.internal.transport.sshd.agent.connector;version="7.3.1";x-internal:=true
diff --git a/org.eclipse.jgit.ssh.apache.agent/META-INF/SOURCE-MANIFEST.MF b/org.eclipse.jgit.ssh.apache.agent/META-INF/SOURCE-MANIFEST.MF
index 7570bcc..5109585 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: 7.2.2.qualifier
-Eclipse-SourceBundle: org.eclipse.jgit.ssh.apache.agent;version="7.2.2.qualifier";roots="."
+Bundle-Version: 7.3.1.qualifier
+Eclipse-SourceBundle: org.eclipse.jgit.ssh.apache.agent;version="7.3.1.qualifier";roots="."
diff --git a/org.eclipse.jgit.ssh.apache.agent/pom.xml b/org.eclipse.jgit.ssh.apache.agent/pom.xml
index 229d2f6..9b9ea60 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>7.2.2-SNAPSHOT</version>
+    <version>7.3.1-SNAPSHOT</version>
   </parent>
 
   <artifactId>org.eclipse.jgit.ssh.apache.agent</artifactId>
diff --git a/org.eclipse.jgit.ssh.apache.test/META-INF/MANIFEST.MF b/org.eclipse.jgit.ssh.apache.test/META-INF/MANIFEST.MF
index 37b4321..eec422c 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: 7.2.2.qualifier
+Bundle-Version: 7.3.1.qualifier
 Bundle-Vendor: %Bundle-Vendor
 Bundle-Localization: plugin
 Bundle-RequiredExecutionEnvironment: JavaSE-17
@@ -25,22 +25,22 @@
  org.apache.sshd.core;version="[2.15.0,2.16.0)",
  org.apache.sshd.server;version="[2.15.0,2.16.0)",
  org.apache.sshd.server.forward;version="[2.15.0,2.16.0)",
- org.eclipse.jgit.annotations;version="[7.2.2,7.3.0)",
- org.eclipse.jgit.api;version="[7.2.2,7.3.0)",
- org.eclipse.jgit.api.errors;version="[7.2.2,7.3.0)",
- org.eclipse.jgit.errors;version="[7.2.2,7.3.0)",
- org.eclipse.jgit.internal.signing.ssh;version="[7.2.2,7.3.0)",
- org.eclipse.jgit.internal.storage.file;version="[7.2.2,7.3.0)",
- org.eclipse.jgit.internal.transport.sshd;version="[7.2.2,7.3.0)",
- org.eclipse.jgit.internal.transport.sshd.proxy;version="[7.2.2,7.3.0)",
- org.eclipse.jgit.junit;version="[7.2.2,7.3.0)",
- org.eclipse.jgit.junit.ssh;version="[7.2.2,7.3.0)",
- org.eclipse.jgit.lib;version="[7.2.2,7.3.0)",
- org.eclipse.jgit.revwalk;version="[7.2.2,7.3.0)",
- org.eclipse.jgit.transport;version="[7.2.2,7.3.0)",
- org.eclipse.jgit.transport.sshd;version="[7.2.2,7.3.0)",
- org.eclipse.jgit.transport.sshd.agent;version="[7.2.2,7.3.0)",
- org.eclipse.jgit.util;version="[7.2.2,7.3.0)",
+ org.eclipse.jgit.annotations;version="[7.3.1,7.4.0)",
+ org.eclipse.jgit.api;version="[7.3.1,7.4.0)",
+ org.eclipse.jgit.api.errors;version="[7.3.1,7.4.0)",
+ org.eclipse.jgit.errors;version="[7.3.1,7.4.0)",
+ org.eclipse.jgit.internal.signing.ssh;version="[7.3.1,7.4.0)",
+ org.eclipse.jgit.internal.storage.file;version="[7.3.1,7.4.0)",
+ org.eclipse.jgit.internal.transport.sshd;version="[7.3.1,7.4.0)",
+ org.eclipse.jgit.internal.transport.sshd.proxy;version="[7.3.1,7.4.0)",
+ org.eclipse.jgit.junit;version="[7.3.1,7.4.0)",
+ org.eclipse.jgit.junit.ssh;version="[7.3.1,7.4.0)",
+ org.eclipse.jgit.lib;version="[7.3.1,7.4.0)",
+ org.eclipse.jgit.revwalk;version="[7.3.1,7.4.0)",
+ org.eclipse.jgit.transport;version="[7.3.1,7.4.0)",
+ org.eclipse.jgit.transport.sshd;version="[7.3.1,7.4.0)",
+ org.eclipse.jgit.transport.sshd.agent;version="[7.3.1,7.4.0)",
+ org.eclipse.jgit.util;version="[7.3.1,7.4.0)",
  org.junit;version="[4.13,5.0.0)",
  org.junit.experimental.theories;version="[4.13,5.0.0)",
  org.junit.rules;version="[4.13.0,5.0.0)",
diff --git a/org.eclipse.jgit.ssh.apache.test/pom.xml b/org.eclipse.jgit.ssh.apache.test/pom.xml
index f0cd1d0..7e64e01 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>7.2.2-SNAPSHOT</version>
+    <version>7.3.1-SNAPSHOT</version>
   </parent>
 
   <artifactId>org.eclipse.jgit.ssh.apache.test</artifactId>
diff --git a/org.eclipse.jgit.ssh.apache/BUILD b/org.eclipse.jgit.ssh.apache/BUILD
index 83709c3..c32635f 100644
--- a/org.eclipse.jgit.ssh.apache/BUILD
+++ b/org.eclipse.jgit.ssh.apache/BUILD
@@ -12,6 +12,10 @@
     resource_strip_prefix = "org.eclipse.jgit.ssh.apache/resources",
     resources = RESOURCES,
     deps = [
+        "//lib:bcpg",
+        "//lib:bcpkix",
+        "//lib:bcprov",
+        "//lib:bcutil",
         "//lib:slf4j-api",
         "//lib:sshd-osgi",
         "//lib:sshd-sftp",
diff --git a/org.eclipse.jgit.ssh.apache/META-INF/MANIFEST.MF b/org.eclipse.jgit.ssh.apache/META-INF/MANIFEST.MF
index 6a39ae0..98f21f5 100644
--- a/org.eclipse.jgit.ssh.apache/META-INF/MANIFEST.MF
+++ b/org.eclipse.jgit.ssh.apache/META-INF/MANIFEST.MF
@@ -6,10 +6,10 @@
 Bundle-Vendor: %Bundle-Vendor
 Bundle-Localization: OSGI-INF/l10n/plugin
 Bundle-ActivationPolicy: lazy
-Bundle-Version: 7.2.2.qualifier
+Bundle-Version: 7.3.1.qualifier
 Bundle-RequiredExecutionEnvironment: JavaSE-17
-Export-Package: org.eclipse.jgit.internal.signing.ssh;version="7.2.2";x-friends:="org.eclipse.jgit.ssh.apache.test",
- org.eclipse.jgit.internal.transport.sshd;version="7.2.2";x-friends:="org.eclipse.jgit.ssh.apache.test";
+Export-Package: org.eclipse.jgit.internal.signing.ssh;version="7.3.1";x-friends:="org.eclipse.jgit.ssh.apache.test",
+ org.eclipse.jgit.internal.transport.sshd;version="7.3.1";x-friends:="org.eclipse.jgit.ssh.apache.test";
   uses:="org.apache.sshd.client,
    org.apache.sshd.client.auth,
    org.apache.sshd.client.auth.keyboard,
@@ -24,20 +24,21 @@
    org.apache.sshd.common.signature,
    org.apache.sshd.common.util.buffer,
    org.eclipse.jgit.transport",
- org.eclipse.jgit.internal.transport.sshd.agent;version="7.2.2";x-internal:=true,
- org.eclipse.jgit.internal.transport.sshd.auth;version="7.2.2";x-internal:=true,
- org.eclipse.jgit.internal.transport.sshd.pkcs11;version="7.2.2";x-internal:=true,
- org.eclipse.jgit.internal.transport.sshd.proxy;version="7.2.2";x-friends:="org.eclipse.jgit.ssh.apache.test",
- org.eclipse.jgit.signing.ssh;version="7.2.2";uses:="org.eclipse.jgit.lib",
- org.eclipse.jgit.transport.sshd;version="7.2.2";
+ org.eclipse.jgit.internal.transport.sshd.agent;version="7.3.1";x-internal:=true,
+ org.eclipse.jgit.internal.transport.sshd.auth;version="7.3.1";x-internal:=true,
+ org.eclipse.jgit.internal.transport.sshd.pkcs11;version="7.3.1";x-internal:=true,
+ org.eclipse.jgit.internal.transport.sshd.proxy;version="7.3.1";x-friends:="org.eclipse.jgit.ssh.apache.test",
+ org.eclipse.jgit.signing.ssh;version="7.3.1";uses:="org.eclipse.jgit.lib",
+ org.eclipse.jgit.transport.sshd;version="7.3.1";
   uses:="org.eclipse.jgit.transport,
    org.apache.sshd.client.config.hosts,
    org.apache.sshd.common.keyprovider,
    org.eclipse.jgit.util,
    org.apache.sshd.client.session,
    org.apache.sshd.client.keyverifier",
- org.eclipse.jgit.transport.sshd.agent;version="7.2.2"
-Import-Package: org.apache.sshd.agent;version="[2.15.0,2.16.0)",
+ org.eclipse.jgit.transport.sshd.agent;version="7.3.1"
+Import-Package: org.bouncycastle.jce.provider;version="[1.80.0,2.0.0)",
+ org.apache.sshd.agent;version="[2.15.0,2.16.0)",
  org.apache.sshd.client;version="[2.15.0,2.16.0)",
  org.apache.sshd.client.auth;version="[2.15.0,2.16.0)",
  org.apache.sshd.client.auth.keyboard;version="[2.15.0,2.16.0)",
@@ -89,14 +90,14 @@
  org.apache.sshd.sftp;version="[2.15.0,2.16.0)",
  org.apache.sshd.sftp.client;version="[2.15.0,2.16.0)",
  org.apache.sshd.sftp.common;version="[2.15.0,2.16.0)",
- org.eclipse.jgit.annotations;version="[7.2.2,7.3.0)",
- org.eclipse.jgit.api.errors;version="[7.2.2,7.3.0)",
- org.eclipse.jgit.errors;version="[7.2.2,7.3.0)",
- org.eclipse.jgit.fnmatch;version="[7.2.2,7.3.0)",
- org.eclipse.jgit.internal.storage.file;version="[7.2.2,7.3.0)",
- org.eclipse.jgit.internal.transport.ssh;version="[7.2.2,7.3.0)",
- org.eclipse.jgit.lib;version="[7.2.2,7.3.0)",
- org.eclipse.jgit.nls;version="[7.2.2,7.3.0)",
- org.eclipse.jgit.transport;version="[7.2.2,7.3.0)",
- org.eclipse.jgit.util;version="[7.2.2,7.3.0)",
+ org.eclipse.jgit.annotations;version="[7.3.1,7.4.0)",
+ org.eclipse.jgit.api.errors;version="[7.3.1,7.4.0)",
+ org.eclipse.jgit.errors;version="[7.3.1,7.4.0)",
+ org.eclipse.jgit.fnmatch;version="[7.3.1,7.4.0)",
+ org.eclipse.jgit.internal.storage.file;version="[7.3.1,7.4.0)",
+ org.eclipse.jgit.internal.transport.ssh;version="[7.3.1,7.4.0)",
+ org.eclipse.jgit.lib;version="[7.3.1,7.4.0)",
+ org.eclipse.jgit.nls;version="[7.3.1,7.4.0)",
+ org.eclipse.jgit.transport;version="[7.3.1,7.4.0)",
+ org.eclipse.jgit.util;version="[7.3.1,7.4.0)",
  org.slf4j;version="[1.7.0,3.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 a4c95d4..87360df 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: 7.2.2.qualifier
-Eclipse-SourceBundle: org.eclipse.jgit.ssh.apache;version="7.2.2.qualifier";roots="."
+Bundle-Version: 7.3.1.qualifier
+Eclipse-SourceBundle: org.eclipse.jgit.ssh.apache;version="7.3.1.qualifier";roots="."
diff --git a/org.eclipse.jgit.ssh.apache/pom.xml b/org.eclipse.jgit.ssh.apache/pom.xml
index 0ad70b5..1895c21 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>7.2.2-SNAPSHOT</version>
+    <version>7.3.1-SNAPSHOT</version>
   </parent>
 
   <artifactId>org.eclipse.jgit.ssh.apache</artifactId>
diff --git a/org.eclipse.jgit.ssh.jsch.test/META-INF/MANIFEST.MF b/org.eclipse.jgit.ssh.jsch.test/META-INF/MANIFEST.MF
index 502f4f9..6201cc5 100644
--- a/org.eclipse.jgit.ssh.jsch.test/META-INF/MANIFEST.MF
+++ b/org.eclipse.jgit.ssh.jsch.test/META-INF/MANIFEST.MF
@@ -3,20 +3,20 @@
 Bundle-Name: %Bundle-Name
 Automatic-Module-Name: org.eclipse.jgit.ssh.jsch.test
 Bundle-SymbolicName: org.eclipse.jgit.ssh.jsch.test
-Bundle-Version: 7.2.2.qualifier
+Bundle-Version: 7.3.1.qualifier
 Bundle-Vendor: %Bundle-Vendor
 Bundle-Localization: plugin
 Bundle-RequiredExecutionEnvironment: JavaSE-17
 Require-Bundle: org.hamcrest.core;bundle-version="[1.3.0,2.0.0)"
 Import-Package: com.jcraft.jsch;version="[0.1.54,0.2.0)",
- org.eclipse.jgit.errors;version="[7.2.2,7.3.0)",
- org.eclipse.jgit.internal.storage.file;version="[7.2.2,7.3.0)",
- org.eclipse.jgit.junit;version="[7.2.2,7.3.0)",
- org.eclipse.jgit.junit.ssh;version="[7.2.2,7.3.0)",
- org.eclipse.jgit.lib;version="[7.2.2,7.3.0)",
- org.eclipse.jgit.transport;version="[7.2.2,7.3.0)",
- org.eclipse.jgit.transport.ssh.jsch;version="[7.2.2,7.3.0)",
- org.eclipse.jgit.util;version="[7.2.2,7.3.0)",
+ org.eclipse.jgit.errors;version="[7.3.1,7.4.0)",
+ org.eclipse.jgit.internal.storage.file;version="[7.3.1,7.4.0)",
+ org.eclipse.jgit.junit;version="[7.3.1,7.4.0)",
+ org.eclipse.jgit.junit.ssh;version="[7.3.1,7.4.0)",
+ org.eclipse.jgit.lib;version="[7.3.1,7.4.0)",
+ org.eclipse.jgit.transport;version="[7.3.1,7.4.0)",
+ org.eclipse.jgit.transport.ssh.jsch;version="[7.3.1,7.4.0)",
+ org.eclipse.jgit.util;version="[7.3.1,7.4.0)",
  org.junit;version="[4.13,5.0.0)",
  org.junit.experimental.theories;version="[4.13,5.0.0)",
  org.junit.runner;version="[4.13,5.0.0)"
diff --git a/org.eclipse.jgit.ssh.jsch.test/pom.xml b/org.eclipse.jgit.ssh.jsch.test/pom.xml
index 68fee6b..bbd3a17 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>7.2.2-SNAPSHOT</version>
+    <version>7.3.1-SNAPSHOT</version>
   </parent>
 
   <artifactId>org.eclipse.jgit.ssh.jsch.test</artifactId>
diff --git a/org.eclipse.jgit.ssh.jsch/META-INF/MANIFEST.MF b/org.eclipse.jgit.ssh.jsch/META-INF/MANIFEST.MF
index 2cae67a..5910786 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="[7.2.2,7.3.0)"
+Fragment-Host: org.eclipse.jgit;bundle-version="[7.3.1,7.4.0)"
 Bundle-Vendor: %Bundle-Vendor
 Bundle-Localization: OSGI-INF/l10n/jsch
 Bundle-ActivationPolicy: lazy
-Bundle-Version: 7.2.2.qualifier
+Bundle-Version: 7.3.1.qualifier
 Bundle-RequiredExecutionEnvironment: JavaSE-17
-Export-Package: org.eclipse.jgit.transport.ssh.jsch;version="7.2.2"
+Export-Package: org.eclipse.jgit.transport.ssh.jsch;version="7.3.1"
 Import-Package: com.jcraft.jsch;version="[0.1.37,0.2.0)",
- org.eclipse.jgit.errors;version="[7.2.2,7.3.0)",
- org.eclipse.jgit.internal;version="[7.2.2,7.3.0)",
- org.eclipse.jgit.internal.transport.ssh;version="[7.2.2,7.3.0)",
- org.eclipse.jgit.nls;version="[7.2.2,7.3.0)",
- org.eclipse.jgit.transport;version="[7.2.2,7.3.0)",
- org.eclipse.jgit.util;version="[7.2.2,7.3.0)",
- org.eclipse.jgit.util.io;version="[7.2.2,7.3.0)",
+ org.eclipse.jgit.errors;version="[7.3.1,7.4.0)",
+ org.eclipse.jgit.internal;version="[7.3.1,7.4.0)",
+ org.eclipse.jgit.internal.transport.ssh;version="[7.3.1,7.4.0)",
+ org.eclipse.jgit.nls;version="[7.3.1,7.4.0)",
+ org.eclipse.jgit.transport;version="[7.3.1,7.4.0)",
+ org.eclipse.jgit.util;version="[7.3.1,7.4.0)",
+ org.eclipse.jgit.util.io;version="[7.3.1,7.4.0)",
  org.slf4j;version="[1.7.0,3.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 964fb5d..1c267da 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: 7.2.2.qualifier
-Eclipse-SourceBundle: org.eclipse.jgit.ssh.jsch;version="7.2.2.qualifier";roots="."
+Bundle-Version: 7.3.1.qualifier
+Eclipse-SourceBundle: org.eclipse.jgit.ssh.jsch;version="7.3.1.qualifier";roots="."
diff --git a/org.eclipse.jgit.ssh.jsch/pom.xml b/org.eclipse.jgit.ssh.jsch/pom.xml
index 5a41c06..af7cc53 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>7.2.2-SNAPSHOT</version>
+    <version>7.3.1-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 58d072f..fc02bbb 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: 7.2.2.qualifier
+Bundle-Version: 7.3.1.qualifier
 Bundle-Localization: plugin
 Bundle-Vendor: %Bundle-Vendor
 Bundle-RequiredExecutionEnvironment: JavaSE-17
@@ -22,66 +22,66 @@
  org.apache.commons.io.output;version="[2.15.0,3.0.0)",
  org.apache.commons.lang3;version="[3.17.0,4.0.0)",
  org.assertj.core.api;version="[3.14.0,4.0.0)",
- org.eclipse.jgit.annotations;version="[7.2.2,7.3.0)",
- org.eclipse.jgit.api;version="[7.2.2,7.3.0)",
- org.eclipse.jgit.api.errors;version="[7.2.2,7.3.0)",
- org.eclipse.jgit.archive;version="[7.2.2,7.3.0)",
- org.eclipse.jgit.attributes;version="[7.2.2,7.3.0)",
- org.eclipse.jgit.awtui;version="[7.2.2,7.3.0)",
- org.eclipse.jgit.blame;version="[7.2.2,7.3.0)",
- org.eclipse.jgit.blame.cache;version="[7.2.2,7.3.0)",
- org.eclipse.jgit.diff;version="[7.2.2,7.3.0)",
- org.eclipse.jgit.dircache;version="[7.2.2,7.3.0)",
- org.eclipse.jgit.errors;version="[7.2.2,7.3.0)",
- org.eclipse.jgit.events;version="[7.2.2,7.3.0)",
- org.eclipse.jgit.fnmatch;version="[7.2.2,7.3.0)",
- org.eclipse.jgit.gitrepo;version="[7.2.2,7.3.0)",
- org.eclipse.jgit.hooks;version="[7.2.2,7.3.0)",
- org.eclipse.jgit.ignore;version="[7.2.2,7.3.0)",
- org.eclipse.jgit.ignore.internal;version="[7.2.2,7.3.0)",
- org.eclipse.jgit.internal;version="[7.2.2,7.3.0)",
- org.eclipse.jgit.internal.diff;version="[7.2.2,7.3.0)",
- org.eclipse.jgit.internal.diffmergetool;version="[7.2.2,7.3.0)",
- org.eclipse.jgit.internal.fsck;version="[7.2.2,7.3.0)",
- org.eclipse.jgit.internal.revwalk;version="[7.2.2,7.3.0)",
- org.eclipse.jgit.internal.storage.commitgraph;version="7.2.2",
- org.eclipse.jgit.internal.storage.dfs;version="[7.2.2,7.3.0)",
- org.eclipse.jgit.internal.storage.file;version="[7.2.2,7.3.0)",
- org.eclipse.jgit.internal.storage.io;version="[7.2.2,7.3.0)",
- org.eclipse.jgit.internal.storage.memory;version="[7.2.2,7.3.0)",
- org.eclipse.jgit.internal.storage.midx;version="[7.2.2,7.3.0)",
- org.eclipse.jgit.internal.storage.pack;version="[7.2.2,7.3.0)",
- org.eclipse.jgit.internal.storage.reftable;version="[7.2.2,7.3.0)",
- org.eclipse.jgit.internal.transport.connectivity;version="[7.2.2,7.3.0)",
- org.eclipse.jgit.internal.transport.http;version="[7.2.2,7.3.0)",
- org.eclipse.jgit.internal.transport.parser;version="[7.2.2,7.3.0)",
- org.eclipse.jgit.internal.transport.ssh;version="[7.2.2,7.3.0)",
- org.eclipse.jgit.junit;version="[7.2.2,7.3.0)",
- org.eclipse.jgit.junit.time;version="[7.2.2,7.3.0)",
- org.eclipse.jgit.lfs;version="[7.2.2,7.3.0)",
- org.eclipse.jgit.lib;version="[7.2.2,7.3.0)",
- org.eclipse.jgit.lib.internal;version="[7.2.2,7.3.0)",
- org.eclipse.jgit.logging;version="[7.2.2,7.3.0)",
- org.eclipse.jgit.merge;version="[7.2.2,7.3.0)",
- org.eclipse.jgit.nls;version="[7.2.2,7.3.0)",
- org.eclipse.jgit.notes;version="[7.2.2,7.3.0)",
- org.eclipse.jgit.patch;version="[7.2.2,7.3.0)",
- org.eclipse.jgit.pgm;version="[7.2.2,7.3.0)",
- org.eclipse.jgit.pgm.internal;version="[7.2.2,7.3.0)",
- org.eclipse.jgit.revplot;version="[7.2.2,7.3.0)",
- org.eclipse.jgit.revwalk;version="[7.2.2,7.3.0)",
- org.eclipse.jgit.revwalk.filter;version="[7.2.2,7.3.0)",
- org.eclipse.jgit.storage.file;version="[7.2.2,7.3.0)",
- org.eclipse.jgit.storage.pack;version="[7.2.2,7.3.0)",
- org.eclipse.jgit.submodule;version="[7.2.2,7.3.0)",
- org.eclipse.jgit.transport;version="[7.2.2,7.3.0)",
- org.eclipse.jgit.transport.http;version="[7.2.2,7.3.0)",
- org.eclipse.jgit.transport.resolver;version="[7.2.2,7.3.0)",
- org.eclipse.jgit.treewalk;version="[7.2.2,7.3.0)",
- org.eclipse.jgit.treewalk.filter;version="[7.2.2,7.3.0)",
- org.eclipse.jgit.util;version="[7.2.2,7.3.0)",
- org.eclipse.jgit.util.io;version="[7.2.2,7.3.0)",
- org.eclipse.jgit.util.sha1;version="[7.2.2,7.3.0)",
+ org.eclipse.jgit.annotations;version="[7.3.1,7.4.0)",
+ org.eclipse.jgit.api;version="[7.3.1,7.4.0)",
+ org.eclipse.jgit.api.errors;version="[7.3.1,7.4.0)",
+ org.eclipse.jgit.archive;version="[7.3.1,7.4.0)",
+ org.eclipse.jgit.attributes;version="[7.3.1,7.4.0)",
+ org.eclipse.jgit.awtui;version="[7.3.1,7.4.0)",
+ org.eclipse.jgit.blame;version="[7.3.1,7.4.0)",
+ org.eclipse.jgit.blame.cache;version="[7.3.1,7.4.0)",
+ org.eclipse.jgit.diff;version="[7.3.1,7.4.0)",
+ org.eclipse.jgit.dircache;version="[7.3.1,7.4.0)",
+ org.eclipse.jgit.errors;version="[7.3.1,7.4.0)",
+ org.eclipse.jgit.events;version="[7.3.1,7.4.0)",
+ org.eclipse.jgit.fnmatch;version="[7.3.1,7.4.0)",
+ org.eclipse.jgit.gitrepo;version="[7.3.1,7.4.0)",
+ org.eclipse.jgit.hooks;version="[7.3.1,7.4.0)",
+ org.eclipse.jgit.ignore;version="[7.3.1,7.4.0)",
+ org.eclipse.jgit.ignore.internal;version="[7.3.1,7.4.0)",
+ org.eclipse.jgit.internal;version="[7.3.1,7.4.0)",
+ org.eclipse.jgit.internal.diff;version="[7.3.1,7.4.0)",
+ org.eclipse.jgit.internal.diffmergetool;version="[7.3.1,7.4.0)",
+ org.eclipse.jgit.internal.fsck;version="[7.3.1,7.4.0)",
+ org.eclipse.jgit.internal.revwalk;version="[7.3.1,7.4.0)",
+ org.eclipse.jgit.internal.storage.commitgraph;version="7.3.1",
+ org.eclipse.jgit.internal.storage.dfs;version="[7.3.1,7.4.0)",
+ org.eclipse.jgit.internal.storage.file;version="[7.3.1,7.4.0)",
+ org.eclipse.jgit.internal.storage.io;version="[7.3.1,7.4.0)",
+ org.eclipse.jgit.internal.storage.memory;version="[7.3.1,7.4.0)",
+ org.eclipse.jgit.internal.storage.midx;version="[7.3.1,7.4.0)",
+ org.eclipse.jgit.internal.storage.pack;version="[7.3.1,7.4.0)",
+ org.eclipse.jgit.internal.storage.reftable;version="[7.3.1,7.4.0)",
+ org.eclipse.jgit.internal.transport.connectivity;version="[7.3.1,7.4.0)",
+ org.eclipse.jgit.internal.transport.http;version="[7.3.1,7.4.0)",
+ org.eclipse.jgit.internal.transport.parser;version="[7.3.1,7.4.0)",
+ org.eclipse.jgit.internal.transport.ssh;version="[7.3.1,7.4.0)",
+ org.eclipse.jgit.junit;version="[7.3.1,7.4.0)",
+ org.eclipse.jgit.junit.time;version="[7.3.1,7.4.0)",
+ org.eclipse.jgit.lfs;version="[7.3.1,7.4.0)",
+ org.eclipse.jgit.lib;version="[7.3.1,7.4.0)",
+ org.eclipse.jgit.lib.internal;version="[7.3.1,7.4.0)",
+ org.eclipse.jgit.logging;version="[7.3.1,7.4.0)",
+ org.eclipse.jgit.merge;version="[7.3.1,7.4.0)",
+ org.eclipse.jgit.nls;version="[7.3.1,7.4.0)",
+ org.eclipse.jgit.notes;version="[7.3.1,7.4.0)",
+ org.eclipse.jgit.patch;version="[7.3.1,7.4.0)",
+ org.eclipse.jgit.pgm;version="[7.3.1,7.4.0)",
+ org.eclipse.jgit.pgm.internal;version="[7.3.1,7.4.0)",
+ org.eclipse.jgit.revplot;version="[7.3.1,7.4.0)",
+ org.eclipse.jgit.revwalk;version="[7.3.1,7.4.0)",
+ org.eclipse.jgit.revwalk.filter;version="[7.3.1,7.4.0)",
+ org.eclipse.jgit.storage.file;version="[7.3.1,7.4.0)",
+ org.eclipse.jgit.storage.pack;version="[7.3.1,7.4.0)",
+ org.eclipse.jgit.submodule;version="[7.3.1,7.4.0)",
+ org.eclipse.jgit.transport;version="[7.3.1,7.4.0)",
+ org.eclipse.jgit.transport.http;version="[7.3.1,7.4.0)",
+ org.eclipse.jgit.transport.resolver;version="[7.3.1,7.4.0)",
+ org.eclipse.jgit.treewalk;version="[7.3.1,7.4.0)",
+ org.eclipse.jgit.treewalk.filter;version="[7.3.1,7.4.0)",
+ org.eclipse.jgit.util;version="[7.3.1,7.4.0)",
+ org.eclipse.jgit.util.io;version="[7.3.1,7.4.0)",
+ org.eclipse.jgit.util.sha1;version="[7.3.1,7.4.0)",
  org.junit;version="[4.13,5.0.0)",
  org.junit.experimental.theories;version="[4.13,5.0.0)",
  org.junit.function;version="[4.13.0,5.0.0)",
diff --git a/org.eclipse.jgit.test/exttst/org/eclipse/jgit/ignore/CGitVsJGitRandomIgnorePatternTest.java b/org.eclipse.jgit.test/exttst/org/eclipse/jgit/ignore/CGitVsJGitRandomIgnorePatternTest.java
index 23a267c..47a410b 100644
--- a/org.eclipse.jgit.test/exttst/org/eclipse/jgit/ignore/CGitVsJGitRandomIgnorePatternTest.java
+++ b/org.eclipse.jgit.test/exttst/org/eclipse/jgit/ignore/CGitVsJGitRandomIgnorePatternTest.java
@@ -164,7 +164,7 @@ private Process startCgitCheckIgnore(String path) throws IOException {
 		private String readProcessStream(InputStream processStream)
 				throws IOException {
 			try (BufferedReader stdOut = new BufferedReader(
-					new InputStreamReader(processStream))) {
+					new InputStreamReader(processStream, UTF_8))) {
 
 				StringBuilder out = new StringBuilder();
 				String s;
diff --git a/org.eclipse.jgit.test/exttst/org/eclipse/jgit/internal/storage/midx/CgitMidxCompatibilityTest.java b/org.eclipse.jgit.test/exttst/org/eclipse/jgit/internal/storage/midx/CgitMidxCompatibilityTest.java
index 88f0806..334e52b 100644
--- a/org.eclipse.jgit.test/exttst/org/eclipse/jgit/internal/storage/midx/CgitMidxCompatibilityTest.java
+++ b/org.eclipse.jgit.test/exttst/org/eclipse/jgit/internal/storage/midx/CgitMidxCompatibilityTest.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2025, Google Inc.
+ * Copyright (C) 2025, Google LLC
  *
  * This program and the accompanying materials are made available under the
  * terms of the Eclipse Distribution License v. 1.0 which is available at
@@ -18,6 +18,7 @@
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertTrue;
 
+import java.io.ByteArrayInputStream;
 import java.io.ByteArrayOutputStream;
 import java.io.File;
 import java.io.IOException;
@@ -81,6 +82,16 @@ public void compareBasicChunkSizes()
 
 	}
 
+	@Test
+	public void jgit_loadsCgitMidx()
+			throws IOException, InterruptedException {
+		assertEquals("cgit exit code", 0, run_cgit_multipackindex_write());
+		byte[] cgitMidxBytes = readCgitMidx();
+		MultiPackIndex midx = MultiPackIndexLoader
+				.read(new ByteArrayInputStream(cgitMidxBytes));
+		assertEquals(7, midx.getPackNames().length);
+	}
+
 	private byte[] generateJGitMidx() throws IOException {
 		Map<String, PackIndex> indexes = new HashMap<>();
 		for (Pack pack : db.getObjectDatabase().getPacks()) {
diff --git a/org.eclipse.jgit.test/pom.xml b/org.eclipse.jgit.test/pom.xml
index e514fd1..130dea7 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>7.2.2-SNAPSHOT</version>
+    <version>7.3.1-SNAPSHOT</version>
   </parent>
 
   <artifactId>org.eclipse.jgit.test</artifactId>
diff --git a/org.eclipse.jgit.test/tst-rsrc/org/eclipse/jgit/test/resources/multi-pack-index.v1 b/org.eclipse.jgit.test/tst-rsrc/org/eclipse/jgit/test/resources/multi-pack-index.v1
new file mode 100644
index 0000000..223febe
--- /dev/null
+++ b/org.eclipse.jgit.test/tst-rsrc/org/eclipse/jgit/test/resources/multi-pack-index.v1
Binary files differ
diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/PullCommandTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/PullCommandTest.java
index 6d5e45c..695681d 100644
--- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/PullCommandTest.java
+++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/PullCommandTest.java
@@ -480,7 +480,7 @@ public void testPullWithRebaseConfig3() throws Exception {
 	@Test
 	/** without config it should merge */
 	public void testPullWithoutConfig() throws Exception {
-		Callable<PullResult> setup = target.pull()::call;
+		Callable<PullResult> setup = target.pull();
 		doTestPullWithRebase(setup, TestPullMode.MERGE);
 	}
 
diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/blame/BlameGeneratorCacheTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/blame/BlameGeneratorCacheTest.java
index 65cac11..3e4ac1f 100644
--- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/blame/BlameGeneratorCacheTest.java
+++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/blame/BlameGeneratorCacheTest.java
@@ -19,7 +19,6 @@
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
-import java.util.stream.Collectors;
 
 import org.eclipse.jgit.blame.cache.BlameCache;
 import org.eclipse.jgit.blame.cache.CacheRegion;
@@ -46,7 +45,8 @@ public class BlameGeneratorCacheTest extends RepositoryTestCase {
 	 * L4    |       *C2    C2   *C4     C4
 	 * </pre>
 	 *
-	 * @throws Exception any error
+	 * @throws Exception
+	 *             any error
 	 */
 	@Test
 	public void blame_simple_correctRegions() throws Exception {
@@ -87,7 +87,64 @@ public void blame_simple_cacheUsage() throws Exception {
 		assertCacheUsage(c4, blameAndCache(c4), true, 1);
 		assertCacheUsage(c4, blameAndCache(c3), true, 2);
 		assertCacheUsage(c4, blameAndCache(c2), true, 3);
-		assertCacheUsage(c4, blameAndCache(c1), true, 4);
+		// Cache not needed because c1 doesn't have parents
+		assertCacheUsage(c4, blameAndCache(c1), false, 4);
+	}
+
+	@Test
+	public void blame_simple_createdMidHistory_correctRegions() throws Exception {
+		String c1Content = lines("L1C1", "L2C1", "L3C1");
+		String c2Content = lines("L1C1", "L2C1", "L3C1", "L4C2");
+		String c3Content = lines("L1C1", "L2C3", "L3C3", "L4C2");
+		String c4Content = lines("L1C1", "L2C4", "L3C3", "L4C4");
+
+		RevCommit c0, c1, c2, c3, c4;
+		try (TestRepository<FileRepository> r = new TestRepository<>(db)) {
+			c0 = r.commit().add("otherfile", "content").create();
+			c1 = r.commit().parent(c0).add(FILE, c1Content).create();
+			c2 = r.commit().parent(c1).add(FILE, c2Content).create();
+			c3 = r.commit().parent(c2).add(FILE, c3Content).create();
+			c4 = r.commit().parent(c3).add(FILE, c4Content).create();
+		}
+
+		List<EmittedRegion> expectedRegions = Arrays.asList(
+				new EmittedRegion(c1, 0, 1),
+				new EmittedRegion(c4, 1, 2),
+				new EmittedRegion(c3, 2, 3),
+				new EmittedRegion(c4, 3, 4));
+
+		assertRegions(c4, null, expectedRegions, 4);
+		assertRegions(c4, emptyCache(), expectedRegions, 4);
+		assertRegions(c4, blameAndCache(c4, FILE), expectedRegions, 4);
+		assertRegions(c4, blameAndCache(c3, FILE), expectedRegions, 4);
+		assertRegions(c4, blameAndCache(c2, FILE), expectedRegions, 4);
+		assertRegions(c4, blameAndCache(c1, FILE), expectedRegions, 4);
+		assertRegions(c4, blameAndCache(c0, FILE), expectedRegions, 4);
+	}
+
+	@Test
+	public void blame_simple_createdMidHistory_cacheUsage() throws Exception {
+		String c1Content = lines("L1C1", "L2C1", "L3C1");
+		String c2Content = lines("L1C1", "L2C1", "L3C1", "L4C2");
+		String c3Content = lines("L1C1", "L2C3", "L3C3", "L4C2");
+		String c4Content = lines("L1C1", "L2C4", "L3C3", "L4C4");
+
+		RevCommit c0, c1, c2, c3, c4;
+		try (TestRepository<FileRepository> r = new TestRepository<>(db)) {
+			c0 = r.commit().add("otherfile", "content").create();
+			c1 = r.commit().parent(c0).add(FILE, c1Content).create();
+			c2 = r.commit().parent(c1).add(FILE, c2Content).create();
+			c3 = r.commit().parent(c2).add(FILE, c3Content).create();
+			c4 = r.commit().parent(c3).add(FILE, c4Content).create();
+		}
+
+		assertCacheUsage(c4, null, false, 4);
+		assertCacheUsage(c4, emptyCache(), false, 4);
+		assertCacheUsage(c4, blameAndCache(c4, FILE), true, 1);
+		assertCacheUsage(c4, blameAndCache(c3, FILE), true, 2);
+		assertCacheUsage(c4, blameAndCache(c2, FILE), true, 3);
+		// Cache not needed because c1 created the file
+		assertCacheUsage(c4, blameAndCache(c1, FILE), false, 4);
 	}
 
 	/**
@@ -102,10 +159,11 @@ public void blame_simple_cacheUsage() throws Exception {
 	 * L4    |       *C2
 	 * </pre>
 	 *
-	 * @throws Exception any error
+	 * @throws Exception
+	 *             any error
 	 */
 	@Test
-	public void blame_ovewrite_correctRegions() throws Exception {
+	public void blame_overwrite_correctRegions() throws Exception {
 		RevCommit c1, c2, c3;
 		try (TestRepository<FileRepository> r = new TestRepository<>(db)) {
 			c1 = commit(r, lines("L1C1", "L2C1", "L3C1"));
@@ -166,7 +224,8 @@ public void blame_overwrite_cacheUsage() throws Exception {
 	 *              L8-L11 b (from sideB)
 	 * </pre>
 	 *
-	 * @throws Exception any error
+	 * @throws Exception
+	 *             any error
 	 */
 	@Test
 	public void blame_merge_correctRegions() throws Exception {
@@ -204,14 +263,13 @@ public void blame_merge_cacheUsage() throws Exception {
 		assertCacheUsage(mergedTip, null, /* cacheUsed */ false,
 				/* candidates */ 4);
 		assertCacheUsage(mergedTip, emptyCache(), false, 4);
-		assertCacheUsage(mergedTip, blameAndCache(mergedTip), true, 1);
 
 		// While splitting unblamed regions to parents, sideA comes first
 		// and gets "aaaa----". Processing is by commit time, so sideB is
 		// explored first
 		assertCacheUsage(mergedTip, blameAndCache(sideA), true, 3);
 		assertCacheUsage(mergedTip, blameAndCache(sideB), true, 4);
-		assertCacheUsage(mergedTip, blameAndCache(root), true, 4);
+		assertCacheUsage(mergedTip, blameAndCache(root), false, 4);
 	}
 
 	/**
@@ -226,7 +284,8 @@ public void blame_merge_cacheUsage() throws Exception {
 	 * L4    |              C1      C1
 	 * </pre>
 	 *
-	 * @throws Exception any error
+	 * @throws Exception
+	 *             any error
 	 */
 	@Test
 	public void blame_movingBlock_correctRegions() throws Exception {
@@ -263,7 +322,77 @@ public void blame_movingBlock_cacheUsage() throws Exception {
 		assertCacheUsage(c3, emptyCache(), false, 3);
 		assertCacheUsage(c3, blameAndCache(c3), true, 1);
 		assertCacheUsage(c3, blameAndCache(c2), true, 2);
-		assertCacheUsage(c3, blameAndCache(c1), true, 3);
+		assertCacheUsage(c3, blameAndCache(c1), false, 3);
+	}
+
+	@Test
+	public void blame_cacheOnlyOnChange_unmodifiedInSomeCommits_cacheUsage() throws Exception {
+		String README = "README";
+		String fileC1Content = lines("L1C1", "L2C1", "L3C1");
+		String fileC2Content = lines("L1C1", "L2C1", "L3C1", "L4C2");
+		String fileC3Content = lines("L1C1", "L2C3", "L3C3", "L4C2");
+		String fileC4Content = lines("L1C1", "L2C4", "L3C3", "L4C4");
+
+		RevCommit c1, c2, c3, c4, ni;
+		try (TestRepository<FileRepository> r = new TestRepository<>(db)) {
+			c1 = r.commit().add(FILE, fileC1Content).create();
+			c2 = r.commit().parent(c1).add(FILE, fileC2Content).create();
+			// Keep FILE and edit 100 times README
+			ni = c2;
+			for (int i = 0; i < 100; i++) {
+				ni = r.commit().parent(ni).add(README, "whatever " + i).create();
+			}
+			c3 = r.commit().parent(ni).add(FILE, fileC3Content).create();
+			c4 = r.commit().parent(c3).add(FILE, fileC4Content).create();
+			r.branch("refs/heads/master").update(c4);
+		}
+
+		InMemoryBlameCache empty = emptyCache();
+		assertCacheUsage(c4, empty, false, 104);
+		assertEquals(3, empty.callCount);
+
+		InMemoryBlameCache c4Cached = blameAndCache(c4, FILE);
+		assertCacheUsage(c4, c4Cached, true, 1);
+		assertEquals(1, c4Cached.callCount);
+
+		InMemoryBlameCache c3Cached = blameAndCache(c3, FILE);
+		assertCacheUsage(c4, c3Cached, true, 2);
+		assertEquals(2, c3Cached.callCount);
+
+		// This commit doesn't touch the file, shouldn't check the cache
+		InMemoryBlameCache niCached = blameAndCache(ni, FILE);
+		assertCacheUsage(c4, niCached, false, 104);
+		assertEquals(3, niCached.callCount);
+
+		InMemoryBlameCache c2Cached = blameAndCache(c2, FILE);
+		assertCacheUsage(c4, c2Cached, true, 103);
+		assertEquals(3, c2Cached.callCount);
+
+		// No parents, c1 doesn't need cache.
+		InMemoryBlameCache c1Cached = blameAndCache(c1, FILE);
+		assertCacheUsage(c4, c1Cached, false, 104);
+		assertEquals(3, c1Cached.callCount);
+	}
+
+	@Test
+	public void blame_cacheOnlyOnChange_renameWithoutChange_cacheUsage() throws Exception {
+		String OTHER = "other.txt";
+		String c1Content = lines("L1C1", "L2C1", "L3C1");
+		String c2Content = lines("L1C1", "L2C1", "L3C1", "L4C2");
+
+		RevCommit c1, c2, c3;
+		try (TestRepository<FileRepository> r = new TestRepository<>(db)) {
+			c1 = r.commit().add(OTHER, c1Content).create();
+			c2 = r.commit().parent(c1).add(OTHER, c2Content).create();
+			c3 = r.commit().parent(c2).rm(OTHER).add(FILE, c2Content).create();
+			r.branch("refs/heads/master").update(c3);
+		}
+
+		assertCacheUsage(c3, null, false, 3);
+		assertCacheUsage(c3, emptyCache(), false, 3);
+		assertCacheUsage(c3, blameAndCache(c3, FILE), true, 1);
+		assertCacheUsage(c3, blameAndCache(c2, OTHER), true, 2);
+		assertCacheUsage(c3, blameAndCache(c1, OTHER), false, 3);
 	}
 
 	private void assertRegions(RevCommit commit, InMemoryBlameCache cache,
@@ -278,11 +407,11 @@ private void assertRegions(RevCommit commit, InMemoryBlameCache cache,
 	}
 
 	private void assertCacheUsage(RevCommit commit, InMemoryBlameCache cache,
-			boolean useCache, int candidatesVisited) throws IOException {
+			boolean cacheHit, int candidatesVisited) throws IOException {
 		try (BlameGenerator gen = new BlameGenerator(db, FILE, cache)) {
 			gen.push(null, db.parseCommit(commit));
 			consume(gen);
-			assertEquals(useCache, gen.getStats().isCacheHit());
+			assertEquals(cacheHit, gen.getStats().isCacheHit());
 			assertEquals(candidatesVisited,
 					gen.getStats().getCandidatesVisited());
 		}
@@ -300,8 +429,8 @@ private static void assertAllLinesCovered(int lines,
 				regions.get(regions.size() - 1).resultEnd());
 	}
 
-	private static void assertRegionsEquals(
-			List<EmittedRegion> expected, List<EmittedRegion> actual) {
+	private static void assertRegionsEquals(List<EmittedRegion> expected,
+			List<EmittedRegion> actual) {
 		assertEquals(expected.size(), actual.size());
 		Collections.sort(actual);
 		for (int i = 0; i < expected.size(); i++) {
@@ -328,15 +457,20 @@ private List<EmittedRegion> consume(BlameGenerator generator)
 
 	private InMemoryBlameCache blameAndCache(RevCommit commit)
 			throws IOException {
+		return blameAndCache(commit, FILE);
+	}
+
+	private InMemoryBlameCache blameAndCache(RevCommit commit, String path)
+			throws IOException {
 		List<CacheRegion> regions;
-		try (BlameGenerator generator = new BlameGenerator(db, FILE)) {
+		try (BlameGenerator generator = new BlameGenerator(db, path)) {
 			generator.push(null, commit);
 			regions = consume(generator).stream()
 					.map(EmittedRegion::asCacheRegion)
-					.collect(Collectors.toUnmodifiableList());
+					.toList();
 		}
 		InMemoryBlameCache cache = new InMemoryBlameCache("<x>");
-		cache.put(commit, FILE, regions);
+		cache.put(commit, path, regions);
 		return cache;
 	}
 
@@ -347,7 +481,24 @@ private static RevCommit commitAsLines(TestRepository<?> r,
 
 	private static RevCommit commit(TestRepository<?> r, String contents,
 			RevCommit... parents) throws Exception {
-		return r.commit(r.tree(r.file(FILE, r.blob(contents))), parents);
+		return commit(r, Map.of(FILE, contents), parents);
+	}
+
+	private static RevCommit commit(TestRepository<?> r,
+			Map<String, String> fileContents, RevCommit... parents)
+			throws Exception {
+		TestRepository<?>.CommitBuilder builder = r.commit();
+		for (RevCommit commit : parents) {
+			builder.parent(commit);
+		}
+		fileContents.forEach((path, content) -> {
+			try {
+				builder.add(path, content);
+			} catch (Exception e) {
+				throw new RuntimeException(e);
+			}
+		});
+		return builder.create();
 	}
 
 	private static String lines(String... l) {
@@ -372,18 +523,21 @@ private static class InMemoryBlameCache implements BlameCache {
 
 		private final String description;
 
+		private int callCount;
+
 		public InMemoryBlameCache(String description) {
 			this.description = description;
 		}
 
 		@Override
 		public List<CacheRegion> get(Repository repo, ObjectId commitId,
-									 String path) throws IOException {
+				String path) throws IOException {
+			callCount++;
 			return cache.get(new Key(commitId.name(), path));
 		}
 
 		public void put(ObjectId commitId, String path,
-						List<CacheRegion> cachedRegions) {
+				List<CacheRegion> cachedRegions) {
 			cache.put(new Key(commitId.name(), path), cachedRegions);
 		}
 
diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/diff/EditListTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/diff/EditListTest.java
index f657bab..a2c20aa 100644
--- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/diff/EditListTest.java
+++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/diff/EditListTest.java
@@ -28,7 +28,7 @@ public void testEmpty() {
 		assertTrue(l.isEmpty());
 		assertEquals("EditList[]", l.toString());
 
-		assertEquals(l, l);
+		assertTrue(l.equals(l));
 		assertEquals(new EditList(), l);
 		assertFalse(l.equals(""));
 		assertEquals(l.hashCode(), new EditList().hashCode());
@@ -44,7 +44,7 @@ public void testAddOne() {
 		assertSame(e, l.get(0));
 		assertSame(e, l.iterator().next());
 
-		assertEquals(l, l);
+		assertTrue(l.equals(l));
 		assertFalse(l.equals(new EditList()));
 
 		final EditList l2 = new EditList();
@@ -69,7 +69,7 @@ public void testAddTwo() {
 		assertSame(e1, i.next());
 		assertSame(e2, i.next());
 
-		assertEquals(l, l);
+		assertTrue(l.equals(l));
 		assertFalse(l.equals(new EditList()));
 
 		final EditList l2 = new EditList();
diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/diff/EditTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/diff/EditTest.java
index 8ab9bb1..86c6d77 100644
--- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/diff/EditTest.java
+++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/diff/EditTest.java
@@ -98,7 +98,7 @@ public void testEquals1() {
 		final Edit e1 = new Edit(1, 2, 3, 4);
 		final Edit e2 = new Edit(1, 2, 3, 4);
 
-		assertEquals(e1, e1);
+		assertTrue(e1.equals(e1));
 		assertEquals(e2, e1);
 		assertEquals(e1, e2);
 		assertEquals(e1.hashCode(), e2.hashCode());
diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/ignore/BasicRuleTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/ignore/BasicRuleTest.java
index 6112952..6983eaa 100644
--- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/ignore/BasicRuleTest.java
+++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/ignore/BasicRuleTest.java
@@ -31,7 +31,7 @@ public void test() {
 		assertFalse(rule1.getNegation());
 		assertTrue(rule3.getNegation());
 		assertNotEquals(rule1, null);
-		assertEquals(rule1, rule1);
+		assertTrue(rule1.equals(rule1));
 		assertEquals(rule1, rule2);
 		assertNotEquals(rule1, rule3);
 		assertNotEquals(rule1, rule4);
diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/dfs/DfsInserterTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/dfs/DfsInserterTest.java
index 0b558ed..49f399c 100644
--- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/dfs/DfsInserterTest.java
+++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/dfs/DfsInserterTest.java
@@ -214,7 +214,7 @@ public void testInserterIgnoresUnreachable() throws IOException {
 	}
 
 	@Test
-	public void testNoCheckExisting() throws IOException {
+	public void testNoDuplicates() throws IOException {
 		byte[] contents = Constants.encode("foo");
 		ObjectId fooId;
 		try (ObjectInserter ins = db.newObjectInserter()) {
@@ -224,21 +224,20 @@ public void testNoCheckExisting() throws IOException {
 		assertEquals(1, db.getObjectDatabase().listPacks().size());
 
 		try (ObjectInserter ins = db.newObjectInserter()) {
-			((DfsInserter) ins).checkExisting(false);
+			ins.insert(Constants.OBJ_BLOB, Constants.encode("bar"));
 			assertEquals(fooId, ins.insert(Constants.OBJ_BLOB, contents));
 			ins.flush();
 		}
 		assertEquals(2, db.getObjectDatabase().listPacks().size());
 
-		// Verify that we have a foo in both INSERT packs.
+		// Newer packs are first. Verify that foo is only in the second pack
 		try (DfsReader reader = new DfsReader(db.getObjectDatabase())) {
 			DfsPackFile packs[] = db.getObjectDatabase().getPacks();
-
 			assertEquals(2, packs.length);
 			DfsPackFile p1 = packs[0];
 			assertEquals(PackSource.INSERT,
 					p1.getPackDescription().getPackSource());
-			assertTrue(p1.hasObject(reader, fooId));
+			assertFalse(p1.hasObject(reader, fooId));
 
 			DfsPackFile p2 = packs[1];
 			assertEquals(PackSource.INSERT,
diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/file/FileReftableStackTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/file/FileReftableStackTest.java
index 6c79927..e8363ce 100644
--- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/file/FileReftableStackTest.java
+++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/file/FileReftableStackTest.java
@@ -81,8 +81,7 @@ void writeBranches(FileReftableStack stack, String template, int start,
 	}
 
 	public void testCompaction(int N) throws Exception {
-		try (FileReftableStack stack = new FileReftableStack(
-				new File(reftableDir, "refs"), reftableDir, null,
+		try (FileReftableStack stack = new FileReftableStack(reftableDir, null,
 				() -> new Config())) {
 			writeBranches(stack, "refs/heads/branch%d", 0, N);
 			MergedReftable table = stack.getMergedReftable();
@@ -124,8 +123,7 @@ public void missingReftable() throws Exception {
 		// Can't delete in-use files on Windows.
 		assumeFalse(SystemReader.getInstance().isWindows());
 
-		try (FileReftableStack stack = new FileReftableStack(
-				new File(reftableDir, "refs"), reftableDir, null,
+		try (FileReftableStack stack = new FileReftableStack(reftableDir, null,
 				() -> new Config())) {
 			outer: for (int i = 0; i < 10; i++) {
 				final long next = stack.getMergedReftable().maxUpdateIndex()
@@ -152,8 +150,8 @@ public void missingReftable() throws Exception {
 			}
 		}
 		assertThrows(FileNotFoundException.class,
-				() -> new FileReftableStack(new File(reftableDir, "refs"),
-						reftableDir, null, () -> new Config()));
+				() -> new FileReftableStack(reftableDir, null,
+						() -> new Config()));
 	}
 
 	@Test
diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/midx/MultiPackIndexBuilderTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/midx/MultiPackIndexBuilderTest.java
new file mode 100644
index 0000000..e6fefc6
--- /dev/null
+++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/midx/MultiPackIndexBuilderTest.java
@@ -0,0 +1,107 @@
+/*
+ * Copyright (C) 2024, GerritForge Inc. and others
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Distribution License v. 1.0 which is available at
+ * https://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+package org.eclipse.jgit.internal.storage.midx;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertThrows;
+
+import org.eclipse.jgit.internal.storage.midx.MultiPackIndexLoader.MultiPackIndexBuilder;
+import org.eclipse.jgit.internal.storage.midx.MultiPackIndexLoader.MultiPackIndexFormatException;
+import org.junit.Test;
+
+public class MultiPackIndexBuilderTest {
+
+	@Test
+	public void testRepeatedChunk() throws Exception {
+		byte[] buffer = new byte[2048];
+
+		MultiPackIndexBuilder builder1 = MultiPackIndexBuilder.builder();
+		builder1.addOidFanout(buffer);
+		Exception e1 = assertThrows(MultiPackIndexFormatException.class, () -> {
+			builder1.addOidFanout(buffer);
+		});
+		assertEquals("midx chunk id 0x4f494446 appears multiple times",
+				e1.getMessage());
+
+		MultiPackIndexBuilder builder2 = MultiPackIndexBuilder.builder();
+		builder2.addOidLookUp(buffer);
+		Exception e2 = assertThrows(MultiPackIndexFormatException.class, () -> {
+			builder2.addOidLookUp(buffer);
+		});
+		assertEquals("midx chunk id 0x4f49444c appears multiple times",
+				e2.getMessage());
+
+		MultiPackIndexBuilder builder3 = MultiPackIndexBuilder.builder();
+		builder3.addObjectOffsets(buffer);
+		Exception e3 = assertThrows(MultiPackIndexFormatException.class, () -> {
+			builder3.addObjectOffsets(buffer);
+		});
+		assertEquals("midx chunk id 0x4f4f4646 appears multiple times",
+				e3.getMessage());
+
+		MultiPackIndexBuilder builder4 = MultiPackIndexBuilder.builder();
+		builder4.addPackNames(buffer);
+		Exception e4 = assertThrows(MultiPackIndexFormatException.class, () -> {
+			builder4.addPackNames(buffer);
+		});
+		assertEquals("midx chunk id 0x504e414d appears multiple times",
+				e4.getMessage());
+
+		MultiPackIndexBuilder builder5 = MultiPackIndexBuilder.builder();
+		builder5.addBitmappedPacks(buffer);
+		Exception e5 = assertThrows(MultiPackIndexFormatException.class, () -> {
+			builder5.addBitmappedPacks(buffer);
+		});
+		assertEquals("midx chunk id 0x42544d50 appears multiple times",
+				e5.getMessage());
+
+		MultiPackIndexBuilder builder6 = MultiPackIndexBuilder.builder();
+		builder6.addObjectLargeOffsets(buffer);
+		Exception e6 = assertThrows(MultiPackIndexFormatException.class, () -> {
+			builder6.addObjectLargeOffsets(buffer);
+		});
+		assertEquals("midx chunk id 0x4c4f4646 appears multiple times",
+				e6.getMessage());
+
+		MultiPackIndexBuilder builder7 = MultiPackIndexBuilder.builder();
+		builder7.addReverseIndex(buffer);
+		Exception e7 = assertThrows(MultiPackIndexFormatException.class, () -> {
+			builder7.addReverseIndex(buffer);
+		});
+		assertEquals("midx chunk id 0x52494458 appears multiple times",
+				e7.getMessage());
+	}
+
+	@Test
+	public void testNeededChunk() {
+		byte[] buffer = new byte[2048];
+
+		Exception e1 = assertThrows(MultiPackIndexFormatException.class, () -> {
+			MultiPackIndexBuilder.builder().addOidLookUp(buffer).build();
+		});
+		assertEquals("midx 0x4f494446 chunk has not been loaded",
+				e1.getMessage());
+
+		Exception e2 = assertThrows(MultiPackIndexFormatException.class, () -> {
+			MultiPackIndexBuilder.builder().addOidFanout(buffer)
+					.addOidLookUp(buffer).build();
+		});
+		assertEquals("midx 0x504e414d chunk has not been loaded",
+				e2.getMessage());
+
+		Exception e3 = assertThrows(MultiPackIndexFormatException.class, () -> {
+			MultiPackIndexBuilder.builder().addOidFanout(buffer)
+					.addOidLookUp(buffer).addPackNames(buffer).build();
+		});
+		assertEquals("midx 0x4f4f4646 chunk has not been loaded",
+				e3.getMessage());
+	}
+}
diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/midx/MultiPackIndexLoaderTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/midx/MultiPackIndexLoaderTest.java
new file mode 100644
index 0000000..494f1d1
--- /dev/null
+++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/midx/MultiPackIndexLoaderTest.java
@@ -0,0 +1,90 @@
+/*
+ * Copyright (C) 2024, GerritForge Inc. and others
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Distribution License v. 1.0 which is available at
+ * https://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+package org.eclipse.jgit.internal.storage.midx;
+
+import static java.nio.charset.StandardCharsets.UTF_8;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertThrows;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.util.List;
+import java.util.Map;
+
+import org.eclipse.jgit.internal.storage.file.PackIndex;
+import org.eclipse.jgit.junit.FakeIndexFactory;
+import org.eclipse.jgit.junit.JGitTestUtil;
+import org.eclipse.jgit.lib.NullProgressMonitor;
+import org.junit.Test;
+
+/**
+ * Test that the loader accepts valid files, discard broken files
+ * <p>
+ * Contents and lookups are covered in the MultiPackIndexTest
+ */
+public class MultiPackIndexLoaderTest {
+
+	@Test
+	public void load_validFile_basic_upstream() throws Exception {
+		MultiPackIndex midx = MultiPackIndexLoader
+				.open(JGitTestUtil.getTestResourceFile("multi-pack-index.v1"));
+		assertNotNull(midx);
+	}
+
+	@Test
+	public void load_validFile_basic_jgit() throws Exception {
+		PackIndex idxOne = FakeIndexFactory.indexOf(List.of(
+				new FakeIndexFactory.IndexObject(
+						"0000000000000000000000000000000000000001", 500),
+				new FakeIndexFactory.IndexObject(
+						"0000000000000000000000000000000000000005", 12),
+				new FakeIndexFactory.IndexObject(
+						"0000000000000000000000000000000000000010", 1500)));
+		PackIndex idxTwo = FakeIndexFactory.indexOf(List.of(
+				new FakeIndexFactory.IndexObject(
+						"0000000000000000000000000000000000000002", 501),
+				new FakeIndexFactory.IndexObject(
+						"0000000000000000000000000000000000000003", 13),
+				new FakeIndexFactory.IndexObject(
+						"0000000000000000000000000000000000000015", 1501)));
+		PackIndex idxThree = FakeIndexFactory.indexOf(List.of(
+				new FakeIndexFactory.IndexObject(
+						"0000000000000000000000000000000000000004", 502),
+				new FakeIndexFactory.IndexObject(
+						"0000000000000000000000000000000000000007", 14),
+				new FakeIndexFactory.IndexObject(
+						"0000000000000000000000000000000000000012", 1502)));
+
+		Map<String, PackIndex> packs = Map.of("p1", idxOne, "p2", idxTwo, "p3",
+				idxThree);
+		MultiPackIndexWriter writer = new MultiPackIndexWriter();
+		ByteArrayOutputStream out = new ByteArrayOutputStream();
+		writer.write(NullProgressMonitor.INSTANCE, out, packs);
+
+		MultiPackIndex midx = MultiPackIndexLoader
+				.read(new ByteArrayInputStream(out.toByteArray()));
+		assertNotNull(midx);
+	}
+
+	@Test
+	public void load_emptyFile() {
+		assertThrows(IOException.class, () -> MultiPackIndexLoader
+				.read(new ByteArrayInputStream(new byte[0])));
+	}
+
+	@Test
+	public void load_rubbishFile() {
+		assertThrows(MultiPackIndexLoader.MultiPackIndexFormatException.class,
+				() -> MultiPackIndexLoader.read(new ByteArrayInputStream(
+						"More than 12 bytes of not-midx".getBytes(UTF_8))));
+	}
+}
diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/midx/MultiPackIndexTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/midx/MultiPackIndexTest.java
new file mode 100644
index 0000000..ab45285
--- /dev/null
+++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/midx/MultiPackIndexTest.java
@@ -0,0 +1,345 @@
+/*
+ * Copyright (C) 2024, GerritForge Inc. and others
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Distribution License v. 1.0 which is available at
+ * https://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+package org.eclipse.jgit.internal.storage.midx;
+
+import static org.junit.Assert.assertArrayEquals;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertTrue;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import org.eclipse.jgit.internal.storage.file.PackIndex;
+import org.eclipse.jgit.junit.FakeIndexFactory;
+import org.eclipse.jgit.junit.JGitTestUtil;
+import org.eclipse.jgit.lib.AbbreviatedObjectId;
+import org.eclipse.jgit.lib.NullProgressMonitor;
+import org.eclipse.jgit.lib.ObjectId;
+import org.junit.Test;
+
+public class MultiPackIndexTest {
+
+	@Test
+	public void basic_upstream() throws IOException {
+		int knownPackId = 22;
+		int knowOffset = 258;
+		String knownOid = "3f4ee50f784c1e9550f09a67d2ffc1bc76917bdc";
+		String knownPackName = "pack-e4b191e4343f2b7ff851026c2d8595a001077344.idx";
+		String[] packNames = {
+				"pack-15d67b35f2b6a66ff995e09cedb36b101e0e0262.idx",
+				"pack-1a979514a5965e71523187a17806e03af44344ed.idx",
+				"pack-1de6731c035633ba8f5b41dacbc680a5a36ddd90.idx",
+				"pack-1ee98948e4e362c56f3cdec7f5837d06e152854f.idx",
+				"pack-1f6fe52ac3d33f3091d8eb8497474554bfa80bc4.idx",
+				"pack-34b1aa6b437a9d968412454204c2676a88dc55fa.idx",
+				"pack-3b245f7b4aff32a52d0520608f662bbf403792b9.idx",
+				"pack-47901f7f8d1c440492035c4165796a330c7f79e0.idx",
+				"pack-4e7f889b79aea8905a0062ce1bd68e5ef3af6a55.idx",
+				"pack-71ea652e4aea2cbc609545b4fbc3eda6325d88a1.idx",
+				"pack-723b1238411a4257c18167e91fbabed313ba332f.idx",
+				"pack-7bd57092a7daa4dc31277e1ec86f3de8d968ae17.idx",
+				"pack-883d4f469c5ea0f6d373ee623a758aeaf17715fc.idx",
+				"pack-8eadd378a011ddaa5ec751f2a6d9789ef501120f.idx",
+				"pack-92221b6f79a211944ccc6740fc22c9553ea1ba22.idx",
+				"pack-b139d0cae5f54c70d057a8f4d2cf99f0ae0c326c.idx",
+				"pack-b4f5c96d1fa6b1fac17a2a43710693c5514a9224.idx",
+				"pack-bed4bc1521f965e55a5a8a58dffaaefc70ea4753.idx",
+				"pack-cdc6baa7d90707a3c0dac4c188f797f0f79b97bb.idx",
+				"pack-d6d58a58fa24b74c8c082f4f63c4d2ddfb824cc9.idx",
+				"pack-daec59ae07f1091f3b81bd8266481bb5db3c868a.idx",
+				"pack-e2197d60e09ad9091407eff4e06d39ec940851e1.idx",
+				"pack-e4b191e4343f2b7ff851026c2d8595a001077344.idx",
+				"pack-eedf783b5da4caa57be33b08990fe57f245a7413.idx",
+				"pack-efb23e968801b9050bc70f0115a8a0eec88fb879.idx",
+				"pack-f919c0660c207ddf6bb0569a3041d682d19fb4f7.idx" };
+		MultiPackIndex midx = MultiPackIndexLoader
+				.open(JGitTestUtil.getTestResourceFile("multi-pack-index.v1"));
+		assertNotNull(midx);
+		assertArrayEquals(packNames, midx.getPackNames());
+
+		MultiPackIndex.PackOffset oo = midx.find(ObjectId.fromString(knownOid));
+
+		assertEquals(knowOffset, oo.getOffset());
+		assertEquals(knownPackId, oo.getPackId());
+		assertEquals(knownPackName, midx.getPackNames()[oo.getPackId()]);
+	}
+
+	@Test
+	public void basicMidx() throws IOException {
+		PackIndex idxOne = FakeIndexFactory.indexOf(List.of(
+				new FakeIndexFactory.IndexObject(
+						"0000000000000000000000000000000000000001", 500),
+				new FakeIndexFactory.IndexObject(
+						"0000000000000000000000000000000000000005", 12),
+				new FakeIndexFactory.IndexObject(
+						"0000000000000000000000000000000000000010", 1500)));
+		PackIndex idxTwo = FakeIndexFactory.indexOf(List.of(
+				new FakeIndexFactory.IndexObject(
+						"0000000000000000000000000000000000000002", 501),
+				new FakeIndexFactory.IndexObject(
+						"0000000000000000000000000000000000000003", 13),
+				new FakeIndexFactory.IndexObject(
+						"0000000000000000000000000000000000000015", 1501)));
+		PackIndex idxThree = FakeIndexFactory.indexOf(List.of(
+				new FakeIndexFactory.IndexObject(
+						"0000000000000000000000000000000000000004", 502),
+				new FakeIndexFactory.IndexObject(
+						"0000000000000000000000000000000000000007", 14),
+				new FakeIndexFactory.IndexObject(
+						"0000000000000000000000000000000000000012", 1502)));
+
+		Map<String, PackIndex> packs = Map.of("p1", idxOne, "p2", idxTwo, "p3",
+				idxThree);
+		MultiPackIndexWriter writer = new MultiPackIndexWriter();
+		ByteArrayOutputStream out = new ByteArrayOutputStream();
+		writer.write(NullProgressMonitor.INSTANCE, out, packs);
+
+		MultiPackIndex midx = MultiPackIndexLoader
+				.read(new ByteArrayInputStream(out.toByteArray()));
+		assertEquals(3, midx.getPackNames().length);
+		assertInIndex(midx, 0, "0000000000000000000000000000000000000001", 500);
+		assertInIndex(midx, 0, "0000000000000000000000000000000000000005", 12);
+		assertInIndex(midx, 0, "0000000000000000000000000000000000000010",
+				1500);
+		assertInIndex(midx, 1, "0000000000000000000000000000000000000002", 501);
+		assertInIndex(midx, 1, "0000000000000000000000000000000000000003", 13);
+		assertInIndex(midx, 1, "0000000000000000000000000000000000000015",
+				1501);
+		assertInIndex(midx, 2, "0000000000000000000000000000000000000004", 502);
+		assertInIndex(midx, 2, "0000000000000000000000000000000000000007", 14);
+		assertInIndex(midx, 2, "0000000000000000000000000000000000000012",
+				1502);
+
+		assertNull(midx.find(ObjectId.zeroId()));
+	}
+
+	@Test
+	public void jgit_largeOffsetChunk() throws IOException {
+		PackIndex idxOne = FakeIndexFactory.indexOf(List.of(
+				new FakeIndexFactory.IndexObject(
+						"0000000000000000000000000000000000000001", (1L << 34)),
+				new FakeIndexFactory.IndexObject(
+						"0000000000000000000000000000000000000005", 12)));
+		PackIndex idxTwo = FakeIndexFactory.indexOf(List.of(
+				new FakeIndexFactory.IndexObject(
+						"0000000000000000000000000000000000000002", (1L << 35)),
+				new FakeIndexFactory.IndexObject(
+						"0000000000000000000000000000000000000003", 13)));
+		Map<String, PackIndex> packs = Map.of("p1", idxOne, "p2", idxTwo);
+		MultiPackIndexWriter writer = new MultiPackIndexWriter();
+		ByteArrayOutputStream out = new ByteArrayOutputStream();
+		writer.write(NullProgressMonitor.INSTANCE, out, packs);
+
+		MultiPackIndex midx = MultiPackIndexLoader
+				.read(new ByteArrayInputStream(out.toByteArray()));
+		assertEquals(2, midx.getPackNames().length);
+		assertInIndex(midx, 0, "0000000000000000000000000000000000000001",
+				(1L << 34));
+		assertInIndex(midx, 0, "0000000000000000000000000000000000000005", 12);
+		assertInIndex(midx, 1, "0000000000000000000000000000000000000002",
+				(1L << 35));
+	}
+
+	@Test
+	public void jgit_largeOffset_noChunk() throws IOException {
+		// All offsets fit in 32 bits, no large offset chunk
+		// Most significant bit to 1 is still valid offset
+		PackIndex idxOne = FakeIndexFactory.indexOf(List.of(
+				new FakeIndexFactory.IndexObject(
+						"0000000000000000000000000000000000000001",
+						0xff00_0000),
+				new FakeIndexFactory.IndexObject(
+						"0000000000000000000000000000000000000005", 12)));
+		PackIndex idxTwo = FakeIndexFactory.indexOf(List.of(
+				new FakeIndexFactory.IndexObject(
+						"0000000000000000000000000000000000000002", 501),
+				new FakeIndexFactory.IndexObject(
+						"0000000000000000000000000000000000000003", 13)));
+		Map<String, PackIndex> packs = Map.of("p1", idxOne, "p2", idxTwo);
+		MultiPackIndexWriter writer = new MultiPackIndexWriter();
+		ByteArrayOutputStream out = new ByteArrayOutputStream();
+		writer.write(NullProgressMonitor.INSTANCE, out, packs);
+
+		MultiPackIndex midx = MultiPackIndexLoader
+				.read(new ByteArrayInputStream(out.toByteArray()));
+		assertEquals(2, midx.getPackNames().length);
+		assertInIndex(midx, 0, "0000000000000000000000000000000000000001",
+				0xff00_0000L);
+		assertInIndex(midx, 0, "0000000000000000000000000000000000000005", 12);
+	}
+
+	@Test
+	public void jgit_resolve() throws IOException {
+		AbbreviatedObjectId abbrev = AbbreviatedObjectId
+				.fromString("32fe829a1c");
+
+		PackIndex idxOne = indexWith(
+				// Noise
+				"0000000000000000000000000000000000000001",
+				"3000000000000000000000000000000000000005",
+				// One before abbrev
+				"32fe829a1b000000000000000000000000000001",
+				// matches
+				"32fe829a1c000000000000000000000000000001",
+				"32fe829a1c000000000000000000000000000100",
+				// One after abbrev
+				"32fe829a1d000000000000000000000000000000");
+		PackIndex idxTwo = indexWith(
+				// Noise
+				"8888880000000000000000000000000000000002",
+				"bbbbbb0000000000000000000000000000000003",
+				// Match
+				"32fe829a1c000000000000000000000000000010");
+
+		Map<String, PackIndex> packs = Map.of("p1", idxOne, "p2", idxTwo);
+		MultiPackIndexWriter writer = new MultiPackIndexWriter();
+		ByteArrayOutputStream out = new ByteArrayOutputStream();
+		writer.write(NullProgressMonitor.INSTANCE, out, packs);
+		MultiPackIndex midx = MultiPackIndexLoader
+				.read(new ByteArrayInputStream(out.toByteArray()));
+
+
+		Set<ObjectId> results = new HashSet<>();
+		midx.resolve(results, abbrev, 100);
+
+		assertEquals(3, results.size());
+		assertTrue(results.contains(ObjectId
+				.fromString("32fe829a1c000000000000000000000000000001")));
+		assertTrue(results.contains(ObjectId
+				.fromString("32fe829a1c000000000000000000000000000010")));
+		assertTrue(results.contains(ObjectId
+				.fromString("32fe829a1c000000000000000000000000000100")));
+
+	}
+
+	@Test
+	public void jgit_resolve_matchLimit() throws IOException {
+		AbbreviatedObjectId abbrev = AbbreviatedObjectId
+				.fromString("32fe829a1c");
+
+		PackIndex idxOne = indexWith(
+				// Noise
+				"0000000000000000000000000000000000000001",
+				"3000000000000000000000000000000000000005",
+				// One before abbrev
+				"32fe829a1b000000000000000000000000000001",
+				// matches
+				"32fe829a1c000000000000000000000000000001",
+				"32fe829a1c000000000000000000000000000100",
+				// One after abbrev
+				"32fe829a1d000000000000000000000000000000");
+		PackIndex idxTwo = indexWith(
+				// Noise
+				"8888880000000000000000000000000000000002",
+				"bbbbbb0000000000000000000000000000000003",
+				// Match
+				"32fe829a1c000000000000000000000000000010");
+
+		Map<String, PackIndex> packs = Map.of("p1", idxOne, "p2", idxTwo);
+		MultiPackIndexWriter writer = new MultiPackIndexWriter();
+		ByteArrayOutputStream out = new ByteArrayOutputStream();
+		writer.write(NullProgressMonitor.INSTANCE, out, packs);
+		MultiPackIndex midx = MultiPackIndexLoader
+				.read(new ByteArrayInputStream(out.toByteArray()));
+
+
+		Set<ObjectId> results = new HashSet<>();
+		midx.resolve(results, abbrev, 2);
+
+		assertEquals(2, results.size());
+		assertTrue(results.contains(ObjectId
+				.fromString("32fe829a1c000000000000000000000000000001")));
+		assertTrue(results.contains(ObjectId
+				.fromString("32fe829a1c000000000000000000000000000010")));
+	}
+
+	@Test
+	public void jgit_resolve_noMatches() throws IOException {
+		AbbreviatedObjectId abbrev = AbbreviatedObjectId
+				.fromString("4400000000");
+
+		PackIndex idxOne = indexWith(
+				"0000000000000000000000000000000000000001",
+				"3000000000000000000000000000000000000005",
+				"32fe829a1b000000000000000000000000000001",
+				"32fe829a1c000000000000000000000000000001",
+				"32fe829a1c000000000000000000000000000100",
+				"32fe829a1d000000000000000000000000000000");
+		PackIndex idxTwo = indexWith(
+				// Noise
+				"8888880000000000000000000000000000000002",
+				"bbbbbb0000000000000000000000000000000003",
+				"32fe829a1c000000000000000000000000000010");
+
+		Map<String, PackIndex> packs = Map.of("p1", idxOne, "p2", idxTwo);
+		MultiPackIndexWriter writer = new MultiPackIndexWriter();
+		ByteArrayOutputStream out = new ByteArrayOutputStream();
+		writer.write(NullProgressMonitor.INSTANCE, out, packs);
+		MultiPackIndex midx = MultiPackIndexLoader
+				.read(new ByteArrayInputStream(out.toByteArray()));
+
+
+		Set<ObjectId> results = new HashSet<>();
+		midx.resolve(results, abbrev, 200);
+
+		assertEquals(0, results.size());
+	}
+
+	@Test
+	public void jgit_resolve_empty() throws IOException {
+		AbbreviatedObjectId abbrev = AbbreviatedObjectId
+				.fromString("4400000000");
+
+		PackIndex idxOne = FakeIndexFactory.indexOf(List.of());
+		PackIndex idxTwo = FakeIndexFactory.indexOf(List.of());
+
+		Map<String, PackIndex> packs = Map.of("p1", idxOne, "p2", idxTwo);
+		MultiPackIndexWriter writer = new MultiPackIndexWriter();
+		ByteArrayOutputStream out = new ByteArrayOutputStream();
+		writer.write(NullProgressMonitor.INSTANCE, out, packs);
+		MultiPackIndex midx = MultiPackIndexLoader
+				.read(new ByteArrayInputStream(out.toByteArray()));
+
+
+		Set<ObjectId> results = new HashSet<>();
+		midx.resolve(results, abbrev, 200);
+
+		assertEquals(0, results.size());
+	}
+
+	private static PackIndex indexWith(String... oids) {
+		List<FakeIndexFactory.IndexObject> idxObjs = new ArrayList<>(
+				oids.length);
+		int offset = 12;
+		for (String oid : oids) {
+			idxObjs.add(new FakeIndexFactory.IndexObject(oid, offset));
+			offset += 10;
+		}
+		return FakeIndexFactory.indexOf(idxObjs);
+	}
+
+	private static void assertInIndex(MultiPackIndex midx, int expectedPackId,
+			String oid, long expectedOffset) {
+		MultiPackIndex.PackOffset packOffset = midx
+				.find(ObjectId.fromString(oid));
+		assertNotNull(packOffset);
+		assertEquals("Wrong packId for " + oid, expectedPackId,
+				packOffset.getPackId());
+		assertEquals(expectedOffset, packOffset.getOffset());
+	}
+}
diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/midx/MultiPackIndexWriterTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/midx/MultiPackIndexWriterTest.java
index 82f3eb1..8b57a2d 100644
--- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/midx/MultiPackIndexWriterTest.java
+++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/midx/MultiPackIndexWriterTest.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2025, Google Inc.
+ * Copyright (C) 2025, Google LLC
  *
  * This program and the accompanying materials are made available under the
  * terms of the Eclipse Distribution License v. 1.0 which is available at
@@ -139,6 +139,24 @@ public void write_largeOffset() throws IOException {
 		assertEquals(5, chunkIds.indexOf(MIDX_CHUNKID_PACKNAMES));
 	}
 
+	@Test
+	public void jgit_emptyMidx() throws IOException {
+		PackIndex idxOne = FakeIndexFactory.indexOf(List.of());
+		PackIndex idxTwo = FakeIndexFactory.indexOf(List.of());
+		Map<String, PackIndex> packs = Map.of("p1", idxOne, "p2", idxTwo);
+		MultiPackIndexWriter writer = new MultiPackIndexWriter();
+		ByteArrayOutputStream out = new ByteArrayOutputStream();
+		writer.write(NullProgressMonitor.INSTANCE, out, packs);
+		List<Integer> chunkIds = readChunkIds(out);
+		assertEquals(1134, out.size());
+		assertEquals(5, chunkIds.size());
+		assertEquals(0, chunkIds.indexOf(MIDX_CHUNKID_OIDFANOUT));
+		assertEquals(1, chunkIds.indexOf(MIDX_CHUNKID_OIDLOOKUP));
+		assertEquals(2, chunkIds.indexOf(MIDX_CHUNKID_OBJECTOFFSETS));
+		assertEquals(3, chunkIds.indexOf(MIDX_CHUNKID_REVINDEX));
+		assertEquals(4, chunkIds.indexOf(MIDX_CHUNKID_PACKNAMES));
+	}
+
 	private List<Integer> readChunkIds(ByteArrayOutputStream out) {
 		List<Integer> chunkIds = new ArrayList<>();
 		byte[] raw = out.toByteArray();
diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/midx/PackIndexMergerTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/midx/PackIndexMergerTest.java
index 1d8bde0..8218cbc 100644
--- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/midx/PackIndexMergerTest.java
+++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/midx/PackIndexMergerTest.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2025, Google Inc.
+ * Copyright (C) 2025, Google LLC
  *
  * This program and the accompanying materials are made available under the
  * terms of the Eclipse Distribution License v. 1.0 which is available at
diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/midx/PackIndexPeekIteratorTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/midx/PackIndexPeekIteratorTest.java
index 917288a..0b3ccac 100644
--- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/midx/PackIndexPeekIteratorTest.java
+++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/midx/PackIndexPeekIteratorTest.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2025, Google Inc.
+ * Copyright (C) 2025, Google LLC
  *
  * This program and the accompanying materials are made available under the
  * terms of the Eclipse Distribution License v. 1.0 which is available at
diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/reftable/ReftableCompactorTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/reftable/ReftableCompactorTest.java
index 6fc7f25..62dbda4 100644
--- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/reftable/ReftableCompactorTest.java
+++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/reftable/ReftableCompactorTest.java
@@ -19,6 +19,8 @@
 
 import java.io.ByteArrayOutputStream;
 import java.io.IOException;
+import java.time.Instant;
+import java.time.ZoneId;
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.List;
@@ -27,6 +29,7 @@
 import org.eclipse.jgit.internal.storage.reftable.ReftableWriter.Stats;
 import org.eclipse.jgit.lib.ObjectId;
 import org.eclipse.jgit.lib.ObjectIdRef;
+import org.eclipse.jgit.lib.PersonIdent;
 import org.eclipse.jgit.lib.Ref;
 import org.junit.Test;
 
@@ -279,6 +282,95 @@ public void twoTablesNotIncludeOneDelete() throws IOException {
 		}
 	}
 
+	@Test
+	public void reflog_all() throws IOException {
+		byte[] inTab;
+		try (ByteArrayOutputStream inBuf = new ByteArrayOutputStream()) {
+			ReftableWriter writer = new ReftableWriter(inBuf)
+					.setMinUpdateIndex(0).setMaxUpdateIndex(2).begin();
+			writer.writeLog(MASTER, 2, person(Instant.ofEpochSecond(500)),
+					id(3), id(4), null);
+			writer.writeLog(MASTER, 1, person(Instant.ofEpochSecond(300)),
+					id(2), id(3), null);
+			writer.writeLog(MASTER, 0, person(Instant.ofEpochSecond(100)),
+					id(1), id(2), null);
+			writer.finish();
+			inTab = inBuf.toByteArray();
+		}
+
+		ReftableCompactor compactor;
+		try (ByteArrayOutputStream outBuf = new ByteArrayOutputStream()) {
+			compactor = new ReftableCompactor(outBuf);
+			// No setReflogExpire time is set
+			List<ReftableReader> readers = new ArrayList<>();
+			readers.add(read(inTab));
+			compactor.addAll(readers);
+			compactor.compact();
+		}
+		Stats stats = compactor.getStats();
+		assertEquals(3, stats.logCount());
+	}
+
+	@Test
+	public void reflog_setExpireOlderThan() throws IOException {
+		byte[] inTab;
+		try (ByteArrayOutputStream inBuf = new ByteArrayOutputStream()) {
+			ReftableWriter writer = new ReftableWriter(inBuf)
+					.setMinUpdateIndex(0).setMaxUpdateIndex(2).begin();
+			writer.writeLog(MASTER, 2, person(Instant.ofEpochSecond(500)),
+					id(3), id(4), null);
+			writer.writeLog(MASTER, 1, person(Instant.ofEpochSecond(300)),
+					id(2), id(3), null);
+			writer.writeLog(MASTER, 0, person(Instant.ofEpochSecond(100)),
+					id(1), id(2), null);
+			writer.finish();
+			inTab = inBuf.toByteArray();
+		}
+
+		ReftableCompactor compactor;
+		try (ByteArrayOutputStream outBuf = new ByteArrayOutputStream()) {
+			compactor = new ReftableCompactor(outBuf);
+			compactor.setReflogExpireOlderThan(Instant.ofEpochSecond(300));
+			List<ReftableReader> readers = new ArrayList<>();
+			readers.add(read(inTab));
+			compactor.addAll(readers);
+			compactor.compact();
+		}
+
+		Stats stats = compactor.getStats();
+		assertEquals(2, stats.logCount());
+	}
+
+	@Test
+	public void reflog_disable() throws IOException {
+		byte[] inTab;
+		try (ByteArrayOutputStream inBuf = new ByteArrayOutputStream()) {
+			ReftableWriter writer = new ReftableWriter(inBuf)
+					.setMinUpdateIndex(0).setMaxUpdateIndex(2).begin();
+			writer.writeLog(MASTER, 2, person(Instant.ofEpochSecond(500)),
+					id(3), id(4), null);
+			writer.writeLog(MASTER, 1, person(Instant.ofEpochSecond(300)),
+					id(2), id(3), null);
+			writer.writeLog(MASTER, 0, person(Instant.ofEpochSecond(100)),
+					id(1), id(2), null);
+			writer.finish();
+			inTab = inBuf.toByteArray();
+		}
+
+		ReftableCompactor compactor;
+		try (ByteArrayOutputStream outBuf = new ByteArrayOutputStream()) {
+			compactor = new ReftableCompactor(outBuf);
+			compactor.setReflogExpireOlderThan(Instant.MAX);
+			List<ReftableReader> readers = new ArrayList<>();
+			readers.add(read(inTab));
+			compactor.addAll(readers);
+			compactor.compact();
+		}
+
+		Stats stats = compactor.getStats();
+		assertEquals(0, stats.logCount());
+	}
+
 	private static Ref ref(String name, int id) {
 		return new ObjectIdRef.PeeledNonTag(PACKED, name, id(id));
 	}
@@ -296,6 +388,10 @@ private static ObjectId id(int i) {
 		return ObjectId.fromRaw(buf);
 	}
 
+	private static PersonIdent person(Instant when) {
+		return new PersonIdent("a. u. thor", "author@jgit.com", when, ZoneId.systemDefault());
+	}
+
 	private static ReftableReader read(byte[] table) {
 		return new ReftableReader(BlockSource.from(table));
 	}
diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/revwalk/RevWalkCommitGraphTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/revwalk/RevWalkCommitGraphTest.java
index c2f8f10..e47dd89 100644
--- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/revwalk/RevWalkCommitGraphTest.java
+++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/revwalk/RevWalkCommitGraphTest.java
@@ -37,8 +37,9 @@
 import org.eclipse.jgit.revwalk.filter.RevFilter;
 import org.eclipse.jgit.storage.file.FileBasedConfig;
 import org.eclipse.jgit.treewalk.filter.AndTreeFilter;
+import org.eclipse.jgit.treewalk.filter.ChangedPathTreeFilter;
+import org.eclipse.jgit.treewalk.filter.OrTreeFilter;
 import org.eclipse.jgit.treewalk.filter.PathFilter;
-import org.eclipse.jgit.treewalk.filter.PathFilterGroup;
 import org.eclipse.jgit.treewalk.filter.TreeFilter;
 import org.junit.Test;
 
@@ -172,61 +173,99 @@ public void testTreeFilter() throws Exception {
 	}
 
 	@Test
-	public void testChangedPathFilter() throws Exception {
-		RevCommit c1 = commitFile("file1", "1", "master");
-		commitFile("file2", "2", "master");
-		RevCommit c3 = commitFile("file1", "3", "master");
-		RevCommit c4 = commitFile("file2", "4", "master");
+	public void testChangedPathFilter_allModify() throws Exception {
+		RevCommit c1 = commit(tree(file("file1", blob("1"))));
+		RevCommit c2 = commit(tree(file("file2", blob("2"))), c1);
+		RevCommit c3 = commit(tree(file("file1", blob("3"))), c2);
+		RevCommit c4 = commit(tree(file("file2", blob("4"))), c3);
 
-		enableAndWriteCommitGraph();
-
-		TreeRevFilter trf = new TreeRevFilter(rw, PathFilter.create("file1"));
-		rw.markStart(rw.lookupCommit(c4));
-		rw.setRevFilter(trf);
-		assertEquals(c3, rw.next());
-		assertEquals(c1, rw.next());
-		assertNull(rw.next());
-
-		// 1 commit that has exactly one parent and matches path
-		assertEquals(1, trf.getChangedPathFilterTruePositive());
-
-		// No false positives
-		assertEquals(0, trf.getChangedPathFilterFalsePositive());
-
-		// 2 commits that have exactly one parent and don't match path
-		assertEquals(2, trf.getChangedPathFilterNegative());
-	}
-
-	@Test
-	public void testChangedPathFilterWithMultiPaths() throws Exception {
-		RevCommit c1 = commitFile("file1", "1", "master");
-		RevCommit c2 = commitFile("file1", "2", "master");
-		RevCommit c3 = commitFile("file2", "3", "master");
-		RevCommit c4 = commitFile("file3", "4", "master");
+		branch(c4, "master");
 
 		enableAndWriteCommitGraph();
 
 		TreeRevFilter trf = new TreeRevFilter(rw,
-				PathFilterGroup.createFromStrings(List.of("file1", "file2")));
+				ChangedPathTreeFilter.create("file1"));
 		rw.markStart(rw.lookupCommit(c4));
 		rw.setRevFilter(trf);
+		assertEquals(c4, rw.next());
 		assertEquals(c3, rw.next());
 		assertEquals(c2, rw.next());
 		assertEquals(c1, rw.next());
 		assertNull(rw.next());
 
-		// c2 and c3 has either file1 or file2, c1 did not use ChangedPathFilter
-		// since it has no parent
+		// all commits modified file1 but c1 did not have a parent
+		assertEquals(3, trf.getChangedPathFilterTruePositive());
+
+		// No false positives
+		assertEquals(0, trf.getChangedPathFilterFalsePositive());
+
+		// No negatives because all 4 commits had modified file1
+		assertEquals(0, trf.getChangedPathFilterNegative());
+	}
+
+	@Test
+	public void testChangedPathFilter_someModify() throws Exception {
+		RevCommit c1 = commit(tree(file("file1", blob("1"))));
+		RevCommit c2 = commit(tree(file("file1", blob("1"))), c1);
+		RevCommit c3 = commit(tree(file("file1", blob("2"))), c2);
+		RevCommit c4 = commit(tree(file("file1", blob("1"))), c3);
+
+		branch(c4, "master");
+
+		enableAndWriteCommitGraph();
+
+		TreeRevFilter trf = new TreeRevFilter(rw,
+				ChangedPathTreeFilter.create("file1"));
+		rw.markStart(rw.lookupCommit(c4));
+		rw.setRevFilter(trf);
+		assertEquals(c4, rw.next());
+		assertEquals(c3, rw.next());
+		assertEquals(c1, rw.next());
+		assertNull(rw.next());
+
+		// c4 and c3 modified file1. c1 did not have a parent
 		assertEquals(2, trf.getChangedPathFilterTruePositive());
 
 		// No false positives
 		assertEquals(0, trf.getChangedPathFilterFalsePositive());
 
-		// c4 does not match either file1 or file2
+		// c2 did not modify file1
 		assertEquals(1, trf.getChangedPathFilterNegative());
 	}
 
 	@Test
+	public void testChangedPathFilterWithMultiPaths() throws Exception {
+		RevCommit c1 = commit(tree(file("file1", blob("1"))));
+		RevCommit c2 = commit(tree(file("file1", blob("2"))), c1);
+		RevCommit c3 = commit(tree(file("file2", blob("3"))), c2);
+		RevCommit c4 = commit(tree(file("file3", blob("4"))), c3);
+
+		branch(c4, "master");
+
+		enableAndWriteCommitGraph();
+
+		TreeRevFilter trf = new TreeRevFilter(rw,
+				ChangedPathTreeFilter.create("file1", "file2"));
+		rw.markStart(rw.lookupCommit(c4));
+		rw.setRevFilter(trf);
+		assertEquals(c4, rw.next());
+		assertEquals(c3, rw.next());
+		assertEquals(c2, rw.next());
+		assertEquals(c1, rw.next());
+		assertNull(rw.next());
+
+		// all commits have modified either file1 or file2, c1 did not have a
+		// parent
+		assertEquals(3, trf.getChangedPathFilterTruePositive());
+
+		// No false positives
+		assertEquals(0, trf.getChangedPathFilterFalsePositive());
+
+		// No negative
+		assertEquals(0, trf.getChangedPathFilterNegative());
+	}
+
+	@Test
 	public void testChangedPathFilterWithFollowFilter() throws Exception {
 		RevCommit c0 = commit(tree());
 		RevCommit c1 = commit(tree(file("file", blob("contents"))), c0);
@@ -245,9 +284,8 @@ public void testChangedPathFilterWithFollowFilter() throws Exception {
 		db.getConfig().setString(ConfigConstants.CONFIG_DIFF_SECTION, null,
 				ConfigConstants.CONFIG_KEY_RENAMES, "true");
 
-		TreeRevFilter trf = new TreeRevFilter(rw,
-				new FollowFilter(PathFilter.create("renamed-file"),
-						db.getConfig().get(DiffConfig.KEY)));
+		TreeRevFilter trf = new TreeRevFilter(rw, FollowFilter
+				.create("renamed-file", db.getConfig().get(DiffConfig.KEY)));
 		rw.markStart(rw.lookupCommit(c4));
 		rw.setRevFilter(trf);
 		assertEquals(c3, rw.next());
@@ -267,6 +305,296 @@ public void testChangedPathFilterWithFollowFilter() throws Exception {
 	}
 
 	@Test
+	public void testChangedPathFilter_pathFilter_or_pathFilter_binaryOperation()
+			throws Exception {
+		RevCommit c1 = commit(tree(file("file1", blob("1"))));
+		RevCommit c2 = commit(
+				tree(file("file1", blob("1")), file("file2", blob("2"))), c1);
+		RevCommit c3 = commit(tree(file("file2", blob("2"))), c2);
+		RevCommit c4 = commit(
+				tree(file("file2", blob("2")), file("file3", blob("3"))), c3);
+		RevCommit c5 = commit(
+				tree(file("file2", blob("2")), file("file3", blob("3"))), c4);
+
+		branch(c5, "master");
+
+		enableAndWriteCommitGraph();
+
+		ChangedPathTreeFilter pf1 = ChangedPathTreeFilter.create("file1");
+		ChangedPathTreeFilter pf2 = ChangedPathTreeFilter.create("file2");
+
+		TreeFilter tf = OrTreeFilter
+				.create(new ChangedPathTreeFilter[] { pf1, pf2 });
+
+		TreeRevFilter trf = new TreeRevFilter(rw, tf);
+		rw.markStart(rw.lookupCommit(c5));
+		rw.setRevFilter(trf);
+		assertEquals(c3, rw.next());
+		assertEquals(c2, rw.next());
+		assertEquals(c1, rw.next());
+		assertNull(rw.next());
+
+		// c2 and c3 has either file1 or file2, c1 is not counted as
+		// ChangedPathFilter only applies to commits with 1 parent
+		assertEquals(2, trf.getChangedPathFilterTruePositive());
+
+		// No false positives
+		assertEquals(0, trf.getChangedPathFilterFalsePositive());
+
+		// c4 and c5 did not modify file1 or file2
+		assertEquals(2, trf.getChangedPathFilterNegative());
+	}
+
+	@Test
+	public void testChangedPathFilter_pathFilter_or_pathFilter_or_pathFilter_listOperation()
+			throws Exception {
+		RevCommit c1 = commit(tree(file("file1", blob("1"))));
+		RevCommit c2 = commit(
+				tree(file("file1", blob("1")), file("file2", blob("2"))), c1);
+		RevCommit c3 = commit(tree(file("file2", blob("2"))), c2);
+		RevCommit c4 = commit(tree(file("file3", blob("3"))), c3);
+		RevCommit c5 = commit(tree(file("file3", blob("3"))), c4);
+
+		branch(c5, "master");
+
+		enableAndWriteCommitGraph();
+
+		ChangedPathTreeFilter pf1 = ChangedPathTreeFilter.create("file1");
+		ChangedPathTreeFilter pf2 = ChangedPathTreeFilter.create("file2");
+		ChangedPathTreeFilter pf3 = ChangedPathTreeFilter.create("file3");
+
+		TreeFilter tf = OrTreeFilter
+				.create(new ChangedPathTreeFilter[] { pf1, pf2, pf3 });
+
+		TreeRevFilter trf = new TreeRevFilter(rw, tf);
+		rw.markStart(rw.lookupCommit(c5));
+		rw.setRevFilter(trf);
+		assertEquals(c4, rw.next());
+		assertEquals(c3, rw.next());
+		assertEquals(c2, rw.next());
+		assertEquals(c1, rw.next());
+		assertNull(rw.next());
+
+		// c2 and c3 has either modified file1 or file2 or file3, c1 is not
+		// counted as ChangedPathFilter only applies to commits with 1 parent
+		assertEquals(3, trf.getChangedPathFilterTruePositive());
+
+		// No false positives
+		assertEquals(0, trf.getChangedPathFilterFalsePositive());
+
+		// c5 does not modify either file1 or file2 or file3
+		assertEquals(1, trf.getChangedPathFilterNegative());
+	}
+
+	@Test
+	public void testChangedPathFilter_pathFilter_or_nonPathFilter_binaryOperation()
+			throws Exception {
+		RevCommit c1 = commit(tree(file("file1", blob("1"))));
+		RevCommit c2 = commit(tree(file("file2", blob("2"))), c1);
+		RevCommit c3 = commit(tree(file("file2", blob("3"))), c2);
+		RevCommit c4 = commit(tree(file("file2", blob("3"))), c3);
+
+		branch(c4, "master");
+
+		enableAndWriteCommitGraph();
+
+		ChangedPathTreeFilter pf = ChangedPathTreeFilter.create("file1");
+		TreeFilter npf = TreeFilter.ANY_DIFF;
+
+		TreeFilter tf = OrTreeFilter.create(new TreeFilter[] { pf, npf });
+
+		TreeRevFilter trf = new TreeRevFilter(rw, tf);
+		rw.markStart(rw.lookupCommit(c4));
+		rw.setRevFilter(trf);
+		assertEquals(c3, rw.next());
+		assertEquals(c2, rw.next());
+		assertEquals(c1, rw.next());
+		assertNull(rw.next());
+
+		// c2 modified file1, c3 defaulted positive due to ANY_DIFF, c1 is not
+		// counted as ChangedPathFilter only applies to commits with 1 parent
+		assertEquals(2, trf.getChangedPathFilterTruePositive());
+
+		// c4 defaulted positive due to ANY_DIFF, but didn't no diff with its
+		// parent c3
+		assertEquals(1, trf.getChangedPathFilterFalsePositive());
+
+		// No negative due to the OrTreeFilter
+		assertEquals(0, trf.getChangedPathFilterNegative());
+	}
+
+	@Test
+	public void testChangedPathFilter_nonPathFilter_or_nonPathFilter_binaryOperation()
+			throws Exception {
+		RevCommit c1 = commitFile("file1", "1", "master");
+		RevCommit c2 = commitFile("file2", "2", "master");
+		RevCommit c3 = commitFile("file3", "3", "master");
+		RevCommit c4 = commitFile("file4", "4", "master");
+
+		enableAndWriteCommitGraph();
+
+		TreeFilter npf1 = TreeFilter.ANY_DIFF;
+		TreeFilter npf2 = TreeFilter.ANY_DIFF;
+
+		TreeFilter tf = OrTreeFilter.create(new TreeFilter[] { npf1, npf2 });
+
+		TreeRevFilter trf = new TreeRevFilter(rw, tf);
+		rw.markStart(rw.lookupCommit(c4));
+		rw.setRevFilter(trf);
+		assertEquals(c4, rw.next());
+		assertEquals(c3, rw.next());
+		assertEquals(c2, rw.next());
+		assertEquals(c1, rw.next());
+		assertNull(rw.next());
+
+		// No true positives since there's no pathFilter
+		assertEquals(0, trf.getChangedPathFilterTruePositive());
+
+		// No false positives since there's no pathFilter
+		assertEquals(0, trf.getChangedPathFilterFalsePositive());
+
+		// No negative since there's no pathFilter
+		assertEquals(0, trf.getChangedPathFilterNegative());
+	}
+
+	@Test
+	public void testChangedPathFilter_pathFilter_and_pathFilter_binaryOperation()
+			throws Exception {
+		RevCommit c1 = commit(tree(file("file1", blob("1"))));
+		RevCommit c2 = commit(tree(file("file2", blob("2"))), c1);
+
+		branch(c2, "master");
+
+		enableAndWriteCommitGraph();
+
+		ChangedPathTreeFilter pf1 = ChangedPathTreeFilter.create("file1");
+		ChangedPathTreeFilter pf2 = ChangedPathTreeFilter.create("file2");
+
+		TreeFilter atf = AndTreeFilter
+				.create(new ChangedPathTreeFilter[] { pf1, pf2 });
+		TreeRevFilter trf = new TreeRevFilter(rw, atf);
+
+		rw.markStart(rw.lookupCommit(c2));
+		rw.setRevFilter(trf);
+
+		assertNull(rw.next());
+
+		// c1 is not counted as ChangedPathFilter only applies to commits with 1
+		// parent
+		assertEquals(0, trf.getChangedPathFilterTruePositive());
+
+		// c2 has modified both file 1 and file2,
+		// however nothing is returned from TreeWalk since a TreeHead
+		// cannot be two paths at once
+		assertEquals(1, trf.getChangedPathFilterFalsePositive());
+
+		// No negatives
+		assertEquals(0, trf.getChangedPathFilterNegative());
+	}
+
+	@Test
+	public void testChangedPathFilter_pathFilter_and_pathFilter_and_pathFilter_listOperation()
+			throws Exception {
+		RevCommit c1 = commit(tree(file("file1", blob("1"))));
+		RevCommit c2 = commit(tree(file("file2", blob("2"))), c1);
+		RevCommit c3 = commit(tree(file("file3", blob("3"))), c2);
+
+		branch(c3, "master");
+
+		enableAndWriteCommitGraph();
+
+		ChangedPathTreeFilter pf1 = ChangedPathTreeFilter.create("file1");
+		ChangedPathTreeFilter pf2 = ChangedPathTreeFilter.create("file2");
+		ChangedPathTreeFilter pf3 = ChangedPathTreeFilter.create("file3");
+
+		TreeFilter tf = AndTreeFilter
+				.create(new ChangedPathTreeFilter[] { pf1, pf2, pf3 });
+
+		TreeRevFilter trf = new TreeRevFilter(rw, tf);
+		rw.markStart(rw.lookupCommit(c3));
+		rw.setRevFilter(trf);
+		assertNull(rw.next());
+
+		// c1 is not counted as ChangedPathFilter only applies to commits with 1
+		// parent
+		assertEquals(0, trf.getChangedPathFilterTruePositive());
+
+		// No false positives
+		assertEquals(0, trf.getChangedPathFilterFalsePositive());
+
+		// c2 and c3 can not possibly have both file1, file2, and file3 as
+		// treeHead at once
+		assertEquals(2, trf.getChangedPathFilterNegative());
+	}
+
+	@Test
+	public void testChangedPathFilter_pathFilter_and_nonPathFilter_binaryOperation()
+			throws Exception {
+		RevCommit c1 = commit(tree(file("file1", blob("1"))));
+		RevCommit c2 = commit(tree(file("file1", blob("2"))), c1);
+		RevCommit c3 = commit(tree(file("file1", blob("2"))), c2);
+
+		branch(c3, "master");
+
+		enableAndWriteCommitGraph();
+
+		ChangedPathTreeFilter pf = ChangedPathTreeFilter.create("file1");
+		TreeFilter npf = TreeFilter.ANY_DIFF;
+
+		TreeFilter tf = AndTreeFilter.create(new TreeFilter[] { pf, npf });
+
+		TreeRevFilter trf = new TreeRevFilter(rw, tf);
+		rw.markStart(rw.lookupCommit(c3));
+		rw.setRevFilter(trf);
+		assertEquals(c2, rw.next());
+		assertEquals(c1, rw.next());
+		assertNull(rw.next());
+
+		// c2 modified file1 and c1 is not counted as ChangedPathFilter only
+		// applies to commits with 1 parent
+		assertEquals(1, trf.getChangedPathFilterTruePositive());
+
+		// No false positives
+		assertEquals(0, trf.getChangedPathFilterFalsePositive());
+
+		// c3 did not modify file1
+		assertEquals(1, trf.getChangedPathFilterNegative());
+	}
+
+	@Test
+	public void testChangedPathFilter_nonPathFilter_and_nonPathFilter_binaryOperation()
+			throws Exception {
+		RevCommit c1 = commitFile("file1", "1", "master");
+		commitFile("file1", "1", "master");
+		RevCommit c3 = commitFile("file3", "3", "master");
+		RevCommit c4 = commitFile("file4", "4", "master");
+
+		enableAndWriteCommitGraph();
+
+		TreeFilter npf1 = TreeFilter.ANY_DIFF;
+		TreeFilter npf2 = TreeFilter.ANY_DIFF;
+
+		TreeFilter tf = AndTreeFilter.create(new TreeFilter[] { npf1, npf2 });
+
+		TreeRevFilter trf = new TreeRevFilter(rw, tf);
+		rw.markStart(rw.lookupCommit(c4));
+		rw.setRevFilter(trf);
+		assertEquals(c4, rw.next());
+		assertEquals(c3, rw.next());
+		assertEquals(c1, rw.next());
+		assertNull(rw.next());
+
+		// No true positives since there's no path
+		assertEquals(0, trf.getChangedPathFilterTruePositive());
+
+		// No false positives since there's no path
+		assertEquals(0, trf.getChangedPathFilterFalsePositive());
+
+		// No negative since there's no path
+		assertEquals(0, trf.getChangedPathFilterNegative());
+	}
+
+	@Test
 	public void testWalkWithCommitMessageFilter() throws Exception {
 		RevCommit a = commit();
 		RevCommit b = commitBuilder().parent(a)
diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/treewalk/filter/ChangedPathTreeFilterTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/treewalk/filter/ChangedPathTreeFilterTest.java
new file mode 100644
index 0000000..88f6b75
--- /dev/null
+++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/treewalk/filter/ChangedPathTreeFilterTest.java
@@ -0,0 +1,122 @@
+/*
+ * Copyright (C) 2025, Google LLC
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Distribution License v. 1.0 which is available at
+ * https://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+package org.eclipse.jgit.treewalk.filter;
+
+import static java.nio.charset.StandardCharsets.UTF_8;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+
+import java.nio.ByteBuffer;
+import java.util.Arrays;
+import java.util.stream.Collectors;
+
+import org.eclipse.jgit.internal.storage.commitgraph.ChangedPathFilter;
+import org.eclipse.jgit.lib.ObjectId;
+import org.eclipse.jgit.revwalk.RevCommit;
+import org.eclipse.jgit.revwalk.RevWalk;
+import org.eclipse.jgit.treewalk.filter.TreeFilter.MutableBoolean;
+import org.junit.Test;
+
+public class ChangedPathTreeFilterTest {
+
+    @Test
+    public void shouldTreeWalk_no_usingCpf() {
+        ChangedPathTreeFilter f = ChangedPathTreeFilter.create("a/b");
+        MutableBoolean cfpUsed = new MutableBoolean();
+
+        boolean result = f.shouldTreeWalk(FakeRevCommit.withCpfFor("c"), null,
+                cfpUsed);
+
+        assertFalse(result);
+        assertTrue(cfpUsed.get());
+    }
+
+    @Test
+    public void shouldTreeWalk_yes_usingCpf() {
+        ChangedPathTreeFilter f = ChangedPathTreeFilter.create("a/b");
+        MutableBoolean cfpUsed = new MutableBoolean();
+
+        boolean result = f.shouldTreeWalk(FakeRevCommit.withCpfFor("a/b"), null,
+                cfpUsed);
+
+        assertTrue(result);
+        assertTrue(cfpUsed.get());
+    }
+
+    @Test
+    public void shouldTreeWalk_yes_noCpf() {
+        ChangedPathTreeFilter f = ChangedPathTreeFilter.create("a/b");
+        MutableBoolean cfpUsed = new MutableBoolean();
+
+        boolean result = f.shouldTreeWalk(FakeRevCommit.noCpf(), null,
+                cfpUsed);
+
+        assertTrue(result);
+        assertFalse(cfpUsed.get());
+    }
+
+    @Test
+    public void shouldTreeWalk_no_usingCpf_noReport() {
+        ChangedPathTreeFilter f = ChangedPathTreeFilter.create("a/b");
+        boolean result = f.shouldTreeWalk(FakeRevCommit.withCpfFor("c"), null,
+                null);
+
+        assertFalse(result);
+    }
+
+    @Test
+    public void shouldTreeWalk_yes_usingCpf_noReport() {
+        ChangedPathTreeFilter f = ChangedPathTreeFilter.create("a/b");
+        boolean result = f.shouldTreeWalk(FakeRevCommit.withCpfFor("a/b"), null,
+                null);
+        assertTrue(result);
+    }
+
+    @Test
+    public void shouldTreeWalk_yes_noCpf_noReport() {
+        ChangedPathTreeFilter f = ChangedPathTreeFilter.create("a/b");
+        boolean result = f.shouldTreeWalk(FakeRevCommit.noCpf(), null,
+                null);
+
+        assertTrue(result);
+    }
+
+    private static class FakeRevCommit extends RevCommit {
+
+        static RevCommit withCpfFor(String... paths) {
+            return new FakeRevCommit(
+                    ChangedPathFilter.fromPaths(Arrays.stream(paths)
+                            .map(str -> ByteBuffer.wrap(str.getBytes(UTF_8)))
+                            .collect(Collectors.toSet())));
+        }
+
+        static RevCommit noCpf() {
+            return new FakeRevCommit(null);
+        }
+
+        private final ChangedPathFilter cpf;
+
+        /**
+         * Create a new commit reference.
+         *
+         * @param cpf
+         *            changedPathFilter
+         */
+        protected FakeRevCommit(ChangedPathFilter cpf) {
+            super(ObjectId.zeroId());
+            this.cpf = cpf;
+        }
+
+        @Override
+        public ChangedPathFilter getChangedPathFilter(RevWalk rw) {
+            return cpf;
+        }
+    }
+}
\ No newline at end of file
diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/util/RefMapTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/util/RefMapTest.java
index a8077fd..0c9cb2d 100644
--- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/util/RefMapTest.java
+++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/util/RefMapTest.java
@@ -423,7 +423,7 @@ public void testEntryType() {
 		Map.Entry<String, Ref> ent_b = itr.next();
 
 		assertEquals(ent_a.hashCode(), "A".hashCode());
-		assertEquals(ent_a, ent_a);
+		assertTrue(ent_a.equals(ent_a));
 		assertFalse(ent_a.equals(ent_b));
 
 		assertEquals(a.toString(), ent_a.toString());
diff --git a/org.eclipse.jgit.ui/META-INF/MANIFEST.MF b/org.eclipse.jgit.ui/META-INF/MANIFEST.MF
index eb80688..e487510 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: 7.2.2.qualifier
+Bundle-Version: 7.3.1.qualifier
 Bundle-Vendor: %Bundle-Vendor
 Bundle-RequiredExecutionEnvironment: JavaSE-17
-Export-Package: org.eclipse.jgit.awtui;version="7.2.2"
-Import-Package: org.eclipse.jgit.errors;version="[7.2.2,7.3.0)",
- org.eclipse.jgit.lib;version="[7.2.2,7.3.0)",
- org.eclipse.jgit.nls;version="[7.2.2,7.3.0)",
- org.eclipse.jgit.revplot;version="[7.2.2,7.3.0)",
- org.eclipse.jgit.revwalk;version="[7.2.2,7.3.0)",
- org.eclipse.jgit.transport;version="[7.2.2,7.3.0)",
- org.eclipse.jgit.util;version="[7.2.2,7.3.0)"
+Export-Package: org.eclipse.jgit.awtui;version="7.3.1"
+Import-Package: org.eclipse.jgit.errors;version="[7.3.1,7.4.0)",
+ org.eclipse.jgit.lib;version="[7.3.1,7.4.0)",
+ org.eclipse.jgit.nls;version="[7.3.1,7.4.0)",
+ org.eclipse.jgit.revplot;version="[7.3.1,7.4.0)",
+ org.eclipse.jgit.revwalk;version="[7.3.1,7.4.0)",
+ org.eclipse.jgit.transport;version="[7.3.1,7.4.0)",
+ org.eclipse.jgit.util;version="[7.3.1,7.4.0)"
diff --git a/org.eclipse.jgit.ui/META-INF/SOURCE-MANIFEST.MF b/org.eclipse.jgit.ui/META-INF/SOURCE-MANIFEST.MF
index 851cbdc..d272a1b 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: 7.2.2.qualifier
-Eclipse-SourceBundle: org.eclipse.jgit.ui;version="7.2.2.qualifier";roots="."
+Bundle-Version: 7.3.1.qualifier
+Eclipse-SourceBundle: org.eclipse.jgit.ui;version="7.3.1.qualifier";roots="."
diff --git a/org.eclipse.jgit.ui/pom.xml b/org.eclipse.jgit.ui/pom.xml
index df375c8..5c67272 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>7.2.2-SNAPSHOT</version>
+    <version>7.3.1-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 c2013f6..9549aae 100644
--- a/org.eclipse.jgit/META-INF/MANIFEST.MF
+++ b/org.eclipse.jgit/META-INF/MANIFEST.MF
@@ -3,14 +3,14 @@
 Bundle-Name: %Bundle-Name
 Automatic-Module-Name: org.eclipse.jgit
 Bundle-SymbolicName: org.eclipse.jgit
-Bundle-Version: 7.2.2.qualifier
+Bundle-Version: 7.3.1.qualifier
 Bundle-Localization: OSGI-INF/l10n/plugin
 Bundle-Vendor: %Bundle-Vendor
 Bundle-ActivationPolicy: lazy
 Service-Component: OSGI-INF/org.eclipse.jgit.internal.util.CleanupService.xml
 Eclipse-ExtensibleAPI: true
-Export-Package: org.eclipse.jgit.annotations;version="7.2.2",
- org.eclipse.jgit.api;version="7.2.2";
+Export-Package: org.eclipse.jgit.annotations;version="7.3.1",
+ org.eclipse.jgit.api;version="7.3.1";
   uses:="org.eclipse.jgit.transport,
    org.eclipse.jgit.notes,
    org.eclipse.jgit.dircache,
@@ -25,21 +25,21 @@
    org.eclipse.jgit.revwalk.filter,
    org.eclipse.jgit.blame,
    org.eclipse.jgit.merge",
- org.eclipse.jgit.api.errors;version="7.2.2";
+ org.eclipse.jgit.api.errors;version="7.3.1";
   uses:="org.eclipse.jgit.lib,
    org.eclipse.jgit.errors",
- org.eclipse.jgit.attributes;version="7.2.2";
+ org.eclipse.jgit.attributes;version="7.3.1";
   uses:="org.eclipse.jgit.lib,
    org.eclipse.jgit.treewalk",
- org.eclipse.jgit.blame;version="7.2.2";
+ org.eclipse.jgit.blame;version="7.3.1";
   uses:="org.eclipse.jgit.lib,
    org.eclipse.jgit.revwalk,
    org.eclipse.jgit.blame.cache,
    org.eclipse.jgit.diff,
    org.eclipse.jgit.treewalk.filter",
- org.eclipse.jgit.blame.cache;version="7.2.2";
+ org.eclipse.jgit.blame.cache;version="7.3.1";
   uses:="org.eclipse.jgit.lib",
- org.eclipse.jgit.diff;version="7.2.2";
+ org.eclipse.jgit.diff;version="7.3.1";
   uses:="org.eclipse.jgit.lib,
    org.eclipse.jgit.revwalk,
    org.eclipse.jgit.patch,
@@ -47,55 +47,55 @@
    org.eclipse.jgit.treewalk.filter,
    org.eclipse.jgit.treewalk,
    org.eclipse.jgit.util",
- org.eclipse.jgit.dircache;version="7.2.2";
+ org.eclipse.jgit.dircache;version="7.3.1";
   uses:="org.eclipse.jgit.events,
    org.eclipse.jgit.lib,
    org.eclipse.jgit.attributes,
    org.eclipse.jgit.treewalk,
    org.eclipse.jgit.util",
- org.eclipse.jgit.errors;version="7.2.2";
+ org.eclipse.jgit.errors;version="7.3.1";
   uses:="org.eclipse.jgit.transport,
    org.eclipse.jgit.dircache,
    org.eclipse.jgit.lib",
- org.eclipse.jgit.events;version="7.2.2";
+ org.eclipse.jgit.events;version="7.3.1";
   uses:="org.eclipse.jgit.lib",
- org.eclipse.jgit.fnmatch;version="7.2.2",
- org.eclipse.jgit.gitrepo;version="7.2.2";
+ org.eclipse.jgit.fnmatch;version="7.3.1",
+ org.eclipse.jgit.gitrepo;version="7.3.1";
   uses:="org.xml.sax.helpers,
    org.eclipse.jgit.api,
    org.eclipse.jgit.api.errors,
    org.eclipse.jgit.lib,
    org.eclipse.jgit.revwalk,
    org.xml.sax",
- org.eclipse.jgit.gitrepo.internal;version="7.2.2";x-internal:=true,
- org.eclipse.jgit.hooks;version="7.2.2";
+ org.eclipse.jgit.gitrepo.internal;version="7.3.1";x-internal:=true,
+ org.eclipse.jgit.hooks;version="7.3.1";
   uses:="org.eclipse.jgit.lib,
    org.eclipse.jgit.util",
- org.eclipse.jgit.ignore;version="7.2.2",
- org.eclipse.jgit.ignore.internal;version="7.2.2";
+ org.eclipse.jgit.ignore;version="7.3.1",
+ org.eclipse.jgit.ignore.internal;version="7.3.1";
   x-friends:="org.eclipse.jgit.test",
- org.eclipse.jgit.internal;version="7.2.2";
+ org.eclipse.jgit.internal;version="7.3.1";
   x-friends:="org.eclipse.jgit.test,
    org.eclipse.jgit.http.test",
- org.eclipse.jgit.internal.diff;version="7.2.2";
+ org.eclipse.jgit.internal.diff;version="7.3.1";
   x-friends:="org.eclipse.jgit.test",
- org.eclipse.jgit.internal.diffmergetool;version="7.2.2";
+ org.eclipse.jgit.internal.diffmergetool;version="7.3.1";
   x-friends:="org.eclipse.jgit.test,
    org.eclipse.jgit.pgm.test,
    org.eclipse.jgit.pgm,
    org.eclipse.egit.ui",
- org.eclipse.jgit.internal.fsck;version="7.2.2";
+ org.eclipse.jgit.internal.fsck;version="7.3.1";
   x-friends:="org.eclipse.jgit.test",
- org.eclipse.jgit.internal.revwalk;version="7.2.2";
+ org.eclipse.jgit.internal.revwalk;version="7.3.1";
   x-friends:="org.eclipse.jgit.test",
- org.eclipse.jgit.internal.storage.commitgraph;version="7.2.2";
+ org.eclipse.jgit.internal.storage.commitgraph;version="7.3.1";
   x-friends:="org.eclipse.jgit.test",
- org.eclipse.jgit.internal.storage.dfs;version="7.2.2";
+ org.eclipse.jgit.internal.storage.dfs;version="7.3.1";
   x-friends:="org.eclipse.jgit.test,
    org.eclipse.jgit.http.server,
    org.eclipse.jgit.http.test,
    org.eclipse.jgit.lfs.test",
- org.eclipse.jgit.internal.storage.file;version="7.2.2";
+ org.eclipse.jgit.internal.storage.file;version="7.3.1";
   x-friends:="org.eclipse.jgit.test,
    org.eclipse.jgit.junit,
    org.eclipse.jgit.junit.http,
@@ -104,37 +104,37 @@
    org.eclipse.jgit.pgm,
    org.eclipse.jgit.pgm.test,
    org.eclipse.jgit.ssh.apache",
- org.eclipse.jgit.internal.storage.io;version="7.2.2";
+ org.eclipse.jgit.internal.storage.io;version="7.3.1";
   x-friends:="org.eclipse.jgit.junit,
    org.eclipse.jgit.test,
    org.eclipse.jgit.pgm",
- org.eclipse.jgit.internal.storage.memory;version="7.2.2";
+ org.eclipse.jgit.internal.storage.memory;version="7.3.1";
   x-friends:="org.eclipse.jgit.test",
- org.eclipse.jgit.internal.storage.midx;version="7.2.2";x-internal:=true,
- org.eclipse.jgit.internal.storage.pack;version="7.2.2";
+ org.eclipse.jgit.internal.storage.midx;version="7.3.1";x-internal:=true,
+ org.eclipse.jgit.internal.storage.pack;version="7.3.1";
   x-friends:="org.eclipse.jgit.junit,
    org.eclipse.jgit.test,
    org.eclipse.jgit.pgm",
- org.eclipse.jgit.internal.storage.reftable;version="7.2.2";
+ org.eclipse.jgit.internal.storage.reftable;version="7.3.1";
   x-friends:="org.eclipse.jgit.http.test,
    org.eclipse.jgit.junit,
    org.eclipse.jgit.test,
    org.eclipse.jgit.pgm",
- org.eclipse.jgit.internal.submodule;version="7.2.2";x-internal:=true,
- org.eclipse.jgit.internal.transport.connectivity;version="7.2.2";
+ org.eclipse.jgit.internal.submodule;version="7.3.1";x-internal:=true,
+ org.eclipse.jgit.internal.transport.connectivity;version="7.3.1";
   x-friends:="org.eclipse.jgit.test",
- org.eclipse.jgit.internal.transport.http;version="7.2.2";
+ org.eclipse.jgit.internal.transport.http;version="7.3.1";
   x-friends:="org.eclipse.jgit.test",
- org.eclipse.jgit.internal.transport.parser;version="7.2.2";
+ org.eclipse.jgit.internal.transport.parser;version="7.3.1";
   x-friends:="org.eclipse.jgit.http.server,
    org.eclipse.jgit.test",
- org.eclipse.jgit.internal.transport.ssh;version="7.2.2";
+ org.eclipse.jgit.internal.transport.ssh;version="7.3.1";
   x-friends:="org.eclipse.jgit.ssh.apache,
    org.eclipse.jgit.ssh.jsch,
    org.eclipse.jgit.test",
- org.eclipse.jgit.internal.util;version="7.2.2";
+ org.eclipse.jgit.internal.util;version="7.3.1";
   x-friends:="org.eclipse.jgit.junit",
- org.eclipse.jgit.lib;version="7.2.2";
+ org.eclipse.jgit.lib;version="7.3.1";
   uses:="org.eclipse.jgit.transport,
    org.eclipse.jgit.util.sha1,
    org.eclipse.jgit.dircache,
@@ -149,12 +149,12 @@
    org.eclipse.jgit.util,
    org.eclipse.jgit.submodule,
    org.eclipse.jgit.util.time",
- org.eclipse.jgit.lib.internal;version="7.2.2";
+ org.eclipse.jgit.lib.internal;version="7.3.1";
   x-friends:="org.eclipse.jgit.test,
    org.eclipse.jgit.pgm,
    org.eclipse.egit.ui",
- org.eclipse.jgit.logging;version="7.2.2",
- org.eclipse.jgit.merge;version="7.2.2";
+ org.eclipse.jgit.logging;version="7.3.1",
+ org.eclipse.jgit.merge;version="7.3.1";
   uses:="org.eclipse.jgit.dircache,
    org.eclipse.jgit.lib,
    org.eclipse.jgit.revwalk,
@@ -163,42 +163,42 @@
    org.eclipse.jgit.util,
    org.eclipse.jgit.api,
    org.eclipse.jgit.attributes",
- org.eclipse.jgit.nls;version="7.2.2",
- org.eclipse.jgit.notes;version="7.2.2";
+ org.eclipse.jgit.nls;version="7.3.1",
+ org.eclipse.jgit.notes;version="7.3.1";
   uses:="org.eclipse.jgit.lib,
    org.eclipse.jgit.revwalk,
    org.eclipse.jgit.treewalk,
    org.eclipse.jgit.merge",
- org.eclipse.jgit.patch;version="7.2.2";
+ org.eclipse.jgit.patch;version="7.3.1";
   uses:="org.eclipse.jgit.lib,
    org.eclipse.jgit.revwalk,
    org.eclipse.jgit.diff",
- org.eclipse.jgit.revplot;version="7.2.2";
+ org.eclipse.jgit.revplot;version="7.3.1";
   uses:="org.eclipse.jgit.revwalk,
    org.eclipse.jgit.lib",
- org.eclipse.jgit.revwalk;version="7.2.2";
+ org.eclipse.jgit.revwalk;version="7.3.1";
   uses:="org.eclipse.jgit.lib,
    org.eclipse.jgit.revwalk.filter,
    org.eclipse.jgit.diff,
    org.eclipse.jgit.treewalk.filter,
    org.eclipse.jgit.treewalk,
    org.eclipse.jgit.internal.storage.commitgraph",
- org.eclipse.jgit.revwalk.filter;version="7.2.2";
+ org.eclipse.jgit.revwalk.filter;version="7.3.1";
   uses:="org.eclipse.jgit.revwalk,
    org.eclipse.jgit.lib,
    org.eclipse.jgit.util",
- org.eclipse.jgit.storage.file;version="7.2.2";
+ org.eclipse.jgit.storage.file;version="7.3.1";
   uses:="org.eclipse.jgit.lib,
    org.eclipse.jgit.util",
- org.eclipse.jgit.storage.pack;version="7.2.2";
+ org.eclipse.jgit.storage.pack;version="7.3.1";
   uses:="org.eclipse.jgit.lib",
- org.eclipse.jgit.submodule;version="7.2.2";
+ org.eclipse.jgit.submodule;version="7.3.1";
   uses:="org.eclipse.jgit.lib,
    org.eclipse.jgit.treewalk.filter,
    org.eclipse.jgit.diff,
    org.eclipse.jgit.treewalk,
    org.eclipse.jgit.util",
- org.eclipse.jgit.transport;version="7.2.2";
+ org.eclipse.jgit.transport;version="7.3.1";
   uses:="javax.crypto,
    org.eclipse.jgit.hooks,
    org.eclipse.jgit.util.io,
@@ -211,21 +211,21 @@
    org.eclipse.jgit.transport.resolver,
    org.eclipse.jgit.storage.pack,
    org.eclipse.jgit.errors",
- org.eclipse.jgit.transport.http;version="7.2.2";
+ org.eclipse.jgit.transport.http;version="7.3.1";
   uses:="javax.net.ssl",
- org.eclipse.jgit.transport.resolver;version="7.2.2";
+ org.eclipse.jgit.transport.resolver;version="7.3.1";
   uses:="org.eclipse.jgit.transport,
    org.eclipse.jgit.lib",
- org.eclipse.jgit.treewalk;version="7.2.2";
+ org.eclipse.jgit.treewalk;version="7.3.1";
   uses:="org.eclipse.jgit.dircache,
    org.eclipse.jgit.lib,
    org.eclipse.jgit.attributes,
    org.eclipse.jgit.revwalk,
    org.eclipse.jgit.treewalk.filter,
    org.eclipse.jgit.util",
- org.eclipse.jgit.treewalk.filter;version="7.2.2";
+ org.eclipse.jgit.treewalk.filter;version="7.3.1";
   uses:="org.eclipse.jgit.treewalk",
- org.eclipse.jgit.util;version="7.2.2";
+ org.eclipse.jgit.util;version="7.3.1";
   uses:="org.eclipse.jgit.transport,
    org.eclipse.jgit.hooks,
    org.eclipse.jgit.revwalk,
@@ -238,12 +238,12 @@
    org.eclipse.jgit.treewalk,
    javax.net.ssl,
    org.eclipse.jgit.util.time",
- org.eclipse.jgit.util.io;version="7.2.2";
+ org.eclipse.jgit.util.io;version="7.3.1";
   uses:="org.eclipse.jgit.attributes,
    org.eclipse.jgit.lib,
    org.eclipse.jgit.treewalk",
- org.eclipse.jgit.util.sha1;version="7.2.2",
- org.eclipse.jgit.util.time;version="7.2.2"
+ org.eclipse.jgit.util.sha1;version="7.3.1",
+ org.eclipse.jgit.util.time;version="7.3.1"
 Bundle-RequiredExecutionEnvironment: JavaSE-17
 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 dc4706e..b5dfafe 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: 7.2.2.qualifier
-Eclipse-SourceBundle: org.eclipse.jgit;version="7.2.2.qualifier";roots="."
+Bundle-Version: 7.3.1.qualifier
+Eclipse-SourceBundle: org.eclipse.jgit;version="7.3.1.qualifier";roots="."
diff --git a/org.eclipse.jgit/pom.xml b/org.eclipse.jgit/pom.xml
index 87fe65b..ba560bc 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>7.2.2-SNAPSHOT</version>
+    <version>7.3.1-SNAPSHOT</version>
   </parent>
 
   <artifactId>org.eclipse.jgit</artifactId>
diff --git a/org.eclipse.jgit/resources/org/eclipse/jgit/internal/JGitText.properties b/org.eclipse.jgit/resources/org/eclipse/jgit/internal/JGitText.properties
index 27270a1..01c8cff 100644
--- a/org.eclipse.jgit/resources/org/eclipse/jgit/internal/JGitText.properties
+++ b/org.eclipse.jgit/resources/org/eclipse/jgit/internal/JGitText.properties
@@ -496,6 +496,7 @@
 logLargerFiletimeDiff={}: inconsistent duration from file timestamps on {}, {}: diff = {} > {} (last good value). Aborting measurement.
 logSmallerFiletime={}: got smaller file timestamp on {}, {}: {} < {}. Aborting measurement at resolution {}.
 logXDGConfigHomeInvalid=Environment variable XDG_CONFIG_HOME contains an invalid path {}
+logXDGCacheHomeInvalid=Environment variable XDG_CACHE_HOME contains an invalid path {}
 looseObjectHandleIsStale=loose-object {0} file handle is stale. retry {1} of {2}
 maxCountMustBeNonNegative=max count must be >= 0
 mergeConflictOnNonNoteEntries=Merge conflict on non-note entries: base = {0}, ours = {1}, theirs = {2}
@@ -508,6 +509,9 @@
 mergeToolNotGivenError=No merge tool provided and no defaults configured.
 mergeToolNullError=Parameter for merge tool cannot be null.
 messageAndTaggerNotAllowedInUnannotatedTags = Unannotated tags cannot have a message or tagger
+midxChunkNeeded=midx 0x{0} chunk has not been loaded
+midxChunkRepeated=midx chunk id 0x{0} appears multiple times
+midxChunkUnknown=unknown midx chunk: 0x{0}
 minutesAgo={0} minutes ago
 mismatchOffset=mismatch offset for object {0}
 mismatchCRC=mismatch CRC for object {0}
@@ -528,6 +532,8 @@
 month=month
 months=months
 monthsAgo={0} months ago
+multiPackIndexFileIsTooLargeForJgit=Multipack index file is too large for jgit
+multiPackIndexPackCountMismatch=Multipack index: header mentions %d packs but packfile names chunk has %d
 multiPackIndexUnexpectedSize=MultiPack index: expected %d bytes but out has %d bytes
 multiPackIndexWritingCancelled=Multipack index writing was canceled
 multipleMergeBasesFor=Multiple merge bases for:\n  {0}\n  {1} found:\n  {2}\n  {3}
@@ -557,6 +563,7 @@
 notADIRCFile=Not a DIRC file.
 notAGitDirectory=not a git directory
 notAPACKFile=Not a PACK file.
+notAMIDX=not a multi-pack-index
 notARef=Not a ref: {0}: {1}
 notASCIIString=Not ASCII string: {0}
 notAuthorized=not authorized
@@ -852,6 +859,7 @@
 unmergedPaths=Repository contains unmerged paths
 unpackException=Exception while parsing pack stream
 unreadableCommitGraph=Unreadable commit-graph: {0}
+unreadableMIDX=Unreadable multi-pack-index: {0}
 unreadableObjectSizeIndex=Unreadable object size index. First {0} bytes are ''{1}''
 unreadablePackIndex=Unreadable pack index: {0}
 unrecognizedPackExtension=Unrecognized pack extension: {0}
@@ -865,6 +873,7 @@
 unsupportedEncryptionVersion=Unsupported encryption version: {0}
 unsupportedGC=Unsupported garbage collector for repository type: {0}
 unsupportedMark=Mark not supported
+unsupportedMIDXVersion=Unsupported MIDX version
 unsupportedObjectSizeIndexVersion=Unsupported object size index version {0}
 unsupportedOperationNotAddAtEnd=Not add-at-end: {0}
 unsupportedPackIndexVersion=Unsupported pack index version {0}
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/api/LogCommand.java b/org.eclipse.jgit/src/org/eclipse/jgit/api/LogCommand.java
index 555e351..2a8d34e 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/api/LogCommand.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/api/LogCommand.java
@@ -110,10 +110,10 @@ public Iterable<RevCommit> call() throws GitAPIException, NoHeadException {
 		}
 		if (!filters.isEmpty()) {
 			if (filters.size() == 1) {
-				filters.add(TreeFilter.ANY_DIFF);
+				walk.setTreeFilter(filters.get(0));
+			} else {
+				walk.setTreeFilter(AndTreeFilter.create(filters));
 			}
-			walk.setTreeFilter(AndTreeFilter.create(filters));
-
 		}
 		if (skip > -1 && maxCount > -1)
 			walk.setRevFilter(AndRevFilter.create(SkipRevFilter.create(skip),
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/blame/BlameGenerator.java b/org.eclipse.jgit/src/org/eclipse/jgit/blame/BlameGenerator.java
index 2d499ca..979c8ce 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/blame/BlameGenerator.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/blame/BlameGenerator.java
@@ -652,19 +652,6 @@ public boolean next() throws IOException {
 			if (n == null)
 				return done();
 			stats.candidatesVisited += 1;
-			if (blameCache != null && useCache) {
-				List<CacheRegion> cachedBlame = blameCache.get(repository,
-						n.sourceCommit, n.sourcePath.getPath());
-				if (cachedBlame != null) {
-					BlameRegionMerger rb = new BlameRegionMerger(repository,
-							revPool, cachedBlame);
-					Candidate fullyBlamed = rb.mergeCandidate(n);
-					if (fullyBlamed != null) {
-						stats.cacheHit = true;
-						return result(fullyBlamed);
-					}
-				}
-			}
 
 			int pCnt = n.getParentCount();
 			if (pCnt == 1) {
@@ -769,6 +756,27 @@ private void push(Candidate toInsert) {
 		}
 	}
 
+	@Nullable
+	private Candidate blameFromCache(Candidate n) throws IOException {
+		if (blameCache == null || !useCache) {
+			return null;
+		}
+
+		List<CacheRegion> cachedBlame = blameCache.get(repository,
+				n.sourceCommit, n.sourcePath.getPath());
+		if (cachedBlame == null) {
+			return null;
+		}
+		BlameRegionMerger rb = new BlameRegionMerger(repository, revPool,
+				cachedBlame);
+		Candidate fullyBlamed = rb.mergeCandidate(n);
+		if (fullyBlamed == null) {
+			return null;
+		}
+		stats.cacheHit = true;
+		return fullyBlamed;
+	}
+
 	private boolean processOne(Candidate n) throws IOException {
 		RevCommit parent = n.getParent(0);
 		if (parent == null)
@@ -791,12 +799,17 @@ private boolean processOne(Candidate n) throws IOException {
 		if (0 == r.getOldId().prefixCompare(n.sourceBlob)) {
 			// A 100% rename without any content change can also
 			// skip directly to the parent.
+			Candidate cached = blameFromCache(n);
+			if (cached != null) {
+				return result(cached);
+			}
 			n.sourceCommit = parent;
 			n.sourcePath = PathFilter.create(r.getOldPath());
 			push(n);
 			return false;
 		}
 
+
 		Candidate next = n.create(getRepository(), parent,
 				PathFilter.create(r.getOldPath()));
 		next.sourceBlob = r.getOldId().toObjectId();
@@ -833,6 +846,11 @@ private boolean split(Candidate parent, Candidate source)
 			return false;
 		}
 
+		Candidate cached = blameFromCache(source);
+		if (cached != null) {
+			return result(cached);
+		}
+
 		parent.takeBlame(editList, source);
 		if (parent.regionList != null)
 			push(parent);
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/blame/BlameResult.java b/org.eclipse.jgit/src/org/eclipse/jgit/blame/BlameResult.java
index 48f6b7e..5e2746c 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/blame/BlameResult.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/blame/BlameResult.java
@@ -79,7 +79,6 @@ public static BlameResult create(BlameGenerator gen) throws IOException {
 
 	BlameResult(BlameGenerator bg, String path, RawText text) {
 		generator = bg;
-		generator.setUseCache(false);
 		resultPath = path;
 		resultContents = text;
 
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 bf252f9..8928f47 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/internal/JGitText.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/internal/JGitText.java
@@ -526,6 +526,8 @@ public static JGitText get() {
 	/***/ public String logLargerFiletimeDiff;
 	/***/ public String logSmallerFiletime;
 	/***/ public String logXDGConfigHomeInvalid;
+
+	/***/ public String logXDGCacheHomeInvalid;
 	/***/ public String looseObjectHandleIsStale;
 	/***/ public String maxCountMustBeNonNegative;
 	/***/ public String mergeConflictOnNonNoteEntries;
@@ -538,6 +540,9 @@ public static JGitText get() {
 	/***/ public String mergeToolNotGivenError;
 	/***/ public String mergeToolNullError;
 	/***/ public String messageAndTaggerNotAllowedInUnannotatedTags;
+	/***/ public String midxChunkNeeded;
+	/***/ public String midxChunkRepeated;
+	/***/ public String midxChunkUnknown;
 	/***/ public String minutesAgo;
 	/***/ public String mismatchOffset;
 	/***/ public String mismatchCRC;
@@ -558,6 +563,8 @@ public static JGitText get() {
 	/***/ public String month;
 	/***/ public String months;
 	/***/ public String monthsAgo;
+	/***/ public String multiPackIndexFileIsTooLargeForJgit;
+	/***/ public String multiPackIndexPackCountMismatch;
 	/***/ public String multiPackIndexUnexpectedSize;
 	/***/ public String multiPackIndexWritingCancelled;
 	/***/ public String multipleMergeBasesFor;
@@ -586,6 +593,7 @@ public static JGitText get() {
 	/***/ public String notACommitGraph;
 	/***/ public String notADIRCFile;
 	/***/ public String notAGitDirectory;
+	/***/ public String notAMIDX;
 	/***/ public String notAPACKFile;
 	/***/ public String notARef;
 	/***/ public String notASCIIString;
@@ -881,6 +889,7 @@ public static JGitText get() {
 	/***/ public String unmergedPaths;
 	/***/ public String unpackException;
 	/***/ public String unreadableCommitGraph;
+	/***/ public String unreadableMIDX;
 	/***/ public String unreadableObjectSizeIndex;
 	/***/ public String unreadablePackIndex;
 	/***/ public String unrecognizedPackExtension;
@@ -894,6 +903,7 @@ public static JGitText get() {
 	/***/ public String unsupportedEncryptionVersion;
 	/***/ public String unsupportedGC;
 	/***/ public String unsupportedMark;
+	/***/ public String unsupportedMIDXVersion;
 	/***/ public String unsupportedObjectIdVersion;
 	/***/ public String unsupportedObjectSizeIndexVersion;
 	/***/ public String unsupportedOperationNotAddAtEnd;
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/dfs/DfsInserter.java b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/dfs/DfsInserter.java
index 16315bf..dd9e4b9 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/dfs/DfsInserter.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/dfs/DfsInserter.java
@@ -83,7 +83,6 @@ public class DfsInserter extends ObjectInserter {
 	DfsPackDescription packDsc;
 	PackStream packOut;
 	private boolean rollback;
-	private boolean checkExisting = true;
 
 	/**
 	 * Initialize a new inserter.
@@ -98,18 +97,6 @@ protected DfsInserter(DfsObjDatabase db) {
 				ConfigConstants.CONFIG_KEY_MIN_BYTES_OBJ_SIZE_INDEX, -1);
 	}
 
-	/**
-	 * Check existence
-	 *
-	 * @param check
-	 *            if {@code false}, will write out possibly-duplicate objects
-	 *            without first checking whether they exist in the repo; default
-	 *            is true.
-	 */
-	public void checkExisting(boolean check) {
-		checkExisting = check;
-	}
-
 	void setCompressionLevel(int compression) {
 		this.compression = compression;
 	}
@@ -130,8 +117,9 @@ public ObjectId insert(int type, byte[] data, int off, int len)
 		if (objectMap != null && objectMap.contains(id))
 			return id;
 		// Ignore unreachable (garbage) objects here.
-		if (checkExisting && db.has(id, true))
+		if (db.has(id, true)) {
 			return id;
+		}
 
 		long offset = beginObject(type, len);
 		packOut.compress.write(data, off, len);
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/dfs/DfsPackCompactor.java b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/dfs/DfsPackCompactor.java
index f9c01b9..6339b03 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/dfs/DfsPackCompactor.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/dfs/DfsPackCompactor.java
@@ -405,7 +405,7 @@ private void addObjectsToPack(PackWriter pw, DfsReader ctx,
 				pw.addObject(obj);
 				obj.add(added);
 
-				src.representation(rep, id.offset, ctx, rev);
+				src.fillRepresentation(rep, id.offset, ctx, rev);
 				if (rep.getFormat() != PACK_DELTA)
 					continue;
 
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/dfs/DfsPackFile.java b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/dfs/DfsPackFile.java
index 48ed47a..618969f 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/dfs/DfsPackFile.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/dfs/DfsPackFile.java
@@ -27,6 +27,9 @@
 import java.nio.ByteBuffer;
 import java.nio.channels.Channels;
 import java.text.MessageFormat;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.List;
 import java.util.Set;
 import java.util.concurrent.atomic.AtomicBoolean;
 import java.util.concurrent.atomic.AtomicReference;
@@ -49,6 +52,7 @@
 import org.eclipse.jgit.internal.storage.file.PackReverseIndex;
 import org.eclipse.jgit.internal.storage.file.PackReverseIndexFactory;
 import org.eclipse.jgit.internal.storage.pack.BinaryDelta;
+import org.eclipse.jgit.internal.storage.pack.ObjectToPack;
 import org.eclipse.jgit.internal.storage.pack.PackOutputStream;
 import org.eclipse.jgit.internal.storage.pack.StoredObjectRepresentation;
 import org.eclipse.jgit.lib.AbbreviatedObjectId;
@@ -59,6 +63,7 @@
 import org.eclipse.jgit.lib.ObjectLoader;
 import org.eclipse.jgit.lib.Repository;
 import org.eclipse.jgit.lib.StoredConfig;
+import org.eclipse.jgit.util.BlockList;
 import org.eclipse.jgit.util.LongList;
 
 /**
@@ -71,6 +76,10 @@ public final class DfsPackFile extends BlockBasedFile {
 
 	private static final long REF_POSITION = 0;
 
+	private static final Comparator<DfsObjectToPack> OFFSET_SORT = (
+			DfsObjectToPack a,
+			DfsObjectToPack b) -> Long.signum(a.getOffset() - b.getOffset());
+
 	/**
 	 * Loader for the default file-based {@link PackBitmapIndex} implementation.
 	 */
@@ -139,11 +148,15 @@ interface PackIndexes {
 			 *
 			 * @param ctx
 			 *            reader to find the raw bytes
+			 * @param idx
+			 *            primary index for this reverse index (probably loaded
+			 *            via #index(DfsReader))
 			 * @return the reverse index of the pack
 			 * @throws IOException
 			 *             a problem finding/parsing the reverse index
 			 */
-			PackReverseIndex reverseIndex(DfsReader ctx) throws IOException;
+			PackReverseIndex reverseIndex(DfsReader ctx, PackIndex idx)
+					throws IOException;
 		}
 
 		/**
@@ -364,7 +377,7 @@ public PackReverseIndex getReverseIdx(DfsReader ctx) throws IOException {
 			return reverseIndex;
 		}
 
-		reverseIndex = indexFactory.getPackIndexes().reverseIndex(ctx);
+		reverseIndex = indexFactory.getPackIndexes().reverseIndex(ctx, idx(ctx));
 		if (reverseIndex == null) {
 			throw new IOException(
 					"Couldn't get a reference to the reverse index"); //$NON-NLS-1$
@@ -451,25 +464,45 @@ long findOffset(DfsReader ctx, AnyObjectId id) throws IOException {
 		return idx(ctx).findOffset(id);
 	}
 
+	/**
+	 * Return objects in the list available in this pack, sorted in (pack,
+	 * offset) order.
+	 *
+	 * @param ctx
+	 *            a reader
+	 * @param objects
+	 *            objects we are looking for
+	 * @param skipFound
+	 *            ignore objects already found.
+	 * @return list of objects with pack and offset set.
+	 * @throws IOException
+	 *             an error occurred
+	 */
+	List<DfsObjectToPack> findAllFromPack(DfsReader ctx,
+			Iterable<ObjectToPack> objects, boolean skipFound)
+			throws IOException {
+		List<DfsObjectToPack> tmp = new BlockList<>();
+		for (ObjectToPack obj : objects) {
+			DfsObjectToPack otp = (DfsObjectToPack) obj;
+			if (skipFound && otp.isFound()) {
+				continue;
+			}
+			long p = idx(ctx).findOffset(otp);
+			if (p <= 0 || isCorrupt(p)) {
+				continue;
+			}
+			otp.setOffset(p);
+			tmp.add(otp);
+		}
+		Collections.sort(tmp, OFFSET_SORT);
+		return tmp;
+	}
+
 	void resolve(DfsReader ctx, Set<ObjectId> matches, AbbreviatedObjectId id,
 			int matchLimit) throws IOException {
 		idx(ctx).resolve(matches, id, matchLimit);
 	}
 
-	/**
-	 * Obtain the total number of objects available in this pack. This method
-	 * relies on pack index, giving number of effectively available objects.
-	 *
-	 * @param ctx
-	 *            current reader for the calling thread.
-	 * @return number of objects in index of this pack, likewise in this pack
-	 * @throws IOException
-	 *             the index file cannot be loaded into memory.
-	 */
-	long getObjectCount(DfsReader ctx) throws IOException {
-		return idx(ctx).getObjectCount();
-	}
-
 	private byte[] decompress(long position, int sz, DfsReader ctx)
 			throws IOException, DataFormatException {
 		byte[] dstbuf;
@@ -1165,12 +1198,47 @@ long getIndexedObjectSize(DfsReader ctx, AnyObjectId id)
 		return sizeIdx.getSize(idxPosition);
 	}
 
-	void representation(DfsObjectRepresentation r, final long pos,
+	/**
+	 * Populates the representation object with the details of how the object at
+	 * "pos" is stored in this pack (e.g. whole or deltified, its packed
+	 * length).
+	 *
+	 * @param r
+	 *            represention object to carry data
+	 * @param offset
+	 *            offset in this pack of the object
+	 * @param ctx
+	 *            a reader
+	 * @throws IOException
+	 *             an error reading the object from disk
+	 */
+	void fillRepresentation(DfsObjectRepresentation r, long offset,
+			DfsReader ctx) throws IOException {
+		fillRepresentation(r, offset, ctx, getReverseIdx(ctx));
+	}
+
+	/**
+	 * Populates the representation object with the details of how the object at
+	 * "pos" is stored in this pack (e.g. whole or deltified, its packed
+	 * length).
+	 *
+	 * @param r
+	 *            represention object to carry data
+	 * @param offset
+	 *            offset in this pack of the object
+	 * @param ctx
+	 *            a reader
+	 * @param rev
+	 *            reverse index of this pack
+	 * @throws IOException
+	 *             an error reading the object from disk
+	 */
+	void fillRepresentation(DfsObjectRepresentation r, long offset,
 			DfsReader ctx, PackReverseIndex rev)
 			throws IOException {
-		r.offset = pos;
+		r.offset = offset;
 		final byte[] ib = ctx.tempId;
-		readFully(pos, ib, 0, 20, ctx);
+		readFully(offset, ib, 0, 20, ctx);
 		int c = ib[0] & 0xff;
 		int p = 1;
 		final int typeCode = (c >> 4) & 7;
@@ -1178,7 +1246,7 @@ void representation(DfsObjectRepresentation r, final long pos,
 			c = ib[p++] & 0xff;
 		}
 
-		long len = rev.findNextOffset(pos, length - 20) - pos;
+		long len = rev.findNextOffset(offset, length - 20) - offset;
 		switch (typeCode) {
 		case Constants.OBJ_COMMIT:
 		case Constants.OBJ_TREE:
@@ -1199,13 +1267,13 @@ void representation(DfsObjectRepresentation r, final long pos,
 				ofs += (c & 127);
 			}
 			r.format = StoredObjectRepresentation.PACK_DELTA;
-			r.baseId = rev.findObject(pos - ofs);
+			r.baseId = rev.findObject(offset - ofs);
 			r.length = len - p;
 			return;
 		}
 
 		case Constants.OBJ_REF_DELTA: {
-			readFully(pos + p, ib, 0, 20, ctx);
+			readFully(offset + p, ib, 0, 20, ctx);
 			r.format = StoredObjectRepresentation.PACK_DELTA;
 			r.baseId = ObjectId.fromRaw(ib);
 			r.length = len - p - 20;
@@ -1540,8 +1608,8 @@ private static RefWithSize<PackIndex> loadPackIndex(DfsReader ctx,
 		}
 
 		@Override
-		public PackReverseIndex reverseIndex(DfsReader ctx) throws IOException {
-			PackIndex idx = index(ctx);
+		public PackReverseIndex reverseIndex(DfsReader ctx, PackIndex idx)
+				throws IOException {
 			DfsStreamKey revKey = desc.getStreamKey(REVERSE_INDEX);
 			// Keep the value parsed in the loader, in case the Ref<> is
 			// nullified in ClockBlockCacheTable#reserveSpace
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/dfs/DfsReader.java b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/dfs/DfsReader.java
index 62f6753..04288bc 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/dfs/DfsReader.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/dfs/DfsReader.java
@@ -38,8 +38,6 @@
 import org.eclipse.jgit.internal.storage.dfs.DfsReader.PackLoadListener.DfsBlockData;
 import org.eclipse.jgit.internal.storage.file.BitmapIndexImpl;
 import org.eclipse.jgit.internal.storage.file.PackBitmapIndex;
-import org.eclipse.jgit.internal.storage.file.PackIndex;
-import org.eclipse.jgit.internal.storage.file.PackReverseIndex;
 import org.eclipse.jgit.internal.storage.pack.CachedPack;
 import org.eclipse.jgit.internal.storage.pack.ObjectReuseAsIs;
 import org.eclipse.jgit.internal.storage.pack.ObjectToPack;
@@ -58,7 +56,6 @@
 import org.eclipse.jgit.lib.ObjectLoader;
 import org.eclipse.jgit.lib.ObjectReader;
 import org.eclipse.jgit.lib.ProgressMonitor;
-import org.eclipse.jgit.util.BlockList;
 
 /**
  * Reader to access repository content through.
@@ -619,10 +616,6 @@ public DfsObjectToPack newObjectToPack(AnyObjectId objectId, int type) {
 		return new DfsObjectToPack(objectId, type);
 	}
 
-	private static final Comparator<DfsObjectToPack> OFFSET_SORT = (
-			DfsObjectToPack a,
-			DfsObjectToPack b) -> Long.signum(a.getOffset() - b.getOffset());
-
 	@Override
 	public void selectObjectRepresentation(PackWriter packer,
 			ProgressMonitor monitor, Iterable<ObjectToPack> objects)
@@ -642,16 +635,15 @@ private void trySelectRepresentation(PackWriter packer,
 			ProgressMonitor monitor, Iterable<ObjectToPack> objects,
 			List<DfsPackFile> packs, boolean skipFound) throws IOException {
 		for (DfsPackFile pack : packs) {
-			List<DfsObjectToPack> tmp = findAllFromPack(pack, objects, skipFound);
-			if (tmp.isEmpty())
+			List<DfsObjectToPack> inPack = pack.findAllFromPack(this, objects, skipFound);
+			if (inPack.isEmpty())
 				continue;
-			Collections.sort(tmp, OFFSET_SORT);
-			PackReverseIndex rev = pack.getReverseIdx(this);
 			DfsObjectRepresentation rep = new DfsObjectRepresentation(pack);
-			for (DfsObjectToPack otp : tmp) {
-				pack.representation(rep, otp.getOffset(), this, rev);
+			for (DfsObjectToPack otp : inPack) {
+				// Populate rep.{offset,length} from the pack
+				pack.fillRepresentation(rep, otp.getOffset(), this);
 				otp.setOffset(0);
-				packer.select(otp, rep);
+				packer.select(otp, rep); // Set otp.offset from rep
 				if (!otp.isFound()) {
 					otp.setFound();
 					monitor.update(1);
@@ -698,24 +690,7 @@ private static boolean checkGarbagePacks(Iterable<ObjectToPack> objects) {
 		return false;
 	}
 
-	private List<DfsObjectToPack> findAllFromPack(DfsPackFile pack,
-			Iterable<ObjectToPack> objects, boolean skipFound)
-					throws IOException {
-		List<DfsObjectToPack> tmp = new BlockList<>();
-		PackIndex idx = pack.getPackIndex(this);
-		for (ObjectToPack obj : objects) {
-			DfsObjectToPack otp = (DfsObjectToPack) obj;
-			if (skipFound && otp.isFound()) {
-				continue;
-			}
-			long p = idx.findOffset(otp);
-			if (0 < p && !pack.isCorrupt(p)) {
-				otp.setOffset(p);
-				tmp.add(otp);
-			}
-		}
-		return tmp;
-	}
+
 
 	@Override
 	public void copyObjectAsIs(PackOutputStream out, ObjectToPack otp,
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/FileReftableDatabase.java b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/FileReftableDatabase.java
index d5a060f..64f8c9b 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/FileReftableDatabase.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/FileReftableDatabase.java
@@ -24,7 +24,6 @@
 import java.util.Map;
 import java.util.Set;
 import java.util.TreeSet;
-import java.util.concurrent.atomic.AtomicBoolean;
 import java.util.concurrent.locks.Lock;
 import java.util.concurrent.locks.ReentrantLock;
 import java.util.stream.Collectors;
@@ -73,19 +72,14 @@ public class FileReftableDatabase extends RefDatabase {
 
 	private final FileReftableStack reftableStack;
 
-	private final AtomicBoolean autoRefresh;
+	private volatile boolean autoRefresh;
 
 	FileReftableDatabase(FileRepository repo) throws IOException {
-		this(repo, new File(new File(repo.getCommonDirectory(), Constants.REFTABLE),
-				Constants.TABLES_LIST));
-	}
-
-	FileReftableDatabase(FileRepository repo, File refstackName) throws IOException {
 		this.fileRepository = repo;
-		this.autoRefresh = new AtomicBoolean(repo.getConfig().getBoolean(
+		this.autoRefresh = repo.getConfig().getBoolean(
 				ConfigConstants.CONFIG_REFTABLE_SECTION,
-				ConfigConstants.CONFIG_KEY_AUTOREFRESH, false));
-		this.reftableStack = new FileReftableStack(refstackName,
+				ConfigConstants.CONFIG_KEY_AUTOREFRESH, false);
+		this.reftableStack = new FileReftableStack(
 				new File(fileRepository.getCommonDirectory(), Constants.REFTABLE),
 			() -> fileRepository.fireEvent(new RefsChangedEvent()),
 			() -> fileRepository.getConfig());
@@ -242,7 +236,7 @@ public Ref peel(Ref ref) throws IOException {
 	 *            date.
 	 */
 	public void setAutoRefresh(boolean autoRefresh) {
-		this.autoRefresh.set(autoRefresh);
+		this.autoRefresh = autoRefresh;
 	}
 
 	/**
@@ -252,11 +246,11 @@ public void setAutoRefresh(boolean autoRefresh) {
 	 *         date.
 	 */
 	public boolean isAutoRefresh() {
-		return autoRefresh.get();
+		return autoRefresh;
 	}
 
 	private void autoRefresh() {
-		if (autoRefresh.get()) {
+		if (autoRefresh) {
 			refresh();
 		}
 	}
@@ -690,32 +684,20 @@ private static Ref refForWrite(RevWalk rw, Ref r) throws IOException {
 	 *            the repository
 	 * @param writeLogs
 	 *            whether to write reflogs
-	 * @return a reftable based RefDB from an existing repository.
 	 * @throws IOException
 	 *             on IO error
 	 */
-	public static FileReftableDatabase convertFrom(FileRepository repo,
-			boolean writeLogs) throws IOException {
-		FileReftableDatabase newDb = null;
-		File reftableList = null;
-		try {
-			File reftableDir = new File(repo.getCommonDirectory(),
-					Constants.REFTABLE);
-			reftableList = new File(reftableDir, Constants.TABLES_LIST);
-			if (!reftableDir.isDirectory()) {
-				reftableDir.mkdir();
-			}
-
-			try (FileReftableStack stack = new FileReftableStack(reftableList,
-					reftableDir, null, () -> repo.getConfig())) {
-				stack.addReftable(rw -> writeConvertTable(repo, rw, writeLogs));
-			}
-			reftableList = null;
-		} finally {
-			if (reftableList != null) {
-				reftableList.delete();
-			}
+	public static void convertFrom(FileRepository repo, boolean writeLogs)
+			throws IOException {
+		File reftableDir = new File(repo.getCommonDirectory(),
+				Constants.REFTABLE);
+		if (!reftableDir.isDirectory()) {
+			reftableDir.mkdir();
 		}
-		return newDb;
+
+		try (FileReftableStack stack = new FileReftableStack(reftableDir, null,
+				() -> repo.getConfig())) {
+			stack.addReftable(rw -> writeConvertTable(repo, rw, writeLogs));
+		}
 	}
 }
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/FileReftableStack.java b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/FileReftableStack.java
index b2c8892..6658575 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/FileReftableStack.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/FileReftableStack.java
@@ -42,6 +42,7 @@
 import org.eclipse.jgit.internal.storage.reftable.ReftableReader;
 import org.eclipse.jgit.internal.storage.reftable.ReftableWriter;
 import org.eclipse.jgit.lib.Config;
+import org.eclipse.jgit.lib.Constants;
 import org.eclipse.jgit.lib.CoreConfig;
 import org.eclipse.jgit.lib.CoreConfig.TrustStat;
 import org.eclipse.jgit.util.FileUtils;
@@ -69,7 +70,7 @@ private static class StackEntry {
 
 	private long lastNextUpdateIndex;
 
-	private final File stackPath;
+	private final File tablesListFile;
 
 	private final File reftableDir;
 
@@ -111,8 +112,6 @@ static class CompactionStats {
 	/**
 	 * Creates a stack corresponding to the list of reftables in the argument
 	 *
-	 * @param stackPath
-	 *            the filename for the stack.
 	 * @param reftableDir
 	 *            the dir holding the tables.
 	 * @param onChange
@@ -122,10 +121,10 @@ static class CompactionStats {
 	 * @throws IOException
 	 *             on I/O problems
 	 */
-	public FileReftableStack(File stackPath, File reftableDir,
+	public FileReftableStack(File reftableDir,
 			@Nullable Runnable onChange, Supplier<Config> configSupplier)
 			throws IOException {
-		this.stackPath = stackPath;
+		this.tablesListFile = new File(reftableDir, Constants.TABLES_LIST);
 		this.reftableDir = reftableDir;
 		this.stack = new ArrayList<>();
 		this.configSupplier = configSupplier;
@@ -244,7 +243,7 @@ void reload() throws IOException {
 		}
 
 		if (!success) {
-			throw new LockFailedException(stackPath);
+			throw new LockFailedException(tablesListFile);
 		}
 
 		mergedReftable = new MergedReftable(stack.stream()
@@ -288,14 +287,14 @@ private List<String> readTableNames() throws IOException {
 		List<String> names = new ArrayList<>(stack.size() + 1);
 		old = snapshot.get();
 		try (BufferedReader br = new BufferedReader(
-				new InputStreamReader(new FileInputStream(stackPath), UTF_8))) {
+				new InputStreamReader(new FileInputStream(tablesListFile), UTF_8))) {
 			String line;
 			while ((line = br.readLine()) != null) {
 				if (!line.isEmpty()) {
 					names.add(line);
 				}
 			}
-			snapshot.compareAndSet(old, FileSnapshot.save(stackPath));
+			snapshot.compareAndSet(old, FileSnapshot.save(tablesListFile));
 		} catch (FileNotFoundException e) {
 			// file isn't there: empty repository.
 			snapshot.compareAndSet(old, FileSnapshot.MISSING_FILE);
@@ -315,15 +314,16 @@ boolean isUpToDate() throws IOException {
 				break;
 			case AFTER_OPEN:
 				try (InputStream stream = Files
-						.newInputStream(stackPath.toPath())) {
-					// open the tables.list file to refresh attributes (on some
-					// NFS clients)
+						.newInputStream(reftableDir.toPath())) {
+					// open the refs/reftable/ directory to refresh attributes
+					// of reftable files and the tables.list file listing their
+					// names (on some NFS clients)
 				} catch (FileNotFoundException | NoSuchFileException e) {
 					// ignore
 				}
 				//$FALL-THROUGH$
 			case ALWAYS:
-				if (!snapshot.get().isModified(stackPath)) {
+				if (!snapshot.get().isModified(tablesListFile)) {
 					return true;
 				}
 				break;
@@ -387,7 +387,7 @@ private String filename(long low, long high) {
 	 */
 	@SuppressWarnings("nls")
 	public boolean addReftable(Writer w) throws IOException {
-		LockFile lock = new LockFile(stackPath);
+		LockFile lock = new LockFile(tablesListFile);
 		try {
 			if (!lock.lockForAppend()) {
 				return false;
@@ -398,8 +398,7 @@ public boolean addReftable(Writer w) throws IOException {
 
 			String fn = filename(nextUpdateIndex(), nextUpdateIndex());
 
-			File tmpTable = File.createTempFile(fn + "_", ".ref",
-					stackPath.getParentFile());
+			File tmpTable = File.createTempFile(fn + "_", ".ref", reftableDir);
 
 			ReftableWriter.Stats s;
 			try (FileOutputStream fos = new FileOutputStream(tmpTable)) {
@@ -453,7 +452,7 @@ private File compactLocked(int first, int last) throws IOException {
 		String fn = filename(first, last);
 
 		File tmpTable = File.createTempFile(fn + "_", ".ref", //$NON-NLS-1$//$NON-NLS-2$
-				stackPath.getParentFile());
+				reftableDir);
 		try (FileOutputStream fos = new FileOutputStream(tmpTable)) {
 			ReftableCompactor c = new ReftableCompactor(fos)
 					.setConfig(reftableConfig())
@@ -497,7 +496,7 @@ boolean compactRange(int first, int last) throws IOException {
 		if (first >= last) {
 			return true;
 		}
-		LockFile lock = new LockFile(stackPath);
+		LockFile lock = new LockFile(tablesListFile);
 
 		File tmpTable = null;
 		List<LockFile> subtableLocks = new ArrayList<>();
@@ -526,7 +525,7 @@ boolean compactRange(int first, int last) throws IOException {
 
 			tmpTable = compactLocked(first, last);
 
-			lock = new LockFile(stackPath);
+			lock = new LockFile(tablesListFile);
 			if (!lock.lock()) {
 				return false;
 			}
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/GC.java b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/GC.java
index 05bd970..c08a92e 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/GC.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/GC.java
@@ -104,6 +104,7 @@
 import org.eclipse.jgit.util.FileUtils;
 import org.eclipse.jgit.util.GitTimeParser;
 import org.eclipse.jgit.util.StringUtils;
+import org.eclipse.jgit.util.SystemReader;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -182,7 +183,7 @@ public static void setExecutor(ExecutorService e) {
 	 * prune() to inspect only those reflog entries which have been added since
 	 * last repack().
 	 */
-	private long lastRepackTime;
+	private Instant lastRepackTime;
 
 	/**
 	 * Whether gc should do automatic housekeeping
@@ -805,7 +806,7 @@ private static boolean equals(Ref r1, Ref r2) {
 	public Collection<Pack> repack() throws IOException {
 		Collection<Pack> toBeDeleted = repo.getObjectDatabase().getPacks();
 
-		long time = System.currentTimeMillis();
+		Instant time = SystemReader.getInstance().now();
 		Collection<Ref> refsBefore = getAllRefs();
 
 		Set<ObjectId> allHeadsAndTags = new HashSet<>();
@@ -821,7 +822,7 @@ public Collection<Pack> repack() throws IOException {
 
 		for (Ref ref : refsBefore) {
 			checkCancelled();
-			nonHeads.addAll(listRefLogObjects(ref, 0));
+			nonHeads.addAll(listRefLogObjects(ref, Instant.EPOCH));
 			if (ref.isSymbolic() || ref.getObjectId() == null) {
 				continue;
 			}
@@ -1151,12 +1152,13 @@ private void deleteTempPacksIdx() {
 	 * @param ref
 	 *            the ref which log should be inspected
 	 * @param minTime
-	 *            only reflog entries not older then this time are processed
+	 *            only reflog entries equal or younger than this time are
+	 *            processed
 	 * @return the {@link ObjectId}s contained in the reflog
 	 * @throws IOException
 	 *             if an IO error occurred
 	 */
-	private Set<ObjectId> listRefLogObjects(Ref ref, long minTime) throws IOException {
+	private Set<ObjectId> listRefLogObjects(Ref ref, Instant minTime) throws IOException {
 		ReflogReader reflogReader = repo.getRefDatabase().getReflogReader(ref);
 		List<ReflogEntry> rlEntries = reflogReader
 				.getReverseEntries();
@@ -1164,8 +1166,9 @@ private Set<ObjectId> listRefLogObjects(Ref ref, long minTime) throws IOExceptio
 			return Collections.emptySet();
 		Set<ObjectId> ret = new HashSet<>();
 		for (ReflogEntry e : rlEntries) {
-			if (e.getWho().getWhen().getTime() < minTime)
+			if (e.getWho().getWhenAsInstant().isBefore(minTime)) {
 				break;
+			}
 			ObjectId newId = e.getNewId();
 			if (newId != null && !ObjectId.zeroId().equals(newId))
 				ret.add(newId);
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/PackFile.java b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/PackFile.java
index c9b05ad..5f2015b 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/PackFile.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/PackFile.java
@@ -185,7 +185,11 @@ private static String getExtPrefix(boolean isPreserved) {
 
 	private static PackExt getPackExt(String endsWithExtension) {
 		for (PackExt ext : PackExt.values()) {
-			if (endsWithExtension.endsWith(ext.getExtension())) {
+			if (endsWithExtension.equals(ext.getExtension())) {
+				return ext;
+			}
+
+			if (endsWithExtension.equals("old-" + ext.getExtension())) {
 				return ext;
 			}
 		}
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/midx/MultiPackIndex.java b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/midx/MultiPackIndex.java
new file mode 100644
index 0000000..15b5239
--- /dev/null
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/midx/MultiPackIndex.java
@@ -0,0 +1,103 @@
+/*
+ * Copyright (C) 2024, GerritForge Inc. and others
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Distribution License v. 1.0 which is available at
+ * https://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+package org.eclipse.jgit.internal.storage.midx;
+
+import java.util.Set;
+
+import org.eclipse.jgit.lib.AbbreviatedObjectId;
+import org.eclipse.jgit.lib.AnyObjectId;
+import org.eclipse.jgit.lib.ObjectId;
+
+/**
+ * An index over multiple packs
+ */
+public interface MultiPackIndex {
+
+	/**
+	 * Obtain the array of packfiles in the MultiPackIndex.
+	 * <p>
+	 * The pack ids correspond to positions in this list.
+	 *
+	 * @return array of packnames refered in this multipak index
+	 */
+	String[] getPackNames();
+
+	/**
+	 * Does this index contains the object
+	 *
+	 * @param oid
+	 *            object id
+	 * @return true of the index knows this the object
+	 */
+	boolean hasObject(AnyObjectId oid);
+
+	/**
+	 * Obtain the location of the object.
+	 * <p>
+	 * The returned object can be reused by the implementations. Callers
+	 * must create a #copy() if they want to keep a reference.
+	 *
+	 * @param objectId
+	 *            objectId to read.
+	 * @return mutable instance with the location or null if not found.
+	 */
+	PackOffset find(AnyObjectId objectId);
+
+	/**
+	 * Find objects matching the prefix abbreviation.
+	 *
+	 * @param matches
+	 *            set to add any located ObjectIds to. This is an output
+	 *            parameter.
+	 * @param id
+	 *            prefix to search for.
+	 * @param matchLimit
+	 *            maximum number of results to return. At most this many
+	 *            ObjectIds should be added to matches before returning.
+	 */
+	void resolve(Set<ObjectId> matches, AbbreviatedObjectId id, int matchLimit);
+
+	/**
+	 * Memory size of this multipack index
+	 *
+	 * @return size of this multipack index in memory, in bytes
+	 */
+	long getMemorySize();
+
+	/**
+	 * (packId, offset) coordinates of an object
+	 */
+	class PackOffset {
+
+		int packId;
+
+		long offset;
+
+		protected PackOffset setValues(int packId, long offset) {
+			this.packId = packId;
+			this.offset = offset;
+			return this;
+		}
+
+		public int getPackId() {
+			return packId;
+		}
+
+		public long getOffset() {
+			return offset;
+		}
+
+		public PackOffset copy() {
+			PackOffset copy = new PackOffset();
+			return copy.setValues(this.packId, this.offset);
+		}
+	}
+}
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/midx/MultiPackIndexConstants.java b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/midx/MultiPackIndexConstants.java
index 6122a9a..5d86f44 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/midx/MultiPackIndexConstants.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/midx/MultiPackIndexConstants.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2025, Google Inc.
+ * Copyright (C) 2025, Google LLC
  *
  * This program and the accompanying materials are made available under the
  * terms of the Eclipse Distribution License v. 1.0 which is available at
@@ -50,6 +50,9 @@ class MultiPackIndexConstants {
 	/** "RIDX" chunk */
 	static final int MIDX_CHUNKID_REVINDEX = 0x52494458;
 
+	/** "BTMP" chunk */
+	static final int MIDX_CHUNKID_BITMAPPEDPACKS = 0x42544D50;
+
 	private MultiPackIndexConstants() {
 	}
 }
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/midx/MultiPackIndexLoader.java b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/midx/MultiPackIndexLoader.java
new file mode 100644
index 0000000..0e51e90
--- /dev/null
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/midx/MultiPackIndexLoader.java
@@ -0,0 +1,350 @@
+/*
+ * Copyright (C) 2024, GerritForge Inc. and others
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Distribution License v. 1.0 which is available at
+ * https://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+package org.eclipse.jgit.internal.storage.midx;
+
+import static java.nio.charset.StandardCharsets.UTF_8;
+import static org.eclipse.jgit.internal.storage.midx.MultiPackIndexConstants.CHUNK_LOOKUP_WIDTH;
+import static org.eclipse.jgit.internal.storage.midx.MultiPackIndexConstants.MIDX_CHUNKID_BITMAPPEDPACKS;
+import static org.eclipse.jgit.internal.storage.midx.MultiPackIndexConstants.MIDX_CHUNKID_LARGEOFFSETS;
+import static org.eclipse.jgit.internal.storage.midx.MultiPackIndexConstants.MIDX_CHUNKID_OBJECTOFFSETS;
+import static org.eclipse.jgit.internal.storage.midx.MultiPackIndexConstants.MIDX_CHUNKID_OIDFANOUT;
+import static org.eclipse.jgit.internal.storage.midx.MultiPackIndexConstants.MIDX_CHUNKID_OIDLOOKUP;
+import static org.eclipse.jgit.internal.storage.midx.MultiPackIndexConstants.MIDX_CHUNKID_PACKNAMES;
+import static org.eclipse.jgit.internal.storage.midx.MultiPackIndexConstants.MIDX_CHUNKID_REVINDEX;
+import static org.eclipse.jgit.internal.storage.midx.MultiPackIndexConstants.MIDX_SIGNATURE;
+import static org.eclipse.jgit.lib.Constants.OBJECT_ID_LENGTH;
+
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.io.InputStream;
+import java.text.MessageFormat;
+import java.util.ArrayList;
+import java.util.List;
+
+import org.eclipse.jgit.internal.JGitText;
+import org.eclipse.jgit.util.IO;
+import org.eclipse.jgit.util.NB;
+import org.eclipse.jgit.util.io.SilentFileInputStream;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * The loader returns the representation of the MultiPackIndex file content.
+ */
+public class MultiPackIndexLoader {
+	private final static Logger LOG = LoggerFactory
+			.getLogger(MultiPackIndexLoader.class);
+
+	/**
+	 * Open an existing MultiPackIndex file for reading.
+	 * <p>
+	 * The format of the file will be automatically detected and a proper access
+	 * implementation for that format will be constructed and returned to the
+	 * caller. The file may or may not be held open by the returned instance.
+	 *
+	 * @param midxFile
+	 *            existing multi-pack-index to read.
+	 * @return a copy of the multi-pack-index file in memory
+	 * @throws FileNotFoundException
+	 *             the file does not exist.
+	 * @throws MultiPackIndexFormatException
+	 *             MultiPackIndex file's format is different from we expected.
+	 * @throws java.io.IOException
+	 *             the file exists but could not be read due to security errors
+	 *             or unexpected data corruption.
+	 */
+	public static MultiPackIndex open(File midxFile)
+			throws FileNotFoundException, MultiPackIndexFormatException,
+			IOException {
+		try (SilentFileInputStream fd = new SilentFileInputStream(midxFile)) {
+			try {
+				return read(fd);
+			} catch (MultiPackIndexFormatException fe) {
+				throw fe;
+			} catch (IOException ioe) {
+				throw new IOException(
+						MessageFormat.format(JGitText.get().unreadableMIDX,
+								midxFile.getAbsolutePath()),
+						ioe);
+			}
+		}
+	}
+
+	/**
+	 * Read an existing MultiPackIndex file from a buffered stream.
+	 * <p>
+	 * The format of the file will be automatically detected and a proper access
+	 * implementation for that format will be constructed and returned to the
+	 * caller. The file may or may not be held open by the returned instance.
+	 *
+	 * @param fd
+	 *            stream to read the multipack-index file from. The stream must be
+	 *            buffered as some small IOs are performed against the stream.
+	 *            The caller is responsible for closing the stream.
+	 * @return a copy of the MultiPackIndex file in memory
+	 * @throws MultiPackIndexFormatException
+	 *             the MultiPackIndex file's format is different from we
+	 *             expected.
+	 * @throws java.io.IOException
+	 *             the stream cannot be read.
+	 */
+	public static MultiPackIndex read(InputStream fd)
+			throws MultiPackIndexFormatException, IOException {
+		byte[] hdr = new byte[12];
+		IO.readFully(fd, hdr, 0, hdr.length);
+
+		int magic = NB.decodeInt32(hdr, 0);
+
+		if (magic != MIDX_SIGNATURE) {
+			throw new MultiPackIndexFormatException(JGitText.get().notAMIDX);
+		}
+
+		// Check MultiPackIndex version
+		int v = hdr[4];
+		if (v != 1) {
+			throw new MultiPackIndexFormatException(MessageFormat
+					.format(JGitText.get().unsupportedMIDXVersion, v));
+		}
+
+		// Read the object Id version (1 byte)
+		// 1 => SHA-1
+		// 2 => SHA-256
+		// TODO: If the hash type does not match the repository's hash
+		// algorithm,
+		// the multi-pack-index file should be ignored with a warning
+		// presented to the user.
+		int commitIdVersion = hdr[5];
+		if (commitIdVersion != 1) {
+			throw new MultiPackIndexFormatException(
+					JGitText.get().incorrectOBJECT_ID_LENGTH);
+		}
+
+		// Read the number of "chunkOffsets" (1 byte)
+		int chunkCount = hdr[6];
+
+		// Read the number of multi-pack-index files (1 byte)
+		// This value is currently always zero.
+		// TODO populate this
+		// int numberOfMultiPackIndexFiles = hdr[7];
+
+		// Number of packfiles (4 bytes)
+		int packCount = NB.decodeInt32(hdr, 8);
+
+		byte[] lookupBuffer = new byte[CHUNK_LOOKUP_WIDTH * (chunkCount + 1)];
+
+		IO.readFully(fd, lookupBuffer, 0, lookupBuffer.length);
+
+		List<ChunkSegment> chunks = new ArrayList<>(chunkCount + 1);
+		for (int i = 0; i <= chunkCount; i++) {
+			// chunks[chunkCount] is just a marker, in order to record the
+			// length of the last chunk.
+			int id = NB.decodeInt32(lookupBuffer, i * 12);
+			long offset = NB.decodeInt64(lookupBuffer, i * 12 + 4);
+			chunks.add(new ChunkSegment(id, offset));
+		}
+
+		MultiPackIndexBuilder builder = MultiPackIndexBuilder.builder();
+		builder.setPackCount(packCount);
+		for (int i = 0; i < chunkCount; i++) {
+			long chunkOffset = chunks.get(i).offset;
+			int chunkId = chunks.get(i).id;
+			long len = chunks.get(i + 1).offset - chunkOffset;
+
+			if (len > Integer.MAX_VALUE - 8) { // http://stackoverflow.com/a/8381338
+				throw new MultiPackIndexFormatException(
+						JGitText.get().multiPackIndexFileIsTooLargeForJgit);
+			}
+
+			byte[] buffer = new byte[(int) len];
+			IO.readFully(fd, buffer, 0, buffer.length);
+
+			switch (chunkId) {
+			case MIDX_CHUNKID_OIDFANOUT:
+				builder.addOidFanout(buffer);
+				break;
+			case MIDX_CHUNKID_OIDLOOKUP:
+				builder.addOidLookUp(buffer);
+				break;
+			case MIDX_CHUNKID_PACKNAMES:
+				builder.addPackNames(buffer);
+				break;
+			case MIDX_CHUNKID_BITMAPPEDPACKS:
+				builder.addBitmappedPacks(buffer);
+				break;
+			case MIDX_CHUNKID_OBJECTOFFSETS:
+				builder.addObjectOffsets(buffer);
+				break;
+			case MIDX_CHUNKID_LARGEOFFSETS:
+				builder.addObjectLargeOffsets(buffer);
+				break;
+			default:
+				LOG.warn(MessageFormat.format(JGitText.get().midxChunkUnknown,
+						Integer.toHexString(chunkId)));
+			}
+		}
+		return builder.build();
+	}
+
+	private record ChunkSegment(int id, long offset) {}
+
+	/**
+	 * Accumulate byte[] of the different chunks, to build a multipack index
+	 */
+	// Visible for testing
+	static class MultiPackIndexBuilder {
+
+		private final int hashLength;
+
+		private int packCount;
+
+		private byte[] oidFanout;
+
+		private byte[] oidLookup;
+
+		private String[] packNames;
+
+		private byte[] bitmappedPackfiles;
+
+		private byte[] objectOffsets;
+
+		// Optional
+		private byte[] largeObjectOffsets;
+
+		// Optional
+		private byte[] bitmapPackOrder;
+
+		private MultiPackIndexBuilder(int hashLength) {
+			this.hashLength = hashLength;
+		}
+
+		/**
+		 * Create builder
+		 *
+		 * @return A builder of {@link MultiPackIndex}.
+		 */
+		static MultiPackIndexBuilder builder() {
+			return new MultiPackIndexBuilder(OBJECT_ID_LENGTH);
+		}
+
+		MultiPackIndexBuilder setPackCount(int packCount) {
+			this.packCount = packCount;
+			return this;
+		}
+
+		MultiPackIndexBuilder addOidFanout(byte[] buffer)
+				throws MultiPackIndexFormatException {
+			assertChunkNotSeenYet(oidFanout, MIDX_CHUNKID_OIDFANOUT);
+			oidFanout = buffer;
+			return this;
+		}
+
+		MultiPackIndexBuilder addOidLookUp(byte[] buffer)
+				throws MultiPackIndexFormatException {
+			assertChunkNotSeenYet(oidLookup, MIDX_CHUNKID_OIDLOOKUP);
+			oidLookup = buffer;
+			return this;
+		}
+
+		MultiPackIndexBuilder addPackNames(byte[] buffer)
+				throws MultiPackIndexFormatException {
+			assertChunkNotSeenYet(packNames, MIDX_CHUNKID_PACKNAMES);
+			packNames = new String(buffer, UTF_8).split("\u0000");
+			return this;
+		}
+
+		MultiPackIndexBuilder addBitmappedPacks(byte[] buffer)
+				throws MultiPackIndexFormatException {
+			assertChunkNotSeenYet(bitmappedPackfiles,
+					MIDX_CHUNKID_BITMAPPEDPACKS);
+			bitmappedPackfiles = buffer;
+			return this;
+		}
+
+		MultiPackIndexBuilder addObjectOffsets(byte[] buffer)
+				throws MultiPackIndexFormatException {
+			assertChunkNotSeenYet(objectOffsets, MIDX_CHUNKID_OBJECTOFFSETS);
+			objectOffsets = buffer;
+			return this;
+		}
+
+		MultiPackIndexBuilder addObjectLargeOffsets(byte[] buffer)
+				throws MultiPackIndexFormatException {
+			assertChunkNotSeenYet(largeObjectOffsets,
+					MIDX_CHUNKID_LARGEOFFSETS);
+			largeObjectOffsets = buffer;
+			return this;
+		}
+
+		MultiPackIndexBuilder addReverseIndex(byte[] buffer)
+				throws MultiPackIndexFormatException {
+			assertChunkNotSeenYet(bitmapPackOrder, MIDX_CHUNKID_REVINDEX);
+			bitmapPackOrder = buffer;
+			return this;
+		}
+
+		MultiPackIndex build() throws MultiPackIndexFormatException {
+			assertChunkNotNull(oidFanout, MIDX_CHUNKID_OIDFANOUT);
+			assertChunkNotNull(oidLookup, MIDX_CHUNKID_OIDLOOKUP);
+			assertChunkNotNull(packNames, MIDX_CHUNKID_PACKNAMES);
+			assertChunkNotNull(objectOffsets, MIDX_CHUNKID_OBJECTOFFSETS);
+
+			assertPackCounts(packCount, packNames.length);
+			return new MultiPackIndexV1(hashLength, oidFanout, oidLookup,
+					packNames, bitmappedPackfiles, objectOffsets, largeObjectOffsets);
+		}
+
+		private static void assertChunkNotNull(Object object, int chunkId)
+				throws MultiPackIndexFormatException {
+			if (object == null) {
+				throw new MultiPackIndexFormatException(
+						MessageFormat.format(JGitText.get().midxChunkNeeded,
+								Integer.toHexString(chunkId)));
+			}
+		}
+
+		private static void assertChunkNotSeenYet(Object object, int chunkId)
+				throws MultiPackIndexFormatException {
+			if (object != null) {
+				throw new MultiPackIndexFormatException(
+						MessageFormat.format(JGitText.get().midxChunkRepeated,
+								Integer.toHexString(chunkId)));
+			}
+		}
+
+		private static void assertPackCounts(int headerCount,
+				int packfileNamesCount) throws MultiPackIndexFormatException {
+			if (headerCount != packfileNamesCount) {
+				throw new MultiPackIndexFormatException(MessageFormat.format(
+						JGitText.get().multiPackIndexPackCountMismatch,
+						headerCount, packfileNamesCount));
+			}
+		}
+	}
+
+	/**
+	 * Thrown when a MultiPackIndex file's format is different from we expected
+	 */
+	public static class MultiPackIndexFormatException extends IOException {
+
+		private static final long serialVersionUID = 1L;
+
+		/**
+		 * Construct an exception.
+		 *
+		 * @param why
+		 *            description of the type of error.
+		 */
+		MultiPackIndexFormatException(String why) {
+			super(why);
+		}
+	}
+}
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/midx/MultiPackIndexPrettyPrinter.java b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/midx/MultiPackIndexPrettyPrinter.java
index 795d39e..948b7bc 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/midx/MultiPackIndexPrettyPrinter.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/midx/MultiPackIndexPrettyPrinter.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2025, Google Inc.
+ * Copyright (C) 2025, Google LLC
  *
  * This program and the accompanying materials are made available under the
  * terms of the Eclipse Distribution License v. 1.0 which is available at
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/midx/MultiPackIndexV1.java b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/midx/MultiPackIndexV1.java
new file mode 100644
index 0000000..be752cc
--- /dev/null
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/midx/MultiPackIndexV1.java
@@ -0,0 +1,289 @@
+/*
+ * Copyright (C) 2024, GerritForge Inc. and others
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Distribution License v. 1.0 which is available at
+ * https://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+package org.eclipse.jgit.internal.storage.midx;
+
+import java.nio.charset.StandardCharsets;
+import java.util.Arrays;
+import java.util.Set;
+
+import org.eclipse.jgit.annotations.NonNull;
+import org.eclipse.jgit.annotations.Nullable;
+import org.eclipse.jgit.internal.JGitText;
+import org.eclipse.jgit.internal.storage.midx.MultiPackIndexLoader.MultiPackIndexFormatException;
+import org.eclipse.jgit.lib.AbbreviatedObjectId;
+import org.eclipse.jgit.lib.AnyObjectId;
+import org.eclipse.jgit.lib.ObjectId;
+import org.eclipse.jgit.util.NB;
+
+/**
+ * Support for the MultiPackIndex v1 format.
+ *
+ * @see MultiPackIndex
+ */
+class MultiPackIndexV1 implements MultiPackIndex {
+
+	private final OidLookup idx;
+
+	private final String[] packNames;
+
+	private final byte[] bitmappedPackfiles;
+
+	private final OffsetLookup offsets;
+
+	private final PackOffset result = new PackOffset();
+
+	MultiPackIndexV1(int hashLength, @NonNull byte[] oidFanout,
+			@NonNull byte[] oidLookup, String[] packNames,
+			byte[] bitmappedPackfiles, byte[] objectOffsets,
+			byte[] largeObjectOffsets) throws MultiPackIndexFormatException {
+		this.bitmappedPackfiles = bitmappedPackfiles;
+		this.idx = new OidLookup(hashLength, oidFanout, oidLookup);
+		this.offsets = new OffsetLookup(objectOffsets, largeObjectOffsets);
+		this.packNames = packNames;
+	}
+
+	@Override
+	public String[] getPackNames() {
+		return packNames;
+	}
+
+	@Override
+	public boolean hasObject(AnyObjectId oid) {
+		return idx.findMultiPackIndexPosition(oid) != -1;
+	}
+
+	@Override
+	@Nullable
+	public PackOffset find(AnyObjectId objectId) {
+		int position = idx.findMultiPackIndexPosition(objectId);
+		if (position == -1) {
+			return null;
+		}
+		offsets.getObjectOffset(position, result);
+		return result;
+	}
+
+	@Override
+	public void resolve(Set<ObjectId> matches, AbbreviatedObjectId id,
+			int matchLimit) {
+		idx.resolve(matches, id, matchLimit);
+	}
+
+	@Override
+	public long getMemorySize() {
+		int packNamesSize = Arrays.stream(packNames)
+				.mapToInt(s -> s.getBytes(StandardCharsets.UTF_8).length).sum();
+		return packNamesSize + byteArrayLengh(bitmappedPackfiles)
+				+ idx.getMemorySize() + offsets.getMemorySize();
+	}
+
+	@Override
+	public String toString() {
+		return "MultiPackIndexV1 {idx=" + idx + ", packfileNames=" //$NON-NLS-1$ //$NON-NLS-2$
+				+ Arrays.toString(packNames) + ", bitmappedPackfiles=" //$NON-NLS-1$
+				+ byteArrayToString(bitmappedPackfiles) + ", objectOffsets=" //$NON-NLS-1$
+				+ offsets + '}';
+	}
+
+	private static String byteArrayToString(byte[] array) {
+		return array == null ? "null" : new String(array); //$NON-NLS-1$
+	}
+
+	private static int byteArrayLengh(byte[] array) {
+		return array == null ? 0 : array.length;
+	}
+
+	/**
+	 * Wraps the small and large offset chunks (if exists), to lookup offsets.
+	 */
+	private static class OffsetLookup {
+		private static final int OBJECT_OFFSETS_DATA_WIDTH = 8;
+
+		private static final int BIT_31_ON = 0x80000000;
+
+		private static final int TOGGLE_BIT_31 = 0x7fff_ffff;
+
+		private final byte[] offsets;
+
+		private final byte[] largeOffsets;
+
+		/**
+		 * Initialize the ObjectOffsets.
+		 *
+		 * @param offsets
+		 *            content of ObjectOffset Chunk.
+		 * @param largeOffsets
+		 *            content of largo offsets chunks (can be null).
+		 */
+		OffsetLookup(@NonNull byte[] offsets, byte[] largeOffsets) {
+			this.offsets = offsets;
+			this.largeOffsets = largeOffsets;
+		}
+
+		/**
+		 * Get the metadata of a commit。
+		 *
+		 * @param position
+		 *            the position in the multi-pack-index of the object.
+		 * @param result
+		 *            an instance of PackOffset to populate with the result.
+		 */
+		void getObjectOffset(int position, PackOffset result) {
+			int offsetInChunk = position * OBJECT_OFFSETS_DATA_WIDTH;
+			int packId = NB.decodeInt32(offsets, offsetInChunk);
+			int offset = NB.decodeInt32(offsets, offsetInChunk + 4);
+			if ((offset & BIT_31_ON) != 0) {
+				long bigOffset;
+				if (largeOffsets == null) {
+					bigOffset = NB.decodeUInt32(offsets, offsetInChunk + 4);
+				} else {
+					int bigOffsetPos = (offset & TOGGLE_BIT_31);
+					bigOffset = NB.decodeInt64(largeOffsets, bigOffsetPos * 8);
+				}
+				result.setValues(packId, bigOffset);
+				return;
+			}
+			result.setValues(packId, offset);
+		}
+
+		long getMemorySize() {
+			return (long) byteArrayLengh(offsets)
+					+ byteArrayLengh(largeOffsets);
+		}
+	}
+
+	/**
+	 * Combines the fanout and oid list chunks, to lookup Oids with an efficient
+	 * binary search
+	 */
+	private static class OidLookup {
+
+		private static final int FANOUT = 256;
+
+		private final int hashLength;
+
+		private final int[] fanoutTable;
+
+		private final byte[] oidLookup;
+
+		/**
+		 * Initialize the MultiPackIndexIndex.
+		 *
+		 * @param hashLength
+		 *            length of object hash.
+		 * @param oidFanout
+		 *            content of OID Fanout Chunk.
+		 * @param oidLookup
+		 *            content of OID Lookup Chunk.
+		 * @throws MultiPackIndexFormatException
+		 *             MultiPackIndex file's format is different from we
+		 *             expected.
+		 */
+		OidLookup(int hashLength, @NonNull byte[] oidFanout,
+				@NonNull byte[] oidLookup)
+				throws MultiPackIndexFormatException {
+			this.hashLength = hashLength;
+			this.oidLookup = oidLookup;
+
+			int[] table = new int[FANOUT];
+			long uint32;
+			for (int k = 0; k < table.length; k++) {
+				uint32 = NB.decodeUInt32(oidFanout, k * 4);
+				if (uint32 > Integer.MAX_VALUE) {
+					throw new MultiPackIndexFormatException(
+							JGitText.get().multiPackIndexFileIsTooLargeForJgit);
+				}
+				table[k] = (int) uint32;
+			}
+			this.fanoutTable = table;
+		}
+
+		/**
+		 * Find the position in the MultiPackIndex file of the specified id.
+		 *
+		 * @param id
+		 *            the id for which the multi-pack-index position will be
+		 *            found.
+		 * @return the MultiPackIndex position or -1 if the object was not
+		 *         found.
+		 */
+		int findMultiPackIndexPosition(AnyObjectId id) {
+			int levelOne = id.getFirstByte();
+			int high = fanoutTable[levelOne];
+			int low = 0;
+			if (levelOne > 0) {
+				low = fanoutTable[levelOne - 1];
+			}
+			while (low < high) {
+				int mid = (low + high) >>> 1;
+				int cmp = id.compareTo(oidLookup, hashLength * mid);
+				if (cmp < 0) {
+					high = mid;
+				} else if (cmp == 0) {
+					return mid;
+				} else {
+					low = mid + 1;
+				}
+			}
+			return -1;
+		}
+
+		void resolve(Set<ObjectId> matches, AbbreviatedObjectId id,
+				int matchLimit) {
+			if (matches.size() >= matchLimit) {
+				return;
+			}
+
+			if (oidLookup.length == 0) {
+				return;
+			}
+
+			int high = fanoutTable[id.getFirstByte()];
+			int low = id.getFirstByte() == 0 ? 0
+					: fanoutTable[id.getFirstByte() - 1];
+			do {
+				int p = (low + high) >>> 1;
+				int cmp = id.prefixCompare(oidLookup, idOffset(p));
+				if (cmp < 0) {
+					high = p;
+					continue;
+				}
+
+				if (cmp > 0) {
+					low = p + 1;
+					continue;
+				}
+
+				// Got a match.
+				// We may have landed in the middle of the matches. Move
+				// backwards to the start of matches, then walk forwards.
+				while (0 < p
+						&& id.prefixCompare(oidLookup, idOffset(p - 1)) == 0) {
+					p--;
+				}
+				while (p < high && id.prefixCompare(oidLookup, idOffset(p)) == 0
+						&& matches.size() < matchLimit) {
+					matches.add(ObjectId.fromRaw(oidLookup, idOffset(p)));
+					p++;
+				}
+				return;
+			} while (low < high);
+		}
+
+		private int idOffset(int position) {
+			return position * hashLength;
+		}
+
+		long getMemorySize() {
+			return 4L + byteArrayLengh(oidLookup) + (FANOUT * 4);
+		}
+	}
+}
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/midx/MultiPackIndexWriter.java b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/midx/MultiPackIndexWriter.java
index bddf3ac..b42c821 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/midx/MultiPackIndexWriter.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/midx/MultiPackIndexWriter.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2025, Google Inc.
+ * Copyright (C) 2025, Google LLC
  *
  * This program and the accompanying materials are made available under the
  * terms of the Eclipse Distribution License v. 1.0 which is available at
@@ -65,10 +65,11 @@ public class MultiPackIndexWriter {
 	 * @param inputs
 	 *            pairs of name and index for each pack to include in the
 	 *            multipack index.
+	 * @return bytes written into the stream
 	 * @throws IOException
 	 *             Error writing to the stream
 	 */
-	public void write(ProgressMonitor monitor, OutputStream outputStream,
+	public long write(ProgressMonitor monitor, OutputStream outputStream,
 			Map<String, PackIndex> inputs) throws IOException {
 		PackIndexMerger data = new PackIndexMerger(inputs);
 
@@ -91,6 +92,7 @@ public void write(ProgressMonitor monitor, OutputStream outputStream,
 						Long.valueOf(expectedSize),
 						Long.valueOf(out.length())));
 			}
+			return expectedSize;
 		} catch (InterruptedIOException e) {
 			throw new IOException(JGitText.get().multiPackIndexWritingCancelled,
 					e);
@@ -297,7 +299,7 @@ private void writeRidx(WriteContext ctx) throws IOException {
 		for (int i = 0; i < ctx.data.getPackCount(); i++) {
 			List<OffsetPosition> offsetsForPack = packOffsets
 					.get(Integer.valueOf(i));
-			if (offsetsForPack.isEmpty()) {
+			if (offsetsForPack == null) {
 				continue;
 			}
 			offsetsForPack.sort(Comparator.comparing(OffsetPosition::offset));
@@ -358,7 +360,6 @@ private void writeCheckSum(CancellableDigestOutputStream out)
 		out.flush();
 	}
 
-
 	private record OffsetPosition(long offset, int position) {
 	}
 
@@ -367,7 +368,8 @@ private record OffsetPosition(long offset, int position) {
 	 * offset chunk must exist, and offsets larger than 2^31-1 must be stored in
 	 * it instead
 	 *
-	 * @param offset object offset
+	 * @param offset
+	 *            object offset
 	 *
 	 * @return true if the offset fits in 31 bits
 	 */
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/midx/PackIndexMerger.java b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/midx/PackIndexMerger.java
index 89814af..f236658 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/midx/PackIndexMerger.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/midx/PackIndexMerger.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2025, Google Inc.
+ * Copyright (C) 2025, Google LLC
  *
  * This program and the accompanying materials are made available under the
  * terms of the Eclipse Distribution License v. 1.0 which is available at
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/pack/PackExt.java b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/pack/PackExt.java
index e6daaea..d5bb5f2 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/pack/PackExt.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/pack/PackExt.java
@@ -36,7 +36,10 @@ public enum PackExt {
 	COMMIT_GRAPH("graph"), //$NON-NLS-1$
 
 	/** An object size index. */
-	OBJECT_SIZE_INDEX("objsize"); //$NON-NLS-1$
+	OBJECT_SIZE_INDEX("objsize"), //$NON-NLS-1$
+
+	/** Multi pack index */
+	MULTI_PACK_INDEX("midx"); //$NON-NLS-1$
 
 	private final String ext;
 
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/reftable/BlockWriter.java b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/reftable/BlockWriter.java
index c70f2e4..0ddfa57 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/reftable/BlockWriter.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/reftable/BlockWriter.java
@@ -524,8 +524,8 @@ static class LogEntry extends Entry {
 
 			this.oldId = oldId;
 			this.newId = newId;
-			this.timeSecs = who.getWhen().getTime() / 1000L;
-			this.tz = (short) who.getTimeZoneOffset();
+			this.timeSecs = who.getWhenAsInstant().getEpochSecond();
+			this.tz = (short) (who.getZoneOffset().getTotalSeconds() / 60);
 			this.name = who.getName().getBytes(UTF_8);
 			this.email = who.getEmailAddress().getBytes(UTF_8);
 			this.msg = message.getBytes(UTF_8);
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/reftable/ReftableCompactor.java b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/reftable/ReftableCompactor.java
index 3c4bc75..7e5f4eb 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/reftable/ReftableCompactor.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/reftable/ReftableCompactor.java
@@ -12,6 +12,7 @@
 
 import java.io.IOException;
 import java.io.OutputStream;
+import java.time.Instant;
 import java.util.ArrayDeque;
 import java.util.ArrayList;
 import java.util.List;
@@ -28,20 +29,26 @@
  * to shadow any lower reftable that may have the reference present.
  * <p>
  * By default all log entries within the range defined by
- * {@link #setReflogExpireMinUpdateIndex(long)} and {@link #setReflogExpireMaxUpdateIndex(long)} are
- * copied, even if no references in the output file match the log records.
- * Callers may truncate the log to a more recent time horizon with
- * {@link #setReflogExpireOldestReflogTimeMillis(long)}, or disable the log altogether with
- * {@code setOldestReflogTimeMillis(Long.MAX_VALUE)}.
+ * {@link #setReflogExpireMinUpdateIndex(long)} and
+ * {@link #setReflogExpireMaxUpdateIndex(long)} are copied, even if no
+ * references in the output file match the log records. Callers may truncate the
+ * log to a more recent time horizon with
+ * {@link #setReflogExpireOlderThan(Instant)}, or disable the log
+ * altogether with {@code setReflogExpireOldestReflogTime(Instant.MAX)}.
  */
 public class ReftableCompactor {
 	private final ReftableWriter writer;
+
 	private final ArrayDeque<ReftableReader> tables = new ArrayDeque<>();
 
 	private boolean includeDeletes;
+
 	private long reflogExpireMinUpdateIndex = 0;
+
 	private long reflogExpireMaxUpdateIndex = Long.MAX_VALUE;
-	private long reflogExpireOldestReflogTimeMillis;
+
+	private Instant reflogExpireOldestReflogTime = Instant.EPOCH;
+
 	private Stats stats;
 
 	/**
@@ -122,9 +129,29 @@ public ReftableCompactor setReflogExpireMaxUpdateIndex(long max) {
 	 *            entries that predate {@code timeMillis} will be discarded.
 	 *            Specified in Java standard milliseconds since the epoch.
 	 * @return {@code this}
+	 *
+	 * @deprecated Use {@link #setReflogExpireOlderThan(Instant)} instead
 	 */
-	public ReftableCompactor setReflogExpireOldestReflogTimeMillis(long timeMillis) {
-		reflogExpireOldestReflogTimeMillis = timeMillis;
+	@Deprecated(since="7.3")
+	public ReftableCompactor setReflogExpireOldestReflogTimeMillis(
+			long timeMillis) {
+		return setReflogExpireOlderThan(timeMillis == Long.MAX_VALUE
+				? Instant.MAX
+				: Instant.ofEpochMilli(timeMillis));
+	}
+
+	/**
+	 * Set oldest reflog time to preserve.
+	 *
+	 * @param cutTime
+	 *            oldest log time to preserve. Entries whose timestamps are
+	 *            {@code >= cutTime} will be copied into the output file. Log
+	 *            entries that predate {@code cutTime} will be discarded.
+	 * @return {@code this}
+	 */
+	public ReftableCompactor setReflogExpireOlderThan(
+			Instant cutTime) {
+		reflogExpireOldestReflogTime = cutTime;
 		return this;
 	}
 
@@ -182,14 +209,15 @@ private void mergeRefs(MergedReftable mr) throws IOException {
 	}
 
 	private void mergeLogs(MergedReftable mr) throws IOException {
-		if (reflogExpireOldestReflogTimeMillis == Long.MAX_VALUE) {
+		if (reflogExpireOldestReflogTime == Instant.MAX) {
 			return;
 		}
 
 		try (LogCursor lc = mr.allLogs()) {
 			while (lc.next()) {
 				long updateIndex = lc.getUpdateIndex();
-				if (updateIndex > reflogExpireMaxUpdateIndex || updateIndex < reflogExpireMinUpdateIndex) {
+				if (updateIndex > reflogExpireMaxUpdateIndex
+						|| updateIndex < reflogExpireMinUpdateIndex) {
 					continue;
 				}
 
@@ -203,14 +231,9 @@ private void mergeLogs(MergedReftable mr) throws IOException {
 				}
 
 				PersonIdent who = log.getWho();
-				if (who.getWhen().getTime() >= reflogExpireOldestReflogTimeMillis) {
-					writer.writeLog(
-							refName,
-							updateIndex,
-							who,
-							log.getOldId(),
-							log.getNewId(),
-							log.getComment());
+				if (who.getWhenAsInstant().compareTo(reflogExpireOldestReflogTime) >= 0) {
+					writer.writeLog(refName, updateIndex, who, log.getOldId(),
+							log.getNewId(), log.getComment());
 				}
 			}
 		}
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/lib/Constants.java b/org.eclipse.jgit/src/org/eclipse/jgit/lib/Constants.java
index 997f4ed..9de8392 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/lib/Constants.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/lib/Constants.java
@@ -345,6 +345,15 @@ public final class Constants {
 	public static final String XDG_CONFIG_HOME = "XDG_CONFIG_HOME";
 
 	/**
+	 * The key of the XDG_CACHE_HOME directory defined in the
+	 * <a href="https://wiki.archlinux.org/index.php/XDG_Base_Directory">
+	 * XDG Base Directory specification</a>.
+	 *
+	 * @since 7.3
+	 */
+	public static final String XDG_CACHE_HOME = "XDG_CACHE_HOME";
+
+	/**
 	 * The environment variable that limits how close to the root of the file
 	 * systems JGit will traverse when looking for a repository root.
 	 */
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/revplot/PlotWalk.java b/org.eclipse.jgit/src/org/eclipse/jgit/revplot/PlotWalk.java
index 0f6bd2d..c8c454a 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/revplot/PlotWalk.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/revplot/PlotWalk.java
@@ -169,8 +169,9 @@ public int compare(Ref o1, Ref o2) {
 		}
 
 		long timeof(RevObject o) {
-			if (o instanceof RevCommit)
-				return ((RevCommit) o).getCommitTime();
+			if (o instanceof RevCommit) {
+				return ((RevCommit) o).getCommitTime() * 1000L;
+			}
 			if (o instanceof RevTag) {
 				RevTag tag = (RevTag) o;
 				try {
@@ -179,7 +180,7 @@ long timeof(RevObject o) {
 					return 0;
 				}
 				PersonIdent who = tag.getTaggerIdent();
-				return who != null ? who.getWhen().getTime() : 0;
+				return who != null ? who.getWhenAsInstant().toEpochMilli() : 0;
 			}
 			return 0;
 		}
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/FollowFilter.java b/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/FollowFilter.java
index 35ef51f..12e6c4e 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/FollowFilter.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/FollowFilter.java
@@ -18,7 +18,7 @@
 import org.eclipse.jgit.errors.IncorrectObjectTypeException;
 import org.eclipse.jgit.errors.MissingObjectException;
 import org.eclipse.jgit.treewalk.TreeWalk;
-import org.eclipse.jgit.treewalk.filter.PathFilter;
+import org.eclipse.jgit.treewalk.filter.ChangedPathTreeFilter;
 import org.eclipse.jgit.treewalk.filter.TreeFilter;
 
 /**
@@ -56,39 +56,44 @@ public class FollowFilter extends TreeFilter {
 	 * @since 3.0
 	 */
 	public static FollowFilter create(String path, DiffConfig cfg) {
-		return new FollowFilter(PathFilter.create(path), cfg);
+		return new FollowFilter(ChangedPathTreeFilter.create(path), cfg);
 	}
 
-	private final PathFilter path;
+	private final ChangedPathTreeFilter path;
 	final DiffConfig cfg;
 
 	private RenameCallback renameCallback;
 
-	FollowFilter(PathFilter path, DiffConfig cfg) {
+	FollowFilter(ChangedPathTreeFilter path, DiffConfig cfg) {
 		this.path = path;
 		this.cfg = cfg;
 	}
 
-	/** @return the path this filter matches. */
 	/**
 	 * Get the path this filter matches.
 	 *
 	 * @return the path this filter matches.
 	 */
 	public String getPath() {
-		return path.getPath();
+		return path.getPaths().get(0);
 	}
 
 	@Override
 	public boolean include(TreeWalk walker)
 			throws MissingObjectException, IncorrectObjectTypeException,
 			IOException {
-		return path.include(walker) && ANY_DIFF.include(walker);
+		return path.include(walker);
+	}
+
+	@Override
+	public boolean shouldTreeWalk(RevCommit c, RevWalk rw,
+			MutableBoolean cpfUsed) {
+		return path.shouldTreeWalk(c, rw, cpfUsed);
 	}
 
 	@Override
 	public boolean shouldBeRecursive() {
-		return path.shouldBeRecursive() || ANY_DIFF.shouldBeRecursive();
+		return path.shouldBeRecursive();
 	}
 
 	@Override
@@ -105,9 +110,7 @@ public TreeFilter clone() {
 	@SuppressWarnings("nls")
 	@Override
 	public String toString() {
-		return "(FOLLOW(" + path.toString() + ")" //
-				+ " AND " //
-				+ ANY_DIFF.toString() + ")";
+		return "(FOLLOW(" + path.toString() + "))";
 	}
 
 	/**
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/TreeRevFilter.java b/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/TreeRevFilter.java
index 99943b7..e9a3e72 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/TreeRevFilter.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/TreeRevFilter.java
@@ -12,15 +12,11 @@
 
 import java.io.IOException;
 import java.util.List;
-import java.util.Optional;
-import java.util.Set;
 
-import org.eclipse.jgit.internal.storage.commitgraph.ChangedPathFilter;
 import org.eclipse.jgit.diff.DiffConfig;
 import org.eclipse.jgit.diff.DiffEntry;
 import org.eclipse.jgit.diff.DiffEntry.ChangeType;
 import org.eclipse.jgit.diff.RenameDetector;
-import org.eclipse.jgit.errors.CorruptObjectException;
 import org.eclipse.jgit.errors.IncorrectObjectTypeException;
 import org.eclipse.jgit.errors.MissingObjectException;
 import org.eclipse.jgit.errors.StopWalkException;
@@ -28,6 +24,7 @@
 import org.eclipse.jgit.revwalk.filter.RevFilter;
 import org.eclipse.jgit.treewalk.TreeWalk;
 import org.eclipse.jgit.treewalk.filter.TreeFilter;
+import org.eclipse.jgit.treewalk.filter.TreeFilter.MutableBoolean;
 
 /**
  * Filter applying a {@link org.eclipse.jgit.treewalk.filter.TreeFilter} against
@@ -50,6 +47,8 @@ public class TreeRevFilter extends RevFilter {
 
 	private final TreeWalk pathFilter;
 
+	private final MutableBoolean changedPathFilterUsed = new MutableBoolean();
+
 	private long changedPathFilterTruePositive = 0;
 
 	private long changedPathFilterFalsePositive = 0;
@@ -126,24 +125,15 @@ public boolean include(RevWalk walker, RevCommit c)
 		}
 		trees[nParents] = c.getTree();
 		tw.reset(trees);
+		changedPathFilterUsed.reset();
 
 		if (nParents == 1) {
 			// We have exactly one parent. This is a very common case.
 			//
 			int chgs = 0, adds = 0;
-			boolean changedPathFilterUsed = false;
-			boolean mustCalculateChgs = true;
-			ChangedPathFilter cpf = c.getChangedPathFilter(walker);
-			if (cpf != null) {
-				Optional<Set<byte[]>> paths = pathFilter.getFilter()
-						.getPathsBestEffort();
-				if (paths.isPresent()) {
-					changedPathFilterUsed = true;
-					if (paths.get().stream().noneMatch(cpf::maybeContains)) {
-						mustCalculateChgs = false;
-					}
-				}
-			}
+			TreeFilter tf = pathFilter.getFilter();
+			boolean mustCalculateChgs = tf.shouldTreeWalk(c, walker,
+					changedPathFilterUsed);
 			if (mustCalculateChgs) {
 				while (tw.next()) {
 					chgs++;
@@ -153,7 +143,7 @@ public boolean include(RevWalk walker, RevCommit c)
 						break; // no point in looking at this further.
 					}
 				}
-				if (changedPathFilterUsed) {
+				if (changedPathFilterUsed.get()) {
 					if (chgs > 0) {
 						changedPathFilterTruePositive++;
 					} else {
@@ -161,7 +151,7 @@ public boolean include(RevWalk walker, RevCommit c)
 					}
 				}
 			} else {
-				if (changedPathFilterUsed) {
+				if (changedPathFilterUsed.get()) {
 					changedPathFilterNegative++;
 				}
 			}
@@ -315,9 +305,7 @@ public long getChangedPathFilterNegative() {
 	}
 
 	private void updateFollowFilter(ObjectId[] trees, DiffConfig cfg,
-			RevCommit commit)
-			throws MissingObjectException, IncorrectObjectTypeException,
-			CorruptObjectException, IOException {
+			RevCommit commit) throws IOException {
 		TreeWalk tw = pathFilter;
 		FollowFilter oldFilter = (FollowFilter) tw.getFilter();
 		tw.setFilter(TreeFilter.ANY_DIFF);
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/treewalk/filter/AndTreeFilter.java b/org.eclipse.jgit/src/org/eclipse/jgit/treewalk/filter/AndTreeFilter.java
index c6804da..b35dbeb 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/treewalk/filter/AndTreeFilter.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/treewalk/filter/AndTreeFilter.java
@@ -12,11 +12,14 @@
 package org.eclipse.jgit.treewalk.filter;
 
 import java.io.IOException;
+import java.util.Arrays;
 import java.util.Collection;
 
 import org.eclipse.jgit.errors.IncorrectObjectTypeException;
 import org.eclipse.jgit.errors.MissingObjectException;
 import org.eclipse.jgit.internal.JGitText;
+import org.eclipse.jgit.revwalk.RevCommit;
+import org.eclipse.jgit.revwalk.RevWalk;
 import org.eclipse.jgit.treewalk.TreeWalk;
 
 /**
@@ -100,6 +103,13 @@ public boolean include(TreeWalk walker)
 		}
 
 		@Override
+		public boolean shouldTreeWalk(RevCommit c, RevWalk rw,
+				MutableBoolean cpfUsed) {
+			return a.shouldTreeWalk(c, rw, cpfUsed)
+					&& b.shouldTreeWalk(c, rw, cpfUsed);
+		}
+
+		@Override
 		public int matchFilter(TreeWalk walker)
 				throws MissingObjectException, IncorrectObjectTypeException,
 				IOException {
@@ -174,6 +184,13 @@ public boolean shouldBeRecursive() {
 		}
 
 		@Override
+		public boolean shouldTreeWalk(RevCommit c, RevWalk rw,
+				MutableBoolean cpfUsed) {
+			return Arrays.stream(subfilters)
+					.allMatch(t -> t.shouldTreeWalk(c, rw, cpfUsed));
+		}
+
+		@Override
 		public TreeFilter clone() {
 			final TreeFilter[] s = new TreeFilter[subfilters.length];
 			for (int i = 0; i < s.length; i++)
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/treewalk/filter/ChangedPathTreeFilter.java b/org.eclipse.jgit/src/org/eclipse/jgit/treewalk/filter/ChangedPathTreeFilter.java
new file mode 100644
index 0000000..2400e12
--- /dev/null
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/treewalk/filter/ChangedPathTreeFilter.java
@@ -0,0 +1,134 @@
+/*
+ * Copyright (C) 2025, Google LLC and others
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Distribution License v. 1.0 which is available at
+ * https://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+package org.eclipse.jgit.treewalk.filter;
+
+import org.eclipse.jgit.internal.JGitText;
+import org.eclipse.jgit.internal.storage.commitgraph.ChangedPathFilter;
+import org.eclipse.jgit.lib.Constants;
+import org.eclipse.jgit.revwalk.RevCommit;
+import org.eclipse.jgit.revwalk.RevWalk;
+import org.eclipse.jgit.treewalk.TreeWalk;
+import org.eclipse.jgit.util.StringUtils;
+
+import java.io.IOException;
+import java.util.Arrays;
+import java.util.List;
+import java.util.stream.Collectors;
+
+/**
+ * Filter tree entries that modified the contents of particular file paths.
+ * <p>
+ * Equivalent to AndTreeFilter(PathFilter, AnyDiffFilter). This filter uses
+ * {@link org.eclipse.jgit.internal.storage.commitgraph.ChangedPathFilter}
+ * (bloom filters) when available to discard commits without diffing their
+ * trees.
+ *
+ * @since 7.3
+ */
+public class ChangedPathTreeFilter extends TreeFilter {
+
+	private TreeFilter pathFilter;
+
+	private List<String> paths;
+
+	private List<byte[]> rawPaths;
+
+	/**
+	 * Create a TreeFilter for trees modifying one or more user supplied paths.
+	 * <p>
+	 * Path strings are relative to the root of the repository. If the user's
+	 * input should be assumed relative to a subdirectory of the repository the
+	 * caller must prepend the subdirectory's path prior to creating the filter.
+	 * <p>
+	 * Path strings use '/' to delimit directories on all platforms.
+	 * <p>
+	 * Paths may appear in any order within the collection. Sorting may be done
+	 * internally when the group is constructed if doing so will improve path
+	 * matching performance.
+	 *
+	 * @param paths
+	 *            the paths to test against. Must have at least one entry.
+	 * @return a new filter for the list of paths supplied.
+	 */
+	public static ChangedPathTreeFilter create(String... paths) {
+		return new ChangedPathTreeFilter(paths);
+	}
+
+	private ChangedPathTreeFilter(String... paths) {
+		List<String> filtered = Arrays.stream(paths)
+				.map(s -> StringUtils.trim(s, '/'))
+				.collect(Collectors.toList());
+
+		if (filtered.size() == 0)
+			throw new IllegalArgumentException(
+					JGitText.get().atLeastOnePathIsRequired);
+
+		if (filtered.stream().anyMatch(s -> s.isEmpty() || s.isBlank())) {
+			throw new IllegalArgumentException(
+					JGitText.get().emptyPathNotPermitted);
+		}
+
+		this.paths = filtered;
+		this.rawPaths = this.paths.stream().map(Constants::encode)
+				.collect(Collectors.toList());
+		if (filtered.size() == 1) {
+			this.pathFilter = PathFilter.create(paths[0]);
+		} else {
+			this.pathFilter = OrTreeFilter.create(Arrays.stream(paths)
+					.map(PathFilter::create).collect(Collectors.toList()));
+		}
+	}
+
+	@Override
+	public boolean shouldTreeWalk(RevCommit c, RevWalk rw,
+			MutableBoolean cpfUsed) {
+		ChangedPathFilter cpf = c.getChangedPathFilter(rw);
+		if (cpf == null) {
+			return true;
+		}
+		if (cpfUsed != null) {
+			cpfUsed.orValue(true);
+		}
+		// return true if at least one path might exist in cpf
+		return rawPaths.stream().anyMatch(cpf::maybeContains);
+	}
+
+	@Override
+	public boolean include(TreeWalk walker) throws IOException {
+		return pathFilter.include(walker) && ANY_DIFF.include(walker);
+	}
+
+	@Override
+	public boolean shouldBeRecursive() {
+		return pathFilter.shouldBeRecursive() || ANY_DIFF.shouldBeRecursive();
+	}
+
+	@Override
+	public ChangedPathTreeFilter clone() {
+		return this;
+	}
+
+	/**
+	 * Get the paths this filter matches.
+	 *
+	 * @return the paths this filter matches.
+	 */
+	public List<String> getPaths() {
+		return paths;
+	}
+
+	@Override
+	public String toString() {
+		return "(CHANGED_PATH(" + pathFilter.toString() + ")" //
+				+ " AND " //
+				+ ANY_DIFF.toString() + ")";
+	}
+}
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/treewalk/filter/OrTreeFilter.java b/org.eclipse.jgit/src/org/eclipse/jgit/treewalk/filter/OrTreeFilter.java
index 3c18a9f..ce23825 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/treewalk/filter/OrTreeFilter.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/treewalk/filter/OrTreeFilter.java
@@ -12,11 +12,14 @@
 package org.eclipse.jgit.treewalk.filter;
 
 import java.io.IOException;
+import java.util.Arrays;
 import java.util.Collection;
 
 import org.eclipse.jgit.errors.IncorrectObjectTypeException;
 import org.eclipse.jgit.errors.MissingObjectException;
 import org.eclipse.jgit.internal.JGitText;
+import org.eclipse.jgit.revwalk.RevCommit;
+import org.eclipse.jgit.revwalk.RevWalk;
 import org.eclipse.jgit.treewalk.TreeWalk;
 
 /**
@@ -116,6 +119,13 @@ public int matchFilter(TreeWalk walker)
 		}
 
 		@Override
+		public boolean shouldTreeWalk(RevCommit c, RevWalk rw,
+				MutableBoolean cpfUsed) {
+			return a.shouldTreeWalk(c, rw, cpfUsed)
+					|| b.shouldTreeWalk(c, rw, cpfUsed);
+		}
+
+		@Override
 		public boolean shouldBeRecursive() {
 			return a.shouldBeRecursive() || b.shouldBeRecursive();
 		}
@@ -164,6 +174,13 @@ public int matchFilter(TreeWalk walker)
 		}
 
 		@Override
+		public boolean shouldTreeWalk(RevCommit c, RevWalk rw,
+				MutableBoolean cpfUsed) {
+			return Arrays.stream(subfilters)
+					.anyMatch(t -> t.shouldTreeWalk(c, rw, cpfUsed));
+		}
+
+		@Override
 		public boolean shouldBeRecursive() {
 			for (TreeFilter f : subfilters)
 				if (f.shouldBeRecursive())
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/treewalk/filter/TreeFilter.java b/org.eclipse.jgit/src/org/eclipse/jgit/treewalk/filter/TreeFilter.java
index a9066dc..8159843 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/treewalk/filter/TreeFilter.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/treewalk/filter/TreeFilter.java
@@ -14,9 +14,12 @@
 import java.util.Optional;
 import java.util.Set;
 
+import org.eclipse.jgit.annotations.Nullable;
 import org.eclipse.jgit.dircache.DirCacheIterator;
 import org.eclipse.jgit.errors.IncorrectObjectTypeException;
 import org.eclipse.jgit.errors.MissingObjectException;
+import org.eclipse.jgit.revwalk.RevCommit;
+import org.eclipse.jgit.revwalk.RevWalk;
 import org.eclipse.jgit.treewalk.TreeWalk;
 import org.eclipse.jgit.treewalk.WorkingTreeIterator;
 
@@ -210,14 +213,38 @@ public int matchFilter(TreeWalk walker) throws MissingObjectException,
 	public abstract boolean shouldBeRecursive();
 
 	/**
-	 * If this filter checks that at least one of the paths in a set has been
+	 * Return true if the tree entries within this commit require
+	 * {@link #include(TreeWalk)} to correctly determine whether they are
+	 * interesting to report.
+	 * <p>
+	 * Otherwise, all tree entries within this commit are UNINTERESTING for this
+	 * tree filter.
+	 *
+	 * @param c
+	 *            the commit being considered by the TreeFilter.
+	 * @param rw
+	 *            the RevWalk used in retrieving relevant commit data.
+	 * @param cpfUsed
+	 *            if not null, it reports if the changedPathFilter was used in
+	 *            this method
+	 * @return True if the tree entries within c require
+	 *         {@link #include(TreeWalk)}.
+	 * @since 7.3
+	 */
+	public boolean shouldTreeWalk(RevCommit c, RevWalk rw,
+			@Nullable MutableBoolean cpfUsed) {
+		return true;
+	}
+
+	/**
+	 * If this filter checks that a specific set of paths have all been
 	 * modified, returns that set of paths to be checked against a changed path
 	 * filter. Otherwise, returns empty.
 	 *
 	 * @return a set of paths, or empty
-	 *
-	 * @since 6.7
+	 * @deprecated use {@code shouldTreeWalk} instead.
 	 */
+	@Deprecated(since = "7.3")
 	public Optional<Set<byte[]>> getPathsBestEffort() {
 		return Optional.empty();
 	}
@@ -242,4 +269,33 @@ public String toString() {
 		}
 		return n.replace('$', '.');
 	}
+
+	/**
+	 * Mutable wrapper to return a boolean in a function parameter.
+	 *
+	 * @since 7.3
+	 */
+	public static class MutableBoolean {
+		private boolean value;
+
+		/**
+		 * Return the boolean value.
+		 *
+		 * @return The state of the internal boolean value.
+		 */
+		public boolean get() {
+			return value;
+		}
+
+		void orValue(boolean v) {
+			value = value || v;
+		}
+
+		/**
+		 * Reset the boolean value.
+		 */
+		public void reset() {
+			value = false;
+		}
+	}
 }
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/util/FS.java b/org.eclipse.jgit/src/org/eclipse/jgit/util/FS.java
index 59bbacf..6a40fad 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/util/FS.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/util/FS.java
@@ -363,6 +363,7 @@ public static FileStoreAttributes get(Path path) {
 
 		private static FileStoreAttributes getFileStoreAttributes(Path dir) {
 			FileStore s;
+			CompletableFuture<Optional<FileStoreAttributes>> f = null;
 			try {
 				if (Files.exists(dir)) {
 					s = Files.getFileStore(dir);
@@ -385,7 +386,7 @@ private static FileStoreAttributes getFileStoreAttributes(Path dir) {
 					return FALLBACK_FILESTORE_ATTRIBUTES;
 				}
 
-				CompletableFuture<Optional<FileStoreAttributes>> f = CompletableFuture
+				f = CompletableFuture
 						.supplyAsync(() -> {
 							Lock lock = locks.computeIfAbsent(s,
 									l -> new ReentrantLock());
@@ -455,10 +456,13 @@ private static FileStoreAttributes getFileStoreAttributes(Path dir) {
 				}
 				// fall through and return fallback
 			} catch (IOException | ExecutionException | CancellationException e) {
+				cancel(f);
 				LOG.error(e.getMessage(), e);
 			} catch (TimeoutException | SecurityException e) {
+				cancel(f);
 				// use fallback
 			} catch (InterruptedException e) {
+				cancel(f);
 				LOG.error(e.getMessage(), e);
 				Thread.currentThread().interrupt();
 			}
@@ -467,6 +471,13 @@ private static FileStoreAttributes getFileStoreAttributes(Path dir) {
 			return FALLBACK_FILESTORE_ATTRIBUTES;
 		}
 
+		private static void cancel(
+				CompletableFuture<Optional<FileStoreAttributes>> f) {
+			if (f != null) {
+				f.cancel(true);
+			}
+		}
+
 		@SuppressWarnings("boxing")
 		private static Duration measureMinimalRacyInterval(Path dir) {
 			LOG.debug("{}: start measure minimal racy interval in {}", //$NON-NLS-1$
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/util/SystemReader.java b/org.eclipse.jgit/src/org/eclipse/jgit/util/SystemReader.java
index 22b82b3..0b7c620 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/util/SystemReader.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/util/SystemReader.java
@@ -492,6 +492,36 @@ public Path getXdgConfigDirectory(FS fileSystem) {
 	}
 
 	/**
+	 * Gets the directory denoted by environment variable XDG_CACHE_HOME. If
+	 * the variable is not set or empty, return a path for
+	 * {@code $HOME/.cache}.
+	 *
+	 * @param fileSystem
+	 *            {@link FS} to get the user's home directory
+	 * @return a {@link Path} denoting the directory, which may exist or not, or
+	 *         {@code null} if the environment variable is not set and there is
+	 *         no home directory, or the path is invalid.
+	 * @since 7.3
+	 */
+	public Path getXdgCacheDirectory(FS fileSystem) {
+		String cacheHomePath = getenv(Constants.XDG_CACHE_HOME);
+		if (StringUtils.isEmptyOrNull(cacheHomePath)) {
+			File home = fileSystem.userHome();
+			if (home == null) {
+				return null;
+			}
+			cacheHomePath = new File(home, ".cache").getAbsolutePath(); //$NON-NLS-1$
+		}
+		try {
+			return Paths.get(cacheHomePath);
+		} catch (InvalidPathException e) {
+			LOG.error(JGitText.get().logXDGCacheHomeInvalid, cacheHomePath,
+					e);
+		}
+		return null;
+	}
+
+	/**
 	 * Update config and its parents if they seem modified
 	 *
 	 * @param config
diff --git a/pom.xml b/pom.xml
index 3e4ab20..b0c12d7 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>7.2.2-SNAPSHOT</version>
+  <version>7.3.1-SNAPSHOT</version>
 
   <name>JGit - Parent</name>
   <url>${jgit-url}</url>
@@ -33,7 +33,7 @@
   </description>
 
   <scm>
-    <url>https://eclipse.gerrithub.io/plugins/gitiles/eclipse-jgit/jgit</url>
+    <url>https://eclipse.gerrithub.io/admin/repos/eclipse-jgit/jgit</url>
     <connection>scm:git:https://eclipse.gerrithub.io/eclipse-jgit/jgit</connection>
   </scm>
 
@@ -118,7 +118,7 @@
 
     <project.build.outputTimestamp>${commit.time.iso}</project.build.outputTimestamp>
 
-    <jgit-last-release-version>7.1.0.202411261347-r</jgit-last-release-version>
+    <jgit-last-release-version>7.2.0.202503040940-r</jgit-last-release-version>
     <ant-version>1.10.15</ant-version>
     <apache-sshd-version>2.15.0</apache-sshd-version>
     <jsch-version>0.1.55</jsch-version>
@@ -130,25 +130,25 @@
     <commons-compress-version>1.27.1</commons-compress-version>
     <osgi-core-version>6.0.0</osgi-core-version>
     <servlet-api-version>6.1.0</servlet-api-version>
-    <jetty-version>12.0.16</jetty-version>
+    <jetty-version>12.0.21</jetty-version>
     <japicmp-version>0.23.1</japicmp-version>
     <httpclient-version>4.5.14</httpclient-version>
     <httpcore-version>4.4.16</httpcore-version>
     <slf4j-version>1.7.36</slf4j-version>
     <maven-javadoc-plugin-version>3.11.2</maven-javadoc-plugin-version>
-    <gson-version>2.12.1</gson-version>
+    <gson-version>2.13.1</gson-version>
     <bouncycastle-version>1.80</bouncycastle-version>
-    <spotbugs-maven-plugin-version>4.9.1.0</spotbugs-maven-plugin-version>
-    <maven-project-info-reports-plugin-version>3.8.0</maven-project-info-reports-plugin-version>
+    <spotbugs-maven-plugin-version>4.9.3.0</spotbugs-maven-plugin-version>
+    <maven-project-info-reports-plugin-version>3.9.0</maven-project-info-reports-plugin-version>
     <maven-jxr-plugin-version>3.6.0</maven-jxr-plugin-version>
-    <maven-surefire-plugin-version>3.5.2</maven-surefire-plugin-version>
+    <maven-surefire-plugin-version>3.5.3</maven-surefire-plugin-version>
     <maven-surefire-report-plugin-version>${maven-surefire-plugin-version}</maven-surefire-report-plugin-version>
     <maven-compiler-plugin-version>3.14.0</maven-compiler-plugin-version>
     <plexus-compiler-version>2.13.0</plexus-compiler-version>
     <hamcrest-version>2.2</hamcrest-version>
     <assertj-version>3.27.3</assertj-version>
-    <jna-version>5.16.0</jna-version>
-    <byte-buddy-version>1.17.1</byte-buddy-version>
+    <jna-version>5.17.0</jna-version>
+    <byte-buddy-version>1.17.5</byte-buddy-version>
 
     <!-- Properties to enable jacoco code coverage analysis -->
     <sonar.core.codeCoveragePlugin>jacoco</sonar.core.codeCoveragePlugin>
@@ -305,7 +305,7 @@
         <plugin>
           <groupId>org.jacoco</groupId>
           <artifactId>jacoco-maven-plugin</artifactId>
-          <version>0.8.12</version>
+          <version>0.8.13</version>
         </plugin>
         <plugin>
           <groupId>org.apache.maven.plugins</groupId>
@@ -337,12 +337,12 @@
         <plugin>
           <groupId>org.apache.maven.plugins</groupId>
           <artifactId>maven-deploy-plugin</artifactId>
-          <version>3.1.3</version>
+          <version>3.1.4</version>
         </plugin>
         <plugin>
           <groupId>org.apache.maven.plugins</groupId>
           <artifactId>maven-install-plugin</artifactId>
-          <version>3.1.3</version>
+          <version>3.1.4</version>
         </plugin>
         <plugin>
           <groupId>org.apache.maven.plugins</groupId>
@@ -357,7 +357,7 @@
         <plugin>
           <groupId>org.springframework.boot</groupId>
           <artifactId>spring-boot-maven-plugin</artifactId>
-          <version>3.4.3</version>
+          <version>3.5.0</version>
         </plugin>
         <plugin>
           <groupId>org.eclipse.dash</groupId>
@@ -636,7 +636,7 @@
       <plugin>
         <groupId>io.github.git-commit-id</groupId>
         <artifactId>git-commit-id-maven-plugin</artifactId>
-        <version>9.0.1</version>
+        <version>9.0.2</version>
         <executions>
           <execution>
             <id>get-the-git-infos</id>
@@ -655,7 +655,7 @@
       <plugin>
         <groupId>org.codehaus.gmavenplus</groupId>
         <artifactId>gmavenplus-plugin</artifactId>
-        <version>4.1.1</version>
+        <version>4.2.0</version>
         <dependencies>
           <dependency>
             <groupId>org.apache.groovy</groupId>
@@ -911,7 +911,7 @@
       <dependency>
         <groupId>org.apache.commons</groupId>
         <artifactId>commons-io</artifactId>
-        <version>2.18.0</version>
+        <version>2.19.0</version>
       </dependency>
 
       <dependency>
@@ -1020,7 +1020,7 @@
       <dependency>
         <groupId>org.mockito</groupId>
         <artifactId>mockito-core</artifactId>
-        <version>5.15.2</version>
+        <version>5.18.0</version>
       </dependency>
 
       <dependency>
diff --git a/tools/BUILD b/tools/BUILD
index 844f004..379a9bd 100644
--- a/tools/BUILD
+++ b/tools/BUILD
@@ -54,7 +54,7 @@
         "-Xep:ArrayHashCode:ERROR",
         "-Xep:ArraysAsListPrimitiveArray:ERROR",
         "-Xep:ArrayToString:ERROR",
-        "-Xep:AssertEqualsArgumentOrderChecker:ERROR",
+        "-Xep:AssertEqualsArgumentOrderChecker:WARN",
         "-Xep:AssertionFailureIgnored:WARN",
         "-Xep:AsyncCallableReturnsNull:ERROR",
         "-Xep:AsyncFunctionReturnsNull:ERROR",
diff --git a/tools/bazlets.bzl b/tools/bazlets.bzl
deleted file mode 100644
index f089af4..0000000
--- a/tools/bazlets.bzl
+++ /dev/null
@@ -1,18 +0,0 @@
-load("@bazel_tools//tools/build_defs/repo:git.bzl", "git_repository")
-
-NAME = "com_googlesource_gerrit_bazlets"
-
-def load_bazlets(
-        commit,
-        local_path = None):
-    if not local_path:
-        git_repository(
-            name = NAME,
-            remote = "https://gerrit.googlesource.com/bazlets",
-            commit = commit,
-        )
-    else:
-        native.local_repository(
-            name = NAME,
-            path = local_path,
-        )