Merge branch 'stable-7.4' into stable-7.5 * stable-7.4: junit.http: Extract AppServerBase to dedupe the EE8 AppServer overlay Bazel: Add EE8 servlet test targets Bazel: Add EE8 servlet bridge targets Bazel: Rename //lib:servlet-api to //lib:jakarta-servlet-api Bazel: format build files with buildifier Update SHA1 of Jetty ee8 artefacts since stable-7.5 uses a different Jetty version than stable-7.4. Change-Id: Ia0f0a2b7aad09b9e61ed40b2f217690855a608e6
diff --git a/.github/workflows/generate-maven-sbom.yaml b/.github/workflows/generate-maven-sbom.yaml new file mode 100644 index 0000000..f717d67 --- /dev/null +++ b/.github/workflows/generate-maven-sbom.yaml
@@ -0,0 +1,72 @@ +name: Generate Maven SBOM + +on: + push: + tags: + - "v**" # Triggers when someone pushes a tag that starts with 'v' + + workflow_dispatch: + # The custom 'Version' input field allows running the workflow for older git + # refs, where this workflow file did not exist yet. This would not be + # possible with the builtin "Use workflow from" input field. + inputs: + version: + description: "Version" + default: "master" + required: true + +env: + JAVA_VERSION: '17' + JAVA_DISTRO: 'temurin' + PLUGIN_VERSION: '2.9.1' + SBOM_TYPE: 'makeAggregateBom' + PROJECT_VERSION: "${{ github.event_name == 'release' && github.event.release.tag_name || github.event.inputs.version }}" + +permissions: + contents: read + +jobs: + generate-sbom: + runs-on: ubuntu-latest + outputs: + # Make env var available in re-usuable workflow (see actions/runner#2372) + project-version: ${{ env.PROJECT_VERSION }} + steps: + - name: Checkout repository at '${{ env.PROJECT_VERSION }}' + uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 + with: + fetch-depth: 0 + ref: ${{ env.PROJECT_VERSION }} + persist-credentials: false + + - name: Setup Java SDK + uses: actions/setup-java@dded0888837ed1f317902acf8a20df0ad188d165 # v5.0.0 + with: + java-version: ${{ env.JAVA_VERSION }} + distribution: ${{ env.JAVA_DISTRO }} + + - name: Generate + run: | + mvn org.cyclonedx:cyclonedx-maven-plugin:${PLUGIN_VERSION}:${SBOM_TYPE} \ + -DoutputFormat=json \ + -DoutputDirectory=target \ + -DoutputName=cyclonedx + + + - name: Upload + uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5.0.0 + with: + name: sbom + path: target/cyclonedx.json + + # Store SBOM and metadata in a predefined format for otterdog to pick up + store-sbom-data: + needs: ['generate-sbom'] + uses: eclipse-csi/workflows/.github/workflows/store-sbom-data.yml@main + with: + projectName: 'JGit' + projectVersion: ${{ needs.generate-sbom.outputs.project-version }} + bomArtifact: 'sbom' + bomFilename: 'cyclonedx.json' + parentProject: '6638fa7e-8518-4528-9419-e24f629b7e9f' +
diff --git a/.gitignore b/.gitignore index 1671449..2fd1727 100644 --- a/.gitignore +++ b/.gitignore
@@ -1,5 +1,8 @@ /.project /org.eclipse.jgit.benchmarks/dependency-reduced-pom.xml +/tools/maven-central/out/ +/tools/maven-central/staging-deploy/ +/tools/maven-central/jreleaser.yml target/ infer-out bazel-*
diff --git a/README.md b/README.md index f1f485a..acd1227 100644 --- a/README.md +++ b/README.md
@@ -1,15 +1,47 @@ -# Java Git +# Eclipse JGit An implementation of the Git version control system in pure Java. -This project is licensed under the __EDL__ (Eclipse Distribution -License). +### License + +[](https://opensource.org/licenses/BSD-3-Clause) +<br/> +JGit is licensed under the Eclipse Distribution License 1.0 (BSD-3-Clause). + + +### Latest Release + +[](https://search.maven.org/artifact/org.eclipse.jgit/org.eclipse.jgit) +[](https://javadoc.io/doc/org.eclipse.jgit/org.eclipse.jgit) +[](https://adoptium.net/temurin/releases?version=17&os=any&arch=any) + +### Support + +[](https://github.com/eclipse-jgit/jgit/issues) +[](https://github.com/eclipse-jgit/jgit/discussions) +<br/> +Post questions, comments or discussions to the jgit-dev@eclipse.org mailing list. +You need to be [subscribed](https://dev.eclipse.org/mailman/listinfo/jgit-dev) +to post. + +### Contributing + +[]() +[]() +[]() +[]() +<br/> +See the [JGit and EGit Contributor Guide](http://wiki.eclipse.org/EGit/Contributor_Guide). + +### Build JGit can be imported straight into Eclipse and built and tested from there. It can be built from the command line using [Maven](https://maven.apache.org/) or [Bazel](https://bazel.build/). The CI builds use Maven and run on [Jenkins](https://ci.eclipse.org/jgit/). +## Modules + - __org.eclipse.jgit__ A pure Java library capable of being run standalone, with no @@ -161,17 +193,6 @@ - multi-pack index - split index -## Support - -Post questions, comments or discussions to the jgit-dev@eclipse.org mailing list. -You need to be [subscribed](https://dev.eclipse.org/mailman/listinfo/jgit-dev) -to post. File bugs and enhancement requests in -[Bugzilla](https://wiki.eclipse.org/EGit/Contributor_Guide#Filing_Bugs). - -## Contributing - -See the [EGit Contributor Guide](http://wiki.eclipse.org/EGit/Contributor_Guide). - ## About Git More information about Git, its repository format, and the canonical
diff --git a/WORKSPACE b/WORKSPACE index 7f5fec8..b6ef0b0 100644 --- a/WORKSPACE +++ b/WORKSPACE
@@ -132,24 +132,24 @@ sha1 = "09d9e7024535fb4a3f74367ba7e0a2f5093af638", ) -JNA_VERS = "5.17.0" +JNA_VERS = "5.18.1" maven_jar( name = "jna", artifact = "net.java.dev.jna:jna:" + JNA_VERS, - sha1 = "33d12735bef894440780fce64f9758d420c7bae2", + sha1 = "b27ba04287cc4abe769642fe8318d39fc89bf937", ) maven_jar( name = "jna-platform", artifact = "net.java.dev.jna:jna-platform:" + JNA_VERS, - sha1 = "a4934c44d25a9d8c2ddf4203affd20330cb3426f", + sha1 = "dd817f391efc492041c9ae91127527c13750a789", ) maven_jar( name = "commons-codec", - artifact = "commons-codec:commons-codec:1.19.0", - sha1 = "8c0dbe3ae883fceda9b50a6c76e745e548073388", + artifact = "commons-codec:commons-codec:1.20.0", + sha1 = "6a671d1c456a875ff61abec63216f754078bb0ed", ) maven_jar( @@ -158,16 +158,18 @@ sha1 = "a3fcc5d3c29b2b03433aa2d2f2d2c1b1638924a1", ) +SLF4J_VERS = "2.0.17" + maven_jar( name = "log-api", - artifact = "org.slf4j:slf4j-api:1.7.36", - sha1 = "6c62681a2f655b49963a5983b8b0950a6120ae14", + artifact = "org.slf4j:slf4j-api:" + SLF4J_VERS, + sha1 = "d9e58ac9c7779ba3bf8142aff6c830617a7fe60f", ) maven_jar( name = "slf4j-simple", - artifact = "org.slf4j:slf4j-simple:1.7.36", - sha1 = "a41f9cfe6faafb2eb83a1c7dd2d0dfd844e2a936", + artifact = "org.slf4j:slf4j-simple:" + SLF4J_VERS, + sha1 = "9872a3fd794ffe7b18d17747926a64d61526ca96", ) maven_jar( @@ -190,20 +192,20 @@ maven_jar( name = "commons-lang3", - artifact = "org.apache.commons:commons-lang3:3.18.0", - sha1 = "fb14946f0e39748a6571de0635acbe44e7885491", + artifact = "org.apache.commons:commons-lang3:3.20.0", + sha1 = "65897b3e5731220962e659e001904af3c3cbeba9", ) maven_jar( name = "commons-io", - artifact = "commons-io:commons-io:2.20.0", - sha1 = "36f3474daec2849c149e877614e7f979b2082cd2", + artifact = "commons-io:commons-io:2.21.0", + sha1 = "52a6f68fe5afe335cde95461dd5c3412f04996f7", ) maven_jar( name = "tukaani-xz", - artifact = "org.tukaani:xz:1.10", - sha1 = "1be8166f89e035a56c6bfc67dbc423996fe577e2", + artifact = "org.tukaani:xz:1.11", + sha1 = "bdfd1774efb216f506f4f3c5b08c205b308c50aa", ) maven_jar( @@ -220,34 +222,34 @@ maven_jar( name = "hamcrest", - artifact = "org.hamcrest:hamcrest:2.2", - sha1 = "1820c0968dba3a11a1b30669bb1f01978a91dedc", + artifact = "org.hamcrest:hamcrest:3.0", + sha1 = "8fd9b78a8e6a6510a078a9e30e9e86a6035cfaf7", ) maven_jar( name = "mockito", - artifact = "org.mockito:mockito-core:5.19.0", - sha1 = "82b320935809e3c8ff92c2007dae5dff88d76f32", + artifact = "org.mockito:mockito-core:5.20.0", + sha1 = "a32f446f38acf636363c5693db6498047731b9e0", ) maven_jar( name = "assertj-core", - artifact = "org.assertj:assertj-core:3.27.4", - sha1 = "65e62575f7e422df6d290dc1cb15f3c97108b2b1", + artifact = "org.assertj:assertj-core:3.27.6", + sha1 = "8f34ccd6808899ad1d0aac6a770b73191f2f2a53", ) -BYTE_BUDDY_VERSION = "1.17.7" +BYTE_BUDDY_VERSION = "1.18.1" maven_jar( name = "bytebuddy", artifact = "net.bytebuddy:byte-buddy:" + BYTE_BUDDY_VERSION, - sha1 = "3856bfab61beb23e099a0d6629f2ba8de4b98ace", + sha1 = "b7bc5138c3250d4b065caccc89666bf25e4de392", ) maven_jar( name = "bytebuddy-agent", artifact = "net.bytebuddy:byte-buddy-agent:" + BYTE_BUDDY_VERSION, - sha1 = "fbf3d6d649ed37fc9e9c59480a05be0a26e3c2da", + sha1 = "d8e26676f505594ef51dfd275218fcc21c3656ef", ) maven_jar( @@ -258,100 +260,100 @@ maven_jar( name = "gson", - artifact = "com.google.code.gson:gson:2.13.1", - sha1 = "853ce06c11316b33a8eae5e9095da096a9528b8f", + artifact = "com.google.code.gson:gson:2.13.2", + sha1 = "48b8230771e573b54ce6e867a9001e75977fe78e", ) -JETTY_VER = "12.1.0" +JETTY_VER = "12.1.4" maven_jar( name = "jetty-servlet", artifact = "org.eclipse.jetty.ee10:jetty-ee10-servlet:" + JETTY_VER, - sha1 = "56c5180952f23a6af4d8f7e34e84a838c7d284cb", + sha1 = "77ce63899d8a3d65ccdd68c6948faab9899ad66d", ) maven_jar( name = "jetty-ee8-nested", artifact = "org.eclipse.jetty.ee8:jetty-ee8-nested:" + JETTY_VER, - sha1 = "8118cdcdf9cdf163584d47e136e1cee17b547985", + sha1 = "f0f7177357594c872a6da340dbcc748fbdaa4048", ) maven_jar( name = "jetty-security-ee8", artifact = "org.eclipse.jetty.ee8:jetty-ee8-security:" + JETTY_VER, - sha1 = "d25c84218ef00b7e54f537acdee3fda8f20be975", + sha1 = "605d9573c48b7852b7b50aad870b130db93d42d6", ) maven_jar( name = "jetty-servlet-ee8", artifact = "org.eclipse.jetty.ee8:jetty-ee8-servlet:" + JETTY_VER, - sha1 = "881b69b15540215aace32ab7c985abb6e4fe0c25", + sha1 = "42188210ad02c9eac3b811ee68a4dc1b844972f2", ) maven_jar( name = "jetty-security", artifact = "org.eclipse.jetty:jetty-security:" + JETTY_VER, - sha1 = "5fb2a02cc342fd132e5a358ecbb4479aabf58a3a", + sha1 = "1110c675e052608f9be78ff65884ae68672d793b", ) maven_jar( name = "jetty-server", artifact = "org.eclipse.jetty:jetty-server:" + JETTY_VER, - sha1 = "a53a5d0d03aaeab03908ff854cdd5e9ee256efca", + sha1 = "142e34e6e3ae2645df5a59c002180c9cbeeb940e", ) maven_jar( name = "jetty-session", artifact = "org.eclipse.jetty:jetty-session:" + JETTY_VER, - sha1 = "be1be354522861b72fdaade01f798ad7f6ffbac4", + sha1 = "85fe6e7bba3dccdac5d76f451f6e126f1da6ab87", ) maven_jar( name = "jetty-http", artifact = "org.eclipse.jetty:jetty-http:" + JETTY_VER, - sha1 = "d74935bc8eb25780453dfd0a2e93c2729b566e79", + sha1 = "310c2c94836b5675e97621f62d7d1f0cab79a142", ) maven_jar( name = "jetty-io", artifact = "org.eclipse.jetty:jetty-io:" + JETTY_VER, - sha1 = "611910afde7e9a2cfda3cad1ec1466cdba55e444", + sha1 = "f637ebb6d9cc27bedef24514d9a475b343f6fd17", ) maven_jar( name = "jetty-util", artifact = "org.eclipse.jetty:jetty-util:" + JETTY_VER, - sha1 = "e0d96b47d0289006941757352c6fe7e5d9370c3b", + sha1 = "f0ebb90ade7a18f5f8c2c1513d4433ccfbada69b", ) maven_jar( name = "jetty-util-ajax", artifact = "org.eclipse.jetty:jetty-util-ajax:" + JETTY_VER, - sha1 = "26c44a954086af8518fcb311c94c5703f1d3093b", + sha1 = "f14e709057b93e88c69e7060d591e9582146899b", ) -BOUNCYCASTLE_VER = "1.81" +BOUNCYCASTLE_VER = "1.82" maven_jar( name = "bcpg", artifact = "org.bouncycastle:bcpg-jdk18on:" + BOUNCYCASTLE_VER, - sha1 = "7cd50193dd6a080a203716d993f7a246c8d94291", + sha1 = "55cd7f445018b18119e3f2e67978fb39445b791c", ) maven_jar( name = "bcprov", artifact = "org.bouncycastle:bcprov-jdk18on:" + BOUNCYCASTLE_VER, - sha1 = "d17c094daef57dbd80af71687a475aa6df7cbe54", + sha1 = "e1118397395d21909a1b7b15120d0c2a68d7fd0c", ) maven_jar( name = "bcutil", artifact = "org.bouncycastle:bcutil-jdk18on:" + BOUNCYCASTLE_VER, - sha1 = "e2dd79395ab435094142b6aba219f35adcba0f01", + sha1 = "1850911d674c91ce6444783ff10478e2c6e9bbf9", ) maven_jar( name = "bcpkix", artifact = "org.bouncycastle:bcpkix-jdk18on:" + BOUNCYCASTLE_VER, - sha1 = "819fd6f5d170c8b8bf8c5acc73816e9c36574042", + sha1 = "ad7b7155abac3e4e4f73579d5176c11f7659c560", )
diff --git a/org.eclipse.jgit.ant.test/META-INF/MANIFEST.MF b/org.eclipse.jgit.ant.test/META-INF/MANIFEST.MF index fdad3a7..b3e4719 100644 --- a/org.eclipse.jgit.ant.test/META-INF/MANIFEST.MF +++ b/org.eclipse.jgit.ant.test/META-INF/MANIFEST.MF
@@ -5,14 +5,14 @@ Automatic-Module-Name: org.eclipse.jgit.ant.test Bundle-SymbolicName: org.eclipse.jgit.ant.test Bundle-Vendor: %Bundle-Vendor -Bundle-Version: 7.4.1.qualifier +Bundle-Version: 7.5.1.qualifier Bundle-ActivationPolicy: lazy Bundle-RequiredExecutionEnvironment: JavaSE-17 Bundle-SCM: url=https://github.com/eclipse-jgit/jgit, connection=scm:git:https://eclipse.gerrithub.io/eclipse-jgit/jgit.git, developerConnection=scm:git:https://eclipse.gerrithub.io/a/eclipse-jgit/jgit.git Import-Package: org.apache.tools.ant, - org.eclipse.jgit.ant.tasks;version="[7.4.1,7.5.0)", - org.eclipse.jgit.junit;version="[7.4.1,7.5.0)", - org.eclipse.jgit.lib;version="[7.4.1,7.5.0)", - org.eclipse.jgit.util;version="[7.4.1,7.5.0)", - org.hamcrest.core;version="[1.1.0,3.0.0)", + org.eclipse.jgit.ant.tasks;version="[7.5.1,7.6.0)", + org.eclipse.jgit.junit;version="[7.5.1,7.6.0)", + org.eclipse.jgit.lib;version="[7.5.1,7.6.0)", + org.eclipse.jgit.util;version="[7.5.1,7.6.0)", + org.hamcrest;version="[3.0.0,4.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 39d8a03..937b78a 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.4.1-SNAPSHOT</version> + <version>7.5.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 46cf048..bf1a61d 100644 --- a/org.eclipse.jgit.ant/META-INF/MANIFEST.MF +++ b/org.eclipse.jgit.ant/META-INF/MANIFEST.MF
@@ -3,14 +3,14 @@ Bundle-Name: %Bundle-Name Automatic-Module-Name: org.eclipse.jgit.ant Bundle-SymbolicName: org.eclipse.jgit.ant -Bundle-Version: 7.4.1.qualifier +Bundle-Version: 7.5.1.qualifier Bundle-RequiredExecutionEnvironment: JavaSE-17 Bundle-SCM: url=https://github.com/eclipse-jgit/jgit, connection=scm:git:https://eclipse.gerrithub.io/eclipse-jgit/jgit.git, developerConnection=scm:git:https://eclipse.gerrithub.io/a/eclipse-jgit/jgit.git Import-Package: org.apache.tools.ant, - org.eclipse.jgit.storage.file;version="[7.4.1,7.5.0)" + org.eclipse.jgit.storage.file;version="[7.5.1,7.6.0)" Bundle-Localization: OSGI-INF/l10n/plugin Bundle-Vendor: %Bundle-Vendor -Export-Package: org.eclipse.jgit.ant;version="7.4.1", - org.eclipse.jgit.ant.tasks;version="7.4.1"; +Export-Package: org.eclipse.jgit.ant;version="7.5.1", + org.eclipse.jgit.ant.tasks;version="7.5.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 334dcf8..8bc02c8 100644 --- a/org.eclipse.jgit.ant/META-INF/SOURCE-MANIFEST.MF +++ b/org.eclipse.jgit.ant/META-INF/SOURCE-MANIFEST.MF
@@ -3,6 +3,6 @@ Bundle-Name: org.eclipse.jgit.ant - Sources Bundle-SymbolicName: org.eclipse.jgit.ant.source Bundle-Vendor: Eclipse.org - JGit -Bundle-Version: 7.4.1.qualifier +Bundle-Version: 7.5.1.qualifier Bundle-SCM: url=https://github.com/eclipse-jgit/jgit, connection=scm:git:https://eclipse.gerrithub.io/eclipse-jgit/jgit.git, developerConnection=scm:git:https://eclipse.gerrithub.io/a/eclipse-jgit/jgit.git -Eclipse-SourceBundle: org.eclipse.jgit.ant;version="7.4.1.qualifier";roots="." +Eclipse-SourceBundle: org.eclipse.jgit.ant;version="7.5.1.qualifier";roots="."
diff --git a/org.eclipse.jgit.ant/pom.xml b/org.eclipse.jgit.ant/pom.xml index 446b4c7..fcd4371 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.4.1-SNAPSHOT</version> + <version>7.5.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 0d01fae..07b850d 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.4.1.qualifier +Bundle-Version: 7.5.1.qualifier Bundle-Vendor: %Bundle-Vendor Bundle-Localization: OSGI-INF/l10n/plugin Bundle-RequiredExecutionEnvironment: JavaSE-17 @@ -14,18 +14,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.4.1,7.5.0)", - org.eclipse.jgit.lib;version="[7.4.1,7.5.0)", - org.eclipse.jgit.nls;version="[7.4.1,7.5.0)", - org.eclipse.jgit.revwalk;version="[7.4.1,7.5.0)", - org.eclipse.jgit.util;version="[7.4.1,7.5.0)", + org.eclipse.jgit.api;version="[7.5.1,7.6.0)", + org.eclipse.jgit.lib;version="[7.5.1,7.6.0)", + org.eclipse.jgit.nls;version="[7.5.1,7.6.0)", + org.eclipse.jgit.revwalk;version="[7.5.1,7.6.0)", + org.eclipse.jgit.util;version="[7.5.1,7.6.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.4.1"; +Export-Package: org.eclipse.jgit.archive;version="7.5.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.4.1";x-internal:=true + org.eclipse.jgit.archive.internal;version="7.5.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 51e8ac8..831f34f 100644 --- a/org.eclipse.jgit.archive/META-INF/SOURCE-MANIFEST.MF +++ b/org.eclipse.jgit.archive/META-INF/SOURCE-MANIFEST.MF
@@ -3,6 +3,6 @@ Bundle-Name: org.eclipse.jgit.archive - Sources Bundle-SymbolicName: org.eclipse.jgit.archive.source Bundle-Vendor: Eclipse.org - JGit -Bundle-Version: 7.4.1.qualifier +Bundle-Version: 7.5.1.qualifier Bundle-SCM: url=https://github.com/eclipse-jgit/jgit, connection=scm:git:https://eclipse.gerrithub.io/eclipse-jgit/jgit.git, developerConnection=scm:git:https://eclipse.gerrithub.io/a/eclipse-jgit/jgit.git -Eclipse-SourceBundle: org.eclipse.jgit.archive;version="7.4.1.qualifier";roots="." +Eclipse-SourceBundle: org.eclipse.jgit.archive;version="7.5.1.qualifier";roots="."
diff --git a/org.eclipse.jgit.archive/pom.xml b/org.eclipse.jgit.archive/pom.xml index c8c3c7c..3e1cbea 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.4.1-SNAPSHOT</version> + <version>7.5.1-SNAPSHOT</version> </parent> <artifactId>org.eclipse.jgit.archive</artifactId>
diff --git a/org.eclipse.jgit.benchmarks/pom.xml b/org.eclipse.jgit.benchmarks/pom.xml index dc24e6c..7d9f9e6 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.4.1-SNAPSHOT</version> + <version>7.5.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 581881f..44bc58b 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.4.1-SNAPSHOT</version> + <version>7.5.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.4.1-SNAPSHOT</version> + <version>7.5.1-SNAPSHOT</version> </dependency> <dependency> <groupId>org.eclipse.jgit</groupId> <artifactId>org.eclipse.jgit.ant</artifactId> - <version>7.4.1-SNAPSHOT</version> + <version>7.5.1-SNAPSHOT</version> </dependency> <dependency> <groupId>org.eclipse.jgit</groupId> <artifactId>org.eclipse.jgit.archive</artifactId> - <version>7.4.1-SNAPSHOT</version> + <version>7.5.1-SNAPSHOT</version> </dependency> <dependency> <groupId>org.eclipse.jgit</groupId> <artifactId>org.eclipse.jgit.http.apache</artifactId> - <version>7.4.1-SNAPSHOT</version> + <version>7.5.1-SNAPSHOT</version> </dependency> <dependency> <groupId>org.eclipse.jgit</groupId> <artifactId>org.eclipse.jgit.http.server</artifactId> - <version>7.4.1-SNAPSHOT</version> + <version>7.5.1-SNAPSHOT</version> </dependency> <dependency> <groupId>org.eclipse.jgit</groupId> <artifactId>org.eclipse.jgit.lfs</artifactId> - <version>7.4.1-SNAPSHOT</version> + <version>7.5.1-SNAPSHOT</version> </dependency> <dependency> <groupId>org.eclipse.jgit</groupId> <artifactId>org.eclipse.jgit.lfs.server</artifactId> - <version>7.4.1-SNAPSHOT</version> + <version>7.5.1-SNAPSHOT</version> </dependency> <dependency> <groupId>org.eclipse.jgit</groupId> <artifactId>org.eclipse.jgit.pgm</artifactId> - <version>7.4.1-SNAPSHOT</version> + <version>7.5.1-SNAPSHOT</version> </dependency> <dependency> <groupId>org.eclipse.jgit</groupId> <artifactId>org.eclipse.jgit.ui</artifactId> - <version>7.4.1-SNAPSHOT</version> + <version>7.5.1-SNAPSHOT</version> </dependency> <dependency> <groupId>org.eclipse.jgit</groupId> <artifactId>org.eclipse.jgit.ssh.apache</artifactId> - <version>7.4.1-SNAPSHOT</version> + <version>7.5.1-SNAPSHOT</version> </dependency> <dependency> <groupId>org.eclipse.jgit</groupId> <artifactId>org.eclipse.jgit.test</artifactId> - <version>7.4.1-SNAPSHOT</version> + <version>7.5.1-SNAPSHOT</version> </dependency> <dependency> <groupId>org.eclipse.jgit</groupId> <artifactId>org.eclipse.jgit.ant.test</artifactId> - <version>7.4.1-SNAPSHOT</version> + <version>7.5.1-SNAPSHOT</version> </dependency> <dependency> <groupId>org.eclipse.jgit</groupId> <artifactId>org.eclipse.jgit.http.test</artifactId> - <version>7.4.1-SNAPSHOT</version> + <version>7.5.1-SNAPSHOT</version> </dependency> <dependency> <groupId>org.eclipse.jgit</groupId> <artifactId>org.eclipse.jgit.pgm.test</artifactId> - <version>7.4.1-SNAPSHOT</version> + <version>7.5.1-SNAPSHOT</version> </dependency> <dependency> <groupId>org.eclipse.jgit</groupId> <artifactId>org.eclipse.jgit.lfs.test</artifactId> - <version>7.4.1-SNAPSHOT</version> + <version>7.5.1-SNAPSHOT</version> </dependency> <dependency> <groupId>org.eclipse.jgit</groupId> <artifactId>org.eclipse.jgit.lfs.server.test</artifactId> - <version>7.4.1-SNAPSHOT</version> + <version>7.5.1-SNAPSHOT</version> </dependency> <dependency> <groupId>org.eclipse.jgit</groupId> <artifactId>org.eclipse.jgit.ssh.apache.test</artifactId> - <version>7.4.1-SNAPSHOT</version> + <version>7.5.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 ee66caf..4136a34 100644 --- a/org.eclipse.jgit.gpg.bc.test/META-INF/MANIFEST.MF +++ b/org.eclipse.jgit.gpg.bc.test/META-INF/MANIFEST.MF
@@ -3,21 +3,21 @@ Bundle-Name: %Bundle-Name Automatic-Module-Name: org.eclipse.jgit.gpg.bc.test Bundle-SymbolicName: org.eclipse.jgit.gpg.bc.test -Bundle-Version: 7.4.1.qualifier +Bundle-Version: 7.5.1.qualifier Bundle-Vendor: %Bundle-Vendor Bundle-Localization: plugin Bundle-RequiredExecutionEnvironment: JavaSE-17 Bundle-SCM: url=https://github.com/eclipse-jgit/jgit, connection=scm:git:https://eclipse.gerrithub.io/eclipse-jgit/jgit.git, developerConnection=scm:git:https://eclipse.gerrithub.io/a/eclipse-jgit/jgit.git -Require-Bundle: org.hamcrest.core;bundle-version="[1.3.0,2.0.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.4.1,7.5.0)", - org.eclipse.jgit.gpg.bc.internal.keys;version="[7.4.1,7.5.0)", - org.eclipse.jgit.util.sha1;version="[7.4.1,7.5.0)", + org.eclipse.jgit.gpg.bc.internal;version="[7.5.1,7.6.0)", + org.eclipse.jgit.gpg.bc.internal.keys;version="[7.5.1,7.6.0)", + org.eclipse.jgit.util.sha1;version="[7.5.1,7.6.0)", + org.hamcrest;version="[3.0.0,4.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)"
diff --git a/org.eclipse.jgit.gpg.bc.test/pom.xml b/org.eclipse.jgit.gpg.bc.test/pom.xml index 3114dfd..b489073 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.4.1-SNAPSHOT</version> + <version>7.5.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 ab9cdfe..b6c43a7 100644 --- a/org.eclipse.jgit.gpg.bc/META-INF/MANIFEST.MF +++ b/org.eclipse.jgit.gpg.bc/META-INF/MANIFEST.MF
@@ -3,10 +3,10 @@ Bundle-Name: %Bundle-Name Automatic-Module-Name: org.eclipse.jgit.gpg.bc Bundle-SymbolicName: org.eclipse.jgit.gpg.bc;singleton:=true -Fragment-Host: org.eclipse.jgit;bundle-version="[7.4.1,7.5.0)" +Fragment-Host: org.eclipse.jgit;bundle-version="[7.5.1,7.6.0)" Bundle-Vendor: %Bundle-Vendor Bundle-Localization: OSGI-INF/l10n/gpg_bc -Bundle-Version: 7.4.1.qualifier +Bundle-Version: 7.5.1.qualifier Bundle-RequiredExecutionEnvironment: JavaSE-17 Bundle-SCM: url=https://github.com/eclipse-jgit/jgit, connection=scm:git:https://eclipse.gerrithub.io/eclipse-jgit/jgit.git, developerConnection=scm:git:https://eclipse.gerrithub.io/a/eclipse-jgit/jgit.git Import-Package: org.bouncycastle.asn1;version="[1.80.0,2.0.0)", @@ -27,5 +27,5 @@ 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.4.1";x-friends:="org.eclipse.jgit.gpg.bc.test", - org.eclipse.jgit.gpg.bc.internal.keys;version="7.4.1";x-friends:="org.eclipse.jgit.gpg.bc.test" +Export-Package: org.eclipse.jgit.gpg.bc.internal;version="7.5.1";x-friends:="org.eclipse.jgit.gpg.bc.test", + org.eclipse.jgit.gpg.bc.internal.keys;version="7.5.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 d325fcf..6a4d2b0 100644 --- a/org.eclipse.jgit.gpg.bc/META-INF/SOURCE-MANIFEST.MF +++ b/org.eclipse.jgit.gpg.bc/META-INF/SOURCE-MANIFEST.MF
@@ -3,6 +3,6 @@ Bundle-Name: org.eclipse.jgit.gpg.bc - Sources Bundle-SymbolicName: org.eclipse.jgit.gpg.bc.source Bundle-Vendor: Eclipse.org - JGit -Bundle-Version: 7.4.1.qualifier +Bundle-Version: 7.5.1.qualifier Bundle-SCM: url=https://github.com/eclipse-jgit/jgit, connection=scm:git:https://eclipse.gerrithub.io/eclipse-jgit/jgit.git, developerConnection=scm:git:https://eclipse.gerrithub.io/a/eclipse-jgit/jgit.git -Eclipse-SourceBundle: org.eclipse.jgit.gpg.bc;version="7.4.1.qualifier";roots="." +Eclipse-SourceBundle: org.eclipse.jgit.gpg.bc;version="7.5.1.qualifier";roots="."
diff --git a/org.eclipse.jgit.gpg.bc/pom.xml b/org.eclipse.jgit.gpg.bc/pom.xml index edcc6c2..fe4f637 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.4.1-SNAPSHOT</version> + <version>7.5.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 42a3856..aba7386 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.4.1.qualifier +Bundle-Version: 7.5.1.qualifier Bundle-RequiredExecutionEnvironment: JavaSE-17 Bundle-SCM: url=https://github.com/eclipse-jgit/jgit, connection=scm:git:https://eclipse.gerrithub.io/eclipse-jgit/jgit.git, developerConnection=scm:git:https://eclipse.gerrithub.io/a/eclipse-jgit/jgit.git Bundle-Localization: OSGI-INF/l10n/plugin @@ -27,11 +27,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.4.1,7.5.0)", - org.eclipse.jgit.nls;version="[7.4.1,7.5.0)", - org.eclipse.jgit.transport.http;version="[7.4.1,7.5.0)", - org.eclipse.jgit.util;version="[7.4.1,7.5.0)" -Export-Package: org.eclipse.jgit.transport.http.apache;version="7.4.1"; + org.eclipse.jgit.annotations;version="[7.5.1,7.6.0)", + org.eclipse.jgit.nls;version="[7.5.1,7.6.0)", + org.eclipse.jgit.transport.http;version="[7.5.1,7.6.0)", + org.eclipse.jgit.util;version="[7.5.1,7.6.0)" +Export-Package: org.eclipse.jgit.transport.http.apache;version="7.5.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 d52f778..50c6aba 100644 --- a/org.eclipse.jgit.http.apache/META-INF/SOURCE-MANIFEST.MF +++ b/org.eclipse.jgit.http.apache/META-INF/SOURCE-MANIFEST.MF
@@ -3,6 +3,6 @@ Bundle-Name: org.eclipse.jgit.http.apache - Sources Bundle-SymbolicName: org.eclipse.jgit.http.apache.source Bundle-Vendor: Eclipse.org - JGit -Bundle-Version: 7.4.1.qualifier +Bundle-Version: 7.5.1.qualifier Bundle-SCM: url=https://github.com/eclipse-jgit/jgit, connection=scm:git:https://eclipse.gerrithub.io/eclipse-jgit/jgit.git, developerConnection=scm:git:https://eclipse.gerrithub.io/a/eclipse-jgit/jgit.git -Eclipse-SourceBundle: org.eclipse.jgit.http.apache;version="7.4.1.qualifier";roots="." +Eclipse-SourceBundle: org.eclipse.jgit.http.apache;version="7.5.1.qualifier";roots="."
diff --git a/org.eclipse.jgit.http.apache/pom.xml b/org.eclipse.jgit.http.apache/pom.xml index 37d9d55..9f8c083 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.4.1-SNAPSHOT</version> + <version>7.5.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 0c679ba..5fc3c47 100644 --- a/org.eclipse.jgit.http.server/META-INF/MANIFEST.MF +++ b/org.eclipse.jgit.http.server/META-INF/MANIFEST.MF
@@ -3,31 +3,31 @@ Bundle-Name: %Bundle-Name Automatic-Module-Name: org.eclipse.jgit.http.server Bundle-SymbolicName: org.eclipse.jgit.http.server -Bundle-Version: 7.4.1.qualifier +Bundle-Version: 7.5.1.qualifier Bundle-Localization: OSGI-INF/l10n/plugin Bundle-Vendor: %Bundle-Vendor Bundle-ActivationPolicy: lazy Bundle-RequiredExecutionEnvironment: JavaSE-17 Bundle-SCM: url=https://github.com/eclipse-jgit/jgit, connection=scm:git:https://eclipse.gerrithub.io/eclipse-jgit/jgit.git, developerConnection=scm:git:https://eclipse.gerrithub.io/a/eclipse-jgit/jgit.git -Export-Package: org.eclipse.jgit.http.server;version="7.4.1", - org.eclipse.jgit.http.server.glue;version="7.4.1"; +Export-Package: org.eclipse.jgit.http.server;version="7.5.1", + org.eclipse.jgit.http.server.glue;version="7.5.1"; uses:="jakarta.servlet, jakarta.servlet.http", - org.eclipse.jgit.http.server.resolver;version="7.4.1"; + org.eclipse.jgit.http.server.resolver;version="7.5.1"; uses:="jakarta.servlet.http org.eclipse.jgit.transport.resolver, org.eclipse.jgit.lib, org.eclipse.jgit.transport, 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.4.1,7.5.0)", - org.eclipse.jgit.errors;version="[7.4.1,7.5.0)", - org.eclipse.jgit.internal.storage.dfs;version="[7.4.1,7.5.0)", - org.eclipse.jgit.internal.storage.file;version="[7.4.1,7.5.0)", - org.eclipse.jgit.internal.transport.parser;version="[7.4.1,7.5.0)", - org.eclipse.jgit.lib;version="[7.4.1,7.5.0)", - org.eclipse.jgit.nls;version="[7.4.1,7.5.0)", - org.eclipse.jgit.revwalk;version="[7.4.1,7.5.0)", - org.eclipse.jgit.transport;version="[7.4.1,7.5.0)", - org.eclipse.jgit.transport.resolver;version="[7.4.1,7.5.0)", - org.eclipse.jgit.util;version="[7.4.1,7.5.0)" + org.eclipse.jgit.annotations;version="[7.5.1,7.6.0)", + org.eclipse.jgit.errors;version="[7.5.1,7.6.0)", + org.eclipse.jgit.internal.storage.dfs;version="[7.5.1,7.6.0)", + org.eclipse.jgit.internal.storage.file;version="[7.5.1,7.6.0)", + org.eclipse.jgit.internal.transport.parser;version="[7.5.1,7.6.0)", + org.eclipse.jgit.lib;version="[7.5.1,7.6.0)", + org.eclipse.jgit.nls;version="[7.5.1,7.6.0)", + org.eclipse.jgit.revwalk;version="[7.5.1,7.6.0)", + org.eclipse.jgit.transport;version="[7.5.1,7.6.0)", + org.eclipse.jgit.transport.resolver;version="[7.5.1,7.6.0)", + org.eclipse.jgit.util;version="[7.5.1,7.6.0)"
diff --git a/org.eclipse.jgit.http.server/META-INF/SOURCE-MANIFEST.MF b/org.eclipse.jgit.http.server/META-INF/SOURCE-MANIFEST.MF index e07aab5..8556eac 100644 --- a/org.eclipse.jgit.http.server/META-INF/SOURCE-MANIFEST.MF +++ b/org.eclipse.jgit.http.server/META-INF/SOURCE-MANIFEST.MF
@@ -3,6 +3,6 @@ Bundle-Name: org.eclipse.jgit.http.server - Sources Bundle-SymbolicName: org.eclipse.jgit.http.server.source Bundle-Vendor: Eclipse.org - JGit -Bundle-Version: 7.4.1.qualifier +Bundle-Version: 7.5.1.qualifier Bundle-SCM: url=https://github.com/eclipse-jgit/jgit, connection=scm:git:https://eclipse.gerrithub.io/eclipse-jgit/jgit.git, developerConnection=scm:git:https://eclipse.gerrithub.io/a/eclipse-jgit/jgit.git -Eclipse-SourceBundle: org.eclipse.jgit.http.server;version="7.4.1.qualifier";roots="." +Eclipse-SourceBundle: org.eclipse.jgit.http.server;version="7.5.1.qualifier";roots="."
diff --git a/org.eclipse.jgit.http.server/pom.xml b/org.eclipse.jgit.http.server/pom.xml index 8050bad..27a3d3e 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.4.1-SNAPSHOT</version> + <version>7.5.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 3c60ae2..cc47e35 100644 --- a/org.eclipse.jgit.http.test/META-INF/MANIFEST.MF +++ b/org.eclipse.jgit.http.test/META-INF/MANIFEST.MF
@@ -3,13 +3,11 @@ Bundle-Name: %Bundle-Name Automatic-Module-Name: org.eclipse.jgit.http.test Bundle-SymbolicName: org.eclipse.jgit.http.test -Bundle-Version: 7.4.1.qualifier +Bundle-Version: 7.5.1.qualifier Bundle-Vendor: %Bundle-Vendor Bundle-Localization: plugin Bundle-RequiredExecutionEnvironment: JavaSE-17 Bundle-SCM: url=https://github.com/eclipse-jgit/jgit, connection=scm:git:https://eclipse.gerrithub.io/eclipse-jgit/jgit.git, developerConnection=scm:git:https://eclipse.gerrithub.io/a/eclipse-jgit/jgit.git -Require-Bundle: org.hamcrest.core;bundle-version="[1.3.0,2.0.0)", - org.hamcrest.library;bundle-version="[1.3.0,2.0.0)" Import-Package: jakarta.servlet;version="[6.0.0,7.0.0)", jakarta.servlet.http;version="[6.0.0,7.0.0)", net.bytebuddy.agent;version="[1.9.0,2.0.0)", @@ -30,26 +28,27 @@ 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.4.1,7.5.0)", - org.eclipse.jgit.errors;version="[7.4.1,7.5.0)", - org.eclipse.jgit.http.server;version="[7.4.1,7.5.0)", - org.eclipse.jgit.http.server.glue;version="[7.4.1,7.5.0)", - org.eclipse.jgit.http.server.resolver;version="[7.4.1,7.5.0)", - org.eclipse.jgit.internal;version="[7.4.1,7.5.0)", - org.eclipse.jgit.internal.storage.dfs;version="[7.4.1,7.5.0)", - org.eclipse.jgit.internal.storage.file;version="[7.4.1,7.5.0)", - org.eclipse.jgit.internal.storage.reftable;version="[7.4.1,7.5.0)", - org.eclipse.jgit.junit;version="[7.4.1,7.5.0)", - org.eclipse.jgit.junit.http;version="[7.4.1,7.5.0)", - org.eclipse.jgit.lib;version="[7.4.1,7.5.0)", - org.eclipse.jgit.nls;version="[7.4.1,7.5.0)", - org.eclipse.jgit.revwalk;version="[7.4.1,7.5.0)", - org.eclipse.jgit.storage.file;version="[7.4.1,7.5.0)", - org.eclipse.jgit.transport;version="[7.4.1,7.5.0)", - org.eclipse.jgit.transport.http;version="[7.4.1,7.5.0)", - org.eclipse.jgit.transport.http.apache;version="[7.4.1,7.5.0)", - org.eclipse.jgit.transport.resolver;version="[7.4.1,7.5.0)", - org.eclipse.jgit.util;version="[7.4.1,7.5.0)", + org.eclipse.jgit.api;version="[7.5.1,7.6.0)", + org.eclipse.jgit.errors;version="[7.5.1,7.6.0)", + org.eclipse.jgit.http.server;version="[7.5.1,7.6.0)", + org.eclipse.jgit.http.server.glue;version="[7.5.1,7.6.0)", + org.eclipse.jgit.http.server.resolver;version="[7.5.1,7.6.0)", + org.eclipse.jgit.internal;version="[7.5.1,7.6.0)", + org.eclipse.jgit.internal.storage.dfs;version="[7.5.1,7.6.0)", + org.eclipse.jgit.internal.storage.file;version="[7.5.1,7.6.0)", + org.eclipse.jgit.internal.storage.reftable;version="[7.5.1,7.6.0)", + org.eclipse.jgit.junit;version="[7.5.1,7.6.0)", + org.eclipse.jgit.junit.http;version="[7.5.1,7.6.0)", + org.eclipse.jgit.lib;version="[7.5.1,7.6.0)", + org.eclipse.jgit.nls;version="[7.5.1,7.6.0)", + org.eclipse.jgit.revwalk;version="[7.5.1,7.6.0)", + org.eclipse.jgit.storage.file;version="[7.5.1,7.6.0)", + org.eclipse.jgit.transport;version="[7.5.1,7.6.0)", + org.eclipse.jgit.transport.http;version="[7.5.1,7.6.0)", + org.eclipse.jgit.transport.http.apache;version="[7.5.1,7.6.0)", + org.eclipse.jgit.transport.resolver;version="[7.5.1,7.6.0)", + org.eclipse.jgit.util;version="[7.5.1,7.6.0)", + org.hamcrest;version="[3.0.0,4.0.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 339213f..aa5d258 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.4.1-SNAPSHOT</version> + <version>7.5.1-SNAPSHOT</version> </parent> <artifactId>org.eclipse.jgit.http.test</artifactId>
diff --git a/org.eclipse.jgit.junit.http/META-INF/MANIFEST.MF b/org.eclipse.jgit.junit.http/META-INF/MANIFEST.MF index 9262f16..b0c2fd0 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.4.1.qualifier +Bundle-Version: 7.5.1.qualifier Bundle-Localization: OSGI-INF/l10n/plugin Bundle-Vendor: %Bundle-Vendor Bundle-ActivationPolicy: lazy @@ -23,17 +23,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.4.1,7.5.0)", - org.eclipse.jgit.http.server;version="[7.4.1,7.5.0)", - org.eclipse.jgit.internal.storage.file;version="[7.4.1,7.5.0)", - org.eclipse.jgit.junit;version="[7.4.1,7.5.0)", - org.eclipse.jgit.lib;version="[7.4.1,7.5.0)", - org.eclipse.jgit.revwalk;version="[7.4.1,7.5.0)", - org.eclipse.jgit.transport;version="[7.4.1,7.5.0)", - org.eclipse.jgit.transport.resolver;version="[7.4.1,7.5.0)", + org.eclipse.jgit.errors;version="[7.5.1,7.6.0)", + org.eclipse.jgit.http.server;version="[7.5.1,7.6.0)", + org.eclipse.jgit.internal.storage.file;version="[7.5.1,7.6.0)", + org.eclipse.jgit.junit;version="[7.5.1,7.6.0)", + org.eclipse.jgit.lib;version="[7.5.1,7.6.0)", + org.eclipse.jgit.revwalk;version="[7.5.1,7.6.0)", + org.eclipse.jgit.transport;version="[7.5.1,7.6.0)", + org.eclipse.jgit.transport.resolver;version="[7.5.1,7.6.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.4.1"; +Export-Package: org.eclipse.jgit.junit.http;version="7.5.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 1fffbbb..03e8795 100644 --- a/org.eclipse.jgit.junit.http/META-INF/SOURCE-MANIFEST.MF +++ b/org.eclipse.jgit.junit.http/META-INF/SOURCE-MANIFEST.MF
@@ -3,6 +3,6 @@ Bundle-Name: org.eclipse.jgit.junit.http - Sources Bundle-SymbolicName: org.eclipse.jgit.junit.http.source Bundle-Vendor: Eclipse.org - JGit -Bundle-Version: 7.4.1.qualifier +Bundle-Version: 7.5.1.qualifier Bundle-SCM: url=https://github.com/eclipse-jgit/jgit, connection=scm:git:https://eclipse.gerrithub.io/eclipse-jgit/jgit.git, developerConnection=scm:git:https://eclipse.gerrithub.io/a/eclipse-jgit/jgit.git -Eclipse-SourceBundle: org.eclipse.jgit.junit.http;version="7.4.1.qualifier";roots="." +Eclipse-SourceBundle: org.eclipse.jgit.junit.http;version="7.5.1.qualifier";roots="."
diff --git a/org.eclipse.jgit.junit.http/pom.xml b/org.eclipse.jgit.junit.http/pom.xml index cde5b2c..a840c4f 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.4.1-SNAPSHOT</version> + <version>7.5.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 6a20aac..7b62993 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.4.1.qualifier +Bundle-Version: 7.5.1.qualifier Bundle-Localization: OSGI-INF/l10n/plugin Bundle-Vendor: %Bundle-Vendor Bundle-ActivationPolicy: lazy @@ -34,16 +34,16 @@ org.apache.sshd.server.subsystem;version="[2.16.0,2.17.0)", org.apache.sshd.sftp;version="[2.16.0,2.17.0)", org.apache.sshd.sftp.server;version="[2.16.0,2.17.0)", - org.eclipse.jgit.annotations;version="[7.4.1,7.5.0)", - org.eclipse.jgit.api;version="[7.4.1,7.5.0)", - org.eclipse.jgit.api.errors;version="[7.4.1,7.5.0)", - org.eclipse.jgit.errors;version="[7.4.1,7.5.0)", - org.eclipse.jgit.junit;version="[7.4.1,7.5.0)", - org.eclipse.jgit.lib;version="[7.4.1,7.5.0)", - org.eclipse.jgit.revwalk;version="[7.4.1,7.5.0)", - org.eclipse.jgit.transport;version="[7.4.1,7.5.0)", - org.eclipse.jgit.util;version="[7.4.1,7.5.0)", + org.eclipse.jgit.annotations;version="[7.5.1,7.6.0)", + org.eclipse.jgit.api;version="[7.5.1,7.6.0)", + org.eclipse.jgit.api.errors;version="[7.5.1,7.6.0)", + org.eclipse.jgit.errors;version="[7.5.1,7.6.0)", + org.eclipse.jgit.junit;version="[7.5.1,7.6.0)", + org.eclipse.jgit.lib;version="[7.5.1,7.6.0)", + org.eclipse.jgit.revwalk;version="[7.5.1,7.6.0)", + org.eclipse.jgit.transport;version="[7.5.1,7.6.0)", + org.eclipse.jgit.util;version="[7.5.1,7.6.0)", org.junit;version="[4.13,5.0.0)", org.junit.experimental.theories;version="[4.13,5.0.0)", org.slf4j;version="[1.7.0,3.0.0)" -Export-Package: org.eclipse.jgit.junit.ssh;version="7.4.1" +Export-Package: org.eclipse.jgit.junit.ssh;version="7.5.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 498244c..3202ac0 100644 --- a/org.eclipse.jgit.junit.ssh/META-INF/SOURCE-MANIFEST.MF +++ b/org.eclipse.jgit.junit.ssh/META-INF/SOURCE-MANIFEST.MF
@@ -3,6 +3,6 @@ Bundle-Name: org.eclipse.jgit.junit.ssh - Sources Bundle-SymbolicName: org.eclipse.jgit.junit.ssh.source Bundle-Vendor: Eclipse.org - JGit -Bundle-Version: 7.4.1.qualifier +Bundle-Version: 7.5.1.qualifier Bundle-SCM: url=https://github.com/eclipse-jgit/jgit, connection=scm:git:https://eclipse.gerrithub.io/eclipse-jgit/jgit.git, developerConnection=scm:git:https://eclipse.gerrithub.io/a/eclipse-jgit/jgit.git -Eclipse-SourceBundle: org.eclipse.jgit.junit.ssh;version="7.4.1.qualifier";roots="." +Eclipse-SourceBundle: org.eclipse.jgit.junit.ssh;version="7.5.1.qualifier";roots="."
diff --git a/org.eclipse.jgit.junit.ssh/pom.xml b/org.eclipse.jgit.junit.ssh/pom.xml index 51a2d4e..b596c7b 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.4.1-SNAPSHOT</version> + <version>7.5.1-SNAPSHOT</version> </parent> <artifactId>org.eclipse.jgit.junit.ssh</artifactId>
diff --git a/org.eclipse.jgit.junit/.settings/.api_filters b/org.eclipse.jgit.junit/.settings/.api_filters deleted file mode 100644 index 2781530..0000000 --- a/org.eclipse.jgit.junit/.settings/.api_filters +++ /dev/null
@@ -1,11 +0,0 @@ -<?xml version="1.0" encoding="UTF-8" standalone="no"?> -<component id="org.eclipse.jgit.junit" version="2"> - <resource path="src/org/eclipse/jgit/junit/LocalDiskRepositoryTestCase.java" type="org.eclipse.jgit.junit.LocalDiskRepositoryTestCase"> - <filter id="336658481"> - <message_arguments> - <message_argument value="org.eclipse.jgit.junit.LocalDiskRepositoryTestCase"/> - <message_argument value="testRoot"/> - </message_arguments> - </filter> - </resource> -</component>
diff --git a/org.eclipse.jgit.junit/META-INF/MANIFEST.MF b/org.eclipse.jgit.junit/META-INF/MANIFEST.MF index 10dce2c..4c01b09 100644 --- a/org.eclipse.jgit.junit/META-INF/MANIFEST.MF +++ b/org.eclipse.jgit.junit/META-INF/MANIFEST.MF
@@ -3,38 +3,38 @@ Bundle-Name: %Bundle-Name Automatic-Module-Name: org.eclipse.jgit.junit Bundle-SymbolicName: org.eclipse.jgit.junit -Bundle-Version: 7.4.1.qualifier +Bundle-Version: 7.5.1.qualifier Bundle-Localization: OSGI-INF/l10n/plugin Bundle-Vendor: %Bundle-Vendor Bundle-ActivationPolicy: lazy Bundle-RequiredExecutionEnvironment: JavaSE-17 Bundle-SCM: url=https://github.com/eclipse-jgit/jgit, connection=scm:git:https://eclipse.gerrithub.io/eclipse-jgit/jgit.git, developerConnection=scm:git:https://eclipse.gerrithub.io/a/eclipse-jgit/jgit.git -Import-Package: org.eclipse.jgit.annotations;version="[7.4.1,7.5.0)", - org.eclipse.jgit.api;version="[7.4.1,7.5.0)", - org.eclipse.jgit.api.errors;version="[7.4.1,7.5.0)", - org.eclipse.jgit.dircache;version="[7.4.1,7.5.0)", - org.eclipse.jgit.errors;version="[7.4.1,7.5.0)", - org.eclipse.jgit.internal.storage.file;version="[7.4.1,7.5.0)", - org.eclipse.jgit.internal.storage.pack;version="[7.4.1,7.5.0)", - org.eclipse.jgit.internal.util;version="[7.4.1,7.5.0)", - org.eclipse.jgit.lib;version="[7.4.1,7.5.0)", - org.eclipse.jgit.merge;version="[7.4.1,7.5.0)", - org.eclipse.jgit.revwalk;version="[7.4.1,7.5.0)", - org.eclipse.jgit.storage.file;version="[7.4.1,7.5.0)", - org.eclipse.jgit.storage.pack;version="[7.4.1,7.5.0)", - org.eclipse.jgit.transport;version="7.4.1", - org.eclipse.jgit.treewalk;version="[7.4.1,7.5.0)", - org.eclipse.jgit.treewalk.filter;version="[7.4.1,7.5.0)", - org.eclipse.jgit.util;version="[7.4.1,7.5.0)", - org.eclipse.jgit.util.io;version="[7.4.1,7.5.0)", - org.eclipse.jgit.util.time;version="[7.4.1,7.5.0)", +Import-Package: org.eclipse.jgit.annotations;version="[7.5.1,7.6.0)", + org.eclipse.jgit.api;version="[7.5.1,7.6.0)", + org.eclipse.jgit.api.errors;version="[7.5.1,7.6.0)", + org.eclipse.jgit.dircache;version="[7.5.1,7.6.0)", + org.eclipse.jgit.errors;version="[7.5.1,7.6.0)", + org.eclipse.jgit.internal.storage.file;version="[7.5.1,7.6.0)", + org.eclipse.jgit.internal.storage.pack;version="[7.5.1,7.6.0)", + org.eclipse.jgit.internal.util;version="[7.5.1,7.6.0)", + org.eclipse.jgit.lib;version="[7.5.1,7.6.0)", + org.eclipse.jgit.merge;version="[7.5.1,7.6.0)", + org.eclipse.jgit.revwalk;version="[7.5.1,7.6.0)", + org.eclipse.jgit.storage.file;version="[7.5.1,7.6.0)", + org.eclipse.jgit.storage.pack;version="[7.5.1,7.6.0)", + org.eclipse.jgit.transport;version="7.5.1", + org.eclipse.jgit.treewalk;version="[7.5.1,7.6.0)", + org.eclipse.jgit.treewalk.filter;version="[7.5.1,7.6.0)", + org.eclipse.jgit.util;version="[7.5.1,7.6.0)", + org.eclipse.jgit.util.io;version="[7.5.1,7.6.0)", + org.eclipse.jgit.util.time;version="[7.5.1,7.6.0)", org.junit;version="[4.13,5.0.0)", org.junit.rules;version="[4.13,5.0.0)", org.junit.runner;version="[4.13,5.0.0)", org.junit.runners;version="[4.13,5.0.0)", org.junit.runners.model;version="[4.13,5.0.0)", org.slf4j;version="[1.7.0,3.0.0)" -Export-Package: org.eclipse.jgit.junit;version="7.4.1"; +Export-Package: org.eclipse.jgit.junit;version="7.5.1"; uses:="org.eclipse.jgit.dircache, org.eclipse.jgit.lib, org.eclipse.jgit.revwalk, @@ -47,4 +47,4 @@ org.junit.runners.model, org.junit.runner, org.eclipse.jgit.util.time", - org.eclipse.jgit.junit.time;version="7.4.1";uses:="org.eclipse.jgit.util.time" + org.eclipse.jgit.junit.time;version="7.5.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 364082e..77e9a51 100644 --- a/org.eclipse.jgit.junit/META-INF/SOURCE-MANIFEST.MF +++ b/org.eclipse.jgit.junit/META-INF/SOURCE-MANIFEST.MF
@@ -3,6 +3,6 @@ Bundle-Name: org.eclipse.jgit.junit - Sources Bundle-SymbolicName: org.eclipse.jgit.junit.source Bundle-Vendor: Eclipse.org - JGit -Bundle-Version: 7.4.1.qualifier +Bundle-Version: 7.5.1.qualifier Bundle-SCM: url=https://github.com/eclipse-jgit/jgit, connection=scm:git:https://eclipse.gerrithub.io/eclipse-jgit/jgit.git, developerConnection=scm:git:https://eclipse.gerrithub.io/a/eclipse-jgit/jgit.git -Eclipse-SourceBundle: org.eclipse.jgit.junit;version="7.4.1.qualifier";roots="." +Eclipse-SourceBundle: org.eclipse.jgit.junit;version="7.5.1.qualifier";roots="."
diff --git a/org.eclipse.jgit.junit/pom.xml b/org.eclipse.jgit.junit/pom.xml index 20cd3eb..f02ecbf 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.4.1-SNAPSHOT</version> + <version>7.5.1-SNAPSHOT</version> </parent> <artifactId>org.eclipse.jgit.junit</artifactId>
diff --git a/org.eclipse.jgit.junit/src/org/eclipse/jgit/junit/FakeIndexFactory.java b/org.eclipse.jgit.junit/src/org/eclipse/jgit/junit/FakeIndexFactory.java index eb23bec..a1d28c9 100644 --- a/org.eclipse.jgit.junit/src/org/eclipse/jgit/junit/FakeIndexFactory.java +++ b/org.eclipse.jgit.junit/src/org/eclipse/jgit/junit/FakeIndexFactory.java
@@ -188,7 +188,7 @@ public void verifyPackChecksum(String packFilePath) { @Override public ObjectId findObject(long offset) { - IndexObject indexObject = ridx.get(offset); + IndexObject indexObject = ridx.get(Long.valueOf(offset)); if (indexObject == null) { return null; } @@ -198,7 +198,7 @@ public ObjectId findObject(long offset) { @Override public long findNextOffset(long offset, long maxOffset) throws CorruptObjectException { - IndexObject o = ridx.get(offset); + IndexObject o = ridx.get(Long.valueOf(offset)); if (o == null) { throw new CorruptObjectException("Invalid offset"); //$NON-NLS-1$ } @@ -211,7 +211,7 @@ public long findNextOffset(long offset, long maxOffset) @Override public int findPosition(long offset) { - IndexObject indexObject = ridx.get(offset); + IndexObject indexObject = ridx.get(Long.valueOf(offset)); return byOffset.indexOf(indexObject); }
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 02b7a69..36a0724 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.4.1.qualifier +Bundle-Version: 7.5.1.qualifier Bundle-Vendor: %Bundle-Vendor Bundle-Localization: plugin Bundle-RequiredExecutionEnvironment: JavaSE-17 @@ -27,25 +27,25 @@ 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.4.1,7.5.0)", - org.eclipse.jgit.api.errors;version="[7.4.1,7.5.0)", - org.eclipse.jgit.internal.storage.file;version="[7.4.1,7.5.0)", - org.eclipse.jgit.junit;version="[7.4.1,7.5.0)", - org.eclipse.jgit.junit.http;version="[7.4.1,7.5.0)", - org.eclipse.jgit.lfs;version="[7.4.1,7.5.0)", - org.eclipse.jgit.lfs.errors;version="[7.4.1,7.5.0)", - org.eclipse.jgit.lfs.lib;version="[7.4.1,7.5.0)", - org.eclipse.jgit.lfs.server;version="[7.4.1,7.5.0)", - org.eclipse.jgit.lfs.server.fs;version="[7.4.1,7.5.0)", - org.eclipse.jgit.lfs.test;version="[7.4.1,7.5.0)", - org.eclipse.jgit.lib;version="[7.4.1,7.5.0)", - org.eclipse.jgit.revwalk;version="[7.4.1,7.5.0)", - org.eclipse.jgit.storage.file;version="[7.4.1,7.5.0)", - org.eclipse.jgit.transport;version="[7.4.1,7.5.0)", - org.eclipse.jgit.treewalk;version="[7.4.1,7.5.0)", - org.eclipse.jgit.treewalk.filter;version="[7.4.1,7.5.0)", - org.eclipse.jgit.util;version="[7.4.1,7.5.0)", - org.hamcrest.core;version="[1.1.0,3.0.0)", + org.eclipse.jgit.api;version="[7.5.1,7.6.0)", + org.eclipse.jgit.api.errors;version="[7.5.1,7.6.0)", + org.eclipse.jgit.internal.storage.file;version="[7.5.1,7.6.0)", + org.eclipse.jgit.junit;version="[7.5.1,7.6.0)", + org.eclipse.jgit.junit.http;version="[7.5.1,7.6.0)", + org.eclipse.jgit.lfs;version="[7.5.1,7.6.0)", + org.eclipse.jgit.lfs.errors;version="[7.5.1,7.6.0)", + org.eclipse.jgit.lfs.lib;version="[7.5.1,7.6.0)", + org.eclipse.jgit.lfs.server;version="[7.5.1,7.6.0)", + org.eclipse.jgit.lfs.server.fs;version="[7.5.1,7.6.0)", + org.eclipse.jgit.lfs.test;version="[7.5.1,7.6.0)", + org.eclipse.jgit.lib;version="[7.5.1,7.6.0)", + org.eclipse.jgit.revwalk;version="[7.5.1,7.6.0)", + org.eclipse.jgit.storage.file;version="[7.5.1,7.6.0)", + org.eclipse.jgit.transport;version="[7.5.1,7.6.0)", + org.eclipse.jgit.treewalk;version="[7.5.1,7.6.0)", + org.eclipse.jgit.treewalk.filter;version="[7.5.1,7.6.0)", + org.eclipse.jgit.util;version="[7.5.1,7.6.0)", + org.hamcrest;version="[3.0.0,4.0.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.lfs.server.test/pom.xml b/org.eclipse.jgit.lfs.server.test/pom.xml index f00f85e..346c3d3 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.4.1-SNAPSHOT</version> + <version>7.5.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 5ef7b85..51577c3 100644 --- a/org.eclipse.jgit.lfs.server/META-INF/MANIFEST.MF +++ b/org.eclipse.jgit.lfs.server/META-INF/MANIFEST.MF
@@ -3,21 +3,21 @@ Bundle-Name: %Bundle-Name Automatic-Module-Name: org.eclipse.jgit.lfs.server Bundle-SymbolicName: org.eclipse.jgit.lfs.server -Bundle-Version: 7.4.1.qualifier +Bundle-Version: 7.5.1.qualifier Bundle-Localization: OSGI-INF/l10n/plugin Bundle-Vendor: %Bundle-Vendor Bundle-RequiredExecutionEnvironment: JavaSE-17 Bundle-SCM: url=https://github.com/eclipse-jgit/jgit, connection=scm:git:https://eclipse.gerrithub.io/eclipse-jgit/jgit.git, developerConnection=scm:git:https://eclipse.gerrithub.io/a/eclipse-jgit/jgit.git -Export-Package: org.eclipse.jgit.lfs.server;version="7.4.1"; +Export-Package: org.eclipse.jgit.lfs.server;version="7.5.1"; uses:="jakarta.servlet.http, org.eclipse.jgit.lfs.lib", - org.eclipse.jgit.lfs.server.fs;version="7.4.1"; + org.eclipse.jgit.lfs.server.fs;version="7.5.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.4.1";x-internal:=true, - org.eclipse.jgit.lfs.server.s3;version="7.4.1"; + org.eclipse.jgit.lfs.server.internal;version="7.5.1";x-internal:=true, + org.eclipse.jgit.lfs.server.s3;version="7.5.1"; uses:="org.eclipse.jgit.lfs.server, org.eclipse.jgit.lfs.lib" Import-Package: com.google.gson;version="[2.8.0,3.0.0)", @@ -25,15 +25,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.4.1,7.5.0)", - org.eclipse.jgit.internal;version="[7.4.1,7.5.0)", - org.eclipse.jgit.internal.storage.file;version="[7.4.1,7.5.0)", - org.eclipse.jgit.lfs.errors;version="[7.4.1,7.5.0)", - org.eclipse.jgit.lfs.internal;version="[7.4.1,7.5.0)", - org.eclipse.jgit.lfs.lib;version="[7.4.1,7.5.0)", - org.eclipse.jgit.lib;version="[7.4.1,7.5.0)", - org.eclipse.jgit.nls;version="[7.4.1,7.5.0)", - org.eclipse.jgit.transport.http;version="[7.4.1,7.5.0)", - org.eclipse.jgit.transport.http.apache;version="[7.4.1,7.5.0)", - org.eclipse.jgit.util;version="[7.4.1,7.5.0)", + org.eclipse.jgit.annotations;version="[7.5.1,7.6.0)", + org.eclipse.jgit.internal;version="[7.5.1,7.6.0)", + org.eclipse.jgit.internal.storage.file;version="[7.5.1,7.6.0)", + org.eclipse.jgit.lfs.errors;version="[7.5.1,7.6.0)", + org.eclipse.jgit.lfs.internal;version="[7.5.1,7.6.0)", + org.eclipse.jgit.lfs.lib;version="[7.5.1,7.6.0)", + org.eclipse.jgit.lib;version="[7.5.1,7.6.0)", + org.eclipse.jgit.nls;version="[7.5.1,7.6.0)", + org.eclipse.jgit.transport.http;version="[7.5.1,7.6.0)", + org.eclipse.jgit.transport.http.apache;version="[7.5.1,7.6.0)", + org.eclipse.jgit.util;version="[7.5.1,7.6.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 9dcf4b8..16a895d 100644 --- a/org.eclipse.jgit.lfs.server/META-INF/SOURCE-MANIFEST.MF +++ b/org.eclipse.jgit.lfs.server/META-INF/SOURCE-MANIFEST.MF
@@ -3,6 +3,6 @@ Bundle-Name: org.eclipse.jgit.lfs.server - Sources Bundle-SymbolicName: org.eclipse.jgit.lfs.server.source Bundle-Vendor: Eclipse.org - JGit -Bundle-Version: 7.4.1.qualifier +Bundle-Version: 7.5.1.qualifier Bundle-SCM: url=https://github.com/eclipse-jgit/jgit, connection=scm:git:https://eclipse.gerrithub.io/eclipse-jgit/jgit.git, developerConnection=scm:git:https://eclipse.gerrithub.io/a/eclipse-jgit/jgit.git -Eclipse-SourceBundle: org.eclipse.jgit.lfs.server;version="7.4.1.qualifier";roots="." +Eclipse-SourceBundle: org.eclipse.jgit.lfs.server;version="7.5.1.qualifier";roots="."
diff --git a/org.eclipse.jgit.lfs.server/pom.xml b/org.eclipse.jgit.lfs.server/pom.xml index 875b486..61c3557 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.4.1-SNAPSHOT</version> + <version>7.5.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 189cfc0..116fb5c 100644 --- a/org.eclipse.jgit.lfs.test/META-INF/MANIFEST.MF +++ b/org.eclipse.jgit.lfs.test/META-INF/MANIFEST.MF
@@ -3,29 +3,29 @@ Bundle-Name: %Bundle-Name Automatic-Module-Name: org.eclipse.jgit.lfs.test Bundle-SymbolicName: org.eclipse.jgit.lfs.test -Bundle-Version: 7.4.1.qualifier +Bundle-Version: 7.5.1.qualifier Bundle-Vendor: %Bundle-Vendor Bundle-Localization: plugin Bundle-RequiredExecutionEnvironment: JavaSE-17 Bundle-SCM: url=https://github.com/eclipse-jgit/jgit, connection=scm:git:https://eclipse.gerrithub.io/eclipse-jgit/jgit.git, developerConnection=scm:git:https://eclipse.gerrithub.io/a/eclipse-jgit/jgit.git -Import-Package: org.eclipse.jgit.api;version="[7.4.1,7.5.0)", - org.eclipse.jgit.attributes;version="[7.4.1,7.5.0)", - org.eclipse.jgit.internal.storage.dfs;version="[7.4.1,7.5.0)", - org.eclipse.jgit.internal.storage.file;version="[7.4.1,7.5.0)", - org.eclipse.jgit.junit;version="[7.4.1,7.5.0)", - org.eclipse.jgit.lfs;version="[7.4.1,7.5.0)", - org.eclipse.jgit.lfs.errors;version="[7.4.1,7.5.0)", - org.eclipse.jgit.lfs.internal;version="[7.4.1,7.5.0)", - org.eclipse.jgit.lfs.lib;version="[7.4.1,7.5.0)", - org.eclipse.jgit.lib;version="[7.4.1,7.5.0)", - org.eclipse.jgit.revwalk;version="[7.4.1,7.5.0)", - org.eclipse.jgit.transport;version="[7.4.1,7.5.0)", - org.eclipse.jgit.transport.http;version="[7.4.1,7.5.0)", - org.eclipse.jgit.treewalk;version="[7.4.1,7.5.0)", - org.eclipse.jgit.treewalk.filter;version="[7.4.1,7.5.0)", - org.eclipse.jgit.util;version="[7.4.1,7.5.0)", - org.hamcrest.core;version="[1.1.0,3.0.0)", +Import-Package: org.eclipse.jgit.api;version="[7.5.1,7.6.0)", + org.eclipse.jgit.attributes;version="[7.5.1,7.6.0)", + org.eclipse.jgit.internal.storage.dfs;version="[7.5.1,7.6.0)", + org.eclipse.jgit.internal.storage.file;version="[7.5.1,7.6.0)", + org.eclipse.jgit.junit;version="[7.5.1,7.6.0)", + org.eclipse.jgit.lfs;version="[7.5.1,7.6.0)", + org.eclipse.jgit.lfs.errors;version="[7.5.1,7.6.0)", + org.eclipse.jgit.lfs.internal;version="[7.5.1,7.6.0)", + org.eclipse.jgit.lfs.lib;version="[7.5.1,7.6.0)", + org.eclipse.jgit.lib;version="[7.5.1,7.6.0)", + org.eclipse.jgit.revwalk;version="[7.5.1,7.6.0)", + org.eclipse.jgit.transport;version="[7.5.1,7.6.0)", + org.eclipse.jgit.transport.http;version="[7.5.1,7.6.0)", + org.eclipse.jgit.treewalk;version="[7.5.1,7.6.0)", + org.eclipse.jgit.treewalk.filter;version="[7.5.1,7.6.0)", + org.eclipse.jgit.util;version="[7.5.1,7.6.0)", + org.hamcrest;version="[3.0.0,4.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.4.1";x-friends:="org.eclipse.jgit.lfs.server.test" +Export-Package: org.eclipse.jgit.lfs.test;version="7.5.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 cdd9ee3..011781c 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.4.1-SNAPSHOT</version> + <version>7.5.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 d6e2bec..ac88fc7 100644 --- a/org.eclipse.jgit.lfs/META-INF/MANIFEST.MF +++ b/org.eclipse.jgit.lfs/META-INF/MANIFEST.MF
@@ -3,33 +3,33 @@ Bundle-Name: %Bundle-Name Automatic-Module-Name: org.eclipse.jgit.lfs Bundle-SymbolicName: org.eclipse.jgit.lfs -Bundle-Version: 7.4.1.qualifier +Bundle-Version: 7.5.1.qualifier Bundle-Localization: OSGI-INF/l10n/plugin Bundle-Vendor: %Bundle-Vendor Bundle-RequiredExecutionEnvironment: JavaSE-17 Bundle-SCM: url=https://github.com/eclipse-jgit/jgit, connection=scm:git:https://eclipse.gerrithub.io/eclipse-jgit/jgit.git, developerConnection=scm:git:https://eclipse.gerrithub.io/a/eclipse-jgit/jgit.git -Export-Package: org.eclipse.jgit.lfs;version="7.4.1", - org.eclipse.jgit.lfs.errors;version="7.4.1", - org.eclipse.jgit.lfs.internal;version="7.4.1";x-friends:="org.eclipse.jgit.lfs.test,org.eclipse.jgit.lfs.server.fs,org.eclipse.jgit.lfs.server", - org.eclipse.jgit.lfs.lib;version="7.4.1" +Export-Package: org.eclipse.jgit.lfs;version="7.5.1", + org.eclipse.jgit.lfs.errors;version="7.5.1", + org.eclipse.jgit.lfs.internal;version="7.5.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.5.1" 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.4.1,7.5.0)";resolution:=optional, - org.eclipse.jgit.api.errors;version="[7.4.1,7.5.0)", - org.eclipse.jgit.attributes;version="[7.4.1,7.5.0)", - org.eclipse.jgit.diff;version="[7.4.1,7.5.0)", - org.eclipse.jgit.dircache;version="[7.4.1,7.5.0)", - org.eclipse.jgit.errors;version="[7.4.1,7.5.0)", - org.eclipse.jgit.hooks;version="[7.4.1,7.5.0)", - org.eclipse.jgit.internal.storage.file;version="[7.4.1,7.5.0)", - org.eclipse.jgit.lib;version="[7.4.1,7.5.0)", - org.eclipse.jgit.nls;version="[7.4.1,7.5.0)", - org.eclipse.jgit.revwalk;version="[7.4.1,7.5.0)", - org.eclipse.jgit.storage.file;version="[7.4.1,7.5.0)", - org.eclipse.jgit.storage.pack;version="[7.4.1,7.5.0)", - org.eclipse.jgit.transport;version="[7.4.1,7.5.0)", - org.eclipse.jgit.transport.http;version="[7.4.1,7.5.0)", - org.eclipse.jgit.treewalk;version="[7.4.1,7.5.0)", - org.eclipse.jgit.treewalk.filter;version="[7.4.1,7.5.0)", - org.eclipse.jgit.util;version="[7.4.1,7.5.0)", - org.eclipse.jgit.util.io;version="[7.4.1,7.5.0)" + org.eclipse.jgit.annotations;version="[7.5.1,7.6.0)";resolution:=optional, + org.eclipse.jgit.api.errors;version="[7.5.1,7.6.0)", + org.eclipse.jgit.attributes;version="[7.5.1,7.6.0)", + org.eclipse.jgit.diff;version="[7.5.1,7.6.0)", + org.eclipse.jgit.dircache;version="[7.5.1,7.6.0)", + org.eclipse.jgit.errors;version="[7.5.1,7.6.0)", + org.eclipse.jgit.hooks;version="[7.5.1,7.6.0)", + org.eclipse.jgit.internal.storage.file;version="[7.5.1,7.6.0)", + org.eclipse.jgit.lib;version="[7.5.1,7.6.0)", + org.eclipse.jgit.nls;version="[7.5.1,7.6.0)", + org.eclipse.jgit.revwalk;version="[7.5.1,7.6.0)", + org.eclipse.jgit.storage.file;version="[7.5.1,7.6.0)", + org.eclipse.jgit.storage.pack;version="[7.5.1,7.6.0)", + org.eclipse.jgit.transport;version="[7.5.1,7.6.0)", + org.eclipse.jgit.transport.http;version="[7.5.1,7.6.0)", + org.eclipse.jgit.treewalk;version="[7.5.1,7.6.0)", + org.eclipse.jgit.treewalk.filter;version="[7.5.1,7.6.0)", + org.eclipse.jgit.util;version="[7.5.1,7.6.0)", + org.eclipse.jgit.util.io;version="[7.5.1,7.6.0)"
diff --git a/org.eclipse.jgit.lfs/META-INF/SOURCE-MANIFEST.MF b/org.eclipse.jgit.lfs/META-INF/SOURCE-MANIFEST.MF index 8da8f95..69d6100 100644 --- a/org.eclipse.jgit.lfs/META-INF/SOURCE-MANIFEST.MF +++ b/org.eclipse.jgit.lfs/META-INF/SOURCE-MANIFEST.MF
@@ -3,6 +3,6 @@ Bundle-Name: org.eclipse.jgit.lfs - Sources Bundle-SymbolicName: org.eclipse.jgit.lfs.source Bundle-Vendor: Eclipse.org - JGit -Bundle-Version: 7.4.1.qualifier +Bundle-Version: 7.5.1.qualifier Bundle-SCM: url=https://github.com/eclipse-jgit/jgit, connection=scm:git:https://eclipse.gerrithub.io/eclipse-jgit/jgit.git, developerConnection=scm:git:https://eclipse.gerrithub.io/a/eclipse-jgit/jgit.git -Eclipse-SourceBundle: org.eclipse.jgit.lfs;version="7.4.1.qualifier";roots="." +Eclipse-SourceBundle: org.eclipse.jgit.lfs;version="7.5.1.qualifier";roots="."
diff --git a/org.eclipse.jgit.lfs/pom.xml b/org.eclipse.jgit.lfs/pom.xml index fe65299..3e58809 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.4.1-SNAPSHOT</version> + <version>7.5.1-SNAPSHOT</version> </parent> <artifactId>org.eclipse.jgit.lfs</artifactId>
diff --git a/org.eclipse.jgit.lfs/src/org/eclipse/jgit/lfs/LfsPrePushHook.java b/org.eclipse.jgit.lfs/src/org/eclipse/jgit/lfs/LfsPrePushHook.java index 802835c..fbccc56 100644 --- a/org.eclipse.jgit.lfs/src/org/eclipse/jgit/lfs/LfsPrePushHook.java +++ b/org.eclipse.jgit.lfs/src/org/eclipse/jgit/lfs/LfsPrePushHook.java
@@ -13,6 +13,7 @@ import static org.eclipse.jgit.lfs.Protocol.OPERATION_UPLOAD; import static org.eclipse.jgit.lfs.internal.LfsConnectionFactory.toRequest; import static org.eclipse.jgit.transport.http.HttpConnection.HTTP_OK; +import static org.eclipse.jgit.transport.http.HttpConnection.HTTP_CREATED; import static org.eclipse.jgit.util.HttpSupport.METHOD_POST; import static org.eclipse.jgit.util.HttpSupport.METHOD_PUT; @@ -255,7 +256,7 @@ private void uploadFile(Protocol.ObjectInfo o, } } int responseCode = contentServer.getResponseCode(); - if (responseCode != HTTP_OK) { + if (responseCode != HTTP_OK && responseCode != HTTP_CREATED) { throw new IOException(MessageFormat.format( LfsText.get().serverFailure, contentServer.getURL(), Integer.valueOf(responseCode)));
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 06d1578..bb374ff 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.4.1.qualifier" + version="7.5.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 ff19611..c890a56 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.4.1-SNAPSHOT</version> + <version>7.5.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 e56b452..e544ec6 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.4.1.qualifier" + version="7.5.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.4.1" match="equivalent"/> + <import plugin="org.eclipse.jgit" version="7.5.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 0727a43..77f7c73 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.4.1-SNAPSHOT</version> + <version>7.5.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 631b721..014382b 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.4.1.qualifier" + version="7.5.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.4.1" match="equivalent"/> + <import plugin="org.eclipse.jgit" version="7.5.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 dbc8397..b2b8faa 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.4.1-SNAPSHOT</version> + <version>7.5.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 bb6bfea..01d927e 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.4.1.qualifier" + version="7.5.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.4.1" match="equivalent"/> + <import plugin="org.eclipse.jgit" version="7.5.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 ac8dbb5..687df88 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.4.1-SNAPSHOT</version> + <version>7.5.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 decb642..b4ba75e 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.4.1.qualifier" + version="7.5.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.4.1" match="equivalent"/> + <import feature="org.eclipse.jgit" version="7.5.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 7cc8c01..f7207f2 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.4.1-SNAPSHOT</version> + <version>7.5.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 f06516e..82978df 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.4.1.qualifier" + version="7.5.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.4.1" match="equivalent"/> - <import feature="org.eclipse.jgit.lfs" version="7.4.1" match="equivalent"/> - <import feature="org.eclipse.jgit.ssh.apache" version="7.4.1" match="equivalent"/> + <import feature="org.eclipse.jgit" version="7.5.1" match="equivalent"/> + <import feature="org.eclipse.jgit.lfs" version="7.5.1" match="equivalent"/> + <import feature="org.eclipse.jgit.ssh.apache" version="7.5.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 71c8a39..0249b15 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.4.1-SNAPSHOT</version> + <version>7.5.1-SNAPSHOT</version> </parent> <groupId>org.eclipse.jgit.feature</groupId>
diff --git a/org.eclipse.jgit.packaging/org.eclipse.jgit.repository/category.xml b/org.eclipse.jgit.packaging/org.eclipse.jgit.repository/category.xml index eef699c..08294c7 100644 --- a/org.eclipse.jgit.packaging/org.eclipse.jgit.repository/category.xml +++ b/org.eclipse.jgit.packaging/org.eclipse.jgit.repository/category.xml
@@ -234,6 +234,24 @@ <bundle id="org.osgi.service.cm.source"> <category name="JGit-dependency-bundles"/> </bundle> + <bundle id="org.objectweb.asm"> + <category name="JGit-dependency-bundles"/> + </bundle> + <bundle id="org.objectweb.asm.commons"> + <category name="JGit-dependency-bundles"/> + </bundle> + <bundle id="org.objectweb.asm.util"> + <category name="JGit-dependency-bundles"/> + </bundle> + <bundle id="org.objectweb.asm.tree"> + <category name="JGit-dependency-bundles"/> + </bundle> + <bundle id="org.objectweb.asm.tree.analysis"> + <category name="JGit-dependency-bundles"/> + </bundle> + <bundle id="org.apache.aries.spifly.dynamic.bundle"> + <category name="JGit-dependency-bundles"/> + </bundle> <category-def name="JGit" label="Java implementation of Git"> <description> Java implementation of Git
diff --git a/org.eclipse.jgit.packaging/org.eclipse.jgit.repository/pom.xml b/org.eclipse.jgit.packaging/org.eclipse.jgit.repository/pom.xml index 1e5a9b4..0e6e88f 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.4.1-SNAPSHOT</version> + <version>7.5.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 eb2494b..14022eb 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.4.1.qualifier" + version="7.5.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.4.1" match="equivalent"/> + <import feature="org.eclipse.jgit" version="7.5.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 11ccb15..777b856 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.4.1-SNAPSHOT</version> + <version>7.5.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.4.1-SNAPSHOT</version> + <version>7.5.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 09c8938..48edba8 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.4.1.qualifier" + version="7.5.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.4.1" match="equivalent"/> + <import feature="org.eclipse.jgit" version="7.5.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 d0988b7..7aa2732 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.4.1-SNAPSHOT</version> + <version>7.5.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 7617dbd..e48160a 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.4.1.qualifier" + version="7.5.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.4.1" match="equivalent"/> + <import plugin="org.eclipse.jgit" version="7.5.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 ad87d14..f79389f 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.4.1-SNAPSHOT</version> + <version>7.5.1-SNAPSHOT</version> </parent> <groupId>org.eclipse.jgit.feature</groupId>
diff --git a/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.32.tpd b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.32.tpd deleted file mode 100644 index b8574c7..0000000 --- a/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.32.tpd +++ /dev/null
@@ -1,8 +0,0 @@ -target "jgit-4.32" with source configurePhase - -include "orbit/orbit-4.32.tpd" -include "maven/dependencies.tpd" - -location "https://download.eclipse.org/staging/2024-06/" { - org.eclipse.osgi lazy -}
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 deleted file mode 100644 index eb2f21f..0000000 --- a/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.33.target +++ /dev/null
@@ -1,288 +0,0 @@ -<?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="1756150983"> - <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.14.v20230922-1200"/> - <unit id="org.apache.ant.source" version="1.10.14.v20230922-1200"/> - <unit id="org.apache.httpcomponents.httpclient" version="4.5.14"/> - <unit id="org.apache.httpcomponents.httpclient.source" version="4.5.14"/> - <unit id="org.apache.httpcomponents.httpcore" version="4.4.16"/> - <unit id="org.apache.httpcomponents.httpcore.source" version="4.4.16"/> - <unit id="org.hamcrest.core" version="1.3.0.v20230809-1000"/> - <unit id="org.hamcrest.core.source" version="1.3.0.v20230809-1000"/> - <unit id="org.hamcrest.library" version="1.3.0.v20230809-1000"/> - <unit id="org.hamcrest.library.source" version="1.3.0.v20230809-1000"/> - <unit id="org.junit" version="4.13.2.v20230809-1000"/> - <unit id="org.junit.source" version="4.13.2.v20230809-1000"/> - <unit id="org.objenesis" version="3.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/2024-09"/> - </location> - <location includeMode="slicer" includeAllPlatforms="false" includeSource="true" includeConfigurePhase="true" type="InstallableUnit"> - <unit id="org.eclipse.osgi" version="0.0.0"/> - <repository location="https://download.eclipse.org/releases/2024-09/"/> - </location> - <location includeDependencyDepth="none" includeDependencyScopes="compile" includeSource="true" missingManifest="error" type="Maven" label="xz"> - <dependencies> - <dependency> - <groupId>org.tukaani</groupId> - <artifactId>xz</artifactId> - <version>1.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.16.0</version> - <type>jar</type> - </dependency> - <dependency> - <groupId>org.apache.sshd</groupId> - <artifactId>sshd-sftp</artifactId> - <version>2.16.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.19.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.1.0</version> - <type>jar</type> - </dependency> - <dependency> - <groupId>org.eclipse.jetty</groupId> - <artifactId>jetty-http</artifactId> - <version>12.1.0</version> - <type>jar</type> - </dependency> - <dependency> - <groupId>org.eclipse.jetty</groupId> - <artifactId>jetty-io</artifactId> - <version>12.1.0</version> - <type>jar</type> - </dependency> - <dependency> - <groupId>org.eclipse.jetty</groupId> - <artifactId>jetty-security</artifactId> - <version>12.1.0</version> - <type>jar</type> - </dependency> - <dependency> - <groupId>org.eclipse.jetty</groupId> - <artifactId>jetty-server</artifactId> - <version>12.1.0</version> - <type>jar</type> - </dependency> - <dependency> - <groupId>org.eclipse.jetty</groupId> - <artifactId>jetty-session</artifactId> - <version>12.1.0</version> - <type>jar</type> - </dependency> - <dependency> - <groupId>org.eclipse.jetty</groupId> - <artifactId>jetty-util</artifactId> - <version>12.1.0</version> - <type>jar</type> - </dependency> - <dependency> - <groupId>org.eclipse.jetty</groupId> - <artifactId>jetty-util-ajax</artifactId> - <version>12.1.0</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.7</version> - <type>jar</type> - </dependency> - <dependency> - <groupId>net.bytebuddy</groupId> - <artifactId>byte-buddy-agent</artifactId> - <version>1.17.7</version> - <type>jar</type> - </dependency> - </dependencies> - </location> - <location includeDependencyDepth="none" includeDependencyScopes="compile" includeSource="true" missingManifest="error" type="Maven" label="bouncycastle"> - <dependencies> - <dependency> - <groupId>org.bouncycastle</groupId> - <artifactId>bcpg-jdk18on</artifactId> - <version>1.81</version> - <type>jar</type> - </dependency> - <dependency> - <groupId>org.bouncycastle</groupId> - <artifactId>bcprov-jdk18on</artifactId> - <version>1.81</version> - <type>jar</type> - </dependency> - <dependency> - <groupId>org.bouncycastle</groupId> - <artifactId>bcpkix-jdk18on</artifactId> - <version>1.81</version> - <type>jar</type> - </dependency> - <dependency> - <groupId>org.bouncycastle</groupId> - <artifactId>bcutil-jdk18on</artifactId> - <version>1.81</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.4</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.19.0</version> - <type>jar</type> - </dependency> - <dependency> - <groupId>org.apache.commons</groupId> - <artifactId>commons-compress</artifactId> - <version>1.28.0</version> - <type>jar</type> - </dependency> - <dependency> - <groupId>org.apache.commons</groupId> - <artifactId>commons-lang3</artifactId> - <version>3.18.0</version> - <type>jar</type> - </dependency> - <dependency> - <groupId>commons-io</groupId> - <artifactId>commons-io</artifactId> - <version>2.20.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.33.tpd b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.33.tpd deleted file mode 100644 index 74c6878..0000000 --- a/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.33.tpd +++ /dev/null
@@ -1,8 +0,0 @@ -target "jgit-4.33" with source configurePhase - -include "orbit/orbit-4.33.tpd" -include "maven/dependencies.tpd" - -location "https://download.eclipse.org/releases/2024-09/" { - org.eclipse.osgi lazy -}
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 aa318cf..b75d6f7 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="1756150982"> +<target name="jgit-4.34" sequenceNumber="1763654302"> <locations> <location includeMode="slicer" includeAllPlatforms="false" includeSource="true" includeConfigurePhase="true" type="InstallableUnit"> <unit id="com.jcraft.jsch" version="0.1.55.v20230916-1400"/> @@ -10,16 +10,20 @@ <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.aries.spifly.dynamic.bundle" version="1.3.7"/> <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.hamcrest" version="3.0.0"/> + <unit id="org.hamcrest.source" version="3.0.0"/> <unit id="org.junit" version="4.13.2.v20240929-1000"/> <unit id="org.junit.source" version="4.13.2.v20240929-1000"/> + <unit id="org.objectweb.asm" version="9.7.1"/> + <unit id="org.objectweb.asm.commons" version="9.7.1"/> + <unit id="org.objectweb.asm.util" version="9.7.1"/> + <unit id="org.objectweb.asm.tree" version="9.7.1"/> + <unit id="org.objectweb.asm.tree.analysis" version="9.7.1"/> <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"/> @@ -35,7 +39,7 @@ <dependency> <groupId>org.tukaani</groupId> <artifactId>xz</artifactId> - <version>1.10</version> + <version>1.11</version> <type>jar</type> </dependency> </dependencies> @@ -45,13 +49,13 @@ <dependency> <groupId>org.slf4j</groupId> <artifactId>slf4j-api</artifactId> - <version>1.7.36</version> + <version>2.0.17</version> <type>jar</type> </dependency> <dependency> <groupId>org.slf4j</groupId> <artifactId>slf4j-simple</artifactId> - <version>1.7.36</version> + <version>2.0.17</version> <type>jar</type> </dependency> </dependencies> @@ -77,7 +81,7 @@ <dependency> <groupId>org.mockito</groupId> <artifactId>mockito-core</artifactId> - <version>5.19.0</version> + <version>5.20.0</version> <type>jar</type> </dependency> </dependencies> @@ -87,13 +91,13 @@ <dependency> <groupId>net.java.dev.jna</groupId> <artifactId>jna</artifactId> - <version>5.17.0</version> + <version>5.18.1</version> <type>jar</type> </dependency> <dependency> <groupId>net.java.dev.jna</groupId> <artifactId>jna-platform</artifactId> - <version>5.17.0</version> + <version>5.18.1</version> <type>jar</type> </dependency> </dependencies> @@ -103,49 +107,49 @@ <dependency> <groupId>org.eclipse.jetty.ee10</groupId> <artifactId>jetty-ee10-servlet</artifactId> - <version>12.1.0</version> + <version>12.1.4</version> <type>jar</type> </dependency> <dependency> <groupId>org.eclipse.jetty</groupId> <artifactId>jetty-http</artifactId> - <version>12.1.0</version> + <version>12.1.4</version> <type>jar</type> </dependency> <dependency> <groupId>org.eclipse.jetty</groupId> <artifactId>jetty-io</artifactId> - <version>12.1.0</version> + <version>12.1.4</version> <type>jar</type> </dependency> <dependency> <groupId>org.eclipse.jetty</groupId> <artifactId>jetty-security</artifactId> - <version>12.1.0</version> + <version>12.1.4</version> <type>jar</type> </dependency> <dependency> <groupId>org.eclipse.jetty</groupId> <artifactId>jetty-server</artifactId> - <version>12.1.0</version> + <version>12.1.4</version> <type>jar</type> </dependency> <dependency> <groupId>org.eclipse.jetty</groupId> <artifactId>jetty-session</artifactId> - <version>12.1.0</version> + <version>12.1.4</version> <type>jar</type> </dependency> <dependency> <groupId>org.eclipse.jetty</groupId> <artifactId>jetty-util</artifactId> - <version>12.1.0</version> + <version>12.1.4</version> <type>jar</type> </dependency> <dependency> <groupId>org.eclipse.jetty</groupId> <artifactId>jetty-util-ajax</artifactId> - <version>12.1.0</version> + <version>12.1.4</version> <type>jar</type> </dependency> <dependency> @@ -171,7 +175,7 @@ <dependency> <groupId>org.hamcrest</groupId> <artifactId>hamcrest</artifactId> - <version>2.2</version> + <version>3.0</version> <type>jar</type> </dependency> </dependencies> @@ -181,7 +185,7 @@ <dependency> <groupId>com.google.code.gson</groupId> <artifactId>gson</artifactId> - <version>2.13.1</version> + <version>2.13.2</version> <type>jar</type> </dependency> </dependencies> @@ -191,13 +195,13 @@ <dependency> <groupId>net.bytebuddy</groupId> <artifactId>byte-buddy</artifactId> - <version>1.17.7</version> + <version>1.18.1</version> <type>jar</type> </dependency> <dependency> <groupId>net.bytebuddy</groupId> <artifactId>byte-buddy-agent</artifactId> - <version>1.17.7</version> + <version>1.18.1</version> <type>jar</type> </dependency> </dependencies> @@ -207,25 +211,25 @@ <dependency> <groupId>org.bouncycastle</groupId> <artifactId>bcpg-jdk18on</artifactId> - <version>1.81</version> + <version>1.82</version> <type>jar</type> </dependency> <dependency> <groupId>org.bouncycastle</groupId> <artifactId>bcprov-jdk18on</artifactId> - <version>1.81</version> + <version>1.82</version> <type>jar</type> </dependency> <dependency> <groupId>org.bouncycastle</groupId> <artifactId>bcpkix-jdk18on</artifactId> - <version>1.81</version> + <version>1.82</version> <type>jar</type> </dependency> <dependency> <groupId>org.bouncycastle</groupId> <artifactId>bcutil-jdk18on</artifactId> - <version>1.81</version> + <version>1.82</version> <type>jar</type> </dependency> </dependencies> @@ -235,7 +239,7 @@ <dependency> <groupId>org.assertj</groupId> <artifactId>assertj-core</artifactId> - <version>3.27.4</version> + <version>3.27.6</version> <type>jar</type> </dependency> </dependencies> @@ -255,7 +259,7 @@ <dependency> <groupId>commons-codec</groupId> <artifactId>commons-codec</artifactId> - <version>1.19.0</version> + <version>1.20.0</version> <type>jar</type> </dependency> <dependency> @@ -267,13 +271,13 @@ <dependency> <groupId>org.apache.commons</groupId> <artifactId>commons-lang3</artifactId> - <version>3.18.0</version> + <version>3.20.0</version> <type>jar</type> </dependency> <dependency> <groupId>commons-io</groupId> <artifactId>commons-io</artifactId> - <version>2.20.0</version> + <version>2.21.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 6049694..0a7d6e2 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="1756150982"> +<target name="jgit-4.35" sequenceNumber="1763654302"> <locations> <location includeMode="slicer" includeAllPlatforms="false" includeSource="true" includeConfigurePhase="true" type="InstallableUnit"> <unit id="com.jcraft.jsch" version="0.1.55.v20230916-1400"/> @@ -10,16 +10,20 @@ <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.aries.spifly.dynamic.bundle" version="1.3.7"/> <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.hamcrest" version="3.0.0"/> + <unit id="org.hamcrest.source" version="3.0.0"/> <unit id="org.junit" version="4.13.2.v20240929-1000"/> <unit id="org.junit.source" version="4.13.2.v20240929-1000"/> + <unit id="org.objectweb.asm" version="9.7.1"/> + <unit id="org.objectweb.asm.commons" version="9.7.1"/> + <unit id="org.objectweb.asm.util" version="9.7.1"/> + <unit id="org.objectweb.asm.tree" version="9.7.1"/> + <unit id="org.objectweb.asm.tree.analysis" version="9.7.1"/> <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"/> @@ -35,7 +39,7 @@ <dependency> <groupId>org.tukaani</groupId> <artifactId>xz</artifactId> - <version>1.10</version> + <version>1.11</version> <type>jar</type> </dependency> </dependencies> @@ -45,13 +49,13 @@ <dependency> <groupId>org.slf4j</groupId> <artifactId>slf4j-api</artifactId> - <version>1.7.36</version> + <version>2.0.17</version> <type>jar</type> </dependency> <dependency> <groupId>org.slf4j</groupId> <artifactId>slf4j-simple</artifactId> - <version>1.7.36</version> + <version>2.0.17</version> <type>jar</type> </dependency> </dependencies> @@ -77,7 +81,7 @@ <dependency> <groupId>org.mockito</groupId> <artifactId>mockito-core</artifactId> - <version>5.19.0</version> + <version>5.20.0</version> <type>jar</type> </dependency> </dependencies> @@ -87,13 +91,13 @@ <dependency> <groupId>net.java.dev.jna</groupId> <artifactId>jna</artifactId> - <version>5.17.0</version> + <version>5.18.1</version> <type>jar</type> </dependency> <dependency> <groupId>net.java.dev.jna</groupId> <artifactId>jna-platform</artifactId> - <version>5.17.0</version> + <version>5.18.1</version> <type>jar</type> </dependency> </dependencies> @@ -103,49 +107,49 @@ <dependency> <groupId>org.eclipse.jetty.ee10</groupId> <artifactId>jetty-ee10-servlet</artifactId> - <version>12.1.0</version> + <version>12.1.4</version> <type>jar</type> </dependency> <dependency> <groupId>org.eclipse.jetty</groupId> <artifactId>jetty-http</artifactId> - <version>12.1.0</version> + <version>12.1.4</version> <type>jar</type> </dependency> <dependency> <groupId>org.eclipse.jetty</groupId> <artifactId>jetty-io</artifactId> - <version>12.1.0</version> + <version>12.1.4</version> <type>jar</type> </dependency> <dependency> <groupId>org.eclipse.jetty</groupId> <artifactId>jetty-security</artifactId> - <version>12.1.0</version> + <version>12.1.4</version> <type>jar</type> </dependency> <dependency> <groupId>org.eclipse.jetty</groupId> <artifactId>jetty-server</artifactId> - <version>12.1.0</version> + <version>12.1.4</version> <type>jar</type> </dependency> <dependency> <groupId>org.eclipse.jetty</groupId> <artifactId>jetty-session</artifactId> - <version>12.1.0</version> + <version>12.1.4</version> <type>jar</type> </dependency> <dependency> <groupId>org.eclipse.jetty</groupId> <artifactId>jetty-util</artifactId> - <version>12.1.0</version> + <version>12.1.4</version> <type>jar</type> </dependency> <dependency> <groupId>org.eclipse.jetty</groupId> <artifactId>jetty-util-ajax</artifactId> - <version>12.1.0</version> + <version>12.1.4</version> <type>jar</type> </dependency> <dependency> @@ -171,7 +175,7 @@ <dependency> <groupId>org.hamcrest</groupId> <artifactId>hamcrest</artifactId> - <version>2.2</version> + <version>3.0</version> <type>jar</type> </dependency> </dependencies> @@ -181,7 +185,7 @@ <dependency> <groupId>com.google.code.gson</groupId> <artifactId>gson</artifactId> - <version>2.13.1</version> + <version>2.13.2</version> <type>jar</type> </dependency> </dependencies> @@ -191,13 +195,13 @@ <dependency> <groupId>net.bytebuddy</groupId> <artifactId>byte-buddy</artifactId> - <version>1.17.7</version> + <version>1.18.1</version> <type>jar</type> </dependency> <dependency> <groupId>net.bytebuddy</groupId> <artifactId>byte-buddy-agent</artifactId> - <version>1.17.7</version> + <version>1.18.1</version> <type>jar</type> </dependency> </dependencies> @@ -207,25 +211,25 @@ <dependency> <groupId>org.bouncycastle</groupId> <artifactId>bcpg-jdk18on</artifactId> - <version>1.81</version> + <version>1.82</version> <type>jar</type> </dependency> <dependency> <groupId>org.bouncycastle</groupId> <artifactId>bcprov-jdk18on</artifactId> - <version>1.81</version> + <version>1.82</version> <type>jar</type> </dependency> <dependency> <groupId>org.bouncycastle</groupId> <artifactId>bcpkix-jdk18on</artifactId> - <version>1.81</version> + <version>1.82</version> <type>jar</type> </dependency> <dependency> <groupId>org.bouncycastle</groupId> <artifactId>bcutil-jdk18on</artifactId> - <version>1.81</version> + <version>1.82</version> <type>jar</type> </dependency> </dependencies> @@ -235,7 +239,7 @@ <dependency> <groupId>org.assertj</groupId> <artifactId>assertj-core</artifactId> - <version>3.27.4</version> + <version>3.27.6</version> <type>jar</type> </dependency> </dependencies> @@ -255,7 +259,7 @@ <dependency> <groupId>commons-codec</groupId> <artifactId>commons-codec</artifactId> - <version>1.19.0</version> + <version>1.20.0</version> <type>jar</type> </dependency> <dependency> @@ -267,13 +271,13 @@ <dependency> <groupId>org.apache.commons</groupId> <artifactId>commons-lang3</artifactId> - <version>3.18.0</version> + <version>3.20.0</version> <type>jar</type> </dependency> <dependency> <groupId>commons-io</groupId> <artifactId>commons-io</artifactId> - <version>2.20.0</version> + <version>2.21.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 index cd2bc2b..5500a78 100644 --- 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
@@ -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.36" sequenceNumber="1756150982"> +<target name="jgit-4.36" sequenceNumber="1763654302"> <locations> <location includeMode="slicer" includeAllPlatforms="false" includeSource="true" includeConfigurePhase="true" type="InstallableUnit"> <unit id="com.jcraft.jsch" version="0.1.55.v20230916-1400"/> @@ -10,16 +10,20 @@ <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.aries.spifly.dynamic.bundle" version="1.3.7"/> <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.hamcrest" version="3.0.0"/> + <unit id="org.hamcrest.source" version="3.0.0"/> <unit id="org.junit" version="4.13.2.v20240929-1000"/> <unit id="org.junit.source" version="4.13.2.v20240929-1000"/> + <unit id="org.objectweb.asm" version="9.8.0"/> + <unit id="org.objectweb.asm.commons" version="9.8.0"/> + <unit id="org.objectweb.asm.util" version="9.8.0"/> + <unit id="org.objectweb.asm.tree" version="9.8.0"/> + <unit id="org.objectweb.asm.tree.analysis" version="9.8.0"/> <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"/> @@ -35,7 +39,7 @@ <dependency> <groupId>org.tukaani</groupId> <artifactId>xz</artifactId> - <version>1.10</version> + <version>1.11</version> <type>jar</type> </dependency> </dependencies> @@ -45,13 +49,13 @@ <dependency> <groupId>org.slf4j</groupId> <artifactId>slf4j-api</artifactId> - <version>1.7.36</version> + <version>2.0.17</version> <type>jar</type> </dependency> <dependency> <groupId>org.slf4j</groupId> <artifactId>slf4j-simple</artifactId> - <version>1.7.36</version> + <version>2.0.17</version> <type>jar</type> </dependency> </dependencies> @@ -77,7 +81,7 @@ <dependency> <groupId>org.mockito</groupId> <artifactId>mockito-core</artifactId> - <version>5.19.0</version> + <version>5.20.0</version> <type>jar</type> </dependency> </dependencies> @@ -87,13 +91,13 @@ <dependency> <groupId>net.java.dev.jna</groupId> <artifactId>jna</artifactId> - <version>5.17.0</version> + <version>5.18.1</version> <type>jar</type> </dependency> <dependency> <groupId>net.java.dev.jna</groupId> <artifactId>jna-platform</artifactId> - <version>5.17.0</version> + <version>5.18.1</version> <type>jar</type> </dependency> </dependencies> @@ -103,49 +107,49 @@ <dependency> <groupId>org.eclipse.jetty.ee10</groupId> <artifactId>jetty-ee10-servlet</artifactId> - <version>12.1.0</version> + <version>12.1.4</version> <type>jar</type> </dependency> <dependency> <groupId>org.eclipse.jetty</groupId> <artifactId>jetty-http</artifactId> - <version>12.1.0</version> + <version>12.1.4</version> <type>jar</type> </dependency> <dependency> <groupId>org.eclipse.jetty</groupId> <artifactId>jetty-io</artifactId> - <version>12.1.0</version> + <version>12.1.4</version> <type>jar</type> </dependency> <dependency> <groupId>org.eclipse.jetty</groupId> <artifactId>jetty-security</artifactId> - <version>12.1.0</version> + <version>12.1.4</version> <type>jar</type> </dependency> <dependency> <groupId>org.eclipse.jetty</groupId> <artifactId>jetty-server</artifactId> - <version>12.1.0</version> + <version>12.1.4</version> <type>jar</type> </dependency> <dependency> <groupId>org.eclipse.jetty</groupId> <artifactId>jetty-session</artifactId> - <version>12.1.0</version> + <version>12.1.4</version> <type>jar</type> </dependency> <dependency> <groupId>org.eclipse.jetty</groupId> <artifactId>jetty-util</artifactId> - <version>12.1.0</version> + <version>12.1.4</version> <type>jar</type> </dependency> <dependency> <groupId>org.eclipse.jetty</groupId> <artifactId>jetty-util-ajax</artifactId> - <version>12.1.0</version> + <version>12.1.4</version> <type>jar</type> </dependency> <dependency> @@ -171,7 +175,7 @@ <dependency> <groupId>org.hamcrest</groupId> <artifactId>hamcrest</artifactId> - <version>2.2</version> + <version>3.0</version> <type>jar</type> </dependency> </dependencies> @@ -181,7 +185,7 @@ <dependency> <groupId>com.google.code.gson</groupId> <artifactId>gson</artifactId> - <version>2.13.1</version> + <version>2.13.2</version> <type>jar</type> </dependency> </dependencies> @@ -191,13 +195,13 @@ <dependency> <groupId>net.bytebuddy</groupId> <artifactId>byte-buddy</artifactId> - <version>1.17.7</version> + <version>1.18.1</version> <type>jar</type> </dependency> <dependency> <groupId>net.bytebuddy</groupId> <artifactId>byte-buddy-agent</artifactId> - <version>1.17.7</version> + <version>1.18.1</version> <type>jar</type> </dependency> </dependencies> @@ -207,25 +211,25 @@ <dependency> <groupId>org.bouncycastle</groupId> <artifactId>bcpg-jdk18on</artifactId> - <version>1.81</version> + <version>1.82</version> <type>jar</type> </dependency> <dependency> <groupId>org.bouncycastle</groupId> <artifactId>bcprov-jdk18on</artifactId> - <version>1.81</version> + <version>1.82</version> <type>jar</type> </dependency> <dependency> <groupId>org.bouncycastle</groupId> <artifactId>bcpkix-jdk18on</artifactId> - <version>1.81</version> + <version>1.82</version> <type>jar</type> </dependency> <dependency> <groupId>org.bouncycastle</groupId> <artifactId>bcutil-jdk18on</artifactId> - <version>1.81</version> + <version>1.82</version> <type>jar</type> </dependency> </dependencies> @@ -235,7 +239,7 @@ <dependency> <groupId>org.assertj</groupId> <artifactId>assertj-core</artifactId> - <version>3.27.4</version> + <version>3.27.6</version> <type>jar</type> </dependency> </dependencies> @@ -255,7 +259,7 @@ <dependency> <groupId>commons-codec</groupId> <artifactId>commons-codec</artifactId> - <version>1.19.0</version> + <version>1.20.0</version> <type>jar</type> </dependency> <dependency> @@ -267,13 +271,13 @@ <dependency> <groupId>org.apache.commons</groupId> <artifactId>commons-lang3</artifactId> - <version>3.18.0</version> + <version>3.20.0</version> <type>jar</type> </dependency> <dependency> <groupId>commons-io</groupId> <artifactId>commons-io</artifactId> - <version>2.20.0</version> + <version>2.21.0</version> <type>jar</type> </dependency> <dependency>
diff --git a/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.37.target b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.37.target index 54bccdd..1900eda 100644 --- a/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.37.target +++ b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.37.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.37" sequenceNumber="1756150985"> +<target name="jgit-4.37" sequenceNumber="1763654303"> <locations> <location includeMode="slicer" includeAllPlatforms="false" includeSource="true" includeConfigurePhase="true" type="InstallableUnit"> <unit id="com.jcraft.jsch" version="0.1.55.v20230916-1400"/> @@ -10,16 +10,20 @@ <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.aries.spifly.dynamic.bundle" version="1.3.7"/> <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.hamcrest" version="3.0.0"/> + <unit id="org.hamcrest.source" version="3.0.0"/> <unit id="org.junit" version="4.13.2.v20240929-1000"/> <unit id="org.junit.source" version="4.13.2.v20240929-1000"/> + <unit id="org.objectweb.asm" version="9.8.0"/> + <unit id="org.objectweb.asm.commons" version="9.8.0"/> + <unit id="org.objectweb.asm.util" version="9.8.0"/> + <unit id="org.objectweb.asm.tree" version="9.8.0"/> + <unit id="org.objectweb.asm.tree.analysis" version="9.8.0"/> <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"/> @@ -35,7 +39,7 @@ <dependency> <groupId>org.tukaani</groupId> <artifactId>xz</artifactId> - <version>1.10</version> + <version>1.11</version> <type>jar</type> </dependency> </dependencies> @@ -45,13 +49,13 @@ <dependency> <groupId>org.slf4j</groupId> <artifactId>slf4j-api</artifactId> - <version>1.7.36</version> + <version>2.0.17</version> <type>jar</type> </dependency> <dependency> <groupId>org.slf4j</groupId> <artifactId>slf4j-simple</artifactId> - <version>1.7.36</version> + <version>2.0.17</version> <type>jar</type> </dependency> </dependencies> @@ -77,7 +81,7 @@ <dependency> <groupId>org.mockito</groupId> <artifactId>mockito-core</artifactId> - <version>5.19.0</version> + <version>5.20.0</version> <type>jar</type> </dependency> </dependencies> @@ -87,13 +91,13 @@ <dependency> <groupId>net.java.dev.jna</groupId> <artifactId>jna</artifactId> - <version>5.17.0</version> + <version>5.18.1</version> <type>jar</type> </dependency> <dependency> <groupId>net.java.dev.jna</groupId> <artifactId>jna-platform</artifactId> - <version>5.17.0</version> + <version>5.18.1</version> <type>jar</type> </dependency> </dependencies> @@ -103,49 +107,49 @@ <dependency> <groupId>org.eclipse.jetty.ee10</groupId> <artifactId>jetty-ee10-servlet</artifactId> - <version>12.1.0</version> + <version>12.1.4</version> <type>jar</type> </dependency> <dependency> <groupId>org.eclipse.jetty</groupId> <artifactId>jetty-http</artifactId> - <version>12.1.0</version> + <version>12.1.4</version> <type>jar</type> </dependency> <dependency> <groupId>org.eclipse.jetty</groupId> <artifactId>jetty-io</artifactId> - <version>12.1.0</version> + <version>12.1.4</version> <type>jar</type> </dependency> <dependency> <groupId>org.eclipse.jetty</groupId> <artifactId>jetty-security</artifactId> - <version>12.1.0</version> + <version>12.1.4</version> <type>jar</type> </dependency> <dependency> <groupId>org.eclipse.jetty</groupId> <artifactId>jetty-server</artifactId> - <version>12.1.0</version> + <version>12.1.4</version> <type>jar</type> </dependency> <dependency> <groupId>org.eclipse.jetty</groupId> <artifactId>jetty-session</artifactId> - <version>12.1.0</version> + <version>12.1.4</version> <type>jar</type> </dependency> <dependency> <groupId>org.eclipse.jetty</groupId> <artifactId>jetty-util</artifactId> - <version>12.1.0</version> + <version>12.1.4</version> <type>jar</type> </dependency> <dependency> <groupId>org.eclipse.jetty</groupId> <artifactId>jetty-util-ajax</artifactId> - <version>12.1.0</version> + <version>12.1.4</version> <type>jar</type> </dependency> <dependency> @@ -171,7 +175,7 @@ <dependency> <groupId>org.hamcrest</groupId> <artifactId>hamcrest</artifactId> - <version>2.2</version> + <version>3.0</version> <type>jar</type> </dependency> </dependencies> @@ -181,7 +185,7 @@ <dependency> <groupId>com.google.code.gson</groupId> <artifactId>gson</artifactId> - <version>2.13.1</version> + <version>2.13.2</version> <type>jar</type> </dependency> </dependencies> @@ -191,13 +195,13 @@ <dependency> <groupId>net.bytebuddy</groupId> <artifactId>byte-buddy</artifactId> - <version>1.17.7</version> + <version>1.18.1</version> <type>jar</type> </dependency> <dependency> <groupId>net.bytebuddy</groupId> <artifactId>byte-buddy-agent</artifactId> - <version>1.17.7</version> + <version>1.18.1</version> <type>jar</type> </dependency> </dependencies> @@ -207,25 +211,25 @@ <dependency> <groupId>org.bouncycastle</groupId> <artifactId>bcpg-jdk18on</artifactId> - <version>1.81</version> + <version>1.82</version> <type>jar</type> </dependency> <dependency> <groupId>org.bouncycastle</groupId> <artifactId>bcprov-jdk18on</artifactId> - <version>1.81</version> + <version>1.82</version> <type>jar</type> </dependency> <dependency> <groupId>org.bouncycastle</groupId> <artifactId>bcpkix-jdk18on</artifactId> - <version>1.81</version> + <version>1.82</version> <type>jar</type> </dependency> <dependency> <groupId>org.bouncycastle</groupId> <artifactId>bcutil-jdk18on</artifactId> - <version>1.81</version> + <version>1.82</version> <type>jar</type> </dependency> </dependencies> @@ -235,7 +239,7 @@ <dependency> <groupId>org.assertj</groupId> <artifactId>assertj-core</artifactId> - <version>3.27.4</version> + <version>3.27.6</version> <type>jar</type> </dependency> </dependencies> @@ -255,7 +259,7 @@ <dependency> <groupId>commons-codec</groupId> <artifactId>commons-codec</artifactId> - <version>1.19.0</version> + <version>1.20.0</version> <type>jar</type> </dependency> <dependency> @@ -267,13 +271,13 @@ <dependency> <groupId>org.apache.commons</groupId> <artifactId>commons-lang3</artifactId> - <version>3.18.0</version> + <version>3.20.0</version> <type>jar</type> </dependency> <dependency> <groupId>commons-io</groupId> <artifactId>commons-io</artifactId> - <version>2.20.0</version> + <version>2.21.0</version> <type>jar</type> </dependency> <dependency>
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.38.target similarity index 84% rename from org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.32.target rename to org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.38.target index 4765602..2571b91 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.38.target
@@ -1,41 +1,45 @@ <?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="1756150982"> +<target name="jgit-4.38" sequenceNumber="1763654304"> <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.14.v20230922-1200"/> - <unit id="org.apache.ant.source" version="1.10.14.v20230922-1200"/> + <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.aries.spifly.dynamic.bundle" version="1.3.7"/> <unit id="org.apache.httpcomponents.httpclient" version="4.5.14"/> <unit id="org.apache.httpcomponents.httpclient.source" version="4.5.14"/> <unit id="org.apache.httpcomponents.httpcore" version="4.4.16"/> <unit id="org.apache.httpcomponents.httpcore.source" version="4.4.16"/> - <unit id="org.hamcrest.core" version="1.3.0.v20230809-1000"/> - <unit id="org.hamcrest.core.source" version="1.3.0.v20230809-1000"/> - <unit id="org.hamcrest.library" version="1.3.0.v20230809-1000"/> - <unit id="org.hamcrest.library.source" version="1.3.0.v20230809-1000"/> - <unit id="org.junit" version="4.13.2.v20230809-1000"/> - <unit id="org.junit.source" version="4.13.2.v20230809-1000"/> + <unit id="org.hamcrest" version="3.0.0"/> + <unit id="org.hamcrest.source" version="3.0.0"/> + <unit id="org.junit" version="4.13.2.v20240929-1000"/> + <unit id="org.junit.source" version="4.13.2.v20240929-1000"/> + <unit id="org.objectweb.asm" version="9.9.0"/> + <unit id="org.objectweb.asm.commons" version="9.9.0"/> + <unit id="org.objectweb.asm.util" version="9.9.0"/> + <unit id="org.objectweb.asm.tree" version="9.9.0"/> + <unit id="org.objectweb.asm.tree.analysis" version="9.9.0"/> <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/2024-06"/> + <repository location="https://download.eclipse.org/tools/orbit/simrel/orbit-aggregation/2025-12"/> </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/2024-06/"/> + <repository location="https://download.eclipse.org/staging/2025-12/"/> </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> + <version>1.11</version> <type>jar</type> </dependency> </dependencies> @@ -45,13 +49,13 @@ <dependency> <groupId>org.slf4j</groupId> <artifactId>slf4j-api</artifactId> - <version>1.7.36</version> + <version>2.0.17</version> <type>jar</type> </dependency> <dependency> <groupId>org.slf4j</groupId> <artifactId>slf4j-simple</artifactId> - <version>1.7.36</version> + <version>2.0.17</version> <type>jar</type> </dependency> </dependencies> @@ -77,7 +81,7 @@ <dependency> <groupId>org.mockito</groupId> <artifactId>mockito-core</artifactId> - <version>5.19.0</version> + <version>5.20.0</version> <type>jar</type> </dependency> </dependencies> @@ -87,13 +91,13 @@ <dependency> <groupId>net.java.dev.jna</groupId> <artifactId>jna</artifactId> - <version>5.17.0</version> + <version>5.18.1</version> <type>jar</type> </dependency> <dependency> <groupId>net.java.dev.jna</groupId> <artifactId>jna-platform</artifactId> - <version>5.17.0</version> + <version>5.18.1</version> <type>jar</type> </dependency> </dependencies> @@ -103,49 +107,49 @@ <dependency> <groupId>org.eclipse.jetty.ee10</groupId> <artifactId>jetty-ee10-servlet</artifactId> - <version>12.1.0</version> + <version>12.1.4</version> <type>jar</type> </dependency> <dependency> <groupId>org.eclipse.jetty</groupId> <artifactId>jetty-http</artifactId> - <version>12.1.0</version> + <version>12.1.4</version> <type>jar</type> </dependency> <dependency> <groupId>org.eclipse.jetty</groupId> <artifactId>jetty-io</artifactId> - <version>12.1.0</version> + <version>12.1.4</version> <type>jar</type> </dependency> <dependency> <groupId>org.eclipse.jetty</groupId> <artifactId>jetty-security</artifactId> - <version>12.1.0</version> + <version>12.1.4</version> <type>jar</type> </dependency> <dependency> <groupId>org.eclipse.jetty</groupId> <artifactId>jetty-server</artifactId> - <version>12.1.0</version> + <version>12.1.4</version> <type>jar</type> </dependency> <dependency> <groupId>org.eclipse.jetty</groupId> <artifactId>jetty-session</artifactId> - <version>12.1.0</version> + <version>12.1.4</version> <type>jar</type> </dependency> <dependency> <groupId>org.eclipse.jetty</groupId> <artifactId>jetty-util</artifactId> - <version>12.1.0</version> + <version>12.1.4</version> <type>jar</type> </dependency> <dependency> <groupId>org.eclipse.jetty</groupId> <artifactId>jetty-util-ajax</artifactId> - <version>12.1.0</version> + <version>12.1.4</version> <type>jar</type> </dependency> <dependency> @@ -171,7 +175,7 @@ <dependency> <groupId>org.hamcrest</groupId> <artifactId>hamcrest</artifactId> - <version>2.2</version> + <version>3.0</version> <type>jar</type> </dependency> </dependencies> @@ -181,7 +185,7 @@ <dependency> <groupId>com.google.code.gson</groupId> <artifactId>gson</artifactId> - <version>2.13.1</version> + <version>2.13.2</version> <type>jar</type> </dependency> </dependencies> @@ -191,13 +195,13 @@ <dependency> <groupId>net.bytebuddy</groupId> <artifactId>byte-buddy</artifactId> - <version>1.17.7</version> + <version>1.18.1</version> <type>jar</type> </dependency> <dependency> <groupId>net.bytebuddy</groupId> <artifactId>byte-buddy-agent</artifactId> - <version>1.17.7</version> + <version>1.18.1</version> <type>jar</type> </dependency> </dependencies> @@ -207,25 +211,25 @@ <dependency> <groupId>org.bouncycastle</groupId> <artifactId>bcpg-jdk18on</artifactId> - <version>1.81</version> + <version>1.82</version> <type>jar</type> </dependency> <dependency> <groupId>org.bouncycastle</groupId> <artifactId>bcprov-jdk18on</artifactId> - <version>1.81</version> + <version>1.82</version> <type>jar</type> </dependency> <dependency> <groupId>org.bouncycastle</groupId> <artifactId>bcpkix-jdk18on</artifactId> - <version>1.81</version> + <version>1.82</version> <type>jar</type> </dependency> <dependency> <groupId>org.bouncycastle</groupId> <artifactId>bcutil-jdk18on</artifactId> - <version>1.81</version> + <version>1.82</version> <type>jar</type> </dependency> </dependencies> @@ -235,7 +239,7 @@ <dependency> <groupId>org.assertj</groupId> <artifactId>assertj-core</artifactId> - <version>3.27.4</version> + <version>3.27.6</version> <type>jar</type> </dependency> </dependencies> @@ -255,7 +259,7 @@ <dependency> <groupId>commons-codec</groupId> <artifactId>commons-codec</artifactId> - <version>1.19.0</version> + <version>1.20.0</version> <type>jar</type> </dependency> <dependency> @@ -267,13 +271,13 @@ <dependency> <groupId>org.apache.commons</groupId> <artifactId>commons-lang3</artifactId> - <version>3.18.0</version> + <version>3.20.0</version> <type>jar</type> </dependency> <dependency> <groupId>commons-io</groupId> <artifactId>commons-io</artifactId> - <version>2.20.0</version> + <version>2.21.0</version> <type>jar</type> </dependency> <dependency>
diff --git a/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.38.tpd b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.38.tpd new file mode 100644 index 0000000..cd20f43 --- /dev/null +++ b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.38.tpd
@@ -0,0 +1,8 @@ +target "jgit-4.38" with source configurePhase + +include "orbit/orbit-4.38.tpd" +include "maven/dependencies.tpd" + +location "https://download.eclipse.org/staging/2025-12/" { + 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 f901454..bd29539 100644 --- a/org.eclipse.jgit.packaging/org.eclipse.jgit.target/maven/dependencies.tpd +++ b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/maven/dependencies.tpd
@@ -10,7 +10,7 @@ dependency { groupId = "commons-codec" artifactId = "commons-codec" - version = "1.19.0" + version = "1.20.0" } dependency { groupId = "org.apache.commons" @@ -20,12 +20,12 @@ dependency { groupId = "org.apache.commons" artifactId = "commons-lang3" - version = "3.18.0" + version = "3.20.0" } dependency { groupId = "commons-io" artifactId = "commons-io" - version = "2.20.0" + version = "2.21.0" } dependency { groupId = "commons-logging" @@ -56,7 +56,7 @@ dependency { groupId = "org.assertj" artifactId = "assertj-core" - version = "3.27.4" + version = "3.27.6" } } @@ -69,22 +69,22 @@ dependency { groupId = "org.bouncycastle" artifactId = "bcpg-jdk18on" - version = "1.81" + version = "1.82" } dependency { groupId = "org.bouncycastle" artifactId = "bcprov-jdk18on" - version = "1.81" + version = "1.82" } dependency { groupId = "org.bouncycastle" artifactId = "bcpkix-jdk18on" - version = "1.81" + version = "1.82" } dependency { groupId = "org.bouncycastle" artifactId = "bcutil-jdk18on" - version = "1.81" + version = "1.82" } } @@ -97,12 +97,12 @@ dependency { groupId = "net.bytebuddy" artifactId = "byte-buddy" - version = "1.17.7" + version = "1.18.1" } dependency { groupId = "net.bytebuddy" artifactId = "byte-buddy-agent" - version = "1.17.7" + version = "1.18.1" } } @@ -115,7 +115,7 @@ dependency { groupId = "com.google.code.gson" artifactId = "gson" - version = "2.13.1" + version = "2.13.2" } } @@ -128,7 +128,7 @@ dependency { groupId = "org.hamcrest" artifactId = "hamcrest" - version = "2.2" + version = "3.0" } } @@ -154,42 +154,42 @@ dependency { groupId = "org.eclipse.jetty.ee10" artifactId = "jetty-ee10-servlet" - version = "12.1.0" + version = "12.1.4" } dependency { groupId = "org.eclipse.jetty" artifactId = "jetty-http" - version = "12.1.0" + version = "12.1.4" } dependency { groupId = "org.eclipse.jetty" artifactId = "jetty-io" - version = "12.1.0" + version = "12.1.4" } dependency { groupId = "org.eclipse.jetty" artifactId = "jetty-security" - version = "12.1.0" + version = "12.1.4" } dependency { groupId = "org.eclipse.jetty" artifactId = "jetty-server" - version = "12.1.0" + version = "12.1.4" } dependency { groupId = "org.eclipse.jetty" artifactId = "jetty-session" - version = "12.1.0" + version = "12.1.4" } dependency { groupId = "org.eclipse.jetty" artifactId = "jetty-util" - version = "12.1.0" + version = "12.1.4" } dependency { groupId = "org.eclipse.jetty" artifactId = "jetty-util-ajax" - version = "12.1.0" + version = "12.1.4" } dependency { groupId = "jakarta.servlet" @@ -207,12 +207,12 @@ dependency { groupId = "net.java.dev.jna" artifactId = "jna" - version = "5.17.0" + version = "5.18.1" } dependency { groupId = "net.java.dev.jna" artifactId = "jna-platform" - version = "5.17.0" + version = "5.18.1" } } @@ -225,7 +225,7 @@ dependency { groupId = "org.mockito" artifactId = "mockito-core" - version = "5.19.0" + version = "5.20.0" } } @@ -256,12 +256,12 @@ dependency { groupId = "org.slf4j" artifactId = "slf4j-api" - version = "1.7.36" + version = "2.0.17" } dependency { groupId = "org.slf4j" artifactId = "slf4j-simple" - version = "1.7.36" + version = "2.0.17" } } @@ -274,6 +274,6 @@ dependency { groupId = "org.tukaani" artifactId = "xz" - version = "1.10" + version = "1.11" } } \ No newline at end of file
diff --git a/org.eclipse.jgit.packaging/org.eclipse.jgit.target/orbit/orbit-4.32.tpd b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/orbit/orbit-4.32.tpd deleted file mode 100644 index 59fcd87..0000000 --- a/org.eclipse.jgit.packaging/org.eclipse.jgit.target/orbit/orbit-4.32.tpd +++ /dev/null
@@ -1,25 +0,0 @@ -target "orbit-4.32" with source configurePhase -// see https://download.eclipse.org/tools/orbit/downloads/ - -location "https://download.eclipse.org/tools/orbit/simrel/orbit-aggregation/2024-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.14.v20230922-1200,1.10.14.v20230922-1200] - org.apache.ant.source [1.10.14.v20230922-1200,1.10.14.v20230922-1200] - org.apache.httpcomponents.httpclient [4.5.14,4.5.14] - org.apache.httpcomponents.httpclient.source [4.5.14,4.5.14] - org.apache.httpcomponents.httpcore [4.4.16,4.4.16] - org.apache.httpcomponents.httpcore.source [4.4.16,4.4.16] - org.hamcrest.core [1.3.0.v20230809-1000,1.3.0.v20230809-1000] - org.hamcrest.core.source [1.3.0.v20230809-1000,1.3.0.v20230809-1000] - org.hamcrest.library [1.3.0.v20230809-1000,1.3.0.v20230809-1000] - org.hamcrest.library.source [1.3.0.v20230809-1000,1.3.0.v20230809-1000] - org.junit [4.13.2.v20230809-1000,4.13.2.v20230809-1000] - org.junit.source [4.13.2.v20230809-1000,4.13.2.v20230809-1000] - org.objenesis [3.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/org.eclipse.jgit.target/orbit/orbit-4.33.tpd b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/orbit/orbit-4.33.tpd deleted file mode 100644 index 2cfa0a8..0000000 --- a/org.eclipse.jgit.packaging/org.eclipse.jgit.target/orbit/orbit-4.33.tpd +++ /dev/null
@@ -1,25 +0,0 @@ -target "orbit-4.33" with source configurePhase -// see https://download.eclipse.org/tools/orbit/downloads/ - -location "https://download.eclipse.org/tools/orbit/simrel/orbit-aggregation/2024-09" { - 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.14.v20230922-1200,1.10.14.v20230922-1200] - org.apache.ant.source [1.10.14.v20230922-1200,1.10.14.v20230922-1200] - org.apache.httpcomponents.httpclient [4.5.14,4.5.14] - org.apache.httpcomponents.httpclient.source [4.5.14,4.5.14] - org.apache.httpcomponents.httpcore [4.4.16,4.4.16] - org.apache.httpcomponents.httpcore.source [4.4.16,4.4.16] - org.hamcrest.core [1.3.0.v20230809-1000,1.3.0.v20230809-1000] - org.hamcrest.core.source [1.3.0.v20230809-1000,1.3.0.v20230809-1000] - org.hamcrest.library [1.3.0.v20230809-1000,1.3.0.v20230809-1000] - org.hamcrest.library.source [1.3.0.v20230809-1000,1.3.0.v20230809-1000] - org.junit [4.13.2.v20230809-1000,4.13.2.v20230809-1000] - org.junit.source [4.13.2.v20230809-1000,4.13.2.v20230809-1000] - org.objenesis [3.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/org.eclipse.jgit.target/orbit/orbit-4.34.tpd b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/orbit/orbit-4.34.tpd index d3e15bb..d3c2f2f 100644 --- a/org.eclipse.jgit.packaging/org.eclipse.jgit.target/orbit/orbit-4.34.tpd +++ b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/orbit/orbit-4.34.tpd
@@ -8,16 +8,20 @@ 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.aries.spifly.dynamic.bundle [1.3.7,1.3.7] 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.hamcrest [3.0.0,3.0.0] + org.hamcrest.source [3.0.0,3.0.0] 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.objectweb.asm [9.7.1,9.7.1] + org.objectweb.asm.commons [9.7.1,9.7.1] + org.objectweb.asm.util [9.7.1,9.7.1] + org.objectweb.asm.tree [9.7.1,9.7.1] + org.objectweb.asm.tree.analysis [9.7.1,9.7.1] 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]
diff --git a/org.eclipse.jgit.packaging/org.eclipse.jgit.target/orbit/orbit-4.35.tpd b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/orbit/orbit-4.35.tpd index ec6996e..f5f9a08 100644 --- a/org.eclipse.jgit.packaging/org.eclipse.jgit.target/orbit/orbit-4.35.tpd +++ b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/orbit/orbit-4.35.tpd
@@ -8,16 +8,20 @@ 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.aries.spifly.dynamic.bundle [1.3.7,1.3.7] 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.hamcrest [3.0.0,3.0.0] + org.hamcrest.source [3.0.0,3.0.0] 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.objectweb.asm [9.7.1,9.7.1] + org.objectweb.asm.commons [9.7.1,9.7.1] + org.objectweb.asm.util [9.7.1,9.7.1] + org.objectweb.asm.tree [9.7.1,9.7.1] + org.objectweb.asm.tree.analysis [9.7.1,9.7.1] 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]
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 index 4f46583..b60e90d 100644 --- 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
@@ -8,16 +8,20 @@ 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.aries.spifly.dynamic.bundle [1.3.7,1.3.7] 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.hamcrest [3.0.0,3.0.0] + org.hamcrest.source [3.0.0,3.0.0] 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.objectweb.asm [9.8.0,9.8.0] + org.objectweb.asm.commons [9.8.0,9.8.0] + org.objectweb.asm.util [9.8.0,9.8.0] + org.objectweb.asm.tree [9.8.0,9.8.0] + org.objectweb.asm.tree.analysis [9.8.0,9.8.0] 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]
diff --git a/org.eclipse.jgit.packaging/org.eclipse.jgit.target/orbit/orbit-4.37.tpd b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/orbit/orbit-4.37.tpd index 9c1ba4f..c142490 100644 --- a/org.eclipse.jgit.packaging/org.eclipse.jgit.target/orbit/orbit-4.37.tpd +++ b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/orbit/orbit-4.37.tpd
@@ -8,16 +8,20 @@ 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.aries.spifly.dynamic.bundle [1.3.7,1.3.7] 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.hamcrest [3.0.0,3.0.0] + org.hamcrest.source [3.0.0,3.0.0] 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.objectweb.asm [9.8.0,9.8.0] + org.objectweb.asm.commons [9.8.0,9.8.0] + org.objectweb.asm.util [9.8.0,9.8.0] + org.objectweb.asm.tree [9.8.0,9.8.0] + org.objectweb.asm.tree.analysis [9.8.0,9.8.0] 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]
diff --git a/org.eclipse.jgit.packaging/org.eclipse.jgit.target/orbit/orbit-4.38.tpd b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/orbit/orbit-4.38.tpd new file mode 100644 index 0000000..7601cc4 --- /dev/null +++ b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/orbit/orbit-4.38.tpd
@@ -0,0 +1,29 @@ +target "orbit-4.38" with source configurePhase +// see https://download.eclipse.org/tools/orbit/downloads/ + +location "https://download.eclipse.org/tools/orbit/simrel/orbit-aggregation/2025-12" { + 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.aries.spifly.dynamic.bundle [1.3.7,1.3.7] + 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 [3.0.0,3.0.0] + org.hamcrest.source [3.0.0,3.0.0] + 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.objectweb.asm [9.9.0,9.9.0] + org.objectweb.asm.commons [9.9.0,9.9.0] + org.objectweb.asm.util [9.9.0,9.9.0] + org.objectweb.asm.tree [9.9.0,9.9.0] + org.objectweb.asm.tree.analysis [9.9.0,9.9.0] + 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 1d0eff4..08a8989 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.4.1-SNAPSHOT</version> + <version>7.5.1-SNAPSHOT</version> <packaging>pom</packaging> <name>JGit Tycho Parent</name> @@ -31,7 +31,7 @@ <properties> <java.version>17</java.version> <tycho-version>4.0.13</tycho-version> - <target-platform>jgit-4.32</target-platform> + <target-platform>jgit-4.34</target-platform> <project.build.outputTimestamp>${git.commit.time}</project.build.outputTimestamp> </properties>
diff --git a/org.eclipse.jgit.pgm.test/META-INF/MANIFEST.MF b/org.eclipse.jgit.pgm.test/META-INF/MANIFEST.MF index d7b85af..b64d3da 100644 --- a/org.eclipse.jgit.pgm.test/META-INF/MANIFEST.MF +++ b/org.eclipse.jgit.pgm.test/META-INF/MANIFEST.MF
@@ -3,31 +3,31 @@ Bundle-Name: %Bundle-Name Automatic-Module-Name: org.eclipse.jgit.pgm.test Bundle-SymbolicName: org.eclipse.jgit.pgm.test -Bundle-Version: 7.4.1.qualifier +Bundle-Version: 7.5.1.qualifier Bundle-Vendor: %Bundle-Vendor Bundle-Localization: plugin Bundle-ActivationPolicy: lazy Bundle-RequiredExecutionEnvironment: JavaSE-17 Bundle-SCM: url=https://github.com/eclipse-jgit/jgit, connection=scm:git:https://eclipse.gerrithub.io/eclipse-jgit/jgit.git, developerConnection=scm:git:https://eclipse.gerrithub.io/a/eclipse-jgit/jgit.git -Import-Package: org.eclipse.jgit.api;version="[7.4.1,7.5.0)", - org.eclipse.jgit.api.errors;version="[7.4.1,7.5.0)", - org.eclipse.jgit.diff;version="[7.4.1,7.5.0)", - org.eclipse.jgit.dircache;version="[7.4.1,7.5.0)", - org.eclipse.jgit.internal.diffmergetool;version="[7.4.1,7.5.0)", - org.eclipse.jgit.internal.storage.file;version="[7.4.1,7.5.0)", - org.eclipse.jgit.junit;version="[7.4.1,7.5.0)", - org.eclipse.jgit.lib;version="[7.4.1,7.5.0)", - org.eclipse.jgit.lib.internal;version="[7.4.1,7.5.0)", - org.eclipse.jgit.merge;version="[7.4.1,7.5.0)", - org.eclipse.jgit.pgm;version="[7.4.1,7.5.0)", - org.eclipse.jgit.pgm.internal;version="[7.4.1,7.5.0)", - org.eclipse.jgit.pgm.opt;version="[7.4.1,7.5.0)", - org.eclipse.jgit.revwalk;version="[7.4.1,7.5.0)", - org.eclipse.jgit.storage.file;version="[7.4.1,7.5.0)", - org.eclipse.jgit.transport;version="[7.4.1,7.5.0)", - org.eclipse.jgit.treewalk;version="[7.4.1,7.5.0)", - org.eclipse.jgit.util;version="[7.4.1,7.5.0)", - org.eclipse.jgit.util.io;version="[7.4.1,7.5.0)", +Import-Package: org.eclipse.jgit.api;version="[7.5.1,7.6.0)", + org.eclipse.jgit.api.errors;version="[7.5.1,7.6.0)", + org.eclipse.jgit.diff;version="[7.5.1,7.6.0)", + org.eclipse.jgit.dircache;version="[7.5.1,7.6.0)", + org.eclipse.jgit.internal.diffmergetool;version="[7.5.1,7.6.0)", + org.eclipse.jgit.internal.storage.file;version="[7.5.1,7.6.0)", + org.eclipse.jgit.junit;version="[7.5.1,7.6.0)", + org.eclipse.jgit.lib;version="[7.5.1,7.6.0)", + org.eclipse.jgit.lib.internal;version="[7.5.1,7.6.0)", + org.eclipse.jgit.merge;version="[7.5.1,7.6.0)", + org.eclipse.jgit.pgm;version="[7.5.1,7.6.0)", + org.eclipse.jgit.pgm.internal;version="[7.5.1,7.6.0)", + org.eclipse.jgit.pgm.opt;version="[7.5.1,7.6.0)", + org.eclipse.jgit.revwalk;version="[7.5.1,7.6.0)", + org.eclipse.jgit.storage.file;version="[7.5.1,7.6.0)", + org.eclipse.jgit.transport;version="[7.5.1,7.6.0)", + org.eclipse.jgit.treewalk;version="[7.5.1,7.6.0)", + org.eclipse.jgit.util;version="[7.5.1,7.6.0)", + org.eclipse.jgit.util.io;version="[7.5.1,7.6.0)", org.hamcrest.core;bundle-version="[1.1.0,3.0.0)", org.junit;version="[4.13,5.0.0)", org.junit.rules;version="[4.13,5.0.0)",
diff --git a/org.eclipse.jgit.pgm.test/pom.xml b/org.eclipse.jgit.pgm.test/pom.xml index a389ab7..0b9d6f2 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.4.1-SNAPSHOT</version> + <version>7.5.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 d533829..59d772d 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
@@ -97,9 +97,7 @@ public void testCheckoutNonExistingBranch() throws Exception { @Test public void testCheckoutWithNoRef() throws Exception { - assertStringArrayEquals( - "a valid ref is expected", - executeExpectingException("git checkout")); + assertStringArrayEquals("", execute("git checkout")); } @Test
diff --git a/org.eclipse.jgit.pgm/META-INF/MANIFEST.MF b/org.eclipse.jgit.pgm/META-INF/MANIFEST.MF index 1e03676..f65cc73 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.4.1.qualifier +Bundle-Version: 7.5.1.qualifier Bundle-Vendor: %Bundle-Vendor Bundle-Localization: OSGI-INF/l10n/plugin Bundle-RequiredExecutionEnvironment: JavaSE-17 @@ -15,50 +15,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.4.1,7.5.0)", - org.eclipse.jgit.api.errors;version="[7.4.1,7.5.0)", - org.eclipse.jgit.archive;version="[7.4.1,7.5.0)", - org.eclipse.jgit.awtui;version="[7.4.1,7.5.0)", - org.eclipse.jgit.blame;version="[7.4.1,7.5.0)", - org.eclipse.jgit.diff;version="[7.4.1,7.5.0)", - org.eclipse.jgit.dircache;version="[7.4.1,7.5.0)", - org.eclipse.jgit.errors;version="[7.4.1,7.5.0)", - org.eclipse.jgit.gitrepo;version="[7.4.1,7.5.0)", - org.eclipse.jgit.internal.diffmergetool;version="[7.4.1,7.5.0)", - org.eclipse.jgit.internal.storage.file;version="[7.4.1,7.5.0)", - org.eclipse.jgit.internal.storage.io;version="[7.4.1,7.5.0)", - org.eclipse.jgit.internal.storage.midx;version="[7.4.1,7.5.0)", - org.eclipse.jgit.internal.storage.pack;version="[7.4.1,7.5.0)", - org.eclipse.jgit.internal.storage.reftable;version="[7.4.1,7.5.0)", - org.eclipse.jgit.lfs;version="[7.4.1,7.5.0)", - org.eclipse.jgit.lfs.server;version="[7.4.1,7.5.0)", - org.eclipse.jgit.lfs.server.fs;version="[7.4.1,7.5.0)", - org.eclipse.jgit.lfs.server.s3;version="[7.4.1,7.5.0)", - org.eclipse.jgit.lib;version="[7.4.1,7.5.0)", - org.eclipse.jgit.lib.internal;version="[7.4.1,7.5.0)", - org.eclipse.jgit.merge;version="[7.4.1,7.5.0)", - org.eclipse.jgit.nls;version="[7.4.1,7.5.0)", - org.eclipse.jgit.notes;version="[7.4.1,7.5.0)", - org.eclipse.jgit.revplot;version="[7.4.1,7.5.0)", - org.eclipse.jgit.revwalk;version="[7.4.1,7.5.0)", - org.eclipse.jgit.revwalk.filter;version="[7.4.1,7.5.0)", - org.eclipse.jgit.storage.file;version="[7.4.1,7.5.0)", - org.eclipse.jgit.storage.pack;version="[7.4.1,7.5.0)", - org.eclipse.jgit.transport;version="[7.4.1,7.5.0)", - org.eclipse.jgit.transport.http.apache;version="[7.4.1,7.5.0)", - org.eclipse.jgit.transport.resolver;version="[7.4.1,7.5.0)", - org.eclipse.jgit.transport.ssh.jsch;version="[7.4.1,7.5.0)", - org.eclipse.jgit.transport.sshd;version="[7.4.1,7.5.0)", - org.eclipse.jgit.treewalk;version="[7.4.1,7.5.0)", - org.eclipse.jgit.treewalk.filter;version="[7.4.1,7.5.0)", - org.eclipse.jgit.util;version="[7.4.1,7.5.0)", - org.eclipse.jgit.util.io;version="[7.4.1,7.5.0)", + org.eclipse.jgit.api;version="[7.5.1,7.6.0)", + org.eclipse.jgit.api.errors;version="[7.5.1,7.6.0)", + org.eclipse.jgit.archive;version="[7.5.1,7.6.0)", + org.eclipse.jgit.awtui;version="[7.5.1,7.6.0)", + org.eclipse.jgit.blame;version="[7.5.1,7.6.0)", + org.eclipse.jgit.diff;version="[7.5.1,7.6.0)", + org.eclipse.jgit.dircache;version="[7.5.1,7.6.0)", + org.eclipse.jgit.errors;version="[7.5.1,7.6.0)", + org.eclipse.jgit.gitrepo;version="[7.5.1,7.6.0)", + org.eclipse.jgit.internal.diffmergetool;version="[7.5.1,7.6.0)", + org.eclipse.jgit.internal.storage.file;version="[7.5.1,7.6.0)", + org.eclipse.jgit.internal.storage.io;version="[7.5.1,7.6.0)", + org.eclipse.jgit.internal.storage.midx;version="[7.5.1,7.6.0)", + org.eclipse.jgit.internal.storage.pack;version="[7.5.1,7.6.0)", + org.eclipse.jgit.internal.storage.reftable;version="[7.5.1,7.6.0)", + org.eclipse.jgit.lfs;version="[7.5.1,7.6.0)", + org.eclipse.jgit.lfs.server;version="[7.5.1,7.6.0)", + org.eclipse.jgit.lfs.server.fs;version="[7.5.1,7.6.0)", + org.eclipse.jgit.lfs.server.s3;version="[7.5.1,7.6.0)", + org.eclipse.jgit.lib;version="[7.5.1,7.6.0)", + org.eclipse.jgit.lib.internal;version="[7.5.1,7.6.0)", + org.eclipse.jgit.merge;version="[7.5.1,7.6.0)", + org.eclipse.jgit.nls;version="[7.5.1,7.6.0)", + org.eclipse.jgit.notes;version="[7.5.1,7.6.0)", + org.eclipse.jgit.revplot;version="[7.5.1,7.6.0)", + org.eclipse.jgit.revwalk;version="[7.5.1,7.6.0)", + org.eclipse.jgit.revwalk.filter;version="[7.5.1,7.6.0)", + org.eclipse.jgit.storage.file;version="[7.5.1,7.6.0)", + org.eclipse.jgit.storage.pack;version="[7.5.1,7.6.0)", + org.eclipse.jgit.transport;version="[7.5.1,7.6.0)", + org.eclipse.jgit.transport.http.apache;version="[7.5.1,7.6.0)", + org.eclipse.jgit.transport.resolver;version="[7.5.1,7.6.0)", + org.eclipse.jgit.transport.ssh.jsch;version="[7.5.1,7.6.0)", + org.eclipse.jgit.transport.sshd;version="[7.5.1,7.6.0)", + org.eclipse.jgit.treewalk;version="[7.5.1,7.6.0)", + org.eclipse.jgit.treewalk.filter;version="[7.5.1,7.6.0)", + org.eclipse.jgit.util;version="[7.5.1,7.6.0)", + org.eclipse.jgit.util.io;version="[7.5.1,7.6.0)", org.kohsuke.args4j;version="[2.33.0,3.0.0)", org.kohsuke.args4j.spi;version="[2.33.0,3.0.0)" -Export-Package: org.eclipse.jgit.console;version="7.4.1"; +Export-Package: org.eclipse.jgit.console;version="7.5.1"; uses:="org.eclipse.jgit.transport, org.eclipse.jgit.util", - org.eclipse.jgit.pgm;version="7.4.1"; + org.eclipse.jgit.pgm;version="7.5.1"; uses:="org.eclipse.jgit.transport, org.eclipse.jgit.util.io, org.eclipse.jgit.awtui, @@ -70,14 +70,14 @@ org.eclipse.jgit.treewalk, org.eclipse.jgit.api, javax.swing", - org.eclipse.jgit.pgm.debug;version="7.4.1"; + org.eclipse.jgit.pgm.debug;version="7.5.1"; uses:="org.eclipse.jgit.util.io, org.eclipse.jgit.pgm, org.eclipse.jetty.servlet", - org.eclipse.jgit.pgm.internal;version="7.4.1"; + org.eclipse.jgit.pgm.internal;version="7.5.1"; x-friends:="org.eclipse.jgit.pgm.test, org.eclipse.jgit.test", - org.eclipse.jgit.pgm.opt;version="7.4.1"; + org.eclipse.jgit.pgm.opt;version="7.5.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 a4a81c7..1b194cd 100644 --- a/org.eclipse.jgit.pgm/META-INF/SOURCE-MANIFEST.MF +++ b/org.eclipse.jgit.pgm/META-INF/SOURCE-MANIFEST.MF
@@ -3,6 +3,6 @@ Bundle-Name: org.eclipse.jgit.pgm - Sources Bundle-SymbolicName: org.eclipse.jgit.pgm.source Bundle-Vendor: Eclipse.org - JGit -Bundle-Version: 7.4.1.qualifier +Bundle-Version: 7.5.1.qualifier Bundle-SCM: url=https://github.com/eclipse-jgit/jgit, connection=scm:git:https://eclipse.gerrithub.io/eclipse-jgit/jgit.git, developerConnection=scm:git:https://eclipse.gerrithub.io/a/eclipse-jgit/jgit.git -Eclipse-SourceBundle: org.eclipse.jgit.pgm;version="7.4.1.qualifier";roots="." +Eclipse-SourceBundle: org.eclipse.jgit.pgm;version="7.5.1.qualifier";roots="."
diff --git a/org.eclipse.jgit.pgm/pom.xml b/org.eclipse.jgit.pgm/pom.xml index 2902626..2e29c6c 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.4.1-SNAPSHOT</version> + <version>7.5.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 7a218ec..081db18 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
@@ -96,13 +96,11 @@ protected void run() throws Exception { CLIText.get().switchedToBranch, Repository.shortenRefName(ref.getName()))); } 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)); + if (name == null) { + return; } + throw die(MessageFormat.format(CLIText.get().notAValidRefName, + name, e)); } catch (RefNotFoundException e) { throw die(MessageFormat
diff --git a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/MultiPackIndex.java b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/MultiPackIndex.java index 1844223..a7df4fa 100644 --- a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/MultiPackIndex.java +++ b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/MultiPackIndex.java
@@ -16,8 +16,7 @@ import java.io.FileOutputStream; import java.io.IOException; import java.io.PrintWriter; -import java.util.HashMap; -import java.util.Map; +import java.util.LinkedHashMap; import org.eclipse.jgit.internal.storage.file.ObjectDirectory; import org.eclipse.jgit.internal.storage.file.Pack; @@ -87,7 +86,7 @@ private void writeMultiPackIndex() throws IOException { ObjectDirectory odb = (ObjectDirectory) db.getObjectDatabase(); - Map<String, PackIndex> indexes = new HashMap<>(); + LinkedHashMap<String, PackIndex> indexes = new LinkedHashMap<>(); for (Pack pack : odb.getPacks()) { PackFile packFile = pack.getPackFile().create(PackExt.INDEX); try {
diff --git a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/ObjectSizeIndex.java b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/ObjectSizeIndex.java index a40c396..492e273 100644 --- a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/ObjectSizeIndex.java +++ b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/ObjectSizeIndex.java
@@ -69,7 +69,8 @@ private void checkObjectSizeIndex() throws IOException { String name = pack.getPackName(); boolean hasObjectSizeIndex = pack.hasObjectSizeIndex(); outw.println( - String.format(" - %s - %b", name, hasObjectSizeIndex)); + String.format(" - %s - %b", name, + Boolean.valueOf(hasObjectSizeIndex))); } }
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 f788a40..4fad2d2 100644 --- a/org.eclipse.jgit.ssh.apache.agent/META-INF/MANIFEST.MF +++ b/org.eclipse.jgit.ssh.apache.agent/META-INF/MANIFEST.MF
@@ -2,17 +2,17 @@ Bundle-ManifestVersion: 2 Bundle-Name: %Bundle-Name Bundle-SymbolicName: org.eclipse.jgit.ssh.apache.agent;singleton:=true -Bundle-Version: 7.4.1.qualifier +Bundle-Version: 7.5.1.qualifier Bundle-Localization: OSGI-INF/l10n/agent Bundle-Vendor: %Bundle-Vendor -Fragment-Host: org.eclipse.jgit.ssh.apache;bundle-version="[7.4.1,7.5.0)" +Fragment-Host: org.eclipse.jgit.ssh.apache;bundle-version="[7.5.1,7.6.0)" Bundle-ActivationPolicy: lazy Automatic-Module-Name: org.eclipse.jgit.ssh.apache.agent Bundle-RequiredExecutionEnvironment: JavaSE-17 Bundle-SCM: url=https://github.com/eclipse-jgit/jgit, connection=scm:git:https://eclipse.gerrithub.io/eclipse-jgit/jgit.git, developerConnection=scm:git:https://eclipse.gerrithub.io/a/eclipse-jgit/jgit.git -Import-Package: org.eclipse.jgit.transport.sshd;version="[7.4.1,7.5.0)", - org.eclipse.jgit.nls;version="[7.4.1,7.5.0)", - org.eclipse.jgit.util;version="[7.4.1,7.5.0)" +Import-Package: org.eclipse.jgit.transport.sshd;version="[7.5.1,7.6.0)", + org.eclipse.jgit.nls;version="[7.5.1,7.6.0)", + org.eclipse.jgit.util;version="[7.5.1,7.6.0)" Require-Bundle: com.sun.jna;bundle-version="[5.8.0,6.0.0)", com.sun.jna.platform;bundle-version="[5.8.0,6.0.0)" -Export-Package: org.eclipse.jgit.internal.transport.sshd.agent.connector;version="7.4.1";x-internal:=true +Export-Package: org.eclipse.jgit.internal.transport.sshd.agent.connector;version="7.5.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 ba3d6a6..60495c9 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,6 +3,6 @@ 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.4.1.qualifier +Bundle-Version: 7.5.1.qualifier Bundle-SCM: url=https://github.com/eclipse-jgit/jgit, connection=scm:git:https://eclipse.gerrithub.io/eclipse-jgit/jgit.git, developerConnection=scm:git:https://eclipse.gerrithub.io/a/eclipse-jgit/jgit.git -Eclipse-SourceBundle: org.eclipse.jgit.ssh.apache.agent;version="7.4.1.qualifier";roots="." +Eclipse-SourceBundle: org.eclipse.jgit.ssh.apache.agent;version="7.5.1.qualifier";roots="."
diff --git a/org.eclipse.jgit.ssh.apache.agent/pom.xml b/org.eclipse.jgit.ssh.apache.agent/pom.xml index 8af671a..234dcdc 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.4.1-SNAPSHOT</version> + <version>7.5.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 a978990..973164b 100644 --- a/org.eclipse.jgit.ssh.apache.test/META-INF/MANIFEST.MF +++ b/org.eclipse.jgit.ssh.apache.test/META-INF/MANIFEST.MF
@@ -3,13 +3,13 @@ Bundle-Name: %Bundle-Name Automatic-Module-Name: org.eclipse.jgit.ssh.apache.test Bundle-SymbolicName: org.eclipse.jgit.ssh.apache.test -Bundle-Version: 7.4.1.qualifier +Bundle-Version: 7.5.1.qualifier Bundle-Vendor: %Bundle-Vendor Bundle-Localization: plugin Bundle-RequiredExecutionEnvironment: JavaSE-17 Bundle-SCM: url=https://github.com/eclipse-jgit/jgit, connection=scm:git:https://eclipse.gerrithub.io/eclipse-jgit/jgit.git, developerConnection=scm:git:https://eclipse.gerrithub.io/a/eclipse-jgit/jgit.git -Require-Bundle: org.hamcrest.core;bundle-version="[1.3.0,2.0.0)" -Import-Package: org.apache.sshd.certificate;version="[2.16.0,2.17.0)", +Import-Package: org.apache.sshd.agent;version="[2.16.0,2.17.0)", + org.apache.sshd.certificate;version="[2.16.0,2.17.0)", org.apache.sshd.client.config.hosts;version="[2.16.0,2.17.0)", org.apache.sshd.common;version="[2.16.0,2.17.0)", org.apache.sshd.common.auth;version="[2.16.0,2.17.0)", @@ -26,22 +26,23 @@ org.apache.sshd.core;version="[2.16.0,2.17.0)", org.apache.sshd.server;version="[2.16.0,2.17.0)", org.apache.sshd.server.forward;version="[2.16.0,2.17.0)", - org.eclipse.jgit.annotations;version="[7.4.1,7.5.0)", - org.eclipse.jgit.api;version="[7.4.1,7.5.0)", - org.eclipse.jgit.api.errors;version="[7.4.1,7.5.0)", - org.eclipse.jgit.errors;version="[7.4.1,7.5.0)", - org.eclipse.jgit.internal.signing.ssh;version="[7.4.1,7.5.0)", - org.eclipse.jgit.internal.storage.file;version="[7.4.1,7.5.0)", - org.eclipse.jgit.internal.transport.sshd;version="[7.4.1,7.5.0)", - org.eclipse.jgit.internal.transport.sshd.proxy;version="[7.4.1,7.5.0)", - org.eclipse.jgit.junit;version="[7.4.1,7.5.0)", - org.eclipse.jgit.junit.ssh;version="[7.4.1,7.5.0)", - org.eclipse.jgit.lib;version="[7.4.1,7.5.0)", - org.eclipse.jgit.revwalk;version="[7.4.1,7.5.0)", - org.eclipse.jgit.transport;version="[7.4.1,7.5.0)", - org.eclipse.jgit.transport.sshd;version="[7.4.1,7.5.0)", - org.eclipse.jgit.transport.sshd.agent;version="[7.4.1,7.5.0)", - org.eclipse.jgit.util;version="[7.4.1,7.5.0)", + org.eclipse.jgit.annotations;version="[7.5.1,7.6.0)", + org.eclipse.jgit.api;version="[7.5.1,7.6.0)", + org.eclipse.jgit.api.errors;version="[7.5.1,7.6.0)", + org.eclipse.jgit.errors;version="[7.5.1,7.6.0)", + org.eclipse.jgit.internal.signing.ssh;version="[7.5.1,7.6.0)", + org.eclipse.jgit.internal.storage.file;version="[7.5.1,7.6.0)", + org.eclipse.jgit.internal.transport.sshd;version="[7.5.1,7.6.0)", + org.eclipse.jgit.internal.transport.sshd.proxy;version="[7.5.1,7.6.0)", + org.eclipse.jgit.junit;version="[7.5.1,7.6.0)", + org.eclipse.jgit.junit.ssh;version="[7.5.1,7.6.0)", + org.eclipse.jgit.lib;version="[7.5.1,7.6.0)", + org.eclipse.jgit.revwalk;version="[7.5.1,7.6.0)", + org.eclipse.jgit.transport;version="[7.5.1,7.6.0)", + org.eclipse.jgit.transport.sshd;version="[7.5.1,7.6.0)", + org.eclipse.jgit.transport.sshd.agent;version="[7.5.1,7.6.0)", + org.eclipse.jgit.util;version="[7.5.1,7.6.0)", + org.hamcrest;version="[3.0.0,4.0.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 6a1fd60..72ed0d3 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.4.1-SNAPSHOT</version> + <version>7.5.1-SNAPSHOT</version> </parent> <artifactId>org.eclipse.jgit.ssh.apache.test</artifactId>
diff --git a/org.eclipse.jgit.ssh.apache.test/tst/org/eclipse/jgit/transport/sshd/ApacheSshTest.java b/org.eclipse.jgit.ssh.apache.test/tst/org/eclipse/jgit/transport/sshd/ApacheSshTest.java index 8739457..98478e5 100644 --- a/org.eclipse.jgit.ssh.apache.test/tst/org/eclipse/jgit/transport/sshd/ApacheSshTest.java +++ b/org.eclipse.jgit.ssh.apache.test/tst/org/eclipse/jgit/transport/sshd/ApacheSshTest.java
@@ -1,5 +1,5 @@ /* - * Copyright (C) 2018, 2022 Thomas Wolf <thomas.wolf@paranor.ch> and others + * Copyright (C) 2018, 2025 Thomas Wolf <thomas.wolf@paranor.ch> and others * * This program and the accompanying materials are made available under the * terms of the Eclipse Distribution License v. 1.0 which is available at @@ -16,8 +16,10 @@ import static org.junit.Assert.assertThrows; import static org.junit.Assert.assertTrue; +import java.io.BufferedInputStream; import java.io.BufferedWriter; import java.io.File; +import java.io.InputStream; import java.io.IOException; import java.io.UncheckedIOException; import java.net.URISyntaxException; @@ -26,12 +28,17 @@ import java.nio.file.StandardOpenOption; import java.security.KeyPair; import java.security.KeyPairGenerator; +import java.security.PrivateKey; import java.security.PublicKey; import java.util.Arrays; +import java.util.Collection; import java.util.Collections; +import java.util.LinkedHashMap; import java.util.List; +import java.util.Map; import java.util.stream.Collectors; +import org.apache.sshd.agent.SshAgentConstants; import org.apache.sshd.client.config.hosts.KnownHostEntry; import org.apache.sshd.client.config.hosts.KnownHostHashValue; import org.apache.sshd.common.NamedFactory; @@ -43,7 +50,12 @@ import org.apache.sshd.common.kex.DHFactory; import org.apache.sshd.common.kex.KeyExchangeFactory; import org.apache.sshd.common.session.Session; +import org.apache.sshd.common.signature.BuiltinSignatures; +import org.apache.sshd.common.signature.Signature; +import org.apache.sshd.common.util.buffer.ByteArrayBuffer; import org.apache.sshd.common.util.net.SshdSocketAddress; +import org.apache.sshd.common.util.security.SecurityUtils; +import org.apache.sshd.core.CoreModuleProperties; import org.apache.sshd.server.ServerAuthenticationManager; import org.apache.sshd.server.ServerBuilder; import org.apache.sshd.server.SshServer; @@ -55,6 +67,8 @@ import org.eclipse.jgit.transport.RemoteSession; import org.eclipse.jgit.transport.SshSessionFactory; import org.eclipse.jgit.transport.URIish; +import org.eclipse.jgit.transport.sshd.agent.Connector; +import org.eclipse.jgit.transport.sshd.agent.ConnectorFactory; import org.eclipse.jgit.util.FS; import org.junit.Test; import org.junit.experimental.theories.Theories; @@ -63,13 +77,13 @@ @RunWith(Theories.class) public class ApacheSshTest extends SshTestBase { - @Override - protected SshSessionFactory createSessionFactory() { + private SshSessionFactory createSessionFactory( + ConnectorFactory agentFactory) { return new SshdSessionFactoryBuilder() // No proxies in tests .setProxyDataFactory(null) // No ssh-agent in tests - .setConnectorFactory(null) + .setConnectorFactory(agentFactory) // The home directory is mocked at this point! .setHomeDirectory(FS.DETECTED.userHome()) .setSshDirectory(sshDir) @@ -77,6 +91,11 @@ protected SshSessionFactory createSessionFactory() { } @Override + protected SshSessionFactory createSessionFactory() { + return createSessionFactory(null); + } + + @Override protected void installConfig(String... config) { File configFile = new File(sshDir, Constants.CONFIG); if (config != null) { @@ -133,6 +152,35 @@ public void testWrongKeyFirst() throws Exception { "IdentityFile " + userKey.getAbsolutePath()); } + /** + * Test for ext-info-c being sent. Try authenticating first with a wrong RSA + * key. If ext-info-c is not set, the client will re-try three times with + * the wrong key (once for each RSA signature algorithm). Since we set the + * server to disconnect after three failed attempts, the test will fail. If + * ext-info-c _is_ sent, the client will try only once and then try the + * correct ed25519 key next and will succeed. + * + * @throws Exception + * on errors + */ + @Test + public void testKexExtension() throws Exception { + File userKey = new File(getTemporaryDirectory(), "userkey"); + copyTestResource("id_ed25519", userKey); + File publicKey = new File(getTemporaryDirectory(), "userkey.pub"); + copyTestResource("id_ed25519.pub", publicKey); + server.setTestUserPublicKey(publicKey.toPath()); + CoreModuleProperties.MAX_AUTH_REQUESTS.set(server.getPropertyResolver(), + Integer.valueOf(3)); + cloneWith("ssh://git/doesntmatter", defaultCloneDir, null, // + "Host git", // + "HostName localhost", // + "Port " + testPort, // + "User " + TEST_USER, // + "IdentityFile " + privateKey1.getAbsolutePath(), // RSA + "IdentityFile " + userKey.getAbsolutePath()); + } + @Test public void testHashedKnownHosts() throws Exception { assertTrue("Failed to delete known_hosts", knownHosts.delete()); @@ -894,4 +942,182 @@ public void testCipherModificationUnknown() throws Exception { "Ciphers 3des-cbc")); assertTrue(e.getLocalizedMessage().contains("3des-cbc")); } + + /** + * Tests that the client does not try agent keys in an arbitrary order. It + * should try agent keys that correspond to a listed IdentityFile first. + * + * @throws Exception + * on errors + */ + @Test + public void testAgentWithIdentities() throws Exception { + try (FakeAgentConnector fakeAgent = new FakeAgentConnector()) { + // Fill the agent with a few fake RSA key pairs + KeyPairGenerator generator = KeyPairGenerator.getInstance("RSA"); + generator.initialize(1024); + fakeAgent.add(generator.generateKeyPair()); + fakeAgent.add(generator.generateKeyPair()); + fakeAgent.add(generator.generateKeyPair()); + fakeAgent.add(generator.generateKeyPair()); + + File userKey = new File(getTemporaryDirectory(), "userkey"); + copyTestResource("id_ed25519", userKey); + File publicKey = new File(getTemporaryDirectory(), "userkey.pub"); + copyTestResource("id_ed25519.pub", publicKey); + server.setTestUserPublicKey(publicKey.toPath()); + try (InputStream in = new BufferedInputStream( + Files.newInputStream(userKey.toPath()))) { + Iterable<KeyPair> pairs = SecurityUtils + .loadKeyPairIdentities(null, null, in, null); + fakeAgent.add(pairs.iterator().next()); + } + + ConnectorFactory fakeFactory = new FakeConnectorFactory() { + + @Override + public Connector create(String identityAgent, File homeDir) + throws IOException { + return fakeAgent; + } + }; + SshSessionFactory.setInstance(createSessionFactory(fakeFactory)); + CoreModuleProperties.MAX_AUTH_REQUESTS + .set(server.getPropertyResolver(), Integer.valueOf(2)); + cloneWith("ssh://git/doesntmatter", defaultCloneDir, null, // + "Host git", // + "HostName localhost", // + "Port " + testPort, // + "User " + TEST_USER, // + "IdentityFile " + userKey.getAbsolutePath()); + assertTrue("Agent should have been called", fakeAgent.signCalled); + } + } + + /** + * A little dummy implementation of an SSH agent for testing. + */ + private static class FakeAgentConnector implements Connector { + + private Map<String, KeyPair> keys = new LinkedHashMap<>(); + + boolean signCalled; + + void add(KeyPair pair) { + keys.put(KeyUtils.getFingerPrint(pair.getPublic()), pair); + } + + @Override + public void close() throws IOException { + // Nothing to do + } + + @Override + public boolean connect() throws IOException { + return true; + } + + @Override + public byte[] rpc(byte command, byte[] message) throws IOException { + switch (command) { + case SshAgentConstants.SSH2_AGENTC_REQUEST_IDENTITIES: + return list(); + case SshAgentConstants.SSH2_AGENTC_SIGN_REQUEST: + signCalled = true; + return sign(message); + default: + return new byte[] { SshAgentConstants.SSH_AGENT_SUCCESS }; + } + } + + private byte[] list() { + ByteArrayBuffer result = new ByteArrayBuffer(); + result.putByte(SshAgentConstants.SSH2_AGENT_IDENTITIES_ANSWER); + result.putInt(keys.size()); + for (KeyPair pair : keys.values()) { + result.putPublicKey(pair.getPublic()); + result.putString(""); // Comment + } + return result.getCompactData(); + } + + private byte[] sign(byte[] message) { + ByteArrayBuffer buf = new ByteArrayBuffer(message, 5, + message.length - 5); + try { + PublicKey pk = buf.getPublicKey(); + byte[] dataToSign = buf.getBytes(); + int flags = buf.getInt(); + KeyPair pair = keys.get(KeyUtils.getFingerPrint(pk)); + if (pair == null) { + return new byte[] { SshAgentConstants.SSH_AGENT_FAILURE }; + } + // Figure out key type and signature + PrivateKey sk = pair.getPrivate(); + String keyType = KeyUtils.getKeyType(sk); + String signatureAlgorithm = keyType; + // We ignore complications for sk-keys or certificates here + if (keyType.equals("ssh-rsa")) { + switch (flags & 6) { + case 2: + signatureAlgorithm = KeyUtils.RSA_SHA256_KEY_TYPE_ALIAS; + break; + case 4: + signatureAlgorithm = KeyUtils.RSA_SHA512_KEY_TYPE_ALIAS; + break; + default: + break; + } + } + Signature signer = BuiltinSignatures + .fromFactoryName(signatureAlgorithm).create(); + signer.initSigner(null, sk); + signer.update(null, dataToSign); + ByteArrayBuffer sig = new ByteArrayBuffer(); + sig.putString(signatureAlgorithm); + sig.putBytes(signer.sign(null)); + ByteArrayBuffer result = new ByteArrayBuffer(); + result.putByte(SshAgentConstants.SSH2_AGENT_SIGN_RESPONSE); + result.putBytes(sig.getCompactData()); + return result.getCompactData(); + } catch (Exception e) { + return new byte[] { SshAgentConstants.SSH_AGENT_FAILURE }; + } + } + } + + abstract static class FakeConnectorFactory implements ConnectorFactory { + + @Override + public boolean isSupported() { + return true; + } + + @Override + public String getName() { + return "fake"; + } + + @Override + public Collection<ConnectorDescriptor> getSupportedConnectors() { + return Collections.singleton(getDefaultConnector()); + } + + @Override + public ConnectorDescriptor getDefaultConnector() { + return new ConnectorDescriptor() { + + @Override + public String getIdentityAgent() { + return "fake"; + } + + @Override + public String getDisplayName() { + return "fake"; + } + }; + } + + } }
diff --git a/org.eclipse.jgit.ssh.apache/META-INF/MANIFEST.MF b/org.eclipse.jgit.ssh.apache/META-INF/MANIFEST.MF index 6184991..d85e7b7 100644 --- a/org.eclipse.jgit.ssh.apache/META-INF/MANIFEST.MF +++ b/org.eclipse.jgit.ssh.apache/META-INF/MANIFEST.MF
@@ -6,11 +6,11 @@ Bundle-Vendor: %Bundle-Vendor Bundle-Localization: OSGI-INF/l10n/plugin Bundle-ActivationPolicy: lazy -Bundle-Version: 7.4.1.qualifier +Bundle-Version: 7.5.1.qualifier Bundle-RequiredExecutionEnvironment: JavaSE-17 Bundle-SCM: url=https://github.com/eclipse-jgit/jgit, connection=scm:git:https://eclipse.gerrithub.io/eclipse-jgit/jgit.git, developerConnection=scm:git:https://eclipse.gerrithub.io/a/eclipse-jgit/jgit.git -Export-Package: org.eclipse.jgit.internal.signing.ssh;version="7.4.1";x-friends:="org.eclipse.jgit.ssh.apache.test", - org.eclipse.jgit.internal.transport.sshd;version="7.4.1";x-friends:="org.eclipse.jgit.ssh.apache.test"; +Export-Package: org.eclipse.jgit.internal.signing.ssh;version="7.5.1";x-friends:="org.eclipse.jgit.ssh.apache.test", + org.eclipse.jgit.internal.transport.sshd;version="7.5.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, @@ -25,19 +25,19 @@ org.apache.sshd.common.signature, org.apache.sshd.common.util.buffer, org.eclipse.jgit.transport", - org.eclipse.jgit.internal.transport.sshd.agent;version="7.4.1";x-internal:=true, - org.eclipse.jgit.internal.transport.sshd.auth;version="7.4.1";x-internal:=true, - org.eclipse.jgit.internal.transport.sshd.pkcs11;version="7.4.1";x-internal:=true, - org.eclipse.jgit.internal.transport.sshd.proxy;version="7.4.1";x-friends:="org.eclipse.jgit.ssh.apache.test", - org.eclipse.jgit.signing.ssh;version="7.4.1";uses:="org.eclipse.jgit.lib", - org.eclipse.jgit.transport.sshd;version="7.4.1"; + org.eclipse.jgit.internal.transport.sshd.agent;version="7.5.1";x-internal:=true, + org.eclipse.jgit.internal.transport.sshd.auth;version="7.5.1";x-internal:=true, + org.eclipse.jgit.internal.transport.sshd.pkcs11;version="7.5.1";x-internal:=true, + org.eclipse.jgit.internal.transport.sshd.proxy;version="7.5.1";x-friends:="org.eclipse.jgit.ssh.apache.test", + org.eclipse.jgit.signing.ssh;version="7.5.1";uses:="org.eclipse.jgit.lib", + org.eclipse.jgit.transport.sshd;version="7.5.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.4.1" + org.eclipse.jgit.transport.sshd.agent;version="7.5.1" Import-Package: org.bouncycastle.jce.provider;version="[1.80.0,2.0.0)", org.apache.sshd.agent;version="[2.16.0,2.17.0)", org.apache.sshd.client;version="[2.16.0,2.17.0)", @@ -91,14 +91,14 @@ org.apache.sshd.sftp;version="[2.16.0,2.17.0)", org.apache.sshd.sftp.client;version="[2.16.0,2.17.0)", org.apache.sshd.sftp.common;version="[2.16.0,2.17.0)", - org.eclipse.jgit.annotations;version="[7.4.1,7.5.0)", - org.eclipse.jgit.api.errors;version="[7.4.1,7.5.0)", - org.eclipse.jgit.errors;version="[7.4.1,7.5.0)", - org.eclipse.jgit.fnmatch;version="[7.4.1,7.5.0)", - org.eclipse.jgit.internal.storage.file;version="[7.4.1,7.5.0)", - org.eclipse.jgit.internal.transport.ssh;version="[7.4.1,7.5.0)", - org.eclipse.jgit.lib;version="[7.4.1,7.5.0)", - org.eclipse.jgit.nls;version="[7.4.1,7.5.0)", - org.eclipse.jgit.transport;version="[7.4.1,7.5.0)", - org.eclipse.jgit.util;version="[7.4.1,7.5.0)", + org.eclipse.jgit.annotations;version="[7.5.1,7.6.0)", + org.eclipse.jgit.api.errors;version="[7.5.1,7.6.0)", + org.eclipse.jgit.errors;version="[7.5.1,7.6.0)", + org.eclipse.jgit.fnmatch;version="[7.5.1,7.6.0)", + org.eclipse.jgit.internal.storage.file;version="[7.5.1,7.6.0)", + org.eclipse.jgit.internal.transport.ssh;version="[7.5.1,7.6.0)", + org.eclipse.jgit.lib;version="[7.5.1,7.6.0)", + org.eclipse.jgit.nls;version="[7.5.1,7.6.0)", + org.eclipse.jgit.transport;version="[7.5.1,7.6.0)", + org.eclipse.jgit.util;version="[7.5.1,7.6.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 616eea4..ef612b7 100644 --- a/org.eclipse.jgit.ssh.apache/META-INF/SOURCE-MANIFEST.MF +++ b/org.eclipse.jgit.ssh.apache/META-INF/SOURCE-MANIFEST.MF
@@ -3,6 +3,6 @@ Bundle-Name: org.eclipse.jgit.ssh.apache - Sources Bundle-SymbolicName: org.eclipse.jgit.ssh.apache.source Bundle-Vendor: Eclipse.org - JGit -Bundle-Version: 7.4.1.qualifier +Bundle-Version: 7.5.1.qualifier Bundle-SCM: url=https://github.com/eclipse-jgit/jgit, connection=scm:git:https://eclipse.gerrithub.io/eclipse-jgit/jgit.git, developerConnection=scm:git:https://eclipse.gerrithub.io/a/eclipse-jgit/jgit.git -Eclipse-SourceBundle: org.eclipse.jgit.ssh.apache;version="7.4.1.qualifier";roots="." +Eclipse-SourceBundle: org.eclipse.jgit.ssh.apache;version="7.5.1.qualifier";roots="."
diff --git a/org.eclipse.jgit.ssh.apache/pom.xml b/org.eclipse.jgit.ssh.apache/pom.xml index 5dcee13..2de7a76 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.4.1-SNAPSHOT</version> + <version>7.5.1-SNAPSHOT</version> </parent> <artifactId>org.eclipse.jgit.ssh.apache</artifactId>
diff --git a/org.eclipse.jgit.ssh.apache/resources/org/eclipse/jgit/internal/transport/sshd/SshdText.properties b/org.eclipse.jgit.ssh.apache/resources/org/eclipse/jgit/internal/transport/sshd/SshdText.properties index 773c4b9..768b52b 100644 --- a/org.eclipse.jgit.ssh.apache/resources/org/eclipse/jgit/internal/transport/sshd/SshdText.properties +++ b/org.eclipse.jgit.ssh.apache/resources/org/eclipse/jgit/internal/transport/sshd/SshdText.properties
@@ -69,6 +69,7 @@ knownHostsUserAskCreationMsg=File {0} does not exist. knownHostsUserAskCreationPrompt=Create file {0} ? loginDenied=Cannot log in at {0}:{1} +noExplicitKeys=Host config for {0} has 'IdentitiesOnly yes' but no valid 'IdentityFile' configured. passwordPrompt=Password pkcs11Error=ERROR: {0} pkcs11FailedInstantiation=HostConfig for host {0} (hostname {1}): could not instantiate {2} {3} @@ -187,7 +188,6 @@ signSignatureError=Could not create the signature signStderr=Cannot read stderr signTooManyPrivateKeys=Private key file {0} must contain exactly one private key -signTooManyPublicKeys=Public key file {0} must contain exactly one public key signUnknownHashAlgorithm=SSH Signature has an unknown hash algorithm {0} signUnknownSignatureAlgorithm=SSH Signature has an unknown signature algorithm {0} signWrongNamespace=Key may not be used in namespace "{0}".
diff --git a/org.eclipse.jgit.ssh.apache/src/org/eclipse/jgit/internal/signing/ssh/SshCertificateUtils.java b/org.eclipse.jgit.ssh.apache/src/org/eclipse/jgit/internal/signing/ssh/SshCertificateUtils.java index 040c6d4..8ed6b8b 100644 --- a/org.eclipse.jgit.ssh.apache/src/org/eclipse/jgit/internal/signing/ssh/SshCertificateUtils.java +++ b/org.eclipse.jgit.ssh.apache/src/org/eclipse/jgit/internal/signing/ssh/SshCertificateUtils.java
@@ -17,8 +17,6 @@ import org.apache.sshd.common.config.keys.OpenSshCertificate; import org.apache.sshd.common.signature.BuiltinSignatures; import org.apache.sshd.common.signature.Signature; -import org.apache.sshd.common.util.buffer.Buffer; -import org.apache.sshd.common.util.buffer.ByteArrayBuffer; import org.eclipse.jgit.annotations.NonNull; import org.eclipse.jgit.internal.transport.sshd.SshdText; import org.slf4j.Logger; @@ -106,7 +104,7 @@ static String verifySignature(OpenSshCertificate certificate) { Signature signer = factory.create(); try { signer.initVerifier(null, caKey); - signer.update(null, getBlob(certificate)); + signer.update(null, certificate.getMessage()); if (signer.verify(null, certificate.getRawSignature())) { return null; } @@ -118,37 +116,6 @@ static String verifySignature(OpenSshCertificate certificate) { KeyUtils.getFingerPrint(certificate.getCaPubKey())); } - private static byte[] getBlob(OpenSshCertificate certificate) { - // Theoretically, this should be just certificate.getMessage(). But - // Apache MINA sshd has a bug and may return additional bytes if the - // certificate is not the first thing in the buffer it was read from. - // As a work-around, re-create the signed blob from scratch. - // - // This may be replaced by return certificate.getMessage() once the - // upstream bug is fixed. - // - // See https://github.com/apache/mina-sshd/issues/618 - Buffer tmp = new ByteArrayBuffer(); - tmp.putString(certificate.getKeyType()); - tmp.putBytes(certificate.getNonce()); - tmp.putRawPublicKeyBytes(certificate.getCertPubKey()); - tmp.putLong(certificate.getSerial()); - tmp.putInt(certificate.getType().getCode()); - tmp.putString(certificate.getId()); - Buffer list = new ByteArrayBuffer(); - list.putStringList(certificate.getPrincipals(), false); - tmp.putBytes(list.getCompactData()); - tmp.putLong(certificate.getValidAfter()); - tmp.putLong(certificate.getValidBefore()); - tmp.putCertificateOptions(certificate.getCriticalOptions()); - tmp.putCertificateOptions(certificate.getExtensions()); - tmp.putString(certificate.getReserved()); - Buffer inner = new ByteArrayBuffer(); - inner.putRawPublicKey(certificate.getCaPubKey()); - tmp.putBytes(inner.getCompactData()); - return tmp.getCompactData(); - } - /** * Checks whether a certificate is valid at a given time. *
diff --git a/org.eclipse.jgit.ssh.apache/src/org/eclipse/jgit/internal/signing/ssh/SshSigner.java b/org.eclipse.jgit.ssh.apache/src/org/eclipse/jgit/internal/signing/ssh/SshSigner.java index 8cfe5f4..d61be4c 100644 --- a/org.eclipse.jgit.ssh.apache/src/org/eclipse/jgit/internal/signing/ssh/SshSigner.java +++ b/org.eclipse.jgit.ssh.apache/src/org/eclipse/jgit/internal/signing/ssh/SshSigner.java
@@ -15,7 +15,6 @@ import java.io.IOException; import java.io.InputStreamReader; import java.io.StreamCorruptedException; -import java.io.StringReader; import java.nio.file.Files; import java.nio.file.Path; import java.security.GeneralSecurityException; @@ -27,14 +26,14 @@ import java.text.MessageFormat; import java.util.AbstractMap.SimpleImmutableEntry; import java.util.Collection; -import java.util.List; +import java.util.Collections; import java.util.Map; import java.util.Map.Entry; import org.apache.sshd.client.auth.pubkey.PublicKeyIdentity; -import org.apache.sshd.common.config.keys.AuthorizedKeyEntry; import org.apache.sshd.common.config.keys.KeyUtils; import org.apache.sshd.common.config.keys.OpenSshCertificate; +import org.apache.sshd.common.config.keys.PublicKeyEntry; import org.apache.sshd.common.config.keys.PublicKeyEntryResolver; import org.apache.sshd.common.config.keys.loader.KeyPairResourceParser; import org.apache.sshd.common.keyprovider.KeyPairProvider; @@ -243,30 +242,29 @@ private static PublicKeyIdentity getIdentity(String signingKey, PrivateKey privateKey = null; File keyFile = null; if (signingKey.startsWith(GIT_KEY_PREFIX)) { - try (StringReader r = new StringReader( - signingKey.substring(GIT_KEY_PREFIX.length()))) { - publicKey = fromEntry( - AuthorizedKeyEntry.readAuthorizedKeys(r, true)); - } + publicKey = PublicKeyEntry + .parsePublicKeyEntry( + signingKey.substring(GIT_KEY_PREFIX.length())) + .resolvePublicKey(null, Collections.emptyMap(), + PublicKeyEntryResolver.FAILING); } else if (signingKey.startsWith("~/") //$NON-NLS-1$ || signingKey.startsWith('~' + File.separator)) { keyFile = new File(FS.DETECTED.userHome(), signingKey.substring(2)); } else { - try (StringReader r = new StringReader(signingKey)) { - publicKey = fromEntry( - AuthorizedKeyEntry.readAuthorizedKeys(r, true)); - } catch (IOException e) { + try { + publicKey = PublicKeyEntry.parsePublicKeyEntry(signingKey) + .resolvePublicKey(null, Collections.emptyMap(), + PublicKeyEntryResolver.FAILING); + } catch (IllegalArgumentException e) { // Ignore and try to read as a file keyFile = new File(signingKey); } } if (keyFile != null && keyFile.isFile()) { try { - publicKey = fromEntry(AuthorizedKeyEntry - .readAuthorizedKeys(keyFile.toPath())); + publicKey = KeyUtils.loadPublicKey(keyFile.toPath()); if (publicKey == null) { - throw new IOException(MessageFormat.format( - SshdText.get().signTooManyPublicKeys, keyFile)); + throw new StreamCorruptedException(); } // Try to find the private key so we don't go looking for // the agent (or PKCS#11) in vain. @@ -303,6 +301,7 @@ private static PublicKeyIdentity getIdentity(String signingKey, privateKey = pair.getPrivate(); } } + } if (publicKey == null) { throw new IOException(MessageFormat @@ -411,15 +410,6 @@ private static GpgSignature armor(byte[] data) throws IOException { } } - private static PublicKey fromEntry(List<AuthorizedKeyEntry> entries) - throws GeneralSecurityException, IOException { - if (entries == null || entries.size() != 1) { - return null; - } - return entries.get(0).resolvePublicKey(null, - PublicKeyEntryResolver.FAILING); - } - @Override public boolean canLocateSigningKey(Repository repository, GpgConfig config, PersonIdent committer, String signingKey,
diff --git a/org.eclipse.jgit.ssh.apache/src/org/eclipse/jgit/internal/transport/sshd/JGitClientSession.java b/org.eclipse.jgit.ssh.apache/src/org/eclipse/jgit/internal/transport/sshd/JGitClientSession.java index 32d6fac..1ec4c78 100644 --- a/org.eclipse.jgit.ssh.apache/src/org/eclipse/jgit/internal/transport/sshd/JGitClientSession.java +++ b/org.eclipse.jgit.ssh.apache/src/org/eclipse/jgit/internal/transport/sshd/JGitClientSession.java
@@ -569,19 +569,19 @@ protected List<String> doReadIdentification(Buffer buffer, boolean server) start = i + 1; if (log.isDebugEnabled()) { log.debug(format("doReadIdentification({0}) line: ", this) + //$NON-NLS-1$ - escapeControls(line)); + StringUtils.escapeControls(line)); } ident.add(line); if (line.startsWith("SSH-")) { //$NON-NLS-1$ if (hasNul) { throw new StreamCorruptedException( format(SshdText.get().serverIdWithNul, - escapeControls(line))); + StringUtils.escapeControls(line))); } if (line.length() + eol > 255) { throw new StreamCorruptedException( format(SshdText.get().serverIdTooLong, - escapeControls(line))); + StringUtils.escapeControls(line))); } buffer.rpos(start); return ident; @@ -608,21 +608,6 @@ protected List<String> doReadIdentification(Buffer buffer, boolean server) return null; } - private static String escapeControls(String s) { - StringBuilder b = new StringBuilder(); - int l = s.length(); - for (int i = 0; i < l; i++) { - char ch = s.charAt(i); - if (Character.isISOControl(ch)) { - b.append(ch <= 0xF ? "\\u000" : "\\u00") //$NON-NLS-1$ //$NON-NLS-2$ - .append(Integer.toHexString(ch)); - } else { - b.append(ch); - } - } - return b.toString(); - } - @Override public <T> T getAttribute(AttributeKey<T> key) { T value = super.getAttribute(key);
diff --git a/org.eclipse.jgit.ssh.apache/src/org/eclipse/jgit/internal/transport/sshd/JGitPublicKeyAuthentication.java b/org.eclipse.jgit.ssh.apache/src/org/eclipse/jgit/internal/transport/sshd/JGitPublicKeyAuthentication.java index 6aace47..7aaa5c2 100644 --- a/org.eclipse.jgit.ssh.apache/src/org/eclipse/jgit/internal/transport/sshd/JGitPublicKeyAuthentication.java +++ b/org.eclipse.jgit.ssh.apache/src/org/eclipse/jgit/internal/transport/sshd/JGitPublicKeyAuthentication.java
@@ -1,5 +1,5 @@ /* - * Copyright (C) 2018, 2023 Thomas Wolf <twolf@apache.org> and others + * Copyright (C) 2018, 2025 Thomas Wolf <twolf@apache.org> and others * * This program and the accompanying materials are made available under the * terms of the Eclipse Distribution License v. 1.0 which is available at @@ -32,6 +32,7 @@ import java.util.Collection; import java.util.Collections; import java.util.Iterator; +import java.util.LinkedHashMap; import java.util.List; import java.util.Map; import java.util.NoSuchElementException; @@ -381,60 +382,39 @@ protected Iterable<KeyAgentIdentity> initializeAgentIdentities( if (allAgentKeys == null) { return null; } - Collection<PublicKey> identityFiles = identitiesOnly(); - if (GenericUtils.isEmpty(identityFiles)) { + if (hostConfig == null) { + return allAgentKeys; + } + Collection<PublicKey> explicitKeys = getExplicitKeys( + hostConfig.getIdentities()); + if (GenericUtils.isEmpty(explicitKeys)) { + if (hostConfig.isIdentitiesOnly()) { + log.warn(LOG_FORMAT, format(SshdText.get().noExplicitKeys, + hostConfig.getHost())); + return Collections.emptyList(); + } return allAgentKeys; } - // Only consider agent or PKCS11 keys that match a known public key - // file. - return () -> new Iterator<>() { - - private final Iterator<KeyAgentIdentity> identities = allAgentKeys - .iterator(); - - private KeyAgentIdentity next; - - @Override - public boolean hasNext() { - while (next == null && identities.hasNext()) { - KeyAgentIdentity val = identities.next(); - PublicKey pk = val.getKeyIdentity().getPublic(); - // This checks against all explicit keys for any agent - // key, but since identityFiles.size() is typically 1, - // it should be fine. - if (identityFiles.stream() - .anyMatch(k -> KeyUtils.compareKeys(k, pk))) { - next = val; - return true; - } - if (log.isTraceEnabled()) { - log.trace( - "Ignoring SSH agent or PKCS11 {} key not in explicit IdentityFile in SSH config: {}", //$NON-NLS-1$ - KeyUtils.getKeyType(pk), - KeyUtils.getFingerPrint(pk)); - } - } - return next != null; + // Sort the identities such that the ones for the explicitly listed + // keys come first, in the order listed. + Map<String, KeyAgentIdentity> fromAgent = new LinkedHashMap<>(); + allAgentKeys.forEach(k -> fromAgent.computeIfAbsent( + KeyUtils.getFingerPrint(k.getKeyIdentity().getPublic()), + x -> k)); + List<KeyAgentIdentity> result = new ArrayList<>(); + for (PublicKey pk : explicitKeys) { + KeyAgentIdentity id = fromAgent + .remove(KeyUtils.getFingerPrint(pk)); + if (id != null) { + result.add(id); } - - @Override - public KeyAgentIdentity next() { - if (!hasNext()) { - throw new NoSuchElementException(); - } - KeyAgentIdentity result = next; - next = null; - return result; - } - }; - } - - private Collection<PublicKey> identitiesOnly() { - if (hostConfig != null && hostConfig.isIdentitiesOnly()) { - return getExplicitKeys(hostConfig.getIdentities()); } - return Collections.emptyList(); + if (!hostConfig.isIdentitiesOnly()) { + result.addAll(fromAgent.values()); + } + + return result; } private Iterable<KeyAgentIdentity> getAgentIdentities()
diff --git a/org.eclipse.jgit.ssh.apache/src/org/eclipse/jgit/internal/transport/sshd/SshdText.java b/org.eclipse.jgit.ssh.apache/src/org/eclipse/jgit/internal/transport/sshd/SshdText.java index e401378..1d699b2 100644 --- a/org.eclipse.jgit.ssh.apache/src/org/eclipse/jgit/internal/transport/sshd/SshdText.java +++ b/org.eclipse.jgit.ssh.apache/src/org/eclipse/jgit/internal/transport/sshd/SshdText.java
@@ -1,5 +1,5 @@ /* - * Copyright (C) 2018, 2024 Thomas Wolf <twolf@apache.org> and others + * Copyright (C) 2018, 2025 Thomas Wolf <twolf@apache.org> and others * * This program and the accompanying materials are made available under the * terms of the Eclipse Distribution License v. 1.0 which is available at @@ -91,6 +91,7 @@ public static SshdText get() { /***/ public String knownHostsUserAskCreationMsg; /***/ public String knownHostsUserAskCreationPrompt; /***/ public String loginDenied; + /***/ public String noExplicitKeys; /***/ public String passwordPrompt; /***/ public String pkcs11Error; /***/ public String pkcs11FailedInstantiation; @@ -209,7 +210,6 @@ public static SshdText get() { /***/ public String signSignatureError; /***/ public String signStderr; /***/ public String signTooManyPrivateKeys; - /***/ public String signTooManyPublicKeys; /***/ public String signUnknownHashAlgorithm; /***/ public String signUnknownSignatureAlgorithm; /***/ public String signWrongNamespace;
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 4f1a737..4d5cc36 100644 --- a/org.eclipse.jgit.ssh.jsch.test/META-INF/MANIFEST.MF +++ b/org.eclipse.jgit.ssh.jsch.test/META-INF/MANIFEST.MF
@@ -3,22 +3,21 @@ Bundle-Name: %Bundle-Name Automatic-Module-Name: org.eclipse.jgit.ssh.jsch.test Bundle-SymbolicName: org.eclipse.jgit.ssh.jsch.test -Bundle-Version: 7.4.1.qualifier +Bundle-Version: 7.5.1.qualifier Bundle-Vendor: %Bundle-Vendor Bundle-Localization: plugin Bundle-RequiredExecutionEnvironment: JavaSE-17 Bundle-SCM: url=https://github.com/eclipse-jgit/jgit, connection=scm:git:https://eclipse.gerrithub.io/eclipse-jgit/jgit.git, developerConnection=scm:git:https://eclipse.gerrithub.io/a/eclipse-jgit/jgit.git -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.4.1,7.5.0)", - org.eclipse.jgit.internal.storage.file;version="[7.4.1,7.5.0)", - org.eclipse.jgit.junit;version="[7.4.1,7.5.0)", - org.eclipse.jgit.junit.ssh;version="[7.4.1,7.5.0)", - org.eclipse.jgit.lib;version="[7.4.1,7.5.0)", - org.eclipse.jgit.transport;version="[7.4.1,7.5.0)", - org.eclipse.jgit.transport.ssh.jsch;version="[7.4.1,7.5.0)", - org.eclipse.jgit.util;version="[7.4.1,7.5.0)", - org.hamcrest;version="[1.1.0,3.0.0)", + org.eclipse.jgit.errors;version="[7.5.1,7.6.0)", + org.eclipse.jgit.internal.storage.file;version="[7.5.1,7.6.0)", + org.eclipse.jgit.junit;version="[7.5.1,7.6.0)", + org.eclipse.jgit.junit.ssh;version="[7.5.1,7.6.0)", + org.eclipse.jgit.lib;version="[7.5.1,7.6.0)", + org.eclipse.jgit.transport;version="[7.5.1,7.6.0)", + org.eclipse.jgit.transport.ssh.jsch;version="[7.5.1,7.6.0)", + org.eclipse.jgit.util;version="[7.5.1,7.6.0)", + org.hamcrest;version="[3.0.0,4.0.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 9e9282a..0833655 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.4.1-SNAPSHOT</version> + <version>7.5.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 5a16f58..cbaf8ac 100644 --- a/org.eclipse.jgit.ssh.jsch/META-INF/MANIFEST.MF +++ b/org.eclipse.jgit.ssh.jsch/META-INF/MANIFEST.MF
@@ -3,20 +3,20 @@ 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.4.1,7.5.0)" +Fragment-Host: org.eclipse.jgit;bundle-version="[7.5.1,7.6.0)" Bundle-Vendor: %Bundle-Vendor Bundle-Localization: OSGI-INF/l10n/jsch Bundle-ActivationPolicy: lazy -Bundle-Version: 7.4.1.qualifier +Bundle-Version: 7.5.1.qualifier Bundle-RequiredExecutionEnvironment: JavaSE-17 Bundle-SCM: url=https://github.com/eclipse-jgit/jgit, connection=scm:git:https://eclipse.gerrithub.io/eclipse-jgit/jgit.git, developerConnection=scm:git:https://eclipse.gerrithub.io/a/eclipse-jgit/jgit.git -Export-Package: org.eclipse.jgit.transport.ssh.jsch;version="7.4.1" +Export-Package: org.eclipse.jgit.transport.ssh.jsch;version="7.5.1" Import-Package: com.jcraft.jsch;version="[0.1.37,0.2.0)", - org.eclipse.jgit.errors;version="[7.4.1,7.5.0)", - org.eclipse.jgit.internal;version="[7.4.1,7.5.0)", - org.eclipse.jgit.internal.transport.ssh;version="[7.4.1,7.5.0)", - org.eclipse.jgit.nls;version="[7.4.1,7.5.0)", - org.eclipse.jgit.transport;version="[7.4.1,7.5.0)", - org.eclipse.jgit.util;version="[7.4.1,7.5.0)", - org.eclipse.jgit.util.io;version="[7.4.1,7.5.0)", + org.eclipse.jgit.errors;version="[7.5.1,7.6.0)", + org.eclipse.jgit.internal;version="[7.5.1,7.6.0)", + org.eclipse.jgit.internal.transport.ssh;version="[7.5.1,7.6.0)", + org.eclipse.jgit.nls;version="[7.5.1,7.6.0)", + org.eclipse.jgit.transport;version="[7.5.1,7.6.0)", + org.eclipse.jgit.util;version="[7.5.1,7.6.0)", + org.eclipse.jgit.util.io;version="[7.5.1,7.6.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 25c136f..f8b3415 100644 --- a/org.eclipse.jgit.ssh.jsch/META-INF/SOURCE-MANIFEST.MF +++ b/org.eclipse.jgit.ssh.jsch/META-INF/SOURCE-MANIFEST.MF
@@ -3,6 +3,6 @@ Bundle-Name: org.eclipse.jgit.ssh.jsch - Sources Bundle-SymbolicName: org.eclipse.jgit.ssh.jsch.source Bundle-Vendor: Eclipse.org - JGit -Bundle-Version: 7.4.1.qualifier +Bundle-Version: 7.5.1.qualifier Bundle-SCM: url=https://github.com/eclipse-jgit/jgit, connection=scm:git:https://eclipse.gerrithub.io/eclipse-jgit/jgit.git, developerConnection=scm:git:https://eclipse.gerrithub.io/a/eclipse-jgit/jgit.git -Eclipse-SourceBundle: org.eclipse.jgit.ssh.jsch;version="7.4.1.qualifier";roots="." +Eclipse-SourceBundle: org.eclipse.jgit.ssh.jsch;version="7.5.1.qualifier";roots="."
diff --git a/org.eclipse.jgit.ssh.jsch/pom.xml b/org.eclipse.jgit.ssh.jsch/pom.xml index cb706c6..e6781d8 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.4.1-SNAPSHOT</version> + <version>7.5.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 1f6d0eb..1cf7813 100644 --- a/org.eclipse.jgit.test/META-INF/MANIFEST.MF +++ b/org.eclipse.jgit.test/META-INF/MANIFEST.MF
@@ -3,13 +3,11 @@ Bundle-Name: %Bundle-Name Automatic-Module-Name: org.eclipse.jgit.test Bundle-SymbolicName: org.eclipse.jgit.test -Bundle-Version: 7.4.1.qualifier +Bundle-Version: 7.5.1.qualifier Bundle-Localization: plugin Bundle-Vendor: %Bundle-Vendor Bundle-RequiredExecutionEnvironment: JavaSE-17 Bundle-SCM: url=https://github.com/eclipse-jgit/jgit, connection=scm:git:https://eclipse.gerrithub.io/eclipse-jgit/jgit.git, developerConnection=scm:git:https://eclipse.gerrithub.io/a/eclipse-jgit/jgit.git -Require-Bundle: org.hamcrest.core;bundle-version="[1.3.0,2.0.0)", - org.hamcrest.library;bundle-version="[1.3.0,2.0.0)" Import-Package: com.googlecode.javaewah;version="[1.1.6,2.0.0)", net.bytebuddy.agent;version="[1.9.0,2.0.0)", net.bytebuddy.dynamic.loading;version="[1.9.0,2.0.0)", @@ -23,66 +21,68 @@ 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.4.1,7.5.0)", - org.eclipse.jgit.api;version="[7.4.1,7.5.0)", - org.eclipse.jgit.api.errors;version="[7.4.1,7.5.0)", - org.eclipse.jgit.archive;version="[7.4.1,7.5.0)", - org.eclipse.jgit.attributes;version="[7.4.1,7.5.0)", - org.eclipse.jgit.awtui;version="[7.4.1,7.5.0)", - org.eclipse.jgit.blame;version="[7.4.1,7.5.0)", - org.eclipse.jgit.blame.cache;version="[7.4.1,7.5.0)", - org.eclipse.jgit.diff;version="[7.4.1,7.5.0)", - org.eclipse.jgit.dircache;version="[7.4.1,7.5.0)", - org.eclipse.jgit.errors;version="[7.4.1,7.5.0)", - org.eclipse.jgit.events;version="[7.4.1,7.5.0)", - org.eclipse.jgit.fnmatch;version="[7.4.1,7.5.0)", - org.eclipse.jgit.gitrepo;version="[7.4.1,7.5.0)", - org.eclipse.jgit.hooks;version="[7.4.1,7.5.0)", - org.eclipse.jgit.ignore;version="[7.4.1,7.5.0)", - org.eclipse.jgit.ignore.internal;version="[7.4.1,7.5.0)", - org.eclipse.jgit.internal;version="[7.4.1,7.5.0)", - org.eclipse.jgit.internal.diff;version="[7.4.1,7.5.0)", - org.eclipse.jgit.internal.diffmergetool;version="[7.4.1,7.5.0)", - org.eclipse.jgit.internal.fsck;version="[7.4.1,7.5.0)", - org.eclipse.jgit.internal.revwalk;version="[7.4.1,7.5.0)", - org.eclipse.jgit.internal.storage.commitgraph;version="7.4.1", - org.eclipse.jgit.internal.storage.dfs;version="[7.4.1,7.5.0)", - org.eclipse.jgit.internal.storage.file;version="[7.4.1,7.5.0)", - org.eclipse.jgit.internal.storage.io;version="[7.4.1,7.5.0)", - org.eclipse.jgit.internal.storage.memory;version="[7.4.1,7.5.0)", - org.eclipse.jgit.internal.storage.midx;version="[7.4.1,7.5.0)", - org.eclipse.jgit.internal.storage.pack;version="[7.4.1,7.5.0)", - org.eclipse.jgit.internal.storage.reftable;version="[7.4.1,7.5.0)", - org.eclipse.jgit.internal.transport.connectivity;version="[7.4.1,7.5.0)", - org.eclipse.jgit.internal.transport.http;version="[7.4.1,7.5.0)", - org.eclipse.jgit.internal.transport.parser;version="[7.4.1,7.5.0)", - org.eclipse.jgit.internal.transport.ssh;version="[7.4.1,7.5.0)", - org.eclipse.jgit.junit;version="[7.4.1,7.5.0)", - org.eclipse.jgit.junit.time;version="[7.4.1,7.5.0)", - org.eclipse.jgit.lfs;version="[7.4.1,7.5.0)", - org.eclipse.jgit.lib;version="[7.4.1,7.5.0)", - org.eclipse.jgit.lib.internal;version="[7.4.1,7.5.0)", - org.eclipse.jgit.logging;version="[7.4.1,7.5.0)", - org.eclipse.jgit.merge;version="[7.4.1,7.5.0)", - org.eclipse.jgit.nls;version="[7.4.1,7.5.0)", - org.eclipse.jgit.notes;version="[7.4.1,7.5.0)", - org.eclipse.jgit.patch;version="[7.4.1,7.5.0)", - org.eclipse.jgit.pgm;version="[7.4.1,7.5.0)", - org.eclipse.jgit.pgm.internal;version="[7.4.1,7.5.0)", - org.eclipse.jgit.revplot;version="[7.4.1,7.5.0)", - org.eclipse.jgit.revwalk;version="[7.4.1,7.5.0)", - org.eclipse.jgit.revwalk.filter;version="[7.4.1,7.5.0)", - org.eclipse.jgit.storage.file;version="[7.4.1,7.5.0)", - org.eclipse.jgit.storage.pack;version="[7.4.1,7.5.0)", - org.eclipse.jgit.submodule;version="[7.4.1,7.5.0)", - org.eclipse.jgit.transport;version="[7.4.1,7.5.0)", - org.eclipse.jgit.transport.http;version="[7.4.1,7.5.0)", - org.eclipse.jgit.transport.resolver;version="[7.4.1,7.5.0)", - org.eclipse.jgit.treewalk;version="[7.4.1,7.5.0)", - org.eclipse.jgit.treewalk.filter;version="[7.4.1,7.5.0)", - org.eclipse.jgit.util;version="[7.4.1,7.5.0)", - org.eclipse.jgit.util.io;version="[7.4.1,7.5.0)", - org.eclipse.jgit.util.sha1;version="[7.4.1,7.5.0)", + org.eclipse.jgit.annotations;version="[7.5.1,7.6.0)", + org.eclipse.jgit.api;version="[7.5.1,7.6.0)", + org.eclipse.jgit.api.errors;version="[7.5.1,7.6.0)", + org.eclipse.jgit.archive;version="[7.5.1,7.6.0)", + org.eclipse.jgit.attributes;version="[7.5.1,7.6.0)", + org.eclipse.jgit.awtui;version="[7.5.1,7.6.0)", + org.eclipse.jgit.blame;version="[7.5.1,7.6.0)", + org.eclipse.jgit.blame.cache;version="[7.5.1,7.6.0)", + org.eclipse.jgit.diff;version="[7.5.1,7.6.0)", + org.eclipse.jgit.dircache;version="[7.5.1,7.6.0)", + org.eclipse.jgit.errors;version="[7.5.1,7.6.0)", + org.eclipse.jgit.events;version="[7.5.1,7.6.0)", + org.eclipse.jgit.fnmatch;version="[7.5.1,7.6.0)", + org.eclipse.jgit.gitrepo;version="[7.5.1,7.6.0)", + org.eclipse.jgit.hooks;version="[7.5.1,7.6.0)", + org.eclipse.jgit.ignore;version="[7.5.1,7.6.0)", + org.eclipse.jgit.ignore.internal;version="[7.5.1,7.6.0)", + org.eclipse.jgit.internal;version="[7.5.1,7.6.0)", + org.eclipse.jgit.internal.diff;version="[7.5.1,7.6.0)", + org.eclipse.jgit.internal.diffmergetool;version="[7.5.1,7.6.0)", + org.eclipse.jgit.internal.fsck;version="[7.5.1,7.6.0)", + org.eclipse.jgit.internal.revwalk;version="[7.5.1,7.6.0)", + org.eclipse.jgit.internal.storage.commitgraph;version="7.5.1", + org.eclipse.jgit.internal.storage.dfs;version="[7.5.1,7.6.0)", + org.eclipse.jgit.internal.storage.file;version="[7.5.1,7.6.0)", + org.eclipse.jgit.internal.storage.io;version="[7.5.1,7.6.0)", + org.eclipse.jgit.internal.storage.memory;version="[7.5.1,7.6.0)", + org.eclipse.jgit.internal.storage.midx;version="[7.5.1,7.6.0)", + org.eclipse.jgit.internal.storage.pack;version="[7.5.1,7.6.0)", + org.eclipse.jgit.internal.storage.reftable;version="[7.5.1,7.6.0)", + org.eclipse.jgit.internal.transport.connectivity;version="[7.5.1,7.6.0)", + org.eclipse.jgit.internal.transport.http;version="[7.5.1,7.6.0)", + org.eclipse.jgit.internal.transport.parser;version="[7.5.1,7.6.0)", + org.eclipse.jgit.internal.transport.ssh;version="[7.5.1,7.6.0)", + org.eclipse.jgit.junit;version="[7.5.1,7.6.0)", + org.eclipse.jgit.junit.time;version="[7.5.1,7.6.0)", + org.eclipse.jgit.lfs;version="[7.5.1,7.6.0)", + org.eclipse.jgit.lib;version="[7.5.1,7.6.0)", + org.eclipse.jgit.lib.internal;version="[7.5.1,7.6.0)", + org.eclipse.jgit.logging;version="[7.5.1,7.6.0)", + org.eclipse.jgit.merge;version="[7.5.1,7.6.0)", + org.eclipse.jgit.nls;version="[7.5.1,7.6.0)", + org.eclipse.jgit.notes;version="[7.5.1,7.6.0)", + org.eclipse.jgit.patch;version="[7.5.1,7.6.0)", + org.eclipse.jgit.pgm;version="[7.5.1,7.6.0)", + org.eclipse.jgit.pgm.internal;version="[7.5.1,7.6.0)", + org.eclipse.jgit.revplot;version="[7.5.1,7.6.0)", + org.eclipse.jgit.revwalk;version="[7.5.1,7.6.0)", + org.eclipse.jgit.revwalk.filter;version="[7.5.1,7.6.0)", + org.eclipse.jgit.storage.file;version="[7.5.1,7.6.0)", + org.eclipse.jgit.storage.pack;version="[7.5.1,7.6.0)", + org.eclipse.jgit.submodule;version="[7.5.1,7.6.0)", + org.eclipse.jgit.transport;version="[7.5.1,7.6.0)", + org.eclipse.jgit.transport.http;version="[7.5.1,7.6.0)", + org.eclipse.jgit.transport.resolver;version="[7.5.1,7.6.0)", + org.eclipse.jgit.treewalk;version="[7.5.1,7.6.0)", + org.eclipse.jgit.treewalk.filter;version="[7.5.1,7.6.0)", + org.eclipse.jgit.util;version="[7.5.1,7.6.0)", + org.eclipse.jgit.util.io;version="[7.5.1,7.6.0)", + org.eclipse.jgit.util.sha1;version="[7.5.1,7.6.0)", + org.hamcrest;version="[3.0.0,4.0.0)", + org.hamcrest.collection;version="[3.0.0,4.0.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/pom.xml b/org.eclipse.jgit.test/pom.xml index b246680..f3e49af 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.4.1-SNAPSHOT</version> + <version>7.5.1-SNAPSHOT</version> </parent> <artifactId>org.eclipse.jgit.test</artifactId>
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 3e4ac1f..1f02a63 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
@@ -406,6 +406,7 @@ private void assertRegions(RevCommit commit, InMemoryBlameCache cache, } } + @SuppressWarnings("boxing") private void assertCacheUsage(RevCommit commit, InMemoryBlameCache cache, boolean cacheHit, int candidatesVisited) throws IOException { try (BlameGenerator gen = new BlameGenerator(db, FILE, cache)) { @@ -429,6 +430,7 @@ private static void assertAllLinesCovered(int lines, regions.get(regions.size() - 1).resultEnd()); } + @SuppressWarnings("boxing") private static void assertRegionsEquals(List<EmittedRegion> expected, List<EmittedRegion> actual) { assertEquals(expected.size(), actual.size());
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 6983eaa..f5f6bd3 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
@@ -1,5 +1,5 @@ /* - * Copyright (C) 2014, Andrey Loskutov <loskutov@gmx.de> and others + * Copyright (C) 2014, 2025 Andrey Loskutov <loskutov@gmx.de> and others * * This program and the accompanying materials are made available under the * terms of the Eclipse Distribution License v. 1.0 which is available at @@ -58,14 +58,4 @@ public void testStripTrailingChar() { assertEquals("a", Strings.stripTrailing("a///", '/')); assertEquals("a/ ", Strings.stripTrailing("a/ ", '/')); } - - @Test - public void testStripTrailingWhitespace() { - assertEquals("", Strings.stripTrailingWhitespace("")); - assertEquals("", Strings.stripTrailingWhitespace(" ")); - assertEquals("a", Strings.stripTrailingWhitespace("a")); - assertEquals("a", Strings.stripTrailingWhitespace("a ")); - assertEquals("a", Strings.stripTrailingWhitespace("a ")); - assertEquals("a", Strings.stripTrailingWhitespace("a \t")); - } }
diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/ignore/CGitIgnoreTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/ignore/CGitIgnoreTest.java index 083e6cd..14e4150 100644 --- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/ignore/CGitIgnoreTest.java +++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/ignore/CGitIgnoreTest.java
@@ -1,5 +1,5 @@ /* - * Copyright (C) 2017 Thomas Wolf <thomas.wolf@paranor.ch> and others + * Copyright (C) 2017, 2025 Thomas Wolf <twolf@apache.org> and others * * This program and the accompanying materials are made available under the * terms of the Eclipse Distribution License v. 1.0 which is available at @@ -15,14 +15,14 @@ import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; -import java.io.BufferedInputStream; -import java.io.BufferedReader; import java.io.ByteArrayInputStream; import java.io.File; import java.io.IOException; -import java.io.InputStreamReader; +import java.io.InputStream; import java.nio.file.Files; +import java.util.ArrayList; import java.util.LinkedHashSet; +import java.util.List; import java.util.Set; import org.eclipse.jgit.junit.RepositoryTestCase; @@ -72,7 +72,7 @@ private String toString(TemporaryBuffer b) throws IOException { private String[] cgitIgnored() throws Exception { FS fs = db.getFS(); ProcessBuilder builder = fs.runInShell("git", new String[] { "ls-files", - "--ignored", "--exclude-standard", "-o" }); + "--ignored", "--exclude-standard", "-o", "-z" }); builder.directory(db.getWorkTree()); builder.environment().put("HOME", fs.userHome().getAbsolutePath()); ExecutionResult result = fs.execute(builder, @@ -80,17 +80,13 @@ private String toString(TemporaryBuffer b) throws IOException { String errorOut = toString(result.getStderr()); assertEquals("External git failed", "exit 0\n", "exit " + result.getRc() + '\n' + errorOut); - try (BufferedReader r = new BufferedReader(new InputStreamReader( - new BufferedInputStream(result.getStdout().openInputStream()), - UTF_8))) { - return r.lines().toArray(String[]::new); - } + return readLines(result.getStdout()); } private String[] cgitUntracked() throws Exception { FS fs = db.getFS(); ProcessBuilder builder = fs.runInShell("git", - new String[] { "ls-files", "--exclude-standard", "-o" }); + new String[] { "ls-files", "--exclude-standard", "-o", "-z" }); builder.directory(db.getWorkTree()); builder.environment().put("HOME", fs.userHome().getAbsolutePath()); ExecutionResult result = fs.execute(builder, @@ -98,10 +94,26 @@ private String toString(TemporaryBuffer b) throws IOException { String errorOut = toString(result.getStderr()); assertEquals("External git failed", "exit 0\n", "exit " + result.getRc() + '\n' + errorOut); - try (BufferedReader r = new BufferedReader(new InputStreamReader( - new BufferedInputStream(result.getStdout().openInputStream()), - UTF_8))) { - return r.lines().toArray(String[]::new); + return readLines(result.getStdout()); + } + + private String[] readLines(TemporaryBuffer buf) throws IOException { + try (InputStream in = buf.openInputStreamWithAutoDestroy()) { + byte[] data = in.readAllBytes(); + int from = 0; + int to = 0; + List<String> items = new ArrayList<>(); + while (to < data.length) { + if (data[to++] == 0) { + items.add(new String(data, from, to - from - 1, UTF_8)); + from = to; + } + } + if (from < data.length) { + // Last item not terminated by NUL + items.add(new String(data, from, to - from, UTF_8)); + } + return items.toArray(new String[0]); } } @@ -119,7 +131,7 @@ private void jgitIgnoredAndUntracked(LinkedHashSet<String> ignored, ignored.add(walk.getPathString()); } else { // tests of this class won't add any files to the index, - // hence everything what is not ignored is untracked + // hence everything not ignored is untracked untracked.add(walk.getPathString()); } } @@ -302,6 +314,48 @@ public void testSimpleRootGitIgnoreGlobalNegation1() throws Exception { } @Test + public void testSingleBackslash() throws Exception { + createFiles("foo\\", "foo/foo\\", "bar"); + writeTrashFile(".gitignore", "foo\\"); + assertSameAsCGit("foo\\", "foo/foo\\", "bar"); + } + + @Test + public void testDoubleBackslash() throws Exception { + createFiles("foo\\", "foo/foo\\", "bar"); + writeTrashFile(".gitignore", "foo\\\\"); + assertSameAsCGit("bar"); + } + + @Test + public void testSingleBackslashRegexp() throws Exception { + createFiles("foobar\\", "foo/foobar\\", "bar"); + writeTrashFile(".gitignore", "fo*r\\"); + assertSameAsCGit("foobar\\", "foo/foobar\\", "bar"); + } + + @Test + public void testDoubleBackslashRegexp() throws Exception { + createFiles("foobar\\", "foo/foobar\\", "bar"); + writeTrashFile(".gitignore", "fo*r\\\\"); + assertSameAsCGit("bar"); + } + + @Test + public void testSingleBackslashRegexpInside() throws Exception { + createFiles("fo\\obar", "foo/fo\\obar", "bar", "foobar"); + writeTrashFile(".gitignore", "fo\\o*r"); + assertSameAsCGit("fo\\obar", "foo/fo\\obar", "bar"); + } + + @Test + public void testDoubleBackslashRegexpInside() throws Exception { + createFiles("fo\\obar", "foo/fo\\obar", "bar", "foobar"); + writeTrashFile(".gitignore", "fo\\\\o*r"); + assertSameAsCGit("bar", "foobar"); + } + + @Test public void testRepeatedNegationInDifferentFiles5() throws Exception { // see IgnoreNodeTest.testRepeatedNegationInDifferentFiles5 createFiles("a/b/e/nothere.o");
diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/ignore/IgnoreRuleSpecialCasesTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/ignore/IgnoreRuleSpecialCasesTest.java index 28e6858..103059a 100644 --- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/ignore/IgnoreRuleSpecialCasesTest.java +++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/ignore/IgnoreRuleSpecialCasesTest.java
@@ -1,5 +1,5 @@ /* - * Copyright (C) 2008, Florian Köberle <florianskarten@web.de> and others + * Copyright (C) 2008, 2025 Florian Köberle <florianskarten@web.de> and others * * This program and the accompanying materials are made available under the * terms of the Eclipse Distribution License v. 1.0 which is available at @@ -10,7 +10,6 @@ package org.eclipse.jgit.ignore; import static org.junit.Assert.assertEquals; -import static org.junit.Assume.assumeTrue; import org.junit.Test; @@ -18,17 +17,6 @@ public class IgnoreRuleSpecialCasesTest { private void assertMatch(final String pattern, final String input, - final boolean matchExpected, Boolean... assume) { - boolean assumeDir = input.endsWith("/"); - FastIgnoreRule matcher = new FastIgnoreRule(pattern); - if (assume.length == 0 || !assume[0].booleanValue()) { - assertEquals(matchExpected, matcher.isMatch(input, assumeDir)); - } else { - assumeTrue(matchExpected == matcher.isMatch(input, assumeDir)); - } - } - - private void assertFileNameMatch(final String pattern, final String input, final boolean matchExpected) { boolean assumeDir = input.endsWith("/"); FastIgnoreRule matcher = new FastIgnoreRule(pattern); @@ -739,7 +727,7 @@ public void testSpecialGroupCase9() throws Exception { @Test public void testSpecialGroupCase10() throws Exception { - // Second bracket is threated literally, so both [ and : should match + // Second bracket is treated literally, so both [ and : should match assertMatch("[[:]", ":", true); assertMatch("[[:]", "[", true); } @@ -835,6 +823,8 @@ public void testNotEscapingBackslash() throws Exception { assertMatch("c:\\/", "a/c:/", true); assertMatch("c:\\tmp", "c:tmp", true); assertMatch("c:\\tmp", "a/c:tmp", true); + assertMatch("foo\\/bar", "foo/bar", true); + assertMatch("foo\\/bar\\/", "foo/bar/", true); } @Test @@ -844,14 +834,21 @@ public void testMultipleEscapedCharacters1() throws Exception { @Test public void testBackslash() throws Exception { - assertMatch("a\\", "a", true); + assertMatch("a\\", "a", false); assertMatch("\\a", "a", true); - assertMatch("a/\\", "a/", true); - assertMatch("a/b\\", "a/b", true); + assertMatch("a/\\", "a/", false); + assertMatch("a/b\\", "a/b", false); assertMatch("\\a/b", "a/b", true); assertMatch("/\\a", "/a", true); - assertMatch("\\a\\b\\c\\", "abc", true); - assertMatch("/\\a/\\b/\\c\\", "a/b/c", true); + assertMatch("\\a\\b\\c\\", "abc", false); + assertMatch("\\a\\b\\c", "abc", true); + assertMatch("/\\a/\\b/\\c\\", "a/b/c", false); + assertMatch("/\\a/\\b/\\c", "a/b/c", true); + assertMatch("/\\a\\/\\b\\/\\c", "a/b/c", true); + + assertMatch("foo\\", "foo", false); + assertMatch("foo\\", "foo\\", false); + assertMatch("foo\\\\", "foo\\", true); // empty path segment doesn't match assertMatch("\\/a", "/a", false); @@ -859,6 +856,27 @@ public void testBackslash() throws Exception { } @Test + public void testBackslashInRegexp() throws Exception { + assertMatch("f*[\\x]y", "f\\y", false); + assertMatch("f*[\\x]y", "fxy", true); + assertMatch("f*[\\\\x]y", "f\\y", true); + assertMatch("f*[\\\\x]y", "fxy", true); + assertMatch("f*[\\x]y", "foo\\y", false); + assertMatch("f*[\\x]y", "fooxy", true); + assertMatch("f*[\\\\x]y", "foo\\y", true); + assertMatch("f*[\\\\x]y", "fooxy", true); + assertMatch("f*a\\y", "fa\\y", false); + assertMatch("f*a\\y", "fay", true); + assertMatch("f*a\\y", "fooa\\y", false); + assertMatch("f*a\\y", "fooay", true); + assertMatch("f*a\\\\y", "fa\\y", true); + assertMatch("f*a\\\\y", "fooa\\y", true); + assertMatch("f\\*y", "fooy", false); + assertMatch("f\\*y", "f*y", true); + assertMatch("/\\a*A\\/\\b*B\\/\\c*C", "afooA/bfooB/cC", true); + } + + @Test public void testDollar() throws Exception { assertMatch("$", "$", true); assertMatch("$x", "$x", true); @@ -991,27 +1009,27 @@ public void testBracketsRandom() throws Exception { @Test public void testFilePathSimpleCase() throws Exception { - assertFileNameMatch("a/b", "a/b", true); + assertMatch("a/b", "a/b", true); } @Test public void testFilePathCase0() throws Exception { - assertFileNameMatch("a*b", "a/b", false); + assertMatch("a*b", "a/b", false); } @Test public void testFilePathCase1() throws Exception { - assertFileNameMatch("a?b", "a/b", false); + assertMatch("a?b", "a/b", false); } @Test public void testFilePathCase2() throws Exception { - assertFileNameMatch("a*b", "a\\b", true); + assertMatch("a*b", "a\\b", true); } @Test public void testFilePathCase3() throws Exception { - assertFileNameMatch("a?b", "a\\b", true); + assertMatch("a?b", "a\\b", true); } }
diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/indexdiff/IndexDiffWithSymlinkTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/indexdiff/IndexDiffWithSymlinkTest.java index 1119db3..c4efea5 100644 --- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/indexdiff/IndexDiffWithSymlinkTest.java +++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/indexdiff/IndexDiffWithSymlinkTest.java
@@ -65,6 +65,7 @@ import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; +import java.util.Arrays; import java.util.Collections; import org.eclipse.jgit.junit.LocalDiskRepositoryTestCase; @@ -79,6 +80,8 @@ import org.eclipse.jgit.util.SystemReader; import org.junit.Before; import org.junit.Test; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; /** * MacOS-only test for dealing with symlinks in IndexDiff. Recreates using cgit @@ -89,6 +92,9 @@ */ public class IndexDiffWithSymlinkTest extends LocalDiskRepositoryTestCase { + private static final Logger LOG = LoggerFactory + .getLogger(IndexDiffWithSymlinkTest.class); + private static final String FILEREPO = "filerepo"; private static final String TESTFOLDER = "testfolder"; @@ -205,7 +211,17 @@ public void testSymlinkWithEncodingDifference() throws Exception { linkTarget.toString()); raw = rawPath(linkTarget); if (raw != null) { - assertArrayEquals("Expected an NFD link target", NFD, raw); + // Prior to Java 20, Java would convert to NFD on Mac to be + // compliant with HFS+. Since Java 20, it doesn't because APFS + // stores file names in NFC. See JDK-8289689. + if (Arrays.equals(NFD, raw)) { + LOG.info("Symlink was written by Java as NFD"); + } else { + assertArrayEquals("Expected an NFC link target", NFC, raw); + LOG.info("Symlink was written by Java as NFC"); + } + } else { + LOG.warn("Cannot determine raw symbolic link content"); } // Do the indexdiff WorkingTreeIterator iterator = new FileTreeIterator(testRepo);
diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/dfs/DfsBlockMidxTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/dfs/DfsBlockMidxTest.java new file mode 100644 index 0000000..8ac77c6 --- /dev/null +++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/dfs/DfsBlockMidxTest.java
@@ -0,0 +1,111 @@ +/* + * 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 + * http://www.eclipse.org/org/documents/edl-v10.php. + * + * SPDX-License-Identifier: BSD-3-Clause + */ +package org.eclipse.jgit.internal.storage.dfs; + +import static org.junit.Assert.assertArrayEquals; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; + +import java.nio.ByteBuffer; +import java.util.Arrays; + +import org.eclipse.jgit.internal.storage.pack.PackExt; +import org.eclipse.jgit.junit.JGitTestUtil; +import org.eclipse.jgit.junit.TestRng; +import org.junit.Test; + +public class DfsBlockMidxTest { + + private static final DfsStreamKey key = DfsStreamKey + .of(new DfsRepositoryDescription("repo"), "pack-1", PackExt.PACK); + + @Test + public void block_boundaries() { + DfsStreamKey key = DfsStreamKey.of(new DfsRepositoryDescription("repo"), + "pack-1", PackExt.PACK); + DfsBlock block = new DfsBlock(key, 600, new byte[300]); + + DfsBlockMidx midxBlock = new DfsBlockMidx(block, 1000); + assertEquals(block.start, midxBlock.start); + assertEquals(block.end, midxBlock.end); + assertEquals(block.stream, midxBlock.stream); + } + + @Test + public void block_size() { + byte[] rawData = new TestRng(JGitTestUtil.getName()).nextBytes(300); + DfsBlock block600to900 = new DfsBlock(key, 600, rawData); + DfsBlockMidx midxBlock = new DfsBlockMidx(block600to900, 1000); + assertEquals(300, midxBlock.size()); + } + + @Test + public void block_copy_allBytesInBlock() { + byte[] rawData = new TestRng(JGitTestUtil.getName()).nextBytes(300); + // Block from positions 600 to 900 in a pack X + DfsBlock block600to900 = new DfsBlock(key, 600, rawData); + // Pack X starts at offset 1000 in the multipack index + DfsBlockMidx midxBlock = new DfsBlockMidx(block600to900, 1000); + + int bytesToCopy = 50; + byte[] dest = new byte[bytesToCopy]; + // Copy from midx(1700, 1750) => pack(700, 750) => block(100, 150) + int copied = midxBlock.copy(1700, dest, 0, bytesToCopy); + + assertEquals(bytesToCopy, copied); + byte[] expected = Arrays.copyOfRange(rawData, 100, 150); + assertArrayEquals(expected, dest); + } + + @Test + public void block_copy_notEnoughInBlock() { + byte[] rawData = new TestRng(JGitTestUtil.getName()).nextBytes(300); + DfsBlock block600to900 = new DfsBlock(key, 600, rawData); + DfsBlockMidx midxBlock = new DfsBlockMidx(block600to900, 1000); + + int bytesToCopy = 500; + byte[] dest = new byte[bytesToCopy]; + // Copy from midx(1700, 2100) => pack(700, 1100) => block(700, 900) + // (the block doesn't have all the bytes) + int r = midxBlock.copy(1700, dest, 0, bytesToCopy); + + assertEquals(200, r); + byte[] expected = Arrays.copyOfRange(rawData, 100, 300); + assertArrayEqualSegment(expected, dest, 0, 200); + } + + @Test + public void block_contains() { + byte[] rawData = new TestRng(JGitTestUtil.getName()).nextBytes(300); + DfsBlock block600to900 = new DfsBlock(key, 600, rawData); + DfsBlockMidx midxBlock = new DfsBlockMidx(block600to900, 1000); + + assertTrue(midxBlock.contains(key, 1700)); + assertFalse(midxBlock.contains(key, 2100)); + assertFalse(midxBlock.contains(key, 699)); + } + + @Test + public void block_zeroCopyByteBuffer() { + byte[] rawData = new TestRng(JGitTestUtil.getName()).nextBytes(300); + DfsBlock block600to900 = new DfsBlock(key, 600, rawData); + ByteBuffer bb = block600to900.zeroCopyByteBuffer(54); + + assertEquals(rawData[54], bb.get()); + } + + private static void assertArrayEqualSegment(byte[] expected, byte[] actual, int start, int end) { + assertTrue(start < end); + for (int i = start; i < end; i++) { + assertEquals("Diff at position" + i, expected[i], actual[i]); + } + } +}
diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/dfs/DfsGarbageCollectorTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/dfs/DfsGarbageCollectorTest.java index 80bd689..0752cd5 100644 --- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/dfs/DfsGarbageCollectorTest.java +++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/dfs/DfsGarbageCollectorTest.java
@@ -4,6 +4,7 @@ import static org.eclipse.jgit.internal.storage.dfs.DfsObjDatabase.PackSource.GC_REST; import static org.eclipse.jgit.internal.storage.dfs.DfsObjDatabase.PackSource.INSERT; import static org.eclipse.jgit.internal.storage.dfs.DfsObjDatabase.PackSource.UNREACHABLE_GARBAGE; +import static org.eclipse.jgit.internal.storage.pack.PackExt.MULTI_PACK_INDEX; import static org.eclipse.jgit.internal.storage.pack.PackExt.PACK; import static org.eclipse.jgit.internal.storage.pack.PackExt.REFTABLE; import static org.eclipse.jgit.lib.Constants.OBJECT_ID_LENGTH; @@ -18,9 +19,12 @@ import java.io.IOException; import java.time.Instant; import java.time.ZoneOffset; +import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; +import java.util.List; import java.util.concurrent.TimeUnit; +import java.util.stream.Collectors; import org.eclipse.jgit.internal.storage.commitgraph.CommitGraph; import org.eclipse.jgit.internal.storage.commitgraph.CommitGraphWriter; @@ -42,6 +46,7 @@ import org.eclipse.jgit.lib.ObjectId; import org.eclipse.jgit.lib.ObjectIdRef; import org.eclipse.jgit.lib.PersonIdent; +import org.eclipse.jgit.lib.ProgressMonitor; import org.eclipse.jgit.lib.Ref; import org.eclipse.jgit.lib.Repository; import org.eclipse.jgit.revwalk.RevBlob; @@ -62,12 +67,15 @@ public class DfsGarbageCollectorTest { private DfsObjDatabase odb; private MockSystemReader mockSystemReader; + private static final ProgressMonitor NULL_PM = NullProgressMonitor.INSTANCE; + @Before public void setUp() throws IOException { DfsRepositoryDescription desc = new DfsRepositoryDescription("test"); git = new TestRepository<>(new InMemoryRepository(desc)); repo = git.getRepository(); odb = repo.getObjectDatabase(); + odb.setUseMultipackIndex(true); mockSystemReader = new MockSystemReader(); SystemReader.setInstance(mockSystemReader); } @@ -1227,6 +1235,120 @@ public void objectSizeIndex_unreachableGarbage_noIdx() throws Exception { } @Test + public void midx_oneMidx_deleteMidxs_allObjectsOneGC() throws Exception { + String master = "refs/heads/master"; + RevCommit root = git.branch(master).commit().message("root").noParents() + .create(); + git.branch(master).commit().message("commit on head") + .add("file.txt", git.blob("a blob")).parent(root).create(); + assertEquals(3, countPacks(INSERT)); + + DfsPackDescription midx = DfsMidxWriter.writeMidx( + NullProgressMonitor.INSTANCE, odb, + Arrays.asList(odb.getPacks()), null); + odb.commitPack(List.of(midx), null); + + gcNoTtl(); + + // Only one pack, is GC but not multipack index + assertEquals(1, odb.getPacks().length); + DfsPackDescription actualDesc = odb.getPacks()[0].getPackDescription(); + assertEquals(GC, actualDesc.getPackSource()); + assertFalse(actualDesc.hasFileExt(MULTI_PACK_INDEX)); + DfsPackFile pack = odb.getPacks()[0]; + assertFalse(pack instanceof DfsPackFileMidx); + assertFalse(odb.listPacks().contains(midx)); + } + + @Test + public void midx_chainedMidx_deleteMidxs_allObjsInOneGC() throws Exception { + String master = "refs/heads/master"; + List<RevCommit> knownCommits = new ArrayList<>(11); + RevCommit root = git.branch(master).commit().message("root").noParents() + .create(); + knownCommits.add(root); + RevCommit tip = root; + for (int i = 0; i < 10; i++) { + tip = git.branch(master).commit().message("commit on head") + .add("file.txt", git.blob("a blob " + i)).parent(tip) + .create(); + knownCommits.add(tip); + // Each of these creates two packs + } + assertEquals(21, countPacks(INSERT)); + + List<DfsPackFile> basicPacks = Arrays.stream(odb.getPacks()) + .collect(Collectors.toUnmodifiableList()); + DfsPackDescription midx = DfsMidxWriter.writeMidx(NULL_PM, odb, + basicPacks.subList(0, 9), null); + odb.commitPack(List.of(midx), null); + + DfsPackDescription midx2 = DfsMidxWriter.writeMidx(NULL_PM, odb, + basicPacks.subList(9, 21), midx); + odb.commitPack(List.of(midx2), null); + + // Verify we got one pack that is an midx + // This is testing the test code + assertEquals(1, odb.getPacks().length); + assertTrue(odb.getPacks()[0] instanceof DfsPackFileMidx); + DfsPackDescription theDesc = odb.getPacks()[0].getPackDescription(); + assertTrue(theDesc.hasFileExt(MULTI_PACK_INDEX)); + assertEquals(12, theDesc.getCoveredPacks().size()); + assertEquals(theDesc.getMultiPackIndexBase(), midx); + assertEquals(9, + theDesc.getMultiPackIndexBase().getCoveredPacks().size()); + gcNoTtl(); + + // One pack, GC WITHOUT multipack index, contains ALL objects + assertEquals(1, odb.getPacks().length); + DfsPackFile pack = odb.getPacks()[0]; + assertEquals(GC, pack.getPackDescription().getPackSource()); + assertFalse(pack instanceof DfsPackFileMidx); + assertFalse(pack.getPackDescription().hasFileExt(MULTI_PACK_INDEX)); + for (RevCommit c : knownCommits) { + assertTrue(isObjectInPack(c, pack)); + } + assertFalse(odb.listPacks().contains(midx)); + assertFalse(odb.listPacks().contains(midx2)); + } + + @Test + public void midx_packAndMidx_deleteMidxs_allObjectsOneGC() + throws Exception { + String master = "refs/heads/master"; + RevCommit root = git.branch(master).commit().message("root").noParents() + .create(); + RevCommit tip = git.branch(master).commit().message("commit on head") + .add("file.txt", git.blob("a blob")).parent(root).create(); + assertEquals(3, countPacks(INSERT)); + + List<DfsPackFile> packs = Arrays.stream(odb.getPacks()).toList(); + DfsPackDescription midx = DfsMidxWriter.writeMidx(NULL_PM, odb, packs, + null); + odb.commitPack(List.of(midx), null); + + RevBlob blobOutOfMidx = git.blob("some content"); + RevCommit commitOutOfMidx = git.branch(master).commit() + .message("an extra commit").add("other.txt", blobOutOfMidx) + .parent(tip).create(); + assertEquals(3, odb.getPacks().length); // midx + 2 new packs + gcNoTtl(); + + // Only one pack, is GC but not multipack index + assertEquals(1, odb.getPacks().length); + DfsPackDescription actualDesc = odb.getPacks()[0].getPackDescription(); + assertEquals(GC, actualDesc.getPackSource()); + assertFalse(actualDesc.hasFileExt(MULTI_PACK_INDEX)); + assertFalse(odb.listPacks().contains(midx)); + + DfsPackFile pack = odb.getPacks()[0]; + assertTrue(isObjectInPack(root, pack)); + assertTrue(isObjectInPack(root, pack)); + assertTrue(isObjectInPack(blobOutOfMidx, pack)); + assertTrue(isObjectInPack(commitOutOfMidx, pack)); + } + + @Test public void bitmapIndexWrittenDuringGc() throws Exception { int numBranches = 2; int commitsPerBranch = 50;
diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/dfs/DfsObjDatabaseTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/dfs/DfsObjDatabaseTest.java new file mode 100644 index 0000000..e159fef --- /dev/null +++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/dfs/DfsObjDatabaseTest.java
@@ -0,0 +1,345 @@ +/* + * 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.internal.storage.dfs; + +import static org.eclipse.jgit.internal.storage.dfs.DfsObjDatabase.PackSource.COMPACT; +import static org.eclipse.jgit.internal.storage.dfs.DfsObjDatabase.PackSource.GC; +import static org.eclipse.jgit.internal.storage.dfs.DfsObjDatabase.PackSource.INSERT; +import static org.eclipse.jgit.internal.storage.pack.PackExt.MULTI_PACK_INDEX; +import static org.eclipse.jgit.internal.storage.pack.PackExt.PACK; +import static org.eclipse.jgit.internal.storage.pack.PackExt.REFTABLE; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; + +import java.io.IOException; +import java.util.Arrays; +import java.util.Collections; +import java.util.List; + +import org.eclipse.jgit.internal.storage.pack.PackExt; +import org.junit.Before; +import org.junit.Test; + +public class DfsObjDatabaseTest { + InMemoryRepository db; + + private static final DfsRepositoryDescription repoDesc = new DfsRepositoryDescription( + "test"); + + @Before + public void setUp() { + db = new InMemoryRepository(repoDesc); + } + + @Test + public void getPacks_allInMidx_midxEnabled_onlyMidx() throws IOException { + db.getObjectDatabase().setUseMultipackIndex(true); + + DfsPackDescription gcPack = pack("aaaa", GC, 100, PACK); + DfsPackDescription compactPack = pack("cccc", COMPACT, 101, PACK); + DfsPackDescription compactTwoPack = pack("bbbb", COMPACT, 102, PACK); + + DfsPackDescription multiPackIndex = pack("xxxx", GC, 104, + MULTI_PACK_INDEX); + multiPackIndex + .setCoveredPacks(List.of(gcPack, compactPack, compactTwoPack)); + + db.getObjectDatabase().commitPack( + List.of(gcPack, compactPack, compactTwoPack, multiPackIndex), + Collections.emptyList()); + + DfsPackFile[] packs = db.getObjectDatabase().getPacks(); + assertPackList(packs, multiPackIndex); + } + + @Test + public void getPacks_allInMidx_midxDisabled_packsNoMidx() + throws IOException { + db.getObjectDatabase().setUseMultipackIndex(false); + + DfsPackDescription gcPack = pack("aaaa", GC, 100, PACK); + DfsPackDescription compactPack = pack("cccc", COMPACT, 101, PACK); + DfsPackDescription compactTwoPack = pack("bbbb", COMPACT, 102, PACK); + + DfsPackDescription multiPackIndex = pack("xxxx", GC, 104, + MULTI_PACK_INDEX); + multiPackIndex + .setCoveredPacks(List.of(gcPack, compactPack, compactTwoPack)); + + db.getObjectDatabase().commitPack( + List.of(gcPack, compactPack, compactTwoPack, multiPackIndex), + Collections.emptyList()); + + DfsPackFile[] packs = db.getObjectDatabase().getPacks(); + assertPackList(packs, compactTwoPack, compactPack, gcPack); + } + + @Test + public void getPacks_someInMidx_midxEnabled_midxPlusUncovered() + throws IOException { + db.getObjectDatabase().setUseMultipackIndex(true); + + DfsPackDescription gcPack = pack("aaaa", GC, 100, PACK); + DfsPackDescription compactPack = pack("cccc", COMPACT, 101, PACK); + DfsPackDescription insertPack = pack("bbbb", COMPACT, 102, PACK); + + DfsPackDescription multiPackIndex = pack("xxxx", GC, 104, + MULTI_PACK_INDEX); + multiPackIndex.setCoveredPacks(List.of(gcPack, compactPack, insertPack)); + db.getObjectDatabase().commitPack( + List.of(gcPack, compactPack, insertPack, multiPackIndex), + null); + + DfsPackDescription uncoveredPack = pack("dddd", COMPACT, 103, PACK); + db.getObjectDatabase().commitPack(List.of(uncoveredPack), null); + + DfsPackFile[] packs = db.getObjectDatabase().getPacks(); + assertPackList(packs, uncoveredPack, multiPackIndex); + } + + @Test + public void getPacks_someInMidx_midxDisabled_packsNoMidx() + throws IOException { + db.getObjectDatabase().setUseMultipackIndex(false); + + DfsPackDescription gcPack = pack("aaaa", GC, 100, PACK); + DfsPackDescription compactPack = pack("cccc", COMPACT, 101, PACK); + DfsPackDescription insertPack = pack("bbbb", COMPACT, 102, PACK); + + DfsPackDescription multiPackIndex = pack("xxxx", GC, 104, + MULTI_PACK_INDEX); + multiPackIndex + .setCoveredPacks(List.of(gcPack, compactPack, insertPack)); + db.getObjectDatabase().commitPack( + List.of(gcPack, compactPack, insertPack, multiPackIndex), null); + + DfsPackDescription uncoveredPack = pack("dddd", COMPACT, 103, PACK); + db.getObjectDatabase().commitPack(List.of(uncoveredPack), null); + + DfsPackFile[] packs = db.getObjectDatabase().getPacks(); + assertPackList(packs, uncoveredPack, insertPack, compactPack, gcPack); + } + + @Test + public void getPacks_midxChain_midxEnabled_topMidx() throws IOException { + db.getObjectDatabase().setUseMultipackIndex(true); + + DfsPackDescription gcPack = pack("aaaa", GC, 100, PACK); + DfsPackDescription compactPack = pack("cccc", COMPACT, 101, PACK); + DfsPackDescription insertPack = pack("bbbb", COMPACT, 102, PACK); + + DfsPackDescription midxBase = pack("xxxx", GC, 104, + MULTI_PACK_INDEX); + midxBase.setCoveredPacks(List.of(gcPack, compactPack, insertPack)); + db.getObjectDatabase().commitPack( + List.of(gcPack, compactPack, insertPack, midxBase), + null); + + DfsPackDescription insert1 = pack("insert1", INSERT, 105, PACK); + DfsPackDescription insert2 = pack("insert2", INSERT, 106, PACK); + DfsPackDescription midxTip = pack("xxx2", GC, 107, MULTI_PACK_INDEX); + midxTip.setCoveredPacks(List.of(insert1, insert2)); + midxTip.setMultiPackIndexBase(midxBase); + db.getObjectDatabase().commitPack(List.of(insert1, insert2, midxTip), null); + + DfsPackFile[] packs = db.getObjectDatabase().getPacks(); + assertPackList(packs, midxTip); + } + + @Test + public void getPacks_midxChain_midxDisabled_packsNoMidx() + throws IOException { + db.getObjectDatabase().setUseMultipackIndex(false); + + DfsPackDescription gcPack = pack("aaaa", GC, 100, PACK); + DfsPackDescription compactPack = pack("cccc", COMPACT, 101, PACK); + DfsPackDescription insertPack = pack("bbbb", COMPACT, 102, PACK); + + DfsPackDescription midxBase = pack("xxxx", GC, 104, MULTI_PACK_INDEX); + midxBase.setCoveredPacks(List.of(gcPack, compactPack, insertPack)); + db.getObjectDatabase().commitPack( + List.of(gcPack, compactPack, insertPack, midxBase), null); + + DfsPackDescription insert1 = pack("insert1", INSERT, 105, PACK); + DfsPackDescription insert2 = pack("insert2", INSERT, 106, PACK); + DfsPackDescription midxTip = pack("xxx2", GC, 107, MULTI_PACK_INDEX); + midxTip.setCoveredPacks(List.of(insert1, insert2)); + midxTip.setMultiPackIndexBase(midxBase); + db.getObjectDatabase().commitPack(List.of(insert1, insert2, midxTip), + null); + + DfsPackFile[] packs = db.getObjectDatabase().getPacks(); + assertPackList(packs, insert2, insert1, insertPack, compactPack, + gcPack); + } + + @Test + public void getReftables_multipleInsideMidx() throws IOException { + db.getObjectDatabase().setUseMultipackIndex(true); + + DfsPackDescription gcPack = pack("aaaa", GC, 100, PACK, REFTABLE); + DfsPackDescription compactPack = pack("cccc", COMPACT, 101, PACK, + REFTABLE); + DfsPackDescription compactTwoPack = pack("bbbb", COMPACT, 102, PACK); + + DfsPackDescription multiPackIndex = pack("xxxx", GC, 104, + MULTI_PACK_INDEX); + multiPackIndex + .setCoveredPacks(List.of(gcPack, compactPack, compactTwoPack)); + + db.getObjectDatabase().commitPack( + List.of(gcPack, compactPack, compactTwoPack, multiPackIndex), + Collections.emptyList()); + + DfsReftable[] reftables = db.getObjectDatabase().getReftables(); + assertReftableList(reftables, gcPack, compactPack); + } + + @Test + public void getReftables_midxChain() throws IOException { + db.getObjectDatabase().setUseMultipackIndex(true); + + DfsPackDescription gcPack = pack("aaaa", GC, 100, PACK, REFTABLE); + DfsPackDescription compactPack = pack("cccc", COMPACT, 101, PACK, + REFTABLE); + DfsPackDescription insertPack = pack("bbbb", COMPACT, 102, PACK); + + DfsPackDescription midxBase = pack("xxxx", GC, 104, MULTI_PACK_INDEX); + midxBase.setCoveredPacks(List.of(gcPack, compactPack, insertPack)); + db.getObjectDatabase().commitPack( + List.of(gcPack, compactPack, insertPack, midxBase), null); + + DfsPackDescription insert1 = pack("insert1", INSERT, 105, PACK, + REFTABLE); + DfsPackDescription insert2 = pack("insert2", INSERT, 106, PACK); + DfsPackDescription midxTip = pack("xxx2", GC, 107, MULTI_PACK_INDEX); + midxTip.setCoveredPacks(List.of(insert1, insert2)); + midxTip.setMultiPackIndexBase(midxBase); + db.getObjectDatabase().commitPack(List.of(insert1, insert2, midxTip), + null); + + DfsReftable[] reftables = db.getObjectDatabase().getReftables(); + assertReftableList(reftables, gcPack, compactPack, insert1); + } + + @Test + public void getReftables_inAndOutOfMidx() throws IOException { + db.getObjectDatabase().setUseMultipackIndex(true); + + DfsPackDescription gcPack = pack("aaaa", GC, 100, PACK, REFTABLE); + DfsPackDescription compactPack = pack("cccc", COMPACT, 101, PACK); + DfsPackDescription insertPack = pack("bbbb", COMPACT, 102, PACK); + + DfsPackDescription multiPackIndex = pack("xxxx", GC, 104, + MULTI_PACK_INDEX); + multiPackIndex + .setCoveredPacks(List.of(gcPack, compactPack, insertPack)); + db.getObjectDatabase().commitPack( + List.of(gcPack, compactPack, insertPack, multiPackIndex), null); + + DfsPackDescription uncoveredPack = pack("dddd", COMPACT, 103, PACK, + REFTABLE); + db.getObjectDatabase().commitPack(List.of(uncoveredPack), null); + + DfsReftable[] reftables = db.getObjectDatabase().getReftables(); + assertReftableList(reftables, gcPack, uncoveredPack); + } + + @Test + public void commitPack_deleteCoveredPack_deleteMidx() throws IOException { + db.getObjectDatabase().setUseMultipackIndex(true); + + DfsPackDescription gcPack = pack("aaaa", GC, 100, PACK, REFTABLE); + DfsPackDescription compactPack = pack("cccc", COMPACT, 101, PACK); + DfsPackDescription insertPack = pack("bbbb", COMPACT, 102, PACK); + + DfsPackDescription multiPackIndex = pack("xxxx", GC, 104, + MULTI_PACK_INDEX); + multiPackIndex + .setCoveredPacks(List.of(gcPack, compactPack, insertPack)); + db.getObjectDatabase().commitPack( + List.of(gcPack, compactPack, insertPack, multiPackIndex), null); + + // Delete pack covered by midx + db.getObjectDatabase().commitPack(List.of(), List.of(insertPack)); + assertFalse( + db.getObjectDatabase().listPacks().contains(multiPackIndex)); + } + + @Test + public void commitPack_replaceMidxChain_packsUndisturbed() + throws IOException { + db.getObjectDatabase().setUseMultipackIndex(true); + + DfsPackDescription gcPack = pack("aaaa", GC, 100, PACK, REFTABLE); + DfsPackDescription compactPack = pack("cccc", COMPACT, 101, PACK); + DfsPackDescription midx1 = midx("midx1", null, 102, gcPack, + compactPack); + + DfsPackDescription p3 = pack("p3", COMPACT, 103, PACK); + DfsPackDescription p4 = pack("p4", COMPACT, 104, PACK); + DfsPackDescription midx2 = midx("midx2", midx1, 105, p3, p4); + db.getObjectDatabase().commitPack( + List.of(gcPack, compactPack, midx1, p3, p4, midx2), null); + + DfsPackDescription midxAll = midx("midxAll", null, 106, gcPack, + compactPack, p3, p4); + + // Replace the midxs + db.getObjectDatabase().commitPack(List.of(midxAll), + List.of(midx1, midx2)); + + MidxPackList midxPackList = MidxPackList + .create(db.getObjectDatabase().getPacks()); + assertEquals(4, midxPackList.getAllPlainPacks().size()); + assertEquals(1, midxPackList.getAllMidxPacks().size()); + assertFalse(db.getObjectDatabase().listPacks().contains(midx1)); + assertFalse(db.getObjectDatabase().listPacks().contains(midx2)); + assertTrue(db.getObjectDatabase().listPacks().contains(midxAll)); + } + + private static DfsPackDescription pack(String name, + DfsObjDatabase.PackSource source, long timeMs, PackExt... ext) { + DfsPackDescription desc = new DfsPackDescription(repoDesc, name, + source); + desc.setLastModified(timeMs); + for (PackExt packExt : ext) { + desc.addFileExt(packExt); + } + return desc; + } + + private static DfsPackDescription midx(String name, DfsPackDescription base, + long timeMs, DfsPackDescription... covered) { + DfsPackDescription midx = pack(name, GC, timeMs, MULTI_PACK_INDEX); + midx.setCoveredPacks(Arrays.stream(covered).toList()); + if (base != null) { + midx.setMultiPackIndexBase(base); + } + return midx; + } + + private static void assertPackList(DfsPackFile[] actual, + DfsPackDescription... expected) { + assertEquals(expected.length, actual.length); + for (int i = 0; i < expected.length; i++) { + assertEquals(expected[i], actual[i].getPackDescription()); + } + } + + private static void assertReftableList(DfsReftable[] actual, + DfsPackDescription... expected) { + assertEquals(expected.length, actual.length); + for (int i = 0; i < expected.length; i++) { + assertEquals(expected[i], actual[i].getPackDescription()); + } + } +}
diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/dfs/DfsPackCompacterTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/dfs/DfsPackCompacterTest.java index c3b6aa8..84505a8 100644 --- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/dfs/DfsPackCompacterTest.java +++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/dfs/DfsPackCompacterTest.java
@@ -14,6 +14,7 @@ import static org.eclipse.jgit.internal.storage.dfs.DfsObjDatabase.PackSource.INSERT; import static org.eclipse.jgit.internal.storage.pack.PackExt.OBJECT_SIZE_INDEX; import static org.eclipse.jgit.internal.storage.pack.PackExt.PACK; +import static org.eclipse.jgit.lib.Constants.OBJ_BLOB; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; @@ -21,14 +22,20 @@ import java.io.IOException; import java.util.Arrays; import java.util.Optional; +import java.util.zip.Deflater; +import org.eclipse.jgit.junit.JGitTestUtil; import org.eclipse.jgit.junit.TestRepository; +import org.eclipse.jgit.junit.TestRng; import org.eclipse.jgit.lib.ConfigConstants; +import org.eclipse.jgit.lib.ObjectId; import org.eclipse.jgit.revwalk.RevCommit; import org.junit.Before; import org.junit.Test; public class DfsPackCompacterTest { + private static final int AUTO_ADD_SIZE = 5 * 1024 * 1024; // 5 MiB + private TestRepository<InMemoryRepository> git; private InMemoryRepository repo; private DfsObjDatabase odb; @@ -137,19 +144,62 @@ public void testObjectSizeIndexNotWritten() throws Exception { assertFalse(compactPack.get().getPackDescription().hasFileExt(OBJECT_SIZE_INDEX)); } + @Test + public void testPrunePack() throws Exception { + ObjectId o1 = writePackWithRandomBlob(200); + ObjectId o2 = writePackWithRandomBlob(100); + ObjectId o3 = writePackWithRandomBlob(210); + DfsPackFile[] packsToCompact = odb.getPacks(); + + DfsPackCompactor compactor = new DfsPackCompactor(repo); + compactor.add(packsToCompact[1]); + compactor.add(packsToCompact[2]); + compactor.prune(packsToCompact[0]); + + compactor.compact(null); + + assertEquals(1, odb.getPacks().length); + assertFalse(odb.has(o3)); // pack with o3 was pruned + assertTrue(odb.has(o1)); + assertTrue(odb.has(o2)); + } + private TestRepository<InMemoryRepository>.CommitBuilder commit() { return git.commit(); } private void compact() throws IOException { DfsPackCompactor compactor = new DfsPackCompactor(repo); - compactor.autoAdd(); + DfsObjDatabase objdb = repo.getObjectDatabase(); + for (DfsPackFile pack : objdb.getPacks()) { + DfsPackDescription d = pack.getPackDescription(); + if (d.getFileSize(PACK) < AUTO_ADD_SIZE) { + compactor.add(pack); + } else { + compactor.exclude(pack); + } + } compactor.compact(null); odb.clearCache(); } private static void writeObjectSizeIndex(DfsRepository repo, boolean should) { repo.getConfig().setInt(ConfigConstants.CONFIG_PACK_SECTION, null, - ConfigConstants.CONFIG_KEY_MIN_BYTES_OBJ_SIZE_INDEX, should ? 0 : -1); + ConfigConstants.CONFIG_KEY_MIN_BYTES_OBJ_SIZE_INDEX, + should ? 0 : -1); + } + + private ObjectId writePackWithBlob(byte[] data) throws IOException { + DfsInserter ins = (DfsInserter) repo.newObjectInserter(); + ins.setCompressionLevel(Deflater.NO_COMPRESSION); + ObjectId blobId = ins.insert(OBJ_BLOB, data); + ins.flush(); + return blobId; + } + + // Do not use the size twice into the same test (it gives the same blob!) + private ObjectId writePackWithRandomBlob(int size) throws IOException { + byte[] data = new TestRng(JGitTestUtil.getName()).nextBytes(size); + return writePackWithBlob(data); } }
diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/dfs/DfsPackFileMidxTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/dfs/DfsPackFileMidxTest.java new file mode 100644 index 0000000..48611da --- /dev/null +++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/dfs/DfsPackFileMidxTest.java
@@ -0,0 +1,1267 @@ +/* + * 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.internal.storage.dfs; + +import static java.nio.charset.StandardCharsets.UTF_8; +import static org.eclipse.jgit.internal.storage.dfs.DfsObjDatabase.PackSource.GC; +import static org.eclipse.jgit.internal.storage.pack.PackExt.PACK; +import static org.eclipse.jgit.lib.Constants.OBJ_BLOB; +import static org.eclipse.jgit.lib.Constants.OBJ_COMMIT; +import static org.eclipse.jgit.lib.Constants.OBJ_TREE; +import static org.junit.Assert.assertArrayEquals; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertNull; +import static org.junit.Assert.assertThrows; +import static org.junit.Assert.assertTrue; + +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.util.Arrays; +import java.util.HashMap; +import java.util.HashSet; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.zip.Deflater; + +import org.eclipse.jgit.annotations.Nullable; +import org.eclipse.jgit.internal.storage.dfs.DfsPackFileMidx.VOffsetCalculator; +import org.eclipse.jgit.internal.storage.file.PackBitmapIndex; +import org.eclipse.jgit.internal.storage.file.PackIndex; +import org.eclipse.jgit.internal.storage.midx.MultiPackIndex.PackOffset; +import org.eclipse.jgit.internal.storage.midx.MultiPackIndexWriter; +import org.eclipse.jgit.internal.storage.pack.ObjectToPack; +import org.eclipse.jgit.internal.storage.pack.PackExt; +import org.eclipse.jgit.internal.storage.pack.PackOutputStream; +import org.eclipse.jgit.internal.storage.pack.PackWriter; +import org.eclipse.jgit.junit.JGitTestUtil; +import org.eclipse.jgit.junit.TestRepository; +import org.eclipse.jgit.junit.TestRng; +import org.eclipse.jgit.lib.NullProgressMonitor; +import org.eclipse.jgit.lib.ObjectId; +import org.eclipse.jgit.lib.ObjectInserter; +import org.eclipse.jgit.lib.ObjectLoader; +import org.eclipse.jgit.lib.ProgressMonitor; +import org.eclipse.jgit.revwalk.RevBlob; +import org.eclipse.jgit.revwalk.RevCommit; +import org.eclipse.jgit.revwalk.RevTree; +import org.eclipse.jgit.revwalk.RevWalk; +import org.eclipse.jgit.storage.pack.PackConfig; +import org.junit.Before; +import org.junit.Test; + +public class DfsPackFileMidxTest { + + private static final ObjectId NOT_IN_PACK = ObjectId + .fromString("3f306cb3fcd5116919fecad615524bd6e6ea4ba7"); + + InMemoryRepository db; + + @Before + public void setUp() { + db = new InMemoryRepository(new DfsRepositoryDescription("test")); + } + + @Test + public void midx_findIdxPosition() throws IOException { + ObjectId o1 = writePackWithBlob("something".getBytes(UTF_8)); + ObjectId o2 = writePackWithBlob("something else".getBytes(UTF_8)); + ObjectId o3 = writePackWithBlob("and more".getBytes(UTF_8)); + DfsPackFile midx = writeMultipackIndex(); + + try (DfsReader ctx = db.getObjectDatabase().newReader()) { + assertEquals(2, midx.findIdxPosition(ctx, o1)); + assertEquals(0, midx.findIdxPosition(ctx, o2)); + assertEquals(1, midx.findIdxPosition(ctx, o3)); + assertEquals(-1, midx.findIdxPosition(ctx, NOT_IN_PACK)); + } + } + + @Test + public void midx_findIdxPosition_withBase() throws IOException { + ObjectId o1 = writePackWithBlob("o1".getBytes(UTF_8)); + ObjectId o2 = writePackWithBlob("o2".getBytes(UTF_8)); + ObjectId o3 = writePackWithBlob("o3".getBytes(UTF_8)); + ObjectId o4 = writePackWithBlob("o4".getBytes(UTF_8)); + ObjectId o5 = writePackWithBlob("o5".getBytes(UTF_8)); + ObjectId o6 = writePackWithBlob("o6".getBytes(UTF_8)); + DfsPackFile[] packs = db.getObjectDatabase().getPacks(); + + // Packs are in reverse insertion order + DfsPackFileMidx midxBase = writeMultipackIndex( + Arrays.copyOfRange(packs, 4, 6), null); + DfsPackFileMidx midxMid = writeMultipackIndex( + Arrays.copyOfRange(packs, 2, 4), midxBase); + DfsPackFileMidx midxTip = writeMultipackIndex( + Arrays.copyOfRange(packs, 0, 2), midxMid); + + try (DfsReader ctx = db.getObjectDatabase().newReader()) { + assertEquals(0, midxTip.findIdxPosition(ctx, o1)); + assertEquals(1, midxTip.findIdxPosition(ctx, o2)); + assertEquals(2, midxTip.findIdxPosition(ctx, o3)); + assertEquals(3, midxTip.findIdxPosition(ctx, o4)); + // In sha1 order + assertEquals(5, midxTip.findIdxPosition(ctx, o5)); + assertEquals(4, midxTip.findIdxPosition(ctx, o6)); + } + } + + @Test + public void midx_hasObject() throws IOException { + ObjectId o1 = writePackWithRandomBlob(100); + ObjectId o2 = writePackWithRandomBlob(200); + ObjectId o3 = writePackWithRandomBlob(150); + DfsPackFile midx = writeMultipackIndex(); + + // DfsPackFile midx = readDfsPackFileMidx(); + try (DfsReader ctx = db.getObjectDatabase().newReader()) { + assertTrue(midx.hasObject(ctx, o1)); + assertTrue(midx.hasObject(ctx, o2)); + assertTrue(midx.hasObject(ctx, o3)); + assertFalse(midx.hasObject(ctx, NOT_IN_PACK)); + } + } + + @Test + public void midx_hasObject_withBase() throws IOException { + ObjectId o1 = writePackWithRandomBlob(100); + ObjectId o2 = writePackWithRandomBlob(200); + ObjectId o3 = writePackWithRandomBlob(150); + ObjectId o4 = writePackWithRandomBlob(400); + ObjectId o5 = writePackWithRandomBlob(500); + ObjectId o6 = writePackWithRandomBlob(600); + DfsPackFile[] packs = db.getObjectDatabase().getPacks(); + + // Packs are in reverse insertion order + DfsPackFileMidx midxBase = writeMultipackIndex( + Arrays.copyOfRange(packs, 3, 6), null); + DfsPackFileMidx midxTip = writeMultipackIndex( + Arrays.copyOfRange(packs, 0, 3), midxBase); + + try (DfsReader ctx = db.getObjectDatabase().newReader()) { + assertTrue(midxBase.hasObject(ctx, o1)); + assertTrue(midxBase.hasObject(ctx, o2)); + assertTrue(midxBase.hasObject(ctx, o3)); + // These are not in base + assertFalse(midxBase.hasObject(ctx, o4)); + assertFalse(midxBase.hasObject(ctx, o5)); + assertFalse(midxBase.hasObject(ctx, o6)); + + // Top midx has all objects + assertTrue(midxTip.hasObject(ctx, o1)); + assertTrue(midxTip.hasObject(ctx, o2)); + assertTrue(midxTip.hasObject(ctx, o3)); + assertTrue(midxTip.hasObject(ctx, o4)); + assertTrue(midxTip.hasObject(ctx, o5)); + assertTrue(midxTip.hasObject(ctx, o6)); + } + } + + @Test + public void midx_get() throws IOException { + byte[] contentOne = "ONE".getBytes(UTF_8); + byte[] contentTwo = "TWO".getBytes(UTF_8); + byte[] contentThree = "THREE".getBytes(UTF_8); + + ObjectId o1 = writePackWithBlob(contentOne); + ObjectId o2 = writePackWithBlob(contentTwo); + ObjectId o3 = writePackWithBlob(contentThree); + DfsPackFile midx = writeMultipackIndex(); + + try (DfsReader ctx = db.getObjectDatabase().newReader()) { + ObjectLoader objectLoader = midx.get(ctx, o1); + assertArrayEquals(contentOne, safeGetBytes(objectLoader)); + objectLoader = midx.get(ctx, o2); + assertArrayEquals(contentTwo, safeGetBytes(objectLoader)); + objectLoader = midx.get(ctx, o3); + assertArrayEquals(contentThree, safeGetBytes(objectLoader)); + assertNull(midx.get(ctx, NOT_IN_PACK)); + } + } + + @Test + public void midx_get_withBase() throws IOException { + byte[] contentOne = "ONE".getBytes(UTF_8); + byte[] contentTwo = "TWO".getBytes(UTF_8); + byte[] contentThree = "THREE".getBytes(UTF_8); + byte[] contentFour = "FOUR".getBytes(UTF_8); + byte[] contentFive = "FIVE".getBytes(UTF_8); + byte[] contentSix = "SIX".getBytes(UTF_8); + + ObjectId o1 = writePackWithBlob(contentOne); + ObjectId o2 = writePackWithBlob(contentTwo); + ObjectId o3 = writePackWithBlob(contentThree); + ObjectId o4 = writePackWithBlob(contentFour); + ObjectId o5 = writePackWithBlob(contentFive); + ObjectId o6 = writePackWithBlob(contentSix); + + DfsPackFile[] packs = db.getObjectDatabase().getPacks(); + // Packs are in reverse insertion order + DfsPackFileMidx midxBase = writeMultipackIndex( + Arrays.copyOfRange(packs, 3, 6), null); + DfsPackFileMidx midxTip = writeMultipackIndex( + Arrays.copyOfRange(packs, 0, 3), midxBase); + + try (DfsReader ctx = db.getObjectDatabase().newReader()) { + ObjectLoader objectLoader = midxTip.get(ctx, o1); + assertArrayEquals(contentOne, safeGetBytes(objectLoader)); + objectLoader = midxTip.get(ctx, o2); + assertArrayEquals(contentTwo, safeGetBytes(objectLoader)); + objectLoader = midxTip.get(ctx, o3); + assertArrayEquals(contentThree, safeGetBytes(objectLoader)); + objectLoader = midxTip.get(ctx, o4); + assertArrayEquals(contentFour, safeGetBytes(objectLoader)); + objectLoader = midxTip.get(ctx, o5); + assertArrayEquals(contentFive, safeGetBytes(objectLoader)); + objectLoader = midxTip.get(ctx, o6); + assertArrayEquals(contentSix, safeGetBytes(objectLoader)); + + assertNull(midxTip.get(ctx, NOT_IN_PACK)); + } + } + + @Test + public void midx_load() throws IOException { + byte[] contentOne = "ONE".getBytes(UTF_8); + byte[] contentTwo = "TWO".getBytes(UTF_8); + byte[] contentThree = "THREE".getBytes(UTF_8); + + ObjectId o1 = writePackWithBlob(contentOne); + ObjectId o2 = writePackWithBlob(contentTwo); + ObjectId o3 = writePackWithBlob(contentThree); + DfsPackFile midx = writeMultipackIndex(); + + try (DfsReader ctx = db.getObjectDatabase().newReader()) { + ObjectLoader objectLoader = midx.load(ctx, + midx.findOffset(ctx, o1)); + assertArrayEquals(contentOne, safeGetBytes(objectLoader)); + objectLoader = midx.load(ctx, midx.findOffset(ctx, o2)); + assertArrayEquals(contentTwo, safeGetBytes(objectLoader)); + objectLoader = midx.load(ctx, midx.findOffset(ctx, o3)); + assertArrayEquals(contentThree, safeGetBytes(objectLoader)); + + assertThrows(IllegalArgumentException.class, + () -> midx.load(ctx, 500)); + assertNull(midx.load(ctx, -1)); + } + } + + @Test + public void midx_load_withBase() throws IOException { + byte[] contentOne = "ONE".getBytes(UTF_8); + byte[] contentTwo = "TWO".getBytes(UTF_8); + byte[] contentThree = "THREE".getBytes(UTF_8); + byte[] contentFour = "FOUR".getBytes(UTF_8); + byte[] contentFive = "FIVE".getBytes(UTF_8); + byte[] contentSix = "SIX".getBytes(UTF_8); + + ObjectId o1 = writePackWithBlob(contentOne); + ObjectId o2 = writePackWithBlob(contentTwo); + ObjectId o3 = writePackWithBlob(contentThree); + ObjectId o4 = writePackWithBlob(contentFour); + ObjectId o5 = writePackWithBlob(contentFive); + ObjectId o6 = writePackWithBlob(contentSix); + + DfsPackFile[] packs = db.getObjectDatabase().getPacks(); + // Packs are in reverse insertion order + DfsPackFileMidx midxBase = writeMultipackIndex( + Arrays.copyOfRange(packs, 3, 6), null); + DfsPackFileMidx midxTip = writeMultipackIndex( + Arrays.copyOfRange(packs, 0, 3), midxBase); + + try (DfsReader ctx = db.getObjectDatabase().newReader()) { + ObjectLoader objectLoader = midxTip.load(ctx, + midxTip.findOffset(ctx, o1)); + assertArrayEquals(contentOne, safeGetBytes(objectLoader)); + objectLoader = midxTip.load(ctx, midxTip.findOffset(ctx, o2)); + assertArrayEquals(contentTwo, safeGetBytes(objectLoader)); + objectLoader = midxTip.load(ctx, midxTip.findOffset(ctx, o3)); + assertArrayEquals(contentThree, safeGetBytes(objectLoader)); + objectLoader = midxTip.load(ctx, midxTip.findOffset(ctx, o4)); + assertArrayEquals(contentFour, safeGetBytes(objectLoader)); + objectLoader = midxTip.load(ctx, midxTip.findOffset(ctx, o5)); + assertArrayEquals(contentFive, safeGetBytes(objectLoader)); + objectLoader = midxTip.load(ctx, midxTip.findOffset(ctx, o6)); + assertArrayEquals(contentSix, safeGetBytes(objectLoader)); + + assertNull(midxTip.load(ctx, midxTip.findOffset(ctx, NOT_IN_PACK))); + } + } + + @Test + public void midx_findOffset() throws IOException { + ObjectId o1 = writePackWithRandomBlob(100); + ObjectId o2 = writePackWithRandomBlob(200); + ObjectId o3 = writePackWithRandomBlob(150); + // Packs are written in the midx in reverse insertion time + DfsPackFileMidx midx = writeMultipackIndex(); + + DfsPackFile packOne = findPack(o1); + DfsPackFile packTwo = findPack(o2); + long packTwoSize = packTwo.getPackDescription().getFileSize(PACK); + DfsPackFile packThree = findPack(o3); + long packThreeSize = packThree.getPackDescription().getFileSize(PACK); + + try (DfsReader ctx = db.getObjectDatabase().newReader()) { + long posOne = midx.findOffset(ctx, o1); + DfsPackFileMidx.DfsPackOffset po = midx.getOffsetCalculator() + .decode(posOne); + assertEquals(12, po.getPackOffset()); + assertEquals(packThreeSize + packTwoSize, po.getPackStart()); + assertEquals(packOne.getPackDescription(), + po.getPack().getPackDescription()); + + long posTwo = midx.findOffset(ctx, o2); + po = midx.getOffsetCalculator().decode(posTwo); + assertEquals(12, po.getPackOffset()); + assertEquals(packThreeSize, po.getPackStart()); + assertEquals(packTwo.getPackDescription(), + po.getPack().getPackDescription()); + + long posThree = midx.findOffset(ctx, o3); + po = midx.getOffsetCalculator().decode(posThree); + assertEquals(12, po.getPackOffset()); + assertEquals(0, po.getPackStart()); + assertEquals(packThree.getPackDescription(), + po.getPack().getPackDescription()); + + long posNon = midx.findOffset(ctx, NOT_IN_PACK); + assertEquals(-1, posNon); + } + } + + @Test + public void midx_resolve() throws Exception { + ObjectId o1 = writePackWithRandomBlob(100); + writePackWithRandomBlob(200); + ObjectId o2 = writePackWithRandomBlob(150); + DfsPackFile midx = writeMultipackIndex(); + + try (DfsReader ctx = db.getObjectDatabase().newReader()) { + Set<ObjectId> matches = new HashSet<>(); + midx.resolve(ctx, matches, o1.abbreviate(6), 100); + assertEquals(1, matches.size()); + + matches.clear(); + midx.resolve(ctx, matches, o2.abbreviate(6), 100); + assertEquals(1, matches.size()); + + matches = new HashSet<>(); + midx.resolve(ctx, matches, NOT_IN_PACK.abbreviate(8), 100); + assertEquals(0, matches.size()); + } + } + + @Test + public void midx_resolve_withBase() throws Exception { + ObjectId o1 = writePackWithRandomBlob(100); + ObjectId o2 = writePackWithRandomBlob(200); + writePackWithRandomBlob(150); + ObjectId o4 = writePackWithRandomBlob(400); + writePackWithRandomBlob(500); + writePackWithRandomBlob(600); + + DfsPackFile[] packs = db.getObjectDatabase().getPacks(); + // Packs are in reverse insertion order + DfsPackFileMidx midxBase = writeMultipackIndex( + Arrays.copyOfRange(packs, 3, 6), null); + DfsPackFileMidx midxTip = writeMultipackIndex( + Arrays.copyOfRange(packs, 0, 3), midxBase); + + try (DfsReader ctx = db.getObjectDatabase().newReader()) { + Set<ObjectId> matches = new HashSet<>(); + // Test with an ID that exists in the base + assertTrue(midxTip.hasObject(ctx, o1)); + midxTip.resolve(ctx, matches, o1.abbreviate(6), 100); + assertEquals(1, matches.size()); + assertTrue(matches.contains(o1)); + + matches.clear(); + // Test with an ID that exists in the tip + midxTip.resolve(ctx, matches, o4.abbreviate(6), 100); + assertTrue(matches.contains(o4)); + assertEquals(1, matches.size()); + + matches.clear(); + midxTip.resolve(ctx, matches, o2.abbreviate(6), 1); + assertTrue(matches.contains(o2)); + assertEquals(1, matches.size()); + + matches.clear(); + midxTip.resolve(ctx, matches, NOT_IN_PACK.abbreviate(8), 100); + assertEquals(0, matches.size()); + } + } + + @Test + public void midx_findAllFromPack() throws Exception { + ObjectId o1 = writePackWithRandomBlob(100); + ObjectId o2 = writePackWithRandomBlob(200); + ObjectId o3 = writePackWithRandomBlob(150); + DfsPackFile midx = writeMultipackIndex(); + + List<ObjectToPack> otps = List.of(new DfsObjectToPack(o1, OBJ_BLOB), + new DfsObjectToPack(o2, OBJ_BLOB), + new DfsObjectToPack(o3, OBJ_BLOB), + new DfsObjectToPack(NOT_IN_PACK, OBJ_BLOB)); + + try (DfsReader ctx = db.getObjectDatabase().newReader()) { + List<DfsObjectToPack> allFromPack = midx.findAllFromPack(ctx, otps, + true); + assertEquals(3, allFromPack.size()); + + // Objects are in (pack, offset) order (i.e. reverse pack insert) + DfsObjectToPack oneToPack = allFromPack.get(0); + assertEquals(midx.findOffset(ctx, o3), oneToPack.getOffset()); + + DfsObjectToPack twoToPack = allFromPack.get(1); + assertEquals(midx.findOffset(ctx, o2), twoToPack.getOffset()); + + DfsObjectToPack threeToPack = allFromPack.get(2); + assertEquals(midx.findOffset(ctx, o1), threeToPack.getOffset()); + } + } + + @Test + public void midx_findAllFromPack_withBase() throws Exception { + ObjectId o1 = writePackWithRandomBlob(100); + ObjectId o2 = writePackWithRandomBlob(200); + ObjectId o3 = writePackWithRandomBlob(150); + ObjectId o4 = writePackWithRandomBlob(400); + ObjectId o5 = writePackWithRandomBlob(500); + ObjectId o6 = writePackWithRandomBlob(600); + + DfsPackFile[] packs = db.getObjectDatabase().getPacks(); + // Packs are in reverse insertion order (o6 -> o1) + DfsPackFileMidx midxBase = writeMultipackIndex( + Arrays.copyOfRange(packs, 3, 6), null); + DfsPackFileMidx midxTip = writeMultipackIndex( + Arrays.copyOfRange(packs, 0, 3), midxBase); + + List<ObjectToPack> otps = List.of(new DfsObjectToPack(o1, OBJ_BLOB), + new DfsObjectToPack(o4, OBJ_BLOB), + new DfsObjectToPack(o2, OBJ_BLOB), + new DfsObjectToPack(o5, OBJ_BLOB), + new DfsObjectToPack(NOT_IN_PACK, OBJ_BLOB), + new DfsObjectToPack(o3, OBJ_BLOB), + new DfsObjectToPack(o6, OBJ_BLOB)); + + try (DfsReader ctx = db.getObjectDatabase().newReader()) { + List<DfsObjectToPack> allFromPack = midxTip.findAllFromPack(ctx, + otps, true); + assertEquals(6, allFromPack.size()); + + // Objects are in midx-offset order which is: + // base(o3 < o2 < o1) -> tip (06 < 05 < o4) + DfsObjectToPack oneToPack = allFromPack.get(0); + assertEquals(midxTip.findOffset(ctx, o3), oneToPack.getOffset()); + + DfsObjectToPack twoToPack = allFromPack.get(1); + assertEquals(midxTip.findOffset(ctx, o2), twoToPack.getOffset()); + + DfsObjectToPack threeToPack = allFromPack.get(2); + assertEquals(midxTip.findOffset(ctx, o1), threeToPack.getOffset()); + + DfsObjectToPack fourToPack = allFromPack.get(3); + assertEquals(midxTip.findOffset(ctx, o6), fourToPack.getOffset()); + + DfsObjectToPack fiveToPack = allFromPack.get(4); + assertEquals(midxTip.findOffset(ctx, o5), fiveToPack.getOffset()); + + DfsObjectToPack sixToPack = allFromPack.get(5); + assertEquals(midxTip.findOffset(ctx, o4), sixToPack.getOffset()); + } + } + + @Test + public void midx_copyPackAsIs() throws Exception { + writePackWithRandomBlob(100); + writePackWithRandomBlob(200); + writePackWithRandomBlob(150); + + long expectedPackSize = Arrays.stream(db.getObjectDatabase().getPacks()) + .mapToLong(pack -> pack.getPackDescription().getFileSize(PACK)) + .map(size -> size - 12 - 20) // remove header + CRC + .sum(); + DfsPackFile midx = writeMultipackIndex(); + + try (DfsReader ctx = db.getObjectDatabase().newReader(); + PackWriter pw = new PackWriter(new PackConfig(), ctx); + ByteArrayOutputStream os = new ByteArrayOutputStream(); + PackOutputStream out = new PackOutputStream( + NullProgressMonitor.INSTANCE, os, pw)) { + midx.copyPackAsIs(out, ctx); + out.flush(); + assertEquals(expectedPackSize, os.size()); + } + } + + @Test + public void midx_copyPackAsIs_withBase() throws Exception { + writePackWithRandomBlob(100); + writePackWithRandomBlob(200); + writePackWithRandomBlob(150); + writePackWithRandomBlob(400); + writePackWithRandomBlob(500); + writePackWithRandomBlob(600); + + DfsPackFile[] packs = db.getObjectDatabase().getPacks(); + long expectedPackSize = Arrays.stream(packs) + .mapToLong(pack -> pack.getPackDescription().getFileSize(PACK)) + .map(size -> size - 12 - 20) // remove header + CRC + .sum(); + + DfsPackFileMidx midxBase = writeMultipackIndex( + Arrays.copyOfRange(packs, 3, 6), null); + DfsPackFileMidx midxTip = writeMultipackIndex( + Arrays.copyOfRange(packs, 0, 3), midxBase); + + try (DfsReader ctx = db.getObjectDatabase().newReader(); + PackWriter pw = new PackWriter(new PackConfig(), ctx); + ByteArrayOutputStream os = new ByteArrayOutputStream(); + PackOutputStream out = new PackOutputStream( + NullProgressMonitor.INSTANCE, os, pw)) { + midxTip.copyPackAsIs(out, ctx); + out.flush(); + assertEquals(expectedPackSize, os.size()); + } + } + + @Test + public void midx_copyAsIs() throws Exception { + writePackWithRandomBlob(100); + ObjectId blob = writePackWithRandomBlob(200); + writePackWithRandomBlob(150); + DfsPackFileMidx midx = writeMultipackIndex(); + + assertEquals(213, copyAsIs(midx, blob).length); + } + + @Test + public void midx_copyAsIs_withBase() throws Exception { + writePackWithRandomBlob(100); + ObjectId baseObject = writePackWithRandomBlob(200); + writePackWithRandomBlob(150); + writePackWithRandomBlob(400); + ObjectId tipObject = writePackWithRandomBlob(500); + writePackWithRandomBlob(600); + + DfsPackFile[] packs = db.getObjectDatabase().getPacks(); + // Packs are in reverse insertion order + DfsPackFileMidx midxBase = writeMultipackIndex( + Arrays.copyOfRange(packs, 3, 6), null); + DfsPackFileMidx midxTip = writeMultipackIndex( + Arrays.copyOfRange(packs, 0, 3), midxBase); + + assertEquals(213, copyAsIs(midxTip, baseObject).length); + assertEquals(513, copyAsIs(midxTip, tipObject).length); + } + + private byte[] copyAsIs(DfsPackFileMidx midx, ObjectId oid) + throws Exception { + try (DfsReader ctx = db.getObjectDatabase().newReader(); + PackWriter pw = new PackWriter(new PackConfig(), ctx); + ByteArrayOutputStream os = new ByteArrayOutputStream(); + PackOutputStream out = new PackOutputStream( + NullProgressMonitor.INSTANCE, os, pw)) { + // Object in the base + ObjectToPack otp = new DfsObjectToPack(oid, OBJ_BLOB); + DfsObjectToPack inPack = midx + .findAllFromPack(ctx, List.of(otp), false).get(0); + DfsObjectRepresentation r = new DfsObjectRepresentation(midx); + midx.fillRepresentation(r, inPack.getOffset(), ctx); + inPack.select(r); + midx.copyAsIs(out, inPack, false, ctx); + out.flush(); + return os.toByteArray(); + } + } + + @Test + public void midx_getDeltaHeader() { + // TODO(ifrade): Implement + } + + @Test + public void midx_getObjectType() throws Exception { + ObjectId commit = writePackWithCommit(); + ObjectId blob = writePackWithRandomBlob(200); + DfsPackFile midx = writeMultipackIndex(); + + try (RevWalk rw = new RevWalk(db); + DfsReader ctx = db.getObjectDatabase().newReader()) { + RevCommit aCommit = rw.parseCommit(commit); + RevTree aTree = rw.parseTree(aCommit.getTree()); + + long commitPos = midx.findOffset(ctx, commit); + assertEquals(OBJ_COMMIT, midx.getObjectType(ctx, commitPos)); + + long treePos = midx.findOffset(ctx, aTree); + assertEquals(OBJ_TREE, midx.getObjectType(ctx, treePos)); + + long blobPos = midx.findOffset(ctx, blob); + assertEquals(OBJ_BLOB, midx.getObjectType(ctx, blobPos)); + + assertThrows(IllegalArgumentException.class, + () -> midx.getObjectType(ctx, 12000)); + } + } + + @Test + public void midx_getObjectType_withBase() throws Exception { + // This first commit creates two packs + ObjectId commit = writePackWithCommit(); + ObjectId blob = writePackWithRandomBlob(200); + writePackWithCommit(); + + writePackWithCommit(); + writePackWithRandomBlob(300); + ObjectId newCommit = writePackWithCommit(); + + DfsPackFile[] packs = db.getObjectDatabase().getPacks(); + // Packs are in reverse insertion order + DfsPackFileMidx midxBase = writeMultipackIndex( + Arrays.copyOfRange(packs, 4, 7), null); + DfsPackFileMidx midxTip = writeMultipackIndex( + Arrays.copyOfRange(packs, 0, 4), midxBase); + + try (RevWalk rw = new RevWalk(db); + DfsReader ctx = db.getObjectDatabase().newReader()) { + RevCommit aCommit = rw.parseCommit(commit); + RevTree aTree = rw.parseTree(aCommit.getTree()); + + long commitPos = midxTip.findOffset(ctx, commit); + assertEquals(OBJ_COMMIT, midxTip.getObjectType(ctx, commitPos)); + + long treePos = midxTip.findOffset(ctx, aTree); + assertEquals(OBJ_TREE, midxTip.getObjectType(ctx, treePos)); + + long blobPos = midxTip.findOffset(ctx, blob); + assertEquals(OBJ_BLOB, midxTip.getObjectType(ctx, blobPos)); + + long commitPosTip = midxTip.findOffset(ctx, newCommit); + assertEquals(OBJ_COMMIT, midxTip.getObjectType(ctx, commitPosTip)); + + assertThrows(IllegalArgumentException.class, + () -> midxTip.getObjectType(ctx, 12000)); + } + } + + @Test + public void midx_getObjectSize_byId() throws Exception { + ObjectId commit = writePackWithCommit(); + ObjectId blob = writePackWithRandomBlob(200); + DfsPackFile midx = writeMultipackIndex(); + + try (RevWalk rw = new RevWalk(db); + DfsReader ctx = db.getObjectDatabase().newReader()) { + RevCommit aCommit = rw.parseCommit(commit); + RevTree aTree = rw.parseTree(aCommit.getTree()); + RevBlob aBlob = rw.lookupBlob(blob); + + assertEquals(168, midx.getObjectSize(ctx, aCommit)); + assertEquals(33, midx.getObjectSize(ctx, aTree)); + assertEquals(200, midx.getObjectSize(ctx, aBlob)); + + assertEquals(-1, midx.getObjectSize(ctx, NOT_IN_PACK)); + } + } + + @Test + public void midx_getObjectSize_byId_withBase() throws Exception { + ObjectId commit = writePackWithCommit(); + ObjectId blob = writePackWithRandomBlob(200); + + writePackWithRandomBlob(300); + ObjectId blobTwo = writePackWithRandomBlob(100); + System.out.println( + "pack count: " + db.getObjectDatabase().getPacks().length); + + DfsPackFile[] packs = db.getObjectDatabase().getPacks(); + // Packs are in reverse insertion order + DfsPackFileMidx midxBase = writeMultipackIndex( + Arrays.copyOfRange(packs, 3, 5), null); + DfsPackFileMidx midxTip = writeMultipackIndex( + Arrays.copyOfRange(packs, 0, 3), midxBase); + + try (RevWalk rw = new RevWalk(db); + DfsReader ctx = db.getObjectDatabase().newReader()) { + RevCommit aCommit = rw.parseCommit(commit); + RevTree aTree = rw.parseTree(aCommit.getTree()); + + assertEquals(168, midxTip.getObjectSize(ctx, aCommit)); + assertEquals(33, midxTip.getObjectSize(ctx, aTree)); + assertEquals(200, midxTip.getObjectSize(ctx, blob)); + assertEquals(100, midxTip.getObjectSize(ctx, blobTwo)); + + assertEquals(-1, midxTip.getObjectSize(ctx, NOT_IN_PACK)); + } + } + + @Test + public void midx_getObjectSize_byOffset() throws Exception { + ObjectId commit = writePackWithCommit(); + ObjectId blob = writePackWithRandomBlob(200); + DfsPackFile midx = writeMultipackIndex(); + + try (RevWalk rw = new RevWalk(db); + DfsReader ctx = db.getObjectDatabase().newReader()) { + RevCommit aCommit = rw.parseCommit(commit); + RevTree aTree = rw.parseTree(aCommit.getTree()); + RevBlob aBlob = rw.lookupBlob(blob); + + assertEquals(168, + midx.getObjectSize(ctx, midx.findOffset(ctx, aCommit))); + assertEquals(33, + midx.getObjectSize(ctx, midx.findOffset(ctx, aTree))); + assertEquals(200, + midx.getObjectSize(ctx, midx.findOffset(ctx, aBlob))); + + assertEquals(-1, midx.getObjectSize(ctx, -1)); + } + } + + @Test + public void midx_getObjectSize_byOffset_withBase() throws Exception { + ObjectId commit = writePackWithCommit(); + ObjectId blob = writePackWithRandomBlob(200); + + writePackWithRandomBlob(300); + ObjectId blobTwo = writePackWithRandomBlob(100); + + DfsPackFile[] packs = db.getObjectDatabase().getPacks(); + // Packs are in reverse insertion order + DfsPackFileMidx midxBase = writeMultipackIndex( + Arrays.copyOfRange(packs, 3, 5), null); + DfsPackFileMidx midxTip = writeMultipackIndex( + Arrays.copyOfRange(packs, 0, 3), midxBase); + + try (RevWalk rw = new RevWalk(db); + DfsReader ctx = db.getObjectDatabase().newReader()) { + RevCommit aCommit = rw.parseCommit(commit); + RevTree aTree = rw.parseTree(aCommit.getTree()); + + assertEquals(168, midxTip.getObjectSize(ctx, + midxTip.findOffset(ctx, aCommit))); + assertEquals(33, + midxTip.getObjectSize(ctx, midxTip.findOffset(ctx, aTree))); + assertEquals(200, + midxTip.getObjectSize(ctx, midxTip.findOffset(ctx, blob))); + assertEquals(100, midxTip.getObjectSize(ctx, + midxTip.findOffset(ctx, blobTwo))); + + assertEquals(-1, midxTip.getObjectSize(ctx, -1)); + assertEquals(-1, midxTip.getObjectSize(ctx, + midxTip.findOffset(ctx, NOT_IN_PACK))); + } + } + + @Test + public void midx_objectSizeIndex_disabled() throws Exception { + writePackWithCommit(); + writePackWithRandomBlob(200); + DfsPackFile midx = writeMultipackIndex(); + + try (DfsReader ctx = db.getObjectDatabase().newReader()) { + assertFalse(midx.hasObjectSizeIndex(ctx)); + } + } + + @Test + public void midx_fillRepresentation() throws Exception { + writePackWithRandomBlob(200); + RevCommit commit = writePackWithCommit(); + DfsPackFile midx = writeMultipackIndex(); + + DfsObjectRepresentation rep = fillRepresentation(midx, commit, + OBJ_COMMIT); + assertEquals(midx, rep.pack); + assertEquals(347, rep.offset); + assertEquals(120, rep.length); + } + + DfsObjectRepresentation fillRepresentation(DfsPackFile midx, + ObjectId commit, int typeHint) throws Exception { + try (DfsReader ctx = db.getObjectDatabase().newReader()) { + ObjectToPack otp = new DfsObjectToPack(commit, typeHint); + DfsObjectToPack inPack = midx + .findAllFromPack(ctx, List.of(otp), true).get(0); + DfsObjectRepresentation rep = new DfsObjectRepresentation(midx); + midx.fillRepresentation(rep, inPack.getOffset(), ctx); + return rep; + } + } + + @Test + public void midx_fillRepresentation_withBase() throws Exception { + RevCommit commitInBase = writePackWithCommit(); + ObjectId blob = writePackWithRandomBlob(300); + writePackWithRandomBlob(500); + writePackWithRandomBlob(100); + RevCommit commitInTip = writePackWithCommit(); + + DfsPackFile[] packs = db.getObjectDatabase().getPacks(); + assertEquals(6, packs.length); + DfsPackFileMidx midxBase = writeMultipackIndex( + Arrays.copyOfRange(packs, 3, 6), null); + DfsPackFileMidx midxTip = writeMultipackIndex( + Arrays.copyOfRange(packs, 0, 3), midxBase); + + try (DfsReader ctx = db.getObjectDatabase().newReader()) { + // Commit in tip midx + DfsObjectRepresentation rep = fillRepresentation(midxTip, + commitInTip, OBJ_COMMIT); + assertEquals(midxTip.getPackDescription(), + rep.pack.getPackDescription()); + assertEquals(midxTip.findOffset(ctx, commitInTip), rep.offset); + assertEquals(150, rep.length); + + // Commit in base midx + rep = fillRepresentation(midxTip, commitInBase, OBJ_COMMIT); + assertEquals(midxTip.getPackDescription(), + rep.pack.getPackDescription()); + assertEquals(midxTip.findOffset(ctx, commitInBase), rep.offset); + assertEquals(120, rep.length); + + // Blob in base + rep = fillRepresentation(midxTip, blob, OBJ_COMMIT); + assertEquals(midxTip.getPackDescription(), + rep.pack.getPackDescription()); + assertEquals(midxTip.findOffset(ctx, blob), rep.offset); + assertEquals(311, rep.length); + } + } + + @Test + public void midx_getBitmapIndex() throws Exception { + RevCommit c1 = writePackWithCommit(); + RevCommit c2 = writePackWithCommit(); + gcWithBitmaps(); + + ObjectId blob = writePackWithRandomBlob(300); + DfsPackFileMidx dfsPackFileMidx = writeMultipackIndex(); + try (DfsReader ctx = db.getObjectDatabase().newReader()) { + PackBitmapIndex bitmapIndex = dfsPackFileMidx.getBitmapIndex(ctx); + assertNotNull(bitmapIndex); + // Both commits have same tree and blob + assertEquals(4, bitmapIndex.getObjectCount()); + assertEquals(1, bitmapIndex.findPosition(c1)); + assertEquals(0, bitmapIndex.findPosition(c2)); + assertEquals(-1, bitmapIndex.findPosition(blob)); + } + } + + @Test + public void midx_getAllCoveredPacks() throws Exception { + writePackWithCommit(); + writePackWithRandomBlob(300); + writePackWithRandomBlob(500); + + DfsPackFile[] packs = db.getObjectDatabase().getPacks(); + assertEquals(4, packs.length); + DfsPackFileMidx midx = writeMultipackIndex(packs, null); + + assertEquals(4, midx.getAllCoveredPacks().size()); + List<DfsPackDescription> expected = Arrays.stream(packs) + .map(p -> p.getPackDescription()).toList(); + List<DfsPackDescription> actual = midx.getAllCoveredPacks().stream() + .map(DfsPackFile::getPackDescription).toList(); + assertEquals(expected, actual); + } + + @Test + public void midx_getAllCoveredPacks_withBase() throws Exception { + writePackWithCommit(); + writePackWithRandomBlob(300); + writePackWithRandomBlob(500); + writePackWithRandomBlob(100); + writePackWithCommit(); + + DfsPackFile[] packs = db.getObjectDatabase().getPacks(); + assertEquals(6, packs.length); + DfsPackFileMidx midxBase = writeMultipackIndex( + Arrays.copyOfRange(packs, 4, 6), null); + DfsPackFileMidx midxMiddle = writeMultipackIndex( + Arrays.copyOfRange(packs, 2, 4), midxBase); + DfsPackFileMidx midxTip = writeMultipackIndex( + Arrays.copyOfRange(packs, 0, 2), midxMiddle); + + assertEquals(6, midxTip.getAllCoveredPacks().size()); + List<DfsPackDescription> expected = Arrays.stream(packs) + .map(DfsPackFile::getPackDescription).toList(); + List<DfsPackDescription> actual = midxTip.getAllCoveredPacks().stream() + .map(DfsPackFile::getPackDescription).toList(); + assertEquals(expected, actual); + } + + @Test + public void midx_getCoveredPacks_withBase_onlyTopMidx() throws Exception { + writePackWithCommit(); + writePackWithRandomBlob(300); + writePackWithRandomBlob(500); + writePackWithRandomBlob(100); + writePackWithCommit(); + + DfsPackFile[] packs = db.getObjectDatabase().getPacks(); + assertEquals(6, packs.length); + DfsPackFileMidx midxBase = writeMultipackIndex( + Arrays.copyOfRange(packs, 3, 6), null); + DfsPackFileMidx midxTip = writeMultipackIndex( + Arrays.copyOfRange(packs, 0, 3), midxBase); + + assertEquals(3, midxTip.getCoveredPacks().size()); + List<DfsPackDescription> expected = Arrays + .stream(Arrays.copyOfRange(packs, 0, 3)) + .map(DfsPackFile::getPackDescription).toList(); + List<DfsPackDescription> actual = midxTip.getCoveredPacks().stream() + .map(DfsPackFile::getPackDescription).toList(); + assertEquals(expected, actual); + } + + @Test + public void midx_corrupt() throws Exception { + RevCommit commit = writePackWithCommit(); + writePackWithRandomBlob(200); + DfsPackFile midx = writeMultipackIndex(); + try (DfsReader ctx = db.getObjectDatabase().newReader()) { + assertFalse(midx.isCorrupt(midx.findOffset(ctx, commit))); + } + } + + @Test + public void packwriter_via_midx() throws Exception { + RevCommit commit = writePackWithCommit(); + ObjectId blob = writePackWithBlob("booooohooooo".getBytes(UTF_8)); + ObjectId notPacked = writePackWithBlob("baaaaahaa".getBytes(UTF_8)); + writeMultipackIndex(); + + byte[] writtenPack; + try (DfsReader ctx = db.getObjectDatabase().newReader(); + RevWalk rw = new RevWalk(ctx); + PackWriter pw = new PackWriter(db, ctx)) { + pw.addObject(rw.lookupBlob(blob)); + pw.addObject(rw.lookupCommit(commit)); + + try (ByteArrayOutputStream out = new ByteArrayOutputStream()) { + CounterProgressMonitor cpm = new CounterProgressMonitor(); + pw.writePack(NullProgressMonitor.INSTANCE, cpm, out); + out.flush(); + assertEquals(178, out.size()); + assertEquals(2, cpm.objectsPacked); + writtenPack = out.toByteArray(); + } + } + + try (InMemoryRepository dest = new InMemoryRepository( + new DfsRepositoryDescription("test")); + ObjectInserter ins = dest.getObjectDatabase().newInserter()) { + ins.newPackParser(new ByteArrayInputStream(writtenPack)) + .parse(NullProgressMonitor.INSTANCE); + assertTrue(dest.getObjectDatabase().has(commit)); + assertTrue(dest.getObjectDatabase().has(blob)); + assertFalse(dest.getObjectDatabase().has(notPacked)); + } + } + + @Test + public void voffsetcalculator_encode() { + DfsPackFile one = createDfsPackFile(800); + DfsPackFile two = createDfsPackFile(1200); + DfsPackFile three = createDfsPackFile(900); + + VOffsetCalculator calc = VOffsetCalculator + .fromPacks(new DfsPackFile[] { one, two, three }, null); + + PackOffset po = PackOffset.create(0, 12); + assertEquals(12, calc.encode(po)); + po = PackOffset.create(1, 12); + assertEquals(800 + 12, calc.encode(po)); + po = PackOffset.create(2, 12); + assertEquals(800 + 1200 + 12, calc.encode(po)); + } + + @Test + public void voffsetcalculator_decode() { + DfsPackFile one = createDfsPackFile(800); + DfsPackFile two = createDfsPackFile(1200); + DfsPackFile three = createDfsPackFile(900); + + VOffsetCalculator calc = VOffsetCalculator + .fromPacks(new DfsPackFile[] { one, two, three }, null); + + // In first pack + DfsPackFileMidx.DfsPackOffset decoded = calc.decode(130); + assertEquals(one.getPackDescription(), + decoded.getPack().getPackDescription()); + assertEquals(130, decoded.getPackOffset()); + assertEquals(0, decoded.getPackStart()); + + // In second pack + decoded = calc.decode(812); + assertEquals(two.getPackDescription(), + decoded.getPack().getPackDescription()); + assertEquals(12, decoded.getPackOffset()); + assertEquals(800, decoded.getPackStart()); + + // In third pack + decoded = calc.decode(2100); + assertEquals(two.getPackDescription(), + decoded.getPack().getPackDescription()); + assertEquals(100, decoded.getPackOffset()); + assertEquals(2000, decoded.getPackStart()); + } + + @Test + public void voffsetcalculator_notFound() { + DfsPackFile one = createDfsPackFile(800); + DfsPackFile two = createDfsPackFile(1200); + DfsPackFile three = createDfsPackFile(900); + + VOffsetCalculator calc = VOffsetCalculator + .fromPacks(new DfsPackFile[] { one, two, three }, null); + + assertEquals(-1, calc.encode(null)); + assertNull(calc.decode(-1)); + } + + @Test + public void voffsetcalculator_maxOffset() { + DfsPackFile one = createDfsPackFile(800); + DfsPackFile two = createDfsPackFile(1200); + DfsPackFile three = createDfsPackFile(900); + + long totalSize = one.getPackDescription().getFileSize(PACK) + + two.getPackDescription().getFileSize(PACK) + + three.getPackDescription().getFileSize(PACK); + + VOffsetCalculator calc = VOffsetCalculator + .fromPacks(new DfsPackFile[] { one, two, three }, null); + + assertEquals(totalSize, calc.getMaxOffset()); + } + + @Test + public void voffsetcalculator_withBase_encode() { + DfsPackFile one = createDfsPackFile(800); + DfsPackFile two = createDfsPackFile(1200); + DfsPackFile three = createDfsPackFile(900); + + VOffsetCalculator baseCalc = VOffsetCalculator + .fromPacks(new DfsPackFile[] { one, two, three }, null); + + DfsPackFile four = createDfsPackFile(900); + DfsPackFile five = createDfsPackFile(1300); + DfsPackFile six = createDfsPackFile(1000); + + VOffsetCalculator calc = VOffsetCalculator + .fromPacks(new DfsPackFile[] { four, five, six }, baseCalc); + + // These packIds are now from the second top midx + int firstMidxByteSize = 2900; + PackOffset po = PackOffset.create(0, 12); + assertEquals(12 + firstMidxByteSize, calc.encode(po)); + po = PackOffset.create(1, 12); + assertEquals(900 + 12 + firstMidxByteSize, calc.encode(po)); + po = PackOffset.create(2, 12); + assertEquals(900 + 1300 + 12 + firstMidxByteSize, calc.encode(po)); + } + + @Test + public void voffsetcalculator_withBase_decode() { + DfsPackFile one = createDfsPackFile(800); + DfsPackFile two = createDfsPackFile(1200); + DfsPackFile three = createDfsPackFile(900); + VOffsetCalculator baseCalc = VOffsetCalculator + .fromPacks(new DfsPackFile[] { one, two, three }, null); + + DfsPackFile four = createDfsPackFile(900); + DfsPackFile five = createDfsPackFile(1300); + DfsPackFile six = createDfsPackFile(1000); + + VOffsetCalculator calc = VOffsetCalculator + .fromPacks(new DfsPackFile[] { four, five, six }, baseCalc); + + // In pack 1 + DfsPackFileMidx.DfsPackOffset decoded = calc.decode(130); + assertEquals(one.getPackDescription(), + decoded.getPack().getPackDescription()); + assertEquals(130, decoded.getPackOffset()); + assertEquals(0, decoded.getPackStart()); + + // In pack 3 + decoded = calc.decode(2300); + assertEquals(three.getPackDescription(), + decoded.getPack().getPackDescription()); + assertEquals(300, decoded.getPackOffset()); + assertEquals(2000, decoded.getPackStart()); + + // In pack 4 + decoded = calc.decode(3000); + assertEquals(four.getPackDescription(), + decoded.getPack().getPackDescription()); + assertEquals(100, decoded.getPackOffset()); + assertEquals(2900, decoded.getPackStart()); + + // In pack 6 + int packSixStart = 800 + 1200 + 900 + 900 + 1300; + decoded = calc.decode(packSixStart + 130); + assertEquals(six.getPackDescription(), + decoded.getPack().getPackDescription()); + assertEquals(130, decoded.getPackOffset()); + assertEquals(packSixStart, decoded.getPackStart()); + } + + @Test + public void voffsetcalculator_withBase_maxOffset() { + DfsPackFile one = createDfsPackFile(800); + DfsPackFile two = createDfsPackFile(1200); + DfsPackFile three = createDfsPackFile(900); + + VOffsetCalculator baseCalc = VOffsetCalculator + .fromPacks(new DfsPackFile[] { one, two, three }, null); + + DfsPackFile four = createDfsPackFile(900); + DfsPackFile five = createDfsPackFile(1300); + DfsPackFile six = createDfsPackFile(1000); + + VOffsetCalculator calc = VOffsetCalculator + .fromPacks(new DfsPackFile[] { four, five, six }, baseCalc); + + int expectedMaxOffset = 800 + 1200 + 900 + 900 + 1300 + 1000; + assertEquals(expectedMaxOffset, calc.getMaxOffset()); + } + + private static DfsPackFile createDfsPackFile(int size) { + DfsPackDescription desc = new DfsPackDescription( + new DfsRepositoryDescription("the_repo"), "pack_blabla", GC); + desc.addFileExt(PACK); + desc.setFileSize(PACK, size); + desc.setObjectCount(1); + return new DfsPackFile(null, desc); + } + + private DfsPackFileMidx writeMultipackIndex() throws IOException { + return writeMultipackIndex(db.getObjectDatabase().getPacks(), null); + } + + private void gcWithBitmaps() throws IOException { + DfsGarbageCollector garbageCollector = new DfsGarbageCollector(db); + garbageCollector.pack(NullProgressMonitor.INSTANCE); + } + + private DfsPackFileMidx writeMultipackIndex(DfsPackFile[] packs, + DfsPackFileMidx base) throws IOException { + LinkedHashMap<String, PackIndex> forMidx = new LinkedHashMap<>( + packs.length); + Map<String, DfsPackDescription> descByName = new HashMap<>( + packs.length); + try (DfsReader ctx = db.getObjectDatabase().newReader()) { + for (DfsPackFile pack : packs) { + forMidx.put(pack.getPackDescription().getPackName(), + pack.getPackIndex(ctx)); + descByName.put(pack.getPackDescription().getPackName(), + pack.getPackDescription()); + } + } + MultiPackIndexWriter w = new MultiPackIndexWriter(); + DfsPackDescription desc = db.getObjectDatabase().newPack(GC); + try (DfsOutputStream out = db.getObjectDatabase().writeFile(desc, + PackExt.MULTI_PACK_INDEX)) { + MultiPackIndexWriter.Result midxStats = w + .write(NullProgressMonitor.INSTANCE, out, forMidx); + desc.setCoveredPacks(midxStats.packNames().stream() + .map(descByName::get).toList()); + desc.addFileExt(PackExt.MULTI_PACK_INDEX); + } + db.getObjectDatabase().commitPack(List.of(desc), null); + return DfsPackFileMidx.create(DfsBlockCache.getInstance(), desc, + Arrays.asList(packs), base); + } + + private RevCommit writePackWithCommit() throws Exception { + try (TestRepository<InMemoryRepository> repository = new TestRepository<>( + db)) { + return repository.branch("/refs/heads/main").commit() + .add("blob1", "blob1").create(); + } + } + + private ObjectId writePackWithRandomBlob(int size) throws IOException { + byte[] data = new TestRng(JGitTestUtil.getName()).nextBytes(size); + return writePackWithBlob(data); + } + + private ObjectId writePackWithBlob(byte[] data) throws IOException { + DfsInserter ins = (DfsInserter) db.newObjectInserter(); + ins.setCompressionLevel(Deflater.NO_COMPRESSION); + ObjectId blobId = ins.insert(OBJ_BLOB, data); + ins.flush(); + return blobId; + } + + private DfsPackFile findPack(ObjectId oid) throws IOException { + DfsPackFile[] packs = db.getObjectDatabase().getPacks(); + try (DfsReader ctx = db.getObjectDatabase().newReader()) { + for (DfsPackFile pack : packs) { + if (pack.hasObject(ctx, oid)) { + return pack; + } + } + } + throw new IllegalArgumentException("Object not in any pack"); + } + + private static final class CounterProgressMonitor + implements ProgressMonitor { + + int objectsPacked = 0; + + @Override + public void start(int totalTasks) { + // empty + } + + @Override + public void beginTask(String title, int totalWork) { + System.out.println("Starting " + title); + } + + @Override + public void update(int completed) { + objectsPacked += 1; + } + + @Override + public void endTask() { + // empty + } + + @Override + public boolean isCancelled() { + return false; + } + + @Override + public void showDuration(boolean enabled) { + // empty + } + } + + private byte[] safeGetBytes(@Nullable ObjectLoader ol) { + assertNotNull(ol); + byte[] data = ol.getBytes(); + assertNotNull(data); + return data; + } +}
diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/dfs/MidxDescListTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/dfs/MidxDescListTest.java new file mode 100644 index 0000000..d349bcf --- /dev/null +++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/dfs/MidxDescListTest.java
@@ -0,0 +1,141 @@ +/* + * 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.internal.storage.dfs; + +import static org.eclipse.jgit.internal.storage.dfs.DfsObjDatabase.PackSource.COMPACT; +import static org.eclipse.jgit.internal.storage.dfs.DfsObjDatabase.PackSource.GC; +import static org.eclipse.jgit.internal.storage.dfs.DfsObjDatabase.PackSource.INSERT; +import static org.eclipse.jgit.internal.storage.pack.PackExt.MULTI_PACK_INDEX; +import static org.eclipse.jgit.internal.storage.pack.PackExt.PACK; +import static org.junit.Assert.assertEquals; + +import java.util.Arrays; +import java.util.List; + +import org.eclipse.jgit.internal.storage.pack.PackExt; +import org.junit.Test; + +public class MidxDescListTest { + + private static final DfsRepositoryDescription REPO_DESC = new DfsRepositoryDescription( + "testrepo"); + + @Test + public void findAllImpactedMidx_onlyPacks() { + DfsPackDescription gcPack = desc("aaa", GC, PACK); + DfsPackDescription compactPack = desc("bbb", COMPACT, PACK); + DfsPackDescription insertPack = desc("ccc", INSERT, PACK); + List<DfsPackDescription> packs = List.of(gcPack, compactPack, + insertPack); + + MidxDescList packList = MidxDescList.create(packs); + assertEquals(0, packList.findAllCoveringMidxs(packs).size()); + } + + @Test + public void findAllImpactedMidx_onlyMidx() { + DfsPackDescription gcPack = desc("aaa", GC, PACK); + DfsPackDescription compactPack = desc("bbb", COMPACT, PACK); + DfsPackDescription insertPack = desc("ccc", INSERT, PACK); + DfsPackDescription midxPack = midxDesc("midx", null, gcPack, + compactPack, insertPack); + List<DfsPackDescription> packs = List.of(gcPack, compactPack, + insertPack, midxPack); + + MidxDescList packList = MidxDescList.create(packs); + assertEquals(1, packList.findAllCoveringMidxs(gcPack).size()); + assertEquals(1, packList.findAllCoveringMidxs(compactPack).size()); + assertEquals(1, packList.findAllCoveringMidxs(insertPack).size()); + + assertEquals("multiple packs covered", 1, packList + .findAllCoveringMidxs(List.of(gcPack, compactPack)).size()); + } + + @Test + public void findAllImpactedMidx_midxPlusOne() { + DfsPackDescription gcPack = desc("aaa", GC, PACK); + DfsPackDescription compactPack = desc("bbb", COMPACT, PACK); + DfsPackDescription insertPack = desc("ccc", INSERT, PACK); + DfsPackDescription midxPack = midxDesc("midx", null, gcPack, + compactPack, insertPack); + DfsPackDescription nonMidxInsertPack = desc("non-midx", INSERT, PACK); + List<DfsPackDescription> packs = List.of(gcPack, compactPack, + insertPack, midxPack, nonMidxInsertPack); + + MidxDescList packList = MidxDescList.create(packs); + assertEquals(1, packList.findAllCoveringMidxs(gcPack).size()); + assertEquals(1, packList.findAllCoveringMidxs(compactPack).size()); + assertEquals(1, packList.findAllCoveringMidxs(insertPack).size()); + assertEquals(0, + packList.findAllCoveringMidxs(nonMidxInsertPack).size()); + + assertEquals("multiple packs covered", 1, packList + .findAllCoveringMidxs(List.of(gcPack, compactPack)).size()); + assertEquals("some covered", 1, packList + .findAllCoveringMidxs(List.of(insertPack, nonMidxInsertPack)) + .size()); + } + + @Test + public void findAllImpactedMidxs_nestedMidx() { + DfsPackDescription gcPack = desc("base-gc", GC, PACK); + DfsPackDescription compactPack = desc("base-compact1", COMPACT, PACK); + DfsPackDescription baseMidx = midxDesc("base-midx", null, gcPack, + compactPack); + + DfsPackDescription middlePack = desc("middle-insert", INSERT, PACK); + DfsPackDescription middlePack2 = desc("middle-insert2", INSERT, PACK); + DfsPackDescription middleMidx = midxDesc("middle-midx", baseMidx, + middlePack, middlePack2); + + DfsPackDescription tipPack = desc("compact2", COMPACT, PACK); + DfsPackDescription tipPack2 = desc("compact3", COMPACT, PACK); + DfsPackDescription tipMidx = midxDesc("tipMidx", middleMidx, tipPack, + tipPack2); + + List<DfsPackDescription> packs = List.of(gcPack, compactPack, baseMidx, + middlePack, middlePack2, middleMidx, tipPack, tipPack2, + tipMidx); + + MidxDescList packList = MidxDescList.create(packs); + assertEquals("one covered tip midx", 1, + packList.findAllCoveringMidxs(tipPack).size()); + assertEquals("one covered middle midx", 2, + packList.findAllCoveringMidxs(middlePack).size()); + assertEquals("one covered base midx", 3, + packList.findAllCoveringMidxs(compactPack).size()); + assertEquals("multiple covered in chain", 3, packList + .findAllCoveringMidxs(List.of(tipPack, middlePack, compactPack)) + .size()); + assertEquals("midx itself is covered", 1, + packList.findAllCoveringMidxs(tipMidx).size()); + assertEquals("inner midx is covered", 2, + packList.findAllCoveringMidxs(middleMidx).size()); + } + + private DfsPackDescription desc(String name, + DfsObjDatabase.PackSource source, PackExt... exts) { + DfsPackDescription desc = new DfsPackDescription(REPO_DESC, name, + source); + for (PackExt ext : exts) { + desc.addFileExt(ext); + } + return desc; + } + + private DfsPackDescription midxDesc(String name, DfsPackDescription base, + DfsPackDescription... covered) { + DfsPackDescription midx = desc(name, GC, MULTI_PACK_INDEX); + midx.setCoveredPacks(Arrays.stream(covered).toList()); + midx.setMultiPackIndexBase(base); + return midx; + } + +}
diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/dfs/MidxPackFilterTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/dfs/MidxPackFilterTest.java new file mode 100644 index 0000000..584bab1 --- /dev/null +++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/dfs/MidxPackFilterTest.java
@@ -0,0 +1,237 @@ +/* + * 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.internal.storage.dfs; + +import static org.eclipse.jgit.internal.storage.dfs.DfsObjDatabase.PackSource.COMPACT; +import static org.eclipse.jgit.internal.storage.dfs.DfsObjDatabase.PackSource.GC; +import static org.eclipse.jgit.internal.storage.dfs.DfsObjDatabase.PackSource.INSERT; +import static org.eclipse.jgit.internal.storage.pack.PackExt.MULTI_PACK_INDEX; +import static org.eclipse.jgit.internal.storage.pack.PackExt.PACK; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; + +import java.util.List; + +import org.eclipse.jgit.internal.storage.pack.PackExt; +import org.junit.Test; + +public class MidxPackFilterTest { + private static final DfsRepositoryDescription repoDesc = new DfsRepositoryDescription( + "test"); + + private static int timeCounter = 0; + + @Test + public void useMidx_oneMidxCoversAll_onlyMidx() { + DfsPackDescription gc = pack("aaaa", GC, PACK); + DfsPackDescription compact = pack("cccc", COMPACT, PACK); + DfsPackDescription compactTwo = pack("bbbb", COMPACT, PACK); + DfsPackDescription midx = pack("midx", GC, MULTI_PACK_INDEX); + midx.setCoveredPacks(List.of(gc, compact, compactTwo)); + + List<DfsPackDescription> reorgPacks = MidxPackFilter + .useMidx(List.of(gc, compact, compactTwo, midx)); + assertEquals(1, reorgPacks.size()); + assertEquals(midx, reorgPacks.get(0)); + } + + @Test + public void useMidx_midxAndOneUncoveredPack_midxAndPack() { + DfsPackDescription gc = pack("aaaa", GC, PACK); + DfsPackDescription compact = pack("cccc", COMPACT, PACK); + DfsPackDescription compactTwo = pack("bbbb", COMPACT, PACK); + DfsPackDescription midx = pack("midx", GC, MULTI_PACK_INDEX); + midx.setCoveredPacks(List.of(gc, compact, compactTwo)); + + DfsPackDescription extra = pack("extra", COMPACT, PACK); + + List<DfsPackDescription> reorgPacks = MidxPackFilter + .useMidx(List.of(gc, compact, compactTwo, midx, extra)); + assertEquals(2, reorgPacks.size()); + assertTrue(reorgPacks.contains(midx)); + assertTrue(reorgPacks.contains(extra)); + } + + @Test + public void useMidx_noMidx_allPacks() { + DfsPackDescription gc = pack("aaaa", GC, PACK); + DfsPackDescription compact = pack("cccc", COMPACT, PACK); + DfsPackDescription compactTwo = pack("bbbb", COMPACT, PACK); + + List<DfsPackDescription> reorgPacks = MidxPackFilter + .useMidx(List.of(gc, compact, compactTwo)); + assertEquals(3, reorgPacks.size()); + assertTrue(reorgPacks.contains(gc)); + assertTrue(reorgPacks.contains(compact)); + assertTrue(reorgPacks.contains(compactTwo)); + } + + @Test + public void useMidx_midxMissesOnePack_onlyPacks() { + DfsPackDescription gc = pack("aaaa", GC, PACK); + DfsPackDescription compact = pack("cccc", COMPACT, PACK); + DfsPackDescription compactTwo = pack("bbbb", COMPACT, PACK); + DfsPackDescription midx = pack("midx", GC, MULTI_PACK_INDEX); + midx.setCoveredPacks(List.of(gc, compact, compactTwo)); + + List<DfsPackDescription> reorgPacks = MidxPackFilter + .useMidx(List.of(gc, compactTwo, midx)); // compact missing + assertEquals(2, reorgPacks.size()); + assertTrue(reorgPacks.contains(gc)); + assertTrue(reorgPacks.contains(compactTwo)); + } + + @Test + public void useMidx_nestedMidx_onlyTopMidx() { + DfsPackDescription gc = pack("aaaa", GC, PACK); + DfsPackDescription compact = pack("cccc", COMPACT, PACK); + DfsPackDescription firstMidx = pack("midx1", GC, MULTI_PACK_INDEX); + firstMidx.setCoveredPacks(List.of(gc, compact)); + + DfsPackDescription compact2 = pack("dddd", COMPACT, PACK); + DfsPackDescription compact3 = pack("eeee", COMPACT, PACK); + DfsPackDescription topMidx = pack("midx2", GC, MULTI_PACK_INDEX); + topMidx.setCoveredPacks(List.of(compact2, compact3)); + topMidx.setMultiPackIndexBase(firstMidx); + + List<DfsPackDescription> reorgPacks = MidxPackFilter.useMidx( + List.of(gc, compact, firstMidx, compact2, compact3, topMidx)); + assertEquals(1, reorgPacks.size()); + assertTrue(reorgPacks.contains(topMidx)); + } + + @Test + public void useMidx_nestedMidxAndOnePack_topMidxAndPack() { + DfsPackDescription gc = pack("aaaa", GC, PACK); + DfsPackDescription compact = pack("cccc", COMPACT, PACK); + DfsPackDescription firstMidx = pack("midx1", GC, MULTI_PACK_INDEX); + firstMidx.setCoveredPacks(List.of(gc, compact)); + + DfsPackDescription compact2 = pack("dddd", COMPACT, PACK); + DfsPackDescription compact3 = pack("eeee", COMPACT, PACK); + DfsPackDescription topMidx = pack("midx2", GC, MULTI_PACK_INDEX); + topMidx.setCoveredPacks(List.of(compact2, compact3)); + topMidx.setMultiPackIndexBase(firstMidx); + + DfsPackDescription uncovered = pack("uncovered", INSERT, PACK); + + List<DfsPackDescription> reorgPacks = MidxPackFilter.useMidx(List.of(gc, + compact, firstMidx, compact2, compact3, topMidx, uncovered)); + assertEquals(2, reorgPacks.size()); + assertTrue(reorgPacks.contains(topMidx)); + assertTrue(reorgPacks.contains(uncovered)); + } + + @Test + public void skipMidx_oneMidxCoversAll_allPacks() { + DfsPackDescription gc = pack("aaaa", GC, PACK); + DfsPackDescription compact = pack("cccc", COMPACT, PACK); + DfsPackDescription compactTwo = pack("bbbb", COMPACT, PACK); + DfsPackDescription midx = pack("midx", GC, MULTI_PACK_INDEX); + midx.setCoveredPacks(List.of(gc, compact, compactTwo)); + + List<DfsPackDescription> reorgPacks = MidxPackFilter + .skipMidxs(List.of(gc, compact, compactTwo, midx)); + assertEquals(3, reorgPacks.size()); + assertTrue(reorgPacks.contains(gc)); + assertTrue(reorgPacks.contains(compact)); + assertTrue(reorgPacks.contains(compactTwo)); + } + + @Test + public void skipMidx_midxAndOneUncoveredPack_allPacks() { + DfsPackDescription gc = pack("aaaa", GC, PACK); + DfsPackDescription compact = pack("cccc", COMPACT, PACK); + DfsPackDescription compactTwo = pack("bbbb", COMPACT, PACK); + DfsPackDescription midx = pack("midx", GC, MULTI_PACK_INDEX); + midx.setCoveredPacks(List.of(gc, compact, compactTwo)); + + DfsPackDescription extra = pack("extra", COMPACT, PACK); + + List<DfsPackDescription> reorgPacks = MidxPackFilter + .skipMidxs(List.of(gc, compact, compactTwo, midx, extra)); + assertEquals(4, reorgPacks.size()); + assertTrue(reorgPacks.contains(gc)); + assertTrue(reorgPacks.contains(compact)); + assertTrue(reorgPacks.contains(compactTwo)); + assertTrue(reorgPacks.contains(extra)); + } + + @Test + public void skipMidx_noMidx_allPacks() { + DfsPackDescription gc = pack("aaaa", GC, PACK); + DfsPackDescription compact = pack("cccc", COMPACT, PACK); + DfsPackDescription compactTwo = pack("bbbb", COMPACT, PACK); + + List<DfsPackDescription> reorgPacks = MidxPackFilter + .skipMidxs(List.of(gc, compact, compactTwo)); + assertEquals(3, reorgPacks.size()); + assertTrue(reorgPacks.contains(gc)); + assertTrue(reorgPacks.contains(compact)); + assertTrue(reorgPacks.contains(compactTwo)); + } + + @Test + public void skipMidx_nestedMidx_allPacks() { + DfsPackDescription gc = pack("aaaa", GC, PACK); + DfsPackDescription compact = pack("cccc", COMPACT, PACK); + DfsPackDescription firstMidx = pack("midx1", GC, MULTI_PACK_INDEX); + firstMidx.setCoveredPacks(List.of(gc, compact)); + + DfsPackDescription compact2 = pack("dddd", COMPACT, PACK); + DfsPackDescription compact3 = pack("eeee", COMPACT, PACK); + DfsPackDescription topMidx = pack("midx2", GC, MULTI_PACK_INDEX); + topMidx.setCoveredPacks(List.of(compact2, compact3)); + topMidx.setMultiPackIndexBase(firstMidx); + + List<DfsPackDescription> reorgPacks = MidxPackFilter.skipMidxs( + List.of(gc, compact, firstMidx, compact2, compact3, topMidx)); + assertEquals(4, reorgPacks.size()); + assertTrue(reorgPacks.contains(gc)); + assertTrue(reorgPacks.contains(compact)); + assertTrue(reorgPacks.contains(compact2)); + assertTrue(reorgPacks.contains(compact3)); + } + + @Test + public void skipMidx_nestedMidxAndOnePack_allPacks() { + DfsPackDescription gc = pack("aaaa", GC, PACK); + DfsPackDescription compact = pack("cccc", COMPACT, PACK); + DfsPackDescription firstMidx = pack("midx1", GC, MULTI_PACK_INDEX); + firstMidx.setCoveredPacks(List.of(gc, compact)); + + DfsPackDescription compact2 = pack("dddd", COMPACT, PACK); + DfsPackDescription compact3 = pack("eeee", COMPACT, PACK); + DfsPackDescription topMidx = pack("midx2", GC, MULTI_PACK_INDEX); + topMidx.setCoveredPacks(List.of(compact2, compact3)); + topMidx.setMultiPackIndexBase(firstMidx); + + DfsPackDescription uncovered = pack("uncovered", INSERT, PACK); + + List<DfsPackDescription> reorgPacks = MidxPackFilter + .skipMidxs(List.of(gc, compact, firstMidx, compact2, compact3, + topMidx, uncovered)); + assertEquals(5, reorgPacks.size()); + assertTrue(reorgPacks.contains(gc)); + assertTrue(reorgPacks.contains(compact)); + assertTrue(reorgPacks.contains(compact2)); + assertTrue(reorgPacks.contains(compact3)); + assertTrue(reorgPacks.contains(uncovered)); + } + + private static DfsPackDescription pack(String name, + DfsObjDatabase.PackSource source, PackExt ext) { + DfsPackDescription desc = new DfsPackDescription(repoDesc, name, + source); + desc.setLastModified(timeCounter++); + desc.addFileExt(ext); + return desc; + } +}
diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/dfs/MidxPackListTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/dfs/MidxPackListTest.java new file mode 100644 index 0000000..f20ca38 --- /dev/null +++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/dfs/MidxPackListTest.java
@@ -0,0 +1,349 @@ +/* + * 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.internal.storage.dfs; + +import static java.util.Arrays.asList; +import static org.eclipse.jgit.lib.Constants.OBJ_BLOB; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNull; + +import java.io.IOException; +import java.nio.charset.StandardCharsets; +import java.util.Arrays; +import java.util.List; +import java.util.zip.Deflater; + +import org.eclipse.jgit.junit.JGitTestUtil; +import org.eclipse.jgit.junit.TestRng; +import org.eclipse.jgit.lib.NullProgressMonitor; +import org.eclipse.jgit.lib.ObjectId; +import org.junit.Before; +import org.junit.Test; + +public class MidxPackListTest { + + InMemoryRepository db; + + @Before + public void setUp() { + db = new InMemoryRepository(new DfsRepositoryDescription("test")); + db.getObjectDatabase().setUseMultipackIndex(true); + } + + @Test + public void getAllPlainPacks_onlyPlain() throws IOException { + setupThreePacks(); + DfsPackFile[] packs = db.getObjectDatabase().getPacks(); + MidxPackList packList = MidxPackList.create(packs); + assertEquals(3, packList.getAllPlainPacks().size()); + } + + @Test + public void getAllPlainPacks_onlyMidx() throws IOException { + setupThreePacksAndMidx(); + + DfsPackFile[] packs = db.getObjectDatabase().getPacks(); + assertEquals(1, packs.length); + MidxPackList packList = MidxPackList.create(packs); + assertEquals(3, packList.getAllPlainPacks().size()); + } + + @Test + public void getAllPlainPacks_midxPlusOne() throws IOException { + setupThreePacksAndMidx(); + writePackWithRandomBlob(60); + + DfsPackFile[] packs = db.getObjectDatabase().getPacks(); + assertEquals(2, packs.length); + MidxPackList packList = MidxPackList.create(packs); + assertEquals(4, packList.getAllPlainPacks().size()); + } + + @Test + public void getAllPlainPacks_nestedMidx() throws IOException { + setupSixPacksThreeMidx(); + + DfsPackFile[] packs = db.getObjectDatabase().getPacks(); + assertEquals(1, packs.length); + MidxPackList packList = MidxPackList.create(packs); + assertEquals(6, packList.getAllPlainPacks().size()); + } + + @Test + public void getAllMidxPacks_onlyPlain() throws IOException { + setupThreePacks(); + + MidxPackList packList = MidxPackList + .create(db.getObjectDatabase().getPacks()); + assertEquals(0, packList.getAllMidxPacks().size()); + } + + @Test + public void getAllMidxPacks_onlyMidx() throws IOException { + setupThreePacksAndMidx(); + + MidxPackList packList = MidxPackList + .create(db.getObjectDatabase().getPacks()); + assertEquals(1, packList.getAllMidxPacks().size()); + } + + @Test + public void getAllMidxPacks_midxPlusOne() throws IOException { + setupThreePacksAndMidx(); + writePackWithRandomBlob(60); + + DfsPackFile[] packs = db.getObjectDatabase().getPacks(); + assertEquals(2, packs.length); + MidxPackList packList = MidxPackList.create(packs); + assertEquals(1, packList.getAllMidxPacks().size()); + } + + @Test + public void getAllMidxPacks_nestedMidx() throws IOException { + setupSixPacksThreeMidx(); + + DfsPackFile[] packs = db.getObjectDatabase().getPacks(); + assertEquals(1, packs.length); + MidxPackList packList = MidxPackList.create(packs); + assertEquals(3, packList.getAllMidxPacks().size()); + } + + @Test + public void findAllImpactedMidx_onlyPacks() throws IOException { + setupThreePacks(); + + DfsPackFile[] packs = db.getObjectDatabase().getPacks(); + MidxPackList packList = MidxPackList + .create(db.getObjectDatabase().getPacks()); + assertEquals(0, packList.findAllCoveringMidxs(asList(packs)).size()); + } + + @Test + public void findAllImpactedMidx_onlyMidx() throws IOException { + setupThreePacksAndMidx(); + + DfsPackFile[] packs = db.getObjectDatabase().getPacks(); + MidxPackList packList = MidxPackList.create(packs); + List<DfsPackFile> covered = ((DfsPackFileMidx) packs[0]) + .getAllCoveredPacks(); + assertEquals(1, packList.findAllCoveringMidxs(covered.get(0)).size()); + assertEquals(1, packList.findAllCoveringMidxs(covered.get(1)).size()); + assertEquals(1, packList.findAllCoveringMidxs(covered.get(2)).size()); + + assertEquals("multiple packs covered", 1, + packList.findAllCoveringMidxs(covered.subList(0, 2)).size()); + } + + @Test + public void findAllImpactedMidx_midxPlusOne() throws IOException { + setupThreePacksAndMidx(); + writePackWithRandomBlob(60); + + DfsPackFile[] packs = db.getObjectDatabase().getPacks(); + assertEquals(2, packs.length); + + DfsPackFile uncoveredPack = packs[0]; + List<DfsPackFile> coveredPacks = ((DfsPackFileMidx) packs[1]) + .getAllCoveredPacks(); + assertEquals(3, coveredPacks.size()); + + MidxPackList packList = MidxPackList.create(packs); + assertEquals("one non covered", 0, + packList.findAllCoveringMidxs(uncoveredPack).size()); + assertEquals("one and covered", 1, + packList.findAllCoveringMidxs(coveredPacks.get(1)).size()); + assertEquals( + "two, only one covered", 1, packList + .findAllCoveringMidxs( + List.of(uncoveredPack, coveredPacks.get(2))) + .size()); + } + + @Test + public void findAllImpactedMidxs_nestedMidx() throws IOException { + setupSixPacksThreeMidx(); + + DfsPackFile[] packs = db.getObjectDatabase().getPacks(); + assertEquals(1, packs.length); + MidxPackList packList = MidxPackList.create(packs); + List<DfsPackFile> coveredPacks = ((DfsPackFileMidx) packs[0]) + .getAllCoveredPacks(); + assertEquals(6, coveredPacks.size()); + + assertEquals("one covered tip midx", 1, + packList.findAllCoveringMidxs(coveredPacks.get(0)).size()); + assertEquals("one covered middle midx", 2, + packList.findAllCoveringMidxs(coveredPacks.get(2)).size()); + assertEquals("one covered base midx", 3, + packList.findAllCoveringMidxs(coveredPacks.get(4)).size()); + assertEquals( + "multiple covered in chain", 3, packList + .findAllCoveringMidxs(List.of(coveredPacks.get(1), + coveredPacks.get(2), coveredPacks.get(5))) + .size()); + } + + @Test + public void getTopMidxPack_noMidx_null() throws IOException { + setupThreePacks(); + MidxPackList packList = MidxPackList + .create(db.getObjectDatabase().getPacks()); + assertNull(packList.getTopMidxPack()); + } + + @Test + public void getTopMidxPack_oneMidx_returned() throws IOException { + DfsPackFileMidx midx = setupThreePacksAndMidx(); + MidxPackList packList = MidxPackList + .create(db.getObjectDatabase().getPacks()); + assertEquals(midx.getPackDescription(), + packList.getTopMidxPack().getPackDescription()); + } + + @Test + public void getTopMidxPack_multipleMidx_mostRecent() throws IOException { + writePackWithRandomBlob(100); + writePackWithRandomBlob(300); + writePackWithRandomBlob(50); + writePackWithRandomBlob(400); + writePackWithRandomBlob(130); + writePackWithRandomBlob(500); + DfsPackFile[] packs = db.getObjectDatabase().getPacks(); + assertEquals(6, packs.length); + + // midx covers first two packs + writeMultipackIndex(Arrays.copyOfRange(packs, 4, 6), null); + + // chain of midxs covering all + DfsPackFileMidx midxBase = writeMultipackIndex( + Arrays.copyOfRange(packs, 4, 6), null); + DfsPackFileMidx midxMid = writeMultipackIndex( + Arrays.copyOfRange(packs, 2, 4), midxBase); + DfsPackFileMidx chainTwo = writeMultipackIndex( + Arrays.copyOfRange(packs, 0, 2), midxMid); + + MidxPackList packList = MidxPackList + .create(db.getObjectDatabase().getPacks()); + assertEquals(chainTwo.getPackDescription(), + packList.getTopMidxPack().getPackDescription()); + } + + @Test + public void getPlainPacksNotCoveredBy_null_all() throws IOException { + setupThreePacks(); + MidxPackList packList = MidxPackList + .create(db.getObjectDatabase().getPacks()); + assertEquals(3, packList.getPlainPacksNotCoveredBy(null).size()); + } + + @Test + public void getPlainPacksNotCoveredBy_midxCoversAll_nothing() + throws IOException { + DfsPackFileMidx midx = setupThreePacksAndMidx(); + MidxPackList packList = MidxPackList + .create(db.getObjectDatabase().getPacks()); + assertEquals(0, packList.getPlainPacksNotCoveredBy(midx).size()); + } + + @Test + public void getPlainPacksNotCoveredBy_midxMissesOne_one() + throws IOException { + DfsPackFileMidx midx = setupThreePacksAndMidx(); + writePackWithBlob("getPlainPacksNotCovered_missingone" + .getBytes(StandardCharsets.UTF_8)); + MidxPackList packList = MidxPackList + .create(db.getObjectDatabase().getPacks()); + assertEquals(1, packList.getPlainPacksNotCoveredBy(midx).size()); + } + + @Test + public void getPlainPacksNotCoveredBy_midxChain() throws IOException { + writePackWithRandomBlob(100); + writePackWithRandomBlob(300); + writePackWithRandomBlob(50); + writePackWithRandomBlob(400); + writePackWithRandomBlob(130); + writePackWithRandomBlob(500); + DfsPackFile[] packs = db.getObjectDatabase().getPacks(); + assertEquals(6, packs.length); + DfsPackFileMidx midxBase = writeMultipackIndex( + Arrays.copyOfRange(packs, 4, 6), null); + DfsPackFileMidx midxMid = writeMultipackIndex( + Arrays.copyOfRange(packs, 2, 4), midxBase); + DfsPackFileMidx midxTip = writeMultipackIndex( + Arrays.copyOfRange(packs, 0, 2), midxMid); + + MidxPackList packList = MidxPackList + .create(db.getObjectDatabase().getPacks()); + assertEquals(4, packList.getPlainPacksNotCoveredBy(midxBase).size()); + assertEquals(2, packList.getPlainPacksNotCoveredBy(midxMid).size()); + assertEquals(0, packList.getPlainPacksNotCoveredBy(midxTip).size()); + } + + private void setupThreePacks() throws IOException { + writePackWithRandomBlob(100); + writePackWithRandomBlob(300); + writePackWithRandomBlob(50); + } + + private DfsPackFileMidx setupThreePacksAndMidx() throws IOException { + writePackWithRandomBlob(100); + writePackWithRandomBlob(300); + writePackWithRandomBlob(50); + return writeMultipackIndex(); + } + + private void setupSixPacksThreeMidx() throws IOException { + writePackWithRandomBlob(100); + writePackWithRandomBlob(300); + writePackWithRandomBlob(50); + writePackWithRandomBlob(400); + writePackWithRandomBlob(130); + writePackWithRandomBlob(500); + DfsPackFile[] packs = db.getObjectDatabase().getPacks(); + assertEquals(6, packs.length); + DfsPackFileMidx midxBase = writeMultipackIndex( + Arrays.copyOfRange(packs, 4, 6), null); + DfsPackFileMidx midxMid = writeMultipackIndex( + Arrays.copyOfRange(packs, 2, 4), midxBase); + writeMultipackIndex(Arrays.copyOfRange(packs, 0, 2), midxMid); + assertEquals("only top midx", 1, + db.getObjectDatabase().getPacks().length); + } + + private DfsPackFileMidx writeMultipackIndex() throws IOException { + return writeMultipackIndex(db.getObjectDatabase().getPacks(), null); + } + + private DfsPackFileMidx writeMultipackIndex(DfsPackFile[] packs, + DfsPackFileMidx base) throws IOException { + List<DfsPackFile> packfiles = asList(packs); + DfsPackDescription desc = DfsMidxWriter.writeMidx( + NullProgressMonitor.INSTANCE, db.getObjectDatabase(), packfiles, + base != null ? base.getPackDescription() : null); + db.getObjectDatabase().commitPack(List.of(desc), null); + return DfsPackFileMidx.create(DfsBlockCache.getInstance(), desc, + packfiles, base); + } + + private ObjectId writePackWithBlob(byte[] data) throws IOException { + DfsInserter ins = (DfsInserter) db.newObjectInserter(); + ins.setCompressionLevel(Deflater.NO_COMPRESSION); + ObjectId blobId = ins.insert(OBJ_BLOB, data); + ins.flush(); + return blobId; + } + + // Do not use the size twice into the same test (it gives the same blob!) + private ObjectId writePackWithRandomBlob(int size) throws IOException { + byte[] data = new TestRng(JGitTestUtil.getName()).nextBytes(size); + return writePackWithBlob(data); + } +}
diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/file/BasePackWriterTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/file/BasePackWriterTest.java index cd73c6a..b8404aa 100644 --- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/file/BasePackWriterTest.java +++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/file/BasePackWriterTest.java
@@ -16,6 +16,7 @@ import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertThrows; import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; import static org.mockito.ArgumentMatchers.any; @@ -63,7 +64,9 @@ import org.eclipse.jgit.transport.PackParser; import org.junit.After; import org.junit.Before; +import org.junit.Rule; import org.junit.Test; +import org.junit.rules.TestName; import org.mockito.Mockito; public class BasePackWriterTest extends SampleDataRepositoryTestCase { @@ -74,6 +77,8 @@ public class BasePackWriterTest extends SampleDataRepositoryTestCase { private static final Set<ObjectIdSet> EMPTY_ID_SET = Collections .<ObjectIdSet> emptySet(); + private static final boolean UNSHALLOW_FETCH = true; + private PackConfig config; private PackWriter writer; @@ -96,6 +101,10 @@ public class BasePackWriterTest extends SampleDataRepositoryTestCase { private RevBlob contentE; + private RevBlob contentF; + + private RevBlob contentG; + private RevCommit c1; private RevCommit c2; @@ -106,6 +115,13 @@ public class BasePackWriterTest extends SampleDataRepositoryTestCase { private RevCommit c5; + private RevCommit c6; + + private RevCommit c7; + + @Rule + public TestName testName = new TestName(); + @Override @Before public void setUp() throws Exception { @@ -205,12 +221,9 @@ public void testWriteEmptyPack2() throws IOException { public void testNotIgnoreNonExistingObjects() throws IOException { final ObjectId nonExisting = ObjectId .fromString("0000000000000000000000000000000000000001"); - try { - createVerifyOpenPack(NONE, haves(nonExisting), false, false); - fail("Should have thrown MissingObjectException"); - } catch (MissingObjectException x) { - // expected - } + assertThrows(MissingObjectException.class, + () -> createVerifyOpenPack(NONE, haves(nonExisting), false, + false)); } /** @@ -599,13 +612,19 @@ public void testExclude() throws Exception { } private static void assertContent(PackIndex pi, List<ObjectId> expected) { - assertEquals("Pack index has wrong size.", expected.size(), - pi.getObjectCount()); - for (int i = 0; i < pi.getObjectCount(); i++) - assertTrue( - "Pack index didn't contain the expected id " - + pi.getObjectId(i), - expected.contains(pi.getObjectId(i))); + Set<ObjectId> packedObjectIds = new HashSet<>(); + for (int i = 0; i < pi.getObjectCount(); i++) { + packedObjectIds.add(pi.getObjectId(i)); + } + for (ObjectId packedObjectId : packedObjectIds) { + assertTrue("Unexpected id in pack index: " + packedObjectId, + expected.contains(packedObjectId)); + } + for (ObjectId expectedObjectId : expected) { + assertTrue("Pack index didn't contain the expected id " + expectedObjectId, + packedObjectIds.contains(expectedObjectId)); + } + assertEquals("Pack index has wrong size.", expected.size(), pi.getObjectCount()); } @Test @@ -702,6 +721,141 @@ public void testShallowFetchShallowAncestorDepth2() throws Exception { } @Test + public void testUnshallowFetchShallowAncestorToMaxDepth() throws Exception { + // [unshallow-branch] + // | + // v + //c1 <--- c2 <--- c3 <--- c4 <--- c5 <--- c6 <-[main-branch] + // ^ + // | + // [stable-branch] + // + // The above graph shows the test-case of a linear history created + // by setupRepoForUnshallowFetch(), where we simulate the branches + // by wanting both c6 (as 'main-branch') and c3 (as 'stable-branch'). + try (FileRepository repo = setupRepoForUnshallowFetch()) { + // The client has a shallow clone with depth=1 of c2 and then + // requests the unshallow with WANT=stable-branch(c3) and main-branch(c6) + // notifying the server that HAVE, therefore requesting a maximum depth + // of Integer.MAX_VALUE + PackIndex idx = writeUnshallowPack(repo, Integer.MAX_VALUE, wants(c6, c3), haves(c2)); + assertContent(idx, + Arrays.asList(c1.getId(), c1.getTree().getId(), + // NOTE: c2, its tree and BLOB are not expected to be packed + // because the existing shallow repo should have them already + c3.getId(), c3.getTree().getId(), + c4.getId(), c4.getTree().getId(), + c5.getId(), c5.getTree().getId(), + c6.getId(), c6.getTree().getId(), + // NOTE: contentA.getId() is already local as it is referenced by c2's tree + // which is part of the initial shallow clone with depth=1 + contentC.getId(), + contentD.getId(), contentE.getId(), contentF.getId())); + } + } + + @Test + public void testUnshallowFetchShallowMergeCommitToMaxDepth() throws Exception { + // [unshallow-branch] + // | + // v + //c1 <--- c2 <--- c5 <--- c6 <--- c7 <-[main-branch] + // \ / + // -- c3 <--- c4 <-[feature-branch] + // + try (FileRepository repo = setupRepoWithMergeCommitForUnshallowFetch()) { + PackIndex idx = writeUnshallowPack(repo, Integer.MAX_VALUE, wants(c7, c4), haves(c6)); + assertContent(idx, + Arrays.asList(c1.getId(), c1.getTree().getId(), + c2.getId(), c2.getTree().getId(), + c3.getId(), c3.getTree().getId(), + c4.getId(), c4.getTree().getId(), + c5.getId(), c5.getTree().getId(), + c7.getId(), c7.getTree().getId(), + // contentA, contentB, contentE and contentF are already part of c6 tree + contentC.getId(), + contentD.getId(), contentG.getId())); + } + } + + @Test + public void testUnshallowFetchShallowLinearCommitToMaxDepth() throws Exception { + // [unshallow-branch] + // | + // v + //c1 <--- c2 <--- c3 <--- c4 <--- c5 <-[main-branch] + // + try (FileRepository repo = setupRepoWithLinearHistoryForUnshallowFetch()) { + PackIndex idx = writeUnshallowPack(repo, Integer.MAX_VALUE, wants(c5), haves(c3)); + assertContent(idx, + Arrays.asList(c1.getId(), c1.getTree().getId(), + c2.getId(), c2.getTree().getId(), + c4.getId(), c4.getTree().getId(), + c5.getId(), c5.getTree().getId(), + // contentA, contentB are already part of c3 tree + contentD.getId(), contentE.getId())); + } + } + + private FileRepository setupRepoWithMergeCommitForUnshallowFetch() throws Exception { + String commitMessage = testName.getMethodName(); + FileRepository repo = createBareRepository(); + // TestRepository will close the repo, but we need to return an open + // one! + repo.incrementOpen(); + try (TestRepository<Repository> r = new TestRepository<>(repo)) { + BranchBuilder bb = r.branch("refs/heads/master"); + contentA = r.blob("A"); + contentB = r.blob("B"); + contentC = r.blob("C"); + contentD = r.blob("D"); + contentE = r.blob("E"); + contentF = r.blob("F"); + contentG = r.blob("G"); + c1 = bb.commit().message(commitMessage + " c1").add("a", contentA).create(); + c2 = bb.commit().message(commitMessage + " c2").add("b", contentB).create(); + c5 = bb.commit().message(commitMessage + " c5").add("e", contentE).create(); + + BranchBuilder fb = r.branch("refs/heads/feature"); + fb.update(c2); + c3 = fb.commit().message(commitMessage + " c3").add("c", contentC).create(); + c4 = fb.commit().message(commitMessage + " c4").add("d", contentD).create(); + + c6 = bb.commit().message(commitMessage + " c6").add("f", contentF).parent(c4).create(); + r.branch("refs/heads/unshallow").update(c6); + + c7 = bb.commit().message(commitMessage + " c7").add("g", contentG).create(); + r.getRevWalk().parseHeaders(c7); // fully initialize the tip RevCommit + + return repo; + } + } + + private FileRepository setupRepoWithLinearHistoryForUnshallowFetch() throws Exception { + String commitMessage = testName.getMethodName(); + FileRepository repo = createBareRepository(); + // TestRepository will close the repo, but we need to return an open + // one! + repo.incrementOpen(); + try (TestRepository<Repository> r = new TestRepository<>(repo)) { + BranchBuilder bb = r.branch("refs/heads/master"); + contentA = r.blob("A"); + contentB = r.blob("B"); + contentC = r.blob("C"); + contentD = r.blob("D"); + contentE = r.blob("E"); + c1 = bb.commit().message(commitMessage + " c1").add("a", contentA).create(); + c2 = bb.commit().message(commitMessage + " c2").add("b", contentB).create(); + c3 = bb.commit().message(commitMessage + " c3").add("c", contentC).create(); + c4 = bb.commit().message(commitMessage + " c4").add("d", contentD).create(); + c5 = bb.commit().message(commitMessage + " c5").add("e", contentE).create(); + r.branch("refs/heads/unshallow").update(c3); + r.getRevWalk().parseHeaders(c5); // fully initialize the tip RevCommit + return repo; + } + } + + @Test public void testTotalPackFilesScanWhenSearchForReuseTimeoutNotSetTrue() throws Exception { totalPackFilesScanWhenSearchForReuseTimeoutNotSet(true); @@ -713,6 +867,7 @@ public void testTotalPackFilesScanWhenSearchForReuseTimeoutNotSetFalse() totalPackFilesScanWhenSearchForReuseTimeoutNotSet(false); } + @SuppressWarnings("boxing") public void totalPackFilesScanWhenSearchForReuseTimeoutNotSet(boolean doReturn) throws Exception { FileRepository fileRepository = setUpRepoWithMultiplePackfiles(); int numberOfPackFiles = (int) new GC(fileRepository).getStatistics().numberOfPackFiles; @@ -748,6 +903,7 @@ public void testTotalPackFilesScanWhenSkippingSearchForReuseTimeoutCheckFalse() totalPackFilesScanWhenSkippingSearchForReuseTimeoutCheck(false); } + @SuppressWarnings("boxing") public void totalPackFilesScanWhenSkippingSearchForReuseTimeoutCheck( boolean doReturn) throws Exception { FileRepository fileRepository = setUpRepoWithMultiplePackfiles(); @@ -784,6 +940,7 @@ public void partialPackFilesScanWhenDoingSearchForReuseTimeoutCheck() testPartialPackFilesScanWhenDoingSearchForReuseTimeoutCheck(false, expectedSelectCalls); } + @SuppressWarnings("boxing") public void testPartialPackFilesScanWhenDoingSearchForReuseTimeoutCheck( boolean doReturn, int expectedSelectCalls) throws Exception { FileRepository fileRepository = setUpRepoWithMultiplePackfiles(); @@ -856,6 +1013,7 @@ private PackFile getPackFileToWrite(FileRepository fileRepository, } private FileRepository setupRepoForShallowFetch() throws Exception { + String commitMessage = testName.getMethodName(); FileRepository repo = createBareRepository(); // TestRepository will close the repo, but we need to return an open // one! @@ -867,21 +1025,49 @@ private FileRepository setupRepoForShallowFetch() throws Exception { contentC = r.blob("C"); contentD = r.blob("D"); contentE = r.blob("E"); - c1 = bb.commit().add("a", contentA).create(); - c2 = bb.commit().add("b", contentB).create(); - c3 = bb.commit().add("c", contentC).create(); - c4 = bb.commit().add("d", contentD).create(); - c5 = bb.commit().add("e", contentE).create(); + c1 = bb.commit().message(commitMessage + " c1").add("a", contentA).create(); + c2 = bb.commit().message(commitMessage + " c2").add("b", contentB).create(); + c3 = bb.commit().message(commitMessage + " c3").add("c", contentC).create(); + c4 = bb.commit().message(commitMessage + " c4").add("d", contentD).create(); + c5 = bb.commit().message(commitMessage + " c5").add("e", contentE).create(); r.getRevWalk().parseHeaders(c5); // fully initialize the tip RevCommit return repo; } } + private FileRepository setupRepoForUnshallowFetch() throws Exception { + String commitMessage = testName.getMethodName(); + FileRepository repo = createBareRepository(); + // TestRepository will close the repo, but we need to return an open + // one! + repo.incrementOpen(); + try (TestRepository<Repository> r = new TestRepository<>(repo)) { + BranchBuilder bb = r.branch("refs/heads/master"); + contentA = r.blob("A"); + contentB = r.blob("B"); + contentC = r.blob("C"); + contentD = r.blob("D"); + contentE = r.blob("E"); + contentF = r.blob("F"); + contentG = r.blob("G"); + c1 = bb.commit().message(commitMessage + " c1").add("a", contentA).create(); + c2 = bb.commit().message(commitMessage + " c2").add("b", contentB).create(); + c3 = bb.commit().message(commitMessage + " c3").add("c", contentC).create(); + c4 = bb.commit().message(commitMessage + " c4").add("d", contentD).create(); + c5 = bb.commit().message(commitMessage + " c5").add("e", contentE).create(); + c6 = bb.commit().message(commitMessage + " c6").add("f", contentF).create(); + c7 = bb.commit().message(commitMessage + " c7").add("g", contentF).create(); + r.getRevWalk().parseHeaders(c7); // fully initialize the tip RevCommit + + return repo; + } + } + private static PackIndex writePack(FileRepository repo, Set<? extends ObjectId> want, Set<ObjectIdSet> excludeObjects) throws IOException { try (RevWalk walk = new RevWalk(repo)) { - return writePack(repo, walk, 0, want, NONE, excludeObjects); + return writePack(repo, walk, 0, want, NONE, excludeObjects, false); } } @@ -892,13 +1078,22 @@ private static PackIndex writeShallowPack(FileRepository repo, int depth, // marked the client's "shallow" commits. Emulate that here. try (DepthWalk.RevWalk walk = new DepthWalk.RevWalk(repo, depth - 1)) { walk.assumeShallow(shallow); - return writePack(repo, walk, depth, want, have, EMPTY_ID_SET); + return writePack(repo, walk, depth, want, have, EMPTY_ID_SET, false); + } + } + + private static PackIndex writeUnshallowPack(FileRepository repo, int depth, + Set<? extends ObjectId> want, Set<? extends ObjectId> have) throws IOException { + // During negotiation, UploadPack would have set up a DepthWalk and + // marked the client's commits in the HAVE as "unshallow". Emulate that here. + try (DepthWalk.RevWalk walk = new DepthWalk.RevWalk(repo, depth)) { + return writePack(repo, walk, depth, want, have, EMPTY_ID_SET, UNSHALLOW_FETCH); } } private static PackIndex writePack(FileRepository repo, RevWalk walk, int depth, Set<? extends ObjectId> want, - Set<? extends ObjectId> have, Set<ObjectIdSet> excludeObjects) + Set<? extends ObjectId> have, Set<ObjectIdSet> excludeObjects, boolean unshallow) throws IOException { try (PackWriter pw = new PackWriter(repo)) { pw.setDeltaBaseAsOffset(true); @@ -912,6 +1107,10 @@ private static PackIndex writePack(FileRepository repo, RevWalk walk, // ow doesn't need to be closed; caller closes walk. ObjectWalk ow = walk.toObjectWalkWithSameObjects(); + if (unshallow) { + pw.setShallowPack(depth, have); + } + pw.preparePack(NullProgressMonitor.INSTANCE, ow, want, have, NONE); File packdir = repo.getObjectDatabase().getPackDirectory(); PackFile packFile = new PackFile(packdir, pw.computeName(), @@ -1084,8 +1283,8 @@ private void verifyObjectsOrder(ObjectId objectsOrder[]) { for (MutableEntry me : pack) { entries.add(me.cloneEntry()); } - Collections.sort(entries, (MutableEntry o1, MutableEntry o2) -> Long - .signum(o1.getOffset() - o2.getOffset())); + entries.sort((MutableEntry o1, MutableEntry o2) -> Long + .signum(o1.getOffset() - o2.getOffset())); int i = 0; for (MutableEntry me : entries) {
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 index 494f1d1..3c7e27d 100644 --- 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
@@ -17,8 +17,8 @@ import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.IOException; +import java.util.LinkedHashMap; import java.util.List; -import java.util.Map; import org.eclipse.jgit.internal.storage.file.PackIndex; import org.eclipse.jgit.junit.FakeIndexFactory; @@ -64,8 +64,10 @@ public void load_validFile_basic_jgit() throws Exception { new FakeIndexFactory.IndexObject( "0000000000000000000000000000000000000012", 1502))); - Map<String, PackIndex> packs = Map.of("p1", idxOne, "p2", idxTwo, "p3", - idxThree); + LinkedHashMap<String, PackIndex> packs = new LinkedHashMap<>(3); + packs.put("p1", idxOne); + packs.put("p2", idxTwo); + packs.put("p3", idxThree); MultiPackIndexWriter writer = new MultiPackIndexWriter(); ByteArrayOutputStream out = new ByteArrayOutputStream(); writer.write(NullProgressMonitor.INSTANCE, out, packs);
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 index 5de9bd6..6436e31 100644 --- 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
@@ -20,8 +20,8 @@ import java.io.IOException; import java.util.ArrayList; import java.util.HashSet; +import java.util.LinkedHashMap; import java.util.List; -import java.util.Map; import java.util.Set; import org.eclipse.jgit.internal.storage.file.PackIndex; @@ -103,8 +103,8 @@ public void basicMidx() throws IOException { new FakeIndexFactory.IndexObject( "0000000000000000000000000000000000000012", 1502))); - Map<String, PackIndex> packs = Map.of("p1", idxOne, "p2", idxTwo, "p3", - idxThree); + LinkedHashMap<String, PackIndex> packs = orderedMapOf("p1", idxOne, + "p2", idxTwo, "p3", idxThree); MultiPackIndexWriter writer = new MultiPackIndexWriter(); ByteArrayOutputStream out = new ByteArrayOutputStream(); writer.write(NullProgressMonitor.INSTANCE, out, packs); @@ -140,7 +140,8 @@ public void jgit_largeOffsetChunk() throws IOException { "0000000000000000000000000000000000000002", (1L << 35)), new FakeIndexFactory.IndexObject( "0000000000000000000000000000000000000003", 13))); - Map<String, PackIndex> packs = Map.of("p1", idxOne, "p2", idxTwo); + LinkedHashMap<String, PackIndex> packs = orderedMapOf("p1", idxOne, + "p2", idxTwo); MultiPackIndexWriter writer = new MultiPackIndexWriter(); ByteArrayOutputStream out = new ByteArrayOutputStream(); writer.write(NullProgressMonitor.INSTANCE, out, packs); @@ -170,7 +171,8 @@ public void jgit_largeOffset_noChunk() throws IOException { "0000000000000000000000000000000000000002", 501), new FakeIndexFactory.IndexObject( "0000000000000000000000000000000000000003", 13))); - Map<String, PackIndex> packs = Map.of("p1", idxOne, "p2", idxTwo); + LinkedHashMap<String, PackIndex> packs = orderedMapOf("p1", idxOne, + "p2", idxTwo); MultiPackIndexWriter writer = new MultiPackIndexWriter(); ByteArrayOutputStream out = new ByteArrayOutputStream(); writer.write(NullProgressMonitor.INSTANCE, out, packs); @@ -206,7 +208,8 @@ public void jgit_resolve() throws IOException { // Match "32fe829a1c000000000000000000000000000010"); - Map<String, PackIndex> packs = Map.of("p1", idxOne, "p2", idxTwo); + LinkedHashMap<String, PackIndex> packs = orderedMapOf("p1", idxOne, + "p2", idxTwo); MultiPackIndexWriter writer = new MultiPackIndexWriter(); ByteArrayOutputStream out = new ByteArrayOutputStream(); writer.write(NullProgressMonitor.INSTANCE, out, packs); @@ -249,7 +252,8 @@ public void jgit_resolve_matchLimit() throws IOException { // Match "32fe829a1c000000000000000000000000000010"); - Map<String, PackIndex> packs = Map.of("p1", idxOne, "p2", idxTwo); + LinkedHashMap<String, PackIndex> packs = orderedMapOf("p1", idxOne, + "p2", idxTwo); MultiPackIndexWriter writer = new MultiPackIndexWriter(); ByteArrayOutputStream out = new ByteArrayOutputStream(); writer.write(NullProgressMonitor.INSTANCE, out, packs); @@ -283,13 +287,44 @@ public void jgit_resolve_noMatches() throws IOException { "bbbbbb0000000000000000000000000000000003", "32fe829a1c000000000000000000000000000010"); - Map<String, PackIndex> packs = Map.of("p1", idxOne, "p2", idxTwo); + LinkedHashMap<String, PackIndex> packs = orderedMapOf("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_noMatches_last() throws IOException { + AbbreviatedObjectId abbrev = AbbreviatedObjectId + .fromString("dd00000000"); + + PackIndex idxOne = indexWith("0000000000000000000000000000000000000001", + "3000000000000000000000000000000000000005", + "32fe829a1b000000000000000000000000000001", + "32fe829a1c000000000000000000000000000001", + "32fe829a1c000000000000000000000000000100", + "32fe829a1d000000000000000000000000000000"); + PackIndex idxTwo = indexWith( + // Noise + "8888880000000000000000000000000000000002", + "bbbbbb0000000000000000000000000000000003", + "32fe829a1c000000000000000000000000000010"); + + LinkedHashMap<String, PackIndex> packs = orderedMapOf("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); @@ -305,7 +340,8 @@ public void jgit_resolve_empty() throws IOException { PackIndex idxOne = FakeIndexFactory.indexOf(List.of()); PackIndex idxTwo = FakeIndexFactory.indexOf(List.of()); - Map<String, PackIndex> packs = Map.of("p1", idxOne, "p2", idxTwo); + LinkedHashMap<String, PackIndex> packs = orderedMapOf("p1", idxOne, + "p2", idxTwo); MultiPackIndexWriter writer = new MultiPackIndexWriter(); ByteArrayOutputStream out = new ByteArrayOutputStream(); writer.write(NullProgressMonitor.INSTANCE, out, packs); @@ -342,8 +378,8 @@ public void jgit_findPosition() throws IOException { new FakeIndexFactory.IndexObject( "0000000000000000000000000000000000000012", 1502))); - Map<String, PackIndex> packs = Map.of("p1", idxOne, "p2", idxTwo, "p3", - idxThree); + LinkedHashMap<String, PackIndex> packs = orderedMapOf("p1", idxOne, + "p2", idxTwo, "p3", idxThree); MultiPackIndexWriter writer = new MultiPackIndexWriter(); ByteArrayOutputStream out = new ByteArrayOutputStream(); writer.write(NullProgressMonitor.INSTANCE, out, packs); @@ -397,8 +433,8 @@ public void jgit_getObjectCount() throws IOException { new FakeIndexFactory.IndexObject( "0000000000000000000000000000000000000012", 1502))); - Map<String, PackIndex> packs = Map.of("p1", idxOne, "p2", idxTwo, "p3", - idxThree); + LinkedHashMap<String, PackIndex> packs = orderedMapOf("p1", idxOne, + "p2", idxTwo, "p3", idxThree); MultiPackIndexWriter writer = new MultiPackIndexWriter(); ByteArrayOutputStream out = new ByteArrayOutputStream(); writer.write(NullProgressMonitor.INSTANCE, out, packs); @@ -413,7 +449,8 @@ public void jgit_getObjectCount_emtpy() throws IOException { PackIndex idxOne = FakeIndexFactory.indexOf(List.of()); PackIndex idxTwo = FakeIndexFactory.indexOf(List.of()); - Map<String, PackIndex> packs = Map.of("p1", idxOne, "p2", idxTwo); + LinkedHashMap<String, PackIndex> packs = orderedMapOf("p1", idxOne, + "p2", idxTwo); MultiPackIndexWriter writer = new MultiPackIndexWriter(); ByteArrayOutputStream out = new ByteArrayOutputStream(); writer.write(NullProgressMonitor.INSTANCE, out, packs); @@ -443,4 +480,21 @@ private static void assertInIndex(MultiPackIndex midx, int expectedPackId, packOffset.getPackId()); assertEquals(expectedOffset, packOffset.getOffset()); } + + private static LinkedHashMap<String, PackIndex> orderedMapOf(String s1, + PackIndex pi1, String s2, PackIndex pi2) { + LinkedHashMap<String, PackIndex> map = new LinkedHashMap<>(2); + map.put(s1, pi1); + map.put(s2, pi2); + return map; + } + + private static LinkedHashMap<String, PackIndex> orderedMapOf(String s1, + PackIndex pi1, String s2, PackIndex pi2, String s3, PackIndex pi3) { + LinkedHashMap<String, PackIndex> map = new LinkedHashMap<>(2); + map.put(s1, pi1); + map.put(s2, pi2); + map.put(s3, pi3); + return map; + } }
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 8b57a2d..9b085a3 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
@@ -22,8 +22,8 @@ import java.io.IOException; import java.util.ArrayList; import java.util.Arrays; +import java.util.LinkedHashMap; import java.util.List; -import java.util.Map; import org.eclipse.jgit.internal.storage.file.PackIndex; import org.eclipse.jgit.junit.FakeIndexFactory; @@ -32,6 +32,7 @@ import org.eclipse.jgit.util.NB; import org.junit.Test; +@SuppressWarnings("boxing") public class MultiPackIndexWriterTest { @Test @@ -45,8 +46,9 @@ public void write_allSmallOffsets() throws IOException { object("0000000000000000000000000000000000000004", 1500), object("0000000000000000000000000000000000000006", 3000)); - Map<String, PackIndex> data = Map.of("packname1", index1, "packname2", - index2); + LinkedHashMap<String, PackIndex> data = new LinkedHashMap<>(); + data.put("packname1", index1); + data.put("packname2", index2); MultiPackIndexWriter writer = new MultiPackIndexWriter(); ByteArrayOutputStream out = new ByteArrayOutputStream(); @@ -74,13 +76,15 @@ public void write_smallOffset_limit() throws IOException { PackIndex index1 = indexOf( object("0000000000000000000000000000000000000001", 500), object("0000000000000000000000000000000000000003", 1500), - object("0000000000000000000000000000000000000005", (1L << 32) -1)); + object("0000000000000000000000000000000000000005", + (1L << 32) - 1)); PackIndex index2 = indexOf( object("0000000000000000000000000000000000000002", 500), object("0000000000000000000000000000000000000004", 1500), object("0000000000000000000000000000000000000006", 3000)); - Map<String, PackIndex> data = - Map.of("packname1", index1, "packname2", index2); + LinkedHashMap<String, PackIndex> data = new LinkedHashMap<>(2); + data.put("packname1", index1); + data.put("packname2", index2); MultiPackIndexWriter writer = new MultiPackIndexWriter(); ByteArrayOutputStream out = new ByteArrayOutputStream(); @@ -113,12 +117,14 @@ public void write_largeOffset() throws IOException { object("0000000000000000000000000000000000000002", 500), object("0000000000000000000000000000000000000004", 1500), object("0000000000000000000000000000000000000006", 3000)); - Map<String, PackIndex> data = - Map.of("packname1", index1, "packname2", index2); + LinkedHashMap<String, PackIndex> data = new LinkedHashMap<>(2); + data.put("bbbbbbbbb", index1); + data.put("aaaaaaaaa", index2); MultiPackIndexWriter writer = new MultiPackIndexWriter(); ByteArrayOutputStream out = new ByteArrayOutputStream(); - writer.write(NullProgressMonitor.INSTANCE, out, data); + MultiPackIndexWriter.Result result = writer + .write(NullProgressMonitor.INSTANCE, out, data); // header (12 bytes) // + chunkHeader (7 * 12 bytes) // + fanout table (256 * 4 bytes) @@ -137,13 +143,18 @@ public void write_largeOffset() throws IOException { assertEquals(3, chunkIds.indexOf(MIDX_CHUNKID_LARGEOFFSETS)); assertEquals(4, chunkIds.indexOf(MIDX_CHUNKID_REVINDEX)); assertEquals(5, chunkIds.indexOf(MIDX_CHUNKID_PACKNAMES)); + + assertEquals("bbbbbbbbb", result.packNames().get(0)); + assertEquals("aaaaaaaaa", result.packNames().get(1)); } @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); + LinkedHashMap<String, PackIndex> packs = new LinkedHashMap<>(2); + packs.put("p1", idxOne); + packs.put("p2", idxTwo); MultiPackIndexWriter writer = new MultiPackIndexWriter(); ByteArrayOutputStream out = new ByteArrayOutputStream(); writer.write(NullProgressMonitor.INSTANCE, out, packs);
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 8218cbc..0eafdaf 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
@@ -15,7 +15,7 @@ import java.util.Arrays; import java.util.Iterator; -import java.util.Map; +import java.util.LinkedHashMap; import org.eclipse.jgit.internal.storage.file.PackIndex; import org.eclipse.jgit.junit.FakeIndexFactory; @@ -39,7 +39,7 @@ public void rawIterator_noDuplicates() { oidOffset("0000000000000000000000000000000000000007", 14), oidOffset("0000000000000000000000000000000000000012", 1502)); PackIndexMerger merger = new PackIndexMerger( - Map.of("p1", idxOne, "p2", idxTwo, "p3", idxThree)); + orderedMapOf("p1", idxOne, "p2", idxTwo, "p3", idxThree)); assertEquals(9, merger.getUniqueObjectCount()); assertEquals(3, merger.getPackCount()); assertFalse(merger.needsLargeOffsetsChunk()); @@ -60,13 +60,48 @@ public void rawIterator_noDuplicates() { } @Test + public void rawIterator_noDuplicates_honorPackOrder() { + PackIndex idxOne = indexOf( + oidOffset("0000000000000000000000000000000000000001", 500), + oidOffset("0000000000000000000000000000000000000005", 12), + oidOffset("0000000000000000000000000000000000000010", 1500)); + PackIndex idxTwo = indexOf( + oidOffset("0000000000000000000000000000000000000002", 501), + oidOffset("0000000000000000000000000000000000000003", 13), + oidOffset("0000000000000000000000000000000000000015", 1501)); + PackIndex idxThree = indexOf( + oidOffset("0000000000000000000000000000000000000004", 502), + oidOffset("0000000000000000000000000000000000000007", 14), + oidOffset("0000000000000000000000000000000000000012", 1502)); + PackIndexMerger merger = new PackIndexMerger( + orderedMapOf("p3", idxThree, "p2", idxTwo, "p1", idxOne)); + assertEquals(9, merger.getUniqueObjectCount()); + assertEquals(3, merger.getPackCount()); + assertFalse(merger.needsLargeOffsetsChunk()); + Iterator<PackIndexMerger.MidxMutableEntry> it = merger.rawIterator(); + assertNextEntry(it, "0000000000000000000000000000000000000001", 2, 500); + assertNextEntry(it, "0000000000000000000000000000000000000002", 1, 501); + assertNextEntry(it, "0000000000000000000000000000000000000003", 1, 13); + assertNextEntry(it, "0000000000000000000000000000000000000004", 0, 502); + assertNextEntry(it, "0000000000000000000000000000000000000005", 2, 12); + assertNextEntry(it, "0000000000000000000000000000000000000007", 0, 14); + assertNextEntry(it, "0000000000000000000000000000000000000010", 2, + 1500); + assertNextEntry(it, "0000000000000000000000000000000000000012", 0, + 1502); + assertNextEntry(it, "0000000000000000000000000000000000000015", 1, + 1501); + assertFalse(it.hasNext()); + } + + @Test public void rawIterator_allDuplicates() { PackIndex idxOne = indexOf( oidOffset("0000000000000000000000000000000000000001", 500), oidOffset("0000000000000000000000000000000000000005", 12), oidOffset("0000000000000000000000000000000000000010", 1500)); PackIndexMerger merger = new PackIndexMerger( - Map.of("p1", idxOne, "p2", idxOne, "p3", idxOne)); + orderedMapOf("p1", idxOne, "p2", idxOne, "p3", idxOne)); assertEquals(3, merger.getUniqueObjectCount()); assertEquals(3, merger.getPackCount()); assertFalse(merger.needsLargeOffsetsChunk()); @@ -101,7 +136,7 @@ public void bySha1Iterator_noDuplicates() { oidOffset("0000000000000000000000000000000000000007", 14), oidOffset("0000000000000000000000000000000000000012", 1502)); PackIndexMerger merger = new PackIndexMerger( - Map.of("p1", idxOne, "p2", idxTwo, "p3", idxThree)); + orderedMapOf("p1", idxOne, "p2", idxTwo, "p3", idxThree)); assertEquals(9, merger.getUniqueObjectCount()); assertEquals(3, merger.getPackCount()); assertFalse(merger.needsLargeOffsetsChunk()); @@ -128,7 +163,7 @@ public void bySha1Iterator_allDuplicates() { oidOffset("0000000000000000000000000000000000000005", 12), oidOffset("0000000000000000000000000000000000000010", 1500)); PackIndexMerger merger = new PackIndexMerger( - Map.of("p1", idxOne, "p2", idxOne, "p3", idxOne)); + orderedMapOf("p1", idxOne, "p2", idxOne, "p3", idxOne)); assertEquals(3, merger.getUniqueObjectCount()); assertEquals(3, merger.getPackCount()); assertFalse(merger.needsLargeOffsetsChunk()); @@ -152,7 +187,7 @@ public void bySha1Iterator_differentIndexSizes() { oidOffset("0000000000000000000000000000000000000007", 12), oidOffset("0000000000000000000000000000000000000012", 1500)); PackIndexMerger merger = new PackIndexMerger( - Map.of("p1", idxOne, "p2", idxTwo, "p3", idxThree)); + orderedMapOf("p1", idxOne, "p2", idxTwo, "p3", idxThree)); assertEquals(6, merger.getUniqueObjectCount()); assertEquals(3, merger.getPackCount()); assertFalse(merger.needsLargeOffsetsChunk()); @@ -170,7 +205,7 @@ public void bySha1Iterator_differentIndexSizes() { @Test public void merger_noIndexes() { - PackIndexMerger merger = new PackIndexMerger(Map.of()); + PackIndexMerger merger = new PackIndexMerger(new LinkedHashMap<>()); assertEquals(0, merger.getUniqueObjectCount()); assertFalse(merger.needsLargeOffsetsChunk()); assertTrue(merger.getPackNames().isEmpty()); @@ -181,7 +216,7 @@ public void merger_noIndexes() { @Test public void merger_emptyIndexes() { PackIndexMerger merger = new PackIndexMerger( - Map.of("p1", indexOf(), "p2", indexOf())); + orderedMapOf("p1", indexOf(), "p2", indexOf())); assertEquals(0, merger.getUniqueObjectCount()); assertFalse(merger.needsLargeOffsetsChunk()); assertEquals(2, merger.getPackNames().size()); @@ -197,7 +232,7 @@ public void bySha1Iterator_largeOffsets_needsChunk() { PackIndex idx2 = indexOf(oidOffset( "0000000000000000000000000000000000000003", (1L << 31) + 10)); PackIndexMerger merger = new PackIndexMerger( - Map.of("p1", idx1, "p2", idx2)); + orderedMapOf("p1", idx1, "p2", idx2)); assertTrue(merger.needsLargeOffsetsChunk()); assertEquals(2, merger.getOffsetsOver31BitsCount()); assertEquals(3, merger.getUniqueObjectCount()); @@ -213,7 +248,7 @@ public void bySha1Iterator_largeOffsets_noChunk() { PackIndex idx2 = indexOf(oidOffset( "0000000000000000000000000000000000000003", (1L << 31) + 10)); PackIndexMerger merger = new PackIndexMerger( - Map.of("p1", idx1, "p2", idx2)); + orderedMapOf("p1", idx1, "p2", idx2)); assertFalse(merger.needsLargeOffsetsChunk()); assertEquals(2, merger.getOffsetsOver31BitsCount()); assertEquals(3, merger.getUniqueObjectCount()); @@ -236,4 +271,22 @@ private static IndexObject oidOffset(String oid, long offset) { private static PackIndex indexOf(IndexObject... objs) { return FakeIndexFactory.indexOf(Arrays.asList(objs)); } + + private static LinkedHashMap<String, PackIndex> orderedMapOf(String s1, + PackIndex pi1, String s2, PackIndex pi2) { + LinkedHashMap map = new LinkedHashMap(3); + map.put(s1, pi1); + map.put(s2, pi2); + return map; + } + + private static LinkedHashMap<String, PackIndex> orderedMapOf(String s1, + PackIndex pi1, String s2, PackIndex pi2, String s3, PackIndex pi3) { + LinkedHashMap map = new LinkedHashMap(3); + map.put(s1, pi1); + map.put(s2, pi2); + map.put(s3, pi3); + return map; + } + }
diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/lib/ConfigTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/lib/ConfigTest.java index 06fee8e..2d87226 100644 --- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/lib/ConfigTest.java +++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/lib/ConfigTest.java
@@ -1295,14 +1295,14 @@ public void testTimeUnitDefaultValue() throws ConfigInvalidException { // value is empty assertEquals(20, parse("[a]\na=\" \"\n").getTimeUnit("a", null, "a", 20, MILLISECONDS)); - - // value is not numeric - assertEquals(20, parse("[a]\na=test\n").getTimeUnit("a", null, "a", 20, - MILLISECONDS)); } @Test public void testTimeUnitInvalid() { + assertThrows("Invalid time unit value: a.a=test", + IllegalArgumentException.class, + () -> parseTime("test", MILLISECONDS)); + assertThrows("Invalid time unit value: a.a=1 monttthhh", IllegalArgumentException.class, () -> parseTime("1 monttthhh", DAYS));
diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/lib/DirCacheCheckoutTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/lib/DirCacheCheckoutTest.java index 0fafcd6..d64cfc5 100644 --- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/lib/DirCacheCheckoutTest.java +++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/lib/DirCacheCheckoutTest.java
@@ -58,6 +58,7 @@ import org.eclipse.jgit.util.FS; import org.eclipse.jgit.util.FileUtils; import org.eclipse.jgit.util.StringUtils; +import org.eclipse.jgit.util.SystemReader; import org.junit.Assume; import org.junit.Test; @@ -1982,7 +1983,20 @@ public void testFolderFileAndContentConflicts() throws Exception { @Test public void testLongFilename() throws Exception { - char[] bytes = new char[253]; + int maximumFileNameLength = 253; + String osName = SystemReader.getInstance().getProperty("os.name"); + if (osName != null) { + switch (osName) { + case "NONSTOP_KERNEL": + // Safely truncate file names to the maximum supported + // by the HPE NonStop OSS file system. + maximumFileNameLength = 248; + break; + default: + break; + } + } + char[] bytes = new char[maximumFileNameLength]; Arrays.fill(bytes, 'f'); String longFileName = new String(bytes); // 1
diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/transport/PushCertificateParserTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/transport/PushCertificateParserTest.java index 5db4563..118ce18 100644 --- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/transport/PushCertificateParserTest.java +++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/transport/PushCertificateParserTest.java
@@ -57,6 +57,7 @@ import java.io.InputStreamReader; import java.io.Reader; import java.io.StringReader; +import java.util.List; import org.eclipse.jgit.errors.PackProtocolException; import org.eclipse.jgit.internal.storage.dfs.DfsRepositoryDescription; @@ -364,6 +365,77 @@ public void testMissingPusheeField() throws Exception { assertFalse(cert.toText().contains(PushCertificateParser.PUSHEE)); } + @Test + public void testWithPushOptions() throws Exception { + // Same cert as INPUT, but with push-option lines added after nonce + String inputWithOptions = "001ccertificate version 0.1\n" + + "0041pusher Dave Borowitz <dborowitz@google.com> 1433954361 -0700\n" + + "0024pushee git://localhost/repo.git\n" + + "002anonce 1433954361-bde756572d665bba81d8\n" + + "0024push-option label=Code-Review+2\n" + + "0021push-option label=Verified+1\n" + + "0017push-option submit\n" + + "0020push-option hashtag=bug fix\n" + + "0005\n" + + "00680000000000000000000000000000000000000000" + + " 6c2b981a177396fb47345b7df3e4d3f854c6bea7" + + " refs/heads/master\n" + + "0022-----BEGIN PGP SIGNATURE-----\n" + + "0016Version: GnuPG v1\n" + + "0005\n" + + "0045iQEcBAABAgAGBQJVeGg5AAoJEPfTicJkUdPkUggH/RKAeI9/i/LduuiqrL/SSdIa\n" + + "00459tYaSqJKLbXz63M/AW4Sp+4u+dVCQvnAt/a35CVEnpZz6hN4Kn/tiswOWVJf4CO7\n" + + "0045htNubGs5ZMwvD6sLYqKAnrM3WxV/2TbbjzjZW6Jkidz3jz/WRT4SmjGYiEO7aA+V\n" + + "00454ZdIS9f7sW5VsHHYlNThCA7vH8Uu48bUovFXyQlPTX0pToSgrWV3JnTxDNxfn3iG\n" + + "0045IL0zTY/qwVCdXgFownLcs6J050xrrBWIKqfcWr3u4D2aCLyR0v+S/KArr7ulZygY\n" + + "0045+SOklImn8TAZiNxhWtA6ens66IiammUkZYFv7SSzoPLFZT4dC84SmGPWgf94NoQ=\n" + + "000a=XFeC\n" + + "0020-----END PGP SIGNATURE-----\n" + + "0012push-cert-end\n"; + + PacketLineIn pckIn = newPacketLineIn(inputWithOptions); + PushCertificateParser parser = + new PushCertificateParser(db, newEnabledConfig()); + parser.receiveHeader(pckIn, false); + + parser.addCommand(pckIn.readString()); + assertEquals(PushCertificateParser.BEGIN_SIGNATURE, pckIn.readString()); + parser.receiveSignature(pckIn); + + PushCertificate cert = parser.build(); + assertNotNull(cert); + assertEquals("0.1", cert.getVersion()); + assertEquals("Dave Borowitz", cert.getPusherIdent().getName()); + + // Verify push options were parsed and are available on the certificate + List<String> pushOptions = cert.getPushOptions(); + assertEquals(4, pushOptions.size()); + assertEquals("label=Code-Review+2", pushOptions.get(0)); + assertEquals("label=Verified+1", pushOptions.get(1)); + assertEquals("submit", pushOptions.get(2)); + assertEquals("hashtag=bug fix", pushOptions.get(3)); + + // Verify that toText() includes push options (critical for signature verification) + String text = cert.toText(); + assertTrue("toText() must include push-option lines", + text.contains("push-option label=Code-Review+2")); + assertTrue("toText() must include push-option lines", + text.contains("push-option label=Verified+1")); + assertTrue("toText() must include push-option lines", + text.contains("push-option submit")); + assertTrue("toText() must include push-option lines", + text.contains("push-option hashtag=bug fix")); + + // Verify push options appear after nonce and before empty line + int nonceIndex = text.indexOf("nonce"); + int pushOptionIndex = text.indexOf("push-option"); + int emptyLineIndex = text.indexOf("\n\n"); + assertTrue("push-option must appear after nonce", + pushOptionIndex > nonceIndex); + assertTrue("push-option must appear before empty line separator", + pushOptionIndex < emptyLineIndex); + } + private static String concatPacketLines(String input, int begin, int end) throws IOException { StringBuilder result = new StringBuilder();
diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/transport/ReceivePackTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/transport/ReceivePackTest.java index 156746d..595b970 100644 --- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/transport/ReceivePackTest.java +++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/transport/ReceivePackTest.java
@@ -45,8 +45,15 @@ import static org.junit.Assert.assertEquals; import static org.junit.Assert.fail; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.List; + import org.eclipse.jgit.errors.PackProtocolException; +import org.eclipse.jgit.internal.JGitText; import org.eclipse.jgit.lib.ObjectId; +import org.eclipse.jgit.transport.ReceiveCommand.Result; import org.junit.Test; /** Tests for receive-pack utilities. */ @@ -82,4 +89,62 @@ private void assertParseCommandFails(String input) { // Expected. } } + + @Test + public void testCertificatePushOptionsMismatch() throws Exception { + ReceiveCommand cmd1 = new ReceiveCommand( + ObjectId.fromString("0000000000000000000000000000000000000000"), + ObjectId.fromString("deadbeefdeadbeefdeadbeefdeadbeefdeadbeef"), + "refs/heads/master"); + ReceiveCommand cmd2 = new ReceiveCommand( + ObjectId.fromString("0000000000000000000000000000000000000000"), + ObjectId.fromString("badc0ffebadc0ffebadc0ffebadc0ffebadc0ffe"), + "refs/heads/branch"); + + List<ReceiveCommand> commands = new ArrayList<>(); + commands.add(cmd1); + commands.add(cmd2); + + ReceivePack.validateCertificatePushOptions( + Arrays.asList("option1", "option2"), + Arrays.asList("option1", "different"), commands); + + assertEquals(Result.REJECTED_OTHER_REASON, cmd1.getResult()); + assertEquals(Result.REJECTED_OTHER_REASON, cmd2.getResult()); + assertEquals(JGitText.get().pushCertificateInconsistentPushOptions, + cmd1.getMessage()); + assertEquals(JGitText.get().pushCertificateInconsistentPushOptions, + cmd2.getMessage()); + } + + @Test + public void testCertificatePushOptionsMatch() throws Exception { + ReceiveCommand cmd = new ReceiveCommand( + ObjectId.fromString("0000000000000000000000000000000000000000"), + ObjectId.fromString("deadbeefdeadbeefdeadbeefdeadbeefdeadbeef"), + "refs/heads/master"); + + List<ReceiveCommand> commands = Collections.singletonList(cmd); + + ReceivePack.validateCertificatePushOptions( + Arrays.asList("option1", "option2"), + Arrays.asList("option1", "option2"), commands); + + assertEquals(Result.NOT_ATTEMPTED, cmd.getResult()); + } + + @Test + public void testCertificatePushOptionsNullTreatedAsEmpty() throws Exception { + ReceiveCommand cmd = new ReceiveCommand( + ObjectId.fromString("0000000000000000000000000000000000000000"), + ObjectId.fromString("deadbeefdeadbeefdeadbeefdeadbeefdeadbeef"), + "refs/heads/master"); + + List<ReceiveCommand> commands = Collections.singletonList(cmd); + + ReceivePack.validateCertificatePushOptions(Collections.emptyList(), + null, commands); + + assertEquals(Result.NOT_ATTEMPTED, cmd.getResult()); + } }
diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/util/StringUtilsTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/util/StringUtilsTest.java index 9a1c710..3980cca 100644 --- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/util/StringUtilsTest.java +++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/util/StringUtilsTest.java
@@ -191,4 +191,22 @@ public void testTrim() { assertNull(StringUtils.trim(null, '/')); } + + @Test + public void testEscapeControls() { + assertEquals("", StringUtils.escapeControls(null)); + assertEquals("", StringUtils.escapeControls("")); + for (char c = 0; c < 256; c++) { + String test = "a" + c; + if (Character.isISOControl(c) && c != '\t' && c != '\n' + && c != '\r') { + assertEquals("Failed on " + ((int) c), + String.format("a\\u%04x", Integer.valueOf(c)), + StringUtils.escapeControls(test)); + } else { + assertEquals("Failed on " + ((int) c), test, + StringUtils.escapeControls(test)); + } + } + } }
diff --git a/org.eclipse.jgit.ui/META-INF/MANIFEST.MF b/org.eclipse.jgit.ui/META-INF/MANIFEST.MF index 498fa2a..9059d02 100644 --- a/org.eclipse.jgit.ui/META-INF/MANIFEST.MF +++ b/org.eclipse.jgit.ui/META-INF/MANIFEST.MF
@@ -4,15 +4,15 @@ Bundle-Name: %Bundle-Name Automatic-Module-Name: org.eclipse.jgit.ui Bundle-SymbolicName: org.eclipse.jgit.ui -Bundle-Version: 7.4.1.qualifier +Bundle-Version: 7.5.1.qualifier Bundle-Vendor: %Bundle-Vendor Bundle-RequiredExecutionEnvironment: JavaSE-17 Bundle-SCM: url=https://github.com/eclipse-jgit/jgit, connection=scm:git:https://eclipse.gerrithub.io/eclipse-jgit/jgit.git, developerConnection=scm:git:https://eclipse.gerrithub.io/a/eclipse-jgit/jgit.git -Export-Package: org.eclipse.jgit.awtui;version="7.4.1" -Import-Package: org.eclipse.jgit.errors;version="[7.4.1,7.5.0)", - org.eclipse.jgit.lib;version="[7.4.1,7.5.0)", - org.eclipse.jgit.nls;version="[7.4.1,7.5.0)", - org.eclipse.jgit.revplot;version="[7.4.1,7.5.0)", - org.eclipse.jgit.revwalk;version="[7.4.1,7.5.0)", - org.eclipse.jgit.transport;version="[7.4.1,7.5.0)", - org.eclipse.jgit.util;version="[7.4.1,7.5.0)" +Export-Package: org.eclipse.jgit.awtui;version="7.5.1" +Import-Package: org.eclipse.jgit.errors;version="[7.5.1,7.6.0)", + org.eclipse.jgit.lib;version="[7.5.1,7.6.0)", + org.eclipse.jgit.nls;version="[7.5.1,7.6.0)", + org.eclipse.jgit.revplot;version="[7.5.1,7.6.0)", + org.eclipse.jgit.revwalk;version="[7.5.1,7.6.0)", + org.eclipse.jgit.transport;version="[7.5.1,7.6.0)", + org.eclipse.jgit.util;version="[7.5.1,7.6.0)"
diff --git a/org.eclipse.jgit.ui/META-INF/SOURCE-MANIFEST.MF b/org.eclipse.jgit.ui/META-INF/SOURCE-MANIFEST.MF index 43332a0..5eedf45 100644 --- a/org.eclipse.jgit.ui/META-INF/SOURCE-MANIFEST.MF +++ b/org.eclipse.jgit.ui/META-INF/SOURCE-MANIFEST.MF
@@ -3,6 +3,6 @@ Bundle-Name: org.eclipse.jgit.ui - Sources Bundle-SymbolicName: org.eclipse.jgit.ui.source Bundle-Vendor: Eclipse.org - JGit -Bundle-Version: 7.4.1.qualifier +Bundle-Version: 7.5.1.qualifier Bundle-SCM: url=https://github.com/eclipse-jgit/jgit, connection=scm:git:https://eclipse.gerrithub.io/eclipse-jgit/jgit.git, developerConnection=scm:git:https://eclipse.gerrithub.io/a/eclipse-jgit/jgit.git -Eclipse-SourceBundle: org.eclipse.jgit.ui;version="7.4.1.qualifier";roots="." +Eclipse-SourceBundle: org.eclipse.jgit.ui;version="7.5.1.qualifier";roots="."
diff --git a/org.eclipse.jgit.ui/pom.xml b/org.eclipse.jgit.ui/pom.xml index 8fd243e..385b86f 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.4.1-SNAPSHOT</version> + <version>7.5.1-SNAPSHOT</version> </parent> <artifactId>org.eclipse.jgit.ui</artifactId>
diff --git a/org.eclipse.jgit/.settings/.api_filters b/org.eclipse.jgit/.settings/.api_filters index eeed75f..6a7d44a 100644 --- a/org.eclipse.jgit/.settings/.api_filters +++ b/org.eclipse.jgit/.settings/.api_filters
@@ -1,73 +1,26 @@ <?xml version="1.0" encoding="UTF-8" standalone="no"?> <component id="org.eclipse.jgit" version="2"> - <resource path="META-INF/MANIFEST.MF"> - <filter id="923795461"> + <resource path="src/org/eclipse/jgit/lib/CoreConfig.java" type="org.eclipse.jgit.lib.CoreConfig"> + <filter id="336658481"> <message_arguments> - <message_argument value="7.2.2"/> - <message_argument value="7.1.0"/> - </message_arguments> - </filter> - <filter id="934281281"> - <message_arguments> - <message_argument value="org.eclipse.jgit.lib"/> - <message_argument value="8.1.0"/> - <message_argument value="7.1.0"/> + <message_argument value="org.eclipse.jgit.lib.CoreConfig"/> + <message_argument value="DEFAULT_MULTIPACK_INDEX_ENABLE"/> </message_arguments> </filter> </resource> - <resource path="src/org/eclipse/jgit/lib/RefDatabase.java" type="org.eclipse.jgit.lib.RefDatabase"> - <filter id="336695337"> + <resource path="src/org/eclipse/jgit/revwalk/RevFlag.java" type="org.eclipse.jgit.revwalk.RevFlag"> + <filter id="336658481"> <message_arguments> - <message_argument value="org.eclipse.jgit.lib.RefDatabase"/> - <message_argument value="getReflogReader(Ref)"/> + <message_argument value="org.eclipse.jgit.revwalk.RevFlag"/> + <message_argument value="UNSHALLOW"/> </message_arguments> </filter> </resource> - <resource path="src/org/eclipse/jgit/lib/TypedConfigGetter.java" type="org.eclipse.jgit.lib.TypedConfigGetter"> - <filter id="403804204"> + <resource path="src/org/eclipse/jgit/transport/http/HttpConnection.java" type="org.eclipse.jgit.transport.http.HttpConnection"> + <filter id="403767336"> <message_arguments> - <message_argument value="org.eclipse.jgit.lib.TypedConfigGetter"/> - <message_argument value="getBoolean(Config, String, String, String, Boolean)"/> - </message_arguments> - </filter> - <filter id="403804204"> - <message_arguments> - <message_argument value="org.eclipse.jgit.lib.TypedConfigGetter"/> - <message_argument value="getInt(Config, String, String, String, Integer)"/> - </message_arguments> - </filter> - <filter id="403804204"> - <message_arguments> - <message_argument value="org.eclipse.jgit.lib.TypedConfigGetter"/> - <message_argument value="getIntInRange(Config, String, String, String, int, int, Integer)"/> - </message_arguments> - </filter> - <filter id="403804204"> - <message_arguments> - <message_argument value="org.eclipse.jgit.lib.TypedConfigGetter"/> - <message_argument value="getLong(Config, String, String, String, Long)"/> - </message_arguments> - </filter> - <filter id="403804204"> - <message_arguments> - <message_argument value="org.eclipse.jgit.lib.TypedConfigGetter"/> - <message_argument value="getTimeUnit(Config, String, String, String, Long, TimeUnit)"/> - </message_arguments> - </filter> - </resource> - <resource path="src/org/eclipse/jgit/revwalk/RevWalk.java" type="org.eclipse.jgit.revwalk.RevWalk"> - <filter id="1142947843"> - <message_arguments> - <message_argument value="6.10.1"/> - <message_argument value="isMergedIntoAnyCommit(RevCommit, Collection<RevCommit>)"/> - </message_arguments> - </filter> - </resource> - <resource path="src/org/eclipse/jgit/util/Iterators.java" type="org.eclipse.jgit.util.Iterators"> - <filter id="1109393411"> - <message_arguments> - <message_argument value="6.10.2"/> - <message_argument value="org.eclipse.jgit.util.Iterators"/> + <message_argument value="org.eclipse.jgit.transport.http.HttpConnection"/> + <message_argument value="HTTP_CREATED"/> </message_arguments> </filter> </resource>
diff --git a/org.eclipse.jgit/META-INF/MANIFEST.MF b/org.eclipse.jgit/META-INF/MANIFEST.MF index 839d46b..a7f899a 100644 --- a/org.eclipse.jgit/META-INF/MANIFEST.MF +++ b/org.eclipse.jgit/META-INF/MANIFEST.MF
@@ -3,7 +3,7 @@ Bundle-Name: %Bundle-Name Automatic-Module-Name: org.eclipse.jgit Bundle-SymbolicName: org.eclipse.jgit -Bundle-Version: 7.4.1.qualifier +Bundle-Version: 7.5.1.qualifier Bundle-Localization: OSGI-INF/l10n/plugin Bundle-Vendor: %Bundle-Vendor Bundle-ActivationPolicy: lazy @@ -11,8 +11,8 @@ Bundle-SCM: url=https://github.com/eclipse-jgit/jgit, connection=scm:git:https://eclipse.gerrithub.io/eclipse-jgit/jgit.git, developerConnection=scm:git:https://eclipse.gerrithub.io/a/eclipse-jgit/jgit.git Service-Component: OSGI-INF/org.eclipse.jgit.internal.util.CleanupService.xml Eclipse-ExtensibleAPI: true -Export-Package: org.eclipse.jgit.annotations;version="7.4.1", - org.eclipse.jgit.api;version="7.4.1"; +Export-Package: org.eclipse.jgit.annotations;version="7.5.1", + org.eclipse.jgit.api;version="7.5.1"; uses:="org.eclipse.jgit.transport, org.eclipse.jgit.notes, org.eclipse.jgit.dircache, @@ -27,21 +27,21 @@ org.eclipse.jgit.revwalk.filter, org.eclipse.jgit.blame, org.eclipse.jgit.merge", - org.eclipse.jgit.api.errors;version="7.4.1"; + org.eclipse.jgit.api.errors;version="7.5.1"; uses:="org.eclipse.jgit.lib, org.eclipse.jgit.errors", - org.eclipse.jgit.attributes;version="7.4.1"; + org.eclipse.jgit.attributes;version="7.5.1"; uses:="org.eclipse.jgit.lib, org.eclipse.jgit.treewalk", - org.eclipse.jgit.blame;version="7.4.1"; + org.eclipse.jgit.blame;version="7.5.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.4.1"; + org.eclipse.jgit.blame.cache;version="7.5.1"; uses:="org.eclipse.jgit.lib", - org.eclipse.jgit.diff;version="7.4.1"; + org.eclipse.jgit.diff;version="7.5.1"; uses:="org.eclipse.jgit.lib, org.eclipse.jgit.revwalk, org.eclipse.jgit.patch, @@ -49,55 +49,55 @@ org.eclipse.jgit.treewalk.filter, org.eclipse.jgit.treewalk, org.eclipse.jgit.util", - org.eclipse.jgit.dircache;version="7.4.1"; + org.eclipse.jgit.dircache;version="7.5.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.4.1"; + org.eclipse.jgit.errors;version="7.5.1"; uses:="org.eclipse.jgit.transport, org.eclipse.jgit.dircache, org.eclipse.jgit.lib", - org.eclipse.jgit.events;version="7.4.1"; + org.eclipse.jgit.events;version="7.5.1"; uses:="org.eclipse.jgit.lib", - org.eclipse.jgit.fnmatch;version="7.4.1", - org.eclipse.jgit.gitrepo;version="7.4.1"; + org.eclipse.jgit.fnmatch;version="7.5.1", + org.eclipse.jgit.gitrepo;version="7.5.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.4.1";x-internal:=true, - org.eclipse.jgit.hooks;version="7.4.1"; + org.eclipse.jgit.gitrepo.internal;version="7.5.1";x-internal:=true, + org.eclipse.jgit.hooks;version="7.5.1"; uses:="org.eclipse.jgit.lib, org.eclipse.jgit.util", - org.eclipse.jgit.ignore;version="7.4.1", - org.eclipse.jgit.ignore.internal;version="7.4.1"; + org.eclipse.jgit.ignore;version="7.5.1", + org.eclipse.jgit.ignore.internal;version="7.5.1"; x-friends:="org.eclipse.jgit.test", - org.eclipse.jgit.internal;version="7.4.1"; + org.eclipse.jgit.internal;version="7.5.1"; x-friends:="org.eclipse.jgit.test, org.eclipse.jgit.http.test", - org.eclipse.jgit.internal.diff;version="7.4.1"; + org.eclipse.jgit.internal.diff;version="7.5.1"; x-friends:="org.eclipse.jgit.test", - org.eclipse.jgit.internal.diffmergetool;version="7.4.1"; + org.eclipse.jgit.internal.diffmergetool;version="7.5.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.4.1"; + org.eclipse.jgit.internal.fsck;version="7.5.1"; x-friends:="org.eclipse.jgit.test", - org.eclipse.jgit.internal.revwalk;version="7.4.1"; + org.eclipse.jgit.internal.revwalk;version="7.5.1"; x-friends:="org.eclipse.jgit.test", - org.eclipse.jgit.internal.storage.commitgraph;version="7.4.1"; + org.eclipse.jgit.internal.storage.commitgraph;version="7.5.1"; x-friends:="org.eclipse.jgit.test", - org.eclipse.jgit.internal.storage.dfs;version="7.4.1"; + org.eclipse.jgit.internal.storage.dfs;version="7.5.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.4.1"; + org.eclipse.jgit.internal.storage.file;version="7.5.1"; x-friends:="org.eclipse.jgit.test, org.eclipse.jgit.junit, org.eclipse.jgit.junit.http, @@ -109,37 +109,39 @@ org.eclipse.jgit.ssh.apache, org.eclipse.jgit.ssh.apache.test, org.eclipse.jgit.ssh.jsch.test", - org.eclipse.jgit.internal.storage.io;version="7.4.1"; + org.eclipse.jgit.internal.storage.io;version="7.5.1"; x-friends:="org.eclipse.jgit.junit, org.eclipse.jgit.test, org.eclipse.jgit.pgm", - org.eclipse.jgit.internal.storage.memory;version="7.4.1"; + org.eclipse.jgit.internal.storage.memory;version="7.5.1"; x-friends:="org.eclipse.jgit.test", - org.eclipse.jgit.internal.storage.midx;version="7.4.1";x-internal:=true, - org.eclipse.jgit.internal.storage.pack;version="7.4.1"; + org.eclipse.jgit.internal.storage.midx;version="7.5.1"; + x-friends:="org.eclipse.jgit.pgm, + org.eclipse.jgit.test", + org.eclipse.jgit.internal.storage.pack;version="7.5.1"; x-friends:="org.eclipse.jgit.junit, org.eclipse.jgit.test, org.eclipse.jgit.pgm", - org.eclipse.jgit.internal.storage.reftable;version="7.4.1"; + org.eclipse.jgit.internal.storage.reftable;version="7.5.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.4.1";x-internal:=true, - org.eclipse.jgit.internal.transport.connectivity;version="7.4.1"; + org.eclipse.jgit.internal.submodule;version="7.5.1";x-internal:=true, + org.eclipse.jgit.internal.transport.connectivity;version="7.5.1"; x-friends:="org.eclipse.jgit.test", - org.eclipse.jgit.internal.transport.http;version="7.4.1"; + org.eclipse.jgit.internal.transport.http;version="7.5.1"; x-friends:="org.eclipse.jgit.test", - org.eclipse.jgit.internal.transport.parser;version="7.4.1"; + org.eclipse.jgit.internal.transport.parser;version="7.5.1"; x-friends:="org.eclipse.jgit.http.server, org.eclipse.jgit.test", - org.eclipse.jgit.internal.transport.ssh;version="7.4.1"; + org.eclipse.jgit.internal.transport.ssh;version="7.5.1"; x-friends:="org.eclipse.jgit.ssh.apache, org.eclipse.jgit.ssh.jsch, org.eclipse.jgit.test", - org.eclipse.jgit.internal.util;version="7.4.1"; + org.eclipse.jgit.internal.util;version="7.5.1"; x-friends:="org.eclipse.jgit.junit", - org.eclipse.jgit.lib;version="7.4.1"; + org.eclipse.jgit.lib;version="7.5.1"; uses:="org.eclipse.jgit.transport, org.eclipse.jgit.util.sha1, org.eclipse.jgit.dircache, @@ -154,12 +156,12 @@ org.eclipse.jgit.util, org.eclipse.jgit.submodule, org.eclipse.jgit.util.time", - org.eclipse.jgit.lib.internal;version="7.4.1"; + org.eclipse.jgit.lib.internal;version="7.5.1"; x-friends:="org.eclipse.jgit.test, org.eclipse.jgit.pgm, org.eclipse.egit.ui", - org.eclipse.jgit.logging;version="7.4.1", - org.eclipse.jgit.merge;version="7.4.1"; + org.eclipse.jgit.logging;version="7.5.1", + org.eclipse.jgit.merge;version="7.5.1"; uses:="org.eclipse.jgit.dircache, org.eclipse.jgit.lib, org.eclipse.jgit.revwalk, @@ -168,42 +170,42 @@ org.eclipse.jgit.util, org.eclipse.jgit.api, org.eclipse.jgit.attributes", - org.eclipse.jgit.nls;version="7.4.1", - org.eclipse.jgit.notes;version="7.4.1"; + org.eclipse.jgit.nls;version="7.5.1", + org.eclipse.jgit.notes;version="7.5.1"; uses:="org.eclipse.jgit.lib, org.eclipse.jgit.revwalk, org.eclipse.jgit.treewalk, org.eclipse.jgit.merge", - org.eclipse.jgit.patch;version="7.4.1"; + org.eclipse.jgit.patch;version="7.5.1"; uses:="org.eclipse.jgit.lib, org.eclipse.jgit.revwalk, org.eclipse.jgit.diff", - org.eclipse.jgit.revplot;version="7.4.1"; + org.eclipse.jgit.revplot;version="7.5.1"; uses:="org.eclipse.jgit.revwalk, org.eclipse.jgit.lib", - org.eclipse.jgit.revwalk;version="7.4.1"; + org.eclipse.jgit.revwalk;version="7.5.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.4.1"; + org.eclipse.jgit.revwalk.filter;version="7.5.1"; uses:="org.eclipse.jgit.revwalk, org.eclipse.jgit.lib, org.eclipse.jgit.util", - org.eclipse.jgit.storage.file;version="7.4.1"; + org.eclipse.jgit.storage.file;version="7.5.1"; uses:="org.eclipse.jgit.lib, org.eclipse.jgit.util", - org.eclipse.jgit.storage.pack;version="7.4.1"; + org.eclipse.jgit.storage.pack;version="7.5.1"; uses:="org.eclipse.jgit.lib", - org.eclipse.jgit.submodule;version="7.4.1"; + org.eclipse.jgit.submodule;version="7.5.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.4.1"; + org.eclipse.jgit.transport;version="7.5.1"; uses:="javax.crypto, org.eclipse.jgit.hooks, org.eclipse.jgit.util.io, @@ -216,21 +218,21 @@ org.eclipse.jgit.transport.resolver, org.eclipse.jgit.storage.pack, org.eclipse.jgit.errors", - org.eclipse.jgit.transport.http;version="7.4.1"; + org.eclipse.jgit.transport.http;version="7.5.1"; uses:="javax.net.ssl", - org.eclipse.jgit.transport.resolver;version="7.4.1"; + org.eclipse.jgit.transport.resolver;version="7.5.1"; uses:="org.eclipse.jgit.transport, org.eclipse.jgit.lib", - org.eclipse.jgit.treewalk;version="7.4.1"; + org.eclipse.jgit.treewalk;version="7.5.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.4.1"; + org.eclipse.jgit.treewalk.filter;version="7.5.1"; uses:="org.eclipse.jgit.treewalk", - org.eclipse.jgit.util;version="7.4.1"; + org.eclipse.jgit.util;version="7.5.1"; uses:="org.eclipse.jgit.transport, org.eclipse.jgit.hooks, org.eclipse.jgit.revwalk, @@ -243,12 +245,12 @@ org.eclipse.jgit.treewalk, javax.net.ssl, org.eclipse.jgit.util.time", - org.eclipse.jgit.util.io;version="7.4.1"; + org.eclipse.jgit.util.io;version="7.5.1"; uses:="org.eclipse.jgit.attributes, org.eclipse.jgit.lib, org.eclipse.jgit.treewalk", - org.eclipse.jgit.util.sha1;version="7.4.1", - org.eclipse.jgit.util.time;version="7.4.1" + org.eclipse.jgit.util.sha1;version="7.5.1", + org.eclipse.jgit.util.time;version="7.5.1" Import-Package: com.googlecode.javaewah;version="[1.1.6,2.0.0)", javax.crypto, javax.management,
diff --git a/org.eclipse.jgit/META-INF/SOURCE-MANIFEST.MF b/org.eclipse.jgit/META-INF/SOURCE-MANIFEST.MF index 7637f70..52c0cae 100644 --- a/org.eclipse.jgit/META-INF/SOURCE-MANIFEST.MF +++ b/org.eclipse.jgit/META-INF/SOURCE-MANIFEST.MF
@@ -3,6 +3,6 @@ Bundle-Name: org.eclipse.jgit - Sources Bundle-SymbolicName: org.eclipse.jgit.source Bundle-Vendor: Eclipse.org - JGit -Bundle-Version: 7.4.1.qualifier +Bundle-Version: 7.5.1.qualifier Bundle-SCM: url=https://github.com/eclipse-jgit/jgit, connection=scm:git:https://eclipse.gerrithub.io/eclipse-jgit/jgit.git, developerConnection=scm:git:https://eclipse.gerrithub.io/a/eclipse-jgit/jgit.git -Eclipse-SourceBundle: org.eclipse.jgit;version="7.4.1.qualifier";roots="." +Eclipse-SourceBundle: org.eclipse.jgit;version="7.5.1.qualifier";roots="."
diff --git a/org.eclipse.jgit/pom.xml b/org.eclipse.jgit/pom.xml index 286d41e..0e52b76 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.4.1-SNAPSHOT</version> + <version>7.5.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 dffb849..0d50360 100644 --- a/org.eclipse.jgit/resources/org/eclipse/jgit/internal/JGitText.properties +++ b/org.eclipse.jgit/resources/org/eclipse/jgit/internal/JGitText.properties
@@ -68,6 +68,7 @@ bitmapsMustBePrepared=Bitmaps must be prepared before they may be written. bitmapUseNoopNoListener=Use NOOP instance for no listener blameNotCommittedYet=Not Committed Yet +blameRegionCoverAllLines=Cached blame should cover all lines blockLimitNotMultipleOfBlockSize=blockLimit {0} must be a multiple of blockSize {1} blockLimitNotPositive=blockLimit must be positive: {0} blockSizeNotPowerOf2=blockSize must be a power of 2 @@ -639,6 +640,7 @@ pushCertificateInvalidFieldValue=Push certificate has missing or invalid value for {0}: {1} pushCertificateInvalidHeader=Push certificate has invalid header format pushCertificateInvalidSignature=Push certificate has invalid signature format +pushCertificateInconsistentPushOptions=Push certificate push options do not match command push options pushDefaultNothing=No refspec given and push.default=nothing; no upstream branch can be determined pushDefaultNoUpstream=No upstream branch found for local branch ''{0}'' pushDefaultSimple=push.default=simple requires local branch name ''{0}'' to be equal to upstream tracked branch name ''{1}''
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/blame/BlameRegionMerger.java b/org.eclipse.jgit/src/org/eclipse/jgit/blame/BlameRegionMerger.java index 67bc6fb..8ad50b5 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/blame/BlameRegionMerger.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/blame/BlameRegionMerger.java
@@ -15,6 +15,7 @@ import java.util.List; import org.eclipse.jgit.blame.cache.CacheRegion; +import org.eclipse.jgit.internal.JGitText; import org.eclipse.jgit.lib.ObjectId; import org.eclipse.jgit.lib.Repository; import org.eclipse.jgit.revwalk.RevCommit; @@ -72,8 +73,7 @@ Candidate mergeCandidate(Candidate candidate) { List<Candidate> mergeOneRegion(Region region) throws IOException { List<CacheRegion> overlaps = findOverlaps(region); if (overlaps.isEmpty()) { - throw new IOException( - "Cached blame should cover all lines"); + throw new IOException(JGitText.get().blameRegionCoverAllLines); } /* * Cached regions cover the whole file. We find first which ones overlap
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/ignore/FastIgnoreRule.java b/org.eclipse.jgit/src/org/eclipse/jgit/ignore/FastIgnoreRule.java index b041729..6e26999 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/ignore/FastIgnoreRule.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/ignore/FastIgnoreRule.java
@@ -1,5 +1,5 @@ /* - * Copyright (C) 2014, 2021 Andrey Loskutov <loskutov@gmx.de> and others + * Copyright (C) 2014, 2025 Andrey Loskutov <loskutov@gmx.de> and others * * This program and the accompanying materials are made available under the * terms of the Eclipse Distribution License v. 1.0 which is available at @@ -12,7 +12,6 @@ import static org.eclipse.jgit.ignore.IMatcher.NO_MATCH; import static org.eclipse.jgit.ignore.internal.Strings.isDirectoryPattern; import static org.eclipse.jgit.ignore.internal.Strings.stripTrailing; -import static org.eclipse.jgit.ignore.internal.Strings.stripTrailingWhitespace; import java.text.MessageFormat; @@ -72,7 +71,7 @@ void parse(String pattern) throws InvalidPatternException { if (pattern == null) { throw new IllegalArgumentException("Pattern must not be null!"); //$NON-NLS-1$ } - if (pattern.length() == 0) { + if (pattern.isEmpty() || pattern.charAt(0) == '#') { dirOnly = false; inverse = false; this.matcher = NO_MATCH; @@ -81,29 +80,19 @@ void parse(String pattern) throws InvalidPatternException { inverse = pattern.charAt(0) == '!'; if (inverse) { pattern = pattern.substring(1); - if (pattern.length() == 0) { + if (pattern.isEmpty() + || (pattern.length() == 1 && pattern.charAt(0) == '\\')) { dirOnly = false; this.matcher = NO_MATCH; return; } } - if (pattern.charAt(0) == '#') { - this.matcher = NO_MATCH; - dirOnly = false; - return; - } - if (pattern.charAt(0) == '\\' && pattern.length() > 1) { - char next = pattern.charAt(1); - if (next == '!' || next == '#') { - // remove backslash escaping first special characters - pattern = pattern.substring(1); - } - } dirOnly = isDirectoryPattern(pattern); if (dirOnly) { - pattern = stripTrailingWhitespace(pattern); + pattern = pattern.stripTrailing(); pattern = stripTrailing(pattern, PATH_SEPARATOR); - if (pattern.length() == 0) { + if (pattern.isEmpty() + || (pattern.length() == 1 && pattern.charAt(0) == '\\')) { this.matcher = NO_MATCH; return; }
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/ignore/internal/NameMatcher.java b/org.eclipse.jgit/src/org/eclipse/jgit/ignore/internal/NameMatcher.java index 4f8e149..9cf5505 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/ignore/internal/NameMatcher.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/ignore/internal/NameMatcher.java
@@ -1,5 +1,5 @@ /* - * Copyright (C) 2014, Andrey Loskutov <loskutov@gmx.de> and others + * Copyright (C) 2014, 2025 Andrey Loskutov <loskutov@gmx.de> and others * * This program and the accompanying materials are made available under the * terms of the Eclipse Distribution License v. 1.0 which is available at @@ -28,7 +28,7 @@ public class NameMatcher extends AbstractMatcher { super(pattern, dirOnly); slash = getPathSeparator(pathSeparator); if (deleteBackslash) { - pattern = Strings.deleteBackslash(pattern); + pattern = Strings.unescape(pattern); } beginning = pattern.length() == 0 ? false : pattern.charAt(0) == slash; if (!beginning) {
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/ignore/internal/PathMatcher.java b/org.eclipse.jgit/src/org/eclipse/jgit/ignore/internal/PathMatcher.java index a40568d..dc77687 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/ignore/internal/PathMatcher.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/ignore/internal/PathMatcher.java
@@ -1,5 +1,5 @@ /* - * Copyright (C) 2014, Andrey Loskutov <loskutov@gmx.de> and others + * Copyright (C) 2014, 2025 Andrey Loskutov <loskutov@gmx.de> and others * * This program and the accompanying materials are made available under the * terms of the Eclipse Distribution License v. 1.0 which is available at @@ -97,11 +97,17 @@ public static IMatcher createPathMatcher(String pattern, Character pathSeparator, boolean dirOnly) throws InvalidPatternException { pattern = trim(pattern); + if (isEscape(pattern, pattern.length() - 1) && !dirOnly) { + // Last character is a backslash that is an escape: never matches or + // produces an error. + return IMatcher.NO_MATCH; // Or throw an exception? + } char slash = Strings.getPathSeparator(pathSeparator); // ignore possible leading and trailing slash int slashIdx = pattern.indexOf(slash, 1); - if (slashIdx > 0 && slashIdx < pattern.length() - 1) + if (slashIdx > 0 && slashIdx < pattern.length() - 1) { return new PathMatcher(pattern, pathSeparator, dirOnly); + } return createNameMatcher0(pattern, pathSeparator, dirOnly, true); } @@ -114,18 +120,32 @@ public static IMatcher createPathMatcher(String pattern, * @return trimmed pattern */ private static String trim(String pattern) { - while (pattern.length() > 0 - && pattern.charAt(pattern.length() - 1) == ' ') { - if (pattern.length() > 1 - && pattern.charAt(pattern.length() - 2) == '\\') { - // last space was escaped by backslash: remove backslash and - // keep space - pattern = pattern.substring(0, pattern.length() - 2) + " "; //$NON-NLS-1$ - return pattern; - } - pattern = pattern.substring(0, pattern.length() - 1); + int i = pattern.length() - 1; + while (i >= 0 && pattern.charAt(i) == ' ') { + i--; } - return pattern; + if (i < 0) { + return ""; //$NON-NLS-1$ + } else if (i == pattern.length() - 1) { + // Last character was not a space. + return pattern; + } + // i is on the last non-space + if (isEscape(pattern, i)) { + // Last space was escaped by backslash: remove backslash and + // keep space + return pattern.substring(0, i) + ' '; + } + return pattern.substring(0, i + 1); + } + + private static boolean isEscape(String pattern, int from) { + // Count backslashes, if odd the last one is an escape + int i = from; + while (i >= 0 && pattern.charAt(i) == '\\') { + i--; + } + return ((from - i) & 1) != 0; } private static IMatcher createNameMatcher0(String segment,
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/ignore/internal/Strings.java b/org.eclipse.jgit/src/org/eclipse/jgit/ignore/internal/Strings.java index 3305a74..d048559 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/ignore/internal/Strings.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/ignore/internal/Strings.java
@@ -1,5 +1,5 @@ /* - * Copyright (C) 2014, 2017 Andrey Loskutov <loskutov@gmx.de> and others + * Copyright (C) 2014, 2025 Andrey Loskutov <loskutov@gmx.de> and others * * This program and the accompanying materials are made available under the * terms of the Eclipse Distribution License v. 1.0 which is available at @@ -56,26 +56,6 @@ public static String stripTrailing(String pattern, char c) { } /** - * Strip trailing whitespace characters - * - * @param pattern - * non null - * @return new string with all trailing whitespace removed - */ - public static String stripTrailingWhitespace(String pattern) { - for (int i = pattern.length() - 1; i >= 0; i--) { - char charAt = pattern.charAt(i); - if (!Character.isWhitespace(charAt)) { - if (i == pattern.length() - 1) { - return pattern; - } - return pattern.substring(0, i + 1); - } - } - return ""; //$NON-NLS-1$ - } - - /** * Check if pattern is a directory pattern ending with a path separator * * @param pattern @@ -153,8 +133,7 @@ static boolean isWildCard(String pattern) { } private static boolean isComplexWildcard(String pattern) { - int idx1 = pattern.indexOf('['); - if (idx1 != -1) { + if (pattern.indexOf('[') != -1) { return true; } if (pattern.indexOf('?') != -1) { @@ -169,30 +148,28 @@ private static boolean isComplexWildcard(String pattern) { return false; } char nextChar = pattern.charAt(nextIdx); - if (escapedByBackslash(nextChar)) { - return true; - } - return false; + // If the backslash _might_ escape a metacharacter, we have + // something complex + return nextChar == '?' || nextChar == '*' || nextChar == '['; } return false; } - private static boolean escapedByBackslash(char nextChar) { - return nextChar == '?' || nextChar == '*' || nextChar == '['; - } - static PatternState checkWildCards(String pattern) { - if (isComplexWildcard(pattern)) + if (isComplexWildcard(pattern)) { return PatternState.COMPLEX; + } int startIdx = pattern.indexOf('*'); - if (startIdx < 0) + if (startIdx < 0) { return PatternState.NONE; + } - if (startIdx == pattern.length() - 1) + if (startIdx == pattern.length() - 1) { return PatternState.TRAILING_ASTERISK_ONLY; - if (pattern.lastIndexOf('*') == 0) + } + if (pattern.lastIndexOf('*') == 0) { return PatternState.LEADING_ASTERISK_ONLY; - + } return PatternState.COMPLEX; } @@ -287,7 +264,7 @@ static Pattern convertGlob(String pattern) throws InvalidPatternException { break; case '.': - if (seenEscape) + if (seenEscape || in_brackets > 0) sb.append(c); else sb.append('\\').append('.'); @@ -305,7 +282,7 @@ static Pattern convertGlob(String pattern) throws InvalidPatternException { if (lookBehind(sb) == '[' && isLetter(lookAhead(pattern, i))) in_char_class = true; - sb.append(':'); + sb.append(c); break; case '-': @@ -315,22 +292,30 @@ && isLetter(lookAhead(pattern, i))) else sb.append(c); } else - sb.append('-'); + sb.append(c); break; case '\\': - if (in_brackets > 0) { - char lookAhead = lookAhead(pattern, i); - if (lookAhead == ']' || lookAhead == '[') - ignoreLastBracket = true; - } else { - // - char lookAhead = lookAhead(pattern, i); - if (lookAhead != '\\' && lookAhead != '[' - && lookAhead != '?' && lookAhead != '*' - && lookAhead != ' ' && lookBehind(sb) != '\\') { - break; - } + if (seenEscape) { + sb.append(c); + seenEscape = false; + continue; + } + if (i + 1 == pattern.length()) { + // Lone backslash at end of pattern is dropped. + break; + } + char lookAhead = lookAhead(pattern, i); + if (in_brackets > 0 && (lookAhead == ']' || lookAhead == '[')) { + ignoreLastBracket = true; + } + if (lookAhead == '0' || (lookAhead >= 'a' && lookAhead <= 'z') + || (lookAhead >= 'A' && lookAhead <= 'Z')) { + // Can be escaped in a glob pattern, but don't need to. + // Escaping these is invalid in a Java regexp. Glob patterns + // do not have the escaped constructs a Java regexp has + // (like \d, \Q, \x, or also \0). + break; } sb.append(c); break; @@ -473,28 +458,25 @@ private static String checkPosixCharClass(char[] buffer) { return null; } - static String deleteBackslash(String s) { + static String unescape(String s) { if (s.indexOf('\\') < 0) { return s; } - StringBuilder sb = new StringBuilder(s.length()); - for (int i = 0; i < s.length(); i++) { + int len = s.length(); + StringBuilder sb = new StringBuilder(len); + for (int i = 0; i < len; i++) { char ch = s.charAt(i); if (ch == '\\') { - if (i + 1 == s.length()) { - continue; + if (i + 1 < len) { + char next = s.charAt(i + 1); + if (next == '\\') { + sb.append(ch); + i++; + } } - char next = s.charAt(i + 1); - if (next == '\\') { - sb.append(ch); - i++; - continue; - } - if (!escapedByBackslash(next)) { - continue; - } + } else { + sb.append(ch); } - sb.append(ch); } return sb.toString(); }
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 10c2b29..9d2bb97 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/internal/JGitText.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/internal/JGitText.java
@@ -98,6 +98,7 @@ public static JGitText get() { /***/ public String bitmapsMustBePrepared; /***/ public String bitmapUseNoopNoListener; /***/ public String blameNotCommittedYet; + /***/ public String blameRegionCoverAllLines; /***/ public String blockLimitNotMultipleOfBlockSize; /***/ public String blockLimitNotPositive; /***/ public String blockSizeNotPowerOf2; @@ -670,6 +671,7 @@ public static JGitText get() { /***/ public String pushCertificateInvalidFieldValue; /***/ public String pushCertificateInvalidHeader; /***/ public String pushCertificateInvalidSignature; + /***/ public String pushCertificateInconsistentPushOptions; /***/ public String pushDefaultNothing; /***/ public String pushDefaultNoUpstream; /***/ public String pushDefaultSimple;
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/dfs/DfsBlock.java b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/dfs/DfsBlock.java index 16f80bc..8f2db71 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/dfs/DfsBlock.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/dfs/DfsBlock.java
@@ -21,7 +21,7 @@ import org.eclipse.jgit.internal.storage.pack.PackOutputStream; /** A cached slice of a {@link BlockBasedFile}. */ -final class DfsBlock { +sealed class DfsBlock permits DfsBlockMidx { final DfsStreamKey stream; final long start; final long end; @@ -34,6 +34,14 @@ final class DfsBlock { block = buf; } + protected DfsBlock(DfsBlock other) { + stream = other.stream; + start = other.start; + end = other.end; + // Subclass overrides methods using block + block = null; + } + int size() { return block.length; } @@ -53,7 +61,7 @@ int copy(long pos, byte[] dstbuf, int dstoff, int cnt) { return copy(ptr, dstbuf, dstoff, cnt); } - int copy(int p, byte[] b, int o, int n) { + private int copy(int p, byte[] b, int o, int n) { n = Math.min(block.length - p, n); System.arraycopy(block, p, b, o, n); return n;
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/dfs/DfsBlockMidx.java b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/dfs/DfsBlockMidx.java new file mode 100644 index 0000000..f3bdc17 --- /dev/null +++ b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/dfs/DfsBlockMidx.java
@@ -0,0 +1,86 @@ +/* + * 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 + * http://www.eclipse.org/org/documents/edl-v10.php. + * + * SPDX-License-Identifier: BSD-3-Clause + */ +package org.eclipse.jgit.internal.storage.dfs; + +import org.eclipse.jgit.internal.storage.pack.PackOutputStream; + +import java.io.IOException; +import java.nio.ByteBuffer; +import java.util.zip.CRC32; +import java.util.zip.DataFormatException; +import java.util.zip.Inflater; + +/** + * DfsBlock where offsets come from the multipack index + * <p> + * This is the DfsBlock returned by the multipack index. It wraps the block of + * the real file translating offsets from midx to pack. + */ +final class DfsBlockMidx extends DfsBlock { + private final DfsBlock src; + + private final long midxPackStart; + + /** + * Map midx offsets to a real pack block + * + * @param packBlock + * the real pack block + * @param midxPackStart + * midx offset where the pack (of this block) starts + */ + DfsBlockMidx(DfsBlock packBlock, long midxPackStart) { + // Use start/end/key from the pack block + super(packBlock); + this.src = packBlock; + this.midxPackStart = midxPackStart; + } + + @Override + int size() { + return src.size(); + } + + @Override + ByteBuffer zeroCopyByteBuffer(int n) { + return src.zeroCopyByteBuffer(n); + } + + @Override + boolean contains(DfsStreamKey want, long pos) { + return src.contains(want, pos - midxPackStart); + } + + @Override + int copy(long pos, byte[] dstbuf, int dstoff, int cnt) { + return src.copy(pos - midxPackStart, dstbuf, dstoff, cnt); + } + + @Override + int setInput(long pos, Inflater inf) throws DataFormatException { + return src.setInput(pos - midxPackStart, inf); + } + + @Override + void crc32(CRC32 out, long pos, int cnt) { + src.crc32(out, pos - midxPackStart, cnt); + } + + @Override + void write(PackOutputStream out, long pos, int cnt) throws IOException { + src.write(out, pos - midxPackStart, cnt); + } + + @Override + void check(Inflater inf, byte[] tmp, long pos, int cnt) + throws DataFormatException { + src.check(inf, tmp, pos - midxPackStart, cnt); + } +}
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/dfs/DfsGarbageCollector.java b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/dfs/DfsGarbageCollector.java index 199481c..d7c480d 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/dfs/DfsGarbageCollector.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/dfs/DfsGarbageCollector.java
@@ -25,6 +25,7 @@ import java.io.IOException; import java.time.Instant; +import java.util.ArrayDeque; import java.util.ArrayList; import java.util.Arrays; import java.util.Calendar; @@ -33,6 +34,7 @@ import java.util.GregorianCalendar; import java.util.HashSet; import java.util.List; +import java.util.Queue; import java.util.Set; import java.util.concurrent.TimeUnit; @@ -431,9 +433,10 @@ private Collection<Ref> getAllRefs() throws IOException { } private void readPacksBefore() throws IOException { - DfsPackFile[] packs = objdb.getPacks(); - packsBefore = new ArrayList<>(packs.length); - expiredGarbagePacks = new ArrayList<>(packs.length); + DfsPackFile[] rawPacks = objdb.getPacks(); + List<DfsPackFile> packs = getPlainPacks(rawPacks); + packsBefore = new ArrayList<>(packs.size()); + expiredGarbagePacks = new ArrayList<>(packs.size()); long now = SystemReader.getInstance().now().toEpochMilli(); for (DfsPackFile p : packs) { @@ -448,6 +451,24 @@ private void readPacksBefore() throws IOException { } } + private static List<DfsPackFile> getPlainPacks(DfsPackFile[] packs) { + List<DfsPackFile> plainPacks = new ArrayList<>(); + Queue<DfsPackFile> pending = new ArrayDeque<>( + Arrays.stream(packs).toList()); + while (!pending.isEmpty()) { + DfsPackFile pack = pending.poll(); + if (pack instanceof DfsPackFileMidx midxPack) { + plainPacks.addAll(midxPack.getCoveredPacks()); + if (midxPack.getMultipackIndexBase() != null) { + pending.add(midxPack.getMultipackIndexBase()); + } + } else { + plainPacks.add(pack); + } + } + return plainPacks; + } + private void readReftablesBefore() throws IOException { DfsReftable[] tables = objdb.getReftables(); reftablesBefore = new ArrayList<>(Arrays.asList(tables)); @@ -568,6 +589,7 @@ private Set<DfsPackDescription> toPrune() { for (DfsPackFile pack : expiredGarbagePacks) { toPrune.add(pack.getPackDescription()); } + return toPrune; }
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/dfs/DfsMidxWriter.java b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/dfs/DfsMidxWriter.java new file mode 100644 index 0000000..28ef98d --- /dev/null +++ b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/dfs/DfsMidxWriter.java
@@ -0,0 +1,87 @@ +/* + * 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.internal.storage.dfs; + +import static java.util.stream.Collectors.toList; +import static java.util.stream.Collectors.toMap; +import static org.eclipse.jgit.internal.storage.dfs.DfsObjDatabase.PackSource.GC; +import static org.eclipse.jgit.internal.storage.pack.PackExt.MULTI_PACK_INDEX; + +import java.io.IOException; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; +import java.util.function.Function; + +import org.eclipse.jgit.annotations.Nullable; +import org.eclipse.jgit.internal.storage.file.PackIndex; +import org.eclipse.jgit.internal.storage.midx.MultiPackIndexWriter; +import org.eclipse.jgit.lib.ProgressMonitor; + +/** + * Create a pack with a multipack index, setting the required fields in the + * description. + */ +public class DfsMidxWriter { + + private DfsMidxWriter() { + } + + /** + * Create a pack with the multipack index + * + * @param pm + * a progress monitor + * @param objdb + * an object database + * @param packs + * the packs to cover + * @param base + * parent of this midx in the chain (if any). + * @return a pack (uncommitted) with the multipack index of the packs passed + * as parameter. + * @throws IOException + * an error opening the packs or writing the stream. + */ + public static DfsPackDescription writeMidx(ProgressMonitor pm, + DfsObjDatabase objdb, List<DfsPackFile> packs, + @Nullable DfsPackDescription base) throws IOException { + LinkedHashMap<String, PackIndex> inputs = new LinkedHashMap<>( + packs.size()); + try (DfsReader ctx = objdb.newReader()) { + for (DfsPackFile pack : packs) { + inputs.put(pack.getPackDescription().getPackName(), + pack.getPackIndex(ctx)); + } + } + + DfsPackDescription midxPackDesc = objdb.newPack(GC); + try (DfsOutputStream out = objdb.writeFile(midxPackDesc, + MULTI_PACK_INDEX)) { + MultiPackIndexWriter w = new MultiPackIndexWriter(); + MultiPackIndexWriter.Result result = w.write(pm, out, inputs); + midxPackDesc.addFileExt(MULTI_PACK_INDEX); + midxPackDesc.setObjectCount(result.objectCount()); + + Map<String, DfsPackDescription> byName = packs.stream() + .map(DfsPackFile::getPackDescription) + .collect(toMap(DfsPackDescription::getPackName, + Function.identity())); + List<DfsPackDescription> coveredPacks = result.packNames().stream() + .map(byName::get).collect(toList()); + midxPackDesc.setCoveredPacks(coveredPacks); + if (base != null) { + midxPackDesc.setMultiPackIndexBase(base); + } + } + + return midxPackDesc; + } +}
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/dfs/DfsObjDatabase.java b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/dfs/DfsObjDatabase.java index 1a873d1..fc6596e 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/dfs/DfsObjDatabase.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/dfs/DfsObjDatabase.java
@@ -13,13 +13,14 @@ import static java.util.stream.Collectors.joining; import static org.eclipse.jgit.internal.storage.pack.PackExt.BITMAP_INDEX; import static org.eclipse.jgit.internal.storage.pack.PackExt.INDEX; +import static org.eclipse.jgit.internal.storage.pack.PackExt.MULTI_PACK_INDEX; +import static org.eclipse.jgit.internal.storage.pack.PackExt.REFTABLE; import java.io.FileNotFoundException; import java.io.IOException; import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; -import java.util.Collections; import java.util.Comparator; import java.util.HashMap; import java.util.HashSet; @@ -27,13 +28,15 @@ import java.util.Map; import java.util.Set; import java.util.concurrent.atomic.AtomicReference; +import java.util.stream.Collectors; import org.eclipse.jgit.internal.storage.file.BasePackIndexWriter; import org.eclipse.jgit.internal.storage.file.PackBitmapIndexWriterV1; -import org.eclipse.jgit.internal.storage.pack.PackIndexWriter; import org.eclipse.jgit.internal.storage.pack.PackBitmapIndexWriter; import org.eclipse.jgit.internal.storage.pack.PackExt; +import org.eclipse.jgit.internal.storage.pack.PackIndexWriter; import org.eclipse.jgit.lib.AnyObjectId; +import org.eclipse.jgit.lib.ConfigConstants; import org.eclipse.jgit.lib.ObjectDatabase; import org.eclipse.jgit.lib.ObjectInserter; import org.eclipse.jgit.lib.ObjectReader; @@ -198,6 +201,8 @@ public String toString() { private Comparator<DfsPackDescription> packComparator; + private boolean useMultipackIndex; + /** * Initialize an object database for our repository. * @@ -212,6 +217,9 @@ protected DfsObjDatabase(DfsRepository repository, this.packList = new AtomicReference<>(NO_PACKS); this.readerOptions = options; this.packComparator = DfsPackDescription.objectLookupComparator(); + this.useMultipackIndex = repository.getConfig().getBoolean( + ConfigConstants.CONFIG_CORE_SECTION, + ConfigConstants.CONFIG_KEY_MULTIPACKINDEX, false); } /** @@ -249,6 +257,28 @@ public ObjectInserter newInserter() { } /** + * Whether to use multipack indexes in the list of packs + * <p> + * This overrides the value in the core.multiPackIndex config key read at + * construction time. + * + * @param value + * value to set in the flag + */ + public void setUseMultipackIndex(boolean value) { + this.useMultipackIndex = value; + } + + /** + * Should this object db return multipack indexes + * + * @return current value of the flag + */ + protected boolean useMultipackIndex() { + return this.useMultipackIndex; + } + + /** * Scan and list all available pack files in the repository. * * @return list of available packs. The returned array is shared with the @@ -420,6 +450,9 @@ protected void commitPack(Collection<DfsPackDescription> desc, /** * Implementation of pack commit. + * <p> + * Implementations must take care to clean up midxs that become invalid when + * any of their covered packs is replaced. * * @see #commitPack(Collection, Collection) * @param desc @@ -455,6 +488,11 @@ protected abstract void commitPackImpl(Collection<DfsPackDescription> desc, * The returned list must support random access and must be mutable by the * caller. It is sorted in place using the natural sorting of the returned * DfsPackDescription objects. + * <p> + * With multipack index enabled, this method returns the descriptions of the + * multipack index(es) (which include descriptions of covered packs) and of + * packs not covered by the midxs. With multipack index disabled, it returns + * only regular packs (the midx is just ignored). * * @return available packs. May be empty if there are no packs. * @throws java.io.IOException @@ -578,11 +616,13 @@ private PackList scanPacksImpl(PackList old) throws IOException { Map<DfsPackDescription, DfsPackFile> packs = packMap(old); Map<DfsPackDescription, DfsReftable> reftables = reftableMap(old); - List<DfsPackDescription> scanned = listPacks(); - Collections.sort(scanned, packComparator); + List<DfsPackDescription> scanned = useMultipackIndex() + ? MidxPackFilter.useMidx(listPacks()) + : MidxPackFilter.skipMidxs(listPacks()); + scanned.sort(packComparator); List<DfsPackFile> newPacks = new ArrayList<>(scanned.size()); - List<DfsReftable> newReftables = new ArrayList<>(scanned.size()); + List<DfsPackDescription> packsWithReftables = new ArrayList<>(); boolean foundNew = false; for (DfsPackDescription dsc : scanned) { DfsPackFile oldPack = packs.remove(dsc); @@ -591,8 +631,20 @@ private PackList scanPacksImpl(PackList old) throws IOException { } else if (dsc.hasFileExt(PackExt.PACK)) { newPacks.add(createDfsPackFile(cache, dsc)); foundNew = true; + } else if (dsc.hasFileExt(MULTI_PACK_INDEX)) { + newPacks.add( + createDfsPackFileMidx(cache, dsc, packsWithReftables)); + foundNew = true; } + if (dsc.hasFileExt(REFTABLE)) { + packsWithReftables.add(dsc); + } + } + + List<DfsReftable> newReftables = new ArrayList<>( + packsWithReftables.size()); + for (DfsPackDescription dsc : packsWithReftables) { DfsReftable oldReftable = reftables.remove(dsc); if (oldReftable != null) { newReftables.add(oldReftable); @@ -607,7 +659,7 @@ private PackList scanPacksImpl(PackList old) throws IOException { if (!foundNew) { return old; } - Collections.sort(newReftables, reftableComparator()); + newReftables.sort(reftableComparator()); return new PackList( newPacks.toArray(new DfsPackFile[0]), newReftables.toArray(new DfsReftable[0])); @@ -615,7 +667,7 @@ private PackList scanPacksImpl(PackList old) throws IOException { /** * Create instances of DfsPackFile - * + * <p> * Implementors can decide to construct or wrap DfsPackFile in different * ways. * @@ -630,6 +682,38 @@ protected DfsPackFile createDfsPackFile(DfsBlockCache cache, return new DfsPackFile(cache, dsc); } + /** + * Create instances of DfsPackFileMidx + * + * @param cache + * block cache + * @param dsc + * pack description + * @param containsReftables + * used to return packs inside this midx that also have reftables + * + * @return the dfs packfile + */ + protected DfsPackFileMidx createDfsPackFileMidx(DfsBlockCache cache, + DfsPackDescription dsc, + List<DfsPackDescription> containsReftables) { + DfsPackFileMidx base = null; + if (dsc.getMultiPackIndexBase() != null) { + // The base is always a multipack index + base = createDfsPackFileMidx(cache, dsc.getMultiPackIndexBase(), + containsReftables); + } + // A pack shouldn't be in the pack list and inside a multipack index + // at the same time. In that case, we will have it under two + // different DfsPackFile instances. + List<DfsPackFile> coveredPacks = dsc.getCoveredPacks().stream() + .map(desc -> createDfsPackFile(cache, desc)) + .collect(Collectors.toUnmodifiableList()); + dsc.getCoveredPacks().stream().filter(d -> d.hasFileExt(REFTABLE)) + .forEach(containsReftables::add); + return DfsPackFileMidx.create(cache, dsc, coveredPacks, base); + } + private static Map<DfsPackDescription, DfsPackFile> packMap(PackList old) { Map<DfsPackDescription, DfsPackFile> forReuse = new HashMap<>(); for (DfsPackFile p : old.packs) {
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 6339b03..8860cce 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
@@ -11,7 +11,6 @@ package org.eclipse.jgit.internal.storage.dfs; import static org.eclipse.jgit.internal.storage.dfs.DfsObjDatabase.PackSource.COMPACT; -import static org.eclipse.jgit.internal.storage.dfs.DfsObjDatabase.PackSource.GC; import static org.eclipse.jgit.internal.storage.pack.PackExt.OBJECT_SIZE_INDEX; import static org.eclipse.jgit.internal.storage.pack.PackExt.PACK; import static org.eclipse.jgit.internal.storage.pack.PackExt.REFTABLE; @@ -68,10 +67,11 @@ public class DfsPackCompactor { private final List<DfsReftable> srcReftables; private final List<ObjectIdSet> exclude; + private final List<DfsPackDescription> prune; + private PackStatistics newStats; private DfsPackDescription outDesc; - private int autoAddSize; private ReftableConfig reftableConfig; private RevWalk rw; @@ -86,10 +86,10 @@ public class DfsPackCompactor { */ public DfsPackCompactor(DfsRepository repository) { repo = repository; - autoAddSize = 5 * 1024 * 1024; // 5 MiB srcPacks = new ArrayList<>(); srcReftables = new ArrayList<>(); exclude = new ArrayList<>(4); + prune = new ArrayList<>(); } /** @@ -135,38 +135,6 @@ public DfsPackCompactor add(DfsReftable table) { } /** - * Automatically select pack and reftables to be included, and add them. - * <p> - * Packs are selected based on size, smaller packs get included while bigger - * ones are omitted. - * - * @return {@code this} - * @throws java.io.IOException - * existing packs cannot be read. - */ - public DfsPackCompactor autoAdd() throws IOException { - DfsObjDatabase objdb = repo.getObjectDatabase(); - for (DfsPackFile pack : objdb.getPacks()) { - DfsPackDescription d = pack.getPackDescription(); - if (d.getFileSize(PACK) < autoAddSize) - add(pack); - else - exclude(pack); - } - - if (reftableConfig != null) { - for (DfsReftable table : objdb.getReftables()) { - DfsPackDescription d = table.getPackDescription(); - if (d.getPackSource() != GC - && d.getFileSize(REFTABLE) < autoAddSize) { - add(table); - } - } - } - return this; - } - - /** * Exclude objects from the compacted pack. * * @param set @@ -188,11 +156,23 @@ public DfsPackCompactor exclude(ObjectIdSet set) { * pack index cannot be loaded. */ public DfsPackCompactor exclude(DfsPackFile pack) throws IOException { - final PackIndex idx; + final ObjectIdSet objectIdSet; try (DfsReader ctx = (DfsReader) repo.newObjectReader()) { - idx = pack.getPackIndex(ctx); + objectIdSet = pack.asObjectIdSet(ctx); } - return exclude(idx); + return exclude(objectIdSet); + } + + /** + * Delete also this pack when writing to the db the compacted packs + * + * @param pack + * a pack to delete + * @return {@code this} + */ + public DfsPackCompactor prune(DfsPackFile pack) { + prune.add(pack.getPackDescription()); + return this; } /** @@ -367,6 +347,7 @@ private Collection<DfsPackDescription> toPrune() { Set<DfsPackDescription> toPrune = new HashSet<>(); toPrune.addAll(packs); toPrune.addAll(reftables); + toPrune.addAll(prune); return toPrune; }
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/dfs/DfsPackDescription.java b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/dfs/DfsPackDescription.java index 663190a..d4fe566 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/dfs/DfsPackDescription.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/dfs/DfsPackDescription.java
@@ -13,10 +13,14 @@ import static org.eclipse.jgit.internal.storage.pack.PackExt.PACK; import static org.eclipse.jgit.internal.storage.pack.PackExt.REFTABLE; +import java.util.ArrayList; import java.util.Arrays; +import java.util.Collections; import java.util.Comparator; +import java.util.List; import org.eclipse.jgit.annotations.NonNull; +import org.eclipse.jgit.annotations.Nullable; import org.eclipse.jgit.internal.storage.commitgraph.CommitGraphWriter; import org.eclipse.jgit.internal.storage.dfs.DfsObjDatabase.PackSource; import org.eclipse.jgit.internal.storage.pack.PackExt; @@ -150,6 +154,11 @@ static Comparator<DfsPackDescription> reuseComparator() { private int indexVersion; private long estimatedPackSize; + // Packs required by this pack (because it is e.g. a multipack index) + private List<? extends DfsPackDescription> coveredPacks = Collections.EMPTY_LIST; + + private DfsPackDescription multiPackIndexBase; + /** * Initialize a description by pack name and repository. * <p> @@ -210,6 +219,15 @@ public boolean hasFileExt(PackExt ext) { } /** + * The basic pack name (no extension) for this pack + * + * @return pack name + */ + public String getPackName() { + return packName; + } + + /** * Get file name * * @param ext @@ -527,6 +545,52 @@ public DfsPackDescription setIndexVersion(int version) { return this; } + /** + * Packs "included" in this pack (e.g because this is a multi-pack index) + * + * @return descriptions of the packs which are included in this one. Empty + * list if none. Never null. + */ + @NonNull + public List<DfsPackDescription> getCoveredPacks() { + return new ArrayList<>(coveredPacks); + } + + /** + * Set the list of packs required by this one (usually for multi-pack index) + * + * @param coveredPacks + * list of pack names without extension + */ + public void setCoveredPacks( + List<? extends DfsPackDescription> coveredPacks) { + if (coveredPacks == null) { + throw new IllegalStateException( + "Cannot set to null coveredPacks. Use empty list if needed."); //$NON-NLS-1$ + } + this.coveredPacks = coveredPacks; + } + + /** + * The base if this multipack index + * + * @return the base of this multipack index + */ + @Nullable + public DfsPackDescription getMultiPackIndexBase() { + return multiPackIndexBase; + } + + /** + * Set the base of this multipack index + * + * @param desc + * pack with the multipack index preceding this one + */ + public void setMultiPackIndexBase(DfsPackDescription desc) { + this.multiPackIndexBase = desc; + } + @Override public int hashCode() { return packName.hashCode();
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 05b63ea..ecc97e9 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
@@ -37,6 +37,7 @@ import java.util.zip.DataFormatException; import java.util.zip.Inflater; +import org.eclipse.jgit.annotations.NonNull; import org.eclipse.jgit.errors.CorruptObjectException; import org.eclipse.jgit.errors.LargeObjectException; import org.eclipse.jgit.errors.MissingObjectException; @@ -57,9 +58,11 @@ import org.eclipse.jgit.internal.storage.pack.StoredObjectRepresentation; import org.eclipse.jgit.lib.AbbreviatedObjectId; import org.eclipse.jgit.lib.AnyObjectId; +import org.eclipse.jgit.lib.BitmapIndex; import org.eclipse.jgit.lib.ConfigConstants; import org.eclipse.jgit.lib.Constants; import org.eclipse.jgit.lib.ObjectId; +import org.eclipse.jgit.lib.ObjectIdSet; import org.eclipse.jgit.lib.ObjectLoader; import org.eclipse.jgit.lib.Repository; import org.eclipse.jgit.lib.StoredConfig; @@ -71,12 +74,15 @@ * delta packed format yielding high compression of lots of object where some * objects are similar. */ -public final class DfsPackFile extends BlockBasedFile { +public sealed class DfsPackFile extends BlockBasedFile permits DfsPackFileMidx { private static final int REC_SIZE = Constants.OBJECT_ID_LENGTH + 8; private static final long REF_POSITION = 0; - private static final Comparator<DfsObjectToPack> OFFSET_SORT = ( + /** + * Order objects by offset + */ + protected static final Comparator<DfsObjectToPack> OFFSET_SORT = ( DfsObjectToPack a, DfsObjectToPack b) -> Long.signum(a.getOffset() - b.getOffset()); @@ -248,6 +254,22 @@ public PackIndex getPackIndex(DfsReader ctx) throws IOException { return idx(ctx); } + /** + * Get a view of this packfile as a set of objects + * <p> + * To use when the caller only needs to check inclusion (without specific + * order or getting offsets). + * + * @param ctx + * reader context + * @return a view of this packfile as a set of objects + * @throws IOException + * cannot load the backing data from storage + */ + public ObjectIdSet asObjectIdSet(DfsReader ctx) throws IOException { + return idx(ctx); + } + private PackIndex idx(DfsReader ctx) throws IOException { if (index != null) { return index; @@ -1201,6 +1223,34 @@ long getIndexedObjectSize(DfsReader ctx, int idxPosition) } /** + * Return pack(s) with all its objects included in the bitmap. + * <p> + * The bitmap is modified removing the objects in the returned packs. + * <p> + * The list could contain more than one pack in the multipack-index case. + * + * @param ctx + * a reader + * @param need + * bitmap with the required objects. It can be modified in this + * call. The objects from the returned packs are removed from the + * bitmap. + * @return list of packs with ALL their objects in the bitmap. + * @throws IOException + * error reading the bitmap index. + */ + @NonNull + List<DfsPackFile> fullyIncludedIn(DfsReader ctx, + BitmapIndex.BitmapBuilder need) throws IOException { + PackBitmapIndex bi = this.getBitmapIndex(ctx); + if (bi != null && need.removeAllOrNone(bi)) { + return Collections.singletonList(this); + } + + return Collections.emptyList(); + } + + /** * 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).
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/dfs/DfsPackFileMidx.java b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/dfs/DfsPackFileMidx.java new file mode 100644 index 0000000..742fe6c --- /dev/null +++ b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/dfs/DfsPackFileMidx.java
@@ -0,0 +1,610 @@ +/* + * 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.internal.storage.dfs; + +import static org.eclipse.jgit.internal.storage.pack.PackExt.MULTI_PACK_INDEX; +import static org.eclipse.jgit.internal.storage.pack.PackExt.PACK; + +import java.io.IOException; +import java.nio.channels.Channels; +import java.util.ArrayList; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.concurrent.atomic.AtomicReference; +import java.util.function.Function; +import java.util.stream.Collectors; +import java.util.zip.DataFormatException; + +import org.eclipse.jgit.annotations.Nullable; +import org.eclipse.jgit.errors.StoredObjectRepresentationNotAvailableException; +import org.eclipse.jgit.internal.storage.commitgraph.CommitGraph; +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.midx.MultiPackIndex; +import org.eclipse.jgit.internal.storage.midx.MultiPackIndex.PackOffset; +import org.eclipse.jgit.internal.storage.midx.MultiPackIndexLoader; +import org.eclipse.jgit.internal.storage.pack.ObjectToPack; +import org.eclipse.jgit.internal.storage.pack.PackOutputStream; +import org.eclipse.jgit.lib.AbbreviatedObjectId; +import org.eclipse.jgit.lib.AnyObjectId; +import org.eclipse.jgit.lib.BitmapIndex; +import org.eclipse.jgit.lib.ObjectId; +import org.eclipse.jgit.lib.ObjectIdSet; +import org.eclipse.jgit.lib.ObjectLoader; +import org.eclipse.jgit.util.BlockList; + +/** + * Implementation of a DfsPackfile that tries to solve the queries in a + * multipack index before resorting to the real packs. + * <p> + * It uses the position in the multipack index of the objects as their "offset". + */ +public final class DfsPackFileMidx extends DfsPackFile { + + private static final int REF_POSITION = 0; + + private final List<DfsPackFile> packs; + + // The required packs, in the order specified in the multipack index + // Initialized lazily, when the midx is loaded + private final DfsPackFile[] packsInIdOrder; + + private MultiPackIndex midx; + + private final DfsPackFileMidx base; + + private final VOffsetCalculator offsetCalculator; + + static DfsPackFileMidx create(DfsBlockCache cache, DfsPackDescription desc, + List<DfsPackFile> reqPacks, DfsPackFileMidx base) { + return new DfsPackFileMidx(cache, desc, reqPacks, base); + } + + private DfsPackFileMidx(DfsBlockCache cache, DfsPackDescription desc, + List<DfsPackFile> requiredPacks, @Nullable DfsPackFileMidx base) { + super(cache, desc); + this.base = base; + this.packs = requiredPacks; + String[] coveredPackNames = desc.getCoveredPacks().stream() + .map(DfsPackDescription::getPackName).toArray(String[]::new); + packsInIdOrder = getPacksInMidxIdOrder(coveredPackNames); + offsetCalculator = VOffsetCalculator.fromPacks(packsInIdOrder, + base != null ? base.getOffsetCalculator() : null); + this.length = offsetCalculator.getMaxOffset(); + } + + private MultiPackIndex midx(DfsReader ctx) throws IOException { + if (midx != null) { + return midx; + } + + DfsStreamKey revKey = desc.getStreamKey(MULTI_PACK_INDEX); + // Keep the value parsed in the loader, in case the Ref<> is + // nullified in ClockBlockCacheTable#reserveSpace + // before we read its value. + AtomicReference<MultiPackIndex> loadedRef = new AtomicReference<>(null); + DfsBlockCache.Ref<MultiPackIndex> cachedRef = cache.getOrLoadRef(revKey, + REF_POSITION, () -> { + RefWithSize midx1 = loadMultiPackIndex(ctx, desc); + loadedRef.set(midx1.idx); + return new DfsBlockCache.Ref<>(revKey, REF_POSITION, + midx1.size, midx1.idx); + }); + // if (loadedRef.get() == null) { + // ctx.stats.ridxCacheHit; + // } + midx = cachedRef.get() != null ? cachedRef.get() : loadedRef.get(); + return midx; + } + + private static RefWithSize loadMultiPackIndex(DfsReader ctx, + DfsPackDescription desc) throws IOException { + try (ReadableChannel rc = ctx.db.openFile(desc, MULTI_PACK_INDEX)) { + MultiPackIndex midx = MultiPackIndexLoader + .read(Channels.newInputStream(rc)); + // ctx.stats.readIdxBytes += rc.position(); + return new RefWithSize(midx, midx.getMemorySize()); + } + } + + private record RefWithSize(MultiPackIndex idx, long size) { + } + + private DfsPackFile[] getPacksInMidxIdOrder(String[] packNames) { + Map<String, DfsPackFile> byName = packs.stream() + .collect(Collectors.toUnmodifiableMap( + p -> p.getPackDescription().getPackName(), + Function.identity())); + DfsPackFile[] result = new DfsPackFile[desc.getCoveredPacks().size()]; + for (int i = 0; i < packNames.length; i++) { + DfsPackFile pack = byName.get(packNames[i]); + if (pack == null) { + // This should have been checked in the object db + // when the pack description was loaded + throw new IllegalStateException("Required pack missing"); //$NON-NLS-1$ + } + result[i] = pack; + } + return result; + } + + // Visible for testing + VOffsetCalculator getOffsetCalculator() { + return offsetCalculator; + } + + @Override + public PackIndex getPackIndex(DfsReader ctx) { + throw new IllegalStateException( + "Shouldn't use multipack index if the primary index is needed"); //$NON-NLS-1$ + } + + @Override + public ObjectIdSet asObjectIdSet(DfsReader ctx) throws IOException { + MultiPackIndex multiPackIndex = midx(ctx); + return objectId -> multiPackIndex.hasObject(objectId); + } + + @Override + public PackReverseIndex getReverseIdx(DfsReader ctx) { + throw new IllegalStateException( + "Shouldn't use multipack index if the reverse index is needed"); //$NON-NLS-1$ + } + + @Override + public PackBitmapIndex getBitmapIndex(DfsReader ctx) throws IOException { + // TODO(ifrade): at some point we will have bitmaps over the multipack + // index + // At the moment bitmap is in GC, at the end of the chain + if (base != null) { + return base.getBitmapIndex(ctx); + } + + for (DfsPackFile pack : packsInIdOrder) { + PackBitmapIndex bitmapIndex = pack.getBitmapIndex(ctx); + if (bitmapIndex != null) { + return bitmapIndex; + } + } + return null; + } + + @Override + List<DfsPackFile> fullyIncludedIn(DfsReader ctx, + BitmapIndex.BitmapBuilder need) throws IOException { + List<DfsPackFile> fullyIncluded = new ArrayList<>(); + for (DfsPackFile pack : packs) { + List<DfsPackFile> includedPacks = pack.fullyIncludedIn(ctx, need); + if (!includedPacks.isEmpty()) { + fullyIncluded.addAll(includedPacks); + } + } + + if (base != null) { + fullyIncluded.addAll(base.fullyIncludedIn(ctx, need)); + } + + return fullyIncluded; + } + + @Override + public CommitGraph getCommitGraph(DfsReader ctx) throws IOException { + for (DfsPackFile pack : packs) { + CommitGraph cg = pack.getCommitGraph(ctx); + if (cg != null) { + return cg; + } + } + return null; + } + + /** + * Count of objects in this <b>pack</> (i.e. including, recursively, its + * base) + * + * @param ctx + * a reader + * @return count of objects in this pack, including its bases + * @throws IOException + * an error reading a midx in the chain + */ + private int getObjectCount(DfsReader ctx) throws IOException { + int baseObjectCount = base == null ? 0 : base.getObjectCount(ctx); + return midx(ctx).getObjectCount() + baseObjectCount; + } + + /** + * Packs indexed by this multipack index (base NOT included) + * + * @return packs indexed by this multipack index + */ + public List<DfsPackFile> getCoveredPacks() { + return packs; + } + + /** + * All packs indexed by this multipack index and its chain + * <p> + * This does not include the inner multipack indexes themselves, only their + * covered packs. + * + * @return packs indexed by this multipack index and its parents. + */ + public List<DfsPackFile> getAllCoveredPacks() { + List<DfsPackFile> coveredPacks = new ArrayList<>(packs); + DfsPackFileMidx base = getMultipackIndexBase(); + while (base != null) { + coveredPacks.addAll(base.getCoveredPacks()); + base = base.getMultipackIndexBase(); + } + + return coveredPacks; + } + + /** + * Base of this multipack index + * <p> + * If this midx is part of a chain, this is its parent + * + * @return the base of this multipack index + */ + public DfsPackFileMidx getMultipackIndexBase() { + return base; + } + + @Override + public int findIdxPosition(DfsReader ctx, AnyObjectId id) + throws IOException { + int p = midx(ctx).findPosition(id); + if (p >= 0) { + int baseObjects = base == null ? 0 : base.getObjectCount(ctx); + return p + baseObjects; + } + + if (base == null) { + return -1; + } + + return base.findIdxPosition(ctx, id); + } + + @Override + public boolean hasObject(DfsReader ctx, AnyObjectId id) throws IOException { + if (midx(ctx).hasObject(id)) { + return true; + } + + if (base == null) { + return false; + } + + return base.hasObject(ctx, id); + } + + @Override + ObjectLoader get(DfsReader ctx, AnyObjectId id) throws IOException { + PackOffset location = midx(ctx).find(id); + if (location != null) { + return packsInIdOrder[location.getPackId()].get(ctx, id); + } + + if (base == null) { + return null; + } + + return base.get(ctx, id); + } + + @Override + ObjectLoader load(DfsReader ctx, long midxOffset) throws IOException { + DfsPackOffset location = offsetCalculator.decode(midxOffset); + if (location == null) { + return null; + } + return location.getPack().load(ctx, location.getPackOffset()); + } + + @Override + long findOffset(DfsReader ctx, AnyObjectId id) throws IOException { + PackOffset location = midx(ctx).find(id); + if (location != null) { + return offsetCalculator.encode(location); + } + + if (base == null) { + return -1; + } + + return base.findOffset(ctx, id); + } + + @Override + void resolve(DfsReader ctx, Set<ObjectId> matches, AbbreviatedObjectId id, + int matchLimit) throws IOException { + midx(ctx).resolve(matches, id, matchLimit); + if (matches.size() < matchLimit && base != null) { + base.resolve(ctx, matches, id, matchLimit); + } + } + + @Override + void copyPackAsIs(PackOutputStream out, DfsReader ctx) throws IOException { + // Assumming the order of the packs does not really matter + for (DfsPackFile pack : packs) { + pack.copyPackAsIs(out, ctx); + } + + if (base != null) { + base.copyPackAsIs(out, ctx); + } + } + + @Override + void copyAsIs(PackOutputStream out, DfsObjectToPack src, boolean validate, + DfsReader ctx) throws IOException, + StoredObjectRepresentationNotAvailableException { + if (src.pack != this) { + throw new IllegalArgumentException( + "pack mismatch in object description"); //$NON-NLS-1$ + } + + DfsPackOffset location = offsetCalculator.decode(src.offset); + // The real pack requires the real offset + src.offset = location.getPackOffset(); + location.getPack().copyAsIs(out, src, validate, ctx); + // Restore, just in case + src.offset = location.getPackStart() + location.getPackOffset(); + } + + @Override + byte[] getDeltaHeader(DfsReader ctx, long pos) + throws IOException, DataFormatException { + DfsPackOffset location = offsetCalculator.decode(pos); + return location.getPack().getDeltaHeader(ctx, location.getPackOffset()); + } + + @Override + int getObjectType(DfsReader ctx, long pos) throws IOException { + DfsPackOffset location = offsetCalculator.decode(pos); + return location.getPack().getObjectType(ctx, location.getPackOffset()); + } + + @Override + long getObjectSize(DfsReader ctx, AnyObjectId id) throws IOException { + PackOffset local = midx(ctx).find(id); + if (local != null) { + return packsInIdOrder[local.getPackId()].getObjectSize(ctx, id); + } + + if (base == null) { + return -1; + } + + return base.getObjectSize(ctx, id); + } + + @Override + long getObjectSize(DfsReader ctx, long pos) throws IOException { + if (pos < 0) { + return -1; + } + DfsPackOffset location = offsetCalculator.decode(pos); + return location.getPack().getObjectSize(ctx, location.getPackOffset()); + } + + @Override + boolean hasObjectSizeIndex(DfsReader ctx) { + return false; + } + + @Override + int getObjectSizeIndexThreshold(DfsReader ctx) { + return Integer.MAX_VALUE; + } + + @Override + long getIndexedObjectSize(DfsReader ctx, int idxPosition) { + // TODO(ifrade): if we forward to the pack, it reads its primary index + return -1; + } + + @Override + List<DfsObjectToPack> findAllFromPack(DfsReader ctx, + Iterable<ObjectToPack> objects, boolean skipFound) + throws IOException { + List<DfsObjectToPack> tmp = new BlockList<>(); + List<ObjectToPack> notFoundHere = new BlockList<>(); + for (ObjectToPack obj : objects) { + DfsObjectToPack otp = (DfsObjectToPack) obj; + if (skipFound && otp.isFound()) { + continue; + } + long p = offsetCalculator.encode(midx(ctx).find(otp)); + if (p < 0) { + notFoundHere.add(otp); + continue; + } + otp.setOffset(p); + tmp.add(otp); + } + + if (base != null && !notFoundHere.isEmpty()) { + List<DfsObjectToPack> inChain = base.findAllFromPack(ctx, + notFoundHere, skipFound); + tmp.addAll(inChain); + } + tmp.sort(OFFSET_SORT); + return tmp; + } + + @Override + void fillRepresentation(DfsObjectRepresentation r, long offset, + DfsReader ctx) throws IOException { + DfsPackOffset location = offsetCalculator.decode(offset); + if (location == null) { + throw new IllegalArgumentException("Invalid offset in midx"); //$NON-NLS-1$ + } + // This will load the reverse index. The multipack index removes + // duplicated objects, so next offset in midx is not necessarily the + // following object in pack. + location.getPack().fillRepresentation(r, location.getPackOffset(), ctx); + // We return *our* midx offset, not the one in the pack + r.offset = offset; + } + + @Override + void fillRepresentation(DfsObjectRepresentation r, long offset, + DfsReader ctx, PackReverseIndex rev) { + // This method shouldn't be called on the midx pack + throw new UnsupportedOperationException(); + } + + @Override + boolean isCorrupt(long offset) { + // The index must have been loaded before to have this offset + DfsPackOffset location = offsetCalculator.decode(offset); + if (location == null) { + throw new IllegalArgumentException("Invalid offset in midx"); //$NON-NLS-1$ + } + return location.getPack().isCorrupt(location.getPackOffset()); + } + + @Override + DfsBlock readOneBlock(long pos, DfsReader ctx, ReadableChannel rc) + throws IOException { + // The index must have been loaded before to have this offset + DfsPackOffset location = offsetCalculator.decode(pos); + return new DfsBlockMidx(location.getPack().readOneBlock( + location.getPackOffset(), ctx, rc), location.getPackStart()); + } + + @Override + DfsBlock getOrLoadBlock(long pos, DfsReader ctx) throws IOException { + // The index must have been loaded before to have this offset + DfsPackOffset location = offsetCalculator.decode(pos); + return new DfsBlockMidx(location.getPack().getOrLoadBlock( + location.getPackOffset(), ctx), location.getPackStart()); + } + + // Visible for testing + static class VOffsetCalculator { + private final DfsPackFile[] packs; + + private final long[] accSizes; + + private final long baseMaxOffset; + + private final VOffsetCalculator baseOffsetCalculator; + + private final DfsPackOffset poBuffer = new DfsPackOffset(); + + static VOffsetCalculator fromPacks(DfsPackFile[] packsInIdOrder, + VOffsetCalculator baseOffsetCalculator) { + long[] accSizes = new long[packsInIdOrder.length + 1]; + accSizes[0] = 0; + for (int i = 0; i < packsInIdOrder.length; i++) { + accSizes[i + 1] = accSizes[i] + packsInIdOrder[i] + .getPackDescription().getFileSize(PACK); + } + return new VOffsetCalculator(packsInIdOrder, accSizes, + baseOffsetCalculator); + } + + VOffsetCalculator(DfsPackFile[] packs, long[] packSizes, + VOffsetCalculator baseOffsetCalculator) { + this.packs = packs; + this.baseOffsetCalculator = baseOffsetCalculator; + this.baseMaxOffset = baseOffsetCalculator != null + ? baseOffsetCalculator.getMaxOffset() + : 0; + accSizes = packSizes; + } + + long encode(PackOffset location) { + if (location == null) { + return -1; + } + return location.getOffset() + accSizes[location.getPackId()] + + baseMaxOffset; + } + + DfsPackOffset decode(long voffset) { + if (voffset == -1) { + return null; + } + + if (voffset < baseMaxOffset) { + return baseOffsetCalculator.decode(voffset); + } + + long localOffset = voffset - baseMaxOffset; + for (int i = 0; i < accSizes.length; i++) { + if (localOffset <= accSizes[i]) { + return poBuffer.setValues(packs[i - 1], + accSizes[i - 1] + baseMaxOffset, voffset); + } + } + throw new IllegalArgumentException("Asking offset beyond limits"); //$NON-NLS-1$ + } + + long getMaxOffset() { + return accSizes[accSizes.length - 1] + baseMaxOffset; + } + } + + static class DfsPackOffset { + private DfsPackFile pack; + + private long packStart; + + private long offset; + + private DfsPackOffset setValues(DfsPackFile pack, long packStart, + long globalOffset) { + this.pack = pack; + this.packStart = packStart; + this.offset = globalOffset; + return this; + } + + /** + * The pack + * + * @return the pack + */ + DfsPackFile getPack() { + return pack; + } + + /** + * Where the pack starts in the total midx concat of packs + * <p> + * After loading a block, callers will use "midx-offsets" to refer to + * positions. We need this to bring the value to the block. + * + * @return offset where the pack starts, when all packs are concatenated + * in midx order. + */ + long getPackStart() { + return packStart; + } + + /** + * Offset inside the pack (regular offset) + * + * @return offset inside this pack + */ + long getPackOffset() { + return offset - packStart; + } + } +}
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 f50cd59..2272cc5 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
@@ -24,6 +24,7 @@ import java.util.List; import java.util.Optional; import java.util.Set; +import java.util.stream.Collectors; import java.util.zip.DataFormatException; import java.util.zip.Inflater; @@ -149,10 +150,12 @@ public Optional<CommitGraph> getCommitGraph() throws IOException { public Collection<CachedPack> getCachedPacksAndUpdate( BitmapBuilder needBitmap) throws IOException { for (DfsPackFile pack : db.getPacks()) { - PackBitmapIndex bitmapIndex = pack.getBitmapIndex(this); - if (needBitmap.removeAllOrNone(bitmapIndex)) - return Collections.<CachedPack> singletonList( - new DfsCachedPack(pack)); + // p != pack in the multipack index case + List<DfsPackFile> p = pack.fullyIncludedIn(this, needBitmap); + if (!p.isEmpty()) { + return p.stream().map(DfsCachedPack::new) + .collect(Collectors.toUnmodifiableList()); + } } return Collections.emptyList(); }
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/dfs/InMemoryRepository.java b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/dfs/InMemoryRepository.java index fe8dc17..b9c68f7 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/dfs/InMemoryRepository.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/dfs/InMemoryRepository.java
@@ -19,6 +19,7 @@ import java.util.List; import java.util.Set; import java.util.concurrent.atomic.AtomicInteger; +import java.util.stream.Collectors; import org.eclipse.jgit.annotations.Nullable; import org.eclipse.jgit.internal.storage.dfs.DfsObjDatabase.PackSource; @@ -153,8 +154,15 @@ protected synchronized void commitPackImpl( n = new ArrayList<>(desc.size() + packs.size()); n.addAll(desc); n.addAll(packs); - if (replace != null) + if (replace != null) { n.removeAll(replace); + MidxDescList midxs = MidxDescList.create(packs.stream() + .filter(p -> p.hasFileExt(PackExt.MULTI_PACK_INDEX)) + .collect(Collectors.toUnmodifiableList())); + Set<DfsPackDescription> affectedMidxs = midxs + .findAllCoveringMidxs(replace); + n.removeAll(affectedMidxs); + } packs = n; clearCache(); }
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/dfs/MidxDescList.java b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/dfs/MidxDescList.java new file mode 100644 index 0000000..8b0baf7 --- /dev/null +++ b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/dfs/MidxDescList.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.internal.storage.dfs; + +import static org.eclipse.jgit.internal.storage.pack.PackExt.MULTI_PACK_INDEX; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collection; +import java.util.Collections; +import java.util.HashSet; +import java.util.List; +import java.util.Set; + +/** + * Helper class for calculations over a list of pack descriptions + */ +public class MidxDescList { + /** + * Wrap the list of pack descriptions into a MidxDescList + * <p> + * The input list is well-formed, doesn't have duplicated packs/midxs. + * + * @param descs + * list of pack descriptions + * @return amidxDescList instance + */ + public static MidxDescList create(DfsPackDescription[] descs) { + return new MidxDescList(Arrays.asList(descs)); + } + + /** + * Wrap the packs list into amidxDescList + * <p> + * The input list is well-formed, doesn't have duplicated packs/midxs. + * + * @param descs + * list of pack descriptions + * @return amidxDescList instance + */ + public static MidxDescList create(List<DfsPackDescription> descs) { + return new MidxDescList(descs); + } + + private final List<DfsPackDescription> descs; + + private MidxDescList(List<DfsPackDescription> descs) { + this.descs = descs; + } + + /** + * Wrapper over {@link #findAllCoveringMidxs(Collection)} for the tests + * + * @param pack + * a single pack + * @return midxs containing the pack + */ + public Set<DfsPackDescription> findAllCoveringMidxs( + DfsPackDescription pack) { + return findAllCoveringMidxs(List.of(pack)); + } + + /** + * Return the union of midxs that cover the query packs (directly or + * indirectly). + * <p> + * An midx covers itself and its bases. + * + * @param queryPacks + * packs to be modified + * @return midxs covering any of the query packs + */ + public Set<DfsPackDescription> findAllCoveringMidxs( + Collection<DfsPackDescription> queryPacks) { + if (queryPacks.isEmpty()) { + return Collections.emptySet(); + } + + List<DfsPackDescription> knownMidxs = descs.stream() + .filter(dsc -> dsc.hasFileExt(MULTI_PACK_INDEX)).toList(); + + if (knownMidxs.isEmpty()) { + return Collections.emptySet(); + } + + // TODO(ifrade): Delete from queryPacks as we find them and stop if we + // are done + Set<DfsPackDescription> impactedMidxs = new HashSet<>(); + for (DfsPackDescription midx : knownMidxs) { + List<DfsPackDescription> visitedMidxs = new ArrayList<>(); + DfsPackDescription current = midx; + while (current != null) { + visitedMidxs.add(current); + if (queryPacks.contains(current) + || containsAny(current.getCoveredPacks(), queryPacks)) { + // Anything above in the chain is also covering this pack + impactedMidxs.addAll(visitedMidxs); + // Reset the list and keep going, maybe something + // deeper in the chain is also affected + visitedMidxs.clear(); + } + current = current.getMultiPackIndexBase(); + } + visitedMidxs.clear(); + } + + return impactedMidxs; + } + + private static boolean containsAny(List<DfsPackDescription> inMidx, + Collection<DfsPackDescription> queryPacks) { + Set<DfsPackDescription> inMidxSet = new HashSet<>(inMidx); + return queryPacks.stream().anyMatch(inMidxSet::contains); + } +}
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/dfs/MidxPackFilter.java b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/dfs/MidxPackFilter.java new file mode 100644 index 0000000..50de974 --- /dev/null +++ b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/dfs/MidxPackFilter.java
@@ -0,0 +1,98 @@ +/* + * 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.internal.storage.dfs; + +import org.eclipse.jgit.internal.storage.pack.PackExt; + +import java.util.HashSet; +import java.util.List; +import java.util.Set; +import java.util.stream.Collectors; + +/** + * Format a flat list of packs and midxs into a valid list of packs. + * <p> + * A valid list of packs is either: + * <ul> + * <li>A list with midxs and uncovered packs</li> + * <li>A list of packs (without any midx)</li> + * </ul> + */ +public class MidxPackFilter { + + private MidxPackFilter() { + } + + /** + * Reorganize the flat list of packs removing the midxs + * + * @param packs + * flat list of all packs in the repo, may include midx. Packs + * covered by the midx appear also on their own. + * @return a list of packs without midxs + */ + public static List<DfsPackDescription> skipMidxs( + List<DfsPackDescription> packs) { + // Covered packs appear also on their own in the list, so we can just + // take the midx out. + return packs.stream() + .filter(desc -> !desc.hasFileExt(PackExt.MULTI_PACK_INDEX)) + .collect(Collectors.toList()); + } + + /** + * Remove from the list any packs covered by midxs. + * <p> + * This verifies that all referenced packs by the midxs exist. + * + * @param packs + * list of packs with maybe some midxs + * @return midxs and uncovered packs. All the input packs if no midx. Ignore + * midxs with missing covered packs. + */ + public static List<DfsPackDescription> useMidx( + List<DfsPackDescription> packs) { + // Take the packs covered by the midxs out of the list + List<DfsPackDescription> midxs = packs.stream() + .filter(desc -> desc.hasFileExt(PackExt.MULTI_PACK_INDEX)) + .toList(); + if (midxs.isEmpty()) { + return packs; + } + + Set<DfsPackDescription> inputPacks = new HashSet<>(packs); + Set<DfsPackDescription> allCoveredPacks = new HashSet<>(); + for (DfsPackDescription midx : midxs) { + Set<DfsPackDescription> coveredPacks = new HashSet<>(); + findCoveredPacks(midx, coveredPacks); + if (!inputPacks.containsAll(coveredPacks)) { + // This midx references packs not in the pack db. + // It could be part of a chain, so we just ignore all midxs + return skipMidxs(packs); + } + allCoveredPacks.addAll(coveredPacks); + } + + return packs.stream().filter(d -> !allCoveredPacks.contains(d)) + .collect(Collectors.toList()); + } + + private static void findCoveredPacks(DfsPackDescription midx, + Set<DfsPackDescription> covered) { + if (!midx.getCoveredPacks().isEmpty()) { + covered.addAll(midx.getCoveredPacks()); + } + + if (midx.getMultiPackIndexBase() != null) { + findCoveredPacks(midx.getMultiPackIndexBase(), covered); + covered.add(midx.getMultiPackIndexBase()); + } + } +}
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/dfs/MidxPackList.java b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/dfs/MidxPackList.java new file mode 100644 index 0000000..f485725 --- /dev/null +++ b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/dfs/MidxPackList.java
@@ -0,0 +1,215 @@ +/* + * 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.internal.storage.dfs; + +import static org.eclipse.jgit.internal.storage.pack.PackExt.MULTI_PACK_INDEX; + +import java.util.ArrayDeque; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.Comparator; +import java.util.List; +import java.util.Optional; +import java.util.Queue; +import java.util.Set; +import java.util.TreeSet; + +import org.eclipse.jgit.annotations.Nullable; + +/** + * Helper class to manipulate a list of packs with (maybe) midxs. + **/ +public final class MidxPackList { + + private static final Comparator<DfsPackFile> PACK_NAME_COMPARATOR = Comparator + .comparing(pack -> pack.getPackDescription().getPackName()); + + /** + * Wrap the packs list into a MidxPackList + * <p> + * The input list is well-formed, doesn't have duplicated packs/midxs. + * + * @param packs + * list of packs (regular or tip midxs) + * @return a MidxPackList instance + */ + public static MidxPackList create(DfsPackFile[] packs) { + return new MidxPackList(packs); + } + + private final List<DfsPackFile> packs; + + private MidxPackList(DfsPackFile[] packs) { + this.packs = Arrays.asList(packs); + } + + /** + * Get all plain packs in the list, either top-level or inside midxs + * + * @return a list of all "real" packs in this pack list, either top level or + * inside midxs. + **/ + public List<DfsPackFile> getAllPlainPacks() { + List<DfsPackFile> plainPacks = new ArrayList<>(); + Queue<DfsPackFile> pending = new ArrayDeque<>(packs); + while (!pending.isEmpty()) { + DfsPackFile pack = pending.poll(); + if (pack instanceof DfsPackFileMidx midxPack) { + plainPacks.addAll(midxPack.getCoveredPacks()); + if (midxPack.getMultipackIndexBase() != null) { + pending.add(midxPack.getMultipackIndexBase()); + } + } else { + plainPacks.add(pack); + } + } + return plainPacks; + } + + /** + * Get all midx in the list, either top-level or inside other midxs + * + * @return a list of all midxs in thist list, either top level or nested + * inside other midxs. + **/ + public List<DfsPackFileMidx> getAllMidxPacks() { + List<DfsPackFileMidx> topLevelMidxs = packs.stream().filter( + p -> p.getPackDescription().hasFileExt(MULTI_PACK_INDEX)) + .map(p -> (DfsPackFileMidx) p).toList(); + + List<DfsPackFileMidx> midxPacks = new ArrayList<>(); + Queue<DfsPackFileMidx> pending = new ArrayDeque<>(topLevelMidxs); + while (!pending.isEmpty()) { + DfsPackFileMidx midx = pending.poll(); + midxPacks.add(midx); + if (midx.getMultipackIndexBase() != null) { + pending.add(midx.getMultipackIndexBase()); + } + } + return midxPacks; + } + + /** + * Alias for {@link #findAllCoveringMidxs(List)}, as convenience for tests + * + * @param pack + * a single pack + * @return all the midxs that include (directly or indirectly) the pack + */ + Set<DfsPackFileMidx> findAllCoveringMidxs(DfsPackFile pack) { + return findAllCoveringMidxs(List.of(pack)); + } + + /** + * Return all the midxs that cover (directoy or indirectly) a set of packs + * <p> + * In a chain like midx3(p6, p5) -> midx2(p4, p3) -> midx1(p2, p1), if we + * check for p3, midx3 and midx2 are covering it and midx1 is not. + * + * @param queryPacks + * subset of packs we are checking for coverage + * @return set of midxs from the packlist that should also be removed + */ + public Set<DfsPackFileMidx> findAllCoveringMidxs( + List<DfsPackFile> queryPacks) { + if (queryPacks.isEmpty()) { + return Collections.emptySet(); + } + + List<DfsPackFileMidx> topLevelMidxs = packs.stream().filter( + p -> p.getPackDescription().hasFileExt(MULTI_PACK_INDEX)) + .map(p -> (DfsPackFileMidx) p).toList(); + + if (topLevelMidxs.isEmpty()) { + return Collections.emptySet(); + } + + // TODO(ifrade): Delete from queryPacks as we find them and stop if we + // are done + Set<DfsPackFileMidx> impactedMidxs = asSet(List.of()); + for (DfsPackFileMidx midx : topLevelMidxs) { + List<DfsPackFileMidx> visitedMidxs = new ArrayList<>(); + DfsPackFileMidx current = midx; + while (current != null) { + visitedMidxs.add(current); + if (containsAny(current.getCoveredPacks(), queryPacks)) { + // Anything above in the chain is also covering this pack + impactedMidxs.addAll(visitedMidxs); + // Reset the list and keep going, maybe something + // deeper in the chain is also affected + visitedMidxs.clear(); + } + current = current.getMultipackIndexBase(); + } + visitedMidxs.clear(); + } + + return impactedMidxs; + } + + /** + * Return the top midx of the chain in the repo + * + * <p> + * In the unlikely case of multiple unconnected midxs, take the most recent. + * + * @return top midx + */ + public DfsPackFileMidx getTopMidxPack() { + List<DfsPackFileMidx> topLevelMidxs = packs.stream().filter( + p -> p.getPackDescription().hasFileExt(MULTI_PACK_INDEX)) + .map(p -> (DfsPackFileMidx) p).toList(); + if (topLevelMidxs.isEmpty()) { + return null; + } + + if (topLevelMidxs.size() == 1) { + return topLevelMidxs.get(0); + } + + Optional<DfsPackFileMidx> newest = topLevelMidxs.stream().max(Comparator + .comparingLong(p -> p.getPackDescription().getLastModified())); + return newest.orElse(null); + } + + /** + * Return all the plain packs not covered by this midx or its parents. + * + * @param midx + * a multipack index. Null midx returns all packs in db. + * @return all the packs in the db that are not covered by this midx or its + * parents. + */ + public List<DfsPackFile> getPlainPacksNotCoveredBy( + @Nullable DfsPackFileMidx midx) { + if (midx == null) { + return getAllPlainPacks(); + } + TreeSet<DfsPackFile> covered = asSet(midx.getAllCoveredPacks()); + // We cannot just take "all packs that are not midx" from the list + // because this midx could be the middle in a chain. + return getAllPlainPacks().stream().filter(p -> !covered.contains(p)) + .toList(); + } + + private static boolean containsAny(List<DfsPackFile> inMidx, + List<DfsPackFile> queryPacks) { + Set<DfsPackFile> inMidxSet = asSet(inMidx); + return queryPacks.stream().anyMatch(inMidxSet::contains); + } + + private static <T extends DfsPackFile> TreeSet<T> asSet( + List<T> initialValues) { + TreeSet<T> theSet = new TreeSet<>(PACK_NAME_COMPARATOR); + theSet.addAll(initialValues); + return theSet; + } +} \ No newline at end of file
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 64f8c9b..c46a17b 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
@@ -622,9 +622,7 @@ private static void writeConvertTable(Repository repo, ReftableWriter w, if (writeLogs) { for (Ref r : refs) { ReflogReader rlr = refDb.getReflogReader(r); - if (rlr != null) { - size = Math.max(rlr.getReverseEntries().size(), size); - } + size = Math.max(rlr.getReverseEntries().size(), size); } } // We must use 1 here, nextUpdateIndex() on the empty stack is 1.
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 5f2015b..01f9a07 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
@@ -189,7 +189,7 @@ private static PackExt getPackExt(String endsWithExtension) { return ext; } - if (endsWithExtension.equals("old-" + ext.getExtension())) { + if (endsWithExtension.equals("old-" + ext.getExtension())) { //$NON-NLS-1$ return ext; } }
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/PackObjectSizeIndexHelper.java b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/PackObjectSizeIndexHelper.java index acef741..07a9495 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/PackObjectSizeIndexHelper.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/PackObjectSizeIndexHelper.java
@@ -46,7 +46,7 @@ public static void forAllPacks(ObjectDirectory db, ProgressMonitor pm) List<PackedObjectInfo> objectsInPack = getObjectsInPack(wc, pack, pm); LOG.debug(String.format(" index has %d objects", //$NON-NLS-1$ - objectsInPack.size())); + Integer.valueOf(objectsInPack.size()))); if (objectsInPack.isEmpty()) { continue; } @@ -61,7 +61,7 @@ public static void forAllPacks(ObjectDirectory db, ProgressMonitor pm) writer.write(objectsInPack); } LOG.info(String.format(" done writing. Took %d ms", //$NON-NLS-1$ - System.currentTimeMillis() - start)); + Long.valueOf(System.currentTimeMillis() - start))); } }
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 index 61caddc..1d4f47a 100644 --- 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
@@ -112,7 +112,8 @@ public static MultiPackIndex read(InputStream fd) int v = hdr[4]; if (v != 1) { throw new MultiPackIndexFormatException(MessageFormat - .format(JGitText.get().unsupportedMIDXVersion, v)); + .format(JGitText.get().unsupportedMIDXVersion, + Integer.valueOf(v))); } // Read the object Id version (1 byte) @@ -325,7 +326,8 @@ private static void assertPackCounts(int headerCount, if (headerCount != packfileNamesCount) { throw new MultiPackIndexFormatException(MessageFormat.format( JGitText.get().multiPackIndexPackCountMismatch, - headerCount, packfileNamesCount)); + Integer.valueOf(headerCount), + Integer.valueOf(packfileNamesCount))); } } }
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 index e80958f..8ae1fe6 100644 --- 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
@@ -256,36 +256,44 @@ void resolve(Set<ObjectId> matches, AbbreviatedObjectId id, return; } - int high = fanoutTable[id.getFirstByte()]; - int low = id.getFirstByte() == 0 ? 0 - : fanoutTable[id.getFirstByte() - 1]; - do { - int p = (low + high) >>> 1; + int levelOne = id.getFirstByte(); + int high = fanoutTable[levelOne]; + int low = 0; + if (levelOne > 0) { + low = fanoutTable[levelOne - 1]; + } + + int p = -1; + boolean found = false; + while (low < high) { + p = (low + high) >>> 1; int cmp = id.prefixCompare(oidLookup, idOffset(p)); if (cmp < 0) { high = p; - continue; - } - - if (cmp > 0) { + } else if (cmp == 0) { + found = true; + break; + } else { 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++; - } + if (!found) { return; - } while (low < high); + } + + // 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++; + } } private int idOffset(int position) {
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 f236658..fd040b9 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
@@ -14,7 +14,6 @@ import java.util.List; import java.util.Map; import java.util.NoSuchElementException; -import java.util.stream.Collectors; import org.eclipse.jgit.internal.storage.file.PackIndex; import org.eclipse.jgit.lib.AnyObjectId; @@ -93,12 +92,17 @@ private void fill(int packId, PackIndex.MutableEntry other) { private final int uniqueObjectCount; + /** + * Build a common view of these pack indexes + * <p> + * Order matters: in case of duplicates, the first pack with the object wins + * + * @param packs + * map of pack names to indexes, ordered. + */ PackIndexMerger(Map<String, PackIndex> packs) { - this.packNames = packs.keySet().stream().sorted() - .collect(Collectors.toUnmodifiableList()); - - this.indexes = packNames.stream().map(packs::get) - .collect(Collectors.toUnmodifiableList()); + this.packNames = packs.keySet().stream().toList(); + this.indexes = packs.values().stream().toList(); // Iterate for duplicates int objectCount = 0; @@ -252,7 +256,7 @@ public MidxMutableEntry next() { mutableEntry.fill(winner.getPackId(), winner.peek()); if (winner.next() == null) { indexIterators.remove(winner); - }; + } return mutableEntry; } }
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/lib/ConfigConstants.java b/org.eclipse.jgit/src/org/eclipse/jgit/lib/ConfigConstants.java index c455032..56b801e 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/lib/ConfigConstants.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/lib/ConfigConstants.java
@@ -1115,4 +1115,11 @@ public final class ConfigConstants { * @since 7.2 */ public static final String CONFIG_KEY_AUTOREFRESH = "autorefresh"; + + /** + * The "multiPackIndex" key + * + * @since 7.5 + */ + public static final String CONFIG_KEY_MULTIPACKINDEX = "multiPackIndex"; }
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/lib/CoreConfig.java b/org.eclipse.jgit/src/org/eclipse/jgit/lib/CoreConfig.java index 0e27b27..1c6be07 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/lib/CoreConfig.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/lib/CoreConfig.java
@@ -128,6 +128,13 @@ public enum LogRefUpdates { public static final boolean DEFAULT_COMMIT_GRAPH_ENABLE = false; /** + * Default value of multipack index enable option: {@value} + * + * @since 7.5 + */ + public static final boolean DEFAULT_MULTIPACK_INDEX_ENABLE = false; + + /** * Permissible values for {@code core.trustPackedRefsStat}. * * @since 6.1.1 @@ -205,6 +212,8 @@ public enum TrustStat { private final boolean commitGraph; + private final boolean multiPackIndex; + private final TrustStat trustStat; private final TrustStat trustPackedRefsStat; @@ -264,6 +273,9 @@ public enum HideDotFiles { commitGraph = rc.getBoolean(ConfigConstants.CONFIG_CORE_SECTION, ConfigConstants.CONFIG_COMMIT_GRAPH, DEFAULT_COMMIT_GRAPH_ENABLE); + multiPackIndex = rc.getBoolean(ConfigConstants.CONFIG_CORE_SECTION, + ConfigConstants.CONFIG_KEY_MULTIPACKINDEX, + DEFAULT_MULTIPACK_INDEX_ENABLE); trustStat = parseTrustStat(rc); trustPackedRefsStat = parseTrustPackedRefsStat(rc); @@ -378,6 +390,19 @@ public boolean enableCommitGraph() { } /** + * Whether to read the multipack index file (if it exists). Default to + * {@value org.eclipse.jgit.lib.CoreConfig#DEFAULT_MULTIPACK_INDEX_ENABLE}. + * + * @return whether to use the multipack index in the repo. If false, just + * ignore the multipack index. + * + * @since 7.5 + */ + public boolean useMultiPackIndex() { + return multiPackIndex; + } + + /** * Get how far we can trust file attributes of packed-refs file which is * used to store {@link org.eclipse.jgit.lib.Ref}s in * {@link org.eclipse.jgit.internal.storage.file.RefDirectory}.
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/lib/DefaultTypedConfigGetter.java b/org.eclipse.jgit/src/org/eclipse/jgit/lib/DefaultTypedConfigGetter.java index 3059f28..588c102 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/lib/DefaultTypedConfigGetter.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/lib/DefaultTypedConfigGetter.java
@@ -32,7 +32,7 @@ */ public class DefaultTypedConfigGetter implements TypedConfigGetter { - @SuppressWarnings("boxed") + @SuppressWarnings({ "boxed", "boxing" }) @Override public boolean getBoolean(Config config, String section, String subsection, String name, boolean defaultValue) { @@ -115,6 +115,7 @@ public <T extends Enum<?>> T getEnum(Config config, T[] all, String section, JGitText.get().enumValueNotSupported2, section, name, value)); } + @SuppressWarnings("boxing") @Override public int getInt(Config config, String section, String subsection, String name, int defaultValue) { @@ -144,6 +145,7 @@ public Integer getInt(Config config, String section, String subsection, .format(JGitText.get().integerValueOutOfRange, section, name)); } + @SuppressWarnings("boxing") @Override public int getIntInRange(Config config, String section, String subsection, String name, int minValue, int maxValue, int defaultValue) { @@ -173,6 +175,7 @@ public Integer getIntInRange(Config config, String section, subsection, name, val, minValue, maxValue)); } + @SuppressWarnings("boxing") @Override public long getLong(Config config, String section, String subsection, String name, long defaultValue) { @@ -201,6 +204,7 @@ public Long getLong(Config config, String section, String subsection, } } + @SuppressWarnings("boxing") @Override public long getTimeUnit(Config config, String section, String subsection, String name, long defaultValue, TimeUnit wantUnit) { @@ -227,9 +231,9 @@ public Long getTimeUnit(Config config, String section, String subsection, } Matcher m = Pattern.compile("^(0|[1-9][0-9]*)\\s*(.*)$") //$NON-NLS-1$ - .matcher(valueString); + .matcher(s); if (!m.matches()) { - return defaultValue; + throw notTimeUnit(section, subsection, name, valueString); } String digits = m.group(1);
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/lib/TypedConfigGetter.java b/org.eclipse.jgit/src/org/eclipse/jgit/lib/TypedConfigGetter.java index 3d4e0d1..dfdba13 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/lib/TypedConfigGetter.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/lib/TypedConfigGetter.java
@@ -264,6 +264,8 @@ Long getLong(Config config, String section, String subsection, String name, * indication of the units. * @return the value, or {@code defaultValue} if not set, expressed in * {@code units}. + * @throws IllegalArgumentException + * if the value cannot be parsed. * @deprecated use * {@link #getTimeUnit(Config, String, String, String, Long, TimeUnit)} * instead @@ -292,6 +294,8 @@ long getTimeUnit(Config config, String section, String subsection, * indication of the units. * @return the value, or {@code defaultValue} if not set, expressed in * {@code units}. + * @throws IllegalArgumentException + * if the value cannot be parsed. * @since 7.2 */ @Nullable
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/BoundaryGenerator.java b/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/BoundaryGenerator.java index bdf63ff..ed78047 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/BoundaryGenerator.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/BoundaryGenerator.java
@@ -16,6 +16,8 @@ import org.eclipse.jgit.errors.IncorrectObjectTypeException; import org.eclipse.jgit.errors.MissingObjectException; +import static org.eclipse.jgit.revwalk.RevFlag.UNSHALLOW; + class BoundaryGenerator extends Generator { static final int UNINTERESTING = RevWalk.UNINTERESTING; @@ -82,7 +84,7 @@ RevCommit next() throws MissingObjectException, break; } RevCommit p = c.getParent(i); - if ((p.flags & UNINTERESTING) != 0) { + if ((p.flags & UNINTERESTING) != 0 && !p.has(UNSHALLOW)) { held.add(p); } }
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/DepthGenerator.java b/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/DepthGenerator.java index 664f8fa..3fabbc2 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/DepthGenerator.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/DepthGenerator.java
@@ -17,6 +17,8 @@ import org.eclipse.jgit.errors.MissingObjectException; import org.eclipse.jgit.lib.ObjectId; +import static org.eclipse.jgit.revwalk.RevFlag.UNSHALLOW; + /** * Only produce commits which are below a specified depth. * @@ -32,14 +34,6 @@ class DepthGenerator extends Generator { private final RevWalk walk; /** - * Commits which used to be shallow in the client, but which are - * being extended as part of this fetch. These commits should be - * returned to the caller as UNINTERESTING so that their blobs/trees - * can be marked appropriately in the pack writer. - */ - private final RevFlag UNSHALLOW; - - /** * Commits which the normal framework has marked as UNINTERESTING, * but which we now care about again. This happens if a client is * extending a shallow checkout to become deeper--the new commits at @@ -73,7 +67,6 @@ class DepthGenerator extends Generator { this.depth = w.getDepth(); this.deepenSince = w.getDeepenSince(); - this.UNSHALLOW = w.getUnshallowFlag(); this.REINTERESTING = w.getReinterestingFlag(); this.DEEPEN_NOT = w.getDeepenNotFlag();
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/DepthWalk.java b/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/DepthWalk.java index a7ffd34..7795ce2 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/DepthWalk.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/DepthWalk.java
@@ -64,7 +64,9 @@ default List<ObjectId> getDeepenNots() { * Get flag marking commits that should become unshallow. * * @return flag marking commits that should become unshallow. + * @deprecated use {@link RevFlag#UNSHALLOW} instead */ + @Deprecated(forRemoval = true, since = "7.5") RevFlag getUnshallowFlag(); /** @@ -136,8 +138,6 @@ public class RevWalk extends org.eclipse.jgit.revwalk.RevWalk implements DepthWa private List<ObjectId> deepenNots; - private final RevFlag UNSHALLOW; - private final RevFlag REINTERESTING; private final RevFlag DEEPEN_NOT; @@ -155,7 +155,6 @@ public RevWalk(Repository repo, int depth) { this.depth = depth; this.deepenNots = Collections.emptyList(); - this.UNSHALLOW = newFlag("UNSHALLOW"); //$NON-NLS-1$ this.REINTERESTING = newFlag("REINTERESTING"); //$NON-NLS-1$ this.DEEPEN_NOT = newFlag("DEEPEN_NOT"); //$NON-NLS-1$ } @@ -173,7 +172,6 @@ public RevWalk(ObjectReader or, int depth) { this.depth = depth; this.deepenNots = Collections.emptyList(); - this.UNSHALLOW = newFlag("UNSHALLOW"); //$NON-NLS-1$ this.REINTERESTING = newFlag("REINTERESTING"); //$NON-NLS-1$ this.DEEPEN_NOT = newFlag("DEEPEN_NOT"); //$NON-NLS-1$ } @@ -240,9 +238,13 @@ public void setDeepenNots(List<ObjectId> deepenNots) { this.deepenNots = Objects.requireNonNull(deepenNots); } + /** + * @deprecated use {@link RevFlag#UNSHALLOW} instead + */ + @Deprecated(forRemoval = true, since = "7.5") @Override public RevFlag getUnshallowFlag() { - return UNSHALLOW; + return RevFlag.UNSHALLOW; } @Override @@ -279,8 +281,6 @@ public class ObjectWalk extends org.eclipse.jgit.revwalk.ObjectWalk implements D private List<ObjectId> deepenNots; - private final RevFlag UNSHALLOW; - private final RevFlag REINTERESTING; private final RevFlag DEEPEN_NOT; @@ -298,7 +298,6 @@ public ObjectWalk(Repository repo, int depth) { this.depth = depth; this.deepenNots = Collections.emptyList(); - this.UNSHALLOW = newFlag("UNSHALLOW"); //$NON-NLS-1$ this.REINTERESTING = newFlag("REINTERESTING"); //$NON-NLS-1$ this.DEEPEN_NOT = newFlag("DEEPEN_NOT"); //$NON-NLS-1$ } @@ -316,7 +315,6 @@ public ObjectWalk(ObjectReader or, int depth) { this.depth = depth; this.deepenNots = Collections.emptyList(); - this.UNSHALLOW = newFlag("UNSHALLOW"); //$NON-NLS-1$ this.REINTERESTING = newFlag("REINTERESTING"); //$NON-NLS-1$ this.DEEPEN_NOT = newFlag("DEEPEN_NOT"); //$NON-NLS-1$ } @@ -362,8 +360,9 @@ public void markRoot(RevObject o) throws MissingObjectException, */ public void markUnshallow(RevObject c) throws MissingObjectException, IncorrectObjectTypeException, IOException { - if (c instanceof RevCommit) - c.add(UNSHALLOW); + if (c instanceof RevCommit) { + c.add(RevFlag.UNSHALLOW); + } super.markStart(c); } @@ -387,9 +386,13 @@ public List<ObjectId> getDeepenNots() { return deepenNots; } + /** + * @deprecated use {@link RevFlag#UNSHALLOW} instead + */ + @Deprecated(forRemoval = true, since = "7.5") @Override public RevFlag getUnshallowFlag() { - return UNSHALLOW; + return RevFlag.UNSHALLOW; } @Override
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/RevFlag.java b/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/RevFlag.java index 3221bf6..f0083b7 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/RevFlag.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/RevFlag.java
@@ -46,6 +46,18 @@ public class RevFlag { */ public static final RevFlag SEEN = new StaticRevFlag("SEEN", RevWalk.SEEN); //$NON-NLS-1$ + /** + * Set on RevObject instances when generating a navigation for unshallow request. + * <p> + * Commits which used to be shallow in the client, but which are + * being extended as part of this fetch. These commits should be + * returned to the caller as UNINTERESTING so that their blobs/trees + * can be marked appropriately in the pack writer. + * + * @since 7.5 + */ + public static final RevFlag UNSHALLOW = new StaticRevFlag("UNSHALLOW", RevWalk.UNSHALLOW); //$NON-NLS-1$ + final RevWalk walker; final String name;
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/RevWalk.java b/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/RevWalk.java index 4b8be70..ba7573a 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/RevWalk.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/RevWalk.java
@@ -163,9 +163,21 @@ public class RevWalk implements Iterable<RevCommit>, AutoCloseable { static final int TREE_REV_FILTER_APPLIED = 1 << 7; /** + * Set on a RevObject marked for being unshallowed. + * <p> + * This flag is used by the RevWalk's generators for keeping track + * that some objects have been marked uninteresting, however, they + * need to allow the navigation to continue for managing the unshallow + * of a shallow clone. + * + * @see DepthGenerator + */ + static final int UNSHALLOW = 1 << 8; + + /** * Number of flag bits we keep internal for our own use. See above flags. */ - static final int RESERVED_FLAGS = 8; + static final int RESERVED_FLAGS = 9; private static final int APP_FLAGS = -1 & ~((1 << RESERVED_FLAGS) - 1);
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/TopoSortGenerator.java b/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/TopoSortGenerator.java index 950b0a4..4cc0fdc 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/TopoSortGenerator.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/TopoSortGenerator.java
@@ -51,7 +51,9 @@ class TopoSortGenerator extends Generator { break; } for (RevCommit p : c.getParents()) { - p.inDegree++; + if (!p.has(RevFlag.UNSHALLOW)) { + p.inDegree++; + } if (firstParent) { break; }
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/transport/PushCertificate.java b/org.eclipse.jgit/src/org/eclipse/jgit/transport/PushCertificate.java index 437abb0..b95d094 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/transport/PushCertificate.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/transport/PushCertificate.java
@@ -53,11 +53,12 @@ public enum NonceStatus { private final String nonce; private final NonceStatus nonceStatus; private final List<ReceiveCommand> commands; + private final List<String> pushOptions; private final String signature; PushCertificate(String version, PushCertificateIdent pusher, String pushee, String nonce, NonceStatus nonceStatus, List<ReceiveCommand> commands, - String signature) { + List<String> pushOptions, String signature) { if (version == null || version.isEmpty()) { throw new IllegalArgumentException(MessageFormat.format( JGitText.get().pushCertificateInvalidField, VERSION)); @@ -95,6 +96,7 @@ public enum NonceStatus { this.nonce = nonce; this.nonceStatus = nonceStatus; this.commands = commands; + this.pushOptions = pushOptions; this.signature = signature; } @@ -171,6 +173,16 @@ public List<ReceiveCommand> getCommands() { } /** + * Get the list of push options that were included in the push certificate. + * + * @return the push options, or an empty list if none. + * @since 7.5 + */ + public List<String> getPushOptions() { + return pushOptions; + } + + /** * Get the raw signature * * @return the raw signature, consisting of the lines received between the @@ -212,8 +224,12 @@ private StringBuilder toStringBuilder() { if (pushee != null) { sb.append(PUSHEE).append(' ').append(pushee).append('\n'); } - sb.append(NONCE).append(' ').append(nonce).append('\n') - .append('\n'); + sb.append(NONCE).append(' ').append(nonce).append('\n'); + for (String option : pushOptions) { + sb.append(PushCertificateParser.PUSH_OPTION).append(' ') + .append(option).append('\n'); + } + sb.append('\n'); for (ReceiveCommand cmd : commands) { sb.append(cmd.getOldId().name()) .append(' ').append(cmd.getNewId().name())
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/transport/PushCertificateParser.java b/org.eclipse.jgit/src/org/eclipse/jgit/transport/PushCertificateParser.java index 463d053..5e9ac97 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/transport/PushCertificateParser.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/transport/PushCertificateParser.java
@@ -47,6 +47,8 @@ public class PushCertificateParser { static final String NONCE = "nonce"; //$NON-NLS-1$ + static final String PUSH_OPTION = "push-option"; //$NON-NLS-1$ + static final String END_CERT = "push-cert-end"; //$NON-NLS-1$ private static final String VERSION_0_1 = "0.1"; //$NON-NLS-1$ @@ -173,6 +175,7 @@ public static PushCertificate fromString(String str) private final boolean enabled; private final NonceGenerator nonceGenerator; private final List<ReceiveCommand> commands = new ArrayList<>(); + private final List<String> pushOptions = new ArrayList<>(); /** * <p>Constructor for PushCertificateParser.</p> @@ -251,7 +254,8 @@ public PushCertificate build() throws IOException { } try { return new PushCertificate(version, pusher, pushee, receivedNonce, - nonceStatus, Collections.unmodifiableList(commands), signature); + nonceStatus, Collections.unmodifiableList(commands), + Collections.unmodifiableList(pushOptions), signature); } catch (IllegalArgumentException e) { throw new IOException(e.getMessage(), e); } @@ -368,10 +372,16 @@ private void receiveHeader(StringReader reader, boolean stateless) ? nonceGenerator.verify( receivedNonce, sentNonce(), db, stateless, nonceSlopLimit) : NonceStatus.UNSOLICITED; - // An empty line. - if (!reader.read().isEmpty()) { - throw new PackProtocolException( - JGitText.get().pushCertificateInvalidHeader); + // Read push-option lines (if any) before the empty line separator + String line; + while (!(line = reader.read()).isEmpty()) { + if (line.startsWith(PUSH_OPTION + " ")) { //$NON-NLS-1$ + pushOptions.add(parseHeader(line, PUSH_OPTION)); + } else { + // Not a push-option, should be empty line + throw new PackProtocolException( + JGitText.get().pushCertificateInvalidHeader); + } } } catch (EOFException eof) { throw new PackProtocolException(
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/transport/PushCertificateStore.java b/org.eclipse.jgit/src/org/eclipse/jgit/transport/PushCertificateStore.java index 6bdaf0e..6a27d06 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/transport/PushCertificateStore.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/transport/PushCertificateStore.java
@@ -504,7 +504,7 @@ private static String buildMessage(PushCertificate cert) { } else { sb.append(MessageFormat.format( JGitText.get().storePushCertMultipleRefs, - cert.getCommands().size())); + Integer.valueOf(cert.getCommands().size()))); } return sb.append('\n').toString(); }
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/transport/ReceivePack.java b/org.eclipse.jgit/src/org/eclipse/jgit/transport/ReceivePack.java index 6f211e0..3d9c81c 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/transport/ReceivePack.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/transport/ReceivePack.java
@@ -40,6 +40,7 @@ import java.util.HashSet; import java.util.List; import java.util.Map; +import java.util.Objects; import java.util.Set; import java.util.concurrent.TimeUnit; import java.util.function.Function; @@ -1375,6 +1376,11 @@ private void recvCommands() throws IOException { if (hasCommands()) { readPostCommands(pck); } + // Verify that push options in the certificate match the post-command ones. + if (pushCert != null) { + validateCertificatePushOptions(pushCert.getPushOptions(), + pushOptions, commands); + } } catch (Throwable t) { discardCommands(); throw t; @@ -1406,6 +1412,35 @@ private void parseShallow(String idStr) throws PackProtocolException { } /** + * Validates that push options in the certificate match the post-command + * push options. If they don't match, marks all commands as rejected. + * <p> + * This prevents tampering with signed push certificates by ensuring the + * options that were signed match exactly the options sent after the + * commands. + * + * @param certPushOptions + * the push options from the certificate + * @param postCommandPushOptions + * the push options sent after commands (may be null) + * @param commands + * the list of commands to reject if validation fails + */ + static void validateCertificatePushOptions(List<String> certPushOptions, + List<String> postCommandPushOptions, List<ReceiveCommand> commands) { + List<String> postOptions = postCommandPushOptions == null + ? Collections.emptyList() + : postCommandPushOptions; + if (!Objects.equals(certPushOptions, postOptions)) { + // Mark all commands as rejected like in C Git. + for (ReceiveCommand cmd : commands) { + cmd.setResult(Result.REJECTED_OTHER_REASON, + JGitText.get().pushCertificateInconsistentPushOptions); + } + } + } + + /** * @param in * request stream. * @throws IOException
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/transport/http/HttpConnection.java b/org.eclipse.jgit/src/org/eclipse/jgit/transport/http/HttpConnection.java index 95b8221..76c961a 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/transport/http/HttpConnection.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/transport/http/HttpConnection.java
@@ -43,6 +43,14 @@ public interface HttpConnection { int HTTP_OK = java.net.HttpURLConnection.HTTP_OK; /** + * HttpURLConnection#HTTP_CREATED + * + * @see HttpURLConnection#HTTP_CREATED + * @since 7.5 + */ + int HTTP_CREATED = java.net.HttpURLConnection.HTTP_CREATED; + + /** * HttpURLConnection#HTTP_NOT_AUTHORITATIVE * * @see HttpURLConnection#HTTP_NOT_AUTHORITATIVE
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 6a40fad..b555c0b 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/util/FS.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/util/FS.java
@@ -1325,8 +1325,7 @@ protected static String readPipe(File dir, String[] command, boolean debug = LOG.isDebugEnabled(); try { if (debug) { - LOG.debug("readpipe " + Arrays.asList(command) + "," //$NON-NLS-1$ //$NON-NLS-2$ - + dir); + LOG.debug("readpipe {},{}", Arrays.asList(command), dir); //$NON-NLS-1$ } ProcessBuilder pb = new ProcessBuilder(command); pb.directory(dir); @@ -1348,11 +1347,12 @@ protected static String readPipe(File dir, String[] command, new InputStreamReader(p.getInputStream(), encoding))) { r = lineRead.readLine(); if (debug) { - LOG.debug("readpipe may return '" + r + "'"); //$NON-NLS-1$ //$NON-NLS-2$ + LOG.debug("readpipe may return '{}'", //$NON-NLS-1$ + StringUtils.escapeControls(r)); LOG.debug("remaining output:\n"); //$NON-NLS-1$ String l; while ((l = lineRead.readLine()) != null) { - LOG.debug(l); + LOG.debug("{}", StringUtils.escapeControls(l)); //$NON-NLS-1$ } } }
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/util/StringUtils.java b/org.eclipse.jgit/src/org/eclipse/jgit/util/StringUtils.java index e381a3b..c3782c7 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/util/StringUtils.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/util/StringUtils.java
@@ -539,4 +539,33 @@ public static String formatWithSuffix(long value) { } return first; } + + /** + * Escapes all ISO control characters in {@code text} by their Unicode + * string representation. TAB, CR, and LF are preserved. + * + * @param text + * to escape + * @return the text with all ISO control characters except TAB, CR, and LF + * replaced by their Unicode representation + * @since 7.5 + */ + public static @NonNull String escapeControls(@Nullable String text) { + if (text == null) { + return ""; //$NON-NLS-1$ + } + StringBuilder b = new StringBuilder(); + int l = text.length(); + for (int i = 0; i < l; i++) { + char ch = text.charAt(i); + if (Character.isISOControl(ch) + && !(ch == '\t' || ch == '\r' || ch == '\n')) { + b.append(ch <= 0xF ? "\\u000" : "\\u00") //$NON-NLS-1$ //$NON-NLS-2$ + .append(Integer.toHexString(ch)); + } else { + b.append(ch); + } + } + return b.toString(); + } }
diff --git a/pom.xml b/pom.xml index 016ef83..f4e15e6 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.4.1-SNAPSHOT</version> + <version>7.5.1-SNAPSHOT</version> <name>JGit - Parent</name> <url>${jgit-url}</url> @@ -118,7 +118,7 @@ <project.build.outputTimestamp>${commit.time.iso}</project.build.outputTimestamp> - <jgit-last-release-version>7.3.0.202506031305-r</jgit-last-release-version> + <jgit-last-release-version>7.4.0.202509020913-r</jgit-last-release-version> <ant-version>1.10.15</ant-version> <apache-sshd-version>2.16.0</apache-sshd-version> <jsch-version>0.1.55</jsch-version> @@ -130,25 +130,25 @@ <commons-compress-version>1.28.0</commons-compress-version> <osgi-core-version>6.0.0</osgi-core-version> <servlet-api-version>6.1.0</servlet-api-version> - <jetty-version>12.1.0</jetty-version> - <japicmp-version>0.23.1</japicmp-version> + <jetty-version>12.1.4</jetty-version> + <japicmp-version>0.24.2</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.13.1</gson-version> - <bouncycastle-version>1.81</bouncycastle-version> - <spotbugs-maven-plugin-version>4.9.3.0</spotbugs-maven-plugin-version> + <slf4j-version>2.0.17</slf4j-version> + <maven-javadoc-plugin-version>3.12.0</maven-javadoc-plugin-version> + <gson-version>2.13.2</gson-version> + <bouncycastle-version>1.82</bouncycastle-version> + <spotbugs-maven-plugin-version>4.9.8.1</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.3</maven-surefire-plugin-version> + <maven-surefire-plugin-version>3.5.4</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.4</assertj-version> - <jna-version>5.17.0</jna-version> - <byte-buddy-version>1.17.7</byte-buddy-version> + <maven-compiler-plugin-version>3.14.1</maven-compiler-plugin-version> + <plexus-compiler-version>2.16.0</plexus-compiler-version> + <hamcrest-version>3.0</hamcrest-version> + <assertj-version>3.27.6</assertj-version> + <jna-version>5.18.1</jna-version> + <byte-buddy-version>1.18.1</byte-buddy-version> <!-- Properties to enable jacoco code coverage analysis --> <sonar.core.codeCoveragePlugin>jacoco</sonar.core.codeCoveragePlugin> @@ -208,13 +208,13 @@ <plugin> <artifactId>maven-clean-plugin</artifactId> - <version>3.4.1</version> + <version>3.5.0</version> </plugin> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-shade-plugin</artifactId> - <version>3.6.0</version> + <version>3.6.1</version> </plugin> <plugin> @@ -226,7 +226,7 @@ <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-dependency-plugin</artifactId> - <version>3.8.1</version> + <version>3.9.0</version> </plugin> <plugin> @@ -255,7 +255,7 @@ <plugin> <groupId>org.codehaus.mojo</groupId> <artifactId>build-helper-maven-plugin</artifactId> - <version>3.6.0</version> + <version>3.6.1</version> </plugin> <plugin> @@ -277,7 +277,7 @@ <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-pmd-plugin</artifactId> - <version>3.26.0</version> + <version>3.27.0</version> <configuration> <inputEncoding>${project.build.sourceEncoding}</inputEncoding> <minimumTokens>100</minimumTokens> @@ -300,12 +300,12 @@ <plugin> <groupId>org.eclipse.cbi.maven.plugins</groupId> <artifactId>eclipse-jarsigner-plugin</artifactId> - <version>1.5.2</version> + <version>1.5.3</version> </plugin> <plugin> <groupId>org.jacoco</groupId> <artifactId>jacoco-maven-plugin</artifactId> - <version>0.8.13</version> + <version>0.8.14</version> </plugin> <plugin> <groupId>org.apache.maven.plugins</groupId> @@ -372,7 +372,7 @@ <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-artifact-plugin</artifactId> - <version>3.6.0</version> + <version>3.6.1</version> <configuration> <ignore>**/*cyclonedx.json</ignore> <reproducible>true</reproducible> @@ -381,7 +381,7 @@ <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-enforcer-plugin</artifactId> - <version>3.5.0</version> + <version>3.6.2</version> </plugin> </plugins> </pluginManagement> @@ -609,7 +609,7 @@ <artifactId>cyclonedx-maven-plugin</artifactId> <configuration> <projectType>library</projectType> - <schemaVersion>1.4</schemaVersion> + <schemaVersion>1.6</schemaVersion> <includeBomSerialNumber>true</includeBomSerialNumber> <includeCompileScope>true</includeCompileScope> <includeProvidedScope>true</includeProvidedScope> @@ -655,7 +655,7 @@ <plugin> <groupId>org.codehaus.gmavenplus</groupId> <artifactId>gmavenplus-plugin</artifactId> - <version>4.2.0</version> + <version>4.2.1</version> <dependencies> <dependency> <groupId>org.apache.groovy</groupId> @@ -899,7 +899,7 @@ <dependency> <groupId>commons-codec</groupId> <artifactId>commons-codec</artifactId> - <version>1.19.0</version> + <version>1.20.0</version> </dependency> <dependency> @@ -911,7 +911,7 @@ <dependency> <groupId>org.apache.commons</groupId> <artifactId>commons-io</artifactId> - <version>2.20.0</version> + <version>2.21.0</version> </dependency> <dependency> @@ -923,7 +923,7 @@ <dependency> <groupId>org.tukaani</groupId> <artifactId>xz</artifactId> - <version>1.10</version> + <version>1.11</version> <optional>true</optional> </dependency> @@ -1020,7 +1020,7 @@ <dependency> <groupId>org.mockito</groupId> <artifactId>mockito-core</artifactId> - <version>5.19.0</version> + <version>5.20.0</version> </dependency> <dependency> @@ -1129,7 +1129,7 @@ <dependency> <groupId>org.eclipse.jdt</groupId> <artifactId>ecj</artifactId> - <version>3.40.0</version> + <version>3.43.0</version> </dependency> </dependencies> </plugin>
diff --git a/tools/maven-central/Pipfile b/tools/maven-central/Pipfile new file mode 100644 index 0000000..cffba46 --- /dev/null +++ b/tools/maven-central/Pipfile
@@ -0,0 +1,17 @@ +[[source]] +url = "https://pypi.org/simple" +verify_ssl = true +name = "pypi" + +[packages] +requests = "*" +argparse = "*" +pyyaml = "*" + +[dev-packages] +flake8 = "*" +black = "*" + +[requires] +python_version = "3.12" +python_full_version = "3.12.9"
diff --git a/tools/maven-central/Pipfile.lock b/tools/maven-central/Pipfile.lock new file mode 100644 index 0000000..40358c9 --- /dev/null +++ b/tools/maven-central/Pipfile.lock
@@ -0,0 +1,339 @@ +{ + "_meta": { + "hash": { + "sha256": "096165cac35064650a41e592a40a9d1e13ae4022a1f6d43582534f1c3bf0dbf9" + }, + "pipfile-spec": 6, + "requires": { + "python_full_version": "3.12.9", + "python_version": "3.12" + }, + "sources": [ + { + "name": "pypi", + "url": "https://pypi.org/simple", + "verify_ssl": true + } + ] + }, + "default": { + "argparse": { + "hashes": [ + "sha256:62b089a55be1d8949cd2bc7e0df0bddb9e028faefc8c32038cc84862aefdd6e4", + "sha256:c31647edb69fd3d465a847ea3157d37bed1f95f19760b11a47aa91c04b666314" + ], + "index": "pypi", + "version": "==1.4.0" + }, + "certifi": { + "hashes": [ + "sha256:e564105f78ded564e3ae7c923924435e1daa7463faeab5bb932bc53ffae63407", + "sha256:f6c12493cfb1b06ba2ff328595af9350c65d6644968e5d3a2ffd78699af217a5" + ], + "markers": "python_version >= '3.7'", + "version": "==2025.8.3" + }, + "charset-normalizer": { + "hashes": [ + "sha256:00237675befef519d9af72169d8604a067d92755e84fe76492fef5441db05b91", + "sha256:02425242e96bcf29a49711b0ca9f37e451da7c70562bc10e8ed992a5a7a25cc0", + "sha256:027b776c26d38b7f15b26a5da1044f376455fb3766df8fc38563b4efbc515154", + "sha256:07a0eae9e2787b586e129fdcbe1af6997f8d0e5abaa0bc98c0e20e124d67e601", + "sha256:0cacf8f7297b0c4fcb74227692ca46b4a5852f8f4f24b3c766dd94a1075c4884", + "sha256:0e78314bdc32fa80696f72fa16dc61168fda4d6a0c014e0380f9d02f0e5d8a07", + "sha256:0f2be7e0cf7754b9a30eb01f4295cc3d4358a479843b31f328afd210e2c7598c", + "sha256:13faeacfe61784e2559e690fc53fa4c5ae97c6fcedb8eb6fb8d0a15b475d2c64", + "sha256:14c2a87c65b351109f6abfc424cab3927b3bdece6f706e4d12faaf3d52ee5efe", + "sha256:1606f4a55c0fd363d754049cdf400175ee96c992b1f8018b993941f221221c5f", + "sha256:16a8770207946ac75703458e2c743631c79c59c5890c80011d536248f8eaa432", + "sha256:18343b2d246dc6761a249ba1fb13f9ee9a2bcd95decc767319506056ea4ad4dc", + "sha256:18b97b8404387b96cdbd30ad660f6407799126d26a39ca65729162fd810a99aa", + "sha256:1bb60174149316da1c35fa5233681f7c0f9f514509b8e399ab70fea5f17e45c9", + "sha256:1e8ac75d72fa3775e0b7cb7e4629cec13b7514d928d15ef8ea06bca03ef01cae", + "sha256:1ef99f0456d3d46a50945c98de1774da86f8e992ab5c77865ea8b8195341fc19", + "sha256:2001a39612b241dae17b4687898843f254f8748b796a2e16f1051a17078d991d", + "sha256:23b6b24d74478dc833444cbd927c338349d6ae852ba53a0d02a2de1fce45b96e", + "sha256:252098c8c7a873e17dd696ed98bbe91dbacd571da4b87df3736768efa7a792e4", + "sha256:257f26fed7d7ff59921b78244f3cd93ed2af1800ff048c33f624c87475819dd7", + "sha256:2c322db9c8c89009a990ef07c3bcc9f011a3269bc06782f916cd3d9eed7c9312", + "sha256:30a96e1e1f865f78b030d65241c1ee850cdf422d869e9028e2fc1d5e4db73b92", + "sha256:30d006f98569de3459c2fc1f2acde170b7b2bd265dc1943e87e1a4efe1b67c31", + "sha256:31a9a6f775f9bcd865d88ee350f0ffb0e25936a7f930ca98995c05abf1faf21c", + "sha256:320e8e66157cc4e247d9ddca8e21f427efc7a04bbd0ac8a9faf56583fa543f9f", + "sha256:34a7f768e3f985abdb42841e20e17b330ad3aaf4bb7e7aeeb73db2e70f077b99", + "sha256:3653fad4fe3ed447a596ae8638b437f827234f01a8cd801842e43f3d0a6b281b", + "sha256:3cd35b7e8aedeb9e34c41385fda4f73ba609e561faedfae0a9e75e44ac558a15", + "sha256:3cfb2aad70f2c6debfbcb717f23b7eb55febc0bb23dcffc0f076009da10c6392", + "sha256:416175faf02e4b0810f1f38bcb54682878a4af94059a1cd63b8747244420801f", + "sha256:41d1fc408ff5fdfb910200ec0e74abc40387bccb3252f3f27c0676731df2b2c8", + "sha256:42e5088973e56e31e4fa58eb6bd709e42fc03799c11c42929592889a2e54c491", + "sha256:4ca4c094de7771a98d7fbd67d9e5dbf1eb73efa4f744a730437d8a3a5cf994f0", + "sha256:511729f456829ef86ac41ca78c63a5cb55240ed23b4b737faca0eb1abb1c41bc", + "sha256:53cd68b185d98dde4ad8990e56a58dea83a4162161b1ea9272e5c9182ce415e0", + "sha256:585f3b2a80fbd26b048a0be90c5aae8f06605d3c92615911c3a2b03a8a3b796f", + "sha256:5b413b0b1bfd94dbf4023ad6945889f374cd24e3f62de58d6bb102c4d9ae534a", + "sha256:5d8d01eac18c423815ed4f4a2ec3b439d654e55ee4ad610e153cf02faf67ea40", + "sha256:6aab0f181c486f973bc7262a97f5aca3ee7e1437011ef0c2ec04b5a11d16c927", + "sha256:6cf8fd4c04756b6b60146d98cd8a77d0cdae0e1ca20329da2ac85eed779b6849", + "sha256:6fb70de56f1859a3f71261cbe41005f56a7842cc348d3aeb26237560bfa5e0ce", + "sha256:6fce4b8500244f6fcb71465d4a4930d132ba9ab8e71a7859e6a5d59851068d14", + "sha256:70bfc5f2c318afece2f5838ea5e4c3febada0be750fcf4775641052bbba14d05", + "sha256:73dc19b562516fc9bcf6e5d6e596df0b4eb98d87e4f79f3ae71840e6ed21361c", + "sha256:74d77e25adda8581ffc1c720f1c81ca082921329452eba58b16233ab1842141c", + "sha256:78deba4d8f9590fe4dae384aeff04082510a709957e968753ff3c48399f6f92a", + "sha256:86df271bf921c2ee3818f0522e9a5b8092ca2ad8b065ece5d7d9d0e9f4849bcc", + "sha256:88ab34806dea0671532d3f82d82b85e8fc23d7b2dd12fa837978dad9bb392a34", + "sha256:8999f965f922ae054125286faf9f11bc6932184b93011d138925a1773830bbe9", + "sha256:8dcfc373f888e4fb39a7bc57e93e3b845e7f462dacc008d9749568b1c4ece096", + "sha256:939578d9d8fd4299220161fdd76e86c6a251987476f5243e8864a7844476ba14", + "sha256:96b2b3d1a83ad55310de8c7b4a2d04d9277d5591f40761274856635acc5fcb30", + "sha256:a2d08ac246bb48479170408d6c19f6385fa743e7157d716e144cad849b2dd94b", + "sha256:b256ee2e749283ef3ddcff51a675ff43798d92d746d1a6e4631bf8c707d22d0b", + "sha256:b5e3b2d152e74e100a9e9573837aba24aab611d39428ded46f4e4022ea7d1942", + "sha256:b89bc04de1d83006373429975f8ef9e7932534b8cc9ca582e4db7d20d91816db", + "sha256:bd28b817ea8c70215401f657edef3a8aa83c29d447fb0b622c35403780ba11d5", + "sha256:c60e092517a73c632ec38e290eba714e9627abe9d301c8c8a12ec32c314a2a4b", + "sha256:c6dbd0ccdda3a2ba7c2ecd9d77b37f3b5831687d8dc1b6ca5f56a4880cc7b7ce", + "sha256:c6e490913a46fa054e03699c70019ab869e990270597018cef1d8562132c2669", + "sha256:c6f162aabe9a91a309510d74eeb6507fab5fff92337a15acbe77753d88d9dcf0", + "sha256:c6fd51128a41297f5409deab284fecbe5305ebd7e5a1f959bee1c054622b7018", + "sha256:cc34f233c9e71701040d772aa7490318673aa7164a0efe3172b2981218c26d93", + "sha256:cc9370a2da1ac13f0153780040f465839e6cccb4a1e44810124b4e22483c93fe", + "sha256:ccf600859c183d70eb47e05a44cd80a4ce77394d1ac0f79dbd2dd90a69a3a049", + "sha256:ce571ab16d890d23b5c278547ba694193a45011ff86a9162a71307ed9f86759a", + "sha256:cf1ebb7d78e1ad8ec2a8c4732c7be2e736f6e5123a4146c5b89c9d1f585f8cef", + "sha256:d0e909868420b7049dafd3a31d45125b31143eec59235311fc4c57ea26a4acd2", + "sha256:d22dbedd33326a4a5190dd4fe9e9e693ef12160c77382d9e87919bce54f3d4ca", + "sha256:d716a916938e03231e86e43782ca7878fb602a125a91e7acb8b5112e2e96ac16", + "sha256:d79c198e27580c8e958906f803e63cddb77653731be08851c7df0b1a14a8fc0f", + "sha256:d95bfb53c211b57198bb91c46dd5a2d8018b3af446583aab40074bf7988401cb", + "sha256:e28e334d3ff134e88989d90ba04b47d84382a828c061d0d1027b1b12a62b39b1", + "sha256:ec557499516fc90fd374bf2e32349a2887a876fbf162c160e3c01b6849eaf557", + "sha256:fb6fecfd65564f208cbf0fba07f107fb661bcd1a7c389edbced3f7a493f70e37", + "sha256:fb731e5deb0c7ef82d698b0f4c5bb724633ee2a489401594c5c88b02e6cb15f7", + "sha256:fb7f67a1bfa6e40b438170ebdc8158b78dc465a5a67b6dde178a46987b244a72", + "sha256:fd10de089bcdcd1be95a2f73dbe6254798ec1bda9f450d5828c96f93e2536b9c", + "sha256:fdabf8315679312cfa71302f9bd509ded4f2f263fb5b765cf1433b39106c3cc9" + ], + "markers": "python_version >= '3.7'", + "version": "==3.4.3" + }, + "idna": { + "hashes": [ + "sha256:12f65c9b470abda6dc35cf8e63cc574b1c52b11df2c86030af0ac09b01b13ea9", + "sha256:946d195a0d259cbba61165e88e65941f16e9b36ea6ddb97f00452bae8b1287d3" + ], + "markers": "python_version >= '3.6'", + "version": "==3.10" + }, + "pyyaml": { + "hashes": [ + "sha256:00c4bdeba853cc34e7dd471f16b4114f4162dc03e6b7afcc2128711f0eca823c", + "sha256:0150219816b6a1fa26fb4699fb7daa9caf09eb1999f3b70fb6e786805e80375a", + "sha256:02893d100e99e03eda1c8fd5c441d8c60103fd175728e23e431db1b589cf5ab3", + "sha256:02ea2dfa234451bbb8772601d7b8e426c2bfa197136796224e50e35a78777956", + "sha256:0f29edc409a6392443abf94b9cf89ce99889a1dd5376d94316ae5145dfedd5d6", + "sha256:10892704fc220243f5305762e276552a0395f7beb4dbf9b14ec8fd43b57f126c", + "sha256:16249ee61e95f858e83976573de0f5b2893b3677ba71c9dd36b9cf8be9ac6d65", + "sha256:1d37d57ad971609cf3c53ba6a7e365e40660e3be0e5175fa9f2365a379d6095a", + "sha256:1ebe39cb5fc479422b83de611d14e2c0d3bb2a18bbcb01f229ab3cfbd8fee7a0", + "sha256:214ed4befebe12df36bcc8bc2b64b396ca31be9304b8f59e25c11cf94a4c033b", + "sha256:2283a07e2c21a2aa78d9c4442724ec1eb15f5e42a723b99cb3d822d48f5f7ad1", + "sha256:22ba7cfcad58ef3ecddc7ed1db3409af68d023b7f940da23c6c2a1890976eda6", + "sha256:27c0abcb4a5dac13684a37f76e701e054692a9b2d3064b70f5e4eb54810553d7", + "sha256:28c8d926f98f432f88adc23edf2e6d4921ac26fb084b028c733d01868d19007e", + "sha256:2e71d11abed7344e42a8849600193d15b6def118602c4c176f748e4583246007", + "sha256:34d5fcd24b8445fadc33f9cf348c1047101756fd760b4dacb5c3e99755703310", + "sha256:37503bfbfc9d2c40b344d06b2199cf0e96e97957ab1c1b546fd4f87e53e5d3e4", + "sha256:3c5677e12444c15717b902a5798264fa7909e41153cdf9ef7ad571b704a63dd9", + "sha256:3ff07ec89bae51176c0549bc4c63aa6202991da2d9a6129d7aef7f1407d3f295", + "sha256:41715c910c881bc081f1e8872880d3c650acf13dfa8214bad49ed4cede7c34ea", + "sha256:418cf3f2111bc80e0933b2cd8cd04f286338bb88bdc7bc8e6dd775ebde60b5e0", + "sha256:44edc647873928551a01e7a563d7452ccdebee747728c1080d881d68af7b997e", + "sha256:4a2e8cebe2ff6ab7d1050ecd59c25d4c8bd7e6f400f5f82b96557ac0abafd0ac", + "sha256:4ad1906908f2f5ae4e5a8ddfce73c320c2a1429ec52eafd27138b7f1cbe341c9", + "sha256:501a031947e3a9025ed4405a168e6ef5ae3126c59f90ce0cd6f2bfc477be31b7", + "sha256:5190d403f121660ce8d1d2c1bb2ef1bd05b5f68533fc5c2ea899bd15f4399b35", + "sha256:5498cd1645aa724a7c71c8f378eb29ebe23da2fc0d7a08071d89469bf1d2defb", + "sha256:5cf4e27da7e3fbed4d6c3d8e797387aaad68102272f8f9752883bc32d61cb87b", + "sha256:5e0b74767e5f8c593e8c9b5912019159ed0533c70051e9cce3e8b6aa699fcd69", + "sha256:5ed875a24292240029e4483f9d4a4b8a1ae08843b9c54f43fcc11e404532a8a5", + "sha256:5fcd34e47f6e0b794d17de1b4ff496c00986e1c83f7ab2fb8fcfe9616ff7477b", + "sha256:5fdec68f91a0c6739b380c83b951e2c72ac0197ace422360e6d5a959d8d97b2c", + "sha256:6344df0d5755a2c9a276d4473ae6b90647e216ab4757f8426893b5dd2ac3f369", + "sha256:64386e5e707d03a7e172c0701abfb7e10f0fb753ee1d773128192742712a98fd", + "sha256:652cb6edd41e718550aad172851962662ff2681490a8a711af6a4d288dd96824", + "sha256:66291b10affd76d76f54fad28e22e51719ef9ba22b29e1d7d03d6777a9174198", + "sha256:66e1674c3ef6f541c35191caae2d429b967b99e02040f5ba928632d9a7f0f065", + "sha256:6adc77889b628398debc7b65c073bcb99c4a0237b248cacaf3fe8a557563ef6c", + "sha256:79005a0d97d5ddabfeeea4cf676af11e647e41d81c9a7722a193022accdb6b7c", + "sha256:7c6610def4f163542a622a73fb39f534f8c101d690126992300bf3207eab9764", + "sha256:7f047e29dcae44602496db43be01ad42fc6f1cc0d8cd6c83d342306c32270196", + "sha256:8098f252adfa6c80ab48096053f512f2321f0b998f98150cea9bd23d83e1467b", + "sha256:850774a7879607d3a6f50d36d04f00ee69e7fc816450e5f7e58d7f17f1ae5c00", + "sha256:8d1fab6bb153a416f9aeb4b8763bc0f22a5586065f86f7664fc23339fc1c1fac", + "sha256:8da9669d359f02c0b91ccc01cac4a67f16afec0dac22c2ad09f46bee0697eba8", + "sha256:8dc52c23056b9ddd46818a57b78404882310fb473d63f17b07d5c40421e47f8e", + "sha256:9149cad251584d5fb4981be1ecde53a1ca46c891a79788c0df828d2f166bda28", + "sha256:93dda82c9c22deb0a405ea4dc5f2d0cda384168e466364dec6255b293923b2f3", + "sha256:96b533f0e99f6579b3d4d4995707cf36df9100d67e0c8303a0c55b27b5f99bc5", + "sha256:9c57bb8c96f6d1808c030b1687b9b5fb476abaa47f0db9c0101f5e9f394e97f4", + "sha256:9c7708761fccb9397fe64bbc0395abcae8c4bf7b0eac081e12b809bf47700d0b", + "sha256:9f3bfb4965eb874431221a3ff3fdcddc7e74e3b07799e0e84ca4a0f867d449bf", + "sha256:a33284e20b78bd4a18c8c2282d549d10bc8408a2a7ff57653c0cf0b9be0afce5", + "sha256:a80cb027f6b349846a3bf6d73b5e95e782175e52f22108cfa17876aaeff93702", + "sha256:b30236e45cf30d2b8e7b3e85881719e98507abed1011bf463a8fa23e9c3e98a8", + "sha256:b3bc83488de33889877a0f2543ade9f70c67d66d9ebb4ac959502e12de895788", + "sha256:b865addae83924361678b652338317d1bd7e79b1f4596f96b96c77a5a34b34da", + "sha256:b8bb0864c5a28024fac8a632c443c87c5aa6f215c0b126c449ae1a150412f31d", + "sha256:ba1cc08a7ccde2d2ec775841541641e4548226580ab850948cbfda66a1befcdc", + "sha256:bdb2c67c6c1390b63c6ff89f210c8fd09d9a1217a465701eac7316313c915e4c", + "sha256:c1ff362665ae507275af2853520967820d9124984e0f7466736aea23d8611fba", + "sha256:c2514fceb77bc5e7a2f7adfaa1feb2fb311607c9cb518dbc378688ec73d8292f", + "sha256:c3355370a2c156cffb25e876646f149d5d68f5e0a3ce86a5084dd0b64a994917", + "sha256:c458b6d084f9b935061bc36216e8a69a7e293a2f1e68bf956dcd9e6cbcd143f5", + "sha256:d0eae10f8159e8fdad514efdc92d74fd8d682c933a6dd088030f3834bc8e6b26", + "sha256:d76623373421df22fb4cf8817020cbb7ef15c725b9d5e45f17e189bfc384190f", + "sha256:ebc55a14a21cb14062aa4162f906cd962b28e2e9ea38f9b4391244cd8de4ae0b", + "sha256:eda16858a3cab07b80edaf74336ece1f986ba330fdb8ee0d6c0d68fe82bc96be", + "sha256:ee2922902c45ae8ccada2c5b501ab86c36525b883eff4255313a253a3160861c", + "sha256:efd7b85f94a6f21e4932043973a7ba2613b059c4a000551892ac9f1d11f5baf3", + "sha256:f7057c9a337546edc7973c0d3ba84ddcdf0daa14533c2065749c9075001090e6", + "sha256:fa160448684b4e94d80416c0fa4aac48967a969efe22931448d853ada8baf926", + "sha256:fc09d0aa354569bc501d4e787133afc08552722d3ab34836a80547331bb5d4a0" + ], + "index": "pypi", + "markers": "python_version >= '3.8'", + "version": "==6.0.3" + }, + "requests": { + "hashes": [ + "sha256:2462f94637a34fd532264295e186976db0f5d453d1cdd31473c85a6a161affb6", + "sha256:dbba0bac56e100853db0ea71b82b4dfd5fe2bf6d3754a8893c3af500cec7d7cf" + ], + "index": "pypi", + "markers": "python_version >= '3.9'", + "version": "==2.32.5" + }, + "urllib3": { + "hashes": [ + "sha256:3fc47733c7e419d4bc3f6b3dc2b4f890bb743906a30d56ba4a5bfa4bbff92760", + "sha256:e6b01673c0fa6a13e374b50871808eb3bf7046c4b125b216f6bf1cc604cff0dc" + ], + "markers": "python_version >= '3.9'", + "version": "==2.5.0" + } + }, + "develop": { + "black": { + "hashes": [ + "sha256:0172a012f725b792c358d57fe7b6b6e8e67375dd157f64fa7a3097b3ed3e2175", + "sha256:0474bca9a0dd1b51791fcc507a4e02078a1c63f6d4e4ae5544b9848c7adfb619", + "sha256:154b06d618233fe468236ba1f0e40823d4eb08b26f5e9261526fde34916b9140", + "sha256:1b9dc70c21ef8b43248f1d86aedd2aaf75ae110b958a7909ad8463c4aa0880b0", + "sha256:2ab0ce111ef026790e9b13bd216fa7bc48edd934ffc4cbf78808b235793cbc92", + "sha256:3bec74ee60f8dfef564b573a96b8930f7b6a538e846123d5ad77ba14a8d7a64f", + "sha256:456386fe87bad41b806d53c062e2974615825c7a52159cde7ccaeb0695fa28fa", + "sha256:474b34c1342cdc157d307b56c4c65bce916480c4a8f6551fdc6bf9b486a7c4ae", + "sha256:77e7060a00c5ec4b3367c55f39cf9b06e68965a4f2e61cecacd6d0d9b7ec945a", + "sha256:846d58e3ce7879ec1ffe816bb9df6d006cd9590515ed5d17db14e17666b2b357", + "sha256:8e46eecf65a095fa62e53245ae2795c90bdecabd53b50c448d0a8bcd0d2e74c4", + "sha256:9101ee58ddc2442199a25cb648d46ba22cd580b00ca4b44234a324e3ec7a0f7e", + "sha256:a16b14a44c1af60a210d8da28e108e13e75a284bf21a9afa6b4571f96ab8bb9d", + "sha256:aaf319612536d502fdd0e88ce52d8f1352b2c0a955cc2798f79eeca9d3af0608", + "sha256:b756fc75871cb1bcac5499552d771822fd9db5a2bb8db2a7247936ca48f39831", + "sha256:c0372a93e16b3954208417bfe448e09b0de5cc721d521866cd9e0acac3c04a1f", + "sha256:ce41ed2614b706fd55fd0b4a6909d06b5bab344ffbfadc6ef34ae50adba3d4f7", + "sha256:d119957b37cc641596063cd7db2656c5be3752ac17877017b2ffcdb9dfc4d2b1", + "sha256:e3c1f4cd5e93842774d9ee4ef6cd8d17790e65f44f7cdbaab5f2cf8ccf22a823", + "sha256:e593466de7b998374ea2585a471ba90553283fb9beefcfa430d84a2651ed5933", + "sha256:ef69351df3c84485a8beb6f7b8f9721e2009e20ef80a8d619e2d1788b7816d47", + "sha256:f96b6726d690c96c60ba682955199f8c39abc1ae0c3a494a9c62c0184049a713" + ], + "index": "pypi", + "markers": "python_version >= '3.9'", + "version": "==25.9.0" + }, + "click": { + "hashes": [ + "sha256:9b9f285302c6e3064f4330c05f05b81945b2a39544279343e6e7c5f27a9baddc", + "sha256:e7b8232224eba16f4ebe410c25ced9f7875cb5f3263ffc93cc3e8da705e229c4" + ], + "markers": "python_version >= '3.10'", + "version": "==8.3.0" + }, + "flake8": { + "hashes": [ + "sha256:b9696257b9ce8beb888cdbe31cf885c90d31928fe202be0889a7cdafad32f01e", + "sha256:fe044858146b9fc69b551a4b490d69cf960fcb78ad1edcb84e7fbb1b4a8e3872" + ], + "index": "pypi", + "markers": "python_version >= '3.9'", + "version": "==7.3.0" + }, + "mccabe": { + "hashes": [ + "sha256:348e0240c33b60bbdf4e523192ef919f28cb2c3d7d5c7794f74009290f236325", + "sha256:6c2d30ab6be0e4a46919781807b4f0d834ebdd6c6e3dca0bda5a15f863427b6e" + ], + "markers": "python_version >= '3.6'", + "version": "==0.7.0" + }, + "mypy-extensions": { + "hashes": [ + "sha256:1be4cccdb0f2482337c4743e60421de3a356cd97508abadd57d47403e94f5505", + "sha256:52e68efc3284861e772bbcd66823fde5ae21fd2fdb51c62a211403730b916558" + ], + "markers": "python_version >= '3.8'", + "version": "==1.1.0" + }, + "packaging": { + "hashes": [ + "sha256:29572ef2b1f17581046b3a2227d5c611fb25ec70ca1ba8554b24b0e69331a484", + "sha256:d443872c98d677bf60f6a1f2f8c1cb748e8fe762d2bf9d3148b5599295b0fc4f" + ], + "markers": "python_version >= '3.8'", + "version": "==25.0" + }, + "pathspec": { + "hashes": [ + "sha256:a0d503e138a4c123b27490a4f7beda6a01c6f288df0e4a8b79c7eb0dc7b4cc08", + "sha256:a482d51503a1ab33b1c67a6c3813a26953dbdc71c31dacaef9a838c4e29f5712" + ], + "markers": "python_version >= '3.8'", + "version": "==0.12.1" + }, + "platformdirs": { + "hashes": [ + "sha256:abd01743f24e5287cd7a5db3752faf1a2d65353f38ec26d98e25a6db65958c85", + "sha256:ca753cf4d81dc309bc67b0ea38fd15dc97bc30ce419a7f58d13eb3bf14c4febf" + ], + "markers": "python_version >= '3.9'", + "version": "==4.4.0" + }, + "pycodestyle": { + "hashes": [ + "sha256:c4b5b517d278089ff9d0abdec919cd97262a3367449ea1c8b49b91529167b783", + "sha256:dd6bf7cb4ee77f8e016f9c8e74a35ddd9f67e1d5fd4184d86c3b98e07099f42d" + ], + "markers": "python_version >= '3.9'", + "version": "==2.14.0" + }, + "pyflakes": { + "hashes": [ + "sha256:b24f96fafb7d2ab0ec5075b7350b3d2d2218eab42003821c06344973d3ea2f58", + "sha256:f742a7dbd0d9cb9ea41e9a24a918996e8170c799fa528688d40dd582c8265f4f" + ], + "markers": "python_version >= '3.9'", + "version": "==3.4.0" + }, + "pytokens": { + "hashes": [ + "sha256:c9a4bfa0be1d26aebce03e6884ba454e842f186a59ea43a6d3b25af58223c044", + "sha256:db7b72284e480e69fb085d9f251f66b3d2df8b7166059261258ff35f50fb711b" + ], + "markers": "python_version >= '3.8'", + "version": "==0.1.10" + } + } +}
diff --git a/tools/maven-central/README.md b/tools/maven-central/README.md new file mode 100644 index 0000000..40156a5 --- /dev/null +++ b/tools/maven-central/README.md
@@ -0,0 +1,85 @@ +# Creating a JGit release and deploying it to Maven Central + +## Prerequisites + +- you need to be a Eclipse JGit committer +- install [jreleaser CLI](https://jreleaser.org/guide/latest/install.html) +- install [python 3.12](https://www.python.org/) +- install [pipenv](https://pipenv.pypa.io/en/latest/installation.html) we use below to setup a python virtualenv +- we sign release tags and Maven artifacts using GPG. + Follow [Git Tools - Signing Your Work](https://git-scm.com/book/en/v2/Git-Tools-Signing-Your-Work) + to set this up on your computer before creating the first release. + +## Configure credentials for deployment to Maven Central Portal + +- register a user account on the [Maven Central Portal](https://central.sonatype.com/) +- ask Eclipse Foundation to get yourself registered for the + [Maven Central namespace](https://central.sonatype.org/register/namespace/) `org.eclipse.jgit` +- login to the [Maven Central Portal](https://central.sonatype.com/) +- if you don't already have one [create a user token](https://central.sonatype.org/publish/generate-portal-token/) + [here](https://central.sonatype.com/usertoken) +- add the username and token from the user token to ~/.jreleaser/config.toml + ``` + JRELEASER_GITHUB_TOKEN="EMPTY" + JRELEASER_MAVENCENTRAL_TOKEN="maven central token" + JRELEASER_MAVENCENTRAL_USERNAME="maven central username" + ``` +- store your gpg passphrase used for GPG signing the Maven artifacts in ~/.gnupg/passphrase +- restrict read access to the jreleaser config and the gpg passphrase file to yourself + ``` + chmod 600 ~/.jreleaser/config.toml + chmod 600 ~/.gnupg/passphrase + ``` + +## Create a JGit release and deploy it to repo.eclipse.org + +- Use the `tools/release.sh` script to create a new release, e.g. + ``` + ./tools/release.sh v6.1.0.202203080745-r + ``` + this script + - modifies all version identifiers in `pom.xml` files and OSGi manifests to the new release version + - creates a commit + - tags the release commit using a signed, annotated tag +- release versions have 5 parts `major.minor.patch.buildTimestamp-qualifier` +- since 6.8 we use UTC timezone for the buildTimestamp part of the version number, earlier we used EST. +- `qualifier` is `m1`, `m2`, ..., for milestones, `rc1`, `rc2`, ... for release candidates and `r` for releases +- we create all milestones and releases on a dedicated stable branch to avoid interference with + ongoing development on `master`. E.g. use the `stable-6.1` branch for releasing `6.1.0` and + subsequent patch releases like `6.1.1`. +- push the locally created release commit to eclipse.gerrithub.io for review +- wait for the verification build to succeed until it votes `+1` on the `Verified` label +- review and submit the release change, then push the release tag to `eclipse.gerrithub.io` + ``` + $ git push origin tag v6.1.0.202203080745-r + ``` +- the CI job will build the release version and deploy it to the + [Eclipse Maven Repository](https://repo.eclipse.org/content/groups/releases/org/eclipse/jgit/) + +## Deploy a JGit release to Maven Central + +- prepare virtualenv for `download_release.py`: + ``` + $ cd tools/maven-central + $ pipenv --python 3.12 + $ pipenv sync + ``` +- download a JGit release from repo.eclipse.org and create artifact signature files (`.asc`) + using your GPG signing key + ``` + $ pipenv run ./download_release.py 6.1.0.202203080745-r + ``` +- deploy the release to maven central portal + ``` + $ JRELEASER_MAVENCENTRAL_STAGE=UPLOAD jreleaser deploy + ``` +- check in the [Maven Central Portal](https://central.sonatype.com/publishing/deployments) + if the release looks good. You can download uploaded artifacts from there. + How to manually test a staged release is explained + [here](https://central.sonatype.org/publish/publish-portal-api/#manually-testing-a-deployment-bundle) +- publish the new release + - by clicking "Publish" on the [portal deployment page](https://central.sonatype.com/publishing/deployments) + - or by running + ``` + $ JRELEASER_MAVENCENTRAL_STAGE=PUBLISH jreleaser deploy + ```
diff --git a/tools/maven-central/deploy.rb b/tools/maven-central/deploy.rb deleted file mode 100755 index ece1337..0000000 --- a/tools/maven-central/deploy.rb +++ /dev/null
@@ -1,74 +0,0 @@ -#!/usr/bin/env ruby -require 'rubygems' -require 'highline/import' - -def run(args) - system(*args) -end - -def deploy_jar(artifact, version, prefix) - pom = "#{artifact}-#{version}.pom" - binary = "#{artifact}-#{version}.jar" - javadoc = "#{artifact}-#{version}-javadoc.jar" - sources = "#{artifact}-#{version}-sources.jar" - - run prefix + ["-DpomFile=#{pom}", "-Dfile=#{binary}"] - run prefix + ["-DpomFile=#{pom}", "-Dfile=#{sources}", - "-Dclassifier=sources"] - run prefix + ["-DpomFile=#{pom}", "-Dfile=#{javadoc}", - "-Dclassifier=javadoc"] -end - -def deploy_parent(version, prefix) - pom = "org.eclipse.jgit-parent-#{version}.pom" - run prefix + ["-DpomFile=#{pom}", "-Dfile=#{pom}"] -end - -def deploy_sh(artifact, version, prefix) - pom = "#{artifact}-#{version}.pom" - sh = "#{artifact}-#{version}.sh" - run prefix + ["-DpomFile=#{pom}", "-Dfile=#{sh}", "-Dpackaging=sh"] -end - -def get_passphrase(prompt="Enter your GPG Passphrase") - ask(prompt) {|q| q.echo = false} -end - -version = ARGV[0].freeze -if version =~ /\A(\d+\.\d+\.\d+)\.(\d{12})-(m\d|rc\d|r)\Z/ - printf "version %s qualifier %s classifier %s\n", $1, $2, $3 -else - printf "invalid version %s\n", version - abort -end - -url = 'https://oss.sonatype.org/service/local/staging/deploy/maven2/' -repositoryId = 'sonatype-nexus-staging' -puts "gpg passphrase ?" -passphrase = get_passphrase() - -group = 'org.eclipse.jgit' -artifacts = [group, - group + '.ant', - group + '.archive', - group + '.gpg.bc', - group + '.http.apache', - group + '.http.server', - group + '.junit', - group + '.junit.http', - group + '.junit.ssh', - group + '.lfs', - group + '.lfs.server', - group + '.pgm', - group + '.ssh.apache', - group + '.ssh.apache.agent', - group + '.ssh.jsch', - group + '.ui'] - -prefix = ["mvn", "gpg:sign-and-deploy-file", "-Dgpg.passphrase=#{passphrase}", - "-Durl=#{url}", "-DrepositoryId=#{repositoryId}"] -deploy_parent(version, prefix) -artifacts.each do |artifact| - deploy_jar(artifact, version, prefix) -end -deploy_sh('org.eclipse.jgit.pgm', version, prefix)
diff --git a/tools/maven-central/download.rb b/tools/maven-central/download.rb deleted file mode 100755 index b3c4e3d..0000000 --- a/tools/maven-central/download.rb +++ /dev/null
@@ -1,43 +0,0 @@ -#!/usr/bin/env ruby -version = ARGV[0].freeze -if version =~ /\A(\d+\.\d+\.\d+)\.(\d{12})-(m\d|rc\d|r)\Z/ - printf "version %s qualifier %s classifier %s\n", $1, $2, $3 -else - printf "invalid version %s\n", version - abort -end - -group = 'org.eclipse.jgit' -artifacts = [group, - group + '.ant', - group + '.archive', - group + '.gpg.bc', - group + '.http.apache', - group + '.http.server', - group + '.junit', - group + '.junit.http', - group + '.junit.ssh', - group + '.lfs', - group + '.lfs.server', - group + '.pgm', - group + '.ssh.apache', - group + '.ssh.apache.agent', - group + '.ssh.jsch', - group + '.ui'] - -puts 'Deleting current files' -`rm -fr *.jar *.sh *.pom` - -puts 'Downloading org.eclipse.jgit-parent' -`curl -s https://repo.eclipse.org/content/repositories/jgit-releases/org/eclipse/jgit/#{group}-parent/#{version}/#{group}-parent-#{version}.pom -o #{group}-parent-#{version}.pom` - -artifacts.each {|artifact| - puts "Downloading #{artifact}-#{version}.jar" - `curl -s https://repo.eclipse.org/content/repositories/jgit-releases/org/eclipse/jgit/#{artifact}/#{version}/#{artifact}-#{version}.jar -o #{artifact}-#{version}.jar` - `curl -s https://repo.eclipse.org/content/repositories/jgit-releases/org/eclipse/jgit/#{artifact}/#{version}/#{artifact}-#{version}.pom -o #{artifact}-#{version}.pom` - `curl -s https://repo.eclipse.org/content/repositories/jgit-releases/org/eclipse/jgit/#{artifact}/#{version}/#{artifact}-#{version}-javadoc.jar -o #{artifact}-#{version}-javadoc.jar` - `curl -s https://repo.eclipse.org/content/repositories/jgit-releases/org/eclipse/jgit/#{artifact}/#{version}/#{artifact}-#{version}-sources.jar -o #{artifact}-#{version}-sources.jar` -} - -puts "Downloading org.eclipse.jgit.pgm-#{version}.sh" -`curl -s https://repo.eclipse.org/content/repositories/jgit-releases/org/eclipse/jgit/#{group}.pgm/#{version}/#{group}.pgm-#{version}.sh -o #{group}.pgm-#{version}.sh`
diff --git a/tools/maven-central/download_release.py b/tools/maven-central/download_release.py new file mode 100755 index 0000000..4ce44bc --- /dev/null +++ b/tools/maven-central/download_release.py
@@ -0,0 +1,226 @@ +#!/usr/bin/env python3 +import argparse +import os +import pathlib +import requests +import subprocess +import xml.etree.ElementTree as ET +import yaml +from concurrent.futures import ThreadPoolExecutor +from functools import partial + + +BASE_REPO_URL = "https://repo.eclipse.org/content/groups/releases" +JGIT_GROUP_ID = "org.eclipse.jgit" +JGIT_PARENT_ARTIFACT_ID = "org.eclipse.jgit-parent" +DOWNLOAD_DIR = "staging-deploy" + + +class Dumper(yaml.Dumper): + def increase_indent(self, flow=False, *args, **kwargs): + return super().increase_indent(flow=flow, indentless=False) + + +def fetch_and_parse_pom(url): + """Fetches and parses a Maven POM file from a URL.""" + print(f"Fetching parent POM from {url}") + try: + response = requests.get(url) + response.raise_for_status() + return ET.fromstring(response.content) + except requests.exceptions.RequestException as e: + print(f"Error fetching POM: {e}") + exit(1) + + +def get_pom_info(pom_root): + """Extracts GAV and modules from a parsed POM XML.""" + ns = {"m": "http://maven.apache.org/POM/4.0.0"} + + group_id_elem = pom_root.find("m:groupId", ns) + if group_id_elem is None: + group_id_elem = pom_root.find("m:parent/m:groupId", ns) + + version_elem = pom_root.find("m:version", ns) + if version_elem is None: + version_elem = pom_root.find("m:parent/m:version", ns) + + java_version_elem = None + for prop in pom_root.findall("m:properties", ns): + java_version_elem = prop.find("m:java.version", ns) + if java_version_elem is not None: + break + + info = { + "groupId": group_id_elem.text, + "artifactId": pom_root.find("m:artifactId", ns).text, + "version": version_elem.text, + "java_version": java_version_elem.text, + "modules": [ + module.text for module in pom_root.findall("m:modules/m:module", ns) + ], + } + return info + + +def download_artifacts(artifacts_to_download): + """Downloads all artifacts for the given GAVs into the DOWNLOAD_DIR.""" + for artifact in artifacts_to_download: + group_path = artifact["groupId"].replace(".", "/") + base_url = f"{BASE_REPO_URL}/{group_path}/{artifact['artifactId']}/{artifact['version']}" + group_download_dir = f"{DOWNLOAD_DIR}/{group_path}" + artifact_download_dir = ( + f"{group_download_dir}/{artifact['artifactId']}/{artifact['version']}" + ) + if not os.path.exists(artifact_download_dir): + os.makedirs(artifact_download_dir) + + filenames = [f"{artifact['artifactId']}-{artifact['version']}.pom"] + if "parent" not in artifact["artifactId"]: + filenames.extend( + [ + f"{artifact['artifactId']}-{artifact['version']}.jar", + f"{artifact['artifactId']}-{artifact['version']}-sources.jar", + f"{artifact['artifactId']}-{artifact['version']}-javadoc.jar", + f"{artifact['artifactId']}-{artifact['version']}-cyclonedx.json", + f"{artifact['artifactId']}-{artifact['version']}.sh", + ] + ) + + print( + f"\nDownloading artifacts for {artifact['groupId']}:{artifact['artifactId']}:{artifact['version']}" + ) + download_task = partial(download_file, artifact_download_dir, base_url) + with ThreadPoolExecutor(max_workers=8) as executor: + executor.map(download_task, filenames) + + +def download_file(artifact_download_dir, base_url, filename): + """Downloads the given file from base_url to artifact_download_dir in a Maven repository layout""" + url = f"{base_url}/{filename}" + local_path = os.path.join(artifact_download_dir, filename) + + try: + with requests.get(url, stream=True) as r: + if r.status_code == 200: + with open(local_path, "wb") as f: + for chunk in r.iter_content(chunk_size=8192): + f.write(chunk) + print(f" Downloaded: {filename}") + elif r.status_code == 404: + pass + else: + print( + f" Warning: Failed to download {filename} (Status: {r.status_code})" + ) + except requests.exceptions.RequestException as e: + print(f" Error downloading {filename}: {e}") + + +def sign_artifacts(passphrase_file): + """GPG signs all artifacts under DOWNLOAD_DIR""" + artifact_dir = pathlib.Path(DOWNLOAD_DIR) + print("Signing artifacts") + for file in artifact_dir.rglob("*"): + if file.is_file() and file.suffix in {".jar", ".pom", ".sh", ".json"}: + try: + subprocess.run( + [ + "gpg", + "--batch", + "--yes", + "--pinentry-mode", + "loopback", + "--passphrase-file", + passphrase_file, + "--armor", + "--detach-sign", + str(file), + ], + check=True, + ) + print(f" Signed: {str(file)}") + except subprocess.CalledProcessError as e: + print(f"Error signing {file}: {e.stderr}") + + +def jreleaser_set_values(jgit_version, java_version): + """Generates jreleaser.yml from template and sets values extracted from parent pom""" + if not jgit_version: + print("jgit_version undefined") + if not java_version: + print("java_version undefined") + + with open("jreleaser.yml.template", "r") as f: + data = yaml.safe_load(f) + + data["project"]["version"] = jgit_version + data["project"]["languages"]["java"]["version"] = java_version + + with open("jreleaser.yml", "w") as f: + yaml.dump(data, f, sort_keys=False, Dumper=Dumper) + + +def main(): + """Main execution function.""" + parser = argparse.ArgumentParser( + description="""Download artifacts of a JGit release from repo.eclipse.org.""", + usage="%(prog)s <version> [--passphrase_file <path to passphrase file> (default: ~/.gnupg/passphrase)]", + ) + # 'version' as a positional argument + parser.add_argument( + "version", help="The JGit version to process (e.g., 5.13.4.202507202350-r)." + ) + parser.add_argument( + "--passphrase_file", + help="Path to file containing gpg passphrase", + default=f"{pathlib.Path.home()}/.gnupg/passphrase", + ) + args = parser.parse_args() + jgit_version = args.version + passphrase_file = args.passphrase_file + + group_path = JGIT_GROUP_ID.replace(".", "/") + filename = f"{JGIT_PARENT_ARTIFACT_ID}-{jgit_version}.pom" + parent_pom_url = f"{BASE_REPO_URL}/{group_path}/{JGIT_PARENT_ARTIFACT_ID}/{jgit_version}/{filename}" + + pom_root = fetch_and_parse_pom(parent_pom_url) + parent_info = get_pom_info(pom_root) + + if parent_info["version"] != jgit_version: + print( + f"Warning: The version in the POM ('{parent_info['version']}') does not match the requested version ('{jgit_version}')." + ) + print("Proceeding with the version found in the POM file.") + + print("\n--- Project Information ---") + print(f"GroupId: {parent_info['groupId']}") + print(f"ArtifactId: {parent_info['artifactId']}") + print(f"Version: {parent_info['version']}") + print(f"Found {len(parent_info['modules'])} modules.") + + artifacts_to_process = [] + artifacts_to_process.append( + { + "groupId": parent_info["groupId"], + "artifactId": parent_info["artifactId"], + "version": parent_info["version"], + } + ) + for module in parent_info["modules"]: + if not module.endswith((".test", ".coverage", ".benchmarks")): + artifacts_to_process.append( + { + "groupId": parent_info["groupId"], + "artifactId": module, + "version": parent_info["version"], + } + ) + + download_artifacts(artifacts_to_process) + sign_artifacts(passphrase_file) + jreleaser_set_values(parent_info["version"], parent_info["java_version"]) + + +if __name__ == "__main__": + main()
diff --git a/tools/maven-central/jreleaser.yml.template b/tools/maven-central/jreleaser.yml.template new file mode 100644 index 0000000..a926cc4 --- /dev/null +++ b/tools/maven-central/jreleaser.yml.template
@@ -0,0 +1,50 @@ +# JReleaser configuration template for JGit release promotion to Maven Central. +project: + name: 'org.eclipse.jgit' + version: + description: 'JGit - The Java Git Implementation' + license: 'BSD-3-Clause' + authors: + - 'The JGit Committers' + languages: + java: + groupId: org.eclipse.jgit + version: + links: + homepage: https://github.com/eclipse-jgit/jgit/ + +release: + github: + skipRelease: true + +signing: + active: RELEASE + armored: true + mode: COMMAND + +deploy: + maven: + mavenCentral: + org.eclipse.jgit: + active: RELEASE + url: https://central.sonatype.com/api/v1/publisher + snapshotSupported: false + authorization: BASIC + applyMavenCentralRules: true + sign: false + verifyPom: false + namespace: 'org.eclipse.jgit' + stagingRepositories: + - staging-deploy + connectTimeout: 20 + readTimeout: 60 + retryDelay: 60 + maxRetries: 100 + +files: + globs: + - pattern: staging-deploy/**/*.jar + - pattern: staging-deploy/**/*-cyclonedx.json + - pattern: staging-deploy/**/*-javadoc.jar + - pattern: staging-deploy/**/*-sources.jar + - pattern: staging-deploy/**/*.sh