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>
This commit is contained in:
Matthias Sohn 2019-06-11 23:09:19 +02:00
commit c177c6f4c5
102 changed files with 3069 additions and 500 deletions

1
.bazelversion Normal file
View File

@ -0,0 +1 @@
0.26.1

View File

@ -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",
)

View File

@ -64,7 +64,6 @@
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 @@ private static String etag(byte[] content) {
}
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() {

View File

@ -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 void testHttpClientWantsV2ButServerNotConfigured() throws Exception {
// 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 void testV2HttpFirstResponse() throws Exception {
// 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 void testV2HttpSubsequentResponse() throws Exception {
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/]*"));
}

View File

@ -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 void testPush_UnpackError_TruncatedPack() throws Exception {
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();

View File

@ -44,6 +44,7 @@
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.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 void testParallelUploads() throws Exception {
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();

View File

@ -84,7 +84,7 @@ private static class Upload extends 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 @@ private static class Download extends 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);

View File

@ -170,7 +170,7 @@ private static final long hexUInt64(final byte[] bs, int p, final int end) {
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) {

View File

@ -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"/>

View File

@ -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

View File

@ -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"/>

View File

@ -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

View File

@ -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"/>

View File

@ -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

View File

@ -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"/>

View File

@ -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

View File

@ -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"/>

View File

@ -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

View File

@ -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"/>

View File

@ -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

View File

@ -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"/>

View File

@ -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

View File

@ -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]

View File

@ -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

View File

@ -96,7 +96,7 @@ protected void run() throws Exception {
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);

View File

@ -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 @@ protected void run() {
cmd.setTarget(tree);
}
cmd.setLong(longDesc);
cmd.setTags(useTags);
cmd.setAlways(always);
cmd.setMatch(patterns.toArray(new String[0]));
String result = null;
try {

View File

@ -85,7 +85,7 @@ protected void run() {
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);

View File

@ -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);

View File

@ -80,7 +80,7 @@ protected void run() {
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);
}

View File

@ -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);
}

View File

@ -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",
]]

View File

@ -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)",

View File

@ -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,
)

View File

@ -0,0 +1 @@
some-domain /some/path1 FALSE 0 key1 value1

View File

@ -0,0 +1,2 @@
some-domain1 TRUE /some/path1 FALSE 1893499200000 key1 valueFromSimple1
some-domain1 TRUE /some/path1 FALSE 1893499200000 key2 valueFromSimple1

View File

@ -0,0 +1,2 @@
some-domain1 TRUE /some/path1 FALSE 1893499200000 key1 valueFromSimple2
some-domain1 TRUE /some/path1 FALSE 1893499200000 key3 valueFromSimple2

View File

@ -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

View File

@ -98,7 +98,7 @@ public void testClean() throws NoWorkTreeException, GitAPIException {
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 void testCleanDirs() throws NoWorkTreeException, GitAPIException {
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 void testCleanWithPaths() throws NoWorkTreeException,
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 void testCleanWithDryRun() throws NoWorkTreeException,
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 void testCleanDirsWithDryRun() throws NoWorkTreeException,
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)

View File

@ -718,6 +718,34 @@ public void testCloneWithAutoSetupRebase() throws Exception {
}
@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();
}

View File

@ -661,6 +661,54 @@ public void commitWithAutoCrlfAndNonNormalizedIndex() throws Exception {
}
}
@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)) {

View File

@ -109,7 +109,7 @@ public void testDescribe() throws Exception {
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 void testDescribe() throws Exception {
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 void testDescribe() throws Exception {
// 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 void testDescribe() throws Exception {
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 void testDescribeMultiMatch() throws Exception {
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 void testDescribeBranch() throws Exception {
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 void t1DominatesT2() throws Exception {
} 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 void t1nearerT2() throws Exception {
assertEquals("t1-3-gbb389a4", describe(c4));
} else {
assertEquals(null, describe(c4));
assertEquals("bb389a4", describe(c4, false, true));
}
}
@ -401,6 +416,25 @@ public void t1sameDepthT2() throws Exception {
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 @@ private static void touch(File f, String contents) throws Exception {
}
}
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 {

View File

@ -176,12 +176,13 @@ public boolean isForceUpdate() {
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);

View File

@ -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);
}
}

View File

@ -1457,6 +1457,41 @@ public void testInvalidGroupHeader() throws ConfigInvalidException {
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);

View File

@ -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++;
}
}
}

