diff options
author | Matthias Sohn <matthias.sohn@sap.com> | 2019-06-11 23:09:19 +0200 |
---|---|---|
committer | Matthias Sohn <matthias.sohn@sap.com> | 2019-06-11 23:30:26 +0200 |
commit | c177c6f4c53eb8d42bc3de81a8d914949e6ab5aa (patch) | |
tree | 9cc973178d97078f9db806c64c9a74189272dccc | |
parent | 84c315b2a09b70904259628bfeb8dd002f954f77 (diff) | |
parent | 1cfcde48534dcc9510e6e58d422a78fcd156c85f (diff) | |
download | jgit-c177c6f4c53eb8d42bc3de81a8d914949e6ab5aa.tar.gz jgit-c177c6f4c53eb8d42bc3de81a8d914949e6ab5aa.zip |
Merge branch 'master' into stable-5.4
* master:
Handle missing "ours" stage in WorkingTreeIterator.hasCrLfInIndex()
Config: Add helper method to check for empty value
ErrorProne: Increase severity of FutureReturnValueIgnored to ERROR
FS_Win32: Add missing parentheses on if-blocks
Upgrade spotbugs to 3.1.12
Abbreviated{Long}ObjectId: Make operator precedence explicit
GC: Update TODO comments
FS_POSIX: Fix reference comparison of Boolean.FALSE
Increase bazel timeout for long running tests
Use bazelisk to switch between used bazel version
Bump minimum Bazel version to 0.26.1
Bazel: Bump skylib library version to 0.8.0
Retry loading config when locked by another process
Make pull --rebase on an unborn branch do a checkout
Warn if configured cookie file is missing
Handle escaped CR-LF in git config files
DescribeCommand: use glob match instead of path match
Fix off-by-one error in RebaseTodoFile when reading a todo file
Consistently use "!isEmpty()" to detect non-empty list
TransportHttp: Check for non-empty list with "!isEmpty()" rather than
"size() > 0"
TransportHttp: Fix comparison of size with ">= 0"
NetscapeCookieFileTest: Split HttpCookiesMatcher to own class
Bazel: Add missing dependency on mockito for TransportHttpTest
Determine hard-linking and nlink support per FileStore
Support reading and writing cookies.
Repository: Add getIdentifier() method to avoid instanceof operator
Update to Orbit R20190602212107
PacketLineIn: Deprecate the END constant
PacketLineIn: Add an iterator over strings in the input stream
Replace most usages of PacketLineIn.END with PacketLineIn.end()
PacketLineIn: Deprecate DELIM constant
Replace trivial reference comparison of PacketLineIn.{DELIM,END}
PacketLineIn: Rename isDelim to isDelimiter
ProtocolV2ParserTest: Fix typo in comment
Upgrade Bouncy Castle to 1.61
Update to Orbit R20190531194818 and rollback update to Ant 1.10.6
cli: Add the --always option to describe
DescribeCommand: Support the "always" option
cli: Add the --tags option to describe
DescribeCommand: Consistenly omit the default value
Remove excess blank line in FileUtilsTest
PacketLineIn: Add helper methods to check for END and DELIM
UploadPackTest: Rename variable to avoid hiding class member
UploadPackTest: Add missing <> operator on instantiation of ArrayList
BitmapCalculator: javadoc fixes
RevWalkUtils: add progress callback to findBranchesReachableFrom
Upgrade maven-source-plugin to 3.1.0
Upgrade maven-jar-plugin to 3.1.2
Upgrade jacoco-maven-plugin to 0.8.4
BitmapCalculator and its test: add missing license header
RevWalk: new method createReachabilityChecker()
Change-Id: I4d76c7c0dbe6411c842f3468b709f7df51789c08
Signed-off-by: Matthias Sohn <matthias.sohn@sap.com>
102 files changed, 3068 insertions, 499 deletions
diff --git a/.bazelversion b/.bazelversion new file mode 100644 index 0000000000..30f6cf8d98 --- /dev/null +++ b/.bazelversion @@ -0,0 +1 @@ +0.26.1 @@ -4,14 +4,14 @@ load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive") http_archive( name = "bazel_skylib", - sha256 = "bbccf674aa441c266df9894182d80de104cabd19be98be002f6d478aaa31574d", - strip_prefix = "bazel-skylib-2169ae1c374aab4a09aa90e65efe1a3aad4e279b", - urls = ["https://github.com/bazelbuild/bazel-skylib/archive/2169ae1c374aab4a09aa90e65efe1a3aad4e279b.tar.gz"], + sha256 = "2ea8a5ed2b448baf4a6855d3ce049c4c452a6470b1efd1504fdb7c1c134d220a", + strip_prefix = "bazel-skylib-0.8.0", + urls = ["https://github.com/bazelbuild/bazel-skylib/archive/0.8.0.tar.gz"], ) load("@bazel_skylib//lib:versions.bzl", "versions") -versions.check(minimum_bazel_version = "0.19.0") +versions.check(minimum_bazel_version = "0.26.1") load("//tools:bazlets.bzl", "load_bazlets") @@ -212,25 +212,25 @@ maven_jar( src_sha1 = "94e89a8c9f82e38555e95b9f7f58344a247e862c", ) -BOUNCYCASTLE_VER = "1.60" +BOUNCYCASTLE_VER = "1.61" maven_jar( name = "bcpg", artifact = "org.bouncycastle:bcpg-jdk15on:" + BOUNCYCASTLE_VER, - sha1 = "13c7a199c484127daad298996e95818478431a2c", - src_sha1 = "edcd9e86d95e39b4da39bb295efd93bc4f56266e", + sha1 = "422656435514ab8a28752b117d5d2646660a0ace", + src_sha1 = "836da34e11114cbce8fa99f54175f8f3278d1cce", ) maven_jar( name = "bcprov", artifact = "org.bouncycastle:bcprov-jdk15on:" + BOUNCYCASTLE_VER, - sha1 = "bd47ad3bd14b8e82595c7adaa143501e60842a84", - src_sha1 = "7c57a4d13fe53d9abb967bba600dd0b293dafd6a", + sha1 = "00df4b474e71be02c1349c3292d98886f888d1f7", + src_sha1 = "3bf88046a16098ea6cc41576dd50d512854d39e1", ) maven_jar( name = "bcpkix", artifact = "org.bouncycastle:bcpkix-jdk15on:" + BOUNCYCASTLE_VER, - sha1 = "d0c46320fbc07be3a24eb13a56cee4e3d38e0c75", - src_sha1 = "a25f041293f401af08efba63ff4bbdce98134a03", + sha1 = "89bb3aa5b98b48e584eee2a7401b7682a46779b4", + src_sha1 = "a0498d09200a18737eccc05aa81bbd05c1be0f8c", ) diff --git a/org.eclipse.jgit.http.server/src/org/eclipse/jgit/http/server/ServletUtils.java b/org.eclipse.jgit.http.server/src/org/eclipse/jgit/http/server/ServletUtils.java index b6d73b5591..256279bfed 100644 --- a/org.eclipse.jgit.http.server/src/org/eclipse/jgit/http/server/ServletUtils.java +++ b/org.eclipse.jgit.http.server/src/org/eclipse/jgit/http/server/ServletUtils.java @@ -64,7 +64,6 @@ import javax.servlet.ServletRequest; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; -import org.eclipse.jgit.internal.storage.dfs.DfsRepository; import org.eclipse.jgit.lib.Constants; import org.eclipse.jgit.lib.ObjectId; import org.eclipse.jgit.lib.Repository; @@ -276,12 +275,11 @@ public final class ServletUtils { } static String identify(Repository git) { - if (git instanceof DfsRepository) { - return ((DfsRepository) git).getDescription().getRepositoryName(); - } else if (git.getDirectory() != null) { - return git.getDirectory().getPath(); + String identifier = git.getIdentifier(); + if (identifier == null) { + return "unknown"; } - return "unknown"; + return identifier; } private ServletUtils() { diff --git a/org.eclipse.jgit.http.test/tst/org/eclipse/jgit/http/test/HttpClientTests.java b/org.eclipse.jgit.http.test/tst/org/eclipse/jgit/http/test/HttpClientTests.java index 1660f14f34..8ec2f51cff 100644 --- a/org.eclipse.jgit.http.test/tst/org/eclipse/jgit/http/test/HttpClientTests.java +++ b/org.eclipse.jgit.http.test/tst/org/eclipse/jgit/http/test/HttpClientTests.java @@ -44,7 +44,6 @@ package org.eclipse.jgit.http.test; import static org.hamcrest.Matchers.is; -import static org.hamcrest.Matchers.theInstance; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertNotNull; @@ -366,7 +365,7 @@ public class HttpClientTests extends HttpTestCase { // Check that we get a v0 response. assertThat(pckIn.readString(), is("# service=git-upload-pack")); - assertThat(pckIn.readString(), theInstance(PacketLineIn.END)); + assertTrue(PacketLineIn.isEnd(pckIn.readString())); assertTrue(pckIn.readString().matches("[0-9a-f]{40} HEAD.*")); } @@ -388,8 +387,7 @@ public class HttpClientTests extends HttpTestCase { // What remains are capabilities - ensure that all of them are // non-empty strings, and that we see END at the end. - String s; - while ((s = pckIn.readString()) != PacketLineIn.END) { + for (String s : pckIn.readStrings()) { assertTrue(!s.isEmpty()); } } @@ -422,8 +420,7 @@ public class HttpClientTests extends HttpTestCase { PacketLineIn pckIn = new PacketLineIn(c.getInputStream()); // Just check that we get what looks like a ref advertisement. - String s; - while ((s = pckIn.readString()) != PacketLineIn.END) { + for (String s : pckIn.readStrings()) { assertTrue(s.matches("[0-9a-f]{40} [A-Za-z/]*")); } diff --git a/org.eclipse.jgit.http.test/tst/org/eclipse/jgit/http/test/ProtocolErrorTest.java b/org.eclipse.jgit.http.test/tst/org/eclipse/jgit/http/test/ProtocolErrorTest.java index f0fac5ab51..6a3d8829bb 100644 --- a/org.eclipse.jgit.http.test/tst/org/eclipse/jgit/http/test/ProtocolErrorTest.java +++ b/org.eclipse.jgit.http.test/tst/org/eclipse/jgit/http/test/ProtocolErrorTest.java @@ -44,7 +44,7 @@ package org.eclipse.jgit.http.test; import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertSame; +import static org.junit.Assert.assertTrue; import java.io.ByteArrayOutputStream; import java.io.IOException; @@ -157,7 +157,7 @@ public class ProtocolErrorTest extends HttpTestCase { pckin.readString()); assertEquals("ng refs/objects/A n/a (unpacker error)", pckin.readString()); - assertSame(PacketLineIn.END, pckin.readString()); + assertTrue(PacketLineIn.isEnd(pckin.readString())); } } finally { c.disconnect(); diff --git a/org.eclipse.jgit.lfs.server.test/tst/org/eclipse/jgit/lfs/server/fs/UploadTest.java b/org.eclipse.jgit.lfs.server.test/tst/org/eclipse/jgit/lfs/server/fs/UploadTest.java index c6f9535564..2334ec37af 100644 --- a/org.eclipse.jgit.lfs.server.test/tst/org/eclipse/jgit/lfs/server/fs/UploadTest.java +++ b/org.eclipse.jgit.lfs.server.test/tst/org/eclipse/jgit/lfs/server/fs/UploadTest.java @@ -44,6 +44,7 @@ package org.eclipse.jgit.lfs.server.fs; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; @@ -56,6 +57,7 @@ import java.util.List; import java.util.concurrent.CyclicBarrier; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; +import java.util.concurrent.Future; import java.util.concurrent.TimeUnit; import org.eclipse.jgit.lfs.lib.AnyLongObjectId; @@ -122,11 +124,12 @@ public class UploadTest extends LfsServerTest { ExecutorService e = Executors.newFixedThreadPool(count); try { for (Path p : paths) { - e.submit(() -> { + Future<Object> result = e.submit(() -> { barrier.await(); putContent(p); return null; }); + assertNotNull(result); } } finally { e.shutdown(); diff --git a/org.eclipse.jgit.lfs.server/src/org/eclipse/jgit/lfs/server/TransferHandler.java b/org.eclipse.jgit.lfs.server/src/org/eclipse/jgit/lfs/server/TransferHandler.java index 4fea92e111..6c36661c3e 100644 --- a/org.eclipse.jgit.lfs.server/src/org/eclipse/jgit/lfs/server/TransferHandler.java +++ b/org.eclipse.jgit.lfs.server/src/org/eclipse/jgit/lfs/server/TransferHandler.java @@ -84,7 +84,7 @@ abstract class TransferHandler { @Override Body process() throws IOException { Response.Body body = new Response.Body(); - if (objects.size() > 0) { + if (!objects.isEmpty()) { body.objects = new ArrayList<>(); for (LfsObject o : objects) { addObjectInfo(body, o); @@ -122,7 +122,7 @@ abstract class TransferHandler { @Override Body process() throws IOException { Response.Body body = new Response.Body(); - if (objects.size() > 0) { + if (!objects.isEmpty()) { body.objects = new ArrayList<>(); for (LfsObject o : objects) { addObjectInfo(body, o); diff --git a/org.eclipse.jgit.lfs/src/org/eclipse/jgit/lfs/lib/AbbreviatedLongObjectId.java b/org.eclipse.jgit.lfs/src/org/eclipse/jgit/lfs/lib/AbbreviatedLongObjectId.java index bdd1b39c0d..5109d9bbba 100644 --- a/org.eclipse.jgit.lfs/src/org/eclipse/jgit/lfs/lib/AbbreviatedLongObjectId.java +++ b/org.eclipse.jgit.lfs/src/org/eclipse/jgit/lfs/lib/AbbreviatedLongObjectId.java @@ -170,7 +170,7 @@ public final class AbbreviatedLongObjectId implements Serializable { r |= RawParseUtils.parseHexInt4(bs[p++]); n++; } - return r << (16 - n) * 4; + return r << ((16 - n) * 4); } static long mask(int nibbles, long word, long v) { 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 440092a174..1915747206 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,7 +1,7 @@ <?xml version="1.0" encoding="UTF-8" standalone="no"?> <?pde?> <!-- generated with https://github.com/eclipse-cbi/targetplatform-dsl --> -<target name="jgit-4.10" sequenceNumber="1558537043"> +<target name="jgit-4.10" sequenceNumber="1559548426"> <locations> <location includeMode="slicer" includeAllPlatforms="false" includeSource="true" includeConfigurePhase="true" type="InstallableUnit"> <unit id="org.eclipse.jetty.client" version="9.4.14.v20181114"/> @@ -23,8 +23,8 @@ <repository id="jetty-9.4.14" location="http://download.eclipse.org/jetty/updates/jetty-bundles-9.x/9.4.14.v20181114"/> </location> <location includeMode="slicer" includeAllPlatforms="false" includeSource="true" includeConfigurePhase="true" type="InstallableUnit"> - <unit id="org.apache.ant" version="1.10.6.v20190516-0412"/> - <unit id="org.apache.ant.source" version="1.10.6.v20190516-0412"/> + <unit id="org.apache.ant" version="1.10.5.v20190526-1402"/> + <unit id="org.apache.ant.source" version="1.10.5.v20190526-1402"/> <unit id="org.apache.commons.codec" version="1.10.0.v20180409-1845"/> <unit id="org.apache.commons.codec.source" version="1.10.0.v20180409-1845"/> <unit id="org.apache.commons.compress" version="1.18.0.v20181121-2221"/> @@ -37,12 +37,12 @@ <unit id="org.apache.httpcomponents.httpcore.source" version="4.4.10.v20190123-2214"/> <unit id="org.apache.log4j" version="1.2.15.v201012070815"/> <unit id="org.apache.log4j.source" version="1.2.15.v201012070815"/> - <unit id="org.bouncycastle.bcpg" version="1.60.0.v20181210-2057"/> - <unit id="org.bouncycastle.bcpg.source" version="1.60.0.v20181210-2057"/> - <unit id="org.bouncycastle.bcpkix" version="1.60.0.v20181210-2057"/> - <unit id="org.bouncycastle.bcpkix.source" version="1.60.0.v20181210-2057"/> - <unit id="org.bouncycastle.bcprov" version="1.60.0.v20181210-2057"/> - <unit id="org.bouncycastle.bcprov.source" version="1.60.0.v20181210-2057"/> + <unit id="org.bouncycastle.bcpg" version="1.61.0.v20190602-1335"/> + <unit id="org.bouncycastle.bcpg.source" version="1.61.0.v20190602-1335"/> + <unit id="org.bouncycastle.bcpkix" version="1.61.0.v20190602-1335"/> + <unit id="org.bouncycastle.bcpkix.source" version="1.61.0.v20190602-1335"/> + <unit id="org.bouncycastle.bcprov" version="1.61.0.v20190602-1335"/> + <unit id="org.bouncycastle.bcprov.source" version="1.61.0.v20190602-1335"/> <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.hamcrest" version="1.1.0.v20090501071000"/> @@ -82,7 +82,7 @@ <unit id="org.apache.sshd.osgi.source" version="2.2.0.v20190425-2127"/> <unit id="org.apache.sshd.sftp" version="2.2.0.v20190425-2127"/> <unit id="org.apache.sshd.sftp.source" version="2.2.0.v20190425-2127"/> - <repository location="http://download.eclipse.org/tools/orbit/downloads/drops/S20190521195709/repository"/> + <repository location="https://download.eclipse.org/tools/orbit/downloads/drops/R20190602212107/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 5bfd814115..6beb42e33a 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.14.tpd" -include "orbit/S20190521195709.tpd" +include "orbit/R20190602212107-2019-06.tpd" location "http://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 a3ad331a46..e5ea33101f 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,7 +1,7 @@ <?xml version="1.0" encoding="UTF-8" standalone="no"?> <?pde?> <!-- generated with https://github.com/eclipse-cbi/targetplatform-dsl --> -<target name="jgit-4.11" sequenceNumber="1558539017"> +<target name="jgit-4.11" sequenceNumber="1559548429"> <locations> <location includeMode="slicer" includeAllPlatforms="false" includeSource="true" includeConfigurePhase="true" type="InstallableUnit"> <unit id="org.eclipse.jetty.client" version="9.4.14.v20181114"/> @@ -23,8 +23,8 @@ <repository id="jetty-9.4.14" location="http://download.eclipse.org/jetty/updates/jetty-bundles-9.x/9.4.14.v20181114"/> </location> <location includeMode="slicer" includeAllPlatforms="false" includeSource="true" includeConfigurePhase="true" type="InstallableUnit"> - <unit id="org.apache.ant" version="1.10.6.v20190516-0412"/> - <unit id="org.apache.ant.source" version="1.10.6.v20190516-0412"/> + <unit id="org.apache.ant" version="1.10.5.v20190526-1402"/> + <unit id="org.apache.ant.source" version="1.10.5.v20190526-1402"/> <unit id="org.apache.commons.codec" version="1.10.0.v20180409-1845"/> <unit id="org.apache.commons.codec.source" version="1.10.0.v20180409-1845"/> <unit id="org.apache.commons.compress" version="1.18.0.v20181121-2221"/> @@ -37,12 +37,12 @@ <unit id="org.apache.httpcomponents.httpcore.source" version="4.4.10.v20190123-2214"/> <unit id="org.apache.log4j" version="1.2.15.v201012070815"/> <unit id="org.apache.log4j.source" version="1.2.15.v201012070815"/> - <unit id="org.bouncycastle.bcpg" version="1.60.0.v20181210-2057"/> - <unit id="org.bouncycastle.bcpg.source" version="1.60.0.v20181210-2057"/> - <unit id="org.bouncycastle.bcpkix" version="1.60.0.v20181210-2057"/> - <unit id="org.bouncycastle.bcpkix.source" version="1.60.0.v20181210-2057"/> - <unit id="org.bouncycastle.bcprov" version="1.60.0.v20181210-2057"/> - <unit id="org.bouncycastle.bcprov.source" version="1.60.0.v20181210-2057"/> + <unit id="org.bouncycastle.bcpg" version="1.61.0.v20190602-1335"/> + <unit id="org.bouncycastle.bcpg.source" version="1.61.0.v20190602-1335"/> + <unit id="org.bouncycastle.bcpkix" version="1.61.0.v20190602-1335"/> + <unit id="org.bouncycastle.bcpkix.source" version="1.61.0.v20190602-1335"/> + <unit id="org.bouncycastle.bcprov" version="1.61.0.v20190602-1335"/> + <unit id="org.bouncycastle.bcprov.source" version="1.61.0.v20190602-1335"/> <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.hamcrest" version="1.1.0.v20090501071000"/> @@ -82,7 +82,7 @@ <unit id="org.apache.sshd.osgi.source" version="2.2.0.v20190425-2127"/> <unit id="org.apache.sshd.sftp" version="2.2.0.v20190425-2127"/> <unit id="org.apache.sshd.sftp.source" version="2.2.0.v20190425-2127"/> - <repository location="http://download.eclipse.org/tools/orbit/downloads/drops/S20190521195709/repository"/> + <repository location="https://download.eclipse.org/tools/orbit/downloads/drops/R20190602212107/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 8b3b509fd9..e09e8c387d 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.14.tpd" -include "orbit/S20190521195709.tpd" +include "orbit/R20190602212107-2019-06.tpd" location "http://download.eclipse.org/releases/2019-03/" { org.eclipse.osgi lazy diff --git a/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.12-staging.target b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.12-staging.target index 2ea7b79f92..5daa8e8ad5 100644 --- a/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.12-staging.target +++ b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.12-staging.target @@ -1,7 +1,7 @@ <?xml version="1.0" encoding="UTF-8" standalone="no"?> <?pde?> <!-- generated with https://github.com/eclipse-cbi/targetplatform-dsl --> -<target name="jgit-4.12-staging" sequenceNumber="1558539043"> +<target name="jgit-4.12-staging" sequenceNumber="1559548433"> <locations> <location includeMode="slicer" includeAllPlatforms="false" includeSource="true" includeConfigurePhase="true" type="InstallableUnit"> <unit id="org.eclipse.jetty.client" version="9.4.14.v20181114"/> @@ -23,8 +23,8 @@ <repository id="jetty-9.4.14" location="http://download.eclipse.org/jetty/updates/jetty-bundles-9.x/9.4.14.v20181114"/> </location> <location includeMode="slicer" includeAllPlatforms="false" includeSource="true" includeConfigurePhase="true" type="InstallableUnit"> - <unit id="org.apache.ant" version="1.10.6.v20190516-0412"/> - <unit id="org.apache.ant.source" version="1.10.6.v20190516-0412"/> + <unit id="org.apache.ant" version="1.10.5.v20190526-1402"/> + <unit id="org.apache.ant.source" version="1.10.5.v20190526-1402"/> <unit id="org.apache.commons.codec" version="1.10.0.v20180409-1845"/> <unit id="org.apache.commons.codec.source" version="1.10.0.v20180409-1845"/> <unit id="org.apache.commons.compress" version="1.18.0.v20181121-2221"/> @@ -37,12 +37,12 @@ <unit id="org.apache.httpcomponents.httpcore.source" version="4.4.10.v20190123-2214"/> <unit id="org.apache.log4j" version="1.2.15.v201012070815"/> <unit id="org.apache.log4j.source" version="1.2.15.v201012070815"/> - <unit id="org.bouncycastle.bcpg" version="1.60.0.v20181210-2057"/> - <unit id="org.bouncycastle.bcpg.source" version="1.60.0.v20181210-2057"/> - <unit id="org.bouncycastle.bcpkix" version="1.60.0.v20181210-2057"/> - <unit id="org.bouncycastle.bcpkix.source" version="1.60.0.v20181210-2057"/> - <unit id="org.bouncycastle.bcprov" version="1.60.0.v20181210-2057"/> - <unit id="org.bouncycastle.bcprov.source" version="1.60.0.v20181210-2057"/> + <unit id="org.bouncycastle.bcpg" version="1.61.0.v20190602-1335"/> + <unit id="org.bouncycastle.bcpg.source" version="1.61.0.v20190602-1335"/> + <unit id="org.bouncycastle.bcpkix" version="1.61.0.v20190602-1335"/> + <unit id="org.bouncycastle.bcpkix.source" version="1.61.0.v20190602-1335"/> + <unit id="org.bouncycastle.bcprov" version="1.61.0.v20190602-1335"/> + <unit id="org.bouncycastle.bcprov.source" version="1.61.0.v20190602-1335"/> <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.hamcrest" version="1.1.0.v20090501071000"/> @@ -82,7 +82,7 @@ <unit id="org.apache.sshd.osgi.source" version="2.2.0.v20190425-2127"/> <unit id="org.apache.sshd.sftp" version="2.2.0.v20190425-2127"/> <unit id="org.apache.sshd.sftp.source" version="2.2.0.v20190425-2127"/> - <repository location="http://download.eclipse.org/tools/orbit/downloads/drops/S20190521195709/repository"/> + <repository location="https://download.eclipse.org/tools/orbit/downloads/drops/R20190602212107/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-staging.tpd b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.12-staging.tpd index f0cd3049fa..43b64a0301 100644 --- a/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.12-staging.tpd +++ b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.12-staging.tpd @@ -1,7 +1,7 @@ target "jgit-4.12-staging" with source configurePhase include "projects/jetty-9.4.14.tpd" -include "orbit/S20190521195709.tpd" +include "orbit/R20190602212107-2019-06.tpd" location "http://download.eclipse.org/staging/2019-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 64cf3e7d2d..0638b46a34 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,7 +1,7 @@ <?xml version="1.0" encoding="UTF-8" standalone="no"?> <?pde?> <!-- generated with https://github.com/eclipse-cbi/targetplatform-dsl --> -<target name="jgit-4.6" sequenceNumber="1558539043"> +<target name="jgit-4.6" sequenceNumber="1559548436"> <locations> <location includeMode="slicer" includeAllPlatforms="false" includeSource="true" includeConfigurePhase="true" type="InstallableUnit"> <unit id="org.eclipse.jetty.client" version="9.4.14.v20181114"/> @@ -23,8 +23,8 @@ <repository id="jetty-9.4.14" location="http://download.eclipse.org/jetty/updates/jetty-bundles-9.x/9.4.14.v20181114"/> </location> <location includeMode="slicer" includeAllPlatforms="false" includeSource="true" includeConfigurePhase="true" type="InstallableUnit"> - <unit id="org.apache.ant" version="1.10.6.v20190516-0412"/> - <unit id="org.apache.ant.source" version="1.10.6.v20190516-0412"/> + <unit id="org.apache.ant" version="1.10.5.v20190526-1402"/> + <unit id="org.apache.ant.source" version="1.10.5.v20190526-1402"/> <unit id="org.apache.commons.codec" version="1.10.0.v20180409-1845"/> <unit id="org.apache.commons.codec.source" version="1.10.0.v20180409-1845"/> <unit id="org.apache.commons.compress" version="1.18.0.v20181121-2221"/> @@ -37,12 +37,12 @@ <unit id="org.apache.httpcomponents.httpcore.source" version="4.4.10.v20190123-2214"/> <unit id="org.apache.log4j" version="1.2.15.v201012070815"/> <unit id="org.apache.log4j.source" version="1.2.15.v201012070815"/> - <unit id="org.bouncycastle.bcpg" version="1.60.0.v20181210-2057"/> - <unit id="org.bouncycastle.bcpg.source" version="1.60.0.v20181210-2057"/> - <unit id="org.bouncycastle.bcpkix" version="1.60.0.v20181210-2057"/> - <unit id="org.bouncycastle.bcpkix.source" version="1.60.0.v20181210-2057"/> - <unit id="org.bouncycastle.bcprov" version="1.60.0.v20181210-2057"/> - <unit id="org.bouncycastle.bcprov.source" version="1.60.0.v20181210-2057"/> + <unit id="org.bouncycastle.bcpg" version="1.61.0.v20190602-1335"/> + <unit id="org.bouncycastle.bcpg.source" version="1.61.0.v20190602-1335"/> + <unit id="org.bouncycastle.bcpkix" version="1.61.0.v20190602-1335"/> + <unit id="org.bouncycastle.bcpkix.source" version="1.61.0.v20190602-1335"/> + <unit id="org.bouncycastle.bcprov" version="1.61.0.v20190602-1335"/> + <unit id="org.bouncycastle.bcprov.source" version="1.61.0.v20190602-1335"/> <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.hamcrest" version="1.1.0.v20090501071000"/> @@ -82,7 +82,7 @@ <unit id="org.apache.sshd.osgi.source" version="2.2.0.v20190425-2127"/> <unit id="org.apache.sshd.sftp" version="2.2.0.v20190425-2127"/> <unit id="org.apache.sshd.sftp.source" version="2.2.0.v20190425-2127"/> - <repository location="http://download.eclipse.org/tools/orbit/downloads/drops/S20190521195709/repository"/> + <repository location="https://download.eclipse.org/tools/orbit/downloads/drops/R20190602212107/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 8ae721fed0..1a2c9a3a16 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.14.tpd" -include "orbit/S20190521195709.tpd" +include "orbit/R20190602212107-2019-06.tpd" location "http://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 eb8c8e91df..1044299df5 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,7 +1,7 @@ <?xml version="1.0" encoding="UTF-8" standalone="no"?> <?pde?> <!-- generated with https://github.com/eclipse-cbi/targetplatform-dsl --> -<target name="jgit-4.7" sequenceNumber="1558539038"> +<target name="jgit-4.7" sequenceNumber="1559548440"> <locations> <location includeMode="slicer" includeAllPlatforms="false" includeSource="true" includeConfigurePhase="true" type="InstallableUnit"> <unit id="org.eclipse.jetty.client" version="9.4.14.v20181114"/> @@ -23,8 +23,8 @@ <repository id="jetty-9.4.14" location="http://download.eclipse.org/jetty/updates/jetty-bundles-9.x/9.4.14.v20181114"/> </location> <location includeMode="slicer" includeAllPlatforms="false" includeSource="true" includeConfigurePhase="true" type="InstallableUnit"> - <unit id="org.apache.ant" version="1.10.6.v20190516-0412"/> - <unit id="org.apache.ant.source" version="1.10.6.v20190516-0412"/> + <unit id="org.apache.ant" version="1.10.5.v20190526-1402"/> + <unit id="org.apache.ant.source" version="1.10.5.v20190526-1402"/> <unit id="org.apache.commons.codec" version="1.10.0.v20180409-1845"/> <unit id="org.apache.commons.codec.source" version="1.10.0.v20180409-1845"/> <unit id="org.apache.commons.compress" version="1.18.0.v20181121-2221"/> @@ -37,12 +37,12 @@ <unit id="org.apache.httpcomponents.httpcore.source" version="4.4.10.v20190123-2214"/> <unit id="org.apache.log4j" version="1.2.15.v201012070815"/> <unit id="org.apache.log4j.source" version="1.2.15.v201012070815"/> - <unit id="org.bouncycastle.bcpg" version="1.60.0.v20181210-2057"/> - <unit id="org.bouncycastle.bcpg.source" version="1.60.0.v20181210-2057"/> - <unit id="org.bouncycastle.bcpkix" version="1.60.0.v20181210-2057"/> - <unit id="org.bouncycastle.bcpkix.source" version="1.60.0.v20181210-2057"/> - <unit id="org.bouncycastle.bcprov" version="1.60.0.v20181210-2057"/> - <unit id="org.bouncycastle.bcprov.source" version="1.60.0.v20181210-2057"/> + <unit id="org.bouncycastle.bcpg" version="1.61.0.v20190602-1335"/> + <unit id="org.bouncycastle.bcpg.source" version="1.61.0.v20190602-1335"/> + <unit id="org.bouncycastle.bcpkix" version="1.61.0.v20190602-1335"/> + <unit id="org.bouncycastle.bcpkix.source" version="1.61.0.v20190602-1335"/> + <unit id="org.bouncycastle.bcprov" version="1.61.0.v20190602-1335"/> + <unit id="org.bouncycastle.bcprov.source" version="1.61.0.v20190602-1335"/> <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.hamcrest" version="1.1.0.v20090501071000"/> @@ -82,7 +82,7 @@ <unit id="org.apache.sshd.osgi.source" version="2.2.0.v20190425-2127"/> <unit id="org.apache.sshd.sftp" version="2.2.0.v20190425-2127"/> <unit id="org.apache.sshd.sftp.source" version="2.2.0.v20190425-2127"/> - <repository location="http://download.eclipse.org/tools/orbit/downloads/drops/S20190521195709/repository"/> + <repository location="https://download.eclipse.org/tools/orbit/downloads/drops/R20190602212107/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 430506aeea..fc1b046edd 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.14.tpd" -include "orbit/S20190521195709.tpd" +include "orbit/R20190602212107-2019-06.tpd" location "http://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 9764a61580..a5f948fdee 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,7 +1,7 @@ <?xml version="1.0" encoding="UTF-8" standalone="no"?> <?pde?> <!-- generated with https://github.com/eclipse-cbi/targetplatform-dsl --> -<target name="jgit-4.8" sequenceNumber="1558539037"> +<target name="jgit-4.8" sequenceNumber="1559548443"> <locations> <location includeMode="slicer" includeAllPlatforms="false" includeSource="true" includeConfigurePhase="true" type="InstallableUnit"> <unit id="org.eclipse.jetty.client" version="9.4.14.v20181114"/> @@ -23,8 +23,8 @@ <repository id="jetty-9.4.14" location="http://download.eclipse.org/jetty/updates/jetty-bundles-9.x/9.4.14.v20181114"/> </location> <location includeMode="slicer" includeAllPlatforms="false" includeSource="true" includeConfigurePhase="true" type="InstallableUnit"> - <unit id="org.apache.ant" version="1.10.6.v20190516-0412"/> - <unit id="org.apache.ant.source" version="1.10.6.v20190516-0412"/> + <unit id="org.apache.ant" version="1.10.5.v20190526-1402"/> + <unit id="org.apache.ant.source" version="1.10.5.v20190526-1402"/> <unit id="org.apache.commons.codec" version="1.10.0.v20180409-1845"/> <unit id="org.apache.commons.codec.source" version="1.10.0.v20180409-1845"/> <unit id="org.apache.commons.compress" version="1.18.0.v20181121-2221"/> @@ -37,12 +37,12 @@ <unit id="org.apache.httpcomponents.httpcore.source" version="4.4.10.v20190123-2214"/> <unit id="org.apache.log4j" version="1.2.15.v201012070815"/> <unit id="org.apache.log4j.source" version="1.2.15.v201012070815"/> - <unit id="org.bouncycastle.bcpg" version="1.60.0.v20181210-2057"/> - <unit id="org.bouncycastle.bcpg.source" version="1.60.0.v20181210-2057"/> - <unit id="org.bouncycastle.bcpkix" version="1.60.0.v20181210-2057"/> - <unit id="org.bouncycastle.bcpkix.source" version="1.60.0.v20181210-2057"/> - <unit id="org.bouncycastle.bcprov" version="1.60.0.v20181210-2057"/> - <unit id="org.bouncycastle.bcprov.source" version="1.60.0.v20181210-2057"/> + <unit id="org.bouncycastle.bcpg" version="1.61.0.v20190602-1335"/> + <unit id="org.bouncycastle.bcpg.source" version="1.61.0.v20190602-1335"/> + <unit id="org.bouncycastle.bcpkix" version="1.61.0.v20190602-1335"/> + <unit id="org.bouncycastle.bcpkix.source" version="1.61.0.v20190602-1335"/> + <unit id="org.bouncycastle.bcprov" version="1.61.0.v20190602-1335"/> + <unit id="org.bouncycastle.bcprov.source" version="1.61.0.v20190602-1335"/> <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.hamcrest" version="1.1.0.v20090501071000"/> @@ -82,7 +82,7 @@ <unit id="org.apache.sshd.osgi.source" version="2.2.0.v20190425-2127"/> <unit id="org.apache.sshd.sftp" version="2.2.0.v20190425-2127"/> <unit id="org.apache.sshd.sftp.source" version="2.2.0.v20190425-2127"/> - <repository location="http://download.eclipse.org/tools/orbit/downloads/drops/S20190521195709/repository"/> + <repository location="https://download.eclipse.org/tools/orbit/downloads/drops/R20190602212107/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 e18fc7255c..a8f837e9ca 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.14.tpd" -include "orbit/S20190521195709.tpd" +include "orbit/R20190602212107-2019-06.tpd" location "http://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 331d141b65..e0afda3a6e 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,7 +1,7 @@ <?xml version="1.0" encoding="UTF-8" standalone="no"?> <?pde?> <!-- generated with https://github.com/eclipse-cbi/targetplatform-dsl --> -<target name="jgit-4.9" sequenceNumber="1558539042"> +<target name="jgit-4.9" sequenceNumber="1559548447"> <locations> <location includeMode="slicer" includeAllPlatforms="false" includeSource="true" includeConfigurePhase="true" type="InstallableUnit"> <unit id="org.eclipse.jetty.client" version="9.4.14.v20181114"/> @@ -23,8 +23,8 @@ <repository id="jetty-9.4.14" location="http://download.eclipse.org/jetty/updates/jetty-bundles-9.x/9.4.14.v20181114"/> </location> <location includeMode="slicer" includeAllPlatforms="false" includeSource="true" includeConfigurePhase="true" type="InstallableUnit"> - <unit id="org.apache.ant" version="1.10.6.v20190516-0412"/> - <unit id="org.apache.ant.source" version="1.10.6.v20190516-0412"/> + <unit id="org.apache.ant" version="1.10.5.v20190526-1402"/> + <unit id="org.apache.ant.source" version="1.10.5.v20190526-1402"/> <unit id="org.apache.commons.codec" version="1.10.0.v20180409-1845"/> <unit id="org.apache.commons.codec.source" version="1.10.0.v20180409-1845"/> <unit id="org.apache.commons.compress" version="1.18.0.v20181121-2221"/> @@ -37,12 +37,12 @@ <unit id="org.apache.httpcomponents.httpcore.source" version="4.4.10.v20190123-2214"/> <unit id="org.apache.log4j" version="1.2.15.v201012070815"/> <unit id="org.apache.log4j.source" version="1.2.15.v201012070815"/> - <unit id="org.bouncycastle.bcpg" version="1.60.0.v20181210-2057"/> - <unit id="org.bouncycastle.bcpg.source" version="1.60.0.v20181210-2057"/> - <unit id="org.bouncycastle.bcpkix" version="1.60.0.v20181210-2057"/> - <unit id="org.bouncycastle.bcpkix.source" version="1.60.0.v20181210-2057"/> - <unit id="org.bouncycastle.bcprov" version="1.60.0.v20181210-2057"/> - <unit id="org.bouncycastle.bcprov.source" version="1.60.0.v20181210-2057"/> + <unit id="org.bouncycastle.bcpg" version="1.61.0.v20190602-1335"/> + <unit id="org.bouncycastle.bcpg.source" version="1.61.0.v20190602-1335"/> + <unit id="org.bouncycastle.bcpkix" version="1.61.0.v20190602-1335"/> + <unit id="org.bouncycastle.bcpkix.source" version="1.61.0.v20190602-1335"/> + <unit id="org.bouncycastle.bcprov" version="1.61.0.v20190602-1335"/> + <unit id="org.bouncycastle.bcprov.source" version="1.61.0.v20190602-1335"/> <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.hamcrest" version="1.1.0.v20090501071000"/> @@ -82,7 +82,7 @@ <unit id="org.apache.sshd.osgi.source" version="2.2.0.v20190425-2127"/> <unit id="org.apache.sshd.sftp" version="2.2.0.v20190425-2127"/> <unit id="org.apache.sshd.sftp.source" version="2.2.0.v20190425-2127"/> - <repository location="http://download.eclipse.org/tools/orbit/downloads/drops/S20190521195709/repository"/> + <repository location="https://download.eclipse.org/tools/orbit/downloads/drops/R20190602212107/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 6b71dff4a4..f91f53eb8b 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.14.tpd" -include "orbit/S20190521195709.tpd" +include "orbit/R20190602212107-2019-06.tpd" location "http://download.eclipse.org/releases/2018-09/" { org.eclipse.osgi lazy diff --git a/org.eclipse.jgit.packaging/org.eclipse.jgit.target/orbit/S20190521195709.tpd b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/orbit/R20190602212107-2019-06.tpd index d526ab4325..df9a810e07 100644 --- a/org.eclipse.jgit.packaging/org.eclipse.jgit.target/orbit/S20190521195709.tpd +++ b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/orbit/R20190602212107-2019-06.tpd @@ -1,9 +1,9 @@ -target "S20190521195709" with source configurePhase +target "R20190602212107-2019-06" with source configurePhase // see http://download.eclipse.org/tools/orbit/downloads/ -location "http://download.eclipse.org/tools/orbit/downloads/drops/S20190521195709/repository" { - org.apache.ant [1.10.6.v20190516-0412,1.10.6.v20190516-0412] - org.apache.ant.source [1.10.6.v20190516-0412,1.10.6.v20190516-0412] +location "https://download.eclipse.org/tools/orbit/downloads/drops/R20190602212107/repository" { + org.apache.ant [1.10.5.v20190526-1402,1.10.5.v20190526-1402] + org.apache.ant.source [1.10.5.v20190526-1402,1.10.5.v20190526-1402] org.apache.commons.codec [1.10.0.v20180409-1845,1.10.0.v20180409-1845] org.apache.commons.codec.source [1.10.0.v20180409-1845,1.10.0.v20180409-1845] org.apache.commons.compress [1.18.0.v20181121-2221,1.18.0.v20181121-2221] @@ -16,12 +16,12 @@ location "http://download.eclipse.org/tools/orbit/downloads/drops/S2019052119570 org.apache.httpcomponents.httpcore.source [4.4.10.v20190123-2214,4.4.10.v20190123-2214] org.apache.log4j [1.2.15.v201012070815,1.2.15.v201012070815] org.apache.log4j.source [1.2.15.v201012070815,1.2.15.v201012070815] - org.bouncycastle.bcpg [1.60.0.v20181210-2057,1.60.0.v20181210-2057] - org.bouncycastle.bcpg.source [1.60.0.v20181210-2057,1.60.0.v20181210-2057] - org.bouncycastle.bcpkix [1.60.0.v20181210-2057,1.60.0.v20181210-2057] - org.bouncycastle.bcpkix.source [1.60.0.v20181210-2057,1.60.0.v20181210-2057] - org.bouncycastle.bcprov [1.60.0.v20181210-2057,1.60.0.v20181210-2057] - org.bouncycastle.bcprov.source [1.60.0.v20181210-2057,1.60.0.v20181210-2057] + org.bouncycastle.bcpg [1.61.0.v20190602-1335,1.61.0.v20190602-1335] + org.bouncycastle.bcpg.source [1.61.0.v20190602-1335,1.61.0.v20190602-1335] + org.bouncycastle.bcpkix [1.61.0.v20190602-1335,1.61.0.v20190602-1335] + org.bouncycastle.bcpkix.source [1.61.0.v20190602-1335,1.61.0.v20190602-1335] + org.bouncycastle.bcprov [1.61.0.v20190602-1335,1.61.0.v20190602-1335] + org.bouncycastle.bcprov.source [1.61.0.v20190602-1335,1.61.0.v20190602-1335] 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.hamcrest [1.1.0.v20090501071000,1.1.0.v20090501071000] 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 b9982fe6a0..2a5a31eba8 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 @@ -222,6 +222,7 @@ unsupportedOperation=Unsupported operation: {0} untrackedFiles=Untracked files: 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_Blame=Show what revision and author last modified each line usage_Clean=Remove untracked files from the working tree @@ -289,6 +290,7 @@ usage_Status=Show the working tree status usage_StopTrackingAFile=Stop tracking a file usage_TextHashFunctions=Scan repository to compute maximum number of collisions for hash functions usage_UpdateRemoteRepositoryFromLocalRefs=Update remote repository from local refs +usage_UseTags=Use any tag including lightweight tags usage_WriteDirCache=Write the DirCache usage_abbrevCommits=abbreviate commits to N + 1 digits usage_abortConnectionIfNoActivity=abort connection if no activity diff --git a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/Checkout.java b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/Checkout.java index 7e1737f872..3df37e51c3 100644 --- a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/Checkout.java +++ b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/Checkout.java @@ -96,7 +96,7 @@ class Checkout extends TextBuiltin { try (Git git = new Git(db)) { CheckoutCommand command = git.checkout() .setProgressMonitor(new TextProgressMonitor(errw)); - if (paths.size() > 0) { + if (!paths.isEmpty()) { command.setStartPoint(name); if (paths.size() == 1 && paths.get(0).equals(".")) { //$NON-NLS-1$ command.setAllPaths(true); diff --git a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/Describe.java b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/Describe.java index d89fee6239..8a572f44b4 100644 --- a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/Describe.java +++ b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/Describe.java @@ -65,6 +65,12 @@ class Describe extends TextBuiltin { @Option(name = "--long", usage = "usage_LongFormat") private boolean longDesc; + @Option(name = "--tags", usage = "usage_UseTags") + private boolean useTags; + + @Option(name = "--always", usage = "usage_AlwaysFallback") + private boolean always; + @Option(name = "--match", usage = "usage_Match", metaVar = "metaVar_pattern") private List<String> patterns = new ArrayList<>(); @@ -77,6 +83,8 @@ class Describe extends TextBuiltin { cmd.setTarget(tree); } cmd.setLong(longDesc); + cmd.setTags(useTags); + cmd.setAlways(always); cmd.setMatch(patterns.toArray(new String[0])); String result = null; try { diff --git a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/LsFiles.java b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/LsFiles.java index ef25844973..e3ed30dc40 100644 --- a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/LsFiles.java +++ b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/LsFiles.java @@ -85,7 +85,7 @@ class LsFiles extends TextBuiltin { CanonicalTreeParser p = new CanonicalTreeParser(); p.reset(rw.getObjectReader(), c.getTree()); tw.reset(); // drop the first empty tree, which we do not need here - if (paths.size() > 0) { + if (!paths.isEmpty()) { tw.setFilter(PathFilterGroup.createFromStrings(paths)); } tw.addTree(p); diff --git a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/LsTree.java b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/LsTree.java index 2a2bb7cc91..19f2d7ae4f 100644 --- a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/LsTree.java +++ b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/LsTree.java @@ -76,7 +76,7 @@ class LsTree extends TextBuiltin { protected void run() { try (TreeWalk walk = new TreeWalk(db)) { walk.reset(); // drop the first empty tree, which we do not need here - if (paths.size() > 0) { + if (!paths.isEmpty()) { walk.setFilter(PathFilterGroup.createFromStrings(paths)); } walk.setRecursive(recursive); diff --git a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/Reset.java b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/Reset.java index b3e81c6d65..e1a290731c 100644 --- a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/Reset.java +++ b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/Reset.java @@ -80,7 +80,7 @@ class Reset extends TextBuiltin { try (Git git = new Git(db)) { ResetCommand command = git.reset(); command.setRef(commit); - if (paths.size() > 0) { + if (!paths.isEmpty()) { for (String path : paths) { command.addPath(path); } diff --git a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/Status.java b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/Status.java index 8b187587bc..c3887fe9c3 100644 --- a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/Status.java +++ b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/Status.java @@ -93,7 +93,7 @@ class Status extends TextBuiltin { protected void run() { try (Git git = new Git(db)) { StatusCommand statusCommand = git.status(); - if (filterPaths != null && filterPaths.size() > 0) { + if (filterPaths != null) { for (String path : filterPaths) { statusCommand.addPath(path); } diff --git a/org.eclipse.jgit.test/BUILD b/org.eclipse.jgit.test/BUILD index be4fdbdea9..5c0540fb9b 100644 --- a/org.eclipse.jgit.test/BUILD +++ b/org.eclipse.jgit.test/BUILD @@ -28,6 +28,7 @@ HELPERS = glob( "treewalk/filter/AlwaysCloneTreeFilter.java", "test/resources/SampleDataRepositoryTestCase.java", "util/CPUTimeStopWatch.java", + "util/http/HttpCookiesMatcher.java", "util/io/Strings.java", ]] diff --git a/org.eclipse.jgit.test/META-INF/MANIFEST.MF b/org.eclipse.jgit.test/META-INF/MANIFEST.MF index 73c8de8525..1c6211d53d 100644 --- a/org.eclipse.jgit.test/META-INF/MANIFEST.MF +++ b/org.eclipse.jgit.test/META-INF/MANIFEST.MF @@ -11,7 +11,7 @@ Bundle-RequiredExecutionEnvironment: JavaSE-1.8 Import-Package: com.googlecode.javaewah;version="[1.1.6,2.0.0)", com.jcraft.jsch;version="[0.1.54,0.2.0)", net.bytebuddy.dynamic.loading;version="[1.7.0,2.0.0)", - org.bouncycastle.util.encoders;version="[1.60.0,2.0.0)", + org.bouncycastle.util.encoders;version="[1.61.0,2.0.0)", org.eclipse.jgit.annotations;version="[5.4.0,5.5.0)", org.eclipse.jgit.api;version="[5.4.0,5.5.0)", org.eclipse.jgit.api.errors;version="[5.4.0,5.5.0)", @@ -35,6 +35,7 @@ Import-Package: com.googlecode.javaewah;version="[1.1.6,2.0.0)", org.eclipse.jgit.internal.storage.pack;version="[5.4.0,5.5.0)", org.eclipse.jgit.internal.storage.reftable;version="[5.4.0,5.5.0)", org.eclipse.jgit.internal.storage.reftree;version="[5.4.0,5.5.0)", + org.eclipse.jgit.internal.transport.http;version="[5.4.0,5.5.0)", org.eclipse.jgit.internal.transport.parser;version="[5.4.0,5.5.0)", org.eclipse.jgit.junit;version="[5.4.0,5.5.0)", org.eclipse.jgit.junit.ssh;version="[5.4.0,5.5.0)", diff --git a/org.eclipse.jgit.test/tests.bzl b/org.eclipse.jgit.test/tests.bzl index 6b5c7a1df1..d639a5bea1 100644 --- a/org.eclipse.jgit.test/tests.bzl +++ b/org.eclipse.jgit.test/tests.bzl @@ -7,6 +7,7 @@ def tests(tests): for src in tests: name = src[len("tst/"):len(src) - len(".java")].replace("/", "_") labels = [] + timeout = "moderate" if name.startswith("org_eclipse_jgit_"): l = name[len("org.eclipse.jgit_"):] if l.startswith("internal_storage_"): @@ -53,9 +54,15 @@ def tests(tests): additional_deps = [ "//lib:mockito", ] + if src.endswith("TransportHttpTest.java"): + additional_deps = [ + "//lib:mockito", + ] heap_size = "-Xmx256m" if src.endswith("HugeCommitMessageTest.java"): heap_size = "-Xmx512m" + if src.endswith("EolRepositoryTest.java") or src.endswith("GcCommitSelectionTest.java"): + timeout = "long" junit_tests( name = name, @@ -73,4 +80,5 @@ def tests(tests): ], flaky = flaky, jvm_flags = [heap_size, "-Dfile.encoding=UTF-8"], + timeout = timeout, ) diff --git a/org.eclipse.jgit.test/tst-rsrc/org/eclipse/jgit/internal/transport/http/cookies-invalid.txt b/org.eclipse.jgit.test/tst-rsrc/org/eclipse/jgit/internal/transport/http/cookies-invalid.txt new file mode 100644 index 0000000000..bbc6a7329a --- /dev/null +++ b/org.eclipse.jgit.test/tst-rsrc/org/eclipse/jgit/internal/transport/http/cookies-invalid.txt @@ -0,0 +1 @@ +some-domain /some/path1 FALSE 0 key1 value1
\ No newline at end of file diff --git a/org.eclipse.jgit.test/tst-rsrc/org/eclipse/jgit/internal/transport/http/cookies-simple1.txt b/org.eclipse.jgit.test/tst-rsrc/org/eclipse/jgit/internal/transport/http/cookies-simple1.txt new file mode 100644 index 0000000000..e06b38c712 --- /dev/null +++ b/org.eclipse.jgit.test/tst-rsrc/org/eclipse/jgit/internal/transport/http/cookies-simple1.txt @@ -0,0 +1,2 @@ +some-domain1 TRUE /some/path1 FALSE 1893499200000 key1 valueFromSimple1 +some-domain1 TRUE /some/path1 FALSE 1893499200000 key2 valueFromSimple1
\ No newline at end of file diff --git a/org.eclipse.jgit.test/tst-rsrc/org/eclipse/jgit/internal/transport/http/cookies-simple2.txt b/org.eclipse.jgit.test/tst-rsrc/org/eclipse/jgit/internal/transport/http/cookies-simple2.txt new file mode 100644 index 0000000000..4bf6723fda --- /dev/null +++ b/org.eclipse.jgit.test/tst-rsrc/org/eclipse/jgit/internal/transport/http/cookies-simple2.txt @@ -0,0 +1,2 @@ +some-domain1 TRUE /some/path1 FALSE 1893499200000 key1 valueFromSimple2 +some-domain1 TRUE /some/path1 FALSE 1893499200000 key3 valueFromSimple2
\ No newline at end of file diff --git a/org.eclipse.jgit.test/tst-rsrc/org/eclipse/jgit/internal/transport/http/cookies-with-empty-and-comment-lines.txt b/org.eclipse.jgit.test/tst-rsrc/org/eclipse/jgit/internal/transport/http/cookies-with-empty-and-comment-lines.txt new file mode 100644 index 0000000000..a9b8a28153 --- /dev/null +++ b/org.eclipse.jgit.test/tst-rsrc/org/eclipse/jgit/internal/transport/http/cookies-with-empty-and-comment-lines.txt @@ -0,0 +1,8 @@ +# first line is a comment +# the next cookie is supposed to be removed, because it has expired already +some-domain1 TRUE /some/path1 FALSE 0 key1 value1 + +# expires date is 01/01/2030 @ 12:00am (UTC) +#HttpOnly_.some-domain2 TRUE /some/path2 TRUE 1893499200000 key2 value2 + +some-domain3 TRUE /some/path3 FALSE 1893499200000 key3 value3
\ No newline at end of file diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/CleanCommandTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/CleanCommandTest.java index 4eeaf4d6e4..c9852e8b83 100644 --- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/CleanCommandTest.java +++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/CleanCommandTest.java @@ -98,7 +98,7 @@ public class CleanCommandTest extends RepositoryTestCase { StatusCommand command = git.status(); Status status = command.call(); Set<String> files = status.getUntracked(); - assertTrue(files.size() > 0); + assertFalse(files.isEmpty()); // run clean Set<String> cleanedFiles = git.clean().call(); @@ -120,7 +120,7 @@ public class CleanCommandTest extends RepositoryTestCase { StatusCommand command = git.status(); Status status = command.call(); Set<String> files = status.getUntracked(); - assertTrue(files.size() > 0); + assertFalse(files.isEmpty()); // run clean Set<String> cleanedFiles = git.clean().setCleanDirectories(true).call(); @@ -143,7 +143,7 @@ public class CleanCommandTest extends RepositoryTestCase { StatusCommand command = git.status(); Status status = command.call(); Set<String> files = status.getUntracked(); - assertTrue(files.size() > 0); + assertFalse(files.isEmpty()); // run clean with setPaths Set<String> paths = new TreeSet<>(); @@ -164,7 +164,7 @@ public class CleanCommandTest extends RepositoryTestCase { StatusCommand command = git.status(); Status status = command.call(); Set<String> files = status.getUntracked(); - assertTrue(files.size() > 0); + assertFalse(files.isEmpty()); // run clean Set<String> cleanedFiles = git.clean().setDryRun(true).call(); @@ -186,7 +186,7 @@ public class CleanCommandTest extends RepositoryTestCase { StatusCommand command = git.status(); Status status = command.call(); Set<String> files = status.getUntracked(); - assertTrue(files.size() > 0); + assertFalse(files.isEmpty()); // run clean Set<String> cleanedFiles = git.clean().setDryRun(true) diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/CloneCommandTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/CloneCommandTest.java index 1523b49ecc..74d13883e1 100644 --- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/CloneCommandTest.java +++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/CloneCommandTest.java @@ -718,6 +718,34 @@ public class CloneCommandTest extends RepositoryTestCase { } + @Test + public void testCloneWithPullMerge() throws Exception { + File directory = createTempDirectory("testCloneRepository1"); + try (Git g = Git.init().setDirectory(directory).setBare(false).call()) { + g.remoteAdd().setName(Constants.DEFAULT_REMOTE_NAME) + .setUri(new URIish(fileUri())).call(); + PullResult result = g.pull().setRebase(false).call(); + assertTrue(result.isSuccessful()); + assertEquals("refs/heads/master", + g.getRepository().getFullBranch()); + checkFile(new File(directory, "Test.txt"), "Hello world"); + } + } + + @Test + public void testCloneWithPullRebase() throws Exception { + File directory = createTempDirectory("testCloneRepository1"); + try (Git g = Git.init().setDirectory(directory).setBare(false).call()) { + g.remoteAdd().setName(Constants.DEFAULT_REMOTE_NAME) + .setUri(new URIish(fileUri())).call(); + PullResult result = g.pull().setRebase(true).call(); + assertTrue(result.isSuccessful()); + assertEquals("refs/heads/master", + g.getRepository().getFullBranch()); + checkFile(new File(directory, "Test.txt"), "Hello world"); + } + } + private String fileUri() { return "file://" + git.getRepository().getWorkTree().getAbsolutePath(); } diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/CommitCommandTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/CommitCommandTest.java index 4bfac1505a..18fed4bff7 100644 --- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/CommitCommandTest.java +++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/CommitCommandTest.java @@ -661,6 +661,54 @@ public class CommitCommandTest extends RepositoryTestCase { } } + @Test + public void testDeletionConflictWithAutoCrlf() throws Exception { + try (Git git = new Git(db)) { + // Commit a file with CR/LF into the index + FileBasedConfig config = db.getConfig(); + config.setString("core", null, "autocrlf", "false"); + config.save(); + File file = writeTrashFile("file.txt", "foo\r\n"); + git.add().addFilepattern("file.txt").call(); + git.commit().setMessage("Initial").call(); + // Switch to side branch + git.checkout().setCreateBranch(true).setName("side").call(); + assertTrue(file.delete()); + git.rm().addFilepattern("file.txt").call(); + git.commit().setMessage("Side").call(); + // Switch on autocrlf=true + config.setString("core", null, "autocrlf", "true"); + config.save(); + // Switch back to master and commit a conflict + git.checkout().setName("master").call(); + writeTrashFile("file.txt", "foob\r\n"); + git.add().addFilepattern("file.txt").call(); + assertEquals("[file.txt, mode:100644, content:foob\r\n]", + indexState(CONTENT)); + writeTrashFile("g", "file2.txt", "anything"); + git.add().addFilepattern("g/file2.txt"); + RevCommit master = git.commit().setMessage("Second").call(); + // Switch to side branch again so that the deletion is "ours" + git.checkout().setName("side").call(); + // Cherry pick master: produces a delete-modify conflict. + CherryPickResult pick = git.cherryPick().include(master).call(); + assertEquals("Expected a cherry-pick conflict", + CherryPickStatus.CONFLICTING, pick.getStatus()); + // XXX: g/file2.txt should actually be staged already, but isn't. + git.add().addFilepattern("g/file2.txt").call(); + // Resolve the conflict by taking the master version + writeTrashFile("file.txt", "foob\r\n"); + git.add().addFilepattern("file.txt").call(); + git.commit().setMessage("Cherry").call(); + // We expect this to be committed with a single LF since there is no + // "ours" stage. + assertEquals( + "[file.txt, mode:100644, content:foob\n]" + + "[g/file2.txt, mode:100644, content:anything]", + indexState(CONTENT)); + } + } + private void testConflictWithAutoCrlf(String baseLf, String lf) throws Exception { try (Git git = new Git(db)) { diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/DescribeCommandTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/DescribeCommandTest.java index bc3ac7a723..df9ae6a0fb 100644 --- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/DescribeCommandTest.java +++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/DescribeCommandTest.java @@ -109,7 +109,7 @@ public class DescribeCommandTest extends RepositoryTestCase { assertNameStartsWith(c4, "3e563c5"); assertNull(describe(c1)); - assertNull(describe(c1, true)); + assertNull(describe(c1, true, false)); assertNull(describe(c1, "a*", "b*", "c*")); assertNull(describe(c2, "bob*")); assertNull(describe(c2, "?ob*")); @@ -120,7 +120,7 @@ public class DescribeCommandTest extends RepositoryTestCase { assertEquals("alice-t1", describe(c2, "a*", "b*", "c*")); assertEquals("bob-t2", describe(c3)); - assertEquals("bob-t2-0-g44579eb", describe(c3, true)); + assertEquals("bob-t2-0-g44579eb", describe(c3, true, false)); assertEquals("alice-t1-1-g44579eb", describe(c3, "alice*")); assertEquals("alice-t1-1-g44579eb", describe(c3, "a??c?-t*")); assertEquals("bob-t2", describe(c3, "bob*")); @@ -129,7 +129,7 @@ public class DescribeCommandTest extends RepositoryTestCase { // the value verified with git-describe(1) assertEquals("bob-t2-1-g3e563c5", describe(c4)); - assertEquals("bob-t2-1-g3e563c5", describe(c4, true)); + assertEquals("bob-t2-1-g3e563c5", describe(c4, true, false)); assertEquals("alice-t1-2-g3e563c5", describe(c4, "alice*")); assertEquals("bob-t2-1-g3e563c5", describe(c4, "bob*")); assertEquals("bob-t2-1-g3e563c5", describe(c4, "a*", "b*", "c*")); @@ -137,6 +137,10 @@ public class DescribeCommandTest extends RepositoryTestCase { assertEquals(null, describe(c2)); assertEquals(null, describe(c3)); assertEquals(null, describe(c4)); + + assertEquals("3747db3", describe(c2, false, true)); + assertEquals("44579eb", describe(c3, false, true)); + assertEquals("3e563c5", describe(c4, false, true)); } // test default target @@ -169,6 +173,10 @@ public class DescribeCommandTest extends RepositoryTestCase { if (!useAnnotatedTags && !describeUseAllTags) { assertEquals(null, describe(c1)); assertEquals(null, describe(c2)); + + assertEquals("fd70040", describe(c1, false, true)); + assertEquals("b89dead", describe(c2, false, true)); + return; } @@ -235,9 +243,11 @@ public class DescribeCommandTest extends RepositoryTestCase { assertEquals("2 commits: c4 and c3", "t-2-g119892b", describe(c4)); } else { assertEquals(null, describe(c4)); + + assertEquals("119892b", describe(c4, false, true)); } assertNull(describe(c3)); - assertNull(describe(c3, true)); + assertNull(describe(c3, true, false)); } private void branch(String name, ObjectId base) throws GitAPIException { @@ -279,6 +289,9 @@ public class DescribeCommandTest extends RepositoryTestCase { } else { assertEquals(null, describe(c4)); assertEquals(null, describe(c3)); + + assertEquals("119892b", describe(c4, false, true)); + assertEquals("0244e7f", describe(c3, false, true)); } } @@ -368,6 +381,8 @@ public class DescribeCommandTest extends RepositoryTestCase { assertEquals("t1-3-gbb389a4", describe(c4)); } else { assertEquals(null, describe(c4)); + + assertEquals("bb389a4", describe(c4, false, true)); } } @@ -401,6 +416,25 @@ public class DescribeCommandTest extends RepositoryTestCase { assertEquals("t2-4-gbb389a4", describe(c4)); } else { assertEquals(null, describe(c4)); + + assertEquals("bb389a4", describe(c4, false, true)); + } + } + + @Test + public void globMatchWithSlashes() throws Exception { + ObjectId c1 = modify("aaa"); + tag("a/b/version"); + ObjectId c2 = modify("bbb"); + tag("a/b/version2"); + if (useAnnotatedTags || describeUseAllTags) { + assertEquals("a/b/version", describe(c1, "*/version*")); + assertEquals("a/b/version2", describe(c2, "*/version*")); + } else { + assertNull(describe(c1)); + assertNull(describe(c1, "*/version*")); + assertNull(describe(c2)); + assertNull(describe(c2, "*/version*")); } } @@ -433,14 +467,14 @@ public class DescribeCommandTest extends RepositoryTestCase { } } - private String describe(ObjectId c1, boolean longDesc) + private String describe(ObjectId c1, boolean longDesc, boolean always) throws GitAPIException, IOException { return git.describe().setTarget(c1).setTags(describeUseAllTags) - .setLong(longDesc).call(); + .setLong(longDesc).setAlways(always).call(); } private String describe(ObjectId c1) throws GitAPIException, IOException { - return describe(c1, false); + return describe(c1, false, false); } private String describe(ObjectId c1, String... patterns) throws Exception { diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/file/GcPackRefsTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/file/GcPackRefsTest.java index 1fa5aa09ad..54708da03c 100644 --- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/file/GcPackRefsTest.java +++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/file/GcPackRefsTest.java @@ -176,12 +176,13 @@ public class GcPackRefsTest extends GcTestCase { return update.update(); }); - pool.submit(() -> { + Future<Result> result2 = pool.submit(() -> { refUpdateLockedRef.await(); gc.packRefs(); packRefsDone.await(); return null; }); + assertNull(result2.get()); assertSame(result.get(), Result.FORCED); diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/transport/http/NetscapeCookieFileTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/transport/http/NetscapeCookieFileTest.java new file mode 100644 index 0000000000..0a3f89e238 --- /dev/null +++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/transport/http/NetscapeCookieFileTest.java @@ -0,0 +1,339 @@ +/* + * Copyright (C) 2018, Konrad Windszus <konrad_w@gmx.de> + * and other copyright owners as documented in the project's IP log. + * + * This program and the accompanying materials are made available + * under the terms of the Eclipse Distribution License v1.0 which + * accompanies this distribution, is reproduced below, and is + * available at http://www.eclipse.org/org/documents/edl-v10.php + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or + * without modification, are permitted provided that the following + * conditions are met: + * + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * - Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials provided + * with the distribution. + * + * - Neither the name of the Eclipse Foundation, Inc. nor the + * names of its contributors may be used to endorse or promote + * products derived from this software without specific prior + * written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +package org.eclipse.jgit.internal.transport.http; + +import java.io.IOException; +import java.io.InputStream; +import java.io.Writer; +import java.net.HttpCookie; +import java.net.URL; +import java.nio.charset.StandardCharsets; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.StandardCopyOption; +import java.time.Instant; +import java.util.Arrays; +import java.util.Date; +import java.util.LinkedHashSet; +import java.util.List; +import java.util.Set; +import java.util.regex.Pattern; + +import org.eclipse.jgit.internal.storage.file.LockFile; +import org.eclipse.jgit.internal.transport.http.NetscapeCookieFile; +import org.eclipse.jgit.util.http.HttpCookiesMatcher; +import org.hamcrest.CoreMatchers; +import org.junit.Assert; +import org.junit.Before; +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.TemporaryFolder; + +public class NetscapeCookieFileTest { + + @Rule + public TemporaryFolder folder = new TemporaryFolder(); + + private Path tmpFile; + + private URL baseUrl; + + /** + * This is the expiration date that is used in the test cookie files + */ + private static long JAN_01_2030_NOON = Instant + .parse("2030-01-01T12:00:00.000Z").toEpochMilli(); + + @Before + public void setUp() throws IOException { + // this will not only return a new file name but also create new empty + // file! + tmpFile = folder.newFile().toPath(); + baseUrl = new URL("http://domain.com/my/path"); + } + + @Test + public void testMergeCookies() { + Set<HttpCookie> cookieSet1 = new LinkedHashSet<>(); + HttpCookie cookie = new HttpCookie("key1", "valueFromSet1"); + cookieSet1.add(cookie); + cookie = new HttpCookie("key2", "valueFromSet1"); + cookieSet1.add(cookie); + + Set<HttpCookie> cookieSet2 = new LinkedHashSet<>(); + cookie = new HttpCookie("key1", "valueFromSet2"); + cookieSet2.add(cookie); + cookie = new HttpCookie("key3", "valueFromSet2"); + cookieSet2.add(cookie); + + Set<HttpCookie> cookiesExpectedMergedSet = new LinkedHashSet<>(); + cookie = new HttpCookie("key1", "valueFromSet1"); + cookiesExpectedMergedSet.add(cookie); + cookie = new HttpCookie("key2", "valueFromSet1"); + cookiesExpectedMergedSet.add(cookie); + cookie = new HttpCookie("key3", "valueFromSet2"); + cookiesExpectedMergedSet.add(cookie); + + Assert.assertThat( + NetscapeCookieFile.mergeCookies(cookieSet1, cookieSet2), + HttpCookiesMatcher.containsInOrder(cookiesExpectedMergedSet)); + + Assert.assertThat(NetscapeCookieFile.mergeCookies(cookieSet1, null), + HttpCookiesMatcher.containsInOrder(cookieSet1)); + } + + @Test + public void testWriteToNewFile() throws IOException { + Set<HttpCookie> cookies = new LinkedHashSet<>(); + cookies.add(new HttpCookie("key1", "value")); + // first cookie is a session cookie (and should be ignored) + + HttpCookie cookie = new HttpCookie("key2", "value"); + cookie.setSecure(true); + cookie.setDomain("mydomain.com"); + cookie.setPath("/"); + cookie.setMaxAge(1000); + cookies.add(cookie); + Date creationDate = new Date(); + try (Writer writer = Files.newBufferedWriter(tmpFile, + StandardCharsets.US_ASCII)) { + NetscapeCookieFile.write(writer, cookies, baseUrl, creationDate); + } + + String expectedExpiration = String + .valueOf(creationDate.getTime() + (cookie.getMaxAge() * 1000)); + + Assert.assertThat( + Files.readAllLines(tmpFile, StandardCharsets.US_ASCII), + CoreMatchers + .equalTo(Arrays.asList("mydomain.com\tTRUE\t/\tTRUE\t" + + expectedExpiration + "\tkey2\tvalue"))); + } + + @Test + public void testWriteToExistingFile() throws IOException { + try (InputStream input = this.getClass() + .getResourceAsStream("cookies-simple1.txt")) { + Files.copy(input, tmpFile, StandardCopyOption.REPLACE_EXISTING); + } + + Set<HttpCookie> cookies = new LinkedHashSet<>(); + HttpCookie cookie = new HttpCookie("key2", "value2"); + cookie.setMaxAge(1000); + cookies.add(cookie); + Date creationDate = new Date(); + try (Writer writer = Files.newBufferedWriter(tmpFile, + StandardCharsets.US_ASCII)) { + NetscapeCookieFile.write(writer, cookies, baseUrl, creationDate); + } + String expectedExpiration = String + .valueOf(creationDate.getTime() + (cookie.getMaxAge() * 1000)); + + Assert.assertThat( + Files.readAllLines(tmpFile, StandardCharsets.US_ASCII), + CoreMatchers.equalTo( + Arrays.asList("domain.com\tTRUE\t/my/path\tFALSE\t" + + expectedExpiration + "\tkey2\tvalue2"))); + } + + @Test(expected = IOException.class) + public void testWriteWhileSomeoneIsHoldingTheLock() + throws IllegalArgumentException, IOException, InterruptedException { + try (InputStream input = this.getClass() + .getResourceAsStream("cookies-simple1.txt")) { + Files.copy(input, tmpFile, StandardCopyOption.REPLACE_EXISTING); + } + NetscapeCookieFile cookieFile = new NetscapeCookieFile(tmpFile); + // now imitate another process/thread holding the lock file + LockFile lockFile = new LockFile(tmpFile.toFile()); + try { + Assert.assertTrue("Could not acquire lock", lockFile.lock()); + cookieFile.write(baseUrl); + } finally { + lockFile.unlock(); + } + } + + @Test + public void testWriteAfterAnotherJgitProcessModifiedTheFile() + throws IOException, InterruptedException { + try (InputStream input = this.getClass() + .getResourceAsStream("cookies-simple1.txt")) { + Files.copy(input, tmpFile, StandardCopyOption.REPLACE_EXISTING); + } + NetscapeCookieFile cookieFile = new NetscapeCookieFile(tmpFile); + cookieFile.getCookies(true); + // now modify file externally + try (InputStream input = this.getClass() + .getResourceAsStream("cookies-simple2.txt")) { + Files.copy(input, tmpFile, StandardCopyOption.REPLACE_EXISTING); + } + // now try to write + cookieFile.write(baseUrl); + + // validate that the external changes are there as well + // due to rounding errors (conversion from ms to sec to ms) + // the expiration date might not be exact + List<String> lines = Files.readAllLines(tmpFile, + StandardCharsets.US_ASCII); + + Assert.assertEquals("Expected 3 lines", 3, lines.size()); + assertStringMatchesPatternWithInexactNumber(lines.get(0), + "some-domain1\tTRUE\t/some/path1\tFALSE\t(\\d*)\tkey1\tvalueFromSimple2", + JAN_01_2030_NOON, 1000); + assertStringMatchesPatternWithInexactNumber(lines.get(1), + "some-domain1\tTRUE\t/some/path1\tFALSE\t(\\d*)\tkey3\tvalueFromSimple2", + JAN_01_2030_NOON, 1000); + assertStringMatchesPatternWithInexactNumber(lines.get(2), + "some-domain1\tTRUE\t/some/path1\tFALSE\t(\\d*)\tkey2\tvalueFromSimple1", + JAN_01_2030_NOON, 1000); + } + + @SuppressWarnings("boxing") + private static final void assertStringMatchesPatternWithInexactNumber( + String string, String pattern, long expectedNumericValue, + long delta) { + java.util.regex.Matcher matcher = Pattern.compile(pattern) + .matcher(string); + Assert.assertTrue("Given string '" + string + "' does not match '" + + pattern + "'", matcher.matches()); + // extract numeric value + Long actualNumericValue = Long.decode(matcher.group(1)); + + Assert.assertTrue( + "Value is supposed to be close to " + expectedNumericValue + + " but is " + actualNumericValue + ".", + Math.abs(expectedNumericValue - actualNumericValue) <= delta); + } + + @Test + public void testWriteAndReadCycle() throws IOException { + Set<HttpCookie> cookies = new LinkedHashSet<>(); + + HttpCookie cookie = new HttpCookie("key1", "value1"); + cookie.setPath("/some/path1"); + cookie.setDomain("some-domain1"); + cookie.setMaxAge(1000); + cookies.add(cookie); + cookie = new HttpCookie("key2", "value2"); + cookie.setSecure(true); + cookie.setPath("/some/path2"); + cookie.setDomain("some-domain2"); + cookie.setMaxAge(1000); + cookie.setHttpOnly(true); + cookies.add(cookie); + + Date creationDate = new Date(); + + try (Writer writer = Files.newBufferedWriter(tmpFile, + StandardCharsets.US_ASCII)) { + NetscapeCookieFile.write(writer, cookies, baseUrl, creationDate); + } + Set<HttpCookie> actualCookies = new NetscapeCookieFile(tmpFile, + creationDate).getCookies(true); + Assert.assertThat(actualCookies, + HttpCookiesMatcher.containsInOrder(cookies)); + } + + @Test + public void testReadAndWriteCycle() throws IOException { + try (InputStream input = this.getClass() + .getResourceAsStream("cookies-simple1.txt")) { + Files.copy(input, tmpFile, StandardCopyOption.REPLACE_EXISTING); + } + // round up to the next second (to prevent rounding errors) + Date creationDate = new Date( + (System.currentTimeMillis() / 1000) * 1000); + Set<HttpCookie> cookies = new NetscapeCookieFile(tmpFile, creationDate) + .getCookies(true); + Path tmpFile2 = folder.newFile().toPath(); + try (Writer writer = Files.newBufferedWriter(tmpFile2, + StandardCharsets.US_ASCII)) { + NetscapeCookieFile.write(writer, cookies, baseUrl, creationDate); + } + // compare original file with newly written one, they should not differ + Assert.assertEquals(Files.readAllLines(tmpFile), + Files.readAllLines(tmpFile2)); + } + + @Test + public void testReadWithEmptyAndCommentLines() throws IOException { + try (InputStream input = this.getClass().getResourceAsStream( + "cookies-with-empty-and-comment-lines.txt")) { + Files.copy(input, tmpFile, StandardCopyOption.REPLACE_EXISTING); + } + + Date creationDate = new Date(); + Set<HttpCookie> cookies = new LinkedHashSet<>(); + + HttpCookie cookie = new HttpCookie("key2", "value2"); + cookie.setDomain("some-domain2"); + cookie.setPath("/some/path2"); + cookie.setMaxAge((JAN_01_2030_NOON - creationDate.getTime()) / 1000); + cookie.setSecure(true); + cookie.setHttpOnly(true); + cookies.add(cookie); + + cookie = new HttpCookie("key3", "value3"); + cookie.setDomain("some-domain3"); + cookie.setPath("/some/path3"); + cookie.setMaxAge((JAN_01_2030_NOON - creationDate.getTime()) / 1000); + cookies.add(cookie); + + Set<HttpCookie> actualCookies = new NetscapeCookieFile(tmpFile, creationDate) + .getCookies(true); + Assert.assertThat(actualCookies, + HttpCookiesMatcher.containsInOrder(cookies)); + } + + @Test + public void testReadInvalidFile() throws IOException { + try (InputStream input = this.getClass() + .getResourceAsStream("cookies-invalid.txt")) { + Files.copy(input, tmpFile, StandardCopyOption.REPLACE_EXISTING); + } + + new NetscapeCookieFile(tmpFile) + .getCookies(true); + } +} diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/lib/ConfigTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/lib/ConfigTest.java index 5a4bd886ab..e3985cc970 100644 --- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/lib/ConfigTest.java +++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/lib/ConfigTest.java @@ -1457,6 +1457,41 @@ public class ConfigTest { parse("[foo \"bar\" ]\nfoo=bar\n"); } + @Test + public void testCrLf() throws ConfigInvalidException { + assertEquals("true", parseEscapedValue("true\r\n")); + } + + @Test + public void testLfContinuation() throws ConfigInvalidException { + assertEquals("true", parseEscapedValue("tr\\\nue")); + } + + @Test + public void testCrCharContinuation() throws ConfigInvalidException { + expectedEx.expect(ConfigInvalidException.class); + expectedEx.expectMessage("Bad escape: \\u000d"); + parseEscapedValue("tr\\\rue"); + } + + @Test + public void testCrEOFContinuation() throws ConfigInvalidException { + expectedEx.expect(ConfigInvalidException.class); + expectedEx.expectMessage("Bad escape: \\u000d"); + parseEscapedValue("tr\\\r"); + } + + @Test + public void testCrLfContinuation() throws ConfigInvalidException { + assertEquals("true", parseEscapedValue("tr\\\r\nue")); + } + + @Test + public void testWhitespaceContinuation() throws ConfigInvalidException { + assertEquals("tr ue", parseEscapedValue("tr \\\n ue")); + assertEquals("tr ue", parseEscapedValue("tr \\\r\n ue")); + } + private static void assertValueRoundTrip(String value) throws ConfigInvalidException { assertValueRoundTrip(value, value); diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/lib/RebaseTodoFileTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/lib/RebaseTodoFileTest.java new file mode 100644 index 0000000000..5cfc75ca93 --- /dev/null +++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/lib/RebaseTodoFileTest.java @@ -0,0 +1,142 @@ +/* + * Copyright (C) 2019, Thomas Wolf <thomas.wolf@paranor.ch> + * and other copyright owners as documented in the project's IP log. + * + * This program and the accompanying materials are made available + * under the terms of the Eclipse Distribution License v1.0 which + * accompanies this distribution, is reproduced below, and is + * available at http://www.eclipse.org/org/documents/edl-v10.php + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or + * without modification, are permitted provided that the following + * conditions are met: + * + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * - Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials provided + * with the distribution. + * + * - Neither the name of the Eclipse Foundation, Inc. nor the + * names of its contributors may be used to endorse or promote + * products derived from this software without specific prior + * written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +package org.eclipse.jgit.lib; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.fail; + +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.util.Arrays; +import java.util.List; + +import org.eclipse.jgit.junit.RepositoryTestCase; +import org.junit.Test; + +public class RebaseTodoFileTest extends RepositoryTestCase { + + private static final String TEST_TODO = "test.todo"; + + private void createTodoList(String... lines) throws IOException { + Path p = Paths.get(db.getDirectory().getAbsolutePath(), TEST_TODO); + Files.write(p, Arrays.asList(lines)); + } + + @Test + public void testReadTodoFile() throws Exception { + String[] expected = { "reword " + ObjectId.zeroId().name() + " Foo", + "# A comment in the the todo list", + "pick " + ObjectId.zeroId().name() + " Foo fie", + "squash " + ObjectId.zeroId().name() + " F", + "fixup " + ObjectId.zeroId().name(), + "edit " + ObjectId.zeroId().name() + " f", + "edit " + ObjectId.zeroId().name() + ' ' }; + createTodoList(expected); + RebaseTodoFile todo = new RebaseTodoFile(db); + List<RebaseTodoLine> lines = todo.readRebaseTodo(TEST_TODO, true); + assertEquals("Expected 7 lines", 7, lines.size()); + int i = 0; + for (RebaseTodoLine line : lines) { + switch (i) { + case 0: + assertEquals("Expected REWORD", RebaseTodoLine.Action.REWORD, + line.getAction()); + assertEquals("Unexpected ID", ObjectId.zeroId().abbreviate(40), + line.getCommit()); + assertEquals("Unexpected Message", "Foo", + line.getShortMessage()); + break; + case 1: + assertEquals("Expected COMMENT", RebaseTodoLine.Action.COMMENT, + line.getAction()); + assertEquals("Unexpected Message", + "# A comment in the the todo list", + line.getComment()); + break; + case 2: + assertEquals("Expected PICK", RebaseTodoLine.Action.PICK, + line.getAction()); + assertEquals("Unexpected ID", ObjectId.zeroId().abbreviate(40), + line.getCommit()); + assertEquals("Unexpected Message", "Foo fie", + line.getShortMessage()); + break; + case 3: + assertEquals("Expected SQUASH", RebaseTodoLine.Action.SQUASH, + line.getAction()); + assertEquals("Unexpected ID", ObjectId.zeroId().abbreviate(40), + line.getCommit()); + assertEquals("Unexpected Message", "F", line.getShortMessage()); + break; + case 4: + assertEquals("Expected FIXUP", RebaseTodoLine.Action.FIXUP, + line.getAction()); + assertEquals("Unexpected ID", ObjectId.zeroId().abbreviate(40), + line.getCommit()); + assertEquals("Unexpected Message", "", line.getShortMessage()); + break; + case 5: + assertEquals("Expected EDIT", RebaseTodoLine.Action.EDIT, + line.getAction()); + assertEquals("Unexpected ID", ObjectId.zeroId().abbreviate(40), + line.getCommit()); + assertEquals("Unexpected Message", "f", line.getShortMessage()); + break; + case 6: + assertEquals("Expected EDIT", RebaseTodoLine.Action.EDIT, + line.getAction()); + assertEquals("Unexpected ID", ObjectId.zeroId().abbreviate(40), + line.getCommit()); + assertEquals("Unexpected Message", "", line.getShortMessage()); + break; + default: + fail("Too many lines"); + return; + } + i++; + } + } +} diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/revwalk/BitmapCalculatorTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/revwalk/BitmapCalculatorTest.java index 3a78e1e623..c5d4d4238d 100644 --- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/revwalk/BitmapCalculatorTest.java +++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/revwalk/BitmapCalculatorTest.java @@ -1,3 +1,45 @@ +/* + * Copyright (C) 2019, Google LLC. + * and other copyright owners as documented in the project's IP log. + * + * This program and the accompanying materials are made available + * under the terms of the Eclipse Distribution License v1.0 which + * accompanies this distribution, is reproduced below, and is + * available at http://www.eclipse.org/org/documents/edl-v10.php + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or + * without modification, are permitted provided that the following + * conditions are met: + * + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * - Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials provided + * with the distribution. + * + * - Neither the name of the Eclipse Foundation, Inc. nor the + * names of its contributors may be used to endorse or promote + * products derived from this software without specific prior + * written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ package org.eclipse.jgit.revwalk; import static org.junit.Assert.assertEquals; diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/transport/PacketLineInTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/transport/PacketLineInTest.java index 8b1d860059..f512d2849b 100644 --- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/transport/PacketLineInTest.java +++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/transport/PacketLineInTest.java @@ -44,7 +44,8 @@ package org.eclipse.jgit.transport; import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNotSame; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; import static org.junit.Assert.assertSame; import static org.junit.Assert.fail; @@ -142,21 +143,21 @@ public class PacketLineInTest { init("0004"); final String act = in.readString(); assertEquals("", act); - assertNotSame(PacketLineIn.END, act); + assertFalse(PacketLineIn.isEnd(act)); assertEOF(); } @Test public void testReadString_End() throws IOException { init("0000"); - assertSame(PacketLineIn.END, in.readString()); + assertTrue(PacketLineIn.isEnd(in.readString())); assertEOF(); } @Test public void testReadString_Delim() throws IOException { init("0001"); - assertSame(PacketLineIn.DELIM, in.readString()); + assertTrue(PacketLineIn.isDelimiter(in.readString())); assertEOF(); } @@ -183,14 +184,14 @@ public class PacketLineInTest { init("0004"); final String act = in.readStringRaw(); assertEquals("", act); - assertNotSame(PacketLineIn.END, act); + assertFalse(PacketLineIn.isEnd(act)); assertEOF(); } @Test public void testReadStringRaw_End() throws IOException { init("0000"); - assertSame(PacketLineIn.END, in.readStringRaw()); + assertTrue(PacketLineIn.isEnd(in.readString())); assertEOF(); } diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/transport/ProtocolV0ParserTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/transport/ProtocolV0ParserTest.java index 28a9c03ecc..6e8327c792 100644 --- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/transport/ProtocolV0ParserTest.java +++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/transport/ProtocolV0ParserTest.java @@ -64,9 +64,9 @@ public class ProtocolV0ParserTest { ByteArrayOutputStream send = new ByteArrayOutputStream(); PacketLineOut pckOut = new PacketLineOut(send); for (String line : inputLines) { - if (line == PacketLineIn.END) { + if (PacketLineIn.isEnd(line)) { pckOut.end(); - } else if (line == PacketLineIn.DELIM) { + } else if (PacketLineIn.isDelimiter(line)) { pckOut.writeDelim(); } else { pckOut.writeString(line); @@ -90,7 +90,7 @@ public class ProtocolV0ParserTest { "4624442d68ee402a94364191085b77137618633e", "thin-pack", "no-progress", "include-tag", "ofs-delta", "\n"), "want f900c8326a43303685c46b279b9f70411bff1a4b\n", - PacketLineIn.END); + PacketLineIn.end()); ProtocolV0Parser parser = new ProtocolV0Parser(defaultConfig()); FetchV0Request request = parser.recvWants(pckIn); assertTrue(request.getClientCapabilities() @@ -114,7 +114,7 @@ public class ProtocolV0ParserTest { "4624442d68ee402a94364191085b77137618633e", "thin-pack", "agent=JGit.test/0.0.1", "\n"), "want f900c8326a43303685c46b279b9f70411bff1a4b\n", - PacketLineIn.END); + PacketLineIn.end()); ProtocolV0Parser parser = new ProtocolV0Parser(defaultConfig()); FetchV0Request request = parser.recvWants(pckIn); assertTrue(request.getClientCapabilities() @@ -136,7 +136,7 @@ public class ProtocolV0ParserTest { PacketLineIn pckIn = formatAsPacketLine( "want 4624442d68ee402a94364191085b77137618633e\n", "want f900c8326a43303685c46b279b9f70411bff1a4b\n", - PacketLineIn.END); + PacketLineIn.end()); ProtocolV0Parser parser = new ProtocolV0Parser(defaultConfig()); FetchV0Request request = parser.recvWants(pckIn); assertTrue(request.getClientCapabilities().isEmpty()); @@ -151,7 +151,7 @@ public class ProtocolV0ParserTest { PacketLineIn pckIn = formatAsPacketLine( "want 4624442d68ee402a94364191085b77137618633e\n", "want f900c8326a43303685c46b279b9f70411bff1a4b\n", "deepen 3\n", - PacketLineIn.END); + PacketLineIn.end()); ProtocolV0Parser parser = new ProtocolV0Parser(defaultConfig()); FetchV0Request request = parser.recvWants(pckIn); assertTrue(request.getClientCapabilities().isEmpty()); @@ -168,7 +168,7 @@ public class ProtocolV0ParserTest { "want 4624442d68ee402a94364191085b77137618633e\n", "want f900c8326a43303685c46b279b9f70411bff1a4b\n", "shallow 4b643d0ef739a1b494e7d6926d8d8ed80d35edf4\n", - PacketLineIn.END); + PacketLineIn.end()); ProtocolV0Parser parser = new ProtocolV0Parser(defaultConfig()); FetchV0Request request = parser.recvWants(pckIn); assertTrue(request.getClientCapabilities().isEmpty()); @@ -186,7 +186,7 @@ public class ProtocolV0ParserTest { "want 4624442d68ee402a94364191085b77137618633e\n", "want f900c8326a43303685c46b279b9f70411bff1a4b\n", "filter blob:limit=13000\n", - PacketLineIn.END); + PacketLineIn.end()); ProtocolV0Parser parser = new ProtocolV0Parser(defaultConfig()); FetchV0Request request = parser.recvWants(pckIn); assertTrue(request.getClientCapabilities().isEmpty()); diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/transport/ProtocolV2ParserTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/transport/ProtocolV2ParserTest.java index 740d92ef4d..0d70cd6121 100644 --- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/transport/ProtocolV2ParserTest.java +++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/transport/ProtocolV2ParserTest.java @@ -123,9 +123,9 @@ public class ProtocolV2ParserTest { ByteArrayOutputStream send = new ByteArrayOutputStream(); PacketLineOut pckOut = new PacketLineOut(send); for (String line : inputLines) { - if (line == PacketLineIn.END) { + if (PacketLineIn.isEnd(line)) { pckOut.end(); - } else if (line == PacketLineIn.DELIM) { + } else if (PacketLineIn.isDelimiter(line)) { pckOut.writeDelim(); } else { pckOut.writeString(line); @@ -136,19 +136,19 @@ public class ProtocolV2ParserTest { } /* - * Succesful fetch with the basic core commands of the protocol. + * Successful fetch with the basic core commands of the protocol. */ @Test public void testFetchBasicArguments() throws PackProtocolException, IOException { PacketLineIn pckIn = formatAsPacketLine( - PacketLineIn.DELIM, + PacketLineIn.delimiter(), "thin-pack", "no-progress", "include-tag", "ofs-delta", "want 4624442d68ee402a94364191085b77137618633e", "want f900c8326a43303685c46b279b9f70411bff1a4b", "have 554f6e41067b9e3e565b6988a8294fac1cb78f4b", "have abc760ab9ad72f08209943251b36cb886a578f87", "done", - PacketLineIn.END); + PacketLineIn.end()); ProtocolV2Parser parser = new ProtocolV2Parser( ConfigBuilder.getDefault()); FetchV2Request request = parser.parseFetchRequest(pckIn); @@ -173,12 +173,12 @@ public class ProtocolV2ParserTest { @Test public void testFetchWithShallow_deepen() throws IOException { PacketLineIn pckIn = formatAsPacketLine( - PacketLineIn.DELIM, + PacketLineIn.delimiter(), "deepen 15", "deepen-relative", "shallow 28274d02c489f4c7e68153056e9061a46f62d7a0", "shallow 145e683b229dcab9d0e2ccb01b386f9ecc17d29d", - PacketLineIn.END); + PacketLineIn.end()); ProtocolV2Parser parser = new ProtocolV2Parser( ConfigBuilder.getDefault()); FetchV2Request request = parser.parseFetchRequest(pckIn); @@ -193,11 +193,11 @@ public class ProtocolV2ParserTest { @Test public void testFetchWithShallow_deepenNot() throws IOException { - PacketLineIn pckIn = formatAsPacketLine(PacketLineIn.DELIM, + PacketLineIn pckIn = formatAsPacketLine(PacketLineIn.delimiter(), "shallow 28274d02c489f4c7e68153056e9061a46f62d7a0", "shallow 145e683b229dcab9d0e2ccb01b386f9ecc17d29d", "deepen-not a08595f76159b09d57553e37a5123f1091bb13e7", - PacketLineIn.END); + PacketLineIn.end()); ProtocolV2Parser parser = new ProtocolV2Parser( ConfigBuilder.getDefault()); FetchV2Request request = parser.parseFetchRequest(pckIn); @@ -210,11 +210,11 @@ public class ProtocolV2ParserTest { @Test public void testFetchWithShallow_deepenSince() throws IOException { - PacketLineIn pckIn = formatAsPacketLine(PacketLineIn.DELIM, + PacketLineIn pckIn = formatAsPacketLine(PacketLineIn.delimiter(), "shallow 28274d02c489f4c7e68153056e9061a46f62d7a0", "shallow 145e683b229dcab9d0e2ccb01b386f9ecc17d29d", "deepen-since 123123123", - PacketLineIn.END); + PacketLineIn.end()); ProtocolV2Parser parser = new ProtocolV2Parser( ConfigBuilder.getDefault()); FetchV2Request request = parser.parseFetchRequest(pckIn); @@ -226,9 +226,9 @@ public class ProtocolV2ParserTest { @Test public void testFetchWithNoneFilter() throws IOException { - PacketLineIn pckIn = formatAsPacketLine(PacketLineIn.DELIM, + PacketLineIn pckIn = formatAsPacketLine(PacketLineIn.delimiter(), "filter blob:none", - PacketLineIn.END); + PacketLineIn.end()); ProtocolV2Parser parser = new ProtocolV2Parser( ConfigBuilder.start().allowFilter().done()); FetchV2Request request = parser.parseFetchRequest(pckIn); @@ -238,9 +238,9 @@ public class ProtocolV2ParserTest { @Test public void testFetchWithBlobSizeFilter() throws IOException { - PacketLineIn pckIn = formatAsPacketLine(PacketLineIn.DELIM, + PacketLineIn pckIn = formatAsPacketLine(PacketLineIn.delimiter(), "filter blob:limit=15", - PacketLineIn.END); + PacketLineIn.end()); ProtocolV2Parser parser = new ProtocolV2Parser( ConfigBuilder.start().allowFilter().done()); FetchV2Request request = parser.parseFetchRequest(pckIn); @@ -250,9 +250,9 @@ public class ProtocolV2ParserTest { @Test public void testFetchWithTreeDepthFilter() throws IOException { - PacketLineIn pckIn = formatAsPacketLine(PacketLineIn.DELIM, + PacketLineIn pckIn = formatAsPacketLine(PacketLineIn.delimiter(), "filter tree:3", - PacketLineIn.END); + PacketLineIn.end()); ProtocolV2Parser parser = new ProtocolV2Parser( ConfigBuilder.start().allowFilter().done()); FetchV2Request request = parser.parseFetchRequest(pckIn); @@ -262,10 +262,10 @@ public class ProtocolV2ParserTest { @Test public void testFetchMustNotHaveMultipleFilters() throws IOException { - PacketLineIn pckIn = formatAsPacketLine(PacketLineIn.DELIM, + PacketLineIn pckIn = formatAsPacketLine(PacketLineIn.delimiter(), "filter blob:none", "filter blob:limit=12", - PacketLineIn.END); + PacketLineIn.end()); ProtocolV2Parser parser = new ProtocolV2Parser( ConfigBuilder.start().allowFilter().done()); @@ -275,8 +275,8 @@ public class ProtocolV2ParserTest { @Test public void testFetchFilterWithoutAllowFilter() throws IOException { - PacketLineIn pckIn = formatAsPacketLine(PacketLineIn.DELIM, - "filter blob:limit=12", PacketLineIn.END); + PacketLineIn pckIn = formatAsPacketLine(PacketLineIn.delimiter(), + "filter blob:limit=12", PacketLineIn.end()); ProtocolV2Parser parser = new ProtocolV2Parser( ConfigBuilder.getDefault()); @@ -291,10 +291,10 @@ public class ProtocolV2ParserTest { testRepo.update("branchA", one); testRepo.update("branchB", two); - PacketLineIn pckIn = formatAsPacketLine(PacketLineIn.DELIM, + PacketLineIn pckIn = formatAsPacketLine(PacketLineIn.delimiter(), "want e4980cdc48cfa1301493ca94eb70523f6788b819", "want-ref refs/heads/branchA", - PacketLineIn.END); + PacketLineIn.end()); ProtocolV2Parser parser = new ProtocolV2Parser( ConfigBuilder.start().allowRefInWant().done()); @@ -309,10 +309,10 @@ public class ProtocolV2ParserTest { @Test public void testFetchWithRefInWantUnknownRef() throws Exception { - PacketLineIn pckIn = formatAsPacketLine(PacketLineIn.DELIM, + PacketLineIn pckIn = formatAsPacketLine(PacketLineIn.delimiter(), "want e4980cdc48cfa1301493ca94eb70523f6788b819", "want-ref refs/heads/branchC", - PacketLineIn.END); + PacketLineIn.end()); ProtocolV2Parser parser = new ProtocolV2Parser( ConfigBuilder.start().allowRefInWant().done()); @@ -328,8 +328,8 @@ public class ProtocolV2ParserTest { @Test public void testLsRefsMinimalReq() throws IOException { - PacketLineIn pckIn = formatAsPacketLine(PacketLineIn.DELIM, - PacketLineIn.END); + PacketLineIn pckIn = formatAsPacketLine(PacketLineIn.delimiter(), + PacketLineIn.end()); ProtocolV2Parser parser = new ProtocolV2Parser( ConfigBuilder.getDefault()); @@ -341,8 +341,8 @@ public class ProtocolV2ParserTest { @Test public void testLsRefsSymrefs() throws IOException { - PacketLineIn pckIn = formatAsPacketLine(PacketLineIn.DELIM, "symrefs", - PacketLineIn.END); + PacketLineIn pckIn = formatAsPacketLine(PacketLineIn.delimiter(), "symrefs", + PacketLineIn.end()); ProtocolV2Parser parser = new ProtocolV2Parser( ConfigBuilder.getDefault()); @@ -356,9 +356,9 @@ public class ProtocolV2ParserTest { @Test public void testLsRefsPeel() throws IOException { PacketLineIn pckIn = formatAsPacketLine( - PacketLineIn.DELIM, + PacketLineIn.delimiter(), "peel", - PacketLineIn.END); + PacketLineIn.end()); ProtocolV2Parser parser = new ProtocolV2Parser( ConfigBuilder.getDefault()); @@ -370,9 +370,9 @@ public class ProtocolV2ParserTest { @Test public void testLsRefsRefPrefixes() throws IOException { - PacketLineIn pckIn = formatAsPacketLine(PacketLineIn.DELIM, + PacketLineIn pckIn = formatAsPacketLine(PacketLineIn.delimiter(), "ref-prefix refs/for", "ref-prefix refs/heads", - PacketLineIn.END); + PacketLineIn.end()); ProtocolV2Parser parser = new ProtocolV2Parser( ConfigBuilder.getDefault()); diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/transport/ReceivePackAdvertiseRefsHookTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/transport/ReceivePackAdvertiseRefsHookTest.java index 50c8a29543..5d208eea73 100644 --- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/transport/ReceivePackAdvertiseRefsHookTest.java +++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/transport/ReceivePackAdvertiseRefsHookTest.java @@ -306,11 +306,11 @@ public class ReceivePackAdvertiseRefsHookTest extends LocalDiskRepositoryTestCas int nul = master.indexOf('\0'); assertTrue("has capability list", nul > 0); assertEquals(B.name() + ' ' + R_MASTER, master.substring(0, nul)); - assertSame(PacketLineIn.END, r.readString()); + assertTrue(PacketLineIn.isEnd(r.readString())); assertEquals("unpack error Missing commit " + P.name(), r.readString()); assertEquals("ng refs/heads/s n/a (unpacker error)", r.readString()); - assertSame(PacketLineIn.END, r.readString()); + assertTrue(PacketLineIn.isEnd(r.readString())); } private static void receive(final ReceivePack rp, @@ -366,13 +366,13 @@ public class ReceivePackAdvertiseRefsHookTest extends LocalDiskRepositoryTestCas int nul = master.indexOf('\0'); assertTrue("has capability list", nul > 0); assertEquals(B.name() + ' ' + R_MASTER, master.substring(0, nul)); - assertSame(PacketLineIn.END, r.readString()); + assertTrue(PacketLineIn.isEnd(r.readString())); assertEquals("unpack error Missing blob " + b.name(), r.readString()); assertEquals("ng refs/heads/s n/a (unpacker error)", r.readString()); - assertSame(PacketLineIn.END, r.readString()); + assertTrue(PacketLineIn.isEnd(r.readString())); } } @@ -419,13 +419,13 @@ public class ReceivePackAdvertiseRefsHookTest extends LocalDiskRepositoryTestCas int nul = master.indexOf('\0'); assertTrue("has capability list", nul > 0); assertEquals(B.name() + ' ' + R_MASTER, master.substring(0, nul)); - assertSame(PacketLineIn.END, r.readString()); + assertTrue(PacketLineIn.isEnd(r.readString())); assertEquals("unpack error Missing blob " + b.name(), r.readString()); assertEquals("ng refs/heads/s n/a (unpacker error)", r.readString()); - assertSame(PacketLineIn.END, r.readString()); + assertTrue(PacketLineIn.isEnd(r.readString())); } } @@ -473,13 +473,13 @@ public class ReceivePackAdvertiseRefsHookTest extends LocalDiskRepositoryTestCas int nul = master.indexOf('\0'); assertTrue("has capability list", nul > 0); assertEquals(B.name() + ' ' + R_MASTER, master.substring(0, nul)); - assertSame(PacketLineIn.END, r.readString()); + assertTrue(PacketLineIn.isEnd(r.readString())); assertEquals("unpack error Missing blob " + n.name(), r.readString()); assertEquals("ng refs/heads/s n/a (unpacker error)", r.readString()); - assertSame(PacketLineIn.END, r.readString()); + assertTrue(PacketLineIn.isEnd(r.readString())); } } @@ -504,13 +504,13 @@ public class ReceivePackAdvertiseRefsHookTest extends LocalDiskRepositoryTestCas int nul = master.indexOf('\0'); assertTrue("has capability list", nul > 0); assertEquals(B.name() + ' ' + R_MASTER, master.substring(0, nul)); - assertSame(PacketLineIn.END, r.readString()); + assertTrue(PacketLineIn.isEnd(r.readString())); String errorLine = r.readString(); assertTrue(errorLine.startsWith("unpack error")); assertTrue(errorLine.contains("Invalid submodule URL '-")); assertEquals("ng refs/heads/s n/a (unpacker error)", r.readString()); - assertSame(PacketLineIn.END, r.readString()); + assertTrue(PacketLineIn.isEnd(r.readString())); } private TemporaryBuffer.Heap setupSourceRepoInvalidGitmodules() @@ -589,13 +589,13 @@ public class ReceivePackAdvertiseRefsHookTest extends LocalDiskRepositoryTestCas int nul = master.indexOf('\0'); assertTrue("has capability list", nul > 0); assertEquals(B.name() + ' ' + R_MASTER, master.substring(0, nul)); - assertSame(PacketLineIn.END, r.readString()); + assertTrue(PacketLineIn.isEnd(r.readString())); assertEquals("unpack error Missing tree " + t.name(), r.readString()); assertEquals("ng refs/heads/s n/a (unpacker error)", r.readString()); - assertSame(PacketLineIn.END, r.readString()); + assertTrue(PacketLineIn.isEnd(r.readString())); } } diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/transport/RefAdvertiserTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/transport/RefAdvertiserTest.java index ce69adf9c1..ccb548d919 100644 --- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/transport/RefAdvertiserTest.java +++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/transport/RefAdvertiserTest.java @@ -45,7 +45,7 @@ package org.eclipse.jgit.transport; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertSame; +import static org.junit.Assert.assertTrue; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; @@ -95,7 +95,7 @@ public class RefAdvertiserTest { assertEquals(id(3).name() + " refs/Iñtërnâtiônà lizætiøn☃💩\n", s); s = pckIn.readStringRaw(); - assertSame(PacketLineIn.END, s); + assertTrue(PacketLineIn.isEnd(s)); } private static ObjectId id(int i) { diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/transport/TransportHttpTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/transport/TransportHttpTest.java new file mode 100644 index 0000000000..ee0e0af8c4 --- /dev/null +++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/transport/TransportHttpTest.java @@ -0,0 +1,189 @@ +/* + * Copyright (C) 2018, Konrad Windszus <konrad_w@gmx.de> + * and other copyright owners as documented in the project's IP log. + * + * This program and the accompanying materials are made available + * under the terms of the Eclipse Distribution License v1.0 which + * accompanies this distribution, is reproduced below, and is + * available at http://www.eclipse.org/org/documents/edl-v10.php + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or + * without modification, are permitted provided that the following + * conditions are met: + * + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * - Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials provided + * with the distribution. + * + * - Neither the name of the Eclipse Foundation, Inc. nor the + * names of its contributors may be used to endorse or promote + * products derived from this software without specific prior + * written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +package org.eclipse.jgit.transport; + +import java.io.File; +import java.io.IOException; +import java.net.HttpCookie; +import java.time.Instant; +import java.util.Arrays; +import java.util.Collections; +import java.util.Date; +import java.util.LinkedHashSet; +import java.util.Set; + +import org.eclipse.jgit.internal.transport.http.NetscapeCookieFile; +import org.eclipse.jgit.lib.Config; +import org.eclipse.jgit.test.resources.SampleDataRepositoryTestCase; +import org.eclipse.jgit.transport.http.HttpConnection; +import org.eclipse.jgit.util.http.HttpCookiesMatcher; +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; +import org.mockito.ArgumentMatchers; +import org.mockito.Mockito; + +public class TransportHttpTest extends SampleDataRepositoryTestCase { + private URIish uri; + private File cookieFile; + + @Override + @Before + public void setUp() throws Exception { + super.setUp(); + uri = new URIish("https://everyones.loves.git/u/2"); + + final Config config = db.getConfig(); + config.setBoolean("http", null, "saveCookies", true); + cookieFile = createTempFile(); + config.setString("http", null, "cookieFile", + cookieFile.getAbsolutePath()); + } + + @Test + public void testMatchesCookieDomain() { + Assert.assertTrue(TransportHttp.matchesCookieDomain("example.com", + "example.com")); + Assert.assertTrue(TransportHttp.matchesCookieDomain("Example.Com", + "example.cOM")); + Assert.assertTrue(TransportHttp.matchesCookieDomain( + "some.subdomain.example.com", "example.com")); + Assert.assertFalse(TransportHttp + .matchesCookieDomain("someotherexample.com", "example.com")); + Assert.assertFalse(TransportHttp.matchesCookieDomain("example.com", + "example1.com")); + Assert.assertFalse(TransportHttp + .matchesCookieDomain("sub.sub.example.com", ".example.com")); + Assert.assertTrue(TransportHttp.matchesCookieDomain("host.example.com", + "example.com")); + Assert.assertTrue(TransportHttp.matchesCookieDomain( + "something.example.com", "something.example.com")); + Assert.assertTrue(TransportHttp.matchesCookieDomain( + "host.something.example.com", "something.example.com")); + } + + @Test + public void testMatchesCookiePath() { + Assert.assertTrue( + TransportHttp.matchesCookiePath("/some/path", "/some/path")); + Assert.assertTrue(TransportHttp.matchesCookiePath("/some/path/child", + "/some/path")); + Assert.assertTrue(TransportHttp.matchesCookiePath("/some/path/child", + "/some/path/")); + Assert.assertFalse(TransportHttp.matchesCookiePath("/some/pathother", + "/some/path")); + Assert.assertFalse( + TransportHttp.matchesCookiePath("otherpath", "/some/path")); + } + + @Test + public void testProcessResponseCookies() throws IOException { + HttpConnection connection = Mockito.mock(HttpConnection.class); + Mockito.when( + connection.getHeaderFields(ArgumentMatchers.eq("Set-Cookie"))) + .thenReturn(Arrays.asList( + "id=a3fWa; Expires=Fri, 01 Jan 2100 11:00:00 GMT; Secure; HttpOnly", + "sessionid=38afes7a8; HttpOnly; Path=/")); + Mockito.when( + connection.getHeaderFields(ArgumentMatchers.eq("Set-Cookie2"))) + .thenReturn(Collections + .singletonList("cookie2=some value; Max-Age=1234; Path=/")); + + try (TransportHttp transportHttp = new TransportHttp(db, uri)) { + Date creationDate = new Date(); + transportHttp.processResponseCookies(connection); + + // evaluate written cookie file + Set<HttpCookie> expectedCookies = new LinkedHashSet<>(); + + HttpCookie cookie = new HttpCookie("id", "a3fWa"); + cookie.setDomain("everyones.loves.git"); + cookie.setPath("/u/2/"); + + cookie.setMaxAge( + (Instant.parse("2100-01-01T11:00:00.000Z").toEpochMilli() + - creationDate.getTime()) / 1000); + cookie.setSecure(true); + cookie.setHttpOnly(true); + expectedCookies.add(cookie); + + cookie = new HttpCookie("cookie2", "some value"); + cookie.setDomain("everyones.loves.git"); + cookie.setPath("/"); + cookie.setMaxAge(1234); + expectedCookies.add(cookie); + + Assert.assertThat( + new NetscapeCookieFile(cookieFile.toPath()) + .getCookies(true), + HttpCookiesMatcher.containsInOrder(expectedCookies, 5)); + } + } + + @Test + public void testProcessResponseCookiesNotPersistingWithSaveCookiesFalse() + throws IOException { + HttpConnection connection = Mockito.mock(HttpConnection.class); + Mockito.when( + connection.getHeaderFields(ArgumentMatchers.eq("Set-Cookie"))) + .thenReturn(Arrays.asList( + "id=a3fWa; Expires=Thu, 21 Oct 2100 11:00:00 GMT; Secure; HttpOnly", + "sessionid=38afes7a8; HttpOnly; Path=/")); + Mockito.when( + connection.getHeaderFields(ArgumentMatchers.eq("Set-Cookie2"))) + .thenReturn(Collections.singletonList( + "cookie2=some value; Max-Age=1234; Path=/")); + + // tweak config + final Config config = db.getConfig(); + config.setBoolean("http", null, "saveCookies", false); + + try (TransportHttp transportHttp = new TransportHttp(db, uri)) { + transportHttp.processResponseCookies(connection); + + // evaluate written cookie file + Assert.assertFalse("Cookie file was not supposed to be written!", + cookieFile.exists()); + } + } +} diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/transport/UploadPackTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/transport/UploadPackTest.java index 9ffcbccc8f..260130b2bd 100644 --- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/transport/UploadPackTest.java +++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/transport/UploadPackTest.java @@ -4,7 +4,6 @@ import static org.hamcrest.Matchers.containsString; import static org.hamcrest.Matchers.hasItems; import static org.hamcrest.Matchers.is; import static org.hamcrest.Matchers.notNullValue; -import static org.hamcrest.Matchers.theInstance; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertNotNull; @@ -428,9 +427,9 @@ public class UploadPackTest { try (ByteArrayOutputStream send = new ByteArrayOutputStream()) { PacketLineOut pckOut = new PacketLineOut(send); for (String line : inputLines) { - if (line == PacketLineIn.END) { + if (PacketLineIn.isEnd(line)) { pckOut.end(); - } else if (line == PacketLineIn.DELIM) { + } else if (PacketLineIn.isDelimiter(line)) { pckOut.writeDelim(); } else { pckOut.writeString(line); @@ -453,7 +452,7 @@ public class UploadPackTest { PacketLineIn pckIn = new PacketLineIn(recvStream); // drain capabilities - while (pckIn.readString() != PacketLineIn.END) { + while (!PacketLineIn.isEnd(pckIn.readString())) { // do nothing } return recvStream; @@ -490,7 +489,7 @@ public class UploadPackTest { public void testV2Capabilities() throws Exception { TestV2Hook hook = new TestV2Hook(); ByteArrayInputStream recvStream = - uploadPackV2Setup(null, null, hook, PacketLineIn.END); + uploadPackV2Setup(null, null, hook, PacketLineIn.end()); PacketLineIn pckIn = new PacketLineIn(recvStream); assertThat(hook.capabilitiesRequest, notNullValue()); assertThat(pckIn.readString(), is("version 2")); @@ -504,14 +503,14 @@ public class UploadPackTest { // and additional capabilities to be added to existing // commands without requiring test changes. hasItems("ls-refs", "fetch=shallow", "server-option")); - assertTrue(pckIn.readString() == PacketLineIn.END); + assertTrue(PacketLineIn.isEnd(pckIn.readString())); } @Test public void testV2CapabilitiesAllowFilter() throws Exception { server.getConfig().setBoolean("uploadpack", null, "allowfilter", true); ByteArrayInputStream recvStream = - uploadPackV2Setup(null, null, null, PacketLineIn.END); + uploadPackV2Setup(null, null, null, PacketLineIn.end()); PacketLineIn pckIn = new PacketLineIn(recvStream); assertThat(pckIn.readString(), is("version 2")); @@ -521,14 +520,14 @@ public class UploadPackTest { // TODO(jonathantanmy) This check overspecifies the // order of the capabilities of "fetch". hasItems("ls-refs", "fetch=filter shallow", "server-option")); - assertTrue(pckIn.readString() == PacketLineIn.END); + assertTrue(PacketLineIn.isEnd(pckIn.readString())); } @Test public void testV2CapabilitiesRefInWant() throws Exception { server.getConfig().setBoolean("uploadpack", null, "allowrefinwant", true); ByteArrayInputStream recvStream = - uploadPackV2Setup(null, null, null, PacketLineIn.END); + uploadPackV2Setup(null, null, null, PacketLineIn.end()); PacketLineIn pckIn = new PacketLineIn(recvStream); assertThat(pckIn.readString(), is("version 2")); @@ -539,14 +538,14 @@ public class UploadPackTest { // order of the capabilities of "fetch". hasItems("ls-refs", "fetch=ref-in-want shallow", "server-option")); - assertTrue(pckIn.readString() == PacketLineIn.END); + assertTrue(PacketLineIn.isEnd(pckIn.readString())); } @Test public void testV2CapabilitiesRefInWantNotAdvertisedIfUnallowed() throws Exception { server.getConfig().setBoolean("uploadpack", null, "allowrefinwant", false); ByteArrayInputStream recvStream = - uploadPackV2Setup(null, null, null, PacketLineIn.END); + uploadPackV2Setup(null, null, null, PacketLineIn.end()); PacketLineIn pckIn = new PacketLineIn(recvStream); assertThat(pckIn.readString(), is("version 2")); @@ -554,7 +553,7 @@ public class UploadPackTest { Arrays.asList(pckIn.readString(), pckIn.readString(), pckIn.readString()), hasItems("ls-refs", "fetch=shallow", "server-option")); - assertTrue(pckIn.readString() == PacketLineIn.END); + assertTrue(PacketLineIn.isEnd(pckIn.readString())); } @Test @@ -562,7 +561,7 @@ public class UploadPackTest { server.getConfig().setBoolean("uploadpack", null, "allowrefinwant", true); server.getConfig().setBoolean("uploadpack", null, "advertiserefinwant", false); ByteArrayInputStream recvStream = - uploadPackV2Setup(null, null, null, PacketLineIn.END); + uploadPackV2Setup(null, null, null, PacketLineIn.end()); PacketLineIn pckIn = new PacketLineIn(recvStream); assertThat(pckIn.readString(), is("version 2")); @@ -570,12 +569,12 @@ public class UploadPackTest { Arrays.asList(pckIn.readString(), pckIn.readString(), pckIn.readString()), hasItems("ls-refs", "fetch=shallow", "server-option")); - assertTrue(pckIn.readString() == PacketLineIn.END); + assertTrue(PacketLineIn.isEnd(pckIn.readString())); } @Test public void testV2EmptyRequest() throws Exception { - ByteArrayInputStream recvStream = uploadPackV2(PacketLineIn.END); + ByteArrayInputStream recvStream = uploadPackV2(PacketLineIn.end()); // Verify that there is nothing more after the capability // advertisement. assertEquals(0, recvStream.available()); @@ -591,14 +590,14 @@ public class UploadPackTest { TestV2Hook hook = new TestV2Hook(); ByteArrayInputStream recvStream = uploadPackV2(null, null, hook, - "command=ls-refs\n", PacketLineIn.END); + "command=ls-refs\n", PacketLineIn.end()); PacketLineIn pckIn = new PacketLineIn(recvStream); assertThat(hook.lsRefsRequest, notNullValue()); assertThat(pckIn.readString(), is(tip.toObjectId().getName() + " HEAD")); assertThat(pckIn.readString(), is(tip.toObjectId().getName() + " refs/heads/master")); assertThat(pckIn.readString(), is(tag.toObjectId().getName() + " refs/tags/tag")); - assertTrue(pckIn.readString() == PacketLineIn.END); + assertTrue(PacketLineIn.isEnd(pckIn.readString())); } @Test @@ -609,13 +608,14 @@ public class UploadPackTest { RevTag tag = remote.tag("tag", tip); remote.update("refs/tags/tag", tag); - ByteArrayInputStream recvStream = uploadPackV2("command=ls-refs\n", PacketLineIn.DELIM, "symrefs", PacketLineIn.END); + ByteArrayInputStream recvStream = uploadPackV2("command=ls-refs\n", + PacketLineIn.delimiter(), "symrefs", PacketLineIn.end()); PacketLineIn pckIn = new PacketLineIn(recvStream); assertThat(pckIn.readString(), is(tip.toObjectId().getName() + " HEAD symref-target:refs/heads/master")); assertThat(pckIn.readString(), is(tip.toObjectId().getName() + " refs/heads/master")); assertThat(pckIn.readString(), is(tag.toObjectId().getName() + " refs/tags/tag")); - assertTrue(pckIn.readString() == PacketLineIn.END); + assertTrue(PacketLineIn.isEnd(pckIn.readString())); } @Test @@ -626,7 +626,8 @@ public class UploadPackTest { RevTag tag = remote.tag("tag", tip); remote.update("refs/tags/tag", tag); - ByteArrayInputStream recvStream = uploadPackV2("command=ls-refs\n", PacketLineIn.DELIM, "peel", PacketLineIn.END); + ByteArrayInputStream recvStream = uploadPackV2("command=ls-refs\n", + PacketLineIn.delimiter(), "peel", PacketLineIn.end()); PacketLineIn pckIn = new PacketLineIn(recvStream); assertThat(pckIn.readString(), is(tip.toObjectId().getName() + " HEAD")); @@ -635,7 +636,7 @@ public class UploadPackTest { pckIn.readString(), is(tag.toObjectId().getName() + " refs/tags/tag peeled:" + tip.toObjectId().getName())); - assertTrue(pckIn.readString() == PacketLineIn.END); + assertTrue(PacketLineIn.isEnd(pckIn.readString())); } @Test @@ -647,8 +648,9 @@ public class UploadPackTest { remote.update("refs/tags/tag", tag); ByteArrayInputStream recvStream = uploadPackV2( - "command=ls-refs\n", PacketLineIn.DELIM, "symrefs", "peel", PacketLineIn.END, - "command=ls-refs\n", PacketLineIn.DELIM, PacketLineIn.END); + "command=ls-refs\n", PacketLineIn.delimiter(), "symrefs", + "peel", PacketLineIn.end(), "command=ls-refs\n", + PacketLineIn.delimiter(), PacketLineIn.end()); PacketLineIn pckIn = new PacketLineIn(recvStream); assertThat(pckIn.readString(), is(tip.toObjectId().getName() + " HEAD symref-target:refs/heads/master")); @@ -657,11 +659,11 @@ public class UploadPackTest { pckIn.readString(), is(tag.toObjectId().getName() + " refs/tags/tag peeled:" + tip.toObjectId().getName())); - assertTrue(pckIn.readString() == PacketLineIn.END); + assertTrue(PacketLineIn.isEnd(pckIn.readString())); assertThat(pckIn.readString(), is(tip.toObjectId().getName() + " HEAD")); assertThat(pckIn.readString(), is(tip.toObjectId().getName() + " refs/heads/master")); assertThat(pckIn.readString(), is(tag.toObjectId().getName() + " refs/tags/tag")); - assertTrue(pckIn.readString() == PacketLineIn.END); + assertTrue(PacketLineIn.isEnd(pckIn.readString())); } @Test @@ -673,15 +675,15 @@ public class UploadPackTest { ByteArrayInputStream recvStream = uploadPackV2( "command=ls-refs\n", - PacketLineIn.DELIM, + PacketLineIn.delimiter(), "ref-prefix refs/heads/maste", "ref-prefix refs/heads/other", - PacketLineIn.END); + PacketLineIn.end()); PacketLineIn pckIn = new PacketLineIn(recvStream); assertThat(pckIn.readString(), is(tip.toObjectId().getName() + " refs/heads/master")); assertThat(pckIn.readString(), is(tip.toObjectId().getName() + " refs/heads/other")); - assertTrue(pckIn.readString() == PacketLineIn.END); + assertTrue(PacketLineIn.isEnd(pckIn.readString())); } @Test @@ -692,15 +694,15 @@ public class UploadPackTest { ByteArrayInputStream recvStream = uploadPackV2( "command=ls-refs\n", - PacketLineIn.DELIM, + PacketLineIn.delimiter(), "ref-prefix refs/heads/maste", "ref-prefix r", - PacketLineIn.END); + PacketLineIn.end()); PacketLineIn pckIn = new PacketLineIn(recvStream); assertThat(pckIn.readString(), is(tip.toObjectId().getName() + " refs/heads/master")); assertThat(pckIn.readString(), is(tip.toObjectId().getName() + " refs/heads/other")); - assertTrue(pckIn.readString() == PacketLineIn.END); + assertTrue(PacketLineIn.isEnd(pckIn.readString())); } @Test @@ -709,17 +711,17 @@ public class UploadPackTest { thrown.expectMessage("unexpected invalid-argument"); uploadPackV2( "command=ls-refs\n", - PacketLineIn.DELIM, + PacketLineIn.delimiter(), "invalid-argument\n", - PacketLineIn.END); + PacketLineIn.end()); } @Test public void testV2LsRefsServerOptions() throws Exception { String[] lines = { "command=ls-refs\n", "server-option=one\n", "server-option=two\n", - PacketLineIn.DELIM, - PacketLineIn.END }; + PacketLineIn.delimiter(), + PacketLineIn.end() }; TestV2Hook testHook = new TestV2Hook(); uploadPackV2Setup(null, null, testHook, lines); @@ -763,9 +765,9 @@ public class UploadPackTest { null, null, "command=fetch\n", - PacketLineIn.DELIM, + PacketLineIn.delimiter(), "want " + advertized.name() + "\n", - PacketLineIn.END); + PacketLineIn.end()); // This doesn't thrown.expect(TransportException.class); @@ -776,9 +778,9 @@ public class UploadPackTest { null, null, "command=fetch\n", - PacketLineIn.DELIM, + PacketLineIn.delimiter(), "want " + unadvertized.name() + "\n", - PacketLineIn.END); + PacketLineIn.end()); } @Test @@ -794,9 +796,9 @@ public class UploadPackTest { null, null, "command=fetch\n", - PacketLineIn.DELIM, + PacketLineIn.delimiter(), "want " + reachable.name() + "\n", - PacketLineIn.END); + PacketLineIn.end()); // This doesn't thrown.expect(TransportException.class); @@ -807,9 +809,9 @@ public class UploadPackTest { null, null, "command=fetch\n", - PacketLineIn.DELIM, + PacketLineIn.delimiter(), "want " + unreachable.name() + "\n", - PacketLineIn.END); + PacketLineIn.end()); } @Test @@ -824,9 +826,9 @@ public class UploadPackTest { new RejectAllRefFilter(), null, "command=fetch\n", - PacketLineIn.DELIM, + PacketLineIn.delimiter(), "want " + tip.name() + "\n", - PacketLineIn.END); + PacketLineIn.end()); // This doesn't thrown.expect(TransportException.class); @@ -837,9 +839,9 @@ public class UploadPackTest { new RejectAllRefFilter(), null, "command=fetch\n", - PacketLineIn.DELIM, + PacketLineIn.delimiter(), "want " + parentOfTip.name() + "\n", - PacketLineIn.END); + PacketLineIn.end()); } @Test @@ -855,9 +857,9 @@ public class UploadPackTest { new RejectAllRefFilter(), null, "command=fetch\n", - PacketLineIn.DELIM, + PacketLineIn.delimiter(), "want " + parentOfTip.name() + "\n", - PacketLineIn.END); + PacketLineIn.end()); // This doesn't thrown.expect(TransportException.class); @@ -868,9 +870,9 @@ public class UploadPackTest { new RejectAllRefFilter(), null, "command=fetch\n", - PacketLineIn.DELIM, + PacketLineIn.delimiter(), "want " + unreachable.name() + "\n", - PacketLineIn.END); + PacketLineIn.end()); } @Test @@ -883,9 +885,9 @@ public class UploadPackTest { null, null, "command=fetch\n", - PacketLineIn.DELIM, + PacketLineIn.delimiter(), "want " + unreachable.name() + "\n", - PacketLineIn.END); + PacketLineIn.end()); } @Test @@ -899,16 +901,16 @@ public class UploadPackTest { ByteArrayInputStream recvStream = uploadPackV2( "command=fetch\n", - PacketLineIn.DELIM, + PacketLineIn.delimiter(), "want " + fooChild.toObjectId().getName() + "\n", "want " + barChild.toObjectId().getName() + "\n", "have " + fooParent.toObjectId().getName() + "\n", - PacketLineIn.END); + PacketLineIn.end()); PacketLineIn pckIn = new PacketLineIn(recvStream); assertThat(pckIn.readString(), is("acknowledgments")); assertThat(pckIn.readString(), is("ACK " + fooParent.toObjectId().getName())); - assertThat(pckIn.readString(), theInstance(PacketLineIn.END)); + assertTrue(PacketLineIn.isEnd(pckIn.readString())); } @Test @@ -922,12 +924,12 @@ public class UploadPackTest { ByteArrayInputStream recvStream = uploadPackV2( "command=fetch\n", - PacketLineIn.DELIM, + PacketLineIn.delimiter(), "want " + fooChild.toObjectId().getName() + "\n", "want " + barChild.toObjectId().getName() + "\n", "have " + fooParent.toObjectId().getName() + "\n", "have " + barParent.toObjectId().getName() + "\n", - PacketLineIn.END); + PacketLineIn.end()); PacketLineIn pckIn = new PacketLineIn(recvStream); assertThat(pckIn.readString(), is("acknowledgments")); @@ -937,7 +939,7 @@ public class UploadPackTest { "ACK " + fooParent.toObjectId().getName(), "ACK " + barParent.toObjectId().getName())); assertThat(pckIn.readString(), is("ready")); - assertThat(pckIn.readString(), theInstance(PacketLineIn.DELIM)); + assertTrue(PacketLineIn.isDelimiter(pckIn.readString())); assertThat(pckIn.readString(), is("packfile")); parsePack(recvStream); assertFalse(client.getObjectDatabase().has(fooParent.toObjectId())); @@ -957,12 +959,12 @@ public class UploadPackTest { ByteArrayInputStream recvStream = uploadPackV2( "command=fetch\n", - PacketLineIn.DELIM, + PacketLineIn.delimiter(), "want " + fooChild.toObjectId().getName() + "\n", "want " + barChild.toObjectId().getName() + "\n", "have " + fooParent.toObjectId().getName() + "\n", "done\n", - PacketLineIn.END); + PacketLineIn.end()); PacketLineIn pckIn = new PacketLineIn(recvStream); assertThat(pckIn.readString(), is("packfile")); @@ -986,12 +988,12 @@ public class UploadPackTest { // Pretend that we have parent to get a thin pack based on it. ByteArrayInputStream recvStream = uploadPackV2( "command=fetch\n", - PacketLineIn.DELIM, + PacketLineIn.delimiter(), "want " + child.toObjectId().getName() + "\n", "have " + parent.toObjectId().getName() + "\n", "thin-pack\n", "done\n", - PacketLineIn.END); + PacketLineIn.end()); PacketLineIn pckIn = new PacketLineIn(recvStream); assertThat(pckIn.readString(), is("packfile")); @@ -1012,10 +1014,10 @@ public class UploadPackTest { StringWriter sw = new StringWriter(); ByteArrayInputStream recvStream = uploadPackV2( "command=fetch\n", - PacketLineIn.DELIM, + PacketLineIn.delimiter(), "want " + commit.toObjectId().getName() + "\n", "done\n", - PacketLineIn.END); + PacketLineIn.end()); PacketLineIn pckIn = new PacketLineIn(recvStream); assertThat(pckIn.readString(), is("packfile")); parsePack(recvStream, new TextProgressMonitor(sw)); @@ -1025,11 +1027,11 @@ public class UploadPackTest { sw = new StringWriter(); recvStream = uploadPackV2( "command=fetch\n", - PacketLineIn.DELIM, + PacketLineIn.delimiter(), "want " + commit.toObjectId().getName() + "\n", "no-progress\n", "done\n", - PacketLineIn.END); + PacketLineIn.end()); pckIn = new PacketLineIn(recvStream); assertThat(pckIn.readString(), is("packfile")); parsePack(recvStream, new TextProgressMonitor(sw)); @@ -1046,10 +1048,10 @@ public class UploadPackTest { // Without include-tag. ByteArrayInputStream recvStream = uploadPackV2( "command=fetch\n", - PacketLineIn.DELIM, + PacketLineIn.delimiter(), "want " + commit.toObjectId().getName() + "\n", "done\n", - PacketLineIn.END); + PacketLineIn.end()); PacketLineIn pckIn = new PacketLineIn(recvStream); assertThat(pckIn.readString(), is("packfile")); parsePack(recvStream); @@ -1058,11 +1060,11 @@ public class UploadPackTest { // With tag. recvStream = uploadPackV2( "command=fetch\n", - PacketLineIn.DELIM, + PacketLineIn.delimiter(), "want " + commit.toObjectId().getName() + "\n", "include-tag\n", "done\n", - PacketLineIn.END); + PacketLineIn.end()); pckIn = new PacketLineIn(recvStream); assertThat(pckIn.readString(), is("packfile")); parsePack(recvStream); @@ -1082,27 +1084,27 @@ public class UploadPackTest { // Without ofs-delta. ByteArrayInputStream recvStream = uploadPackV2( "command=fetch\n", - PacketLineIn.DELIM, + PacketLineIn.delimiter(), "want " + child.toObjectId().getName() + "\n", "done\n", - PacketLineIn.END); + PacketLineIn.end()); PacketLineIn pckIn = new PacketLineIn(recvStream); assertThat(pckIn.readString(), is("packfile")); - ReceivedPackStatistics stats = parsePack(recvStream); - assertTrue(stats.getNumOfsDelta() == 0); + ReceivedPackStatistics receivedStats = parsePack(recvStream); + assertTrue(receivedStats.getNumOfsDelta() == 0); // With ofs-delta. recvStream = uploadPackV2( "command=fetch\n", - PacketLineIn.DELIM, + PacketLineIn.delimiter(), "want " + child.toObjectId().getName() + "\n", "ofs-delta\n", "done\n", - PacketLineIn.END); + PacketLineIn.end()); pckIn = new PacketLineIn(recvStream); assertThat(pckIn.readString(), is("packfile")); - stats = parsePack(recvStream); - assertTrue(stats.getNumOfsDelta() != 0); + receivedStats = parsePack(recvStream); + assertTrue(receivedStats.getNumOfsDelta() != 0); } @Test @@ -1116,11 +1118,11 @@ public class UploadPackTest { // commonParent, so it doesn't send it. ByteArrayInputStream recvStream = uploadPackV2( "command=fetch\n", - PacketLineIn.DELIM, + PacketLineIn.delimiter(), "want " + barChild.toObjectId().getName() + "\n", "have " + fooChild.toObjectId().getName() + "\n", "done\n", - PacketLineIn.END); + PacketLineIn.end()); PacketLineIn pckIn = new PacketLineIn(recvStream); assertThat(pckIn.readString(), is("packfile")); parsePack(recvStream); @@ -1131,12 +1133,12 @@ public class UploadPackTest { // commonParent, so it sends it. recvStream = uploadPackV2( "command=fetch\n", - PacketLineIn.DELIM, + PacketLineIn.delimiter(), "want " + barChild.toObjectId().getName() + "\n", "have " + fooChild.toObjectId().getName() + "\n", "shallow " + fooChild.toObjectId().getName() + "\n", "done\n", - PacketLineIn.END); + PacketLineIn.end()); pckIn = new PacketLineIn(recvStream); assertThat(pckIn.readString(), is("packfile")); parsePack(recvStream); @@ -1152,15 +1154,15 @@ public class UploadPackTest { // "deepen 1" sends only the child. ByteArrayInputStream recvStream = uploadPackV2( "command=fetch\n", - PacketLineIn.DELIM, + PacketLineIn.delimiter(), "want " + child.toObjectId().getName() + "\n", "deepen 1\n", "done\n", - PacketLineIn.END); + PacketLineIn.end()); PacketLineIn pckIn = new PacketLineIn(recvStream); assertThat(pckIn.readString(), is("shallow-info")); assertThat(pckIn.readString(), is("shallow " + child.toObjectId().getName())); - assertThat(pckIn.readString(), theInstance(PacketLineIn.DELIM)); + assertTrue(PacketLineIn.isDelimiter(pckIn.readString())); assertThat(pckIn.readString(), is("packfile")); parsePack(recvStream); assertTrue(client.getObjectDatabase().has(child.toObjectId())); @@ -1169,10 +1171,10 @@ public class UploadPackTest { // Without that, the parent is sent too. recvStream = uploadPackV2( "command=fetch\n", - PacketLineIn.DELIM, + PacketLineIn.delimiter(), "want " + child.toObjectId().getName() + "\n", "done\n", - PacketLineIn.END); + PacketLineIn.end()); pckIn = new PacketLineIn(recvStream); assertThat(pckIn.readString(), is("packfile")); parsePack(recvStream); @@ -1187,10 +1189,10 @@ public class UploadPackTest { ByteArrayInputStream recvStream = uploadPackV2( "command=fetch\n", - PacketLineIn.DELIM, + PacketLineIn.delimiter(), "want " + child.toObjectId().getName() + "\n", "deepen 1\n", - PacketLineIn.END); + PacketLineIn.end()); PacketLineIn pckIn = new PacketLineIn(recvStream); // Verify that only the correct section is sent. "shallow-info" @@ -1198,7 +1200,7 @@ public class UploadPackTest { // sent only if a packfile is sent. assertThat(pckIn.readString(), is("acknowledgments")); assertThat(pckIn.readString(), is("NAK")); - assertThat(pckIn.readString(), theInstance(PacketLineIn.END)); + assertTrue(PacketLineIn.isEnd(pckIn.readString())); } @Test @@ -1219,13 +1221,13 @@ public class UploadPackTest { // Report that we only have "boundary" as a shallow boundary. ByteArrayInputStream recvStream = uploadPackV2( "command=fetch\n", - PacketLineIn.DELIM, + PacketLineIn.delimiter(), "shallow " + boundary.toObjectId().getName() + "\n", "deepen-since 1510000\n", "want " + merge.toObjectId().getName() + "\n", "have " + boundary.toObjectId().getName() + "\n", "done\n", - PacketLineIn.END); + PacketLineIn.end()); PacketLineIn pckIn = new PacketLineIn(recvStream); assertThat(pckIn.readString(), is("shallow-info")); @@ -1237,7 +1239,7 @@ public class UploadPackTest { // later than the given deepen-since time. assertThat(pckIn.readString(), is("unshallow " + boundary.toObjectId().getName())); - assertThat(pckIn.readString(), theInstance(PacketLineIn.DELIM)); + assertTrue(PacketLineIn.isDelimiter(pckIn.readString())); assertThat(pckIn.readString(), is("packfile")); parsePack(recvStream); @@ -1270,12 +1272,12 @@ public class UploadPackTest { ByteArrayInputStream recvStream = uploadPackV2( "command=fetch\n", - PacketLineIn.DELIM, + PacketLineIn.delimiter(), "deepen-since 1510000\n", "want " + child1.toObjectId().getName() + "\n", "want " + child2.toObjectId().getName() + "\n", "done\n", - PacketLineIn.END); + PacketLineIn.end()); PacketLineIn pckIn = new PacketLineIn(recvStream); assertThat(pckIn.readString(), is("shallow-info")); @@ -1286,7 +1288,7 @@ public class UploadPackTest { "shallow " + child1.toObjectId().getName(), "shallow " + child2.toObjectId().getName())); - assertThat(pckIn.readString(), theInstance(PacketLineIn.DELIM)); + assertTrue(PacketLineIn.isDelimiter(pckIn.readString())); assertThat(pckIn.readString(), is("packfile")); parsePack(recvStream); @@ -1309,11 +1311,11 @@ public class UploadPackTest { thrown.expectMessage("No commits selected for shallow request"); uploadPackV2( "command=fetch\n", - PacketLineIn.DELIM, + PacketLineIn.delimiter(), "deepen-since 1510000\n", "want " + tooOld.toObjectId().getName() + "\n", "done\n", - PacketLineIn.END); + PacketLineIn.end()); } @Test @@ -1332,13 +1334,13 @@ public class UploadPackTest { // wants "merge" while excluding "side". ByteArrayInputStream recvStream = uploadPackV2( "command=fetch\n", - PacketLineIn.DELIM, + PacketLineIn.delimiter(), "shallow " + three.toObjectId().getName() + "\n", "deepen-not side\n", "want " + merge.toObjectId().getName() + "\n", "have " + three.toObjectId().getName() + "\n", "done\n", - PacketLineIn.END); + PacketLineIn.end()); PacketLineIn pckIn = new PacketLineIn(recvStream); assertThat(pckIn.readString(), is("shallow-info")); @@ -1353,7 +1355,7 @@ public class UploadPackTest { // "three" is unshallow because its parent "two" is now available. assertThat(pckIn.readString(), is("unshallow " + three.toObjectId().getName())); - assertThat(pckIn.readString(), theInstance(PacketLineIn.DELIM)); + assertTrue(PacketLineIn.isDelimiter(pckIn.readString())); assertThat(pckIn.readString(), is("packfile")); parsePack(recvStream); @@ -1385,11 +1387,11 @@ public class UploadPackTest { thrown.expectMessage("No commits selected for shallow request"); uploadPackV2( "command=fetch\n", - PacketLineIn.DELIM, + PacketLineIn.delimiter(), "deepen-not four\n", "want " + two.toObjectId().getName() + "\n", "done\n", - PacketLineIn.END); + PacketLineIn.end()); } @Test @@ -1405,15 +1407,15 @@ public class UploadPackTest { ByteArrayInputStream recvStream = uploadPackV2( "command=fetch\n", - PacketLineIn.DELIM, + PacketLineIn.delimiter(), "deepen-not twotag\n", "want " + four.toObjectId().getName() + "\n", "done\n", - PacketLineIn.END); + PacketLineIn.end()); PacketLineIn pckIn = new PacketLineIn(recvStream); assertThat(pckIn.readString(), is("shallow-info")); assertThat(pckIn.readString(), is("shallow " + three.toObjectId().getName())); - assertThat(pckIn.readString(), theInstance(PacketLineIn.DELIM)); + assertTrue(PacketLineIn.isDelimiter(pckIn.readString())); assertThat(pckIn.readString(), is("packfile")); parsePack(recvStream); assertFalse(client.getObjectDatabase().has(one.toObjectId())); @@ -1439,12 +1441,12 @@ public class UploadPackTest { ByteArrayInputStream recvStream = uploadPackV2( "command=fetch\n", - PacketLineIn.DELIM, + PacketLineIn.delimiter(), "deepen-not base\n", "want " + child1.toObjectId().getName() + "\n", "want " + child2.toObjectId().getName() + "\n", "done\n", - PacketLineIn.END); + PacketLineIn.end()); PacketLineIn pckIn = new PacketLineIn(recvStream); assertThat(pckIn.readString(), is("shallow-info")); @@ -1455,7 +1457,7 @@ public class UploadPackTest { "shallow " + child1.toObjectId().getName(), "shallow " + child2.toObjectId().getName())); - assertThat(pckIn.readString(), theInstance(PacketLineIn.DELIM)); + assertTrue(PacketLineIn.isDelimiter(pckIn.readString())); assertThat(pckIn.readString(), is("packfile")); parsePack(recvStream); @@ -1471,16 +1473,16 @@ public class UploadPackTest { thrown.expectMessage("unexpected invalid-argument"); uploadPackV2( "command=fetch\n", - PacketLineIn.DELIM, + PacketLineIn.delimiter(), "invalid-argument\n", - PacketLineIn.END); + PacketLineIn.end()); } @Test public void testV2FetchServerOptions() throws Exception { String[] lines = { "command=fetch\n", "server-option=one\n", - "server-option=two\n", PacketLineIn.DELIM, - PacketLineIn.END }; + "server-option=two\n", PacketLineIn.delimiter(), + PacketLineIn.end() }; TestV2Hook testHook = new TestV2Hook(); uploadPackV2Setup(null, null, testHook, lines); @@ -1504,11 +1506,11 @@ public class UploadPackTest { ByteArrayInputStream recvStream = uploadPackV2( "command=fetch\n", - PacketLineIn.DELIM, + PacketLineIn.delimiter(), "want " + commit.toObjectId().getName() + "\n", "filter blob:limit=5\n", "done\n", - PacketLineIn.END); + PacketLineIn.end()); PacketLineIn pckIn = new PacketLineIn(recvStream); assertThat(pckIn.readString(), is("packfile")); parsePack(recvStream); @@ -1557,15 +1559,15 @@ public class UploadPackTest { long depth, ObjectId... wants) throws Exception { server.getConfig().setBoolean("uploadpack", null, "allowfilter", true); - List<String> input = new ArrayList(); + List<String> input = new ArrayList<>(); input.add("command=fetch\n"); - input.add(PacketLineIn.DELIM); + input.add(PacketLineIn.delimiter()); for (ObjectId want : wants) { input.add("want " + want.getName() + "\n"); } input.add("filter tree:" + depth + "\n"); input.add("done\n"); - input.add(PacketLineIn.END); + input.add(PacketLineIn.end()); ByteArrayInputStream recvStream = uploadPackV2(RequestPolicy.ANY, /*refFilter=*/null, /*hook=*/null, input.toArray(new String[0])); @@ -1846,11 +1848,11 @@ public class UploadPackTest { thrown.expectMessage("unexpected filter blob:limit=5"); uploadPackV2( "command=fetch\n", - PacketLineIn.DELIM, + PacketLineIn.delimiter(), "want " + commit.toObjectId().getName() + "\n", "filter blob:limit=5\n", "done\n", - PacketLineIn.END); + PacketLineIn.end()); } @Test @@ -1861,10 +1863,10 @@ public class UploadPackTest { try { uploadPackV2( "command=fetch\n", - PacketLineIn.DELIM, + PacketLineIn.delimiter(), "want-ref refs/heads/one\n", "done\n", - PacketLineIn.END); + PacketLineIn.end()); } catch (PackProtocolException e) { assertThat( e.getMessage(), @@ -1887,11 +1889,11 @@ public class UploadPackTest { ByteArrayInputStream recvStream = uploadPackV2( "command=fetch\n", - PacketLineIn.DELIM, + PacketLineIn.delimiter(), "want-ref refs/heads/one\n", "want-ref refs/heads/two\n", "done\n", - PacketLineIn.END); + PacketLineIn.end()); PacketLineIn pckIn = new PacketLineIn(recvStream); assertThat(pckIn.readString(), is("wanted-refs")); assertThat( @@ -1899,7 +1901,7 @@ public class UploadPackTest { hasItems( one.toObjectId().getName() + " refs/heads/one", two.toObjectId().getName() + " refs/heads/two")); - assertThat(pckIn.readString(), theInstance(PacketLineIn.DELIM)); + assertTrue(PacketLineIn.isDelimiter(pckIn.readString())); assertThat(pckIn.readString(), is("packfile")); parsePack(recvStream); @@ -1918,11 +1920,11 @@ public class UploadPackTest { try { uploadPackV2( "command=fetch\n", - PacketLineIn.DELIM, + PacketLineIn.delimiter(), "want-ref refs/heads/one\n", "want-ref refs/heads/nonExistentRef\n", "done\n", - PacketLineIn.END); + PacketLineIn.end()); } catch (PackProtocolException e) { assertThat( e.getMessage(), @@ -1945,17 +1947,17 @@ public class UploadPackTest { ByteArrayInputStream recvStream = uploadPackV2( "command=fetch\n", - PacketLineIn.DELIM, + PacketLineIn.delimiter(), "want-ref refs/heads/one\n", "want " + two.toObjectId().getName() + "\n", "done\n", - PacketLineIn.END); + PacketLineIn.end()); PacketLineIn pckIn = new PacketLineIn(recvStream); assertThat(pckIn.readString(), is("wanted-refs")); assertThat( pckIn.readString(), is(one.toObjectId().getName() + " refs/heads/one")); - assertThat(pckIn.readString(), theInstance(PacketLineIn.DELIM)); + assertTrue(PacketLineIn.isDelimiter(pckIn.readString())); assertThat(pckIn.readString(), is("packfile")); parsePack(recvStream); @@ -1973,11 +1975,11 @@ public class UploadPackTest { ByteArrayInputStream recvStream = uploadPackV2( "command=fetch\n", - PacketLineIn.DELIM, + PacketLineIn.delimiter(), "want-ref refs/heads/one\n", "have " + one.toObjectId().getName(), "done\n", - PacketLineIn.END); + PacketLineIn.end()); PacketLineIn pckIn = new PacketLineIn(recvStream); // The client still needs to know the hash of the object that @@ -1987,7 +1989,7 @@ public class UploadPackTest { assertThat( pckIn.readString(), is(one.toObjectId().getName() + " refs/heads/one")); - assertThat(pckIn.readString(), theInstance(PacketLineIn.DELIM)); + assertTrue(PacketLineIn.isDelimiter(pckIn.readString())); // ... but the client does not need the object itself. assertThat(pckIn.readString(), is("packfile")); @@ -2005,20 +2007,20 @@ public class UploadPackTest { ByteArrayInputStream recvStream = uploadPackV2( "command=fetch\n", - PacketLineIn.DELIM, + PacketLineIn.delimiter(), "want-ref refs/heads/branch1\n", "deepen 1\n", "done\n", - PacketLineIn.END); + PacketLineIn.end()); PacketLineIn pckIn = new PacketLineIn(recvStream); // shallow-info appears first, then wanted-refs. assertThat(pckIn.readString(), is("shallow-info")); assertThat(pckIn.readString(), is("shallow " + child.toObjectId().getName())); - assertThat(pckIn.readString(), theInstance(PacketLineIn.DELIM)); + assertTrue(PacketLineIn.isDelimiter(pckIn.readString())); assertThat(pckIn.readString(), is("wanted-refs")); assertThat(pckIn.readString(), is(child.toObjectId().getName() + " refs/heads/branch1")); - assertThat(pckIn.readString(), theInstance(PacketLineIn.DELIM)); + assertTrue(PacketLineIn.isDelimiter(pckIn.readString())); assertThat(pckIn.readString(), is("packfile")); parsePack(recvStream); assertTrue(client.getObjectDatabase().has(child.toObjectId())); @@ -2036,13 +2038,13 @@ public class UploadPackTest { true); ByteArrayInputStream recvStream = uploadPackV2("command=fetch\n", - PacketLineIn.DELIM, + PacketLineIn.delimiter(), "want-ref refs/heads/three\n", "deepen 3", "shallow 0123012301230123012301230123012301230123", "shallow " + two.getName() + '\n', "done\n", - PacketLineIn.END); + PacketLineIn.end()); PacketLineIn pckIn = new PacketLineIn(recvStream); assertThat(pckIn.readString(), is("shallow-info")); @@ -2050,11 +2052,11 @@ public class UploadPackTest { is("shallow " + one.toObjectId().getName())); assertThat(pckIn.readString(), is("unshallow " + two.toObjectId().getName())); - assertThat(pckIn.readString(), theInstance(PacketLineIn.DELIM)); + assertTrue(PacketLineIn.isDelimiter(pckIn.readString())); assertThat(pckIn.readString(), is("wanted-refs")); assertThat(pckIn.readString(), is(three.toObjectId().getName() + " refs/heads/three")); - assertThat(pckIn.readString(), theInstance(PacketLineIn.DELIM)); + assertTrue(PacketLineIn.isDelimiter(pckIn.readString())); assertThat(pckIn.readString(), is("packfile")); parsePack(recvStream); @@ -2071,7 +2073,7 @@ public class UploadPackTest { UploadPack up = new UploadPack(server); ByteArrayInputStream send = linesAsInputStream( "want " + one.getName() + " agent=JGit-test/1.2.3\n", - PacketLineIn.END, + PacketLineIn.end(), "have 11cedf1b796d44207da702f7d420684022fc0f09\n", "done\n"); ByteArrayOutputStream recv = new ByteArrayOutputStream(); @@ -2092,9 +2094,9 @@ public class UploadPackTest { ByteArrayInputStream send = linesAsInputStream( "command=fetch\n", "agent=JGit-test/1.2.4\n", - PacketLineIn.DELIM, "want " + one.getName() + "\n", + PacketLineIn.delimiter(), "want " + one.getName() + "\n", "have 11cedf1b796d44207da702f7d420684022fc0f09\n", "done\n", - PacketLineIn.END); + PacketLineIn.end()); ByteArrayOutputStream recv = new ByteArrayOutputStream(); up.upload(send, recv, null); diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/util/FileUtilsTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/util/FileUtilsTest.java index c0f4965668..9ee9613f79 100644 --- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/util/FileUtilsTest.java +++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/util/FileUtilsTest.java @@ -137,7 +137,6 @@ public class FileUtilsTest { } @Test - public void testDeleteRecursiveEmpty() throws IOException { File f1 = new File(trash, "test/test/a"); File f2 = new File(trash, "test/a"); diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/util/LRUMapTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/util/LRUMapTest.java new file mode 100644 index 0000000000..da59533aeb --- /dev/null +++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/util/LRUMapTest.java @@ -0,0 +1,78 @@ +/* + * Copyright (C) 2018, Konrad Windszus <konrad_w@gmx.de> + * and other copyright owners as documented in the project's IP log. + * + * This program and the accompanying materials are made available + * under the terms of the Eclipse Distribution License v1.0 which + * accompanies this distribution, is reproduced below, and is + * available at http://www.eclipse.org/org/documents/edl-v10.php + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or + * without modification, are permitted provided that the following + * conditions are met: + * + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * - Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials provided + * with the distribution. + * + * - Neither the name of the Eclipse Foundation, Inc. nor the + * names of its contributors may be used to endorse or promote + * products derived from this software without specific prior + * written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +package org.eclipse.jgit.util; + +import java.util.LinkedHashMap; +import java.util.Map; + +import org.hamcrest.collection.IsIterableContainingInOrder; +import org.junit.Assert; +import org.junit.Test; + +public class LRUMapTest { + + @SuppressWarnings("boxing") + @Test + public void testLRUEntriesAreEvicted() { + Map<Integer, Integer> map = new LRUMap<>(3, 3); + for (int i = 0; i < 3; i++) { + map.put(i, i); + } + // access the last ones + map.get(2); + map.get(0); + + // put another one which exceeds the limit (entry with key "1" is + // evicted) + map.put(3, 3); + + Map<Integer, Integer> expectedMap = new LinkedHashMap<>(); + expectedMap.put(2, 2); + expectedMap.put(0, 0); + expectedMap.put(3, 3); + + Assert.assertThat(map.entrySet(), + IsIterableContainingInOrder + .contains(expectedMap.entrySet().toArray())); + } +} diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/util/http/HttpCookiesMatcher.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/util/http/HttpCookiesMatcher.java new file mode 100644 index 0000000000..8c5b127de2 --- /dev/null +++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/util/http/HttpCookiesMatcher.java @@ -0,0 +1,150 @@ +/* + * Copyright (C) 2018, Konrad Windszus <konrad_w@gmx.de> + * and other copyright owners as documented in the project's IP log. + * + * This program and the accompanying materials are made available + * under the terms of the Eclipse Distribution License v1.0 which + * accompanies this distribution, is reproduced below, and is + * available at http://www.eclipse.org/org/documents/edl-v10.php + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or + * without modification, are permitted provided that the following + * conditions are met: + * + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * - Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials provided + * with the distribution. + * + * - Neither the name of the Eclipse Foundation, Inc. nor the + * names of its contributors may be used to endorse or promote + * products derived from this software without specific prior + * written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +package org.eclipse.jgit.util.http; + +import java.net.HttpCookie; +import java.util.LinkedList; +import java.util.List; + +import org.hamcrest.Description; +import org.hamcrest.Matcher; +import org.hamcrest.TypeSafeMatcher; +import org.hamcrest.collection.IsIterableContainingInOrder; + +public final class HttpCookiesMatcher { + public static Matcher<Iterable<? extends HttpCookie>> containsInOrder( + Iterable<HttpCookie> expectedCookies) { + return containsInOrder(expectedCookies, 0); + } + + public static Matcher<Iterable<? extends HttpCookie>> containsInOrder( + Iterable<HttpCookie> expectedCookies, int allowedMaxAgeDelta) { + final List<Matcher<? super HttpCookie>> cookieMatchers = new LinkedList<>(); + for (HttpCookie cookie : expectedCookies) { + cookieMatchers + .add(new HttpCookieMatcher(cookie, allowedMaxAgeDelta)); + } + return new IsIterableContainingInOrder<>(cookieMatchers); + } + + /** + * The default {@link HttpCookie#equals(Object)} is not good enough for + * testing purposes. Also the {@link HttpCookie#toString()} only emits some + * of the cookie attributes. For testing a dedicated matcher is needed which + * takes into account all attributes. + */ + private static final class HttpCookieMatcher + extends TypeSafeMatcher<HttpCookie> { + + private final HttpCookie cookie; + + private final int allowedMaxAgeDelta; + + public HttpCookieMatcher(HttpCookie cookie, int allowedMaxAgeDelta) { + this.cookie = cookie; + this.allowedMaxAgeDelta = allowedMaxAgeDelta; + } + + @Override + public void describeTo(Description description) { + describeCookie(description, cookie); + } + + @Override + protected void describeMismatchSafely(HttpCookie item, + Description mismatchDescription) { + mismatchDescription.appendText("was "); + describeCookie(mismatchDescription, item); + } + + @Override + protected boolean matchesSafely(HttpCookie otherCookie) { + // the equals method in HttpCookie is not specific enough, we want + // to consider all attributes! + return (equals(cookie.getName(), otherCookie.getName()) + && equals(cookie.getValue(), otherCookie.getValue()) + && equals(cookie.getDomain(), otherCookie.getDomain()) + && equals(cookie.getPath(), otherCookie.getPath()) + && (cookie.getMaxAge() >= otherCookie.getMaxAge() + - allowedMaxAgeDelta) + && (cookie.getMaxAge() <= otherCookie.getMaxAge() + + allowedMaxAgeDelta) + && cookie.isHttpOnly() == otherCookie.isHttpOnly() + && cookie.getSecure() == otherCookie.getSecure() + && cookie.getVersion() == otherCookie.getVersion()); + } + + private static boolean equals(String value1, String value2) { + if (value1 == null && value2 == null) { + return true; + } + if (value1 == null || value2 == null) { + return false; + } + return value1.equals(value2); + } + + @SuppressWarnings("boxing") + protected static void describeCookie(Description description, + HttpCookie cookie) { + description.appendText("HttpCookie["); + description.appendText("name: ").appendValue(cookie.getName()) + .appendText(", "); + description.appendText("value: ").appendValue(cookie.getValue()) + .appendText(", "); + description.appendText("domain: ").appendValue(cookie.getDomain()) + .appendText(", "); + description.appendText("path: ").appendValue(cookie.getPath()) + .appendText(", "); + description.appendText("maxAge: ").appendValue(cookie.getMaxAge()) + .appendText(", "); + description.appendText("httpOnly: ") + .appendValue(cookie.isHttpOnly()).appendText(", "); + description.appendText("secure: ").appendValue(cookie.getSecure()) + .appendText(", "); + description.appendText("version: ").appendValue(cookie.getVersion()) + .appendText(", "); + description.appendText("]"); + } + } +}
\ No newline at end of file diff --git a/org.eclipse.jgit/.settings/.api_filters b/org.eclipse.jgit/.settings/.api_filters index 6719570e05..fc326d4462 100644 --- a/org.eclipse.jgit/.settings/.api_filters +++ b/org.eclipse.jgit/.settings/.api_filters @@ -22,6 +22,14 @@ </message_arguments> </filter> </resource> + <resource path="src/org/eclipse/jgit/lib/Repository.java" type="org.eclipse.jgit.lib.Repository"> + <filter id="336695337"> + <message_arguments> + <message_argument value="org.eclipse.jgit.lib.Repository"/> + <message_argument value="getIdentifier()"/> + </message_arguments> + </filter> + </resource> <resource path="src/org/eclipse/jgit/revwalk/ObjectWalk.java" type="org.eclipse.jgit.revwalk.ObjectWalk"> <filter comment="ignore the risk subclasses could define the same field and cause a name clash" id="336658481"> <message_arguments> @@ -94,6 +102,26 @@ </message_arguments> </filter> </resource> + <resource path="src/org/eclipse/jgit/transport/HttpConfig.java" type="org.eclipse.jgit.transport.HttpConfig"> + <filter id="336658481"> + <message_arguments> + <message_argument value="org.eclipse.jgit.transport.HttpConfig"/> + <message_argument value="COOKIE_FILE_CACHE_LIMIT_KEY"/> + </message_arguments> + </filter> + <filter id="336658481"> + <message_arguments> + <message_argument value="org.eclipse.jgit.transport.HttpConfig"/> + <message_argument value="COOKIE_FILE_KEY"/> + </message_arguments> + </filter> + <filter id="336658481"> + <message_arguments> + <message_argument value="org.eclipse.jgit.transport.HttpConfig"/> + <message_argument value="SAVE_COOKIES_KEY"/> + </message_arguments> + </filter> + </resource> <resource path="src/org/eclipse/jgit/transport/Transport.java" type="org.eclipse.jgit.transport.Transport"> <filter comment="Marked as final since overriding a deprecated stub is likely a mistake" id="421654647"> <message_arguments> @@ -132,4 +160,24 @@ </message_arguments> </filter> </resource> + <resource path="src/org/eclipse/jgit/util/HttpSupport.java" type="org.eclipse.jgit.util.HttpSupport"> + <filter id="336658481"> + <message_arguments> + <message_argument value="org.eclipse.jgit.util.HttpSupport"/> + <message_argument value="HDR_COOKIE"/> + </message_arguments> + </filter> + <filter id="336658481"> + <message_arguments> + <message_argument value="org.eclipse.jgit.util.HttpSupport"/> + <message_argument value="HDR_SET_COOKIE"/> + </message_arguments> + </filter> + <filter id="336658481"> + <message_arguments> + <message_argument value="org.eclipse.jgit.util.HttpSupport"/> + <message_argument value="HDR_SET_COOKIE2"/> + </message_arguments> + </filter> + </resource> </component> diff --git a/org.eclipse.jgit/META-INF/MANIFEST.MF b/org.eclipse.jgit/META-INF/MANIFEST.MF index 95594f29e5..893f0d4305 100644 --- a/org.eclipse.jgit/META-INF/MANIFEST.MF +++ b/org.eclipse.jgit/META-INF/MANIFEST.MF @@ -86,6 +86,7 @@ Export-Package: org.eclipse.jgit.annotations;version="5.4.0", org.eclipse.jgit.pgm", org.eclipse.jgit.internal.storage.reftree;version="5.4.0";x-friends:="org.eclipse.jgit.junit,org.eclipse.jgit.test,org.eclipse.jgit.pgm", org.eclipse.jgit.internal.submodule;version="5.4.0";x-internal:=true, + org.eclipse.jgit.internal.transport.http;version="5.4.0";x-friends:="org.eclipse.jgit.test", org.eclipse.jgit.internal.transport.parser;version="5.4.0";x-friends:="org.eclipse.jgit.http.server,org.eclipse.jgit.test", org.eclipse.jgit.internal.transport.ssh;version="5.4.0";x-friends:="org.eclipse.jgit.ssh.apache", org.eclipse.jgit.lib;version="5.4.0"; @@ -160,16 +161,17 @@ Import-Package: com.googlecode.javaewah;version="[1.1.6,2.0.0)", com.jcraft.jsch;version="[0.1.37,0.2.0)", javax.crypto, javax.net.ssl, - org.bouncycastle;version="[1.60.0,2.0.0)", - org.bouncycastle.bcpg;version="[1.60.0,2.0.0)", - org.bouncycastle.gpg;version="[1.60.0,2.0.0)", - org.bouncycastle.gpg.keybox;version="[1.60.0,2.0.0)", - org.bouncycastle.jce.provider;version="[1.60.0,2.0.0)", - org.bouncycastle.openpgp;version="[1.60.0,2.0.0)", - org.bouncycastle.openpgp.jcajce;version="[1.60.0,2.0.0)", - org.bouncycastle.openpgp.operator;version="[1.60.0,2.0.0)", - org.bouncycastle.openpgp.operator.jcajce;version="[1.60.0,2.0.0)", - org.bouncycastle.util.encoders;version="[1.60.0,2.0.0)", + org.bouncycastle;version="[1.61.0,2.0.0)", + org.bouncycastle.bcpg;version="[1.61.0,2.0.0)", + org.bouncycastle.gpg;version="[1.61.0,2.0.0)", + org.bouncycastle.gpg.keybox;version="[1.61.0,2.0.0)", + org.bouncycastle.gpg.keybox.jcajce;version="[1.61.0,2.0.0)", + org.bouncycastle.jce.provider;version="[1.61.0,2.0.0)", + org.bouncycastle.openpgp;version="[1.61.0,2.0.0)", + org.bouncycastle.openpgp.jcajce;version="[1.61.0,2.0.0)", + org.bouncycastle.openpgp.operator;version="[1.61.0,2.0.0)", + org.bouncycastle.openpgp.operator.jcajce;version="[1.61.0,2.0.0)", + org.bouncycastle.util.encoders;version="[1.61.0,2.0.0)", org.slf4j;version="[1.7.0,2.0.0)", org.xml.sax, org.xml.sax.helpers 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 fc2a26f0d7..df42dc757b 100644 --- a/org.eclipse.jgit/resources/org/eclipse/jgit/internal/JGitText.properties +++ b/org.eclipse.jgit/resources/org/eclipse/jgit/internal/JGitText.properties @@ -139,6 +139,7 @@ configSubsectionContainsNewline=config subsection name contains newline configSubsectionContainsNullByte=config subsection name contains byte 0x00 configValueContainsNullByte=config value contains byte 0x00 configHandleIsStale=config file handle is stale, {0}. retry +configHandleMayBeLocked=config file handle may be locked by other process, {0}. retry connectionFailed=connection failed connectionTimeOut=Connection time out: {0} contextMustBeNonNegative=context must be >= 0 @@ -208,6 +209,10 @@ couldNotDeleteTemporaryIndexFileShouldNotHappen=Could not delete temporary index couldNotGetAdvertisedRef=Remote {0} did not advertise Ref for branch {1}. This Ref may not exist in the remote or may be hidden by permission settings. couldNotGetRepoStatistics=Could not get repository statistics couldNotLockHEAD=Could not lock HEAD +couldNotFindTabInLine=Could not find tab in line {0}. Tab is the mandatory separator for the Netscape Cookie File Format. +couldNotFindSixTabsInLine=Could not find 6 tabs but only {0} in line '{1}'. 7 tab separated columns per line are mandatory for the Netscape Cookie File Format. +couldNotPersistCookies=Could not persist received cookies in file ''{0}'' +couldNotReadCookieFile=Could not read cookie file ''{0}'' couldNotReadIndexInOneGo=Could not read index in one go, only {0} out of {1} read couldNotReadObjectWhileParsingCommit=Could not read an object while parsing commit {0} couldNotRenameDeleteOldIndex=Could not rename delete old index @@ -455,6 +460,7 @@ mismatchOffset=mismatch offset for object {0} mismatchCRC=mismatch CRC for object {0} missingAccesskey=Missing accesskey. missingConfigurationForKey=No value for key {0} found in configuration +missingCookieFile=Configured http.cookieFile ''{0}'' is missing missingCRC=missing CRC for object {0} missingDeltaBase=delta base missingForwardImageInGITBinaryPatch=Missing forward-image in GIT binary patch @@ -625,6 +631,7 @@ rewinding=Rewinding to commit {0} s3ActionDeletion=Deletion s3ActionReading=Reading s3ActionWriting=Writing +searchForReachableBranches=Finding reachable branches searchForReuse=Finding sources searchForSizes=Getting sizes secondsAgo={0} seconds ago diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/api/DescribeCommand.java b/org.eclipse.jgit/src/org/eclipse/jgit/api/DescribeCommand.java index 9ebcf9fd0f..9ad77e65fd 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/api/DescribeCommand.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/api/DescribeCommand.java @@ -63,8 +63,7 @@ import org.eclipse.jgit.api.errors.RefNotFoundException; import org.eclipse.jgit.errors.IncorrectObjectTypeException; import org.eclipse.jgit.errors.InvalidPatternException; import org.eclipse.jgit.errors.MissingObjectException; -import org.eclipse.jgit.ignore.internal.IMatcher; -import org.eclipse.jgit.ignore.internal.PathMatcher; +import org.eclipse.jgit.fnmatch.FileNameMatcher; import org.eclipse.jgit.internal.JGitText; import org.eclipse.jgit.lib.Constants; import org.eclipse.jgit.lib.ObjectId; @@ -104,12 +103,17 @@ public class DescribeCommand extends GitCommand<String> { /** * Pattern matchers to be applied to tags under consideration. */ - private List<IMatcher> matchers = new ArrayList<>(); + private List<FileNameMatcher> matchers = new ArrayList<>(); /** * Whether to use all tags (incl. lightweight) or not. */ - private boolean useTags = false; + private boolean useTags; + + /** + * Whether to show a uniquely abbreviated commit hash as a fallback or not. + */ + private boolean always; /** * Constructor for DescribeCommand. @@ -197,6 +201,21 @@ public class DescribeCommand extends GitCommand<String> { return this; } + /** + * Always describe the commit by eventually falling back to a uniquely + * abbreviated commit hash if no other name matches. + * + * @param always + * <code>true</code> enables falling back to a uniquely + * abbreviated commit hash + * @return {@code this} + * @since 5.4 + */ + public DescribeCommand setAlways(boolean always) { + this.always = always; + return this; + } + private String longDescription(Ref tag, int depth, ObjectId tip) throws IOException { return String.format( @@ -222,7 +241,7 @@ public class DescribeCommand extends GitCommand<String> { */ public DescribeCommand setMatch(String... patterns) throws InvalidPatternException { for (String p : patterns) { - matchers.add(PathMatcher.createPathMatcher(p, null, false)); + matchers.add(new FileNameMatcher(p, null)); } return this; } @@ -255,9 +274,15 @@ public class DescribeCommand extends GitCommand<String> { // Find the first tag that matches in the stream of all tags // filtered by matchers ordered by tie break order Stream<Ref> matchingTags = Stream.empty(); - for (IMatcher matcher : matchers) { + for (FileNameMatcher matcher : matchers) { Stream<Ref> m = tags.stream().filter( - tag -> matcher.matches(tag.getName(), false, false)); + tag -> { + matcher.append( + tag.getName().substring(R_TAGS.length())); + boolean result = matcher.isMatch(); + matcher.reset(); + return result; + }); matchingTags = Stream.of(matchingTags, m).flatMap(i -> i); } return matchingTags.sorted(TAG_TIE_BREAKER).findFirst(); @@ -399,8 +424,9 @@ public class DescribeCommand extends GitCommand<String> { } // if all the nodes are dominated by all the tags, the walk stops - if (candidates.isEmpty()) - return null; + if (candidates.isEmpty()) { + return always ? w.getObjectReader().abbreviate(target).name() : null; + } Candidate best = Collections.min(candidates, (Candidate o1, Candidate o2) -> o1.depth - o2.depth); diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/api/LogCommand.java b/org.eclipse.jgit/src/org/eclipse/jgit/api/LogCommand.java index 9b8016ce20..66de8ae131 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/api/LogCommand.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/api/LogCommand.java @@ -133,7 +133,7 @@ public class LogCommand extends GitCommand<Iterable<RevCommit>> { @Override public Iterable<RevCommit> call() throws GitAPIException, NoHeadException { checkCallable(); - if (pathFilters.size() > 0) + if (!pathFilters.isEmpty()) walk.setTreeFilter(AndTreeFilter.create( PathFilterGroup.create(pathFilters), TreeFilter.ANY_DIFF)); if (skip > -1 && maxCount > -1) 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 f0ad29db49..bdb2d1bbc5 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/api/PullCommand.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/api/PullCommand.java @@ -60,6 +60,7 @@ import org.eclipse.jgit.api.errors.NoHeadException; import org.eclipse.jgit.api.errors.RefNotAdvertisedException; import org.eclipse.jgit.api.errors.RefNotFoundException; import org.eclipse.jgit.api.errors.WrongRepositoryStateException; +import org.eclipse.jgit.dircache.DirCacheCheckout; import org.eclipse.jgit.internal.JGitText; import org.eclipse.jgit.lib.AnyObjectId; import org.eclipse.jgit.lib.BranchConfig.BranchRebaseMode; @@ -67,12 +68,17 @@ import org.eclipse.jgit.lib.Config; import org.eclipse.jgit.lib.ConfigConstants; import org.eclipse.jgit.lib.Constants; import org.eclipse.jgit.lib.NullProgressMonitor; +import org.eclipse.jgit.lib.ObjectId; import org.eclipse.jgit.lib.ProgressMonitor; 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.lib.RepositoryState; import org.eclipse.jgit.lib.SubmoduleConfig.FetchRecurseSubmodulesMode; import org.eclipse.jgit.merge.MergeStrategy; +import org.eclipse.jgit.revwalk.RevCommit; +import org.eclipse.jgit.revwalk.RevWalk; import org.eclipse.jgit.transport.FetchResult; import org.eclipse.jgit.transport.TagOpt; @@ -339,6 +345,45 @@ public class PullCommand extends TransportCommand<PullCommand, PullResult> { PullResult result; if (pullRebaseMode != BranchRebaseMode.NONE) { + try { + Ref head = repo.exactRef(Constants.HEAD); + if (head == null) { + throw new NoHeadException(JGitText + .get().commitOnRepoWithoutHEADCurrentlyNotSupported); + } + ObjectId headId = head.getObjectId(); + if (headId == null) { + // Pull on an unborn branch: checkout + try (RevWalk revWalk = new RevWalk(repo)) { + RevCommit srcCommit = revWalk + .parseCommit(commitToMerge); + DirCacheCheckout dco = new DirCacheCheckout(repo, + repo.lockDirCache(), srcCommit.getTree()); + dco.setFailOnConflict(true); + dco.setProgressMonitor(monitor); + dco.checkout(); + RefUpdate refUpdate = repo + .updateRef(head.getTarget().getName()); + refUpdate.setNewObjectId(commitToMerge); + refUpdate.setExpectedOldObjectId(null); + refUpdate.setRefLogMessage("initial pull", false); //$NON-NLS-1$ + if (refUpdate.update() != Result.NEW) { + throw new NoHeadException(JGitText + .get().commitOnRepoWithoutHEADCurrentlyNotSupported); + } + monitor.endTask(); + return new PullResult(fetchRes, remote, + RebaseResult.result( + RebaseResult.Status.FAST_FORWARD, + srcCommit)); + } + } + } catch (NoHeadException e) { + throw e; + } catch (IOException e) { + throw new JGitInternalException(JGitText + .get().exceptionCaughtDuringExecutionOfPullCommand, e); + } RebaseCommand rebase = new RebaseCommand(repo); RebaseResult rebaseRes = rebase.setUpstream(commitToMerge) .setUpstreamName(upstreamName).setProgressMonitor(monitor) 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 cdd1b80bb4..593874c121 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/api/RebaseCommand.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/api/RebaseCommand.java @@ -490,7 +490,7 @@ public class RebaseCommand extends GitCommand<RebaseResult> { resetSoftToParent(); List<RebaseTodoLine> steps = repo.readRebaseTodo( rebaseState.getPath(GIT_REBASE_TODO), false); - RebaseTodoLine nextStep = steps.size() > 0 ? steps.get(0) : null; + RebaseTodoLine nextStep = steps.isEmpty() ? null : steps.get(0); File messageFixupFile = rebaseState.getFile(MESSAGE_FIXUP); File messageSquashFile = rebaseState.getFile(MESSAGE_SQUASH); if (isSquash && messageFixupFile.exists()) @@ -1083,7 +1083,7 @@ public class RebaseCommand extends GitCommand<RebaseResult> { repo.writeRebaseTodoFile(rebaseState.getPath(GIT_REBASE_TODO), todoLines, false); - if (poppedLines.size() > 0) { + if (!poppedLines.isEmpty()) { repo.writeRebaseTodoFile(rebaseState.getPath(DONE), poppedLines, true); } 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 ca0024d1c9..bdaef5a366 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/internal/JGitText.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/internal/JGitText.java @@ -200,6 +200,7 @@ public class JGitText extends TranslationBundle { /***/ public String configSubsectionContainsNullByte; /***/ public String configValueContainsNullByte; /***/ public String configHandleIsStale; + /***/ public String configHandleMayBeLocked; /***/ public String connectionFailed; /***/ public String connectionTimeOut; /***/ public String contextMustBeNonNegative; @@ -267,9 +268,13 @@ public class JGitText extends TranslationBundle { /***/ public String couldNotCheckOutBecauseOfConflicts; /***/ public String couldNotDeleteLockFileShouldNotHappen; /***/ public String couldNotDeleteTemporaryIndexFileShouldNotHappen; + /***/ public String couldNotFindTabInLine; + /***/ public String couldNotFindSixTabsInLine; /***/ public String couldNotGetAdvertisedRef; /***/ public String couldNotGetRepoStatistics; /***/ public String couldNotLockHEAD; + /***/ public String couldNotPersistCookies; + /***/ public String couldNotReadCookieFile; /***/ public String couldNotReadIndexInOneGo; /***/ public String couldNotReadObjectWhileParsingCommit; /***/ public String couldNotRenameDeleteOldIndex; @@ -516,6 +521,7 @@ public class JGitText extends TranslationBundle { /***/ public String mismatchCRC; /***/ public String missingAccesskey; /***/ public String missingConfigurationForKey; + /***/ public String missingCookieFile; /***/ public String missingCRC; /***/ public String missingDeltaBase; /***/ public String missingForwardImageInGITBinaryPatch; @@ -686,6 +692,7 @@ public class JGitText extends TranslationBundle { /***/ public String s3ActionDeletion; /***/ public String s3ActionReading; /***/ public String s3ActionWriting; + /***/ public String searchForReachableBranches; /***/ public String searchForReuse; /***/ public String searchForSizes; /***/ public String secondsAgo; diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/dfs/DfsRepository.java b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/dfs/DfsRepository.java index 5169e929e4..8e5c5a7f75 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/dfs/DfsRepository.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/dfs/DfsRepository.java @@ -126,6 +126,12 @@ public abstract class DfsRepository extends Repository { /** {@inheritDoc} */ @Override + public String getIdentifier() { + return getDescription().getRepositoryName(); + } + + /** {@inheritDoc} */ + @Override public void scanForRepoChanges() throws IOException { getRefDatabase().refresh(); getObjectDatabase().clearCache(); diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/FileRepository.java b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/FileRepository.java index d82d29e4cf..90772970ae 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/FileRepository.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/FileRepository.java @@ -390,6 +390,17 @@ public class FileRepository extends Repository { /** {@inheritDoc} */ @Override + public String getIdentifier() { + File directory = getDirectory(); + if (directory != null) { + return directory.getPath(); + } else { + throw new IllegalStateException(); + } + } + + /** {@inheritDoc} */ + @Override public FileBasedConfig getConfig() { if (systemConfig.isOutdated()) { try { diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/GC.java b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/GC.java index 00124bcf27..4540860a0d 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/GC.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/GC.java @@ -244,7 +244,7 @@ public class GC { * If the configuration parameter "gc.pruneexpire" couldn't be * parsed */ - // TODO(ms): in 5.0 change signature and return Future<Collection<PackFile>> + // TODO(ms): change signature and return Future<Collection<PackFile>> @SuppressWarnings("FutureReturnValueIgnored") public Collection<PackFile> gc() throws IOException, ParseException { if (!background) { @@ -281,7 +281,7 @@ public class GC { } return Collections.emptyList(); }; - // TODO(ms): in 5.0 change signature and return the Future + // TODO(ms): change signature and return the Future executor().submit(gcTask); return Collections.emptyList(); } diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/internal/transport/http/NetscapeCookieFile.java b/org.eclipse.jgit/src/org/eclipse/jgit/internal/transport/http/NetscapeCookieFile.java new file mode 100644 index 0000000000..075f55c733 --- /dev/null +++ b/org.eclipse.jgit/src/org/eclipse/jgit/internal/transport/http/NetscapeCookieFile.java @@ -0,0 +1,476 @@ +/* + * Copyright (C) 2018, Konrad Windszus <konrad_w@gmx.de> + * and other copyright owners as documented in the project's IP log. + * + * This program and the accompanying materials are made available + * under the terms of the Eclipse Distribution License v1.0 which + * accompanies this distribution, is reproduced below, and is + * available at http://www.eclipse.org/org/documents/edl-v10.php + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or + * without modification, are permitted provided that the following + * conditions are met: + * + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * - Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials provided + * with the distribution. + * + * - Neither the name of the Eclipse Foundation, Inc. nor the + * names of its contributors may be used to endorse or promote + * products derived from this software without specific prior + * written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +package org.eclipse.jgit.internal.transport.http; + +import java.io.BufferedReader; +import java.io.ByteArrayOutputStream; +import java.io.File; +import java.io.FileNotFoundException; +import java.io.IOException; +import java.io.OutputStreamWriter; +import java.io.StringReader; +import java.io.Writer; +import java.net.HttpCookie; +import java.net.URL; +import java.nio.charset.StandardCharsets; +import java.nio.file.Path; +import java.text.MessageFormat; +import java.util.Arrays; +import java.util.Collection; +import java.util.Date; +import java.util.LinkedHashSet; +import java.util.Set; + +import org.eclipse.jgit.annotations.NonNull; +import org.eclipse.jgit.annotations.Nullable; +import org.eclipse.jgit.internal.JGitText; +import org.eclipse.jgit.internal.storage.file.FileSnapshot; +import org.eclipse.jgit.internal.storage.file.LockFile; +import org.eclipse.jgit.lib.Constants; +import org.eclipse.jgit.storage.file.FileBasedConfig; +import org.eclipse.jgit.util.FileUtils; +import org.eclipse.jgit.util.IO; +import org.eclipse.jgit.util.RawParseUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * Wraps all cookies persisted in a <strong>Netscape Cookie File Format</strong> + * being referenced via the git config <a href= + * "https://git-scm.com/docs/git-config#git-config-httpcookieFile">http.cookieFile</a>. + * + * It will only load the cookies lazily, i.e. before calling + * {@link #getCookies(boolean)} the file is not evaluated. This class also + * allows persisting cookies in that file format. + * <p> + * In general this class is not thread-safe. So any consumer needs to take care + * of synchronization! + * + * @see <a href="http://www.cookiecentral.com/faq/#3.5">Netscape Cookie File + * Format</a> + * @see <a href= + * "https://unix.stackexchange.com/questions/36531/format-of-cookies-when-using-wget">Cookie + * format for wget</a> + * @see <a href= + * "https://github.com/curl/curl/blob/07ebaf837843124ee670e5b8c218b80b92e06e47/lib/cookie.c#L745">libcurl + * Cookie file parsing</a> + * @see <a href= + * "https://github.com/curl/curl/blob/07ebaf837843124ee670e5b8c218b80b92e06e47/lib/cookie.c#L1417">libcurl + * Cookie file writing</a> + * @see NetscapeCookieFileCache + */ +public final class NetscapeCookieFile { + + private static final String HTTP_ONLY_PREAMBLE = "#HttpOnly_"; //$NON-NLS-1$ + + private static final String COLUMN_SEPARATOR = "\t"; //$NON-NLS-1$ + + private static final String LINE_SEPARATOR = "\n"; //$NON-NLS-1$ + + /** + * Maximum number of retries to acquire the lock for writing to the + * underlying file. + */ + private static final int LOCK_ACQUIRE_MAX_RETRY_COUNT = 4; + + /** + * Sleep time in milliseconds between retries to acquire the lock for + * writing to the underlying file. + */ + private static final int LOCK_ACQUIRE_RETRY_SLEEP = 500; + + private final Path path; + + private FileSnapshot snapshot; + + private byte[] hash; + + final Date creationDate; + + private Set<HttpCookie> cookies = null; + + private static final Logger LOG = LoggerFactory + .getLogger(NetscapeCookieFile.class); + + /** + * @param path + */ + public NetscapeCookieFile(Path path) { + this(path, new Date()); + } + + NetscapeCookieFile(Path path, Date creationDate) { + this.path = path; + this.snapshot = FileSnapshot.DIRTY; + this.creationDate = creationDate; + } + + /** + * @return the path to the underlying cookie file + */ + public Path getPath() { + return path; + } + + /** + * @param refresh + * if {@code true} updates the list from the underlying cookie + * file if it has been modified since the last read otherwise + * returns the current transient state. In case the cookie file + * has never been read before will always read from the + * underlying file disregarding the value of this parameter. + * @return all cookies (may contain session cookies as well). This does not + * return a copy of the list but rather the original one. Every + * addition to the returned list can afterwards be persisted via + * {@link #write(URL)}. Errors in the underlying file will not lead + * to exceptions but rather to an empty set being returned and the + * underlying error being logged. + */ + public Set<HttpCookie> getCookies(boolean refresh) { + if (cookies == null || refresh) { + try { + byte[] in = getFileContentIfModified(); + Set<HttpCookie> newCookies = parseCookieFile(in, creationDate); + if (cookies != null) { + cookies = mergeCookies(newCookies, cookies); + } else { + cookies = newCookies; + } + return cookies; + } catch (IOException | IllegalArgumentException e) { + LOG.warn( + MessageFormat.format( + JGitText.get().couldNotReadCookieFile, path), + e); + if (cookies == null) { + cookies = new LinkedHashSet<>(); + } + } + } + return cookies; + + } + + /** + * Parses the given file and extracts all cookie information from it. + * + * @param input + * the file content to parse + * @param creationDate + * the date for the creation of the cookies (used to calculate + * the maxAge based on the expiration date given within the file) + * @return the set of parsed cookies from the given file (even expired + * ones). If there is more than one cookie with the same name in + * this file the last one overwrites the first one! + * @throws IOException + * if the given file could not be read for some reason + * @throws IllegalArgumentException + * if the given file does not have a proper format. + */ + private static Set<HttpCookie> parseCookieFile(@NonNull byte[] input, + @NonNull Date creationDate) + throws IOException, IllegalArgumentException { + + String decoded = RawParseUtils.decode(StandardCharsets.US_ASCII, input); + + Set<HttpCookie> cookies = new LinkedHashSet<>(); + try (BufferedReader reader = new BufferedReader( + new StringReader(decoded))) { + String line; + while ((line = reader.readLine()) != null) { + HttpCookie cookie = parseLine(line, creationDate); + if (cookie != null) { + cookies.add(cookie); + } + } + } + return cookies; + } + + private static HttpCookie parseLine(@NonNull String line, + @NonNull Date creationDate) { + if (line.isEmpty() || (line.startsWith("#") //$NON-NLS-1$ + && !line.startsWith(HTTP_ONLY_PREAMBLE))) { + return null; + } + String[] cookieLineParts = line.split(COLUMN_SEPARATOR, 7); + if (cookieLineParts == null) { + throw new IllegalArgumentException(MessageFormat + .format(JGitText.get().couldNotFindTabInLine, line)); + } + if (cookieLineParts.length < 7) { + throw new IllegalArgumentException(MessageFormat.format( + JGitText.get().couldNotFindSixTabsInLine, + Integer.valueOf(cookieLineParts.length), line)); + } + String name = cookieLineParts[5]; + String value = cookieLineParts[6]; + HttpCookie cookie = new HttpCookie(name, value); + + String domain = cookieLineParts[0]; + if (domain.startsWith(HTTP_ONLY_PREAMBLE)) { + cookie.setHttpOnly(true); + domain = domain.substring(HTTP_ONLY_PREAMBLE.length()); + } + // strip off leading "." + // (https://tools.ietf.org/html/rfc6265#section-5.2.3) + if (domain.startsWith(".")) { //$NON-NLS-1$ + domain = domain.substring(1); + } + cookie.setDomain(domain); + // domain evaluation as boolean flag not considered (i.e. always assumed + // to be true) + cookie.setPath(cookieLineParts[2]); + cookie.setSecure(Boolean.parseBoolean(cookieLineParts[3])); + + long expires = Long.parseLong(cookieLineParts[4]); + long maxAge = (expires - creationDate.getTime()) / 1000; + if (maxAge <= 0) { + return null; // skip expired cookies + } + cookie.setMaxAge(maxAge); + return cookie; + } + + /** + * Writes all the cookies being maintained in the set being returned by + * {@link #getCookies(boolean)} to the underlying file. + * + * Session-cookies will not be persisted. + * + * @param url + * url for which to write the cookies (important to derive + * default values for non-explicitly set attributes) + * @throws IOException + * @throws IllegalArgumentException + * @throws InterruptedException + */ + public void write(URL url) + throws IllegalArgumentException, IOException, InterruptedException { + try { + byte[] cookieFileContent = getFileContentIfModified(); + if (cookieFileContent != null) { + LOG.debug( + "Reading the underlying cookie file '{}' as it has been modified since the last access", //$NON-NLS-1$ + path); + // reread new changes if necessary + Set<HttpCookie> cookiesFromFile = NetscapeCookieFile + .parseCookieFile(cookieFileContent, creationDate); + this.cookies = mergeCookies(cookiesFromFile, cookies); + } + } catch (FileNotFoundException e) { + // ignore if file previously did not exist yet! + } + + ByteArrayOutputStream output = new ByteArrayOutputStream(); + try (Writer writer = new OutputStreamWriter(output, + StandardCharsets.US_ASCII)) { + write(writer, cookies, url, creationDate); + } + LockFile lockFile = new LockFile(path.toFile()); + for (int retryCount = 0; retryCount < LOCK_ACQUIRE_MAX_RETRY_COUNT; retryCount++) { + if (lockFile.lock()) { + try { + lockFile.setNeedSnapshot(true); + lockFile.write(output.toByteArray()); + if (!lockFile.commit()) { + throw new IOException(MessageFormat.format( + JGitText.get().cannotCommitWriteTo, path)); + } + } finally { + lockFile.unlock(); + } + return; + } + Thread.sleep(LOCK_ACQUIRE_RETRY_SLEEP); + } + throw new IOException( + MessageFormat.format(JGitText.get().cannotLock, lockFile)); + + } + + /** + * Read the underying file and return its content but only in case it has + * been modified since the last access. Internally calculates the hash and + * maintains {@link FileSnapshot}s to prevent issues described as <a href= + * "https://github.com/git/git/blob/master/Documentation/technical/racy-git.txt">"Racy + * Git problem"</a>. Inspired by {@link FileBasedConfig#load()}. + * + * @return the file contents in case the file has been modified since the + * last access, otherwise {@code null} + * @throws IOException + */ + private byte[] getFileContentIfModified() throws IOException { + final int maxStaleRetries = 5; + int retries = 0; + File file = getPath().toFile(); + if (!file.exists()) { + LOG.warn(MessageFormat.format(JGitText.get().missingCookieFile, + file.getAbsolutePath())); + return new byte[0]; + } + while (true) { + final FileSnapshot oldSnapshot = snapshot; + final FileSnapshot newSnapshot = FileSnapshot.save(file); + try { + final byte[] in = IO.readFully(file); + byte[] newHash = hash(in); + if (Arrays.equals(hash, newHash)) { + if (oldSnapshot.equals(newSnapshot)) { + oldSnapshot.setClean(newSnapshot); + } else { + snapshot = newSnapshot; + } + } else { + snapshot = newSnapshot; + hash = newHash; + } + return in; + } catch (FileNotFoundException e) { + throw e; + } catch (IOException e) { + if (FileUtils.isStaleFileHandle(e) + && retries < maxStaleRetries) { + if (LOG.isDebugEnabled()) { + LOG.debug(MessageFormat.format( + JGitText.get().configHandleIsStale, + Integer.valueOf(retries)), e); + } + retries++; + continue; + } + throw new IOException(MessageFormat + .format(JGitText.get().cannotReadFile, getPath()), e); + } + } + + } + + private byte[] hash(final byte[] in) { + return Constants.newMessageDigest().digest(in); + } + + /** + * Writes the given cookies to the file in the Netscape Cookie File Format + * (also used by curl) + * + * @param writer + * the writer to use to persist the cookies. + * @param cookies + * the cookies to write into the file + * @param url + * the url for which to write the cookie (to derive the default + * values for certain cookie attributes) + * @param creationDate + * the date when the cookie has been created. Important for + * calculation the cookie expiration time (calculated from + * cookie's maxAge and this creation time). + * @throws IOException + */ + static void write(@NonNull Writer writer, + @NonNull Collection<HttpCookie> cookies, @NonNull URL url, + @NonNull Date creationDate) throws IOException { + for (HttpCookie cookie : cookies) { + writeCookie(writer, cookie, url, creationDate); + } + } + + private static void writeCookie(@NonNull Writer writer, + @NonNull HttpCookie cookie, @NonNull URL url, + @NonNull Date creationDate) throws IOException { + if (cookie.getMaxAge() <= 0) { + return; // skip expired cookies + } + String domain = ""; //$NON-NLS-1$ + if (cookie.isHttpOnly()) { + domain = HTTP_ONLY_PREAMBLE; + } + if (cookie.getDomain() != null) { + domain += cookie.getDomain(); + } else { + domain += url.getHost(); + } + writer.write(domain); + writer.write(COLUMN_SEPARATOR); + writer.write("TRUE"); //$NON-NLS-1$ + writer.write(COLUMN_SEPARATOR); + String path = cookie.getPath(); + if (path == null) { + path = url.getPath(); + } + writer.write(path); + writer.write(COLUMN_SEPARATOR); + writer.write(Boolean.toString(cookie.getSecure()).toUpperCase()); + writer.write(COLUMN_SEPARATOR); + final String expirationDate; + // whenCreated field is not accessible in HttpCookie + expirationDate = String + .valueOf(creationDate.getTime() + (cookie.getMaxAge() * 1000)); + writer.write(expirationDate); + writer.write(COLUMN_SEPARATOR); + writer.write(cookie.getName()); + writer.write(COLUMN_SEPARATOR); + writer.write(cookie.getValue()); + writer.write(LINE_SEPARATOR); + } + + /** + * Merge the given sets in the following way. All cookies from + * {@code cookies1} and {@code cookies2} are contained in the resulting set + * which have unique names. If there is a duplicate entry for one name only + * the entry from set {@code cookies1} ends up in the resulting set. + * + * @param cookies1 + * @param cookies2 + * + * @return the merged cookies + */ + static Set<HttpCookie> mergeCookies(Set<HttpCookie> cookies1, + @Nullable Set<HttpCookie> cookies2) { + Set<HttpCookie> mergedCookies = new LinkedHashSet<>(cookies1); + if (cookies2 != null) { + mergedCookies.addAll(cookies2); + } + return mergedCookies; + } +} diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/internal/transport/http/NetscapeCookieFileCache.java b/org.eclipse.jgit/src/org/eclipse/jgit/internal/transport/http/NetscapeCookieFileCache.java new file mode 100644 index 0000000000..882b2d055b --- /dev/null +++ b/org.eclipse.jgit/src/org/eclipse/jgit/internal/transport/http/NetscapeCookieFileCache.java @@ -0,0 +1,106 @@ +/* + * Copyright (C) 2018, Konrad Windszus <konrad_w@gmx.de> + * and other copyright owners as documented in the project's IP log. + * + * This program and the accompanying materials are made available + * under the terms of the Eclipse Distribution License v1.0 which + * accompanies this distribution, is reproduced below, and is + * available at http://www.eclipse.org/org/documents/edl-v10.php + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or + * without modification, are permitted provided that the following + * conditions are met: + * + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * - Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials provided + * with the distribution. + * + * - Neither the name of the Eclipse Foundation, Inc. nor the + * names of its contributors may be used to endorse or promote + * products derived from this software without specific prior + * written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +package org.eclipse.jgit.internal.transport.http; + +import java.nio.file.Path; + +import org.eclipse.jgit.transport.HttpConfig; +import org.eclipse.jgit.util.LRUMap; + +/** + * A cache of all known cookie files ({@link NetscapeCookieFile}). May contain + * at most {@code n} entries, where the least-recently used one is evicted as + * soon as more entries are added. The maximum number of entries (={@code n}) + * can be set via the git config key {@code http.cookieFileCacheLimit}. By + * default it is set to 10. + * <p> + * The cache is global, i.e. it is shared among all consumers within the same + * Java process. + * + * @see NetscapeCookieFile + * + */ +public class NetscapeCookieFileCache { + + private final LRUMap<Path, NetscapeCookieFile> cookieFileMap; + + private static NetscapeCookieFileCache instance; + + private NetscapeCookieFileCache(HttpConfig config) { + cookieFileMap = new LRUMap<>(config.getCookieFileCacheLimit(), + config.getCookieFileCacheLimit()); + } + + /** + * @param config + * the config which defines the limit for this cache + * @return the singleton instance of the cookie file cache. If the cache has + * already been created the given config is ignored (even if it + * differs from the config, with which the cache has originally been + * created) + */ + public static NetscapeCookieFileCache getInstance(HttpConfig config) { + if (instance == null) { + return new NetscapeCookieFileCache(config); + } else { + return instance; + } + } + + /** + * @param path + * the path of the cookie file to retrieve + * @return the cache entry belonging to the requested file + */ + public NetscapeCookieFile getEntry(Path path) { + if (!cookieFileMap.containsKey(path)) { + synchronized (NetscapeCookieFileCache.class) { + if (!cookieFileMap.containsKey(path)) { + cookieFileMap.put(path, new NetscapeCookieFile(path)); + } + } + } + return cookieFileMap.get(path); + } + +} diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/lib/AbbreviatedObjectId.java b/org.eclipse.jgit/src/org/eclipse/jgit/lib/AbbreviatedObjectId.java index d105d0d200..b0339c677f 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/lib/AbbreviatedObjectId.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/lib/AbbreviatedObjectId.java @@ -162,7 +162,7 @@ public final class AbbreviatedObjectId implements Serializable { r |= RawParseUtils.parseHexInt4(bs[p++]); n++; } - return r << (8 - n) * 4; + return r << ((8 - n) * 4); } static int mask(int nibbles, int word, int v) { diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/lib/Config.java b/org.eclipse.jgit/src/org/eclipse/jgit/lib/Config.java index 4726975d07..1032fd0df1 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/lib/Config.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/lib/Config.java @@ -107,7 +107,7 @@ public class Config { * must ensure it is a special copy of the empty string. It also must * be treated like the empty string. */ - static final String MAGIC_EMPTY_VALUE = new String(); + private static final String MISSING_ENTRY = new String(); /** * Create a configuration with no default fallback. @@ -129,6 +129,17 @@ public class Config { } /** + * Check if a given string is the "missing" value. + * + * @param value + * @return true if the given string is the "missing" value. + * @since 5.4 + */ + public static boolean isMissing(String value) { + return value == MISSING_ENTRY; + } + + /** * Globally sets a {@link org.eclipse.jgit.lib.TypedConfigGetter} that is * subsequently used to read typed values from all git configs. * @@ -1041,7 +1052,7 @@ public class Config { if (e.prefix == null || "".equals(e.prefix)) //$NON-NLS-1$ out.append('\t'); out.append(e.name); - if (MAGIC_EMPTY_VALUE != e.value) { + if (MISSING_ENTRY != e.value) { out.append(" ="); //$NON-NLS-1$ if (e.value != null) { out.append(' '); @@ -1132,7 +1143,7 @@ public class Config { e.name = readKeyName(in); if (e.name.endsWith("\n")) { //$NON-NLS-1$ e.name = e.name.substring(0, e.name.length() - 1); - e.value = MAGIC_EMPTY_VALUE; + e.value = MISSING_ENTRY; } else e.value = readValue(in); @@ -1165,7 +1176,7 @@ public class Config { private void addIncludedConfig(final List<ConfigLine> newEntries, ConfigLine line, int depth) throws ConfigInvalidException { if (!line.name.equalsIgnoreCase("path") || //$NON-NLS-1$ - line.value == null || line.value.equals(MAGIC_EMPTY_VALUE)) { + line.value == null || line.value.equals(MISSING_ENTRY)) { throw new ConfigInvalidException(MessageFormat.format( JGitText.get().invalidLineInConfigFileWithParam, line)); } @@ -1413,11 +1424,23 @@ public class Config { case '"': value.append('"'); continue; + case '\r': { + int next = in.read(); + if (next == '\n') { + continue; // CR-LF + } else if (next >= 0) { + in.reset(); + } + break; + } default: - throw new ConfigInvalidException(MessageFormat.format( - JGitText.get().badEscape, - Character.valueOf(((char) c)))); + break; } + throw new ConfigInvalidException( + MessageFormat.format(JGitText.get().badEscape, + Character.isAlphabetic(c) + ? Character.valueOf(((char) c)) + : toUnicodeLiteral(c))); } if ('"' == c) { @@ -1430,6 +1453,11 @@ public class Config { return value.length() > 0 ? value.toString() : null; } + private static String toUnicodeLiteral(int c) { + return String.format("\\u%04x", //$NON-NLS-1$ + Integer.valueOf(c)); + } + /** * Parses a section of the configuration into an application model object. * <p> diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/lib/DefaultTypedConfigGetter.java b/org.eclipse.jgit/src/org/eclipse/jgit/lib/DefaultTypedConfigGetter.java index 6a66cf682f..4c70d20d6c 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/lib/DefaultTypedConfigGetter.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/lib/DefaultTypedConfigGetter.java @@ -72,7 +72,7 @@ public class DefaultTypedConfigGetter implements TypedConfigGetter { if (n == null) { return defaultValue; } - if (Config.MAGIC_EMPTY_VALUE == n) { + if (Config.isMissing(n)) { return true; } try { diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/lib/RebaseTodoFile.java b/org.eclipse.jgit/src/org/eclipse/jgit/lib/RebaseTodoFile.java index 06b4b227c8..c0fcd4161f 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/lib/RebaseTodoFile.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/lib/RebaseTodoFile.java @@ -179,7 +179,7 @@ public class RebaseTodoFile { int nextSpace = RawParseUtils.next(buf, tokenBegin, ' '); int tokenCount = 0; - while (tokenCount < 3 && nextSpace < lineEnd) { + while (tokenCount < 3 && nextSpace <= lineEnd) { switch (tokenCount) { case 0: String actionToken = new String(buf, tokenBegin, @@ -191,8 +191,14 @@ public class RebaseTodoFile { break; case 1: nextSpace = RawParseUtils.next(buf, tokenBegin, ' '); - String commitToken = new String(buf, tokenBegin, - nextSpace - tokenBegin - 1, UTF_8); + String commitToken; + if (nextSpace > lineEnd + 1) { + commitToken = new String(buf, tokenBegin, + lineEnd - tokenBegin + 1, UTF_8); + } else { + commitToken = new String(buf, tokenBegin, + nextSpace - tokenBegin - 1, UTF_8); + } tokenBegin = nextSpace; commit = AbbreviatedObjectId.fromString(commitToken); break; diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/lib/Repository.java b/org.eclipse.jgit/src/org/eclipse/jgit/lib/Repository.java index aac63e9d24..d53b0c926a 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/lib/Repository.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/lib/Repository.java @@ -240,6 +240,15 @@ public abstract class Repository implements AutoCloseable { } /** + * Get repository identifier. + * + * @return repository identifier. The returned identifier has to be unique + * within a given Git server. + * @since 5.4 + */ + public abstract String getIdentifier(); + + /** * Get the object database which stores this repository's data. * * @return the object database which stores this repository's data. diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/lib/internal/BouncyCastleGpgKeyLocator.java b/org.eclipse.jgit/src/org/eclipse/jgit/lib/internal/BouncyCastleGpgKeyLocator.java index df9615fc9d..0d44317658 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/lib/internal/BouncyCastleGpgKeyLocator.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/lib/internal/BouncyCastleGpgKeyLocator.java @@ -54,6 +54,8 @@ import java.nio.file.Files; import java.nio.file.InvalidPathException; import java.nio.file.Path; import java.nio.file.Paths; +import java.security.NoSuchAlgorithmException; +import java.security.NoSuchProviderException; import java.text.MessageFormat; import java.util.Iterator; import java.util.Locale; @@ -67,6 +69,7 @@ import org.bouncycastle.gpg.keybox.KeyBox; import org.bouncycastle.gpg.keybox.KeyInformation; import org.bouncycastle.gpg.keybox.PublicKeyRingBlob; import org.bouncycastle.gpg.keybox.UserID; +import org.bouncycastle.gpg.keybox.jcajce.JcaKeyBoxBuilder; import org.bouncycastle.openpgp.PGPException; import org.bouncycastle.openpgp.PGPPublicKey; import org.bouncycastle.openpgp.PGPSecretKey; @@ -210,9 +213,12 @@ class BouncyCastleGpgKeyLocator { * @return publicKey the public key (maybe <code>null</code>) * @throws IOException * in case of problems reading the file + * @throws NoSuchAlgorithmException + * @throws NoSuchProviderException */ private PGPPublicKey findPublicKeyInKeyBox(Path keyboxFile) - throws IOException { + throws IOException, NoSuchAlgorithmException, + NoSuchProviderException { KeyBox keyBox = readKeyBoxFile(keyboxFile); for (KeyBlob keyBlob : keyBox.getKeyBlobs()) { if (keyBlob.getType() == BlobType.OPEN_PGP_BLOB) { @@ -236,15 +242,17 @@ class BouncyCastleGpgKeyLocator { * @return the secret key * @throws IOException * in case of issues reading key files + * @throws NoSuchAlgorithmException + * @throws NoSuchProviderException * @throws PGPException * in case of issues finding a key * @throws CanceledException * @throws URISyntaxException * @throws UnsupportedCredentialItem */ - public BouncyCastleGpgKey findSecretKey() - throws IOException, PGPException, CanceledException, - UnsupportedCredentialItem, URISyntaxException { + public BouncyCastleGpgKey findSecretKey() throws IOException, + NoSuchAlgorithmException, NoSuchProviderException, PGPException, + CanceledException, UnsupportedCredentialItem, URISyntaxException { if (exists(USER_KEYBOX_PATH)) { PGPPublicKey publicKey = // findPublicKeyInKeyBox(USER_KEYBOX_PATH); @@ -376,14 +384,12 @@ class BouncyCastleGpgKeyLocator { .getPublicKey(); } - private KeyBox readKeyBoxFile(Path keyboxFile) throws IOException { + private KeyBox readKeyBoxFile(Path keyboxFile) throws IOException, + NoSuchAlgorithmException, NoSuchProviderException { KeyBox keyBox; try (InputStream in = new BufferedInputStream( newInputStream(keyboxFile))) { - // note: KeyBox constructor reads in the whole InputStream at once - // this code will change in 1.61 to - // either 'new BcKeyBox(in)' or 'new JcaKeyBoxBuilder().build(in)' - keyBox = new KeyBox(in, new JcaKeyFingerprintCalculator()); + keyBox = new JcaKeyBoxBuilder().build(in); } return keyBox; } diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/lib/internal/BouncyCastleGpgSigner.java b/org.eclipse.jgit/src/org/eclipse/jgit/lib/internal/BouncyCastleGpgSigner.java index 4d696dd9e7..cfe0931b47 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/lib/internal/BouncyCastleGpgSigner.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/lib/internal/BouncyCastleGpgSigner.java @@ -45,6 +45,8 @@ package org.eclipse.jgit.lib.internal; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.net.URISyntaxException; +import java.security.NoSuchAlgorithmException; +import java.security.NoSuchProviderException; import java.security.Security; import org.bouncycastle.bcpg.ArmoredOutputStream; @@ -100,7 +102,8 @@ public class BouncyCastleGpgSigner extends GpgSigner { BouncyCastleGpgKey gpgKey = locateSigningKey(gpgSigningKey, committer, passphrasePrompt); return gpgKey != null; - } catch (PGPException | IOException | URISyntaxException e) { + } catch (PGPException | IOException | NoSuchAlgorithmException + | NoSuchProviderException | URISyntaxException e) { return false; } } @@ -109,7 +112,8 @@ public class BouncyCastleGpgSigner extends GpgSigner { PersonIdent committer, BouncyCastleGpgKeyPassphrasePrompt passphrasePrompt) throws CanceledException, UnsupportedCredentialItem, IOException, - PGPException, URISyntaxException { + NoSuchAlgorithmException, NoSuchProviderException, PGPException, + URISyntaxException { if (gpgSigningKey == null || gpgSigningKey.isEmpty()) { gpgSigningKey = committer.getEmailAddress(); } @@ -153,7 +157,8 @@ public class BouncyCastleGpgSigner extends GpgSigner { signatureGenerator.generate().encode(out); } commit.setGpgSignature(new GpgSignature(buffer.toByteArray())); - } catch (PGPException | IOException | URISyntaxException e) { + } catch (PGPException | IOException | NoSuchAlgorithmException + | NoSuchProviderException | URISyntaxException e) { throw new JGitInternalException(e.getMessage(), e); } } 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 b69327a9b3..0c3d3fec26 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/merge/ResolveMerger.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/merge/ResolveMerger.java @@ -1190,7 +1190,7 @@ public class ResolveMerger extends ThreeWayMerger { * otherwise */ public boolean failed() { - return failingPaths.size() > 0; + return !failingPaths.isEmpty(); } /** diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/BitmapCalculator.java b/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/BitmapCalculator.java index e1d5d4adad..14e95670aa 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/BitmapCalculator.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/BitmapCalculator.java @@ -1,3 +1,45 @@ +/* + * Copyright (C) 2019, Google LLC. + * and other copyright owners as documented in the project's IP log. + * + * This program and the accompanying materials are made available + * under the terms of the Eclipse Distribution License v1.0 which + * accompanies this distribution, is reproduced below, and is + * available at http://www.eclipse.org/org/documents/edl-v10.php + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or + * without modification, are permitted provided that the following + * conditions are met: + * + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * - Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials provided + * with the distribution. + * + * - Neither the name of the Eclipse Foundation, Inc. nor the + * names of its contributors may be used to endorse or promote + * products derived from this software without specific prior + * written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ package org.eclipse.jgit.revwalk; import static java.util.Objects.requireNonNull; @@ -52,8 +94,9 @@ class BitmapCalculator { * @throws MissingObjectException * the supplied id doesn't exist * @throws IncorrectObjectTypeException - * the supplied id doens't refer to a commit or a tag + * the supplied id doesn't refer to a commit or a tag * @throws IOException + * if the walk cannot open a packfile or loose object */ BitmapBuilder getBitmap(RevCommit start, ProgressMonitor pm) throws MissingObjectException, diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/BitmappedReachabilityChecker.java b/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/BitmappedReachabilityChecker.java index ab453433d8..6e510f677b 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/BitmappedReachabilityChecker.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/BitmappedReachabilityChecker.java @@ -55,10 +55,8 @@ import org.eclipse.jgit.lib.NullProgressMonitor; /** * Checks the reachability using bitmaps. - * - * @since 5.4 */ -public class BitmappedReachabilityChecker implements ReachabilityChecker { +class BitmappedReachabilityChecker implements ReachabilityChecker { private final RevWalk walk; diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/PedestrianReachabilityChecker.java b/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/PedestrianReachabilityChecker.java index 4012a45d3c..bba3c5cff3 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/PedestrianReachabilityChecker.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/PedestrianReachabilityChecker.java @@ -52,10 +52,8 @@ import org.eclipse.jgit.errors.MissingObjectException; /** * Checks the reachability walking the graph from the starters towards the * target. - * - * @since 5.4 */ -public class PedestrianReachabilityChecker implements ReachabilityChecker { +class PedestrianReachabilityChecker implements ReachabilityChecker { private final boolean topoSort; diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/RevWalk.java b/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/RevWalk.java index f12eb2ff86..80fc81073c 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/RevWalk.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/RevWalk.java @@ -250,6 +250,23 @@ public class RevWalk implements Iterable<RevCommit>, AutoCloseable { } /** + * Get a reachability checker for commits over this revwalk. + * + * @return the most efficient reachability checker for this repository. + * @throws IOException + * if it cannot open any of the underlying indices. + * + * @since 5.4 + */ + public ReachabilityChecker createReachabilityChecker() throws IOException { + if (reader.getBitmapIndex() != null) { + return new BitmappedReachabilityChecker(this); + } + + return new PedestrianReachabilityChecker(true, this); + } + + /** * {@inheritDoc} * <p> * Release any resources used by this walker's reader. diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/RevWalkUtils.java b/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/RevWalkUtils.java index fabf7075d5..2b721b8877 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/RevWalkUtils.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/RevWalkUtils.java @@ -50,6 +50,9 @@ import java.util.List; import org.eclipse.jgit.errors.IncorrectObjectTypeException; import org.eclipse.jgit.errors.MissingObjectException; +import org.eclipse.jgit.internal.JGitText; +import org.eclipse.jgit.lib.NullProgressMonitor; +import org.eclipse.jgit.lib.ProgressMonitor; import org.eclipse.jgit.lib.Ref; /** @@ -153,15 +156,51 @@ public final class RevWalkUtils { RevWalk revWalk, Collection<Ref> refs) throws MissingObjectException, IncorrectObjectTypeException, IOException { + return findBranchesReachableFrom(commit, revWalk, refs, + NullProgressMonitor.INSTANCE); + } + + /** + * Find the list of branches a given commit is reachable from when following + * parents. + * <p> + * Note that this method calls + * {@link org.eclipse.jgit.revwalk.RevWalk#reset()} at the beginning. + * <p> + * In order to improve performance this method assumes clock skew among + * committers is never larger than 24 hours. + * + * @param commit + * the commit we are looking at + * @param revWalk + * The RevWalk to be used. + * @param refs + * the set of branches we want to see reachability from + * @param monitor + * the callback for progress and cancellation + * @return the list of branches a given commit is reachable from + * @throws org.eclipse.jgit.errors.MissingObjectException + * @throws org.eclipse.jgit.errors.IncorrectObjectTypeException + * @throws java.io.IOException + * @since 5.4 + */ + public static List<Ref> findBranchesReachableFrom(RevCommit commit, + RevWalk revWalk, Collection<Ref> refs, ProgressMonitor monitor) + throws MissingObjectException, IncorrectObjectTypeException, + IOException { // Make sure commit is from the same RevWalk commit = revWalk.parseCommit(commit.getId()); revWalk.reset(); List<Ref> result = new ArrayList<>(); - + monitor.beginTask(JGitText.get().searchForReachableBranches, + refs.size()); final int SKEW = 24*3600; // one day clock skew for (Ref ref : refs) { + if (monitor.isCancelled()) + return result; + monitor.update(1); RevObject maybehead = revWalk.parseAny(ref.getObjectId()); if (!(maybehead instanceof RevCommit)) continue; @@ -176,6 +215,7 @@ public final class RevWalkUtils { if (revWalk.isMergedInto(commit, headCommit)) result.add(ref); } + monitor.endTask(); return result; } diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/storage/file/FileBasedConfig.java b/org.eclipse.jgit/src/org/eclipse/jgit/storage/file/FileBasedConfig.java index 2b31ebd8e3..fc6f4a39cd 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/storage/file/FileBasedConfig.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/storage/file/FileBasedConfig.java @@ -148,7 +148,8 @@ public class FileBasedConfig extends StoredConfig { */ @Override public void load() throws IOException, ConfigInvalidException { - final int maxStaleRetries = 5; + final int maxRetries = 5; + int retryDelayMillis = 20; int retries = 0; while (true) { final FileSnapshot oldSnapshot = snapshot; @@ -177,6 +178,22 @@ public class FileBasedConfig extends StoredConfig { } return; } catch (FileNotFoundException noFile) { + // might be locked by another process (see exception Javadoc) + if (retries < maxRetries && configFile.exists()) { + if (LOG.isDebugEnabled()) { + LOG.debug(MessageFormat.format( + JGitText.get().configHandleMayBeLocked, + Integer.valueOf(retries)), noFile); + } + try { + Thread.sleep(retryDelayMillis); + } catch (InterruptedException e) { + Thread.currentThread().interrupt(); + } + retries++; + retryDelayMillis *= 2; // max wait 1260 ms + continue; + } if (configFile.exists()) { throw noFile; } @@ -185,7 +202,7 @@ public class FileBasedConfig extends StoredConfig { return; } catch (IOException e) { if (FileUtils.isStaleFileHandle(e) - && retries < maxStaleRetries) { + && retries < maxRetries) { if (LOG.isDebugEnabled()) { LOG.debug(MessageFormat.format( JGitText.get().configHandleIsStale, diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/transport/BasePackConnection.java b/org.eclipse.jgit/src/org/eclipse/jgit/transport/BasePackConnection.java index 20a5d9da72..e8724b72db 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/transport/BasePackConnection.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/transport/BasePackConnection.java @@ -201,7 +201,7 @@ abstract class BasePackConnection extends BaseConnection { throw noRepository(); throw eof; } - if (line == PacketLineIn.END) + if (PacketLineIn.isEnd(line)) break; if (line.startsWith("ERR ")) { //$NON-NLS-1$ diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/transport/BasePackPushConnection.java b/org.eclipse.jgit/src/org/eclipse/jgit/transport/BasePackPushConnection.java index 847e901980..35ea35ecb8 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/transport/BasePackPushConnection.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/transport/BasePackPushConnection.java @@ -383,8 +383,7 @@ public abstract class BasePackPushConnection extends BasePackConnection implemen JGitText.get().errorOccurredDuringUnpackingOnTheRemoteEnd, unpackStatus)); } - String refLine; - while ((refLine = pckIn.readString()) != PacketLineIn.END) { + for (String refLine : pckIn.readStrings()) { boolean ok = false; int refNameEnd = -1; if (refLine.startsWith("ok ")) { //$NON-NLS-1$ diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/transport/BaseReceivePack.java b/org.eclipse.jgit/src/org/eclipse/jgit/transport/BaseReceivePack.java index 1741db97fe..e402de0158 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/transport/BaseReceivePack.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/transport/BaseReceivePack.java @@ -1282,7 +1282,7 @@ public abstract class BaseReceivePack { return; throw eof; } - if (line == PacketLineIn.END) { + if (PacketLineIn.isEnd(line)) { break; } diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/transport/BundleWriter.java b/org.eclipse.jgit/src/org/eclipse/jgit/transport/BundleWriter.java index a09b1ff1d2..d1db51eca6 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/transport/BundleWriter.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/transport/BundleWriter.java @@ -227,7 +227,7 @@ public class BundleWriter { exc.add(r.getId()); packWriter.setIndexDisabled(true); packWriter.setDeltaBaseAsOffset(true); - packWriter.setThin(exc.size() > 0); + packWriter.setThin(!exc.isEmpty()); packWriter.setReuseValidatingObjects(false); if (exc.isEmpty()) { packWriter.setTagTargets(tagTargets); diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/transport/HMACSHA1NonceGenerator.java b/org.eclipse.jgit/src/org/eclipse/jgit/transport/HMACSHA1NonceGenerator.java index 53eaa6a7f9..01f6fec7e4 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/transport/HMACSHA1NonceGenerator.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/transport/HMACSHA1NonceGenerator.java @@ -45,14 +45,12 @@ package org.eclipse.jgit.transport; import static java.nio.charset.StandardCharsets.ISO_8859_1; import static java.nio.charset.StandardCharsets.UTF_8; -import java.io.File; import java.security.InvalidKeyException; import java.security.NoSuchAlgorithmException; import javax.crypto.Mac; import javax.crypto.spec.SecretKeySpec; -import org.eclipse.jgit.internal.storage.dfs.DfsRepository; import org.eclipse.jgit.lib.Repository; import org.eclipse.jgit.transport.PushCertificate.NonceStatus; @@ -87,19 +85,7 @@ public class HMACSHA1NonceGenerator implements NonceGenerator { @Override public synchronized String createNonce(Repository repo, long timestamp) throws IllegalStateException { - String path; - if (repo instanceof DfsRepository) { - path = ((DfsRepository) repo).getDescription().getRepositoryName(); - } else { - File directory = repo.getDirectory(); - if (directory != null) { - path = directory.getPath(); - } else { - throw new IllegalStateException(); - } - } - - String input = path + ":" + String.valueOf(timestamp); //$NON-NLS-1$ + String input = repo.getIdentifier() + ":" + String.valueOf(timestamp); //$NON-NLS-1$ byte[] rawHmac = mac.doFinal(input.getBytes(UTF_8)); return Long.toString(timestamp) + "-" + toHex(rawHmac); //$NON-NLS-1$ } diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/transport/HttpConfig.java b/org.eclipse.jgit/src/org/eclipse/jgit/transport/HttpConfig.java index 101ce35685..54c21cbc8c 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/transport/HttpConfig.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/transport/HttpConfig.java @@ -89,6 +89,30 @@ public class HttpConfig { /** git config key for the "sslVerify" setting. */ public static final String SSL_VERIFY_KEY = "sslVerify"; //$NON-NLS-1$ + /** + * git config key for the "cookieFile" setting. + * + * @since 5.4 + */ + public static final String COOKIE_FILE_KEY = "cookieFile"; //$NON-NLS-1$ + + /** + * git config key for the "saveCookies" setting. + * + * @since 5.4 + */ + public static final String SAVE_COOKIES_KEY = "saveCookies"; //$NON-NLS-1$ + + /** + * Custom JGit config key which holds the maximum number of cookie files to + * keep in the cache. + * + * @since 5.4 + */ + public static final String COOKIE_FILE_CACHE_LIMIT_KEY = "cookieFileCacheLimit"; //$NON-NLS-1$ + + private static final int DEFAULT_COOKIE_FILE_CACHE_LIMIT = 10; + private static final String MAX_REDIRECT_SYSTEM_PROPERTY = "http.maxRedirects"; //$NON-NLS-1$ private static final int DEFAULT_MAX_REDIRECTS = 5; @@ -153,6 +177,12 @@ public class HttpConfig { private int maxRedirects; + private String cookieFile; + + private boolean saveCookies; + + private int cookieFileCacheLimit; + /** * Get the "http.postBuffer" setting * @@ -190,6 +220,40 @@ public class HttpConfig { } /** + * Get the "http.cookieFile" setting + * + * @return the value of the "http.cookieFile" setting + * + * @since 5.4 + */ + public String getCookieFile() { + return cookieFile; + } + + /** + * Get the "http.saveCookies" setting + * + * @return the value of the "http.saveCookies" setting + * + * @since 5.4 + */ + public boolean getSaveCookies() { + return saveCookies; + } + + /** + * Get the "http.cookieFileCacheLimit" setting (gives the maximum number of + * cookie files to keep in the LRU cache) + * + * @return the value of the "http.cookieFileCacheLimit" setting + * + * @since 5.4 + */ + public int getCookieFileCacheLimit() { + return cookieFileCacheLimit; + } + + /** * Creates a new {@link org.eclipse.jgit.transport.HttpConfig} tailored to * the given {@link org.eclipse.jgit.transport.URIish}. * @@ -237,6 +301,10 @@ public class HttpConfig { if (redirectLimit < 0) { redirectLimit = MAX_REDIRECTS; } + cookieFile = config.getString(HTTP, null, COOKIE_FILE_KEY); + saveCookies = config.getBoolean(HTTP, SAVE_COOKIES_KEY, false); + cookieFileCacheLimit = config.getInt(HTTP, COOKIE_FILE_CACHE_LIMIT_KEY, + DEFAULT_COOKIE_FILE_CACHE_LIMIT); String match = findMatch(config.getSubsections(HTTP), uri); if (match != null) { // Override with more specific items @@ -251,6 +319,13 @@ public class HttpConfig { if (newMaxRedirects >= 0) { redirectLimit = newMaxRedirects; } + String urlSpecificCookieFile = config.getString(HTTP, match, + COOKIE_FILE_KEY); + if (urlSpecificCookieFile != null) { + cookieFile = urlSpecificCookieFile; + } + saveCookies = config.getBoolean(HTTP, match, SAVE_COOKIES_KEY, + saveCookies); } postBuffer = postBufferSize; sslVerify = sslVerifyFlag; diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/transport/PacketLineIn.java b/org.eclipse.jgit/src/org/eclipse/jgit/transport/PacketLineIn.java index c6e19d5762..90f1b373ba 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/transport/PacketLineIn.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/transport/PacketLineIn.java @@ -49,7 +49,9 @@ import static java.nio.charset.StandardCharsets.UTF_8; import java.io.IOException; import java.io.InputStream; +import java.io.UncheckedIOException; import java.text.MessageFormat; +import java.util.Iterator; import org.eclipse.jgit.errors.PackProtocolException; import org.eclipse.jgit.internal.JGitText; @@ -72,14 +74,25 @@ import org.slf4j.LoggerFactory; public class PacketLineIn { private static final Logger log = LoggerFactory.getLogger(PacketLineIn.class); - /** Magic return from {@link #readString()} when a flush packet is found. */ + /** + * Magic return from {@link #readString()} when a flush packet is found. + * + * @deprecated Callers should use {@link #isEnd(String)} to check if a + * string is the end marker, or + * {@link PacketLineIn#readStrings()} to iterate over all + * strings in the input stream until the marker is reached. + */ + @Deprecated public static final String END = new StringBuilder(0).toString(); /* must not string pool */ /** * Magic return from {@link #readString()} when a delim packet is found. * * @since 5.0 + * @deprecated Callers should use {@link #isDelimiter(String)} to check if a + * string is the delimiter. */ + @Deprecated public static final String DELIM = new StringBuilder(0).toString(); /* must not string pool */ static enum AckNackResult { @@ -193,6 +206,20 @@ public class PacketLineIn { } /** + * Get an iterator to read strings from the input stream. + * + * @return an iterator that calls {@link #readString()} until {@link #END} + * is encountered. + * + * @throws IOException + * on failure to read the initial packet line. + * @since 5.4 + */ + public PacketLineInIterator readStrings() throws IOException { + return new PacketLineInIterator(this); + } + + /** * Read a single UTF-8 encoded string packet from the input stream. * <p> * Unlike {@link #readString()} a trailing LF will be retained. @@ -224,6 +251,52 @@ public class PacketLineIn { return s; } + /** + * Check if a string is the delimiter marker. + * + * @param s + * the string to check + * @return true if the given string is {@link #DELIM}, otherwise false. + * @since 5.4 + */ + public static boolean isDelimiter(String s) { + return s == DELIM; + } + + /** + * Get the delimiter marker. + * <p> + * Intended for use only in tests. + * + * @return The delimiter marker. + */ + static String delimiter() { + return DELIM; + } + + /** + * Get the end marker. + * <p> + * Intended for use only in tests. + * + * @return The end marker. + */ + static String end() { + return END; + } + + /** + * Check if a string is the packet end marker. + * + * @param s + * the string to check + * @return true if the given string is {@link #END}, otherwise false. + * @since 5.4 + */ + public static boolean isEnd(String s) { + return s == END; + } + void discardUntilEnd() throws IOException { for (;;) { int n = readLength(); @@ -282,4 +355,46 @@ public class PacketLineIn { public static class InputOverLimitIOException extends IOException { private static final long serialVersionUID = 1L; } + + /** + * Iterator over packet lines. + * <p> + * Calls {@link #readString()} on the {@link PacketLineIn} until + * {@link #END} is encountered. + * + * @since 5.4 + * + */ + public static class PacketLineInIterator implements Iterable<String> { + private PacketLineIn in; + + private String current; + + PacketLineInIterator(PacketLineIn in) throws IOException { + this.in = in; + current = in.readString(); + } + + @Override + public Iterator<String> iterator() { + return new Iterator<String>() { + @Override + public boolean hasNext() { + return !PacketLineIn.isEnd(current); + } + + @Override + public String next() { + String next = current; + try { + current = in.readString(); + } catch (IOException e) { + throw new UncheckedIOException(e); + } + return next; + } + }; + } + + } } diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/transport/ProtocolV0Parser.java b/org.eclipse.jgit/src/org/eclipse/jgit/transport/ProtocolV0Parser.java index 396327aab0..428a45c09d 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/transport/ProtocolV0Parser.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/transport/ProtocolV0Parser.java @@ -99,7 +99,7 @@ final class ProtocolV0Parser { throw eof; } - if (line == PacketLineIn.END) { + if (PacketLineIn.isEnd(line)) { break; } diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/transport/ProtocolV2Parser.java b/org.eclipse.jgit/src/org/eclipse/jgit/transport/ProtocolV2Parser.java index cb04ff69a9..caba15fc54 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/transport/ProtocolV2Parser.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/transport/ProtocolV2Parser.java @@ -92,7 +92,7 @@ final class ProtocolV2Parser { String agentPrefix = OPTION_AGENT + '='; String line = pckIn.readString(); - while (line != PacketLineIn.DELIM && line != PacketLineIn.END) { + while (!PacketLineIn.isDelimiter(line) && !PacketLineIn.isEnd(line)) { if (line.startsWith(serverOptionPrefix)) { serverOptionConsumer .accept(line.substring(serverOptionPrefix.length())); @@ -133,40 +133,41 @@ final class ProtocolV2Parser { serverOption -> reqBuilder.addServerOption(serverOption), agent -> reqBuilder.setAgent(agent)); - if (line == PacketLineIn.END) { + if (PacketLineIn.isEnd(line)) { return reqBuilder.build(); } - if (line != PacketLineIn.DELIM) { + if (!PacketLineIn.isDelimiter(line)) { throw new PackProtocolException( MessageFormat.format(JGitText.get().unexpectedPacketLine, line)); } boolean filterReceived = false; - while ((line = pckIn.readString()) != PacketLineIn.END) { - if (line.startsWith("want ")) { //$NON-NLS-1$ - reqBuilder.addWantId(ObjectId.fromString(line.substring(5))); + for (String line2 : pckIn.readStrings()) { + if (line2.startsWith("want ")) { //$NON-NLS-1$ + reqBuilder.addWantId(ObjectId.fromString(line2.substring(5))); } else if (transferConfig.isAllowRefInWant() - && line.startsWith(OPTION_WANT_REF + " ")) { //$NON-NLS-1$ - reqBuilder.addWantedRef(line.substring(OPTION_WANT_REF.length() + 1)); - } else if (line.startsWith("have ")) { //$NON-NLS-1$ - reqBuilder.addPeerHas(ObjectId.fromString(line.substring(5))); - } else if (line.equals("done")) { //$NON-NLS-1$ + && line2.startsWith(OPTION_WANT_REF + " ")) { //$NON-NLS-1$ + reqBuilder.addWantedRef( + line2.substring(OPTION_WANT_REF.length() + 1)); + } else if (line2.startsWith("have ")) { //$NON-NLS-1$ + reqBuilder.addPeerHas(ObjectId.fromString(line2.substring(5))); + } else if (line2.equals("done")) { //$NON-NLS-1$ reqBuilder.setDoneReceived(); - } else if (line.equals(OPTION_THIN_PACK)) { + } else if (line2.equals(OPTION_THIN_PACK)) { reqBuilder.addClientCapability(OPTION_THIN_PACK); - } else if (line.equals(OPTION_NO_PROGRESS)) { + } else if (line2.equals(OPTION_NO_PROGRESS)) { reqBuilder.addClientCapability(OPTION_NO_PROGRESS); - } else if (line.equals(OPTION_INCLUDE_TAG)) { + } else if (line2.equals(OPTION_INCLUDE_TAG)) { reqBuilder.addClientCapability(OPTION_INCLUDE_TAG); - } else if (line.equals(OPTION_OFS_DELTA)) { + } else if (line2.equals(OPTION_OFS_DELTA)) { reqBuilder.addClientCapability(OPTION_OFS_DELTA); - } else if (line.startsWith("shallow ")) { //$NON-NLS-1$ + } else if (line2.startsWith("shallow ")) { //$NON-NLS-1$ reqBuilder.addClientShallowCommit( - ObjectId.fromString(line.substring(8))); - } else if (line.startsWith("deepen ")) { //$NON-NLS-1$ - int parsedDepth = Integer.parseInt(line.substring(7)); + ObjectId.fromString(line2.substring(8))); + } else if (line2.startsWith("deepen ")) { //$NON-NLS-1$ + int parsedDepth = Integer.parseInt(line2.substring(7)); if (parsedDepth <= 0) { throw new PackProtocolException( MessageFormat.format(JGitText.get().invalidDepth, @@ -181,19 +182,19 @@ final class ProtocolV2Parser { JGitText.get().deepenNotWithDeepen); } reqBuilder.setDepth(parsedDepth); - } else if (line.startsWith("deepen-not ")) { //$NON-NLS-1$ - reqBuilder.addDeepenNotRef(line.substring(11)); + } else if (line2.startsWith("deepen-not ")) { //$NON-NLS-1$ + reqBuilder.addDeepenNotRef(line2.substring(11)); if (reqBuilder.getDepth() != 0) { throw new PackProtocolException( JGitText.get().deepenNotWithDeepen); } - } else if (line.equals(OPTION_DEEPEN_RELATIVE)) { + } else if (line2.equals(OPTION_DEEPEN_RELATIVE)) { reqBuilder.addClientCapability(OPTION_DEEPEN_RELATIVE); - } else if (line.startsWith("deepen-since ")) { //$NON-NLS-1$ - int ts = Integer.parseInt(line.substring(13)); + } else if (line2.startsWith("deepen-since ")) { //$NON-NLS-1$ + int ts = Integer.parseInt(line2.substring(13)); if (ts <= 0) { throw new PackProtocolException(MessageFormat - .format(JGitText.get().invalidTimestamp, line)); + .format(JGitText.get().invalidTimestamp, line2)); } if (reqBuilder.getDepth() != 0) { throw new PackProtocolException( @@ -201,17 +202,17 @@ final class ProtocolV2Parser { } reqBuilder.setDeepenSince(ts); } else if (transferConfig.isAllowFilter() - && line.startsWith(OPTION_FILTER + ' ')) { + && line2.startsWith(OPTION_FILTER + ' ')) { if (filterReceived) { throw new PackProtocolException( JGitText.get().tooManyFilters); } filterReceived = true; reqBuilder.setFilterSpec(FilterSpec.fromFilterLine( - line.substring(OPTION_FILTER.length() + 1))); + line2.substring(OPTION_FILTER.length() + 1))); } else { throw new PackProtocolException(MessageFormat - .format(JGitText.get().unexpectedPacketLine, line)); + .format(JGitText.get().unexpectedPacketLine, line2)); } } @@ -244,25 +245,25 @@ final class ProtocolV2Parser { serverOption -> builder.addServerOption(serverOption), agent -> builder.setAgent(agent)); - if (line == PacketLineIn.END) { + if (PacketLineIn.isEnd(line)) { return builder.build(); } - if (line != PacketLineIn.DELIM) { + if (!PacketLineIn.isDelimiter(line)) { throw new PackProtocolException(MessageFormat .format(JGitText.get().unexpectedPacketLine, line)); } - while ((line = pckIn.readString()) != PacketLineIn.END) { - if (line.equals("peel")) { //$NON-NLS-1$ + for (String line2 : pckIn.readStrings()) { + if (line2.equals("peel")) { //$NON-NLS-1$ builder.setPeel(true); - } else if (line.equals("symrefs")) { //$NON-NLS-1$ + } else if (line2.equals("symrefs")) { //$NON-NLS-1$ builder.setSymrefs(true); - } else if (line.startsWith("ref-prefix ")) { //$NON-NLS-1$ - prefixes.add(line.substring("ref-prefix ".length())); //$NON-NLS-1$ + } else if (line2.startsWith("ref-prefix ")) { //$NON-NLS-1$ + prefixes.add(line2.substring("ref-prefix ".length())); //$NON-NLS-1$ } else { throw new PackProtocolException(MessageFormat - .format(JGitText.get().unexpectedPacketLine, line)); + .format(JGitText.get().unexpectedPacketLine, line2)); } } diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/transport/ReceivePack.java b/org.eclipse.jgit/src/org/eclipse/jgit/transport/ReceivePack.java index 4652c3fda8..d6adf1e0d8 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/transport/ReceivePack.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/transport/ReceivePack.java @@ -348,7 +348,7 @@ public class ReceivePack extends BaseReceivePack { pushOptions = new ArrayList<>(4); for (;;) { String option = in.readString(); - if (option == PacketLineIn.END) { + if (PacketLineIn.isEnd(option)) { break; } pushOptions.add(option); diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/transport/TransportHttp.java b/org.eclipse.jgit/src/org/eclipse/jgit/transport/TransportHttp.java index b752a65275..27ab879515 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/transport/TransportHttp.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/transport/TransportHttp.java @@ -54,8 +54,11 @@ import static org.eclipse.jgit.util.HttpSupport.HDR_ACCEPT; import static org.eclipse.jgit.util.HttpSupport.HDR_ACCEPT_ENCODING; import static org.eclipse.jgit.util.HttpSupport.HDR_CONTENT_ENCODING; import static org.eclipse.jgit.util.HttpSupport.HDR_CONTENT_TYPE; +import static org.eclipse.jgit.util.HttpSupport.HDR_COOKIE; import static org.eclipse.jgit.util.HttpSupport.HDR_LOCATION; import static org.eclipse.jgit.util.HttpSupport.HDR_PRAGMA; +import static org.eclipse.jgit.util.HttpSupport.HDR_SET_COOKIE; +import static org.eclipse.jgit.util.HttpSupport.HDR_SET_COOKIE2; import static org.eclipse.jgit.util.HttpSupport.HDR_USER_AGENT; import static org.eclipse.jgit.util.HttpSupport.HDR_WWW_AUTHENTICATE; import static org.eclipse.jgit.util.HttpSupport.METHOD_GET; @@ -68,11 +71,15 @@ import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.io.OutputStream; +import java.net.HttpCookie; import java.net.MalformedURLException; import java.net.Proxy; import java.net.ProxySelector; import java.net.URISyntaxException; import java.net.URL; +import java.nio.file.InvalidPathException; +import java.nio.file.Path; +import java.nio.file.Paths; import java.security.cert.CertPathBuilderException; import java.security.cert.CertPathValidatorException; import java.security.cert.CertificateException; @@ -84,6 +91,8 @@ import java.util.Collections; import java.util.EnumSet; import java.util.HashSet; import java.util.LinkedHashSet; +import java.util.LinkedList; +import java.util.List; import java.util.Locale; import java.util.Map; import java.util.Set; @@ -100,6 +109,8 @@ import org.eclipse.jgit.errors.PackProtocolException; import org.eclipse.jgit.errors.TransportException; import org.eclipse.jgit.internal.JGitText; import org.eclipse.jgit.internal.storage.file.RefDirectory; +import org.eclipse.jgit.internal.transport.http.NetscapeCookieFile; +import org.eclipse.jgit.internal.transport.http.NetscapeCookieFileCache; import org.eclipse.jgit.lib.Constants; import org.eclipse.jgit.lib.ObjectId; import org.eclipse.jgit.lib.ObjectIdRef; @@ -116,6 +127,7 @@ import org.eclipse.jgit.util.FS; import org.eclipse.jgit.util.HttpSupport; import org.eclipse.jgit.util.IO; import org.eclipse.jgit.util.RawParseUtils; +import org.eclipse.jgit.util.StringUtils; import org.eclipse.jgit.util.SystemReader; import org.eclipse.jgit.util.TemporaryBuffer; import org.eclipse.jgit.util.io.DisabledOutputStream; @@ -274,6 +286,19 @@ public class TransportHttp extends HttpTransport implements WalkTransport, private boolean sslFailure = false; + /** + * All stored cookies bound to this repo (independent of the baseUrl) + */ + private final NetscapeCookieFile cookieFile; + + /** + * The cookies to be sent with each request to the given {@link #baseUrl}. + * Filtered view on top of {@link #cookieFile} where only cookies which + * apply to the current url are left. This set needs to be filtered for + * expired entries each time prior to sending them. + */ + private final Set<HttpCookie> relevantCookies; + TransportHttp(Repository local, URIish uri) throws NotSupportedException { super(local, uri); @@ -281,6 +306,8 @@ public class TransportHttp extends HttpTransport implements WalkTransport, http = new HttpConfig(local.getConfig(), uri); proxySelector = ProxySelector.getDefault(); sslVerify = http.isSslVerify(); + cookieFile = getCookieFileFromConfig(http); + relevantCookies = filterCookies(cookieFile, baseUrl); } private URL toURL(URIish urish) throws MalformedURLException { @@ -321,6 +348,8 @@ public class TransportHttp extends HttpTransport implements WalkTransport, http = new HttpConfig(uri); proxySelector = ProxySelector.getDefault(); sslVerify = http.isSslVerify(); + cookieFile = getCookieFileFromConfig(http); + relevantCookies = filterCookies(cookieFile, baseUrl); } /** @@ -508,6 +537,7 @@ public class TransportHttp extends HttpTransport implements WalkTransport, conn.setRequestProperty(HDR_ACCEPT, "*/*"); //$NON-NLS-1$ } final int status = HttpSupport.response(conn); + processResponseCookies(conn); switch (status) { case HttpConnection.HTTP_OK: // Check if HttpConnection did some authentication in the @@ -596,6 +626,57 @@ public class TransportHttp extends HttpTransport implements WalkTransport, } } + void processResponseCookies(HttpConnection conn) { + if (cookieFile != null && http.getSaveCookies()) { + List<HttpCookie> foundCookies = new LinkedList<>(); + + List<String> cookieHeaderValues = conn + .getHeaderFields(HDR_SET_COOKIE); + if (!cookieHeaderValues.isEmpty()) { + foundCookies.addAll( + extractCookies(HDR_SET_COOKIE, cookieHeaderValues)); + } + cookieHeaderValues = conn.getHeaderFields(HDR_SET_COOKIE2); + if (!cookieHeaderValues.isEmpty()) { + foundCookies.addAll( + extractCookies(HDR_SET_COOKIE2, cookieHeaderValues)); + } + if (!foundCookies.isEmpty()) { + try { + // update cookie lists with the newly received cookies! + Set<HttpCookie> cookies = cookieFile.getCookies(false); + cookies.addAll(foundCookies); + cookieFile.write(baseUrl); + relevantCookies.addAll(foundCookies); + } catch (IOException | IllegalArgumentException + | InterruptedException e) { + LOG.warn(MessageFormat.format( + JGitText.get().couldNotPersistCookies, + cookieFile.getPath()), e); + } + } + } + } + + private List<HttpCookie> extractCookies(String headerKey, + List<String> headerValues) { + List<HttpCookie> foundCookies = new LinkedList<>(); + for (String headerValue : headerValues) { + foundCookies + .addAll(HttpCookie.parse(headerKey + ':' + headerValue)); + } + // HttpCookies.parse(...) is only compliant with RFC 2965. Make it RFC + // 6265 compliant by applying the logic from + // https://tools.ietf.org/html/rfc6265#section-5.2.3 + for (HttpCookie foundCookie : foundCookies) { + String domain = foundCookie.getDomain(); + if (domain != null && domain.startsWith(".")) { //$NON-NLS-1$ + foundCookie.setDomain(domain.substring(1)); + } + } + return foundCookies; + } + private static class CredentialItems { CredentialItem.InformationalMessage message; @@ -847,14 +928,35 @@ public class TransportHttp extends HttpTransport implements WalkTransport, conn.setConnectTimeout(effTimeOut); conn.setReadTimeout(effTimeOut); } + // set cookie header if necessary + if (!relevantCookies.isEmpty()) { + setCookieHeader(conn); + } + if (this.headers != null && !this.headers.isEmpty()) { - for (Map.Entry<String, String> entry : this.headers.entrySet()) + for (Map.Entry<String, String> entry : this.headers.entrySet()) { conn.setRequestProperty(entry.getKey(), entry.getValue()); + } } authMethod.configureRequest(conn); return conn; } + private void setCookieHeader(HttpConnection conn) { + StringBuilder cookieHeaderValue = new StringBuilder(); + for (HttpCookie cookie : relevantCookies) { + if (!cookie.hasExpired()) { + if (cookieHeaderValue.length() > 0) { + cookieHeaderValue.append(';'); + } + cookieHeaderValue.append(cookie.toString()); + } + } + if (cookieHeaderValue.length() > 0) { + conn.setRequestProperty(HDR_COOKIE, cookieHeaderValue.toString()); + } + } + final InputStream openInputStream(HttpConnection conn) throws IOException { InputStream input = conn.getInputStream(); @@ -868,6 +970,150 @@ public class TransportHttp extends HttpTransport implements WalkTransport, return new TransportException(uri, why); } + private static NetscapeCookieFile getCookieFileFromConfig( + HttpConfig config) { + if (!StringUtils.isEmptyOrNull(config.getCookieFile())) { + try { + Path cookieFilePath = Paths.get(config.getCookieFile()); + return NetscapeCookieFileCache.getInstance(config) + .getEntry(cookieFilePath); + } catch (InvalidPathException e) { + LOG.warn(MessageFormat.format( + JGitText.get().couldNotReadCookieFile, + config.getCookieFile()), e); + } + } + return null; + } + + private static Set<HttpCookie> filterCookies(NetscapeCookieFile cookieFile, + URL url) { + if (cookieFile != null) { + return filterCookies(cookieFile.getCookies(true), url); + } + return Collections.emptySet(); + } + + /** + * + * @param allCookies + * a list of cookies. + * @param url + * the url for which to filter the list of cookies. + * @return only the cookies from {@code allCookies} which are relevant (i.e. + * are not expired, have a matching domain, have a matching path and + * have a matching secure attribute) + */ + private static Set<HttpCookie> filterCookies(Set<HttpCookie> allCookies, + URL url) { + Set<HttpCookie> filteredCookies = new HashSet<>(); + for (HttpCookie cookie : allCookies) { + if (cookie.hasExpired()) { + continue; + } + if (!matchesCookieDomain(url.getHost(), cookie.getDomain())) { + continue; + } + if (!matchesCookiePath(url.getPath(), cookie.getPath())) { + continue; + } + if (cookie.getSecure() && !"https".equals(url.getProtocol())) { //$NON-NLS-1$ + continue; + } + filteredCookies.add(cookie); + } + return filteredCookies; + } + + /** + * + * The utility method to check whether a host name is in a cookie's domain + * or not. Similar to {@link HttpCookie#domainMatches(String, String)} but + * implements domain matching rules according to + * <a href="https://tools.ietf.org/html/rfc6265#section-5.1.3">RFC 6265, + * section 5.1.3</a> instead of the rules from + * <a href="https://tools.ietf.org/html/rfc2965#section-3.3">RFC 2965, + * section 3.3.1</a>. + * <p> + * The former rules are also used by libcurl internally. + * <p> + * The rules are as follows + * + * A string matches another domain string if at least one of the following + * conditions holds: + * <ul> + * <li>The domain string and the string are identical. (Note that both the + * domain string and the string will have been canonicalized to lower case + * at this point.)</li> + * <li>All of the following conditions hold + * <ul> + * <li>The domain string is a suffix of the string.</li> + * <li>The last character of the string that is not included in the domain + * string is a %x2E (".") character.</li> + * <li>The string is a host name (i.e., not an IP address).</li> + * </ul> + * </li> + * </ul> + * + * @param host + * the host to compare against the cookieDomain + * @param cookieDomain + * the domain to compare against + * @return {@code true} if they domain-match; {@code false} if not + * + * @see <a href= "https://tools.ietf.org/html/rfc6265#section-5.1.3">RFC + * 6265, section 5.1.3 (Domain Matching)</a> + * @see <a href= + * "https://bugs.java.com/bugdatabase/view_bug.do?bug_id=8206092">JDK-8206092 + * : HttpCookie.domainMatches() does not match to sub-sub-domain</a> + */ + static boolean matchesCookieDomain(String host, String cookieDomain) { + cookieDomain = cookieDomain.toLowerCase(Locale.ROOT); + host = host.toLowerCase(Locale.ROOT); + if (host.equals(cookieDomain)) { + return true; + } else { + if (!host.endsWith(cookieDomain)) { + return false; + } + return host + .charAt(host.length() - cookieDomain.length() - 1) == '.'; + } + } + + /** + * The utility method to check whether a path is matching a cookie path + * domain or not. The rules are defined by + * <a href="https://tools.ietf.org/html/rfc6265#section-5.1.4">RFC 6265, + * section 5.1.4</a>: + * + * A request-path path-matches a given cookie-path if at least one of the + * following conditions holds: + * <ul> + * <li>The cookie-path and the request-path are identical.</li> + * <li>The cookie-path is a prefix of the request-path, and the last + * character of the cookie-path is %x2F ("/").</li> + * <li>The cookie-path is a prefix of the request-path, and the first + * character of the request-path that is not included in the cookie- path is + * a %x2F ("/") character.</li> + * </ul> + * @param path + * the path to check + * @param cookiePath + * the cookie's path + * + * @return {@code true} if they path-match; {@code false} if not + */ + static boolean matchesCookiePath(String path, String cookiePath) { + if (cookiePath.equals(path)) { + return true; + } + if (!cookiePath.endsWith("/")) { //$NON-NLS-1$ + cookiePath += "/"; //$NON-NLS-1$ + } + return path.startsWith(cookiePath); + } + private boolean isSmartHttp(HttpConnection c, String service) { final String expType = "application/x-" + service + "-advertisement"; //$NON-NLS-1$ //$NON-NLS-2$ final String actType = c.getContentType(); @@ -902,7 +1148,7 @@ public class TransportHttp extends HttpTransport implements WalkTransport, JGitText.get().expectedGot, exp, act)); } - while (pckIn.readString() != PacketLineIn.END) { + while (!PacketLineIn.isEnd(pckIn.readString())) { // for now, ignore the remaining header lines } } diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/transport/UploadPack.java b/org.eclipse.jgit/src/org/eclipse/jgit/transport/UploadPack.java index 3ed9886c45..9278f42adf 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/transport/UploadPack.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/transport/UploadPack.java @@ -106,10 +106,8 @@ import org.eclipse.jgit.lib.RefDatabase; import org.eclipse.jgit.lib.Repository; import org.eclipse.jgit.revwalk.AsyncRevObjectQueue; import org.eclipse.jgit.revwalk.BitmapWalker; -import org.eclipse.jgit.revwalk.BitmappedReachabilityChecker; import org.eclipse.jgit.revwalk.DepthWalk; import org.eclipse.jgit.revwalk.ObjectWalk; -import org.eclipse.jgit.revwalk.PedestrianReachabilityChecker; import org.eclipse.jgit.revwalk.ReachabilityChecker; import org.eclipse.jgit.revwalk.RevCommit; import org.eclipse.jgit.revwalk.RevFlag; @@ -1231,7 +1229,7 @@ public class UploadPack { /* EOF when awaiting command is fine */ return true; } - if (command == PacketLineIn.END) { + if (PacketLineIn.isEnd(command)) { // A blank request is valid according // to the protocol; do nothing in this // case. @@ -1602,7 +1600,7 @@ public class UploadPack { throw eof; } - if (line == PacketLineIn.END) { + if (PacketLineIn.isEnd(line)) { last = processHaveLines(peerHas, last, pckOut); if (commonBase.isEmpty() || multiAck != MultiAck.OFF) pckOut.writeString("NAK\n"); //$NON-NLS-1$ @@ -1909,9 +1907,8 @@ public class UploadPack { } // All wants are commits, we can use ReachabilityChecker - ReachabilityChecker reachabilityChecker = repoHasBitmaps - ? new BitmappedReachabilityChecker(walk) - : new PedestrianReachabilityChecker(true, walk); + ReachabilityChecker reachabilityChecker = walk + .createReachabilityChecker(); List<RevCommit> starters = objectIdsToRevCommits(walk, reachableFrom); 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 c0c24872b2..3efa66459c 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/treewalk/WorkingTreeIterator.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/treewalk/WorkingTreeIterator.java @@ -1516,6 +1516,7 @@ public abstract class WorkingTreeIterator extends AbstractTreeIterator { ObjectId blobId = entry.getObjectId(); if (entry.getStage() > 0 && entry.getStage() != DirCacheEntry.STAGE_2) { + blobId = null; // Merge conflict: check ours (stage 2) byte[] name = entry.getRawPath(); int i = 0; @@ -1523,7 +1524,8 @@ public abstract class WorkingTreeIterator extends AbstractTreeIterator { dirCache.next(1); i++; entry = dirCache.getDirCacheEntry(); - if (!Arrays.equals(name, entry.getRawPath())) { + if (entry == null + || !Arrays.equals(name, entry.getRawPath())) { break; } if (entry.getStage() == DirCacheEntry.STAGE_2) { @@ -1533,17 +1535,20 @@ public abstract class WorkingTreeIterator extends AbstractTreeIterator { } dirCache.back(i); } - try (ObjectReader reader = repository.newObjectReader()) { - ObjectLoader loader = reader.open(blobId, Constants.OBJ_BLOB); - try { - return RawText.isCrLfText(loader.getCachedBytes()); - } catch (LargeObjectException e) { - try (InputStream in = loader.openStream()) { - return RawText.isCrLfText(in); + if (blobId != null) { + try (ObjectReader reader = repository.newObjectReader()) { + ObjectLoader loader = reader.open(blobId, + Constants.OBJ_BLOB); + try { + return RawText.isCrLfText(loader.getCachedBytes()); + } catch (LargeObjectException e) { + try (InputStream in = loader.openStream()) { + return RawText.isCrLfText(in); + } } + } catch (IOException e) { + // Ignore and return false below } - } catch (IOException e) { - // Ignore and return false below } } return false; diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/util/FS_POSIX.java b/org.eclipse.jgit/src/org/eclipse/jgit/util/FS_POSIX.java index 716711e067..faef9fd0f4 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/util/FS_POSIX.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/util/FS_POSIX.java @@ -48,7 +48,8 @@ import java.io.IOException; import java.io.InputStreamReader; import java.io.PrintStream; import java.nio.charset.Charset; -import java.nio.file.AccessDeniedException; +import java.nio.file.FileStore; +import java.nio.file.FileSystemException; import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; @@ -57,9 +58,11 @@ import java.text.MessageFormat; import java.util.ArrayList; import java.util.Arrays; import java.util.List; +import java.util.Map; import java.util.Optional; import java.util.Set; import java.util.UUID; +import java.util.concurrent.ConcurrentHashMap; import org.eclipse.jgit.annotations.Nullable; import org.eclipse.jgit.api.errors.JGitInternalException; @@ -84,7 +87,7 @@ public class FS_POSIX extends FS { private static final int DEFAULT_UMASK = 0022; private volatile int umask = -1; - private volatile boolean supportsUnixNLink = true; + private static final Map<FileStore, Boolean> CAN_HARD_LINK = new ConcurrentHashMap<>(); private volatile AtomicFileCreation supportsAtomicCreateNewFile = AtomicFileCreation.UNDEFINED; @@ -388,12 +391,18 @@ public class FS_POSIX extends FS { if (!lock.createNewFile()) { return false; } - if (supportsAtomicCreateNewFile() || !supportsUnixNLink) { + if (supportsAtomicCreateNewFile()) { return true; } Path lockPath = lock.toPath(); Path link = null; + FileStore store = Files.getFileStore(lockPath); try { + Boolean canLink = CAN_HARD_LINK.computeIfAbsent(store, + s -> Boolean.TRUE); + if (Boolean.FALSE.equals(canLink)) { + return true; + } link = Files.createLink( Paths.get(lock.getAbsolutePath() + ".lnk"), //$NON-NLS-1$ lockPath); @@ -405,11 +414,11 @@ public class FS_POSIX extends FS { nlink)); return false; } else if (nlink < 2) { - supportsUnixNLink = false; + CAN_HARD_LINK.put(store, Boolean.FALSE); } return true; } catch (UnsupportedOperationException | IllegalArgumentException e) { - supportsUnixNLink = false; + CAN_HARD_LINK.put(store, Boolean.FALSE); return true; } finally { if (link != null) { @@ -448,12 +457,18 @@ public class FS_POSIX extends FS { if (!file.createNewFile()) { return token(false, null); } - if (supportsAtomicCreateNewFile() || !supportsUnixNLink) { + if (supportsAtomicCreateNewFile()) { return token(true, null); } Path link = null; Path path = file.toPath(); + FileStore store = Files.getFileStore(path); try { + Boolean canLink = CAN_HARD_LINK.computeIfAbsent(store, + s -> Boolean.TRUE); + if (Boolean.FALSE.equals(canLink)) { + return token(true, null); + } link = Files.createLink(Paths.get(uniqueLinkPath(file)), path); Integer nlink = (Integer) (Files.getAttribute(path, "unix:nlink")); //$NON-NLS-1$ @@ -462,12 +477,12 @@ public class FS_POSIX extends FS { JGitText.get().failedAtomicFileCreation, path, nlink)); return token(false, link); } else if (nlink.intValue() < 2) { - supportsUnixNLink = false; + CAN_HARD_LINK.put(store, Boolean.FALSE); } return token(true, link); } catch (UnsupportedOperationException | IllegalArgumentException - | AccessDeniedException | SecurityException e) { - supportsUnixNLink = false; + | FileSystemException | SecurityException e) { + CAN_HARD_LINK.put(store, Boolean.FALSE); return token(true, link); } } diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/util/FS_Win32.java b/org.eclipse.jgit/src/org/eclipse/jgit/util/FS_Win32.java index 98797dc64f..3ccbd72806 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/util/FS_Win32.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/util/FS_Win32.java @@ -205,18 +205,21 @@ public class FS_Win32 extends FS { @Override protected File userHomeImpl() { String home = SystemReader.getInstance().getenv("HOME"); //$NON-NLS-1$ - if (home != null) + if (home != null) { return resolve(null, home); + } String homeDrive = SystemReader.getInstance().getenv("HOMEDRIVE"); //$NON-NLS-1$ if (homeDrive != null) { String homePath = SystemReader.getInstance().getenv("HOMEPATH"); //$NON-NLS-1$ - if (homePath != null) + if (homePath != null) { return new File(homeDrive, homePath); + } } String homeShare = SystemReader.getInstance().getenv("HOMESHARE"); //$NON-NLS-1$ - if (homeShare != null) + if (homeShare != null) { return new File(homeShare); + } return super.userHomeImpl(); } @@ -237,8 +240,9 @@ public class FS_Win32 extends FS { /** {@inheritDoc} */ @Override public boolean supportsSymlinks() { - if (supportSymlinks == null) + if (supportSymlinks == null) { detectSymlinkSupport(); + } return Boolean.TRUE.equals(supportSymlinks); } @@ -254,12 +258,13 @@ public class FS_Win32 extends FS { | InternalError e) { supportSymlinks = Boolean.FALSE; } finally { - if (tempFile != null) + if (tempFile != null) { try { FileUtils.delete(tempFile); } catch (IOException e) { throw new RuntimeException(e); // panic } + } } } diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/util/HttpSupport.java b/org.eclipse.jgit/src/org/eclipse/jgit/util/HttpSupport.java index 54e4ee01fd..640670debc 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/util/HttpSupport.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/util/HttpSupport.java @@ -170,6 +170,27 @@ public class HttpSupport { public static final String HDR_WWW_AUTHENTICATE = "WWW-Authenticate"; //$NON-NLS-1$ /** + * The {@code Cookie} header. + * + * @since 5.4 + */ + public static final String HDR_COOKIE = "Cookie"; //$NON-NLS-1$ + + /** + * The {@code Set-Cookie} header. + * + * @since 5.4 + */ + public static final String HDR_SET_COOKIE = "Set-Cookie"; //$NON-NLS-1$ + + /** + * The {@code Set-Cookie2} header. + * + * @since 5.4 + */ + public static final String HDR_SET_COOKIE2 = "Set-Cookie2"; //$NON-NLS-1$ + + /** * URL encode a value string into an output buffer. * * @param urlstr diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/util/LRUMap.java b/org.eclipse.jgit/src/org/eclipse/jgit/util/LRUMap.java new file mode 100644 index 0000000000..41c15363f8 --- /dev/null +++ b/org.eclipse.jgit/src/org/eclipse/jgit/util/LRUMap.java @@ -0,0 +1,83 @@ +/* + * Copyright (C) 2018, Konrad Windszus <konrad_w@gmx.de> + * and other copyright owners as documented in the project's IP log. + * + * This program and the accompanying materials are made available + * under the terms of the Eclipse Distribution License v1.0 which + * accompanies this distribution, is reproduced below, and is + * available at http://www.eclipse.org/org/documents/edl-v10.php + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or + * without modification, are permitted provided that the following + * conditions are met: + * + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * - Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials provided + * with the distribution. + * + * - Neither the name of the Eclipse Foundation, Inc. nor the + * names of its contributors may be used to endorse or promote + * products derived from this software without specific prior + * written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +package org.eclipse.jgit.util; + +import java.util.LinkedHashMap; + +/** + * Map with only up to n entries. If a new entry is added so that the map + * contains more than those n entries the least-recently used entry is removed + * from the map. + * + * @param <K> + * the type of keys maintained by this map + * @param <V> + * the type of mapped values + * + * @since 5.4 + */ +public class LRUMap<K, V> extends LinkedHashMap<K, V> { + + private static final long serialVersionUID = 4329609127403759486L; + + private final int limit; + + /** + * Constructs an empty map which may contain at most the given amount of + * entries. + * + * @param initialCapacity + * the initial capacity + * @param limit + * the number of entries the map should have at most + */ + public LRUMap(int initialCapacity, int limit) { + super(initialCapacity, 0.75f, true); + this.limit = limit; + } + + @Override + protected boolean removeEldestEntry(java.util.Map.Entry<K, V> eldest) { + return size() > limit; + } +} @@ -202,8 +202,8 @@ <maven-javadoc-plugin-version>3.1.0</maven-javadoc-plugin-version> <tycho-extras-version>1.3.0</tycho-extras-version> <gson-version>2.8.2</gson-version> - <bouncycastle-version>1.60</bouncycastle-version> - <spotbugs-maven-plugin-version>3.1.11</spotbugs-maven-plugin-version> + <bouncycastle-version>1.61</bouncycastle-version> + <spotbugs-maven-plugin-version>3.1.12</spotbugs-maven-plugin-version> <maven-surefire-version>2.22.2</maven-surefire-version> <maven-compiler-plugin-version>3.8.1</maven-compiler-plugin-version> <maven-project-info-reports-plugin-version>3.0.0</maven-project-info-reports-plugin-version> @@ -239,7 +239,7 @@ <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-jar-plugin</artifactId> - <version>3.1.1</version> + <version>3.1.2</version> <configuration> <archive> <manifestEntries> @@ -282,7 +282,7 @@ <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-source-plugin</artifactId> - <version>3.0.1</version> + <version>3.1.0</version> </plugin> <plugin> @@ -366,7 +366,7 @@ <plugin> <groupId>org.jacoco</groupId> <artifactId>jacoco-maven-plugin</artifactId> - <version>0.8.3</version> + <version>0.8.4</version> </plugin> <plugin> <groupId>org.apache.maven.plugins</groupId> diff --git a/tools/BUILD b/tools/BUILD index f0342ad75a..38daececbe 100644 --- a/tools/BUILD +++ b/tools/BUILD @@ -44,7 +44,7 @@ java_package_configuration( "-Xep:FragmentInjection:ERROR", "-Xep:FragmentNotInstantiable:ERROR", "-Xep:FunctionalInterfaceClash:ERROR", - "-Xep:FutureReturnValueIgnored:WARN", + "-Xep:FutureReturnValueIgnored:ERROR", "-Xep:GetClassOnEnum:ERROR", "-Xep:ImmutableAnnotationChecker:ERROR", "-Xep:ImmutableEnumChecker:WARN", |