diff options
author | Matthias Sohn <matthias.sohn@sap.com> | 2021-05-12 08:59:07 +0200 |
---|---|---|
committer | Matthias Sohn <matthias.sohn@sap.com> | 2021-05-12 08:59:07 +0200 |
commit | 1aa3cf7f416658a4fafd592732ba70f5a1aee19e (patch) | |
tree | 275b1176d04d102832641292a765d1a8f3e1b3a2 | |
parent | b6d4844b5d60f63a46f2b8b42189f70de653b385 (diff) | |
parent | fe3034d5b90a8a1f2592a40a670705fbd7305158 (diff) | |
download | jgit-1aa3cf7f416658a4fafd592732ba70f5a1aee19e.tar.gz jgit-1aa3cf7f416658a4fafd592732ba70f5a1aee19e.zip |
Merge branch 'master' into next
* master: (34 commits)
Remove texts which were added by mistake in 00386272
Fix formatting which was broken in 00386272
LockFile: create OutputStream only when needed
Add a cgit interoperability test for LockFile
Add TemporaryBuffer.toString(int limit)
LockFile: create OutputStream only when needed
Prepare 5.12.0-SNAPSHOT builds
JGit v5.12.0.202105051250-m2
Update jetty to 9.4.40.v20210413
[releng] Update eclipse-jarsigner-plugin to 1.3.1
Implement ours/theirs content conflict resolution
ssh: ensure list is modifiable before using Iterator.remove().
Update orbit to S20210406213021 and add 4.20-staging target
Fix typo in test method name
Allow file mode conflicts in virtual base commit on recursive merge.
sshd: don't lock the known_hosts files on reading
Allow info messages in UsernamePasswordCredentialsProvider
ssh config: do environment variable replacement
sshd: implement server-sig-algs SSH extension (client side)
Upgrade ecj to 3.25.0
...
Change-Id: Ibc39a9c4e431d15b67ab4a307241f47a7f3740a9
83 files changed, 2987 insertions, 804 deletions
@@ -237,55 +237,55 @@ maven_jar( sha1 = "9180733b7df8542621dc12e21e87557e8c99b8cb", ) -JETTY_VER = "9.4.36.v20210114" +JETTY_VER = "9.4.40.v20210413" maven_jar( name = "jetty-servlet", artifact = "org.eclipse.jetty:jetty-servlet:" + JETTY_VER, - sha1 = "b189e52a5ee55ae172e4e99e29c5c314f5daf4b9", - src_sha1 = "3a0fa449772ab0d76625f6afb81f60c32a490613", + sha1 = "41abc058d311baae3fe5411223e4108af212a24a", + src_sha1 = "2e5b2319bce4c74d760106db05deed2a405041ce", ) maven_jar( name = "jetty-security", artifact = "org.eclipse.jetty:jetty-security:" + JETTY_VER, - sha1 = "42030d6ed7dfc0f75818cde0adcf738efc477574", - src_sha1 = "612220a97d45fad3983ccc56b0cb9a271f3fd003", + sha1 = "0c2807eff66ca21b565276e69aa8502524beb204", + src_sha1 = "b4873ec0ab5acc8a383df4dc9046ad5361b5616f", ) maven_jar( name = "jetty-server", artifact = "org.eclipse.jetty:jetty-server:" + JETTY_VER, - sha1 = "88a7d342974aadca658e7386e8d0fcc5c0788f41", - src_sha1 = "4552c0c6db2948e8557db477b6b48d291006e481", + sha1 = "a6d22f20c863d2d7669dbc2399a1a3b25b0f8a20", + src_sha1 = "09f789d2959ea38813be6bd2b751bba9db3a4494", ) maven_jar( name = "jetty-http", artifact = "org.eclipse.jetty:jetty-http:" + JETTY_VER, - sha1 = "1eee89a55e04ff94df0f85d95200fc48acb43d86", - src_sha1 = "552a784ec789c7ba581c5341ae6d8b6353ed5ace", + sha1 = "dea7e5fe28a6580d6900e77d836e650aeecfa9c8", + src_sha1 = "b161959fac6fd932031022ac3fb8b6c34a422feb", ) maven_jar( name = "jetty-io", artifact = "org.eclipse.jetty:jetty-io:" + JETTY_VER, - sha1 = "84a8faf9031eb45a5a2ddb7681e22c483d81ab3a", - src_sha1 = "72d5fc6d909e28f8720394b25babda80805a46b9", + sha1 = "c420368a360c20b40a57897676d581462d0a54c0", + src_sha1 = "6ae54fba76b91f24ec5880202920f0a61b1b050b", ) maven_jar( name = "jetty-util", artifact = "org.eclipse.jetty:jetty-util:" + JETTY_VER, - sha1 = "925257fbcca6b501a25252c7447dbedb021f7404", - src_sha1 = "532e8b66044f4e58ca5da3aec19f02a2f3c16ddd", + sha1 = "1ab1a4f33f293110fdfb3da1911b2a00da78019b", + src_sha1 = "9d537ad9d22c7edfac0e38ba5afc04632716dca5", ) maven_jar( name = "jetty-util-ajax", artifact = "org.eclipse.jetty:jetty-util-ajax:" + JETTY_VER, - sha1 = "2f478130c21787073facb64d7242e06f94980c60", - src_sha1 = "7153d7ca38878d971fd90992c303bb7719ba7a21", + sha1 = "62014fb386f1c3dce53029165fd76435bcb8bb6c", + src_sha1 = "99df1bf89bdd11c9caa0e56cc802b949f896e3d9", ) BOUNCYCASTLE_VER = "1.65" @@ -161,8 +161,8 @@ java_library( visibility = [ "//org.eclipse.jgit:__pkg__", "//org.eclipse.jgit.gpg.bc:__pkg__", - "//org.eclipse.jgit.test:__pkg__", "//org.eclipse.jgit.gpg.bc.test:__pkg__", + "//org.eclipse.jgit.test:__pkg__", ], exports = ["@bcpg//jar"], ) @@ -172,8 +172,8 @@ java_library( visibility = [ "//org.eclipse.jgit:__pkg__", "//org.eclipse.jgit.gpg.bc:__pkg__", - "//org.eclipse.jgit.test:__pkg__", "//org.eclipse.jgit.gpg.bc.test:__pkg__", + "//org.eclipse.jgit.test:__pkg__", ], exports = ["@bcprov//jar"], ) diff --git a/org.eclipse.jgit.benchmarks/pom.xml b/org.eclipse.jgit.benchmarks/pom.xml index e5954e54d7..f14a6a0418 100644 --- a/org.eclipse.jgit.benchmarks/pom.xml +++ b/org.eclipse.jgit.benchmarks/pom.xml @@ -182,7 +182,7 @@ <dependency><!-- add support for ssh/scp --> <groupId>org.apache.maven.wagon</groupId> <artifactId>wagon-ssh</artifactId> - <version>3.4.2</version> + <version>3.4.3</version> </dependency> </dependencies> </plugin> diff --git a/org.eclipse.jgit.gpg.bc.test/BUILD b/org.eclipse.jgit.gpg.bc.test/BUILD index 925536e5d5..4c86effab3 100644 --- a/org.eclipse.jgit.gpg.bc.test/BUILD +++ b/org.eclipse.jgit.gpg.bc.test/BUILD @@ -2,7 +2,6 @@ load( "@com_googlesource_gerrit_bazlets//tools:genrule2.bzl", "genrule2", ) -load("@rules_java//java:defs.bzl", "java_import") load( "@com_googlesource_gerrit_bazlets//tools:junit.bzl", "junit_tests", @@ -11,25 +10,20 @@ load( junit_tests( name = "bc", srcs = glob(["tst/**/*.java"]), + resource_jars = [":tst_rsrc"], tags = ["bc"], deps = [ "//lib:bcpg", "//lib:bcprov", "//lib:junit", - "//org.eclipse.jgit:jgit", "//org.eclipse.jgit.gpg.bc:gpg-bc", - "//org.eclipse.jgit.gpg.bc.test:tst_rsrc", + "//org.eclipse.jgit:jgit", ], ) -java_import( - name = "tst_rsrc", - jars = [":tst_rsrc_jar"], -) - genrule2( - name = "tst_rsrc_jar", + name = "tst_rsrc", srcs = glob(["tst-rsrc/**"]), outs = ["tst_rsrc.jar"], - cmd = "o=$$PWD/$@ && tar cf - $(SRCS) | tar -C $$TMP --strip-components=2 -xf - && cd $$TMP && zip -qr $$o .", + cmd = "tar cf - $(SRCS) | tar -C $$TMP --strip-components=2 -xf - && cd $$TMP && zip -qr $$ROOT/$@ .", ) diff --git a/org.eclipse.jgit.http.server/pom.xml b/org.eclipse.jgit.http.server/pom.xml index 647b4ab1fd..f0935c32df 100644 --- a/org.eclipse.jgit.http.server/pom.xml +++ b/org.eclipse.jgit.http.server/pom.xml @@ -126,6 +126,7 @@ <groupId>${project.groupId}</groupId> <artifactId>${project.artifactId}</artifactId> <version>${jgit-last-release-version}</version> + <type>jar</type> </dependency> </oldVersion> <newVersion> @@ -143,7 +144,7 @@ <breakBuildOnBinaryIncompatibleModifications>false</breakBuildOnBinaryIncompatibleModifications> <onlyBinaryIncompatible>false</onlyBinaryIncompatible> <includeSynthetic>false</includeSynthetic> - <ignoreMissingClasses>false</ignoreMissingClasses> + <ignoreMissingClasses>true</ignoreMissingClasses> <skipPomModules>true</skipPomModules> </parameter> <skip>false</skip> diff --git a/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.10.target b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.10.target index 715986b4bb..cb6dbeb6a2 100644 --- a/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.10.target +++ b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.10.target @@ -1,28 +1,28 @@ <?xml version="1.0" encoding="UTF-8" standalone="no"?> <?pde?> <!-- generated with https://github.com/eclipse-cbi/targetplatform-dsl --> -<target name="jgit-4.10" sequenceNumber="1615333029"> +<target name="jgit-4.10" sequenceNumber="1619186290"> <locations> <location includeMode="slicer" includeAllPlatforms="false" includeSource="true" includeConfigurePhase="true" type="InstallableUnit"> - <unit id="org.eclipse.jetty.client" version="9.4.36.v20210114"/> - <unit id="org.eclipse.jetty.client.source" version="9.4.36.v20210114"/> - <unit id="org.eclipse.jetty.continuation" version="9.4.36.v20210114"/> - <unit id="org.eclipse.jetty.continuation.source" version="9.4.36.v20210114"/> - <unit id="org.eclipse.jetty.http" version="9.4.36.v20210114"/> - <unit id="org.eclipse.jetty.http.source" version="9.4.36.v20210114"/> - <unit id="org.eclipse.jetty.io" version="9.4.36.v20210114"/> - <unit id="org.eclipse.jetty.io.source" version="9.4.36.v20210114"/> - <unit id="org.eclipse.jetty.security" version="9.4.36.v20210114"/> - <unit id="org.eclipse.jetty.security.source" version="9.4.36.v20210114"/> - <unit id="org.eclipse.jetty.server" version="9.4.36.v20210114"/> - <unit id="org.eclipse.jetty.server.source" version="9.4.36.v20210114"/> - <unit id="org.eclipse.jetty.servlet" version="9.4.36.v20210114"/> - <unit id="org.eclipse.jetty.servlet.source" version="9.4.36.v20210114"/> - <unit id="org.eclipse.jetty.util" version="9.4.36.v20210114"/> - <unit id="org.eclipse.jetty.util.source" version="9.4.36.v20210114"/> - <unit id="org.eclipse.jetty.util.ajax" version="9.4.36.v20210114"/> - <unit id="org.eclipse.jetty.util.ajax.source" version="9.4.36.v20210114"/> - <repository id="jetty-9.4.36" location="https://download.eclipse.org/jetty/updates/jetty-bundles-9.x/9.4.36.v20210114/"/> + <unit id="org.eclipse.jetty.client" version="9.4.40.v20210413"/> + <unit id="org.eclipse.jetty.client.source" version="9.4.40.v20210413"/> + <unit id="org.eclipse.jetty.continuation" version="9.4.40.v20210413"/> + <unit id="org.eclipse.jetty.continuation.source" version="9.4.40.v20210413"/> + <unit id="org.eclipse.jetty.http" version="9.4.40.v20210413"/> + <unit id="org.eclipse.jetty.http.source" version="9.4.40.v20210413"/> + <unit id="org.eclipse.jetty.io" version="9.4.40.v20210413"/> + <unit id="org.eclipse.jetty.io.source" version="9.4.40.v20210413"/> + <unit id="org.eclipse.jetty.security" version="9.4.40.v20210413"/> + <unit id="org.eclipse.jetty.security.source" version="9.4.40.v20210413"/> + <unit id="org.eclipse.jetty.server" version="9.4.40.v20210413"/> + <unit id="org.eclipse.jetty.server.source" version="9.4.40.v20210413"/> + <unit id="org.eclipse.jetty.servlet" version="9.4.40.v20210413"/> + <unit id="org.eclipse.jetty.servlet.source" version="9.4.40.v20210413"/> + <unit id="org.eclipse.jetty.util" version="9.4.40.v20210413"/> + <unit id="org.eclipse.jetty.util.source" version="9.4.40.v20210413"/> + <unit id="org.eclipse.jetty.util.ajax" version="9.4.40.v20210413"/> + <unit id="org.eclipse.jetty.util.ajax.source" version="9.4.40.v20210413"/> + <repository id="jetty-9.4.36" location="https://download.eclipse.org/jetty/updates/jetty-bundles-9.x/9.4.40.v20210413/"/> </location> <location includeMode="slicer" includeAllPlatforms="false" includeSource="true" includeConfigurePhase="true" type="InstallableUnit"> <unit id="com.google.gson" version="2.8.6.v20201231-1626"/> @@ -86,7 +86,7 @@ <unit id="org.slf4j.binding.log4j12.source" version="1.7.30.v20201108-2042"/> <unit id="org.tukaani.xz" version="1.8.0.v20180207-1613"/> <unit id="org.tukaani.xz.source" version="1.8.0.v20180207-1613"/> - <repository location="https://download.eclipse.org/tools/orbit/downloads/drops/R20210223232630/repository"/> + <repository location="https://download.eclipse.org/tools/orbit/downloads/drops/S20210406213021/repository"/> </location> <location includeMode="slicer" includeAllPlatforms="false" includeSource="true" includeConfigurePhase="true" type="InstallableUnit"> <unit id="org.eclipse.osgi" version="0.0.0"/> diff --git a/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.10.tpd b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.10.tpd index ed443a6fbf..55a09506fc 100644 --- a/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.10.tpd +++ b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.10.tpd @@ -1,7 +1,7 @@ target "jgit-4.10" with source configurePhase include "projects/jetty-9.4.x.tpd" -include "orbit/R20210223232630-2021-03.tpd" +include "orbit/S20210406213021.tpd" location "https://download.eclipse.org/releases/2018-12/" { org.eclipse.osgi lazy diff --git a/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.11.target b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.11.target index 192671249e..21a6e1f184 100644 --- a/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.11.target +++ b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.11.target @@ -1,28 +1,28 @@ <?xml version="1.0" encoding="UTF-8" standalone="no"?> <?pde?> <!-- generated with https://github.com/eclipse-cbi/targetplatform-dsl --> -<target name="jgit-4.11" sequenceNumber="1615333055"> +<target name="jgit-4.11" sequenceNumber="1619186290"> <locations> <location includeMode="slicer" includeAllPlatforms="false" includeSource="true" includeConfigurePhase="true" type="InstallableUnit"> - <unit id="org.eclipse.jetty.client" version="9.4.36.v20210114"/> - <unit id="org.eclipse.jetty.client.source" version="9.4.36.v20210114"/> - <unit id="org.eclipse.jetty.continuation" version="9.4.36.v20210114"/> - <unit id="org.eclipse.jetty.continuation.source" version="9.4.36.v20210114"/> - <unit id="org.eclipse.jetty.http" version="9.4.36.v20210114"/> - <unit id="org.eclipse.jetty.http.source" version="9.4.36.v20210114"/> - <unit id="org.eclipse.jetty.io" version="9.4.36.v20210114"/> - <unit id="org.eclipse.jetty.io.source" version="9.4.36.v20210114"/> - <unit id="org.eclipse.jetty.security" version="9.4.36.v20210114"/> - <unit id="org.eclipse.jetty.security.source" version="9.4.36.v20210114"/> - <unit id="org.eclipse.jetty.server" version="9.4.36.v20210114"/> - <unit id="org.eclipse.jetty.server.source" version="9.4.36.v20210114"/> - <unit id="org.eclipse.jetty.servlet" version="9.4.36.v20210114"/> - <unit id="org.eclipse.jetty.servlet.source" version="9.4.36.v20210114"/> - <unit id="org.eclipse.jetty.util" version="9.4.36.v20210114"/> - <unit id="org.eclipse.jetty.util.source" version="9.4.36.v20210114"/> - <unit id="org.eclipse.jetty.util.ajax" version="9.4.36.v20210114"/> - <unit id="org.eclipse.jetty.util.ajax.source" version="9.4.36.v20210114"/> - <repository id="jetty-9.4.36" location="https://download.eclipse.org/jetty/updates/jetty-bundles-9.x/9.4.36.v20210114/"/> + <unit id="org.eclipse.jetty.client" version="9.4.40.v20210413"/> + <unit id="org.eclipse.jetty.client.source" version="9.4.40.v20210413"/> + <unit id="org.eclipse.jetty.continuation" version="9.4.40.v20210413"/> + <unit id="org.eclipse.jetty.continuation.source" version="9.4.40.v20210413"/> + <unit id="org.eclipse.jetty.http" version="9.4.40.v20210413"/> + <unit id="org.eclipse.jetty.http.source" version="9.4.40.v20210413"/> + <unit id="org.eclipse.jetty.io" version="9.4.40.v20210413"/> + <unit id="org.eclipse.jetty.io.source" version="9.4.40.v20210413"/> + <unit id="org.eclipse.jetty.security" version="9.4.40.v20210413"/> + <unit id="org.eclipse.jetty.security.source" version="9.4.40.v20210413"/> + <unit id="org.eclipse.jetty.server" version="9.4.40.v20210413"/> + <unit id="org.eclipse.jetty.server.source" version="9.4.40.v20210413"/> + <unit id="org.eclipse.jetty.servlet" version="9.4.40.v20210413"/> + <unit id="org.eclipse.jetty.servlet.source" version="9.4.40.v20210413"/> + <unit id="org.eclipse.jetty.util" version="9.4.40.v20210413"/> + <unit id="org.eclipse.jetty.util.source" version="9.4.40.v20210413"/> + <unit id="org.eclipse.jetty.util.ajax" version="9.4.40.v20210413"/> + <unit id="org.eclipse.jetty.util.ajax.source" version="9.4.40.v20210413"/> + <repository id="jetty-9.4.36" location="https://download.eclipse.org/jetty/updates/jetty-bundles-9.x/9.4.40.v20210413/"/> </location> <location includeMode="slicer" includeAllPlatforms="false" includeSource="true" includeConfigurePhase="true" type="InstallableUnit"> <unit id="com.google.gson" version="2.8.6.v20201231-1626"/> @@ -86,7 +86,7 @@ <unit id="org.slf4j.binding.log4j12.source" version="1.7.30.v20201108-2042"/> <unit id="org.tukaani.xz" version="1.8.0.v20180207-1613"/> <unit id="org.tukaani.xz.source" version="1.8.0.v20180207-1613"/> - <repository location="https://download.eclipse.org/tools/orbit/downloads/drops/R20210223232630/repository"/> + <repository location="https://download.eclipse.org/tools/orbit/downloads/drops/S20210406213021/repository"/> </location> <location includeMode="slicer" includeAllPlatforms="false" includeSource="true" includeConfigurePhase="true" type="InstallableUnit"> <unit id="org.eclipse.osgi" version="0.0.0"/> diff --git a/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.11.tpd b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.11.tpd index 013d6218bc..12b0f75842 100644 --- a/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.11.tpd +++ b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.11.tpd @@ -1,7 +1,7 @@ target "jgit-4.11" with source configurePhase include "projects/jetty-9.4.x.tpd" -include "orbit/R20210223232630-2021-03.tpd" +include "orbit/S20210406213021.tpd" location "https://download.eclipse.org/releases/2019-03/" { org.eclipse.osgi lazy diff --git a/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.12.target b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.12.target index 4449dc3f60..79cf33d40c 100644 --- a/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.12.target +++ b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.12.target @@ -1,28 +1,28 @@ <?xml version="1.0" encoding="UTF-8" standalone="no"?> <?pde?> <!-- generated with https://github.com/eclipse-cbi/targetplatform-dsl --> -<target name="jgit-4.12" sequenceNumber="1615333029"> +<target name="jgit-4.12" sequenceNumber="1619186290"> <locations> <location includeMode="slicer" includeAllPlatforms="false" includeSource="true" includeConfigurePhase="true" type="InstallableUnit"> - <unit id="org.eclipse.jetty.client" version="9.4.36.v20210114"/> - <unit id="org.eclipse.jetty.client.source" version="9.4.36.v20210114"/> - <unit id="org.eclipse.jetty.continuation" version="9.4.36.v20210114"/> - <unit id="org.eclipse.jetty.continuation.source" version="9.4.36.v20210114"/> - <unit id="org.eclipse.jetty.http" version="9.4.36.v20210114"/> - <unit id="org.eclipse.jetty.http.source" version="9.4.36.v20210114"/> - <unit id="org.eclipse.jetty.io" version="9.4.36.v20210114"/> - <unit id="org.eclipse.jetty.io.source" version="9.4.36.v20210114"/> - <unit id="org.eclipse.jetty.security" version="9.4.36.v20210114"/> - <unit id="org.eclipse.jetty.security.source" version="9.4.36.v20210114"/> - <unit id="org.eclipse.jetty.server" version="9.4.36.v20210114"/> - <unit id="org.eclipse.jetty.server.source" version="9.4.36.v20210114"/> - <unit id="org.eclipse.jetty.servlet" version="9.4.36.v20210114"/> - <unit id="org.eclipse.jetty.servlet.source" version="9.4.36.v20210114"/> - <unit id="org.eclipse.jetty.util" version="9.4.36.v20210114"/> - <unit id="org.eclipse.jetty.util.source" version="9.4.36.v20210114"/> - <unit id="org.eclipse.jetty.util.ajax" version="9.4.36.v20210114"/> - <unit id="org.eclipse.jetty.util.ajax.source" version="9.4.36.v20210114"/> - <repository id="jetty-9.4.36" location="https://download.eclipse.org/jetty/updates/jetty-bundles-9.x/9.4.36.v20210114/"/> + <unit id="org.eclipse.jetty.client" version="9.4.40.v20210413"/> + <unit id="org.eclipse.jetty.client.source" version="9.4.40.v20210413"/> + <unit id="org.eclipse.jetty.continuation" version="9.4.40.v20210413"/> + <unit id="org.eclipse.jetty.continuation.source" version="9.4.40.v20210413"/> + <unit id="org.eclipse.jetty.http" version="9.4.40.v20210413"/> + <unit id="org.eclipse.jetty.http.source" version="9.4.40.v20210413"/> + <unit id="org.eclipse.jetty.io" version="9.4.40.v20210413"/> + <unit id="org.eclipse.jetty.io.source" version="9.4.40.v20210413"/> + <unit id="org.eclipse.jetty.security" version="9.4.40.v20210413"/> + <unit id="org.eclipse.jetty.security.source" version="9.4.40.v20210413"/> + <unit id="org.eclipse.jetty.server" version="9.4.40.v20210413"/> + <unit id="org.eclipse.jetty.server.source" version="9.4.40.v20210413"/> + <unit id="org.eclipse.jetty.servlet" version="9.4.40.v20210413"/> + <unit id="org.eclipse.jetty.servlet.source" version="9.4.40.v20210413"/> + <unit id="org.eclipse.jetty.util" version="9.4.40.v20210413"/> + <unit id="org.eclipse.jetty.util.source" version="9.4.40.v20210413"/> + <unit id="org.eclipse.jetty.util.ajax" version="9.4.40.v20210413"/> + <unit id="org.eclipse.jetty.util.ajax.source" version="9.4.40.v20210413"/> + <repository id="jetty-9.4.36" location="https://download.eclipse.org/jetty/updates/jetty-bundles-9.x/9.4.40.v20210413/"/> </location> <location includeMode="slicer" includeAllPlatforms="false" includeSource="true" includeConfigurePhase="true" type="InstallableUnit"> <unit id="com.google.gson" version="2.8.6.v20201231-1626"/> @@ -86,7 +86,7 @@ <unit id="org.slf4j.binding.log4j12.source" version="1.7.30.v20201108-2042"/> <unit id="org.tukaani.xz" version="1.8.0.v20180207-1613"/> <unit id="org.tukaani.xz.source" version="1.8.0.v20180207-1613"/> - <repository location="https://download.eclipse.org/tools/orbit/downloads/drops/R20210223232630/repository"/> + <repository location="https://download.eclipse.org/tools/orbit/downloads/drops/S20210406213021/repository"/> </location> <location includeMode="slicer" includeAllPlatforms="false" includeSource="true" includeConfigurePhase="true" type="InstallableUnit"> <unit id="org.eclipse.osgi" version="0.0.0"/> diff --git a/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.12.tpd b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.12.tpd index 99008ab8c4..6fc7443757 100644 --- a/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.12.tpd +++ b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.12.tpd @@ -1,7 +1,7 @@ target "jgit-4.12" with source configurePhase include "projects/jetty-9.4.x.tpd" -include "orbit/R20210223232630-2021-03.tpd" +include "orbit/S20210406213021.tpd" location "https://download.eclipse.org/releases/2019-06/" { org.eclipse.osgi lazy diff --git a/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.13.target b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.13.target index 01a10e712b..bc2e3d3052 100644 --- a/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.13.target +++ b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.13.target @@ -1,28 +1,28 @@ <?xml version="1.0" encoding="UTF-8" standalone="no"?> <?pde?> <!-- generated with https://github.com/eclipse-cbi/targetplatform-dsl --> -<target name="jgit-4.13" sequenceNumber="1615333029"> +<target name="jgit-4.13" sequenceNumber="1619186290"> <locations> <location includeMode="slicer" includeAllPlatforms="false" includeSource="true" includeConfigurePhase="true" type="InstallableUnit"> - <unit id="org.eclipse.jetty.client" version="9.4.36.v20210114"/> - <unit id="org.eclipse.jetty.client.source" version="9.4.36.v20210114"/> - <unit id="org.eclipse.jetty.continuation" version="9.4.36.v20210114"/> - <unit id="org.eclipse.jetty.continuation.source" version="9.4.36.v20210114"/> - <unit id="org.eclipse.jetty.http" version="9.4.36.v20210114"/> - <unit id="org.eclipse.jetty.http.source" version="9.4.36.v20210114"/> - <unit id="org.eclipse.jetty.io" version="9.4.36.v20210114"/> - <unit id="org.eclipse.jetty.io.source" version="9.4.36.v20210114"/> - <unit id="org.eclipse.jetty.security" version="9.4.36.v20210114"/> - <unit id="org.eclipse.jetty.security.source" version="9.4.36.v20210114"/> - <unit id="org.eclipse.jetty.server" version="9.4.36.v20210114"/> - <unit id="org.eclipse.jetty.server.source" version="9.4.36.v20210114"/> - <unit id="org.eclipse.jetty.servlet" version="9.4.36.v20210114"/> - <unit id="org.eclipse.jetty.servlet.source" version="9.4.36.v20210114"/> - <unit id="org.eclipse.jetty.util" version="9.4.36.v20210114"/> - <unit id="org.eclipse.jetty.util.source" version="9.4.36.v20210114"/> - <unit id="org.eclipse.jetty.util.ajax" version="9.4.36.v20210114"/> - <unit id="org.eclipse.jetty.util.ajax.source" version="9.4.36.v20210114"/> - <repository id="jetty-9.4.36" location="https://download.eclipse.org/jetty/updates/jetty-bundles-9.x/9.4.36.v20210114/"/> + <unit id="org.eclipse.jetty.client" version="9.4.40.v20210413"/> + <unit id="org.eclipse.jetty.client.source" version="9.4.40.v20210413"/> + <unit id="org.eclipse.jetty.continuation" version="9.4.40.v20210413"/> + <unit id="org.eclipse.jetty.continuation.source" version="9.4.40.v20210413"/> + <unit id="org.eclipse.jetty.http" version="9.4.40.v20210413"/> + <unit id="org.eclipse.jetty.http.source" version="9.4.40.v20210413"/> + <unit id="org.eclipse.jetty.io" version="9.4.40.v20210413"/> + <unit id="org.eclipse.jetty.io.source" version="9.4.40.v20210413"/> + <unit id="org.eclipse.jetty.security" version="9.4.40.v20210413"/> + <unit id="org.eclipse.jetty.security.source" version="9.4.40.v20210413"/> + <unit id="org.eclipse.jetty.server" version="9.4.40.v20210413"/> + <unit id="org.eclipse.jetty.server.source" version="9.4.40.v20210413"/> + <unit id="org.eclipse.jetty.servlet" version="9.4.40.v20210413"/> + <unit id="org.eclipse.jetty.servlet.source" version="9.4.40.v20210413"/> + <unit id="org.eclipse.jetty.util" version="9.4.40.v20210413"/> + <unit id="org.eclipse.jetty.util.source" version="9.4.40.v20210413"/> + <unit id="org.eclipse.jetty.util.ajax" version="9.4.40.v20210413"/> + <unit id="org.eclipse.jetty.util.ajax.source" version="9.4.40.v20210413"/> + <repository id="jetty-9.4.36" location="https://download.eclipse.org/jetty/updates/jetty-bundles-9.x/9.4.40.v20210413/"/> </location> <location includeMode="slicer" includeAllPlatforms="false" includeSource="true" includeConfigurePhase="true" type="InstallableUnit"> <unit id="com.google.gson" version="2.8.6.v20201231-1626"/> @@ -86,7 +86,7 @@ <unit id="org.slf4j.binding.log4j12.source" version="1.7.30.v20201108-2042"/> <unit id="org.tukaani.xz" version="1.8.0.v20180207-1613"/> <unit id="org.tukaani.xz.source" version="1.8.0.v20180207-1613"/> - <repository location="https://download.eclipse.org/tools/orbit/downloads/drops/R20210223232630/repository"/> + <repository location="https://download.eclipse.org/tools/orbit/downloads/drops/S20210406213021/repository"/> </location> <location includeMode="slicer" includeAllPlatforms="false" includeSource="true" includeConfigurePhase="true" type="InstallableUnit"> <unit id="org.eclipse.osgi" version="0.0.0"/> diff --git a/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.13.tpd b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.13.tpd index d0db92c599..5dbcbb407f 100644 --- a/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.13.tpd +++ b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.13.tpd @@ -1,7 +1,7 @@ target "jgit-4.13" with source configurePhase include "projects/jetty-9.4.x.tpd" -include "orbit/R20210223232630-2021-03.tpd" +include "orbit/S20210406213021.tpd" location "https://download.eclipse.org/releases/2019-09/" { org.eclipse.osgi lazy diff --git a/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.14.target b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.14.target index b56f9a1f8b..23591b12a5 100644 --- a/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.14.target +++ b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.14.target @@ -1,28 +1,28 @@ <?xml version="1.0" encoding="UTF-8" standalone="no"?> <?pde?> <!-- generated with https://github.com/eclipse-cbi/targetplatform-dsl --> -<target name="jgit-4.14" sequenceNumber="1615333029"> +<target name="jgit-4.14" sequenceNumber="1619186289"> <locations> <location includeMode="slicer" includeAllPlatforms="false" includeSource="true" includeConfigurePhase="true" type="InstallableUnit"> - <unit id="org.eclipse.jetty.client" version="9.4.36.v20210114"/> - <unit id="org.eclipse.jetty.client.source" version="9.4.36.v20210114"/> - <unit id="org.eclipse.jetty.continuation" version="9.4.36.v20210114"/> - <unit id="org.eclipse.jetty.continuation.source" version="9.4.36.v20210114"/> - <unit id="org.eclipse.jetty.http" version="9.4.36.v20210114"/> - <unit id="org.eclipse.jetty.http.source" version="9.4.36.v20210114"/> - <unit id="org.eclipse.jetty.io" version="9.4.36.v20210114"/> - <unit id="org.eclipse.jetty.io.source" version="9.4.36.v20210114"/> - <unit id="org.eclipse.jetty.security" version="9.4.36.v20210114"/> - <unit id="org.eclipse.jetty.security.source" version="9.4.36.v20210114"/> - <unit id="org.eclipse.jetty.server" version="9.4.36.v20210114"/> - <unit id="org.eclipse.jetty.server.source" version="9.4.36.v20210114"/> - <unit id="org.eclipse.jetty.servlet" version="9.4.36.v20210114"/> - <unit id="org.eclipse.jetty.servlet.source" version="9.4.36.v20210114"/> - <unit id="org.eclipse.jetty.util" version="9.4.36.v20210114"/> - <unit id="org.eclipse.jetty.util.source" version="9.4.36.v20210114"/> - <unit id="org.eclipse.jetty.util.ajax" version="9.4.36.v20210114"/> - <unit id="org.eclipse.jetty.util.ajax.source" version="9.4.36.v20210114"/> - <repository id="jetty-9.4.36" location="https://download.eclipse.org/jetty/updates/jetty-bundles-9.x/9.4.36.v20210114/"/> + <unit id="org.eclipse.jetty.client" version="9.4.40.v20210413"/> + <unit id="org.eclipse.jetty.client.source" version="9.4.40.v20210413"/> + <unit id="org.eclipse.jetty.continuation" version="9.4.40.v20210413"/> + <unit id="org.eclipse.jetty.continuation.source" version="9.4.40.v20210413"/> + <unit id="org.eclipse.jetty.http" version="9.4.40.v20210413"/> + <unit id="org.eclipse.jetty.http.source" version="9.4.40.v20210413"/> + <unit id="org.eclipse.jetty.io" version="9.4.40.v20210413"/> + <unit id="org.eclipse.jetty.io.source" version="9.4.40.v20210413"/> + <unit id="org.eclipse.jetty.security" version="9.4.40.v20210413"/> + <unit id="org.eclipse.jetty.security.source" version="9.4.40.v20210413"/> + <unit id="org.eclipse.jetty.server" version="9.4.40.v20210413"/> + <unit id="org.eclipse.jetty.server.source" version="9.4.40.v20210413"/> + <unit id="org.eclipse.jetty.servlet" version="9.4.40.v20210413"/> + <unit id="org.eclipse.jetty.servlet.source" version="9.4.40.v20210413"/> + <unit id="org.eclipse.jetty.util" version="9.4.40.v20210413"/> + <unit id="org.eclipse.jetty.util.source" version="9.4.40.v20210413"/> + <unit id="org.eclipse.jetty.util.ajax" version="9.4.40.v20210413"/> + <unit id="org.eclipse.jetty.util.ajax.source" version="9.4.40.v20210413"/> + <repository id="jetty-9.4.36" location="https://download.eclipse.org/jetty/updates/jetty-bundles-9.x/9.4.40.v20210413/"/> </location> <location includeMode="slicer" includeAllPlatforms="false" includeSource="true" includeConfigurePhase="true" type="InstallableUnit"> <unit id="com.google.gson" version="2.8.6.v20201231-1626"/> @@ -86,7 +86,7 @@ <unit id="org.slf4j.binding.log4j12.source" version="1.7.30.v20201108-2042"/> <unit id="org.tukaani.xz" version="1.8.0.v20180207-1613"/> <unit id="org.tukaani.xz.source" version="1.8.0.v20180207-1613"/> - <repository location="https://download.eclipse.org/tools/orbit/downloads/drops/R20210223232630/repository"/> + <repository location="https://download.eclipse.org/tools/orbit/downloads/drops/S20210406213021/repository"/> </location> <location includeMode="slicer" includeAllPlatforms="false" includeSource="true" includeConfigurePhase="true" type="InstallableUnit"> <unit id="org.eclipse.osgi" version="0.0.0"/> diff --git a/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.14.tpd b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.14.tpd index e0a730e678..3da7ed46fc 100644 --- a/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.14.tpd +++ b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.14.tpd @@ -1,7 +1,7 @@ target "jgit-4.14" with source configurePhase include "projects/jetty-9.4.x.tpd" -include "orbit/R20210223232630-2021-03.tpd" +include "orbit/S20210406213021.tpd" location "https://download.eclipse.org/releases/2019-12/201912181000/" { org.eclipse.osgi lazy diff --git a/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.15.target b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.15.target index f3820a780c..1a11dfff35 100644 --- a/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.15.target +++ b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.15.target @@ -1,28 +1,28 @@ <?xml version="1.0" encoding="UTF-8" standalone="no"?> <?pde?> <!-- generated with https://github.com/eclipse-cbi/targetplatform-dsl --> -<target name="jgit-4.15" sequenceNumber="1615333029"> +<target name="jgit-4.15" sequenceNumber="1619186289"> <locations> <location includeMode="slicer" includeAllPlatforms="false" includeSource="true" includeConfigurePhase="true" type="InstallableUnit"> - <unit id="org.eclipse.jetty.client" version="9.4.36.v20210114"/> - <unit id="org.eclipse.jetty.client.source" version="9.4.36.v20210114"/> - <unit id="org.eclipse.jetty.continuation" version="9.4.36.v20210114"/> - <unit id="org.eclipse.jetty.continuation.source" version="9.4.36.v20210114"/> - <unit id="org.eclipse.jetty.http" version="9.4.36.v20210114"/> - <unit id="org.eclipse.jetty.http.source" version="9.4.36.v20210114"/> - <unit id="org.eclipse.jetty.io" version="9.4.36.v20210114"/> - <unit id="org.eclipse.jetty.io.source" version="9.4.36.v20210114"/> - <unit id="org.eclipse.jetty.security" version="9.4.36.v20210114"/> - <unit id="org.eclipse.jetty.security.source" version="9.4.36.v20210114"/> - <unit id="org.eclipse.jetty.server" version="9.4.36.v20210114"/> - <unit id="org.eclipse.jetty.server.source" version="9.4.36.v20210114"/> - <unit id="org.eclipse.jetty.servlet" version="9.4.36.v20210114"/> - <unit id="org.eclipse.jetty.servlet.source" version="9.4.36.v20210114"/> - <unit id="org.eclipse.jetty.util" version="9.4.36.v20210114"/> - <unit id="org.eclipse.jetty.util.source" version="9.4.36.v20210114"/> - <unit id="org.eclipse.jetty.util.ajax" version="9.4.36.v20210114"/> - <unit id="org.eclipse.jetty.util.ajax.source" version="9.4.36.v20210114"/> - <repository id="jetty-9.4.36" location="https://download.eclipse.org/jetty/updates/jetty-bundles-9.x/9.4.36.v20210114/"/> + <unit id="org.eclipse.jetty.client" version="9.4.40.v20210413"/> + <unit id="org.eclipse.jetty.client.source" version="9.4.40.v20210413"/> + <unit id="org.eclipse.jetty.continuation" version="9.4.40.v20210413"/> + <unit id="org.eclipse.jetty.continuation.source" version="9.4.40.v20210413"/> + <unit id="org.eclipse.jetty.http" version="9.4.40.v20210413"/> + <unit id="org.eclipse.jetty.http.source" version="9.4.40.v20210413"/> + <unit id="org.eclipse.jetty.io" version="9.4.40.v20210413"/> + <unit id="org.eclipse.jetty.io.source" version="9.4.40.v20210413"/> + <unit id="org.eclipse.jetty.security" version="9.4.40.v20210413"/> + <unit id="org.eclipse.jetty.security.source" version="9.4.40.v20210413"/> + <unit id="org.eclipse.jetty.server" version="9.4.40.v20210413"/> + <unit id="org.eclipse.jetty.server.source" version="9.4.40.v20210413"/> + <unit id="org.eclipse.jetty.servlet" version="9.4.40.v20210413"/> + <unit id="org.eclipse.jetty.servlet.source" version="9.4.40.v20210413"/> + <unit id="org.eclipse.jetty.util" version="9.4.40.v20210413"/> + <unit id="org.eclipse.jetty.util.source" version="9.4.40.v20210413"/> + <unit id="org.eclipse.jetty.util.ajax" version="9.4.40.v20210413"/> + <unit id="org.eclipse.jetty.util.ajax.source" version="9.4.40.v20210413"/> + <repository id="jetty-9.4.36" location="https://download.eclipse.org/jetty/updates/jetty-bundles-9.x/9.4.40.v20210413/"/> </location> <location includeMode="slicer" includeAllPlatforms="false" includeSource="true" includeConfigurePhase="true" type="InstallableUnit"> <unit id="com.google.gson" version="2.8.6.v20201231-1626"/> @@ -86,7 +86,7 @@ <unit id="org.slf4j.binding.log4j12.source" version="1.7.30.v20201108-2042"/> <unit id="org.tukaani.xz" version="1.8.0.v20180207-1613"/> <unit id="org.tukaani.xz.source" version="1.8.0.v20180207-1613"/> - <repository location="https://download.eclipse.org/tools/orbit/downloads/drops/R20210223232630/repository"/> + <repository location="https://download.eclipse.org/tools/orbit/downloads/drops/S20210406213021/repository"/> </location> <location includeMode="slicer" includeAllPlatforms="false" includeSource="true" includeConfigurePhase="true" type="InstallableUnit"> <unit id="org.eclipse.osgi" version="0.0.0"/> diff --git a/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.15.tpd b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.15.tpd index 773a9a9ba6..49ae4eac6e 100644 --- a/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.15.tpd +++ b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.15.tpd @@ -1,7 +1,7 @@ target "jgit-4.15" with source configurePhase include "projects/jetty-9.4.x.tpd" -include "orbit/R20210223232630-2021-03.tpd" +include "orbit/S20210406213021.tpd" location "https://download.eclipse.org/releases/2020-03/202003181000/" { org.eclipse.osgi lazy diff --git a/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.16.target b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.16.target index 6a9f58291a..ae9511ac6c 100644 --- a/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.16.target +++ b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.16.target @@ -1,28 +1,28 @@ <?xml version="1.0" encoding="UTF-8" standalone="no"?> <?pde?> <!-- generated with https://github.com/eclipse-cbi/targetplatform-dsl --> -<target name="jgit-4.16" sequenceNumber="1615333030"> +<target name="jgit-4.16" sequenceNumber="1619186290"> <locations> <location includeMode="slicer" includeAllPlatforms="false" includeSource="true" includeConfigurePhase="true" type="InstallableUnit"> - <unit id="org.eclipse.jetty.client" version="9.4.36.v20210114"/> - <unit id="org.eclipse.jetty.client.source" version="9.4.36.v20210114"/> - <unit id="org.eclipse.jetty.continuation" version="9.4.36.v20210114"/> - <unit id="org.eclipse.jetty.continuation.source" version="9.4.36.v20210114"/> - <unit id="org.eclipse.jetty.http" version="9.4.36.v20210114"/> - <unit id="org.eclipse.jetty.http.source" version="9.4.36.v20210114"/> - <unit id="org.eclipse.jetty.io" version="9.4.36.v20210114"/> - <unit id="org.eclipse.jetty.io.source" version="9.4.36.v20210114"/> - <unit id="org.eclipse.jetty.security" version="9.4.36.v20210114"/> - <unit id="org.eclipse.jetty.security.source" version="9.4.36.v20210114"/> - <unit id="org.eclipse.jetty.server" version="9.4.36.v20210114"/> - <unit id="org.eclipse.jetty.server.source" version="9.4.36.v20210114"/> - <unit id="org.eclipse.jetty.servlet" version="9.4.36.v20210114"/> - <unit id="org.eclipse.jetty.servlet.source" version="9.4.36.v20210114"/> - <unit id="org.eclipse.jetty.util" version="9.4.36.v20210114"/> - <unit id="org.eclipse.jetty.util.source" version="9.4.36.v20210114"/> - <unit id="org.eclipse.jetty.util.ajax" version="9.4.36.v20210114"/> - <unit id="org.eclipse.jetty.util.ajax.source" version="9.4.36.v20210114"/> - <repository id="jetty-9.4.36" location="https://download.eclipse.org/jetty/updates/jetty-bundles-9.x/9.4.36.v20210114/"/> + <unit id="org.eclipse.jetty.client" version="9.4.40.v20210413"/> + <unit id="org.eclipse.jetty.client.source" version="9.4.40.v20210413"/> + <unit id="org.eclipse.jetty.continuation" version="9.4.40.v20210413"/> + <unit id="org.eclipse.jetty.continuation.source" version="9.4.40.v20210413"/> + <unit id="org.eclipse.jetty.http" version="9.4.40.v20210413"/> + <unit id="org.eclipse.jetty.http.source" version="9.4.40.v20210413"/> + <unit id="org.eclipse.jetty.io" version="9.4.40.v20210413"/> + <unit id="org.eclipse.jetty.io.source" version="9.4.40.v20210413"/> + <unit id="org.eclipse.jetty.security" version="9.4.40.v20210413"/> + <unit id="org.eclipse.jetty.security.source" version="9.4.40.v20210413"/> + <unit id="org.eclipse.jetty.server" version="9.4.40.v20210413"/> + <unit id="org.eclipse.jetty.server.source" version="9.4.40.v20210413"/> + <unit id="org.eclipse.jetty.servlet" version="9.4.40.v20210413"/> + <unit id="org.eclipse.jetty.servlet.source" version="9.4.40.v20210413"/> + <unit id="org.eclipse.jetty.util" version="9.4.40.v20210413"/> + <unit id="org.eclipse.jetty.util.source" version="9.4.40.v20210413"/> + <unit id="org.eclipse.jetty.util.ajax" version="9.4.40.v20210413"/> + <unit id="org.eclipse.jetty.util.ajax.source" version="9.4.40.v20210413"/> + <repository id="jetty-9.4.36" location="https://download.eclipse.org/jetty/updates/jetty-bundles-9.x/9.4.40.v20210413/"/> </location> <location includeMode="slicer" includeAllPlatforms="false" includeSource="true" includeConfigurePhase="true" type="InstallableUnit"> <unit id="com.google.gson" version="2.8.6.v20201231-1626"/> @@ -86,7 +86,7 @@ <unit id="org.slf4j.binding.log4j12.source" version="1.7.30.v20201108-2042"/> <unit id="org.tukaani.xz" version="1.8.0.v20180207-1613"/> <unit id="org.tukaani.xz.source" version="1.8.0.v20180207-1613"/> - <repository location="https://download.eclipse.org/tools/orbit/downloads/drops/R20210223232630/repository"/> + <repository location="https://download.eclipse.org/tools/orbit/downloads/drops/S20210406213021/repository"/> </location> <location includeMode="slicer" includeAllPlatforms="false" includeSource="true" includeConfigurePhase="true" type="InstallableUnit"> <unit id="org.eclipse.osgi" version="0.0.0"/> diff --git a/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.16.tpd b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.16.tpd index 8b4de8bb30..4e6a745015 100644 --- a/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.16.tpd +++ b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.16.tpd @@ -1,7 +1,7 @@ target "jgit-4.16" with source configurePhase include "projects/jetty-9.4.x.tpd" -include "orbit/R20210223232630-2021-03.tpd" +include "orbit/S20210406213021.tpd" location "https://download.eclipse.org/releases/2020-06/" { org.eclipse.osgi lazy diff --git a/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.17.target b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.17.target index b7481e09f2..5578abb120 100644 --- a/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.17.target +++ b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.17.target @@ -1,28 +1,28 @@ <?xml version="1.0" encoding="UTF-8" standalone="no"?> <?pde?> <!-- generated with https://github.com/eclipse-cbi/targetplatform-dsl --> -<target name="jgit-4.17" sequenceNumber="1615333030"> +<target name="jgit-4.17" sequenceNumber="1619186290"> <locations> <location includeMode="slicer" includeAllPlatforms="false" includeSource="true" includeConfigurePhase="true" type="InstallableUnit"> - <unit id="org.eclipse.jetty.client" version="9.4.36.v20210114"/> - <unit id="org.eclipse.jetty.client.source" version="9.4.36.v20210114"/> - <unit id="org.eclipse.jetty.continuation" version="9.4.36.v20210114"/> - <unit id="org.eclipse.jetty.continuation.source" version="9.4.36.v20210114"/> - <unit id="org.eclipse.jetty.http" version="9.4.36.v20210114"/> - <unit id="org.eclipse.jetty.http.source" version="9.4.36.v20210114"/> - <unit id="org.eclipse.jetty.io" version="9.4.36.v20210114"/> - <unit id="org.eclipse.jetty.io.source" version="9.4.36.v20210114"/> - <unit id="org.eclipse.jetty.security" version="9.4.36.v20210114"/> - <unit id="org.eclipse.jetty.security.source" version="9.4.36.v20210114"/> - <unit id="org.eclipse.jetty.server" version="9.4.36.v20210114"/> - <unit id="org.eclipse.jetty.server.source" version="9.4.36.v20210114"/> - <unit id="org.eclipse.jetty.servlet" version="9.4.36.v20210114"/> - <unit id="org.eclipse.jetty.servlet.source" version="9.4.36.v20210114"/> - <unit id="org.eclipse.jetty.util" version="9.4.36.v20210114"/> - <unit id="org.eclipse.jetty.util.source" version="9.4.36.v20210114"/> - <unit id="org.eclipse.jetty.util.ajax" version="9.4.36.v20210114"/> - <unit id="org.eclipse.jetty.util.ajax.source" version="9.4.36.v20210114"/> - <repository id="jetty-9.4.36" location="https://download.eclipse.org/jetty/updates/jetty-bundles-9.x/9.4.36.v20210114/"/> + <unit id="org.eclipse.jetty.client" version="9.4.40.v20210413"/> + <unit id="org.eclipse.jetty.client.source" version="9.4.40.v20210413"/> + <unit id="org.eclipse.jetty.continuation" version="9.4.40.v20210413"/> + <unit id="org.eclipse.jetty.continuation.source" version="9.4.40.v20210413"/> + <unit id="org.eclipse.jetty.http" version="9.4.40.v20210413"/> + <unit id="org.eclipse.jetty.http.source" version="9.4.40.v20210413"/> + <unit id="org.eclipse.jetty.io" version="9.4.40.v20210413"/> + <unit id="org.eclipse.jetty.io.source" version="9.4.40.v20210413"/> + <unit id="org.eclipse.jetty.security" version="9.4.40.v20210413"/> + <unit id="org.eclipse.jetty.security.source" version="9.4.40.v20210413"/> + <unit id="org.eclipse.jetty.server" version="9.4.40.v20210413"/> + <unit id="org.eclipse.jetty.server.source" version="9.4.40.v20210413"/> + <unit id="org.eclipse.jetty.servlet" version="9.4.40.v20210413"/> + <unit id="org.eclipse.jetty.servlet.source" version="9.4.40.v20210413"/> + <unit id="org.eclipse.jetty.util" version="9.4.40.v20210413"/> + <unit id="org.eclipse.jetty.util.source" version="9.4.40.v20210413"/> + <unit id="org.eclipse.jetty.util.ajax" version="9.4.40.v20210413"/> + <unit id="org.eclipse.jetty.util.ajax.source" version="9.4.40.v20210413"/> + <repository id="jetty-9.4.36" location="https://download.eclipse.org/jetty/updates/jetty-bundles-9.x/9.4.40.v20210413/"/> </location> <location includeMode="slicer" includeAllPlatforms="false" includeSource="true" includeConfigurePhase="true" type="InstallableUnit"> <unit id="com.google.gson" version="2.8.6.v20201231-1626"/> @@ -86,7 +86,7 @@ <unit id="org.slf4j.binding.log4j12.source" version="1.7.30.v20201108-2042"/> <unit id="org.tukaani.xz" version="1.8.0.v20180207-1613"/> <unit id="org.tukaani.xz.source" version="1.8.0.v20180207-1613"/> - <repository location="https://download.eclipse.org/tools/orbit/downloads/drops/R20210223232630/repository"/> + <repository location="https://download.eclipse.org/tools/orbit/downloads/drops/S20210406213021/repository"/> </location> <location includeMode="slicer" includeAllPlatforms="false" includeSource="true" includeConfigurePhase="true" type="InstallableUnit"> <unit id="org.eclipse.osgi" version="0.0.0"/> diff --git a/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.17.tpd b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.17.tpd index b2585be73c..cad8a5c684 100644 --- a/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.17.tpd +++ b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.17.tpd @@ -1,7 +1,7 @@ target "jgit-4.17" with source configurePhase include "projects/jetty-9.4.x.tpd" -include "orbit/R20210223232630-2021-03.tpd" +include "orbit/S20210406213021.tpd" location "https://download.eclipse.org/releases/2020-09/" { org.eclipse.osgi lazy diff --git a/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.18.target b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.18.target index 6d851a2526..42bfa0cd20 100644 --- a/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.18.target +++ b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.18.target @@ -1,28 +1,28 @@ <?xml version="1.0" encoding="UTF-8" standalone="no"?> <?pde?> <!-- generated with https://github.com/eclipse-cbi/targetplatform-dsl --> -<target name="jgit-4.18" sequenceNumber="1615333029"> +<target name="jgit-4.18" sequenceNumber="1619186290"> <locations> <location includeMode="slicer" includeAllPlatforms="false" includeSource="true" includeConfigurePhase="true" type="InstallableUnit"> - <unit id="org.eclipse.jetty.client" version="9.4.36.v20210114"/> - <unit id="org.eclipse.jetty.client.source" version="9.4.36.v20210114"/> - <unit id="org.eclipse.jetty.continuation" version="9.4.36.v20210114"/> - <unit id="org.eclipse.jetty.continuation.source" version="9.4.36.v20210114"/> - <unit id="org.eclipse.jetty.http" version="9.4.36.v20210114"/> - <unit id="org.eclipse.jetty.http.source" version="9.4.36.v20210114"/> - <unit id="org.eclipse.jetty.io" version="9.4.36.v20210114"/> - <unit id="org.eclipse.jetty.io.source" version="9.4.36.v20210114"/> - <unit id="org.eclipse.jetty.security" version="9.4.36.v20210114"/> - <unit id="org.eclipse.jetty.security.source" version="9.4.36.v20210114"/> - <unit id="org.eclipse.jetty.server" version="9.4.36.v20210114"/> - <unit id="org.eclipse.jetty.server.source" version="9.4.36.v20210114"/> - <unit id="org.eclipse.jetty.servlet" version="9.4.36.v20210114"/> - <unit id="org.eclipse.jetty.servlet.source" version="9.4.36.v20210114"/> - <unit id="org.eclipse.jetty.util" version="9.4.36.v20210114"/> - <unit id="org.eclipse.jetty.util.source" version="9.4.36.v20210114"/> - <unit id="org.eclipse.jetty.util.ajax" version="9.4.36.v20210114"/> - <unit id="org.eclipse.jetty.util.ajax.source" version="9.4.36.v20210114"/> - <repository id="jetty-9.4.36" location="https://download.eclipse.org/jetty/updates/jetty-bundles-9.x/9.4.36.v20210114/"/> + <unit id="org.eclipse.jetty.client" version="9.4.40.v20210413"/> + <unit id="org.eclipse.jetty.client.source" version="9.4.40.v20210413"/> + <unit id="org.eclipse.jetty.continuation" version="9.4.40.v20210413"/> + <unit id="org.eclipse.jetty.continuation.source" version="9.4.40.v20210413"/> + <unit id="org.eclipse.jetty.http" version="9.4.40.v20210413"/> + <unit id="org.eclipse.jetty.http.source" version="9.4.40.v20210413"/> + <unit id="org.eclipse.jetty.io" version="9.4.40.v20210413"/> + <unit id="org.eclipse.jetty.io.source" version="9.4.40.v20210413"/> + <unit id="org.eclipse.jetty.security" version="9.4.40.v20210413"/> + <unit id="org.eclipse.jetty.security.source" version="9.4.40.v20210413"/> + <unit id="org.eclipse.jetty.server" version="9.4.40.v20210413"/> + <unit id="org.eclipse.jetty.server.source" version="9.4.40.v20210413"/> + <unit id="org.eclipse.jetty.servlet" version="9.4.40.v20210413"/> + <unit id="org.eclipse.jetty.servlet.source" version="9.4.40.v20210413"/> + <unit id="org.eclipse.jetty.util" version="9.4.40.v20210413"/> + <unit id="org.eclipse.jetty.util.source" version="9.4.40.v20210413"/> + <unit id="org.eclipse.jetty.util.ajax" version="9.4.40.v20210413"/> + <unit id="org.eclipse.jetty.util.ajax.source" version="9.4.40.v20210413"/> + <repository id="jetty-9.4.36" location="https://download.eclipse.org/jetty/updates/jetty-bundles-9.x/9.4.40.v20210413/"/> </location> <location includeMode="slicer" includeAllPlatforms="false" includeSource="true" includeConfigurePhase="true" type="InstallableUnit"> <unit id="com.google.gson" version="2.8.6.v20201231-1626"/> @@ -86,7 +86,7 @@ <unit id="org.slf4j.binding.log4j12.source" version="1.7.30.v20201108-2042"/> <unit id="org.tukaani.xz" version="1.8.0.v20180207-1613"/> <unit id="org.tukaani.xz.source" version="1.8.0.v20180207-1613"/> - <repository location="https://download.eclipse.org/tools/orbit/downloads/drops/R20210223232630/repository"/> + <repository location="https://download.eclipse.org/tools/orbit/downloads/drops/S20210406213021/repository"/> </location> <location includeMode="slicer" includeAllPlatforms="false" includeSource="true" includeConfigurePhase="true" type="InstallableUnit"> <unit id="org.eclipse.osgi" version="0.0.0"/> diff --git a/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.18.tpd b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.18.tpd index 6d16256dc3..6f0b0c359a 100644 --- a/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.18.tpd +++ b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.18.tpd @@ -1,7 +1,7 @@ target "jgit-4.18" with source configurePhase include "projects/jetty-9.4.x.tpd" -include "orbit/R20210223232630-2021-03.tpd" +include "orbit/S20210406213021.tpd" location "https://download.eclipse.org/releases/2020-12/" { org.eclipse.osgi lazy diff --git a/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.19-staging.target b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.19.target index 1a0505de99..16af40036d 100644 --- a/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.19-staging.target +++ b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.19.target @@ -1,28 +1,28 @@ <?xml version="1.0" encoding="UTF-8" standalone="no"?> <?pde?> <!-- generated with https://github.com/eclipse-cbi/targetplatform-dsl --> -<target name="jgit-4.19-staging" sequenceNumber="1615333029"> +<target name="jgit-4.19-staging" sequenceNumber="1619186288"> <locations> <location includeMode="slicer" includeAllPlatforms="false" includeSource="true" includeConfigurePhase="true" type="InstallableUnit"> - <unit id="org.eclipse.jetty.client" version="9.4.36.v20210114"/> - <unit id="org.eclipse.jetty.client.source" version="9.4.36.v20210114"/> - <unit id="org.eclipse.jetty.continuation" version="9.4.36.v20210114"/> - <unit id="org.eclipse.jetty.continuation.source" version="9.4.36.v20210114"/> - <unit id="org.eclipse.jetty.http" version="9.4.36.v20210114"/> - <unit id="org.eclipse.jetty.http.source" version="9.4.36.v20210114"/> - <unit id="org.eclipse.jetty.io" version="9.4.36.v20210114"/> - <unit id="org.eclipse.jetty.io.source" version="9.4.36.v20210114"/> - <unit id="org.eclipse.jetty.security" version="9.4.36.v20210114"/> - <unit id="org.eclipse.jetty.security.source" version="9.4.36.v20210114"/> - <unit id="org.eclipse.jetty.server" version="9.4.36.v20210114"/> - <unit id="org.eclipse.jetty.server.source" version="9.4.36.v20210114"/> - <unit id="org.eclipse.jetty.servlet" version="9.4.36.v20210114"/> - <unit id="org.eclipse.jetty.servlet.source" version="9.4.36.v20210114"/> - <unit id="org.eclipse.jetty.util" version="9.4.36.v20210114"/> - <unit id="org.eclipse.jetty.util.source" version="9.4.36.v20210114"/> - <unit id="org.eclipse.jetty.util.ajax" version="9.4.36.v20210114"/> - <unit id="org.eclipse.jetty.util.ajax.source" version="9.4.36.v20210114"/> - <repository id="jetty-9.4.36" location="https://download.eclipse.org/jetty/updates/jetty-bundles-9.x/9.4.36.v20210114/"/> + <unit id="org.eclipse.jetty.client" version="9.4.40.v20210413"/> + <unit id="org.eclipse.jetty.client.source" version="9.4.40.v20210413"/> + <unit id="org.eclipse.jetty.continuation" version="9.4.40.v20210413"/> + <unit id="org.eclipse.jetty.continuation.source" version="9.4.40.v20210413"/> + <unit id="org.eclipse.jetty.http" version="9.4.40.v20210413"/> + <unit id="org.eclipse.jetty.http.source" version="9.4.40.v20210413"/> + <unit id="org.eclipse.jetty.io" version="9.4.40.v20210413"/> + <unit id="org.eclipse.jetty.io.source" version="9.4.40.v20210413"/> + <unit id="org.eclipse.jetty.security" version="9.4.40.v20210413"/> + <unit id="org.eclipse.jetty.security.source" version="9.4.40.v20210413"/> + <unit id="org.eclipse.jetty.server" version="9.4.40.v20210413"/> + <unit id="org.eclipse.jetty.server.source" version="9.4.40.v20210413"/> + <unit id="org.eclipse.jetty.servlet" version="9.4.40.v20210413"/> + <unit id="org.eclipse.jetty.servlet.source" version="9.4.40.v20210413"/> + <unit id="org.eclipse.jetty.util" version="9.4.40.v20210413"/> + <unit id="org.eclipse.jetty.util.source" version="9.4.40.v20210413"/> + <unit id="org.eclipse.jetty.util.ajax" version="9.4.40.v20210413"/> + <unit id="org.eclipse.jetty.util.ajax.source" version="9.4.40.v20210413"/> + <repository id="jetty-9.4.36" location="https://download.eclipse.org/jetty/updates/jetty-bundles-9.x/9.4.40.v20210413/"/> </location> <location includeMode="slicer" includeAllPlatforms="false" includeSource="true" includeConfigurePhase="true" type="InstallableUnit"> <unit id="com.google.gson" version="2.8.6.v20201231-1626"/> @@ -86,7 +86,7 @@ <unit id="org.slf4j.binding.log4j12.source" version="1.7.30.v20201108-2042"/> <unit id="org.tukaani.xz" version="1.8.0.v20180207-1613"/> <unit id="org.tukaani.xz.source" version="1.8.0.v20180207-1613"/> - <repository location="https://download.eclipse.org/tools/orbit/downloads/drops/R20210223232630/repository"/> + <repository location="https://download.eclipse.org/tools/orbit/downloads/drops/S20210406213021/repository"/> </location> <location includeMode="slicer" includeAllPlatforms="false" includeSource="true" includeConfigurePhase="true" type="InstallableUnit"> <unit id="org.eclipse.osgi" version="0.0.0"/> diff --git a/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.19-staging.tpd b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.19.tpd index 7ed5377d56..6809f052a5 100644 --- a/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.19-staging.tpd +++ b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.19.tpd @@ -1,7 +1,7 @@ target "jgit-4.19-staging" with source configurePhase include "projects/jetty-9.4.x.tpd" -include "orbit/R20210223232630-2021-03.tpd" +include "orbit/S20210406213021.tpd" location "https://download.eclipse.org/staging/2021-03/" { org.eclipse.osgi lazy diff --git a/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.20-staging.target b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.20-staging.target new file mode 100644 index 0000000000..28471a3e23 --- /dev/null +++ b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.20-staging.target @@ -0,0 +1,96 @@ +<?xml version="1.0" encoding="UTF-8" standalone="no"?> +<?pde?> +<!-- generated with https://github.com/eclipse-cbi/targetplatform-dsl --> +<target name="jgit-4.20-staging" sequenceNumber="1619186291"> + <locations> + <location includeMode="slicer" includeAllPlatforms="false" includeSource="true" includeConfigurePhase="true" type="InstallableUnit"> + <unit id="org.eclipse.jetty.client" version="9.4.40.v20210413"/> + <unit id="org.eclipse.jetty.client.source" version="9.4.40.v20210413"/> + <unit id="org.eclipse.jetty.continuation" version="9.4.40.v20210413"/> + <unit id="org.eclipse.jetty.continuation.source" version="9.4.40.v20210413"/> + <unit id="org.eclipse.jetty.http" version="9.4.40.v20210413"/> + <unit id="org.eclipse.jetty.http.source" version="9.4.40.v20210413"/> + <unit id="org.eclipse.jetty.io" version="9.4.40.v20210413"/> + <unit id="org.eclipse.jetty.io.source" version="9.4.40.v20210413"/> + <unit id="org.eclipse.jetty.security" version="9.4.40.v20210413"/> + <unit id="org.eclipse.jetty.security.source" version="9.4.40.v20210413"/> + <unit id="org.eclipse.jetty.server" version="9.4.40.v20210413"/> + <unit id="org.eclipse.jetty.server.source" version="9.4.40.v20210413"/> + <unit id="org.eclipse.jetty.servlet" version="9.4.40.v20210413"/> + <unit id="org.eclipse.jetty.servlet.source" version="9.4.40.v20210413"/> + <unit id="org.eclipse.jetty.util" version="9.4.40.v20210413"/> + <unit id="org.eclipse.jetty.util.source" version="9.4.40.v20210413"/> + <unit id="org.eclipse.jetty.util.ajax" version="9.4.40.v20210413"/> + <unit id="org.eclipse.jetty.util.ajax.source" version="9.4.40.v20210413"/> + <repository id="jetty-9.4.36" location="https://download.eclipse.org/jetty/updates/jetty-bundles-9.x/9.4.40.v20210413/"/> + </location> + <location includeMode="slicer" includeAllPlatforms="false" includeSource="true" includeConfigurePhase="true" type="InstallableUnit"> + <unit id="com.google.gson" version="2.8.6.v20201231-1626"/> + <unit id="com.google.gson.source" version="2.8.6.v20201231-1626"/> + <unit id="com.jcraft.jsch" version="0.1.55.v20190404-1902"/> + <unit id="com.jcraft.jsch.source" version="0.1.55.v20190404-1902"/> + <unit id="com.jcraft.jzlib" version="1.1.1.v201205102305"/> + <unit id="com.jcraft.jzlib.source" version="1.1.1.v201205102305"/> + <unit id="javaewah" version="1.1.7.v20200107-0831"/> + <unit id="javaewah.source" version="1.1.7.v20200107-0831"/> + <unit id="javax.servlet" version="3.1.0.v201410161800"/> + <unit id="javax.servlet.source" version="3.1.0.v201410161800"/> + <unit id="net.bytebuddy.byte-buddy" version="1.9.0.v20181107-1410"/> + <unit id="net.bytebuddy.byte-buddy-agent" version="1.9.0.v20181106-1534"/> + <unit id="net.bytebuddy.byte-buddy-agent.source" version="1.9.0.v20181106-1534"/> + <unit id="net.bytebuddy.byte-buddy.source" version="1.9.0.v20181107-1410"/> + <unit id="net.i2p.crypto.eddsa" version="0.3.0.v20181102-1323"/> + <unit id="net.i2p.crypto.eddsa.source" version="0.3.0.v20181102-1323"/> + <unit id="org.apache.ant" version="1.10.9.v20201106-1946"/> + <unit id="org.apache.ant.source" version="1.10.9.v20201106-1946"/> + <unit id="org.apache.commons.codec" version="1.14.0.v20200818-1422"/> + <unit id="org.apache.commons.codec.source" version="1.14.0.v20200818-1422"/> + <unit id="org.apache.commons.compress" version="1.19.0.v20200106-2343"/> + <unit id="org.apache.commons.compress.source" version="1.19.0.v20200106-2343"/> + <unit id="org.apache.commons.logging" version="1.2.0.v20180409-1502"/> + <unit id="org.apache.commons.logging.source" version="1.2.0.v20180409-1502"/> + <unit id="org.apache.httpcomponents.httpclient" version="4.5.13.v20210128-2225"/> + <unit id="org.apache.httpcomponents.httpclient.source" version="4.5.13.v20210128-2225"/> + <unit id="org.apache.httpcomponents.httpcore" version="4.4.14.v20210128-2225"/> + <unit id="org.apache.httpcomponents.httpcore.source" version="4.4.14.v20210128-2225"/> + <unit id="org.apache.log4j" version="1.2.15.v201012070815"/> + <unit id="org.apache.log4j.source" version="1.2.15.v201012070815"/> + <unit id="org.apache.sshd.osgi" version="2.6.0.v20210201-2003"/> + <unit id="org.apache.sshd.osgi.source" version="2.6.0.v20210201-2003"/> + <unit id="org.apache.sshd.sftp" version="2.6.0.v20210201-2003"/> + <unit id="org.apache.sshd.sftp.source" version="2.6.0.v20210201-2003"/> + <unit id="org.assertj" version="3.14.0.v20200120-1926"/> + <unit id="org.assertj.source" version="3.14.0.v20200120-1926"/> + <unit id="org.bouncycastle.bcpg" version="1.65.0.v20200527-1955"/> + <unit id="org.bouncycastle.bcpg.source" version="1.65.0.v20200527-1955"/> + <unit id="org.bouncycastle.bcpkix" version="1.65.0.v20200527-1955"/> + <unit id="org.bouncycastle.bcpkix.source" version="1.65.0.v20200527-1955"/> + <unit id="org.bouncycastle.bcprov" version="1.65.1.v20200529-1514"/> + <unit id="org.bouncycastle.bcprov.source" version="1.65.1.v20200529-1514"/> + <unit id="org.hamcrest" version="1.1.0.v20090501071000"/> + <unit id="org.hamcrest.core" version="1.3.0.v20180420-1519"/> + <unit id="org.hamcrest.core.source" version="1.3.0.v20180420-1519"/> + <unit id="org.hamcrest.library" version="1.3.0.v20180524-2246"/> + <unit id="org.hamcrest.library.source" version="1.3.0.v20180524-2246"/> + <unit id="org.junit" version="4.13.0.v20200204-1500"/> + <unit id="org.junit.source" version="4.13.0.v20200204-1500"/> + <unit id="org.kohsuke.args4j" version="2.33.0.v20160323-2218"/> + <unit id="org.kohsuke.args4j.source" version="2.33.0.v20160323-2218"/> + <unit id="org.mockito" version="2.23.0.v20200310-1642"/> + <unit id="org.mockito.source" version="2.23.0.v20200310-1642"/> + <unit id="org.objenesis" version="2.6.0.v20180420-1519"/> + <unit id="org.objenesis.source" version="2.6.0.v20180420-1519"/> + <unit id="org.slf4j.api" version="1.7.30.v20200204-2150"/> + <unit id="org.slf4j.api.source" version="1.7.30.v20200204-2150"/> + <unit id="org.slf4j.binding.log4j12" version="1.7.30.v20201108-2042"/> + <unit id="org.slf4j.binding.log4j12.source" version="1.7.30.v20201108-2042"/> + <unit id="org.tukaani.xz" version="1.8.0.v20180207-1613"/> + <unit id="org.tukaani.xz.source" version="1.8.0.v20180207-1613"/> + <repository location="https://download.eclipse.org/tools/orbit/downloads/drops/S20210406213021/repository"/> + </location> + <location includeMode="slicer" includeAllPlatforms="false" includeSource="true" includeConfigurePhase="true" type="InstallableUnit"> + <unit id="org.eclipse.osgi" version="0.0.0"/> + <repository location="https://download.eclipse.org/staging/2021-06/"/> + </location> + </locations> +</target> diff --git a/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.20-staging.tpd b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.20-staging.tpd new file mode 100644 index 0000000000..e7d4f257c3 --- /dev/null +++ b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.20-staging.tpd @@ -0,0 +1,8 @@ +target "jgit-4.20-staging" with source configurePhase + +include "projects/jetty-9.4.x.tpd" +include "orbit/S20210406213021.tpd" + +location "https://download.eclipse.org/staging/2021-06/" { + org.eclipse.osgi lazy +} diff --git a/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.6.target b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.6.target index 249be4cf3c..8aa7d08441 100644 --- a/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.6.target +++ b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.6.target @@ -1,28 +1,28 @@ <?xml version="1.0" encoding="UTF-8" standalone="no"?> <?pde?> <!-- generated with https://github.com/eclipse-cbi/targetplatform-dsl --> -<target name="jgit-4.6" sequenceNumber="1615333044"> +<target name="jgit-4.6" sequenceNumber="1619186309"> <locations> <location includeMode="slicer" includeAllPlatforms="false" includeSource="true" includeConfigurePhase="true" type="InstallableUnit"> - <unit id="org.eclipse.jetty.client" version="9.4.36.v20210114"/> - <unit id="org.eclipse.jetty.client.source" version="9.4.36.v20210114"/> - <unit id="org.eclipse.jetty.continuation" version="9.4.36.v20210114"/> - <unit id="org.eclipse.jetty.continuation.source" version="9.4.36.v20210114"/> - <unit id="org.eclipse.jetty.http" version="9.4.36.v20210114"/> - <unit id="org.eclipse.jetty.http.source" version="9.4.36.v20210114"/> - <unit id="org.eclipse.jetty.io" version="9.4.36.v20210114"/> - <unit id="org.eclipse.jetty.io.source" version="9.4.36.v20210114"/> - <unit id="org.eclipse.jetty.security" version="9.4.36.v20210114"/> - <unit id="org.eclipse.jetty.security.source" version="9.4.36.v20210114"/> - <unit id="org.eclipse.jetty.server" version="9.4.36.v20210114"/> - <unit id="org.eclipse.jetty.server.source" version="9.4.36.v20210114"/> - <unit id="org.eclipse.jetty.servlet" version="9.4.36.v20210114"/> - <unit id="org.eclipse.jetty.servlet.source" version="9.4.36.v20210114"/> - <unit id="org.eclipse.jetty.util" version="9.4.36.v20210114"/> - <unit id="org.eclipse.jetty.util.source" version="9.4.36.v20210114"/> - <unit id="org.eclipse.jetty.util.ajax" version="9.4.36.v20210114"/> - <unit id="org.eclipse.jetty.util.ajax.source" version="9.4.36.v20210114"/> - <repository id="jetty-9.4.36" location="https://download.eclipse.org/jetty/updates/jetty-bundles-9.x/9.4.36.v20210114/"/> + <unit id="org.eclipse.jetty.client" version="9.4.40.v20210413"/> + <unit id="org.eclipse.jetty.client.source" version="9.4.40.v20210413"/> + <unit id="org.eclipse.jetty.continuation" version="9.4.40.v20210413"/> + <unit id="org.eclipse.jetty.continuation.source" version="9.4.40.v20210413"/> + <unit id="org.eclipse.jetty.http" version="9.4.40.v20210413"/> + <unit id="org.eclipse.jetty.http.source" version="9.4.40.v20210413"/> + <unit id="org.eclipse.jetty.io" version="9.4.40.v20210413"/> + <unit id="org.eclipse.jetty.io.source" version="9.4.40.v20210413"/> + <unit id="org.eclipse.jetty.security" version="9.4.40.v20210413"/> + <unit id="org.eclipse.jetty.security.source" version="9.4.40.v20210413"/> + <unit id="org.eclipse.jetty.server" version="9.4.40.v20210413"/> + <unit id="org.eclipse.jetty.server.source" version="9.4.40.v20210413"/> + <unit id="org.eclipse.jetty.servlet" version="9.4.40.v20210413"/> + <unit id="org.eclipse.jetty.servlet.source" version="9.4.40.v20210413"/> + <unit id="org.eclipse.jetty.util" version="9.4.40.v20210413"/> + <unit id="org.eclipse.jetty.util.source" version="9.4.40.v20210413"/> + <unit id="org.eclipse.jetty.util.ajax" version="9.4.40.v20210413"/> + <unit id="org.eclipse.jetty.util.ajax.source" version="9.4.40.v20210413"/> + <repository id="jetty-9.4.36" location="https://download.eclipse.org/jetty/updates/jetty-bundles-9.x/9.4.40.v20210413/"/> </location> <location includeMode="slicer" includeAllPlatforms="false" includeSource="true" includeConfigurePhase="true" type="InstallableUnit"> <unit id="com.google.gson" version="2.8.6.v20201231-1626"/> @@ -86,7 +86,7 @@ <unit id="org.slf4j.binding.log4j12.source" version="1.7.30.v20201108-2042"/> <unit id="org.tukaani.xz" version="1.8.0.v20180207-1613"/> <unit id="org.tukaani.xz.source" version="1.8.0.v20180207-1613"/> - <repository location="https://download.eclipse.org/tools/orbit/downloads/drops/R20210223232630/repository"/> + <repository location="https://download.eclipse.org/tools/orbit/downloads/drops/S20210406213021/repository"/> </location> <location includeMode="slicer" includeAllPlatforms="false" includeSource="true" includeConfigurePhase="true" type="InstallableUnit"> <unit id="org.eclipse.osgi" version="0.0.0"/> diff --git a/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.6.tpd b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.6.tpd index 6e7cd8b66f..4128209b5a 100644 --- a/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.6.tpd +++ b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.6.tpd @@ -1,7 +1,7 @@ target "jgit-4.6" with source configurePhase include "projects/jetty-9.4.x.tpd" -include "orbit/R20210223232630-2021-03.tpd" +include "orbit/S20210406213021.tpd" location "https://download.eclipse.org/releases/neon/" { org.eclipse.osgi lazy diff --git a/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.7.target b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.7.target index 72c44d7b4a..178640abc0 100644 --- a/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.7.target +++ b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.7.target @@ -1,28 +1,28 @@ <?xml version="1.0" encoding="UTF-8" standalone="no"?> <?pde?> <!-- generated with https://github.com/eclipse-cbi/targetplatform-dsl --> -<target name="jgit-4.7" sequenceNumber="1615333034"> +<target name="jgit-4.7" sequenceNumber="1619186297"> <locations> <location includeMode="slicer" includeAllPlatforms="false" includeSource="true" includeConfigurePhase="true" type="InstallableUnit"> - <unit id="org.eclipse.jetty.client" version="9.4.36.v20210114"/> - <unit id="org.eclipse.jetty.client.source" version="9.4.36.v20210114"/> - <unit id="org.eclipse.jetty.continuation" version="9.4.36.v20210114"/> - <unit id="org.eclipse.jetty.continuation.source" version="9.4.36.v20210114"/> - <unit id="org.eclipse.jetty.http" version="9.4.36.v20210114"/> - <unit id="org.eclipse.jetty.http.source" version="9.4.36.v20210114"/> - <unit id="org.eclipse.jetty.io" version="9.4.36.v20210114"/> - <unit id="org.eclipse.jetty.io.source" version="9.4.36.v20210114"/> - <unit id="org.eclipse.jetty.security" version="9.4.36.v20210114"/> - <unit id="org.eclipse.jetty.security.source" version="9.4.36.v20210114"/> - <unit id="org.eclipse.jetty.server" version="9.4.36.v20210114"/> - <unit id="org.eclipse.jetty.server.source" version="9.4.36.v20210114"/> - <unit id="org.eclipse.jetty.servlet" version="9.4.36.v20210114"/> - <unit id="org.eclipse.jetty.servlet.source" version="9.4.36.v20210114"/> - <unit id="org.eclipse.jetty.util" version="9.4.36.v20210114"/> - <unit id="org.eclipse.jetty.util.source" version="9.4.36.v20210114"/> - <unit id="org.eclipse.jetty.util.ajax" version="9.4.36.v20210114"/> - <unit id="org.eclipse.jetty.util.ajax.source" version="9.4.36.v20210114"/> - <repository id="jetty-9.4.36" location="https://download.eclipse.org/jetty/updates/jetty-bundles-9.x/9.4.36.v20210114/"/> + <unit id="org.eclipse.jetty.client" version="9.4.40.v20210413"/> + <unit id="org.eclipse.jetty.client.source" version="9.4.40.v20210413"/> + <unit id="org.eclipse.jetty.continuation" version="9.4.40.v20210413"/> + <unit id="org.eclipse.jetty.continuation.source" version="9.4.40.v20210413"/> + <unit id="org.eclipse.jetty.http" version="9.4.40.v20210413"/> + <unit id="org.eclipse.jetty.http.source" version="9.4.40.v20210413"/> + <unit id="org.eclipse.jetty.io" version="9.4.40.v20210413"/> + <unit id="org.eclipse.jetty.io.source" version="9.4.40.v20210413"/> + <unit id="org.eclipse.jetty.security" version="9.4.40.v20210413"/> + <unit id="org.eclipse.jetty.security.source" version="9.4.40.v20210413"/> + <unit id="org.eclipse.jetty.server" version="9.4.40.v20210413"/> + <unit id="org.eclipse.jetty.server.source" version="9.4.40.v20210413"/> + <unit id="org.eclipse.jetty.servlet" version="9.4.40.v20210413"/> + <unit id="org.eclipse.jetty.servlet.source" version="9.4.40.v20210413"/> + <unit id="org.eclipse.jetty.util" version="9.4.40.v20210413"/> + <unit id="org.eclipse.jetty.util.source" version="9.4.40.v20210413"/> + <unit id="org.eclipse.jetty.util.ajax" version="9.4.40.v20210413"/> + <unit id="org.eclipse.jetty.util.ajax.source" version="9.4.40.v20210413"/> + <repository id="jetty-9.4.36" location="https://download.eclipse.org/jetty/updates/jetty-bundles-9.x/9.4.40.v20210413/"/> </location> <location includeMode="slicer" includeAllPlatforms="false" includeSource="true" includeConfigurePhase="true" type="InstallableUnit"> <unit id="com.google.gson" version="2.8.6.v20201231-1626"/> @@ -86,7 +86,7 @@ <unit id="org.slf4j.binding.log4j12.source" version="1.7.30.v20201108-2042"/> <unit id="org.tukaani.xz" version="1.8.0.v20180207-1613"/> <unit id="org.tukaani.xz.source" version="1.8.0.v20180207-1613"/> - <repository location="https://download.eclipse.org/tools/orbit/downloads/drops/R20210223232630/repository"/> + <repository location="https://download.eclipse.org/tools/orbit/downloads/drops/S20210406213021/repository"/> </location> <location includeMode="slicer" includeAllPlatforms="false" includeSource="true" includeConfigurePhase="true" type="InstallableUnit"> <unit id="org.eclipse.osgi" version="0.0.0"/> diff --git a/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.7.tpd b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.7.tpd index 5a58b006e0..68c6b7beaa 100644 --- a/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.7.tpd +++ b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.7.tpd @@ -1,7 +1,7 @@ target "jgit-4.7" with source configurePhase include "projects/jetty-9.4.x.tpd" -include "orbit/R20210223232630-2021-03.tpd" +include "orbit/S20210406213021.tpd" location "https://download.eclipse.org/releases/oxygen/" { org.eclipse.osgi lazy diff --git a/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.8.target b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.8.target index 10e3deaf7a..e5d0829981 100644 --- a/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.8.target +++ b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.8.target @@ -1,28 +1,28 @@ <?xml version="1.0" encoding="UTF-8" standalone="no"?> <?pde?> <!-- generated with https://github.com/eclipse-cbi/targetplatform-dsl --> -<target name="jgit-4.8" sequenceNumber="1615333030"> +<target name="jgit-4.8" sequenceNumber="1619186290"> <locations> <location includeMode="slicer" includeAllPlatforms="false" includeSource="true" includeConfigurePhase="true" type="InstallableUnit"> - <unit id="org.eclipse.jetty.client" version="9.4.36.v20210114"/> - <unit id="org.eclipse.jetty.client.source" version="9.4.36.v20210114"/> - <unit id="org.eclipse.jetty.continuation" version="9.4.36.v20210114"/> - <unit id="org.eclipse.jetty.continuation.source" version="9.4.36.v20210114"/> - <unit id="org.eclipse.jetty.http" version="9.4.36.v20210114"/> - <unit id="org.eclipse.jetty.http.source" version="9.4.36.v20210114"/> - <unit id="org.eclipse.jetty.io" version="9.4.36.v20210114"/> - <unit id="org.eclipse.jetty.io.source" version="9.4.36.v20210114"/> - <unit id="org.eclipse.jetty.security" version="9.4.36.v20210114"/> - <unit id="org.eclipse.jetty.security.source" version="9.4.36.v20210114"/> - <unit id="org.eclipse.jetty.server" version="9.4.36.v20210114"/> - <unit id="org.eclipse.jetty.server.source" version="9.4.36.v20210114"/> - <unit id="org.eclipse.jetty.servlet" version="9.4.36.v20210114"/> - <unit id="org.eclipse.jetty.servlet.source" version="9.4.36.v20210114"/> - <unit id="org.eclipse.jetty.util" version="9.4.36.v20210114"/> - <unit id="org.eclipse.jetty.util.source" version="9.4.36.v20210114"/> - <unit id="org.eclipse.jetty.util.ajax" version="9.4.36.v20210114"/> - <unit id="org.eclipse.jetty.util.ajax.source" version="9.4.36.v20210114"/> - <repository id="jetty-9.4.36" location="https://download.eclipse.org/jetty/updates/jetty-bundles-9.x/9.4.36.v20210114/"/> + <unit id="org.eclipse.jetty.client" version="9.4.40.v20210413"/> + <unit id="org.eclipse.jetty.client.source" version="9.4.40.v20210413"/> + <unit id="org.eclipse.jetty.continuation" version="9.4.40.v20210413"/> + <unit id="org.eclipse.jetty.continuation.source" version="9.4.40.v20210413"/> + <unit id="org.eclipse.jetty.http" version="9.4.40.v20210413"/> + <unit id="org.eclipse.jetty.http.source" version="9.4.40.v20210413"/> + <unit id="org.eclipse.jetty.io" version="9.4.40.v20210413"/> + <unit id="org.eclipse.jetty.io.source" version="9.4.40.v20210413"/> + <unit id="org.eclipse.jetty.security" version="9.4.40.v20210413"/> + <unit id="org.eclipse.jetty.security.source" version="9.4.40.v20210413"/> + <unit id="org.eclipse.jetty.server" version="9.4.40.v20210413"/> + <unit id="org.eclipse.jetty.server.source" version="9.4.40.v20210413"/> + <unit id="org.eclipse.jetty.servlet" version="9.4.40.v20210413"/> + <unit id="org.eclipse.jetty.servlet.source" version="9.4.40.v20210413"/> + <unit id="org.eclipse.jetty.util" version="9.4.40.v20210413"/> + <unit id="org.eclipse.jetty.util.source" version="9.4.40.v20210413"/> + <unit id="org.eclipse.jetty.util.ajax" version="9.4.40.v20210413"/> + <unit id="org.eclipse.jetty.util.ajax.source" version="9.4.40.v20210413"/> + <repository id="jetty-9.4.36" location="https://download.eclipse.org/jetty/updates/jetty-bundles-9.x/9.4.40.v20210413/"/> </location> <location includeMode="slicer" includeAllPlatforms="false" includeSource="true" includeConfigurePhase="true" type="InstallableUnit"> <unit id="com.google.gson" version="2.8.6.v20201231-1626"/> @@ -86,7 +86,7 @@ <unit id="org.slf4j.binding.log4j12.source" version="1.7.30.v20201108-2042"/> <unit id="org.tukaani.xz" version="1.8.0.v20180207-1613"/> <unit id="org.tukaani.xz.source" version="1.8.0.v20180207-1613"/> - <repository location="https://download.eclipse.org/tools/orbit/downloads/drops/R20210223232630/repository"/> + <repository location="https://download.eclipse.org/tools/orbit/downloads/drops/S20210406213021/repository"/> </location> <location includeMode="slicer" includeAllPlatforms="false" includeSource="true" includeConfigurePhase="true" type="InstallableUnit"> <unit id="org.eclipse.osgi" version="0.0.0"/> diff --git a/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.8.tpd b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.8.tpd index 31148776f6..f7ac2c0b94 100644 --- a/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.8.tpd +++ b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.8.tpd @@ -1,7 +1,7 @@ target "jgit-4.8" with source configurePhase include "projects/jetty-9.4.x.tpd" -include "orbit/R20210223232630-2021-03.tpd" +include "orbit/S20210406213021.tpd" location "https://download.eclipse.org/releases/photon/" { org.eclipse.osgi lazy diff --git a/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.9.target b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.9.target index 55b3c60568..46c2644b3c 100644 --- a/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.9.target +++ b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.9.target @@ -1,28 +1,28 @@ <?xml version="1.0" encoding="UTF-8" standalone="no"?> <?pde?> <!-- generated with https://github.com/eclipse-cbi/targetplatform-dsl --> -<target name="jgit-4.9" sequenceNumber="1615333029"> +<target name="jgit-4.9" sequenceNumber="1619186290"> <locations> <location includeMode="slicer" includeAllPlatforms="false" includeSource="true" includeConfigurePhase="true" type="InstallableUnit"> - <unit id="org.eclipse.jetty.client" version="9.4.36.v20210114"/> - <unit id="org.eclipse.jetty.client.source" version="9.4.36.v20210114"/> - <unit id="org.eclipse.jetty.continuation" version="9.4.36.v20210114"/> - <unit id="org.eclipse.jetty.continuation.source" version="9.4.36.v20210114"/> - <unit id="org.eclipse.jetty.http" version="9.4.36.v20210114"/> - <unit id="org.eclipse.jetty.http.source" version="9.4.36.v20210114"/> - <unit id="org.eclipse.jetty.io" version="9.4.36.v20210114"/> - <unit id="org.eclipse.jetty.io.source" version="9.4.36.v20210114"/> - <unit id="org.eclipse.jetty.security" version="9.4.36.v20210114"/> - <unit id="org.eclipse.jetty.security.source" version="9.4.36.v20210114"/> - <unit id="org.eclipse.jetty.server" version="9.4.36.v20210114"/> - <unit id="org.eclipse.jetty.server.source" version="9.4.36.v20210114"/> - <unit id="org.eclipse.jetty.servlet" version="9.4.36.v20210114"/> - <unit id="org.eclipse.jetty.servlet.source" version="9.4.36.v20210114"/> - <unit id="org.eclipse.jetty.util" version="9.4.36.v20210114"/> - <unit id="org.eclipse.jetty.util.source" version="9.4.36.v20210114"/> - <unit id="org.eclipse.jetty.util.ajax" version="9.4.36.v20210114"/> - <unit id="org.eclipse.jetty.util.ajax.source" version="9.4.36.v20210114"/> - <repository id="jetty-9.4.36" location="https://download.eclipse.org/jetty/updates/jetty-bundles-9.x/9.4.36.v20210114/"/> + <unit id="org.eclipse.jetty.client" version="9.4.40.v20210413"/> + <unit id="org.eclipse.jetty.client.source" version="9.4.40.v20210413"/> + <unit id="org.eclipse.jetty.continuation" version="9.4.40.v20210413"/> + <unit id="org.eclipse.jetty.continuation.source" version="9.4.40.v20210413"/> + <unit id="org.eclipse.jetty.http" version="9.4.40.v20210413"/> + <unit id="org.eclipse.jetty.http.source" version="9.4.40.v20210413"/> + <unit id="org.eclipse.jetty.io" version="9.4.40.v20210413"/> + <unit id="org.eclipse.jetty.io.source" version="9.4.40.v20210413"/> + <unit id="org.eclipse.jetty.security" version="9.4.40.v20210413"/> + <unit id="org.eclipse.jetty.security.source" version="9.4.40.v20210413"/> + <unit id="org.eclipse.jetty.server" version="9.4.40.v20210413"/> + <unit id="org.eclipse.jetty.server.source" version="9.4.40.v20210413"/> + <unit id="org.eclipse.jetty.servlet" version="9.4.40.v20210413"/> + <unit id="org.eclipse.jetty.servlet.source" version="9.4.40.v20210413"/> + <unit id="org.eclipse.jetty.util" version="9.4.40.v20210413"/> + <unit id="org.eclipse.jetty.util.source" version="9.4.40.v20210413"/> + <unit id="org.eclipse.jetty.util.ajax" version="9.4.40.v20210413"/> + <unit id="org.eclipse.jetty.util.ajax.source" version="9.4.40.v20210413"/> + <repository id="jetty-9.4.36" location="https://download.eclipse.org/jetty/updates/jetty-bundles-9.x/9.4.40.v20210413/"/> </location> <location includeMode="slicer" includeAllPlatforms="false" includeSource="true" includeConfigurePhase="true" type="InstallableUnit"> <unit id="com.google.gson" version="2.8.6.v20201231-1626"/> @@ -86,7 +86,7 @@ <unit id="org.slf4j.binding.log4j12.source" version="1.7.30.v20201108-2042"/> <unit id="org.tukaani.xz" version="1.8.0.v20180207-1613"/> <unit id="org.tukaani.xz.source" version="1.8.0.v20180207-1613"/> - <repository location="https://download.eclipse.org/tools/orbit/downloads/drops/R20210223232630/repository"/> + <repository location="https://download.eclipse.org/tools/orbit/downloads/drops/S20210406213021/repository"/> </location> <location includeMode="slicer" includeAllPlatforms="false" includeSource="true" includeConfigurePhase="true" type="InstallableUnit"> <unit id="org.eclipse.osgi" version="0.0.0"/> diff --git a/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.9.tpd b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.9.tpd index 132a0b06f0..c77376aae4 100644 --- a/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.9.tpd +++ b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.9.tpd @@ -1,7 +1,7 @@ target "jgit-4.9" with source configurePhase include "projects/jetty-9.4.x.tpd" -include "orbit/R20210223232630-2021-03.tpd" +include "orbit/S20210406213021.tpd" location "https://download.eclipse.org/releases/2018-09/" { org.eclipse.osgi lazy diff --git a/org.eclipse.jgit.packaging/org.eclipse.jgit.target/orbit/S20210406213021.tpd b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/orbit/S20210406213021.tpd new file mode 100644 index 0000000000..45d0fd1618 --- /dev/null +++ b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/orbit/S20210406213021.tpd @@ -0,0 +1,66 @@ +target "S20210406213021" with source configurePhase +// see https://download.eclipse.org/tools/orbit/downloads/ + +location "https://download.eclipse.org/tools/orbit/downloads/drops/S20210406213021/repository" { + com.google.gson [2.8.6.v20201231-1626,2.8.6.v20201231-1626] + com.google.gson.source [2.8.6.v20201231-1626,2.8.6.v20201231-1626] + com.jcraft.jsch [0.1.55.v20190404-1902,0.1.55.v20190404-1902] + com.jcraft.jsch.source [0.1.55.v20190404-1902,0.1.55.v20190404-1902] + com.jcraft.jzlib [1.1.1.v201205102305,1.1.1.v201205102305] + com.jcraft.jzlib.source [1.1.1.v201205102305,1.1.1.v201205102305] + javaewah [1.1.7.v20200107-0831,1.1.7.v20200107-0831] + javaewah.source [1.1.7.v20200107-0831,1.1.7.v20200107-0831] + javax.servlet [3.1.0.v201410161800,3.1.0.v201410161800] + javax.servlet.source [3.1.0.v201410161800,3.1.0.v201410161800] + net.bytebuddy.byte-buddy [1.9.0.v20181107-1410,1.9.0.v20181107-1410] + net.bytebuddy.byte-buddy-agent [1.9.0.v20181106-1534,1.9.0.v20181106-1534] + net.bytebuddy.byte-buddy-agent.source [1.9.0.v20181106-1534,1.9.0.v20181106-1534] + net.bytebuddy.byte-buddy.source [1.9.0.v20181107-1410,1.9.0.v20181107-1410] + net.i2p.crypto.eddsa [0.3.0.v20181102-1323,0.3.0.v20181102-1323] + net.i2p.crypto.eddsa.source [0.3.0.v20181102-1323,0.3.0.v20181102-1323] + org.apache.ant [1.10.9.v20201106-1946,1.10.9.v20201106-1946] + org.apache.ant.source [1.10.9.v20201106-1946,1.10.9.v20201106-1946] + org.apache.commons.codec [1.14.0.v20200818-1422,1.14.0.v20200818-1422] + org.apache.commons.codec.source [1.14.0.v20200818-1422,1.14.0.v20200818-1422] + org.apache.commons.compress [1.19.0.v20200106-2343,1.19.0.v20200106-2343] + org.apache.commons.compress.source [1.19.0.v20200106-2343,1.19.0.v20200106-2343] + org.apache.commons.logging [1.2.0.v20180409-1502,1.2.0.v20180409-1502] + org.apache.commons.logging.source [1.2.0.v20180409-1502,1.2.0.v20180409-1502] + org.apache.httpcomponents.httpclient [4.5.13.v20210128-2225,4.5.13.v20210128-2225] + org.apache.httpcomponents.httpclient.source [4.5.13.v20210128-2225,4.5.13.v20210128-2225] + org.apache.httpcomponents.httpcore [4.4.14.v20210128-2225,4.4.14.v20210128-2225] + org.apache.httpcomponents.httpcore.source [4.4.14.v20210128-2225,4.4.14.v20210128-2225] + org.apache.log4j [1.2.15.v201012070815,1.2.15.v201012070815] + org.apache.log4j.source [1.2.15.v201012070815,1.2.15.v201012070815] + org.apache.sshd.osgi [2.6.0.v20210201-2003,2.6.0.v20210201-2003] + org.apache.sshd.osgi.source [2.6.0.v20210201-2003,2.6.0.v20210201-2003] + org.apache.sshd.sftp [2.6.0.v20210201-2003,2.6.0.v20210201-2003] + org.apache.sshd.sftp.source [2.6.0.v20210201-2003,2.6.0.v20210201-2003] + org.assertj [3.14.0.v20200120-1926,3.14.0.v20200120-1926] + org.assertj.source [3.14.0.v20200120-1926,3.14.0.v20200120-1926] + org.bouncycastle.bcpg [1.65.0.v20200527-1955,1.65.0.v20200527-1955] + org.bouncycastle.bcpg.source [1.65.0.v20200527-1955,1.65.0.v20200527-1955] + org.bouncycastle.bcpkix [1.65.0.v20200527-1955,1.65.0.v20200527-1955] + org.bouncycastle.bcpkix.source [1.65.0.v20200527-1955,1.65.0.v20200527-1955] + org.bouncycastle.bcprov [1.65.1.v20200529-1514,1.65.1.v20200529-1514] + org.bouncycastle.bcprov.source [1.65.1.v20200529-1514,1.65.1.v20200529-1514] + org.hamcrest [1.1.0.v20090501071000,1.1.0.v20090501071000] + org.hamcrest.core [1.3.0.v20180420-1519,1.3.0.v20180420-1519] + org.hamcrest.core.source [1.3.0.v20180420-1519,1.3.0.v20180420-1519] + org.hamcrest.library [1.3.0.v20180524-2246,1.3.0.v20180524-2246] + org.hamcrest.library.source [1.3.0.v20180524-2246,1.3.0.v20180524-2246] + org.junit [4.13.0.v20200204-1500,4.13.0.v20200204-1500] + org.junit.source [4.13.0.v20200204-1500,4.13.0.v20200204-1500] + org.kohsuke.args4j [2.33.0.v20160323-2218,2.33.0.v20160323-2218] + org.kohsuke.args4j.source [2.33.0.v20160323-2218,2.33.0.v20160323-2218] + org.mockito [2.23.0.v20200310-1642,2.23.0.v20200310-1642] + org.mockito.source [2.23.0.v20200310-1642,2.23.0.v20200310-1642] + org.objenesis [2.6.0.v20180420-1519,2.6.0.v20180420-1519] + org.objenesis.source [2.6.0.v20180420-1519,2.6.0.v20180420-1519] + org.slf4j.api [1.7.30.v20200204-2150,1.7.30.v20200204-2150] + org.slf4j.api.source [1.7.30.v20200204-2150,1.7.30.v20200204-2150] + org.slf4j.binding.log4j12 [1.7.30.v20201108-2042,1.7.30.v20201108-2042] + org.slf4j.binding.log4j12.source [1.7.30.v20201108-2042,1.7.30.v20201108-2042] + org.tukaani.xz [1.8.0.v20180207-1613,1.8.0.v20180207-1613] + org.tukaani.xz.source [1.8.0.v20180207-1613,1.8.0.v20180207-1613] +} diff --git a/org.eclipse.jgit.packaging/org.eclipse.jgit.target/projects/jetty-9.4.x.tpd b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/projects/jetty-9.4.x.tpd index 4eec8aa354..0f0b1005ce 100644 --- a/org.eclipse.jgit.packaging/org.eclipse.jgit.target/projects/jetty-9.4.x.tpd +++ b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/projects/jetty-9.4.x.tpd @@ -1,22 +1,22 @@ target "jetty-9.4.x" with source configurePhase -location jetty-9.4.36 "https://download.eclipse.org/jetty/updates/jetty-bundles-9.x/9.4.36.v20210114/" { - org.eclipse.jetty.client [9.4.36.v20210114,9.4.36.v20210114] - org.eclipse.jetty.client.source [9.4.36.v20210114,9.4.36.v20210114] - org.eclipse.jetty.continuation [9.4.36.v20210114,9.4.36.v20210114] - org.eclipse.jetty.continuation.source [9.4.36.v20210114,9.4.36.v20210114] - org.eclipse.jetty.http [9.4.36.v20210114,9.4.36.v20210114] - org.eclipse.jetty.http.source [9.4.36.v20210114,9.4.36.v20210114] - org.eclipse.jetty.io [9.4.36.v20210114,9.4.36.v20210114] - org.eclipse.jetty.io.source [9.4.36.v20210114,9.4.36.v20210114] - org.eclipse.jetty.security [9.4.36.v20210114,9.4.36.v20210114] - org.eclipse.jetty.security.source [9.4.36.v20210114,9.4.36.v20210114] - org.eclipse.jetty.server [9.4.36.v20210114,9.4.36.v20210114] - org.eclipse.jetty.server.source [9.4.36.v20210114,9.4.36.v20210114] - org.eclipse.jetty.servlet [9.4.36.v20210114,9.4.36.v20210114] - org.eclipse.jetty.servlet.source [9.4.36.v20210114,9.4.36.v20210114] - org.eclipse.jetty.util [9.4.36.v20210114,9.4.36.v20210114] - org.eclipse.jetty.util.source [9.4.36.v20210114,9.4.36.v20210114] - org.eclipse.jetty.util.ajax [9.4.36.v20210114,9.4.36.v20210114] - org.eclipse.jetty.util.ajax.source [9.4.36.v20210114,9.4.36.v20210114] +location jetty-9.4.40 "https://download.eclipse.org/jetty/updates/jetty-bundles-9.x/9.4.40.v20210413/" { + org.eclipse.jetty.client [9.4.40.v20210413,9.4.40.v20210413] + org.eclipse.jetty.client.source [9.4.40.v20210413,9.4.40.v20210413] + org.eclipse.jetty.continuation [9.4.40.v20210413,9.4.40.v20210413] + org.eclipse.jetty.continuation.source [9.4.40.v20210413,9.4.40.v20210413] + org.eclipse.jetty.http [9.4.40.v20210413,9.4.40.v20210413] + org.eclipse.jetty.http.source [9.4.40.v20210413,9.4.40.v20210413] + org.eclipse.jetty.io [9.4.40.v20210413,9.4.40.v20210413] + org.eclipse.jetty.io.source [9.4.40.v20210413,9.4.40.v20210413] + org.eclipse.jetty.security [9.4.40.v20210413,9.4.40.v20210413] + org.eclipse.jetty.security.source [9.4.40.v20210413,9.4.40.v20210413] + org.eclipse.jetty.server [9.4.40.v20210413,9.4.40.v20210413] + org.eclipse.jetty.server.source [9.4.40.v20210413,9.4.40.v20210413] + org.eclipse.jetty.servlet [9.4.40.v20210413,9.4.40.v20210413] + org.eclipse.jetty.servlet.source [9.4.40.v20210413,9.4.40.v20210413] + org.eclipse.jetty.util [9.4.40.v20210413,9.4.40.v20210413] + org.eclipse.jetty.util.source [9.4.40.v20210413,9.4.40.v20210413] + org.eclipse.jetty.util.ajax [9.4.40.v20210413,9.4.40.v20210413] + org.eclipse.jetty.util.ajax.source [9.4.40.v20210413,9.4.40.v20210413] } diff --git a/org.eclipse.jgit.packaging/pom.xml b/org.eclipse.jgit.packaging/pom.xml index 313c6632c2..f3287f1b8f 100644 --- a/org.eclipse.jgit.packaging/pom.xml +++ b/org.eclipse.jgit.packaging/pom.xml @@ -294,7 +294,7 @@ <plugin> <groupId>org.eclipse.cbi.maven.plugins</groupId> <artifactId>eclipse-jarsigner-plugin</artifactId> - <version>1.1.7</version> + <version>1.3.1</version> </plugin> <plugin> <groupId>org.codehaus.mojo</groupId> diff --git a/org.eclipse.jgit.pgm/resources/org/eclipse/jgit/pgm/internal/CLIText.properties b/org.eclipse.jgit.pgm/resources/org/eclipse/jgit/pgm/internal/CLIText.properties index 83846ee8e9..38deab99a0 100644 --- a/org.eclipse.jgit.pgm/resources/org/eclipse/jgit/pgm/internal/CLIText.properties +++ b/org.eclipse.jgit.pgm/resources/org/eclipse/jgit/pgm/internal/CLIText.properties @@ -115,6 +115,7 @@ metaVar_configFile=FILE metaVar_connProp=conn.prop metaVar_diffAlg=ALGORITHM metaVar_directory=DIRECTORY +metaVar_extraArgument=ours|theirs metaVar_file=FILE metaVar_filepattern=filepattern metaVar_gitDir=GIT_DIR @@ -217,6 +218,7 @@ timeInMilliSeconds={0} ms treeIsRequired=argument tree is required tooManyRefsGiven=Too many refs given unknownIoErrorStdout=An unknown I/O error occurred on standard output +unknownExtraArgument=unknown extra argument -X {0} specified unknownMergeStrategy=unknown merge strategy {0} specified unknownSubcommand=Unknown subcommand: {0} unmergedPaths=Unmerged paths: @@ -226,6 +228,7 @@ updating=Updating {0}..{1} usage_Aggressive=This option will cause gc to more aggressively optimize the repository at the expense of taking much more time usage_AlwaysFallback=Show uniquely abbreviated commit object as fallback usage_bareClone=Make a bare Git repository. That is, instead of creating [DIRECTORY] and placing the administrative files in [DIRECTORY]/.git, make the [DIRECTORY] itself the $GIT_DIR. +usage_extraArgument=Pass an extra argument to a merge driver. Currently supported are "-X ours" and "-X theirs". usage_mirrorClone=Set up a mirror of the source repository. This implies --bare. Compared to --bare, --mirror not only maps \ local branches of the source to local branches of the target, it maps all refs (including remote-tracking branches, notes etc.) \ and sets up a refspec configuration such that all these refs are overwritten by a git remote update in the target repository. diff --git a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/Merge.java b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/Merge.java index fdc449e063..ca4877fb34 100644 --- a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/Merge.java +++ b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/Merge.java @@ -24,6 +24,7 @@ import org.eclipse.jgit.lib.AnyObjectId; import org.eclipse.jgit.lib.Constants; import org.eclipse.jgit.lib.ObjectId; import org.eclipse.jgit.lib.Ref; +import org.eclipse.jgit.merge.ContentMergeStrategy; import org.eclipse.jgit.merge.MergeStrategy; import org.eclipse.jgit.merge.ResolveMerger.MergeFailureReason; import org.eclipse.jgit.pgm.internal.CLIText; @@ -69,6 +70,20 @@ class Merge extends TextBuiltin { @Option(name = "-m", usage = "usage_message") private String message; + private ContentMergeStrategy contentStrategy = null; + + @Option(name = "--strategy-option", aliases = { "-X" }, + metaVar = "metaVar_extraArgument", usage = "usage_extraArgument") + void extraArg(String name) { + if (ContentMergeStrategy.OURS.name().equalsIgnoreCase(name)) { + contentStrategy = ContentMergeStrategy.OURS; + } else if (ContentMergeStrategy.THEIRS.name().equalsIgnoreCase(name)) { + contentStrategy = ContentMergeStrategy.THEIRS; + } else { + throw die(MessageFormat.format(CLIText.get().unknownExtraArgument, name)); + } + } + /** {@inheritDoc} */ @Override protected void run() { @@ -96,8 +111,11 @@ class Merge extends TextBuiltin { Ref oldHead = getOldHead(); MergeResult result; try (Git git = new Git(db)) { - MergeCommand mergeCmd = git.merge().setStrategy(mergeStrategy) - .setSquash(squash).setFastForward(ff) + MergeCommand mergeCmd = git.merge() + .setStrategy(mergeStrategy) + .setContentMergeStrategy(contentStrategy) + .setSquash(squash) + .setFastForward(ff) .setCommit(!noCommit); if (srcRef != null) { mergeCmd.include(srcRef); diff --git a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/internal/CLIText.java b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/internal/CLIText.java index 991b3ba58a..8e49a76a33 100644 --- a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/internal/CLIText.java +++ b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/internal/CLIText.java @@ -284,6 +284,7 @@ public class CLIText extends TranslationBundle { /***/ public String tooManyRefsGiven; /***/ public String treeIsRequired; /***/ public char[] unknownIoErrorStdout; + /***/ public String unknownExtraArgument; /***/ public String unknownMergeStrategy; /***/ public String unknownSubcommand; /***/ public String unmergedPaths; diff --git a/org.eclipse.jgit.ssh.apache.test/META-INF/MANIFEST.MF b/org.eclipse.jgit.ssh.apache.test/META-INF/MANIFEST.MF index d881d87755..0070730123 100644 --- a/org.eclipse.jgit.ssh.apache.test/META-INF/MANIFEST.MF +++ b/org.eclipse.jgit.ssh.apache.test/META-INF/MANIFEST.MF @@ -14,6 +14,7 @@ Import-Package: org.apache.sshd.client.config.hosts;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.signature;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)", diff --git a/org.eclipse.jgit.ssh.apache.test/build.properties b/org.eclipse.jgit.ssh.apache.test/build.properties index 9ffa0caf78..406c5a768f 100644 --- a/org.eclipse.jgit.ssh.apache.test/build.properties +++ b/org.eclipse.jgit.ssh.apache.test/build.properties @@ -3,3 +3,5 @@ output.. = bin/ bin.includes = META-INF/,\ .,\ plugin.properties +additional.bundles = org.apache.log4j,\ + org.slf4j.binding.log4j12 diff --git a/org.eclipse.jgit.ssh.apache.test/tst/org/eclipse/jgit/transport/sshd/ApacheSshTest.java b/org.eclipse.jgit.ssh.apache.test/tst/org/eclipse/jgit/transport/sshd/ApacheSshTest.java index 97f97f9028..c56d2307c6 100644 --- a/org.eclipse.jgit.ssh.apache.test/tst/org/eclipse/jgit/transport/sshd/ApacheSshTest.java +++ b/org.eclipse.jgit.ssh.apache.test/tst/org/eclipse/jgit/transport/sshd/ApacheSshTest.java @@ -47,7 +47,9 @@ import org.eclipse.jgit.api.Git; import org.eclipse.jgit.api.errors.TransportException; import org.eclipse.jgit.junit.ssh.SshTestBase; import org.eclipse.jgit.lib.Constants; +import org.eclipse.jgit.transport.RemoteSession; import org.eclipse.jgit.transport.SshSessionFactory; +import org.eclipse.jgit.transport.URIish; import org.eclipse.jgit.util.FS; import org.junit.Test; import org.junit.experimental.theories.Theories; @@ -232,64 +234,89 @@ public class ApacheSshTest extends SshTestBase { } /** - * Creates a simple proxy server. Accepts only publickey authentication from - * the given user with the given key, allows all forwardings. Adds the - * proxy's host key to {@link #knownHosts}. + * Creates a simple SSH server without git setup. * * @param user * to accept * @param userKey * public key of that user at this server - * @param report - * single-element array to report back the forwarded address. - * @return the started server + * @return the {@link SshServer}, not yet started * @throws Exception */ - private SshServer createProxy(String user, File userKey, - SshdSocketAddress[] report) throws Exception { - SshServer proxy = SshServer.setUpDefaultServer(); + private SshServer createServer(String user, File userKey) throws Exception { + SshServer srv = SshServer.setUpDefaultServer(); // Give the server its own host key KeyPairGenerator generator = KeyPairGenerator.getInstance("RSA"); generator.initialize(2048); KeyPair proxyHostKey = generator.generateKeyPair(); - proxy.setKeyPairProvider( + srv.setKeyPairProvider( session -> Collections.singletonList(proxyHostKey)); // Allow (only) publickey authentication - proxy.setUserAuthFactories(Collections.singletonList( + srv.setUserAuthFactories(Collections.singletonList( ServerAuthenticationManager.DEFAULT_USER_AUTH_PUBLIC_KEY_FACTORY)); // Install the user's public key PublicKey userProxyKey = AuthorizedKeyEntry .readAuthorizedKeys(userKey.toPath()).get(0) .resolvePublicKey(null, PublicKeyEntryResolver.IGNORING); - proxy.setPublickeyAuthenticator( + srv.setPublickeyAuthenticator( (userName, publicKey, session) -> user.equals(userName) && KeyUtils.compareKeys(userProxyKey, publicKey)); - // Allow forwarding - proxy.setForwardingFilter(new StaticDecisionForwardingFilter(true) { + return srv; + } - @Override - protected boolean checkAcceptance(String request, Session session, - SshdSocketAddress target) { - report[0] = target; - return super.checkAcceptance(request, session, target); - } - }); - proxy.start(); + /** + * Writes the server's host key to our knownhosts file. + * + * @param srv to register + * @throws Exception + */ + private void registerServer(SshServer srv) throws Exception { // Add the proxy's host key to knownhosts try (BufferedWriter writer = Files.newBufferedWriter( knownHosts.toPath(), StandardCharsets.US_ASCII, StandardOpenOption.WRITE, StandardOpenOption.APPEND)) { writer.append('\n'); KnownHostHashValue.appendHostPattern(writer, "localhost", - proxy.getPort()); + srv.getPort()); writer.append(','); KnownHostHashValue.appendHostPattern(writer, "127.0.0.1", - proxy.getPort()); + srv.getPort()); writer.append(' '); PublicKeyEntry.appendPublicKeyEntry(writer, - proxyHostKey.getPublic()); + srv.getKeyPairProvider().loadKeys(null).iterator().next().getPublic()); writer.append('\n'); } + } + + /** + * Creates a simple proxy server. Accepts only publickey authentication from + * the given user with the given key, allows all forwardings. Adds the + * proxy's host key to {@link #knownHosts}. + * + * @param user + * to accept + * @param userKey + * public key of that user at this server + * @param report + * single-element array to report back the forwarded address. + * @return the started server + * @throws Exception + */ + private SshServer createProxy(String user, File userKey, + SshdSocketAddress[] report) throws Exception { + SshServer proxy = createServer(user, userKey); + // Allow forwarding + proxy.setForwardingFilter(new StaticDecisionForwardingFilter(true) { + + @Override + protected boolean checkAcceptance(String request, Session session, + SshdSocketAddress target) { + report[0] = target; + return super.checkAcceptance(request, session, target); + } + }); + proxy.start(); + registerServer(proxy); return proxy; } @@ -606,4 +633,73 @@ public class ApacheSshTest extends SshTestBase { } } } + + /** + * Tests that one can log in to an old server that doesn't handle + * rsa-sha2-512 if one puts ssh-rsa first in the client's list of public key + * signature algorithms. + * + * @see <a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=572056">bug + * 572056</a> + * @throws Exception + * on failure + */ + @Test + public void testConnectAuthSshRsaPubkeyAcceptedAlgorithms() + throws Exception { + try (SshServer oldServer = createServer(TEST_USER, publicKey1)) { + oldServer.setSignatureFactoriesNames("ssh-rsa"); + oldServer.start(); + registerServer(oldServer); + installConfig("Host server", // + "HostName localhost", // + "Port " + oldServer.getPort(), // + "User " + TEST_USER, // + "IdentityFile " + privateKey1.getAbsolutePath(), // + "PubkeyAcceptedAlgorithms ^ssh-rsa"); + RemoteSession session = getSessionFactory().getSession( + new URIish("ssh://server/doesntmatter"), null, FS.DETECTED, + 10000); + assertNotNull(session); + session.disconnect(); + } + } + + /** + * Tests that one can log in to an old server that knows only the ssh-rsa + * signature algorithm. The client has by default the list of signature + * algorithms for RSA as "rsa-sha2-512,rsa-sha2-256,ssh-rsa". It should try + * all three with the single key configured, and finally succeed. + * <p> + * The re-ordering mechanism (see + * {@link #testConnectAuthSshRsaPubkeyAcceptedAlgorithms()}) is still + * important; servers may impose a penalty (back-off delay) for subsequent + * attempts with signature algorithms unknown to the server. So a user + * connecting to such a server and noticing delays may still want to put + * ssh-rsa first in the list for that host. + * </p> + * + * @see <a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=572056">bug + * 572056</a> + * @throws Exception + * on failure + */ + @Test + public void testConnectAuthSshRsa() throws Exception { + try (SshServer oldServer = createServer(TEST_USER, publicKey1)) { + oldServer.setSignatureFactoriesNames("ssh-rsa"); + oldServer.start(); + registerServer(oldServer); + installConfig("Host server", // + "HostName localhost", // + "Port " + oldServer.getPort(), // + "User " + TEST_USER, // + "IdentityFile " + privateKey1.getAbsolutePath()); + RemoteSession session = getSessionFactory().getSession( + new URIish("ssh://server/doesntmatter"), null, FS.DETECTED, + 10000); + assertNotNull(session); + session.disconnect(); + } + } } diff --git a/org.eclipse.jgit.ssh.apache/META-INF/MANIFEST.MF b/org.eclipse.jgit.ssh.apache/META-INF/MANIFEST.MF index faa52b26ac..89b5133afc 100644 --- a/org.eclipse.jgit.ssh.apache/META-INF/MANIFEST.MF +++ b/org.eclipse.jgit.ssh.apache/META-INF/MANIFEST.MF @@ -59,6 +59,8 @@ Import-Package: net.i2p.crypto.eddsa;version="[0.3.0,0.4.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.kex.extension;version="[2.6.0,2.7.0)", + org.apache.sshd.common.kex.extension.parser;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)", diff --git a/org.eclipse.jgit.ssh.apache/resources/org/eclipse/jgit/internal/transport/sshd/SshdText.properties b/org.eclipse.jgit.ssh.apache/resources/org/eclipse/jgit/internal/transport/sshd/SshdText.properties index f810fd40e4..5bc0867674 100644 --- a/org.eclipse.jgit.ssh.apache/resources/org/eclipse/jgit/internal/transport/sshd/SshdText.properties +++ b/org.eclipse.jgit.ssh.apache/resources/org/eclipse/jgit/internal/transport/sshd/SshdText.properties @@ -5,8 +5,7 @@ configInvalidPath=Invalid path in ssh config key {0}: {1} configInvalidPattern=Invalid pattern in ssh config key {0}: {1} configInvalidPositive=Ssh config entry {0} must be a strictly positive number but is ''{1}'' configInvalidProxyJump=Ssh config, host ''{0}'': Cannot parse ProxyJump ''{1}'' -configNoKnownHostKeyAlgorithms=No implementations for any of the algorithms ''{0}'' given in HostKeyAlgorithms in the ssh config; using the default. -configNoRemainingHostKeyAlgorithms=Ssh config removed all host key algorithms: HostKeyAlgorithms ''{0}'' +configNoKnownAlgorithms=Ssh config ''{0}'' ''{1}'' resulted in empty list (none known, or all known removed); using default. configProxyJumpNotSsh=Non-ssh URI in ProxyJump ssh config configProxyJumpWithPath=ProxyJump ssh config: jump host specification must not have a path ftpCloseFailed=Closing the SFTP channel failed @@ -25,7 +24,6 @@ keyEncryptedPrompt=Passphrase keyEncryptedRetry=Encrypted key ''{0}'' could not be decrypted. Enter the passphrase again. keyLoadFailed=Could not load key ''{0}'' knownHostsCouldNotUpdate=Could not update known hosts file {0} -knownHostsFileLockedRead=Could not read known hosts file (locked) {0} knownHostsFileLockedUpdate=Could not update known hosts file (locked) {0} knownHostsFileReadFailed=Failed to read known hosts file {0} knownHostsInvalidLine=Known hosts file {0} contains invalid line {1} @@ -77,6 +75,9 @@ proxySocksPasswordTooLong=Password for proxy {0} must be at most 255 bytes long, proxySocksUnexpectedMessage=Unexpected message received from SOCKS5 proxy {0}; client state {1}: {2} proxySocksUnexpectedVersion=Expected SOCKS version 5, got {0} proxySocksUsernameTooLong=User name for proxy {0} must be at most 255 bytes long, is {1} bytes: {2} +pubkeyAuthWrongCommand=Public key authentication received unknown SSH command {0} from {1} ({2}) +pubkeyAuthWrongKey=Public key authentication received wrong key; sent {0}, got back {1} from {2} ({3}) +pubkeyAuthWrongSignatureAlgorithm=Public key authentication requested signature type {0} but got back {1} from {2} ({3}) serverIdNotReceived=No server identification received within {0} bytes serverIdTooLong=Server identification is longer than 255 characters (including line ending): {0} serverIdWithNul=Server identification contains a NUL character: {0} diff --git a/org.eclipse.jgit.ssh.apache/src/org/eclipse/jgit/internal/transport/sshd/JGitClientSession.java b/org.eclipse.jgit.ssh.apache/src/org/eclipse/jgit/internal/transport/sshd/JGitClientSession.java index 66713ba632..8183a92b9f 100644 --- a/org.eclipse.jgit.ssh.apache/src/org/eclipse/jgit/internal/transport/sshd/JGitClientSession.java +++ b/org.eclipse.jgit.ssh.apache/src/org/eclipse/jgit/internal/transport/sshd/JGitClientSession.java @@ -21,6 +21,7 @@ import java.security.PublicKey; import java.util.ArrayList; import java.util.Collection; import java.util.Collections; +import java.util.HashSet; import java.util.Iterator; import java.util.LinkedHashSet; import java.util.List; @@ -45,6 +46,7 @@ import org.eclipse.jgit.fnmatch.FileNameMatcher; import org.eclipse.jgit.internal.transport.sshd.proxy.StatefulProxyConnector; import org.eclipse.jgit.transport.CredentialsProvider; import org.eclipse.jgit.transport.SshConstants; +import org.eclipse.jgit.util.StringUtils; /** * A {@link org.apache.sshd.client.session.ClientSession ClientSession} that can @@ -201,48 +203,23 @@ public class JGitClientSession extends ClientSessionImpl { @Override protected String resolveAvailableSignaturesProposal( FactoryManager manager) { - Set<String> defaultSignatures = new LinkedHashSet<>(); - defaultSignatures.addAll(getSignatureFactoriesNames()); + List<String> defaultSignatures = getSignatureFactoriesNames(); HostConfigEntry config = resolveAttribute( JGitSshClient.HOST_CONFIG_ENTRY); - String hostKeyAlgorithms = config + String algorithms = config .getProperty(SshConstants.HOST_KEY_ALGORITHMS); - if (hostKeyAlgorithms != null && !hostKeyAlgorithms.isEmpty()) { - char first = hostKeyAlgorithms.charAt(0); - switch (first) { - case '+': - // Additions make not much sense -- it's either in - // defaultSignatures already, or we have no implementation for - // it. No point in proposing it. - return String.join(",", defaultSignatures); //$NON-NLS-1$ - case '-': - // This takes wildcard patterns! - removeFromList(defaultSignatures, - SshConstants.HOST_KEY_ALGORITHMS, - hostKeyAlgorithms.substring(1)); - if (defaultSignatures.isEmpty()) { - // Too bad: user config error. Warn here, and then fail - // later. - log.warn(format( - SshdText.get().configNoRemainingHostKeyAlgorithms, - hostKeyAlgorithms)); - } - return String.join(",", defaultSignatures); //$NON-NLS-1$ - default: - // Default is overridden -- only accept the ones for which we do - // have an implementation. - List<String> newNames = filteredList(defaultSignatures, - hostKeyAlgorithms); - if (newNames.isEmpty()) { - log.warn(format( - SshdText.get().configNoKnownHostKeyAlgorithms, - hostKeyAlgorithms)); - // Use the default instead. - } else { - return String.join(",", newNames); //$NON-NLS-1$ + if (!StringUtils.isEmptyOrNull(algorithms)) { + List<String> result = modifyAlgorithmList(defaultSignatures, + algorithms, SshConstants.HOST_KEY_ALGORITHMS); + if (!result.isEmpty()) { + if (log.isDebugEnabled()) { + log.debug(SshConstants.HOST_KEY_ALGORITHMS + ' ' + result); } - break; + return String.join(",", result); //$NON-NLS-1$ } + log.warn(format(SshdText.get().configNoKnownAlgorithms, + SshConstants.HOST_KEY_ALGORITHMS, + algorithms)); } // No HostKeyAlgorithms; using default -- change order to put existing // keys first. @@ -262,11 +239,67 @@ public class JGitClientSession extends ClientSessionImpl { } } reordered.addAll(defaultSignatures); + if (log.isDebugEnabled()) { + log.debug(SshConstants.HOST_KEY_ALGORITHMS + ' ' + reordered); + } return String.join(",", reordered); //$NON-NLS-1$ } + if (log.isDebugEnabled()) { + log.debug( + SshConstants.HOST_KEY_ALGORITHMS + ' ' + defaultSignatures); + } return String.join(",", defaultSignatures); //$NON-NLS-1$ } + /** + * Modifies a given algorithm list according to a list from the ssh config, + * including remove ('-') and reordering ('^') operators. Addition ('+') is + * not handled since we have no way of adding dynamically implementations, + * and the defaultList is supposed to contain all known implementations + * already. + * + * @param defaultList + * to modify + * @param fromConfig + * telling how to modify the {@code defaultList}, must not be + * {@code null} or empty + * @param overrideKey + * ssh config key; used for logging + * @return the modified list or {@code null} if {@code overrideKey} is not + * set + */ + public List<String> modifyAlgorithmList(List<String> defaultList, + String fromConfig, String overrideKey) { + Set<String> defaults = new LinkedHashSet<>(); + defaults.addAll(defaultList); + switch (fromConfig.charAt(0)) { + case '+': + // Additions make not much sense -- it's either in + // defaultList already, or we have no implementation for + // it. No point in proposing it. + return defaultList; + case '-': + // This takes wildcard patterns! + removeFromList(defaults, overrideKey, fromConfig.substring(1)); + return new ArrayList<>(defaults); + case '^': + // Specified entries go to the front of the default list + List<String> allSignatures = filteredList(defaults, + fromConfig.substring(1)); + Set<String> atFront = new HashSet<>(allSignatures); + for (String sig : defaults) { + if (!atFront.contains(sig)) { + allSignatures.add(sig); + } + } + return allSignatures; + default: + // Default is overridden -- only accept the ones for which we do + // have an implementation. + return filteredList(defaults, fromConfig); + } + } + private void removeFromList(Set<String> current, String key, String patterns) { for (String toRemove : patterns.split("\\s*,\\s*")) { //$NON-NLS-1$ diff --git a/org.eclipse.jgit.ssh.apache/src/org/eclipse/jgit/internal/transport/sshd/JGitKexExtensionHandler.java b/org.eclipse.jgit.ssh.apache/src/org/eclipse/jgit/internal/transport/sshd/JGitKexExtensionHandler.java new file mode 100644 index 0000000000..9446aaa7d6 --- /dev/null +++ b/org.eclipse.jgit.ssh.apache/src/org/eclipse/jgit/internal/transport/sshd/JGitKexExtensionHandler.java @@ -0,0 +1,163 @@ +/* + * Copyright (C) 2021 Thomas Wolf <thomas.wolf@paranor.ch> and others + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Distribution License v. 1.0 which is available at + * https://www.eclipse.org/org/documents/edl-v10.php. + * + * SPDX-License-Identifier: BSD-3-Clause + */ +package org.eclipse.jgit.internal.transport.sshd; + +import java.io.IOException; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.TreeSet; + +import org.apache.sshd.common.AttributeRepository.AttributeKey; +import org.apache.sshd.common.NamedFactory; +import org.apache.sshd.common.kex.KexProposalOption; +import org.apache.sshd.common.kex.extension.KexExtensionHandler; +import org.apache.sshd.common.kex.extension.KexExtensions; +import org.apache.sshd.common.kex.extension.parser.ServerSignatureAlgorithms; +import org.apache.sshd.common.session.Session; +import org.apache.sshd.common.signature.Signature; +import org.apache.sshd.common.util.logging.AbstractLoggingBean; +import org.eclipse.jgit.util.StringUtils; + +/** + * Do not use the DefaultClientKexExtensionHandler from sshd; it doesn't work + * properly because of misconceptions. See SSHD-1141. + * + * @see <a href="https://issues.apache.org/jira/browse/SSHD-1141">SSHD-1141</a> + */ +public class JGitKexExtensionHandler extends AbstractLoggingBean + implements KexExtensionHandler { + + /** Singleton instance. */ + public static final JGitKexExtensionHandler INSTANCE = new JGitKexExtensionHandler(); + + /** + * Session {@link AttributeKey} used to store whether the extension + * indicator was already sent. + */ + private static final AttributeKey<Boolean> CLIENT_PROPOSAL_MADE = new AttributeKey<>(); + + /** + * Session {@link AttributeKey} storing the algorithms announced by the + * server as known. + */ + public static final AttributeKey<Set<String>> SERVER_ALGORITHMS = new AttributeKey<>(); + + private JGitKexExtensionHandler() { + // No public instantiation for singleton + } + + @Override + public boolean isKexExtensionsAvailable(Session session, + AvailabilityPhase phase) throws IOException { + return !AvailabilityPhase.PREKEX.equals(phase); + } + + @Override + public void handleKexInitProposal(Session session, boolean initiator, + Map<KexProposalOption, String> proposal) throws IOException { + // If it's the very first time, we may add the marker telling the server + // that we are ready to handle SSH_MSG_EXT_INFO + if (session == null || session.isServerSession() || !initiator) { + return; + } + if (session.getAttribute(CLIENT_PROPOSAL_MADE) != null) { + return; + } + String kexAlgorithms = proposal.get(KexProposalOption.SERVERKEYS); + if (StringUtils.isEmptyOrNull(kexAlgorithms)) { + return; + } + List<String> algorithms = new ArrayList<>(); + // We're a client. We mustn't send the server extension, and we should + // send the client extension only once. + for (String algo : kexAlgorithms.split(",")) { //$NON-NLS-1$ + if (KexExtensions.CLIENT_KEX_EXTENSION.equalsIgnoreCase(algo) + || KexExtensions.SERVER_KEX_EXTENSION + .equalsIgnoreCase(algo)) { + continue; + } + algorithms.add(algo); + } + // Tell the server that we want to receive SSH2_MSG_EXT_INFO + algorithms.add(KexExtensions.CLIENT_KEX_EXTENSION); + if (log.isDebugEnabled()) { + log.debug( + "handleKexInitProposal({}): proposing HostKeyAlgorithms {}", //$NON-NLS-1$ + session, algorithms); + } + proposal.put(KexProposalOption.SERVERKEYS, + String.join(",", algorithms)); //$NON-NLS-1$ + session.setAttribute(CLIENT_PROPOSAL_MADE, Boolean.TRUE); + } + + @Override + public boolean handleKexExtensionRequest(Session session, int index, + int count, String name, byte[] data) throws IOException { + if (ServerSignatureAlgorithms.NAME.equals(name)) { + handleServerSignatureAlgorithms(session, + ServerSignatureAlgorithms.INSTANCE.parseExtension(data)); + } + return true; + } + + /** + * Perform updates after a server-sig-algs extension has been received. + * + * @param session + * the message was received for + * @param serverAlgorithms + * signature algorithm names announced by the server + */ + protected void handleServerSignatureAlgorithms(Session session, + Collection<String> serverAlgorithms) { + if (log.isDebugEnabled()) { + log.debug("handleServerSignatureAlgorithms({}): {}", session, //$NON-NLS-1$ + serverAlgorithms); + } + // Client determines order; server says what it supports. Re-order + // such that supported ones are at the front, in client order, + // followed by unsupported ones, also in client order. + if (serverAlgorithms != null && !serverAlgorithms.isEmpty()) { + List<NamedFactory<Signature>> clientAlgorithms = new ArrayList<>( + session.getSignatureFactories()); + if (log.isDebugEnabled()) { + log.debug( + "handleServerSignatureAlgorithms({}): PubkeyAcceptedAlgorithms before: {}", //$NON-NLS-1$ + session, clientAlgorithms); + } + List<NamedFactory<Signature>> unknown = new ArrayList<>(); + Set<String> known = new TreeSet<>(String.CASE_INSENSITIVE_ORDER); + known.addAll(serverAlgorithms); + for (Iterator<NamedFactory<Signature>> iter = clientAlgorithms + .iterator(); iter.hasNext();) { + NamedFactory<Signature> algo = iter.next(); + if (!known.contains(algo.getName())) { + unknown.add(algo); + iter.remove(); + } + } + // Re-add the unknown ones at the end. Per RFC 8308, some + // servers may not announce _all_ their supported algorithms, + // and a client may use unknown algorithms. + clientAlgorithms.addAll(unknown); + if (log.isDebugEnabled()) { + log.debug( + "handleServerSignatureAlgorithms({}): PubkeyAcceptedAlgorithms after: {}", //$NON-NLS-1$ + session, clientAlgorithms); + } + session.setAttribute(SERVER_ALGORITHMS, known); + session.setSignatureFactories(clientAlgorithms); + } + } +} diff --git a/org.eclipse.jgit.ssh.apache/src/org/eclipse/jgit/internal/transport/sshd/JGitPublicKeyAuthFactory.java b/org.eclipse.jgit.ssh.apache/src/org/eclipse/jgit/internal/transport/sshd/JGitPublicKeyAuthFactory.java new file mode 100644 index 0000000000..0e3e24dcff --- /dev/null +++ b/org.eclipse.jgit.ssh.apache/src/org/eclipse/jgit/internal/transport/sshd/JGitPublicKeyAuthFactory.java @@ -0,0 +1,35 @@ +/* + * Copyright (C) 2018, 2021 Thomas Wolf <thomas.wolf@paranor.ch> and others + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Distribution License v. 1.0 which is available at + * https://www.eclipse.org/org/documents/edl-v10.php. + * + * SPDX-License-Identifier: BSD-3-Clause + */ +package org.eclipse.jgit.internal.transport.sshd; + +import java.io.IOException; + +import org.apache.sshd.client.auth.pubkey.UserAuthPublicKey; +import org.apache.sshd.client.auth.pubkey.UserAuthPublicKeyFactory; +import org.apache.sshd.client.session.ClientSession; + +/** + * A customized authentication factory for public key user authentication. + */ +public class JGitPublicKeyAuthFactory extends UserAuthPublicKeyFactory { + + /** The singleton {@link JGitPublicKeyAuthFactory}. */ + public static final JGitPublicKeyAuthFactory FACTORY = new JGitPublicKeyAuthFactory(); + + private JGitPublicKeyAuthFactory() { + super(); + } + + @Override + public UserAuthPublicKey createUserAuth(ClientSession session) + throws IOException { + return new JGitPublicKeyAuthentication(getSignatureFactories()); + } +} diff --git a/org.eclipse.jgit.ssh.apache/src/org/eclipse/jgit/internal/transport/sshd/JGitPublicKeyAuthentication.java b/org.eclipse.jgit.ssh.apache/src/org/eclipse/jgit/internal/transport/sshd/JGitPublicKeyAuthentication.java new file mode 100644 index 0000000000..6755094420 --- /dev/null +++ b/org.eclipse.jgit.ssh.apache/src/org/eclipse/jgit/internal/transport/sshd/JGitPublicKeyAuthentication.java @@ -0,0 +1,224 @@ +/* + * Copyright (C) 2018, 2021 Thomas Wolf <thomas.wolf@paranor.ch> and others + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Distribution License v. 1.0 which is available at + * https://www.eclipse.org/org/documents/edl-v10.php. + * + * SPDX-License-Identifier: BSD-3-Clause + */ +package org.eclipse.jgit.internal.transport.sshd; + +import java.io.IOException; +import java.security.PublicKey; +import java.security.spec.InvalidKeySpecException; +import java.text.MessageFormat; +import java.util.Deque; +import java.util.HashSet; +import java.util.LinkedList; +import java.util.List; +import java.util.Set; + +import org.apache.sshd.client.auth.pubkey.UserAuthPublicKey; +import org.apache.sshd.client.session.ClientSession; +import org.apache.sshd.common.NamedFactory; +import org.apache.sshd.common.NamedResource; +import org.apache.sshd.common.RuntimeSshException; +import org.apache.sshd.common.SshConstants; +import org.apache.sshd.common.config.keys.KeyUtils; +import org.apache.sshd.common.signature.Signature; +import org.apache.sshd.common.signature.SignatureFactoriesHolder; +import org.apache.sshd.common.util.buffer.Buffer; + +/** + * Custom {@link UserAuthPublicKey} implementation fixing SSHD-1105: if there + * are several signature algorithms applicable for a public key type, we must + * try them all, in the correct order. + * + * @see <a href="https://issues.apache.org/jira/browse/SSHD-1105">SSHD-1105</a> + * @see <a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=572056">Bug + * 572056</a> + */ +public class JGitPublicKeyAuthentication extends UserAuthPublicKey { + + private final Deque<String> currentAlgorithms = new LinkedList<>(); + + private String chosenAlgorithm; + + JGitPublicKeyAuthentication(List<NamedFactory<Signature>> factories) { + super(factories); + } + + @Override + protected boolean sendAuthDataRequest(ClientSession session, String service) + throws Exception { + if (current == null) { + currentAlgorithms.clear(); + chosenAlgorithm = null; + } + String currentAlgorithm = null; + if (current != null && !currentAlgorithms.isEmpty()) { + currentAlgorithm = currentAlgorithms.poll(); + if (chosenAlgorithm != null) { + Set<String> knownServerAlgorithms = session.getAttribute( + JGitKexExtensionHandler.SERVER_ALGORITHMS); + if (knownServerAlgorithms != null + && knownServerAlgorithms.contains(chosenAlgorithm)) { + // We've tried key 'current' with 'chosenAlgorithm', but it + // failed. However, the server had told us it supported + // 'chosenAlgorithm'. Thus it makes no sense to continue + // with this key and other signature algorithms. Skip to the + // next key, if any. + currentAlgorithm = null; + } + } + } + if (currentAlgorithm == null) { + try { + if (keys == null || !keys.hasNext()) { + if (log.isDebugEnabled()) { + log.debug( + "sendAuthDataRequest({})[{}] no more keys to send", //$NON-NLS-1$ + session, service); + } + current = null; + return false; + } + current = keys.next(); + currentAlgorithms.clear(); + chosenAlgorithm = null; + } catch (Error e) { // Copied from superclass + throw new RuntimeSshException(e); + } + } + PublicKey key; + try { + key = current.getPublicKey(); + } catch (Error e) { // Copied from superclass + throw new RuntimeSshException(e); + } + if (currentAlgorithm == null) { + String keyType = KeyUtils.getKeyType(key); + Set<String> aliases = new HashSet<>( + KeyUtils.getAllEquivalentKeyTypes(keyType)); + aliases.add(keyType); + List<NamedFactory<Signature>> existingFactories; + if (current instanceof SignatureFactoriesHolder) { + existingFactories = ((SignatureFactoriesHolder) current) + .getSignatureFactories(); + } else { + existingFactories = getSignatureFactories(); + } + if (existingFactories != null) { + if (log.isDebugEnabled()) { + log.debug( + "sendAuthDataRequest({})[{}] selecting from PubKeyAcceptedAlgorithms {}", //$NON-NLS-1$ + session, service, + NamedResource.getNames(existingFactories)); + } + // Select the factories by name and in order + existingFactories.forEach(f -> { + if (aliases.contains(f.getName())) { + currentAlgorithms.add(f.getName()); + } + }); + } + currentAlgorithm = currentAlgorithms.isEmpty() ? keyType + : currentAlgorithms.poll(); + } + String name = getName(); + if (log.isDebugEnabled()) { + log.debug( + "sendAuthDataRequest({})[{}] send SSH_MSG_USERAUTH_REQUEST request {} type={} - fingerprint={}", //$NON-NLS-1$ + session, service, name, currentAlgorithm, + KeyUtils.getFingerPrint(key)); + } + + chosenAlgorithm = currentAlgorithm; + Buffer buffer = session + .createBuffer(SshConstants.SSH_MSG_USERAUTH_REQUEST); + buffer.putString(session.getUsername()); + buffer.putString(service); + buffer.putString(name); + buffer.putBoolean(false); + buffer.putString(currentAlgorithm); + buffer.putPublicKey(key); + session.writePacket(buffer); + return true; + } + + @Override + protected boolean processAuthDataRequest(ClientSession session, + String service, Buffer buffer) throws Exception { + String name = getName(); + int cmd = buffer.getUByte(); + if (cmd != SshConstants.SSH_MSG_USERAUTH_PK_OK) { + throw new IllegalStateException(MessageFormat.format( + SshdText.get().pubkeyAuthWrongCommand, + SshConstants.getCommandMessageName(cmd), + session.getConnectAddress(), session.getServerVersion())); + } + PublicKey key; + try { + key = current.getPublicKey(); + } catch (Error e) { // Copied from superclass + throw new RuntimeSshException(e); + } + String rspKeyAlgorithm = buffer.getString(); + PublicKey rspKey = buffer.getPublicKey(); + if (log.isDebugEnabled()) { + log.debug( + "processAuthDataRequest({})[{}][{}] SSH_MSG_USERAUTH_PK_OK type={}, fingerprint={}", //$NON-NLS-1$ + session, service, name, rspKeyAlgorithm, + KeyUtils.getFingerPrint(rspKey)); + } + if (!KeyUtils.compareKeys(rspKey, key)) { + throw new InvalidKeySpecException(MessageFormat.format( + SshdText.get().pubkeyAuthWrongKey, + KeyUtils.getFingerPrint(key), + KeyUtils.getFingerPrint(rspKey), + session.getConnectAddress(), session.getServerVersion())); + } + if (!chosenAlgorithm.equalsIgnoreCase(rspKeyAlgorithm)) { + // 'algo' SHOULD be the same as 'chosenAlgorithm', which is the one + // we sent above. See https://tools.ietf.org/html/rfc4252#page-9 . + // + // However, at least Github (SSH-2.0-babeld-383743ad) servers seem + // to return the key type, not the algorithm name. + // + // So we don't check but just log the inconsistency. We sign using + // 'chosenAlgorithm' in any case, so we don't really care what the + // server says here. + log.warn(MessageFormat.format( + SshdText.get().pubkeyAuthWrongSignatureAlgorithm, + chosenAlgorithm, rspKeyAlgorithm, session.getConnectAddress(), + session.getServerVersion())); + } + String username = session.getUsername(); + Buffer out = session + .createBuffer(SshConstants.SSH_MSG_USERAUTH_REQUEST); + out.putString(username); + out.putString(service); + out.putString(name); + out.putBoolean(true); + out.putString(chosenAlgorithm); + out.putPublicKey(key); + if (log.isDebugEnabled()) { + log.debug( + "processAuthDataRequest({})[{}][{}]: signing with algorithm {}", //$NON-NLS-1$ + session, service, name, chosenAlgorithm); + } + appendSignature(session, service, name, username, chosenAlgorithm, key, + out); + session.writePacket(out); + return true; + } + + @Override + protected void releaseKeys() throws IOException { + currentAlgorithms.clear(); + current = null; + chosenAlgorithm = null; + super.releaseKeys(); + } +} diff --git a/org.eclipse.jgit.ssh.apache/src/org/eclipse/jgit/internal/transport/sshd/JGitSshClient.java b/org.eclipse.jgit.ssh.apache/src/org/eclipse/jgit/internal/transport/sshd/JGitSshClient.java index 74455dc808..071e1979d3 100644 --- a/org.eclipse.jgit.ssh.apache/src/org/eclipse/jgit/internal/transport/sshd/JGitSshClient.java +++ b/org.eclipse.jgit.ssh.apache/src/org/eclipse/jgit/internal/transport/sshd/JGitSshClient.java @@ -267,6 +267,24 @@ public class JGitSshClient extends SshClient { session.setUsername(username); session.setConnectAddress(address); session.setHostConfigEntry(hostConfig); + // Set signature algorithms for public key authentication + String pubkeyAlgos = hostConfig + .getProperty(SshConstants.PUBKEY_ACCEPTED_ALGORITHMS); + if (!StringUtils.isEmptyOrNull(pubkeyAlgos)) { + List<String> signatures = getSignatureFactoriesNames(); + signatures = session.modifyAlgorithmList(signatures, pubkeyAlgos, + SshConstants.PUBKEY_ACCEPTED_ALGORITHMS); + if (!signatures.isEmpty()) { + if (log.isDebugEnabled()) { + log.debug(SshConstants.PUBKEY_ACCEPTED_ALGORITHMS + ' ' + + signatures); + } + session.setSignatureFactoriesNames(signatures); + } else { + log.warn(format(SshdText.get().configNoKnownAlgorithms, + SshConstants.PUBKEY_ACCEPTED_ALGORITHMS, pubkeyAlgos)); + } + } if (session.getCredentialsProvider() == null) { session.setCredentialsProvider(getCredentialsProvider()); } diff --git a/org.eclipse.jgit.ssh.apache/src/org/eclipse/jgit/internal/transport/sshd/OpenSshServerKeyDatabase.java b/org.eclipse.jgit.ssh.apache/src/org/eclipse/jgit/internal/transport/sshd/OpenSshServerKeyDatabase.java index 47e09b75d7..1a530b7743 100644 --- a/org.eclipse.jgit.ssh.apache/src/org/eclipse/jgit/internal/transport/sshd/OpenSshServerKeyDatabase.java +++ b/org.eclipse.jgit.ssh.apache/src/org/eclipse/jgit/internal/transport/sshd/OpenSshServerKeyDatabase.java @@ -21,6 +21,7 @@ import java.net.InetSocketAddress; import java.net.SocketAddress; import java.nio.file.Files; import java.nio.file.InvalidPathException; +import java.nio.file.NoSuchFileException; import java.nio.file.Path; import java.nio.file.Paths; import java.security.GeneralSecurityException; @@ -561,29 +562,17 @@ public class OpenSshServerKeyDatabase @Override public List<HostEntryPair> get() { Path path = getPath(); - try { - if (checkReloadRequired()) { - if (!Files.exists(path)) { - // Has disappeared. - resetReloadAttributes(); - return Collections.emptyList(); - } - LockFile lock = new LockFile(path.toFile()); - if (lock.lock()) { - try { - entries = reload(getPath()); - } finally { - lock.unlock(); - } - } else { - LOG.warn(format(SshdText.get().knownHostsFileLockedRead, - path)); + synchronized (this) { + try { + if (checkReloadRequired()) { + entries = reload(getPath()); } + } catch (IOException e) { + LOG.warn(format(SshdText.get().knownHostsFileReadFailed, + path)); } - } catch (IOException e) { - LOG.warn(format(SshdText.get().knownHostsFileReadFailed, path)); + return Collections.unmodifiableList(entries); } - return Collections.unmodifiableList(entries); } private List<HostEntryPair> reload(Path path) throws IOException { @@ -616,7 +605,7 @@ public class OpenSshServerKeyDatabase } } return newEntries; - } catch (FileNotFoundException e) { + } catch (FileNotFoundException | NoSuchFileException e) { resetReloadAttributes(); return Collections.emptyList(); } diff --git a/org.eclipse.jgit.ssh.apache/src/org/eclipse/jgit/internal/transport/sshd/SshdText.java b/org.eclipse.jgit.ssh.apache/src/org/eclipse/jgit/internal/transport/sshd/SshdText.java index 13bb3ebe75..73c2288ccc 100644 --- a/org.eclipse.jgit.ssh.apache/src/org/eclipse/jgit/internal/transport/sshd/SshdText.java +++ b/org.eclipse.jgit.ssh.apache/src/org/eclipse/jgit/internal/transport/sshd/SshdText.java @@ -25,8 +25,7 @@ public final class SshdText extends TranslationBundle { /***/ public String configInvalidPattern; /***/ public String configInvalidPositive; /***/ public String configInvalidProxyJump; - /***/ public String configNoKnownHostKeyAlgorithms; - /***/ public String configNoRemainingHostKeyAlgorithms; + /***/ public String configNoKnownAlgorithms; /***/ public String configProxyJumpNotSsh; /***/ public String configProxyJumpWithPath; /***/ public String ftpCloseFailed; @@ -45,7 +44,6 @@ public final class SshdText extends TranslationBundle { /***/ public String keyEncryptedRetry; /***/ public String keyLoadFailed; /***/ public String knownHostsCouldNotUpdate; - /***/ public String knownHostsFileLockedRead; /***/ public String knownHostsFileLockedUpdate; /***/ public String knownHostsFileReadFailed; /***/ public String knownHostsInvalidLine; @@ -89,6 +87,9 @@ public final class SshdText extends TranslationBundle { /***/ public String proxySocksUnexpectedMessage; /***/ public String proxySocksUnexpectedVersion; /***/ public String proxySocksUsernameTooLong; + /***/ public String pubkeyAuthWrongCommand; + /***/ public String pubkeyAuthWrongKey; + /***/ public String pubkeyAuthWrongSignatureAlgorithm; /***/ public String serverIdNotReceived; /***/ public String serverIdTooLong; /***/ public String serverIdWithNul; diff --git a/org.eclipse.jgit.ssh.apache/src/org/eclipse/jgit/transport/sshd/SshdSessionFactory.java b/org.eclipse.jgit.ssh.apache/src/org/eclipse/jgit/transport/sshd/SshdSessionFactory.java index 357994d431..2d7e0c7c77 100644 --- a/org.eclipse.jgit.ssh.apache/src/org/eclipse/jgit/transport/sshd/SshdSessionFactory.java +++ b/org.eclipse.jgit.ssh.apache/src/org/eclipse/jgit/transport/sshd/SshdSessionFactory.java @@ -32,10 +32,9 @@ import org.apache.sshd.client.ClientBuilder; import org.apache.sshd.client.SshClient; import org.apache.sshd.client.auth.UserAuthFactory; import org.apache.sshd.client.auth.keyboard.UserAuthKeyboardInteractiveFactory; -import org.apache.sshd.client.auth.pubkey.UserAuthPublicKeyFactory; import org.apache.sshd.client.config.hosts.HostConfigEntryResolver; -import org.apache.sshd.common.SshException; import org.apache.sshd.common.NamedFactory; +import org.apache.sshd.common.SshException; import org.apache.sshd.common.compression.BuiltinCompressions; import org.apache.sshd.common.config.keys.FilePasswordProvider; import org.apache.sshd.common.config.keys.loader.openssh.kdf.BCryptKdfOptions; @@ -48,7 +47,9 @@ import org.eclipse.jgit.internal.transport.ssh.OpenSshConfigFile; import org.eclipse.jgit.internal.transport.sshd.AuthenticationCanceledException; import org.eclipse.jgit.internal.transport.sshd.CachingKeyPairProvider; import org.eclipse.jgit.internal.transport.sshd.GssApiWithMicAuthFactory; +import org.eclipse.jgit.internal.transport.sshd.JGitKexExtensionHandler; import org.eclipse.jgit.internal.transport.sshd.JGitPasswordAuthFactory; +import org.eclipse.jgit.internal.transport.sshd.JGitPublicKeyAuthFactory; import org.eclipse.jgit.internal.transport.sshd.JGitServerKeyVerifier; import org.eclipse.jgit.internal.transport.sshd.JGitSshClient; import org.eclipse.jgit.internal.transport.sshd.JGitSshConfig; @@ -216,6 +217,7 @@ public class SshdSessionFactory extends SshSessionFactory implements Closeable { new JGitUserInteraction(credentialsProvider)); client.setUserAuthFactories(getUserAuthFactories()); client.setKeyIdentityProvider(defaultKeysProvider); + client.setKexExtensionHandler(JGitKexExtensionHandler.INSTANCE); // JGit-specific things: JGitSshClient jgitClient = (JGitSshClient) client; jgitClient.setKeyCache(getKeyCache()); @@ -577,7 +579,7 @@ public class SshdSessionFactory extends SshSessionFactory implements Closeable { // Password auth doesn't have this problem. return Collections.unmodifiableList( Arrays.asList(GssApiWithMicAuthFactory.INSTANCE, - UserAuthPublicKeyFactory.INSTANCE, + JGitPublicKeyAuthFactory.FACTORY, JGitPasswordAuthFactory.INSTANCE, UserAuthKeyboardInteractiveFactory.INSTANCE)); } diff --git a/org.eclipse.jgit.ssh.jsch.test/tst/org/eclipse/jgit/transport/OpenSshConfigTest.java b/org.eclipse.jgit.ssh.jsch.test/tst/org/eclipse/jgit/transport/OpenSshConfigTest.java index af09f499f5..4be2271a8c 100644 --- a/org.eclipse.jgit.ssh.jsch.test/tst/org/eclipse/jgit/transport/OpenSshConfigTest.java +++ b/org.eclipse.jgit.ssh.jsch.test/tst/org/eclipse/jgit/transport/OpenSshConfigTest.java @@ -58,6 +58,7 @@ public class OpenSshConfigTest extends RepositoryTestCase { FileUtils.mkdir(configFile.getParentFile()); mockSystemReader.setProperty(Constants.OS_USER_NAME_KEY, "jex_junit"); + mockSystemReader.setProperty("TST_VAR", "TEST"); osc = new OpenSshConfig(home, configFile); } @@ -467,4 +468,53 @@ public class OpenSshConfigTest extends RepositoryTestCase { new File(new File(home, ".ssh"), localhost + "_id_dsa"), h.getIdentityFile()); } + + @Test + public void testPubKeyAcceptedAlgorithms() throws Exception { + config("Host=orcz\n\tPubkeyAcceptedAlgorithms ^ssh-rsa"); + Host h = osc.lookup("orcz"); + Config c = h.getConfig(); + assertEquals("^ssh-rsa", + c.getValue(SshConstants.PUBKEY_ACCEPTED_ALGORITHMS)); + assertEquals("^ssh-rsa", c.getValue("PubkeyAcceptedKeyTypes")); + } + + @Test + public void testPubKeyAcceptedKeyTypes() throws Exception { + config("Host=orcz\n\tPubkeyAcceptedKeyTypes ^ssh-rsa"); + Host h = osc.lookup("orcz"); + Config c = h.getConfig(); + assertEquals("^ssh-rsa", + c.getValue(SshConstants.PUBKEY_ACCEPTED_ALGORITHMS)); + assertEquals("^ssh-rsa", c.getValue("PubkeyAcceptedKeyTypes")); + } + + @Test + public void testEolComments() throws Exception { + config("#Comment\nHost=orcz #Comment\n\tPubkeyAcceptedAlgorithms ^ssh-rsa # Comment\n#Comment"); + Host h = osc.lookup("orcz"); + assertNotNull(h); + Config c = h.getConfig(); + assertEquals("^ssh-rsa", + c.getValue(SshConstants.PUBKEY_ACCEPTED_ALGORITHMS)); + } + + @Test + public void testEnVarSubstitution() throws Exception { + config("Host orcz\nIdentityFile /tmp/${TST_VAR}\n" + + "CertificateFile /tmp/${}/foo\nUser ${TST_VAR}\nIdentityAgent /tmp/${TST_VAR/bar"); + Host h = osc.lookup("orcz"); + assertNotNull(h); + Config c = h.getConfig(); + assertEquals("/tmp/TEST", + c.getValue(SshConstants.IDENTITY_FILE)); + // No variable name + assertEquals("/tmp/${}/foo", c.getValue(SshConstants.CERTIFICATE_FILE)); + // User doesn't get env var substitution: + assertEquals("${TST_VAR}", c.getValue(SshConstants.USER)); + assertEquals("${TST_VAR}", h.getUser()); + // Unterminated: + assertEquals("/tmp/${TST_VAR/bar", + c.getValue(SshConstants.IDENTITY_AGENT)); + } } diff --git a/org.eclipse.jgit.test/exttst/org/eclipse/jgit/internal/storage/file/CGitLockFileTest.java b/org.eclipse.jgit.test/exttst/org/eclipse/jgit/internal/storage/file/CGitLockFileTest.java new file mode 100644 index 0000000000..4c194752b4 --- /dev/null +++ b/org.eclipse.jgit.test/exttst/org/eclipse/jgit/internal/storage/file/CGitLockFileTest.java @@ -0,0 +1,57 @@ +/* + * Copyright (C) 2021 SAP SE and others + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Distribution License v. 1.0 which is available at + * https://www.eclipse.org/org/documents/edl-v10.php. + * + * SPDX-License-Identifier: BSD-3-Clause + */ +package org.eclipse.jgit.internal.storage.file; + +import static org.junit.Assert.assertNotEquals; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertTrue; + +import org.eclipse.jgit.api.Git; +import org.eclipse.jgit.junit.RepositoryTestCase; +import org.eclipse.jgit.revwalk.RevCommit; +import org.eclipse.jgit.util.FS; +import org.eclipse.jgit.util.FS.ExecutionResult; +import org.junit.Test; + +/** + * Unit tests of {@link LockFile} testing interoperability with C git + */ +public class CGitLockFileTest extends RepositoryTestCase { + + @Test + public void testLockedTwiceFails() throws Exception { + try (Git git = new Git(db)) { + writeTrashFile("file.txt", "content"); + git.add().addFilepattern("file.txt").call(); + RevCommit commit1 = git.commit().setMessage("create file").call(); + + assertNotNull(commit1); + writeTrashFile("file.txt", "content2"); + git.add().addFilepattern("file.txt").call(); + assertNotNull(git.commit().setMessage("edit file").call()); + + LockFile lf = new LockFile(db.getIndexFile()); + assertTrue(lf.lock()); + try { + String[] command = new String[] { "git", "checkout", + commit1.name() }; + ProcessBuilder pb = new ProcessBuilder(command); + pb.directory(db.getWorkTree()); + ExecutionResult result = FS.DETECTED.execute(pb, null); + assertNotEquals(0, result.getRc()); + String err = result.getStderr().toString().split("\\R")[0]; + assertTrue(err.matches( + "fatal: Unable to create .*/\\.git/index\\.lock': File exists\\.")); + } finally { + lf.unlock(); + } + } + } +} diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/CherryPickCommandTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/CherryPickCommandTest.java index 9dd129c335..f4f0ecd689 100644 --- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/CherryPickCommandTest.java +++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/CherryPickCommandTest.java @@ -34,6 +34,8 @@ import org.eclipse.jgit.lib.FileMode; import org.eclipse.jgit.lib.ObjectId; import org.eclipse.jgit.lib.ReflogReader; import org.eclipse.jgit.lib.RepositoryState; +import org.eclipse.jgit.merge.ContentMergeStrategy; +import org.eclipse.jgit.merge.MergeStrategy; import org.eclipse.jgit.merge.ResolveMerger.MergeFailureReason; import org.eclipse.jgit.revwalk.RevCommit; import org.junit.Test; @@ -193,7 +195,7 @@ public class CherryPickCommandTest extends RepositoryTestCase { } @Test - public void testCherryPickConflictResolutionNoCOmmit() throws Exception { + public void testCherryPickConflictResolutionNoCommit() throws Exception { Git git = new Git(db); RevCommit sideCommit = prepareCherryPick(git); @@ -280,6 +282,70 @@ public class CherryPickCommandTest extends RepositoryTestCase { } @Test + public void testCherryPickOurs() throws Exception { + try (Git git = new Git(db)) { + RevCommit sideCommit = prepareCherryPick(git); + + CherryPickResult result = git.cherryPick() + .include(sideCommit.getId()) + .setStrategy(MergeStrategy.OURS) + .call(); + assertEquals(CherryPickStatus.OK, result.getStatus()); + + String expected = "a(master)"; + checkFile(new File(db.getWorkTree(), "a"), expected); + } + } + + @Test + public void testCherryPickTheirs() throws Exception { + try (Git git = new Git(db)) { + RevCommit sideCommit = prepareCherryPick(git); + + CherryPickResult result = git.cherryPick() + .include(sideCommit.getId()) + .setStrategy(MergeStrategy.THEIRS) + .call(); + assertEquals(CherryPickStatus.OK, result.getStatus()); + + String expected = "a(side)"; + checkFile(new File(db.getWorkTree(), "a"), expected); + } + } + + @Test + public void testCherryPickXours() throws Exception { + try (Git git = new Git(db)) { + RevCommit sideCommit = prepareCherryPickStrategyOption(git); + + CherryPickResult result = git.cherryPick() + .include(sideCommit.getId()) + .setContentMergeStrategy(ContentMergeStrategy.OURS) + .call(); + assertEquals(CherryPickStatus.OK, result.getStatus()); + + String expected = "a\nmaster\nc\nd\n"; + checkFile(new File(db.getWorkTree(), "a"), expected); + } + } + + @Test + public void testCherryPickXtheirs() throws Exception { + try (Git git = new Git(db)) { + RevCommit sideCommit = prepareCherryPickStrategyOption(git); + + CherryPickResult result = git.cherryPick() + .include(sideCommit.getId()) + .setContentMergeStrategy(ContentMergeStrategy.THEIRS) + .call(); + assertEquals(CherryPickStatus.OK, result.getStatus()); + + String expected = "a\nside\nc\nd\n"; + checkFile(new File(db.getWorkTree(), "a"), expected); + } + } + + @Test public void testCherryPickConflictMarkers() throws Exception { try (Git git = new Git(db)) { RevCommit sideCommit = prepareCherryPick(git); @@ -384,6 +450,31 @@ public class CherryPickCommandTest extends RepositoryTestCase { return sideCommit; } + private RevCommit prepareCherryPickStrategyOption(Git git) + throws Exception { + // create, add and commit file a + writeTrashFile("a", "a\nb\nc\n"); + git.add().addFilepattern("a").call(); + RevCommit firstMasterCommit = git.commit().setMessage("first master") + .call(); + + // create and checkout side branch + createBranch(firstMasterCommit, "refs/heads/side"); + checkoutBranch("refs/heads/side"); + // modify, add and commit file a + writeTrashFile("a", "a\nside\nc\nd\n"); + git.add().addFilepattern("a").call(); + RevCommit sideCommit = git.commit().setMessage("side").call(); + + // checkout master branch + checkoutBranch("refs/heads/master"); + // modify, add and commit file a + writeTrashFile("a", "a\nmaster\nc\n"); + git.add().addFilepattern("a").call(); + git.commit().setMessage("second master").call(); + return sideCommit; + } + private void doCherryPickAndCheckResult(final Git git, final RevCommit sideCommit, final MergeFailureReason reason) throws Exception { diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/MergeCommandTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/MergeCommandTest.java index 8747c85dec..bc4e9405ea 100644 --- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/MergeCommandTest.java +++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/MergeCommandTest.java @@ -14,6 +14,7 @@ import static org.eclipse.jgit.lib.Constants.MASTER; import static org.eclipse.jgit.lib.Constants.R_HEADS; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertNull; import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; @@ -25,6 +26,7 @@ import java.util.regex.Pattern; import org.eclipse.jgit.api.MergeCommand.FastForwardMode; import org.eclipse.jgit.api.MergeResult.MergeStatus; +import org.eclipse.jgit.api.ResetCommand.ResetType; import org.eclipse.jgit.api.errors.InvalidMergeHeadsException; import org.eclipse.jgit.junit.RepositoryTestCase; import org.eclipse.jgit.junit.TestRepository; @@ -34,6 +36,7 @@ import org.eclipse.jgit.lib.Ref; import org.eclipse.jgit.lib.Repository; import org.eclipse.jgit.lib.RepositoryState; import org.eclipse.jgit.lib.Sets; +import org.eclipse.jgit.merge.ContentMergeStrategy; import org.eclipse.jgit.merge.MergeStrategy; import org.eclipse.jgit.merge.ResolveMerger.MergeFailureReason; import org.eclipse.jgit.revwalk.RevCommit; @@ -306,6 +309,200 @@ public class MergeCommandTest extends RepositoryTestCase { } @Test + public void testContentMergeXtheirs() throws Exception { + try (Git git = new Git(db)) { + writeTrashFile("a", "1\na\n3\n"); + writeTrashFile("b", "1\nb\n3\n"); + writeTrashFile("c/c/c", "1\nc\n3\n"); + git.add().addFilepattern("a").addFilepattern("b") + .addFilepattern("c/c/c").call(); + RevCommit initialCommit = git.commit().setMessage("initial").call(); + + createBranch(initialCommit, "refs/heads/side"); + checkoutBranch("refs/heads/side"); + + writeTrashFile("a", "1\na(side)\n3\n4\n"); + writeTrashFile("b", "1\nb(side)\n3\n4\n"); + git.add().addFilepattern("a").addFilepattern("b").call(); + RevCommit secondCommit = git.commit().setMessage("side").call(); + + assertEquals("1\nb(side)\n3\n4\n", + read(new File(db.getWorkTree(), "b"))); + checkoutBranch("refs/heads/master"); + assertEquals("1\nb\n3\n", read(new File(db.getWorkTree(), "b"))); + + writeTrashFile("a", "1\na(main)\n3\n"); + writeTrashFile("c/c/c", "1\nc(main)\n3\n"); + git.add().addFilepattern("a").addFilepattern("c/c/c").call(); + git.commit().setMessage("main").call(); + + MergeResult result = git.merge().include(secondCommit.getId()) + .setStrategy(MergeStrategy.RESOLVE) + .setContentMergeStrategy(ContentMergeStrategy.THEIRS) + .call(); + assertEquals(MergeStatus.MERGED, result.getMergeStatus()); + + assertEquals("1\na(side)\n3\n4\n", + read(new File(db.getWorkTree(), "a"))); + assertEquals("1\nb(side)\n3\n4\n", + read(new File(db.getWorkTree(), "b"))); + assertEquals("1\nc(main)\n3\n", + read(new File(db.getWorkTree(), "c/c/c"))); + + assertNull(result.getConflicts()); + + assertEquals(RepositoryState.SAFE, db.getRepositoryState()); + } + } + + @Test + public void testContentMergeXours() throws Exception { + try (Git git = new Git(db)) { + writeTrashFile("a", "1\na\n3\n"); + writeTrashFile("b", "1\nb\n3\n"); + writeTrashFile("c/c/c", "1\nc\n3\n"); + git.add().addFilepattern("a").addFilepattern("b") + .addFilepattern("c/c/c").call(); + RevCommit initialCommit = git.commit().setMessage("initial").call(); + + createBranch(initialCommit, "refs/heads/side"); + checkoutBranch("refs/heads/side"); + + writeTrashFile("a", "1\na(side)\n3\n4\n"); + writeTrashFile("b", "1\nb(side)\n3\n4\n"); + git.add().addFilepattern("a").addFilepattern("b").call(); + RevCommit secondCommit = git.commit().setMessage("side").call(); + + assertEquals("1\nb(side)\n3\n4\n", + read(new File(db.getWorkTree(), "b"))); + checkoutBranch("refs/heads/master"); + assertEquals("1\nb\n3\n", read(new File(db.getWorkTree(), "b"))); + + writeTrashFile("a", "1\na(main)\n3\n"); + writeTrashFile("c/c/c", "1\nc(main)\n3\n"); + git.add().addFilepattern("a").addFilepattern("c/c/c").call(); + git.commit().setMessage("main").call(); + + MergeResult result = git.merge().include(secondCommit.getId()) + .setStrategy(MergeStrategy.RESOLVE) + .setContentMergeStrategy(ContentMergeStrategy.OURS).call(); + assertEquals(MergeStatus.MERGED, result.getMergeStatus()); + + assertEquals("1\na(main)\n3\n4\n", + read(new File(db.getWorkTree(), "a"))); + assertEquals("1\nb(side)\n3\n4\n", + read(new File(db.getWorkTree(), "b"))); + assertEquals("1\nc(main)\n3\n", + read(new File(db.getWorkTree(), "c/c/c"))); + + assertNull(result.getConflicts()); + + assertEquals(RepositoryState.SAFE, db.getRepositoryState()); + } + } + + @Test + public void testBinaryContentMerge() throws Exception { + try (Git git = new Git(db)) { + writeTrashFile(".gitattributes", "a binary"); + writeTrashFile("a", "initial"); + git.add().addFilepattern(".").call(); + RevCommit initialCommit = git.commit().setMessage("initial").call(); + + createBranch(initialCommit, "refs/heads/side"); + checkoutBranch("refs/heads/side"); + + writeTrashFile("a", "side"); + git.add().addFilepattern("a").call(); + RevCommit secondCommit = git.commit().setMessage("side").call(); + + checkoutBranch("refs/heads/master"); + + writeTrashFile("a", "main"); + git.add().addFilepattern("a").call(); + git.commit().setMessage("main").call(); + + MergeResult result = git.merge().include(secondCommit.getId()) + .setStrategy(MergeStrategy.RESOLVE).call(); + assertEquals(MergeStatus.CONFLICTING, result.getMergeStatus()); + + assertEquals("main", read(new File(db.getWorkTree(), "a"))); + + // Hmmm... there doesn't seem to be a way to figure out which files + // had a binary conflict from a MergeResult... + + assertEquals(RepositoryState.MERGING, db.getRepositoryState()); + } + } + + @Test + public void testBinaryContentMergeXtheirs() throws Exception { + try (Git git = new Git(db)) { + writeTrashFile(".gitattributes", "a binary"); + writeTrashFile("a", "initial"); + git.add().addFilepattern(".").call(); + RevCommit initialCommit = git.commit().setMessage("initial").call(); + + createBranch(initialCommit, "refs/heads/side"); + checkoutBranch("refs/heads/side"); + + writeTrashFile("a", "side"); + git.add().addFilepattern("a").call(); + RevCommit secondCommit = git.commit().setMessage("side").call(); + + checkoutBranch("refs/heads/master"); + + writeTrashFile("a", "main"); + git.add().addFilepattern("a").call(); + git.commit().setMessage("main").call(); + + MergeResult result = git.merge().include(secondCommit.getId()) + .setStrategy(MergeStrategy.RESOLVE) + .setContentMergeStrategy(ContentMergeStrategy.THEIRS) + .call(); + assertEquals(MergeStatus.MERGED, result.getMergeStatus()); + + assertEquals("side", read(new File(db.getWorkTree(), "a"))); + + assertNull(result.getConflicts()); + assertEquals(RepositoryState.SAFE, db.getRepositoryState()); + } + } + + @Test + public void testBinaryContentMergeXours() throws Exception { + try (Git git = new Git(db)) { + writeTrashFile(".gitattributes", "a binary"); + writeTrashFile("a", "initial"); + git.add().addFilepattern(".").call(); + RevCommit initialCommit = git.commit().setMessage("initial").call(); + + createBranch(initialCommit, "refs/heads/side"); + checkoutBranch("refs/heads/side"); + + writeTrashFile("a", "side"); + git.add().addFilepattern("a").call(); + RevCommit secondCommit = git.commit().setMessage("side").call(); + + checkoutBranch("refs/heads/master"); + + writeTrashFile("a", "main"); + git.add().addFilepattern("a").call(); + git.commit().setMessage("main").call(); + + MergeResult result = git.merge().include(secondCommit.getId()) + .setStrategy(MergeStrategy.RESOLVE) + .setContentMergeStrategy(ContentMergeStrategy.OURS).call(); + assertEquals(MergeStatus.MERGED, result.getMergeStatus()); + + assertEquals("main", read(new File(db.getWorkTree(), "a"))); + + assertNull(result.getConflicts()); + assertEquals(RepositoryState.SAFE, db.getRepositoryState()); + } + } + + @Test public void testMergeTag() throws Exception { try (Git git = new Git(db)) { writeTrashFile("a", "a"); @@ -790,17 +987,96 @@ public class MergeCommandTest extends RepositoryTestCase { // delete a on master to generate conflict checkoutBranch("refs/heads/master"); git.rm().addFilepattern("a").call(); + RevCommit thirdCommit = git.commit().setMessage("main").call(); + + for (ContentMergeStrategy contentStrategy : ContentMergeStrategy + .values()) { + // merge side with master + MergeResult result = git.merge().include(secondCommit.getId()) + .setStrategy(MergeStrategy.RESOLVE) + .setContentMergeStrategy(contentStrategy) + .call(); + assertEquals("merge -X " + contentStrategy.name(), + MergeStatus.CONFLICTING, result.getMergeStatus()); + + // result should be 'a' conflicting with workspace content from + // side + assertTrue("merge -X " + contentStrategy.name(), + new File(db.getWorkTree(), "a").exists()); + assertEquals("merge -X " + contentStrategy.name(), + "1\na(side)\n3\n", + read(new File(db.getWorkTree(), "a"))); + assertEquals("merge -X " + contentStrategy.name(), "1\nb\n3\n", + read(new File(db.getWorkTree(), "b"))); + git.reset().setMode(ResetType.HARD).setRef(thirdCommit.name()) + .call(); + } + } + } + + @Test + public void testDeletionOnMasterTheirs() throws Exception { + try (Git git = new Git(db)) { + writeTrashFile("a", "1\na\n3\n"); + writeTrashFile("b", "1\nb\n3\n"); + git.add().addFilepattern("a").addFilepattern("b").call(); + RevCommit initialCommit = git.commit().setMessage("initial").call(); + + // create side branch and modify "a" + createBranch(initialCommit, "refs/heads/side"); + checkoutBranch("refs/heads/side"); + writeTrashFile("a", "1\na(side)\n3\n"); + git.add().addFilepattern("a").call(); + RevCommit secondCommit = git.commit().setMessage("side").call(); + + // delete a on master to generate conflict + checkoutBranch("refs/heads/master"); + git.rm().addFilepattern("a").call(); git.commit().setMessage("main").call(); // merge side with master MergeResult result = git.merge().include(secondCommit.getId()) - .setStrategy(MergeStrategy.RESOLVE).call(); - assertEquals(MergeStatus.CONFLICTING, result.getMergeStatus()); + .setStrategy(MergeStrategy.THEIRS) + .call(); + assertEquals(MergeStatus.MERGED, result.getMergeStatus()); - // result should be 'a' conflicting with workspace content from side + // result should be 'a' assertTrue(new File(db.getWorkTree(), "a").exists()); - assertEquals("1\na(side)\n3\n", read(new File(db.getWorkTree(), "a"))); + assertEquals("1\na(side)\n3\n", + read(new File(db.getWorkTree(), "a"))); + assertEquals("1\nb\n3\n", read(new File(db.getWorkTree(), "b"))); + assertTrue(git.status().call().isClean()); + } + } + + @Test + public void testDeletionOnMasterOurs() throws Exception { + try (Git git = new Git(db)) { + writeTrashFile("a", "1\na\n3\n"); + writeTrashFile("b", "1\nb\n3\n"); + git.add().addFilepattern("a").addFilepattern("b").call(); + RevCommit initialCommit = git.commit().setMessage("initial").call(); + + // create side branch and modify "a" + createBranch(initialCommit, "refs/heads/side"); + checkoutBranch("refs/heads/side"); + writeTrashFile("a", "1\na(side)\n3\n"); + git.add().addFilepattern("a").call(); + RevCommit secondCommit = git.commit().setMessage("side").call(); + + // delete a on master to generate conflict + checkoutBranch("refs/heads/master"); + git.rm().addFilepattern("a").call(); + git.commit().setMessage("main").call(); + + // merge side with master + MergeResult result = git.merge().include(secondCommit.getId()) + .setStrategy(MergeStrategy.OURS).call(); + assertEquals(MergeStatus.MERGED, result.getMergeStatus()); + + assertFalse(new File(db.getWorkTree(), "a").exists()); assertEquals("1\nb\n3\n", read(new File(db.getWorkTree(), "b"))); + assertTrue(git.status().call().isClean()); } } @@ -822,19 +1098,99 @@ public class MergeCommandTest extends RepositoryTestCase { checkoutBranch("refs/heads/master"); writeTrashFile("a", "1\na(main)\n3\n"); git.add().addFilepattern("a").call(); + RevCommit thirdCommit = git.commit().setMessage("main").call(); + + for (ContentMergeStrategy contentStrategy : ContentMergeStrategy + .values()) { + // merge side with master + MergeResult result = git.merge().include(secondCommit.getId()) + .setStrategy(MergeStrategy.RESOLVE) + .setContentMergeStrategy(contentStrategy) + .call(); + assertEquals("merge -X " + contentStrategy.name(), + MergeStatus.CONFLICTING, result.getMergeStatus()); + + assertTrue("merge -X " + contentStrategy.name(), + new File(db.getWorkTree(), "a").exists()); + assertEquals("merge -X " + contentStrategy.name(), + "1\na(main)\n3\n", + read(new File(db.getWorkTree(), "a"))); + assertEquals("merge -X " + contentStrategy.name(), "1\nb\n3\n", + read(new File(db.getWorkTree(), "b"))); + + assertNotNull("merge -X " + contentStrategy.name(), + result.getConflicts()); + assertEquals("merge -X " + contentStrategy.name(), 1, + result.getConflicts().size()); + assertEquals("merge -X " + contentStrategy.name(), 3, + result.getConflicts().get("a")[0].length); + git.reset().setMode(ResetType.HARD).setRef(thirdCommit.name()) + .call(); + } + } + } + + @Test + public void testDeletionOnSideTheirs() throws Exception { + try (Git git = new Git(db)) { + writeTrashFile("a", "1\na\n3\n"); + writeTrashFile("b", "1\nb\n3\n"); + git.add().addFilepattern("a").addFilepattern("b").call(); + RevCommit initialCommit = git.commit().setMessage("initial").call(); + + // create side branch and delete "a" + createBranch(initialCommit, "refs/heads/side"); + checkoutBranch("refs/heads/side"); + git.rm().addFilepattern("a").call(); + RevCommit secondCommit = git.commit().setMessage("side").call(); + + // update a on master to generate conflict + checkoutBranch("refs/heads/master"); + writeTrashFile("a", "1\na(main)\n3\n"); + git.add().addFilepattern("a").call(); git.commit().setMessage("main").call(); // merge side with master MergeResult result = git.merge().include(secondCommit.getId()) - .setStrategy(MergeStrategy.RESOLVE).call(); - assertEquals(MergeStatus.CONFLICTING, result.getMergeStatus()); + .setStrategy(MergeStrategy.THEIRS).call(); + assertEquals(MergeStatus.MERGED, result.getMergeStatus()); - assertTrue(new File(db.getWorkTree(), "a").exists()); - assertEquals("1\na(main)\n3\n", read(new File(db.getWorkTree(), "a"))); + assertFalse(new File(db.getWorkTree(), "a").exists()); assertEquals("1\nb\n3\n", read(new File(db.getWorkTree(), "b"))); + assertTrue(git.status().call().isClean()); + } + } - assertEquals(1, result.getConflicts().size()); - assertEquals(3, result.getConflicts().get("a")[0].length); + @Test + public void testDeletionOnSideOurs() throws Exception { + try (Git git = new Git(db)) { + writeTrashFile("a", "1\na\n3\n"); + writeTrashFile("b", "1\nb\n3\n"); + git.add().addFilepattern("a").addFilepattern("b").call(); + RevCommit initialCommit = git.commit().setMessage("initial").call(); + + // create side branch and delete "a" + createBranch(initialCommit, "refs/heads/side"); + checkoutBranch("refs/heads/side"); + git.rm().addFilepattern("a").call(); + RevCommit secondCommit = git.commit().setMessage("side").call(); + + // update a on master to generate conflict + checkoutBranch("refs/heads/master"); + writeTrashFile("a", "1\na(main)\n3\n"); + git.add().addFilepattern("a").call(); + git.commit().setMessage("main").call(); + + // merge side with master + MergeResult result = git.merge().include(secondCommit.getId()) + .setStrategy(MergeStrategy.OURS).call(); + assertEquals(MergeStatus.MERGED, result.getMergeStatus()); + + assertTrue(new File(db.getWorkTree(), "a").exists()); + assertEquals("1\na(main)\n3\n", + read(new File(db.getWorkTree(), "a"))); + assertEquals("1\nb\n3\n", read(new File(db.getWorkTree(), "b"))); + assertTrue(git.status().call().isClean()); } } diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/PullCommandTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/PullCommandTest.java index e4af44e6f8..9af77aa3e8 100644 --- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/PullCommandTest.java +++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/PullCommandTest.java @@ -34,6 +34,8 @@ import org.eclipse.jgit.lib.RefUpdate; import org.eclipse.jgit.lib.Repository; import org.eclipse.jgit.lib.RepositoryState; import org.eclipse.jgit.lib.StoredConfig; +import org.eclipse.jgit.merge.ContentMergeStrategy; +import org.eclipse.jgit.merge.MergeStrategy; import org.eclipse.jgit.revwalk.RevCommit; import org.eclipse.jgit.revwalk.RevSort; import org.eclipse.jgit.revwalk.RevWalk; @@ -154,6 +156,75 @@ public class PullCommandTest extends RepositoryTestCase { } @Test + public void testPullConflictTheirs() throws Exception { + PullResult res = target.pull().call(); + // nothing to update since we don't have different data yet + assertTrue(res.getFetchResult().getTrackingRefUpdates().isEmpty()); + assertTrue(res.getMergeResult().getMergeStatus() + .equals(MergeStatus.ALREADY_UP_TO_DATE)); + + assertFileContentsEqual(targetFile, "Hello world"); + + // change the source file + writeToFile(sourceFile, "Source change"); + source.add().addFilepattern("SomeFile.txt").call(); + source.commit().setMessage("Source change in remote").call(); + + // change the target file + writeToFile(targetFile, "Target change"); + target.add().addFilepattern("SomeFile.txt").call(); + target.commit().setMessage("Target change in local").call(); + + res = target.pull().setStrategy(MergeStrategy.THEIRS).call(); + + assertTrue(res.isSuccessful()); + assertFileContentsEqual(targetFile, "Source change"); + assertEquals(RepositoryState.SAFE, + target.getRepository().getRepositoryState()); + assertTrue(target.status().call().isClean()); + } + + @Test + public void testPullConflictXtheirs() throws Exception { + PullResult res = target.pull().call(); + // nothing to update since we don't have different data yet + assertTrue(res.getFetchResult().getTrackingRefUpdates().isEmpty()); + assertTrue(res.getMergeResult().getMergeStatus() + .equals(MergeStatus.ALREADY_UP_TO_DATE)); + + assertFileContentsEqual(targetFile, "Hello world"); + + // change the source file + writeToFile(sourceFile, "a\nHello\nb\n"); + source.add().addFilepattern("SomeFile.txt").call(); + source.commit().setMessage("Multi-line change in remote").call(); + + // Pull again + res = target.pull().call(); + assertTrue(res.isSuccessful()); + assertFileContentsEqual(targetFile, "a\nHello\nb\n"); + + // change the source file + writeToFile(sourceFile, "a\nSource change\nb\n"); + source.add().addFilepattern("SomeFile.txt").call(); + source.commit().setMessage("Source change in remote").call(); + + // change the target file + writeToFile(targetFile, "a\nTarget change\nb\nc\n"); + target.add().addFilepattern("SomeFile.txt").call(); + target.commit().setMessage("Target change in local").call(); + + res = target.pull().setContentMergeStrategy(ContentMergeStrategy.THEIRS) + .call(); + + assertTrue(res.isSuccessful()); + assertFileContentsEqual(targetFile, "a\nSource change\nb\nc\n"); + assertEquals(RepositoryState.SAFE, + target.getRepository().getRepositoryState()); + assertTrue(target.status().call().isClean()); + } + + @Test public void testPullWithUntrackedStash() throws Exception { target.pull().call(); diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/RevertCommandTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/RevertCommandTest.java index 57c8991f3a..cfa8486ac5 100644 --- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/RevertCommandTest.java +++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/RevertCommandTest.java @@ -253,7 +253,7 @@ public class RevertCommandTest extends RepositoryTestCase { } @Test - public void testRevertkConflictReset() throws Exception { + public void testRevertConflictReset() throws Exception { try (Git git = new Git(db)) { RevCommit sideCommit = prepareRevert(git); diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/StashApplyCommandTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/StashApplyCommandTest.java index f109cbf50f..49b31b1c4c 100644 --- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/StashApplyCommandTest.java +++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/StashApplyCommandTest.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2012, GitHub Inc. and others + * Copyright (C) 2012, 2021 GitHub Inc. and others * * This program and the accompanying materials are made available under the * terms of the Eclipse Distribution License v. 1.0 which is available at @@ -28,6 +28,8 @@ import org.eclipse.jgit.internal.JGitText; import org.eclipse.jgit.junit.RepositoryTestCase; import org.eclipse.jgit.lib.ObjectId; import org.eclipse.jgit.lib.Repository; +import org.eclipse.jgit.merge.ContentMergeStrategy; +import org.eclipse.jgit.merge.MergeStrategy; import org.eclipse.jgit.revwalk.RevCommit; import org.eclipse.jgit.util.FileUtils; import org.junit.After; @@ -427,6 +429,135 @@ public class StashApplyCommandTest extends RepositoryTestCase { } @Test + public void stashedContentMergeXtheirs() throws Exception { + writeTrashFile(PATH, "content\nmore content\n"); + git.add().addFilepattern(PATH).call(); + git.commit().setMessage("more content").call(); + + writeTrashFile(PATH, "content\nhead change\nmore content\n"); + git.add().addFilepattern(PATH).call(); + git.commit().setMessage("even content").call(); + + writeTrashFile(PATH, "content\nstashed change\nmore content\n"); + + RevCommit stashed = git.stashCreate().call(); + assertNotNull(stashed); + assertEquals("content\nhead change\nmore content\n", + read(committedFile)); + assertTrue(git.status().call().isClean()); + recorder.assertEvent(new String[] { PATH }, ChangeRecorder.EMPTY); + + writeTrashFile(PATH, "content\nmore content\ncommitted change\n"); + git.add().addFilepattern(PATH).call(); + git.commit().setMessage("committed change").call(); + recorder.assertNoEvent(); + + git.stashApply().setContentMergeStrategy(ContentMergeStrategy.THEIRS) + .call(); + recorder.assertEvent(new String[] { PATH }, ChangeRecorder.EMPTY); + Status status = new StatusCommand(db).call(); + assertEquals('[' + PATH + ']', status.getModified().toString()); + assertEquals( + "content\nstashed change\nmore content\ncommitted change\n", + read(PATH)); + } + + @Test + public void stashedContentMergeXours() throws Exception { + writeTrashFile(PATH, "content\nmore content\n"); + git.add().addFilepattern(PATH).call(); + git.commit().setMessage("more content").call(); + + writeTrashFile(PATH, "content\nhead change\nmore content\n"); + git.add().addFilepattern(PATH).call(); + git.commit().setMessage("even content").call(); + + writeTrashFile(PATH, "content\nstashed change\nmore content\n"); + + RevCommit stashed = git.stashCreate().call(); + assertNotNull(stashed); + assertEquals("content\nhead change\nmore content\n", + read(committedFile)); + assertTrue(git.status().call().isClean()); + recorder.assertEvent(new String[] { PATH }, ChangeRecorder.EMPTY); + + writeTrashFile(PATH, + "content\nnew head\nmore content\ncommitted change\n"); + git.add().addFilepattern(PATH).call(); + git.commit().setMessage("committed change").call(); + recorder.assertNoEvent(); + + git.stashApply().setContentMergeStrategy(ContentMergeStrategy.OURS) + .call(); + recorder.assertEvent(new String[] { PATH }, ChangeRecorder.EMPTY); + assertTrue(git.status().call().isClean()); + assertEquals("content\nnew head\nmore content\ncommitted change\n", + read(PATH)); + } + + @Test + public void stashedContentMergeTheirs() throws Exception { + writeTrashFile(PATH, "content\nmore content\n"); + git.add().addFilepattern(PATH).call(); + git.commit().setMessage("more content").call(); + + writeTrashFile(PATH, "content\nhead change\nmore content\n"); + git.add().addFilepattern(PATH).call(); + git.commit().setMessage("even content").call(); + + writeTrashFile(PATH, "content\nstashed change\nmore content\n"); + + RevCommit stashed = git.stashCreate().call(); + assertNotNull(stashed); + assertEquals("content\nhead change\nmore content\n", + read(committedFile)); + assertTrue(git.status().call().isClean()); + recorder.assertEvent(new String[] { PATH }, ChangeRecorder.EMPTY); + + writeTrashFile(PATH, "content\nmore content\ncommitted change\n"); + git.add().addFilepattern(PATH).call(); + git.commit().setMessage("committed change").call(); + recorder.assertNoEvent(); + + git.stashApply().setStrategy(MergeStrategy.THEIRS).call(); + recorder.assertEvent(new String[] { PATH }, ChangeRecorder.EMPTY); + Status status = new StatusCommand(db).call(); + assertEquals('[' + PATH + ']', status.getModified().toString()); + assertEquals("content\nstashed change\nmore content\n", read(PATH)); + } + + @Test + public void stashedContentMergeOurs() throws Exception { + writeTrashFile(PATH, "content\nmore content\n"); + git.add().addFilepattern(PATH).call(); + git.commit().setMessage("more content").call(); + + writeTrashFile(PATH, "content\nhead change\nmore content\n"); + git.add().addFilepattern(PATH).call(); + git.commit().setMessage("even content").call(); + + writeTrashFile(PATH, "content\nstashed change\nmore content\n"); + + RevCommit stashed = git.stashCreate().call(); + assertNotNull(stashed); + assertEquals("content\nhead change\nmore content\n", + read(committedFile)); + assertTrue(git.status().call().isClean()); + recorder.assertEvent(new String[] { PATH }, ChangeRecorder.EMPTY); + + writeTrashFile(PATH, "content\nmore content\ncommitted change\n"); + git.add().addFilepattern(PATH).call(); + git.commit().setMessage("committed change").call(); + recorder.assertNoEvent(); + + // Doesn't make any sense... should be a no-op + git.stashApply().setStrategy(MergeStrategy.OURS).call(); + recorder.assertNoEvent(); + assertTrue(git.status().call().isClean()); + assertEquals("content\nmore content\ncommitted change\n", read(PATH)); + } + + @Test public void stashedApplyOnOtherBranch() throws Exception { writeTrashFile(PATH, "content\nmore content\n"); git.add().addFilepattern(PATH).call(); diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/file/LockFileTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/file/LockFileTest.java index 0f93749d9b..509935dfb9 100644 --- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/file/LockFileTest.java +++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/file/LockFileTest.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2012, GitHub Inc. and others + * Copyright (C) 2012, 2021 GitHub Inc. and others * * This program and the accompanying materials are made available under the * terms of the Eclipse Distribution License v. 1.0 which is available at @@ -9,10 +9,16 @@ */ package org.eclipse.jgit.internal.storage.file; +import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertThrows; import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; +import java.io.File; +import java.io.OutputStream; +import java.nio.charset.StandardCharsets; + import org.eclipse.jgit.api.Git; import org.eclipse.jgit.api.errors.JGitInternalException; import org.eclipse.jgit.errors.LockFailedException; @@ -49,4 +55,149 @@ public class LockFileTest extends RepositoryTestCase { } } } + + @Test + public void testLockTwice() throws Exception { + File f = writeTrashFile("somefile", "content"); + LockFile lock = new LockFile(f); + assertTrue(lock.lock()); + lock.write("other".getBytes(StandardCharsets.US_ASCII)); + lock.commit(); + assertFalse(lock.isLocked()); + checkFile(f, "other"); + assertTrue(lock.lock()); + assertTrue(lock.isLocked()); + try (OutputStream out = lock.getOutputStream()) { + out.write("second".getBytes(StandardCharsets.US_ASCII)); + } + lock.commit(); + assertFalse(lock.isLocked()); + checkFile(f, "second"); + } + + @Test + public void testLockTwiceUnlock() throws Exception { + File f = writeTrashFile("somefile", "content"); + LockFile lock = new LockFile(f); + assertTrue(lock.lock()); + assertTrue(lock.isLocked()); + lock.write("other".getBytes(StandardCharsets.US_ASCII)); + lock.unlock(); + assertFalse(lock.isLocked()); + checkFile(f, "content"); + assertTrue(lock.lock()); + assertTrue(lock.isLocked()); + try (OutputStream out = lock.getOutputStream()) { + out.write("second".getBytes(StandardCharsets.US_ASCII)); + } + lock.commit(); + assertFalse(lock.isLocked()); + checkFile(f, "second"); + } + + @Test + public void testLockWriteTwiceThrows1() throws Exception { + File f = writeTrashFile("somefile", "content"); + LockFile lock = new LockFile(f); + assertTrue(lock.lock()); + assertTrue(lock.isLocked()); + lock.write("other".getBytes(StandardCharsets.US_ASCII)); + assertThrows(Exception.class, + () -> lock.write("second".getBytes(StandardCharsets.US_ASCII))); + lock.unlock(); + } + + @Test + public void testLockWriteTwiceThrows2() throws Exception { + File f = writeTrashFile("somefile", "content"); + LockFile lock = new LockFile(f); + assertTrue(lock.lock()); + assertTrue(lock.isLocked()); + try (OutputStream out = lock.getOutputStream()) { + out.write("other".getBytes(StandardCharsets.US_ASCII)); + } + assertThrows(Exception.class, + () -> lock.write("second".getBytes(StandardCharsets.US_ASCII))); + lock.unlock(); + } + + @Test + public void testLockWriteTwiceThrows3() throws Exception { + File f = writeTrashFile("somefile", "content"); + LockFile lock = new LockFile(f); + assertTrue(lock.lock()); + assertTrue(lock.isLocked()); + lock.write("other".getBytes(StandardCharsets.US_ASCII)); + assertThrows(Exception.class, () -> { + try (OutputStream out = lock.getOutputStream()) { + out.write("second".getBytes(StandardCharsets.US_ASCII)); + } + }); + lock.unlock(); + } + + @Test + public void testLockWriteTwiceThrows4() throws Exception { + File f = writeTrashFile("somefile", "content"); + LockFile lock = new LockFile(f); + assertTrue(lock.lock()); + assertTrue(lock.isLocked()); + try (OutputStream out = lock.getOutputStream()) { + out.write("other".getBytes(StandardCharsets.US_ASCII)); + } + assertThrows(Exception.class, () -> { + try (OutputStream out = lock.getOutputStream()) { + out.write("second".getBytes(StandardCharsets.US_ASCII)); + } + }); + lock.unlock(); + } + + @Test + public void testLockUnclosedCommitThrows() throws Exception { + File f = writeTrashFile("somefile", "content"); + LockFile lock = new LockFile(f); + assertTrue(lock.lock()); + assertTrue(lock.isLocked()); + try (OutputStream out = lock.getOutputStream()) { + out.write("other".getBytes(StandardCharsets.US_ASCII)); + assertThrows(Exception.class, () -> lock.commit()); + } + } + + @Test + public void testLockNested() throws Exception { + File f = writeTrashFile("somefile", "content"); + LockFile lock = new LockFile(f); + assertTrue(lock.lock()); + assertTrue(lock.isLocked()); + assertThrows(IllegalStateException.class, () -> lock.lock()); + assertTrue(lock.isLocked()); + lock.unlock(); + } + + @Test + public void testLockHeld() throws Exception { + File f = writeTrashFile("somefile", "content"); + LockFile lock = new LockFile(f); + assertTrue(lock.lock()); + assertTrue(lock.isLocked()); + LockFile lock2 = new LockFile(f); + assertFalse(lock2.lock()); + assertFalse(lock2.isLocked()); + assertTrue(lock.isLocked()); + lock.unlock(); + } + + @Test + public void testLockForAppend() throws Exception { + File f = writeTrashFile("somefile", "content"); + LockFile lock = new LockFile(f); + assertTrue(lock.lockForAppend()); + assertTrue(lock.isLocked()); + lock.write("other".getBytes(StandardCharsets.US_ASCII)); + lock.commit(); + assertFalse(lock.isLocked()); + checkFile(f, "contentother"); + } } diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/merge/MergerTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/merge/MergerTest.java index eecf25be90..6cbb4a89b2 100644 --- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/merge/MergerTest.java +++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/merge/MergerTest.java @@ -1648,6 +1648,82 @@ public class MergerTest extends RepositoryTestCase { indexState(CONTENT)); } + /** + * Merging two commits when files have equal content, but conflicting file mode + * in the virtual ancestor. + * + * <p> + * This test has the same set up as + * {@code checkFileDirMergeConflictInVirtualAncestor_NoConflictInChildren}, only + * with the mode conflict in A1 and A2. + */ + @Theory + public void checkModeMergeConflictInVirtualAncestor(MergeStrategy strategy) throws Exception { + if (!strategy.equals(MergeStrategy.RECURSIVE)) { + return; + } + + Git git = Git.wrap(db); + + // master + writeTrashFile("c", "initial file"); + git.add().addFilepattern("c").call(); + RevCommit commitI = git.commit().setMessage("Initial commit").call(); + + File a = writeTrashFile("a", "content in Ancestor"); + git.add().addFilepattern("a").call(); + RevCommit commitA1 = git.commit().setMessage("Ancestor 1").call(); + + a = writeTrashFile("a", "content in Child 1 (commited on master)"); + git.add().addFilepattern("a").call(); + // commit C1M + git.commit().setMessage("Child 1 on master").call(); + + git.checkout().setCreateBranch(true).setStartPoint(commitI).setName("branch-to-merge").call(); + // "a" becomes executable in A2 + a = writeTrashFile("a", "content in Ancestor"); + a.setExecutable(true); + git.add().addFilepattern("a").call(); + RevCommit commitA2 = git.commit().setMessage("Ancestor 2").call(); + + // second branch + git.checkout().setCreateBranch(true).setStartPoint(commitA1).setName("second-branch").call(); + a = writeTrashFile("a", "content in Child 2 (commited on second-branch)"); + git.add().addFilepattern("a").call(); + // commit C2S + git.commit().setMessage("Child 2 on second-branch").call(); + + // Merge branch-to-merge into second-branch + MergeResult mergeResult = git.merge().include(commitA2).setStrategy(strategy).call(); + assertEquals(mergeResult.getNewHead(), null); + assertEquals(mergeResult.getMergeStatus(), MergeStatus.CONFLICTING); + // Resolve the conflict manually, merge "a" as non-executable + a = writeTrashFile("a", "merge conflict resolution"); + a.setExecutable(false); + git.add().addFilepattern("a").call(); + RevCommit commitC3S = git.commit().setMessage("Child 3 on second bug - resolve merge conflict").call(); + + // Merge branch-to-merge into master + git.checkout().setName("master").call(); + mergeResult = git.merge().include(commitA2).setStrategy(strategy).call(); + assertEquals(mergeResult.getNewHead(), null); + assertEquals(mergeResult.getMergeStatus(), MergeStatus.CONFLICTING); + + // Resolve the conflict manually - merge "a" as non-executable + a = writeTrashFile("a", "merge conflict resolution"); + a.setExecutable(false); + git.add().addFilepattern("a").call(); + // commit C4M + git.commit().setMessage("Child 4 on master - resolve merge conflict").call(); + + // Merge C4M (second-branch) into master (C3S) + // Conflict in virtual base should be here, but there are no conflicts in + // children + mergeResult = git.merge().include(commitC3S).call(); + assertEquals(mergeResult.getMergeStatus(), MergeStatus.MERGED); + + } + private void writeSubmodule(String path, ObjectId commit) throws IOException, ConfigInvalidException { addSubmoduleToIndex(path, commit); diff --git a/org.eclipse.jgit/resources/org/eclipse/jgit/internal/JGitText.properties b/org.eclipse.jgit/resources/org/eclipse/jgit/internal/JGitText.properties index 33087d7622..2fa8713daa 100644 --- a/org.eclipse.jgit/resources/org/eclipse/jgit/internal/JGitText.properties +++ b/org.eclipse.jgit/resources/org/eclipse/jgit/internal/JGitText.properties @@ -415,11 +415,14 @@ listingPacks=Listing packs localObjectsIncomplete=Local objects incomplete. localRefIsMissingObjects=Local ref {0} is missing object(s). localRepository=local repository +lockAlreadyHeld=Lock on {0} already held lockCountMustBeGreaterOrEqual1=lockCount must be >= 1 lockError=lock error: {0} lockFailedRetry=locking {0} failed after {1} retries lockOnNotClosed=Lock on {0} not closed. lockOnNotHeld=Lock on {0} not held. +lockStreamClosed=Output to lock on {0} already closed +lockStreamMultiple=Output to lock on {0} already opened logInconsistentFiletimeDiff={}: inconsistent duration from file timestamps on {}, {}: {} > {}, but diff = {}. Aborting measurement at resolution {}. logLargerFiletimeDiff={}: inconsistent duration from file timestamps on {}, {}: diff = {} > {} (last good value). Aborting measurement. logSmallerFiletime={}: got smaller file timestamp on {}, {}: {} < {}. Aborting measurement at resolution {}. @@ -530,6 +533,7 @@ peeledRefIsRequired=Peeled ref is required. peerDidNotSupplyACompleteObjectGraph=peer did not supply a complete object graph personIdentEmailNonNull=E-mail address of PersonIdent must not be null. personIdentNameNonNull=Name of PersonIdent must not be null. +postCommitHookFailed=Execution of post-commit hook failed: {0}. prefixRemote=remote: problemWithResolvingPushRefSpecsLocally=Problem with resolving push ref specs locally: {0} progressMonUploading=Uploading {0} diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/api/CherryPickCommand.java b/org.eclipse.jgit/src/org/eclipse/jgit/api/CherryPickCommand.java index 5d0154c6dc..7922f9e729 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/api/CherryPickCommand.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/api/CherryPickCommand.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2010, Christian Halstrick <christian.halstrick@sap.com> and others + * Copyright (C) 2010, 2021 Christian Halstrick <christian.halstrick@sap.com> and others * * This program and the accompanying materials are made available under the * terms of the Eclipse Distribution License v. 1.0 which is available at @@ -13,6 +13,7 @@ import java.io.IOException; import java.text.MessageFormat; import java.util.LinkedList; import java.util.List; +import java.util.Map; import org.eclipse.jgit.api.errors.ConcurrentRefUpdateException; import org.eclipse.jgit.api.errors.GitAPIException; @@ -35,9 +36,12 @@ import org.eclipse.jgit.lib.ProgressMonitor; import org.eclipse.jgit.lib.Ref; import org.eclipse.jgit.lib.Ref.Storage; import org.eclipse.jgit.lib.Repository; +import org.eclipse.jgit.merge.ContentMergeStrategy; import org.eclipse.jgit.merge.MergeMessageFormatter; import org.eclipse.jgit.merge.MergeStrategy; +import org.eclipse.jgit.merge.Merger; import org.eclipse.jgit.merge.ResolveMerger; +import org.eclipse.jgit.merge.ResolveMerger.MergeFailureReason; import org.eclipse.jgit.revwalk.RevCommit; import org.eclipse.jgit.revwalk.RevWalk; import org.eclipse.jgit.treewalk.FileTreeIterator; @@ -61,6 +65,8 @@ public class CherryPickCommand extends GitCommand<CherryPickResult> { private MergeStrategy strategy = MergeStrategy.RECURSIVE; + private ContentMergeStrategy contentStrategy; + private Integer mainlineParentNumber; private boolean noCommit = false; @@ -121,16 +127,30 @@ public class CherryPickCommand extends GitCommand<CherryPickResult> { String cherryPickName = srcCommit.getId().abbreviate(7).name() + " " + srcCommit.getShortMessage(); //$NON-NLS-1$ - ResolveMerger merger = (ResolveMerger) strategy.newMerger(repo); - merger.setWorkingTreeIterator(new FileTreeIterator(repo)); - merger.setBase(srcParent.getTree()); - merger.setCommitNames(new String[] { "BASE", ourName, //$NON-NLS-1$ - cherryPickName }); - if (merger.merge(newHead, srcCommit)) { - if (!merger.getModifiedFiles().isEmpty()) { + Merger merger = strategy.newMerger(repo); + merger.setProgressMonitor(monitor); + boolean noProblems; + Map<String, MergeFailureReason> failingPaths = null; + List<String> unmergedPaths = null; + if (merger instanceof ResolveMerger) { + ResolveMerger resolveMerger = (ResolveMerger) merger; + resolveMerger.setContentMergeStrategy(contentStrategy); + resolveMerger.setCommitNames( + new String[] { "BASE", ourName, cherryPickName }); //$NON-NLS-1$ + resolveMerger + .setWorkingTreeIterator(new FileTreeIterator(repo)); + resolveMerger.setBase(srcParent.getTree()); + noProblems = merger.merge(newHead, srcCommit); + failingPaths = resolveMerger.getFailingPaths(); + unmergedPaths = resolveMerger.getUnmergedPaths(); + if (!resolveMerger.getModifiedFiles().isEmpty()) { repo.fireEvent(new WorkingTreeModifiedEvent( - merger.getModifiedFiles(), null)); + resolveMerger.getModifiedFiles(), null)); } + } else { + noProblems = merger.merge(newHead, srcCommit); + } + if (noProblems) { if (AnyObjectId.isEqual(newHead.getTree().getId(), merger.getResultTreeId())) { continue; @@ -153,24 +173,26 @@ public class CherryPickCommand extends GitCommand<CherryPickResult> { } cherryPickedRefs.add(src); } else { - if (merger.failed()) { - return new CherryPickResult(merger.getFailingPaths()); + if (failingPaths != null && !failingPaths.isEmpty()) { + return new CherryPickResult(failingPaths); } // there are merge conflicts - String message = new MergeMessageFormatter() + String message; + if (unmergedPaths != null) { + message = new MergeMessageFormatter() .formatWithConflicts(srcCommit.getFullMessage(), - merger.getUnmergedPaths()); + unmergedPaths); + } else { + message = srcCommit.getFullMessage(); + } if (!noCommit) { repo.writeCherryPickHead(srcCommit.getId()); } repo.writeMergeCommitMsg(message); - repo.fireEvent(new WorkingTreeModifiedEvent( - merger.getModifiedFiles(), null)); - return CherryPickResult.CONFLICT; } } @@ -291,6 +313,22 @@ public class CherryPickCommand extends GitCommand<CherryPickResult> { } /** + * Sets the content merge strategy to use if the + * {@link #setStrategy(MergeStrategy) merge strategy} is "resolve" or + * "recursive". + * + * @param strategy + * the {@link ContentMergeStrategy} to be used + * @return {@code this} + * @since 5.12 + */ + public CherryPickCommand setContentMergeStrategy( + ContentMergeStrategy strategy) { + this.contentStrategy = strategy; + return this; + } + + /** * Set the (1-based) parent number to diff against * * @param mainlineParentNumber diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/api/CommitCommand.java b/org.eclipse.jgit/src/org/eclipse/jgit/api/CommitCommand.java index 041276c0f8..37f1d482aa 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/api/CommitCommand.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/api/CommitCommand.java @@ -20,6 +20,7 @@ import java.util.LinkedList; import java.util.List; import org.eclipse.jgit.api.errors.AbortedByHookException; +import org.eclipse.jgit.api.errors.CanceledException; import org.eclipse.jgit.api.errors.ConcurrentRefUpdateException; import org.eclipse.jgit.api.errors.EmptyCommitException; import org.eclipse.jgit.api.errors.GitAPIException; @@ -36,6 +37,8 @@ import org.eclipse.jgit.dircache.DirCacheBuildIterator; import org.eclipse.jgit.dircache.DirCacheBuilder; import org.eclipse.jgit.dircache.DirCacheEntry; import org.eclipse.jgit.dircache.DirCacheIterator; +import org.eclipse.jgit.errors.IncorrectObjectTypeException; +import org.eclipse.jgit.errors.MissingObjectException; import org.eclipse.jgit.errors.UnmergedPathException; import org.eclipse.jgit.hooks.CommitMsgHook; import org.eclipse.jgit.hooks.Hooks; @@ -67,6 +70,8 @@ import org.eclipse.jgit.treewalk.FileTreeIterator; import org.eclipse.jgit.treewalk.TreeWalk; import org.eclipse.jgit.treewalk.TreeWalk.OperationType; import org.eclipse.jgit.util.ChangeIdUtil; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; /** * A class used to execute a {@code Commit} command. It has setters for all @@ -78,6 +83,9 @@ import org.eclipse.jgit.util.ChangeIdUtil; * >Git documentation about Commit</a> */ public class CommitCommand extends GitCommand<RevCommit> { + private static final Logger log = LoggerFactory + .getLogger(CommitCommand.class); + private PersonIdent author; private PersonIdent committer; @@ -173,8 +181,7 @@ public class CommitCommand extends GitCommand<RevCommit> { if (all && !repo.isBare()) { try (Git git = new Git(repo)) { - git.add() - .addFilepattern(".") //$NON-NLS-1$ + git.add().addFilepattern(".") //$NON-NLS-1$ .setUpdate(true).call(); } catch (NoFilepatternException e) { // should really not happen @@ -212,7 +219,7 @@ public class CommitCommand extends GitCommand<RevCommit> { .setCommitMessage(message).call(); } - // lock the index + RevCommit revCommit; DirCache index = repo.lockDirCache(); try (ObjectInserter odi = repo.newObjectInserter()) { if (!only.isEmpty()) @@ -226,100 +233,37 @@ public class CommitCommand extends GitCommand<RevCommit> { if (insertChangeId) insertChangeId(indexTreeId); - // Check for empty commits - if (headId != null && !allowEmpty.booleanValue()) { - RevCommit headCommit = rw.parseCommit(headId); - headCommit.getTree(); - if (indexTreeId.equals(headCommit.getTree())) { - throw new EmptyCommitException( - JGitText.get().emptyCommit); - } - } + checkIfEmpty(rw, headId, indexTreeId); // Create a Commit object, populate it and write it CommitBuilder commit = new CommitBuilder(); commit.setCommitter(committer); commit.setAuthor(author); commit.setMessage(message); - commit.setParentIds(parents); commit.setTreeId(indexTreeId); if (signCommit.booleanValue()) { - if (gpgSigner == null) { - throw new ServiceUnavailableException( - JGitText.get().signingServiceUnavailable); - } - if (gpgSigner instanceof GpgObjectSigner) { - ((GpgObjectSigner) gpgSigner).signObject(commit, - signingKey, committer, credentialsProvider, - gpgConfig); - } else { - if (gpgConfig.getKeyFormat() != GpgFormat.OPENPGP) { - throw new UnsupportedSigningFormatException(JGitText - .get().onlyOpenPgpSupportedForSigning); - } - gpgSigner.sign(commit, signingKey, committer, - credentialsProvider); - } + sign(commit); } ObjectId commitId = odi.insert(commit); odi.flush(); + revCommit = rw.parseCommit(commitId); - RevCommit revCommit = rw.parseCommit(commitId); - RefUpdate ru = repo.updateRef(Constants.HEAD); - ru.setNewObjectId(commitId); - if (!useDefaultReflogMessage) { - ru.setRefLogMessage(reflogComment, false); - } else { - String prefix = amend ? "commit (amend): " //$NON-NLS-1$ - : parents.isEmpty() ? "commit (initial): " //$NON-NLS-1$ - : "commit: "; //$NON-NLS-1$ - ru.setRefLogMessage(prefix + revCommit.getShortMessage(), - false); - } - if (headId != null) - ru.setExpectedOldObjectId(headId); - else - ru.setExpectedOldObjectId(ObjectId.zeroId()); - Result rc = ru.forceUpdate(); - switch (rc) { - case NEW: - case FORCED: - case FAST_FORWARD: { - setCallable(false); - if (state == RepositoryState.MERGING_RESOLVED - || isMergeDuringRebase(state)) { - // Commit was successful. Now delete the files - // used for merge commits - repo.writeMergeCommitMsg(null); - repo.writeMergeHeads(null); - } else if (state == RepositoryState.CHERRY_PICKING_RESOLVED) { - repo.writeMergeCommitMsg(null); - repo.writeCherryPickHead(null); - } else if (state == RepositoryState.REVERTING_RESOLVED) { - repo.writeMergeCommitMsg(null); - repo.writeRevertHead(null); - } - Hooks.postCommit(repo, - hookOutRedirect.get(PostCommitHook.NAME), - hookErrRedirect.get(PostCommitHook.NAME)).call(); - - return revCommit; - } - case REJECTED: - case LOCK_FAILURE: - throw new ConcurrentRefUpdateException( - JGitText.get().couldNotLockHEAD, ru.getRef(), rc); - default: - throw new JGitInternalException(MessageFormat.format( - JGitText.get().updatingRefFailed, Constants.HEAD, - commitId.toString(), rc)); - } + updateRef(state, headId, revCommit, commitId); } finally { index.unlock(); } + try { + Hooks.postCommit(repo, hookOutRedirect.get(PostCommitHook.NAME), + hookErrRedirect.get(PostCommitHook.NAME)).call(); + } catch (Exception e) { + log.error(MessageFormat.format( + JGitText.get().postCommitHookFailed, e.getMessage()), + e); + } + return revCommit; } catch (UnmergedPathException e) { throw new UnmergedPathsException(e); } catch (IOException e) { @@ -328,6 +272,89 @@ public class CommitCommand extends GitCommand<RevCommit> { } } + private void checkIfEmpty(RevWalk rw, ObjectId headId, ObjectId indexTreeId) + throws EmptyCommitException, MissingObjectException, + IncorrectObjectTypeException, IOException { + if (headId != null && !allowEmpty.booleanValue()) { + RevCommit headCommit = rw.parseCommit(headId); + headCommit.getTree(); + if (indexTreeId.equals(headCommit.getTree())) { + throw new EmptyCommitException(JGitText.get().emptyCommit); + } + } + } + + private void sign(CommitBuilder commit) throws ServiceUnavailableException, + CanceledException, UnsupportedSigningFormatException { + if (gpgSigner == null) { + throw new ServiceUnavailableException( + JGitText.get().signingServiceUnavailable); + } + if (gpgSigner instanceof GpgObjectSigner) { + ((GpgObjectSigner) gpgSigner).signObject(commit, + signingKey, committer, credentialsProvider, + gpgConfig); + } else { + if (gpgConfig.getKeyFormat() != GpgFormat.OPENPGP) { + throw new UnsupportedSigningFormatException(JGitText + .get().onlyOpenPgpSupportedForSigning); + } + gpgSigner.sign(commit, signingKey, committer, + credentialsProvider); + } + } + + private void updateRef(RepositoryState state, ObjectId headId, + RevCommit revCommit, ObjectId commitId) + throws ConcurrentRefUpdateException, IOException { + RefUpdate ru = repo.updateRef(Constants.HEAD); + ru.setNewObjectId(commitId); + if (!useDefaultReflogMessage) { + ru.setRefLogMessage(reflogComment, false); + } else { + String prefix = amend ? "commit (amend): " //$NON-NLS-1$ + : parents.isEmpty() ? "commit (initial): " //$NON-NLS-1$ + : "commit: "; //$NON-NLS-1$ + ru.setRefLogMessage(prefix + revCommit.getShortMessage(), + false); + } + if (headId != null) { + ru.setExpectedOldObjectId(headId); + } else { + ru.setExpectedOldObjectId(ObjectId.zeroId()); + } + Result rc = ru.forceUpdate(); + switch (rc) { + case NEW: + case FORCED: + case FAST_FORWARD: { + setCallable(false); + if (state == RepositoryState.MERGING_RESOLVED + || isMergeDuringRebase(state)) { + // Commit was successful. Now delete the files + // used for merge commits + repo.writeMergeCommitMsg(null); + repo.writeMergeHeads(null); + } else if (state == RepositoryState.CHERRY_PICKING_RESOLVED) { + repo.writeMergeCommitMsg(null); + repo.writeCherryPickHead(null); + } else if (state == RepositoryState.REVERTING_RESOLVED) { + repo.writeMergeCommitMsg(null); + repo.writeRevertHead(null); + } + break; + } + case REJECTED: + case LOCK_FAILURE: + throw new ConcurrentRefUpdateException( + JGitText.get().couldNotLockHEAD, ru.getRef(), rc); + default: + throw new JGitInternalException(MessageFormat.format( + JGitText.get().updatingRefFailed, Constants.HEAD, + commitId.toString(), rc)); + } + } + private void insertChangeId(ObjectId treeId) { ObjectId firstParentId = null; if (!parents.isEmpty()) diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/api/MergeCommand.java b/org.eclipse.jgit/src/org/eclipse/jgit/api/MergeCommand.java index d88f4ec561..c611f915ae 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/api/MergeCommand.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/api/MergeCommand.java @@ -1,7 +1,7 @@ /* * Copyright (C) 2010, Christian Halstrick <christian.halstrick@sap.com> - * Copyright (C) 2010-2014, Stefan Lay <stefan.lay@sap.com> - * Copyright (C) 2016, Laurent Delaigue <laurent.delaigue@obeo.fr> and others + * Copyright (C) 2010, 2014, Stefan Lay <stefan.lay@sap.com> + * Copyright (C) 2016, 2021 Laurent Delaigue <laurent.delaigue@obeo.fr> 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 @@ -45,6 +45,7 @@ import org.eclipse.jgit.lib.Ref.Storage; import org.eclipse.jgit.lib.RefUpdate; import org.eclipse.jgit.lib.RefUpdate.Result; import org.eclipse.jgit.lib.Repository; +import org.eclipse.jgit.merge.ContentMergeStrategy; import org.eclipse.jgit.merge.MergeConfig; import org.eclipse.jgit.merge.MergeMessageFormatter; import org.eclipse.jgit.merge.MergeStrategy; @@ -71,6 +72,8 @@ public class MergeCommand extends GitCommand<MergeResult> { private MergeStrategy mergeStrategy = MergeStrategy.RECURSIVE; + private ContentMergeStrategy contentStrategy; + private List<Ref> commits = new LinkedList<>(); private Boolean squash; @@ -320,6 +323,7 @@ public class MergeCommand extends GitCommand<MergeResult> { List<String> unmergedPaths = null; if (merger instanceof ResolveMerger) { ResolveMerger resolveMerger = (ResolveMerger) merger; + resolveMerger.setContentMergeStrategy(contentStrategy); resolveMerger.setCommitNames(new String[] { "BASE", "HEAD", ref.getName() }); //$NON-NLS-1$ //$NON-NLS-2$ resolveMerger.setWorkingTreeIterator(new FileTreeIterator(repo)); @@ -473,6 +477,22 @@ public class MergeCommand extends GitCommand<MergeResult> { } /** + * Sets the content merge strategy to use if the + * {@link #setStrategy(MergeStrategy) merge strategy} is "resolve" or + * "recursive". + * + * @param strategy + * the {@link ContentMergeStrategy} to be used + * @return {@code this} + * @since 5.12 + */ + public MergeCommand setContentMergeStrategy(ContentMergeStrategy strategy) { + checkCallable(); + this.contentStrategy = strategy; + return this; + } + + /** * Reference to a commit to be merged with the current head * * @param aCommit diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/api/PullCommand.java b/org.eclipse.jgit/src/org/eclipse/jgit/api/PullCommand.java index 449250890c..281ecfd011 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/api/PullCommand.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/api/PullCommand.java @@ -1,7 +1,7 @@ /* * Copyright (C) 2010, Christian Halstrick <christian.halstrick@sap.com> * Copyright (C) 2010, Mathias Kinzler <mathias.kinzler@sap.com> - * Copyright (C) 2016, Laurent Delaigue <laurent.delaigue@obeo.fr> and others + * Copyright (C) 2016, 2021 Laurent Delaigue <laurent.delaigue@obeo.fr> 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 @@ -43,6 +43,7 @@ import org.eclipse.jgit.lib.RefUpdate.Result; import org.eclipse.jgit.lib.Repository; import org.eclipse.jgit.lib.RepositoryState; import org.eclipse.jgit.lib.SubmoduleConfig.FetchRecurseSubmodulesMode; +import org.eclipse.jgit.merge.ContentMergeStrategy; import org.eclipse.jgit.merge.MergeStrategy; import org.eclipse.jgit.revwalk.RevCommit; import org.eclipse.jgit.revwalk.RevWalk; @@ -69,6 +70,8 @@ public class PullCommand extends TransportCommand<PullCommand, PullResult> { private MergeStrategy strategy = MergeStrategy.RECURSIVE; + private ContentMergeStrategy contentStrategy; + private TagOpt tagOption; private FastForwardMode fastForwardMode; @@ -275,8 +278,7 @@ public class PullCommand extends TransportCommand<PullCommand, PullResult> { JGitText.get().pullTaskName)); // we check the updates to see which of the updated branches - // corresponds - // to the remote branch name + // corresponds to the remote branch name AnyObjectId commitToMerge; if (isRemote) { Ref r = null; @@ -354,8 +356,11 @@ public class PullCommand extends TransportCommand<PullCommand, PullResult> { } RebaseCommand rebase = new RebaseCommand(repo); RebaseResult rebaseRes = rebase.setUpstream(commitToMerge) - .setUpstreamName(upstreamName).setProgressMonitor(monitor) - .setOperation(Operation.BEGIN).setStrategy(strategy) + .setProgressMonitor(monitor) + .setUpstreamName(upstreamName) + .setOperation(Operation.BEGIN) + .setStrategy(strategy) + .setContentMergeStrategy(contentStrategy) .setPreserveMerges( pullRebaseMode == BranchRebaseMode.PRESERVE) .call(); @@ -363,7 +368,9 @@ public class PullCommand extends TransportCommand<PullCommand, PullResult> { } else { MergeCommand merge = new MergeCommand(repo); MergeResult mergeRes = merge.include(upstreamName, commitToMerge) - .setStrategy(strategy).setProgressMonitor(monitor) + .setProgressMonitor(monitor) + .setStrategy(strategy) + .setContentMergeStrategy(contentStrategy) .setFastForward(getFastForwardMode()).call(); monitor.update(1); result = new PullResult(fetchRes, remote, mergeRes); @@ -442,6 +449,21 @@ public class PullCommand extends TransportCommand<PullCommand, PullResult> { } /** + * Sets the content merge strategy to use if the + * {@link #setStrategy(MergeStrategy) merge strategy} is "resolve" or + * "recursive". + * + * @param strategy + * the {@link ContentMergeStrategy} to be used + * @return {@code this} + * @since 5.12 + */ + public PullCommand setContentMergeStrategy(ContentMergeStrategy strategy) { + this.contentStrategy = strategy; + return this; + } + + /** * Set the specification of annotated tag behavior during fetch * * @param tagOpt diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/api/RebaseCommand.java b/org.eclipse.jgit/src/org/eclipse/jgit/api/RebaseCommand.java index 836175dcea..a26ffc2e66 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/api/RebaseCommand.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/api/RebaseCommand.java @@ -1,6 +1,6 @@ /* * Copyright (C) 2010, 2013 Mathias Kinzler <mathias.kinzler@sap.com> - * Copyright (C) 2016, Laurent Delaigue <laurent.delaigue@obeo.fr> and others + * Copyright (C) 2016, 2021 Laurent Delaigue <laurent.delaigue@obeo.fr> 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 @@ -65,6 +65,7 @@ import org.eclipse.jgit.lib.Ref; import org.eclipse.jgit.lib.RefUpdate; import org.eclipse.jgit.lib.RefUpdate.Result; import org.eclipse.jgit.lib.Repository; +import org.eclipse.jgit.merge.ContentMergeStrategy; import org.eclipse.jgit.merge.MergeStrategy; import org.eclipse.jgit.revwalk.RevCommit; import org.eclipse.jgit.revwalk.RevSort; @@ -212,6 +213,8 @@ public class RebaseCommand extends GitCommand<RebaseResult> { private MergeStrategy strategy = MergeStrategy.RECURSIVE; + private ContentMergeStrategy contentStrategy; + private boolean preserveMerges = false; /** @@ -501,8 +504,11 @@ public class RebaseCommand extends GitCommand<RebaseResult> { String ourCommitName = getOurCommitName(); try (Git git = new Git(repo)) { CherryPickResult cherryPickResult = git.cherryPick() - .include(commitToPick).setOurCommitName(ourCommitName) - .setReflogPrefix(REFLOG_PREFIX).setStrategy(strategy) + .include(commitToPick) + .setOurCommitName(ourCommitName) + .setReflogPrefix(REFLOG_PREFIX) + .setStrategy(strategy) + .setContentMergeStrategy(contentStrategy) .call(); switch (cherryPickResult.getStatus()) { case FAILED: @@ -556,7 +562,8 @@ public class RebaseCommand extends GitCommand<RebaseResult> { .include(commitToPick) .setOurCommitName(ourCommitName) .setReflogPrefix(REFLOG_PREFIX) - .setStrategy(strategy); + .setStrategy(strategy) + .setContentMergeStrategy(contentStrategy); if (isMerge) { pickCommand.setMainlineParentNumber(1); // We write a MERGE_HEAD and later commit explicitly @@ -592,6 +599,8 @@ public class RebaseCommand extends GitCommand<RebaseResult> { MergeCommand merge = git.merge() .setFastForward(MergeCommand.FastForwardMode.NO_FF) .setProgressMonitor(monitor) + .setStrategy(strategy) + .setContentMergeStrategy(contentStrategy) .setCommit(false); for (int i = 1; i < commitToPick.getParentCount(); i++) merge.include(newParents.get(i)); @@ -1137,7 +1146,7 @@ public class RebaseCommand extends GitCommand<RebaseResult> { } private List<RevCommit> calculatePickList(RevCommit headCommit) - throws GitAPIException, NoHeadException, IOException { + throws IOException { List<RevCommit> cherryPickList = new ArrayList<>(); try (RevWalk r = new RevWalk(repo)) { r.sort(RevSort.TOPO_KEEP_BRANCH_TOGETHER, true); @@ -1587,6 +1596,21 @@ public class RebaseCommand extends GitCommand<RebaseResult> { } /** + * Sets the content merge strategy to use if the + * {@link #setStrategy(MergeStrategy) merge strategy} is "resolve" or + * "recursive". + * + * @param strategy + * the {@link ContentMergeStrategy} to be used + * @return {@code this} + * @since 5.12 + */ + public RebaseCommand setContentMergeStrategy(ContentMergeStrategy strategy) { + this.contentStrategy = strategy; + return this; + } + + /** * Whether to preserve merges during rebase * * @param preserve diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/api/StashApplyCommand.java b/org.eclipse.jgit/src/org/eclipse/jgit/api/StashApplyCommand.java index 56b3992fcd..1004d3e50f 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/api/StashApplyCommand.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/api/StashApplyCommand.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2012, 2017 GitHub Inc. and others + * Copyright (C) 2012, 2021 GitHub Inc. and others * * This program and the accompanying materials are made available under the * terms of the Eclipse Distribution License v. 1.0 which is available at @@ -38,7 +38,9 @@ import org.eclipse.jgit.lib.ObjectId; import org.eclipse.jgit.lib.ObjectReader; import org.eclipse.jgit.lib.Repository; import org.eclipse.jgit.lib.RepositoryState; +import org.eclipse.jgit.merge.ContentMergeStrategy; import org.eclipse.jgit.merge.MergeStrategy; +import org.eclipse.jgit.merge.Merger; import org.eclipse.jgit.merge.ResolveMerger; import org.eclipse.jgit.revwalk.RevCommit; import org.eclipse.jgit.revwalk.RevTree; @@ -71,6 +73,8 @@ public class StashApplyCommand extends GitCommand<ObjectId> { private MergeStrategy strategy = MergeStrategy.RECURSIVE; + private ContentMergeStrategy contentStrategy; + /** * Create command to apply the changes of a stashed commit * @@ -166,16 +170,25 @@ public class StashApplyCommand extends GitCommand<ObjectId> { if (restoreUntracked && stashCommit.getParentCount() == 3) untrackedCommit = revWalk.parseCommit(stashCommit.getParent(2)); - ResolveMerger merger = (ResolveMerger) strategy.newMerger(repo); - merger.setCommitNames(new String[] { "stashed HEAD", "HEAD", //$NON-NLS-1$ //$NON-NLS-2$ - "stash" }); //$NON-NLS-1$ - merger.setBase(stashHeadCommit); - merger.setWorkingTreeIterator(new FileTreeIterator(repo)); - boolean mergeSucceeded = merger.merge(headCommit, stashCommit); - List<String> modifiedByMerge = merger.getModifiedFiles(); - if (!modifiedByMerge.isEmpty()) { - repo.fireEvent( - new WorkingTreeModifiedEvent(modifiedByMerge, null)); + Merger merger = strategy.newMerger(repo); + boolean mergeSucceeded; + if (merger instanceof ResolveMerger) { + ResolveMerger resolveMerger = (ResolveMerger) merger; + resolveMerger + .setCommitNames(new String[] { "stashed HEAD", "HEAD", //$NON-NLS-1$ //$NON-NLS-2$ + "stash" }); //$NON-NLS-1$ + resolveMerger.setBase(stashHeadCommit); + resolveMerger + .setWorkingTreeIterator(new FileTreeIterator(repo)); + resolveMerger.setContentMergeStrategy(contentStrategy); + mergeSucceeded = resolveMerger.merge(headCommit, stashCommit); + List<String> modifiedByMerge = resolveMerger.getModifiedFiles(); + if (!modifiedByMerge.isEmpty()) { + repo.fireEvent(new WorkingTreeModifiedEvent(modifiedByMerge, + null)); + } + } else { + mergeSucceeded = merger.merge(headCommit, stashCommit); } if (mergeSucceeded) { DirCache dc = repo.lockDirCache(); @@ -184,11 +197,14 @@ public class StashApplyCommand extends GitCommand<ObjectId> { dco.setFailOnConflict(true); dco.checkout(); // Ignoring failed deletes.... if (restoreIndex) { - ResolveMerger ixMerger = (ResolveMerger) strategy - .newMerger(repo, true); - ixMerger.setCommitNames(new String[] { "stashed HEAD", //$NON-NLS-1$ - "HEAD", "stashed index" }); //$NON-NLS-1$//$NON-NLS-2$ - ixMerger.setBase(stashHeadCommit); + Merger ixMerger = strategy.newMerger(repo, true); + if (ixMerger instanceof ResolveMerger) { + ResolveMerger resolveMerger = (ResolveMerger) ixMerger; + resolveMerger.setCommitNames(new String[] { "stashed HEAD", //$NON-NLS-1$ + "HEAD", "stashed index" }); //$NON-NLS-1$//$NON-NLS-2$ + resolveMerger.setBase(stashHeadCommit); + resolveMerger.setContentMergeStrategy(contentStrategy); + } boolean ok = ixMerger.merge(headCommit, stashIndexCommit); if (ok) { resetIndex(revWalk @@ -200,16 +216,20 @@ public class StashApplyCommand extends GitCommand<ObjectId> { } if (untrackedCommit != null) { - ResolveMerger untrackedMerger = (ResolveMerger) strategy - .newMerger(repo, true); - untrackedMerger.setCommitNames(new String[] { - "null", "HEAD", "untracked files" }); //$NON-NLS-1$//$NON-NLS-2$//$NON-NLS-3$ - // There is no common base for HEAD & untracked files - // because the commit for untracked files has no parent. If - // we use stashHeadCommit as common base (as in the other - // merges) we potentially report conflicts for files - // which are not even member of untracked files commit - untrackedMerger.setBase(null); + Merger untrackedMerger = strategy.newMerger(repo, true); + if (untrackedMerger instanceof ResolveMerger) { + ResolveMerger resolveMerger = (ResolveMerger) untrackedMerger; + resolveMerger.setCommitNames(new String[] { "null", "HEAD", //$NON-NLS-1$//$NON-NLS-2$ + "untracked files" }); //$NON-NLS-1$ + // There is no common base for HEAD & untracked files + // because the commit for untracked files has no parent. + // If we use stashHeadCommit as common base (as in the + // other merges) we potentially report conflicts for + // files which are not even member of untracked files + // commit. + resolveMerger.setBase(null); + resolveMerger.setContentMergeStrategy(contentStrategy); + } boolean ok = untrackedMerger.merge(headCommit, untrackedCommit); if (ok) { @@ -279,6 +299,23 @@ public class StashApplyCommand extends GitCommand<ObjectId> { } /** + * Sets the content merge strategy to use if the + * {@link #setStrategy(MergeStrategy) merge strategy} is "resolve" or + * "recursive". + * + * @param strategy + * the {@link ContentMergeStrategy} to be used + * @return {@code this} + * @since 5.12 + */ + public StashApplyCommand setContentMergeStrategy( + ContentMergeStrategy strategy) { + checkCallable(); + this.contentStrategy = strategy; + return this; + } + + /** * Whether the command should restore untracked files * * @param applyUntracked diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/dircache/DirCacheCheckout.java b/org.eclipse.jgit/src/org/eclipse/jgit/dircache/DirCacheCheckout.java index 671475ed47..c904a782db 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/dircache/DirCacheCheckout.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/dircache/DirCacheCheckout.java @@ -1610,11 +1610,9 @@ public class DirCacheCheckout { } if (rc != 0) { throw new IOException(new FilterFailedException(rc, - checkoutMetadata.smudgeFilterCommand, - path, + checkoutMetadata.smudgeFilterCommand, path, result.getStdout().toByteArray(MAX_EXCEPTION_TEXT_SIZE), - RawParseUtils.decode(result.getStderr() - .toByteArray(MAX_EXCEPTION_TEXT_SIZE)))); + result.getStderr().toString(MAX_EXCEPTION_TEXT_SIZE))); } } diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/internal/JGitText.java b/org.eclipse.jgit/src/org/eclipse/jgit/internal/JGitText.java index 3eef49b1ca..ab9fc5c9bb 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/internal/JGitText.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/internal/JGitText.java @@ -444,10 +444,13 @@ public class JGitText extends TranslationBundle { /***/ public String localRefIsMissingObjects; /***/ public String localRepository; /***/ public String lockCountMustBeGreaterOrEqual1; + /***/ public String lockAlreadyHeld; /***/ public String lockError; /***/ public String lockFailedRetry; /***/ public String lockOnNotClosed; /***/ public String lockOnNotHeld; + /***/ public String lockStreamClosed; + /***/ public String lockStreamMultiple; /***/ public String logInconsistentFiletimeDiff; /***/ public String logLargerFiletimeDiff; /***/ public String logSmallerFiletime; @@ -558,6 +561,7 @@ public class JGitText extends TranslationBundle { /***/ public String peerDidNotSupplyACompleteObjectGraph; /***/ public String personIdentEmailNonNull; /***/ public String personIdentNameNonNull; + /***/ public String postCommitHookFailed; /***/ public String prefixRemote; /***/ public String problemWithResolvingPushRefSpecsLocally; /***/ public String progressMonUploading; diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/FileReftableStack.java b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/FileReftableStack.java index b5e3927bcc..f02c8613a0 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/FileReftableStack.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/FileReftableStack.java @@ -131,33 +131,6 @@ public class FileReftableStack implements AutoCloseable { return stats; } - /** Thrown if the update indices in the stack are not monotonic */ - public static class ReftableNumbersNotIncreasingException - extends RuntimeException { - private static final long serialVersionUID = 1L; - - String name; - - long lastMax; - - long min; - - ReftableNumbersNotIncreasingException(String name, long lastMax, - long min) { - this.name = name; - this.lastMax = lastMax; - this.min = min; - } - - @SuppressWarnings({ "nls", "boxing" }) - @Override - public String toString() { - return String.format( - "ReftableNumbersNotIncreasingException %s: min %d, lastMax %d", - name, min, lastMax); - } - } - /** * Reloads the stack, potentially reusing opened reftableReaders. * @@ -176,7 +149,6 @@ public class FileReftableStack implements AutoCloseable { List<ReftableReader> newTables = new ArrayList<>(); List<StackEntry> newStack = new ArrayList<>(stack.size() + 1); try { - ReftableReader last = null; for (String name : names) { StackEntry entry = new StackEntry(); entry.name = name; @@ -194,15 +166,6 @@ public class FileReftableStack implements AutoCloseable { newTables.add(t); } - if (last != null) { - // TODO: move this to MergedReftable - if (last.maxUpdateIndex() >= t.minUpdateIndex()) { - throw new ReftableNumbersNotIncreasingException(name, - last.maxUpdateIndex(), t.minUpdateIndex()); - } - } - last = t; - entry.reftableReader = t; newStack.add(entry); } diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/LockFile.java b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/LockFile.java index 2e0a6da3a4..78262e9773 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/LockFile.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/LockFile.java @@ -1,6 +1,6 @@ /* * Copyright (C) 2007, Robin Rosenberg <robin.rosenberg@dewire.com> - * Copyright (C) 2006-2008, Shawn O. Pearce <spearce@spearce.org> and others + * Copyright (C) 2006-2021, Shawn O. Pearce <spearce@spearce.org> and others * * This program and the accompanying materials are made available under the * terms of the Eclipse Distribution License v. 1.0 which is available at @@ -96,11 +96,15 @@ public class LockFile { private boolean haveLck; - FileOutputStream os; + private FileOutputStream os; private boolean needSnapshot; - boolean fsync; + private boolean fsync; + + private boolean isAppend; + + private boolean written; private FileSnapshot commitSnapshot; @@ -127,6 +131,10 @@ public class LockFile { * does not hold the lock. */ public boolean lock() throws IOException { + if (haveLck) { + throw new IllegalStateException( + MessageFormat.format(JGitText.get().lockAlreadyHeld, ref)); + } FileUtils.mkdirs(lck.getParentFile(), true); try { token = FS.DETECTED.createNewFileAtomic(lck); @@ -134,18 +142,15 @@ public class LockFile { LOG.error(JGitText.get().failedCreateLockFile, lck, e); throw e; } - if (token.isCreated()) { + boolean obtainedLock = token.isCreated(); + if (obtainedLock) { haveLck = true; - try { - os = new FileOutputStream(lck); - } catch (IOException ioe) { - unlock(); - throw ioe; - } + isAppend = false; + written = false; } else { closeToken(); } - return haveLck; + return obtainedLock; } /** @@ -158,12 +163,24 @@ public class LockFile { * does not hold the lock. */ public boolean lockForAppend() throws IOException { - if (!lock()) + if (!lock()) { return false; + } copyCurrentContent(); + isAppend = true; + written = false; return true; } + // For tests only + boolean isLocked() { + return haveLck; + } + + private FileOutputStream getStream() throws IOException { + return new FileOutputStream(lck, isAppend); + } + /** * Copy the current file content into the temporary file. * <p> @@ -185,32 +202,31 @@ public class LockFile { */ public void copyCurrentContent() throws IOException { requireLock(); - try { + try (FileOutputStream out = getStream()) { try (FileInputStream fis = new FileInputStream(ref)) { if (fsync) { FileChannel in = fis.getChannel(); long pos = 0; long cnt = in.size(); while (0 < cnt) { - long r = os.getChannel().transferFrom(in, pos, cnt); + long r = out.getChannel().transferFrom(in, pos, cnt); pos += r; cnt -= r; } } else { final byte[] buf = new byte[2048]; int r; - while ((r = fis.read(buf)) >= 0) - os.write(buf, 0, r); + while ((r = fis.read(buf)) >= 0) { + out.write(buf, 0, r); + } } + } catch (FileNotFoundException fnfe) { + if (ref.exists()) { + throw fnfe; + } + // Don't worry about a file that doesn't exist yet, it + // conceptually has no current content to copy. } - } catch (FileNotFoundException fnfe) { - if (ref.exists()) { - unlock(); - throw fnfe; - } - // Don't worry about a file that doesn't exist yet, it - // conceptually has no current content to copy. - // } catch (IOException | RuntimeException | Error ioe) { unlock(); throw ioe; @@ -253,18 +269,22 @@ public class LockFile { */ public void write(byte[] content) throws IOException { requireLock(); - try { + try (FileOutputStream out = getStream()) { + if (written) { + throw new IOException(MessageFormat + .format(JGitText.get().lockStreamClosed, ref)); + } if (fsync) { - FileChannel fc = os.getChannel(); + FileChannel fc = out.getChannel(); ByteBuffer buf = ByteBuffer.wrap(content); - while (0 < buf.remaining()) + while (0 < buf.remaining()) { fc.write(buf); + } fc.force(true); } else { - os.write(content); + out.write(content); } - os.close(); - os = null; + written = true; } catch (IOException | RuntimeException | Error ioe) { unlock(); throw ioe; @@ -283,36 +303,67 @@ public class LockFile { public OutputStream getOutputStream() { requireLock(); - final OutputStream out; - if (fsync) - out = Channels.newOutputStream(os.getChannel()); - else - out = os; + if (written || os != null) { + throw new IllegalStateException(MessageFormat + .format(JGitText.get().lockStreamMultiple, ref)); + } return new OutputStream() { + + private OutputStream out; + + private boolean closed; + + private OutputStream get() throws IOException { + if (written) { + throw new IOException(MessageFormat + .format(JGitText.get().lockStreamMultiple, ref)); + } + if (out == null) { + os = getStream(); + if (fsync) { + out = Channels.newOutputStream(os.getChannel()); + } else { + out = os; + } + } + return out; + } + @Override - public void write(byte[] b, int o, int n) - throws IOException { - out.write(b, o, n); + public void write(byte[] b, int o, int n) throws IOException { + get().write(b, o, n); } @Override public void write(byte[] b) throws IOException { - out.write(b); + get().write(b); } @Override public void write(int b) throws IOException { - out.write(b); + get().write(b); } @Override public void close() throws IOException { + if (closed) { + return; + } + closed = true; try { - if (fsync) - os.getChannel().force(true); - out.close(); - os = null; + if (written) { + throw new IOException(MessageFormat + .format(JGitText.get().lockStreamClosed, ref)); + } + if (out != null) { + if (fsync) { + os.getChannel().force(true); + } + out.close(); + os = null; + } + written = true; } catch (IOException | RuntimeException | Error ioe) { unlock(); throw ioe; @@ -322,7 +373,7 @@ public class LockFile { } void requireLock() { - if (os == null) { + if (!haveLck) { unlock(); throw new IllegalStateException(MessageFormat.format(JGitText.get().lockOnNotHeld, ref)); } @@ -411,6 +462,8 @@ public class LockFile { try { FileUtils.rename(lck, ref, StandardCopyOption.ATOMIC_MOVE); haveLck = false; + isAppend = false; + written = false; closeToken(); return true; } catch (IOException e) { @@ -497,6 +550,8 @@ public class LockFile { closeToken(); } } + isAppend = false; + written = false; } /** {@inheritDoc} */ diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/internal/transport/ssh/OpenSshConfigFile.java b/org.eclipse.jgit/src/org/eclipse/jgit/internal/transport/ssh/OpenSshConfigFile.java index 98c63cdcdd..de6a346cb2 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/internal/transport/ssh/OpenSshConfigFile.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/internal/transport/ssh/OpenSshConfigFile.java @@ -23,7 +23,6 @@ import java.util.Collections; import java.util.HashMap; import java.util.LinkedHashMap; import java.util.List; -import java.util.Locale; import java.util.Map; import java.util.Set; import java.util.TreeMap; @@ -224,8 +223,17 @@ public class OpenSshConfigFile implements SshConfigStore { entries.put(DEFAULT_NAME, defaults); while ((line = reader.readLine()) != null) { + // OpenSsh ignores trailing comments on a line. Anything after the + // first # on a line is trimmed away (yes, even if the hash is + // inside quotes). + // + // See https://github.com/openssh/openssh-portable/commit/2bcbf679 + int i = line.indexOf('#'); + if (i >= 0) { + line = line.substring(0, i); + } line = line.trim(); - if (line.isEmpty() || line.startsWith("#")) { //$NON-NLS-1$ + if (line.isEmpty()) { continue; } String[] parts = line.split("[ \t]*[= \t]", 2); //$NON-NLS-1$ @@ -484,12 +492,30 @@ public class OpenSshConfigFile implements SshConfigStore { LIST_KEYS.add(SshConstants.USER_KNOWN_HOSTS_FILE); } + /** + * OpenSSH has renamed some config keys. This maps old names to new + * names. + */ + private static final Map<String, String> ALIASES = new TreeMap<>( + String.CASE_INSENSITIVE_ORDER); + + static { + // See https://github.com/openssh/openssh-portable/commit/ee9c0da80 + ALIASES.put("PubkeyAcceptedKeyTypes", //$NON-NLS-1$ + SshConstants.PUBKEY_ACCEPTED_ALGORITHMS); + } + private Map<String, String> options; private Map<String, List<String>> multiOptions; private Map<String, List<String>> listOptions; + private static String toKey(String key) { + String k = ALIASES.get(key); + return k != null ? k : key; + } + /** * Retrieves the value of a single-valued key, or the first if the key * has multiple values. Keys are case-insensitive, so @@ -501,15 +527,15 @@ public class OpenSshConfigFile implements SshConfigStore { */ @Override public String getValue(String key) { - String result = options != null ? options.get(key) : null; + String k = toKey(key); + String result = options != null ? options.get(k) : null; if (result == null) { // Let's be lenient and return at least the first value from // a list-valued or multi-valued key. - List<String> values = listOptions != null ? listOptions.get(key) + List<String> values = listOptions != null ? listOptions.get(k) : null; if (values == null) { - values = multiOptions != null ? multiOptions.get(key) - : null; + values = multiOptions != null ? multiOptions.get(k) : null; } if (values != null && !values.isEmpty()) { result = values.get(0); @@ -529,10 +555,11 @@ public class OpenSshConfigFile implements SshConfigStore { */ @Override public List<String> getValues(String key) { - List<String> values = listOptions != null ? listOptions.get(key) + String k = toKey(key); + List<String> values = listOptions != null ? listOptions.get(k) : null; if (values == null) { - values = multiOptions != null ? multiOptions.get(key) : null; + values = multiOptions != null ? multiOptions.get(k) : null; } if (values == null || values.isEmpty()) { return new ArrayList<>(); @@ -551,34 +578,35 @@ public class OpenSshConfigFile implements SshConfigStore { * to set or add */ public void setValue(String key, String value) { + String k = toKey(key); if (value == null) { if (multiOptions != null) { - multiOptions.remove(key); + multiOptions.remove(k); } if (listOptions != null) { - listOptions.remove(key); + listOptions.remove(k); } if (options != null) { - options.remove(key); + options.remove(k); } return; } - if (MULTI_KEYS.contains(key)) { + if (MULTI_KEYS.contains(k)) { if (multiOptions == null) { multiOptions = new TreeMap<>(String.CASE_INSENSITIVE_ORDER); } - List<String> values = multiOptions.get(key); + List<String> values = multiOptions.get(k); if (values == null) { values = new ArrayList<>(4); - multiOptions.put(key, values); + multiOptions.put(k, values); } values.add(value); } else { if (options == null) { options = new TreeMap<>(String.CASE_INSENSITIVE_ORDER); } - if (!options.containsKey(key)) { - options.put(key, value); + if (!options.containsKey(k)) { + options.put(k, value); } } } @@ -595,20 +623,21 @@ public class OpenSshConfigFile implements SshConfigStore { if (values.isEmpty()) { return; } + String k = toKey(key); // Check multi-valued keys first; because of the replacement // strategy, they must take precedence over list-valued keys // which always follow the "first occurrence wins" strategy. // // Note that SendEnv is a multi-valued list-valued key. (It's // rather immaterial for JGit, though.) - if (MULTI_KEYS.contains(key)) { + if (MULTI_KEYS.contains(k)) { if (multiOptions == null) { multiOptions = new TreeMap<>(String.CASE_INSENSITIVE_ORDER); } - List<String> items = multiOptions.get(key); + List<String> items = multiOptions.get(k); if (items == null) { items = new ArrayList<>(values); - multiOptions.put(key, items); + multiOptions.put(k, items); } else { items.addAll(values); } @@ -616,8 +645,8 @@ public class OpenSshConfigFile implements SshConfigStore { if (listOptions == null) { listOptions = new TreeMap<>(String.CASE_INSENSITIVE_ORDER); } - if (!listOptions.containsKey(key)) { - listOptions.put(key, values); + if (!listOptions.containsKey(k)) { + listOptions.put(k, values); } } } @@ -630,7 +659,7 @@ public class OpenSshConfigFile implements SshConfigStore { * @return {@code true} if the key is a list-valued key. */ public static boolean isListKey(String key) { - return LIST_KEYS.contains(key.toUpperCase(Locale.ROOT)); + return LIST_KEYS.contains(toKey(key)); } void merge(HostEntry entry) { @@ -679,10 +708,10 @@ public class OpenSshConfigFile implements SshConfigStore { } private List<String> substitute(List<String> values, String allowed, - Replacer r) { + Replacer r, boolean withEnv) { List<String> result = new ArrayList<>(values.size()); for (String value : values) { - result.add(r.substitute(value, allowed)); + result.add(r.substitute(value, allowed, withEnv)); } return result; } @@ -714,7 +743,7 @@ public class OpenSshConfigFile implements SshConfigStore { if (hostName == null || hostName.isEmpty()) { options.put(SshConstants.HOST_NAME, originalHostName); } else { - hostName = r.substitute(hostName, "h"); //$NON-NLS-1$ + hostName = r.substitute(hostName, "h", false); //$NON-NLS-1$ options.put(SshConstants.HOST_NAME, hostName); r.update('h', hostName); } @@ -723,13 +752,13 @@ public class OpenSshConfigFile implements SshConfigStore { List<String> values = multiOptions .get(SshConstants.IDENTITY_FILE); if (values != null) { - values = substitute(values, "dhlru", r); //$NON-NLS-1$ + values = substitute(values, "dhlru", r, true); //$NON-NLS-1$ values = replaceTilde(values, home); multiOptions.put(SshConstants.IDENTITY_FILE, values); } values = multiOptions.get(SshConstants.CERTIFICATE_FILE); if (values != null) { - values = substitute(values, "dhlru", r); //$NON-NLS-1$ + values = substitute(values, "dhlru", r, true); //$NON-NLS-1$ values = replaceTilde(values, home); multiOptions.put(SshConstants.CERTIFICATE_FILE, values); } @@ -746,29 +775,29 @@ public class OpenSshConfigFile implements SshConfigStore { // HOSTNAME already done above String value = options.get(SshConstants.IDENTITY_AGENT); if (value != null) { - value = r.substitute(value, "dhlru"); //$NON-NLS-1$ + value = r.substitute(value, "dhlru", true); //$NON-NLS-1$ value = toFile(value, home).getPath(); options.put(SshConstants.IDENTITY_AGENT, value); } value = options.get(SshConstants.CONTROL_PATH); if (value != null) { - value = r.substitute(value, "ChLlnpru"); //$NON-NLS-1$ + value = r.substitute(value, "ChLlnpru", true); //$NON-NLS-1$ value = toFile(value, home).getPath(); options.put(SshConstants.CONTROL_PATH, value); } value = options.get(SshConstants.LOCAL_COMMAND); if (value != null) { - value = r.substitute(value, "CdhlnprTu"); //$NON-NLS-1$ + value = r.substitute(value, "CdhlnprTu", false); //$NON-NLS-1$ options.put(SshConstants.LOCAL_COMMAND, value); } value = options.get(SshConstants.REMOTE_COMMAND); if (value != null) { - value = r.substitute(value, "Cdhlnpru"); //$NON-NLS-1$ + value = r.substitute(value, "Cdhlnpru", false); //$NON-NLS-1$ options.put(SshConstants.REMOTE_COMMAND, value); } value = options.get(SshConstants.PROXY_COMMAND); if (value != null) { - value = r.substitute(value, "hpr"); //$NON-NLS-1$ + value = r.substitute(value, "hpr", false); //$NON-NLS-1$ options.put(SshConstants.PROXY_COMMAND, value); } } @@ -842,7 +871,7 @@ public class OpenSshConfigFile implements SshConfigStore { replacements.put(Character.valueOf('r'), user == null ? "" : user); //$NON-NLS-1$ replacements.put(Character.valueOf('u'), localUserName); replacements.put(Character.valueOf('C'), - substitute("%l%h%p%r", "hlpr")); //$NON-NLS-1$ //$NON-NLS-2$ + substitute("%l%h%p%r", "hlpr", false)); //$NON-NLS-1$ //$NON-NLS-2$ replacements.put(Character.valueOf('T'), "NONE"); //$NON-NLS-1$ } @@ -850,36 +879,63 @@ public class OpenSshConfigFile implements SshConfigStore { replacements.put(Character.valueOf(key), value); if ("lhpr".indexOf(key) >= 0) { //$NON-NLS-1$ replacements.put(Character.valueOf('C'), - substitute("%l%h%p%r", "hlpr")); //$NON-NLS-1$ //$NON-NLS-2$ + substitute("%l%h%p%r", "hlpr", false)); //$NON-NLS-1$ //$NON-NLS-2$ } } - public String substitute(String input, String allowed) { + public String substitute(String input, String allowed, + boolean withEnv) { if (input == null || input.length() <= 1 - || input.indexOf('%') < 0) { + || input.indexOf('%') < 0 + && (!withEnv || input.indexOf("${") < 0)) { //$NON-NLS-1$ return input; } StringBuilder builder = new StringBuilder(); int start = 0; int length = input.length(); while (start < length) { - int percent = input.indexOf('%', start); - if (percent < 0 || percent + 1 >= length) { - builder.append(input.substring(start)); + char ch = input.charAt(start); + switch (ch) { + case '%': + if (start + 1 >= length) { + break; + } + String replacement = null; + ch = input.charAt(start + 1); + if (ch == '%' || allowed.indexOf(ch) >= 0) { + replacement = replacements.get(Character.valueOf(ch)); + } + if (replacement == null) { + builder.append('%').append(ch); + } else { + builder.append(replacement); + } + start += 2; + continue; + case '$': + if (!withEnv || start + 2 >= length) { + break; + } + ch = input.charAt(start + 1); + if (ch == '{') { + int close = input.indexOf('}', start + 2); + if (close > start + 2) { + String variable = SystemReader.getInstance() + .getenv(input.substring(start + 2, close)); + if (!StringUtils.isEmptyOrNull(variable)) { + builder.append(variable); + } + start = close + 1; + continue; + } + } + ch = '$'; + break; + default: break; } - String replacement = null; - char ch = input.charAt(percent + 1); - if (ch == '%' || allowed.indexOf(ch) >= 0) { - replacement = replacements.get(Character.valueOf(ch)); - } - if (replacement == null) { - builder.append(input.substring(start, percent + 2)); - } else { - builder.append(input.substring(start, percent)) - .append(replacement); - } - start = percent + 2; + builder.append(ch); + start++; } return builder.toString(); } diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/merge/ContentMergeStrategy.java b/org.eclipse.jgit/src/org/eclipse/jgit/merge/ContentMergeStrategy.java new file mode 100644 index 0000000000..6d568643d5 --- /dev/null +++ b/org.eclipse.jgit/src/org/eclipse/jgit/merge/ContentMergeStrategy.java @@ -0,0 +1,27 @@ +/* + * Copyright (C) 2021, Thomas Wolf <thomas.wolf@paranor.ch> and others + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Distribution License v. 1.0 which is available at + * https://www.eclipse.org/org/documents/edl-v10.php. + * + * SPDX-License-Identifier: BSD-3-Clause + */ +package org.eclipse.jgit.merge; + +/** + * How to handle content conflicts. + * + * @since 5.12 + */ +public enum ContentMergeStrategy { + + /** Produce a conflict. */ + CONFLICT, + + /** Resolve the conflict hunk using the ours version. */ + OURS, + + /** Resolve the conflict hunk using the theirs version. */ + THEIRS +}
\ No newline at end of file diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/merge/MergeAlgorithm.java b/org.eclipse.jgit/src/org/eclipse/jgit/merge/MergeAlgorithm.java index 27141c12c4..80607351ae 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/merge/MergeAlgorithm.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/merge/MergeAlgorithm.java @@ -14,6 +14,7 @@ import java.util.ArrayList; import java.util.Iterator; import java.util.List; +import org.eclipse.jgit.annotations.NonNull; import org.eclipse.jgit.diff.DiffAlgorithm; import org.eclipse.jgit.diff.Edit; import org.eclipse.jgit.diff.EditList; @@ -28,8 +29,12 @@ import org.eclipse.jgit.merge.MergeChunk.ConflictState; * diff algorithm. */ public final class MergeAlgorithm { + private final DiffAlgorithm diffAlg; + @NonNull + private ContentMergeStrategy strategy = ContentMergeStrategy.CONFLICT; + /** * Creates a new MergeAlgorithm which uses * {@link org.eclipse.jgit.diff.HistogramDiff} as diff algorithm @@ -48,6 +53,30 @@ public final class MergeAlgorithm { this.diffAlg = diff; } + /** + * Retrieves the {@link ContentMergeStrategy}. + * + * @return the {@link ContentMergeStrategy} in effect + * @since 5.12 + */ + @NonNull + public ContentMergeStrategy getContentMergeStrategy() { + return strategy; + } + + /** + * Sets the {@link ContentMergeStrategy}. + * + * @param strategy + * {@link ContentMergeStrategy} to set; if {@code null}, set + * {@link ContentMergeStrategy#CONFLICT} + * @since 5.12 + */ + public void setContentMergeStrategy(ContentMergeStrategy strategy) { + this.strategy = strategy == null ? ContentMergeStrategy.CONFLICT + : strategy; + } + // An special edit which acts as a sentinel value by marking the end the // list of edits private static final Edit END_EDIT = new Edit(Integer.MAX_VALUE, @@ -79,29 +108,54 @@ public final class MergeAlgorithm { if (theirs.size() != 0) { EditList theirsEdits = diffAlg.diff(cmp, base, theirs); if (!theirsEdits.isEmpty()) { - // we deleted, they modified -> Let their complete content - // conflict with empty text - result.add(1, 0, 0, ConflictState.FIRST_CONFLICTING_RANGE); - result.add(2, 0, theirs.size(), - ConflictState.NEXT_CONFLICTING_RANGE); - } else + // we deleted, they modified + switch (strategy) { + case OURS: + result.add(1, 0, 0, ConflictState.NO_CONFLICT); + break; + case THEIRS: + result.add(2, 0, theirs.size(), + ConflictState.NO_CONFLICT); + break; + default: + // Let their complete content conflict with empty text + result.add(1, 0, 0, + ConflictState.FIRST_CONFLICTING_RANGE); + result.add(2, 0, theirs.size(), + ConflictState.NEXT_CONFLICTING_RANGE); + break; + } + } else { // we deleted, they didn't modify -> Let our deletion win result.add(1, 0, 0, ConflictState.NO_CONFLICT); - } else + } + } else { // we and they deleted -> return a single chunk of nothing result.add(1, 0, 0, ConflictState.NO_CONFLICT); + } return result; } else if (theirs.size() == 0) { EditList oursEdits = diffAlg.diff(cmp, base, ours); if (!oursEdits.isEmpty()) { - // we modified, they deleted -> Let our complete content - // conflict with empty text - result.add(1, 0, ours.size(), - ConflictState.FIRST_CONFLICTING_RANGE); - result.add(2, 0, 0, ConflictState.NEXT_CONFLICTING_RANGE); - } else + // we modified, they deleted + switch (strategy) { + case OURS: + result.add(1, 0, ours.size(), ConflictState.NO_CONFLICT); + break; + case THEIRS: + result.add(2, 0, 0, ConflictState.NO_CONFLICT); + break; + default: + // Let our complete content conflict with empty text + result.add(1, 0, ours.size(), + ConflictState.FIRST_CONFLICTING_RANGE); + result.add(2, 0, 0, ConflictState.NEXT_CONFLICTING_RANGE); + break; + } + } else { // they deleted, we didn't modify -> Let their deletion win result.add(2, 0, 0, ConflictState.NO_CONFLICT); + } return result; } @@ -249,12 +303,26 @@ public final class MergeAlgorithm { // Add the conflict (Only if there is a conflict left to report) if (minBSize > 0 || BSizeDelta != 0) { - result.add(1, oursBeginB + commonPrefix, oursEndB - - commonSuffix, - ConflictState.FIRST_CONFLICTING_RANGE); - result.add(2, theirsBeginB + commonPrefix, theirsEndB - - commonSuffix, - ConflictState.NEXT_CONFLICTING_RANGE); + switch (strategy) { + case OURS: + result.add(1, oursBeginB + commonPrefix, + oursEndB - commonSuffix, + ConflictState.NO_CONFLICT); + break; + case THEIRS: + result.add(2, theirsBeginB + commonPrefix, + theirsEndB - commonSuffix, + ConflictState.NO_CONFLICT); + break; + default: + result.add(1, oursBeginB + commonPrefix, + oursEndB - commonSuffix, + ConflictState.FIRST_CONFLICTING_RANGE); + result.add(2, theirsBeginB + commonPrefix, + theirsEndB - commonSuffix, + ConflictState.NEXT_CONFLICTING_RANGE); + break; + } } // Add the common lines at end of conflict diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/merge/ResolveMerger.java b/org.eclipse.jgit/src/org/eclipse/jgit/merge/ResolveMerger.java index 4bfb38d286..7767662867 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/merge/ResolveMerger.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/merge/ResolveMerger.java @@ -37,6 +37,7 @@ import java.util.LinkedList; import java.util.List; import java.util.Map; +import org.eclipse.jgit.annotations.NonNull; import org.eclipse.jgit.attributes.Attributes; import org.eclipse.jgit.diff.DiffAlgorithm; import org.eclipse.jgit.diff.DiffAlgorithm.SupportedAlgorithm; @@ -268,6 +269,13 @@ public class ResolveMerger extends ThreeWayMerger { private int inCoreLimit; /** + * The {@link ContentMergeStrategy} to use for "resolve" and "recursive" + * merges. + */ + @NonNull + private ContentMergeStrategy contentStrategy = ContentMergeStrategy.CONFLICT; + + /** * Keeps {@link CheckoutMetadata} for {@link #checkout()} and * {@link #cleanUp()}. */ @@ -344,6 +352,29 @@ public class ResolveMerger extends ThreeWayMerger { dircache = DirCache.newInCore(); } + /** + * Retrieves the content merge strategy for content conflicts. + * + * @return the {@link ContentMergeStrategy} in effect + * @since 5.12 + */ + @NonNull + public ContentMergeStrategy getContentMergeStrategy() { + return contentStrategy; + } + + /** + * Sets the content merge strategy for content conflicts. + * + * @param strategy + * {@link ContentMergeStrategy} to use + * @since 5.12 + */ + public void setContentMergeStrategy(ContentMergeStrategy strategy) { + contentStrategy = strategy == null ? ContentMergeStrategy.CONFLICT + : strategy; + } + /** {@inheritDoc} */ @Override protected boolean mergeImpl() throws IOException { @@ -644,15 +675,19 @@ public class ResolveMerger extends ThreeWayMerger { } return true; } - // FileModes are not mergeable. We found a conflict on modes. - // For conflicting entries we don't know lastModified and - // length. - add(tw.getRawPath(), base, DirCacheEntry.STAGE_1, EPOCH, 0); - add(tw.getRawPath(), ours, DirCacheEntry.STAGE_2, EPOCH, 0); - add(tw.getRawPath(), theirs, DirCacheEntry.STAGE_3, EPOCH, 0); - unmergedPaths.add(tw.getPathString()); - mergeResults.put(tw.getPathString(), - new MergeResult<>(Collections.<RawText> emptyList())); + if (!ignoreConflicts) { + // FileModes are not mergeable. We found a conflict on modes. + // For conflicting entries we don't know lastModified and + // length. + // This path can be skipped on ignoreConflicts, so the caller + // could use virtual commit. + add(tw.getRawPath(), base, DirCacheEntry.STAGE_1, EPOCH, 0); + add(tw.getRawPath(), ours, DirCacheEntry.STAGE_2, EPOCH, 0); + add(tw.getRawPath(), theirs, DirCacheEntry.STAGE_3, EPOCH, 0); + unmergedPaths.add(tw.getPathString()); + mergeResults.put(tw.getPathString(), + new MergeResult<>(Collections.emptyList())); + } return true; } @@ -757,6 +792,19 @@ public class ResolveMerger extends ThreeWayMerger { unmergedPaths.add(tw.getPathString()); return true; } else if (!attributes.canBeContentMerged()) { + // File marked as binary + switch (getContentMergeStrategy()) { + case OURS: + keep(ourDce); + return true; + case THEIRS: + DirCacheEntry theirEntry = add(tw.getRawPath(), theirs, + DirCacheEntry.STAGE_0, EPOCH, 0); + addToCheckout(tw.getPathString(), theirEntry, attributes); + return true; + default: + break; + } add(tw.getRawPath(), base, DirCacheEntry.STAGE_1, EPOCH, 0); add(tw.getRawPath(), ours, DirCacheEntry.STAGE_2, EPOCH, 0); add(tw.getRawPath(), theirs, DirCacheEntry.STAGE_3, EPOCH, 0); @@ -771,8 +819,26 @@ public class ResolveMerger extends ThreeWayMerger { return false; } - MergeResult<RawText> result = contentMerge(base, ours, theirs, - attributes); + MergeResult<RawText> result = null; + try { + result = contentMerge(base, ours, theirs, attributes, + getContentMergeStrategy()); + } catch (BinaryBlobException e) { + switch (getContentMergeStrategy()) { + case OURS: + keep(ourDce); + return true; + case THEIRS: + DirCacheEntry theirEntry = add(tw.getRawPath(), theirs, + DirCacheEntry.STAGE_0, EPOCH, 0); + addToCheckout(tw.getPathString(), theirEntry, attributes); + return true; + default: + result = new MergeResult<>(Collections.emptyList()); + result.setContainsConflicts(true); + break; + } + } if (ignoreConflicts) { result.setContainsConflicts(false); } @@ -799,9 +865,16 @@ public class ResolveMerger extends ThreeWayMerger { mergeResults.put(tw.getPathString(), result); unmergedPaths.add(tw.getPathString()); } else { - MergeResult<RawText> result = contentMerge(base, ours, - theirs, attributes); - + // Content merge strategy does not apply to delete-modify + // conflicts! + MergeResult<RawText> result; + try { + result = contentMerge(base, ours, theirs, attributes, + ContentMergeStrategy.CONFLICT); + } catch (BinaryBlobException e) { + result = new MergeResult<>(Collections.emptyList()); + result.setContainsConflicts(true); + } if (ignoreConflicts) { // In case a conflict is detected the working tree file // is again filled with new content (containing conflict @@ -863,32 +936,26 @@ public class ResolveMerger extends ThreeWayMerger { * @param ours * @param theirs * @param attributes + * @param strategy * * @return the result of the content merge + * @throws BinaryBlobException + * if any of the blobs looks like a binary blob * @throws IOException */ private MergeResult<RawText> contentMerge(CanonicalTreeParser base, CanonicalTreeParser ours, CanonicalTreeParser theirs, - Attributes attributes) - throws IOException { - RawText baseText; - RawText ourText; - RawText theirsText; - - try { - baseText = base == null ? RawText.EMPTY_TEXT : getRawText( - base.getEntryObjectId(), attributes); - ourText = ours == null ? RawText.EMPTY_TEXT : getRawText( - ours.getEntryObjectId(), attributes); - theirsText = theirs == null ? RawText.EMPTY_TEXT : getRawText( - theirs.getEntryObjectId(), attributes); - } catch (BinaryBlobException e) { - MergeResult<RawText> r = new MergeResult<>(Collections.<RawText>emptyList()); - r.setContainsConflicts(true); - return r; - } - return (mergeAlgorithm.merge(RawTextComparator.DEFAULT, baseText, - ourText, theirsText)); + Attributes attributes, ContentMergeStrategy strategy) + throws BinaryBlobException, IOException { + RawText baseText = base == null ? RawText.EMPTY_TEXT + : getRawText(base.getEntryObjectId(), attributes); + RawText ourText = ours == null ? RawText.EMPTY_TEXT + : getRawText(ours.getEntryObjectId(), attributes); + RawText theirsText = theirs == null ? RawText.EMPTY_TEXT + : getRawText(theirs.getEntryObjectId(), attributes); + mergeAlgorithm.setContentMergeStrategy(strategy); + return mergeAlgorithm.merge(RawTextComparator.DEFAULT, baseText, + ourText, theirsText); } private boolean isIndexDirty() { diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/transport/SshConstants.java b/org.eclipse.jgit/src/org/eclipse/jgit/transport/SshConstants.java index fff2938e5d..be55cd1b81 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/transport/SshConstants.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/transport/SshConstants.java @@ -114,6 +114,14 @@ public final class SshConstants { /** Key in an ssh config file. */ public static final String PREFERRED_AUTHENTICATIONS = "PreferredAuthentications"; + /** + * Key in an ssh config file; defines signature algorithms for public key + * authentication as a comma-separated list. + * + * @since 5.11 + */ + public static final String PUBKEY_ACCEPTED_ALGORITHMS = "PubkeyAcceptedAlgorithms"; + /** Key in an ssh config file. */ public static final String PROXY_COMMAND = "ProxyCommand"; diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/transport/UsernamePasswordCredentialsProvider.java b/org.eclipse.jgit/src/org/eclipse/jgit/transport/UsernamePasswordCredentialsProvider.java index 979961f2ae..c0de42cb57 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/transport/UsernamePasswordCredentialsProvider.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/transport/UsernamePasswordCredentialsProvider.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2010, Google Inc. and others + * Copyright (C) 2010, 2021 Google Inc. and others * * This program and the accompanying materials are made available under the * terms of the Eclipse Distribution License v. 1.0 which is available at @@ -58,14 +58,21 @@ public class UsernamePasswordCredentialsProvider extends CredentialsProvider { @Override public boolean supports(CredentialItem... items) { for (CredentialItem i : items) { - if (i instanceof CredentialItem.Username) + if (i instanceof CredentialItem.InformationalMessage) { continue; - - else if (i instanceof CredentialItem.Password) + } + if (i instanceof CredentialItem.Username) { continue; - - else - return false; + } + if (i instanceof CredentialItem.Password) { + continue; + } + if (i instanceof CredentialItem.StringType) { + if (i.getPromptText().equals("Password: ")) { //$NON-NLS-1$ + continue; + } + } + return false; } return true; } @@ -75,6 +82,9 @@ public class UsernamePasswordCredentialsProvider extends CredentialsProvider { public boolean get(URIish uri, CredentialItem... items) throws UnsupportedCredentialItem { for (CredentialItem i : items) { + if (i instanceof CredentialItem.InformationalMessage) { + continue; + } if (i instanceof CredentialItem.Username) { ((CredentialItem.Username) i).setValue(username); continue; diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/treewalk/WorkingTreeIterator.java b/org.eclipse.jgit/src/org/eclipse/jgit/treewalk/WorkingTreeIterator.java index 55b7d6279a..0b7c0a9e4b 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/treewalk/WorkingTreeIterator.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/treewalk/WorkingTreeIterator.java @@ -502,8 +502,7 @@ public abstract class WorkingTreeIterator extends AbstractTreeIterator { throw new IOException(new FilterFailedException(rc, filterCommand, getEntryPathString(), result.getStdout().toByteArray(MAX_EXCEPTION_TEXT_SIZE), - RawParseUtils.decode(result.getStderr() - .toByteArray(MAX_EXCEPTION_TEXT_SIZE)))); + result.getStderr().toString(MAX_EXCEPTION_TEXT_SIZE))); } return result.getStdout().openInputStreamWithAutoDestroy(); } diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/util/TemporaryBuffer.java b/org.eclipse.jgit/src/org/eclipse/jgit/util/TemporaryBuffer.java index 562eb05dd9..fb893a66f0 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/util/TemporaryBuffer.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/util/TemporaryBuffer.java @@ -18,6 +18,7 @@ import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; +import java.io.UncheckedIOException; import java.util.ArrayList; import org.eclipse.jgit.internal.JGitText; @@ -213,6 +214,24 @@ public abstract class TemporaryBuffer extends OutputStream { } /** + * Convert first {@code limit} number of bytes of the buffer content to + * String. + * + * @param limit + * the maximum number of bytes to be converted to String + * @return first {@code limit} number of bytes of the buffer content + * converted to String. + * @since 5.12 + */ + public String toString(int limit) { + try { + return RawParseUtils.decode(toByteArray(limit)); + } catch (IOException e) { + throw new UncheckedIOException(e); + } + } + + /** * Convert this buffer's contents into a contiguous byte array. If this size * of the buffer exceeds the limit only return the first {@code limit} bytes * <p> @@ -162,8 +162,8 @@ <commons-compress-version>1.19</commons-compress-version> <osgi-core-version>4.3.1</osgi-core-version> <servlet-api-version>3.1.0</servlet-api-version> - <jetty-version>9.4.36.v20210114</jetty-version> - <japicmp-version>0.14.4</japicmp-version> + <jetty-version>9.4.40.v20210413</jetty-version> + <japicmp-version>0.15.3</japicmp-version> <httpclient-version>4.5.13</httpclient-version> <httpcore-version>4.4.14</httpcore-version> <slf4j-version>1.7.30</slf4j-version> @@ -172,7 +172,7 @@ <tycho-extras-version>1.7.0</tycho-extras-version> <gson-version>2.8.6</gson-version> <bouncycastle-version>1.65</bouncycastle-version> - <spotbugs-maven-plugin-version>4.2.0</spotbugs-maven-plugin-version> + <spotbugs-maven-plugin-version>4.2.2</spotbugs-maven-plugin-version> <maven-project-info-reports-plugin-version>3.1.1</maven-project-info-reports-plugin-version> <maven-jxr-plugin-version>3.0.0</maven-jxr-plugin-version> <maven-surefire-plugin-version>3.0.0-M5</maven-surefire-plugin-version> @@ -347,7 +347,7 @@ <dependency><!-- add support for ssh/scp --> <groupId>org.apache.maven.wagon</groupId> <artifactId>wagon-ssh</artifactId> - <version>3.4.2</version> + <version>3.4.3</version> </dependency> </dependencies> </plugin> @@ -389,7 +389,7 @@ <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> - <version>2.4.1</version> + <version>2.4.4</version> </plugin> </plugins> </pluginManagement> @@ -896,7 +896,7 @@ <dependency> <groupId>org.eclipse.jdt</groupId> <artifactId>ecj</artifactId> - <version>3.24.0</version> + <version>3.25.0</version> </dependency> </dependencies> </plugin> |