View File

@ -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;

View File

@ -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 void testReadString_Len0004() throws IOException {
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 void testReadStringRaw3() throws IOException {
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();
}

View File

@ -64,9 +64,9 @@ private static PacketLineIn formatAsPacketLine(String... inputLines)
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 void testRecvWantsWithCapabilities()
"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 void testRecvWantsWithAgent()
"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 void testRecvWantsWithoutCapabilities()
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 void testRecvWantsDeepen()
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 void testRecvWantsShallow()
"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 void testRecvWantsFilter()
"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());

View File

@ -123,9 +123,9 @@ private static PacketLineIn formatAsPacketLine(String... inputLines)
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 @@ private static PacketLineIn formatAsPacketLine(String... inputLines)
}
/*
* 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 void testFetchBasicArguments()
@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 void testFetchWithShallow_deepen() throws IOException {
@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 void testFetchWithShallow_deepenNot() throws IOException {
@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 void testFetchWithShallow_deepenSince() throws IOException {
@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 void testFetchWithNoneFilter() throws IOException {
@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 void testFetchWithBlobSizeFilter() throws IOException {
@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 void testFetchWithTreeDepthFilter() throws IOException {
@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 void testFetchMustNotHaveMultipleFilters() throws IOException {
@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 void testFetchWithRefInWant() throws Exception {
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 void testFetchWithRefInWant() throws Exception {
@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 void testFetchWithRefInWantUnknownRef() throws Exception {
@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 void testLsRefsMinimalReq() throws IOException {
@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 void testLsRefsSymrefs() throws IOException {
@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 void testLsRefsPeel() throws IOException {
@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());

View File

@ -306,11 +306,11 @@ public void testCreateBranchAtHiddenCommitFails() throws Exception {
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 void testUsingHiddenDeltaBaseFails() throws Exception {
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 void testUsingHiddenCommonBlobFails() throws Exception {
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 void testUsingUnknownBlobFails() throws Exception {
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 void testIncludesInvalidGitmodules() throws Exception {
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 void testUsingUnknownTreeFails() throws Exception {
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()));
}
}

View File

@ -45,7 +45,7 @@
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 void advertiser() throws IOException {
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) {

View File

@ -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());
}
}
}

View File

@ -4,7 +4,6 @@
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 @@ private static ByteArrayInputStream linesAsInputStream(String... inputLines)
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 @@ private ByteArrayInputStream uploadPackV2(RequestPolicy requestPolicy,
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 void onFetch(FetchV2Request req) {
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 void testV2Capabilities() throws Exception {
// 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 void testV2CapabilitiesAllowFilter() throws Exception {
// 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 void testV2CapabilitiesRefInWant() throws Exception {
// 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 void testV2CapabilitiesRefInWantNotAdvertisedIfUnallowed() throws Excepti
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 void testV2CapabilitiesRefInWantNotAdvertisedIfAdvertisingForbidden() thr
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 void testV2CapabilitiesRefInWantNotAdvertisedIfAdvertisingForbidden() thr
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 void testV2LsRefs() throws Exception {
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 void testV2LsRefsSymrefs() throws Exception {
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 void testV2LsRefsPeel() throws Exception {
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 void testV2LsRefsPeel() throws Exception {
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 void testV2LsRefsMultipleCommands() throws Exception {
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 void testV2LsRefsMultipleCommands() throws Exception {
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 void testV2LsRefsRefPrefix() throws Exception {
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 void testV2LsRefsRefPrefixNoSlash() throws Exception {
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 void testV2LsRefsUnrecognizedArgument() throws Exception {
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 void testV2FetchRequestPolicyAdvertised() throws Exception {
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 void testV2FetchRequestPolicyAdvertised() throws Exception {
null,
null,
"command=fetch\n",
PacketLineIn.DELIM,
PacketLineIn.delimiter(),
"want " + unadvertized.name() + "\n",
PacketLineIn.END);
PacketLineIn.end());
}
@Test
@ -794,9 +796,9 @@ public void testV2FetchRequestPolicyReachableCommit() throws Exception {
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 void testV2FetchRequestPolicyReachableCommit() throws Exception {
null,
null,
"command=fetch\n",
PacketLineIn.DELIM,
PacketLineIn.delimiter(),
"want " + unreachable.name() + "\n",
PacketLineIn.END);
PacketLineIn.end());
}
@Test
@ -824,9 +826,9 @@ public void testV2FetchRequestPolicyTip() throws Exception {
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 void testV2FetchRequestPolicyTip() throws Exception {
new RejectAllRefFilter(),
null,
"command=fetch\n",
PacketLineIn.DELIM,
PacketLineIn.delimiter(),
"want " + parentOfTip.name() + "\n",
PacketLineIn.END);
PacketLineIn.end());
}
@Test
@ -855,9 +857,9 @@ public void testV2FetchRequestPolicyReachableCommitTip() throws Exception {
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 void testV2FetchRequestPolicyReachableCommitTip() throws Exception {
new RejectAllRefFilter(),
null,
"command=fetch\n",
PacketLineIn.DELIM,
PacketLineIn.delimiter(),
"want " + unreachable.name() + "\n",
PacketLineIn.END);
PacketLineIn.end());
}
@Test
@ -883,9 +885,9 @@ public void testV2FetchRequestPolicyAny() throws Exception {
null,
null,
"command=fetch\n",
PacketLineIn.DELIM,
PacketLineIn.delimiter(),
"want " + unreachable.name() + "\n",
PacketLineIn.END);
PacketLineIn.end());
}
@Test
@ -899,16 +901,16 @@ public void testV2FetchServerDoesNotStopNegotiation() throws Exception {
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 void testV2FetchServerStopsNegotiation() throws Exception {
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 void testV2FetchServerStopsNegotiation() throws Exception {
"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 void testV2FetchClientStopsNegotiation() throws Exception {
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 void testV2FetchThinPack() throws Exception {
// 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 void testV2FetchNoProgress() throws Exception {
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 void testV2FetchNoProgress() throws Exception {
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 void testV2FetchIncludeTag() throws Exception {
// 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 void testV2FetchIncludeTag() throws Exception {
// 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 void testV2FetchOfsDelta() throws Exception {
// 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 void testV2FetchShallow() throws Exception {
// 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 void testV2FetchShallow() throws Exception {
// 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 void testV2FetchDeepenAndDone() throws Exception {
// "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 void testV2FetchDeepenAndDone() throws Exception {
// 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 void testV2FetchDeepenWithoutDone() throws Exception {
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 void testV2FetchDeepenWithoutDone() throws Exception {
// 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 void testV2FetchShallowSince() throws Exception {
// 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 void testV2FetchShallowSince() throws Exception {
// 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 void testV2FetchShallowSince_excludedParentWithMultipleChildren() throws
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 void testV2FetchShallowSince_excludedParentWithMultipleChildren() throws
"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 void testV2FetchShallowSince_noCommitsSelected() throws Exception {
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 void testV2FetchDeepenNot() throws Exception {
// 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 void testV2FetchDeepenNot() throws Exception {
// "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 void testV2FetchDeepenNot_excludeDescendantOfWant() throws Exception {
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 void testV2FetchDeepenNot_supportAnnotatedTags() throws Exception {
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 void testV2FetchDeepenNot_excludedParentWithMultipleChildren() throws Exc
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 void testV2FetchDeepenNot_excludedParentWithMultipleChildren() throws Exc
"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 void testV2FetchUnrecognizedArgument() throws Exception {
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 void testV2FetchFilter() throws Exception {
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 @@ private void uploadV2WithTreeDepthFilter(
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 void testV2FetchFilterWhenNotAllowed() throws Exception {
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 void testV2FetchWantRefIfNotAllowed() throws Exception {
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 void testV2FetchWantRef() throws Exception {
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 void testV2FetchWantRef() throws Exception {
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 void testV2FetchBadWantRef() throws Exception {
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 void testV2FetchMixedWantRef() throws Exception {
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 void testV2FetchWantRefWeAlreadyHave() throws Exception {
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 void testV2FetchWantRefWeAlreadyHave() throws Exception {
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 void testV2FetchWantRefAndDeepen() throws Exception {
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 void testV2FetchMissingShallow() throws Exception {
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 void testV2FetchMissingShallow() throws Exception {
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 void testGetPeerAgentProtocolV0() throws Exception {
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 void testGetPeerAgentProtocolV2() throws Exception {
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);

View File

@ -137,7 +137,6 @@ public void testDeleteRecursive() throws IOException {
}
@Test
public void testDeleteRecursiveEmpty() throws IOException {
File f1 = new File(trash, "test/test/a");
File f2 = new File(trash, "test/a");

View File

@ -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()));
}
}

View File

@ -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("]");
}
}
}

View File

@ -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>

View File

@ -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

View File

@ -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

View File

@ -63,8 +63,7 @@
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 DescribeCommand setTags(boolean tags) {
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 @@ private String longDescription(Ref tag, int depth, ObjectId tip)
*/
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 @@ private Optional<Ref> getBestMatch(List<Ref> tags) {
// 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 @@ String describe(ObjectId tip) throws IOException {
}
// 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);

