commit 51eea701727ee37d10aaf2388de4683b5d45c4047ea9c3a27d47b7435d6ac34a Author: Fridrich Strba Date: Mon Nov 4 21:19:18 2024 +0000 OBS-URL: https://build.opensuse.org/package/show/Java:packages/eclipse-jgit?expand=0&rev=70 diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 0000000..9b03811 --- /dev/null +++ b/.gitattributes @@ -0,0 +1,23 @@ +## Default LFS +*.7z filter=lfs diff=lfs merge=lfs -text +*.bsp filter=lfs diff=lfs merge=lfs -text +*.bz2 filter=lfs diff=lfs merge=lfs -text +*.gem filter=lfs diff=lfs merge=lfs -text +*.gz filter=lfs diff=lfs merge=lfs -text +*.jar filter=lfs diff=lfs merge=lfs -text +*.lz filter=lfs diff=lfs merge=lfs -text +*.lzma filter=lfs diff=lfs merge=lfs -text +*.obscpio filter=lfs diff=lfs merge=lfs -text +*.oxt filter=lfs diff=lfs merge=lfs -text +*.pdf filter=lfs diff=lfs merge=lfs -text +*.png filter=lfs diff=lfs merge=lfs -text +*.rpm filter=lfs diff=lfs merge=lfs -text +*.tbz filter=lfs diff=lfs merge=lfs -text +*.tbz2 filter=lfs diff=lfs merge=lfs -text +*.tgz filter=lfs diff=lfs merge=lfs -text +*.ttf filter=lfs diff=lfs merge=lfs -text +*.txz filter=lfs diff=lfs merge=lfs -text +*.whl filter=lfs diff=lfs merge=lfs -text +*.xz filter=lfs diff=lfs merge=lfs -text +*.zip filter=lfs diff=lfs merge=lfs -text +*.zst filter=lfs diff=lfs merge=lfs -text diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..57affb6 --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +.osc diff --git a/0002-Don-t-embed-versions-of-third-party-libs-use-feature.patch b/0002-Don-t-embed-versions-of-third-party-libs-use-feature.patch new file mode 100644 index 0000000..c20c900 --- /dev/null +++ b/0002-Don-t-embed-versions-of-third-party-libs-use-feature.patch @@ -0,0 +1,67 @@ +From a6efa36a04bee412b06af2823281ff9b78827ebf Mon Sep 17 00:00:00 2001 +From: Mat Booth +Date: Fri, 29 Jan 2021 18:35:25 +0000 +Subject: [PATCH 2/2] Don't embed versions of third-party libs, use feature + requirements instead + +--- + .../feature.xml | 24 +++---------------- + .../feature.xml | 2 ++ + 2 files changed, 5 insertions(+), 21 deletions(-) + +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 92d171f..ca1f6de 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 +@@ -24,6 +24,9 @@ + + + ++ ++ ++ + + + +@@ -55,25 +58,4 @@ + version="0.0.0" + unpack="false"/> + +- +- +- +- +- +- + +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 48660d5..843896f 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 +@@ -24,6 +24,8 @@ + + + ++ ++ + + + + jgit + diff --git a/eclipse-jgit.changes b/eclipse-jgit.changes new file mode 100644 index 0000000..d3163c8 --- /dev/null +++ b/eclipse-jgit.changes @@ -0,0 +1,139 @@ +------------------------------------------------------------------- +Thu May 23 14:19:57 UTC 2024 - Fridrich Strba + +- Require hamcrest to avoid conflict of providers with hamcrest-core + +------------------------------------------------------------------- +Wed Feb 21 21:55:25 UTC 2024 - Fridrich Strba + +- Use %patch -P N instead of deprecated %patchN. + +------------------------------------------------------------------- +Fri Jan 12 15:25:10 UTC 2024 - Fridrich Strba + +- Modified patch: + * jgit-apache-sshd-2.7.0.patch -> jgit-apache-sshd.patch + + rename patch and make it accept apache-ssd < 3.0.0 + +------------------------------------------------------------------- +Wed Oct 11 08:47:23 UTC 2023 - Fridrich Strba + +- Modified patch: + * jgit-apache-sshd-2.7.0.patch + + extend even more apache-sshd version span + +------------------------------------------------------------------- +Tue Oct 10 15:09:41 UTC 2023 - Fridrich Strba + +- Added patch: + * jgit-CVE-2023-4759.patch + + backport of upstream fix for bsc#1215298 (CVE-2023-4759), + arbitrary file overwrite + +------------------------------------------------------------------- +Fri Oct 6 11:04:41 UTC 2023 - Fridrich Strba + +- Removed patch: + * 0001-Ensure-the-correct-classpath-is-set-for-the-jgit-com.patch + + no need to patch the jgit.sh launcher that we do not use + +------------------------------------------------------------------- +Fri Oct 6 11:00:40 UTC 2023 - Fridrich Strba + +- Craft the jgit script from the real Main class of the jar file + instead of using some superfluous jar launcher. + Fixes bsc#1209646 + +------------------------------------------------------------------- +Wed May 31 19:51:51 UTC 2023 - Fridrich Strba + +- Added patch: + * jgit-jsch.patch + + extend the version range for the required jsch package + + allows building with 0.2.x (which is backward compatible + with 0.1.x) + +------------------------------------------------------------------- +Fri May 5 08:24:40 UTC 2023 - Fridrich Strba + +- Add _multibuild to define 2nd spec file as additional flavor. + Eliminates the need for source package links in OBS. + +------------------------------------------------------------------- +Mon Mar 27 08:18:14 UTC 2023 - Fridrich Strba + +- Require xz-java because the jgit script that we install is + expecting it to be present when composing the classpath + (bsc#1209646) + +------------------------------------------------------------------- +Wed Nov 16 11:24:53 UTC 2022 - Fridrich Strba + +- Modified patch: + * jgit-apache-sshd-2.7.0.patch + + Allow building against apache-sshd 2.8.x and 2.9.x + +------------------------------------------------------------------- +Tue Mar 29 14:06:34 UTC 2022 - Fridrich Strba + +- Force building with Java 11, since tycho is not knowing about any + Java >= 15 + +------------------------------------------------------------------- +Fri Jul 30 12:24:56 UTC 2021 - Fridrich Strba + +- Update to 5.11.0 + * No changelog was made available. + * fixes build against apache-sshd 2.7.0 +- Modified patches: + * 0001-Ensure-the-correct-classpath-is-set-for-the-jgit-com.patch + * 0002-Don-t-embed-versions-of-third-party-libs-use-feature.patch + * jgit-shade.patch + * jgit-5.8.0-java8.patch -> jgit-5.11.0-java8.patch + + Rediff to changed context +- Added patch: + * jgit-apache-sshd-2.7.0.patch + + Adapt to apache-sshd api changes between 2.6.0 and 2.7.0 +- Removed patch: + * 0003-Remove-requirement-on-assertj-core.patch + + Not needed anymore + +------------------------------------------------------------------- +Thu Nov 19 13:00:00 UTC 2020 - Fridrich Strba + +- Fix provides + +------------------------------------------------------------------- +Thu Jul 16 21:23:15 UTC 2020 - Fridrich Strba + +- Added patch: + * jgit-5.8.0-java8.patch + + restore java 8 compatibility when building with java 9+ + +------------------------------------------------------------------- +Fri Jul 3 09:55:53 UTC 2020 - Fridrich Strba + +- Upgrade to 5.8.0 + * No changelog was made available. +- Removed patches: + * fix_jgit_sh.patch + * jgit-feature-deps.patch +- Added patches: + * 0001-Ensure-the-correct-classpath-is-set-for-the-jgit-com.patch + * 0002-Don-t-embed-versions-of-third-party-libs-use-feature.patch + * 0003-Remove-requirement-on-assertj-core.patch + * jgit-shade.patch + +------------------------------------------------------------------- +Wed Apr 8 19:57:21 UTC 2020 - Fridrich Strba + +- Split the build into two spec files instead of multibuild + * First one produces the maven artifacts, the jgit command-line + tool and ant feature + * Second one produces eclipse features + +------------------------------------------------------------------- +Mon Nov 11 12:09:35 UTC 2019 - Fridrich Strba + +- Initial packaging of eclipse-jgit 5.1.3 as a _multibuild package + in order to allow bootstrapping diff --git a/eclipse-jgit.spec b/eclipse-jgit.spec new file mode 100644 index 0000000..fb6ff19 --- /dev/null +++ b/eclipse-jgit.spec @@ -0,0 +1,164 @@ +# +# spec file for package eclipse-jgit +# +# Copyright (c) 2024 SUSE LLC +# +# All modifications and additions to the file contributed by third parties +# remain the property of their copyright owners, unless otherwise agreed +# upon. The license for this file, and modifications and additions to the +# file, is the same license as for the pristine package itself (unless the +# license for the pristine package is not an Open Source License, in which +# case the license is the MIT License). An "Open Source License" is a +# license that conforms to the Open Source Definition (Version 1.9) +# published by the Open Source Initiative. + +# Please submit bugfixes or comments via https://bugs.opensuse.org/ +# + + +%global gittag 5.11.0.202103091610-r +%define __provides_exclude osgi* +Name: eclipse-jgit +Version: 5.11.0 +Release: 0 +Summary: Eclipse JGit +License: BSD-3-Clause +Group: Development/Libraries/Java +URL: https://www.eclipse.org/egit/ +Source0: https://git.eclipse.org/c/jgit/jgit.git/snapshot/jgit-%{gittag}.tar.xz +# Set the correct classpath for the command line tools +# Switch to feature requirements for third-party bundles, also makes the following changes: +# javaewah -> com.googlecode.javaewah.JavaEWAH +# org.slf4j.api -> slf4j.api +# org.slf4j.impl.log4j12 -> slf4j.simple +Patch1: 0002-Don-t-embed-versions-of-third-party-libs-use-feature.patch +Patch2: jgit-shade.patch +Patch3: jgit-5.11.0-java8.patch +Patch4: jgit-apache-sshd.patch +Patch5: jgit-jsch.patch +Patch6: jgit-CVE-2023-4759.patch +Patch7: jgit-bc-179.patch +# For main build +BuildRequires: ant +BuildRequires: apache-commons-compress +BuildRequires: apache-sshd >= 2.7 +BuildRequires: args4j +BuildRequires: bouncycastle +BuildRequires: bouncycastle-pg +BuildRequires: bouncycastle-pkix +BuildRequires: eclipse-platform-bootstrap +BuildRequires: ed25519-java +BuildRequires: fdupes +BuildRequires: git +BuildRequires: google-gson +BuildRequires: hamcrest +BuildRequires: javaewah +BuildRequires: jgit = %{version} +BuildRequires: junit +BuildRequires: jzlib +BuildRequires: maven-local +BuildRequires: slf4j +BuildRequires: tycho +BuildRequires: xml-commons-apis +BuildRequires: xmvn-subst +BuildConflicts: java >= 12 +BuildConflicts: java-devel >= 12 +BuildConflicts: java-headless >= 12 +#!BuildIgnore: eclipse-platform +#!BuildIgnore: tycho-bootstrap +#!BuildRequires: eclipse-emf-core eclipse-ecf-core +Requires: apache-commons-compress +Requires: apache-sshd >= 2.7 +Requires: args4j +Requires: bouncycastle +Requires: bouncycastle-pg +Requires: bouncycastle-pkix +Requires: ed25519-java +Requires: google-gson +Requires: hamcrest +Requires: javaewah +Requires: jgit = %{version} +Requires: junit +Requires: jzlib +Requires: slf4j +Requires: xml-commons-apis +BuildArch: noarch +# Upstream Eclipse no longer supports non-64bit arches +ExcludeArch: s390 %{arm} %{ix86} + +%description +A pure Java implementation of the Git version control system. + +%prep +%setup -q -n jgit-%{gittag} + +%patch -P 1 -p1 +%patch -P 2 -p1 +%patch -P 3 -p1 +%patch -P 4 -p1 +%patch -P 5 -p1 +%patch -P 6 -p1 +%patch -P 7 -p1 + +# Disable multithreaded build +rm .mvn/maven.config + +# Don't try to get deps from local *maven* repo, use tycho resolved ones +for p in $(find org.eclipse.jgit.packaging -name pom.xml) ; do + grep -q dependencies $p && %pom_xpath_remove "pom:dependencies" $p +done + +# Disable "errorprone" compiler +%pom_xpath_remove "pom:plugin[pom:artifactId='maven-compiler-plugin']/pom:configuration/pom:compilerArgs" pom.xml +%pom_xpath_remove "pom:plugin[pom:artifactId='maven-compiler-plugin']/pom:configuration/pom:annotationProcessorPaths" pom.xml + +# Don't need target platform or repository modules with xmvn +%pom_disable_module org.eclipse.jgit.target org.eclipse.jgit.packaging +%pom_disable_module org.eclipse.jgit.repository org.eclipse.jgit.packaging +%pom_xpath_remove "pom:build/pom:pluginManagement/pom:plugins/pom:plugin/pom:configuration/pom:target" org.eclipse.jgit.packaging/pom.xml + +# Don't build source features +%pom_disable_module org.eclipse.jgit.source.feature org.eclipse.jgit.packaging + +# Don't build benchmark and coverage +%pom_disable_module org.eclipse.jgit.benchmarks +%pom_disable_module org.eclipse.jgit.coverage + +# Use newer Felix dep +%pom_change_dep -r org.osgi:org.osgi.core org.osgi:osgi.core + +# Remove unnecessary plugins for RPM builds +%pom_remove_plugin :jacoco-maven-plugin +%pom_remove_plugin :maven-javadoc-plugin +%pom_remove_plugin :maven-enforcer-plugin +%pom_remove_plugin :maven-enforcer-plugin org.eclipse.jgit.packaging +%pom_remove_plugin -r :japicmp-maven-plugin + +# Don't attach shell script artifact +%pom_remove_plugin org.codehaus.mojo:build-helper-maven-plugin org.eclipse.jgit.pgm + +# Remove org.apache.log4j +%pom_remove_dep log4j:log4j . org.eclipse.jgit.pgm +%pom_change_dep org.slf4j:slf4j-log4j12 org.slf4j:slf4j-simple . org.eclipse.jgit.pgm + +pushd org.eclipse.jgit.packaging +%{mvn_package} "::pom::" __noinstall +popd + +%build +pushd org.eclipse.jgit.packaging +%{mvn_build} -j -f +popd + +%install +pushd org.eclipse.jgit.packaging +%mvn_install +popd +xmvn-subst -R %{buildroot} %{_datadir}/eclipse/droplets/jgit +#%fdupes -s %{buildroot}%{_datadir} + +%files -f org.eclipse.jgit.packaging/.mfiles +%license LICENSE +%doc README.md + +%changelog diff --git a/jgit-5.11.0-java8.patch b/jgit-5.11.0-java8.patch new file mode 100644 index 0000000..ae3758e --- /dev/null +++ b/jgit-5.11.0-java8.patch @@ -0,0 +1,282 @@ +diff -urEbwB jgit-5.11.0.202103091610-r/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/dfs/DfsBlock.java jgit-5.11.0.202103091610-r.new/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/dfs/DfsBlock.java +--- jgit-5.11.0.202103091610-r/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/dfs/DfsBlock.java 2021-03-09 22:10:22.000000000 +0100 ++++ jgit-5.11.0.202103091610-r.new/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/dfs/DfsBlock.java 2021-07-30 11:47:47.425624542 +0200 +@@ -13,6 +13,7 @@ + package org.eclipse.jgit.internal.storage.dfs; + + import java.io.IOException; ++import java.nio.Buffer; + import java.nio.ByteBuffer; + import java.util.zip.CRC32; + import java.util.zip.DataFormatException; +@@ -40,7 +41,7 @@ + + ByteBuffer zeroCopyByteBuffer(int n) { + ByteBuffer b = ByteBuffer.wrap(block); +- b.position(n); ++ ((Buffer)b).position(n); + return b; + } + +diff -urEbwB jgit-5.11.0.202103091610-r/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/dfs/DfsPackFile.java jgit-5.11.0.202103091610-r.new/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/dfs/DfsPackFile.java +--- jgit-5.11.0.202103091610-r/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/dfs/DfsPackFile.java 2021-03-09 22:10:22.000000000 +0100 ++++ jgit-5.11.0.202103091610-r.new/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/dfs/DfsPackFile.java 2021-07-30 11:47:47.425624542 +0200 +@@ -21,6 +21,7 @@ + import java.io.EOFException; + import java.io.IOException; + import java.io.InputStream; ++import java.nio.Buffer; + import java.nio.ByteBuffer; + import java.nio.channels.Channels; + import java.text.MessageFormat; +@@ -379,7 +380,7 @@ + + // Need to skip the 'PACK' header for the first read + int ptr = packHeadSkipped ? 0 : 12; +- buf.position(0); ++ ((Buffer)buf).position(0); + int bufLen = read(rc, buf); + if (bufLen <= ptr) { + throw packfileIsTruncated(); +diff -urEbwB jgit-5.11.0.202103091610-r/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/dfs/DfsReftable.java jgit-5.11.0.202103091610-r.new/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/dfs/DfsReftable.java +--- jgit-5.11.0.202103091610-r/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/dfs/DfsReftable.java 2021-03-09 22:10:22.000000000 +0100 ++++ jgit-5.11.0.202103091610-r.new/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/dfs/DfsReftable.java 2021-07-30 11:47:47.425624542 +0200 +@@ -13,6 +13,7 @@ + import static org.eclipse.jgit.internal.storage.pack.PackExt.REFTABLE; + + import java.io.IOException; ++import java.nio.Buffer; + import java.nio.ByteBuffer; + + import org.eclipse.jgit.internal.storage.io.BlockSource; +@@ -102,7 +103,7 @@ + + byte[] dst = new byte[cnt]; + ByteBuffer buf = ByteBuffer.wrap(dst); +- buf.position(ctx.copy(file, pos, dst, 0, cnt)); ++ ((Buffer)buf).position(ctx.copy(file, pos, dst, 0, cnt)); + return buf; + } + +diff -urEbwB jgit-5.11.0.202103091610-r/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/ByteBufferWindow.java jgit-5.11.0.202103091610-r.new/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/ByteBufferWindow.java +--- jgit-5.11.0.202103091610-r/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/ByteBufferWindow.java 2021-03-09 22:10:22.000000000 +0100 ++++ jgit-5.11.0.202103091610-r.new/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/ByteBufferWindow.java 2021-07-30 11:47:47.425624542 +0200 +@@ -13,6 +13,7 @@ + package org.eclipse.jgit.internal.storage.file; + + import java.io.IOException; ++import java.nio.Buffer; + import java.nio.ByteBuffer; + import java.util.zip.DataFormatException; + import java.util.zip.Inflater; +@@ -36,7 +37,7 @@ + @Override + protected int copy(int p, byte[] b, int o, int n) { + final ByteBuffer s = buffer.slice(); +- s.position(p); ++ ((Buffer)s).position(p); + n = Math.min(s.remaining(), n); + s.get(b, o, n); + return n; +@@ -46,7 +47,7 @@ + void write(PackOutputStream out, long pos, int cnt) + throws IOException { + final ByteBuffer s = buffer.slice(); +- s.position((int) (pos - start)); ++ ((Buffer)s).position((int) (pos - start)); + + while (0 < cnt) { + byte[] buf = out.getCopyBuffer(); +@@ -62,7 +63,7 @@ + protected int setInput(int pos, Inflater inf) + throws DataFormatException { + final ByteBuffer s = buffer.slice(); +- s.position(pos); ++ ((Buffer)s).position(pos); + final byte[] tmp = new byte[Math.min(s.remaining(), 512)]; + s.get(tmp, 0, tmp.length); + inf.setInput(tmp, 0, tmp.length); +diff -urEbwB jgit-5.11.0.202103091610-r/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/reftable/BlockReader.java jgit-5.11.0.202103091610-r.new/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/reftable/BlockReader.java +--- jgit-5.11.0.202103091610-r/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/reftable/BlockReader.java 2021-03-09 22:10:22.000000000 +0100 ++++ jgit-5.11.0.202103091610-r.new/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/reftable/BlockReader.java 2021-07-30 11:47:47.425624542 +0200 +@@ -31,6 +31,7 @@ + import static org.eclipse.jgit.lib.Ref.Storage.PACKED; + + import java.io.IOException; ++import java.nio.Buffer; + import java.nio.ByteBuffer; + import java.util.Arrays; + import java.util.zip.DataFormatException; +@@ -272,7 +273,7 @@ + buf = b.array(); + } else { + buf = new byte[bufLen]; +- b.flip(); ++ ((Buffer)b).flip(); + b.get(buf); + } + endPosition = pos + bufLen; +diff -urEbwB jgit-5.11.0.202103091610-r/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/reftable/ReftableReader.java jgit-5.11.0.202103091610-r.new/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/reftable/ReftableReader.java +--- jgit-5.11.0.202103091610-r/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/reftable/ReftableReader.java 2021-03-09 22:10:22.000000000 +0100 ++++ jgit-5.11.0.202103091610-r.new/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/reftable/ReftableReader.java 2021-07-30 11:47:47.425624542 +0200 +@@ -23,6 +23,7 @@ + import static org.eclipse.jgit.lib.Constants.OBJECT_ID_LENGTH; + + import java.io.IOException; ++import java.nio.Buffer; + import java.nio.ByteBuffer; + import java.text.MessageFormat; + import java.util.Arrays; +@@ -341,7 +342,7 @@ + } + + byte[] tmp = new byte[len]; +- buf.flip(); ++ ((Buffer)buf).flip(); + buf.get(tmp); + if (!isFileHeaderMagic(tmp, 0, len)) { + throw new IOException(JGitText.get().invalidReftableFile); +@@ -408,7 +409,7 @@ + buf = tmp.array(); + } else { + buf = new byte[sz]; +- tmp.flip(); ++ ((Buffer)tmp).flip(); + tmp.get(buf); + } + if (pos == 0 && buf[FILE_HEADER_LEN] == FILE_BLOCK_TYPE) { +diff -urEbwB jgit-5.11.0.202103091610-r/org.eclipse.jgit/src/org/eclipse/jgit/transport/RefAdvertiser.java jgit-5.11.0.202103091610-r.new/org.eclipse.jgit/src/org/eclipse/jgit/transport/RefAdvertiser.java +--- jgit-5.11.0.202103091610-r/org.eclipse.jgit/src/org/eclipse/jgit/transport/RefAdvertiser.java 2021-03-09 22:10:22.000000000 +0100 ++++ jgit-5.11.0.202103091610-r.new/org.eclipse.jgit/src/org/eclipse/jgit/transport/RefAdvertiser.java 2021-07-30 11:47:47.425624542 +0200 +@@ -17,6 +17,7 @@ + import static org.eclipse.jgit.transport.GitProtocolConstants.REF_ATTR_SYMREF_TARGET; + + import java.io.IOException; ++import java.nio.Buffer; + import java.nio.ByteBuffer; + import java.nio.CharBuffer; + import java.nio.charset.CharacterCodingException; +@@ -67,7 +68,7 @@ + throws IOException { + id.copyTo(binArr, 0); + binArr[OBJECT_ID_STRING_LENGTH] = ' '; +- binBuf.position(OBJECT_ID_STRING_LENGTH + 1); ++ ((Buffer)binBuf).position(OBJECT_ID_STRING_LENGTH + 1); + append(refName); + if (first) { + first = false; +@@ -90,7 +91,7 @@ + chBuf = CharBuffer.wrap(chArr); + } + str.getChars(0, n, chArr, 0); +- chBuf.position(0).limit(n); ++ ((Buffer)chBuf).position(0).limit(n); + utf8.reset(); + for (;;) { + CoderResult cr = utf8.encode(chBuf, binBuf, true); +@@ -117,7 +118,7 @@ + System.arraycopy(binArr, 0, tmp, 0, cnt); + binArr = tmp; + binBuf = ByteBuffer.wrap(binArr); +- binBuf.position(cnt); ++ ((Buffer)binBuf).position(cnt); + } + + @Override +diff -urEbwB jgit-5.11.0.202103091610-r/org.eclipse.jgit/src/org/eclipse/jgit/util/RawParseUtils.java jgit-5.11.0.202103091610-r.new/org.eclipse.jgit/src/org/eclipse/jgit/util/RawParseUtils.java +--- jgit-5.11.0.202103091610-r/org.eclipse.jgit/src/org/eclipse/jgit/util/RawParseUtils.java 2021-03-09 22:10:22.000000000 +0100 ++++ jgit-5.11.0.202103091610-r.new/org.eclipse.jgit/src/org/eclipse/jgit/util/RawParseUtils.java 2021-07-30 11:47:47.425624542 +0200 +@@ -18,6 +18,7 @@ + import static org.eclipse.jgit.lib.ObjectChecker.encoding; + import static org.eclipse.jgit.lib.ObjectChecker.tagger; + ++import java.nio.Buffer; + import java.nio.ByteBuffer; + import java.nio.charset.CharacterCodingException; + import java.nio.charset.Charset; +@@ -1137,7 +1138,7 @@ + final byte[] buffer, final int start, final int end) + throws CharacterCodingException { + ByteBuffer b = ByteBuffer.wrap(buffer, start, end - start); +- b.mark(); ++ ((Buffer)b).mark(); + + // Try our built-in favorite. The assumption here is that + // decoding will fail if the data is not actually encoded +@@ -1145,7 +1146,7 @@ + try { + return decode(b, UTF_8); + } catch (CharacterCodingException e) { +- b.reset(); ++ ((Buffer)b).reset(); + } + + if (!cs.equals(UTF_8)) { +@@ -1154,7 +1155,7 @@ + try { + return decode(b, cs); + } catch (CharacterCodingException e) { +- b.reset(); ++ ((Buffer)b).reset(); + } + } + +@@ -1165,7 +1166,7 @@ + try { + return decode(b, defcs); + } catch (CharacterCodingException e) { +- b.reset(); ++ ((Buffer)b).reset(); + } + } + +diff -urEbwB jgit-5.11.0.202103091610-r/org.eclipse.jgit.lfs.server/src/org/eclipse/jgit/lfs/server/fs/ObjectDownloadListener.java jgit-5.11.0.202103091610-r.new/org.eclipse.jgit.lfs.server/src/org/eclipse/jgit/lfs/server/fs/ObjectDownloadListener.java +--- jgit-5.11.0.202103091610-r/org.eclipse.jgit.lfs.server/src/org/eclipse/jgit/lfs/server/fs/ObjectDownloadListener.java 2021-03-09 22:10:22.000000000 +0100 ++++ jgit-5.11.0.202103091610-r.new/org.eclipse.jgit.lfs.server/src/org/eclipse/jgit/lfs/server/fs/ObjectDownloadListener.java 2021-07-30 11:47:47.425624542 +0200 +@@ -10,6 +10,7 @@ + package org.eclipse.jgit.lfs.server.fs; + + import java.io.IOException; ++import java.nio.Buffer; + import java.nio.ByteBuffer; + import java.nio.channels.Channels; + import java.nio.channels.ReadableByteChannel; +@@ -85,11 +86,11 @@ + public void onWritePossible() throws IOException { + while (out.isReady()) { + try { +- buffer.clear(); ++ ((Buffer)buffer).clear(); + if (in.read(buffer) < 0) { + buffer = null; + } else { +- buffer.flip(); ++ ((Buffer)buffer).flip(); + } + } catch (Throwable t) { + LOG.log(Level.SEVERE, t.getMessage(), t); +diff -urEbwB jgit-5.11.0.202103091610-r/org.eclipse.jgit.lfs.server/src/org/eclipse/jgit/lfs/server/fs/ObjectUploadListener.java jgit-5.11.0.202103091610-r.new/org.eclipse.jgit.lfs.server/src/org/eclipse/jgit/lfs/server/fs/ObjectUploadListener.java +--- jgit-5.11.0.202103091610-r/org.eclipse.jgit.lfs.server/src/org/eclipse/jgit/lfs/server/fs/ObjectUploadListener.java 2021-03-09 22:10:22.000000000 +0100 ++++ jgit-5.11.0.202103091610-r.new/org.eclipse.jgit.lfs.server/src/org/eclipse/jgit/lfs/server/fs/ObjectUploadListener.java 2021-07-30 11:47:47.425624542 +0200 +@@ -11,6 +11,7 @@ + + import java.io.FileNotFoundException; + import java.io.IOException; ++import java.nio.Buffer; + import java.nio.ByteBuffer; + import java.nio.channels.Channels; + import java.nio.channels.ReadableByteChannel; +@@ -131,11 +132,11 @@ + public void onDataAvailable() throws IOException { + while (in.isReady()) { + if (inChannel.read(buffer) > 0) { +- buffer.flip(); ++ ((Buffer)buffer).flip(); + uploaded += Integer.valueOf(channel.write(buffer)).longValue(); + buffer.compact(); + } else { +- buffer.flip(); ++ ((Buffer)buffer).flip(); + while (buffer.hasRemaining()) { + uploaded += Integer.valueOf(channel.write(buffer)) + .longValue(); diff --git a/jgit-5.11.0.202103091610-r.tar.xz b/jgit-5.11.0.202103091610-r.tar.xz new file mode 100644 index 0000000..0a2ce03 --- /dev/null +++ b/jgit-5.11.0.202103091610-r.tar.xz @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:91621edf2e92b79c377d1fb8e747ac52dde20f39441b091a439a13efe36f0577 +size 2159996 diff --git a/jgit-CVE-2023-4759.patch b/jgit-CVE-2023-4759.patch new file mode 100644 index 0000000..3b41ddb --- /dev/null +++ b/jgit-CVE-2023-4759.patch @@ -0,0 +1,1694 @@ +--- jgit-5.11.0.202103091610-r/org.eclipse.jgit/resources/org/eclipse/jgit/internal/JGitText.properties 2023-10-10 15:45:07.523229821 +0200 ++++ jgit-5.11.0.202103091610-r/org.eclipse.jgit/resources/org/eclipse/jgit/internal/JGitText.properties 2023-10-10 16:05:28.178175915 +0200 +@@ -13,6 +13,8 @@ + aNewObjectIdIsRequired=A NewObjectId is required. + anExceptionOccurredWhileTryingToAddTheIdOfHEAD=An exception occurred while trying to add the Id of HEAD + anSSHSessionHasBeenAlreadyCreated=An SSH session has been already created ++applyPatchDestInvalid=Destination path in patch is invalid ++applyPatchSourceInvalid==Source path in patch is invalid + applyingCommit=Applying {0} + archiveFormatAlreadyAbsent=Archive format already absent: {0} + archiveFormatAlreadyRegistered=Archive format already registered with different implementation: {0} +@@ -522,6 +524,8 @@ + packWriterStatistics=Total {0,number,#0} (delta {1,number,#0}), reused {2,number,#0} (delta {3,number,#0}) + panicCantRenameIndexFile=Panic: index file {0} must be renamed to replace {1}; until then repository is corrupt + patchApplyException=Cannot apply: {0} ++patchApplyErrorWithHunk=Error applying patch in {0}, hunk {1}: {2} ++patchApplyErrorWithoutHunk=Error applying patch in {0}: {1} + patchFormatException=Format error: {0} + pathNotConfigured=Submodule path is not configured + peeledLineBeforeRef=Peeled line before ref. +--- jgit-5.11.0.202103091610-r/org.eclipse.jgit/.settings/.api_filters 2023-10-10 15:45:07.523229821 +0200 ++++ jgit-5.11.0.202103091610-r/org.eclipse.jgit/.settings/.api_filters 2023-10-10 16:24:34.812579919 +0200 +@@ -1,5 +1,13 @@ + + ++ ++ ++ ++ ++ ++ ++ ++ + + + +@@ -8,6 +16,14 @@ + + + ++ ++ ++ ++ ++ ++ ++ ++ + + + +--- jgit-5.11.0.202103091610-r/org.eclipse.jgit/src/org/eclipse/jgit/api/ApplyCommand.java 2023-10-10 15:45:07.523229821 +0200 ++++ jgit-5.11.0.202103091610-r/org.eclipse.jgit/src/org/eclipse/jgit/api/ApplyCommand.java 2023-10-10 16:37:00.354302669 +0200 +@@ -17,21 +17,34 @@ + import java.nio.file.StandardCopyOption; + import java.text.MessageFormat; + import java.util.ArrayList; ++import java.util.Arrays; + import java.util.Iterator; + import java.util.List; + ++import org.eclipse.jgit.annotations.Nullable; + import org.eclipse.jgit.api.errors.GitAPIException; + import org.eclipse.jgit.api.errors.PatchApplyException; + import org.eclipse.jgit.api.errors.PatchFormatException; + import org.eclipse.jgit.diff.DiffEntry.ChangeType; + import org.eclipse.jgit.diff.RawText; ++import org.eclipse.jgit.errors.CorruptObjectException; + import org.eclipse.jgit.internal.JGitText; + import org.eclipse.jgit.lib.FileMode; ++import org.eclipse.jgit.lib.FileModeCache; ++import org.eclipse.jgit.lib.ObjectId; + import org.eclipse.jgit.lib.Repository; + import org.eclipse.jgit.patch.FileHeader; + import org.eclipse.jgit.patch.HunkHeader; + import org.eclipse.jgit.patch.Patch; + import org.eclipse.jgit.util.FileUtils; ++import org.eclipse.jgit.util.RawParseUtils; ++import org.eclipse.jgit.util.SystemReader; ++ ++import static org.eclipse.jgit.diff.DiffEntry.ChangeType.ADD; ++import static org.eclipse.jgit.diff.DiffEntry.ChangeType.COPY; ++import static org.eclipse.jgit.diff.DiffEntry.ChangeType.DELETE; ++import static org.eclipse.jgit.diff.DiffEntry.ChangeType.MODIFY; ++import static org.eclipse.jgit.diff.DiffEntry.ChangeType.RENAME; + + /** + * Apply a patch to files and/or to the index. +@@ -78,6 +91,7 @@ + @Override + public ApplyResult call() throws GitAPIException, PatchFormatException, + PatchApplyException { ++ Result result = new Result(); + checkCallable(); + ApplyResult r = new ApplyResult(); + try { +@@ -89,29 +103,33 @@ + } + if (!p.getErrors().isEmpty()) + throw new PatchFormatException(p.getErrors()); ++ FileModeCache directoryCache = new FileModeCache(repo); + for (FileHeader fh : p.getFiles()) { + ChangeType type = fh.getChangeType(); + File f = null; ++ if (!verifyExistence(fh, new File(repo.getWorkTree(), fh.getOldPath()), new File(repo.getWorkTree(), fh.getNewPath()), result)) { ++ continue; ++ } + switch (type) { + case ADD: +- f = getFile(fh.getNewPath(), true); ++ f = getFile(fh.getNewPath(), true, directoryCache); + apply(f, fh); + break; + case MODIFY: +- f = getFile(fh.getOldPath(), false); ++ f = getFile(fh.getOldPath(), false, directoryCache); + apply(f, fh); + break; + case DELETE: +- f = getFile(fh.getOldPath(), false); ++ f = getFile(fh.getOldPath(), false, directoryCache); + if (!f.delete()) + throw new PatchApplyException(MessageFormat.format( + JGitText.get().cannotDeleteFile, f)); + break; + case RENAME: +- f = getFile(fh.getOldPath(), false); +- File dest = getFile(fh.getNewPath(), false); ++ f = getFile(fh.getOldPath(), false, directoryCache); ++ File dest = getFile(fh.getNewPath(), false, directoryCache); + try { +- FileUtils.mkdirs(dest.getParentFile(), true); ++ directoryCache.safeCreateParentDirectory(fh.getNewPath(), dest.getParentFile(), false); + FileUtils.rename(f, dest, + StandardCopyOption.ATOMIC_MOVE); + } catch (IOException e) { +@@ -121,9 +139,9 @@ + apply(dest, fh); + break; + case COPY: +- f = getFile(fh.getOldPath(), false); +- File target = getFile(fh.getNewPath(), false); +- FileUtils.mkdirs(target.getParentFile(), true); ++ f = getFile(fh.getOldPath(), false, directoryCache); ++ File target = getFile(fh.getNewPath(), false, directoryCache); ++ directoryCache.safeCreateParentDirectory(fh.getNewPath(), target.getParentFile(), false); + Files.copy(f.toPath(), target.toPath()); + apply(target, fh); + } +@@ -137,13 +155,122 @@ + return r; + } + +- private File getFile(String path, boolean create) ++ /** ++ * A wrapper for returning both the applied tree ID and the applied files ++ * list, as well as file specific errors. ++ * ++ * @since 6.3 ++ */ ++ public static class Result { ++ ++ /** ++ * A wrapper for a patch applying error that affects a given file. ++ * ++ * @since 6.6 ++ */ ++ // TODO(ms): rename this class in next major release ++ @SuppressWarnings("JavaLangClash") ++ public static class Error { ++ ++ private String msg; ++ private String oldFileName; ++ private @Nullable HunkHeader hh; ++ ++ private Error(String msg, String oldFileName, ++ @Nullable HunkHeader hh) { ++ this.msg = msg; ++ this.oldFileName = oldFileName; ++ this.hh = hh; ++ } ++ ++ @Override ++ public String toString() { ++ if (hh != null) { ++ return MessageFormat.format(JGitText.get().patchApplyErrorWithHunk, ++ oldFileName, hh, msg); ++ } ++ return MessageFormat.format(JGitText.get().patchApplyErrorWithoutHunk, ++ oldFileName, msg); ++ } ++ ++ } ++ ++ private ObjectId treeId; ++ ++ private List paths; ++ ++ private List errors = new ArrayList<>(); ++ ++ /** ++ * Get modified paths ++ * ++ * @return List of modified paths. ++ */ ++ public List getPaths() { ++ return paths; ++ } ++ ++ /** ++ * Get tree ID ++ * ++ * @return The applied tree ID. ++ */ ++ public ObjectId getTreeId() { ++ return treeId; ++ } ++ ++ /** ++ * Get errors ++ * ++ * @return Errors occurred while applying the patch. ++ * ++ * @since 6.6 ++ */ ++ public List getErrors() { ++ return errors; ++ } ++ ++ private void addError(String msg,String oldFileName, @Nullable HunkHeader hh) { ++ errors.add(new Error(msg, oldFileName, hh)); ++ } ++ } ++ ++ private boolean verifyExistence(FileHeader fh, File src, File dest, ++ Result result) throws IOException { ++ boolean isValid = true; ++ boolean srcShouldExist = Arrays.asList(new ChangeType[]{MODIFY, DELETE, RENAME, COPY}) ++ .contains(fh.getChangeType()); ++ boolean destShouldNotExist = Arrays.asList(new ChangeType[]{ADD, RENAME, COPY}) ++ .contains(fh.getChangeType()); ++ if (srcShouldExist && !validGitPath(fh.getOldPath())) { ++ result.addError(JGitText.get().applyPatchSourceInvalid, ++ fh.getOldPath(), null); ++ isValid = false; ++ } ++ if (destShouldNotExist && !validGitPath(fh.getNewPath())) { ++ result.addError(JGitText.get().applyPatchDestInvalid, ++ fh.getNewPath(), null); ++ isValid = false; ++ } ++ return isValid; ++ } ++ ++ private boolean validGitPath(String path) { ++ try { ++ SystemReader.getInstance().checkPath(path); ++ return true; ++ } catch (CorruptObjectException e) { ++ return false; ++ } ++ } ++ ++ private File getFile(String path, boolean create, FileModeCache directoryCache) + throws PatchApplyException { + File f = new File(getRepository().getWorkTree(), path); + if (create) + try { + File parent = f.getParentFile(); +- FileUtils.mkdirs(parent, true); ++ directoryCache.safeCreateParentDirectory(path, parent, false); + FileUtils.createNewFile(f); + } catch (IOException e) { + throw new PatchApplyException(MessageFormat.format( +--- jgit-5.11.0.202103091610-r/org.eclipse.jgit/src/org/eclipse/jgit/api/CheckoutCommand.java 2023-10-10 15:45:07.523229821 +0200 ++++ jgit-5.11.0.202103091610-r/org.eclipse.jgit/src/org/eclipse/jgit/api/CheckoutCommand.java 2023-10-10 16:04:27.644432299 +0200 +@@ -28,6 +28,7 @@ + import org.eclipse.jgit.api.errors.JGitInternalException; + import org.eclipse.jgit.api.errors.RefAlreadyExistsException; + import org.eclipse.jgit.api.errors.RefNotFoundException; ++import org.eclipse.jgit.dircache.Checkout; + import org.eclipse.jgit.dircache.DirCache; + import org.eclipse.jgit.dircache.DirCacheCheckout; + import org.eclipse.jgit.dircache.DirCacheCheckout.CheckoutMetadata; +@@ -411,6 +412,7 @@ + protected CheckoutCommand checkoutPaths() throws IOException, + RefNotFoundException { + actuallyModifiedPaths = new HashSet<>(); ++ Checkout checkout = new Checkout(repo).setRecursiveDeletion(true); + DirCache dc = repo.lockDirCache(); + try (RevWalk revWalk = new RevWalk(repo); + TreeWalk treeWalk = new TreeWalk(repo, +@@ -419,10 +421,10 @@ + if (!checkoutAllPaths) + treeWalk.setFilter(PathFilterGroup.createFromStrings(paths)); + if (isCheckoutIndex()) +- checkoutPathsFromIndex(treeWalk, dc); ++ checkoutPathsFromIndex(treeWalk, dc, checkout); + else { + RevCommit commit = revWalk.parseCommit(getStartPointObjectId()); +- checkoutPathsFromCommit(treeWalk, dc, commit); ++ checkoutPathsFromCommit(treeWalk, dc, commit, checkout); + } + } finally { + try { +@@ -439,7 +441,8 @@ + return this; + } + +- private void checkoutPathsFromIndex(TreeWalk treeWalk, DirCache dc) ++ private void checkoutPathsFromIndex(TreeWalk treeWalk, DirCache dc, ++ Checkout checkout) + throws IOException { + DirCacheIterator dci = new DirCacheIterator(dc); + treeWalk.addTree(dci); +@@ -465,8 +468,9 @@ + if (stage > DirCacheEntry.STAGE_0) { + if (checkoutStage != null) { + if (stage == checkoutStage.number) { +- checkoutPath(ent, r, new CheckoutMetadata( +- eolStreamType, filterCommand)); ++ checkoutPath(ent, r, checkout, path, ++ new CheckoutMetadata(eolStreamType, ++ filterCommand)); + actuallyModifiedPaths.add(path); + } + } else { +@@ -475,7 +479,8 @@ + throw new JGitInternalException(e.getMessage(), e); + } + } else { +- checkoutPath(ent, r, new CheckoutMetadata(eolStreamType, ++ checkoutPath(ent, r, checkout, path, ++ new CheckoutMetadata(eolStreamType, + filterCommand)); + actuallyModifiedPaths.add(path); + } +@@ -488,7 +493,7 @@ + } + + private void checkoutPathsFromCommit(TreeWalk treeWalk, DirCache dc, +- RevCommit commit) throws IOException { ++ RevCommit commit, Checkout checkout) throws IOException { + treeWalk.addTree(commit.getTree()); + final ObjectReader r = treeWalk.getObjectReader(); + DirCacheEditor editor = dc.editor(); +@@ -510,7 +515,7 @@ + } + ent.setObjectId(blobId); + ent.setFileMode(mode); +- checkoutPath(ent, r, ++ checkoutPath(ent, r, checkout, path, + new CheckoutMetadata(eolStreamType, filterCommand)); + actuallyModifiedPaths.add(path); + } +@@ -520,10 +525,9 @@ + } + + private void checkoutPath(DirCacheEntry entry, ObjectReader reader, +- CheckoutMetadata checkoutMetadata) { ++ Checkout checkout, String path, CheckoutMetadata checkoutMetadata) { + try { +- DirCacheCheckout.checkoutEntry(repo, entry, reader, true, +- checkoutMetadata); ++ checkout.checkout(entry, checkoutMetadata, reader, path); + } catch (IOException e) { + throw new JGitInternalException(MessageFormat.format( + JGitText.get().checkoutConflictWithFile, +--- jgit-5.11.0.202103091610-r/org.eclipse.jgit/src/org/eclipse/jgit/api/StashApplyCommand.java 2023-10-10 15:45:07.526563177 +0200 ++++ jgit-5.11.0.202103091610-r/org.eclipse.jgit/src/org/eclipse/jgit/api/StashApplyCommand.java 2023-10-10 16:04:27.644432299 +0200 +@@ -23,6 +23,7 @@ + import org.eclipse.jgit.api.errors.NoHeadException; + import org.eclipse.jgit.api.errors.StashApplyFailureException; + import org.eclipse.jgit.api.errors.WrongRepositoryStateException; ++import org.eclipse.jgit.dircache.Checkout; + import org.eclipse.jgit.dircache.DirCache; + import org.eclipse.jgit.dircache.DirCacheBuilder; + import org.eclipse.jgit.dircache.DirCacheCheckout; +@@ -345,6 +346,7 @@ + private void resetUntracked(RevTree tree) throws CheckoutConflictException, + IOException { + Set actuallyModifiedPaths = new HashSet<>(); ++ Checkout checkout = new Checkout(repo).setRecursiveDeletion(true); + // TODO maybe NameConflictTreeWalk ? + try (TreeWalk walk = new TreeWalk(repo)) { + walk.addTree(tree); +@@ -368,17 +370,17 @@ + + FileTreeIterator fIter = walk + .getTree(1, FileTreeIterator.class); ++ String gitPath = entry.getPathString(); + if (fIter != null) { + if (fIter.isModified(entry, true, reader)) { + // file exists and is dirty +- throw new CheckoutConflictException( +- entry.getPathString()); ++ throw new CheckoutConflictException(gitPath); + } + } + +- checkoutPath(entry, reader, ++ checkoutPath(entry, gitPath, reader, checkout, + new CheckoutMetadata(eolStreamType, null)); +- actuallyModifiedPaths.add(entry.getPathString()); ++ actuallyModifiedPaths.add(gitPath); + } + } finally { + if (!actuallyModifiedPaths.isEmpty()) { +@@ -388,11 +390,11 @@ + } + } + +- private void checkoutPath(DirCacheEntry entry, ObjectReader reader, +- CheckoutMetadata checkoutMetadata) { ++ private void checkoutPath(DirCacheEntry entry, String gitPath, ++ ObjectReader reader, ++ Checkout checkout, CheckoutMetadata checkoutMetadata) { + try { +- DirCacheCheckout.checkoutEntry(repo, entry, reader, true, +- checkoutMetadata); ++ checkout.checkout(entry, checkoutMetadata, reader, gitPath); + } catch (IOException e) { + throw new JGitInternalException(MessageFormat.format( + JGitText.get().checkoutConflictWithFile, +--- jgit-5.11.0.202103091610-r/org.eclipse.jgit/src/org/eclipse/jgit/dircache/Checkout.java 1970-01-01 01:00:00.000000000 +0100 ++++ jgit-5.11.0.202103091610-r/org.eclipse.jgit/src/org/eclipse/jgit/dircache/Checkout.java 2023-10-10 16:04:27.647765655 +0200 +@@ -0,0 +1,238 @@ ++/* ++ * Copyright (C) 2023, Thomas Wolf and others ++ * ++ * This program and the accompanying materials are made available under the ++ * terms of the Eclipse Distribution License v. 1.0 which is available at ++ * https://www.eclipse.org/org/documents/edl-v10.php. ++ * ++ * SPDX-License-Identifier: BSD-3-Clause ++ */ ++package org.eclipse.jgit.dircache; ++ ++import java.io.File; ++import java.io.FileOutputStream; ++import java.io.IOException; ++import java.nio.file.Files; ++import java.nio.file.LinkOption; ++import java.nio.file.StandardCopyOption; ++import java.text.MessageFormat; ++ ++import org.eclipse.jgit.annotations.NonNull; ++import org.eclipse.jgit.dircache.DirCacheCheckout.CheckoutMetadata; ++import org.eclipse.jgit.internal.JGitText; ++import org.eclipse.jgit.lib.FileMode; ++import org.eclipse.jgit.lib.FileModeCache; ++import org.eclipse.jgit.lib.ObjectLoader; ++import org.eclipse.jgit.lib.ObjectReader; ++import org.eclipse.jgit.lib.Repository; ++import org.eclipse.jgit.lib.CoreConfig.EolStreamType; ++import org.eclipse.jgit.lib.CoreConfig.SymLinks; ++import org.eclipse.jgit.lib.FileModeCache.CacheItem; ++import org.eclipse.jgit.treewalk.WorkingTreeOptions; ++import org.eclipse.jgit.util.FS; ++import org.eclipse.jgit.util.FileUtils; ++import org.eclipse.jgit.util.RawParseUtils; ++ ++/** ++ * An object that can be used to check out many files. ++ * ++ * @since 6.6.1 ++ */ ++public class Checkout { ++ ++ private final FileModeCache cache; ++ ++ private final WorkingTreeOptions options; ++ ++ private boolean recursiveDelete; ++ ++ /** ++ * Creates a new {@link Checkout} for checking out from the given ++ * repository. ++ * ++ * @param repo ++ * the {@link Repository} to check out from ++ */ ++ public Checkout(@NonNull Repository repo) { ++ this(repo, null); ++ } ++ ++ /** ++ * Creates a new {@link Checkout} for checking out from the given ++ * repository. ++ * ++ * @param repo ++ * the {@link Repository} to check out from ++ * @param options ++ * the {@link WorkingTreeOptions} to use; if {@code null}, ++ * read from the {@code repo} config when this object is ++ * created ++ */ ++ public Checkout(@NonNull Repository repo, WorkingTreeOptions options) { ++ this.cache = new FileModeCache(repo); ++ this.options = options != null ? options ++ : repo.getConfig().get(WorkingTreeOptions.KEY); ++ } ++ ++ /** ++ * Retrieves the {@link WorkingTreeOptions} of the repository that are ++ * used. ++ * ++ * @return the {@link WorkingTreeOptions} ++ */ ++ public WorkingTreeOptions getWorkingTreeOptions() { ++ return options; ++ } ++ ++ /** ++ * Defines whether directories that are in the way of the file to be checked ++ * out shall be deleted recursively. ++ * ++ * @param recursive ++ * whether to delete such directories recursively ++ * @return {@code this} ++ */ ++ public Checkout setRecursiveDeletion(boolean recursive) { ++ this.recursiveDelete = recursive; ++ return this; ++ } ++ ++ /** ++ * Ensure that the given parent directory exists, and cache the information ++ * that gitPath refers to a file. ++ * ++ * @param gitPath ++ * of the file to be written ++ * @param parentDir ++ * directory in which the file shall be placed, assumed to be the ++ * parent of the {@code gitPath} ++ * @param makeSpace ++ * whether to delete a possibly existing file at ++ * {@code parentDir} ++ * @throws IOException ++ * if the directory cannot be created, if necessary ++ */ ++ public void safeCreateParentDirectory(String gitPath, File parentDir, ++ boolean makeSpace) throws IOException { ++ cache.safeCreateParentDirectory(gitPath, parentDir, makeSpace); ++ } ++ ++ /** ++ * Checks out the gitlink given by the {@link DirCacheEntry}. ++ * ++ * @param entry ++ * {@link DirCacheEntry} to check out ++ * @param gitPath ++ * the git path of the entry, if known already; otherwise ++ * {@code null} and it's read from the entry itself ++ * @throws IOException ++ * if the gitlink cannot be checked out ++ */ ++ public void checkoutGitlink(DirCacheEntry entry, String gitPath) ++ throws IOException { ++ FS fs = cache.getRepository().getFS(); ++ File workingTree = cache.getRepository().getWorkTree(); ++ String path = gitPath != null ? gitPath : entry.getPathString(); ++ File gitlinkDir = new File(workingTree, path); ++ File parentDir = gitlinkDir.getParentFile(); ++ CacheItem cachedParent = cache.safeCreateDirectory(path, parentDir, ++ false); ++ FileUtils.mkdirs(gitlinkDir, true); ++ cachedParent.insert(path.substring(path.lastIndexOf('/') + 1), ++ FileMode.GITLINK); ++ entry.setLastModified(fs.lastModifiedInstant(gitlinkDir)); ++ } ++ ++ /** ++ * Checks out the file given by the {@link DirCacheEntry}. ++ * ++ * @param entry ++ * {@link DirCacheEntry} to check out ++ * @param metadata ++ * {@link CheckoutMetadata} to use for CR/LF handling and ++ * smudge filtering ++ * @param reader ++ * {@link ObjectReader} to use ++ * @param gitPath ++ * the git path of the entry, if known already; otherwise ++ * {@code null} and it's read from the entry itself ++ * @throws IOException ++ * if the file cannot be checked out ++ */ ++ public void checkout(DirCacheEntry entry, CheckoutMetadata metadata, ++ ObjectReader reader, String gitPath) throws IOException { ++ if (metadata == null) { ++ metadata = CheckoutMetadata.EMPTY; ++ } ++ FS fs = cache.getRepository().getFS(); ++ ObjectLoader ol = reader.open(entry.getObjectId()); ++ String path = gitPath != null ? gitPath : entry.getPathString(); ++ File f = new File(cache.getRepository().getWorkTree(), path); ++ File parentDir = f.getParentFile(); ++ CacheItem cachedParent = cache.safeCreateDirectory(path, parentDir, ++ true); ++ if (entry.getFileMode() == FileMode.SYMLINK ++ && options.getSymLinks() == SymLinks.TRUE) { ++ byte[] bytes = ol.getBytes(); ++ String target = RawParseUtils.decode(bytes); ++ if (recursiveDelete && Files.isDirectory(f.toPath(), ++ LinkOption.NOFOLLOW_LINKS)) { ++ FileUtils.delete(f, FileUtils.RECURSIVE); ++ } ++ fs.createSymLink(f, target); ++ cachedParent.insert(f.getName(), FileMode.SYMLINK); ++ entry.setLength(bytes.length); ++ entry.setLastModified(fs.lastModifiedInstant(f)); ++ return; ++ } ++ ++ String name = f.getName(); ++ if (name.length() > 200) { ++ name = name.substring(0, 200); ++ } ++ File tmpFile = File.createTempFile("._" + name, null, parentDir); //$NON-NLS-1$ ++ ++ DirCacheCheckout.getContent(cache.getRepository(), path, metadata, ol, ++ options, ++ new FileOutputStream(tmpFile)); ++ ++ // The entry needs to correspond to the on-disk file size. If the ++ // content was filtered (either by autocrlf handling or smudge ++ // filters) ask the file system again for the length. Otherwise the ++ // object loader knows the size ++ if (metadata.eolStreamType == EolStreamType.DIRECT ++ && metadata.smudgeFilterCommand == null) { ++ entry.setLength(ol.getSize()); ++ } else { ++ entry.setLength(tmpFile.length()); ++ } ++ ++ if (options.isFileMode() && fs.supportsExecute()) { ++ if (FileMode.EXECUTABLE_FILE.equals(entry.getRawMode())) { ++ if (!fs.canExecute(tmpFile)) ++ fs.setExecute(tmpFile, true); ++ } else { ++ if (fs.canExecute(tmpFile)) ++ fs.setExecute(tmpFile, false); ++ } ++ } ++ try { ++ if (recursiveDelete && Files.isDirectory(f.toPath(), ++ LinkOption.NOFOLLOW_LINKS)) { ++ FileUtils.delete(f, FileUtils.RECURSIVE); ++ } ++ FileUtils.rename(tmpFile, f, StandardCopyOption.ATOMIC_MOVE); ++ cachedParent.remove(f.getName()); ++ } catch (IOException e) { ++ throw new IOException( ++ MessageFormat.format(JGitText.get().renameFileFailed, ++ tmpFile.getPath(), f.getPath()), ++ e); ++ } finally { ++ if (tmpFile.exists()) { ++ FileUtils.delete(tmpFile); ++ } ++ } ++ entry.setLastModified(fs.lastModifiedInstant(f)); ++ } ++} +\ No newline at end of file +--- jgit-5.11.0.202103091610-r/org.eclipse.jgit/src/org/eclipse/jgit/dircache/DirCacheCheckout.java 2023-10-10 15:45:07.529896533 +0200 ++++ jgit-5.11.0.202103091610-r/org.eclipse.jgit/src/org/eclipse/jgit/dircache/DirCacheCheckout.java 2023-10-10 16:39:28.708642256 +0200 +@@ -18,10 +18,8 @@ + import static org.eclipse.jgit.treewalk.TreeWalk.OperationType.CHECKOUT_OP; + + import java.io.File; +-import java.io.FileOutputStream; + import java.io.IOException; + import java.io.OutputStream; +-import java.nio.file.StandardCopyOption; + import java.text.MessageFormat; + import java.time.Instant; + import java.util.ArrayList; +@@ -47,7 +45,6 @@ + import org.eclipse.jgit.lib.Constants; + import org.eclipse.jgit.lib.CoreConfig.AutoCRLF; + import org.eclipse.jgit.lib.CoreConfig.EolStreamType; +-import org.eclipse.jgit.lib.CoreConfig.SymLinks; + import org.eclipse.jgit.lib.FileMode; + import org.eclipse.jgit.lib.NullProgressMonitor; + import org.eclipse.jgit.lib.ObjectChecker; +@@ -67,7 +64,6 @@ + import org.eclipse.jgit.treewalk.filter.PathFilter; + import org.eclipse.jgit.util.FS; + import org.eclipse.jgit.util.FS.ExecutionResult; +-import org.eclipse.jgit.util.FileUtils; + import org.eclipse.jgit.util.IntList; + import org.eclipse.jgit.util.RawParseUtils; + import org.eclipse.jgit.util.SystemReader; +@@ -142,6 +138,8 @@ + + private boolean performingCheckout; + ++ private Checkout checkout; ++ + private ProgressMonitor monitor = NullProgressMonitor.INSTANCE; + + /** +@@ -492,6 +490,7 @@ + CheckoutConflictException, IndexWriteException, CanceledException { + toBeDeleted.clear(); + try (ObjectReader objectReader = repo.getObjectDatabase().newReader()) { ++ checkout = new Checkout(repo, null); + if (headCommitTree != null) + preScanTwoTrees(); + else +@@ -558,9 +557,9 @@ + CheckoutMetadata meta = e.getValue(); + DirCacheEntry entry = dc.getEntry(path); + if (FileMode.GITLINK.equals(entry.getRawMode())) { +- checkoutGitlink(path, entry); ++ checkout.checkoutGitlink(entry, path); + } else { +- checkoutEntry(repo, entry, objectReader, false, meta); ++ checkout.checkout(entry, meta, objectReader, path); + } + e = null; + +@@ -595,8 +594,8 @@ + break; + } + if (entry.getStage() == DirCacheEntry.STAGE_3) { +- checkoutEntry(repo, entry, objectReader, false, +- null); ++ checkout.checkout(entry, null, objectReader, ++ conflict); + break; + } + ++entryIdx; +@@ -619,14 +618,6 @@ + return toBeDeleted.isEmpty(); + } + +- private void checkoutGitlink(String path, DirCacheEntry entry) +- throws IOException { +- File gitlinkDir = new File(repo.getWorkTree(), path); +- FileUtils.mkdirs(gitlinkDir, true); +- FS fs = repo.getFS(); +- entry.setLastModified(fs.lastModifiedInstant(gitlinkDir)); +- } +- + private static ArrayList filterOut(ArrayList strings, + IntList indicesToRemove) { + int n = indicesToRemove.size(); +@@ -1225,10 +1216,11 @@ + if (force) { + if (f == null || f.isModified(e, true, walk.getObjectReader())) { + kept.add(path); +- checkoutEntry(repo, e, walk.getObjectReader(), false, ++ checkout.checkout(e, + new CheckoutMetadata(walk.getEolStreamType(CHECKOUT_OP), + walk.getFilterCommand( +- Constants.ATTR_FILTER_TYPE_SMUDGE))); ++ Constants.ATTR_FILTER_TYPE_SMUDGE)), ++ walk.getObjectReader(), path); + } + } + } +@@ -1453,76 +1445,9 @@ + public static void checkoutEntry(Repository repo, DirCacheEntry entry, + ObjectReader or, boolean deleteRecursive, + CheckoutMetadata checkoutMetadata) throws IOException { +- if (checkoutMetadata == null) +- checkoutMetadata = CheckoutMetadata.EMPTY; +- ObjectLoader ol = or.open(entry.getObjectId()); +- File f = new File(repo.getWorkTree(), entry.getPathString()); +- File parentDir = f.getParentFile(); +- if (parentDir.isFile()) { +- FileUtils.delete(parentDir); +- } +- FileUtils.mkdirs(parentDir, true); +- FS fs = repo.getFS(); +- WorkingTreeOptions opt = repo.getConfig().get(WorkingTreeOptions.KEY); +- if (entry.getFileMode() == FileMode.SYMLINK +- && opt.getSymLinks() == SymLinks.TRUE) { +- byte[] bytes = ol.getBytes(); +- String target = RawParseUtils.decode(bytes); +- if (deleteRecursive && f.isDirectory()) { +- FileUtils.delete(f, FileUtils.RECURSIVE); +- } +- fs.createSymLink(f, target); +- entry.setLength(bytes.length); +- entry.setLastModified(fs.lastModifiedInstant(f)); +- return; +- } +- +- String name = f.getName(); +- if (name.length() > 200) { +- name = name.substring(0, 200); +- } +- File tmpFile = File.createTempFile( +- "._" + name, null, parentDir); //$NON-NLS-1$ +- +- getContent(repo, entry.getPathString(), checkoutMetadata, ol, opt, +- new FileOutputStream(tmpFile)); +- +- // The entry needs to correspond to the on-disk filesize. If the content +- // was filtered (either by autocrlf handling or smudge filters) ask the +- // filesystem again for the length. Otherwise the objectloader knows the +- // size +- if (checkoutMetadata.eolStreamType == EolStreamType.DIRECT +- && checkoutMetadata.smudgeFilterCommand == null) { +- entry.setLength(ol.getSize()); +- } else { +- entry.setLength(tmpFile.length()); +- } +- +- if (opt.isFileMode() && fs.supportsExecute()) { +- if (FileMode.EXECUTABLE_FILE.equals(entry.getRawMode())) { +- if (!fs.canExecute(tmpFile)) +- fs.setExecute(tmpFile, true); +- } else { +- if (fs.canExecute(tmpFile)) +- fs.setExecute(tmpFile, false); +- } +- } +- try { +- if (deleteRecursive && f.isDirectory()) { +- FileUtils.delete(f, FileUtils.RECURSIVE); +- } +- FileUtils.rename(tmpFile, f, StandardCopyOption.ATOMIC_MOVE); +- } catch (IOException e) { +- throw new IOException( +- MessageFormat.format(JGitText.get().renameFileFailed, +- tmpFile.getPath(), f.getPath()), +- e); +- } finally { +- if (tmpFile.exists()) { +- FileUtils.delete(tmpFile); +- } +- } +- entry.setLastModified(fs.lastModifiedInstant(f)); ++ Checkout checkout = new Checkout(repo, null) ++ .setRecursiveDeletion(deleteRecursive); ++ checkout.checkout(entry, checkoutMetadata, or, null); + } + + /** +--- jgit-5.11.0.202103091610-r/org.eclipse.jgit/src/org/eclipse/jgit/internal/JGitText.java 2023-10-10 15:45:07.533229888 +0200 ++++ jgit-5.11.0.202103091610-r/org.eclipse.jgit/src/org/eclipse/jgit/internal/JGitText.java 2023-10-10 16:18:44.090214524 +0200 +@@ -41,6 +41,8 @@ + /***/ public String aNewObjectIdIsRequired; + /***/ public String anExceptionOccurredWhileTryingToAddTheIdOfHEAD; + /***/ public String anSSHSessionHasBeenAlreadyCreated; ++ /***/ public String applyPatchDestInvalid; ++ /***/ public String applyPatchSourceInvalid; + /***/ public String applyingCommit; + /***/ public String archiveFormatAlreadyAbsent; + /***/ public String archiveFormatAlreadyRegistered; +@@ -550,6 +552,8 @@ + /***/ public String packWriterStatistics; + /***/ public String panicCantRenameIndexFile; + /***/ public String patchApplyException; ++ /***/ public String patchApplyErrorWithHunk; ++ /***/ public String patchApplyErrorWithoutHunk; + /***/ public String patchFormatException; + /***/ public String pathNotConfigured; + /***/ public String peeledLineBeforeRef; +--- jgit-5.11.0.202103091610-r/org.eclipse.jgit/src/org/eclipse/jgit/lib/FileModeCache.java 1970-01-01 01:00:00.000000000 +0100 ++++ jgit-5.11.0.202103091610-r/org.eclipse.jgit/src/org/eclipse/jgit/lib/FileModeCache.java 2023-10-10 16:04:27.647765655 +0200 +@@ -0,0 +1,309 @@ ++/* ++ * Copyright (C) 2023, Thomas Wolf and others ++ * ++ * This program and the accompanying materials are made available under the ++ * terms of the Eclipse Distribution License v. 1.0 which is available at ++ * https://www.eclipse.org/org/documents/edl-v10.php. ++ * ++ * SPDX-License-Identifier: BSD-3-Clause ++ */ ++package org.eclipse.jgit.lib; ++ ++import java.io.File; ++import java.io.IOException; ++import java.nio.file.InvalidPathException; ++import java.nio.file.LinkOption; ++import java.nio.file.Path; ++import java.nio.file.attribute.BasicFileAttributeView; ++import java.nio.file.attribute.BasicFileAttributes; ++import java.util.HashMap; ++import java.util.Map; ++ ++import org.eclipse.jgit.annotations.NonNull; ++import org.eclipse.jgit.util.FS; ++import org.eclipse.jgit.util.FileUtils; ++ ++/** ++ * A hierarchical cache of {@link FileMode}s per git path. ++ * ++ * @since 6.6.1 ++ */ ++public class FileModeCache { ++ ++ @NonNull ++ private final CacheItem root = new CacheItem(FileMode.TREE); ++ ++ @NonNull ++ private final Repository repo; ++ ++ /** ++ * Creates a new {@link FileModeCache} for a {@link Repository}. ++ * ++ * @param repo ++ * {@link Repository} this cache is for ++ */ ++ public FileModeCache(@NonNull Repository repo) { ++ this.repo = repo; ++ } ++ ++ /** ++ * Retrieves the {@link Repository}. ++ * ++ * @return the {@link Repository} this {@link FileModeCache} was created for ++ */ ++ @NonNull ++ public Repository getRepository() { ++ return repo; ++ } ++ ++ /** ++ * Obtains the {@link CacheItem} for the working tree root. ++ * ++ * @return the {@link CacheItem} ++ */ ++ @NonNull ++ public CacheItem getRoot() { ++ return root; ++ } ++ ++ /** ++ * Ensure that the given parent directory exists, and cache the information ++ * that gitPath refers to a file. ++ * ++ * @param gitPath ++ * of the file to be written ++ * @param parentDir ++ * directory in which the file shall be placed, assumed to be the ++ * parent of the {@code gitPath} ++ * @param makeSpace ++ * whether to delete a possibly existing file at ++ * {@code parentDir} ++ * @throws IOException ++ * if the directory cannot be created, if necessary ++ */ ++ public void safeCreateParentDirectory(String gitPath, File parentDir, ++ boolean makeSpace) throws IOException { ++ CacheItem cachedParent = safeCreateDirectory(gitPath, parentDir, ++ makeSpace); ++ cachedParent.remove(gitPath.substring(gitPath.lastIndexOf('/') + 1)); ++ } ++ ++ /** ++ * Ensures the given directory {@code dir} with the given git path exists. ++ * ++ * @param gitPath ++ * of a file to be written ++ * @param dir ++ * directory in which the file shall be placed, assumed to be the ++ * parent of the {@code gitPath} ++ * @param makeSpace ++ * whether to remove a file that already at that name ++ * @return A {@link CacheItem} describing the directory, which is guaranteed ++ * to exist ++ * @throws IOException ++ * if the directory cannot be made to exist at the given ++ * location ++ */ ++ public CacheItem safeCreateDirectory(String gitPath, File dir, ++ boolean makeSpace) throws IOException { ++ FS fs = repo.getFS(); ++ int i = gitPath.lastIndexOf('/'); ++ String parentPath = null; ++ if (i >= 0) { ++ if ((makeSpace && dir.isFile()) || fs.isSymLink(dir)) { ++ FileUtils.delete(dir); ++ } ++ parentPath = gitPath.substring(0, i); ++ deleteSymlinkParent(fs, parentPath, repo.getWorkTree()); ++ } ++ FileUtils.mkdirs(dir, true); ++ CacheItem cachedParent = getRoot(); ++ if (parentPath != null) { ++ cachedParent = add(parentPath, FileMode.TREE); ++ } ++ return cachedParent; ++ } ++ ++ private void deleteSymlinkParent(FS fs, String gitPath, File workingTree) ++ throws IOException { ++ if (!fs.supportsSymlinks()) { ++ return; ++ } ++ String[] parts = gitPath.split("/"); //$NON-NLS-1$ ++ int n = parts.length; ++ CacheItem cached = getRoot(); ++ File p = workingTree; ++ for (int i = 0; i < n; i++) { ++ p = new File(p, parts[i]); ++ CacheItem cachedChild = cached != null ? cached.child(parts[i]) ++ : null; ++ boolean delete = false; ++ if (cachedChild != null) { ++ if (FileMode.SYMLINK.equals(cachedChild.getMode())) { ++ delete = true; ++ } ++ } else { ++ try { ++ Path nioPath = FileUtils.toPath(p); ++ BasicFileAttributes attributes = nioPath.getFileSystem() ++ .provider() ++ .getFileAttributeView(nioPath, ++ BasicFileAttributeView.class, ++ LinkOption.NOFOLLOW_LINKS) ++ .readAttributes(); ++ if (attributes.isSymbolicLink()) { ++ delete = p.isDirectory(); ++ } else if (attributes.isRegularFile()) { ++ break; ++ } ++ } catch (InvalidPathException | IOException e) { ++ // If we can't get the attributes the path does not exist, ++ // or if it does a subsequent mkdirs() will also throw an ++ // exception. ++ break; ++ } ++ } ++ if (delete) { ++ // Deletes the symlink ++ FileUtils.delete(p, FileUtils.SKIP_MISSING); ++ if (cached != null) { ++ cached.remove(parts[i]); ++ } ++ break; ++ } ++ cached = cachedChild; ++ } ++ } ++ ++ /** ++ * Records the given {@link FileMode} for the given git path in the cache. ++ * If an entry already exists for the given path, the previously cached file ++ * mode is overwritten. ++ * ++ * @param gitPath ++ * to cache the {@link FileMode} for ++ * @param finalMode ++ * {@link FileMode} to cache ++ * @return the {@link CacheItem} for the path ++ */ ++ @NonNull ++ private CacheItem add(String gitPath, FileMode finalMode) { ++ if (gitPath.isEmpty()) { ++ throw new IllegalArgumentException(); ++ } ++ String[] parts = gitPath.split("/"); //$NON-NLS-1$ ++ int n = parts.length; ++ int i = 0; ++ CacheItem curr = getRoot(); ++ while (i < n) { ++ CacheItem next = curr.child(parts[i]); ++ if (next == null) { ++ break; ++ } ++ curr = next; ++ i++; ++ } ++ if (i == n) { ++ curr.setMode(finalMode); ++ } else { ++ while (i < n) { ++ curr = curr.insert(parts[i], ++ i + 1 == n ? finalMode : FileMode.TREE); ++ i++; ++ } ++ } ++ return curr; ++ } ++ ++ /** ++ * An item from a {@link FileModeCache}, recording information about a git ++ * path (known from context). ++ */ ++ public static class CacheItem { ++ ++ @NonNull ++ private FileMode mode; ++ ++ private Map children; ++ ++ /** ++ * Creates a new {@link CacheItem}. ++ * ++ * @param mode ++ * {@link FileMode} to cache ++ */ ++ public CacheItem(@NonNull FileMode mode) { ++ this.mode = mode; ++ } ++ ++ /** ++ * Retrieves the cached {@link FileMode}. ++ * ++ * @return the {@link FileMode} ++ */ ++ @NonNull ++ public FileMode getMode() { ++ return mode; ++ } ++ ++ /** ++ * Retrieves an immediate child of this {@link CacheItem} by name. ++ * ++ * @param childName ++ * name of the child to get ++ * @return the {@link CacheItem}, or {@code null} if no such child is ++ * known ++ */ ++ public CacheItem child(String childName) { ++ if (children == null) { ++ return null; ++ } ++ return children.get(childName); ++ } ++ ++ /** ++ * Inserts a new cached {@link FileMode} as an immediate child of this ++ * {@link CacheItem}. If there is already a child with the same name, it ++ * is overwritten. ++ * ++ * @param childName ++ * name of the child to create ++ * @param childMode ++ * {@link FileMode} to cache ++ * @return the new {@link CacheItem} created for the child ++ */ ++ public CacheItem insert(String childName, @NonNull FileMode childMode) { ++ if (!FileMode.TREE.equals(mode)) { ++ throw new IllegalArgumentException(); ++ } ++ if (children == null) { ++ children = new HashMap<>(); ++ } ++ CacheItem newItem = new CacheItem(childMode); ++ children.put(childName, newItem); ++ return newItem; ++ } ++ ++ /** ++ * Removes the immediate child with the given name. ++ * ++ * @param childName ++ * name of the child to remove ++ * @return the previously cached {@link CacheItem}, if any ++ */ ++ public CacheItem remove(String childName) { ++ if (children == null) { ++ return null; ++ } ++ return children.remove(childName); ++ } ++ ++ void setMode(@NonNull FileMode mode) { ++ this.mode = mode; ++ if (!FileMode.TREE.equals(mode)) { ++ children = null; ++ } ++ } ++ } ++ ++} +--- jgit-5.11.0.202103091610-r/org.eclipse.jgit/src/org/eclipse/jgit/merge/ResolveMerger.java 2023-10-10 15:45:07.539896600 +0200 ++++ jgit-5.11.0.202103091610-r/org.eclipse.jgit/src/org/eclipse/jgit/merge/ResolveMerger.java 2023-10-10 16:04:27.647765655 +0200 +@@ -43,10 +43,10 @@ + import org.eclipse.jgit.diff.RawText; + import org.eclipse.jgit.diff.RawTextComparator; + import org.eclipse.jgit.diff.Sequence; ++import org.eclipse.jgit.dircache.Checkout; + import org.eclipse.jgit.dircache.DirCache; + import org.eclipse.jgit.dircache.DirCacheBuildIterator; + import org.eclipse.jgit.dircache.DirCacheBuilder; +-import org.eclipse.jgit.dircache.DirCacheCheckout; + import org.eclipse.jgit.dircache.DirCacheCheckout.CheckoutMetadata; + import org.eclipse.jgit.dircache.DirCacheEntry; + import org.eclipse.jgit.errors.BinaryBlobException; +@@ -75,7 +75,6 @@ + import org.eclipse.jgit.treewalk.WorkingTreeIterator; + import org.eclipse.jgit.treewalk.WorkingTreeOptions; + import org.eclipse.jgit.treewalk.filter.TreeFilter; +-import org.eclipse.jgit.util.FS; + import org.eclipse.jgit.util.LfsFactory; + import org.eclipse.jgit.util.LfsFactory.LfsInputStream; + import org.eclipse.jgit.util.TemporaryBuffer; +@@ -85,6 +84,13 @@ + * A three-way merger performing a content-merge if necessary + */ + public class ResolveMerger extends ThreeWayMerger { ++ ++ /** ++ * {@link Checkout} to use for actually checking out files if ++ * {@link #inCore} is {@code false}. ++ */ ++ private Checkout checkout; ++ + /** + * If the merge fails (means: not stopped because of unresolved conflicts) + * this enum is used to explain why it failed +@@ -314,6 +320,7 @@ + implicitDirCache = true; + workingTreeOptions = local.getConfig().get(WorkingTreeOptions.KEY); + } ++ checkout = new Checkout(nonNullRepo(), workingTreeOptions); + } + + /** +@@ -380,12 +387,15 @@ + for (Map.Entry entry : toBeCheckedOut + .entrySet()) { + DirCacheEntry cacheEntry = entry.getValue(); ++ String gitPath = entry.getKey(); + if (cacheEntry.getFileMode() == FileMode.GITLINK) { + new File(nonNullRepo().getWorkTree(), entry.getKey()).mkdirs(); ++ checkout.checkoutGitlink(cacheEntry, gitPath); + } else { +- DirCacheCheckout.checkoutEntry(db, cacheEntry, reader, false, +- checkoutMetadata.get(entry.getKey())); +- modifiedFiles.add(entry.getKey()); ++ checkout.checkout(cacheEntry, ++ checkoutMetadata.get(entry.getKey()), reader, ++ gitPath); ++ modifiedFiles.add(gitPath); + } + } + } +@@ -415,8 +425,8 @@ + String mpath = mpathsIt.next(); + DirCacheEntry entry = dc.getEntry(mpath); + if (entry != null) { +- DirCacheCheckout.checkoutEntry(db, entry, reader, false, +- checkoutMetadata.get(mpath)); ++ checkout.checkout(entry, checkoutMetadata.get(mpath), ++ reader, mpath); + } + mpathsIt.remove(); + } +@@ -1009,15 +1019,12 @@ + Attributes attributes) + throws FileNotFoundException, IOException { + File workTree = nonNullRepo().getWorkTree(); +- FS fs = nonNullRepo().getFS(); +- File of = new File(workTree, tw.getPathString()); +- File parentFolder = of.getParentFile(); +- if (!fs.exists(parentFolder)) { +- parentFolder.mkdirs(); +- } ++ String gitPath = tw.getPathString(); ++ File of = new File(workTree, gitPath); + EolStreamType streamType = EolStreamTypeUtil.detectStreamType( + OperationType.CHECKOUT_OP, workingTreeOptions, + attributes); ++ checkout.safeCreateParentDirectory(tw.getPathString(), of.getParentFile(), false); + try (OutputStream os = EolStreamTypeUtil.wrapOutputStream( + new BufferedOutputStream(new FileOutputStream(of)), + streamType)) { +@@ -1295,9 +1302,9 @@ + // go into the new index. + checkout(); + +- // All content-merges are successfully done. If we can now write the +- // new index we are on quite safe ground. Even if the checkout of +- // files coming from "theirs" fails the user can work around such ++ // All content-merges are successfully done. If we can now write ++ // the new index we are on quite safe ground. Even if the checkout ++ // of files coming from "theirs" fails the user can work around such + // failures by checking out the index again. + if (!builder.commit()) { + cleanUp(); +--- jgit-5.11.0.202103091610-r/org.eclipse.jgit.junit/src/org/eclipse/jgit/junit/TestRepository.java 2023-10-10 15:45:07.469896126 +0200 ++++ jgit-5.11.0.202103091610-r/org.eclipse.jgit.junit/src/org/eclipse/jgit/junit/TestRepository.java 2023-10-10 16:04:27.641098943 +0200 +@@ -276,6 +276,25 @@ + } + + /** ++ * Construct a symlink mode tree entry. ++ * ++ * @param path ++ * path of the symlink. ++ * @param blob ++ * a blob, previously constructed in the repository. ++ * @return the entry. ++ * @throws Exception ++ * if an error occurred ++ * @since 5.13.3 ++ */ ++ public DirCacheEntry link(String path, RevBlob blob) throws Exception { ++ DirCacheEntry e = new DirCacheEntry(path); ++ e.setFileMode(FileMode.SYMLINK); ++ e.setObjectId(blob); ++ return e; ++ } ++ ++ /** + * Construct a tree from a specific listing of file entries. + * + * @param entries +--- jgit-5.11.0.202103091610-r/org.eclipse.jgit.test/tst/org/eclipse/jgit/dircache/DirCacheEntryTest.java 2023-10-10 15:45:07.509896397 +0200 ++++ jgit-5.11.0.202103091610-r/org.eclipse.jgit.test/tst/org/eclipse/jgit/dircache/DirCacheEntryTest.java 2023-10-10 16:04:27.644432299 +0200 +@@ -46,6 +46,16 @@ + assertFalse(isValidPath("a/")); + assertFalse(isValidPath("ab/cd/ef/")); + assertFalse(isValidPath("a\u0000b")); ++ assertFalse(isValidPath(".git")); ++ assertFalse(isValidPath(".GIT")); ++ assertFalse(isValidPath(".Git")); ++ assertFalse(isValidPath(".git/b")); ++ assertFalse(isValidPath(".GIT/b")); ++ assertFalse(isValidPath(".Git/b")); ++ assertFalse(isValidPath("x/y/.git/z/b")); ++ assertFalse(isValidPath("x/y/.GIT/z/b")); ++ assertFalse(isValidPath("x/y/.Git/z/b")); ++ assertTrue(isValidPath("git/b")); + } + + @SuppressWarnings("unused") +--- jgit-5.11.0.202103091610-r/org.eclipse.jgit.test/tst/org/eclipse/jgit/dircache/InvalidPathCheckoutTest.java 1970-01-01 01:00:00.000000000 +0100 ++++ jgit-5.11.0.202103091610-r/org.eclipse.jgit.test/tst/org/eclipse/jgit/dircache/InvalidPathCheckoutTest.java 2023-10-10 16:04:27.644432299 +0200 +@@ -0,0 +1,61 @@ ++/* ++ * Copyright (C) 2023 Thomas Wolf and others ++ * ++ * This program and the accompanying materials are made available under the ++ * terms of the Eclipse Distribution License v. 1.0 which is available at ++ * https://www.eclipse.org/org/documents/edl-v10.php. ++ * ++ * SPDX-License-Identifier: BSD-3-Clause ++ */ ++package org.eclipse.jgit.dircache; ++ ++import static org.junit.Assert.assertFalse; ++import static org.junit.Assert.assertThrows; ++ ++import java.io.File; ++ ++import org.eclipse.jgit.api.Git; ++import org.eclipse.jgit.api.ResetCommand.ResetType; ++import org.eclipse.jgit.junit.RepositoryTestCase; ++import org.eclipse.jgit.junit.TestRepository; ++import org.eclipse.jgit.lib.FileMode; ++import org.eclipse.jgit.lib.Repository; ++import org.eclipse.jgit.revwalk.RevBlob; ++import org.eclipse.jgit.revwalk.RevCommit; ++import org.junit.Test; ++ ++/** ++ * Tests for checking out with invalid paths. ++ */ ++public class InvalidPathCheckoutTest extends RepositoryTestCase { ++ ++ private DirCacheEntry brokenEntry(String fileName, RevBlob blob) { ++ DirCacheEntry entry = new DirCacheEntry("XXXX/" + fileName); ++ entry.path[0] = '.'; ++ entry.path[1] = 'g'; ++ entry.path[2] = 'i'; ++ entry.path[3] = 't'; ++ entry.setFileMode(FileMode.REGULAR_FILE); ++ entry.setObjectId(blob); ++ return entry; ++ } ++ ++ @Test ++ public void testCheckoutIntoDotGit() throws Exception { ++ try (TestRepository repo = new TestRepository<>(db)) { ++ db.incrementOpen(); ++ // DirCacheEntry does not allow any path component to contain ++ // ".git". C git also forbids this. But what if somebody creates ++ // such an entry explicitly? ++ RevCommit base = repo ++ .commit(repo.tree(brokenEntry("b", repo.blob("test")))); ++ try (Git git = new Git(db)) { ++ assertThrows(InvalidPathException.class, () -> git.reset() ++ .setMode(ResetType.HARD).setRef(base.name()).call()); ++ File b = new File(new File(trash, ".git"), "b"); ++ assertFalse(".git/b should not exist", b.exists()); ++ } ++ } ++ } ++ ++} +--- jgit-5.11.0.202103091610-r/org.eclipse.jgit.test/tst/org/eclipse/jgit/symlinks/DirectoryTest.java 1970-01-01 01:00:00.000000000 +0100 ++++ jgit-5.11.0.202103091610-r/org.eclipse.jgit.test/tst/org/eclipse/jgit/symlinks/DirectoryTest.java 2023-10-10 16:04:27.644432299 +0200 +@@ -0,0 +1,254 @@ ++/* ++ * Copyright (C) 2023 Thomas Wolf and others ++ * ++ * This program and the accompanying materials are made available under the ++ * terms of the Eclipse Distribution License v. 1.0 which is available at ++ * https://www.eclipse.org/org/documents/edl-v10.php. ++ * ++ * SPDX-License-Identifier: BSD-3-Clause ++ */ ++package org.eclipse.jgit.symlinks; ++ ++import static org.junit.Assert.assertFalse; ++import static org.junit.Assert.assertNotNull; ++import static org.junit.Assert.assertTrue; ++ ++import java.io.File; ++import java.io.InputStream; ++import java.nio.charset.StandardCharsets; ++import java.nio.file.Files; ++import java.nio.file.LinkOption; ++import java.nio.file.Path; ++ ++import org.eclipse.jgit.api.ApplyResult; ++import org.eclipse.jgit.api.Git; ++import org.eclipse.jgit.api.ResetCommand.ResetType; ++import org.eclipse.jgit.api.errors.PatchApplyException; ++import org.eclipse.jgit.junit.RepositoryTestCase; ++import org.eclipse.jgit.junit.TestRepository; ++import org.eclipse.jgit.lib.ConfigConstants; ++import org.eclipse.jgit.lib.Repository; ++import org.eclipse.jgit.lib.StoredConfig; ++import org.eclipse.jgit.revwalk.RevCommit; ++import org.eclipse.jgit.util.FS; ++import org.eclipse.jgit.util.FileUtils; ++import org.junit.Assume; ++import org.junit.BeforeClass; ++import org.junit.Test; ++import org.junit.runner.RunWith; ++import org.junit.runners.Parameterized; ++import org.junit.runners.Parameterized.Parameter; ++import org.junit.runners.Parameterized.Parameters; ++ ++@RunWith(Parameterized.class) ++public class DirectoryTest extends RepositoryTestCase { ++ ++ @BeforeClass ++ public static void checkPrecondition() throws Exception { ++ Assume.assumeTrue(FS.DETECTED.supportsSymlinks()); ++ Path tempDir = Files.createTempDirectory("jgit"); ++ try { ++ Path a = tempDir.resolve("a"); ++ Files.write(a, "test".getBytes(StandardCharsets.UTF_8)); ++ Path b = tempDir.resolve("A"); ++ Assume.assumeTrue(Files.exists(b)); ++ } finally { ++ FileUtils.delete(tempDir.toFile(), ++ FileUtils.RECURSIVE | FileUtils.IGNORE_ERRORS); ++ } ++ } ++ ++ @Parameters(name = "core.symlinks={0}") ++ public static Boolean[] parameters() { ++ return new Boolean[] { Boolean.TRUE, Boolean.FALSE }; ++ } ++ ++ @Parameter(0) ++ public boolean useSymlinks; ++ ++ private void checkFiles() throws Exception { ++ File a = new File(trash, "a"); ++ assertTrue("a should be a directory", ++ Files.isDirectory(a.toPath(), LinkOption.NOFOLLOW_LINKS)); ++ File b = new File(a, "b"); ++ assertTrue("a/b should exist", b.isFile()); ++ File x = new File(trash, "x"); ++ assertTrue("x should be a directory", ++ Files.isDirectory(x.toPath(), LinkOption.NOFOLLOW_LINKS)); ++ File y = new File(x, "y"); ++ assertTrue("x/y should exist", y.isFile()); ++ } ++ ++ @Test ++ public void testCheckout() throws Exception { ++ StoredConfig config = db.getConfig(); ++ config.setBoolean(ConfigConstants.CONFIG_CORE_SECTION, null, ++ ConfigConstants.CONFIG_KEY_SYMLINKS, useSymlinks); ++ config.save(); ++ try (TestRepository repo = new TestRepository<>(db)) { ++ db.incrementOpen(); ++ // Create links directly in the git repo, then use a hard reset ++ // to get them into the workspace. ++ RevCommit base = repo.commit( ++ repo.tree( ++ repo.link("A", repo.blob(".git")), ++ repo.file("a/b", repo.blob("test")), ++ repo.file("x/y", repo.blob("test2")))); ++ try (Git git = new Git(db)) { ++ git.reset().setMode(ResetType.HARD).setRef(base.name()).call(); ++ File b = new File(new File(trash, ".git"), "b"); ++ assertFalse(".git/b should not exist", b.exists()); ++ checkFiles(); ++ } ++ } ++ } ++ ++ @Test ++ public void testCheckout2() throws Exception { ++ StoredConfig config = db.getConfig(); ++ config.setBoolean(ConfigConstants.CONFIG_CORE_SECTION, null, ++ ConfigConstants.CONFIG_KEY_SYMLINKS, useSymlinks); ++ config.save(); ++ try (TestRepository repo = new TestRepository<>(db)) { ++ db.incrementOpen(); ++ RevCommit base = repo.commit( ++ repo.tree( ++ repo.link("A/B", repo.blob("../.git")), ++ repo.file("a/b/a/b", repo.blob("test")), ++ repo.file("x/y", repo.blob("test2")))); ++ try (Git git = new Git(db)) { ++ boolean testFiles = true; ++ try { ++ git.reset().setMode(ResetType.HARD).setRef(base.name()) ++ .call(); ++ } catch (Exception e) { ++ if (!useSymlinks) { ++ // There is a file in the middle of the path where we'd ++ // expect a directory. This case is not handled ++ // anywhere. What would be a better reply than an IOE? ++ testFiles = false; ++ } else { ++ throw e; ++ } ++ } ++ File a = new File(new File(trash, ".git"), "a"); ++ assertFalse(".git/a should not exist", a.exists()); ++ if (testFiles) { ++ a = new File(trash, "a"); ++ assertTrue("a should be a directory", Files.isDirectory( ++ a.toPath(), LinkOption.NOFOLLOW_LINKS)); ++ File b = new File(a, "b"); ++ assertTrue("a/b should be a directory", Files.isDirectory( ++ a.toPath(), LinkOption.NOFOLLOW_LINKS)); ++ a = new File(b, "a"); ++ assertTrue("a/b/a should be a directory", Files.isDirectory( ++ a.toPath(), LinkOption.NOFOLLOW_LINKS)); ++ b = new File(a, "b"); ++ assertTrue("a/b/a/b should exist", b.isFile()); ++ File x = new File(trash, "x"); ++ assertTrue("x should be a directory", Files.isDirectory( ++ x.toPath(), LinkOption.NOFOLLOW_LINKS)); ++ File y = new File(x, "y"); ++ assertTrue("x/y should exist", y.isFile()); ++ } ++ } ++ } ++ } ++ ++ @Test ++ public void testMerge() throws Exception { ++ StoredConfig config = db.getConfig(); ++ config.setBoolean(ConfigConstants.CONFIG_CORE_SECTION, null, ++ ConfigConstants.CONFIG_KEY_SYMLINKS, useSymlinks); ++ config.save(); ++ try (TestRepository repo = new TestRepository<>(db)) { ++ db.incrementOpen(); ++ RevCommit base = repo.commit( ++ repo.tree(repo.file("q", repo.blob("test")))); ++ RevCommit side = repo.commit( ++ repo.tree( ++ repo.link("A", repo.blob(".git")), ++ repo.file("a/b", repo.blob("test")), ++ repo.file("x/y", repo.blob("test2")))); ++ try (Git git = new Git(db)) { ++ git.reset().setMode(ResetType.HARD).setRef(base.name()).call(); ++ git.merge().include(side) ++ .setMessage("merged").call(); ++ File b = new File(new File(trash, ".git"), "b"); ++ assertFalse(".git/b should not exist", b.exists()); ++ checkFiles(); ++ } ++ } ++ } ++ ++ @Test ++ public void testMerge2() throws Exception { ++ StoredConfig config = db.getConfig(); ++ config.setBoolean(ConfigConstants.CONFIG_CORE_SECTION, null, ++ ConfigConstants.CONFIG_KEY_SYMLINKS, useSymlinks); ++ config.save(); ++ try (TestRepository repo = new TestRepository<>(db)) { ++ db.incrementOpen(); ++ RevCommit base = repo.commit( ++ repo.tree( ++ repo.file("q", repo.blob("test")), ++ repo.link("A", repo.blob(".git")))); ++ RevCommit side = repo.commit( ++ repo.tree( ++ repo.file("a/b", repo.blob("test")), ++ repo.file("x/y", repo.blob("test2")))); ++ try (Git git = new Git(db)) { ++ git.reset().setMode(ResetType.HARD).setRef(base.name()).call(); ++ git.merge().include(side) ++ .setMessage("merged").call(); ++ File b = new File(new File(trash, ".git"), "b"); ++ assertFalse(".git/b should not exist", b.exists()); ++ checkFiles(); ++ } ++ } ++ } ++ ++ @Test ++ public void testApply() throws Exception { ++ StoredConfig config = db.getConfig(); ++ config.setBoolean(ConfigConstants.CONFIG_CORE_SECTION, null, ++ ConfigConstants.CONFIG_KEY_SYMLINKS, useSymlinks); ++ config.save(); ++ // PatchApplier doesn't do symlinks yet. ++ try (TestRepository repo = new TestRepository<>(db)) { ++ db.incrementOpen(); ++ RevCommit base = repo.commit( ++ repo.tree( ++ repo.file("x", repo.blob("test")), ++ repo.link("A", repo.blob(".git")))); ++ try (Git git = new Git(db)) { ++ boolean testFiles = true; ++ git.reset().setMode(ResetType.HARD).setRef(base.name()).call(); ++ try (InputStream patchStream = this.getClass() ++ .getResourceAsStream("dirtest.patch")) { ++ ApplyResult result = git.apply().setPatch(patchStream).call(); ++ assertNotNull(result); ++ } catch (PatchApplyException e) { ++ if (!useSymlinks) { ++ // There is a file there, so the patch won't apply. ++ // Unclear whether an IOE is the correct response, ++ // though. Probably some negative PatchApplier.Result is ++ // more appropriate. ++ testFiles = false; ++ } else { ++ throw e; ++ } ++ } ++ File b = new File(new File(trash, ".git"), "b"); ++ assertFalse(".git/b should not exist", b.exists()); ++ if (testFiles) { ++ File a = new File(trash, "a"); ++ assertTrue("a should be a directory", ++ Files.isDirectory(a.toPath(), LinkOption.NOFOLLOW_LINKS)); ++ b = new File(a, "b"); ++ assertTrue("a/b should exist", b.isFile()); ++ } ++ } ++ } ++ } ++} +\ No newline at end of file +--- jgit-5.11.0.202103091610-r/org.eclipse.jgit.test/tst-rsrc/org/eclipse/jgit/diff/dotgit2.patch 1970-01-01 01:00:00.000000000 +0100 ++++ jgit-5.11.0.202103091610-r/org.eclipse.jgit.test/tst-rsrc/org/eclipse/jgit/diff/dotgit2.patch 2023-10-10 16:04:27.641098943 +0200 +@@ -0,0 +1,9 @@ ++diff --git a/.GIT/b b/.GIT/b ++new file mode 100644 ++index 0000000..de98044 ++--- /dev/null +++++ b/.git/b ++@@ -0,0 +1,3 @@ +++a +++b +++c +\ No newline at end of file +--- jgit-5.11.0.202103091610-r/org.eclipse.jgit.test/tst-rsrc/org/eclipse/jgit/diff/dotgit.patch 1970-01-01 01:00:00.000000000 +0100 ++++ jgit-5.11.0.202103091610-r/org.eclipse.jgit.test/tst-rsrc/org/eclipse/jgit/diff/dotgit.patch 2023-10-10 16:04:27.641098943 +0200 +@@ -0,0 +1,9 @@ ++diff --git a/.git/b b/.git/b ++new file mode 100644 ++index 0000000..de98044 ++--- /dev/null +++++ b/.git/b ++@@ -0,0 +1,3 @@ +++a +++b +++c +\ No newline at end of file +--- jgit-5.11.0.202103091610-r/org.eclipse.jgit.test/tst-rsrc/org/eclipse/jgit/symlinks/dirtest.patch 1970-01-01 01:00:00.000000000 +0100 ++++ jgit-5.11.0.202103091610-r/org.eclipse.jgit.test/tst-rsrc/org/eclipse/jgit/symlinks/dirtest.patch 2023-10-10 16:04:27.644432299 +0200 +@@ -0,0 +1,9 @@ ++diff --git a/a/b b/a/b ++new file mode 100644 ++index 0000000..de98044 ++--- /dev/null +++++ b/a/b ++@@ -0,0 +1,3 @@ +++a +++b +++c +\ No newline at end of file +--- jgit-5.11.0.202103091610-r/org.eclipse.jgit.test/tst-rsrc/org/eclipse/jgit/symlinks/.gitattributes 1970-01-01 01:00:00.000000000 +0100 ++++ jgit-5.11.0.202103091610-r/org.eclipse.jgit.test/tst-rsrc/org/eclipse/jgit/symlinks/.gitattributes 2023-10-10 16:04:27.641098943 +0200 +@@ -0,0 +1 @@ ++*.patch -crlf diff --git a/jgit-apache-sshd.patch b/jgit-apache-sshd.patch new file mode 100644 index 0000000..46df517 --- /dev/null +++ b/jgit-apache-sshd.patch @@ -0,0 +1,260 @@ +diff -urEbwB jgit-5.11.0.202103091610-r/org.eclipse.jgit.junit.ssh/META-INF/MANIFEST.MF jgit-5.11.0.202103091610-r.new/org.eclipse.jgit.junit.ssh/META-INF/MANIFEST.MF +--- jgit-5.11.0.202103091610-r/org.eclipse.jgit.junit.ssh/META-INF/MANIFEST.MF 2021-03-09 22:10:22.000000000 +0100 ++++ jgit-5.11.0.202103091610-r.new/org.eclipse.jgit.junit.ssh/META-INF/MANIFEST.MF 2021-07-30 12:03:35.087914326 +0200 +@@ -8,31 +8,31 @@ + Bundle-Vendor: %Bundle-Vendor + Bundle-ActivationPolicy: lazy + Bundle-RequiredExecutionEnvironment: JavaSE-1.8 +-Import-Package: org.apache.sshd.common;version="[2.6.0,2.7.0)", +- org.apache.sshd.common.config.keys;version="[2.6.0,2.7.0)", +- org.apache.sshd.common.file.virtualfs;version="[2.6.0,2.7.0)", +- org.apache.sshd.common.helpers;version="[2.6.0,2.7.0)", +- org.apache.sshd.common.io;version="[2.6.0,2.7.0)", +- org.apache.sshd.common.kex;version="[2.6.0,2.7.0)", +- org.apache.sshd.common.keyprovider;version="[2.6.0,2.7.0)", +- org.apache.sshd.common.session;version="[2.6.0,2.7.0)", +- org.apache.sshd.common.signature;version="[2.6.0,2.7.0)", +- org.apache.sshd.common.util.buffer;version="[2.6.0,2.7.0)", +- org.apache.sshd.common.util.logging;version="[2.6.0,2.7.0)", +- org.apache.sshd.common.util.security;version="[2.6.0,2.7.0)", +- org.apache.sshd.common.util.threads;version="[2.6.0,2.7.0)", +- org.apache.sshd.core;version="[2.6.0,2.7.0)", +- org.apache.sshd.server;version="[2.6.0,2.7.0)", +- org.apache.sshd.server.auth;version="[2.6.0,2.7.0)", +- org.apache.sshd.server.auth.gss;version="[2.6.0,2.7.0)", +- org.apache.sshd.server.auth.keyboard;version="[2.6.0,2.7.0)", +- org.apache.sshd.server.auth.password;version="[2.6.0,2.7.0)", +- org.apache.sshd.server.command;version="[2.6.0,2.7.0)", +- org.apache.sshd.server.session;version="[2.6.0,2.7.0)", +- org.apache.sshd.server.shell;version="[2.6.0,2.7.0)", +- org.apache.sshd.server.subsystem;version="[2.6.0,2.7.0)", +- org.apache.sshd.sftp;version="[2.6.0,2.7.0)", +- org.apache.sshd.sftp.server;version="[2.6.0,2.7.0)", ++Import-Package: org.apache.sshd.common;version="[2.7.0,3.0.0)", ++ org.apache.sshd.common.config.keys;version="[2.7.0,3.0.0)", ++ org.apache.sshd.common.file.virtualfs;version="[2.7.0,3.0.0)", ++ org.apache.sshd.common.helpers;version="[2.7.0,3.0.0)", ++ org.apache.sshd.common.io;version="[2.7.0,3.0.0)", ++ org.apache.sshd.common.kex;version="[2.7.0,3.0.0)", ++ org.apache.sshd.common.keyprovider;version="[2.7.0,3.0.0)", ++ org.apache.sshd.common.session;version="[2.7.0,3.0.0)", ++ org.apache.sshd.common.signature;version="[2.7.0,3.0.0)", ++ org.apache.sshd.common.util.buffer;version="[2.7.0,3.0.0)", ++ org.apache.sshd.common.util.logging;version="[2.7.0,3.0.0)", ++ org.apache.sshd.common.util.security;version="[2.7.0,3.0.0)", ++ org.apache.sshd.common.util.threads;version="[2.7.0,3.0.0)", ++ org.apache.sshd.core;version="[2.7.0,3.0.0)", ++ org.apache.sshd.server;version="[2.7.0,3.0.0)", ++ org.apache.sshd.server.auth;version="[2.7.0,3.0.0)", ++ org.apache.sshd.server.auth.gss;version="[2.7.0,3.0.0)", ++ org.apache.sshd.server.auth.keyboard;version="[2.7.0,3.0.0)", ++ org.apache.sshd.server.auth.password;version="[2.7.0,3.0.0)", ++ org.apache.sshd.server.command;version="[2.7.0,3.0.0)", ++ org.apache.sshd.server.session;version="[2.7.0,3.0.0)", ++ org.apache.sshd.server.shell;version="[2.7.0,3.0.0)", ++ org.apache.sshd.server.subsystem;version="[2.7.0,3.0.0)", ++ org.apache.sshd.sftp;version="[2.7.0,3.0.0)", ++ org.apache.sshd.sftp.server;version="[2.7.0,3.0.0)", + org.eclipse.jgit.annotations;version="[5.11.0,5.12.0)", + org.eclipse.jgit.api;version="[5.11.0,5.12.0)", + org.eclipse.jgit.api.errors;version="[5.11.0,5.12.0)", +diff -urEbwB jgit-5.11.0.202103091610-r/org.eclipse.jgit.ssh.apache/META-INF/MANIFEST.MF jgit-5.11.0.202103091610-r.new/org.eclipse.jgit.ssh.apache/META-INF/MANIFEST.MF +--- jgit-5.11.0.202103091610-r/org.eclipse.jgit.ssh.apache/META-INF/MANIFEST.MF 2021-03-09 22:10:22.000000000 +0100 ++++ jgit-5.11.0.202103091610-r.new/org.eclipse.jgit.ssh.apache/META-INF/MANIFEST.MF 2021-07-30 12:03:35.087914326 +0200 +@@ -33,51 +33,51 @@ + org.apache.sshd.client.session, + org.apache.sshd.client.keyverifier" + Import-Package: net.i2p.crypto.eddsa;version="[0.3.0,0.4.0)", +- org.apache.sshd.agent;version="[2.6.0,2.7.0)", +- org.apache.sshd.client;version="[2.6.0,2.7.0)", +- org.apache.sshd.client.auth;version="[2.6.0,2.7.0)", +- org.apache.sshd.client.auth.keyboard;version="[2.6.0,2.7.0)", +- org.apache.sshd.client.auth.password;version="[2.6.0,2.7.0)", +- org.apache.sshd.client.auth.pubkey;version="[2.6.0,2.7.0)", +- org.apache.sshd.client.channel;version="[2.6.0,2.7.0)", +- org.apache.sshd.client.config.hosts;version="[2.6.0,2.7.0)", +- org.apache.sshd.client.config.keys;version="[2.6.0,2.7.0)", +- org.apache.sshd.client.future;version="[2.6.0,2.7.0)", +- org.apache.sshd.client.keyverifier;version="[2.6.0,2.7.0)", +- org.apache.sshd.client.session;version="[2.6.0,2.7.0)", +- org.apache.sshd.client.session.forward;version="[2.6.0,2.7.0)", +- org.apache.sshd.common;version="[2.6.0,2.7.0)", +- org.apache.sshd.common.auth;version="[2.6.0,2.7.0)", +- org.apache.sshd.common.channel;version="[2.6.0,2.7.0)", +- org.apache.sshd.common.compression;version="[2.6.0,2.7.0)", +- org.apache.sshd.common.config.keys;version="[2.6.0,2.7.0)", +- org.apache.sshd.common.config.keys.loader;version="[2.6.0,2.7.0)", +- org.apache.sshd.common.config.keys.loader.openssh.kdf;version="[2.6.0,2.7.0)", +- org.apache.sshd.common.digest;version="[2.6.0,2.7.0)", +- org.apache.sshd.common.forward;version="[2.6.0,2.7.0)", +- org.apache.sshd.common.future;version="[2.6.0,2.7.0)", +- org.apache.sshd.common.helpers;version="[2.6.0,2.7.0)", +- org.apache.sshd.common.io;version="[2.6.0,2.7.0)", +- org.apache.sshd.common.kex;version="[2.6.0,2.7.0)", +- org.apache.sshd.common.keyprovider;version="[2.6.0,2.7.0)", +- org.apache.sshd.common.mac;version="[2.6.0,2.7.0)", +- org.apache.sshd.common.random;version="[2.6.0,2.7.0)", +- org.apache.sshd.common.session;version="[2.6.0,2.7.0)", +- org.apache.sshd.common.session.helpers;version="[2.6.0,2.7.0)", +- org.apache.sshd.common.signature;version="[2.6.0,2.7.0)", +- org.apache.sshd.common.util;version="[2.6.0,2.7.0)", +- org.apache.sshd.common.util.buffer;version="[2.6.0,2.7.0)", +- org.apache.sshd.common.util.closeable;version="[2.6.0,2.7.0)", +- org.apache.sshd.common.util.io;version="[2.6.0,2.7.0)", +- org.apache.sshd.common.util.io.resource;version="[2.6.0,2.7.0)", +- org.apache.sshd.common.util.logging;version="[2.6.0,2.7.0)", +- org.apache.sshd.common.util.net;version="[2.6.0,2.7.0)", +- org.apache.sshd.common.util.security;version="[2.6.0,2.7.0)", +- org.apache.sshd.core;version="[2.6.0,2.7.0)", +- org.apache.sshd.server.auth;version="[2.6.0,2.7.0)", +- org.apache.sshd.sftp;version="[2.6.0,2.7.0)", +- org.apache.sshd.sftp.client;version="[2.6.0,2.7.0)", +- org.apache.sshd.sftp.common;version="[2.6.0,2.7.0)", ++ org.apache.sshd.agent;version="[2.7.0,3.0.0)", ++ org.apache.sshd.client;version="[2.7.0,3.0.0)", ++ org.apache.sshd.client.auth;version="[2.7.0,3.0.0)", ++ org.apache.sshd.client.auth.keyboard;version="[2.7.0,3.0.0)", ++ org.apache.sshd.client.auth.password;version="[2.7.0,3.0.0)", ++ org.apache.sshd.client.auth.pubkey;version="[2.7.0,3.0.0)", ++ org.apache.sshd.client.channel;version="[2.7.0,3.0.0)", ++ org.apache.sshd.client.config.hosts;version="[2.7.0,3.0.0)", ++ org.apache.sshd.client.config.keys;version="[2.7.0,3.0.0)", ++ org.apache.sshd.client.future;version="[2.7.0,3.0.0)", ++ org.apache.sshd.client.keyverifier;version="[2.7.0,3.0.0)", ++ org.apache.sshd.client.session;version="[2.7.0,3.0.0)", ++ org.apache.sshd.client.session.forward;version="[2.7.0,3.0.0)", ++ org.apache.sshd.common;version="[2.7.0,3.0.0)", ++ org.apache.sshd.common.auth;version="[2.7.0,3.0.0)", ++ org.apache.sshd.common.channel;version="[2.7.0,3.0.0)", ++ org.apache.sshd.common.compression;version="[2.7.0,3.0.0)", ++ org.apache.sshd.common.config.keys;version="[2.7.0,3.0.0)", ++ org.apache.sshd.common.config.keys.loader;version="[2.7.0,3.0.0)", ++ org.apache.sshd.common.config.keys.loader.openssh.kdf;version="[2.7.0,3.0.0)", ++ org.apache.sshd.common.digest;version="[2.7.0,3.0.0)", ++ org.apache.sshd.common.forward;version="[2.7.0,3.0.0)", ++ org.apache.sshd.common.future;version="[2.7.0,3.0.0)", ++ org.apache.sshd.common.helpers;version="[2.7.0,3.0.0)", ++ org.apache.sshd.common.io;version="[2.7.0,3.0.0)", ++ org.apache.sshd.common.kex;version="[2.7.0,3.0.0)", ++ org.apache.sshd.common.keyprovider;version="[2.7.0,3.0.0)", ++ org.apache.sshd.common.mac;version="[2.7.0,3.0.0)", ++ org.apache.sshd.common.random;version="[2.7.0,3.0.0)", ++ org.apache.sshd.common.session;version="[2.7.0,3.0.0)", ++ org.apache.sshd.common.session.helpers;version="[2.7.0,3.0.0)", ++ org.apache.sshd.common.signature;version="[2.7.0,3.0.0)", ++ org.apache.sshd.common.util;version="[2.7.0,3.0.0)", ++ org.apache.sshd.common.util.buffer;version="[2.7.0,3.0.0)", ++ org.apache.sshd.common.util.closeable;version="[2.7.0,3.0.0)", ++ org.apache.sshd.common.util.io;version="[2.7.0,3.0.0)", ++ org.apache.sshd.common.util.io.resource;version="[2.7.0,3.0.0)", ++ org.apache.sshd.common.util.logging;version="[2.7.0,3.0.0)", ++ org.apache.sshd.common.util.net;version="[2.7.0,3.0.0)", ++ org.apache.sshd.common.util.security;version="[2.7.0,3.0.0)", ++ org.apache.sshd.core;version="[2.7.0,3.0.0)", ++ org.apache.sshd.server.auth;version="[2.7.0,3.0.0)", ++ org.apache.sshd.sftp;version="[2.7.0,3.0.0)", ++ org.apache.sshd.sftp.client;version="[2.7.0,3.0.0)", ++ org.apache.sshd.sftp.common;version="[2.7.0,3.0.0)", + org.eclipse.jgit.annotations;version="[5.11.0,5.12.0)", + org.eclipse.jgit.errors;version="[5.11.0,5.12.0)", + org.eclipse.jgit.fnmatch;version="[5.11.0,5.12.0)", +diff -urEbwB jgit-5.11.0.202103091610-r/org.eclipse.jgit.ssh.apache/src/org/eclipse/jgit/internal/transport/sshd/JGitClientSession.java jgit-5.11.0.202103091610-r.new/org.eclipse.jgit.ssh.apache/src/org/eclipse/jgit/internal/transport/sshd/JGitClientSession.java +--- jgit-5.11.0.202103091610-r/org.eclipse.jgit.ssh.apache/src/org/eclipse/jgit/internal/transport/sshd/JGitClientSession.java 2021-03-09 22:10:22.000000000 +0100 ++++ jgit-5.11.0.202103091610-r.new/org.eclipse.jgit.ssh.apache/src/org/eclipse/jgit/internal/transport/sshd/JGitClientSession.java 2021-07-30 12:04:40.688349950 +0200 +@@ -133,8 +133,8 @@ + } + + @Override +- protected IoWriteFuture sendIdentification(String ident) +- throws IOException { ++ protected IoWriteFuture sendIdentification(String ident, ++ List extraLines) throws Exception { + StatefulProxyConnector proxy = proxyHandler; + if (proxy != null) { + try { +@@ -142,7 +142,8 @@ + // from the peer only once the initial sendKexInit() following + // this call to sendIdentification() has returned! + proxy.runWhenDone(() -> { +- JGitClientSession.super.sendIdentification(ident); ++ JGitClientSession.super.sendIdentification(ident, ++ extraLines); + return null; + }); + // Called only from the ClientSessionImpl constructor, where the +@@ -154,12 +155,11 @@ + throw new IOException(other.getLocalizedMessage(), other); + } + } +- return super.sendIdentification(ident); ++ return super.sendIdentification(ident, extraLines); + } + + @Override +- protected byte[] sendKexInit() +- throws IOException, GeneralSecurityException { ++ protected byte[] sendKexInit() throws Exception { + StatefulProxyConnector proxy = proxyHandler; + if (proxy != null) { + try { +diff -urEbwB jgit-5.11.0.202103091610-r/org.eclipse.jgit.ssh.apache.test/META-INF/MANIFEST.MF jgit-5.11.0.202103091610-r.new/org.eclipse.jgit.ssh.apache.test/META-INF/MANIFEST.MF +--- jgit-5.11.0.202103091610-r/org.eclipse.jgit.ssh.apache.test/META-INF/MANIFEST.MF 2021-03-09 22:10:22.000000000 +0100 ++++ jgit-5.11.0.202103091610-r.new/org.eclipse.jgit.ssh.apache.test/META-INF/MANIFEST.MF 2021-07-30 12:03:35.087914326 +0200 +@@ -7,18 +7,18 @@ + Bundle-Vendor: %Bundle-Vendor + Bundle-Localization: plugin + Bundle-RequiredExecutionEnvironment: JavaSE-1.8 +-Import-Package: org.apache.sshd.client.config.hosts;version="[2.6.0,2.7.0)", +- org.apache.sshd.common;version="[2.6.0,2.7.0)", +- org.apache.sshd.common.auth;version="[2.6.0,2.7.0)", +- org.apache.sshd.common.config.keys;version="[2.6.0,2.7.0)", +- org.apache.sshd.common.helpers;version="[2.6.0,2.7.0)", +- org.apache.sshd.common.keyprovider;version="[2.6.0,2.7.0)", +- org.apache.sshd.common.session;version="[2.6.0,2.7.0)", +- org.apache.sshd.common.util.net;version="[2.6.0,2.7.0)", +- org.apache.sshd.common.util.security;version="[2.6.0,2.7.0)", +- org.apache.sshd.core;version="[2.6.0,2.7.0)", +- org.apache.sshd.server;version="[2.6.0,2.7.0)", +- org.apache.sshd.server.forward;version="[2.6.0,2.7.0)", ++Import-Package: org.apache.sshd.client.config.hosts;version="[2.7.0,3.0.0)", ++ org.apache.sshd.common;version="[2.7.0,3.0.0)", ++ org.apache.sshd.common.auth;version="[2.7.0,3.0.0)", ++ org.apache.sshd.common.config.keys;version="[2.7.0,3.0.0)", ++ org.apache.sshd.common.helpers;version="[2.7.0,3.0.0)", ++ org.apache.sshd.common.keyprovider;version="[2.7.0,3.0.0)", ++ org.apache.sshd.common.session;version="[2.7.0,3.0.0)", ++ org.apache.sshd.common.util.net;version="[2.7.0,3.0.0)", ++ org.apache.sshd.common.util.security;version="[2.7.0,3.0.0)", ++ org.apache.sshd.core;version="[2.7.0,3.0.0)", ++ org.apache.sshd.server;version="[2.7.0,3.0.0)", ++ org.apache.sshd.server.forward;version="[2.7.0,3.0.0)", + org.eclipse.jgit.api;version="[5.11.0,5.12.0)", + org.eclipse.jgit.api.errors;version="[5.11.0,5.12.0)", + org.eclipse.jgit.internal.transport.sshd.proxy;version="[5.11.0,5.12.0)", +diff -urEbwB jgit-5.11.0.202103091610-r/org.eclipse.jgit.test/META-INF/MANIFEST.MF jgit-5.11.0.202103091610-r.new/org.eclipse.jgit.test/META-INF/MANIFEST.MF +--- jgit-5.11.0.202103091610-r/org.eclipse.jgit.test/META-INF/MANIFEST.MF 2021-03-09 22:10:22.000000000 +0100 ++++ jgit-5.11.0.202103091610-r.new/org.eclipse.jgit.test/META-INF/MANIFEST.MF 2021-07-30 11:58:52.578038135 +0200 +@@ -15,7 +15,6 @@ + org.apache.commons.compress.compressors.bzip2;version="[1.15.0,2.0)", + org.apache.commons.compress.compressors.gzip;version="[1.15.0,2.0)", + org.apache.commons.compress.compressors.xz;version="[1.15.0,2.0)", +- org.assertj.core.api;version="[3.14.0,4.0.0)", + org.eclipse.jgit.annotations;version="[5.11.0,5.12.0)", + org.eclipse.jgit.api;version="[5.11.0,5.12.0)", + org.eclipse.jgit.api.errors;version="[5.11.0,5.12.0)", +diff -urEbwB jgit-5.11.0.202103091610-r/org.eclipse.jgit.test/pom.xml jgit-5.11.0.202103091610-r.new/org.eclipse.jgit.test/pom.xml +--- jgit-5.11.0.202103091610-r/org.eclipse.jgit.test/pom.xml 2021-03-09 22:10:22.000000000 +0100 ++++ jgit-5.11.0.202103091610-r.new/org.eclipse.jgit.test/pom.xml 2021-07-30 11:57:51.365631621 +0200 +@@ -66,11 +66,6 @@ + + + +- org.assertj +- assertj-core +- +- +- + org.mockito + mockito-core + 2.23.0 +Only in jgit-5.11.0.202103091610-r/org.eclipse.jgit.test/tst/org/eclipse/jgit/transport: RequestValidatorTestCase.java diff --git a/jgit-bc-179.patch b/jgit-bc-179.patch new file mode 100644 index 0000000..bcee80c --- /dev/null +++ b/jgit-bc-179.patch @@ -0,0 +1,16 @@ +--- jgit-5.11.0.202103091610-r/org.eclipse.jgit.gpg.bc/src/org/eclipse/jgit/gpg/bc/internal/keys/OCBPBEProtectionRemoverFactory.java 2024-11-04 21:53:31.607619683 +0100 ++++ jgit-5.11.0.202103091610-r/org.eclipse.jgit.gpg.bc/src/org/eclipse/jgit/gpg/bc/internal/keys/OCBPBEProtectionRemoverFactory.java 2024-11-04 22:13:28.412238521 +0100 +@@ -116,6 +116,12 @@ + } + } + } ++ ++ public byte[] recoverKeyData(int encAlgorithm, int aeadAlgorithm, ++ byte[] s2kKey, byte[] iv, int packetTag, int keyVersion, ++ byte[] keyData, byte[] pubkeyData) throws PGPException { ++ throw new PGPException("Unimplemented method"); ++ } + }; + } + } +\ No newline at end of file diff --git a/jgit-jsch.patch b/jgit-jsch.patch new file mode 100644 index 0000000..1e42db7 --- /dev/null +++ b/jgit-jsch.patch @@ -0,0 +1,11 @@ +--- jgit-5.11.0.202103091610-r/org.eclipse.jgit.ssh.jsch/META-INF/MANIFEST.MF 2021-03-09 22:10:22.000000000 +0100 ++++ jgit-5.11.0.202103091610-r/org.eclipse.jgit.ssh.jsch/META-INF/MANIFEST.MF 2023-05-31 21:46:41.989226527 +0200 +@@ -15,7 +15,7 @@ + org.eclipse.jgit.internal.transport.ssh, + org.eclipse.jgit.util, + com.jcraft.jsch" +-Import-Package: com.jcraft.jsch;version="[0.1.37,0.2.0)", ++Import-Package: com.jcraft.jsch;version="[0.1.37,1.0.0)", + org.eclipse.jgit.errors;version="[5.11.0,5.12.0)", + org.eclipse.jgit.internal;version="[5.11.0,5.12.0)", + org.eclipse.jgit.internal.transport.ssh;version="[5.11.0,5.12.0)", diff --git a/jgit-shade.patch b/jgit-shade.patch new file mode 100644 index 0000000..bba3076 --- /dev/null +++ b/jgit-shade.patch @@ -0,0 +1,93 @@ +diff -urEbwB jgit-5.11.0.202103091610-r/org.eclipse.jgit.pgm/pom.xml jgit-5.11.0.202103091610-r.new/org.eclipse.jgit.pgm/pom.xml +--- jgit-5.11.0.202103091610-r/org.eclipse.jgit.pgm/pom.xml 2021-03-09 22:10:22.000000000 +0100 ++++ jgit-5.11.0.202103091610-r.new/org.eclipse.jgit.pgm/pom.xml 2021-07-30 11:40:33.894748622 +0200 +@@ -157,19 +157,40 @@ + + + +- org.springframework.boot +- spring-boot-maven-plugin ++ org.apache.maven.plugins ++ maven-shade-plugin + + ++ package + +- repackage ++ shade + + + jgit-cli +- false +- org.eclipse.jgit.pgm.Main +- true +- jgit.sh ++ false ++ ++ ++ ++ ++ org.eclipse.jgit.pgm.Main ++ JGit Command Line Interface ++ ++ ++ ++ ++ ++ ++ *:* ++ ++ META-INF/*.SF ++ META-INF/*.DSA ++ META-INF/*.RSA ++ OSGI-OPT/** ++ ++ ++ ++ true ++ shaded + + + +@@ -184,13 +205,11 @@ + package + + +- +- ++ ++ ++ ++ ++ + + + +Only in jgit-5.11.0.202103091610-r.new/org.eclipse.jgit.pgm: pom.xml.orig +diff -urEbwB jgit-5.11.0.202103091610-r/pom.xml jgit-5.11.0.202103091610-r.new/pom.xml +--- jgit-5.11.0.202103091610-r/pom.xml 2021-03-09 22:10:22.000000000 +0100 ++++ jgit-5.11.0.202103091610-r.new/pom.xml 2021-07-30 11:41:51.715264903 +0200 +@@ -394,16 +394,6 @@ + maven-resources-plugin + 3.2.0 + +- +- org.springframework.boot +- spring-boot-maven-plugin +- 2.4.1 +- +- +- org.eclipse.dash +- license-tool-plugin +- 0.0.1-SNAPSHOT +- + + + +Only in jgit-5.11.0.202103091610-r.new: pom.xml.orig +Only in jgit-5.11.0.202103091610-r.new: pom.xml.rej diff --git a/jgit.changes b/jgit.changes new file mode 100644 index 0000000..d3163c8 --- /dev/null +++ b/jgit.changes @@ -0,0 +1,139 @@ +------------------------------------------------------------------- +Thu May 23 14:19:57 UTC 2024 - Fridrich Strba + +- Require hamcrest to avoid conflict of providers with hamcrest-core + +------------------------------------------------------------------- +Wed Feb 21 21:55:25 UTC 2024 - Fridrich Strba + +- Use %patch -P N instead of deprecated %patchN. + +------------------------------------------------------------------- +Fri Jan 12 15:25:10 UTC 2024 - Fridrich Strba + +- Modified patch: + * jgit-apache-sshd-2.7.0.patch -> jgit-apache-sshd.patch + + rename patch and make it accept apache-ssd < 3.0.0 + +------------------------------------------------------------------- +Wed Oct 11 08:47:23 UTC 2023 - Fridrich Strba + +- Modified patch: + * jgit-apache-sshd-2.7.0.patch + + extend even more apache-sshd version span + +------------------------------------------------------------------- +Tue Oct 10 15:09:41 UTC 2023 - Fridrich Strba + +- Added patch: + * jgit-CVE-2023-4759.patch + + backport of upstream fix for bsc#1215298 (CVE-2023-4759), + arbitrary file overwrite + +------------------------------------------------------------------- +Fri Oct 6 11:04:41 UTC 2023 - Fridrich Strba + +- Removed patch: + * 0001-Ensure-the-correct-classpath-is-set-for-the-jgit-com.patch + + no need to patch the jgit.sh launcher that we do not use + +------------------------------------------------------------------- +Fri Oct 6 11:00:40 UTC 2023 - Fridrich Strba + +- Craft the jgit script from the real Main class of the jar file + instead of using some superfluous jar launcher. + Fixes bsc#1209646 + +------------------------------------------------------------------- +Wed May 31 19:51:51 UTC 2023 - Fridrich Strba + +- Added patch: + * jgit-jsch.patch + + extend the version range for the required jsch package + + allows building with 0.2.x (which is backward compatible + with 0.1.x) + +------------------------------------------------------------------- +Fri May 5 08:24:40 UTC 2023 - Fridrich Strba + +- Add _multibuild to define 2nd spec file as additional flavor. + Eliminates the need for source package links in OBS. + +------------------------------------------------------------------- +Mon Mar 27 08:18:14 UTC 2023 - Fridrich Strba + +- Require xz-java because the jgit script that we install is + expecting it to be present when composing the classpath + (bsc#1209646) + +------------------------------------------------------------------- +Wed Nov 16 11:24:53 UTC 2022 - Fridrich Strba + +- Modified patch: + * jgit-apache-sshd-2.7.0.patch + + Allow building against apache-sshd 2.8.x and 2.9.x + +------------------------------------------------------------------- +Tue Mar 29 14:06:34 UTC 2022 - Fridrich Strba + +- Force building with Java 11, since tycho is not knowing about any + Java >= 15 + +------------------------------------------------------------------- +Fri Jul 30 12:24:56 UTC 2021 - Fridrich Strba + +- Update to 5.11.0 + * No changelog was made available. + * fixes build against apache-sshd 2.7.0 +- Modified patches: + * 0001-Ensure-the-correct-classpath-is-set-for-the-jgit-com.patch + * 0002-Don-t-embed-versions-of-third-party-libs-use-feature.patch + * jgit-shade.patch + * jgit-5.8.0-java8.patch -> jgit-5.11.0-java8.patch + + Rediff to changed context +- Added patch: + * jgit-apache-sshd-2.7.0.patch + + Adapt to apache-sshd api changes between 2.6.0 and 2.7.0 +- Removed patch: + * 0003-Remove-requirement-on-assertj-core.patch + + Not needed anymore + +------------------------------------------------------------------- +Thu Nov 19 13:00:00 UTC 2020 - Fridrich Strba + +- Fix provides + +------------------------------------------------------------------- +Thu Jul 16 21:23:15 UTC 2020 - Fridrich Strba + +- Added patch: + * jgit-5.8.0-java8.patch + + restore java 8 compatibility when building with java 9+ + +------------------------------------------------------------------- +Fri Jul 3 09:55:53 UTC 2020 - Fridrich Strba + +- Upgrade to 5.8.0 + * No changelog was made available. +- Removed patches: + * fix_jgit_sh.patch + * jgit-feature-deps.patch +- Added patches: + * 0001-Ensure-the-correct-classpath-is-set-for-the-jgit-com.patch + * 0002-Don-t-embed-versions-of-third-party-libs-use-feature.patch + * 0003-Remove-requirement-on-assertj-core.patch + * jgit-shade.patch + +------------------------------------------------------------------- +Wed Apr 8 19:57:21 UTC 2020 - Fridrich Strba + +- Split the build into two spec files instead of multibuild + * First one produces the maven artifacts, the jgit command-line + tool and ant feature + * Second one produces eclipse features + +------------------------------------------------------------------- +Mon Nov 11 12:09:35 UTC 2019 - Fridrich Strba + +- Initial packaging of eclipse-jgit 5.1.3 as a _multibuild package + in order to allow bootstrapping diff --git a/jgit.spec b/jgit.spec new file mode 100644 index 0000000..9fc5fc5 --- /dev/null +++ b/jgit.spec @@ -0,0 +1,184 @@ +# +# spec file for package jgit +# +# Copyright (c) 2024 SUSE LLC +# +# All modifications and additions to the file contributed by third parties +# remain the property of their copyright owners, unless otherwise agreed +# upon. The license for this file, and modifications and additions to the +# file, is the same license as for the pristine package itself (unless the +# license for the pristine package is not an Open Source License, in which +# case the license is the MIT License). An "Open Source License" is a +# license that conforms to the Open Source Definition (Version 1.9) +# published by the Open Source Initiative. + +# Please submit bugfixes or comments via https://bugs.opensuse.org/ +# + + +%global gittag 5.11.0.202103091610-r +Name: jgit +Version: 5.11.0 +Release: 0 +Summary: Eclipse JGit +License: BSD-3-Clause +Group: Development/Libraries/Java +URL: https://www.eclipse.org/egit/ +# Use github mirror for now, see: https://bugs.eclipse.org/bugs/show_bug.cgi?id=522144 +Source0: https://git.eclipse.org/c/jgit/jgit.git/snapshot/jgit-%{gittag}.tar.xz +# Set the correct classpath for the command line tools +# Switch to feature requirements for third-party bundles, also makes the following changes: +# javaewah -> com.googlecode.javaewah.JavaEWAH +# org.slf4j.api -> slf4j.api +# org.slf4j.impl.log4j12 -> slf4j.simple +Patch1: 0002-Don-t-embed-versions-of-third-party-libs-use-feature.patch +Patch2: jgit-shade.patch +Patch3: jgit-5.11.0-java8.patch +Patch4: jgit-apache-sshd.patch +Patch5: jgit-jsch.patch +Patch6: jgit-CVE-2023-4759.patch +Patch7: jgit-bc-179.patch +# For main build +BuildRequires: ant +BuildRequires: fdupes +BuildRequires: git +BuildRequires: maven-local +BuildRequires: mvn(args4j:args4j) +BuildRequires: mvn(com.google.code.gson:gson) +BuildRequires: mvn(com.googlecode.javaewah:JavaEWAH) +BuildRequires: mvn(com.jcraft:jsch) +BuildRequires: mvn(com.jcraft:jzlib) +BuildRequires: mvn(javax.servlet:javax.servlet-api) +BuildRequires: mvn(junit:junit) +BuildRequires: mvn(net.i2p.crypto:eddsa) +BuildRequires: mvn(org.apache.ant:ant) +BuildRequires: mvn(org.apache.commons:commons-compress) +BuildRequires: mvn(org.apache.httpcomponents:httpclient) +BuildRequires: mvn(org.apache.httpcomponents:httpcore) +BuildRequires: mvn(org.apache.maven.plugins:maven-antrun-plugin) +BuildRequires: mvn(org.apache.maven.plugins:maven-shade-plugin) +BuildRequires: mvn(org.apache.maven.plugins:maven-source-plugin) +BuildRequires: mvn(org.apache.sshd:sshd-osgi) >= 2.4 +BuildRequires: mvn(org.apache.sshd:sshd-sftp) >= 2.4 +BuildRequires: mvn(org.bouncycastle:bcpg-jdk15on) +BuildRequires: mvn(org.bouncycastle:bcpkix-jdk15on) +BuildRequires: mvn(org.bouncycastle:bcprov-jdk15on) +BuildRequires: mvn(org.codehaus.mojo:build-helper-maven-plugin) +BuildRequires: mvn(org.eclipse.jetty:jetty-servlet) +BuildRequires: mvn(org.mockito:mockito-core) +BuildRequires: mvn(org.osgi:osgi.core) +BuildRequires: mvn(org.slf4j:slf4j-api) +BuildRequires: mvn(org.slf4j:slf4j-simple) +BuildRequires: mvn(org.tukaani:xz) +# All the jars that need to be on the classpath for the script to work +Requires: apache-commons-codec +Requires: apache-commons-compress +Requires: apache-commons-logging +Requires: apache-sshd +Requires: args4j +Requires: ed25519-java +Requires: httpcomponents-client +Requires: httpcomponents-core +Requires: javaewah +Requires: javapackages-tools +Requires: jsch +Requires: jzlib +Requires: slf4j +Requires: xz-java +Obsoletes: %{name}-bootstrap +BuildArch: noarch + +%description +Command line Git tool built entirely in Java. + +%package javadoc +Summary: API documentation for %{name} +Group: Documentation/HTML + +%description javadoc +%{summary}. + +%prep +%setup -q -n jgit-%{gittag} + +%patch -P 1 -p1 +%patch -P 2 -p1 +%patch -P 3 -p1 +%patch -P 4 -p1 +%patch -P 5 -p1 +%patch -P 6 -p1 +%patch -P 7 -p1 + +# Disable multithreaded build +rm .mvn/maven.config + +# Don't try to get deps from local *maven* repo, use tycho resolved ones +for p in $(find org.eclipse.jgit.packaging -name pom.xml) ; do + grep -q dependencies $p && %pom_xpath_remove "pom:dependencies" $p +done + +# Disable "errorprone" compiler +%pom_xpath_remove "pom:plugin[pom:artifactId='maven-compiler-plugin']/pom:configuration/pom:compilerArgs" pom.xml +%pom_xpath_remove "pom:plugin[pom:artifactId='maven-compiler-plugin']/pom:configuration/pom:annotationProcessorPaths" pom.xml + +# Don't need target platform or repository modules with xmvn +%pom_disable_module org.eclipse.jgit.target org.eclipse.jgit.packaging +%pom_disable_module org.eclipse.jgit.repository org.eclipse.jgit.packaging +%pom_xpath_remove "pom:build/pom:pluginManagement/pom:plugins/pom:plugin/pom:configuration/pom:target" org.eclipse.jgit.packaging/pom.xml + +# Don't build source features +%pom_disable_module org.eclipse.jgit.source.feature org.eclipse.jgit.packaging + +# Don't build benchmark and coverage +%pom_disable_module org.eclipse.jgit.benchmarks +%pom_disable_module org.eclipse.jgit.coverage + +# Use newer Felix dep +%pom_change_dep -r org.osgi:org.osgi.core org.osgi:osgi.core + +# Remove unnecessary plugins for RPM builds +%pom_remove_plugin :jacoco-maven-plugin +%pom_remove_plugin :maven-javadoc-plugin +%pom_remove_plugin :maven-enforcer-plugin +%pom_remove_plugin :maven-enforcer-plugin org.eclipse.jgit.packaging +%pom_remove_plugin -r :japicmp-maven-plugin + +# Don't attach shell script artifact +%pom_remove_plugin org.codehaus.mojo:build-helper-maven-plugin org.eclipse.jgit.pgm + +# Remove org.apache.log4j +%pom_remove_dep log4j:log4j . org.eclipse.jgit.pgm +%pom_change_dep org.slf4j:slf4j-log4j12 org.slf4j:slf4j-simple . org.eclipse.jgit.pgm + +%{mvn_package} ":*.test" __noinstall + +%build +%{mvn_build} -f -- \ +%if %{?pkg_vcmp:%pkg_vcmp java-devel >= 9}%{!?pkg_vcmp:0} + -Dmaven.compiler.release=8 \ +%endif + -Pjavac + +%install +%mvn_install +%fdupes -s %{buildroot}%{_javadocdir} + +# Binary +%jpackage_script org.eclipse.jgit.pgm.Main "" "" javaewah:jzlib:jsch:jgit:slf4j/api:slf4j/simple:args4j:commons-compress:httpcomponents/httpcore:httpcomponents/httpclient:commons-logging:commons-codec:eddsa:apache-sshd/sshd-osgi:apache-sshd/sshd-sftp %{name} + +# Ant task configuration +install -dm 755 %{buildroot}%{_sysconfdir}/ant.d +cat > %{buildroot}%{_sysconfdir}/ant.d/jgit <