View File

@ -133,7 +133,7 @@ protected LogCommand(Repository repo) {
@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)

View File

@ -60,6 +60,7 @@
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.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 PullResult call() throws GitAPIException,
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)

View File

@ -490,7 +490,7 @@ private RebaseResult processStep(RebaseTodoLine step, boolean shouldPick)
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 @@ private void popSteps(int numSteps) throws IOException {
repo.writeRebaseTodoFile(rebaseState.getPath(GIT_REBASE_TODO),
todoLines, false);
if (poppedLines.size() > 0) {
if (!poppedLines.isEmpty()) {
repo.writeRebaseTodoFile(rebaseState.getPath(DONE), poppedLines,
true);
}

View File

@ -200,6 +200,7 @@ public static JGitText get() {
/***/ 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 static JGitText get() {
/***/ 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 static JGitText get() {
/***/ 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 static JGitText get() {
/***/ public String s3ActionDeletion;
/***/ public String s3ActionReading;
/***/ public String s3ActionWriting;
/***/ public String searchForReachableBranches;
/***/ public String searchForReuse;
/***/ public String searchForSizes;
/***/ public String secondsAgo;

View File

@ -124,6 +124,12 @@ public StoredConfig getConfig() {
return config;
}
/** {@inheritDoc} */
@Override
public String getIdentifier() {
return getDescription().getRepositoryName();
}
/** {@inheritDoc} */
@Override
public void scanForRepoChanges() throws IOException {

View File

@ -388,6 +388,17 @@ public RefDatabase getRefDatabase() {
return refs;
}
/** {@inheritDoc} */
@Override
public String getIdentifier() {
File directory = getDirectory();
if (directory != null) {
return directory.getPath();
} else {
throw new IllegalStateException();
}
}
/** {@inheritDoc} */
@Override
public FileBasedConfig getConfig() {

View File

@ -244,7 +244,7 @@ public GC(FileRepository repo) {
* 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 Collection<PackFile> gc() throws IOException, ParseException {
}
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();
}

View File

@ -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;
}
}

View File

@ -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);
}
}

View File

@ -162,7 +162,7 @@ private static final int hexUInt32(final byte[] bs, int p, final int end) {
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) {

View File

@ -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.
@ -128,6 +128,17 @@ public Config(Config defaultConfig) {
state = new AtomicReference<>(newState());
}
/**
* 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 String toText() {
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 @@ private List<ConfigLine> fromTextRecurse(String text, int depth,
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 @@ protected byte[] readIncludedConfig(String relPath)
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 @@ private static String readValue(StringReader in)
case '"':
value.append('"');
continue;
default:
throw new ConfigInvalidException(MessageFormat.format(
JGitText.get().badEscape,
Character.valueOf(((char) c))));
case '\r': {
int next = in.read();
if (next == '\n') {
continue; // CR-LF
} else if (next >= 0) {
in.reset();
}
break;
}
default:
break;
}
throw new ConfigInvalidException(
MessageFormat.format(JGitText.get().badEscape,
Character.isAlphabetic(c)
? Character.valueOf(((char) c))
: toUnicodeLiteral(c)));
}
if ('"' == c) {
@ -1430,6 +1453,11 @@ private static String readValue(StringReader in)
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>

View File

@ -72,7 +72,7 @@ public boolean getBoolean(Config config, String section, String subsection,
if (n == null) {
return defaultValue;
}
if (Config.MAGIC_EMPTY_VALUE == n) {
if (Config.isMissing(n)) {
return true;
}
try {

View File

@ -179,7 +179,7 @@ private static RebaseTodoLine parseLine(byte[] buf, int tokenBegin,
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 @@ private static RebaseTodoLine parseLine(byte[] buf, int tokenBegin,
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;

View File

@ -239,6 +239,15 @@ public File getDirectory() {
return gitDir;
}
/**
* 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.
*

View File

@ -54,6 +54,8 @@
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.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 @@ private PGPPublicKey findPublicKeyByUserId(KeyBlob keyBlob)
* @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 @@ private PGPPublicKey findPublicKeyInKeyBox(Path keyboxFile)
* @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 @@ private PGPPublicKey getFirstPublicKey(KeyBlob keyBlob) throws IOException {
.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;
}

View File

@ -45,6 +45,8 @@
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 boolean canLocateSigningKey(@Nullable String gpgSigningKey,
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 @@ private BouncyCastleGpgKey locateSigningKey(@Nullable String gpgSigningKey,
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 void sign(@NonNull CommitBuilder commit,
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);
}
}

View File

@ -1190,7 +1190,7 @@ public Map<String, MergeFailureReason> getFailingPaths() {
* otherwise
*/
public boolean failed() {
return failingPaths.size() > 0;
return !failingPaths.isEmpty();
}
/**

View File

@ -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,

View File

@ -55,10 +55,8 @@
/**
* Checks the reachability using bitmaps.
*
* @since 5.4
*/
public class BitmappedReachabilityChecker implements ReachabilityChecker {
class BitmappedReachabilityChecker implements ReachabilityChecker {
private final RevWalk walk;

View File

@ -52,10 +52,8 @@
/**
* 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;

View File

@ -249,6 +249,23 @@ public ObjectReader getObjectReader() {
return reader;
}
/**
* 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>

View File

@ -50,6 +50,9 @@
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 static List<Ref> findBranchesReachableFrom(RevCommit commit,
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 static List<Ref> findBranchesReachableFrom(RevCommit commit,
if (revWalk.isMergedInto(commit, headCommit))
result.add(ref);
}
monitor.endTask();
return result;
}

View File

@ -148,7 +148,8 @@ public final File getFile() {
*/
@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 void load() throws IOException, ConfigInvalidException {
}
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 void load() throws IOException, ConfigInvalidException {
return;
} catch (IOException e) {
if (FileUtils.isStaleFileHandle(e)
&& retries < maxStaleRetries) {
&& retries < maxRetries) {
if (LOG.isDebugEnabled()) {
LOG.debug(MessageFormat.format(
JGitText.get().configHandleIsStale,

View File

@ -201,7 +201,7 @@ private void readAdvertisedRefsImpl() throws IOException {
throw noRepository();
throw eof;
}
if (line == PacketLineIn.END)
if (PacketLineIn.isEnd(line))
break;
if (line.startsWith("ERR ")) { //$NON-NLS-1$

View File

@ -383,8 +383,7 @@ private void readStatusReport(Map<String, RemoteRefUpdate> refUpdates)
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$

View File

@ -1282,7 +1282,7 @@ protected void recvCommands() throws IOException {
return;
throw eof;
}
if (line == PacketLineIn.END) {
if (PacketLineIn.isEnd(line)) {
break;
}

View File

@ -227,7 +227,7 @@ public void writeBundle(ProgressMonitor monitor, OutputStream os)
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);

View File

@ -45,14 +45,12 @@
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 HMACSHA1NonceGenerator(String seed) throws IllegalStateException {
@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$
}

View File

@ -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 boolean matchConfigValue(String s) {
private int maxRedirects;
private String cookieFile;
private boolean saveCookies;
private int cookieFileCacheLimit;
/**
* Get the "http.postBuffer" setting
*
@ -189,6 +219,40 @@ public int getMaxRedirects() {
return maxRedirects;
}
/**
* 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 @@ private void init(Config config, URIish uri) {
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 @@ private void init(Config config, URIish uri) {
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;

View File

@ -49,7 +49,9 @@
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 @@
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 {
@ -192,6 +205,20 @@ public String readString() throws IOException {
return s;
}
/**
* 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>
@ -224,6 +251,52 @@ public String readStringRaw() throws IOException {
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 @@ private IOException invalidHeader() {
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;
}
};
}
}
}

View File

@ -99,7 +99,7 @@ FetchV0Request recvWants(PacketLineIn pckIn)
throw eof;
}
if (line == PacketLineIn.END) {
if (PacketLineIn.isEnd(line)) {
break;
}

View File

@ -92,7 +92,7 @@ private static String consumeCapabilities(PacketLineIn pckIn,
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 @@ FetchV2Request parseFetchRequest(PacketLineIn pckIn)
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 @@ FetchV2Request parseFetchRequest(PacketLineIn pckIn)
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 @@ FetchV2Request parseFetchRequest(PacketLineIn pckIn)
}
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 @@ LsRefsV2Request parseLsRefsRequest(PacketLineIn pckIn)
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));
}
}

View File

@ -348,7 +348,7 @@ void readPostCommands(PacketLineIn in) throws IOException {
pushOptions = new ArrayList<>(4);
for (;;) {
String option = in.readString();
if (option == PacketLineIn.END) {
if (PacketLineIn.isEnd(option)) {
break;
}
pushOptions.add(option);

View File

@ -54,8 +54,11 @@
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.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.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.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.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 Transport open(URIish uri, Repository local, String remoteName)
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 Transport open(URIish uri, Repository local, String remoteName)
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 @@ protected void setURI(URIish uri) throws NotSupportedException {
http = new HttpConfig(uri);
proxySelector = ProxySelector.getDefault();
sslVerify = http.isSslVerify();
cookieFile = getCookieFileFromConfig(http);
relevantCookies = filterCookies(cookieFile, baseUrl);
}
/**
@ -508,6 +537,7 @@ private HttpConnection connect(String service)
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 @@ private HttpConnection connect(String service)
}
}
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 @@ protected HttpConnection httpOpen(String method, URL u,
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 @@ IOException wrongContentType(String expType, String actType) {
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 @@ private void readSmartHeaders(InputStream in, String service)
JGitText.get().expectedGot, exp, act));
}
while (pckIn.readString() != PacketLineIn.END) {
while (!PacketLineIn.isEnd(pckIn.readString())) {
// for now, ignore the remaining header lines
}
}

View File

@ -106,10 +106,8 @@
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 @@ private boolean serveOneCommandV2() throws IOException {
/* 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 @@ private boolean negotiate(FetchRequest req,
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 @@ private static void checkNotAdvertisedWants(UploadPack up,
}
// 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);

View File

@ -1516,6 +1516,7 @@ private boolean hasCrLfInIndex(DirCacheIterator dirCache) {
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 @@ private boolean hasCrLfInIndex(DirCacheIterator dirCache) {
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 @@ private boolean hasCrLfInIndex(DirCacheIterator dirCache) {
}
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;

View File

@ -48,7 +48,8 @@
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.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 boolean createNewFile(File lock) throws IOException {
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 boolean createNewFile(File lock) throws IOException {
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 LockToken createNewFileAtomic(File file) throws IOException {
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 LockToken createNewFileAtomic(File file) throws IOException {
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);
}
}

View File

@ -205,18 +205,21 @@ protected File discoverGitExe() {
@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 ProcessBuilder runInShell(String cmd, String[] args) {
/** {@inheritDoc} */
@Override
public boolean supportsSymlinks() {
if (supportSymlinks == null)
if (supportSymlinks == null) {
detectSymlinkSupport();
}
return Boolean.TRUE.equals(supportSymlinks);
}
@ -254,12 +258,13 @@ private void detectSymlinkSupport() {
| InternalError e) {
supportSymlinks = Boolean.FALSE;
} finally {
if (tempFile != null)
if (tempFile != null) {
try {
FileUtils.delete(tempFile);
} catch (IOException e) {
throw new RuntimeException(e); // panic
}
}
}
}

View File

@ -169,6 +169,27 @@ public class HttpSupport {
/** The {@code WWW-Authenticate} header. */
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.
*

View File

@ -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;
}
}

Some files were not shown because too many files have changed in this diff Show More