Merge branch 'stable-5.5' into stable-5.6
* stable-5.5:
Revert "RefDirectory.scanRef: Re-use file existence check done in snapshot creation"
Change-Id: I2622f1d384a88a556ba9d88f0d08a37af69e530c
Signed-off-by: Thomas Wolf <thomas.wolf@paranor.ch>
diff --git a/.bazelversion b/.bazelversion
index 227cea2..fd2a018 100644
--- a/.bazelversion
+++ b/.bazelversion
@@ -1 +1 @@
-2.0.0
+3.1.0
diff --git a/Documentation/technical/reftable.md b/Documentation/technical/reftable.md
index 47c61a3..1236a79 100644
--- a/Documentation/technical/reftable.md
+++ b/Documentation/technical/reftable.md
@@ -89,6 +89,10 @@
[ref-fmt]: https://git-scm.com/docs/git-check-ref-format
+### Key unicity
+
+Each entry must have a unique key; repeated keys are disallowed.
+
### Network byte order
All multi-byte, fixed width fields are in network byte order.
@@ -566,6 +570,10 @@
[update-ref]: https://git-scm.com/docs/git-update-ref#_logging_updates
+Contrary to traditional reflog (which is a file), renames are encoded as a
+combination of ref deletion and ref creation.
+
+
#### Reading the log
Readers accessing the log must first read the footer (below) to
@@ -771,12 +779,12 @@
A collection of reftable files are stored in the `$GIT_DIR/reftable/`
directory:
- 00000001.log
- 00000001.ref
- 00000002.ref
+ 00000001-00000001.log
+ 00000002-00000002.ref
+ 00000003-00000003.ref
where reftable files are named by a unique name such as produced by
-the function `${update_index}.ref`.
+the function `${min_update_index}-${max_update_index}.ref`.
Log-only files use the `.log` extension, while ref-only and mixed ref
and log files use `.ref`. extension.
@@ -786,9 +794,9 @@
recent):
$ cat .git/refs
- 00000001.log
- 00000001.ref
- 00000002.ref
+ 00000001-00000001.log
+ 00000002-00000002.ref
+ 00000003-00000003.ref
Readers must read `$GIT_DIR/refs` to determine which files are
relevant right now, and search through the stack in reverse order
@@ -815,8 +823,8 @@
1. Acquire `refs.lock`.
2. Read `refs` to determine current reftables.
3. Select `update_index` to be most recent file's `max_update_index + 1`.
-4. Prepare temp reftable `${update_index}_XXXXXX`, including log entries.
-5. Rename `${update_index}_XXXXXX` to `${update_index}.ref`.
+4. Prepare temp reftable `tmp_XXXXXX`, including log entries.
+5. Rename `tmp_XXXXXX` to `${update_index}-${update_index}.ref`.
6. Copy `refs` to `refs.lock`, appending file from (5).
7. Rename `refs.lock` to `refs`.
@@ -861,12 +869,13 @@
Ownership of these locks prevents other processes from trying
to compact these files.
3. Release `refs.lock`.
-4. Compact `B` and `C` into a temp file `${min_update_index}_XXXXXX`.
+4. Compact `B` and `C` into a temp file `${min_update_index}-${max_update_index}_XXXXXX`.
5. Reacquire lock `refs.lock`.
6. Verify that `B` and `C` are still in the stack, in that order. This
should always be the case, assuming that other processes are adhering
to the locking protocol.
-7. Rename `${min_update_index}_XXXXXX` to `${min_update_index}_2.ref`.
+7. Rename `${min_update_index}-${max_update_index}_XXXXXX` to
+ `${min_update_index}-${max_update_index}.ref`.
8. Write the new stack to `refs.lock`, replacing `B` and `C` with the
file from (4).
9. Rename `refs.lock` to `refs`.
@@ -875,6 +884,9 @@
This strategy permits compactions to proceed independently of updates.
+Each reftable (compacted or not) is uniquely identified by its name, so open
+reftables can be cached by their name.
+
## Alternatives considered
### bzip packed-refs
diff --git a/WORKSPACE b/WORKSPACE
index e40dd40..93962da 100644
--- a/WORKSPACE
+++ b/WORKSPACE
@@ -9,13 +9,18 @@
urls = ["https://github.com/bazelbuild/bazel-skylib/archive/0.8.0.tar.gz"],
)
-load("@bazel_skylib//lib:versions.bzl", "versions")
+# Check Bazel version when invoked by Bazel directly
+load("//tools:bazelisk_version.bzl", "bazelisk_version")
-versions.check(minimum_bazel_version = "0.29.0")
+bazelisk_version(name = "bazelisk_version")
+
+load("@bazelisk_version//:check.bzl", "check_bazel_version")
+
+check_bazel_version()
load("//tools:bazlets.bzl", "load_bazlets")
-load_bazlets(commit = "f53f51fb660552d0581aa0ba52c3836ed63d56a3")
+load_bazlets(commit = "f30a992da9fc855dce819875afb59f9dd6f860cd")
load(
"@com_googlesource_gerrit_bazlets//tools:maven_jar.bzl",
@@ -125,7 +130,7 @@
)
maven_jar(
- name = "servlet-api-3_1",
+ name = "servlet-api",
artifact = "javax.servlet:javax.servlet-api:3.1.0",
sha1 = "3cd63d075497751784b2fa84be59432f4905bf7c",
)
@@ -198,69 +203,69 @@
sha1 = "3edcfe49d2c6053a70a2a47e4e1c2f94998a49cf",
)
-JETTY_VER = "9.4.20.v20190813"
+JETTY_VER = "9.4.22.v20191022"
maven_jar(
name = "jetty-servlet",
artifact = "org.eclipse.jetty:jetty-servlet:" + JETTY_VER,
- sha1 = "d5d6610321bd173aead473e994f170989d633b25",
- src_sha1 = "09aa4fce2579d0905e3bde0b3bc923a032394805",
+ sha1 = "62285df7713347586d55f3f93a96299d1b721714",
+ src_sha1 = "fe2d1f1dc7a82ced141df935a0db5b5cadd76f4a",
)
maven_jar(
name = "jetty-security",
artifact = "org.eclipse.jetty:jetty-security:" + JETTY_VER,
- sha1 = "300c2e6dd62291c512bdaf3ecfefc1e305e26088",
- src_sha1 = "ec03ce3b6a8c0c3dd2bd8b32bc51419caa10ad62",
+ sha1 = "f7b3b61f09b34a69fd6df4f267f3907813c9224c",
+ src_sha1 = "5a1b33c5dde638ce9dbc2e07f0cff862e5029195",
)
maven_jar(
name = "jetty-server",
artifact = "org.eclipse.jetty:jetty-server:" + JETTY_VER,
- sha1 = "d4ee11134bca83db85919a1710fce022c67df3b7",
- src_sha1 = "0db81f86709a8184c793acd309c27dccdb5d439c",
+ sha1 = "f30b9b2cd6f63b073b63c2ac5e7e7f17b63b0908",
+ src_sha1 = "97fbdf8eade55f05d7e99c16fd90d394b248f717",
)
maven_jar(
name = "jetty-http",
artifact = "org.eclipse.jetty:jetty-http:" + JETTY_VER,
- sha1 = "edda2fd904a881114aba79e2f881c6f4004e8148",
- src_sha1 = "3e187c60d578c529f4baa3bbfc727d4b7ca7b93c",
+ sha1 = "f96f87fc73c2b586ff40689cbce6ae62d70f18fa",
+ src_sha1 = "0e51a30d0e3309acfc6ee548b90ff55165fbfa5c",
)
maven_jar(
name = "jetty-io",
artifact = "org.eclipse.jetty:jetty-io:" + JETTY_VER,
- sha1 = "b246c5e350d0aa1b310c07ec362755c34a1cc8cb",
- src_sha1 = "d12619b4df0d202847096a8429b0f96f123c7c77",
+ sha1 = "0f08e62908f94d1238be386302236a42204d566a",
+ src_sha1 = "d31c00383f13c95404ef606f57513569868acd6b",
)
maven_jar(
name = "jetty-util",
artifact = "org.eclipse.jetty:jetty-util:" + JETTY_VER,
- sha1 = "8ee753d673a124ba2880361871ab13f6863b2d40",
- src_sha1 = "2827925d01d95f42d02adf177d2474fbc8a3d5e0",
+ sha1 = "ffe0bf81a2a4a534b79dd981f971c7346a563095",
+ src_sha1 = "42f8abc84a6c4c9d2441d2dfcc60591e3296dc26",
)
-BOUNCYCASTLE_VER = "1.61"
+BOUNCYCASTLE_VER = "1.64"
maven_jar(
name = "bcpg",
artifact = "org.bouncycastle:bcpg-jdk15on:" + BOUNCYCASTLE_VER,
- sha1 = "422656435514ab8a28752b117d5d2646660a0ace",
- src_sha1 = "836da34e11114cbce8fa99f54175f8f3278d1cce",
+ sha1 = "56956a8c63ccadf62e7c678571cf86f30bd84441",
+ src_sha1 = "b241337df9516b35637d9be84451e2f03a81d186",
)
maven_jar(
name = "bcprov",
artifact = "org.bouncycastle:bcprov-jdk15on:" + BOUNCYCASTLE_VER,
- sha1 = "00df4b474e71be02c1349c3292d98886f888d1f7",
- src_sha1 = "3bf88046a16098ea6cc41576dd50d512854d39e1",
+ sha1 = "1467dac1b787b5ad2a18201c0c281df69882259e",
+ src_sha1 = "2881bfaf2c15e9e64b62c2a143db90db7a0d6035",
)
maven_jar(
name = "bcpkix",
artifact = "org.bouncycastle:bcpkix-jdk15on:" + BOUNCYCASTLE_VER,
- sha1 = "89bb3aa5b98b48e584eee2a7401b7682a46779b4",
- src_sha1 = "a0498d09200a18737eccc05aa81bbd05c1be0f8c",
+ sha1 = "3dac163e20110817d850d17e0444852a6d7d0bd7",
+ src_sha1 = "5c87199786c06e1a53adf16b1998386bad52da89",
)
diff --git a/lib/BUILD b/lib/BUILD
index 93bb731..058899f 100644
--- a/lib/BUILD
+++ b/lib/BUILD
@@ -224,7 +224,7 @@
"//org.eclipse.jgit.lfs.server.test:__pkg__",
"//org.eclipse.jgit.pgm:__pkg__",
],
- exports = ["@servlet-api-3_1//jar"],
+ exports = ["@servlet-api//jar"],
)
java_library(
diff --git a/org.eclipse.jgit.ant.test/.settings/org.eclipse.jdt.core.prefs b/org.eclipse.jgit.ant.test/.settings/org.eclipse.jdt.core.prefs
index d4751b5..4c4634a 100644
--- a/org.eclipse.jgit.ant.test/.settings/org.eclipse.jdt.core.prefs
+++ b/org.eclipse.jgit.ant.test/.settings/org.eclipse.jdt.core.prefs
@@ -92,7 +92,7 @@
org.eclipse.jdt.core.compiler.problem.unclosedCloseable=warning
org.eclipse.jdt.core.compiler.problem.undocumentedEmptyBlock=warning
org.eclipse.jdt.core.compiler.problem.unhandledWarningToken=ignore
-org.eclipse.jdt.core.compiler.problem.unnecessaryElse=ignore
+org.eclipse.jdt.core.compiler.problem.unnecessaryElse=warning
org.eclipse.jdt.core.compiler.problem.unnecessaryTypeCheck=error
org.eclipse.jdt.core.compiler.problem.unqualifiedFieldAccess=ignore
org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownException=error
diff --git a/org.eclipse.jgit.ant.test/META-INF/MANIFEST.MF b/org.eclipse.jgit.ant.test/META-INF/MANIFEST.MF
index 74ed271..4f76e40 100644
--- a/org.eclipse.jgit.ant.test/META-INF/MANIFEST.MF
+++ b/org.eclipse.jgit.ant.test/META-INF/MANIFEST.MF
@@ -5,13 +5,13 @@
Automatic-Module-Name: org.eclipse.jgit.ant.test
Bundle-SymbolicName: org.eclipse.jgit.ant.test
Bundle-Vendor: %Bundle-Vendor
-Bundle-Version: 5.5.2.qualifier
+Bundle-Version: 5.6.2.qualifier
Bundle-ActivationPolicy: lazy
Bundle-RequiredExecutionEnvironment: JavaSE-1.8
Import-Package: org.apache.tools.ant,
- org.eclipse.jgit.ant.tasks;version="[5.5.2,5.6.0)",
- org.eclipse.jgit.junit;version="[5.5.2,5.6.0)",
- org.eclipse.jgit.lib;version="[5.5.2,5.6.0)",
- org.eclipse.jgit.util;version="[5.5.2,5.6.0)",
+ org.eclipse.jgit.ant.tasks;version="[5.6.2,5.7.0)",
+ org.eclipse.jgit.junit;version="[5.6.2,5.7.0)",
+ org.eclipse.jgit.lib;version="[5.6.2,5.7.0)",
+ org.eclipse.jgit.util;version="[5.6.2,5.7.0)",
org.hamcrest.core;version="[1.1.0,2.0.0)",
org.junit;version="[4.12,5.0.0)"
diff --git a/org.eclipse.jgit.ant.test/pom.xml b/org.eclipse.jgit.ant.test/pom.xml
index a5d6304..8bbba4c 100644
--- a/org.eclipse.jgit.ant.test/pom.xml
+++ b/org.eclipse.jgit.ant.test/pom.xml
@@ -50,7 +50,7 @@
<parent>
<groupId>org.eclipse.jgit</groupId>
<artifactId>org.eclipse.jgit-parent</artifactId>
- <version>5.5.2-SNAPSHOT</version>
+ <version>5.6.2-SNAPSHOT</version>
</parent>
<artifactId>org.eclipse.jgit.ant.test</artifactId>
diff --git a/org.eclipse.jgit.ant/.settings/org.eclipse.jdt.core.prefs b/org.eclipse.jgit.ant/.settings/org.eclipse.jdt.core.prefs
index 94a1c4f..4335e66 100644
--- a/org.eclipse.jgit.ant/.settings/org.eclipse.jdt.core.prefs
+++ b/org.eclipse.jgit.ant/.settings/org.eclipse.jdt.core.prefs
@@ -92,7 +92,7 @@
org.eclipse.jdt.core.compiler.problem.unclosedCloseable=warning
org.eclipse.jdt.core.compiler.problem.undocumentedEmptyBlock=warning
org.eclipse.jdt.core.compiler.problem.unhandledWarningToken=ignore
-org.eclipse.jdt.core.compiler.problem.unnecessaryElse=ignore
+org.eclipse.jdt.core.compiler.problem.unnecessaryElse=warning
org.eclipse.jdt.core.compiler.problem.unnecessaryTypeCheck=error
org.eclipse.jdt.core.compiler.problem.unqualifiedFieldAccess=ignore
org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownException=warning
diff --git a/org.eclipse.jgit.ant/META-INF/MANIFEST.MF b/org.eclipse.jgit.ant/META-INF/MANIFEST.MF
index fac3286..37c40c2 100644
--- a/org.eclipse.jgit.ant/META-INF/MANIFEST.MF
+++ b/org.eclipse.jgit.ant/META-INF/MANIFEST.MF
@@ -3,13 +3,13 @@
Bundle-Name: %Bundle-Name
Automatic-Module-Name: org.eclipse.jgit.ant
Bundle-SymbolicName: org.eclipse.jgit.ant
-Bundle-Version: 5.5.2.qualifier
+Bundle-Version: 5.6.2.qualifier
Bundle-RequiredExecutionEnvironment: JavaSE-1.8
Import-Package: org.apache.tools.ant,
- org.eclipse.jgit.storage.file;version="[5.5.2,5.6.0)"
+ org.eclipse.jgit.storage.file;version="[5.6.2,5.7.0)"
Bundle-Localization: plugin
Bundle-Vendor: %Bundle-Vendor
-Export-Package: org.eclipse.jgit.ant;version="5.5.2",
- org.eclipse.jgit.ant.tasks;version="5.5.2";
+Export-Package: org.eclipse.jgit.ant;version="5.6.2",
+ org.eclipse.jgit.ant.tasks;version="5.6.2";
uses:="org.apache.tools.ant,
org.apache.tools.ant.types"
diff --git a/org.eclipse.jgit.ant/META-INF/SOURCE-MANIFEST.MF b/org.eclipse.jgit.ant/META-INF/SOURCE-MANIFEST.MF
index a1ba9ce..1c2df65 100644
--- a/org.eclipse.jgit.ant/META-INF/SOURCE-MANIFEST.MF
+++ b/org.eclipse.jgit.ant/META-INF/SOURCE-MANIFEST.MF
@@ -3,5 +3,5 @@
Bundle-Name: org.eclipse.jgit.ant - Sources
Bundle-SymbolicName: org.eclipse.jgit.ant.source
Bundle-Vendor: Eclipse.org - JGit
-Bundle-Version: 5.5.2.qualifier
-Eclipse-SourceBundle: org.eclipse.jgit.ant;version="5.5.2.qualifier";roots="."
+Bundle-Version: 5.6.2.qualifier
+Eclipse-SourceBundle: org.eclipse.jgit.ant;version="5.6.2.qualifier";roots="."
diff --git a/org.eclipse.jgit.ant/pom.xml b/org.eclipse.jgit.ant/pom.xml
index 1c1c494..6066ace 100644
--- a/org.eclipse.jgit.ant/pom.xml
+++ b/org.eclipse.jgit.ant/pom.xml
@@ -48,7 +48,7 @@
<parent>
<groupId>org.eclipse.jgit</groupId>
<artifactId>org.eclipse.jgit-parent</artifactId>
- <version>5.5.2-SNAPSHOT</version>
+ <version>5.6.2-SNAPSHOT</version>
</parent>
<artifactId>org.eclipse.jgit.ant</artifactId>
@@ -71,7 +71,7 @@
<dependency>
<groupId>org.apache.ant</groupId>
<artifactId>ant</artifactId>
- <version>1.10.5</version>
+ <version>1.10.7</version>
</dependency>
</dependencies>
diff --git a/org.eclipse.jgit.archive/.settings/org.eclipse.jdt.core.prefs b/org.eclipse.jgit.archive/.settings/org.eclipse.jdt.core.prefs
index ef6f5e7..bc7ba1e 100644
--- a/org.eclipse.jgit.archive/.settings/org.eclipse.jdt.core.prefs
+++ b/org.eclipse.jgit.archive/.settings/org.eclipse.jdt.core.prefs
@@ -92,7 +92,7 @@
org.eclipse.jdt.core.compiler.problem.unclosedCloseable=warning
org.eclipse.jdt.core.compiler.problem.undocumentedEmptyBlock=warning
org.eclipse.jdt.core.compiler.problem.unhandledWarningToken=ignore
-org.eclipse.jdt.core.compiler.problem.unnecessaryElse=ignore
+org.eclipse.jdt.core.compiler.problem.unnecessaryElse=warning
org.eclipse.jdt.core.compiler.problem.unnecessaryTypeCheck=error
org.eclipse.jdt.core.compiler.problem.unqualifiedFieldAccess=ignore
org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownException=warning
diff --git a/org.eclipse.jgit.archive/META-INF/MANIFEST.MF b/org.eclipse.jgit.archive/META-INF/MANIFEST.MF
index 14167a6..a67ee1c 100644
--- a/org.eclipse.jgit.archive/META-INF/MANIFEST.MF
+++ b/org.eclipse.jgit.archive/META-INF/MANIFEST.MF
@@ -3,7 +3,7 @@
Bundle-Name: %Bundle-Name
Automatic-Module-Name: org.eclipse.jgit.archive
Bundle-SymbolicName: org.eclipse.jgit.archive
-Bundle-Version: 5.5.2.qualifier
+Bundle-Version: 5.6.2.qualifier
Bundle-Vendor: %Bundle-Vendor
Bundle-Localization: plugin
Bundle-RequiredExecutionEnvironment: JavaSE-1.8
@@ -13,17 +13,17 @@
org.apache.commons.compress.compressors.bzip2;version="[1.4,2.0)",
org.apache.commons.compress.compressors.gzip;version="[1.4,2.0)",
org.apache.commons.compress.compressors.xz;version="[1.4,2.0)",
- org.eclipse.jgit.api;version="[5.5.2,5.6.0)",
- org.eclipse.jgit.lib;version="[5.5.2,5.6.0)",
- org.eclipse.jgit.nls;version="[5.5.2,5.6.0)",
- org.eclipse.jgit.revwalk;version="[5.5.2,5.6.0)",
- org.eclipse.jgit.util;version="[5.5.2,5.6.0)",
+ org.eclipse.jgit.api;version="[5.6.2,5.7.0)",
+ org.eclipse.jgit.lib;version="[5.6.2,5.7.0)",
+ org.eclipse.jgit.nls;version="[5.6.2,5.7.0)",
+ org.eclipse.jgit.revwalk;version="[5.6.2,5.7.0)",
+ org.eclipse.jgit.util;version="[5.6.2,5.7.0)",
org.osgi.framework;version="[1.3.0,2.0.0)"
Bundle-ActivationPolicy: lazy
Bundle-Activator: org.eclipse.jgit.archive.FormatActivator
-Export-Package: org.eclipse.jgit.archive;version="5.5.2";
+Export-Package: org.eclipse.jgit.archive;version="5.6.2";
uses:="org.eclipse.jgit.lib,
org.eclipse.jgit.api,
org.apache.commons.compress.archivers,
org.osgi.framework",
- org.eclipse.jgit.archive.internal;version="5.5.2";x-internal:=true
+ org.eclipse.jgit.archive.internal;version="5.6.2";x-internal:=true
diff --git a/org.eclipse.jgit.archive/META-INF/SOURCE-MANIFEST.MF b/org.eclipse.jgit.archive/META-INF/SOURCE-MANIFEST.MF
index 21facee..bb492b0 100644
--- a/org.eclipse.jgit.archive/META-INF/SOURCE-MANIFEST.MF
+++ b/org.eclipse.jgit.archive/META-INF/SOURCE-MANIFEST.MF
@@ -3,5 +3,5 @@
Bundle-Name: org.eclipse.jgit.archive - Sources
Bundle-SymbolicName: org.eclipse.jgit.archive.source
Bundle-Vendor: Eclipse.org - JGit
-Bundle-Version: 5.5.2.qualifier
-Eclipse-SourceBundle: org.eclipse.jgit.archive;version="5.5.2.qualifier";roots="."
+Bundle-Version: 5.6.2.qualifier
+Eclipse-SourceBundle: org.eclipse.jgit.archive;version="5.6.2.qualifier";roots="."
diff --git a/org.eclipse.jgit.archive/pom.xml b/org.eclipse.jgit.archive/pom.xml
index 61d25a6..83078af 100644
--- a/org.eclipse.jgit.archive/pom.xml
+++ b/org.eclipse.jgit.archive/pom.xml
@@ -50,7 +50,7 @@
<parent>
<groupId>org.eclipse.jgit</groupId>
<artifactId>org.eclipse.jgit-parent</artifactId>
- <version>5.5.2-SNAPSHOT</version>
+ <version>5.6.2-SNAPSHOT</version>
</parent>
<artifactId>org.eclipse.jgit.archive</artifactId>
diff --git a/org.eclipse.jgit.benchmarks/pom.xml b/org.eclipse.jgit.benchmarks/pom.xml
index 0aade52..a0cd834 100644
--- a/org.eclipse.jgit.benchmarks/pom.xml
+++ b/org.eclipse.jgit.benchmarks/pom.xml
@@ -47,7 +47,7 @@
<modelVersion>4.0.0</modelVersion>
<groupId>org.eclipse.jgit</groupId>
- <version>5.5.2-SNAPSHOT</version>
+ <version>5.6.2-SNAPSHOT</version>
<artifactId>org.eclipse.jgit.benchmarks</artifactId>
<packaging>jar</packaging>
@@ -131,6 +131,7 @@
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
+ <version>3.2.1</version>
<executions>
<execution>
<phase>package</phase>
diff --git a/org.eclipse.jgit.coverage/pom.xml b/org.eclipse.jgit.coverage/pom.xml
index be76c03..db7c5c4 100644
--- a/org.eclipse.jgit.coverage/pom.xml
+++ b/org.eclipse.jgit.coverage/pom.xml
@@ -5,7 +5,7 @@
<parent>
<groupId>org.eclipse.jgit</groupId>
<artifactId>org.eclipse.jgit-parent</artifactId>
- <version>5.5.2-SNAPSHOT</version>
+ <version>5.6.2-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
@@ -18,88 +18,88 @@
<dependency>
<groupId>org.eclipse.jgit</groupId>
<artifactId>org.eclipse.jgit</artifactId>
- <version>5.5.2-SNAPSHOT</version>
+ <version>5.6.2-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.eclipse.jgit</groupId>
<artifactId>org.eclipse.jgit.ant</artifactId>
- <version>5.5.2-SNAPSHOT</version>
+ <version>5.6.2-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.eclipse.jgit</groupId>
<artifactId>org.eclipse.jgit.archive</artifactId>
- <version>5.5.2-SNAPSHOT</version>
+ <version>5.6.2-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.eclipse.jgit</groupId>
<artifactId>org.eclipse.jgit.http.apache</artifactId>
- <version>5.5.2-SNAPSHOT</version>
+ <version>5.6.2-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.eclipse.jgit</groupId>
<artifactId>org.eclipse.jgit.http.server</artifactId>
- <version>5.5.2-SNAPSHOT</version>
+ <version>5.6.2-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.eclipse.jgit</groupId>
<artifactId>org.eclipse.jgit.lfs</artifactId>
- <version>5.5.2-SNAPSHOT</version>
+ <version>5.6.2-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.eclipse.jgit</groupId>
<artifactId>org.eclipse.jgit.lfs.server</artifactId>
- <version>5.5.2-SNAPSHOT</version>
+ <version>5.6.2-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.eclipse.jgit</groupId>
<artifactId>org.eclipse.jgit.pgm</artifactId>
- <version>5.5.2-SNAPSHOT</version>
+ <version>5.6.2-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.eclipse.jgit</groupId>
<artifactId>org.eclipse.jgit.ui</artifactId>
- <version>5.5.2-SNAPSHOT</version>
+ <version>5.6.2-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.eclipse.jgit</groupId>
<artifactId>org.eclipse.jgit.ssh.apache</artifactId>
- <version>5.5.2-SNAPSHOT</version>
+ <version>5.6.2-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.eclipse.jgit</groupId>
<artifactId>org.eclipse.jgit.test</artifactId>
- <version>5.5.2-SNAPSHOT</version>
+ <version>5.6.2-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.eclipse.jgit</groupId>
<artifactId>org.eclipse.jgit.ant.test</artifactId>
- <version>5.5.2-SNAPSHOT</version>
+ <version>5.6.2-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.eclipse.jgit</groupId>
<artifactId>org.eclipse.jgit.http.test</artifactId>
- <version>5.5.2-SNAPSHOT</version>
+ <version>5.6.2-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.eclipse.jgit</groupId>
<artifactId>org.eclipse.jgit.pgm.test</artifactId>
- <version>5.5.2-SNAPSHOT</version>
+ <version>5.6.2-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.eclipse.jgit</groupId>
<artifactId>org.eclipse.jgit.lfs.test</artifactId>
- <version>5.5.2-SNAPSHOT</version>
+ <version>5.6.2-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.eclipse.jgit</groupId>
<artifactId>org.eclipse.jgit.lfs.server.test</artifactId>
- <version>5.5.2-SNAPSHOT</version>
+ <version>5.6.2-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.eclipse.jgit</groupId>
<artifactId>org.eclipse.jgit.ssh.apache.test</artifactId>
- <version>5.5.2-SNAPSHOT</version>
+ <version>5.6.2-SNAPSHOT</version>
</dependency>
</dependencies>
diff --git a/org.eclipse.jgit.http.apache/.settings/org.eclipse.jdt.core.prefs b/org.eclipse.jgit.http.apache/.settings/org.eclipse.jdt.core.prefs
index 94a1c4f..4335e66 100644
--- a/org.eclipse.jgit.http.apache/.settings/org.eclipse.jdt.core.prefs
+++ b/org.eclipse.jgit.http.apache/.settings/org.eclipse.jdt.core.prefs
@@ -92,7 +92,7 @@
org.eclipse.jdt.core.compiler.problem.unclosedCloseable=warning
org.eclipse.jdt.core.compiler.problem.undocumentedEmptyBlock=warning
org.eclipse.jdt.core.compiler.problem.unhandledWarningToken=ignore
-org.eclipse.jdt.core.compiler.problem.unnecessaryElse=ignore
+org.eclipse.jdt.core.compiler.problem.unnecessaryElse=warning
org.eclipse.jdt.core.compiler.problem.unnecessaryTypeCheck=error
org.eclipse.jdt.core.compiler.problem.unqualifiedFieldAccess=ignore
org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownException=warning
diff --git a/org.eclipse.jgit.http.apache/META-INF/MANIFEST.MF b/org.eclipse.jgit.http.apache/META-INF/MANIFEST.MF
index 84da9f8..2f906a5 100644
--- a/org.eclipse.jgit.http.apache/META-INF/MANIFEST.MF
+++ b/org.eclipse.jgit.http.apache/META-INF/MANIFEST.MF
@@ -3,7 +3,7 @@
Bundle-Name: %Bundle-Name
Automatic-Module-Name: org.eclipse.jgit.http.apache
Bundle-SymbolicName: org.eclipse.jgit.http.apache
-Bundle-Version: 5.5.2.qualifier
+Bundle-Version: 5.6.2.qualifier
Bundle-RequiredExecutionEnvironment: JavaSE-1.8
Bundle-Localization: plugin
Bundle-Vendor: %Bundle-Vendor
@@ -23,11 +23,11 @@
org.apache.http.impl.client;version="[4.3.0,5.0.0)",
org.apache.http.impl.conn;version="[4.3.0,5.0.0)",
org.apache.http.params;version="[4.3.0,5.0.0)",
- org.eclipse.jgit.annotations;version="[5.5.2,5.6.0)",
- org.eclipse.jgit.nls;version="[5.5.2,5.6.0)",
- org.eclipse.jgit.transport.http;version="[5.5.2,5.6.0)",
- org.eclipse.jgit.util;version="[5.5.2,5.6.0)"
-Export-Package: org.eclipse.jgit.transport.http.apache;version="5.5.2";
+ org.eclipse.jgit.annotations;version="[5.6.2,5.7.0)",
+ org.eclipse.jgit.nls;version="[5.6.2,5.7.0)",
+ org.eclipse.jgit.transport.http;version="[5.6.2,5.7.0)",
+ org.eclipse.jgit.util;version="[5.6.2,5.7.0)"
+Export-Package: org.eclipse.jgit.transport.http.apache;version="5.6.2";
uses:="org.apache.http.client,
org.eclipse.jgit.transport.http,
org.apache.http.entity,
diff --git a/org.eclipse.jgit.http.apache/META-INF/SOURCE-MANIFEST.MF b/org.eclipse.jgit.http.apache/META-INF/SOURCE-MANIFEST.MF
index 3666a28..3f52d65 100644
--- a/org.eclipse.jgit.http.apache/META-INF/SOURCE-MANIFEST.MF
+++ b/org.eclipse.jgit.http.apache/META-INF/SOURCE-MANIFEST.MF
@@ -3,5 +3,5 @@
Bundle-Name: org.eclipse.jgit.http.apache - Sources
Bundle-SymbolicName: org.eclipse.jgit.http.apache.source
Bundle-Vendor: Eclipse.org - JGit
-Bundle-Version: 5.5.2.qualifier
-Eclipse-SourceBundle: org.eclipse.jgit.http.apache;version="5.5.2.qualifier";roots="."
+Bundle-Version: 5.6.2.qualifier
+Eclipse-SourceBundle: org.eclipse.jgit.http.apache;version="5.6.2.qualifier";roots="."
diff --git a/org.eclipse.jgit.http.apache/pom.xml b/org.eclipse.jgit.http.apache/pom.xml
index a8f5576..5919dd5 100644
--- a/org.eclipse.jgit.http.apache/pom.xml
+++ b/org.eclipse.jgit.http.apache/pom.xml
@@ -48,7 +48,7 @@
<parent>
<groupId>org.eclipse.jgit</groupId>
<artifactId>org.eclipse.jgit-parent</artifactId>
- <version>5.5.2-SNAPSHOT</version>
+ <version>5.6.2-SNAPSHOT</version>
</parent>
<artifactId>org.eclipse.jgit.http.apache</artifactId>
diff --git a/org.eclipse.jgit.http.apache/src/org/eclipse/jgit/transport/http/apache/HttpClientConnection.java b/org.eclipse.jgit.http.apache/src/org/eclipse/jgit/transport/http/apache/HttpClientConnection.java
index f92c5df..9d9e2f8 100644
--- a/org.eclipse.jgit.http.apache/src/org/eclipse/jgit/transport/http/apache/HttpClientConnection.java
+++ b/org.eclipse.jgit.http.apache/src/org/eclipse/jgit/transport/http/apache/HttpClientConnection.java
@@ -92,6 +92,7 @@
import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
import org.apache.http.impl.client.HttpClientBuilder;
import org.apache.http.impl.client.HttpClients;
+import org.apache.http.impl.client.SystemDefaultCredentialsProvider;
import org.apache.http.impl.conn.BasicHttpClientConnectionManager;
import org.eclipse.jgit.annotations.NonNull;
import org.eclipse.jgit.transport.http.HttpConnection;
@@ -165,6 +166,8 @@ private HttpClient getClient() {
new BasicHttpClientConnectionManager(registry));
}
clientBuilder.setDefaultRequestConfig(configBuilder.build());
+ clientBuilder.setDefaultCredentialsProvider(
+ new SystemDefaultCredentialsProvider());
client = clientBuilder.build();
}
diff --git a/org.eclipse.jgit.http.server/.settings/org.eclipse.jdt.core.prefs b/org.eclipse.jgit.http.server/.settings/org.eclipse.jdt.core.prefs
index 94a1c4f..4335e66 100644
--- a/org.eclipse.jgit.http.server/.settings/org.eclipse.jdt.core.prefs
+++ b/org.eclipse.jgit.http.server/.settings/org.eclipse.jdt.core.prefs
@@ -92,7 +92,7 @@
org.eclipse.jdt.core.compiler.problem.unclosedCloseable=warning
org.eclipse.jdt.core.compiler.problem.undocumentedEmptyBlock=warning
org.eclipse.jdt.core.compiler.problem.unhandledWarningToken=ignore
-org.eclipse.jdt.core.compiler.problem.unnecessaryElse=ignore
+org.eclipse.jdt.core.compiler.problem.unnecessaryElse=warning
org.eclipse.jdt.core.compiler.problem.unnecessaryTypeCheck=error
org.eclipse.jdt.core.compiler.problem.unqualifiedFieldAccess=ignore
org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownException=warning
diff --git a/org.eclipse.jgit.http.server/META-INF/MANIFEST.MF b/org.eclipse.jgit.http.server/META-INF/MANIFEST.MF
index 8d71a4d..f4cde03 100644
--- a/org.eclipse.jgit.http.server/META-INF/MANIFEST.MF
+++ b/org.eclipse.jgit.http.server/META-INF/MANIFEST.MF
@@ -3,13 +3,13 @@
Bundle-Name: %Bundle-Name
Automatic-Module-Name: org.eclipse.jgit.http.server
Bundle-SymbolicName: org.eclipse.jgit.http.server
-Bundle-Version: 5.5.2.qualifier
+Bundle-Version: 5.6.2.qualifier
Bundle-Localization: plugin
Bundle-Vendor: %Bundle-Vendor
-Export-Package: org.eclipse.jgit.http.server;version="5.5.2",
- org.eclipse.jgit.http.server.glue;version="5.5.2";
+Export-Package: org.eclipse.jgit.http.server;version="5.6.2",
+ org.eclipse.jgit.http.server.glue;version="5.6.2";
uses:="javax.servlet,javax.servlet.http",
- org.eclipse.jgit.http.server.resolver;version="5.5.2";
+ org.eclipse.jgit.http.server.resolver;version="5.6.2";
uses:="org.eclipse.jgit.transport.resolver,
org.eclipse.jgit.lib,
org.eclipse.jgit.transport,
@@ -18,13 +18,14 @@
Bundle-RequiredExecutionEnvironment: JavaSE-1.8
Import-Package: javax.servlet;version="[2.5.0,3.2.0)",
javax.servlet.http;version="[2.5.0,3.2.0)",
- org.eclipse.jgit.errors;version="[5.5.2,5.6.0)",
- org.eclipse.jgit.internal.storage.dfs;version="[5.5.2,5.6.0)",
- org.eclipse.jgit.internal.storage.file;version="[5.5.2,5.6.0)",
- org.eclipse.jgit.internal.transport.parser;version="[5.5.2,5.6.0)",
- org.eclipse.jgit.lib;version="[5.5.2,5.6.0)",
- org.eclipse.jgit.nls;version="[5.5.2,5.6.0)",
- org.eclipse.jgit.revwalk;version="[5.5.2,5.6.0)",
- org.eclipse.jgit.transport;version="[5.5.2,5.6.0)",
- org.eclipse.jgit.transport.resolver;version="[5.5.2,5.6.0)",
- org.eclipse.jgit.util;version="[5.5.2,5.6.0)"
+ org.eclipse.jgit.annotations;version="[5.6.2,5.7.0)",
+ org.eclipse.jgit.errors;version="[5.6.2,5.7.0)",
+ org.eclipse.jgit.internal.storage.dfs;version="[5.6.2,5.7.0)",
+ org.eclipse.jgit.internal.storage.file;version="[5.6.2,5.7.0)",
+ org.eclipse.jgit.internal.transport.parser;version="[5.6.2,5.7.0)",
+ org.eclipse.jgit.lib;version="[5.6.2,5.7.0)",
+ org.eclipse.jgit.nls;version="[5.6.2,5.7.0)",
+ org.eclipse.jgit.revwalk;version="[5.6.2,5.7.0)",
+ org.eclipse.jgit.transport;version="[5.6.2,5.7.0)",
+ org.eclipse.jgit.transport.resolver;version="[5.6.2,5.7.0)",
+ org.eclipse.jgit.util;version="[5.6.2,5.7.0)"
diff --git a/org.eclipse.jgit.http.server/META-INF/SOURCE-MANIFEST.MF b/org.eclipse.jgit.http.server/META-INF/SOURCE-MANIFEST.MF
index 39c8877..3298c65 100644
--- a/org.eclipse.jgit.http.server/META-INF/SOURCE-MANIFEST.MF
+++ b/org.eclipse.jgit.http.server/META-INF/SOURCE-MANIFEST.MF
@@ -3,5 +3,5 @@
Bundle-Name: org.eclipse.jgit.http.server - Sources
Bundle-SymbolicName: org.eclipse.jgit.http.server.source
Bundle-Vendor: Eclipse.org - JGit
-Bundle-Version: 5.5.2.qualifier
-Eclipse-SourceBundle: org.eclipse.jgit.http.server;version="5.5.2.qualifier";roots="."
+Bundle-Version: 5.6.2.qualifier
+Eclipse-SourceBundle: org.eclipse.jgit.http.server;version="5.6.2.qualifier";roots="."
diff --git a/org.eclipse.jgit.http.server/pom.xml b/org.eclipse.jgit.http.server/pom.xml
index 2d4f758..a6ae774 100644
--- a/org.eclipse.jgit.http.server/pom.xml
+++ b/org.eclipse.jgit.http.server/pom.xml
@@ -52,7 +52,7 @@
<parent>
<groupId>org.eclipse.jgit</groupId>
<artifactId>org.eclipse.jgit-parent</artifactId>
- <version>5.5.2-SNAPSHOT</version>
+ <version>5.6.2-SNAPSHOT</version>
</parent>
<artifactId>org.eclipse.jgit.http.server</artifactId>
diff --git a/org.eclipse.jgit.http.server/src/org/eclipse/jgit/http/server/GitFilter.java b/org.eclipse.jgit.http.server/src/org/eclipse/jgit/http/server/GitFilter.java
index 1c5e7ec..3396b9b 100644
--- a/org.eclipse.jgit.http.server/src/org/eclipse/jgit/http/server/GitFilter.java
+++ b/org.eclipse.jgit.http.server/src/org/eclipse/jgit/http/server/GitFilter.java
@@ -92,6 +92,8 @@ public class GitFilter extends MetaFilter {
private UploadPackFactory<HttpServletRequest> uploadPackFactory = new DefaultUploadPackFactory();
+ private UploadPackErrorHandler uploadPackErrorHandler;
+
private ReceivePackFactory<HttpServletRequest> receivePackFactory = new DefaultReceivePackFactory();
private final List<Filter> uploadPackFilters = new LinkedList<>();
@@ -150,6 +152,18 @@ public void setUploadPackFactory(UploadPackFactory<HttpServletRequest> f) {
}
/**
+ * Set a custom error handler for git-upload-pack.
+ *
+ * @param h
+ * A custom error handler for git-upload-pack.
+ * @since 5.6
+ */
+ public void setUploadPackErrorHandler(UploadPackErrorHandler h) {
+ assertNotInitialized();
+ this.uploadPackErrorHandler = h;
+ }
+
+ /**
* Add upload-pack filter
*
* @param filter
@@ -212,7 +226,7 @@ public void init(FilterConfig filterConfig) throws ServletException {
b = b.through(new UploadPackServlet.Factory(uploadPackFactory));
for (Filter f : uploadPackFilters)
b = b.through(f);
- b.with(new UploadPackServlet());
+ b.with(new UploadPackServlet(uploadPackErrorHandler));
}
if (receivePackFactory != ReceivePackFactory.DISABLED) {
diff --git a/org.eclipse.jgit.http.server/src/org/eclipse/jgit/http/server/ObjectFileServlet.java b/org.eclipse.jgit.http.server/src/org/eclipse/jgit/http/server/ObjectFileServlet.java
index 5a27be6..922a98a 100644
--- a/org.eclipse.jgit.http.server/src/org/eclipse/jgit/http/server/ObjectFileServlet.java
+++ b/org.eclipse.jgit.http.server/src/org/eclipse/jgit/http/server/ObjectFileServlet.java
@@ -83,7 +83,7 @@ String etag(FileSender sender) throws IOException {
}
}
- private static abstract class PackData extends ObjectFileServlet {
+ private abstract static class PackData extends ObjectFileServlet {
private static final long serialVersionUID = 1L;
PackData(String contentType) {
diff --git a/org.eclipse.jgit.http.server/src/org/eclipse/jgit/http/server/UploadPackErrorHandler.java b/org.eclipse.jgit.http.server/src/org/eclipse/jgit/http/server/UploadPackErrorHandler.java
new file mode 100644
index 0000000..03be087
--- /dev/null
+++ b/org.eclipse.jgit.http.server/src/org/eclipse/jgit/http/server/UploadPackErrorHandler.java
@@ -0,0 +1,59 @@
+/*
+ * Copyright (c) 2019, Google LLC and others
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+package org.eclipse.jgit.http.server;
+
+import java.io.IOException;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.eclipse.jgit.transport.ServiceMayNotContinueException;
+import org.eclipse.jgit.transport.UploadPack;
+
+/**
+ * Handle git-upload-pack errors.
+ *
+ * <p>
+ * This is an entry point for customizing an error handler for git-upload-pack.
+ * Right before calling {@link UploadPack#uploadWithExceptionPropagation}, JGit
+ * will call this handler if specified through {@link GitFilter}. The
+ * implementation of this handler is responsible for calling
+ * {@link UploadPackRunnable} and handling exceptions for clients.
+ *
+ * <p>
+ * If a custom handler is not specified, JGit will use the default error
+ * handler.
+ *
+ * @since 5.6
+ */
+public interface UploadPackErrorHandler {
+ /**
+ * @param req
+ * The HTTP request
+ * @param rsp
+ * The HTTP response
+ * @param r
+ * A continuation that handles a git-upload-pack request.
+ * @throws IOException
+ */
+ void upload(HttpServletRequest req, HttpServletResponse rsp,
+ UploadPackRunnable r) throws IOException;
+
+ /** Process a git-upload-pack request. */
+ public interface UploadPackRunnable {
+ /**
+ * See {@link UploadPack#uploadWithExceptionPropagation}.
+ *
+ * @throws ServiceMayNotContinueException
+ * @throws IOException
+ */
+ void upload() throws ServiceMayNotContinueException, IOException;
+ }
+}
diff --git a/org.eclipse.jgit.http.server/src/org/eclipse/jgit/http/server/UploadPackServlet.java b/org.eclipse.jgit.http.server/src/org/eclipse/jgit/http/server/UploadPackServlet.java
index 0f40371..54561e0 100644
--- a/org.eclipse.jgit.http.server/src/org/eclipse/jgit/http/server/UploadPackServlet.java
+++ b/org.eclipse.jgit.http.server/src/org/eclipse/jgit/http/server/UploadPackServlet.java
@@ -70,7 +70,8 @@
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
-
+import org.eclipse.jgit.annotations.Nullable;
+import org.eclipse.jgit.http.server.UploadPackErrorHandler.UploadPackRunnable;
import org.eclipse.jgit.lib.Repository;
import org.eclipse.jgit.transport.InternalHttpServerGlue;
import org.eclipse.jgit.transport.PacketLineOut;
@@ -181,53 +182,71 @@ public void destroy() {
}
}
+ private final UploadPackErrorHandler handler;
+
+ UploadPackServlet(@Nullable UploadPackErrorHandler handler) {
+ this.handler = handler != null ? handler
+ : this::defaultUploadPackHandler;
+ }
+
/** {@inheritDoc} */
@Override
- public void doPost(final HttpServletRequest req,
- final HttpServletResponse rsp) throws IOException {
+ public void doPost(HttpServletRequest req, HttpServletResponse rsp)
+ throws IOException {
if (!UPLOAD_PACK_REQUEST_TYPE.equals(req.getContentType())) {
rsp.sendError(SC_UNSUPPORTED_MEDIA_TYPE);
return;
}
- SmartOutputStream out = new SmartOutputStream(req, rsp, false) {
- @Override
- public void flush() throws IOException {
- doFlush();
- }
- };
+ UploadPackRunnable r = () -> {
+ UploadPack up = (UploadPack) req.getAttribute(ATTRIBUTE_HANDLER);
+ @SuppressWarnings("resource")
+ SmartOutputStream out = new SmartOutputStream(req, rsp, false) {
+ @Override
+ public void flush() throws IOException {
+ doFlush();
+ }
+ };
- UploadPack up = (UploadPack) req.getAttribute(ATTRIBUTE_HANDLER);
- try {
up.setBiDirectionalPipe(false);
rsp.setContentType(UPLOAD_PACK_RESULT_TYPE);
- up.upload(getInputStream(req), out, null);
- out.close();
-
- } catch (ServiceMayNotContinueException e) {
- if (e.isOutput()) {
+ try {
+ up.upload(getInputStream(req), out, null);
+ out.close();
+ } catch (ServiceMayNotContinueException e) {
+ if (e.isOutput()) {
+ consumeRequestBody(req);
+ out.close();
+ }
+ throw e;
+ } catch (UploadPackInternalServerErrorException e) {
+ // Special case exception, error message was sent to client.
+ log(up.getRepository(), e.getCause());
consumeRequestBody(req);
out.close();
- } else if (!rsp.isCommitted()) {
+ }
+ };
+
+ handler.upload(req, rsp, r);
+ }
+
+ private void defaultUploadPackHandler(HttpServletRequest req,
+ HttpServletResponse rsp, UploadPackRunnable r) throws IOException {
+ try {
+ r.upload();
+ } catch (ServiceMayNotContinueException e) {
+ if (!e.isOutput() && !rsp.isCommitted()) {
rsp.reset();
sendError(req, rsp, e.getStatusCode(), e.getMessage());
}
- return;
-
- } catch (UploadPackInternalServerErrorException e) {
- // Special case exception, error message was sent to client.
- log(up.getRepository(), e.getCause());
- consumeRequestBody(req);
- out.close();
-
} catch (Throwable e) {
+ UploadPack up = (UploadPack) req.getAttribute(ATTRIBUTE_HANDLER);
log(up.getRepository(), e);
if (!rsp.isCommitted()) {
rsp.reset();
sendError(req, rsp, SC_INTERNAL_SERVER_ERROR);
}
- return;
}
}
diff --git a/org.eclipse.jgit.http.server/src/org/eclipse/jgit/http/server/glue/RegexPipeline.java b/org.eclipse.jgit.http.server/src/org/eclipse/jgit/http/server/glue/RegexPipeline.java
index 0108105..06b31a5 100644
--- a/org.eclipse.jgit.http.server/src/org/eclipse/jgit/http/server/glue/RegexPipeline.java
+++ b/org.eclipse.jgit.http.server/src/org/eclipse/jgit/http/server/glue/RegexPipeline.java
@@ -138,7 +138,7 @@ void service(HttpServletRequest req, HttpServletResponse rsp)
// build a request for them so RegexGroupFilter can pick
// a different capture group later. Continue using the
// first capture group as the path info.
- WrappedRequest groups[] = new WrappedRequest[cur.groupCount()];
+ WrappedRequest[] groups = new WrappedRequest[cur.groupCount()];
for (int groupId = 1; groupId <= cur.groupCount(); groupId++) {
final int s = cur.start(groupId);
final String path, info;
diff --git a/org.eclipse.jgit.http.server/src/org/eclipse/jgit/http/server/glue/ServletBinderImpl.java b/org.eclipse.jgit.http.server/src/org/eclipse/jgit/http/server/glue/ServletBinderImpl.java
index f167497..574e94a 100644
--- a/org.eclipse.jgit.http.server/src/org/eclipse/jgit/http/server/glue/ServletBinderImpl.java
+++ b/org.eclipse.jgit.http.server/src/org/eclipse/jgit/http/server/glue/ServletBinderImpl.java
@@ -86,10 +86,10 @@ public void with(HttpServlet servlet) {
* @return the configured servlet, or singleton returning 404 if none.
*/
protected HttpServlet getServlet() {
- if (httpServlet != null)
+ if (httpServlet != null) {
return httpServlet;
- else
- return new ErrorServlet(HttpServletResponse.SC_NOT_FOUND);
+ }
+ return new ErrorServlet(HttpServletResponse.SC_NOT_FOUND);
}
/**
diff --git a/org.eclipse.jgit.http.server/src/org/eclipse/jgit/http/server/resolver/DefaultUploadPackFactory.java b/org.eclipse.jgit.http.server/src/org/eclipse/jgit/http/server/resolver/DefaultUploadPackFactory.java
index a69fab0..b9e6882 100644
--- a/org.eclipse.jgit.http.server/src/org/eclipse/jgit/http/server/resolver/DefaultUploadPackFactory.java
+++ b/org.eclipse.jgit.http.server/src/org/eclipse/jgit/http/server/resolver/DefaultUploadPackFactory.java
@@ -83,8 +83,7 @@ public UploadPack create(HttpServletRequest req, Repository db)
up.setExtraParameters(Arrays.asList(params));
}
return up;
- } else {
- throw new ServiceNotEnabledException();
}
+ throw new ServiceNotEnabledException();
}
}
diff --git a/org.eclipse.jgit.http.test/.settings/org.eclipse.jdt.core.prefs b/org.eclipse.jgit.http.test/.settings/org.eclipse.jdt.core.prefs
index d4751b5..4c4634a 100644
--- a/org.eclipse.jgit.http.test/.settings/org.eclipse.jdt.core.prefs
+++ b/org.eclipse.jgit.http.test/.settings/org.eclipse.jdt.core.prefs
@@ -92,7 +92,7 @@
org.eclipse.jdt.core.compiler.problem.unclosedCloseable=warning
org.eclipse.jdt.core.compiler.problem.undocumentedEmptyBlock=warning
org.eclipse.jdt.core.compiler.problem.unhandledWarningToken=ignore
-org.eclipse.jdt.core.compiler.problem.unnecessaryElse=ignore
+org.eclipse.jdt.core.compiler.problem.unnecessaryElse=warning
org.eclipse.jdt.core.compiler.problem.unnecessaryTypeCheck=error
org.eclipse.jdt.core.compiler.problem.unqualifiedFieldAccess=ignore
org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownException=error
diff --git a/org.eclipse.jgit.http.test/META-INF/MANIFEST.MF b/org.eclipse.jgit.http.test/META-INF/MANIFEST.MF
index cec2a09..0600434 100644
--- a/org.eclipse.jgit.http.test/META-INF/MANIFEST.MF
+++ b/org.eclipse.jgit.http.test/META-INF/MANIFEST.MF
@@ -3,7 +3,7 @@
Bundle-Name: %Bundle-Name
Automatic-Module-Name: org.eclipse.jgit.http.test
Bundle-SymbolicName: org.eclipse.jgit.http.test
-Bundle-Version: 5.5.2.qualifier
+Bundle-Version: 5.6.2.qualifier
Bundle-Vendor: %Bundle-Vendor
Bundle-Localization: plugin
Bundle-RequiredExecutionEnvironment: JavaSE-1.8
@@ -28,25 +28,25 @@
org.eclipse.jetty.util.log;version="[9.4.5,10.0.0)",
org.eclipse.jetty.util.security;version="[9.4.5,10.0.0)",
org.eclipse.jetty.util.thread;version="[9.4.5,10.0.0)",
- org.eclipse.jgit.errors;version="[5.5.2,5.6.0)",
- org.eclipse.jgit.http.server;version="[5.5.2,5.6.0)",
- org.eclipse.jgit.http.server.glue;version="[5.5.2,5.6.0)",
- org.eclipse.jgit.http.server.resolver;version="[5.5.2,5.6.0)",
- org.eclipse.jgit.internal;version="[5.5.2,5.6.0)",
- org.eclipse.jgit.internal.storage.dfs;version="[5.5.2,5.6.0)",
- org.eclipse.jgit.internal.storage.file;version="[5.5.2,5.6.0)",
- org.eclipse.jgit.internal.storage.reftable;version="[5.5.2,5.6.0)",
- org.eclipse.jgit.junit;version="[5.5.2,5.6.0)",
- org.eclipse.jgit.junit.http;version="[5.5.2,5.6.0)",
- org.eclipse.jgit.lib;version="[5.5.2,5.6.0)",
- org.eclipse.jgit.nls;version="[5.5.2,5.6.0)",
- org.eclipse.jgit.revwalk;version="[5.5.2,5.6.0)",
- org.eclipse.jgit.storage.file;version="[5.5.2,5.6.0)",
- org.eclipse.jgit.transport;version="[5.5.2,5.6.0)",
- org.eclipse.jgit.transport.http;version="[5.5.2,5.6.0)",
- org.eclipse.jgit.transport.http.apache;version="[5.5.2,5.6.0)",
- org.eclipse.jgit.transport.resolver;version="[5.5.2,5.6.0)",
- org.eclipse.jgit.util;version="[5.5.2,5.6.0)",
+ org.eclipse.jgit.errors;version="[5.6.2,5.7.0)",
+ org.eclipse.jgit.http.server;version="[5.6.2,5.7.0)",
+ org.eclipse.jgit.http.server.glue;version="[5.6.2,5.7.0)",
+ org.eclipse.jgit.http.server.resolver;version="[5.6.2,5.7.0)",
+ org.eclipse.jgit.internal;version="[5.6.2,5.7.0)",
+ org.eclipse.jgit.internal.storage.dfs;version="[5.6.2,5.7.0)",
+ org.eclipse.jgit.internal.storage.file;version="[5.6.2,5.7.0)",
+ org.eclipse.jgit.internal.storage.reftable;version="[5.6.2,5.7.0)",
+ org.eclipse.jgit.junit;version="[5.6.2,5.7.0)",
+ org.eclipse.jgit.junit.http;version="[5.6.2,5.7.0)",
+ org.eclipse.jgit.lib;version="[5.6.2,5.7.0)",
+ org.eclipse.jgit.nls;version="[5.6.2,5.7.0)",
+ org.eclipse.jgit.revwalk;version="[5.6.2,5.7.0)",
+ org.eclipse.jgit.storage.file;version="[5.6.2,5.7.0)",
+ org.eclipse.jgit.transport;version="[5.6.2,5.7.0)",
+ org.eclipse.jgit.transport.http;version="[5.6.2,5.7.0)",
+ org.eclipse.jgit.transport.http.apache;version="[5.6.2,5.7.0)",
+ org.eclipse.jgit.transport.resolver;version="[5.6.2,5.7.0)",
+ org.eclipse.jgit.util;version="[5.6.2,5.7.0)",
org.hamcrest;version="[1.1.0,2.0.0)",
org.hamcrest.core;version="[1.1.0,2.0.0)",
org.junit;version="[4.12,5.0.0)",
diff --git a/org.eclipse.jgit.http.test/pom.xml b/org.eclipse.jgit.http.test/pom.xml
index 5ab6a7e..854b3c7 100644
--- a/org.eclipse.jgit.http.test/pom.xml
+++ b/org.eclipse.jgit.http.test/pom.xml
@@ -51,7 +51,7 @@
<parent>
<groupId>org.eclipse.jgit</groupId>
<artifactId>org.eclipse.jgit-parent</artifactId>
- <version>5.5.2-SNAPSHOT</version>
+ <version>5.6.2-SNAPSHOT</version>
</parent>
<artifactId>org.eclipse.jgit.http.test</artifactId>
diff --git a/org.eclipse.jgit.http.test/src/org/eclipse/jgit/http/test/RefsUnreadableInMemoryRepository.java b/org.eclipse.jgit.http.test/src/org/eclipse/jgit/http/test/RefsUnreadableInMemoryRepository.java
index 78f909e..6f85979 100644
--- a/org.eclipse.jgit.http.test/src/org/eclipse/jgit/http/test/RefsUnreadableInMemoryRepository.java
+++ b/org.eclipse.jgit.http.test/src/org/eclipse/jgit/http/test/RefsUnreadableInMemoryRepository.java
@@ -43,10 +43,14 @@
package org.eclipse.jgit.http.test;
import java.io.IOException;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
import org.eclipse.jgit.internal.storage.dfs.DfsRepositoryDescription;
import org.eclipse.jgit.internal.storage.dfs.InMemoryRepository;
-import org.eclipse.jgit.internal.storage.reftable.Reftable;
+import org.eclipse.jgit.lib.ObjectId;
+import org.eclipse.jgit.lib.Ref;
import org.eclipse.jgit.lib.RefDatabase;
/**
@@ -82,12 +86,43 @@ void startFailing() {
}
private class RefsUnreadableRefDatabase extends MemRefDatabase {
+
+ /** {@inheritDoc} */
@Override
- protected Reftable reader() throws IOException {
+ public Ref exactRef(String name) throws IOException {
if (failing) {
throw new IOException("disk failed, no refs found");
}
- return super.reader();
+ return super.exactRef(name);
+ }
+
+ /** {@inheritDoc} */
+ @Override
+ public Map<String, Ref> getRefs(String prefix) throws IOException {
+ if (failing) {
+ throw new IOException("disk failed, no refs found");
+ }
+
+ return super.getRefs(prefix);
+ }
+
+ /** {@inheritDoc} */
+ @Override
+ public List<Ref> getRefsByPrefix(String prefix) throws IOException {
+ if (failing) {
+ throw new IOException("disk failed, no refs found");
+ }
+
+ return super.getRefsByPrefix(prefix);
+ }
+
+ /** {@inheritDoc} */
+ @Override
+ public Set<Ref> getTipsWithSha1(ObjectId id) throws IOException {
+ if (failing) {
+ throw new IOException("disk failed, no refs found");
+ }
+ return super.getTipsWithSha1(id);
}
}
}
diff --git a/org.eclipse.jgit.http.test/tst/org/eclipse/jgit/http/test/SmartClientSmartServerTest.java b/org.eclipse.jgit.http.test/tst/org/eclipse/jgit/http/test/SmartClientSmartServerTest.java
index 3401e26..99aa06b 100644
--- a/org.eclipse.jgit.http.test/tst/org/eclipse/jgit/http/test/SmartClientSmartServerTest.java
+++ b/org.eclipse.jgit.http.test/tst/org/eclipse/jgit/http/test/SmartClientSmartServerTest.java
@@ -331,9 +331,8 @@ private String local(String url, boolean toLocal) {
String fragment = u.getRawFragment();
if (fragment != null) {
return u.getRawPath() + '#' + fragment;
- } else {
- return u.getRawPath();
}
+ return u.getRawPath();
} catch (URISyntaxException e) {
return url;
}
diff --git a/org.eclipse.jgit.junit.http/.settings/org.eclipse.jdt.core.prefs b/org.eclipse.jgit.junit.http/.settings/org.eclipse.jdt.core.prefs
index 2ca78ff..3dd5840 100644
--- a/org.eclipse.jgit.junit.http/.settings/org.eclipse.jdt.core.prefs
+++ b/org.eclipse.jgit.junit.http/.settings/org.eclipse.jdt.core.prefs
@@ -92,7 +92,7 @@
org.eclipse.jdt.core.compiler.problem.unclosedCloseable=warning
org.eclipse.jdt.core.compiler.problem.undocumentedEmptyBlock=warning
org.eclipse.jdt.core.compiler.problem.unhandledWarningToken=ignore
-org.eclipse.jdt.core.compiler.problem.unnecessaryElse=ignore
+org.eclipse.jdt.core.compiler.problem.unnecessaryElse=warning
org.eclipse.jdt.core.compiler.problem.unnecessaryTypeCheck=error
org.eclipse.jdt.core.compiler.problem.unqualifiedFieldAccess=ignore
org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownException=error
diff --git a/org.eclipse.jgit.junit.http/META-INF/MANIFEST.MF b/org.eclipse.jgit.junit.http/META-INF/MANIFEST.MF
index a7254a3..26ac174 100644
--- a/org.eclipse.jgit.junit.http/META-INF/MANIFEST.MF
+++ b/org.eclipse.jgit.junit.http/META-INF/MANIFEST.MF
@@ -3,7 +3,7 @@
Bundle-Name: %Bundle-Name
Automatic-Module-Name: org.eclipse.jgit.junit.http
Bundle-SymbolicName: org.eclipse.jgit.junit.http
-Bundle-Version: 5.5.2.qualifier
+Bundle-Version: 5.6.2.qualifier
Bundle-Localization: plugin
Bundle-Vendor: %Bundle-Vendor
Bundle-ActivationPolicy: lazy
@@ -22,16 +22,16 @@
org.eclipse.jetty.util.log;version="[9.4.5,10.0.0)",
org.eclipse.jetty.util.security;version="[9.4.5,10.0.0)",
org.eclipse.jetty.util.ssl;version="[9.4.5,10.0.0)",
- org.eclipse.jgit.errors;version="[5.5.2,5.6.0)",
- org.eclipse.jgit.http.server;version="[5.5.2,5.6.0)",
- org.eclipse.jgit.internal.storage.file;version="[5.5.2,5.6.0)",
- org.eclipse.jgit.junit;version="[5.5.2,5.6.0)",
- org.eclipse.jgit.lib;version="[5.5.2,5.6.0)",
- org.eclipse.jgit.revwalk;version="[5.5.2,5.6.0)",
- org.eclipse.jgit.transport;version="[5.5.2,5.6.0)",
- org.eclipse.jgit.transport.resolver;version="[5.5.2,5.6.0)",
+ org.eclipse.jgit.errors;version="[5.6.2,5.7.0)",
+ org.eclipse.jgit.http.server;version="[5.6.2,5.7.0)",
+ org.eclipse.jgit.internal.storage.file;version="[5.6.2,5.7.0)",
+ org.eclipse.jgit.junit;version="[5.6.2,5.7.0)",
+ org.eclipse.jgit.lib;version="[5.6.2,5.7.0)",
+ org.eclipse.jgit.revwalk;version="[5.6.2,5.7.0)",
+ org.eclipse.jgit.transport;version="[5.6.2,5.7.0)",
+ org.eclipse.jgit.transport.resolver;version="[5.6.2,5.7.0)",
org.junit;version="[4.12,5.0.0)"
-Export-Package: org.eclipse.jgit.junit.http;version="5.5.2";
+Export-Package: org.eclipse.jgit.junit.http;version="5.6.2";
uses:="org.eclipse.jgit.transport,
org.eclipse.jgit.junit,
javax.servlet.http,
diff --git a/org.eclipse.jgit.junit.http/META-INF/SOURCE-MANIFEST.MF b/org.eclipse.jgit.junit.http/META-INF/SOURCE-MANIFEST.MF
index 6f5590b..d8c8161 100644
--- a/org.eclipse.jgit.junit.http/META-INF/SOURCE-MANIFEST.MF
+++ b/org.eclipse.jgit.junit.http/META-INF/SOURCE-MANIFEST.MF
@@ -3,5 +3,5 @@
Bundle-Name: org.eclipse.jgit.junit.http - Sources
Bundle-SymbolicName: org.eclipse.jgit.junit.http.source
Bundle-Vendor: Eclipse.org - JGit
-Bundle-Version: 5.5.2.qualifier
-Eclipse-SourceBundle: org.eclipse.jgit.junit.http;version="5.5.2.qualifier";roots="."
+Bundle-Version: 5.6.2.qualifier
+Eclipse-SourceBundle: org.eclipse.jgit.junit.http;version="5.6.2.qualifier";roots="."
diff --git a/org.eclipse.jgit.junit.http/pom.xml b/org.eclipse.jgit.junit.http/pom.xml
index e4b2c6b..988102c 100644
--- a/org.eclipse.jgit.junit.http/pom.xml
+++ b/org.eclipse.jgit.junit.http/pom.xml
@@ -50,7 +50,7 @@
<parent>
<groupId>org.eclipse.jgit</groupId>
<artifactId>org.eclipse.jgit-parent</artifactId>
- <version>5.5.2-SNAPSHOT</version>
+ <version>5.6.2-SNAPSHOT</version>
</parent>
<artifactId>org.eclipse.jgit.junit.http</artifactId>
diff --git a/org.eclipse.jgit.junit.http/src/org/eclipse/jgit/junit/http/AppServer.java b/org.eclipse.jgit.junit.http/src/org/eclipse/jgit/junit/http/AppServer.java
index ba0138b..e089c87 100644
--- a/org.eclipse.jgit.junit.http/src/org/eclipse/jgit/junit/http/AppServer.java
+++ b/org.eclipse.jgit.junit.http/src/org/eclipse/jgit/junit/http/AppServer.java
@@ -205,7 +205,7 @@ public AppServer(int port, int sslPort) {
}
private SslContextFactory createTestSslContextFactory(String hostName) {
- SslContextFactory factory = new SslContextFactory(true);
+ SslContextFactory.Client factory = new SslContextFactory.Client(true);
String dName = "CN=,OU=,O=,ST=,L=,C=";
@@ -311,10 +311,10 @@ protected void doStart() throws Exception {
@Override
protected String[] loadRoleInfo(UserPrincipal user) {
- if (users.get(user.getName()) == null)
+ if (users.get(user.getName()) == null) {
return null;
- else
- return new String[] { role };
+ }
+ return new String[] { role };
}
@Override
diff --git a/org.eclipse.jgit.junit.ssh/.settings/org.eclipse.jdt.core.prefs b/org.eclipse.jgit.junit.ssh/.settings/org.eclipse.jdt.core.prefs
index 2ca78ff..3dd5840 100644
--- a/org.eclipse.jgit.junit.ssh/.settings/org.eclipse.jdt.core.prefs
+++ b/org.eclipse.jgit.junit.ssh/.settings/org.eclipse.jdt.core.prefs
@@ -92,7 +92,7 @@
org.eclipse.jdt.core.compiler.problem.unclosedCloseable=warning
org.eclipse.jdt.core.compiler.problem.undocumentedEmptyBlock=warning
org.eclipse.jdt.core.compiler.problem.unhandledWarningToken=ignore
-org.eclipse.jdt.core.compiler.problem.unnecessaryElse=ignore
+org.eclipse.jdt.core.compiler.problem.unnecessaryElse=warning
org.eclipse.jdt.core.compiler.problem.unnecessaryTypeCheck=error
org.eclipse.jdt.core.compiler.problem.unqualifiedFieldAccess=ignore
org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownException=error
diff --git a/org.eclipse.jgit.junit.ssh/META-INF/MANIFEST.MF b/org.eclipse.jgit.junit.ssh/META-INF/MANIFEST.MF
index ff2edd3..d66492b 100644
--- a/org.eclipse.jgit.junit.ssh/META-INF/MANIFEST.MF
+++ b/org.eclipse.jgit.junit.ssh/META-INF/MANIFEST.MF
@@ -3,7 +3,7 @@
Bundle-Name: %Bundle-Name
Automatic-Module-Name: org.eclipse.jgit.junit.ssh
Bundle-SymbolicName: org.eclipse.jgit.junit.ssh
-Bundle-Version: 5.5.2.qualifier
+Bundle-Version: 5.6.2.qualifier
Bundle-Localization: plugin
Bundle-Vendor: %Bundle-Vendor
Bundle-ActivationPolicy: lazy
@@ -30,8 +30,8 @@
org.apache.sshd.server.shell;version="[2.2.0,2.3.0)",
org.apache.sshd.server.subsystem;version="[2.2.0,2.3.0)",
org.apache.sshd.server.subsystem.sftp;version="[2.2.0,2.3.0)",
- org.eclipse.jgit.annotations;version="[5.5.2,5.6.0)",
- org.eclipse.jgit.lib;version="[5.5.2,5.6.0)",
- org.eclipse.jgit.transport;version="[5.5.2,5.6.0)",
+ org.eclipse.jgit.annotations;version="[5.6.2,5.7.0)",
+ org.eclipse.jgit.lib;version="[5.6.2,5.7.0)",
+ org.eclipse.jgit.transport;version="[5.6.2,5.7.0)",
org.slf4j;version="[1.7.0,2.0.0)"
-Export-Package: org.eclipse.jgit.junit.ssh;version="5.5.2"
+Export-Package: org.eclipse.jgit.junit.ssh;version="5.6.2"
diff --git a/org.eclipse.jgit.junit.ssh/META-INF/SOURCE-MANIFEST.MF b/org.eclipse.jgit.junit.ssh/META-INF/SOURCE-MANIFEST.MF
index c828888..285ba82 100644
--- a/org.eclipse.jgit.junit.ssh/META-INF/SOURCE-MANIFEST.MF
+++ b/org.eclipse.jgit.junit.ssh/META-INF/SOURCE-MANIFEST.MF
@@ -3,5 +3,5 @@
Bundle-Name: org.eclipse.jgit.junit.ssh - Sources
Bundle-SymbolicName: org.eclipse.jgit.junit.ssh.source
Bundle-Vendor: Eclipse.org - JGit
-Bundle-Version: 5.5.2.qualifier
-Eclipse-SourceBundle: org.eclipse.jgit.junit.ssh;version="5.5.2.qualifier";roots="."
+Bundle-Version: 5.6.2.qualifier
+Eclipse-SourceBundle: org.eclipse.jgit.junit.ssh;version="5.6.2.qualifier";roots="."
diff --git a/org.eclipse.jgit.junit.ssh/pom.xml b/org.eclipse.jgit.junit.ssh/pom.xml
index 3b28c00..cee9037 100644
--- a/org.eclipse.jgit.junit.ssh/pom.xml
+++ b/org.eclipse.jgit.junit.ssh/pom.xml
@@ -50,7 +50,7 @@
<parent>
<groupId>org.eclipse.jgit</groupId>
<artifactId>org.eclipse.jgit-parent</artifactId>
- <version>5.5.2-SNAPSHOT</version>
+ <version>5.6.2-SNAPSHOT</version>
</parent>
<artifactId>org.eclipse.jgit.junit.ssh</artifactId>
diff --git a/org.eclipse.jgit.junit/.settings/.api_filters b/org.eclipse.jgit.junit/.settings/.api_filters
index 4a2da06..025a79d 100644
--- a/org.eclipse.jgit.junit/.settings/.api_filters
+++ b/org.eclipse.jgit.junit/.settings/.api_filters
@@ -8,6 +8,13 @@
<message_argument value="setSystemGitConfig(FileBasedConfig)"/>
</message_arguments>
</filter>
+ <filter id="1141899266">
+ <message_arguments>
+ <message_argument value="5.5"/>
+ <message_argument value="5.6"/>
+ <message_argument value="setJGitConfig(FileBasedConfig)"/>
+ </message_arguments>
+ </filter>
<filter id="1142947843">
<message_arguments>
<message_argument value="5.1.9"/>
diff --git a/org.eclipse.jgit.junit/.settings/org.eclipse.jdt.core.prefs b/org.eclipse.jgit.junit/.settings/org.eclipse.jdt.core.prefs
index b675029..530f8f6 100644
--- a/org.eclipse.jgit.junit/.settings/org.eclipse.jdt.core.prefs
+++ b/org.eclipse.jgit.junit/.settings/org.eclipse.jdt.core.prefs
@@ -103,7 +103,7 @@
org.eclipse.jdt.core.compiler.problem.unlikelyCollectionMethodArgumentType=warning
org.eclipse.jdt.core.compiler.problem.unlikelyCollectionMethodArgumentTypeStrict=disabled
org.eclipse.jdt.core.compiler.problem.unlikelyEqualsArgumentType=info
-org.eclipse.jdt.core.compiler.problem.unnecessaryElse=ignore
+org.eclipse.jdt.core.compiler.problem.unnecessaryElse=warning
org.eclipse.jdt.core.compiler.problem.unnecessaryTypeCheck=error
org.eclipse.jdt.core.compiler.problem.unqualifiedFieldAccess=ignore
org.eclipse.jdt.core.compiler.problem.unstableAutoModuleName=warning
diff --git a/org.eclipse.jgit.junit/META-INF/MANIFEST.MF b/org.eclipse.jgit.junit/META-INF/MANIFEST.MF
index 4de3e46..e61df3a 100644
--- a/org.eclipse.jgit.junit/META-INF/MANIFEST.MF
+++ b/org.eclipse.jgit.junit/META-INF/MANIFEST.MF
@@ -3,35 +3,35 @@
Bundle-Name: %Bundle-Name
Automatic-Module-Name: org.eclipse.jgit.junit
Bundle-SymbolicName: org.eclipse.jgit.junit
-Bundle-Version: 5.5.2.qualifier
+Bundle-Version: 5.6.2.qualifier
Bundle-Localization: plugin
Bundle-Vendor: %Bundle-Vendor
Bundle-ActivationPolicy: lazy
Bundle-RequiredExecutionEnvironment: JavaSE-1.8
-Import-Package: org.eclipse.jgit.annotations;version="[5.5.2,5.6.0)",
- org.eclipse.jgit.api;version="[5.5.2,5.6.0)",
- org.eclipse.jgit.api.errors;version="[5.5.2,5.6.0)",
- org.eclipse.jgit.dircache;version="[5.5.2,5.6.0)",
- org.eclipse.jgit.errors;version="[5.5.2,5.6.0)",
- org.eclipse.jgit.internal.storage.file;version="[5.5.2,5.6.0)",
- org.eclipse.jgit.internal.storage.pack;version="[5.5.2,5.6.0)",
- org.eclipse.jgit.lib;version="[5.5.2,5.6.0)",
- org.eclipse.jgit.merge;version="[5.5.2,5.6.0)",
- org.eclipse.jgit.revwalk;version="[5.5.2,5.6.0)",
- org.eclipse.jgit.storage.file;version="[5.5.2,5.6.0)",
- org.eclipse.jgit.transport;version="5.5.2",
- org.eclipse.jgit.treewalk;version="[5.5.2,5.6.0)",
- org.eclipse.jgit.treewalk.filter;version="[5.5.2,5.6.0)",
- org.eclipse.jgit.util;version="[5.5.2,5.6.0)",
- org.eclipse.jgit.util.io;version="[5.5.2,5.6.0)",
- org.eclipse.jgit.util.time;version="[5.5.2,5.6.0)",
+Import-Package: org.eclipse.jgit.annotations;version="[5.6.2,5.7.0)",
+ org.eclipse.jgit.api;version="[5.6.2,5.7.0)",
+ org.eclipse.jgit.api.errors;version="[5.6.2,5.7.0)",
+ org.eclipse.jgit.dircache;version="[5.6.2,5.7.0)",
+ org.eclipse.jgit.errors;version="[5.6.2,5.7.0)",
+ org.eclipse.jgit.internal.storage.file;version="[5.6.2,5.7.0)",
+ org.eclipse.jgit.internal.storage.pack;version="[5.6.2,5.7.0)",
+ org.eclipse.jgit.lib;version="[5.6.2,5.7.0)",
+ org.eclipse.jgit.merge;version="[5.6.2,5.7.0)",
+ org.eclipse.jgit.revwalk;version="[5.6.2,5.7.0)",
+ org.eclipse.jgit.storage.file;version="[5.6.2,5.7.0)",
+ org.eclipse.jgit.transport;version="5.6.2",
+ org.eclipse.jgit.treewalk;version="[5.6.2,5.7.0)",
+ org.eclipse.jgit.treewalk.filter;version="[5.6.2,5.7.0)",
+ org.eclipse.jgit.util;version="[5.6.2,5.7.0)",
+ org.eclipse.jgit.util.io;version="[5.6.2,5.7.0)",
+ org.eclipse.jgit.util.time;version="[5.6.2,5.7.0)",
org.junit;version="[4.12,5.0.0)",
org.junit.rules;version="[4.12,5.0.0)",
org.junit.runner;version="[4.12,5.0.0)",
org.junit.runners;version="[4.12,5.0.0)",
org.junit.runners.model;version="[4.12,5.0.0)",
org.slf4j;version="[1.7.0,2.0.0)"
-Export-Package: org.eclipse.jgit.junit;version="5.5.2";
+Export-Package: org.eclipse.jgit.junit;version="5.6.2";
uses:="org.eclipse.jgit.dircache,
org.eclipse.jgit.lib,
org.eclipse.jgit.revwalk,
@@ -44,4 +44,4 @@
org.junit.runners.model,
org.junit.runner,
org.eclipse.jgit.util.time",
- org.eclipse.jgit.junit.time;version="5.5.2";uses:="org.eclipse.jgit.util.time"
+ org.eclipse.jgit.junit.time;version="5.6.2";uses:="org.eclipse.jgit.util.time"
diff --git a/org.eclipse.jgit.junit/META-INF/SOURCE-MANIFEST.MF b/org.eclipse.jgit.junit/META-INF/SOURCE-MANIFEST.MF
index 9568f93..de62cba 100644
--- a/org.eclipse.jgit.junit/META-INF/SOURCE-MANIFEST.MF
+++ b/org.eclipse.jgit.junit/META-INF/SOURCE-MANIFEST.MF
@@ -3,5 +3,5 @@
Bundle-Name: org.eclipse.jgit.junit - Sources
Bundle-SymbolicName: org.eclipse.jgit.junit.source
Bundle-Vendor: Eclipse.org - JGit
-Bundle-Version: 5.5.2.qualifier
-Eclipse-SourceBundle: org.eclipse.jgit.junit;version="5.5.2.qualifier";roots="."
+Bundle-Version: 5.6.2.qualifier
+Eclipse-SourceBundle: org.eclipse.jgit.junit;version="5.6.2.qualifier";roots="."
diff --git a/org.eclipse.jgit.junit/pom.xml b/org.eclipse.jgit.junit/pom.xml
index 1ccc220..691392c 100644
--- a/org.eclipse.jgit.junit/pom.xml
+++ b/org.eclipse.jgit.junit/pom.xml
@@ -52,7 +52,7 @@
<parent>
<groupId>org.eclipse.jgit</groupId>
<artifactId>org.eclipse.jgit-parent</artifactId>
- <version>5.5.2-SNAPSHOT</version>
+ <version>5.6.2-SNAPSHOT</version>
</parent>
<artifactId>org.eclipse.jgit.junit</artifactId>
diff --git a/org.eclipse.jgit.junit/src/org/eclipse/jgit/junit/RepeatRule.java b/org.eclipse.jgit.junit/src/org/eclipse/jgit/junit/RepeatRule.java
index 5b58f0b..d003520 100644
--- a/org.eclipse.jgit.junit/src/org/eclipse/jgit/junit/RepeatRule.java
+++ b/org.eclipse.jgit.junit/src/org/eclipse/jgit/junit/RepeatRule.java
@@ -78,7 +78,7 @@
*/
public class RepeatRule implements TestRule {
- private static Logger LOG = Logger
+ private static final Logger LOG = Logger
.getLogger(RepeatRule.class.getName());
/**
diff --git a/org.eclipse.jgit.junit/src/org/eclipse/jgit/junit/TestRepository.java b/org.eclipse.jgit.junit/src/org/eclipse/jgit/junit/TestRepository.java
index 593b960..7b476de 100644
--- a/org.eclipse.jgit.junit/src/org/eclipse/jgit/junit/TestRepository.java
+++ b/org.eclipse.jgit.junit/src/org/eclipse/jgit/junit/TestRepository.java
@@ -784,9 +784,8 @@ public RevCommit cherryPick(AnyObjectId id) throws Exception {
}
update(Constants.HEAD, result);
return pool.parseCommit(result);
- } else {
- throw new IOException("Merge conflict");
}
+ throw new IOException("Merge conflict");
}
/**
diff --git a/org.eclipse.jgit.lfs.server.test/.settings/org.eclipse.jdt.core.prefs b/org.eclipse.jgit.lfs.server.test/.settings/org.eclipse.jdt.core.prefs
index d4751b5..4c4634a 100644
--- a/org.eclipse.jgit.lfs.server.test/.settings/org.eclipse.jdt.core.prefs
+++ b/org.eclipse.jgit.lfs.server.test/.settings/org.eclipse.jdt.core.prefs
@@ -92,7 +92,7 @@
org.eclipse.jdt.core.compiler.problem.unclosedCloseable=warning
org.eclipse.jdt.core.compiler.problem.undocumentedEmptyBlock=warning
org.eclipse.jdt.core.compiler.problem.unhandledWarningToken=ignore
-org.eclipse.jdt.core.compiler.problem.unnecessaryElse=ignore
+org.eclipse.jdt.core.compiler.problem.unnecessaryElse=warning
org.eclipse.jdt.core.compiler.problem.unnecessaryTypeCheck=error
org.eclipse.jdt.core.compiler.problem.unqualifiedFieldAccess=ignore
org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownException=error
diff --git a/org.eclipse.jgit.lfs.server.test/META-INF/MANIFEST.MF b/org.eclipse.jgit.lfs.server.test/META-INF/MANIFEST.MF
index bcd5cf0..5a824cb 100644
--- a/org.eclipse.jgit.lfs.server.test/META-INF/MANIFEST.MF
+++ b/org.eclipse.jgit.lfs.server.test/META-INF/MANIFEST.MF
@@ -3,7 +3,7 @@
Bundle-Name: %Bundle-Name
Automatic-Module-Name: org.eclipse.jgit.lfs.server.test
Bundle-SymbolicName: org.eclipse.jgit.lfs.server.test
-Bundle-Version: 5.5.2.qualifier
+Bundle-Version: 5.6.2.qualifier
Bundle-Vendor: %Bundle-Vendor
Bundle-Localization: plugin
Bundle-RequiredExecutionEnvironment: JavaSE-1.8
@@ -28,24 +28,24 @@
org.eclipse.jetty.util.log;version="[9.4.5,10.0.0)",
org.eclipse.jetty.util.security;version="[9.4.5,10.0.0)",
org.eclipse.jetty.util.thread;version="[9.4.5,10.0.0)",
- org.eclipse.jgit.api;version="[5.5.2,5.6.0)",
- org.eclipse.jgit.api.errors;version="[5.5.2,5.6.0)",
- org.eclipse.jgit.internal.storage.file;version="[5.5.2,5.6.0)",
- org.eclipse.jgit.junit;version="[5.5.2,5.6.0)",
- org.eclipse.jgit.junit.http;version="[5.5.2,5.6.0)",
- org.eclipse.jgit.lfs;version="[5.5.2,5.6.0)",
- org.eclipse.jgit.lfs.errors;version="[5.5.2,5.6.0)",
- org.eclipse.jgit.lfs.lib;version="[5.5.2,5.6.0)",
- org.eclipse.jgit.lfs.server;version="[5.5.2,5.6.0)",
- org.eclipse.jgit.lfs.server.fs;version="[5.5.2,5.6.0)",
- org.eclipse.jgit.lfs.test;version="[5.5.2,5.6.0)",
- org.eclipse.jgit.lib;version="[5.5.2,5.6.0)",
- org.eclipse.jgit.revwalk;version="[5.5.2,5.6.0)",
- org.eclipse.jgit.storage.file;version="[5.5.2,5.6.0)",
- org.eclipse.jgit.transport;version="[5.5.2,5.6.0)",
- org.eclipse.jgit.treewalk;version="[5.5.2,5.6.0)",
- org.eclipse.jgit.treewalk.filter;version="[5.5.2,5.6.0)",
- org.eclipse.jgit.util;version="[5.5.2,5.6.0)",
+ org.eclipse.jgit.api;version="[5.6.2,5.7.0)",
+ org.eclipse.jgit.api.errors;version="[5.6.2,5.7.0)",
+ org.eclipse.jgit.internal.storage.file;version="[5.6.2,5.7.0)",
+ org.eclipse.jgit.junit;version="[5.6.2,5.7.0)",
+ org.eclipse.jgit.junit.http;version="[5.6.2,5.7.0)",
+ org.eclipse.jgit.lfs;version="[5.6.2,5.7.0)",
+ org.eclipse.jgit.lfs.errors;version="[5.6.2,5.7.0)",
+ org.eclipse.jgit.lfs.lib;version="[5.6.2,5.7.0)",
+ org.eclipse.jgit.lfs.server;version="[5.6.2,5.7.0)",
+ org.eclipse.jgit.lfs.server.fs;version="[5.6.2,5.7.0)",
+ org.eclipse.jgit.lfs.test;version="[5.6.2,5.7.0)",
+ org.eclipse.jgit.lib;version="[5.6.2,5.7.0)",
+ org.eclipse.jgit.revwalk;version="[5.6.2,5.7.0)",
+ org.eclipse.jgit.storage.file;version="[5.6.2,5.7.0)",
+ org.eclipse.jgit.transport;version="[5.6.2,5.7.0)",
+ org.eclipse.jgit.treewalk;version="[5.6.2,5.7.0)",
+ org.eclipse.jgit.treewalk.filter;version="[5.6.2,5.7.0)",
+ org.eclipse.jgit.util;version="[5.6.2,5.7.0)",
org.hamcrest.core;version="[1.1.0,2.0.0)",
org.junit;version="[4.12,5.0.0)",
org.junit.rules;version="[4.12,5.0.0)",
diff --git a/org.eclipse.jgit.lfs.server.test/pom.xml b/org.eclipse.jgit.lfs.server.test/pom.xml
index a116a6d..6b0297f 100644
--- a/org.eclipse.jgit.lfs.server.test/pom.xml
+++ b/org.eclipse.jgit.lfs.server.test/pom.xml
@@ -50,7 +50,7 @@
<parent>
<groupId>org.eclipse.jgit</groupId>
<artifactId>org.eclipse.jgit-parent</artifactId>
- <version>5.5.2-SNAPSHOT</version>
+ <version>5.6.2-SNAPSHOT</version>
</parent>
<artifactId>org.eclipse.jgit.lfs.server.test</artifactId>
diff --git a/org.eclipse.jgit.lfs.server/.settings/org.eclipse.jdt.core.prefs b/org.eclipse.jgit.lfs.server/.settings/org.eclipse.jdt.core.prefs
index 525ac67..9fd92b1 100644
--- a/org.eclipse.jgit.lfs.server/.settings/org.eclipse.jdt.core.prefs
+++ b/org.eclipse.jgit.lfs.server/.settings/org.eclipse.jdt.core.prefs
@@ -92,7 +92,7 @@
org.eclipse.jdt.core.compiler.problem.unclosedCloseable=warning
org.eclipse.jdt.core.compiler.problem.undocumentedEmptyBlock=warning
org.eclipse.jdt.core.compiler.problem.unhandledWarningToken=ignore
-org.eclipse.jdt.core.compiler.problem.unnecessaryElse=ignore
+org.eclipse.jdt.core.compiler.problem.unnecessaryElse=warning
org.eclipse.jdt.core.compiler.problem.unnecessaryTypeCheck=error
org.eclipse.jdt.core.compiler.problem.unqualifiedFieldAccess=ignore
org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownException=warning
diff --git a/org.eclipse.jgit.lfs.server/META-INF/MANIFEST.MF b/org.eclipse.jgit.lfs.server/META-INF/MANIFEST.MF
index f519f26..93b5964 100644
--- a/org.eclipse.jgit.lfs.server/META-INF/MANIFEST.MF
+++ b/org.eclipse.jgit.lfs.server/META-INF/MANIFEST.MF
@@ -3,19 +3,19 @@
Bundle-Name: %Bundle-Name
Automatic-Module-Name: org.eclipse.jgit.lfs.server
Bundle-SymbolicName: org.eclipse.jgit.lfs.server
-Bundle-Version: 5.5.2.qualifier
+Bundle-Version: 5.6.2.qualifier
Bundle-Localization: plugin
Bundle-Vendor: %Bundle-Vendor
-Export-Package: org.eclipse.jgit.lfs.server;version="5.5.2";
+Export-Package: org.eclipse.jgit.lfs.server;version="5.6.2";
uses:="javax.servlet.http,
org.eclipse.jgit.lfs.lib",
- org.eclipse.jgit.lfs.server.fs;version="5.5.2";
+ org.eclipse.jgit.lfs.server.fs;version="5.6.2";
uses:="javax.servlet,
javax.servlet.http,
org.eclipse.jgit.lfs.server,
org.eclipse.jgit.lfs.lib",
- org.eclipse.jgit.lfs.server.internal;version="5.5.2";x-internal:=true,
- org.eclipse.jgit.lfs.server.s3;version="5.5.2";
+ org.eclipse.jgit.lfs.server.internal;version="5.6.2";x-internal:=true,
+ org.eclipse.jgit.lfs.server.s3;version="5.6.2";
uses:="org.eclipse.jgit.lfs.server,
org.eclipse.jgit.lfs.lib"
Bundle-RequiredExecutionEnvironment: JavaSE-1.8
@@ -25,15 +25,15 @@
javax.servlet.http;version="[3.1.0,4.0.0)",
org.apache.http;version="[4.3.0,5.0.0)",
org.apache.http.client;version="[4.3.0,5.0.0)",
- org.eclipse.jgit.annotations;version="[5.5.2,5.6.0)",
- org.eclipse.jgit.internal;version="[5.5.2,5.6.0)",
- org.eclipse.jgit.internal.storage.file;version="[5.5.2,5.6.0)",
- org.eclipse.jgit.lfs.errors;version="[5.5.2,5.6.0)",
- org.eclipse.jgit.lfs.internal;version="[5.5.2,5.6.0)",
- org.eclipse.jgit.lfs.lib;version="[5.5.2,5.6.0)",
- org.eclipse.jgit.lib;version="[5.5.2,5.6.0)",
- org.eclipse.jgit.nls;version="[5.5.2,5.6.0)",
- org.eclipse.jgit.transport.http;version="[5.5.2,5.6.0)",
- org.eclipse.jgit.transport.http.apache;version="[5.5.2,5.6.0)",
- org.eclipse.jgit.util;version="[5.5.2,5.6.0)",
+ org.eclipse.jgit.annotations;version="[5.6.2,5.7.0)",
+ org.eclipse.jgit.internal;version="[5.6.2,5.7.0)",
+ org.eclipse.jgit.internal.storage.file;version="[5.6.2,5.7.0)",
+ org.eclipse.jgit.lfs.errors;version="[5.6.2,5.7.0)",
+ org.eclipse.jgit.lfs.internal;version="[5.6.2,5.7.0)",
+ org.eclipse.jgit.lfs.lib;version="[5.6.2,5.7.0)",
+ org.eclipse.jgit.lib;version="[5.6.2,5.7.0)",
+ org.eclipse.jgit.nls;version="[5.6.2,5.7.0)",
+ org.eclipse.jgit.transport.http;version="[5.6.2,5.7.0)",
+ org.eclipse.jgit.transport.http.apache;version="[5.6.2,5.7.0)",
+ org.eclipse.jgit.util;version="[5.6.2,5.7.0)",
org.slf4j;version="[1.7.0,2.0.0)"
diff --git a/org.eclipse.jgit.lfs.server/META-INF/SOURCE-MANIFEST.MF b/org.eclipse.jgit.lfs.server/META-INF/SOURCE-MANIFEST.MF
index 55cdc0b..4624ac7 100644
--- a/org.eclipse.jgit.lfs.server/META-INF/SOURCE-MANIFEST.MF
+++ b/org.eclipse.jgit.lfs.server/META-INF/SOURCE-MANIFEST.MF
@@ -3,5 +3,5 @@
Bundle-Name: org.eclipse.jgit.lfs.server - Sources
Bundle-SymbolicName: org.eclipse.jgit.lfs.server.source
Bundle-Vendor: Eclipse.org - JGit
-Bundle-Version: 5.5.2.qualifier
-Eclipse-SourceBundle: org.eclipse.jgit.lfs.server;version="5.5.2.qualifier";roots="."
+Bundle-Version: 5.6.2.qualifier
+Eclipse-SourceBundle: org.eclipse.jgit.lfs.server;version="5.6.2.qualifier";roots="."
diff --git a/org.eclipse.jgit.lfs.server/pom.xml b/org.eclipse.jgit.lfs.server/pom.xml
index 01a0b8d..7aaf9ff 100644
--- a/org.eclipse.jgit.lfs.server/pom.xml
+++ b/org.eclipse.jgit.lfs.server/pom.xml
@@ -50,7 +50,7 @@
<parent>
<groupId>org.eclipse.jgit</groupId>
<artifactId>org.eclipse.jgit-parent</artifactId>
- <version>5.5.2-SNAPSHOT</version>
+ <version>5.6.2-SNAPSHOT</version>
</parent>
<artifactId>org.eclipse.jgit.lfs.server</artifactId>
diff --git a/org.eclipse.jgit.lfs.server/src/org/eclipse/jgit/lfs/server/LfsProtocolServlet.java b/org.eclipse.jgit.lfs.server/src/org/eclipse/jgit/lfs/server/LfsProtocolServlet.java
index c7f55dd..e29783e 100644
--- a/org.eclipse.jgit.lfs.server/src/org/eclipse/jgit/lfs/server/LfsProtocolServlet.java
+++ b/org.eclipse.jgit.lfs.server/src/org/eclipse/jgit/lfs/server/LfsProtocolServlet.java
@@ -93,7 +93,7 @@
* @since 4.3
*/
public abstract class LfsProtocolServlet extends HttpServlet {
- private static Logger LOG = LoggerFactory
+ private static final Logger LOG = LoggerFactory
.getLogger(LfsProtocolServlet.class);
private static final long serialVersionUID = 1L;
diff --git a/org.eclipse.jgit.lfs.server/src/org/eclipse/jgit/lfs/server/fs/FileLfsRepository.java b/org.eclipse.jgit.lfs.server/src/org/eclipse/jgit/lfs/server/fs/FileLfsRepository.java
index 0a7c37c..ad9ef78 100644
--- a/org.eclipse.jgit.lfs.server/src/org/eclipse/jgit/lfs/server/fs/FileLfsRepository.java
+++ b/org.eclipse.jgit.lfs.server/src/org/eclipse/jgit/lfs/server/fs/FileLfsRepository.java
@@ -110,9 +110,8 @@ public long getSize(AnyLongObjectId id) throws IOException {
Path p = getPath(id);
if (Files.exists(p)) {
return Files.size(p);
- } else {
- return -1;
}
+ return -1;
}
/**
diff --git a/org.eclipse.jgit.lfs.server/src/org/eclipse/jgit/lfs/server/fs/ObjectDownloadListener.java b/org.eclipse.jgit.lfs.server/src/org/eclipse/jgit/lfs/server/fs/ObjectDownloadListener.java
index 06a7726..e65e603 100644
--- a/org.eclipse.jgit.lfs.server/src/org/eclipse/jgit/lfs/server/fs/ObjectDownloadListener.java
+++ b/org.eclipse.jgit.lfs.server/src/org/eclipse/jgit/lfs/server/fs/ObjectDownloadListener.java
@@ -67,7 +67,7 @@
*/
public class ObjectDownloadListener implements WriteListener {
- private static Logger LOG = Logger
+ private static final Logger LOG = Logger
.getLogger(ObjectDownloadListener.class.getName());
private final AsyncContext context;
diff --git a/org.eclipse.jgit.lfs.server/src/org/eclipse/jgit/lfs/server/fs/ObjectUploadListener.java b/org.eclipse.jgit.lfs.server/src/org/eclipse/jgit/lfs/server/fs/ObjectUploadListener.java
index 3bb2899..332e39f 100644
--- a/org.eclipse.jgit.lfs.server/src/org/eclipse/jgit/lfs/server/fs/ObjectUploadListener.java
+++ b/org.eclipse.jgit.lfs.server/src/org/eclipse/jgit/lfs/server/fs/ObjectUploadListener.java
@@ -71,7 +71,7 @@
*/
public class ObjectUploadListener implements ReadListener {
- private static Logger LOG = Logger
+ private static final Logger LOG = Logger
.getLogger(ObjectUploadListener.class.getName());
private final AsyncContext context;
diff --git a/org.eclipse.jgit.lfs.server/src/org/eclipse/jgit/lfs/server/s3/SignerV4.java b/org.eclipse.jgit.lfs.server/src/org/eclipse/jgit/lfs/server/s3/SignerV4.java
index 7b76cec..4bcca4a 100644
--- a/org.eclipse.jgit.lfs.server/src/org/eclipse/jgit/lfs/server/s3/SignerV4.java
+++ b/org.eclipse.jgit.lfs.server/src/org/eclipse/jgit/lfs/server/s3/SignerV4.java
@@ -352,9 +352,8 @@ private static String canonicalizeResourcePath(URL endpoint) {
String encodedPath = urlEncode(path, true);
if (encodedPath.startsWith("/")) { //$NON-NLS-1$
return encodedPath;
- } else {
- return "/" + encodedPath; //$NON-NLS-1$
}
+ return "/" + encodedPath; //$NON-NLS-1$
}
private static byte[] hash(String s) {
diff --git a/org.eclipse.jgit.lfs.test/.settings/org.eclipse.jdt.core.prefs b/org.eclipse.jgit.lfs.test/.settings/org.eclipse.jdt.core.prefs
index d4751b5..4c4634a 100644
--- a/org.eclipse.jgit.lfs.test/.settings/org.eclipse.jdt.core.prefs
+++ b/org.eclipse.jgit.lfs.test/.settings/org.eclipse.jdt.core.prefs
@@ -92,7 +92,7 @@
org.eclipse.jdt.core.compiler.problem.unclosedCloseable=warning
org.eclipse.jdt.core.compiler.problem.undocumentedEmptyBlock=warning
org.eclipse.jdt.core.compiler.problem.unhandledWarningToken=ignore
-org.eclipse.jdt.core.compiler.problem.unnecessaryElse=ignore
+org.eclipse.jdt.core.compiler.problem.unnecessaryElse=warning
org.eclipse.jdt.core.compiler.problem.unnecessaryTypeCheck=error
org.eclipse.jdt.core.compiler.problem.unqualifiedFieldAccess=ignore
org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownException=error
diff --git a/org.eclipse.jgit.lfs.test/META-INF/MANIFEST.MF b/org.eclipse.jgit.lfs.test/META-INF/MANIFEST.MF
index cf10aa6..d2b9ad7 100644
--- a/org.eclipse.jgit.lfs.test/META-INF/MANIFEST.MF
+++ b/org.eclipse.jgit.lfs.test/META-INF/MANIFEST.MF
@@ -3,22 +3,22 @@
Bundle-Name: %Bundle-Name
Automatic-Module-Name: org.eclipse.jgit.lfs.test
Bundle-SymbolicName: org.eclipse.jgit.lfs.test
-Bundle-Version: 5.5.2.qualifier
+Bundle-Version: 5.6.2.qualifier
Bundle-Vendor: %Bundle-Vendor
Bundle-Localization: plugin
Bundle-RequiredExecutionEnvironment: JavaSE-1.8
-Import-Package: org.eclipse.jgit.internal.storage.dfs;version="[5.5.2,5.6.0)",
- org.eclipse.jgit.junit;version="[5.5.2,5.6.0)",
- org.eclipse.jgit.lfs;version="[5.5.2,5.6.0)",
- org.eclipse.jgit.lfs.errors;version="[5.5.2,5.6.0)",
- org.eclipse.jgit.lfs.lib;version="[5.5.2,5.6.0)",
- org.eclipse.jgit.lib;version="[5.5.2,5.6.0)",
- org.eclipse.jgit.revwalk;version="[5.5.2,5.6.0)",
- org.eclipse.jgit.treewalk;version="[5.5.2,5.6.0)",
- org.eclipse.jgit.treewalk.filter;version="[5.5.2,5.6.0)",
- org.eclipse.jgit.util;version="[5.5.2,5.6.0)",
+Import-Package: org.eclipse.jgit.internal.storage.dfs;version="[5.6.2,5.7.0)",
+ org.eclipse.jgit.junit;version="[5.6.2,5.7.0)",
+ org.eclipse.jgit.lfs;version="[5.6.2,5.7.0)",
+ org.eclipse.jgit.lfs.errors;version="[5.6.2,5.7.0)",
+ org.eclipse.jgit.lfs.lib;version="[5.6.2,5.7.0)",
+ org.eclipse.jgit.lib;version="[5.6.2,5.7.0)",
+ org.eclipse.jgit.revwalk;version="[5.6.2,5.7.0)",
+ org.eclipse.jgit.treewalk;version="[5.6.2,5.7.0)",
+ org.eclipse.jgit.treewalk.filter;version="[5.6.2,5.7.0)",
+ org.eclipse.jgit.util;version="[5.6.2,5.7.0)",
org.hamcrest.core;version="[1.1.0,2.0.0)",
org.junit;version="[4.12,5.0.0)",
org.junit.runner;version="[4.12,5.0.0)",
org.junit.runners;version="[4.12,5.0.0)"
-Export-Package: org.eclipse.jgit.lfs.test;version="5.5.2";x-friends:="org.eclipse.jgit.lfs.server.test"
+Export-Package: org.eclipse.jgit.lfs.test;version="5.6.2";x-friends:="org.eclipse.jgit.lfs.server.test"
diff --git a/org.eclipse.jgit.lfs.test/pom.xml b/org.eclipse.jgit.lfs.test/pom.xml
index 8166a07..2c75ad0 100644
--- a/org.eclipse.jgit.lfs.test/pom.xml
+++ b/org.eclipse.jgit.lfs.test/pom.xml
@@ -50,7 +50,7 @@
<parent>
<groupId>org.eclipse.jgit</groupId>
<artifactId>org.eclipse.jgit-parent</artifactId>
- <version>5.5.2-SNAPSHOT</version>
+ <version>5.6.2-SNAPSHOT</version>
</parent>
<artifactId>org.eclipse.jgit.lfs.test</artifactId>
diff --git a/org.eclipse.jgit.lfs/.settings/.api_filters b/org.eclipse.jgit.lfs/.settings/.api_filters
deleted file mode 100644
index 9747df8..0000000
--- a/org.eclipse.jgit.lfs/.settings/.api_filters
+++ /dev/null
@@ -1,12 +0,0 @@
-<?xml version="1.0" encoding="UTF-8" standalone="no"?>
-<component id="org.eclipse.jgit.lfs" version="2">
- <resource path="src/org/eclipse/jgit/lfs/lib/AnyLongObjectId.java" type="org.eclipse.jgit.lfs.lib.AnyLongObjectId">
- <filter id="1141899266">
- <message_arguments>
- <message_argument value="5.4"/>
- <message_argument value="5.5"/>
- <message_argument value="isEqual(AnyLongObjectId, AnyLongObjectId)"/>
- </message_arguments>
- </filter>
- </resource>
-</component>
diff --git a/org.eclipse.jgit.lfs/.settings/org.eclipse.jdt.core.prefs b/org.eclipse.jgit.lfs/.settings/org.eclipse.jdt.core.prefs
index 525ac67..9fd92b1 100644
--- a/org.eclipse.jgit.lfs/.settings/org.eclipse.jdt.core.prefs
+++ b/org.eclipse.jgit.lfs/.settings/org.eclipse.jdt.core.prefs
@@ -92,7 +92,7 @@
org.eclipse.jdt.core.compiler.problem.unclosedCloseable=warning
org.eclipse.jdt.core.compiler.problem.undocumentedEmptyBlock=warning
org.eclipse.jdt.core.compiler.problem.unhandledWarningToken=ignore
-org.eclipse.jdt.core.compiler.problem.unnecessaryElse=ignore
+org.eclipse.jdt.core.compiler.problem.unnecessaryElse=warning
org.eclipse.jdt.core.compiler.problem.unnecessaryTypeCheck=error
org.eclipse.jdt.core.compiler.problem.unqualifiedFieldAccess=ignore
org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownException=warning
diff --git a/org.eclipse.jgit.lfs/META-INF/MANIFEST.MF b/org.eclipse.jgit.lfs/META-INF/MANIFEST.MF
index da1fbd7..8b7371f 100644
--- a/org.eclipse.jgit.lfs/META-INF/MANIFEST.MF
+++ b/org.eclipse.jgit.lfs/META-INF/MANIFEST.MF
@@ -3,33 +3,33 @@
Bundle-Name: %Bundle-Name
Automatic-Module-Name: org.eclipse.jgit.lfs
Bundle-SymbolicName: org.eclipse.jgit.lfs
-Bundle-Version: 5.5.2.qualifier
+Bundle-Version: 5.6.2.qualifier
Bundle-Localization: plugin
Bundle-Vendor: %Bundle-Vendor
-Export-Package: org.eclipse.jgit.lfs;version="5.5.2",
- org.eclipse.jgit.lfs.errors;version="5.5.2",
- org.eclipse.jgit.lfs.internal;version="5.5.2";x-friends:="org.eclipse.jgit.lfs.test,org.eclipse.jgit.lfs.server.fs,org.eclipse.jgit.lfs.server",
- org.eclipse.jgit.lfs.lib;version="5.5.2"
+Export-Package: org.eclipse.jgit.lfs;version="5.6.2",
+ org.eclipse.jgit.lfs.errors;version="5.6.2",
+ org.eclipse.jgit.lfs.internal;version="5.6.2";x-friends:="org.eclipse.jgit.lfs.test,org.eclipse.jgit.lfs.server.fs,org.eclipse.jgit.lfs.server",
+ org.eclipse.jgit.lfs.lib;version="5.6.2"
Bundle-RequiredExecutionEnvironment: JavaSE-1.8
Import-Package: com.google.gson;version="[2.8.2,3.0.0)",
com.google.gson.stream;version="[2.8.2,3.0.0)",
org.apache.http.impl.client;version="[4.2.6,5.0.0)",
org.apache.http.impl.conn;version="[4.2.6,5.0.0)",
- org.eclipse.jgit.annotations;version="[5.5.2,5.6.0)";resolution:=optional,
- org.eclipse.jgit.api.errors;version="[5.5.2,5.6.0)",
- org.eclipse.jgit.attributes;version="[5.5.2,5.6.0)",
- org.eclipse.jgit.diff;version="[5.5.2,5.6.0)",
- org.eclipse.jgit.errors;version="[5.5.2,5.6.0)",
- org.eclipse.jgit.hooks;version="[5.5.2,5.6.0)",
- org.eclipse.jgit.internal.storage.file;version="[5.5.2,5.6.0)",
- org.eclipse.jgit.lib;version="[5.5.2,5.6.0)",
- org.eclipse.jgit.nls;version="[5.5.2,5.6.0)",
- org.eclipse.jgit.revwalk;version="[5.5.2,5.6.0)",
- org.eclipse.jgit.storage.file;version="[5.5.2,5.6.0)",
- org.eclipse.jgit.storage.pack;version="[5.5.2,5.6.0)",
- org.eclipse.jgit.transport;version="[5.5.2,5.6.0)",
- org.eclipse.jgit.transport.http;version="[5.5.2,5.6.0)",
- org.eclipse.jgit.treewalk;version="[5.5.2,5.6.0)",
- org.eclipse.jgit.treewalk.filter;version="[5.5.2,5.6.0)",
- org.eclipse.jgit.util;version="[5.5.2,5.6.0)",
- org.eclipse.jgit.util.io;version="[5.5.2,5.6.0)"
+ org.eclipse.jgit.annotations;version="[5.6.2,5.7.0)";resolution:=optional,
+ org.eclipse.jgit.api.errors;version="[5.6.2,5.7.0)",
+ org.eclipse.jgit.attributes;version="[5.6.2,5.7.0)",
+ org.eclipse.jgit.diff;version="[5.6.2,5.7.0)",
+ org.eclipse.jgit.errors;version="[5.6.2,5.7.0)",
+ org.eclipse.jgit.hooks;version="[5.6.2,5.7.0)",
+ org.eclipse.jgit.internal.storage.file;version="[5.6.2,5.7.0)",
+ org.eclipse.jgit.lib;version="[5.6.2,5.7.0)",
+ org.eclipse.jgit.nls;version="[5.6.2,5.7.0)",
+ org.eclipse.jgit.revwalk;version="[5.6.2,5.7.0)",
+ org.eclipse.jgit.storage.file;version="[5.6.2,5.7.0)",
+ org.eclipse.jgit.storage.pack;version="[5.6.2,5.7.0)",
+ org.eclipse.jgit.transport;version="[5.6.2,5.7.0)",
+ org.eclipse.jgit.transport.http;version="[5.6.2,5.7.0)",
+ org.eclipse.jgit.treewalk;version="[5.6.2,5.7.0)",
+ org.eclipse.jgit.treewalk.filter;version="[5.6.2,5.7.0)",
+ org.eclipse.jgit.util;version="[5.6.2,5.7.0)",
+ org.eclipse.jgit.util.io;version="[5.6.2,5.7.0)"
diff --git a/org.eclipse.jgit.lfs/META-INF/SOURCE-MANIFEST.MF b/org.eclipse.jgit.lfs/META-INF/SOURCE-MANIFEST.MF
index 562747d..e2ff973 100644
--- a/org.eclipse.jgit.lfs/META-INF/SOURCE-MANIFEST.MF
+++ b/org.eclipse.jgit.lfs/META-INF/SOURCE-MANIFEST.MF
@@ -3,5 +3,5 @@
Bundle-Name: org.eclipse.jgit.lfs - Sources
Bundle-SymbolicName: org.eclipse.jgit.lfs.source
Bundle-Vendor: Eclipse.org - JGit
-Bundle-Version: 5.5.2.qualifier
-Eclipse-SourceBundle: org.eclipse.jgit.lfs;version="5.5.2.qualifier";roots="."
+Bundle-Version: 5.6.2.qualifier
+Eclipse-SourceBundle: org.eclipse.jgit.lfs;version="5.6.2.qualifier";roots="."
diff --git a/org.eclipse.jgit.lfs/pom.xml b/org.eclipse.jgit.lfs/pom.xml
index 1f2afd9..7c0d30a 100644
--- a/org.eclipse.jgit.lfs/pom.xml
+++ b/org.eclipse.jgit.lfs/pom.xml
@@ -50,7 +50,7 @@
<parent>
<groupId>org.eclipse.jgit</groupId>
<artifactId>org.eclipse.jgit-parent</artifactId>
- <version>5.5.2-SNAPSHOT</version>
+ <version>5.6.2-SNAPSHOT</version>
</parent>
<artifactId>org.eclipse.jgit.lfs</artifactId>
diff --git a/org.eclipse.jgit.lfs/src/org/eclipse/jgit/lfs/BuiltinLFS.java b/org.eclipse.jgit.lfs/src/org/eclipse/jgit/lfs/BuiltinLFS.java
index 56e3a12..e90d929 100644
--- a/org.eclipse.jgit.lfs/src/org/eclipse/jgit/lfs/BuiltinLFS.java
+++ b/org.eclipse.jgit.lfs/src/org/eclipse/jgit/lfs/BuiltinLFS.java
@@ -83,9 +83,8 @@ public ObjectLoader applySmudgeFilter(Repository db, ObjectLoader loader,
Attribute attribute) throws IOException {
if (isEnabled(db) && (attribute == null || isEnabled(db, attribute))) {
return LfsBlobFilter.smudgeLfsBlob(db, loader);
- } else {
- return loader;
}
+ return loader;
}
@Override
@@ -93,9 +92,8 @@ public LfsInputStream applyCleanFilter(Repository db, InputStream input,
long length, Attribute attribute) throws IOException {
if (isEnabled(db, attribute)) {
return new LfsInputStream(LfsBlobFilter.cleanLfsBlob(db, input));
- } else {
- return new LfsInputStream(input, length);
}
+ return new LfsInputStream(input, length);
}
@Override
@@ -108,6 +106,16 @@ public PrePushHook getPrePushHook(Repository repo,
return null;
}
+ @Override
+ @Nullable
+ public PrePushHook getPrePushHook(Repository repo, PrintStream outputStream,
+ PrintStream errorStream) {
+ if (isEnabled(repo)) {
+ return new LfsPrePushHook(repo, outputStream, errorStream);
+ }
+ return null;
+ }
+
/**
* @param db
* the repository
diff --git a/org.eclipse.jgit.lfs/src/org/eclipse/jgit/lfs/CleanFilter.java b/org.eclipse.jgit.lfs/src/org/eclipse/jgit/lfs/CleanFilter.java
index 80da802..27be4f6 100644
--- a/org.eclipse.jgit.lfs/src/org/eclipse/jgit/lfs/CleanFilter.java
+++ b/org.eclipse.jgit.lfs/src/org/eclipse/jgit/lfs/CleanFilter.java
@@ -78,7 +78,7 @@ public class CleanFilter extends FilterCommand {
* The factory is responsible for creating instances of
* {@link org.eclipse.jgit.lfs.CleanFilter}
*/
- public final static FilterCommandFactory FACTORY = CleanFilter::new;
+ public static final FilterCommandFactory FACTORY = CleanFilter::new;
/**
* Registers this filter by calling
@@ -138,32 +138,30 @@ public int run() throws IOException {
aOut.write(buf, 0, length);
size += length;
return length;
- } else {
- aOut.close();
- AnyLongObjectId loid = aOut.getId();
- aOut = null;
- Path mediaFile = lfsUtil.getMediaFile(loid);
- if (Files.isRegularFile(mediaFile)) {
- long fsSize = Files.size(mediaFile);
- if (fsSize != size) {
- throw new CorruptMediaFile(mediaFile, size, fsSize);
- } else {
- FileUtils.delete(tmpFile.toFile());
- }
- } else {
- Path parent = mediaFile.getParent();
- if (parent != null) {
- FileUtils.mkdirs(parent.toFile(), true);
- }
- FileUtils.rename(tmpFile.toFile(), mediaFile.toFile(),
- StandardCopyOption.ATOMIC_MOVE);
- }
- LfsPointer lfsPointer = new LfsPointer(loid, size);
- lfsPointer.encode(out);
- in.close();
- out.close();
- return -1;
}
+ aOut.close();
+ AnyLongObjectId loid = aOut.getId();
+ aOut = null;
+ Path mediaFile = lfsUtil.getMediaFile(loid);
+ if (Files.isRegularFile(mediaFile)) {
+ long fsSize = Files.size(mediaFile);
+ if (fsSize != size) {
+ throw new CorruptMediaFile(mediaFile, size, fsSize);
+ }
+ FileUtils.delete(tmpFile.toFile());
+ } else {
+ Path parent = mediaFile.getParent();
+ if (parent != null) {
+ FileUtils.mkdirs(parent.toFile(), true);
+ }
+ FileUtils.rename(tmpFile.toFile(), mediaFile.toFile(),
+ StandardCopyOption.ATOMIC_MOVE);
+ }
+ LfsPointer lfsPointer = new LfsPointer(loid, size);
+ lfsPointer.encode(out);
+ in.close();
+ out.close();
+ return -1;
} catch (IOException e) {
if (aOut != null) {
aOut.abort();
diff --git a/org.eclipse.jgit.lfs/src/org/eclipse/jgit/lfs/LfsPrePushHook.java b/org.eclipse.jgit.lfs/src/org/eclipse/jgit/lfs/LfsPrePushHook.java
index 3e6a261..b3e304f 100644
--- a/org.eclipse.jgit.lfs/src/org/eclipse/jgit/lfs/LfsPrePushHook.java
+++ b/org.eclipse.jgit.lfs/src/org/eclipse/jgit/lfs/LfsPrePushHook.java
@@ -107,6 +107,20 @@ public LfsPrePushHook(Repository repo, PrintStream outputStream) {
super(repo, outputStream);
}
+ /**
+ * @param repo
+ * the repository
+ * @param outputStream
+ * not used by this implementation
+ * @param errorStream
+ * not used by this implementation
+ * @since 5.6
+ */
+ public LfsPrePushHook(Repository repo, PrintStream outputStream,
+ PrintStream errorStream) {
+ super(repo, outputStream, errorStream);
+ }
+
@Override
public void setRefs(Collection<RemoteRefUpdate> toRefs) {
this.refs = toRefs;
diff --git a/org.eclipse.jgit.lfs/src/org/eclipse/jgit/lfs/SmudgeFilter.java b/org.eclipse.jgit.lfs/src/org/eclipse/jgit/lfs/SmudgeFilter.java
index 6b30da3..3551ee1 100644
--- a/org.eclipse.jgit.lfs/src/org/eclipse/jgit/lfs/SmudgeFilter.java
+++ b/org.eclipse.jgit.lfs/src/org/eclipse/jgit/lfs/SmudgeFilter.java
@@ -92,7 +92,7 @@ public class SmudgeFilter extends FilterCommand {
* The factory is responsible for creating instances of
* {@link org.eclipse.jgit.lfs.SmudgeFilter}
*/
- public final static FilterCommandFactory FACTORY = SmudgeFilter::new;
+ public static final FilterCommandFactory FACTORY = SmudgeFilter::new;
/**
* Register this filter in JGit
diff --git a/org.eclipse.jgit.lfs/src/org/eclipse/jgit/lfs/internal/LfsConnectionFactory.java b/org.eclipse.jgit.lfs/src/org/eclipse/jgit/lfs/internal/LfsConnectionFactory.java
index feb8b4a..184658d 100644
--- a/org.eclipse.jgit.lfs/src/org/eclipse/jgit/lfs/internal/LfsConnectionFactory.java
+++ b/org.eclipse.jgit.lfs/src/org/eclipse/jgit/lfs/internal/LfsConnectionFactory.java
@@ -179,9 +179,8 @@ private static String discoverLfsUrl(Repository db, String purpose,
remoteUrl, u);
additionalHeaders.putAll(action.header);
return action.href;
- } else {
- return remoteUrl + Protocol.INFO_LFS_ENDPOINT;
}
+ return remoteUrl + Protocol.INFO_LFS_ENDPOINT;
}
private static Protocol.ExpiringAction getSshAuthentication(
@@ -262,9 +261,8 @@ private static String extractProjectName(URIish u) {
if (path.endsWith(org.eclipse.jgit.lib.Constants.DOT_GIT)) {
return path.substring(0, path.length() - 4);
- } else {
- return path;
}
+ return path;
}
/**
diff --git a/org.eclipse.jgit.lfs/src/org/eclipse/jgit/lfs/lib/AnyLongObjectId.java b/org.eclipse.jgit.lfs/src/org/eclipse/jgit/lfs/lib/AnyLongObjectId.java
index b095d20..a9bd27f 100644
--- a/org.eclipse.jgit.lfs/src/org/eclipse/jgit/lfs/lib/AnyLongObjectId.java
+++ b/org.eclipse.jgit.lfs/src/org/eclipse/jgit/lfs/lib/AnyLongObjectId.java
@@ -303,10 +303,10 @@ public final boolean equals(AnyLongObjectId other) {
/** {@inheritDoc} */
@Override
public final boolean equals(Object o) {
- if (o instanceof AnyLongObjectId)
+ if (o instanceof AnyLongObjectId) {
return equals((AnyLongObjectId) o);
- else
- return false;
+ }
+ return false;
}
/**
diff --git a/org.eclipse.jgit.packaging/org.eclipse.jgit.feature/feature.properties b/org.eclipse.jgit.packaging/org.eclipse.jgit.feature/feature.properties
index 169ef7e..d47cc01 100644
--- a/org.eclipse.jgit.packaging/org.eclipse.jgit.feature/feature.properties
+++ b/org.eclipse.jgit.packaging/org.eclipse.jgit.feature/feature.properties
@@ -30,7 +30,6 @@
# "licenseURL" property - URL of the "Feature License"
# do not translate value - just change to point to a locale-specific HTML page
licenseURL=license.html
-
# "license" property - text of the "Feature Update License"
# should be plain text version of license agreement pointed to be "licenseURL"
license=\
@@ -69,7 +68,7 @@
include plug-ins ("Plug-ins"), plug-in fragments ("Fragments"), and\n\
features ("Features").\n\
- Each Plug-in or Fragment may be packaged as a sub-directory or JAR\n\
- (Java™ ARchive) in a directory named "plugins".\n\
+ (Java\u2122 ARchive) in a directory named "plugins".\n\
- A Feature is a bundle of one or more Plug-ins and/or Fragments and\n\
associated material. Each Feature may be packaged as a sub-directory in a\n\
directory named "features". Within a Feature, files named "feature.xml" may\n\
diff --git a/org.eclipse.jgit.packaging/org.eclipse.jgit.feature/feature.xml b/org.eclipse.jgit.packaging/org.eclipse.jgit.feature/feature.xml
index 2a1a0b6..b17ec85 100644
--- a/org.eclipse.jgit.packaging/org.eclipse.jgit.feature/feature.xml
+++ b/org.eclipse.jgit.packaging/org.eclipse.jgit.feature/feature.xml
@@ -2,7 +2,7 @@
<feature
id="org.eclipse.jgit"
label="%featureName"
- version="5.5.2.qualifier"
+ version="5.6.2.qualifier"
provider-name="%providerName">
<description url="http://www.eclipse.org/jgit/">
diff --git a/org.eclipse.jgit.packaging/org.eclipse.jgit.feature/license.html b/org.eclipse.jgit.packaging/org.eclipse.jgit.feature/license.html
index 008b801..004b6de 100644
--- a/org.eclipse.jgit.packaging/org.eclipse.jgit.feature/license.html
+++ b/org.eclipse.jgit.packaging/org.eclipse.jgit.feature/license.html
@@ -5,13 +5,10 @@
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1" />
<title>Eclipse Foundation Software User Agreement</title>
</head>
-
<body lang="EN-US">
<h2>Eclipse Foundation Software User Agreement</h2>
<p>November 22, 2017</p>
-
<h3>Usage Of Content</h3>
-
<p>THE ECLIPSE FOUNDATION MAKES AVAILABLE SOFTWARE, DOCUMENTATION,
INFORMATION AND/OR OTHER MATERIALS FOR OPEN SOURCE PROJECTS
(COLLECTIVELY "CONTENT"). USE OF THE CONTENT IS GOVERNED BY
@@ -24,9 +21,7 @@
AGREEMENT AND THE TERMS AND CONDITIONS OF ANY APPLICABLE LICENSE
AGREEMENTS OR NOTICES INDICATED OR REFERENCED BELOW, THEN YOU MAY NOT
USE THE CONTENT.</p>
-
<h3>Applicable Licenses</h3>
-
<p>
Unless otherwise indicated, all Content made available by the Eclipse
Foundation is provided to you under the terms and conditions of the
@@ -35,13 +30,11 @@
href="http://www.eclipse.org/legal/epl-2.0">http://www.eclipse.org/legal/epl-2.0</a>.
For purposes of the EPL, "Program" will mean the Content.
</p>
-
<p>Content includes, but is not limited to, source code, object
code, documentation and other files maintained in the Eclipse
Foundation source code repository ("Repository") in software
modules ("Modules") and made available as downloadable
archives ("Downloads").</p>
-
<ul>
<li>Content may be structured and packaged into modules to
facilitate delivering, extending, and upgrading the Content. Typical
@@ -62,7 +55,6 @@
"feature.xml" may contain a list of the names and version
numbers of Included Features.</li>
</ul>
-
<p>The terms and conditions governing Plug-ins and Fragments should
be contained in files named "about.html"
("Abouts"). The terms and conditions governing Features and
@@ -70,7 +62,6 @@
"license.html" ("Feature Licenses"). Abouts and
Feature Licenses may be located in any directory of a Download or
Module including, but not limited to the following locations:</p>
-
<ul>
<li>The top-level (root) directory</li>
<li>Plug-in and Fragment directories</li>
@@ -79,7 +70,6 @@
certain Plug-ins</li>
<li>Feature directories</li>
</ul>
-
<p>Note: if a Feature made available by the Eclipse Foundation is
installed using the Provisioning Technology (as defined below), you
must agree to a license ("Feature Update License") during
@@ -92,12 +82,10 @@
Feature Licenses, and Feature Update Licenses contain the terms and
conditions (or references to such terms and conditions) that govern
your use of the associated Content in that directory.</p>
-
<p>THE ABOUTS, FEATURE LICENSES, AND FEATURE UPDATE LICENSES MAY
REFER TO THE EPL OR OTHER LICENSE AGREEMENTS, NOTICES OR TERMS AND
CONDITIONS. SOME OF THESE OTHER LICENSE AGREEMENTS MAY INCLUDE (BUT
ARE NOT LIMITED TO):</p>
-
<ul>
<li>Eclipse Public License Version 1.0 (available at <a
href="http://www.eclipse.org/legal/epl-v10.html">http://www.eclipse.org/legal/epl-v10.html</a>)
@@ -118,16 +106,12 @@
href="http://www.mozilla.org/MPL/MPL-1.1.html">http://www.mozilla.org/MPL/MPL-1.1.html</a>)
</li>
</ul>
-
<p>IT IS YOUR OBLIGATION TO READ AND ACCEPT ALL SUCH TERMS AND
CONDITIONS PRIOR TO USE OF THE CONTENT. If no About, Feature License,
or Feature Update License is provided, please contact the Eclipse
Foundation to determine what terms and conditions govern that
particular Content.</p>
-
-
<h3>Use of Provisioning Technology</h3>
-
<p>
The Eclipse Foundation makes available provisioning software, examples
of which include, but are not limited to, p2 and the Eclipse Update
@@ -140,7 +124,6 @@
href="http://eclipse.org/equinox/p2/repository_packaging.html">http://eclipse.org/equinox/p2/repository_packaging.html</a>
("Specification").
</p>
-
<p>You may use Provisioning Technology to allow other parties to
install Installable Software. You shall be responsible for enabling
the applicable license agreements relating to the Installable Software
@@ -149,7 +132,6 @@
Technology in such a manner and making it available in accordance with
the Specification, you further acknowledge your agreement to, and the
acquisition of all necessary rights to permit the following:</p>
-
<ol>
<li>A series of actions may occur ("Provisioning
Process") in which a user may execute the Provisioning
@@ -171,19 +153,16 @@
provisioning Technology will complete installation of the Installable
Software.</li>
</ol>
-
<h3>Cryptography</h3>
-
<p>Content may contain encryption software. The country in which
you are currently may have restrictions on the import, possession, and
use, and/or re-export to another country, of encryption software.
BEFORE using any encryption software, please check the country's laws,
regulations and policies concerning the import, possession, or use,
and re-export of encryption software, to see if this is permitted.</p>
-
<p>
<small>Java and all Java-based trademarks are trademarks of
Oracle Corporation in the United States, other countries, or both.</small>
</p>
</body>
-</html>
+</html>
\ No newline at end of file
diff --git a/org.eclipse.jgit.packaging/org.eclipse.jgit.feature/pom.xml b/org.eclipse.jgit.packaging/org.eclipse.jgit.feature/pom.xml
index 9f2a30d..b3ae941 100644
--- a/org.eclipse.jgit.packaging/org.eclipse.jgit.feature/pom.xml
+++ b/org.eclipse.jgit.packaging/org.eclipse.jgit.feature/pom.xml
@@ -50,7 +50,7 @@
<parent>
<groupId>org.eclipse.jgit</groupId>
<artifactId>jgit.tycho.parent</artifactId>
- <version>5.5.2-SNAPSHOT</version>
+ <version>5.6.2-SNAPSHOT</version>
</parent>
<groupId>org.eclipse.jgit.feature</groupId>
diff --git a/org.eclipse.jgit.packaging/org.eclipse.jgit.http.apache.feature/feature.properties b/org.eclipse.jgit.packaging/org.eclipse.jgit.http.apache.feature/feature.properties
index 480e9c3..b2fd6ed 100644
--- a/org.eclipse.jgit.packaging/org.eclipse.jgit.http.apache.feature/feature.properties
+++ b/org.eclipse.jgit.packaging/org.eclipse.jgit.http.apache.feature/feature.properties
@@ -30,7 +30,6 @@
# "licenseURL" property - URL of the "Feature License"
# do not translate value - just change to point to a locale-specific HTML page
licenseURL=license.html
-
# "license" property - text of the "Feature Update License"
# should be plain text version of license agreement pointed to be "licenseURL"
license=\
@@ -69,7 +68,7 @@
include plug-ins ("Plug-ins"), plug-in fragments ("Fragments"), and\n\
features ("Features").\n\
- Each Plug-in or Fragment may be packaged as a sub-directory or JAR\n\
- (Java™ ARchive) in a directory named "plugins".\n\
+ (Java\u2122 ARchive) in a directory named "plugins".\n\
- A Feature is a bundle of one or more Plug-ins and/or Fragments and\n\
associated material. Each Feature may be packaged as a sub-directory in a\n\
directory named "features". Within a Feature, files named "feature.xml" may\n\
diff --git a/org.eclipse.jgit.packaging/org.eclipse.jgit.http.apache.feature/feature.xml b/org.eclipse.jgit.packaging/org.eclipse.jgit.http.apache.feature/feature.xml
index 4096f8d..7384143 100644
--- a/org.eclipse.jgit.packaging/org.eclipse.jgit.http.apache.feature/feature.xml
+++ b/org.eclipse.jgit.packaging/org.eclipse.jgit.http.apache.feature/feature.xml
@@ -2,7 +2,7 @@
<feature
id="org.eclipse.jgit.http.apache"
label="%featureName"
- version="5.5.2.qualifier"
+ version="5.6.2.qualifier"
provider-name="%providerName">
<description url="http://www.eclipse.org/jgit/">
@@ -23,7 +23,7 @@
</url>
<requires>
- <import plugin="org.eclipse.jgit" version="5.5.2" match="equivalent"/>
+ <import plugin="org.eclipse.jgit" version="5.6.2" match="equivalent"/>
</requires>
<plugin
diff --git a/org.eclipse.jgit.packaging/org.eclipse.jgit.http.apache.feature/license.html b/org.eclipse.jgit.packaging/org.eclipse.jgit.http.apache.feature/license.html
index 008b801..004b6de 100644
--- a/org.eclipse.jgit.packaging/org.eclipse.jgit.http.apache.feature/license.html
+++ b/org.eclipse.jgit.packaging/org.eclipse.jgit.http.apache.feature/license.html
@@ -5,13 +5,10 @@
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1" />
<title>Eclipse Foundation Software User Agreement</title>
</head>
-
<body lang="EN-US">
<h2>Eclipse Foundation Software User Agreement</h2>
<p>November 22, 2017</p>
-
<h3>Usage Of Content</h3>
-
<p>THE ECLIPSE FOUNDATION MAKES AVAILABLE SOFTWARE, DOCUMENTATION,
INFORMATION AND/OR OTHER MATERIALS FOR OPEN SOURCE PROJECTS
(COLLECTIVELY "CONTENT"). USE OF THE CONTENT IS GOVERNED BY
@@ -24,9 +21,7 @@
AGREEMENT AND THE TERMS AND CONDITIONS OF ANY APPLICABLE LICENSE
AGREEMENTS OR NOTICES INDICATED OR REFERENCED BELOW, THEN YOU MAY NOT
USE THE CONTENT.</p>
-
<h3>Applicable Licenses</h3>
-
<p>
Unless otherwise indicated, all Content made available by the Eclipse
Foundation is provided to you under the terms and conditions of the
@@ -35,13 +30,11 @@
href="http://www.eclipse.org/legal/epl-2.0">http://www.eclipse.org/legal/epl-2.0</a>.
For purposes of the EPL, "Program" will mean the Content.
</p>
-
<p>Content includes, but is not limited to, source code, object
code, documentation and other files maintained in the Eclipse
Foundation source code repository ("Repository") in software
modules ("Modules") and made available as downloadable
archives ("Downloads").</p>
-
<ul>
<li>Content may be structured and packaged into modules to
facilitate delivering, extending, and upgrading the Content. Typical
@@ -62,7 +55,6 @@
"feature.xml" may contain a list of the names and version
numbers of Included Features.</li>
</ul>
-
<p>The terms and conditions governing Plug-ins and Fragments should
be contained in files named "about.html"
("Abouts"). The terms and conditions governing Features and
@@ -70,7 +62,6 @@
"license.html" ("Feature Licenses"). Abouts and
Feature Licenses may be located in any directory of a Download or
Module including, but not limited to the following locations:</p>
-
<ul>
<li>The top-level (root) directory</li>
<li>Plug-in and Fragment directories</li>
@@ -79,7 +70,6 @@
certain Plug-ins</li>
<li>Feature directories</li>
</ul>
-
<p>Note: if a Feature made available by the Eclipse Foundation is
installed using the Provisioning Technology (as defined below), you
must agree to a license ("Feature Update License") during
@@ -92,12 +82,10 @@
Feature Licenses, and Feature Update Licenses contain the terms and
conditions (or references to such terms and conditions) that govern
your use of the associated Content in that directory.</p>
-
<p>THE ABOUTS, FEATURE LICENSES, AND FEATURE UPDATE LICENSES MAY
REFER TO THE EPL OR OTHER LICENSE AGREEMENTS, NOTICES OR TERMS AND
CONDITIONS. SOME OF THESE OTHER LICENSE AGREEMENTS MAY INCLUDE (BUT
ARE NOT LIMITED TO):</p>
-
<ul>
<li>Eclipse Public License Version 1.0 (available at <a
href="http://www.eclipse.org/legal/epl-v10.html">http://www.eclipse.org/legal/epl-v10.html</a>)
@@ -118,16 +106,12 @@
href="http://www.mozilla.org/MPL/MPL-1.1.html">http://www.mozilla.org/MPL/MPL-1.1.html</a>)
</li>
</ul>
-
<p>IT IS YOUR OBLIGATION TO READ AND ACCEPT ALL SUCH TERMS AND
CONDITIONS PRIOR TO USE OF THE CONTENT. If no About, Feature License,
or Feature Update License is provided, please contact the Eclipse
Foundation to determine what terms and conditions govern that
particular Content.</p>
-
-
<h3>Use of Provisioning Technology</h3>
-
<p>
The Eclipse Foundation makes available provisioning software, examples
of which include, but are not limited to, p2 and the Eclipse Update
@@ -140,7 +124,6 @@
href="http://eclipse.org/equinox/p2/repository_packaging.html">http://eclipse.org/equinox/p2/repository_packaging.html</a>
("Specification").
</p>
-
<p>You may use Provisioning Technology to allow other parties to
install Installable Software. You shall be responsible for enabling
the applicable license agreements relating to the Installable Software
@@ -149,7 +132,6 @@
Technology in such a manner and making it available in accordance with
the Specification, you further acknowledge your agreement to, and the
acquisition of all necessary rights to permit the following:</p>
-
<ol>
<li>A series of actions may occur ("Provisioning
Process") in which a user may execute the Provisioning
@@ -171,19 +153,16 @@
provisioning Technology will complete installation of the Installable
Software.</li>
</ol>
-
<h3>Cryptography</h3>
-
<p>Content may contain encryption software. The country in which
you are currently may have restrictions on the import, possession, and
use, and/or re-export to another country, of encryption software.
BEFORE using any encryption software, please check the country's laws,
regulations and policies concerning the import, possession, or use,
and re-export of encryption software, to see if this is permitted.</p>
-
<p>
<small>Java and all Java-based trademarks are trademarks of
Oracle Corporation in the United States, other countries, or both.</small>
</p>
</body>
-</html>
+</html>
\ No newline at end of file
diff --git a/org.eclipse.jgit.packaging/org.eclipse.jgit.http.apache.feature/pom.xml b/org.eclipse.jgit.packaging/org.eclipse.jgit.http.apache.feature/pom.xml
index 200a1e5..cc1238d 100644
--- a/org.eclipse.jgit.packaging/org.eclipse.jgit.http.apache.feature/pom.xml
+++ b/org.eclipse.jgit.packaging/org.eclipse.jgit.http.apache.feature/pom.xml
@@ -50,7 +50,7 @@
<parent>
<groupId>org.eclipse.jgit</groupId>
<artifactId>jgit.tycho.parent</artifactId>
- <version>5.5.2-SNAPSHOT</version>
+ <version>5.6.2-SNAPSHOT</version>
</parent>
<groupId>org.eclipse.jgit.feature</groupId>
diff --git a/org.eclipse.jgit.packaging/org.eclipse.jgit.junit.feature/feature.properties b/org.eclipse.jgit.packaging/org.eclipse.jgit.junit.feature/feature.properties
index 291b29e..acf33a9 100644
--- a/org.eclipse.jgit.packaging/org.eclipse.jgit.junit.feature/feature.properties
+++ b/org.eclipse.jgit.packaging/org.eclipse.jgit.junit.feature/feature.properties
@@ -31,7 +31,6 @@
# "licenseURL" property - URL of the "Feature License"
# do not translate value - just change to point to a locale-specific HTML page
licenseURL=license.html
-
# "license" property - text of the "Feature Update License"
# should be plain text version of license agreement pointed to be "licenseURL"
license=\
@@ -70,7 +69,7 @@
include plug-ins ("Plug-ins"), plug-in fragments ("Fragments"), and\n\
features ("Features").\n\
- Each Plug-in or Fragment may be packaged as a sub-directory or JAR\n\
- (Java™ ARchive) in a directory named "plugins".\n\
+ (Java\u2122 ARchive) in a directory named "plugins".\n\
- A Feature is a bundle of one or more Plug-ins and/or Fragments and\n\
associated material. Each Feature may be packaged as a sub-directory in a\n\
directory named "features". Within a Feature, files named "feature.xml" may\n\
diff --git a/org.eclipse.jgit.packaging/org.eclipse.jgit.junit.feature/feature.xml b/org.eclipse.jgit.packaging/org.eclipse.jgit.junit.feature/feature.xml
index aa43cef..c8bad5c 100644
--- a/org.eclipse.jgit.packaging/org.eclipse.jgit.junit.feature/feature.xml
+++ b/org.eclipse.jgit.packaging/org.eclipse.jgit.junit.feature/feature.xml
@@ -2,7 +2,7 @@
<feature
id="org.eclipse.jgit.junit"
label="%featureName"
- version="5.5.2.qualifier"
+ version="5.6.2.qualifier"
provider-name="%providerName">
<description url="http://www.eclipse.org/jgit/">
@@ -24,7 +24,7 @@
<requires>
<import plugin="com.jcraft.jsch"/>
- <import plugin="org.eclipse.jgit" version="5.5.2" match="equivalent"/>
+ <import plugin="org.eclipse.jgit" version="5.6.2" match="equivalent"/>
</requires>
<plugin
diff --git a/org.eclipse.jgit.packaging/org.eclipse.jgit.junit.feature/license.html b/org.eclipse.jgit.packaging/org.eclipse.jgit.junit.feature/license.html
index 008b801..004b6de 100644
--- a/org.eclipse.jgit.packaging/org.eclipse.jgit.junit.feature/license.html
+++ b/org.eclipse.jgit.packaging/org.eclipse.jgit.junit.feature/license.html
@@ -5,13 +5,10 @@
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1" />
<title>Eclipse Foundation Software User Agreement</title>
</head>
-
<body lang="EN-US">
<h2>Eclipse Foundation Software User Agreement</h2>
<p>November 22, 2017</p>
-
<h3>Usage Of Content</h3>
-
<p>THE ECLIPSE FOUNDATION MAKES AVAILABLE SOFTWARE, DOCUMENTATION,
INFORMATION AND/OR OTHER MATERIALS FOR OPEN SOURCE PROJECTS
(COLLECTIVELY "CONTENT"). USE OF THE CONTENT IS GOVERNED BY
@@ -24,9 +21,7 @@
AGREEMENT AND THE TERMS AND CONDITIONS OF ANY APPLICABLE LICENSE
AGREEMENTS OR NOTICES INDICATED OR REFERENCED BELOW, THEN YOU MAY NOT
USE THE CONTENT.</p>
-
<h3>Applicable Licenses</h3>
-
<p>
Unless otherwise indicated, all Content made available by the Eclipse
Foundation is provided to you under the terms and conditions of the
@@ -35,13 +30,11 @@
href="http://www.eclipse.org/legal/epl-2.0">http://www.eclipse.org/legal/epl-2.0</a>.
For purposes of the EPL, "Program" will mean the Content.
</p>
-
<p>Content includes, but is not limited to, source code, object
code, documentation and other files maintained in the Eclipse
Foundation source code repository ("Repository") in software
modules ("Modules") and made available as downloadable
archives ("Downloads").</p>
-
<ul>
<li>Content may be structured and packaged into modules to
facilitate delivering, extending, and upgrading the Content. Typical
@@ -62,7 +55,6 @@
"feature.xml" may contain a list of the names and version
numbers of Included Features.</li>
</ul>
-
<p>The terms and conditions governing Plug-ins and Fragments should
be contained in files named "about.html"
("Abouts"). The terms and conditions governing Features and
@@ -70,7 +62,6 @@
"license.html" ("Feature Licenses"). Abouts and
Feature Licenses may be located in any directory of a Download or
Module including, but not limited to the following locations:</p>
-
<ul>
<li>The top-level (root) directory</li>
<li>Plug-in and Fragment directories</li>
@@ -79,7 +70,6 @@
certain Plug-ins</li>
<li>Feature directories</li>
</ul>
-
<p>Note: if a Feature made available by the Eclipse Foundation is
installed using the Provisioning Technology (as defined below), you
must agree to a license ("Feature Update License") during
@@ -92,12 +82,10 @@
Feature Licenses, and Feature Update Licenses contain the terms and
conditions (or references to such terms and conditions) that govern
your use of the associated Content in that directory.</p>
-
<p>THE ABOUTS, FEATURE LICENSES, AND FEATURE UPDATE LICENSES MAY
REFER TO THE EPL OR OTHER LICENSE AGREEMENTS, NOTICES OR TERMS AND
CONDITIONS. SOME OF THESE OTHER LICENSE AGREEMENTS MAY INCLUDE (BUT
ARE NOT LIMITED TO):</p>
-
<ul>
<li>Eclipse Public License Version 1.0 (available at <a
href="http://www.eclipse.org/legal/epl-v10.html">http://www.eclipse.org/legal/epl-v10.html</a>)
@@ -118,16 +106,12 @@
href="http://www.mozilla.org/MPL/MPL-1.1.html">http://www.mozilla.org/MPL/MPL-1.1.html</a>)
</li>
</ul>
-
<p>IT IS YOUR OBLIGATION TO READ AND ACCEPT ALL SUCH TERMS AND
CONDITIONS PRIOR TO USE OF THE CONTENT. If no About, Feature License,
or Feature Update License is provided, please contact the Eclipse
Foundation to determine what terms and conditions govern that
particular Content.</p>
-
-
<h3>Use of Provisioning Technology</h3>
-
<p>
The Eclipse Foundation makes available provisioning software, examples
of which include, but are not limited to, p2 and the Eclipse Update
@@ -140,7 +124,6 @@
href="http://eclipse.org/equinox/p2/repository_packaging.html">http://eclipse.org/equinox/p2/repository_packaging.html</a>
("Specification").
</p>
-
<p>You may use Provisioning Technology to allow other parties to
install Installable Software. You shall be responsible for enabling
the applicable license agreements relating to the Installable Software
@@ -149,7 +132,6 @@
Technology in such a manner and making it available in accordance with
the Specification, you further acknowledge your agreement to, and the
acquisition of all necessary rights to permit the following:</p>
-
<ol>
<li>A series of actions may occur ("Provisioning
Process") in which a user may execute the Provisioning
@@ -171,19 +153,16 @@
provisioning Technology will complete installation of the Installable
Software.</li>
</ol>
-
<h3>Cryptography</h3>
-
<p>Content may contain encryption software. The country in which
you are currently may have restrictions on the import, possession, and
use, and/or re-export to another country, of encryption software.
BEFORE using any encryption software, please check the country's laws,
regulations and policies concerning the import, possession, or use,
and re-export of encryption software, to see if this is permitted.</p>
-
<p>
<small>Java and all Java-based trademarks are trademarks of
Oracle Corporation in the United States, other countries, or both.</small>
</p>
</body>
-</html>
+</html>
\ No newline at end of file
diff --git a/org.eclipse.jgit.packaging/org.eclipse.jgit.junit.feature/pom.xml b/org.eclipse.jgit.packaging/org.eclipse.jgit.junit.feature/pom.xml
index 23d3450..148ce1e 100644
--- a/org.eclipse.jgit.packaging/org.eclipse.jgit.junit.feature/pom.xml
+++ b/org.eclipse.jgit.packaging/org.eclipse.jgit.junit.feature/pom.xml
@@ -50,7 +50,7 @@
<parent>
<groupId>org.eclipse.jgit</groupId>
<artifactId>jgit.tycho.parent</artifactId>
- <version>5.5.2-SNAPSHOT</version>
+ <version>5.6.2-SNAPSHOT</version>
</parent>
<groupId>org.eclipse.jgit.feature</groupId>
diff --git a/org.eclipse.jgit.packaging/org.eclipse.jgit.lfs.feature/feature.properties b/org.eclipse.jgit.packaging/org.eclipse.jgit.lfs.feature/feature.properties
index 8387585..5d953fa 100644
--- a/org.eclipse.jgit.packaging/org.eclipse.jgit.lfs.feature/feature.properties
+++ b/org.eclipse.jgit.packaging/org.eclipse.jgit.lfs.feature/feature.properties
@@ -30,7 +30,6 @@
# "licenseURL" property - URL of the "Feature License"
# do not translate value - just change to point to a locale-specific HTML page
licenseURL=license.html
-
# "license" property - text of the "Feature Update License"
# should be plain text version of license agreement pointed to be "licenseURL"
license=\
@@ -69,7 +68,7 @@
include plug-ins ("Plug-ins"), plug-in fragments ("Fragments"), and\n\
features ("Features").\n\
- Each Plug-in or Fragment may be packaged as a sub-directory or JAR\n\
- (Java™ ARchive) in a directory named "plugins".\n\
+ (Java\u2122 ARchive) in a directory named "plugins".\n\
- A Feature is a bundle of one or more Plug-ins and/or Fragments and\n\
associated material. Each Feature may be packaged as a sub-directory in a\n\
directory named "features". Within a Feature, files named "feature.xml" may\n\
@@ -174,4 +173,4 @@
\n\
Java and all Java-based trademarks are trademarks of Oracle Corporation in the\n\
United States, other countries, or both.\n
-########### end of license property ##########################################
+########### end of license property ##########################################
\ No newline at end of file
diff --git a/org.eclipse.jgit.packaging/org.eclipse.jgit.lfs.feature/feature.xml b/org.eclipse.jgit.packaging/org.eclipse.jgit.lfs.feature/feature.xml
index 781e94a..1e26021 100644
--- a/org.eclipse.jgit.packaging/org.eclipse.jgit.lfs.feature/feature.xml
+++ b/org.eclipse.jgit.packaging/org.eclipse.jgit.lfs.feature/feature.xml
@@ -2,7 +2,7 @@
<feature
id="org.eclipse.jgit.lfs"
label="%featureName"
- version="5.5.2.qualifier"
+ version="5.6.2.qualifier"
provider-name="%providerName">
<description url="http://www.eclipse.org/jgit/">
@@ -23,7 +23,7 @@
</url>
<requires>
- <import feature="org.eclipse.jgit" version="5.5.2" match="equivalent"/>
+ <import feature="org.eclipse.jgit" version="5.6.2" match="equivalent"/>
</requires>
<plugin
diff --git a/org.eclipse.jgit.packaging/org.eclipse.jgit.lfs.feature/license.html b/org.eclipse.jgit.packaging/org.eclipse.jgit.lfs.feature/license.html
index 008b801..004b6de 100644
--- a/org.eclipse.jgit.packaging/org.eclipse.jgit.lfs.feature/license.html
+++ b/org.eclipse.jgit.packaging/org.eclipse.jgit.lfs.feature/license.html
@@ -5,13 +5,10 @@
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1" />
<title>Eclipse Foundation Software User Agreement</title>
</head>
-
<body lang="EN-US">
<h2>Eclipse Foundation Software User Agreement</h2>
<p>November 22, 2017</p>
-
<h3>Usage Of Content</h3>
-
<p>THE ECLIPSE FOUNDATION MAKES AVAILABLE SOFTWARE, DOCUMENTATION,
INFORMATION AND/OR OTHER MATERIALS FOR OPEN SOURCE PROJECTS
(COLLECTIVELY "CONTENT"). USE OF THE CONTENT IS GOVERNED BY
@@ -24,9 +21,7 @@
AGREEMENT AND THE TERMS AND CONDITIONS OF ANY APPLICABLE LICENSE
AGREEMENTS OR NOTICES INDICATED OR REFERENCED BELOW, THEN YOU MAY NOT
USE THE CONTENT.</p>
-
<h3>Applicable Licenses</h3>
-
<p>
Unless otherwise indicated, all Content made available by the Eclipse
Foundation is provided to you under the terms and conditions of the
@@ -35,13 +30,11 @@
href="http://www.eclipse.org/legal/epl-2.0">http://www.eclipse.org/legal/epl-2.0</a>.
For purposes of the EPL, "Program" will mean the Content.
</p>
-
<p>Content includes, but is not limited to, source code, object
code, documentation and other files maintained in the Eclipse
Foundation source code repository ("Repository") in software
modules ("Modules") and made available as downloadable
archives ("Downloads").</p>
-
<ul>
<li>Content may be structured and packaged into modules to
facilitate delivering, extending, and upgrading the Content. Typical
@@ -62,7 +55,6 @@
"feature.xml" may contain a list of the names and version
numbers of Included Features.</li>
</ul>
-
<p>The terms and conditions governing Plug-ins and Fragments should
be contained in files named "about.html"
("Abouts"). The terms and conditions governing Features and
@@ -70,7 +62,6 @@
"license.html" ("Feature Licenses"). Abouts and
Feature Licenses may be located in any directory of a Download or
Module including, but not limited to the following locations:</p>
-
<ul>
<li>The top-level (root) directory</li>
<li>Plug-in and Fragment directories</li>
@@ -79,7 +70,6 @@
certain Plug-ins</li>
<li>Feature directories</li>
</ul>
-
<p>Note: if a Feature made available by the Eclipse Foundation is
installed using the Provisioning Technology (as defined below), you
must agree to a license ("Feature Update License") during
@@ -92,12 +82,10 @@
Feature Licenses, and Feature Update Licenses contain the terms and
conditions (or references to such terms and conditions) that govern
your use of the associated Content in that directory.</p>
-
<p>THE ABOUTS, FEATURE LICENSES, AND FEATURE UPDATE LICENSES MAY
REFER TO THE EPL OR OTHER LICENSE AGREEMENTS, NOTICES OR TERMS AND
CONDITIONS. SOME OF THESE OTHER LICENSE AGREEMENTS MAY INCLUDE (BUT
ARE NOT LIMITED TO):</p>
-
<ul>
<li>Eclipse Public License Version 1.0 (available at <a
href="http://www.eclipse.org/legal/epl-v10.html">http://www.eclipse.org/legal/epl-v10.html</a>)
@@ -118,16 +106,12 @@
href="http://www.mozilla.org/MPL/MPL-1.1.html">http://www.mozilla.org/MPL/MPL-1.1.html</a>)
</li>
</ul>
-
<p>IT IS YOUR OBLIGATION TO READ AND ACCEPT ALL SUCH TERMS AND
CONDITIONS PRIOR TO USE OF THE CONTENT. If no About, Feature License,
or Feature Update License is provided, please contact the Eclipse
Foundation to determine what terms and conditions govern that
particular Content.</p>
-
-
<h3>Use of Provisioning Technology</h3>
-
<p>
The Eclipse Foundation makes available provisioning software, examples
of which include, but are not limited to, p2 and the Eclipse Update
@@ -140,7 +124,6 @@
href="http://eclipse.org/equinox/p2/repository_packaging.html">http://eclipse.org/equinox/p2/repository_packaging.html</a>
("Specification").
</p>
-
<p>You may use Provisioning Technology to allow other parties to
install Installable Software. You shall be responsible for enabling
the applicable license agreements relating to the Installable Software
@@ -149,7 +132,6 @@
Technology in such a manner and making it available in accordance with
the Specification, you further acknowledge your agreement to, and the
acquisition of all necessary rights to permit the following:</p>
-
<ol>
<li>A series of actions may occur ("Provisioning
Process") in which a user may execute the Provisioning
@@ -171,19 +153,16 @@
provisioning Technology will complete installation of the Installable
Software.</li>
</ol>
-
<h3>Cryptography</h3>
-
<p>Content may contain encryption software. The country in which
you are currently may have restrictions on the import, possession, and
use, and/or re-export to another country, of encryption software.
BEFORE using any encryption software, please check the country's laws,
regulations and policies concerning the import, possession, or use,
and re-export of encryption software, to see if this is permitted.</p>
-
<p>
<small>Java and all Java-based trademarks are trademarks of
Oracle Corporation in the United States, other countries, or both.</small>
</p>
</body>
-</html>
+</html>
\ No newline at end of file
diff --git a/org.eclipse.jgit.packaging/org.eclipse.jgit.lfs.feature/pom.xml b/org.eclipse.jgit.packaging/org.eclipse.jgit.lfs.feature/pom.xml
index b5fb886..45821a0 100644
--- a/org.eclipse.jgit.packaging/org.eclipse.jgit.lfs.feature/pom.xml
+++ b/org.eclipse.jgit.packaging/org.eclipse.jgit.lfs.feature/pom.xml
@@ -50,7 +50,7 @@
<parent>
<groupId>org.eclipse.jgit</groupId>
<artifactId>jgit.tycho.parent</artifactId>
- <version>5.5.2-SNAPSHOT</version>
+ <version>5.6.2-SNAPSHOT</version>
</parent>
<groupId>org.eclipse.jgit.feature</groupId>
diff --git a/org.eclipse.jgit.packaging/org.eclipse.jgit.pgm.feature/feature.properties b/org.eclipse.jgit.packaging/org.eclipse.jgit.pgm.feature/feature.properties
index ef9031e..450cff4 100644
--- a/org.eclipse.jgit.packaging/org.eclipse.jgit.pgm.feature/feature.properties
+++ b/org.eclipse.jgit.packaging/org.eclipse.jgit.pgm.feature/feature.properties
@@ -30,7 +30,6 @@
# "licenseURL" property - URL of the "Feature License"
# do not translate value - just change to point to a locale-specific HTML page
licenseURL=license.html
-
# "license" property - text of the "Feature Update License"
# should be plain text version of license agreement pointed to be "licenseURL"
license=\
@@ -69,7 +68,7 @@
include plug-ins ("Plug-ins"), plug-in fragments ("Fragments"), and\n\
features ("Features").\n\
- Each Plug-in or Fragment may be packaged as a sub-directory or JAR\n\
- (Java™ ARchive) in a directory named "plugins".\n\
+ (Java\u2122 ARchive) in a directory named "plugins".\n\
- A Feature is a bundle of one or more Plug-ins and/or Fragments and\n\
associated material. Each Feature may be packaged as a sub-directory in a\n\
directory named "features". Within a Feature, files named "feature.xml" may\n\
@@ -174,4 +173,4 @@
\n\
Java and all Java-based trademarks are trademarks of Oracle Corporation in the\n\
United States, other countries, or both.\n
-########### end of license property ##########################################
+########### end of license property ##########################################
\ No newline at end of file
diff --git a/org.eclipse.jgit.packaging/org.eclipse.jgit.pgm.feature/feature.xml b/org.eclipse.jgit.packaging/org.eclipse.jgit.pgm.feature/feature.xml
index 8656890..c092b97 100644
--- a/org.eclipse.jgit.packaging/org.eclipse.jgit.pgm.feature/feature.xml
+++ b/org.eclipse.jgit.packaging/org.eclipse.jgit.pgm.feature/feature.xml
@@ -2,7 +2,7 @@
<feature
id="org.eclipse.jgit.pgm"
label="%featureName"
- version="5.5.2.qualifier"
+ version="5.6.2.qualifier"
provider-name="%providerName">
<description url="http://www.eclipse.org/jgit/">
@@ -35,9 +35,9 @@
version="0.0.0"/>
<requires>
- <import feature="org.eclipse.jgit" version="5.5.2" match="equivalent"/>
- <import feature="org.eclipse.jgit.lfs" version="5.5.2" match="equivalent"/>
- <import feature="org.eclipse.jgit.ssh.apache" version="5.5.2" match="equivalent"/>
+ <import feature="org.eclipse.jgit" version="5.6.2" match="equivalent"/>
+ <import feature="org.eclipse.jgit.lfs" version="5.6.2" match="equivalent"/>
+ <import feature="org.eclipse.jgit.ssh.apache" version="5.6.2" match="equivalent"/>
</requires>
<plugin
diff --git a/org.eclipse.jgit.packaging/org.eclipse.jgit.pgm.feature/license.html b/org.eclipse.jgit.packaging/org.eclipse.jgit.pgm.feature/license.html
index 008b801..004b6de 100644
--- a/org.eclipse.jgit.packaging/org.eclipse.jgit.pgm.feature/license.html
+++ b/org.eclipse.jgit.packaging/org.eclipse.jgit.pgm.feature/license.html
@@ -5,13 +5,10 @@
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1" />
<title>Eclipse Foundation Software User Agreement</title>
</head>
-
<body lang="EN-US">
<h2>Eclipse Foundation Software User Agreement</h2>
<p>November 22, 2017</p>
-
<h3>Usage Of Content</h3>
-
<p>THE ECLIPSE FOUNDATION MAKES AVAILABLE SOFTWARE, DOCUMENTATION,
INFORMATION AND/OR OTHER MATERIALS FOR OPEN SOURCE PROJECTS
(COLLECTIVELY "CONTENT"). USE OF THE CONTENT IS GOVERNED BY
@@ -24,9 +21,7 @@
AGREEMENT AND THE TERMS AND CONDITIONS OF ANY APPLICABLE LICENSE
AGREEMENTS OR NOTICES INDICATED OR REFERENCED BELOW, THEN YOU MAY NOT
USE THE CONTENT.</p>
-
<h3>Applicable Licenses</h3>
-
<p>
Unless otherwise indicated, all Content made available by the Eclipse
Foundation is provided to you under the terms and conditions of the
@@ -35,13 +30,11 @@
href="http://www.eclipse.org/legal/epl-2.0">http://www.eclipse.org/legal/epl-2.0</a>.
For purposes of the EPL, "Program" will mean the Content.
</p>
-
<p>Content includes, but is not limited to, source code, object
code, documentation and other files maintained in the Eclipse
Foundation source code repository ("Repository") in software
modules ("Modules") and made available as downloadable
archives ("Downloads").</p>
-
<ul>
<li>Content may be structured and packaged into modules to
facilitate delivering, extending, and upgrading the Content. Typical
@@ -62,7 +55,6 @@
"feature.xml" may contain a list of the names and version
numbers of Included Features.</li>
</ul>
-
<p>The terms and conditions governing Plug-ins and Fragments should
be contained in files named "about.html"
("Abouts"). The terms and conditions governing Features and
@@ -70,7 +62,6 @@
"license.html" ("Feature Licenses"). Abouts and
Feature Licenses may be located in any directory of a Download or
Module including, but not limited to the following locations:</p>
-
<ul>
<li>The top-level (root) directory</li>
<li>Plug-in and Fragment directories</li>
@@ -79,7 +70,6 @@
certain Plug-ins</li>
<li>Feature directories</li>
</ul>
-
<p>Note: if a Feature made available by the Eclipse Foundation is
installed using the Provisioning Technology (as defined below), you
must agree to a license ("Feature Update License") during
@@ -92,12 +82,10 @@
Feature Licenses, and Feature Update Licenses contain the terms and
conditions (or references to such terms and conditions) that govern
your use of the associated Content in that directory.</p>
-
<p>THE ABOUTS, FEATURE LICENSES, AND FEATURE UPDATE LICENSES MAY
REFER TO THE EPL OR OTHER LICENSE AGREEMENTS, NOTICES OR TERMS AND
CONDITIONS. SOME OF THESE OTHER LICENSE AGREEMENTS MAY INCLUDE (BUT
ARE NOT LIMITED TO):</p>
-
<ul>
<li>Eclipse Public License Version 1.0 (available at <a
href="http://www.eclipse.org/legal/epl-v10.html">http://www.eclipse.org/legal/epl-v10.html</a>)
@@ -118,16 +106,12 @@
href="http://www.mozilla.org/MPL/MPL-1.1.html">http://www.mozilla.org/MPL/MPL-1.1.html</a>)
</li>
</ul>
-
<p>IT IS YOUR OBLIGATION TO READ AND ACCEPT ALL SUCH TERMS AND
CONDITIONS PRIOR TO USE OF THE CONTENT. If no About, Feature License,
or Feature Update License is provided, please contact the Eclipse
Foundation to determine what terms and conditions govern that
particular Content.</p>
-
-
<h3>Use of Provisioning Technology</h3>
-
<p>
The Eclipse Foundation makes available provisioning software, examples
of which include, but are not limited to, p2 and the Eclipse Update
@@ -140,7 +124,6 @@
href="http://eclipse.org/equinox/p2/repository_packaging.html">http://eclipse.org/equinox/p2/repository_packaging.html</a>
("Specification").
</p>
-
<p>You may use Provisioning Technology to allow other parties to
install Installable Software. You shall be responsible for enabling
the applicable license agreements relating to the Installable Software
@@ -149,7 +132,6 @@
Technology in such a manner and making it available in accordance with
the Specification, you further acknowledge your agreement to, and the
acquisition of all necessary rights to permit the following:</p>
-
<ol>
<li>A series of actions may occur ("Provisioning
Process") in which a user may execute the Provisioning
@@ -171,19 +153,16 @@
provisioning Technology will complete installation of the Installable
Software.</li>
</ol>
-
<h3>Cryptography</h3>
-
<p>Content may contain encryption software. The country in which
you are currently may have restrictions on the import, possession, and
use, and/or re-export to another country, of encryption software.
BEFORE using any encryption software, please check the country's laws,
regulations and policies concerning the import, possession, or use,
and re-export of encryption software, to see if this is permitted.</p>
-
<p>
<small>Java and all Java-based trademarks are trademarks of
Oracle Corporation in the United States, other countries, or both.</small>
</p>
</body>
-</html>
+</html>
\ No newline at end of file
diff --git a/org.eclipse.jgit.packaging/org.eclipse.jgit.pgm.feature/pom.xml b/org.eclipse.jgit.packaging/org.eclipse.jgit.pgm.feature/pom.xml
index b4fe972..ff94fb0 100644
--- a/org.eclipse.jgit.packaging/org.eclipse.jgit.pgm.feature/pom.xml
+++ b/org.eclipse.jgit.packaging/org.eclipse.jgit.pgm.feature/pom.xml
@@ -50,7 +50,7 @@
<parent>
<groupId>org.eclipse.jgit</groupId>
<artifactId>jgit.tycho.parent</artifactId>
- <version>5.5.2-SNAPSHOT</version>
+ <version>5.6.2-SNAPSHOT</version>
</parent>
<groupId>org.eclipse.jgit.feature</groupId>
diff --git a/org.eclipse.jgit.packaging/org.eclipse.jgit.repository/pom.xml b/org.eclipse.jgit.packaging/org.eclipse.jgit.repository/pom.xml
index 63c76bf..828133a 100644
--- a/org.eclipse.jgit.packaging/org.eclipse.jgit.repository/pom.xml
+++ b/org.eclipse.jgit.packaging/org.eclipse.jgit.repository/pom.xml
@@ -50,7 +50,7 @@
<parent>
<groupId>org.eclipse.jgit</groupId>
<artifactId>jgit.tycho.parent</artifactId>
- <version>5.5.2-SNAPSHOT</version>
+ <version>5.6.2-SNAPSHOT</version>
</parent>
<artifactId>org.eclipse.jgit.repository</artifactId>
diff --git a/org.eclipse.jgit.packaging/org.eclipse.jgit.source.feature/feature.properties b/org.eclipse.jgit.packaging/org.eclipse.jgit.source.feature/feature.properties
index c04dc63..5043c32 100644
--- a/org.eclipse.jgit.packaging/org.eclipse.jgit.source.feature/feature.properties
+++ b/org.eclipse.jgit.packaging/org.eclipse.jgit.source.feature/feature.properties
@@ -31,7 +31,6 @@
# "licenseURL" property - URL of the "Feature License"
# do not translate value - just change to point to a locale-specific HTML page
licenseURL=license.html
-
# "license" property - text of the "Feature Update License"
# should be plain text version of license agreement pointed to be "licenseURL"
license=\
@@ -70,7 +69,7 @@
include plug-ins ("Plug-ins"), plug-in fragments ("Fragments"), and\n\
features ("Features").\n\
- Each Plug-in or Fragment may be packaged as a sub-directory or JAR\n\
- (Java™ ARchive) in a directory named "plugins".\n\
+ (Java\u2122 ARchive) in a directory named "plugins".\n\
- A Feature is a bundle of one or more Plug-ins and/or Fragments and\n\
associated material. Each Feature may be packaged as a sub-directory in a\n\
directory named "features". Within a Feature, files named "feature.xml" may\n\
@@ -175,4 +174,4 @@
\n\
Java and all Java-based trademarks are trademarks of Oracle Corporation in the\n\
United States, other countries, or both.\n
-########### end of license property ##########################################
+########### end of license property ##########################################
\ No newline at end of file
diff --git a/org.eclipse.jgit.packaging/org.eclipse.jgit.source.feature/feature.xml b/org.eclipse.jgit.packaging/org.eclipse.jgit.source.feature/feature.xml
index 8781c66..2d6e2d8 100644
--- a/org.eclipse.jgit.packaging/org.eclipse.jgit.source.feature/feature.xml
+++ b/org.eclipse.jgit.packaging/org.eclipse.jgit.source.feature/feature.xml
@@ -2,7 +2,7 @@
<feature
id="org.eclipse.jgit.source"
label="%featureName"
- version="5.5.2.qualifier"
+ version="5.6.2.qualifier"
provider-name="%providerName">
<description url="http://www.eclipse.org/jgit/">
@@ -23,7 +23,7 @@
</url>
<requires>
- <import feature="org.eclipse.jgit" version="5.5.2" match="equivalent"/>
+ <import feature="org.eclipse.jgit" version="5.6.2" match="equivalent"/>
</requires>
<plugin
diff --git a/org.eclipse.jgit.packaging/org.eclipse.jgit.source.feature/license.html b/org.eclipse.jgit.packaging/org.eclipse.jgit.source.feature/license.html
index 008b801..004b6de 100644
--- a/org.eclipse.jgit.packaging/org.eclipse.jgit.source.feature/license.html
+++ b/org.eclipse.jgit.packaging/org.eclipse.jgit.source.feature/license.html
@@ -5,13 +5,10 @@
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1" />
<title>Eclipse Foundation Software User Agreement</title>
</head>
-
<body lang="EN-US">
<h2>Eclipse Foundation Software User Agreement</h2>
<p>November 22, 2017</p>
-
<h3>Usage Of Content</h3>
-
<p>THE ECLIPSE FOUNDATION MAKES AVAILABLE SOFTWARE, DOCUMENTATION,
INFORMATION AND/OR OTHER MATERIALS FOR OPEN SOURCE PROJECTS
(COLLECTIVELY "CONTENT"). USE OF THE CONTENT IS GOVERNED BY
@@ -24,9 +21,7 @@
AGREEMENT AND THE TERMS AND CONDITIONS OF ANY APPLICABLE LICENSE
AGREEMENTS OR NOTICES INDICATED OR REFERENCED BELOW, THEN YOU MAY NOT
USE THE CONTENT.</p>
-
<h3>Applicable Licenses</h3>
-
<p>
Unless otherwise indicated, all Content made available by the Eclipse
Foundation is provided to you under the terms and conditions of the
@@ -35,13 +30,11 @@
href="http://www.eclipse.org/legal/epl-2.0">http://www.eclipse.org/legal/epl-2.0</a>.
For purposes of the EPL, "Program" will mean the Content.
</p>
-
<p>Content includes, but is not limited to, source code, object
code, documentation and other files maintained in the Eclipse
Foundation source code repository ("Repository") in software
modules ("Modules") and made available as downloadable
archives ("Downloads").</p>
-
<ul>
<li>Content may be structured and packaged into modules to
facilitate delivering, extending, and upgrading the Content. Typical
@@ -62,7 +55,6 @@
"feature.xml" may contain a list of the names and version
numbers of Included Features.</li>
</ul>
-
<p>The terms and conditions governing Plug-ins and Fragments should
be contained in files named "about.html"
("Abouts"). The terms and conditions governing Features and
@@ -70,7 +62,6 @@
"license.html" ("Feature Licenses"). Abouts and
Feature Licenses may be located in any directory of a Download or
Module including, but not limited to the following locations:</p>
-
<ul>
<li>The top-level (root) directory</li>
<li>Plug-in and Fragment directories</li>
@@ -79,7 +70,6 @@
certain Plug-ins</li>
<li>Feature directories</li>
</ul>
-
<p>Note: if a Feature made available by the Eclipse Foundation is
installed using the Provisioning Technology (as defined below), you
must agree to a license ("Feature Update License") during
@@ -92,12 +82,10 @@
Feature Licenses, and Feature Update Licenses contain the terms and
conditions (or references to such terms and conditions) that govern
your use of the associated Content in that directory.</p>
-
<p>THE ABOUTS, FEATURE LICENSES, AND FEATURE UPDATE LICENSES MAY
REFER TO THE EPL OR OTHER LICENSE AGREEMENTS, NOTICES OR TERMS AND
CONDITIONS. SOME OF THESE OTHER LICENSE AGREEMENTS MAY INCLUDE (BUT
ARE NOT LIMITED TO):</p>
-
<ul>
<li>Eclipse Public License Version 1.0 (available at <a
href="http://www.eclipse.org/legal/epl-v10.html">http://www.eclipse.org/legal/epl-v10.html</a>)
@@ -118,16 +106,12 @@
href="http://www.mozilla.org/MPL/MPL-1.1.html">http://www.mozilla.org/MPL/MPL-1.1.html</a>)
</li>
</ul>
-
<p>IT IS YOUR OBLIGATION TO READ AND ACCEPT ALL SUCH TERMS AND
CONDITIONS PRIOR TO USE OF THE CONTENT. If no About, Feature License,
or Feature Update License is provided, please contact the Eclipse
Foundation to determine what terms and conditions govern that
particular Content.</p>
-
-
<h3>Use of Provisioning Technology</h3>
-
<p>
The Eclipse Foundation makes available provisioning software, examples
of which include, but are not limited to, p2 and the Eclipse Update
@@ -140,7 +124,6 @@
href="http://eclipse.org/equinox/p2/repository_packaging.html">http://eclipse.org/equinox/p2/repository_packaging.html</a>
("Specification").
</p>
-
<p>You may use Provisioning Technology to allow other parties to
install Installable Software. You shall be responsible for enabling
the applicable license agreements relating to the Installable Software
@@ -149,7 +132,6 @@
Technology in such a manner and making it available in accordance with
the Specification, you further acknowledge your agreement to, and the
acquisition of all necessary rights to permit the following:</p>
-
<ol>
<li>A series of actions may occur ("Provisioning
Process") in which a user may execute the Provisioning
@@ -171,19 +153,16 @@
provisioning Technology will complete installation of the Installable
Software.</li>
</ol>
-
<h3>Cryptography</h3>
-
<p>Content may contain encryption software. The country in which
you are currently may have restrictions on the import, possession, and
use, and/or re-export to another country, of encryption software.
BEFORE using any encryption software, please check the country's laws,
regulations and policies concerning the import, possession, or use,
and re-export of encryption software, to see if this is permitted.</p>
-
<p>
<small>Java and all Java-based trademarks are trademarks of
Oracle Corporation in the United States, other countries, or both.</small>
</p>
</body>
-</html>
+</html>
\ No newline at end of file
diff --git a/org.eclipse.jgit.packaging/org.eclipse.jgit.source.feature/pom.xml b/org.eclipse.jgit.packaging/org.eclipse.jgit.source.feature/pom.xml
index 9ce5ec4..17162b6 100644
--- a/org.eclipse.jgit.packaging/org.eclipse.jgit.source.feature/pom.xml
+++ b/org.eclipse.jgit.packaging/org.eclipse.jgit.source.feature/pom.xml
@@ -50,7 +50,7 @@
<parent>
<groupId>org.eclipse.jgit</groupId>
<artifactId>jgit.tycho.parent</artifactId>
- <version>5.5.2-SNAPSHOT</version>
+ <version>5.6.2-SNAPSHOT</version>
</parent>
<groupId>org.eclipse.jgit.feature</groupId>
@@ -63,7 +63,7 @@
<dependency>
<groupId>org.eclipse.jgit.feature</groupId>
<artifactId>org.eclipse.jgit</artifactId>
- <version>5.5.2-SNAPSHOT</version>
+ <version>5.6.2-SNAPSHOT</version>
</dependency>
</dependencies>
diff --git a/org.eclipse.jgit.packaging/org.eclipse.jgit.ssh.apache.feature/feature.properties b/org.eclipse.jgit.packaging/org.eclipse.jgit.ssh.apache.feature/feature.properties
index 2b08612..e412fc2 100644
--- a/org.eclipse.jgit.packaging/org.eclipse.jgit.ssh.apache.feature/feature.properties
+++ b/org.eclipse.jgit.packaging/org.eclipse.jgit.ssh.apache.feature/feature.properties
@@ -30,7 +30,6 @@
# "licenseURL" property - URL of the "Feature License"
# do not translate value - just change to point to a locale-specific HTML page
licenseURL=license.html
-
# "license" property - text of the "Feature Update License"
# should be plain text version of license agreement pointed to be "licenseURL"
license=\
@@ -69,7 +68,7 @@
include plug-ins ("Plug-ins"), plug-in fragments ("Fragments"), and\n\
features ("Features").\n\
- Each Plug-in or Fragment may be packaged as a sub-directory or JAR\n\
- (Java™ ARchive) in a directory named "plugins".\n\
+ (Java\u2122 ARchive) in a directory named "plugins".\n\
- A Feature is a bundle of one or more Plug-ins and/or Fragments and\n\
associated material. Each Feature may be packaged as a sub-directory in a\n\
directory named "features". Within a Feature, files named "feature.xml" may\n\
@@ -174,4 +173,4 @@
\n\
Java and all Java-based trademarks are trademarks of Oracle Corporation in the\n\
United States, other countries, or both.\n
-########### end of license property ##########################################
+########### end of license property ##########################################
\ No newline at end of file
diff --git a/org.eclipse.jgit.packaging/org.eclipse.jgit.ssh.apache.feature/feature.xml b/org.eclipse.jgit.packaging/org.eclipse.jgit.ssh.apache.feature/feature.xml
index a55f941..eb285d6 100644
--- a/org.eclipse.jgit.packaging/org.eclipse.jgit.ssh.apache.feature/feature.xml
+++ b/org.eclipse.jgit.packaging/org.eclipse.jgit.ssh.apache.feature/feature.xml
@@ -2,7 +2,7 @@
<feature
id="org.eclipse.jgit.ssh.apache"
label="%featureName"
- version="5.5.2.qualifier"
+ version="5.6.2.qualifier"
provider-name="%providerName">
<description url="http://www.eclipse.org/jgit/">
@@ -23,7 +23,7 @@
</url>
<requires>
- <import feature="org.eclipse.jgit" version="5.5.2" match="equivalent"/>
+ <import feature="org.eclipse.jgit" version="5.6.2" match="equivalent"/>
</requires>
<plugin
diff --git a/org.eclipse.jgit.packaging/org.eclipse.jgit.ssh.apache.feature/license.html b/org.eclipse.jgit.packaging/org.eclipse.jgit.ssh.apache.feature/license.html
index 008b801..004b6de 100644
--- a/org.eclipse.jgit.packaging/org.eclipse.jgit.ssh.apache.feature/license.html
+++ b/org.eclipse.jgit.packaging/org.eclipse.jgit.ssh.apache.feature/license.html
@@ -5,13 +5,10 @@
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1" />
<title>Eclipse Foundation Software User Agreement</title>
</head>
-
<body lang="EN-US">
<h2>Eclipse Foundation Software User Agreement</h2>
<p>November 22, 2017</p>
-
<h3>Usage Of Content</h3>
-
<p>THE ECLIPSE FOUNDATION MAKES AVAILABLE SOFTWARE, DOCUMENTATION,
INFORMATION AND/OR OTHER MATERIALS FOR OPEN SOURCE PROJECTS
(COLLECTIVELY "CONTENT"). USE OF THE CONTENT IS GOVERNED BY
@@ -24,9 +21,7 @@
AGREEMENT AND THE TERMS AND CONDITIONS OF ANY APPLICABLE LICENSE
AGREEMENTS OR NOTICES INDICATED OR REFERENCED BELOW, THEN YOU MAY NOT
USE THE CONTENT.</p>
-
<h3>Applicable Licenses</h3>
-
<p>
Unless otherwise indicated, all Content made available by the Eclipse
Foundation is provided to you under the terms and conditions of the
@@ -35,13 +30,11 @@
href="http://www.eclipse.org/legal/epl-2.0">http://www.eclipse.org/legal/epl-2.0</a>.
For purposes of the EPL, "Program" will mean the Content.
</p>
-
<p>Content includes, but is not limited to, source code, object
code, documentation and other files maintained in the Eclipse
Foundation source code repository ("Repository") in software
modules ("Modules") and made available as downloadable
archives ("Downloads").</p>
-
<ul>
<li>Content may be structured and packaged into modules to
facilitate delivering, extending, and upgrading the Content. Typical
@@ -62,7 +55,6 @@
"feature.xml" may contain a list of the names and version
numbers of Included Features.</li>
</ul>
-
<p>The terms and conditions governing Plug-ins and Fragments should
be contained in files named "about.html"
("Abouts"). The terms and conditions governing Features and
@@ -70,7 +62,6 @@
"license.html" ("Feature Licenses"). Abouts and
Feature Licenses may be located in any directory of a Download or
Module including, but not limited to the following locations:</p>
-
<ul>
<li>The top-level (root) directory</li>
<li>Plug-in and Fragment directories</li>
@@ -79,7 +70,6 @@
certain Plug-ins</li>
<li>Feature directories</li>
</ul>
-
<p>Note: if a Feature made available by the Eclipse Foundation is
installed using the Provisioning Technology (as defined below), you
must agree to a license ("Feature Update License") during
@@ -92,12 +82,10 @@
Feature Licenses, and Feature Update Licenses contain the terms and
conditions (or references to such terms and conditions) that govern
your use of the associated Content in that directory.</p>
-
<p>THE ABOUTS, FEATURE LICENSES, AND FEATURE UPDATE LICENSES MAY
REFER TO THE EPL OR OTHER LICENSE AGREEMENTS, NOTICES OR TERMS AND
CONDITIONS. SOME OF THESE OTHER LICENSE AGREEMENTS MAY INCLUDE (BUT
ARE NOT LIMITED TO):</p>
-
<ul>
<li>Eclipse Public License Version 1.0 (available at <a
href="http://www.eclipse.org/legal/epl-v10.html">http://www.eclipse.org/legal/epl-v10.html</a>)
@@ -118,16 +106,12 @@
href="http://www.mozilla.org/MPL/MPL-1.1.html">http://www.mozilla.org/MPL/MPL-1.1.html</a>)
</li>
</ul>
-
<p>IT IS YOUR OBLIGATION TO READ AND ACCEPT ALL SUCH TERMS AND
CONDITIONS PRIOR TO USE OF THE CONTENT. If no About, Feature License,
or Feature Update License is provided, please contact the Eclipse
Foundation to determine what terms and conditions govern that
particular Content.</p>
-
-
<h3>Use of Provisioning Technology</h3>
-
<p>
The Eclipse Foundation makes available provisioning software, examples
of which include, but are not limited to, p2 and the Eclipse Update
@@ -140,7 +124,6 @@
href="http://eclipse.org/equinox/p2/repository_packaging.html">http://eclipse.org/equinox/p2/repository_packaging.html</a>
("Specification").
</p>
-
<p>You may use Provisioning Technology to allow other parties to
install Installable Software. You shall be responsible for enabling
the applicable license agreements relating to the Installable Software
@@ -149,7 +132,6 @@
Technology in such a manner and making it available in accordance with
the Specification, you further acknowledge your agreement to, and the
acquisition of all necessary rights to permit the following:</p>
-
<ol>
<li>A series of actions may occur ("Provisioning
Process") in which a user may execute the Provisioning
@@ -171,19 +153,16 @@
provisioning Technology will complete installation of the Installable
Software.</li>
</ol>
-
<h3>Cryptography</h3>
-
<p>Content may contain encryption software. The country in which
you are currently may have restrictions on the import, possession, and
use, and/or re-export to another country, of encryption software.
BEFORE using any encryption software, please check the country's laws,
regulations and policies concerning the import, possession, or use,
and re-export of encryption software, to see if this is permitted.</p>
-
<p>
<small>Java and all Java-based trademarks are trademarks of
Oracle Corporation in the United States, other countries, or both.</small>
</p>
</body>
-</html>
+</html>
\ No newline at end of file
diff --git a/org.eclipse.jgit.packaging/org.eclipse.jgit.ssh.apache.feature/pom.xml b/org.eclipse.jgit.packaging/org.eclipse.jgit.ssh.apache.feature/pom.xml
index 9ebafca..f4ac351 100644
--- a/org.eclipse.jgit.packaging/org.eclipse.jgit.ssh.apache.feature/pom.xml
+++ b/org.eclipse.jgit.packaging/org.eclipse.jgit.ssh.apache.feature/pom.xml
@@ -50,7 +50,7 @@
<parent>
<groupId>org.eclipse.jgit</groupId>
<artifactId>jgit.tycho.parent</artifactId>
- <version>5.5.2-SNAPSHOT</version>
+ <version>5.6.2-SNAPSHOT</version>
</parent>
<groupId>org.eclipse.jgit.feature</groupId>
diff --git a/org.eclipse.jgit.packaging/org.eclipse.jgit.target/META-INF/MANIFEST.MF b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/META-INF/MANIFEST.MF
index 5954a34..42bc17f 100644
--- a/org.eclipse.jgit.packaging/org.eclipse.jgit.target/META-INF/MANIFEST.MF
+++ b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/META-INF/MANIFEST.MF
@@ -2,4 +2,4 @@
Bundle-ManifestVersion: 2
Bundle-Name: JGit Target Platform Bundle
Bundle-SymbolicName: org.eclipse.jgit.target
-Bundle-Version: 5.5.2.qualifier
+Bundle-Version: 5.6.2.qualifier
diff --git a/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.10.target b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.10.target
index 5d9a00a..9fe380e 100644
--- a/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.10.target
+++ b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.10.target
@@ -1,26 +1,26 @@
<?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="1638608437">
+<target name="jgit-4.10" sequenceNumber="1638636816">
<locations>
<location includeMode="slicer" includeAllPlatforms="false" includeSource="true" includeConfigurePhase="true" type="InstallableUnit">
- <unit id="org.eclipse.jetty.client" version="9.4.20.v20190813"/>
- <unit id="org.eclipse.jetty.client.source" version="9.4.20.v20190813"/>
- <unit id="org.eclipse.jetty.continuation" version="9.4.20.v20190813"/>
- <unit id="org.eclipse.jetty.continuation.source" version="9.4.20.v20190813"/>
- <unit id="org.eclipse.jetty.http" version="9.4.20.v20190813"/>
- <unit id="org.eclipse.jetty.http.source" version="9.4.20.v20190813"/>
- <unit id="org.eclipse.jetty.io" version="9.4.20.v20190813"/>
- <unit id="org.eclipse.jetty.io.source" version="9.4.20.v20190813"/>
- <unit id="org.eclipse.jetty.security" version="9.4.20.v20190813"/>
- <unit id="org.eclipse.jetty.security.source" version="9.4.20.v20190813"/>
- <unit id="org.eclipse.jetty.server" version="9.4.20.v20190813"/>
- <unit id="org.eclipse.jetty.server.source" version="9.4.20.v20190813"/>
- <unit id="org.eclipse.jetty.servlet" version="9.4.20.v20190813"/>
- <unit id="org.eclipse.jetty.servlet.source" version="9.4.20.v20190813"/>
- <unit id="org.eclipse.jetty.util" version="9.4.20.v20190813"/>
- <unit id="org.eclipse.jetty.util.source" version="9.4.20.v20190813"/>
- <repository id="jetty-9.4.20" location="https://archive.eclipse.org/jetty/updates/jetty-bundles-9.x/jetty-bundles-9.x/9.4.20.v20190813/"/>
+ <unit id="org.eclipse.jetty.client" version="9.4.22.v20191022"/>
+ <unit id="org.eclipse.jetty.client.source" version="9.4.22.v20191022"/>
+ <unit id="org.eclipse.jetty.continuation" version="9.4.22.v20191022"/>
+ <unit id="org.eclipse.jetty.continuation.source" version="9.4.22.v20191022"/>
+ <unit id="org.eclipse.jetty.http" version="9.4.22.v20191022"/>
+ <unit id="org.eclipse.jetty.http.source" version="9.4.22.v20191022"/>
+ <unit id="org.eclipse.jetty.io" version="9.4.22.v20191022"/>
+ <unit id="org.eclipse.jetty.io.source" version="9.4.22.v20191022"/>
+ <unit id="org.eclipse.jetty.security" version="9.4.22.v20191022"/>
+ <unit id="org.eclipse.jetty.security.source" version="9.4.22.v20191022"/>
+ <unit id="org.eclipse.jetty.server" version="9.4.22.v20191022"/>
+ <unit id="org.eclipse.jetty.server.source" version="9.4.22.v20191022"/>
+ <unit id="org.eclipse.jetty.servlet" version="9.4.22.v20191022"/>
+ <unit id="org.eclipse.jetty.servlet.source" version="9.4.22.v20191022"/>
+ <unit id="org.eclipse.jetty.util" version="9.4.22.v20191022"/>
+ <unit id="org.eclipse.jetty.util.source" version="9.4.22.v20191022"/>
+ <repository id="jetty-9.4.22" location="https://archive.eclipse.org/jetty/updates/jetty-bundles-9.x/jetty-bundles-9.x/9.4.22.v20191022/"/>
</location>
<location includeMode="slicer" includeAllPlatforms="false" includeSource="true" includeConfigurePhase="true" type="InstallableUnit">
<unit id="com.google.gson" version="2.8.2.v20180104-1110"/>
@@ -39,8 +39,8 @@
<unit id="net.bytebuddy.byte-buddy.source" version="1.9.0.v20181107-1410"/>
<unit id="net.i2p.crypto.eddsa" version="0.3.0.v20181102-1323"/>
<unit id="net.i2p.crypto.eddsa.source" version="0.3.0.v20181102-1323"/>
- <unit id="org.apache.ant" version="1.10.5.v20190526-1402"/>
- <unit id="org.apache.ant.source" version="1.10.5.v20190526-1402"/>
+ <unit id="org.apache.ant" version="1.10.7.v20190926-0324"/>
+ <unit id="org.apache.ant.source" version="1.10.7.v20190926-0324"/>
<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"/>
@@ -57,12 +57,12 @@
<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"/>
- <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.bouncycastle.bcpg" version="1.64.0.v20191109-0815"/>
+ <unit id="org.bouncycastle.bcpg.source" version="1.64.0.v20191109-0815"/>
+ <unit id="org.bouncycastle.bcpkix" version="1.64.0.v20191109-0815"/>
+ <unit id="org.bouncycastle.bcpkix.source" version="1.64.0.v20191109-0815"/>
+ <unit id="org.bouncycastle.bcprov" version="1.64.0.v20191109-0815"/>
+ <unit id="org.bouncycastle.bcprov.source" version="1.64.0.v20191109-0815"/>
<unit id="org.hamcrest" version="1.1.0.v20090501071000"/>
<unit id="org.hamcrest.core" version="1.3.0.v20180420-1519"/>
<unit id="org.hamcrest.core.source" version="1.3.0.v20180420-1519"/>
@@ -82,7 +82,7 @@
<unit id="org.slf4j.impl.log4j12.source" version="1.7.2.v20131105-2200"/>
<unit id="org.tukaani.xz" version="1.8.0.v20180207-1613"/>
<unit id="org.tukaani.xz.source" version="1.8.0.v20180207-1613"/>
- <repository location="https://download.eclipse.org/tools/orbit/downloads/drops/R20190827152740/repository"/>
+ <repository location="https://download.eclipse.org/tools/orbit/downloads/drops/R20191126223242/repository"/>
</location>
<location includeMode="slicer" includeAllPlatforms="false" includeSource="true" includeConfigurePhase="true" type="InstallableUnit">
<unit id="org.eclipse.osgi" version="0.0.0"/>
diff --git a/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.10.tpd b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.10.tpd
index 8d0df4f..9eda6b0 100644
--- a/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.10.tpd
+++ b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.10.tpd
@@ -1,7 +1,7 @@
target "jgit-4.10" with source configurePhase
-include "projects/jetty-9.4.20.tpd"
-include "orbit/R20190827152740-2019-09.tpd"
+include "projects/jetty-9.4.22.tpd"
+include "orbit/R20191126223242-2019-12.tpd"
location "https://download.eclipse.org/releases/2018-12/" {
org.eclipse.osgi lazy
diff --git a/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.11.target b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.11.target
index 76fb1ef..0033f2b 100644
--- a/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.11.target
+++ b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.11.target
@@ -1,26 +1,26 @@
<?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="1638608437">
+<target name="jgit-4.11" sequenceNumber="1638636816">
<locations>
<location includeMode="slicer" includeAllPlatforms="false" includeSource="true" includeConfigurePhase="true" type="InstallableUnit">
- <unit id="org.eclipse.jetty.client" version="9.4.20.v20190813"/>
- <unit id="org.eclipse.jetty.client.source" version="9.4.20.v20190813"/>
- <unit id="org.eclipse.jetty.continuation" version="9.4.20.v20190813"/>
- <unit id="org.eclipse.jetty.continuation.source" version="9.4.20.v20190813"/>
- <unit id="org.eclipse.jetty.http" version="9.4.20.v20190813"/>
- <unit id="org.eclipse.jetty.http.source" version="9.4.20.v20190813"/>
- <unit id="org.eclipse.jetty.io" version="9.4.20.v20190813"/>
- <unit id="org.eclipse.jetty.io.source" version="9.4.20.v20190813"/>
- <unit id="org.eclipse.jetty.security" version="9.4.20.v20190813"/>
- <unit id="org.eclipse.jetty.security.source" version="9.4.20.v20190813"/>
- <unit id="org.eclipse.jetty.server" version="9.4.20.v20190813"/>
- <unit id="org.eclipse.jetty.server.source" version="9.4.20.v20190813"/>
- <unit id="org.eclipse.jetty.servlet" version="9.4.20.v20190813"/>
- <unit id="org.eclipse.jetty.servlet.source" version="9.4.20.v20190813"/>
- <unit id="org.eclipse.jetty.util" version="9.4.20.v20190813"/>
- <unit id="org.eclipse.jetty.util.source" version="9.4.20.v20190813"/>
- <repository id="jetty-9.4.20" location="https://archive.eclipse.org/jetty/updates/jetty-bundles-9.x/jetty-bundles-9.x/9.4.20.v20190813/"/>
+ <unit id="org.eclipse.jetty.client" version="9.4.22.v20191022"/>
+ <unit id="org.eclipse.jetty.client.source" version="9.4.22.v20191022"/>
+ <unit id="org.eclipse.jetty.continuation" version="9.4.22.v20191022"/>
+ <unit id="org.eclipse.jetty.continuation.source" version="9.4.22.v20191022"/>
+ <unit id="org.eclipse.jetty.http" version="9.4.22.v20191022"/>
+ <unit id="org.eclipse.jetty.http.source" version="9.4.22.v20191022"/>
+ <unit id="org.eclipse.jetty.io" version="9.4.22.v20191022"/>
+ <unit id="org.eclipse.jetty.io.source" version="9.4.22.v20191022"/>
+ <unit id="org.eclipse.jetty.security" version="9.4.22.v20191022"/>
+ <unit id="org.eclipse.jetty.security.source" version="9.4.22.v20191022"/>
+ <unit id="org.eclipse.jetty.server" version="9.4.22.v20191022"/>
+ <unit id="org.eclipse.jetty.server.source" version="9.4.22.v20191022"/>
+ <unit id="org.eclipse.jetty.servlet" version="9.4.22.v20191022"/>
+ <unit id="org.eclipse.jetty.servlet.source" version="9.4.22.v20191022"/>
+ <unit id="org.eclipse.jetty.util" version="9.4.22.v20191022"/>
+ <unit id="org.eclipse.jetty.util.source" version="9.4.22.v20191022"/>
+ <repository id="jetty-9.4.22" location="https://archive.eclipse.org/jetty/updates/jetty-bundles-9.x/jetty-bundles-9.x/9.4.22.v20191022/"/>
</location>
<location includeMode="slicer" includeAllPlatforms="false" includeSource="true" includeConfigurePhase="true" type="InstallableUnit">
<unit id="com.google.gson" version="2.8.2.v20180104-1110"/>
@@ -39,8 +39,8 @@
<unit id="net.bytebuddy.byte-buddy.source" version="1.9.0.v20181107-1410"/>
<unit id="net.i2p.crypto.eddsa" version="0.3.0.v20181102-1323"/>
<unit id="net.i2p.crypto.eddsa.source" version="0.3.0.v20181102-1323"/>
- <unit id="org.apache.ant" version="1.10.5.v20190526-1402"/>
- <unit id="org.apache.ant.source" version="1.10.5.v20190526-1402"/>
+ <unit id="org.apache.ant" version="1.10.7.v20190926-0324"/>
+ <unit id="org.apache.ant.source" version="1.10.7.v20190926-0324"/>
<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"/>
@@ -57,12 +57,12 @@
<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"/>
- <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.bouncycastle.bcpg" version="1.64.0.v20191109-0815"/>
+ <unit id="org.bouncycastle.bcpg.source" version="1.64.0.v20191109-0815"/>
+ <unit id="org.bouncycastle.bcpkix" version="1.64.0.v20191109-0815"/>
+ <unit id="org.bouncycastle.bcpkix.source" version="1.64.0.v20191109-0815"/>
+ <unit id="org.bouncycastle.bcprov" version="1.64.0.v20191109-0815"/>
+ <unit id="org.bouncycastle.bcprov.source" version="1.64.0.v20191109-0815"/>
<unit id="org.hamcrest" version="1.1.0.v20090501071000"/>
<unit id="org.hamcrest.core" version="1.3.0.v20180420-1519"/>
<unit id="org.hamcrest.core.source" version="1.3.0.v20180420-1519"/>
@@ -82,7 +82,7 @@
<unit id="org.slf4j.impl.log4j12.source" version="1.7.2.v20131105-2200"/>
<unit id="org.tukaani.xz" version="1.8.0.v20180207-1613"/>
<unit id="org.tukaani.xz.source" version="1.8.0.v20180207-1613"/>
- <repository location="https://download.eclipse.org/tools/orbit/downloads/drops/R20190827152740/repository"/>
+ <repository location="https://download.eclipse.org/tools/orbit/downloads/drops/R20191126223242/repository"/>
</location>
<location includeMode="slicer" includeAllPlatforms="false" includeSource="true" includeConfigurePhase="true" type="InstallableUnit">
<unit id="org.eclipse.osgi" version="0.0.0"/>
diff --git a/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.11.tpd b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.11.tpd
index 92eba15..ed0e01b 100644
--- a/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.11.tpd
+++ b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.11.tpd
@@ -1,7 +1,7 @@
target "jgit-4.11" with source configurePhase
-include "projects/jetty-9.4.20.tpd"
-include "orbit/R20190827152740-2019-09.tpd"
+include "projects/jetty-9.4.22.tpd"
+include "orbit/R20191126223242-2019-12.tpd"
location "https://download.eclipse.org/releases/2019-03/" {
org.eclipse.osgi lazy
diff --git a/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.12.target b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.12.target
index 8279a30..c39fbe0 100644
--- a/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.12.target
+++ b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.12.target
@@ -1,26 +1,26 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<?pde?>
<!-- generated with https://github.com/eclipse-cbi/targetplatform-dsl -->
-<target name="jgit-4.12" sequenceNumber="1638608437">
+<target name="jgit-4.12" sequenceNumber="1638636816">
<locations>
<location includeMode="slicer" includeAllPlatforms="false" includeSource="true" includeConfigurePhase="true" type="InstallableUnit">
- <unit id="org.eclipse.jetty.client" version="9.4.20.v20190813"/>
- <unit id="org.eclipse.jetty.client.source" version="9.4.20.v20190813"/>
- <unit id="org.eclipse.jetty.continuation" version="9.4.20.v20190813"/>
- <unit id="org.eclipse.jetty.continuation.source" version="9.4.20.v20190813"/>
- <unit id="org.eclipse.jetty.http" version="9.4.20.v20190813"/>
- <unit id="org.eclipse.jetty.http.source" version="9.4.20.v20190813"/>
- <unit id="org.eclipse.jetty.io" version="9.4.20.v20190813"/>
- <unit id="org.eclipse.jetty.io.source" version="9.4.20.v20190813"/>
- <unit id="org.eclipse.jetty.security" version="9.4.20.v20190813"/>
- <unit id="org.eclipse.jetty.security.source" version="9.4.20.v20190813"/>
- <unit id="org.eclipse.jetty.server" version="9.4.20.v20190813"/>
- <unit id="org.eclipse.jetty.server.source" version="9.4.20.v20190813"/>
- <unit id="org.eclipse.jetty.servlet" version="9.4.20.v20190813"/>
- <unit id="org.eclipse.jetty.servlet.source" version="9.4.20.v20190813"/>
- <unit id="org.eclipse.jetty.util" version="9.4.20.v20190813"/>
- <unit id="org.eclipse.jetty.util.source" version="9.4.20.v20190813"/>
- <repository id="jetty-9.4.20" location="https://archive.eclipse.org/jetty/updates/jetty-bundles-9.x/jetty-bundles-9.x/9.4.20.v20190813/"/>
+ <unit id="org.eclipse.jetty.client" version="9.4.22.v20191022"/>
+ <unit id="org.eclipse.jetty.client.source" version="9.4.22.v20191022"/>
+ <unit id="org.eclipse.jetty.continuation" version="9.4.22.v20191022"/>
+ <unit id="org.eclipse.jetty.continuation.source" version="9.4.22.v20191022"/>
+ <unit id="org.eclipse.jetty.http" version="9.4.22.v20191022"/>
+ <unit id="org.eclipse.jetty.http.source" version="9.4.22.v20191022"/>
+ <unit id="org.eclipse.jetty.io" version="9.4.22.v20191022"/>
+ <unit id="org.eclipse.jetty.io.source" version="9.4.22.v20191022"/>
+ <unit id="org.eclipse.jetty.security" version="9.4.22.v20191022"/>
+ <unit id="org.eclipse.jetty.security.source" version="9.4.22.v20191022"/>
+ <unit id="org.eclipse.jetty.server" version="9.4.22.v20191022"/>
+ <unit id="org.eclipse.jetty.server.source" version="9.4.22.v20191022"/>
+ <unit id="org.eclipse.jetty.servlet" version="9.4.22.v20191022"/>
+ <unit id="org.eclipse.jetty.servlet.source" version="9.4.22.v20191022"/>
+ <unit id="org.eclipse.jetty.util" version="9.4.22.v20191022"/>
+ <unit id="org.eclipse.jetty.util.source" version="9.4.22.v20191022"/>
+ <repository id="jetty-9.4.22" location="https://archive.eclipse.org/jetty/updates/jetty-bundles-9.x/jetty-bundles-9.x/9.4.22.v20191022/"/>
</location>
<location includeMode="slicer" includeAllPlatforms="false" includeSource="true" includeConfigurePhase="true" type="InstallableUnit">
<unit id="com.google.gson" version="2.8.2.v20180104-1110"/>
@@ -39,8 +39,8 @@
<unit id="net.bytebuddy.byte-buddy.source" version="1.9.0.v20181107-1410"/>
<unit id="net.i2p.crypto.eddsa" version="0.3.0.v20181102-1323"/>
<unit id="net.i2p.crypto.eddsa.source" version="0.3.0.v20181102-1323"/>
- <unit id="org.apache.ant" version="1.10.5.v20190526-1402"/>
- <unit id="org.apache.ant.source" version="1.10.5.v20190526-1402"/>
+ <unit id="org.apache.ant" version="1.10.7.v20190926-0324"/>
+ <unit id="org.apache.ant.source" version="1.10.7.v20190926-0324"/>
<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"/>
@@ -57,12 +57,12 @@
<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"/>
- <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.bouncycastle.bcpg" version="1.64.0.v20191109-0815"/>
+ <unit id="org.bouncycastle.bcpg.source" version="1.64.0.v20191109-0815"/>
+ <unit id="org.bouncycastle.bcpkix" version="1.64.0.v20191109-0815"/>
+ <unit id="org.bouncycastle.bcpkix.source" version="1.64.0.v20191109-0815"/>
+ <unit id="org.bouncycastle.bcprov" version="1.64.0.v20191109-0815"/>
+ <unit id="org.bouncycastle.bcprov.source" version="1.64.0.v20191109-0815"/>
<unit id="org.hamcrest" version="1.1.0.v20090501071000"/>
<unit id="org.hamcrest.core" version="1.3.0.v20180420-1519"/>
<unit id="org.hamcrest.core.source" version="1.3.0.v20180420-1519"/>
@@ -82,7 +82,7 @@
<unit id="org.slf4j.impl.log4j12.source" version="1.7.2.v20131105-2200"/>
<unit id="org.tukaani.xz" version="1.8.0.v20180207-1613"/>
<unit id="org.tukaani.xz.source" version="1.8.0.v20180207-1613"/>
- <repository location="https://download.eclipse.org/tools/orbit/downloads/drops/R20190827152740/repository"/>
+ <repository location="https://download.eclipse.org/tools/orbit/downloads/drops/R20191126223242/repository"/>
</location>
<location includeMode="slicer" includeAllPlatforms="false" includeSource="true" includeConfigurePhase="true" type="InstallableUnit">
<unit id="org.eclipse.osgi" version="0.0.0"/>
diff --git a/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.12.tpd b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.12.tpd
index 36d7110..6232167 100644
--- a/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.12.tpd
+++ b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.12.tpd
@@ -1,7 +1,7 @@
target "jgit-4.12" with source configurePhase
-include "projects/jetty-9.4.20.tpd"
-include "orbit/R20190827152740-2019-09.tpd"
+include "projects/jetty-9.4.22.tpd"
+include "orbit/R20191126223242-2019-12.tpd"
location "https://download.eclipse.org/releases/2019-06/" {
org.eclipse.osgi lazy
diff --git a/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.13.target b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.13.target
index 5c7c025..f3d955a 100644
--- a/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.13.target
+++ b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.13.target
@@ -1,26 +1,26 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<?pde?>
<!-- generated with https://github.com/eclipse-cbi/targetplatform-dsl -->
-<target name="jgit-4.13" sequenceNumber="1638608439">
+<target name="jgit-4.13" sequenceNumber="1638636816">
<locations>
<location includeMode="slicer" includeAllPlatforms="false" includeSource="true" includeConfigurePhase="true" type="InstallableUnit">
- <unit id="org.eclipse.jetty.client" version="9.4.20.v20190813"/>
- <unit id="org.eclipse.jetty.client.source" version="9.4.20.v20190813"/>
- <unit id="org.eclipse.jetty.continuation" version="9.4.20.v20190813"/>
- <unit id="org.eclipse.jetty.continuation.source" version="9.4.20.v20190813"/>
- <unit id="org.eclipse.jetty.http" version="9.4.20.v20190813"/>
- <unit id="org.eclipse.jetty.http.source" version="9.4.20.v20190813"/>
- <unit id="org.eclipse.jetty.io" version="9.4.20.v20190813"/>
- <unit id="org.eclipse.jetty.io.source" version="9.4.20.v20190813"/>
- <unit id="org.eclipse.jetty.security" version="9.4.20.v20190813"/>
- <unit id="org.eclipse.jetty.security.source" version="9.4.20.v20190813"/>
- <unit id="org.eclipse.jetty.server" version="9.4.20.v20190813"/>
- <unit id="org.eclipse.jetty.server.source" version="9.4.20.v20190813"/>
- <unit id="org.eclipse.jetty.servlet" version="9.4.20.v20190813"/>
- <unit id="org.eclipse.jetty.servlet.source" version="9.4.20.v20190813"/>
- <unit id="org.eclipse.jetty.util" version="9.4.20.v20190813"/>
- <unit id="org.eclipse.jetty.util.source" version="9.4.20.v20190813"/>
- <repository id="jetty-9.4.20" location="https://archive.eclipse.org/jetty/updates/jetty-bundles-9.x/jetty-bundles-9.x/9.4.20.v20190813/"/>
+ <unit id="org.eclipse.jetty.client" version="9.4.22.v20191022"/>
+ <unit id="org.eclipse.jetty.client.source" version="9.4.22.v20191022"/>
+ <unit id="org.eclipse.jetty.continuation" version="9.4.22.v20191022"/>
+ <unit id="org.eclipse.jetty.continuation.source" version="9.4.22.v20191022"/>
+ <unit id="org.eclipse.jetty.http" version="9.4.22.v20191022"/>
+ <unit id="org.eclipse.jetty.http.source" version="9.4.22.v20191022"/>
+ <unit id="org.eclipse.jetty.io" version="9.4.22.v20191022"/>
+ <unit id="org.eclipse.jetty.io.source" version="9.4.22.v20191022"/>
+ <unit id="org.eclipse.jetty.security" version="9.4.22.v20191022"/>
+ <unit id="org.eclipse.jetty.security.source" version="9.4.22.v20191022"/>
+ <unit id="org.eclipse.jetty.server" version="9.4.22.v20191022"/>
+ <unit id="org.eclipse.jetty.server.source" version="9.4.22.v20191022"/>
+ <unit id="org.eclipse.jetty.servlet" version="9.4.22.v20191022"/>
+ <unit id="org.eclipse.jetty.servlet.source" version="9.4.22.v20191022"/>
+ <unit id="org.eclipse.jetty.util" version="9.4.22.v20191022"/>
+ <unit id="org.eclipse.jetty.util.source" version="9.4.22.v20191022"/>
+ <repository id="jetty-9.4.22" location="https://archive.eclipse.org/jetty/updates/jetty-bundles-9.x/jetty-bundles-9.x/9.4.22.v20191022/"/>
</location>
<location includeMode="slicer" includeAllPlatforms="false" includeSource="true" includeConfigurePhase="true" type="InstallableUnit">
<unit id="com.google.gson" version="2.8.2.v20180104-1110"/>
@@ -39,8 +39,8 @@
<unit id="net.bytebuddy.byte-buddy.source" version="1.9.0.v20181107-1410"/>
<unit id="net.i2p.crypto.eddsa" version="0.3.0.v20181102-1323"/>
<unit id="net.i2p.crypto.eddsa.source" version="0.3.0.v20181102-1323"/>
- <unit id="org.apache.ant" version="1.10.5.v20190526-1402"/>
- <unit id="org.apache.ant.source" version="1.10.5.v20190526-1402"/>
+ <unit id="org.apache.ant" version="1.10.7.v20190926-0324"/>
+ <unit id="org.apache.ant.source" version="1.10.7.v20190926-0324"/>
<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"/>
@@ -57,12 +57,12 @@
<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"/>
- <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.bouncycastle.bcpg" version="1.64.0.v20191109-0815"/>
+ <unit id="org.bouncycastle.bcpg.source" version="1.64.0.v20191109-0815"/>
+ <unit id="org.bouncycastle.bcpkix" version="1.64.0.v20191109-0815"/>
+ <unit id="org.bouncycastle.bcpkix.source" version="1.64.0.v20191109-0815"/>
+ <unit id="org.bouncycastle.bcprov" version="1.64.0.v20191109-0815"/>
+ <unit id="org.bouncycastle.bcprov.source" version="1.64.0.v20191109-0815"/>
<unit id="org.hamcrest" version="1.1.0.v20090501071000"/>
<unit id="org.hamcrest.core" version="1.3.0.v20180420-1519"/>
<unit id="org.hamcrest.core.source" version="1.3.0.v20180420-1519"/>
@@ -82,7 +82,7 @@
<unit id="org.slf4j.impl.log4j12.source" version="1.7.2.v20131105-2200"/>
<unit id="org.tukaani.xz" version="1.8.0.v20180207-1613"/>
<unit id="org.tukaani.xz.source" version="1.8.0.v20180207-1613"/>
- <repository location="https://download.eclipse.org/tools/orbit/downloads/drops/R20190827152740/repository"/>
+ <repository location="https://download.eclipse.org/tools/orbit/downloads/drops/R20191126223242/repository"/>
</location>
<location includeMode="slicer" includeAllPlatforms="false" includeSource="true" includeConfigurePhase="true" type="InstallableUnit">
<unit id="org.eclipse.osgi" version="0.0.0"/>
diff --git a/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.13.tpd b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.13.tpd
index 7eb4649..ff8c6d0 100644
--- a/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.13.tpd
+++ b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.13.tpd
@@ -1,7 +1,7 @@
target "jgit-4.13" with source configurePhase
-include "projects/jetty-9.4.20.tpd"
-include "orbit/R20190827152740-2019-09.tpd"
+include "projects/jetty-9.4.22.tpd"
+include "orbit/R20191126223242-2019-12.tpd"
location "https://download.eclipse.org/releases/2019-09/" {
org.eclipse.osgi lazy
diff --git a/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.14.target b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.14.target
new file mode 100644
index 0000000..fa52a85
--- /dev/null
+++ b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.14.target
@@ -0,0 +1,92 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<?pde?>
+<!-- generated with https://github.com/eclipse-cbi/targetplatform-dsl -->
+<target name="jgit-4.14" sequenceNumber="1638636816">
+ <locations>
+ <location includeMode="slicer" includeAllPlatforms="false" includeSource="true" includeConfigurePhase="true" type="InstallableUnit">
+ <unit id="org.eclipse.jetty.client" version="9.4.22.v20191022"/>
+ <unit id="org.eclipse.jetty.client.source" version="9.4.22.v20191022"/>
+ <unit id="org.eclipse.jetty.continuation" version="9.4.22.v20191022"/>
+ <unit id="org.eclipse.jetty.continuation.source" version="9.4.22.v20191022"/>
+ <unit id="org.eclipse.jetty.http" version="9.4.22.v20191022"/>
+ <unit id="org.eclipse.jetty.http.source" version="9.4.22.v20191022"/>
+ <unit id="org.eclipse.jetty.io" version="9.4.22.v20191022"/>
+ <unit id="org.eclipse.jetty.io.source" version="9.4.22.v20191022"/>
+ <unit id="org.eclipse.jetty.security" version="9.4.22.v20191022"/>
+ <unit id="org.eclipse.jetty.security.source" version="9.4.22.v20191022"/>
+ <unit id="org.eclipse.jetty.server" version="9.4.22.v20191022"/>
+ <unit id="org.eclipse.jetty.server.source" version="9.4.22.v20191022"/>
+ <unit id="org.eclipse.jetty.servlet" version="9.4.22.v20191022"/>
+ <unit id="org.eclipse.jetty.servlet.source" version="9.4.22.v20191022"/>
+ <unit id="org.eclipse.jetty.util" version="9.4.22.v20191022"/>
+ <unit id="org.eclipse.jetty.util.source" version="9.4.22.v20191022"/>
+ <repository id="jetty-9.4.22" location="https://archive.eclipse.org/jetty/updates/jetty-bundles-9.x/jetty-bundles-9.x/9.4.22.v20191022/"/>
+ </location>
+ <location includeMode="slicer" includeAllPlatforms="false" includeSource="true" includeConfigurePhase="true" type="InstallableUnit">
+ <unit id="com.google.gson" version="2.8.2.v20180104-1110"/>
+ <unit id="com.google.gson.source" version="2.8.2.v20180104-1110"/>
+ <unit id="com.jcraft.jsch" version="0.1.55.v20190404-1902"/>
+ <unit id="com.jcraft.jsch.source" version="0.1.55.v20190404-1902"/>
+ <unit id="com.jcraft.jzlib" version="1.1.1.v201205102305"/>
+ <unit id="com.jcraft.jzlib.source" version="1.1.1.v201205102305"/>
+ <unit id="javaewah" version="1.1.6.v20160919-1400"/>
+ <unit id="javaewah.source" version="1.1.6.v20160919-1400"/>
+ <unit id="javax.servlet" version="3.1.0.v201410161800"/>
+ <unit id="javax.servlet.source" version="3.1.0.v201410161800"/>
+ <unit id="net.bytebuddy.byte-buddy" version="1.9.0.v20181107-1410"/>
+ <unit id="net.bytebuddy.byte-buddy-agent" version="1.9.0.v20181106-1534"/>
+ <unit id="net.bytebuddy.byte-buddy-agent.source" version="1.9.0.v20181106-1534"/>
+ <unit id="net.bytebuddy.byte-buddy.source" version="1.9.0.v20181107-1410"/>
+ <unit id="net.i2p.crypto.eddsa" version="0.3.0.v20181102-1323"/>
+ <unit id="net.i2p.crypto.eddsa.source" version="0.3.0.v20181102-1323"/>
+ <unit id="org.apache.ant" version="1.10.7.v20190926-0324"/>
+ <unit id="org.apache.ant.source" version="1.10.7.v20190926-0324"/>
+ <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"/>
+ <unit id="org.apache.commons.compress.source" version="1.18.0.v20181121-2221"/>
+ <unit id="org.apache.commons.logging" version="1.2.0.v20180409-1502"/>
+ <unit id="org.apache.commons.logging.source" version="1.2.0.v20180409-1502"/>
+ <unit id="org.apache.httpcomponents.httpclient" version="4.5.6.v20190503-0009"/>
+ <unit id="org.apache.httpcomponents.httpclient.source" version="4.5.6.v20190503-0009"/>
+ <unit id="org.apache.httpcomponents.httpcore" version="4.4.10.v20190123-2214"/>
+ <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.apache.sshd.osgi" version="2.2.0.v20190425-2127"/>
+ <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"/>
+ <unit id="org.bouncycastle.bcpg" version="1.64.0.v20191109-0815"/>
+ <unit id="org.bouncycastle.bcpg.source" version="1.64.0.v20191109-0815"/>
+ <unit id="org.bouncycastle.bcpkix" version="1.64.0.v20191109-0815"/>
+ <unit id="org.bouncycastle.bcpkix.source" version="1.64.0.v20191109-0815"/>
+ <unit id="org.bouncycastle.bcprov" version="1.64.0.v20191109-0815"/>
+ <unit id="org.bouncycastle.bcprov.source" version="1.64.0.v20191109-0815"/>
+ <unit id="org.hamcrest" version="1.1.0.v20090501071000"/>
+ <unit id="org.hamcrest.core" version="1.3.0.v20180420-1519"/>
+ <unit id="org.hamcrest.core.source" version="1.3.0.v20180420-1519"/>
+ <unit id="org.hamcrest.library" version="1.3.0.v20180524-2246"/>
+ <unit id="org.hamcrest.library.source" version="1.3.0.v20180524-2246"/>
+ <unit id="org.junit" version="4.12.0.v201504281640"/>
+ <unit id="org.junit.source" version="4.12.0.v201504281640"/>
+ <unit id="org.kohsuke.args4j" version="2.33.0.v20160323-2218"/>
+ <unit id="org.kohsuke.args4j.source" version="2.33.0.v20160323-2218"/>
+ <unit id="org.mockito" version="2.23.0.v20190527-1420"/>
+ <unit id="org.mockito.source" version="2.23.0.v20190527-1420"/>
+ <unit id="org.objenesis" version="2.6.0.v20180420-1519"/>
+ <unit id="org.objenesis.source" version="2.6.0.v20180420-1519"/>
+ <unit id="org.slf4j.api" version="1.7.2.v20121108-1250"/>
+ <unit id="org.slf4j.api.source" version="1.7.2.v20121108-1250"/>
+ <unit id="org.slf4j.impl.log4j12" version="1.7.2.v20131105-2200"/>
+ <unit id="org.slf4j.impl.log4j12.source" version="1.7.2.v20131105-2200"/>
+ <unit id="org.tukaani.xz" version="1.8.0.v20180207-1613"/>
+ <unit id="org.tukaani.xz.source" version="1.8.0.v20180207-1613"/>
+ <repository location="https://download.eclipse.org/tools/orbit/downloads/drops/R20191126223242/repository"/>
+ </location>
+ <location includeMode="slicer" includeAllPlatforms="false" includeSource="true" includeConfigurePhase="true" type="InstallableUnit">
+ <unit id="org.eclipse.osgi" version="0.0.0"/>
+ <repository location="https://download.eclipse.org/releases/2019-12/"/>
+ </location>
+ </locations>
+</target>
diff --git a/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.14.tpd b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.14.tpd
new file mode 100644
index 0000000..99fa6e3
--- /dev/null
+++ b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.14.tpd
@@ -0,0 +1,8 @@
+target "jgit-4.14" with source configurePhase
+
+include "projects/jetty-9.4.22.tpd"
+include "orbit/R20191126223242-2019-12.tpd"
+
+location "https://download.eclipse.org/releases/2019-12/" {
+ org.eclipse.osgi lazy
+}
diff --git a/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.6.target b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.6.target
index 72a9c97..cd72a5b 100644
--- a/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.6.target
+++ b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.6.target
@@ -1,26 +1,26 @@
<?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="1638608437">
+<target name="jgit-4.6" sequenceNumber="1638636816">
<locations>
<location includeMode="slicer" includeAllPlatforms="false" includeSource="true" includeConfigurePhase="true" type="InstallableUnit">
- <unit id="org.eclipse.jetty.client" version="9.4.20.v20190813"/>
- <unit id="org.eclipse.jetty.client.source" version="9.4.20.v20190813"/>
- <unit id="org.eclipse.jetty.continuation" version="9.4.20.v20190813"/>
- <unit id="org.eclipse.jetty.continuation.source" version="9.4.20.v20190813"/>
- <unit id="org.eclipse.jetty.http" version="9.4.20.v20190813"/>
- <unit id="org.eclipse.jetty.http.source" version="9.4.20.v20190813"/>
- <unit id="org.eclipse.jetty.io" version="9.4.20.v20190813"/>
- <unit id="org.eclipse.jetty.io.source" version="9.4.20.v20190813"/>
- <unit id="org.eclipse.jetty.security" version="9.4.20.v20190813"/>
- <unit id="org.eclipse.jetty.security.source" version="9.4.20.v20190813"/>
- <unit id="org.eclipse.jetty.server" version="9.4.20.v20190813"/>
- <unit id="org.eclipse.jetty.server.source" version="9.4.20.v20190813"/>
- <unit id="org.eclipse.jetty.servlet" version="9.4.20.v20190813"/>
- <unit id="org.eclipse.jetty.servlet.source" version="9.4.20.v20190813"/>
- <unit id="org.eclipse.jetty.util" version="9.4.20.v20190813"/>
- <unit id="org.eclipse.jetty.util.source" version="9.4.20.v20190813"/>
- <repository id="jetty-9.4.20" location="https://archive.eclipse.org/jetty/updates/jetty-bundles-9.x/jetty-bundles-9.x/9.4.20.v20190813/"/>
+ <unit id="org.eclipse.jetty.client" version="9.4.22.v20191022"/>
+ <unit id="org.eclipse.jetty.client.source" version="9.4.22.v20191022"/>
+ <unit id="org.eclipse.jetty.continuation" version="9.4.22.v20191022"/>
+ <unit id="org.eclipse.jetty.continuation.source" version="9.4.22.v20191022"/>
+ <unit id="org.eclipse.jetty.http" version="9.4.22.v20191022"/>
+ <unit id="org.eclipse.jetty.http.source" version="9.4.22.v20191022"/>
+ <unit id="org.eclipse.jetty.io" version="9.4.22.v20191022"/>
+ <unit id="org.eclipse.jetty.io.source" version="9.4.22.v20191022"/>
+ <unit id="org.eclipse.jetty.security" version="9.4.22.v20191022"/>
+ <unit id="org.eclipse.jetty.security.source" version="9.4.22.v20191022"/>
+ <unit id="org.eclipse.jetty.server" version="9.4.22.v20191022"/>
+ <unit id="org.eclipse.jetty.server.source" version="9.4.22.v20191022"/>
+ <unit id="org.eclipse.jetty.servlet" version="9.4.22.v20191022"/>
+ <unit id="org.eclipse.jetty.servlet.source" version="9.4.22.v20191022"/>
+ <unit id="org.eclipse.jetty.util" version="9.4.22.v20191022"/>
+ <unit id="org.eclipse.jetty.util.source" version="9.4.22.v20191022"/>
+ <repository id="jetty-9.4.22" location="https://archive.eclipse.org/jetty/updates/jetty-bundles-9.x/jetty-bundles-9.x/9.4.22.v20191022/"/>
</location>
<location includeMode="slicer" includeAllPlatforms="false" includeSource="true" includeConfigurePhase="true" type="InstallableUnit">
<unit id="com.google.gson" version="2.8.2.v20180104-1110"/>
@@ -39,8 +39,8 @@
<unit id="net.bytebuddy.byte-buddy.source" version="1.9.0.v20181107-1410"/>
<unit id="net.i2p.crypto.eddsa" version="0.3.0.v20181102-1323"/>
<unit id="net.i2p.crypto.eddsa.source" version="0.3.0.v20181102-1323"/>
- <unit id="org.apache.ant" version="1.10.5.v20190526-1402"/>
- <unit id="org.apache.ant.source" version="1.10.5.v20190526-1402"/>
+ <unit id="org.apache.ant" version="1.10.7.v20190926-0324"/>
+ <unit id="org.apache.ant.source" version="1.10.7.v20190926-0324"/>
<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"/>
@@ -57,12 +57,12 @@
<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"/>
- <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.bouncycastle.bcpg" version="1.64.0.v20191109-0815"/>
+ <unit id="org.bouncycastle.bcpg.source" version="1.64.0.v20191109-0815"/>
+ <unit id="org.bouncycastle.bcpkix" version="1.64.0.v20191109-0815"/>
+ <unit id="org.bouncycastle.bcpkix.source" version="1.64.0.v20191109-0815"/>
+ <unit id="org.bouncycastle.bcprov" version="1.64.0.v20191109-0815"/>
+ <unit id="org.bouncycastle.bcprov.source" version="1.64.0.v20191109-0815"/>
<unit id="org.hamcrest" version="1.1.0.v20090501071000"/>
<unit id="org.hamcrest.core" version="1.3.0.v20180420-1519"/>
<unit id="org.hamcrest.core.source" version="1.3.0.v20180420-1519"/>
@@ -82,7 +82,7 @@
<unit id="org.slf4j.impl.log4j12.source" version="1.7.2.v20131105-2200"/>
<unit id="org.tukaani.xz" version="1.8.0.v20180207-1613"/>
<unit id="org.tukaani.xz.source" version="1.8.0.v20180207-1613"/>
- <repository location="https://download.eclipse.org/tools/orbit/downloads/drops/R20190827152740/repository"/>
+ <repository location="https://download.eclipse.org/tools/orbit/downloads/drops/R20191126223242/repository"/>
</location>
<location includeMode="slicer" includeAllPlatforms="false" includeSource="true" includeConfigurePhase="true" type="InstallableUnit">
<unit id="org.eclipse.osgi" version="0.0.0"/>
diff --git a/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.6.tpd b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.6.tpd
index a88a927..525ad81 100644
--- a/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.6.tpd
+++ b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.6.tpd
@@ -1,7 +1,7 @@
target "jgit-4.6" with source configurePhase
-include "projects/jetty-9.4.20.tpd"
-include "orbit/R20190827152740-2019-09.tpd"
+include "projects/jetty-9.4.22.tpd"
+include "orbit/R20191126223242-2019-12.tpd"
location "https://download.eclipse.org/releases/neon/" {
org.eclipse.osgi lazy
diff --git a/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.7.target b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.7.target
index a43101a..d9eba46 100644
--- a/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.7.target
+++ b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.7.target
@@ -1,26 +1,26 @@
<?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="1638608437">
+<target name="jgit-4.7" sequenceNumber="1638636816">
<locations>
<location includeMode="slicer" includeAllPlatforms="false" includeSource="true" includeConfigurePhase="true" type="InstallableUnit">
- <unit id="org.eclipse.jetty.client" version="9.4.20.v20190813"/>
- <unit id="org.eclipse.jetty.client.source" version="9.4.20.v20190813"/>
- <unit id="org.eclipse.jetty.continuation" version="9.4.20.v20190813"/>
- <unit id="org.eclipse.jetty.continuation.source" version="9.4.20.v20190813"/>
- <unit id="org.eclipse.jetty.http" version="9.4.20.v20190813"/>
- <unit id="org.eclipse.jetty.http.source" version="9.4.20.v20190813"/>
- <unit id="org.eclipse.jetty.io" version="9.4.20.v20190813"/>
- <unit id="org.eclipse.jetty.io.source" version="9.4.20.v20190813"/>
- <unit id="org.eclipse.jetty.security" version="9.4.20.v20190813"/>
- <unit id="org.eclipse.jetty.security.source" version="9.4.20.v20190813"/>
- <unit id="org.eclipse.jetty.server" version="9.4.20.v20190813"/>
- <unit id="org.eclipse.jetty.server.source" version="9.4.20.v20190813"/>
- <unit id="org.eclipse.jetty.servlet" version="9.4.20.v20190813"/>
- <unit id="org.eclipse.jetty.servlet.source" version="9.4.20.v20190813"/>
- <unit id="org.eclipse.jetty.util" version="9.4.20.v20190813"/>
- <unit id="org.eclipse.jetty.util.source" version="9.4.20.v20190813"/>
- <repository id="jetty-9.4.20" location="https://archive.eclipse.org/jetty/updates/jetty-bundles-9.x/jetty-bundles-9.x/9.4.20.v20190813/"/>
+ <unit id="org.eclipse.jetty.client" version="9.4.22.v20191022"/>
+ <unit id="org.eclipse.jetty.client.source" version="9.4.22.v20191022"/>
+ <unit id="org.eclipse.jetty.continuation" version="9.4.22.v20191022"/>
+ <unit id="org.eclipse.jetty.continuation.source" version="9.4.22.v20191022"/>
+ <unit id="org.eclipse.jetty.http" version="9.4.22.v20191022"/>
+ <unit id="org.eclipse.jetty.http.source" version="9.4.22.v20191022"/>
+ <unit id="org.eclipse.jetty.io" version="9.4.22.v20191022"/>
+ <unit id="org.eclipse.jetty.io.source" version="9.4.22.v20191022"/>
+ <unit id="org.eclipse.jetty.security" version="9.4.22.v20191022"/>
+ <unit id="org.eclipse.jetty.security.source" version="9.4.22.v20191022"/>
+ <unit id="org.eclipse.jetty.server" version="9.4.22.v20191022"/>
+ <unit id="org.eclipse.jetty.server.source" version="9.4.22.v20191022"/>
+ <unit id="org.eclipse.jetty.servlet" version="9.4.22.v20191022"/>
+ <unit id="org.eclipse.jetty.servlet.source" version="9.4.22.v20191022"/>
+ <unit id="org.eclipse.jetty.util" version="9.4.22.v20191022"/>
+ <unit id="org.eclipse.jetty.util.source" version="9.4.22.v20191022"/>
+ <repository id="jetty-9.4.22" location="https://archive.eclipse.org/jetty/updates/jetty-bundles-9.x/jetty-bundles-9.x/9.4.22.v20191022/"/>
</location>
<location includeMode="slicer" includeAllPlatforms="false" includeSource="true" includeConfigurePhase="true" type="InstallableUnit">
<unit id="com.google.gson" version="2.8.2.v20180104-1110"/>
@@ -39,8 +39,8 @@
<unit id="net.bytebuddy.byte-buddy.source" version="1.9.0.v20181107-1410"/>
<unit id="net.i2p.crypto.eddsa" version="0.3.0.v20181102-1323"/>
<unit id="net.i2p.crypto.eddsa.source" version="0.3.0.v20181102-1323"/>
- <unit id="org.apache.ant" version="1.10.5.v20190526-1402"/>
- <unit id="org.apache.ant.source" version="1.10.5.v20190526-1402"/>
+ <unit id="org.apache.ant" version="1.10.7.v20190926-0324"/>
+ <unit id="org.apache.ant.source" version="1.10.7.v20190926-0324"/>
<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"/>
@@ -57,12 +57,12 @@
<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"/>
- <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.bouncycastle.bcpg" version="1.64.0.v20191109-0815"/>
+ <unit id="org.bouncycastle.bcpg.source" version="1.64.0.v20191109-0815"/>
+ <unit id="org.bouncycastle.bcpkix" version="1.64.0.v20191109-0815"/>
+ <unit id="org.bouncycastle.bcpkix.source" version="1.64.0.v20191109-0815"/>
+ <unit id="org.bouncycastle.bcprov" version="1.64.0.v20191109-0815"/>
+ <unit id="org.bouncycastle.bcprov.source" version="1.64.0.v20191109-0815"/>
<unit id="org.hamcrest" version="1.1.0.v20090501071000"/>
<unit id="org.hamcrest.core" version="1.3.0.v20180420-1519"/>
<unit id="org.hamcrest.core.source" version="1.3.0.v20180420-1519"/>
@@ -82,7 +82,7 @@
<unit id="org.slf4j.impl.log4j12.source" version="1.7.2.v20131105-2200"/>
<unit id="org.tukaani.xz" version="1.8.0.v20180207-1613"/>
<unit id="org.tukaani.xz.source" version="1.8.0.v20180207-1613"/>
- <repository location="https://download.eclipse.org/tools/orbit/downloads/drops/R20190827152740/repository"/>
+ <repository location="https://download.eclipse.org/tools/orbit/downloads/drops/R20191126223242/repository"/>
</location>
<location includeMode="slicer" includeAllPlatforms="false" includeSource="true" includeConfigurePhase="true" type="InstallableUnit">
<unit id="org.eclipse.osgi" version="0.0.0"/>
diff --git a/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.7.tpd b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.7.tpd
index 38ae2b3..4cac2fd 100644
--- a/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.7.tpd
+++ b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.7.tpd
@@ -1,7 +1,7 @@
target "jgit-4.7" with source configurePhase
-include "projects/jetty-9.4.20.tpd"
-include "orbit/R20190827152740-2019-09.tpd"
+include "projects/jetty-9.4.22.tpd"
+include "orbit/R20191126223242-2019-12.tpd"
location "https://download.eclipse.org/releases/oxygen/" {
org.eclipse.osgi lazy
diff --git a/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.8.target b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.8.target
index cabc810..8cd1e24 100644
--- a/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.8.target
+++ b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.8.target
@@ -1,26 +1,26 @@
<?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="1638608437">
+<target name="jgit-4.8" sequenceNumber="1638636816">
<locations>
<location includeMode="slicer" includeAllPlatforms="false" includeSource="true" includeConfigurePhase="true" type="InstallableUnit">
- <unit id="org.eclipse.jetty.client" version="9.4.20.v20190813"/>
- <unit id="org.eclipse.jetty.client.source" version="9.4.20.v20190813"/>
- <unit id="org.eclipse.jetty.continuation" version="9.4.20.v20190813"/>
- <unit id="org.eclipse.jetty.continuation.source" version="9.4.20.v20190813"/>
- <unit id="org.eclipse.jetty.http" version="9.4.20.v20190813"/>
- <unit id="org.eclipse.jetty.http.source" version="9.4.20.v20190813"/>
- <unit id="org.eclipse.jetty.io" version="9.4.20.v20190813"/>
- <unit id="org.eclipse.jetty.io.source" version="9.4.20.v20190813"/>
- <unit id="org.eclipse.jetty.security" version="9.4.20.v20190813"/>
- <unit id="org.eclipse.jetty.security.source" version="9.4.20.v20190813"/>
- <unit id="org.eclipse.jetty.server" version="9.4.20.v20190813"/>
- <unit id="org.eclipse.jetty.server.source" version="9.4.20.v20190813"/>
- <unit id="org.eclipse.jetty.servlet" version="9.4.20.v20190813"/>
- <unit id="org.eclipse.jetty.servlet.source" version="9.4.20.v20190813"/>
- <unit id="org.eclipse.jetty.util" version="9.4.20.v20190813"/>
- <unit id="org.eclipse.jetty.util.source" version="9.4.20.v20190813"/>
- <repository id="jetty-9.4.20" location="https://archive.eclipse.org/jetty/updates/jetty-bundles-9.x/jetty-bundles-9.x/9.4.20.v20190813/"/>
+ <unit id="org.eclipse.jetty.client" version="9.4.22.v20191022"/>
+ <unit id="org.eclipse.jetty.client.source" version="9.4.22.v20191022"/>
+ <unit id="org.eclipse.jetty.continuation" version="9.4.22.v20191022"/>
+ <unit id="org.eclipse.jetty.continuation.source" version="9.4.22.v20191022"/>
+ <unit id="org.eclipse.jetty.http" version="9.4.22.v20191022"/>
+ <unit id="org.eclipse.jetty.http.source" version="9.4.22.v20191022"/>
+ <unit id="org.eclipse.jetty.io" version="9.4.22.v20191022"/>
+ <unit id="org.eclipse.jetty.io.source" version="9.4.22.v20191022"/>
+ <unit id="org.eclipse.jetty.security" version="9.4.22.v20191022"/>
+ <unit id="org.eclipse.jetty.security.source" version="9.4.22.v20191022"/>
+ <unit id="org.eclipse.jetty.server" version="9.4.22.v20191022"/>
+ <unit id="org.eclipse.jetty.server.source" version="9.4.22.v20191022"/>
+ <unit id="org.eclipse.jetty.servlet" version="9.4.22.v20191022"/>
+ <unit id="org.eclipse.jetty.servlet.source" version="9.4.22.v20191022"/>
+ <unit id="org.eclipse.jetty.util" version="9.4.22.v20191022"/>
+ <unit id="org.eclipse.jetty.util.source" version="9.4.22.v20191022"/>
+ <repository id="jetty-9.4.22" location="https://archive.eclipse.org/jetty/updates/jetty-bundles-9.x/jetty-bundles-9.x/9.4.22.v20191022/"/>
</location>
<location includeMode="slicer" includeAllPlatforms="false" includeSource="true" includeConfigurePhase="true" type="InstallableUnit">
<unit id="com.google.gson" version="2.8.2.v20180104-1110"/>
@@ -39,8 +39,8 @@
<unit id="net.bytebuddy.byte-buddy.source" version="1.9.0.v20181107-1410"/>
<unit id="net.i2p.crypto.eddsa" version="0.3.0.v20181102-1323"/>
<unit id="net.i2p.crypto.eddsa.source" version="0.3.0.v20181102-1323"/>
- <unit id="org.apache.ant" version="1.10.5.v20190526-1402"/>
- <unit id="org.apache.ant.source" version="1.10.5.v20190526-1402"/>
+ <unit id="org.apache.ant" version="1.10.7.v20190926-0324"/>
+ <unit id="org.apache.ant.source" version="1.10.7.v20190926-0324"/>
<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"/>
@@ -57,12 +57,12 @@
<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"/>
- <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.bouncycastle.bcpg" version="1.64.0.v20191109-0815"/>
+ <unit id="org.bouncycastle.bcpg.source" version="1.64.0.v20191109-0815"/>
+ <unit id="org.bouncycastle.bcpkix" version="1.64.0.v20191109-0815"/>
+ <unit id="org.bouncycastle.bcpkix.source" version="1.64.0.v20191109-0815"/>
+ <unit id="org.bouncycastle.bcprov" version="1.64.0.v20191109-0815"/>
+ <unit id="org.bouncycastle.bcprov.source" version="1.64.0.v20191109-0815"/>
<unit id="org.hamcrest" version="1.1.0.v20090501071000"/>
<unit id="org.hamcrest.core" version="1.3.0.v20180420-1519"/>
<unit id="org.hamcrest.core.source" version="1.3.0.v20180420-1519"/>
@@ -82,7 +82,7 @@
<unit id="org.slf4j.impl.log4j12.source" version="1.7.2.v20131105-2200"/>
<unit id="org.tukaani.xz" version="1.8.0.v20180207-1613"/>
<unit id="org.tukaani.xz.source" version="1.8.0.v20180207-1613"/>
- <repository location="https://download.eclipse.org/tools/orbit/downloads/drops/R20190827152740/repository"/>
+ <repository location="https://download.eclipse.org/tools/orbit/downloads/drops/R20191126223242/repository"/>
</location>
<location includeMode="slicer" includeAllPlatforms="false" includeSource="true" includeConfigurePhase="true" type="InstallableUnit">
<unit id="org.eclipse.osgi" version="0.0.0"/>
diff --git a/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.8.tpd b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.8.tpd
index 075525e..258442b 100644
--- a/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.8.tpd
+++ b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.8.tpd
@@ -1,7 +1,7 @@
target "jgit-4.8" with source configurePhase
-include "projects/jetty-9.4.20.tpd"
-include "orbit/R20190827152740-2019-09.tpd"
+include "projects/jetty-9.4.22.tpd"
+include "orbit/R20191126223242-2019-12.tpd"
location "https://download.eclipse.org/releases/photon/" {
org.eclipse.osgi lazy
diff --git a/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.9.target b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.9.target
index 3b2f005..637020d 100644
--- a/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.9.target
+++ b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.9.target
@@ -1,26 +1,26 @@
<?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="1638608437">
+<target name="jgit-4.9" sequenceNumber="1638636816">
<locations>
<location includeMode="slicer" includeAllPlatforms="false" includeSource="true" includeConfigurePhase="true" type="InstallableUnit">
- <unit id="org.eclipse.jetty.client" version="9.4.20.v20190813"/>
- <unit id="org.eclipse.jetty.client.source" version="9.4.20.v20190813"/>
- <unit id="org.eclipse.jetty.continuation" version="9.4.20.v20190813"/>
- <unit id="org.eclipse.jetty.continuation.source" version="9.4.20.v20190813"/>
- <unit id="org.eclipse.jetty.http" version="9.4.20.v20190813"/>
- <unit id="org.eclipse.jetty.http.source" version="9.4.20.v20190813"/>
- <unit id="org.eclipse.jetty.io" version="9.4.20.v20190813"/>
- <unit id="org.eclipse.jetty.io.source" version="9.4.20.v20190813"/>
- <unit id="org.eclipse.jetty.security" version="9.4.20.v20190813"/>
- <unit id="org.eclipse.jetty.security.source" version="9.4.20.v20190813"/>
- <unit id="org.eclipse.jetty.server" version="9.4.20.v20190813"/>
- <unit id="org.eclipse.jetty.server.source" version="9.4.20.v20190813"/>
- <unit id="org.eclipse.jetty.servlet" version="9.4.20.v20190813"/>
- <unit id="org.eclipse.jetty.servlet.source" version="9.4.20.v20190813"/>
- <unit id="org.eclipse.jetty.util" version="9.4.20.v20190813"/>
- <unit id="org.eclipse.jetty.util.source" version="9.4.20.v20190813"/>
- <repository id="jetty-9.4.20" location="https://archive.eclipse.org/jetty/updates/jetty-bundles-9.x/jetty-bundles-9.x/9.4.20.v20190813/"/>
+ <unit id="org.eclipse.jetty.client" version="9.4.22.v20191022"/>
+ <unit id="org.eclipse.jetty.client.source" version="9.4.22.v20191022"/>
+ <unit id="org.eclipse.jetty.continuation" version="9.4.22.v20191022"/>
+ <unit id="org.eclipse.jetty.continuation.source" version="9.4.22.v20191022"/>
+ <unit id="org.eclipse.jetty.http" version="9.4.22.v20191022"/>
+ <unit id="org.eclipse.jetty.http.source" version="9.4.22.v20191022"/>
+ <unit id="org.eclipse.jetty.io" version="9.4.22.v20191022"/>
+ <unit id="org.eclipse.jetty.io.source" version="9.4.22.v20191022"/>
+ <unit id="org.eclipse.jetty.security" version="9.4.22.v20191022"/>
+ <unit id="org.eclipse.jetty.security.source" version="9.4.22.v20191022"/>
+ <unit id="org.eclipse.jetty.server" version="9.4.22.v20191022"/>
+ <unit id="org.eclipse.jetty.server.source" version="9.4.22.v20191022"/>
+ <unit id="org.eclipse.jetty.servlet" version="9.4.22.v20191022"/>
+ <unit id="org.eclipse.jetty.servlet.source" version="9.4.22.v20191022"/>
+ <unit id="org.eclipse.jetty.util" version="9.4.22.v20191022"/>
+ <unit id="org.eclipse.jetty.util.source" version="9.4.22.v20191022"/>
+ <repository id="jetty-9.4.22" location="https://archive.eclipse.org/jetty/updates/jetty-bundles-9.x/jetty-bundles-9.x/9.4.22.v20191022/"/>
</location>
<location includeMode="slicer" includeAllPlatforms="false" includeSource="true" includeConfigurePhase="true" type="InstallableUnit">
<unit id="com.google.gson" version="2.8.2.v20180104-1110"/>
@@ -39,8 +39,8 @@
<unit id="net.bytebuddy.byte-buddy.source" version="1.9.0.v20181107-1410"/>
<unit id="net.i2p.crypto.eddsa" version="0.3.0.v20181102-1323"/>
<unit id="net.i2p.crypto.eddsa.source" version="0.3.0.v20181102-1323"/>
- <unit id="org.apache.ant" version="1.10.5.v20190526-1402"/>
- <unit id="org.apache.ant.source" version="1.10.5.v20190526-1402"/>
+ <unit id="org.apache.ant" version="1.10.7.v20190926-0324"/>
+ <unit id="org.apache.ant.source" version="1.10.7.v20190926-0324"/>
<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"/>
@@ -57,12 +57,12 @@
<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"/>
- <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.bouncycastle.bcpg" version="1.64.0.v20191109-0815"/>
+ <unit id="org.bouncycastle.bcpg.source" version="1.64.0.v20191109-0815"/>
+ <unit id="org.bouncycastle.bcpkix" version="1.64.0.v20191109-0815"/>
+ <unit id="org.bouncycastle.bcpkix.source" version="1.64.0.v20191109-0815"/>
+ <unit id="org.bouncycastle.bcprov" version="1.64.0.v20191109-0815"/>
+ <unit id="org.bouncycastle.bcprov.source" version="1.64.0.v20191109-0815"/>
<unit id="org.hamcrest" version="1.1.0.v20090501071000"/>
<unit id="org.hamcrest.core" version="1.3.0.v20180420-1519"/>
<unit id="org.hamcrest.core.source" version="1.3.0.v20180420-1519"/>
@@ -82,7 +82,7 @@
<unit id="org.slf4j.impl.log4j12.source" version="1.7.2.v20131105-2200"/>
<unit id="org.tukaani.xz" version="1.8.0.v20180207-1613"/>
<unit id="org.tukaani.xz.source" version="1.8.0.v20180207-1613"/>
- <repository location="https://download.eclipse.org/tools/orbit/downloads/drops/R20190827152740/repository"/>
+ <repository location="https://download.eclipse.org/tools/orbit/downloads/drops/R20191126223242/repository"/>
</location>
<location includeMode="slicer" includeAllPlatforms="false" includeSource="true" includeConfigurePhase="true" type="InstallableUnit">
<unit id="org.eclipse.osgi" version="0.0.0"/>
diff --git a/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.9.tpd b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.9.tpd
index 36894cf..c4f2b81 100644
--- a/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.9.tpd
+++ b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.9.tpd
@@ -1,7 +1,7 @@
target "jgit-4.9" with source configurePhase
-include "projects/jetty-9.4.20.tpd"
-include "orbit/R20190827152740-2019-09.tpd"
+include "projects/jetty-9.4.22.tpd"
+include "orbit/R20191126223242-2019-12.tpd"
location "https://download.eclipse.org/releases/2018-09/" {
org.eclipse.osgi lazy
diff --git a/org.eclipse.jgit.packaging/org.eclipse.jgit.target/orbit/R20191126223242-2019-12.tpd b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/orbit/R20191126223242-2019-12.tpd
new file mode 100644
index 0000000..679e919
--- /dev/null
+++ b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/orbit/R20191126223242-2019-12.tpd
@@ -0,0 +1,65 @@
+target "R20191126223242-2019-12" with source configurePhase
+// see http://download.eclipse.org/tools/orbit/downloads/
+
+location "https://download.eclipse.org/tools/orbit/downloads/drops/R20191126223242/repository" {
+ com.google.gson [2.8.2.v20180104-1110,2.8.2.v20180104-1110]
+ com.google.gson.source [2.8.2.v20180104-1110,2.8.2.v20180104-1110]
+ com.jcraft.jsch [0.1.55.v20190404-1902,0.1.55.v20190404-1902]
+ com.jcraft.jsch.source [0.1.55.v20190404-1902,0.1.55.v20190404-1902]
+ com.jcraft.jzlib [1.1.1.v201205102305,1.1.1.v201205102305]
+ com.jcraft.jzlib.source [1.1.1.v201205102305,1.1.1.v201205102305]
+ javaewah [1.1.6.v20160919-1400,1.1.6.v20160919-1400]
+ javaewah.source [1.1.6.v20160919-1400,1.1.6.v20160919-1400]
+ javax.servlet [3.1.0.v201410161800,3.1.0.v201410161800]
+ javax.servlet.source [3.1.0.v201410161800,3.1.0.v201410161800]
+ net.bytebuddy.byte-buddy [1.9.0.v20181107-1410,1.9.0.v20181107-1410]
+ net.bytebuddy.byte-buddy-agent [1.9.0.v20181106-1534,1.9.0.v20181106-1534]
+ net.bytebuddy.byte-buddy-agent.source [1.9.0.v20181106-1534,1.9.0.v20181106-1534]
+ net.bytebuddy.byte-buddy.source [1.9.0.v20181107-1410,1.9.0.v20181107-1410]
+ net.i2p.crypto.eddsa [0.3.0.v20181102-1323,0.3.0.v20181102-1323]
+ net.i2p.crypto.eddsa.source [0.3.0.v20181102-1323,0.3.0.v20181102-1323]
+ org.apache.ant [1.10.7.v20190926-0324,1.10.7.v20190926-0324]
+ org.apache.ant.source [1.10.7.v20190926-0324,1.10.7.v20190926-0324]
+ 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]
+ org.apache.commons.compress.source [1.18.0.v20181121-2221,1.18.0.v20181121-2221]
+ org.apache.commons.logging [1.2.0.v20180409-1502,1.2.0.v20180409-1502]
+ org.apache.commons.logging.source [1.2.0.v20180409-1502,1.2.0.v20180409-1502]
+ org.apache.httpcomponents.httpclient [4.5.6.v20190503-0009,4.5.6.v20190503-0009]
+ org.apache.httpcomponents.httpclient.source [4.5.6.v20190503-0009,4.5.6.v20190503-0009]
+ org.apache.httpcomponents.httpcore [4.4.10.v20190123-2214,4.4.10.v20190123-2214]
+ 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.apache.sshd.osgi [2.2.0.v20190425-2127,2.2.0.v20190425-2127]
+ org.apache.sshd.osgi.source [2.2.0.v20190425-2127,2.2.0.v20190425-2127]
+ org.apache.sshd.sftp [2.2.0.v20190425-2127,2.2.0.v20190425-2127]
+ org.apache.sshd.sftp.source [2.2.0.v20190425-2127,2.2.0.v20190425-2127]
+ org.bouncycastle.bcpg [1.64.0.v20191109-0815,1.64.0.v20191109-0815]
+ org.bouncycastle.bcpg.source [1.64.0.v20191109-0815,1.64.0.v20191109-0815]
+ org.bouncycastle.bcpkix [1.64.0.v20191109-0815,1.64.0.v20191109-0815]
+ org.bouncycastle.bcpkix.source [1.64.0.v20191109-0815,1.64.0.v20191109-0815]
+ org.bouncycastle.bcprov [1.64.0.v20191109-0815,1.64.0.v20191109-0815]
+ org.bouncycastle.bcprov.source [1.64.0.v20191109-0815,1.64.0.v20191109-0815]
+ org.hamcrest [1.1.0.v20090501071000,1.1.0.v20090501071000]
+ org.hamcrest.core [1.3.0.v20180420-1519,1.3.0.v20180420-1519]
+ org.hamcrest.core.source [1.3.0.v20180420-1519,1.3.0.v20180420-1519]
+ org.hamcrest.library [1.3.0.v20180524-2246,1.3.0.v20180524-2246]
+ org.hamcrest.library.source [1.3.0.v20180524-2246,1.3.0.v20180524-2246]
+ org.junit [4.12.0.v201504281640,4.12.0.v201504281640]
+ org.junit.source [4.12.0.v201504281640,4.12.0.v201504281640]
+ org.kohsuke.args4j [2.33.0.v20160323-2218,2.33.0.v20160323-2218]
+ org.kohsuke.args4j.source [2.33.0.v20160323-2218,2.33.0.v20160323-2218]
+ org.mockito [2.23.0.v20190527-1420,2.23.0.v20190527-1420]
+ org.mockito.source [2.23.0.v20190527-1420,2.23.0.v20190527-1420]
+ org.objenesis [2.6.0.v20180420-1519,2.6.0.v20180420-1519]
+ org.objenesis.source [2.6.0.v20180420-1519,2.6.0.v20180420-1519]
+ org.slf4j.api [1.7.2.v20121108-1250,1.7.2.v20121108-1250]
+ org.slf4j.api.source [1.7.2.v20121108-1250,1.7.2.v20121108-1250]
+ org.slf4j.impl.log4j12 [1.7.2.v20131105-2200,1.7.2.v20131105-2200]
+ org.slf4j.impl.log4j12.source [1.7.2.v20131105-2200,1.7.2.v20131105-2200]
+ org.tukaani.xz [1.8.0.v20180207-1613,1.8.0.v20180207-1613]
+ org.tukaani.xz.source [1.8.0.v20180207-1613,1.8.0.v20180207-1613]
+}
+
diff --git a/org.eclipse.jgit.packaging/org.eclipse.jgit.target/pom.xml b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/pom.xml
index c0cf064..e722adb 100644
--- a/org.eclipse.jgit.packaging/org.eclipse.jgit.target/pom.xml
+++ b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/pom.xml
@@ -49,7 +49,7 @@
<parent>
<groupId>org.eclipse.jgit</groupId>
<artifactId>jgit.tycho.parent</artifactId>
- <version>5.5.2-SNAPSHOT</version>
+ <version>5.6.2-SNAPSHOT</version>
</parent>
<artifactId>org.eclipse.jgit.target</artifactId>
diff --git a/org.eclipse.jgit.packaging/org.eclipse.jgit.target/projects/jetty-9.4.20.tpd b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/projects/jetty-9.4.20.tpd
deleted file mode 100644
index 0e4d189..0000000
--- a/org.eclipse.jgit.packaging/org.eclipse.jgit.target/projects/jetty-9.4.20.tpd
+++ /dev/null
@@ -1,20 +0,0 @@
-target "jetty-9.4.20" with source configurePhase
-
-location jetty-9.4.20 "https://archive.eclipse.org/jetty/updates/jetty-bundles-9.x/jetty-bundles-9.x/9.4.20.v20190813/" {
- org.eclipse.jetty.client [9.4.20.v20190813,9.4.20.v20190813]
- org.eclipse.jetty.client.source [9.4.20.v20190813,9.4.20.v20190813]
- org.eclipse.jetty.continuation [9.4.20.v20190813,9.4.20.v20190813]
- org.eclipse.jetty.continuation.source [9.4.20.v20190813,9.4.20.v20190813]
- org.eclipse.jetty.http [9.4.20.v20190813,9.4.20.v20190813]
- org.eclipse.jetty.http.source [9.4.20.v20190813,9.4.20.v20190813]
- org.eclipse.jetty.io [9.4.20.v20190813,9.4.20.v20190813]
- org.eclipse.jetty.io.source [9.4.20.v20190813,9.4.20.v20190813]
- org.eclipse.jetty.security [9.4.20.v20190813,9.4.20.v20190813]
- org.eclipse.jetty.security.source [9.4.20.v20190813,9.4.20.v20190813]
- org.eclipse.jetty.server [9.4.20.v20190813,9.4.20.v20190813]
- org.eclipse.jetty.server.source [9.4.20.v20190813,9.4.20.v20190813]
- org.eclipse.jetty.servlet [9.4.20.v20190813,9.4.20.v20190813]
- org.eclipse.jetty.servlet.source [9.4.20.v20190813,9.4.20.v20190813]
- org.eclipse.jetty.util [9.4.20.v20190813,9.4.20.v20190813]
- org.eclipse.jetty.util.source [9.4.20.v20190813,9.4.20.v20190813]
-}
diff --git a/org.eclipse.jgit.packaging/org.eclipse.jgit.target/projects/jetty-9.4.22.tpd b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/projects/jetty-9.4.22.tpd
new file mode 100644
index 0000000..64012c2
--- /dev/null
+++ b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/projects/jetty-9.4.22.tpd
@@ -0,0 +1,20 @@
+target "jetty-9.4.22" with source configurePhase
+
+location jetty-9.4.22 "https://archive.eclipse.org/jetty/updates/jetty-bundles-9.x/jetty-bundles-9.x/9.4.22.v20191022/" {
+ org.eclipse.jetty.client [9.4.22.v20191022,9.4.22.v20191022]
+ org.eclipse.jetty.client.source [9.4.22.v20191022,9.4.22.v20191022]
+ org.eclipse.jetty.continuation [9.4.22.v20191022,9.4.22.v20191022]
+ org.eclipse.jetty.continuation.source [9.4.22.v20191022,9.4.22.v20191022]
+ org.eclipse.jetty.http [9.4.22.v20191022,9.4.22.v20191022]
+ org.eclipse.jetty.http.source [9.4.22.v20191022,9.4.22.v20191022]
+ org.eclipse.jetty.io [9.4.22.v20191022,9.4.22.v20191022]
+ org.eclipse.jetty.io.source [9.4.22.v20191022,9.4.22.v20191022]
+ org.eclipse.jetty.security [9.4.22.v20191022,9.4.22.v20191022]
+ org.eclipse.jetty.security.source [9.4.22.v20191022,9.4.22.v20191022]
+ org.eclipse.jetty.server [9.4.22.v20191022,9.4.22.v20191022]
+ org.eclipse.jetty.server.source [9.4.22.v20191022,9.4.22.v20191022]
+ org.eclipse.jetty.servlet [9.4.22.v20191022,9.4.22.v20191022]
+ org.eclipse.jetty.servlet.source [9.4.22.v20191022,9.4.22.v20191022]
+ org.eclipse.jetty.util [9.4.22.v20191022,9.4.22.v20191022]
+ org.eclipse.jetty.util.source [9.4.22.v20191022,9.4.22.v20191022]
+}
diff --git a/org.eclipse.jgit.packaging/pom.xml b/org.eclipse.jgit.packaging/pom.xml
index 9c3b926..1a8e9c9 100644
--- a/org.eclipse.jgit.packaging/pom.xml
+++ b/org.eclipse.jgit.packaging/pom.xml
@@ -49,7 +49,7 @@
<groupId>org.eclipse.jgit</groupId>
<artifactId>jgit.tycho.parent</artifactId>
- <version>5.5.2-SNAPSHOT</version>
+ <version>5.6.2-SNAPSHOT</version>
<packaging>pom</packaging>
<name>JGit Tycho Parent</name>
diff --git a/org.eclipse.jgit.pgm.test/.settings/org.eclipse.jdt.core.prefs b/org.eclipse.jgit.pgm.test/.settings/org.eclipse.jdt.core.prefs
index d4751b5..4c4634a 100644
--- a/org.eclipse.jgit.pgm.test/.settings/org.eclipse.jdt.core.prefs
+++ b/org.eclipse.jgit.pgm.test/.settings/org.eclipse.jdt.core.prefs
@@ -92,7 +92,7 @@
org.eclipse.jdt.core.compiler.problem.unclosedCloseable=warning
org.eclipse.jdt.core.compiler.problem.undocumentedEmptyBlock=warning
org.eclipse.jdt.core.compiler.problem.unhandledWarningToken=ignore
-org.eclipse.jdt.core.compiler.problem.unnecessaryElse=ignore
+org.eclipse.jdt.core.compiler.problem.unnecessaryElse=warning
org.eclipse.jdt.core.compiler.problem.unnecessaryTypeCheck=error
org.eclipse.jdt.core.compiler.problem.unqualifiedFieldAccess=ignore
org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownException=error
diff --git a/org.eclipse.jgit.pgm.test/META-INF/MANIFEST.MF b/org.eclipse.jgit.pgm.test/META-INF/MANIFEST.MF
index 2cb36e1..92e895c 100644
--- a/org.eclipse.jgit.pgm.test/META-INF/MANIFEST.MF
+++ b/org.eclipse.jgit.pgm.test/META-INF/MANIFEST.MF
@@ -3,28 +3,28 @@
Bundle-Name: %Bundle-Name
Automatic-Module-Name: org.eclipse.jgit.pgm.test
Bundle-SymbolicName: org.eclipse.jgit.pgm.test
-Bundle-Version: 5.5.2.qualifier
+Bundle-Version: 5.6.2.qualifier
Bundle-Vendor: %Bundle-Vendor
Bundle-Localization: plugin
Bundle-ActivationPolicy: lazy
Bundle-RequiredExecutionEnvironment: JavaSE-1.8
-Import-Package: org.eclipse.jgit.api;version="[5.5.2,5.6.0)",
- org.eclipse.jgit.api.errors;version="[5.5.2,5.6.0)",
- org.eclipse.jgit.diff;version="[5.5.2,5.6.0)",
- org.eclipse.jgit.dircache;version="[5.5.2,5.6.0)",
- org.eclipse.jgit.internal.storage.file;version="5.5.2",
- org.eclipse.jgit.junit;version="[5.5.2,5.6.0)",
- org.eclipse.jgit.lib;version="[5.5.2,5.6.0)",
- org.eclipse.jgit.merge;version="[5.5.2,5.6.0)",
- org.eclipse.jgit.pgm;version="[5.5.2,5.6.0)",
- org.eclipse.jgit.pgm.internal;version="[5.5.2,5.6.0)",
- org.eclipse.jgit.pgm.opt;version="[5.5.2,5.6.0)",
- org.eclipse.jgit.revwalk;version="[5.5.2,5.6.0)",
- org.eclipse.jgit.storage.file;version="[5.5.2,5.6.0)",
- org.eclipse.jgit.transport;version="[5.5.2,5.6.0)",
- org.eclipse.jgit.treewalk;version="[5.5.2,5.6.0)",
- org.eclipse.jgit.util;version="[5.5.2,5.6.0)",
- org.eclipse.jgit.util.io;version="[5.5.2,5.6.0)",
+Import-Package: org.eclipse.jgit.api;version="[5.6.2,5.7.0)",
+ org.eclipse.jgit.api.errors;version="[5.6.2,5.7.0)",
+ org.eclipse.jgit.diff;version="[5.6.2,5.7.0)",
+ org.eclipse.jgit.dircache;version="[5.6.2,5.7.0)",
+ org.eclipse.jgit.internal.storage.file;version="5.6.2",
+ org.eclipse.jgit.junit;version="[5.6.2,5.7.0)",
+ org.eclipse.jgit.lib;version="[5.6.2,5.7.0)",
+ org.eclipse.jgit.merge;version="[5.6.2,5.7.0)",
+ org.eclipse.jgit.pgm;version="[5.6.2,5.7.0)",
+ org.eclipse.jgit.pgm.internal;version="[5.6.2,5.7.0)",
+ org.eclipse.jgit.pgm.opt;version="[5.6.2,5.7.0)",
+ org.eclipse.jgit.revwalk;version="[5.6.2,5.7.0)",
+ org.eclipse.jgit.storage.file;version="[5.6.2,5.7.0)",
+ org.eclipse.jgit.transport;version="[5.6.2,5.7.0)",
+ org.eclipse.jgit.treewalk;version="[5.6.2,5.7.0)",
+ org.eclipse.jgit.util;version="[5.6.2,5.7.0)",
+ org.eclipse.jgit.util.io;version="[5.6.2,5.7.0)",
org.hamcrest.core;bundle-version="[1.1.0,2.0.0)",
org.junit;version="[4.12,5.0.0)",
org.junit.rules;version="[4.12,5.0.0)",
diff --git a/org.eclipse.jgit.pgm.test/pom.xml b/org.eclipse.jgit.pgm.test/pom.xml
index 49535d6..9699004 100644
--- a/org.eclipse.jgit.pgm.test/pom.xml
+++ b/org.eclipse.jgit.pgm.test/pom.xml
@@ -50,7 +50,7 @@
<parent>
<groupId>org.eclipse.jgit</groupId>
<artifactId>org.eclipse.jgit-parent</artifactId>
- <version>5.5.2-SNAPSHOT</version>
+ <version>5.6.2-SNAPSHOT</version>
</parent>
<artifactId>org.eclipse.jgit.pgm.test</artifactId>
diff --git a/org.eclipse.jgit.pgm.test/tst/org/eclipse/jgit/pgm/BlameTest.java b/org.eclipse.jgit.pgm.test/tst/org/eclipse/jgit/pgm/BlameTest.java
index e806872..6da1e46 100644
--- a/org.eclipse.jgit.pgm.test/tst/org/eclipse/jgit/pgm/BlameTest.java
+++ b/org.eclipse.jgit.pgm.test/tst/org/eclipse/jgit/pgm/BlameTest.java
@@ -42,8 +42,14 @@
*/
package org.eclipse.jgit.pgm;
+import static org.junit.Assert.assertTrue;
+
import org.eclipse.jgit.api.Git;
+import org.eclipse.jgit.api.MergeResult;
import org.eclipse.jgit.lib.CLIRepositoryTestCase;
+import org.eclipse.jgit.lib.Constants;
+import org.eclipse.jgit.lib.PersonIdent;
+import org.eclipse.jgit.revwalk.RevCommit;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.ExpectedException;
@@ -85,7 +91,7 @@ public void testBlameStaged() throws Exception {
git.add().addFilepattern("inIndex.txt").call();
}
assertStringArrayEquals(
- " (Not Committed Yet 1) index",
+ "00000000 (Not Committed Yet 2009-08-15 20:12:58 -0330 1) index",
execute("git blame inIndex.txt"));
}
@@ -119,4 +125,36 @@ public void testBlameNonExistingInSubdir() throws Exception {
thrown.expectMessage("no such path 'sub/does_not_exist.txt' in HEAD");
execute("git blame sub/does_not_exist.txt");
}
+
+ @Test
+ public void testBlameMergeConflict() throws Exception {
+ try (Git git = new Git(db)) {
+ writeTrashFile("file", "Origin\n");
+ git.add().addFilepattern("file").call();
+ git.commit().setMessage("initial commit").call();
+ git.checkout().setCreateBranch(true)
+ .setName("side").call();
+ writeTrashFile("file",
+ "Conflicting change from side branch\n");
+ git.add().addFilepattern("file").call();
+ RevCommit side = git.commit().setMessage("side commit")
+ .setCommitter(new PersonIdent("gitter", "")).call();
+ git.checkout().setName(Constants.MASTER).call();
+ writeTrashFile("file", "Change on master branch\n");
+ git.add().addFilepattern("file").call();
+ git.commit().setMessage("Commit conflict on master")
+ .setCommitter(new PersonIdent("gitter", "")).call();
+ MergeResult result = git.merge()
+ .include("side", side).call();
+ assertTrue("Expected conflict on 'file'",
+ result.getConflicts().containsKey("file"));
+ }
+ String[] expected = {
+ "00000000 (Not Committed Yet 2009-08-15 20:12:58 -0330 1) <<<<<<< HEAD",
+ "0f5b671c (gitter 2009-08-15 20:12:58 -0330 2) Change on master branch",
+ "00000000 (Not Committed Yet 2009-08-15 20:12:58 -0330 3) =======",
+ "ae78cff6 (gitter 2009-08-15 20:12:58 -0330 4) Conflicting change from side branch",
+ "00000000 (Not Committed Yet 2009-08-15 20:12:58 -0330 5) >>>>>>> side" };
+ assertArrayOfLinesEquals(expected, execute("git blame file"));
+ }
}
diff --git a/org.eclipse.jgit.pgm.test/tst/org/eclipse/jgit/pgm/CloneTest.java b/org.eclipse.jgit.pgm.test/tst/org/eclipse/jgit/pgm/CloneTest.java
index c31f28c..0ecbd65 100644
--- a/org.eclipse.jgit.pgm.test/tst/org/eclipse/jgit/pgm/CloneTest.java
+++ b/org.eclipse.jgit.pgm.test/tst/org/eclipse/jgit/pgm/CloneTest.java
@@ -44,6 +44,7 @@
import static org.junit.Assert.assertArrayEquals;
import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;
import java.io.File;
@@ -54,7 +55,13 @@
import org.eclipse.jgit.junit.MockSystemReader;
import org.eclipse.jgit.lib.CLIRepositoryTestCase;
import org.eclipse.jgit.lib.Constants;
+import org.eclipse.jgit.lib.ObjectId;
import org.eclipse.jgit.lib.Ref;
+import org.eclipse.jgit.lib.RefUpdate;
+import org.eclipse.jgit.lib.StoredConfig;
+import org.eclipse.jgit.revwalk.RevCommit;
+import org.eclipse.jgit.transport.RefSpec;
+import org.eclipse.jgit.transport.RemoteConfig;
import org.eclipse.jgit.transport.URIish;
import org.eclipse.jgit.util.SystemReader;
import org.junit.Before;
@@ -90,10 +97,10 @@ public void testClone() throws Exception {
assertEquals("expected 1 branch", 1, branches.size());
}
- private void createInitialCommit() throws Exception {
+ private RevCommit createInitialCommit() throws Exception {
JGitTestUtil.writeTrashFile(db, "hello.txt", "world");
git.add().addFilepattern("hello.txt").call();
- git.commit().setMessage("Initial commit").call();
+ return git.commit().setMessage("Initial commit").call();
}
@Test
@@ -154,4 +161,37 @@ public void testCloneBare() throws Exception {
assertEquals("expected 1 branch", 1, branches.size());
assertTrue("expected bare repository", git2.getRepository().isBare());
}
+
+ @Test
+ public void testCloneMirror() throws Exception {
+ ObjectId head = createInitialCommit();
+ // create a non-standard ref
+ RefUpdate ru = db.updateRef("refs/meta/foo/bar");
+ ru.setNewObjectId(head);
+ ru.update();
+
+ File gitDir = db.getDirectory();
+ String sourcePath = gitDir.getAbsolutePath();
+ String targetPath = (new File(sourcePath)).getParentFile()
+ .getParentFile().getAbsolutePath() + File.separator
+ + "target.git";
+ String cmd = "git clone --mirror " + shellQuote(sourcePath) + " "
+ + shellQuote(targetPath);
+ String[] result = execute(cmd);
+ assertArrayEquals(
+ new String[] { "Cloning into '" + targetPath + "'...", "", "" },
+ result);
+ Git git2 = Git.open(new File(targetPath));
+ List<Ref> branches = git2.branchList().call();
+ assertEquals("expected 1 branch", 1, branches.size());
+ assertTrue("expected bare repository", git2.getRepository().isBare());
+ StoredConfig config = git2.getRepository().getConfig();
+ RemoteConfig rc = new RemoteConfig(config, "origin");
+ assertTrue("expected mirror configuration", rc.isMirror());
+ RefSpec fetchRefSpec = rc.getFetchRefSpecs().get(0);
+ assertTrue("exected force udpate", fetchRefSpec.isForceUpdate());
+ assertEquals("refs/*", fetchRefSpec.getSource());
+ assertEquals("refs/*", fetchRefSpec.getDestination());
+ assertNotNull(git2.getRepository().exactRef("refs/meta/foo/bar"));
+ }
}
diff --git a/org.eclipse.jgit.pgm/.settings/org.eclipse.jdt.core.prefs b/org.eclipse.jgit.pgm/.settings/org.eclipse.jdt.core.prefs
index ef6f5e7..bc7ba1e 100644
--- a/org.eclipse.jgit.pgm/.settings/org.eclipse.jdt.core.prefs
+++ b/org.eclipse.jgit.pgm/.settings/org.eclipse.jdt.core.prefs
@@ -92,7 +92,7 @@
org.eclipse.jdt.core.compiler.problem.unclosedCloseable=warning
org.eclipse.jdt.core.compiler.problem.undocumentedEmptyBlock=warning
org.eclipse.jdt.core.compiler.problem.unhandledWarningToken=ignore
-org.eclipse.jdt.core.compiler.problem.unnecessaryElse=ignore
+org.eclipse.jdt.core.compiler.problem.unnecessaryElse=warning
org.eclipse.jdt.core.compiler.problem.unnecessaryTypeCheck=error
org.eclipse.jdt.core.compiler.problem.unqualifiedFieldAccess=ignore
org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownException=warning
diff --git a/org.eclipse.jgit.pgm/META-INF/MANIFEST.MF b/org.eclipse.jgit.pgm/META-INF/MANIFEST.MF
index 0a9074a..9c822cd 100644
--- a/org.eclipse.jgit.pgm/META-INF/MANIFEST.MF
+++ b/org.eclipse.jgit.pgm/META-INF/MANIFEST.MF
@@ -3,7 +3,7 @@
Bundle-Name: %Bundle-Name
Automatic-Module-Name: org.eclipse.jgit.pgm
Bundle-SymbolicName: org.eclipse.jgit.pgm
-Bundle-Version: 5.5.2.qualifier
+Bundle-Version: 5.6.2.qualifier
Bundle-Vendor: %Bundle-Vendor
Bundle-ActivationPolicy: lazy
Bundle-Localization: plugin
@@ -28,50 +28,50 @@
org.eclipse.jetty.util.log;version="[9.4.5,10.0.0)",
org.eclipse.jetty.util.security;version="[9.4.5,10.0.0)",
org.eclipse.jetty.util.thread;version="[9.4.5,10.0.0)",
- org.eclipse.jgit.api;version="[5.5.2,5.6.0)",
- org.eclipse.jgit.api.errors;version="[5.5.2,5.6.0)",
- org.eclipse.jgit.archive;version="[5.5.2,5.6.0)",
- org.eclipse.jgit.awtui;version="[5.5.2,5.6.0)",
- org.eclipse.jgit.blame;version="[5.5.2,5.6.0)",
- org.eclipse.jgit.diff;version="[5.5.2,5.6.0)",
- org.eclipse.jgit.dircache;version="[5.5.2,5.6.0)",
- org.eclipse.jgit.errors;version="[5.5.2,5.6.0)",
- org.eclipse.jgit.gitrepo;version="[5.5.2,5.6.0)",
- org.eclipse.jgit.internal.ketch;version="[5.5.2,5.6.0)",
- org.eclipse.jgit.internal.storage.dfs;version="[5.5.2,5.6.0)",
- org.eclipse.jgit.internal.storage.file;version="[5.5.2,5.6.0)",
- org.eclipse.jgit.internal.storage.io;version="[5.5.2,5.6.0)",
- org.eclipse.jgit.internal.storage.pack;version="[5.5.2,5.6.0)",
- org.eclipse.jgit.internal.storage.reftable;version="[5.5.2,5.6.0)",
- org.eclipse.jgit.internal.storage.reftree;version="[5.5.2,5.6.0)",
- org.eclipse.jgit.lfs;version="[5.5.2,5.6.0)",
- org.eclipse.jgit.lfs.lib;version="[5.5.2,5.6.0)",
- org.eclipse.jgit.lfs.server;version="[5.5.2,5.6.0)",
- org.eclipse.jgit.lfs.server.fs;version="[5.5.2,5.6.0)",
- org.eclipse.jgit.lfs.server.s3;version="[5.5.2,5.6.0)",
- org.eclipse.jgit.lib;version="[5.5.2,5.6.0)",
- org.eclipse.jgit.merge;version="[5.5.2,5.6.0)",
- org.eclipse.jgit.nls;version="[5.5.2,5.6.0)",
- org.eclipse.jgit.notes;version="[5.5.2,5.6.0)",
- org.eclipse.jgit.revplot;version="[5.5.2,5.6.0)",
- org.eclipse.jgit.revwalk;version="[5.5.2,5.6.0)",
- org.eclipse.jgit.revwalk.filter;version="[5.5.2,5.6.0)",
- org.eclipse.jgit.storage.file;version="[5.5.2,5.6.0)",
- org.eclipse.jgit.storage.pack;version="[5.5.2,5.6.0)",
- org.eclipse.jgit.transport;version="[5.5.2,5.6.0)",
- org.eclipse.jgit.transport.http.apache;version="[5.5.2,5.6.0)",
- org.eclipse.jgit.transport.resolver;version="[5.5.2,5.6.0)",
- org.eclipse.jgit.transport.sshd;version="[5.5.2,5.6.0)",
- org.eclipse.jgit.treewalk;version="[5.5.2,5.6.0)",
- org.eclipse.jgit.treewalk.filter;version="[5.5.2,5.6.0)",
- org.eclipse.jgit.util;version="[5.5.2,5.6.0)",
- org.eclipse.jgit.util.io;version="[5.5.2,5.6.0)",
+ org.eclipse.jgit.api;version="[5.6.2,5.7.0)",
+ org.eclipse.jgit.api.errors;version="[5.6.2,5.7.0)",
+ org.eclipse.jgit.archive;version="[5.6.2,5.7.0)",
+ org.eclipse.jgit.awtui;version="[5.6.2,5.7.0)",
+ org.eclipse.jgit.blame;version="[5.6.2,5.7.0)",
+ org.eclipse.jgit.diff;version="[5.6.2,5.7.0)",
+ org.eclipse.jgit.dircache;version="[5.6.2,5.7.0)",
+ org.eclipse.jgit.errors;version="[5.6.2,5.7.0)",
+ org.eclipse.jgit.gitrepo;version="[5.6.2,5.7.0)",
+ org.eclipse.jgit.internal.ketch;version="[5.6.2,5.7.0)",
+ org.eclipse.jgit.internal.storage.dfs;version="[5.6.2,5.7.0)",
+ org.eclipse.jgit.internal.storage.file;version="[5.6.2,5.7.0)",
+ org.eclipse.jgit.internal.storage.io;version="[5.6.2,5.7.0)",
+ org.eclipse.jgit.internal.storage.pack;version="[5.6.2,5.7.0)",
+ org.eclipse.jgit.internal.storage.reftable;version="[5.6.2,5.7.0)",
+ org.eclipse.jgit.internal.storage.reftree;version="[5.6.2,5.7.0)",
+ org.eclipse.jgit.lfs;version="[5.6.2,5.7.0)",
+ org.eclipse.jgit.lfs.lib;version="[5.6.2,5.7.0)",
+ org.eclipse.jgit.lfs.server;version="[5.6.2,5.7.0)",
+ org.eclipse.jgit.lfs.server.fs;version="[5.6.2,5.7.0)",
+ org.eclipse.jgit.lfs.server.s3;version="[5.6.2,5.7.0)",
+ org.eclipse.jgit.lib;version="[5.6.2,5.7.0)",
+ org.eclipse.jgit.merge;version="[5.6.2,5.7.0)",
+ org.eclipse.jgit.nls;version="[5.6.2,5.7.0)",
+ org.eclipse.jgit.notes;version="[5.6.2,5.7.0)",
+ org.eclipse.jgit.revplot;version="[5.6.2,5.7.0)",
+ org.eclipse.jgit.revwalk;version="[5.6.2,5.7.0)",
+ org.eclipse.jgit.revwalk.filter;version="[5.6.2,5.7.0)",
+ org.eclipse.jgit.storage.file;version="[5.6.2,5.7.0)",
+ org.eclipse.jgit.storage.pack;version="[5.6.2,5.7.0)",
+ org.eclipse.jgit.transport;version="[5.6.2,5.7.0)",
+ org.eclipse.jgit.transport.http.apache;version="[5.6.2,5.7.0)",
+ org.eclipse.jgit.transport.resolver;version="[5.6.2,5.7.0)",
+ org.eclipse.jgit.transport.sshd;version="[5.6.2,5.7.0)",
+ org.eclipse.jgit.treewalk;version="[5.6.2,5.7.0)",
+ org.eclipse.jgit.treewalk.filter;version="[5.6.2,5.7.0)",
+ org.eclipse.jgit.util;version="[5.6.2,5.7.0)",
+ org.eclipse.jgit.util.io;version="[5.6.2,5.7.0)",
org.kohsuke.args4j;version="[2.33.0,3.0.0)",
org.kohsuke.args4j.spi;version="[2.33.0,3.0.0)"
-Export-Package: org.eclipse.jgit.console;version="5.5.2";
+Export-Package: org.eclipse.jgit.console;version="5.6.2";
uses:="org.eclipse.jgit.transport,
org.eclipse.jgit.util",
- org.eclipse.jgit.pgm;version="5.5.2";
+ org.eclipse.jgit.pgm;version="5.6.2";
uses:="org.eclipse.jgit.revwalk,
org.eclipse.jgit.treewalk.filter,
org.eclipse.jgit.pgm.opt,
@@ -82,11 +82,11 @@
org.eclipse.jgit.treewalk,
javax.swing,
org.eclipse.jgit.transport",
- org.eclipse.jgit.pgm.debug;version="5.5.2";
+ org.eclipse.jgit.pgm.debug;version="5.6.2";
uses:="org.eclipse.jgit.util.io,
org.eclipse.jgit.pgm",
- org.eclipse.jgit.pgm.internal;version="5.5.2";x-friends:="org.eclipse.jgit.pgm.test,org.eclipse.jgit.test",
- org.eclipse.jgit.pgm.opt;version="5.5.2";
+ org.eclipse.jgit.pgm.internal;version="5.6.2";x-friends:="org.eclipse.jgit.pgm.test,org.eclipse.jgit.test",
+ org.eclipse.jgit.pgm.opt;version="5.6.2";
uses:="org.eclipse.jgit.lib,
org.eclipse.jgit.revwalk,
org.kohsuke.args4j.spi,
diff --git a/org.eclipse.jgit.pgm/META-INF/SOURCE-MANIFEST.MF b/org.eclipse.jgit.pgm/META-INF/SOURCE-MANIFEST.MF
index 1ce53a5..f324bb2 100644
--- a/org.eclipse.jgit.pgm/META-INF/SOURCE-MANIFEST.MF
+++ b/org.eclipse.jgit.pgm/META-INF/SOURCE-MANIFEST.MF
@@ -3,5 +3,5 @@
Bundle-Name: org.eclipse.jgit.pgm - Sources
Bundle-SymbolicName: org.eclipse.jgit.pgm.source
Bundle-Vendor: Eclipse.org - JGit
-Bundle-Version: 5.5.2.qualifier
-Eclipse-SourceBundle: org.eclipse.jgit.pgm;version="5.5.2.qualifier";roots="."
+Bundle-Version: 5.6.2.qualifier
+Eclipse-SourceBundle: org.eclipse.jgit.pgm;version="5.6.2.qualifier";roots="."
diff --git a/org.eclipse.jgit.pgm/META-INF/services/org.eclipse.jgit.pgm.TextBuiltin b/org.eclipse.jgit.pgm/META-INF/services/org.eclipse.jgit.pgm.TextBuiltin
index 39fbe2e..062b964 100644
--- a/org.eclipse.jgit.pgm/META-INF/services/org.eclipse.jgit.pgm.TextBuiltin
+++ b/org.eclipse.jgit.pgm/META-INF/services/org.eclipse.jgit.pgm.TextBuiltin
@@ -8,6 +8,7 @@
org.eclipse.jgit.pgm.Clone
org.eclipse.jgit.pgm.Commit
org.eclipse.jgit.pgm.Config
+org.eclipse.jgit.pgm.ConvertRefStorage
org.eclipse.jgit.pgm.Daemon
org.eclipse.jgit.pgm.Describe
org.eclipse.jgit.pgm.Diff
diff --git a/org.eclipse.jgit.pgm/pom.xml b/org.eclipse.jgit.pgm/pom.xml
index c7bcaf1..c18b7d1 100644
--- a/org.eclipse.jgit.pgm/pom.xml
+++ b/org.eclipse.jgit.pgm/pom.xml
@@ -50,7 +50,7 @@
<parent>
<groupId>org.eclipse.jgit</groupId>
<artifactId>org.eclipse.jgit-parent</artifactId>
- <version>5.5.2-SNAPSHOT</version>
+ <version>5.6.2-SNAPSHOT</version>
</parent>
<artifactId>org.eclipse.jgit.pgm</artifactId>
diff --git a/org.eclipse.jgit.pgm/resources/org/eclipse/jgit/pgm/internal/CLIText.properties b/org.eclipse.jgit.pgm/resources/org/eclipse/jgit/pgm/internal/CLIText.properties
index f029442..02f0543 100644
--- a/org.eclipse.jgit.pgm/resources/org/eclipse/jgit/pgm/internal/CLIText.properties
+++ b/org.eclipse.jgit.pgm/resources/org/eclipse/jgit/pgm/internal/CLIText.properties
@@ -223,6 +223,9 @@
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_mirrorClone=Set up a mirror of the source repository. This implies --bare. Compared to --bare, --mirror not only maps \
+local branches of the source to local branches of the target, it maps all refs (including remote-tracking branches, notes etc.) \
+and sets up a refspec configuration such that all these refs are overwritten by a git remote update in the target repository.
usage_Blame=Show what revision and author last modified each line
usage_Clean=Remove untracked files from the working tree
usage_CommandLineClientForamazonsS3Service=Command line client for Amazon's S3 service
@@ -323,6 +326,8 @@
usage_configLocal=use local configuration in .git/config
usage_configSystem=use system-wide configuration in $(prefix)/etc/gitconfig
usage_configureTheServiceInDaemonServicename=configure the service in daemon.servicename
+usage_convertRefStorage=Convert ref storage to reftable
+usage_convertRefStorageFormat=Format to convert to (reftable or refdir)
usage_createBranchAndCheckout=create branch and check out
usage_deleteBranchEvenIfNotMerged=delete branch (even if not merged)
usage_deleteFullyMergedBranch=delete fully merged branch
diff --git a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/console/ConsoleCredentialsProvider.java b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/console/ConsoleCredentialsProvider.java
index f8442fa..039d094 100644
--- a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/console/ConsoleCredentialsProvider.java
+++ b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/console/ConsoleCredentialsProvider.java
@@ -136,18 +136,15 @@ private boolean get(CredentialItem.StringType item) {
if (v != null) {
item.setValue(new String(v));
return true;
- } else {
- return false;
}
- } else {
- String v = cons.readLine("%s: ", item.getPromptText()); //$NON-NLS-1$
- if (v != null) {
- item.setValue(v);
- return true;
- } else {
- return false;
- }
+ return false;
}
+ String v = cons.readLine("%s: ", item.getPromptText()); //$NON-NLS-1$
+ if (v != null) {
+ item.setValue(v);
+ return true;
+ }
+ return false;
}
private boolean get(CredentialItem.CharArrayType item) {
@@ -156,18 +153,15 @@ private boolean get(CredentialItem.CharArrayType item) {
if (v != null) {
item.setValueNoCopy(v);
return true;
- } else {
- return false;
}
- } else {
- String v = cons.readLine("%s: ", item.getPromptText()); //$NON-NLS-1$
- if (v != null) {
- item.setValueNoCopy(v.toCharArray());
- return true;
- } else {
- return false;
- }
+ return false;
}
+ String v = cons.readLine("%s: ", item.getPromptText()); //$NON-NLS-1$
+ if (v != null) {
+ item.setValueNoCopy(v.toCharArray());
+ return true;
+ }
+ return false;
}
private boolean get(CredentialItem.InformationalMessage item) {
@@ -182,8 +176,7 @@ private boolean get(CredentialItem.YesNoType item) {
if (r != null) {
item.setValue(CLIText.get().answerYes.equalsIgnoreCase(r));
return true;
- } else {
- return false;
}
+ return false;
}
}
diff --git a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/Blame.java b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/Blame.java
index b67b04c..1a4c111 100644
--- a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/Blame.java
+++ b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/Blame.java
@@ -50,7 +50,6 @@
import static java.lang.Long.valueOf;
import static org.eclipse.jgit.lib.Constants.OBJECT_ID_STRING_LENGTH;
-import java.io.File;
import java.io.IOException;
import java.text.MessageFormat;
import java.text.SimpleDateFormat;
@@ -60,11 +59,11 @@
import java.util.Map;
import java.util.regex.Pattern;
+import org.eclipse.jgit.api.errors.NoHeadException;
import org.eclipse.jgit.blame.BlameGenerator;
import org.eclipse.jgit.blame.BlameResult;
import org.eclipse.jgit.diff.RawText;
import org.eclipse.jgit.diff.RawTextComparator;
-import org.eclipse.jgit.dircache.DirCache;
import org.eclipse.jgit.errors.NoWorkTreeException;
import org.eclipse.jgit.lib.Constants;
import org.eclipse.jgit.lib.ObjectId;
@@ -134,6 +133,9 @@ void ignoreAllSpace(@SuppressWarnings("unused") boolean on) {
private BlameResult blame;
+ /** Used to get a current time stamp for lines without commit. */
+ private final PersonIdent dummyDate = new PersonIdent("", ""); //$NON-NLS-1$ //$NON-NLS-2$
+
/** {@inheritDoc} */
@Override
protected void run() {
@@ -186,28 +188,7 @@ protected void run() {
}
generator.push(null, rev);
} else {
- ObjectId head = db.resolve(Constants.HEAD);
- if (head == null) {
- throw die(MessageFormat.format(CLIText.get().noSuchRef,
- Constants.HEAD));
- }
- generator.push(null, head);
- if (!db.isBare()) {
- DirCache dc = db.readDirCache();
- int entry = dc.findEntry(file);
- if (0 <= entry) {
- generator.push(null, dc.getEntry(entry).getObjectId());
- } else {
- throw die(MessageFormat.format(
- CLIText.get().noSuchPathInRef, file,
- Constants.HEAD));
- }
-
- File inTree = new File(db.getWorkTree(), file);
- if (db.getFS().isFile(inTree)) {
- generator.push(null, new RawText(inTree));
- }
- }
+ generator.prepareHead();
}
blame = BlameResult.create(generator);
@@ -236,6 +217,10 @@ protected void run() {
authorWidth = Math.max(authorWidth, author(line).length());
dateWidth = Math.max(dateWidth, date(line).length());
pathWidth = Math.max(pathWidth, path(line).length());
+ } else if (c == null) {
+ authorWidth = Math.max(authorWidth, author(line).length());
+ dateWidth = Math.max(dateWidth, date(line).length());
+ pathWidth = Math.max(pathWidth, path(line).length());
}
while (line + 1 < end
&& sameCommit(blame.getSourceCommit(line + 1), c)) {
@@ -280,7 +265,7 @@ && sameCommit(blame.getSourceCommit(line + 1), c)) {
} while (++line < end
&& sameCommit(blame.getSourceCommit(line), c));
}
- } catch (NoWorkTreeException | IOException e) {
+ } catch (NoWorkTreeException | NoHeadException | IOException e) {
throw die(e.getMessage(), e);
}
}
@@ -373,10 +358,12 @@ private String author(int line) {
}
private String date(int line) {
- if (blame.getSourceCommit(line) == null)
- return ""; //$NON-NLS-1$
-
- PersonIdent author = blame.getSourceAuthor(line);
+ PersonIdent author;
+ if (blame.getSourceCommit(line) == null) {
+ author = dummyDate;
+ } else {
+ author = blame.getSourceAuthor(line);
+ }
if (author == null)
return ""; //$NON-NLS-1$
@@ -394,28 +381,37 @@ private String abbreviate(ObjectReader reader, RevCommit commit)
if (r != null)
return r;
- if (showBlankBoundary && commit.getParentCount() == 0)
- commit = null;
-
if (commit == null) {
- int len = showLongRevision ? OBJECT_ID_STRING_LENGTH : (abbrev + 1);
- StringBuilder b = new StringBuilder(len);
- for (int i = 0; i < len; i++)
- b.append(' ');
- r = b.toString();
-
- } else if (!root && commit.getParentCount() == 0) {
- if (showLongRevision)
- r = "^" + commit.name().substring(0, OBJECT_ID_STRING_LENGTH - 1); //$NON-NLS-1$
- else
- r = "^" + reader.abbreviate(commit, abbrev).name(); //$NON-NLS-1$
+ if (showLongRevision) {
+ r = ObjectId.zeroId().name();
+ } else {
+ r = ObjectId.zeroId().abbreviate(abbrev + 1).name();
+ }
} else {
- if (showLongRevision)
- r = commit.name();
- else
- r = reader.abbreviate(commit, abbrev + 1).name();
- }
+ if (showBlankBoundary && commit.getParentCount() == 0)
+ commit = null;
+ if (commit == null) {
+ int len = showLongRevision ? OBJECT_ID_STRING_LENGTH
+ : (abbrev + 1);
+ StringBuilder b = new StringBuilder(len);
+ for (int i = 0; i < len; i++)
+ b.append(' ');
+ r = b.toString();
+
+ } else if (!root && commit.getParentCount() == 0) {
+ if (showLongRevision)
+ r = "^" + commit.name().substring(0, //$NON-NLS-1$
+ OBJECT_ID_STRING_LENGTH - 1);
+ else
+ r = "^" + reader.abbreviate(commit, abbrev).name(); //$NON-NLS-1$
+ } else {
+ if (showLongRevision)
+ r = commit.name();
+ else
+ r = reader.abbreviate(commit, abbrev + 1).name();
+ }
+ }
abbreviatedCommits.put(commit, r);
return r;
}
diff --git a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/Clone.java b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/Clone.java
index fe24620..a6a031e 100644
--- a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/Clone.java
+++ b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/Clone.java
@@ -74,6 +74,9 @@ class Clone extends AbstractFetchCommand implements CloneCommand.Callback {
@Option(name = "--bare", usage = "usage_bareClone")
private boolean isBare;
+ @Option(name = "--mirror", usage = "usage_mirrorClone")
+ private boolean isMirror;
+
@Option(name = "--quiet", usage = "usage_quiet")
private Boolean quiet;
@@ -103,7 +106,7 @@ protected void run() throws Exception {
if (localName == null) {
try {
localName = uri.getHumanishName();
- if (isBare) {
+ if (isBare || isMirror) {
localName = localName + Constants.DOT_GIT_EXT;
}
localNameF = new File(SystemReader.getInstance().getProperty(
@@ -120,6 +123,7 @@ protected void run() throws Exception {
CloneCommand command = Git.cloneRepository();
command.setURI(sourceUri).setRemote(remoteName).setBare(isBare)
+ .setMirror(isMirror)
.setNoCheckout(noCheckout).setBranch(branch)
.setCloneSubmodules(cloneSubmodules);
diff --git a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/ConvertRefStorage.java b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/ConvertRefStorage.java
new file mode 100644
index 0000000..2fd689b
--- /dev/null
+++ b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/ConvertRefStorage.java
@@ -0,0 +1,60 @@
+/*
+ * 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.pgm;
+
+import org.eclipse.jgit.internal.storage.file.FileRepository;
+import org.kohsuke.args4j.Option;
+
+@Command(common=true, usage="usage_convertRefStorage")
+class ConvertRefStorage extends TextBuiltin {
+
+ @Option(name = "--format", usage = "usage_convertRefStorageFormat")
+ private String format = "reftable"; //$NON-NLS-1$
+
+ /** {@inheritDoc} */
+ @Override
+ protected void run() throws Exception {
+ ((FileRepository) db).convertRefStorage(format, true, true);
+ }
+}
diff --git a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/Status.java b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/Status.java
index c3887fe..23ee933 100644
--- a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/Status.java
+++ b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/Status.java
@@ -306,8 +306,8 @@ protected int printList(Collection<String> list) throws IOException {
}
outw.flush();
return list.size();
- } else
- return 0;
+ }
+ return 0;
}
/**
diff --git a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/debug/BenchmarkReftable.java b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/debug/BenchmarkReftable.java
index 248eaac..27a7347 100644
--- a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/debug/BenchmarkReftable.java
+++ b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/debug/BenchmarkReftable.java
@@ -51,14 +51,18 @@
import static org.eclipse.jgit.lib.Ref.Storage.PACKED;
import java.io.BufferedReader;
+import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStreamReader;
+import java.util.List;
+import org.eclipse.jgit.internal.storage.file.FileReftableStack;
import org.eclipse.jgit.internal.storage.io.BlockSource;
import org.eclipse.jgit.internal.storage.reftable.RefCursor;
import org.eclipse.jgit.internal.storage.reftable.ReftableReader;
+import org.eclipse.jgit.lib.Config;
import org.eclipse.jgit.lib.ObjectId;
import org.eclipse.jgit.lib.ObjectIdRef;
import org.eclipse.jgit.lib.Ref;
@@ -74,7 +78,8 @@ class BenchmarkReftable extends TextBuiltin {
enum Test {
SCAN,
SEEK_COLD, SEEK_HOT,
- BY_ID_COLD, BY_ID_HOT;
+ BY_ID_COLD, BY_ID_HOT,
+ WRITE_STACK,
}
@Option(name = "--tries")
@@ -116,6 +121,9 @@ protected void run() throws Exception {
case BY_ID_HOT:
byIdHot(ObjectId.fromString(objectId));
break;
+ case WRITE_STACK:
+ writeStack();
+ break;
}
}
@@ -124,6 +132,33 @@ private void printf(String fmt, Object... args) throws IOException {
}
@SuppressWarnings({ "nls", "boxing" })
+ private void writeStack() throws Exception {
+ File dir = new File(reftablePath);
+ File stackFile = new File(reftablePath + ".stack");
+
+ dir.mkdirs();
+
+ long start = System.currentTimeMillis();
+ try (FileReftableStack stack = new FileReftableStack(stackFile, dir,
+ null, () -> new Config())) {
+
+ List<Ref> refs = readLsRemote().asList();
+ for (Ref r : refs) {
+ final long j = stack.getMergedReftable().maxUpdateIndex() + 1;
+ if (!stack.addReftable(w -> {
+ w.setMaxUpdateIndex(j).setMinUpdateIndex(j).begin()
+ .writeRef(r);
+ })) {
+ throw new IOException("should succeed");
+ }
+ }
+ long dt = System.currentTimeMillis() - start;
+ printf("%12s %10d ms avg %6d us/write", "reftable", dt,
+ (dt * 1000) / refs.size());
+ }
+ }
+
+ @SuppressWarnings({ "nls", "boxing" })
private void scan() throws Exception {
long start, tot;
diff --git a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/debug/DiffAlgorithms.java b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/debug/DiffAlgorithms.java
index 85a7444..61cf2ab 100644
--- a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/debug/DiffAlgorithms.java
+++ b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/debug/DiffAlgorithms.java
@@ -350,7 +350,7 @@ private static boolean included(String name, List<String> want) {
return false;
}
- private static abstract class Algorithm {
+ private abstract static class Algorithm {
String name;
abstract DiffAlgorithm create();
diff --git a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/debug/LfsStore.java b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/debug/LfsStore.java
index 973b0d7..fe203e3 100644
--- a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/debug/LfsStore.java
+++ b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/debug/LfsStore.java
@@ -161,11 +161,11 @@ private void assertNotRunning() {
}
}
- private static enum StoreType {
+ private enum StoreType {
FS, S3;
}
- private static enum StorageClass {
+ private enum StorageClass {
REDUCED_REDUNDANCY, STANDARD
}
diff --git a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/debug/RebuildCommitGraph.java b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/debug/RebuildCommitGraph.java
index 8948c27..0d30f36 100644
--- a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/debug/RebuildCommitGraph.java
+++ b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/debug/RebuildCommitGraph.java
@@ -189,9 +189,8 @@ private void recreateCommitGraph() throws IOException {
// rewritten.
queue.add(t);
continue REWRITE;
- } else {
- newParents[k] = p.newId;
}
+ newParents[k] = p.newId;
} else {
// We have the old parent object. Use it.
//
diff --git a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/debug/ShowCommands.java b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/debug/ShowCommands.java
index af56d65..d526a53 100644
--- a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/debug/ShowCommands.java
+++ b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/debug/ShowCommands.java
@@ -83,7 +83,7 @@ protected void run() throws Exception {
errw.println();
}
- static enum Format {
+ enum Format {
/** */
USAGE {
@Override
diff --git a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/debug/TextHashFunctions.java b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/debug/TextHashFunctions.java
index a2ea8c2..73ea2a0 100644
--- a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/debug/TextHashFunctions.java
+++ b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/debug/TextHashFunctions.java
@@ -138,9 +138,8 @@ protected int hashRegion(byte[] raw, int ptr, int end) {
Arrays.fill(buf16, (byte) 0);
System.arraycopy(raw, ptr, buf16, 0, end - ptr);
return rabin(buf16, 0);
- } else {
- return rabin(raw, ptr);
}
+ return rabin(raw, ptr);
}
private int rabin(byte[] raw, int ptr) {
@@ -444,7 +443,7 @@ private static class Function {
}
/** Base class for any hashCode function to be tested. */
- private static abstract class Hash extends RawTextComparator {
+ private abstract static class Hash extends RawTextComparator {
String name;
@Override
@@ -454,7 +453,7 @@ public boolean equals(RawText a, int ai, RawText b, int bi) {
}
/** Base class for any hashCode folding function to be tested. */
- private static abstract class Fold {
+ private abstract static class Fold {
String name;
/**
diff --git a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/debug/WriteReftable.java b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/debug/WriteReftable.java
index 6cbc1b0..0320ed1 100644
--- a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/debug/WriteReftable.java
+++ b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/debug/WriteReftable.java
@@ -128,9 +128,9 @@ protected void run() throws Exception {
cfg.setMaxIndexLevels(indexLevels);
}
- ReftableWriter w = new ReftableWriter(cfg);
+ ReftableWriter w = new ReftableWriter(cfg, os);
w.setMinUpdateIndex(min(logs)).setMaxUpdateIndex(max(logs));
- w.begin(os);
+ w.begin();
w.sortAndWriteRefs(refs);
for (LogEntry e : logs) {
w.writeLog(e.ref, e.updateIndex, e.who,
diff --git a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/opt/CmdLineParser.java b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/opt/CmdLineParser.java
index b97aa5b..d3aa38c 100644
--- a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/opt/CmdLineParser.java
+++ b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/opt/CmdLineParser.java
@@ -299,10 +299,10 @@ public boolean required() {
/** {@inheritDoc} */
@Override
protected OptionHandler createOptionHandler(OptionDef o, Setter setter) {
- if (o instanceof NamedOptionDef)
+ if (o instanceof NamedOptionDef) {
return super.createOptionHandler(o, setter);
- else
- return super.createOptionHandler(new MyOptionDef(o), setter);
+ }
+ return super.createOptionHandler(new MyOptionDef(o), setter);
}
diff --git a/org.eclipse.jgit.ssh.apache.test/.settings/org.eclipse.jdt.core.prefs b/org.eclipse.jgit.ssh.apache.test/.settings/org.eclipse.jdt.core.prefs
index 794592d..822846c 100644
--- a/org.eclipse.jgit.ssh.apache.test/.settings/org.eclipse.jdt.core.prefs
+++ b/org.eclipse.jgit.ssh.apache.test/.settings/org.eclipse.jdt.core.prefs
@@ -92,7 +92,7 @@
org.eclipse.jdt.core.compiler.problem.unclosedCloseable=warning
org.eclipse.jdt.core.compiler.problem.undocumentedEmptyBlock=warning
org.eclipse.jdt.core.compiler.problem.unhandledWarningToken=warning
-org.eclipse.jdt.core.compiler.problem.unnecessaryElse=ignore
+org.eclipse.jdt.core.compiler.problem.unnecessaryElse=warning
org.eclipse.jdt.core.compiler.problem.unnecessaryTypeCheck=error
org.eclipse.jdt.core.compiler.problem.unqualifiedFieldAccess=ignore
org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownException=error
diff --git a/org.eclipse.jgit.ssh.apache.test/META-INF/MANIFEST.MF b/org.eclipse.jgit.ssh.apache.test/META-INF/MANIFEST.MF
index 81969e7..e97058c 100644
--- a/org.eclipse.jgit.ssh.apache.test/META-INF/MANIFEST.MF
+++ b/org.eclipse.jgit.ssh.apache.test/META-INF/MANIFEST.MF
@@ -3,7 +3,7 @@
Bundle-Name: %Bundle-Name
Automatic-Module-Name: org.eclipse.jgit.ssh.apache.test
Bundle-SymbolicName: org.eclipse.jgit.ssh.apache.test
-Bundle-Version: 5.5.2.qualifier
+Bundle-Version: 5.6.2.qualifier
Bundle-Vendor: %Bundle-Vendor
Bundle-Localization: plugin
Bundle-RequiredExecutionEnvironment: JavaSE-1.8
@@ -15,15 +15,15 @@
org.apache.sshd.common.session;version="[2.2.0,2.3.0)",
org.apache.sshd.common.util.net;version="[2.2.0,2.3.0)",
org.apache.sshd.common.util.security;version="[2.2.0,2.3.0)",
- org.eclipse.jgit.api.errors;version="[5.5.2,5.6.0)",
- org.eclipse.jgit.internal.transport.sshd.proxy;version="[5.5.2,5.6.0)",
- org.eclipse.jgit.junit;version="[5.5.2,5.6.0)",
- org.eclipse.jgit.junit.ssh;version="[5.5.2,5.6.0)",
- org.eclipse.jgit.lib;version="[5.5.2,5.6.0)",
- org.eclipse.jgit.transport;version="[5.5.2,5.6.0)",
- org.eclipse.jgit.transport.ssh;version="[5.5.2,5.6.0)",
- org.eclipse.jgit.transport.sshd;version="[5.5.2,5.6.0)",
- org.eclipse.jgit.util;version="[5.5.2,5.6.0)",
+ org.eclipse.jgit.api.errors;version="[5.6.2,5.7.0)",
+ org.eclipse.jgit.internal.transport.sshd.proxy;version="[5.6.2,5.7.0)",
+ org.eclipse.jgit.junit;version="[5.6.2,5.7.0)",
+ org.eclipse.jgit.junit.ssh;version="[5.6.2,5.7.0)",
+ org.eclipse.jgit.lib;version="[5.6.2,5.7.0)",
+ org.eclipse.jgit.transport;version="[5.6.2,5.7.0)",
+ org.eclipse.jgit.transport.ssh;version="[5.6.2,5.7.0)",
+ org.eclipse.jgit.transport.sshd;version="[5.6.2,5.7.0)",
+ org.eclipse.jgit.util;version="[5.6.2,5.7.0)",
org.junit;version="[4.12,5.0.0)",
org.junit.experimental.theories;version="[4.12,5.0.0)",
org.junit.runner;version="[4.12,5.0.0)"
diff --git a/org.eclipse.jgit.ssh.apache.test/pom.xml b/org.eclipse.jgit.ssh.apache.test/pom.xml
index 0f2504c..18196bf 100644
--- a/org.eclipse.jgit.ssh.apache.test/pom.xml
+++ b/org.eclipse.jgit.ssh.apache.test/pom.xml
@@ -50,7 +50,7 @@
<parent>
<groupId>org.eclipse.jgit</groupId>
<artifactId>org.eclipse.jgit-parent</artifactId>
- <version>5.5.2-SNAPSHOT</version>
+ <version>5.6.2-SNAPSHOT</version>
</parent>
<artifactId>org.eclipse.jgit.ssh.apache.test</artifactId>
diff --git a/org.eclipse.jgit.ssh.apache/.settings/org.eclipse.jdt.core.prefs b/org.eclipse.jgit.ssh.apache/.settings/org.eclipse.jdt.core.prefs
index 13c32a6..15ef2aa 100644
--- a/org.eclipse.jgit.ssh.apache/.settings/org.eclipse.jdt.core.prefs
+++ b/org.eclipse.jgit.ssh.apache/.settings/org.eclipse.jdt.core.prefs
@@ -92,7 +92,7 @@
org.eclipse.jdt.core.compiler.problem.unclosedCloseable=warning
org.eclipse.jdt.core.compiler.problem.undocumentedEmptyBlock=warning
org.eclipse.jdt.core.compiler.problem.unhandledWarningToken=warning
-org.eclipse.jdt.core.compiler.problem.unnecessaryElse=ignore
+org.eclipse.jdt.core.compiler.problem.unnecessaryElse=warning
org.eclipse.jdt.core.compiler.problem.unnecessaryTypeCheck=error
org.eclipse.jdt.core.compiler.problem.unqualifiedFieldAccess=ignore
org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownException=warning
diff --git a/org.eclipse.jgit.ssh.apache/META-INF/MANIFEST.MF b/org.eclipse.jgit.ssh.apache/META-INF/MANIFEST.MF
index 6a11b18..a04612f 100644
--- a/org.eclipse.jgit.ssh.apache/META-INF/MANIFEST.MF
+++ b/org.eclipse.jgit.ssh.apache/META-INF/MANIFEST.MF
@@ -6,9 +6,9 @@
Bundle-Vendor: %Bundle-Vendor
Bundle-Localization: plugin
Bundle-ActivationPolicy: lazy
-Bundle-Version: 5.5.2.qualifier
+Bundle-Version: 5.6.2.qualifier
Bundle-RequiredExecutionEnvironment: JavaSE-1.8
-Export-Package: org.eclipse.jgit.internal.transport.sshd;version="5.5.2";x-internal:=true;
+Export-Package: org.eclipse.jgit.internal.transport.sshd;version="5.6.2";x-internal:=true;
uses:="org.apache.sshd.client,
org.apache.sshd.client.auth,
org.apache.sshd.client.auth.keyboard,
@@ -23,9 +23,9 @@
org.apache.sshd.common.signature,
org.apache.sshd.common.util.buffer,
org.eclipse.jgit.transport",
- org.eclipse.jgit.internal.transport.sshd.auth;version="5.5.2";x-internal:=true,
- org.eclipse.jgit.internal.transport.sshd.proxy;version="5.5.2";x-friends:="org.eclipse.jgit.ssh.apache.test",
- org.eclipse.jgit.transport.sshd;version="5.5.2";
+ org.eclipse.jgit.internal.transport.sshd.auth;version="5.6.2";x-internal:=true,
+ org.eclipse.jgit.internal.transport.sshd.proxy;version="5.6.2";x-friends:="org.eclipse.jgit.ssh.apache.test",
+ org.eclipse.jgit.transport.sshd;version="5.6.2";
uses:="org.eclipse.jgit.transport,
org.apache.sshd.client.config.hosts,
org.apache.sshd.common.keyprovider,
@@ -75,12 +75,12 @@
org.apache.sshd.common.util.net;version="[2.2.0,2.3.0)",
org.apache.sshd.common.util.security;version="[2.2.0,2.3.0)",
org.apache.sshd.server.auth;version="[2.2.0,2.3.0)",
- org.eclipse.jgit.annotations;version="[5.5.2,5.6.0)",
- org.eclipse.jgit.errors;version="[5.5.2,5.6.0)",
- org.eclipse.jgit.fnmatch;version="[5.5.2,5.6.0)",
- org.eclipse.jgit.internal.storage.file;version="[5.5.2,5.6.0)",
- org.eclipse.jgit.internal.transport.ssh;version="[5.5.2,5.6.0)",
- org.eclipse.jgit.nls;version="[5.5.2,5.6.0)",
- org.eclipse.jgit.transport;version="[5.5.2,5.6.0)",
- org.eclipse.jgit.util;version="[5.5.2,5.6.0)",
+ org.eclipse.jgit.annotations;version="[5.6.2,5.7.0)",
+ org.eclipse.jgit.errors;version="[5.6.2,5.7.0)",
+ org.eclipse.jgit.fnmatch;version="[5.6.2,5.7.0)",
+ org.eclipse.jgit.internal.storage.file;version="[5.6.2,5.7.0)",
+ org.eclipse.jgit.internal.transport.ssh;version="[5.6.2,5.7.0)",
+ org.eclipse.jgit.nls;version="[5.6.2,5.7.0)",
+ org.eclipse.jgit.transport;version="[5.6.2,5.7.0)",
+ org.eclipse.jgit.util;version="[5.6.2,5.7.0)",
org.slf4j;version="[1.7.0,2.0.0)"
diff --git a/org.eclipse.jgit.ssh.apache/META-INF/SOURCE-MANIFEST.MF b/org.eclipse.jgit.ssh.apache/META-INF/SOURCE-MANIFEST.MF
index 8991b5b..93c8e88 100644
--- a/org.eclipse.jgit.ssh.apache/META-INF/SOURCE-MANIFEST.MF
+++ b/org.eclipse.jgit.ssh.apache/META-INF/SOURCE-MANIFEST.MF
@@ -3,5 +3,5 @@
Bundle-Name: org.eclipse.jgit.ssh.apache - Sources
Bundle-SymbolicName: org.eclipse.jgit.ssh.apache.source
Bundle-Vendor: Eclipse.org - JGit
-Bundle-Version: 5.5.2.qualifier
-Eclipse-SourceBundle: org.eclipse.jgit.ssh.apache;version="5.5.2.qualifier";roots="."
+Bundle-Version: 5.6.2.qualifier
+Eclipse-SourceBundle: org.eclipse.jgit.ssh.apache;version="5.6.2.qualifier";roots="."
diff --git a/org.eclipse.jgit.ssh.apache/pom.xml b/org.eclipse.jgit.ssh.apache/pom.xml
index f412d63..19a5c28 100644
--- a/org.eclipse.jgit.ssh.apache/pom.xml
+++ b/org.eclipse.jgit.ssh.apache/pom.xml
@@ -50,7 +50,7 @@
<parent>
<groupId>org.eclipse.jgit</groupId>
<artifactId>org.eclipse.jgit-parent</artifactId>
- <version>5.5.2-SNAPSHOT</version>
+ <version>5.6.2-SNAPSHOT</version>
</parent>
<artifactId>org.eclipse.jgit.ssh.apache</artifactId>
diff --git a/org.eclipse.jgit.ssh.apache/src/org/eclipse/jgit/internal/transport/sshd/CachingKeyPairProvider.java b/org.eclipse.jgit.ssh.apache/src/org/eclipse/jgit/internal/transport/sshd/CachingKeyPairProvider.java
index a1ec318..9673ff0 100644
--- a/org.eclipse.jgit.ssh.apache/src/org/eclipse/jgit/internal/transport/sshd/CachingKeyPairProvider.java
+++ b/org.eclipse.jgit.ssh.apache/src/org/eclipse/jgit/internal/transport/sshd/CachingKeyPairProvider.java
@@ -121,7 +121,7 @@ private KeyPair loadKey(SessionContext session, Path path)
if (cache == null) {
return loadKey(session, resource, path, getPasswordFinder());
}
- Throwable t[] = { null };
+ Throwable[] t = { null };
KeyPair key = cache.get(path, p -> {
try {
return loadKey(session, resource, p, getPasswordFinder());
diff --git a/org.eclipse.jgit.ssh.apache/src/org/eclipse/jgit/internal/transport/sshd/JGitClientSession.java b/org.eclipse.jgit.ssh.apache/src/org/eclipse/jgit/internal/transport/sshd/JGitClientSession.java
index 1954abc..79bd3fa 100644
--- a/org.eclipse.jgit.ssh.apache/src/org/eclipse/jgit/internal/transport/sshd/JGitClientSession.java
+++ b/org.eclipse.jgit.ssh.apache/src/org/eclipse/jgit/internal/transport/sshd/JGitClientSession.java
@@ -179,9 +179,8 @@ protected IoWriteFuture sendIdentification(String ident)
} catch (Exception other) {
throw new IOException(other.getLocalizedMessage(), other);
}
- } else {
- return super.sendIdentification(ident);
}
+ return super.sendIdentification(ident);
}
@Override
@@ -205,9 +204,8 @@ protected IoWriteFuture sendIdentification(String ident)
} catch (Exception other) {
throw new IOException(other.getLocalizedMessage(), other);
}
- } else {
- return super.sendKexInit();
}
+ return super.sendKexInit();
}
/**
diff --git a/org.eclipse.jgit.ssh.apache/src/org/eclipse/jgit/internal/transport/sshd/OpenSshServerKeyDatabase.java b/org.eclipse.jgit.ssh.apache/src/org/eclipse/jgit/internal/transport/sshd/OpenSshServerKeyDatabase.java
index f4849ce..9c0a793 100644
--- a/org.eclipse.jgit.ssh.apache/src/org/eclipse/jgit/internal/transport/sshd/OpenSshServerKeyDatabase.java
+++ b/org.eclipse.jgit.ssh.apache/src/org/eclipse/jgit/internal/transport/sshd/OpenSshServerKeyDatabase.java
@@ -453,9 +453,8 @@ private static boolean askUser(CredentialsProvider provider, URIish uri,
prompt);
items.add(answer);
return provider.get(uri, items) && answer.getValue();
- } else {
- return provider.get(uri, items);
}
+ return provider.get(uri, items);
}
private Check checkMode(SocketAddress remoteAddress, boolean changed) {
diff --git a/org.eclipse.jgit.ssh.apache/src/org/eclipse/jgit/internal/transport/sshd/proxy/HttpParser.java b/org.eclipse.jgit.ssh.apache/src/org/eclipse/jgit/internal/transport/sshd/proxy/HttpParser.java
index b9b32b1..af8bf47 100644
--- a/org.eclipse.jgit.ssh.apache/src/org/eclipse/jgit/internal/transport/sshd/proxy/HttpParser.java
+++ b/org.eclipse.jgit.ssh.apache/src/org/eclipse/jgit/internal/transport/sshd/proxy/HttpParser.java
@@ -207,11 +207,10 @@ private static int parseChallenge(AuthenticationChallenge challenge,
next++;
}
return next;
- } else {
- // This token must be the name of the next authentication
- // scheme.
- return start;
}
+ // This token must be the name of the next authentication
+ // scheme.
+ return start;
}
int nextStart = skipWhiteSpace(header, next + 1);
if (nextStart >= length) {
@@ -244,14 +243,13 @@ private static int parseChallenge(AuthenticationChallenge challenge,
// token, and the equals sign is part of the token
challenge.setToken(header.substring(start, end + 1));
return nextStart + 1;
- } else {
- // Key without value...
- challenge.addArgument(header.substring(start, end), null);
- start = nextStart + 1;
}
+ // Key without value...
+ challenge.addArgument(header.substring(start, end), null);
+ start = nextStart + 1;
} else {
if (header.charAt(nextStart) == '"') {
- int nextEnd[] = { nextStart + 1 };
+ int[] nextEnd = { nextStart + 1 };
String value = scanQuotedString(header, nextStart + 1,
nextEnd);
challenge.addArgument(header.substring(start, end), value);
diff --git a/org.eclipse.jgit.ssh.apache/src/org/eclipse/jgit/internal/transport/sshd/proxy/Socks5ClientConnector.java b/org.eclipse.jgit.ssh.apache/src/org/eclipse/jgit/internal/transport/sshd/proxy/Socks5ClientConnector.java
index 27d6f41..b3681d1 100644
--- a/org.eclipse.jgit.ssh.apache/src/org/eclipse/jgit/internal/transport/sshd/proxy/Socks5ClientConnector.java
+++ b/org.eclipse.jgit.ssh.apache/src/org/eclipse/jgit/internal/transport/sshd/proxy/Socks5ClientConnector.java
@@ -281,11 +281,10 @@ public void sendClientProxyMetadata(ClientSession sshSession)
}
if (i == proposals.length) {
return proposals;
- } else {
- byte[] result = new byte[i];
- System.arraycopy(proposals, 0, result, 0, i);
- return result;
}
+ byte[] result = new byte[i];
+ System.arraycopy(proposals, 0, result, 0, i);
+ return result;
}
private void sendConnectInfo(IoSession session) throws Exception {
diff --git a/org.eclipse.jgit.ssh.apache/src/org/eclipse/jgit/transport/sshd/SshdSession.java b/org.eclipse.jgit.ssh.apache/src/org/eclipse/jgit/transport/sshd/SshdSession.java
index 1e8d7d1..3fc955a 100644
--- a/org.eclipse.jgit.ssh.apache/src/org/eclipse/jgit/transport/sshd/SshdSession.java
+++ b/org.eclipse.jgit.ssh.apache/src/org/eclipse/jgit/transport/sshd/SshdSession.java
@@ -354,9 +354,8 @@ private String absolute(String path) {
if (path.charAt(0) != '/') {
if (cwd.charAt(cwd.length() - 1) == '/') {
return cwd + path;
- } else {
- return cwd + '/' + path;
}
+ return cwd + '/' + path;
}
return path;
}
diff --git a/org.eclipse.jgit.test/.settings/org.eclipse.jdt.core.prefs b/org.eclipse.jgit.test/.settings/org.eclipse.jdt.core.prefs
index d4751b5..4c4634a 100644
--- a/org.eclipse.jgit.test/.settings/org.eclipse.jdt.core.prefs
+++ b/org.eclipse.jgit.test/.settings/org.eclipse.jdt.core.prefs
@@ -92,7 +92,7 @@
org.eclipse.jdt.core.compiler.problem.unclosedCloseable=warning
org.eclipse.jdt.core.compiler.problem.undocumentedEmptyBlock=warning
org.eclipse.jdt.core.compiler.problem.unhandledWarningToken=ignore
-org.eclipse.jdt.core.compiler.problem.unnecessaryElse=ignore
+org.eclipse.jdt.core.compiler.problem.unnecessaryElse=warning
org.eclipse.jdt.core.compiler.problem.unnecessaryTypeCheck=error
org.eclipse.jdt.core.compiler.problem.unqualifiedFieldAccess=ignore
org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownException=error
diff --git a/org.eclipse.jgit.test/BUILD b/org.eclipse.jgit.test/BUILD
index 3f664f9..3d48796 100644
--- a/org.eclipse.jgit.test/BUILD
+++ b/org.eclipse.jgit.test/BUILD
@@ -24,6 +24,7 @@
"revwalk/RevQueueTestCase.java",
"revwalk/RevWalkTestCase.java",
"transport/ObjectIdMatcher.java",
+ "transport/RequestValidatorTestCase.java",
"transport/SpiTransport.java",
"treewalk/filter/AlwaysCloneTreeFilter.java",
"test/resources/SampleDataRepositoryTestCase.java",
diff --git a/org.eclipse.jgit.test/META-INF/MANIFEST.MF b/org.eclipse.jgit.test/META-INF/MANIFEST.MF
index 42c9c57..5b8ce44 100644
--- a/org.eclipse.jgit.test/META-INF/MANIFEST.MF
+++ b/org.eclipse.jgit.test/META-INF/MANIFEST.MF
@@ -3,7 +3,7 @@
Bundle-Name: %Bundle-Name
Automatic-Module-Name: org.eclipse.jgit.test
Bundle-SymbolicName: org.eclipse.jgit.test
-Bundle-Version: 5.5.2.qualifier
+Bundle-Version: 5.6.2.qualifier
Bundle-Localization: plugin
Bundle-Vendor: %Bundle-Vendor
Bundle-ActivationPolicy: lazy
@@ -18,57 +18,58 @@
org.apache.commons.compress.compressors.gzip;version="[1.15.0,2.0)",
org.apache.commons.compress.compressors.xz;version="[1.15.0,2.0)",
org.bouncycastle.util.encoders;version="[1.61.0,2.0.0)",
- org.eclipse.jgit.annotations;version="[5.5.2,5.6.0)",
- org.eclipse.jgit.api;version="[5.5.2,5.6.0)",
- org.eclipse.jgit.api.errors;version="[5.5.2,5.6.0)",
- org.eclipse.jgit.archive;version="[5.5.2,5.6.0)",
- org.eclipse.jgit.attributes;version="[5.5.2,5.6.0)",
- org.eclipse.jgit.awtui;version="[5.5.2,5.6.0)",
- org.eclipse.jgit.blame;version="[5.5.2,5.6.0)",
- org.eclipse.jgit.diff;version="[5.5.2,5.6.0)",
- org.eclipse.jgit.dircache;version="[5.5.2,5.6.0)",
- org.eclipse.jgit.errors;version="[5.5.2,5.6.0)",
- org.eclipse.jgit.events;version="[5.5.2,5.6.0)",
- org.eclipse.jgit.fnmatch;version="[5.5.2,5.6.0)",
- org.eclipse.jgit.gitrepo;version="[5.5.2,5.6.0)",
- org.eclipse.jgit.hooks;version="[5.5.2,5.6.0)",
- org.eclipse.jgit.ignore;version="[5.5.2,5.6.0)",
- org.eclipse.jgit.ignore.internal;version="[5.5.2,5.6.0)",
- org.eclipse.jgit.internal;version="[5.5.2,5.6.0)",
- org.eclipse.jgit.internal.fsck;version="[5.5.2,5.6.0)",
- org.eclipse.jgit.internal.storage.dfs;version="[5.5.2,5.6.0)",
- org.eclipse.jgit.internal.storage.file;version="[5.5.2,5.6.0)",
- org.eclipse.jgit.internal.storage.io;version="[5.5.2,5.6.0)",
- org.eclipse.jgit.internal.storage.pack;version="[5.5.2,5.6.0)",
- org.eclipse.jgit.internal.storage.reftable;version="[5.5.2,5.6.0)",
- org.eclipse.jgit.internal.storage.reftree;version="[5.5.2,5.6.0)",
- org.eclipse.jgit.internal.transport.http;version="[5.5.2,5.6.0)",
- org.eclipse.jgit.internal.transport.parser;version="[5.5.2,5.6.0)",
- org.eclipse.jgit.junit;version="[5.5.2,5.6.0)",
- org.eclipse.jgit.junit.ssh;version="[5.5.2,5.6.0)",
- org.eclipse.jgit.junit.time;version="[5.5.2,5.6.0)",
- org.eclipse.jgit.lfs;version="[5.5.2,5.6.0)",
- org.eclipse.jgit.lib;version="[5.5.2,5.6.0)",
- org.eclipse.jgit.merge;version="[5.5.2,5.6.0)",
- org.eclipse.jgit.nls;version="[5.5.2,5.6.0)",
- org.eclipse.jgit.notes;version="[5.5.2,5.6.0)",
- org.eclipse.jgit.patch;version="[5.5.2,5.6.0)",
- org.eclipse.jgit.pgm;version="[5.5.2,5.6.0)",
- org.eclipse.jgit.pgm.internal;version="[5.5.2,5.6.0)",
- org.eclipse.jgit.revplot;version="[5.5.2,5.6.0)",
- org.eclipse.jgit.revwalk;version="[5.5.2,5.6.0)",
- org.eclipse.jgit.revwalk.filter;version="[5.5.2,5.6.0)",
- org.eclipse.jgit.storage.file;version="[5.5.2,5.6.0)",
- org.eclipse.jgit.storage.pack;version="[5.5.2,5.6.0)",
- org.eclipse.jgit.submodule;version="[5.5.2,5.6.0)",
- org.eclipse.jgit.transport;version="[5.5.2,5.6.0)",
- org.eclipse.jgit.transport.http;version="[5.5.2,5.6.0)",
- org.eclipse.jgit.transport.resolver;version="[5.5.2,5.6.0)",
- org.eclipse.jgit.treewalk;version="[5.5.2,5.6.0)",
- org.eclipse.jgit.treewalk.filter;version="[5.5.2,5.6.0)",
- org.eclipse.jgit.util;version="[5.5.2,5.6.0)",
- org.eclipse.jgit.util.io;version="[5.5.2,5.6.0)",
- org.eclipse.jgit.util.sha1;version="[5.5.2,5.6.0)",
+ org.eclipse.jgit.annotations;version="[5.6.2,5.7.0)",
+ org.eclipse.jgit.api;version="[5.6.2,5.7.0)",
+ org.eclipse.jgit.api.errors;version="[5.6.2,5.7.0)",
+ org.eclipse.jgit.archive;version="[5.6.2,5.7.0)",
+ org.eclipse.jgit.attributes;version="[5.6.2,5.7.0)",
+ org.eclipse.jgit.awtui;version="[5.6.2,5.7.0)",
+ org.eclipse.jgit.blame;version="[5.6.2,5.7.0)",
+ org.eclipse.jgit.diff;version="[5.6.2,5.7.0)",
+ org.eclipse.jgit.dircache;version="[5.6.2,5.7.0)",
+ org.eclipse.jgit.errors;version="[5.6.2,5.7.0)",
+ org.eclipse.jgit.events;version="[5.6.2,5.7.0)",
+ org.eclipse.jgit.fnmatch;version="[5.6.2,5.7.0)",
+ org.eclipse.jgit.gitrepo;version="[5.6.2,5.7.0)",
+ org.eclipse.jgit.hooks;version="[5.6.2,5.7.0)",
+ org.eclipse.jgit.ignore;version="[5.6.2,5.7.0)",
+ org.eclipse.jgit.ignore.internal;version="[5.6.2,5.7.0)",
+ org.eclipse.jgit.internal;version="[5.6.2,5.7.0)",
+ org.eclipse.jgit.internal.fsck;version="[5.6.2,5.7.0)",
+ org.eclipse.jgit.internal.storage.dfs;version="[5.6.2,5.7.0)",
+ org.eclipse.jgit.internal.storage.file;version="[5.6.2,5.7.0)",
+ org.eclipse.jgit.internal.storage.io;version="[5.6.2,5.7.0)",
+ org.eclipse.jgit.internal.storage.pack;version="[5.6.2,5.7.0)",
+ org.eclipse.jgit.internal.storage.reftable;version="[5.6.2,5.7.0)",
+ org.eclipse.jgit.internal.storage.reftree;version="[5.6.2,5.7.0)",
+ org.eclipse.jgit.internal.transport.http;version="[5.6.2,5.7.0)",
+ org.eclipse.jgit.internal.transport.parser;version="[5.6.2,5.7.0)",
+ org.eclipse.jgit.junit;version="[5.6.2,5.7.0)",
+ org.eclipse.jgit.junit.ssh;version="[5.6.2,5.7.0)",
+ org.eclipse.jgit.junit.time;version="[5.6.2,5.7.0)",
+ org.eclipse.jgit.lfs;version="[5.6.2,5.7.0)",
+ org.eclipse.jgit.lib;version="[5.6.2,5.7.0)",
+ org.eclipse.jgit.lib.internal;version="[5.6.2,5.7.0)",
+ org.eclipse.jgit.merge;version="[5.6.2,5.7.0)",
+ org.eclipse.jgit.nls;version="[5.6.2,5.7.0)",
+ org.eclipse.jgit.notes;version="[5.6.2,5.7.0)",
+ org.eclipse.jgit.patch;version="[5.6.2,5.7.0)",
+ org.eclipse.jgit.pgm;version="[5.6.2,5.7.0)",
+ org.eclipse.jgit.pgm.internal;version="[5.6.2,5.7.0)",
+ org.eclipse.jgit.revplot;version="[5.6.2,5.7.0)",
+ org.eclipse.jgit.revwalk;version="[5.6.2,5.7.0)",
+ org.eclipse.jgit.revwalk.filter;version="[5.6.2,5.7.0)",
+ org.eclipse.jgit.storage.file;version="[5.6.2,5.7.0)",
+ org.eclipse.jgit.storage.pack;version="[5.6.2,5.7.0)",
+ org.eclipse.jgit.submodule;version="[5.6.2,5.7.0)",
+ org.eclipse.jgit.transport;version="[5.6.2,5.7.0)",
+ org.eclipse.jgit.transport.http;version="[5.6.2,5.7.0)",
+ org.eclipse.jgit.transport.resolver;version="[5.6.2,5.7.0)",
+ org.eclipse.jgit.treewalk;version="[5.6.2,5.7.0)",
+ org.eclipse.jgit.treewalk.filter;version="[5.6.2,5.7.0)",
+ org.eclipse.jgit.util;version="[5.6.2,5.7.0)",
+ org.eclipse.jgit.util.io;version="[5.6.2,5.7.0)",
+ org.eclipse.jgit.util.sha1;version="[5.6.2,5.7.0)",
org.junit;version="[4.12,5.0.0)",
org.junit.experimental.theories;version="[4.12,5.0.0)",
org.junit.rules;version="[4.12,5.0.0)",
@@ -83,4 +84,4 @@
org.tukaani.xz;version="[1.6.0,2.0)"
Require-Bundle: org.hamcrest.core;bundle-version="[1.1.0,2.0.0)",
org.hamcrest.library;bundle-version="[1.1.0,2.0.0)"
-Export-Package: org.eclipse.jgit.transport.ssh;version="5.5.2";x-friends:="org.eclipse.jgit.ssh.apache.test"
+Export-Package: org.eclipse.jgit.transport.ssh;version="5.6.2";x-friends:="org.eclipse.jgit.ssh.apache.test"
diff --git a/org.eclipse.jgit.test/exttst/org/eclipse/jgit/patch/EGitPatchHistoryTest.java b/org.eclipse.jgit.test/exttst/org/eclipse/jgit/patch/EGitPatchHistoryTest.java
index f597f2f..6a006e2 100644
--- a/org.eclipse.jgit.test/exttst/org/eclipse/jgit/patch/EGitPatchHistoryTest.java
+++ b/org.eclipse.jgit.test/exttst/org/eclipse/jgit/patch/EGitPatchHistoryTest.java
@@ -185,7 +185,7 @@ void onCommit(String commitId, byte[] buf) {
}
}
- static abstract class CommitReader {
+ abstract static class CommitReader {
private Process proc;
CommitReader(String[] args) throws IOException {
diff --git a/org.eclipse.jgit.test/pom.xml b/org.eclipse.jgit.test/pom.xml
index 91c3418..cb04748 100644
--- a/org.eclipse.jgit.test/pom.xml
+++ b/org.eclipse.jgit.test/pom.xml
@@ -52,7 +52,7 @@
<parent>
<groupId>org.eclipse.jgit</groupId>
<artifactId>org.eclipse.jgit-parent</artifactId>
- <version>5.5.2-SNAPSHOT</version>
+ <version>5.6.2-SNAPSHOT</version>
</parent>
<artifactId>org.eclipse.jgit.test</artifactId>
diff --git a/org.eclipse.jgit.test/src/org/eclipse/jgit/events/ChangeRecorder.java b/org.eclipse.jgit.test/src/org/eclipse/jgit/events/ChangeRecorder.java
index 228df35..e1f6b12 100644
--- a/org.eclipse.jgit.test/src/org/eclipse/jgit/events/ChangeRecorder.java
+++ b/org.eclipse.jgit.test/src/org/eclipse/jgit/events/ChangeRecorder.java
@@ -43,7 +43,6 @@
package org.eclipse.jgit.events;
-import static org.junit.Assert.assertArrayEquals;
import static org.junit.Assert.assertEquals;
import java.util.Arrays;
@@ -99,10 +98,12 @@ public void assertEvent(String[] expectedModified,
Arrays.sort(expectedModified);
Arrays.sort(actuallyDeleted);
Arrays.sort(expectedDeleted);
- assertArrayEquals("Unexpected modifications reported", expectedModified,
- actuallyModified);
- assertArrayEquals("Unexpected deletions reported", expectedDeleted,
- actuallyDeleted);
+ assertEquals("Unexpected modifications reported",
+ Arrays.toString(expectedModified),
+ Arrays.toString(actuallyModified));
+ assertEquals("Unexpected deletions reported",
+ Arrays.toString(expectedDeleted),
+ Arrays.toString(actuallyDeleted));
reset();
}
}
diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/AddCommandTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/AddCommandTest.java
index b28e26a..52a9dfa 100644
--- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/AddCommandTest.java
+++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/AddCommandTest.java
@@ -700,26 +700,26 @@ public void testAddWithConflicts() throws Exception {
writer.print("content b");
}
- ObjectInserter newObjectInserter = db.newObjectInserter();
DirCache dc = db.lockDirCache();
- DirCacheBuilder builder = dc.builder();
+ try (ObjectInserter newObjectInserter = db.newObjectInserter()) {
+ DirCacheBuilder builder = dc.builder();
- addEntryToBuilder("b.txt", file2, newObjectInserter, builder, 0);
- addEntryToBuilder("a.txt", file, newObjectInserter, builder, 1);
+ addEntryToBuilder("b.txt", file2, newObjectInserter, builder, 0);
+ addEntryToBuilder("a.txt", file, newObjectInserter, builder, 1);
- try (PrintWriter writer = new PrintWriter(file, UTF_8.name())) {
- writer.print("other content");
+ try (PrintWriter writer = new PrintWriter(file, UTF_8.name())) {
+ writer.print("other content");
+ }
+ addEntryToBuilder("a.txt", file, newObjectInserter, builder, 3);
+
+ try (PrintWriter writer = new PrintWriter(file, UTF_8.name())) {
+ writer.print("our content");
+ }
+ addEntryToBuilder("a.txt", file, newObjectInserter, builder, 2)
+ .getObjectId();
+
+ builder.commit();
}
- addEntryToBuilder("a.txt", file, newObjectInserter, builder, 3);
-
- try (PrintWriter writer = new PrintWriter(file, UTF_8.name())) {
- writer.print("our content");
- }
- addEntryToBuilder("a.txt", file, newObjectInserter, builder, 2)
- .getObjectId();
-
- builder.commit();
-
assertEquals(
"[a.txt, mode:100644, stage:1, content:content]" +
"[a.txt, mode:100644, stage:2, content:our content]" +
@@ -1132,41 +1132,42 @@ public boolean isCaseSensitive() {
}
};
- Git git = Git.open(db.getDirectory(), executableFs);
String path = "a.txt";
String path2 = "a.sh";
writeTrashFile(path, "content");
writeTrashFile(path2, "binary: content");
- git.add().addFilepattern(path).addFilepattern(path2).call();
- RevCommit commit1 = git.commit().setMessage("commit").call();
- try (TreeWalk walk = new TreeWalk(db)) {
- walk.addTree(commit1.getTree());
- walk.next();
- assertEquals(path2, walk.getPathString());
- assertEquals(FileMode.EXECUTABLE_FILE, walk.getFileMode(0));
- walk.next();
- assertEquals(path, walk.getPathString());
- assertEquals(FileMode.REGULAR_FILE, walk.getFileMode(0));
+ try (Git git = Git.open(db.getDirectory(), executableFs)) {
+ git.add().addFilepattern(path).addFilepattern(path2).call();
+ RevCommit commit1 = git.commit().setMessage("commit").call();
+ try (TreeWalk walk = new TreeWalk(db)) {
+ walk.addTree(commit1.getTree());
+ walk.next();
+ assertEquals(path2, walk.getPathString());
+ assertEquals(FileMode.EXECUTABLE_FILE, walk.getFileMode(0));
+ walk.next();
+ assertEquals(path, walk.getPathString());
+ assertEquals(FileMode.REGULAR_FILE, walk.getFileMode(0));
+ }
}
-
config = db.getConfig();
config.setBoolean(ConfigConstants.CONFIG_CORE_SECTION, null,
ConfigConstants.CONFIG_KEY_FILEMODE, false);
config.save();
- Git git2 = Git.open(db.getDirectory(), executableFs);
writeTrashFile(path2, "content2");
writeTrashFile(path, "binary: content2");
- git2.add().addFilepattern(path).addFilepattern(path2).call();
- RevCommit commit2 = git2.commit().setMessage("commit2").call();
- try (TreeWalk walk = new TreeWalk(db)) {
- walk.addTree(commit2.getTree());
- walk.next();
- assertEquals(path2, walk.getPathString());
- assertEquals(FileMode.EXECUTABLE_FILE, walk.getFileMode(0));
- walk.next();
- assertEquals(path, walk.getPathString());
- assertEquals(FileMode.REGULAR_FILE, walk.getFileMode(0));
+ try (Git git2 = Git.open(db.getDirectory(), executableFs)) {
+ git2.add().addFilepattern(path).addFilepattern(path2).call();
+ RevCommit commit2 = git2.commit().setMessage("commit2").call();
+ try (TreeWalk walk = new TreeWalk(db)) {
+ walk.addTree(commit2.getTree());
+ walk.next();
+ assertEquals(path2, walk.getPathString());
+ assertEquals(FileMode.EXECUTABLE_FILE, walk.getFileMode(0));
+ walk.next();
+ assertEquals(path, walk.getPathString());
+ assertEquals(FileMode.REGULAR_FILE, walk.getFileMode(0));
+ }
}
}
@@ -1291,18 +1292,19 @@ private void createNestedRepo(String path) throws IOException {
FileRepositoryBuilder nestedBuilder = new FileRepositoryBuilder();
nestedBuilder.setWorkTree(gitLinkDir);
- Repository nestedRepo = nestedBuilder.build();
- nestedRepo.create();
+ try (Repository nestedRepo = nestedBuilder.build()) {
+ nestedRepo.create();
- writeTrashFile(path, "README1.md", "content");
- writeTrashFile(path, "README2.md", "content");
+ writeTrashFile(path, "README1.md", "content");
+ writeTrashFile(path, "README2.md", "content");
- // Commit these changes in the subrepo
- try (Git git = new Git(nestedRepo)) {
- git.add().addFilepattern(".").call();
- git.commit().setMessage("subrepo commit").call();
- } catch (GitAPIException e) {
- throw new RuntimeException(e);
+ // Commit these changes in the subrepo
+ try (Git git = new Git(nestedRepo)) {
+ git.add().addFilepattern(".").call();
+ git.commit().setMessage("subrepo commit").call();
+ } catch (GitAPIException e) {
+ throw new RuntimeException(e);
+ }
}
}
}
diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/BlameCommandTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/BlameCommandTest.java
index 7e73084..4d1375a 100644
--- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/BlameCommandTest.java
+++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/BlameCommandTest.java
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2011, GitHub Inc.
+ * Copyright (C) 2011, 2019 GitHub Inc.
* and other copyright owners as documented in the project's IP log.
*
* This program and the accompanying materials are made available
@@ -44,6 +44,7 @@
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
import java.io.File;
@@ -462,6 +463,39 @@ public void testConflictingMerge2() throws Exception {
}
@Test
+ public void testUnresolvedMergeConflict() throws Exception {
+ try (Git git = new Git(db)) {
+ RevCommit base = commitFile("file.txt", "Origin\n", "master");
+
+ RevCommit master = commitFile("file.txt",
+ "Change on master branch\n", "master");
+
+ git.checkout().setName("side").setCreateBranch(true)
+ .setStartPoint(base).call();
+ RevCommit side = commitFile("file.txt",
+ "Conflicting change on side\n", "side");
+
+ checkoutBranch("refs/heads/master");
+ MergeResult result = git.merge().include(side).call();
+
+ // The merge results in a conflict, which we do not resolve
+ assertTrue("Expected a conflict",
+ result.getConflicts().containsKey("file.txt"));
+
+ BlameCommand command = new BlameCommand(db);
+ command.setFilePath("file.txt");
+ BlameResult lines = command.call();
+
+ assertEquals(5, lines.getResultContents().size());
+ assertNull(lines.getSourceCommit(0));
+ assertEquals(master, lines.getSourceCommit(1));
+ assertNull(lines.getSourceCommit(2));
+ assertEquals(side, lines.getSourceCommit(3));
+ assertNull(lines.getSourceCommit(4));
+ }
+ }
+
+ @Test
public void testWhitespaceMerge() throws Exception {
try (Git git = new Git(db)) {
RevCommit base = commitFile("file.txt", join("0", "1", "2"), "master");
diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/CherryPickCommandTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/CherryPickCommandTest.java
index fbc2cf6..76958f1 100644
--- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/CherryPickCommandTest.java
+++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/CherryPickCommandTest.java
@@ -58,6 +58,8 @@
import org.eclipse.jgit.api.errors.JGitInternalException;
import org.eclipse.jgit.api.errors.MultipleParentsNotAllowedException;
import org.eclipse.jgit.dircache.DirCache;
+import org.eclipse.jgit.events.ChangeRecorder;
+import org.eclipse.jgit.events.ListenerHandle;
import org.eclipse.jgit.junit.RepositoryTestCase;
import org.eclipse.jgit.lib.ConfigConstants;
import org.eclipse.jgit.lib.Constants;
@@ -325,6 +327,59 @@ public void testCherryPickConflictMarkers() throws Exception {
}
@Test
+ public void testCherryPickConflictFiresModifiedEvent() throws Exception {
+ ListenerHandle listener = null;
+ try (Git git = new Git(db)) {
+ RevCommit sideCommit = prepareCherryPick(git);
+ ChangeRecorder recorder = new ChangeRecorder();
+ listener = db.getListenerList()
+ .addWorkingTreeModifiedListener(recorder);
+ CherryPickResult result = git.cherryPick()
+ .include(sideCommit.getId()).call();
+ assertEquals(CherryPickStatus.CONFLICTING, result.getStatus());
+ recorder.assertEvent(new String[] { "a" }, ChangeRecorder.EMPTY);
+ } finally {
+ if (listener != null) {
+ listener.remove();
+ }
+ }
+ }
+
+ @Test
+ public void testCherryPickNewFileFiresModifiedEvent() throws Exception {
+ ListenerHandle listener = null;
+ try (Git git = new Git(db)) {
+ writeTrashFile("test.txt", "a");
+ git.add().addFilepattern("test.txt").call();
+ git.commit().setMessage("commit1").call();
+ git.checkout().setCreateBranch(true).setName("a").call();
+
+ writeTrashFile("side.txt", "side");
+ git.add().addFilepattern("side.txt").call();
+ RevCommit side = git.commit().setMessage("side").call();
+ assertNotNull(side);
+
+ assertNotNull(git.checkout().setName(Constants.MASTER).call());
+ writeTrashFile("test.txt", "b");
+ assertNotNull(git.add().addFilepattern("test.txt").call());
+ assertNotNull(git.commit().setMessage("commit2").call());
+
+ ChangeRecorder recorder = new ChangeRecorder();
+ listener = db.getListenerList()
+ .addWorkingTreeModifiedListener(recorder);
+ CherryPickResult result = git.cherryPick()
+ .include(side.getId()).call();
+ assertEquals(CherryPickStatus.OK, result.getStatus());
+ recorder.assertEvent(new String[] { "side.txt" },
+ ChangeRecorder.EMPTY);
+ } finally {
+ if (listener != null) {
+ listener.remove();
+ }
+ }
+ }
+
+ @Test
public void testCherryPickOurCommitName() throws Exception {
try (Git git = new Git(db)) {
RevCommit sideCommit = prepareCherryPick(git);
diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/CloneCommandTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/CloneCommandTest.java
index 2270a6a..c42cee3 100644
--- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/CloneCommandTest.java
+++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/CloneCommandTest.java
@@ -67,6 +67,7 @@
import org.eclipse.jgit.lib.Constants;
import org.eclipse.jgit.lib.ObjectId;
import org.eclipse.jgit.lib.Ref;
+import org.eclipse.jgit.lib.RefUpdate;
import org.eclipse.jgit.lib.Repository;
import org.eclipse.jgit.lib.StoredConfig;
import org.eclipse.jgit.revwalk.RevBlob;
@@ -96,10 +97,15 @@ public void setUp() throws Exception {
writeTrashFile("Test.txt", "Hello world");
git.add().addFilepattern("Test.txt").call();
git.commit().setMessage("Initial commit").call();
- git.tag().setName("tag-initial").setMessage("Tag initial").call();
+ Ref head = git.tag().setName("tag-initial").setMessage("Tag initial")
+ .call();
// create a test branch and switch to it
git.checkout().setCreateBranch(true).setName("test").call();
+ // create a non-standard ref
+ RefUpdate ru = db.updateRef("refs/meta/foo/bar");
+ ru.setNewObjectId(head.getObjectId());
+ ru.update();
// commit something on the test branch
writeTrashFile("Test.txt", "Some change");
@@ -397,7 +403,6 @@ public void testCloneRepositoryOnlyOneBranch() throws Exception {
@Test
public void testBareCloneRepositoryOnlyOneBranch() throws Exception {
- // Same thing, but now test with bare repo
File directory = createTempDirectory(
"testCloneRepositoryWithBranch_bare");
CloneCommand command = Git.cloneRepository();
@@ -425,6 +430,33 @@ public void testBareCloneRepositoryOnlyOneBranch() throws Exception {
}
@Test
+ public void testBareCloneRepositoryMirror() throws Exception {
+ File directory = createTempDirectory(
+ "testCloneRepositoryWithBranch_mirror");
+ CloneCommand command = Git.cloneRepository();
+ command.setBranch("refs/heads/master");
+ command.setMirror(true); // implies bare repository
+ command.setDirectory(directory);
+ command.setURI(fileUri());
+ Git git2 = command.call();
+ addRepoToClose(git2.getRepository());
+ assertNotNull(git2);
+ assertTrue(git2.getRepository().isBare());
+ assertNotNull(git2.getRepository().resolve("tag-for-blob"));
+ assertNotNull(git2.getRepository().resolve("tag-initial"));
+ assertEquals(git2.getRepository().getFullBranch(), "refs/heads/master");
+ assertEquals("refs/heads/master, refs/heads/test", allRefNames(
+ git2.branchList().setListMode(ListMode.ALL).call()));
+ assertNotNull(git2.getRepository().exactRef("refs/meta/foo/bar"));
+ RemoteConfig cfg = new RemoteConfig(git2.getRepository().getConfig(),
+ Constants.DEFAULT_REMOTE_NAME);
+ List<RefSpec> specs = cfg.getFetchRefSpecs();
+ assertEquals(1, specs.size());
+ assertEquals(new RefSpec("+refs/*:refs/*"),
+ specs.get(0));
+ }
+
+ @Test
public void testCloneRepositoryOnlyOneTag() throws Exception {
File directory = createTempDirectory("testCloneRepositoryWithBranch");
CloneCommand command = Git.cloneRepository();
@@ -450,6 +482,60 @@ public void testCloneRepositoryOnlyOneTag() throws Exception {
specs.get(0));
}
+ @Test
+ public void testCloneRepositoryAllBranchesTakesPreference()
+ throws Exception {
+ File directory = createTempDirectory(
+ "testCloneRepositoryAllBranchesTakesPreference");
+ CloneCommand command = Git.cloneRepository();
+ command.setCloneAllBranches(true);
+ command.setBranchesToClone(
+ Collections.singletonList("refs/heads/test"));
+ command.setDirectory(directory);
+ command.setURI(fileUri());
+ Git git2 = command.call();
+ addRepoToClose(git2.getRepository());
+ assertNotNull(git2);
+ assertEquals(git2.getRepository().getFullBranch(), "refs/heads/test");
+ // Expect both remote branches to exist; setCloneAllBranches(true)
+ // should override any setBranchesToClone().
+ assertNotNull(
+ git2.getRepository().resolve("refs/remotes/origin/master"));
+ assertNotNull(git2.getRepository().resolve("refs/remotes/origin/test"));
+ RemoteConfig cfg = new RemoteConfig(git2.getRepository().getConfig(),
+ Constants.DEFAULT_REMOTE_NAME);
+ List<RefSpec> specs = cfg.getFetchRefSpecs();
+ assertEquals(1, specs.size());
+ assertEquals(new RefSpec("+refs/heads/*:refs/remotes/origin/*"),
+ specs.get(0));
+ }
+
+ @Test
+ public void testCloneRepositoryAllBranchesIndependent() throws Exception {
+ File directory = createTempDirectory(
+ "testCloneRepositoryAllBranchesIndependent");
+ CloneCommand command = Git.cloneRepository();
+ command.setCloneAllBranches(true);
+ command.setBranchesToClone(
+ Collections.singletonList("refs/heads/test"));
+ command.setCloneAllBranches(false);
+ command.setDirectory(directory);
+ command.setURI(fileUri());
+ Git git2 = command.call();
+ addRepoToClose(git2.getRepository());
+ assertNotNull(git2);
+ assertEquals(git2.getRepository().getFullBranch(), "refs/heads/test");
+ // Expect only the test branch; allBranches was re-set to false
+ assertNull(git2.getRepository().resolve("refs/remotes/origin/master"));
+ assertNotNull(git2.getRepository().resolve("refs/remotes/origin/test"));
+ RemoteConfig cfg = new RemoteConfig(git2.getRepository().getConfig(),
+ Constants.DEFAULT_REMOTE_NAME);
+ List<RefSpec> specs = cfg.getFetchRefSpecs();
+ assertEquals(1, specs.size());
+ assertEquals(new RefSpec("+refs/heads/test:refs/remotes/origin/test"),
+ specs.get(0));
+ }
+
public static String allRefNames(List<Ref> refs) {
StringBuilder sb = new StringBuilder();
for (Ref f : refs) {
@@ -646,25 +732,27 @@ public void testCloneRepositoryWithNestedSubmodules() throws Exception {
assertEquals(sub1Head, pathStatus.getHeadId());
assertEquals(sub1Head, pathStatus.getIndexId());
- SubmoduleWalk walk = SubmoduleWalk.forIndex(git2.getRepository());
- assertTrue(walk.next());
- try (Repository clonedSub1 = walk.getRepository()) {
- assertNotNull(clonedSub1);
- assertEquals(new File(git2.getRepository().getWorkTree(),
- walk.getPath()), clonedSub1.getWorkTree());
- assertEquals(
- new File(new File(git2.getRepository().getDirectory(),
- "modules"), walk.getPath()),
- clonedSub1.getDirectory());
- status = new SubmoduleStatusCommand(clonedSub1);
- statuses = status.call();
+ try (SubmoduleWalk walk = SubmoduleWalk
+ .forIndex(git2.getRepository())) {
+ assertTrue(walk.next());
+ try (Repository clonedSub1 = walk.getRepository()) {
+ assertNotNull(clonedSub1);
+ assertEquals(new File(git2.getRepository().getWorkTree(),
+ walk.getPath()), clonedSub1.getWorkTree());
+ assertEquals(
+ new File(new File(git2.getRepository().getDirectory(),
+ "modules"), walk.getPath()),
+ clonedSub1.getDirectory());
+ status = new SubmoduleStatusCommand(clonedSub1);
+ statuses = status.call();
+ }
+ assertFalse(walk.next());
}
pathStatus = statuses.get(path);
assertNotNull(pathStatus);
assertEquals(SubmoduleStatusType.INITIALIZED, pathStatus.getType());
assertEquals(sub2Head, pathStatus.getHeadId());
assertEquals(sub2Head, pathStatus.getIndexId());
- assertFalse(walk.next());
}
@Test
diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/CommitAndLogCommandTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/CommitAndLogCommandTest.java
index c028ca3..2c51f7b 100644
--- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/CommitAndLogCommandTest.java
+++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/CommitAndLogCommandTest.java
@@ -40,6 +40,7 @@
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
+
package org.eclipse.jgit.api;
import static java.nio.charset.StandardCharsets.UTF_8;
@@ -50,14 +51,10 @@
import static org.junit.Assume.assumeFalse;
import java.io.File;
-import java.io.IOException;
import java.io.PrintWriter;
import org.eclipse.jgit.api.errors.GitAPIException;
-import org.eclipse.jgit.api.errors.JGitInternalException;
import org.eclipse.jgit.api.errors.NoMessageException;
-import org.eclipse.jgit.errors.IncorrectObjectTypeException;
-import org.eclipse.jgit.errors.MissingObjectException;
import org.eclipse.jgit.junit.RepositoryTestCase;
import org.eclipse.jgit.lib.Constants;
import org.eclipse.jgit.lib.ObjectId;
@@ -76,13 +73,12 @@
*/
public class CommitAndLogCommandTest extends RepositoryTestCase {
@Test
- public void testSomeCommits() throws JGitInternalException, IOException,
- GitAPIException {
-
+ public void testSomeCommits() throws Exception {
// do 4 commits
try (Git git = new Git(db)) {
git.commit().setMessage("initial commit").call();
- git.commit().setMessage("second commit").setCommitter(committer).call();
+ git.commit().setMessage("second commit").setCommitter(committer)
+ .call();
git.commit().setMessage("third commit").setAuthor(author).call();
git.commit().setMessage("fourth commit").setAuthor(author)
.setCommitter(committer).call();
@@ -90,79 +86,28 @@ public void testSomeCommits() throws JGitInternalException, IOException,
// check that all commits came in correctly
PersonIdent defaultCommitter = new PersonIdent(db);
- PersonIdent expectedAuthors[] = new PersonIdent[] { defaultCommitter,
- committer, author, author };
+ PersonIdent expectedAuthors[] = new PersonIdent[] {
+ defaultCommitter, committer, author, author };
PersonIdent expectedCommitters[] = new PersonIdent[] {
defaultCommitter, committer, defaultCommitter, committer };
String expectedMessages[] = new String[] { "initial commit",
"second commit", "third commit", "fourth commit" };
int l = expectedAuthors.length - 1;
for (RevCommit c : commits) {
- assertEquals(expectedAuthors[l].getName(), c.getAuthorIdent()
- .getName());
- assertEquals(expectedCommitters[l].getName(), c.getCommitterIdent()
- .getName());
+ assertEquals(expectedAuthors[l].getName(),
+ c.getAuthorIdent().getName());
+ assertEquals(expectedCommitters[l].getName(),
+ c.getCommitterIdent().getName());
assertEquals(c.getFullMessage(), expectedMessages[l]);
l--;
}
assertEquals(l, -1);
ReflogReader reader = db.getReflogReader(Constants.HEAD);
- assertTrue(reader.getLastEntry().getComment().startsWith("commit:"));
+ assertTrue(
+ reader.getLastEntry().getComment().startsWith("commit:"));
reader = db.getReflogReader(db.getBranch());
- assertTrue(reader.getLastEntry().getComment().startsWith("commit:"));
- }
- }
-
- @Test
- public void testLogWithFilter() throws IOException, JGitInternalException,
- GitAPIException {
-
- try (Git git = new Git(db)) {
- // create first file
- File file = new File(db.getWorkTree(), "a.txt");
- FileUtils.createNewFile(file);
- try (PrintWriter writer = new PrintWriter(file, UTF_8.name())) {
- writer.print("content1");
- }
-
- // First commit - a.txt file
- git.add().addFilepattern("a.txt").call();
- git.commit().setMessage("commit1").setCommitter(committer).call();
-
- // create second file
- file = new File(db.getWorkTree(), "b.txt");
- FileUtils.createNewFile(file);
- try (PrintWriter writer = new PrintWriter(file, UTF_8.name())) {
- writer.print("content2");
- }
-
- // Second commit - b.txt file
- git.add().addFilepattern("b.txt").call();
- git.commit().setMessage("commit2").setCommitter(committer).call();
-
- // First log - a.txt filter
- int count = 0;
- for (RevCommit c : git.log().addPath("a.txt").call()) {
- assertEquals("commit1", c.getFullMessage());
- count++;
- }
- assertEquals(1, count);
-
- // Second log - b.txt filter
- count = 0;
- for (RevCommit c : git.log().addPath("b.txt").call()) {
- assertEquals("commit2", c.getFullMessage());
- count++;
- }
- assertEquals(1, count);
-
- // Third log - without filter
- count = 0;
- for (RevCommit c : git.log().call()) {
- assertEquals(committer, c.getCommitterIdent());
- count++;
- }
- assertEquals(2, count);
+ assertTrue(
+ reader.getLastEntry().getComment().startsWith("commit:"));
}
}
@@ -204,19 +149,20 @@ public void testMultipleInvocations() throws GitAPIException {
}
@Test
- public void testMergeEmptyBranches() throws IOException,
- JGitInternalException, GitAPIException {
+ public void testMergeEmptyBranches() throws Exception {
try (Git git = new Git(db)) {
git.commit().setMessage("initial commit").call();
RefUpdate r = db.updateRef("refs/heads/side");
r.setNewObjectId(db.resolve(Constants.HEAD));
assertEquals(r.forceUpdate(), RefUpdate.Result.NEW);
- RevCommit second = git.commit().setMessage("second commit").setCommitter(committer).call();
+ RevCommit second = git.commit().setMessage("second commit")
+ .setCommitter(committer).call();
db.updateRef(Constants.HEAD).link("refs/heads/side");
- RevCommit firstSide = git.commit().setMessage("first side commit").setAuthor(author).call();
+ RevCommit firstSide = git.commit().setMessage("first side commit")
+ .setAuthor(author).call();
- write(new File(db.getDirectory(), Constants.MERGE_HEAD), ObjectId
- .toString(db.resolve("refs/heads/master")));
+ write(new File(db.getDirectory(), Constants.MERGE_HEAD),
+ ObjectId.toString(db.resolve("refs/heads/master")));
write(new File(db.getDirectory(), Constants.MERGE_MSG), "merging");
RevCommit commit = git.commit().call();
@@ -228,8 +174,7 @@ public void testMergeEmptyBranches() throws IOException,
}
@Test
- public void testAddUnstagedChanges() throws IOException,
- JGitInternalException, GitAPIException {
+ public void testAddUnstagedChanges() throws Exception {
File file = new File(db.getWorkTree(), "a.txt");
FileUtils.createNewFile(file);
try (PrintWriter writer = new PrintWriter(file, UTF_8.name())) {
@@ -260,7 +205,7 @@ public void testAddUnstagedChanges() throws IOException,
}
@Test
- public void testModeChange() throws IOException, GitAPIException {
+ public void testModeChange() throws Exception {
assumeFalse(System.getProperty("os.name").startsWith("Windows"));// SKIP
try (Git git = new Git(db)) {
// create file
@@ -278,7 +223,8 @@ public void testModeChange() throws IOException, GitAPIException {
FS fs = db.getFS();
fs.setExecute(file, true);
git.add().addFilepattern("a.txt").call();
- git.commit().setMessage("mode change").setCommitter(committer).call();
+ git.commit().setMessage("mode change").setCommitter(committer)
+ .call();
// pure mode change should be committable with -o option
fs.setExecute(file, false);
@@ -289,34 +235,32 @@ public void testModeChange() throws IOException, GitAPIException {
}
@Test
- public void testCommitRange() throws GitAPIException,
- JGitInternalException, MissingObjectException,
- IncorrectObjectTypeException {
+ public void testCommitRange() throws Exception {
// do 4 commits and set the range to the second and fourth one
try (Git git = new Git(db)) {
git.commit().setMessage("first commit").call();
RevCommit second = git.commit().setMessage("second commit")
.setCommitter(committer).call();
git.commit().setMessage("third commit").setAuthor(author).call();
- RevCommit last = git.commit().setMessage("fourth commit").setAuthor(
- author)
- .setCommitter(committer).call();
- Iterable<RevCommit> commits = git.log().addRange(second.getId(),
- last.getId()).call();
+ RevCommit last = git.commit().setMessage("fourth commit")
+ .setAuthor(author).setCommitter(committer).call();
+ Iterable<RevCommit> commits = git.log()
+ .addRange(second.getId(), last.getId()).call();
// check that we have the third and fourth commit
PersonIdent defaultCommitter = new PersonIdent(db);
- PersonIdent expectedAuthors[] = new PersonIdent[] { author, author };
+ PersonIdent expectedAuthors[] = new PersonIdent[] { author,
+ author };
PersonIdent expectedCommitters[] = new PersonIdent[] {
defaultCommitter, committer };
String expectedMessages[] = new String[] { "third commit",
"fourth commit" };
int l = expectedAuthors.length - 1;
for (RevCommit c : commits) {
- assertEquals(expectedAuthors[l].getName(), c.getAuthorIdent()
- .getName());
- assertEquals(expectedCommitters[l].getName(), c.getCommitterIdent()
- .getName());
+ assertEquals(expectedAuthors[l].getName(),
+ c.getAuthorIdent().getName());
+ assertEquals(expectedCommitters[l].getName(),
+ c.getCommitterIdent().getName());
assertEquals(c.getFullMessage(), expectedMessages[l]);
l--;
}
@@ -325,8 +269,7 @@ public void testCommitRange() throws GitAPIException,
}
@Test
- public void testCommitAmend() throws JGitInternalException, IOException,
- GitAPIException {
+ public void testCommitAmend() throws Exception {
try (Git git = new Git(db)) {
git.commit().setMessage("first comit").call(); // typo
git.commit().setAmend(true).setMessage("first commit").call();
@@ -348,15 +291,14 @@ public void testCommitAmend() throws JGitInternalException, IOException,
}
@Test
- public void testInsertChangeId() throws JGitInternalException,
- GitAPIException {
+ public void testInsertChangeId() throws Exception {
try (Git git = new Git(db)) {
String messageHeader = "Some header line\n\nSome detail explanation\n";
String changeIdTemplate = "\nChange-Id: I"
+ ObjectId.zeroId().getName() + "\n";
String messageFooter = "Some foooter lines\nAnother footer line\n";
- RevCommit commit = git.commit().setMessage(
- messageHeader + messageFooter)
+ RevCommit commit = git.commit()
+ .setMessage(messageHeader + messageFooter)
.setInsertChangeId(true).call();
// we should find a real change id (at the end of the file)
byte[] chars = commit.getFullMessage().getBytes(UTF_8);
@@ -364,11 +306,12 @@ public void testInsertChangeId() throws JGitInternalException,
String lastLine = RawParseUtils.decode(chars, lastLineBegin + 1,
chars.length);
assertTrue(lastLine.contains("Change-Id:"));
- assertFalse(lastLine.contains(
- "Change-Id: I" + ObjectId.zeroId().getName()));
+ assertFalse(lastLine
+ .contains("Change-Id: I" + ObjectId.zeroId().getName()));
- commit = git.commit().setMessage(
- messageHeader + changeIdTemplate + messageFooter)
+ commit = git.commit()
+ .setMessage(
+ messageHeader + changeIdTemplate + messageFooter)
.setInsertChangeId(true).call();
// we should find a real change id (in the line as dictated by the
// template)
@@ -383,11 +326,12 @@ public void testInsertChangeId() throws JGitInternalException,
String line = RawParseUtils.decode(chars, lineStart, lineEnd);
assertTrue(line.contains("Change-Id:"));
- assertFalse(line.contains(
- "Change-Id: I" + ObjectId.zeroId().getName()));
+ assertFalse(line
+ .contains("Change-Id: I" + ObjectId.zeroId().getName()));
- commit = git.commit().setMessage(
- messageHeader + changeIdTemplate + messageFooter)
+ commit = git.commit()
+ .setMessage(
+ messageHeader + changeIdTemplate + messageFooter)
.setInsertChangeId(false).call();
// we should find the untouched template
chars = commit.getFullMessage().getBytes(UTF_8);
@@ -400,8 +344,8 @@ public void testInsertChangeId() throws JGitInternalException,
line = RawParseUtils.decode(chars, lineStart, lineEnd);
- assertTrue(commit.getFullMessage().contains(
- "Change-Id: I" + ObjectId.zeroId().getName()));
+ assertTrue(commit.getFullMessage()
+ .contains("Change-Id: I" + ObjectId.zeroId().getName()));
}
}
}
diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/CommitCommandTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/CommitCommandTest.java
index 3bde0eb..b774921 100644
--- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/CommitCommandTest.java
+++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/CommitCommandTest.java
@@ -49,6 +49,7 @@
import static org.junit.Assert.assertSame;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
+import static org.junit.Assume.assumeTrue;
import java.io.File;
import java.util.Date;
@@ -148,9 +149,10 @@ public boolean isCaseSensitive() {
writeTrashFile(path, "content");
git.add().addFilepattern(path).call();
RevCommit commit1 = git.commit().setMessage("commit").call();
- TreeWalk walk = TreeWalk.forPath(db, path, commit1.getTree());
- assertNotNull(walk);
- assertEquals(FileMode.EXECUTABLE_FILE, walk.getFileMode(0));
+ try (TreeWalk walk = TreeWalk.forPath(db, path, commit1.getTree())) {
+ assertNotNull(walk);
+ assertEquals(FileMode.EXECUTABLE_FILE, walk.getFileMode(0));
+ }
FS nonExecutableFs = new FS() {
@@ -204,9 +206,10 @@ public boolean isCaseSensitive() {
writeTrashFile(path, "content2");
RevCommit commit2 = git2.commit().setOnly(path).setMessage("commit2")
.call();
- walk = TreeWalk.forPath(db, path, commit2.getTree());
- assertNotNull(walk);
- assertEquals(FileMode.EXECUTABLE_FILE, walk.getFileMode(0));
+ try (TreeWalk walk = TreeWalk.forPath(db, path, commit2.getTree())) {
+ assertNotNull(walk);
+ assertEquals(FileMode.EXECUTABLE_FILE, walk.getFileMode(0));
+ }
}
@Test
@@ -225,15 +228,16 @@ public void commitNewSubmodule() throws Exception {
assertNotNull(repo);
addRepoToClose(repo);
- SubmoduleWalk generator = SubmoduleWalk.forIndex(db);
- assertTrue(generator.next());
- assertEquals(path, generator.getPath());
- assertEquals(commit, generator.getObjectId());
- assertEquals(uri, generator.getModulesUrl());
- assertEquals(path, generator.getModulesPath());
- assertEquals(uri, generator.getConfigUrl());
- try (Repository subModRepo = generator.getRepository()) {
- assertNotNull(subModRepo);
+ try (SubmoduleWalk generator = SubmoduleWalk.forIndex(db)) {
+ assertTrue(generator.next());
+ assertEquals(path, generator.getPath());
+ assertEquals(commit, generator.getObjectId());
+ assertEquals(uri, generator.getModulesUrl());
+ assertEquals(path, generator.getModulesPath());
+ assertEquals(uri, generator.getConfigUrl());
+ try (Repository subModRepo = generator.getRepository()) {
+ assertNotNull(subModRepo);
+ }
}
assertEquals(commit, repo.resolve(Constants.HEAD));
@@ -275,15 +279,16 @@ public void commitSubmoduleUpdate() throws Exception {
assertNotNull(repo);
addRepoToClose(repo);
- SubmoduleWalk generator = SubmoduleWalk.forIndex(db);
- assertTrue(generator.next());
- assertEquals(path, generator.getPath());
- assertEquals(commit2, generator.getObjectId());
- assertEquals(uri, generator.getModulesUrl());
- assertEquals(path, generator.getModulesPath());
- assertEquals(uri, generator.getConfigUrl());
- try (Repository subModRepo = generator.getRepository()) {
- assertNotNull(subModRepo);
+ try (SubmoduleWalk generator = SubmoduleWalk.forIndex(db)) {
+ assertTrue(generator.next());
+ assertEquals(path, generator.getPath());
+ assertEquals(commit2, generator.getObjectId());
+ assertEquals(uri, generator.getModulesUrl());
+ assertEquals(path, generator.getModulesPath());
+ assertEquals(uri, generator.getConfigUrl());
+ try (Repository subModRepo = generator.getRepository()) {
+ assertNotNull(subModRepo);
+ }
}
assertEquals(commit2, repo.resolve(Constants.HEAD));
@@ -629,41 +634,64 @@ public void commitOnlyShouldHandleIgnored() throws Exception {
}
}
- @Test
- public void commitWithAutoCrlfAndNonNormalizedIndex() throws Exception {
+ private void nonNormalizedIndexTest(boolean executable) throws Exception {
+ String mode = executable ? "100755" : "100644";
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();
- writeTrashFile("file.txt", "line 1\r\nline 2\r\n");
+ File testFile = writeTrashFile("file.txt", "line 1\r\nline 2\r\n");
+ if (executable) {
+ FS.DETECTED.setExecute(testFile, true);
+ }
git.add().addFilepattern("file.txt").call();
git.commit().setMessage("Initial").call();
assertEquals(
- "[file.txt, mode:100644, content:line 1\r\nline 2\r\n]",
+ "[file.txt, mode:" + mode
+ + ", content:line 1\r\nline 2\r\n]",
indexState(CONTENT));
config.setString("core", null, "autocrlf", "true");
config.save();
writeTrashFile("file.txt", "line 1\r\nline 1.5\r\nline 2\r\n");
- writeTrashFile("file2.txt", "new\r\nfile\r\n");
+ testFile = writeTrashFile("file2.txt", "new\r\nfile\r\n");
+ if (executable) {
+ FS.DETECTED.setExecute(testFile, true);
+ }
git.add().addFilepattern("file.txt").addFilepattern("file2.txt")
.call();
git.commit().setMessage("Second").call();
assertEquals(
- "[file.txt, mode:100644, content:line 1\r\nline 1.5\r\nline 2\r\n]"
- + "[file2.txt, mode:100644, content:new\nfile\n]",
+ "[file.txt, mode:" + mode
+ + ", content:line 1\r\nline 1.5\r\nline 2\r\n]"
+ + "[file2.txt, mode:" + mode
+ + ", content:new\nfile\n]",
indexState(CONTENT));
writeTrashFile("file2.txt", "new\r\nfile\r\ncontent\r\n");
git.add().addFilepattern("file2.txt").call();
git.commit().setMessage("Third").call();
assertEquals(
- "[file.txt, mode:100644, content:line 1\r\nline 1.5\r\nline 2\r\n]"
- + "[file2.txt, mode:100644, content:new\nfile\ncontent\n]",
+ "[file.txt, mode:" + mode
+ + ", content:line 1\r\nline 1.5\r\nline 2\r\n]"
+ + "[file2.txt, mode:" + mode
+ + ", content:new\nfile\ncontent\n]",
indexState(CONTENT));
}
}
@Test
+ public void commitWithAutoCrlfAndNonNormalizedIndex() throws Exception {
+ nonNormalizedIndexTest(false);
+ }
+
+ @Test
+ public void commitExecutableWithAutoCrlfAndNonNormalizedIndex()
+ throws Exception {
+ assumeTrue(FS.DETECTED.supportsExecute());
+ nonNormalizedIndexTest(true);
+ }
+
+ @Test
public void testDeletionConflictWithAutoCrlf() throws Exception {
try (Git git = new Git(db)) {
// Commit a file with CR/LF into the index
diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/EolRepositoryTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/EolRepositoryTest.java
index 47806cb..d0dfd1a 100644
--- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/EolRepositoryTest.java
+++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/EolRepositoryTest.java
@@ -142,8 +142,6 @@ public EolRepositoryTest(String[] testContent, boolean smudgeEntries) {
protected String CONTENT_MIXED;
- private TreeWalk walk;
-
/** work tree root .gitattributes */
private File dotGitattributes;
@@ -689,27 +687,25 @@ private File createAndAddFile(Git git, String path, String content)
private void collectRepositoryState() throws Exception {
dirCache = db.readDirCache();
- walk = beginWalk();
- if (dotGitattributes != null)
- collectEntryContentAndAttributes(F, ".gitattributes", null);
- collectEntryContentAndAttributes(F, fileCRLF.getName(), entryCRLF);
- collectEntryContentAndAttributes(F, fileLF.getName(), entryLF);
- collectEntryContentAndAttributes(F, fileMixed.getName(), entryMixed);
- endWalk();
+ try (TreeWalk walk = new TreeWalk(db)) {
+ walk.addTree(new FileTreeIterator(db));
+ walk.addTree(new DirCacheIterator(db.readDirCache()));
+ if (dotGitattributes != null) {
+ collectEntryContentAndAttributes(walk, F, ".gitattributes",
+ null);
+ }
+ collectEntryContentAndAttributes(walk, F, fileCRLF.getName(),
+ entryCRLF);
+ collectEntryContentAndAttributes(walk, F, fileLF.getName(),
+ entryLF);
+ collectEntryContentAndAttributes(walk, F, fileMixed.getName(),
+ entryMixed);
+ assertFalse("Not all files tested", walk.next());
+ }
}
- private TreeWalk beginWalk() throws Exception {
- TreeWalk newWalk = new TreeWalk(db);
- newWalk.addTree(new FileTreeIterator(db));
- newWalk.addTree(new DirCacheIterator(db.readDirCache()));
- return newWalk;
- }
-
- private void endWalk() throws IOException {
- assertFalse("Not all files tested", walk.next());
- }
-
- private void collectEntryContentAndAttributes(FileMode type, String pathName,
+ private void collectEntryContentAndAttributes(TreeWalk walk, FileMode type,
+ String pathName,
ActualEntry e) throws IOException {
assertTrue("walk has entry", walk.next());
diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/FetchAndPullCommandsRecurseSubmodulesTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/FetchAndPullCommandsRecurseSubmodulesTest.java
index 73a705b..08ded55 100644
--- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/FetchAndPullCommandsRecurseSubmodulesTest.java
+++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/FetchAndPullCommandsRecurseSubmodulesTest.java
@@ -343,19 +343,22 @@ private FetchResult execute(FetchRecurseSubmodulesMode mode, boolean fetch)
private void assertSubmoduleFetchHeads(ObjectId expectedHead1,
ObjectId expectedHead2) throws Exception {
+ Object newHead1 = null;
+ ObjectId newHead2 = null;
try (SubmoduleWalk walk = SubmoduleWalk
.forIndex(git2.getRepository())) {
assertTrue(walk.next());
- Repository r = walk.getRepository();
- ObjectId newHead1 = r.resolve(Constants.FETCH_HEAD);
- ObjectId newHead2;
- try (SubmoduleWalk walk2 = SubmoduleWalk.forIndex(r)) {
- assertTrue(walk2.next());
- newHead2 = walk2.getRepository().resolve(Constants.FETCH_HEAD);
+ try (Repository r = walk.getRepository()) {
+ newHead1 = r.resolve(Constants.FETCH_HEAD);
+ try (SubmoduleWalk walk2 = SubmoduleWalk.forIndex(r)) {
+ assertTrue(walk2.next());
+ try (Repository r2 = walk2.getRepository()) {
+ newHead2 = r2.resolve(Constants.FETCH_HEAD);
+ }
+ }
}
-
- assertEquals(expectedHead1, newHead1);
- assertEquals(expectedHead2, newHead2);
}
+ assertEquals(expectedHead1, newHead1);
+ assertEquals(expectedHead2, newHead2);
}
}
diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/LogFilterTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/LogFilterTest.java
new file mode 100644
index 0000000..988ca58
--- /dev/null
+++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/LogFilterTest.java
@@ -0,0 +1,221 @@
+/*
+ * Copyright (C) 2019, John Tipper <John_Tipper@hotmail.com>
+ * 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.api;
+
+import static java.nio.charset.StandardCharsets.UTF_8;
+import static org.junit.Assert.assertEquals;
+
+import java.io.File;
+import java.io.PrintWriter;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.util.Iterator;
+
+import org.eclipse.jgit.junit.RepositoryTestCase;
+import org.eclipse.jgit.revwalk.RevCommit;
+import org.eclipse.jgit.util.FileUtils;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+
+/**
+ * Testing the log command with include and exclude filters
+ */
+public class LogFilterTest extends RepositoryTestCase {
+ private Git git;
+
+ @Before
+ public void setup() throws Exception {
+ super.setUp();
+ git = new Git(db);
+
+ // create first file
+ File file = new File(db.getWorkTree(), "a.txt");
+ FileUtils.createNewFile(file);
+ try (PrintWriter writer = new PrintWriter(file, UTF_8.name())) {
+ writer.print("content1");
+ }
+
+ // First commit - a.txt file
+ git.add().addFilepattern("a.txt").call();
+ git.commit().setMessage("commit1").setCommitter(committer).call();
+
+ // create second file
+ file = new File(db.getWorkTree(), "b.txt");
+ FileUtils.createNewFile(file);
+ try (PrintWriter writer = new PrintWriter(file, UTF_8.name())) {
+ writer.print("content2");
+ }
+
+ // Second commit - b.txt file
+ git.add().addFilepattern("b.txt").call();
+ git.commit().setMessage("commit2").setCommitter(committer).call();
+
+ // create third file
+ Path includeSubdir = Paths.get(db.getWorkTree().toString(),
+ "subdir-include");
+ includeSubdir.toFile().mkdirs();
+ file = Paths.get(includeSubdir.toString(), "c.txt").toFile();
+ FileUtils.createNewFile(file);
+ try (PrintWriter writer = new PrintWriter(file, UTF_8.name())) {
+ writer.print("content3");
+ }
+
+ // Third commit - c.txt file
+ git.add().addFilepattern("subdir-include").call();
+ git.commit().setMessage("commit3").setCommitter(committer).call();
+
+ // create fourth file
+ Path excludeSubdir = Paths.get(db.getWorkTree().toString(),
+ "subdir-exclude");
+ excludeSubdir.toFile().mkdirs();
+ file = Paths.get(excludeSubdir.toString(), "d.txt").toFile();
+ FileUtils.createNewFile(file);
+ try (PrintWriter writer = new PrintWriter(file, UTF_8.name())) {
+ writer.print("content4");
+ }
+
+ // Fourth commit - d.txt file
+ git.add().addFilepattern("subdir-exclude").call();
+ git.commit().setMessage("commit4").setCommitter(committer).call();
+ }
+
+ @After
+ @Override
+ public void tearDown() throws Exception {
+ git.close();
+ super.tearDown();
+ }
+
+ @Test
+ public void testLogWithFilterCanDistinguishFilesByPath() throws Exception {
+ int count = 0;
+ for (RevCommit c : git.log().addPath("a.txt").call()) {
+ assertEquals("commit1", c.getFullMessage());
+ count++;
+ }
+ assertEquals(1, count);
+
+ count = 0;
+ for (RevCommit c : git.log().addPath("b.txt").call()) {
+ assertEquals("commit2", c.getFullMessage());
+ count++;
+ }
+ assertEquals(1, count);
+ }
+
+ @Test
+ public void testLogWithFilterCanIncludeFilesInDirectory() throws Exception {
+ int count = 0;
+ for (RevCommit c : git.log().addPath("subdir-include").call()) {
+ assertEquals("commit3", c.getFullMessage());
+ count++;
+ }
+ assertEquals(1, count);
+ }
+
+ @Test
+ public void testLogWithFilterCanExcludeFilesInDirectory() throws Exception {
+ int count = 0;
+ Iterator it = git.log().excludePath("subdir-exclude").call().iterator();
+ while (it.hasNext()) {
+ it.next();
+ count++;
+ }
+ // of all the commits, we expect to filter out only d.txt
+ assertEquals(3, count);
+ }
+
+ @Test
+ public void testLogWithoutFilter() throws Exception {
+ int count = 0;
+ for (RevCommit c : git.log().call()) {
+ assertEquals(committer, c.getCommitterIdent());
+ count++;
+ }
+ assertEquals(4, count);
+ }
+
+ @Test
+ public void testLogWithFilterCanExcludeAndIncludeFilesInDifferentDirectories()
+ throws Exception {
+ int count = 0;
+ Iterator it = git.log().addPath("subdir-include")
+ .excludePath("subdir-exclude").call().iterator();
+ while (it.hasNext()) {
+ it.next();
+ count++;
+ }
+ // we expect to include c.txt
+ assertEquals(1, count);
+ }
+
+ @Test
+ public void testLogWithFilterExcludeAndIncludeSameFileIncludesNothing()
+ throws Exception {
+ int count = 0;
+ Iterator it = git.log().addPath("subdir-exclude")
+ .excludePath("subdir-exclude").call().iterator();
+
+ while (it.hasNext()) {
+ it.next();
+ count++;
+ }
+ // we expect the exclude to trump everything
+ assertEquals(0, count);
+ }
+
+ @Test
+ public void testLogWithFilterCanExcludeFileAndDirectory() throws Exception {
+ int count = 0;
+ Iterator it = git.log().excludePath("b.txt")
+ .excludePath("subdir-exclude").call().iterator();
+
+ while (it.hasNext()) {
+ it.next();
+ count++;
+ }
+ // we expect a.txt and c.txt
+ assertEquals(2, count);
+ }
+}
diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/RebaseCommandTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/RebaseCommandTest.java
index 4401bce..7c8ec23 100644
--- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/RebaseCommandTest.java
+++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/RebaseCommandTest.java
@@ -57,12 +57,9 @@
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
-import java.util.ArrayList;
import java.util.Collections;
-import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
-import java.util.Set;
import org.eclipse.jgit.api.MergeResult.MergeStatus;
import org.eclipse.jgit.api.RebaseCommand.InteractiveHandler;
@@ -78,6 +75,7 @@
import org.eclipse.jgit.errors.IllegalTodoFileModification;
import org.eclipse.jgit.errors.IncorrectObjectTypeException;
import org.eclipse.jgit.errors.MissingObjectException;
+import org.eclipse.jgit.events.ChangeRecorder;
import org.eclipse.jgit.events.ListenerHandle;
import org.eclipse.jgit.junit.RepositoryTestCase;
import org.eclipse.jgit.lib.AbbreviatedObjectId;
@@ -2014,10 +2012,9 @@ public void testRebaseWithAutoStashAndSubdirs() throws Exception {
checkoutBranch("refs/heads/topic");
writeTrashFile("sub/file0", "unstaged modified file0");
- Set<String> modifiedFiles = new HashSet<>();
+ ChangeRecorder recorder = new ChangeRecorder();
ListenerHandle handle = db.getListenerList()
- .addWorkingTreeModifiedListener(
- event -> modifiedFiles.addAll(event.getModified()));
+ .addWorkingTreeModifiedListener(recorder);
try {
// rebase
assertEquals(Status.OK, git.rebase()
@@ -2035,9 +2032,8 @@ public void testRebaseWithAutoStashAndSubdirs() throws Exception {
+ "[sub/file0, mode:100644, content:file0]",
indexState(CONTENT));
assertEquals(RepositoryState.SAFE, db.getRepositoryState());
- List<String> modified = new ArrayList<>(modifiedFiles);
- Collections.sort(modified);
- assertEquals("[file1, sub/file0]", modified.toString());
+ recorder.assertEvent(new String[] { "file1", "file2", "sub/file0" },
+ new String[0]);
}
@Test
@@ -2136,10 +2132,12 @@ public void testFastForwardRebaseWithAutoStash() throws Exception {
private List<DiffEntry> getStashedDiff() throws AmbiguousObjectException,
IncorrectObjectTypeException, IOException, MissingObjectException {
ObjectId stashId = db.resolve("stash@{0}");
- RevWalk revWalk = new RevWalk(db);
- RevCommit stashCommit = revWalk.parseCommit(stashId);
- List<DiffEntry> diffs = diffWorkingAgainstHead(stashCommit, revWalk);
- return diffs;
+ try (RevWalk revWalk = new RevWalk(db)) {
+ RevCommit stashCommit = revWalk.parseCommit(stashId);
+ List<DiffEntry> diffs = diffWorkingAgainstHead(stashCommit,
+ revWalk);
+ return diffs;
+ }
}
private TreeWalk createTreeWalk() {
diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/StatusCommandTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/StatusCommandTest.java
index f3ac65c..18580ae 100644
--- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/StatusCommandTest.java
+++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/StatusCommandTest.java
@@ -45,6 +45,7 @@
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
+import static org.junit.Assume.assumeTrue;
import java.io.File;
import java.io.IOException;
@@ -54,6 +55,8 @@
import org.eclipse.jgit.errors.NoWorkTreeException;
import org.eclipse.jgit.junit.RepositoryTestCase;
import org.eclipse.jgit.lib.Sets;
+import org.eclipse.jgit.storage.file.FileBasedConfig;
+import org.eclipse.jgit.util.FS;
import org.junit.Test;
public class StatusCommandTest extends RepositoryTestCase {
@@ -168,4 +171,26 @@ public void testDifferentStatesWithPaths() throws IOException,
assertEquals(Sets.of("a", "D/b", "D/D/d"), stat.getModified());
}
}
+
+ @Test
+ public void testExecutableWithNonNormalizedIndex() throws Exception {
+ assumeTrue(FS.DETECTED.supportsExecute());
+ 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 testFile = writeTrashFile("file.txt", "line 1\r\nline 2\r\n");
+ FS.DETECTED.setExecute(testFile, true);
+ git.add().addFilepattern("file.txt").call();
+ git.commit().setMessage("Initial").call();
+ assertEquals(
+ "[file.txt, mode:100755, content:line 1\r\nline 2\r\n]",
+ indexState(CONTENT));
+ config.setString("core", null, "autocrlf", "true");
+ config.save();
+ Status status = git.status().call();
+ assertTrue("Expected no differences", status.isClean());
+ }
+ }
}
diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/attributes/AttributesHandlerTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/attributes/AttributesHandlerTest.java
index 5868482..adc64d2 100644
--- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/attributes/AttributesHandlerTest.java
+++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/attributes/AttributesHandlerTest.java
@@ -69,83 +69,90 @@ public class AttributesHandlerTest extends RepositoryTestCase {
private static final FileMode F = FileMode.REGULAR_FILE;
- private TreeWalk walk;
-
@Test
public void testExpandNonMacro1() throws Exception {
setupRepo(null, null, null, "*.txt text");
- walk = beginWalk();
- assertIteration(D, "sub");
- assertIteration(F, "sub/.gitattributes");
- assertIteration(F, "sub/a.txt", attrs("text"));
- endWalk();
+ try (TreeWalk walk = beginWalk()) {
+ assertIteration(walk, D, "sub");
+ assertIteration(walk, F, "sub/.gitattributes");
+ assertIteration(walk, F, "sub/a.txt", attrs("text"));
+ assertFalse("Not all files tested", walk.next());
+ }
}
@Test
public void testExpandNonMacro2() throws Exception {
setupRepo(null, null, null, "*.txt -text");
- walk = beginWalk();
- assertIteration(D, "sub");
- assertIteration(F, "sub/.gitattributes");
- assertIteration(F, "sub/a.txt", attrs("-text"));
- endWalk();
+ try (TreeWalk walk = beginWalk()) {
+ assertIteration(walk, D, "sub");
+ assertIteration(walk, F, "sub/.gitattributes");
+ assertIteration(walk, F, "sub/a.txt", attrs("-text"));
+ assertFalse("Not all files tested", walk.next());
+ }
}
@Test
public void testExpandNonMacro3() throws Exception {
setupRepo(null, null, null, "*.txt !text");
- walk = beginWalk();
- assertIteration(D, "sub");
- assertIteration(F, "sub/.gitattributes");
- assertIteration(F, "sub/a.txt", attrs(""));
- endWalk();
+ try (TreeWalk walk = beginWalk()) {
+ assertIteration(walk, D, "sub");
+ assertIteration(walk, F, "sub/.gitattributes");
+ assertIteration(walk, F, "sub/a.txt", attrs(""));
+ assertFalse("Not all files tested", walk.next());
+ }
}
@Test
public void testExpandNonMacro4() throws Exception {
setupRepo(null, null, null, "*.txt text=auto");
- walk = beginWalk();
- assertIteration(D, "sub");
- assertIteration(F, "sub/.gitattributes");
- assertIteration(F, "sub/a.txt", attrs("text=auto"));
- endWalk();
+ try (TreeWalk walk = beginWalk()) {
+ assertIteration(walk, D, "sub");
+ assertIteration(walk, F, "sub/.gitattributes");
+ assertIteration(walk, F, "sub/a.txt", attrs("text=auto"));
+ assertFalse("Not all files tested", walk.next());
+ }
}
@Test
public void testExpandBuiltInMacro1() throws Exception {
setupRepo(null, null, null, "*.txt binary");
- walk = beginWalk();
- assertIteration(D, "sub");
- assertIteration(F, "sub/.gitattributes");
- assertIteration(F, "sub/a.txt", attrs("binary -diff -merge -text"));
- endWalk();
+ try (TreeWalk walk = beginWalk()) {
+ assertIteration(walk, D, "sub");
+ assertIteration(walk, F, "sub/.gitattributes");
+ assertIteration(walk, F, "sub/a.txt",
+ attrs("binary -diff -merge -text"));
+ assertFalse("Not all files tested", walk.next());
+ }
}
@Test
public void testExpandBuiltInMacro2() throws Exception {
setupRepo(null, null, null, "*.txt -binary");
- walk = beginWalk();
- assertIteration(D, "sub");
- assertIteration(F, "sub/.gitattributes");
- assertIteration(F, "sub/a.txt", attrs("-binary diff merge text"));
- endWalk();
+ try (TreeWalk walk = beginWalk()) {
+ assertIteration(walk, D, "sub");
+ assertIteration(walk, F, "sub/.gitattributes");
+ assertIteration(walk, F, "sub/a.txt",
+ attrs("-binary diff merge text"));
+ assertFalse("Not all files tested", walk.next());
+ }
}
@Test
public void testExpandBuiltInMacro3() throws Exception {
setupRepo(null, null, null, "*.txt !binary");
- walk = beginWalk();
- assertIteration(D, "sub");
- assertIteration(F, "sub/.gitattributes");
- assertIteration(F, "sub/a.txt", attrs(""));
- endWalk();
+ try (TreeWalk walk = beginWalk()) {
+ assertIteration(walk, D, "sub");
+ assertIteration(walk, F, "sub/.gitattributes");
+ assertIteration(walk, F, "sub/a.txt", attrs(""));
+ assertFalse("Not all files tested", walk.next());
+ }
}
@Test
@@ -153,44 +160,48 @@ public void testCustomGlobalMacro1() throws Exception {
setupRepo(
"[attr]foo a -b !c d=e", null, null, "*.txt foo");
- walk = beginWalk();
- assertIteration(D, "sub");
- assertIteration(F, "sub/.gitattributes");
- assertIteration(F, "sub/a.txt", attrs("foo a -b d=e"));
- endWalk();
+ try (TreeWalk walk = beginWalk()) {
+ assertIteration(walk, D, "sub");
+ assertIteration(walk, F, "sub/.gitattributes");
+ assertIteration(walk, F, "sub/a.txt", attrs("foo a -b d=e"));
+ assertFalse("Not all files tested", walk.next());
+ }
}
@Test
public void testCustomGlobalMacro2() throws Exception {
setupRepo("[attr]foo a -b !c d=e", null, null, "*.txt -foo");
- walk = beginWalk();
- assertIteration(D, "sub");
- assertIteration(F, "sub/.gitattributes");
- assertIteration(F, "sub/a.txt", attrs("-foo -a b d=e"));
- endWalk();
+ try (TreeWalk walk = beginWalk()) {
+ assertIteration(walk, D, "sub");
+ assertIteration(walk, F, "sub/.gitattributes");
+ assertIteration(walk, F, "sub/a.txt", attrs("-foo -a b d=e"));
+ assertFalse("Not all files tested", walk.next());
+ }
}
@Test
public void testCustomGlobalMacro3() throws Exception {
setupRepo("[attr]foo a -b !c d=e", null, null, "*.txt !foo");
- walk = beginWalk();
- assertIteration(D, "sub");
- assertIteration(F, "sub/.gitattributes");
- assertIteration(F, "sub/a.txt", attrs(""));
- endWalk();
+ try (TreeWalk walk = beginWalk()) {
+ assertIteration(walk, D, "sub");
+ assertIteration(walk, F, "sub/.gitattributes");
+ assertIteration(walk, F, "sub/a.txt", attrs(""));
+ assertFalse("Not all files tested", walk.next());
+ }
}
@Test
public void testCustomGlobalMacro4() throws Exception {
setupRepo("[attr]foo a -b !c d=e", null, null, "*.txt foo=bar");
- walk = beginWalk();
- assertIteration(D, "sub");
- assertIteration(F, "sub/.gitattributes");
- assertIteration(F, "sub/a.txt", attrs("foo=bar a -b d=bar"));
- endWalk();
+ try (TreeWalk walk = beginWalk()) {
+ assertIteration(walk, D, "sub");
+ assertIteration(walk, F, "sub/.gitattributes");
+ assertIteration(walk, F, "sub/a.txt", attrs("foo=bar a -b d=bar"));
+ assertFalse("Not all files tested", walk.next());
+ }
}
@Test
@@ -198,11 +209,12 @@ public void testInfoOverridesGlobal() throws Exception {
setupRepo("[attr]foo bar1",
"[attr]foo bar2", null, "*.txt foo");
- walk = beginWalk();
- assertIteration(D, "sub");
- assertIteration(F, "sub/.gitattributes");
- assertIteration(F, "sub/a.txt", attrs("foo bar2"));
- endWalk();
+ try (TreeWalk walk = beginWalk()) {
+ assertIteration(walk, D, "sub");
+ assertIteration(walk, F, "sub/.gitattributes");
+ assertIteration(walk, F, "sub/a.txt", attrs("foo bar2"));
+ assertFalse("Not all files tested", walk.next());
+ }
}
@Test
@@ -211,12 +223,13 @@ public void testWorkDirRootOverridesGlobal() throws Exception {
null,
"[attr]foo bar3", "*.txt foo");
- walk = beginWalk();
- assertIteration(F, ".gitattributes");
- assertIteration(D, "sub");
- assertIteration(F, "sub/.gitattributes");
- assertIteration(F, "sub/a.txt", attrs("foo bar3"));
- endWalk();
+ try (TreeWalk walk = beginWalk()) {
+ assertIteration(walk, F, ".gitattributes");
+ assertIteration(walk, D, "sub");
+ assertIteration(walk, F, "sub/.gitattributes");
+ assertIteration(walk, F, "sub/a.txt", attrs("foo bar3"));
+ assertFalse("Not all files tested", walk.next());
+ }
}
@Test
@@ -224,12 +237,13 @@ public void testInfoOverridesWorkDirRoot() throws Exception {
setupRepo("[attr]foo bar1",
"[attr]foo bar2", "[attr]foo bar3", "*.txt foo");
- walk = beginWalk();
- assertIteration(F, ".gitattributes");
- assertIteration(D, "sub");
- assertIteration(F, "sub/.gitattributes");
- assertIteration(F, "sub/a.txt", attrs("foo bar2"));
- endWalk();
+ try (TreeWalk walk = beginWalk()) {
+ assertIteration(walk, F, ".gitattributes");
+ assertIteration(walk, D, "sub");
+ assertIteration(walk, F, "sub/.gitattributes");
+ assertIteration(walk, F, "sub/a.txt", attrs("foo bar2"));
+ assertFalse("Not all files tested", walk.next());
+ }
}
@Test
@@ -238,11 +252,12 @@ public void testRecursiveMacro() throws Exception {
"[attr]foo x bar -foo",
null, null, "*.txt foo");
- walk = beginWalk();
- assertIteration(D, "sub");
- assertIteration(F, "sub/.gitattributes");
- assertIteration(F, "sub/a.txt", attrs("foo x bar"));
- endWalk();
+ try (TreeWalk walk = beginWalk()) {
+ assertIteration(walk, D, "sub");
+ assertIteration(walk, F, "sub/.gitattributes");
+ assertIteration(walk, F, "sub/a.txt", attrs("foo x bar"));
+ assertFalse("Not all files tested", walk.next());
+ }
}
@Test
@@ -250,11 +265,12 @@ public void testCyclicMacros() throws Exception {
setupRepo(
"[attr]foo x -bar\n[attr]bar y -foo", null, null, "*.txt foo");
- walk = beginWalk();
- assertIteration(D, "sub");
- assertIteration(F, "sub/.gitattributes");
- assertIteration(F, "sub/a.txt", attrs("foo x -bar -y"));
- endWalk();
+ try (TreeWalk walk = beginWalk()) {
+ assertIteration(walk, D, "sub");
+ assertIteration(walk, F, "sub/.gitattributes");
+ assertIteration(walk, F, "sub/a.txt", attrs("foo x -bar -y"));
+ assertFalse("Not all files tested", walk.next());
+ }
}
@Test
@@ -266,23 +282,30 @@ public void testRelativePaths() throws Exception {
// apply to any of the files here. It would match for a
// further subdirectory sub/sub. The sub/ rules must match
// only for directories.
- walk = beginWalk();
- assertIteration(F, ".gitattributes");
- assertIteration(D, "sub", attrs("global"));
- assertIteration(F, "sub/.gitattributes", attrs("init top_sub"));
- assertIteration(F, "sub/a.txt", attrs("init foo top top_sub"));
- endWalk();
+ try (TreeWalk walk = beginWalk()) {
+ assertIteration(walk, F, ".gitattributes");
+ assertIteration(walk, D, "sub", attrs("global"));
+ assertIteration(walk, F, "sub/.gitattributes",
+ attrs("init top_sub"));
+ assertIteration(walk, F, "sub/a.txt",
+ attrs("init foo top top_sub"));
+ assertFalse("Not all files tested", walk.next());
+ }
// All right, let's see that they *do* apply in sub/sub:
writeTrashFile("sub/sub/b.txt", "b");
- walk = beginWalk();
- assertIteration(F, ".gitattributes");
- assertIteration(D, "sub", attrs("global"));
- assertIteration(F, "sub/.gitattributes", attrs("init top_sub"));
- assertIteration(F, "sub/a.txt", attrs("init foo top top_sub"));
- assertIteration(D, "sub/sub", attrs("init subsub2 top_sub global"));
- assertIteration(F, "sub/sub/b.txt",
- attrs("init foo subsub top top_sub"));
- endWalk();
+ try (TreeWalk walk = beginWalk()) {
+ assertIteration(walk, F, ".gitattributes");
+ assertIteration(walk, D, "sub", attrs("global"));
+ assertIteration(walk, F, "sub/.gitattributes",
+ attrs("init top_sub"));
+ assertIteration(walk, F, "sub/a.txt",
+ attrs("init foo top top_sub"));
+ assertIteration(walk, D, "sub/sub",
+ attrs("init subsub2 top_sub global"));
+ assertIteration(walk, F, "sub/sub/b.txt",
+ attrs("init foo subsub top top_sub"));
+ assertFalse("Not all files tested", walk.next());
+ }
}
@Test
@@ -293,16 +316,17 @@ public void testNestedMatchNot() throws Exception {
writeTrashFile("sub/b.jar", "bj");
writeTrashFile("sub/b.xml", "bx");
// On foo.xml/bar.jar we must not have 'xml'
- walk = beginWalk();
- assertIteration(F, ".gitattributes");
- assertIteration(D, "foo.xml", attrs("xml"));
- assertIteration(F, "foo.xml/bar.jar", attrs("jar"));
- assertIteration(F, "foo.xml/bar.xml", attrs("xml"));
- assertIteration(D, "sub");
- assertIteration(F, "sub/a.txt");
- assertIteration(F, "sub/b.jar", attrs("jar"));
- assertIteration(F, "sub/b.xml", attrs("xml"));
- endWalk();
+ try (TreeWalk walk = beginWalk()) {
+ assertIteration(walk, F, ".gitattributes");
+ assertIteration(walk, D, "foo.xml", attrs("xml"));
+ assertIteration(walk, F, "foo.xml/bar.jar", attrs("jar"));
+ assertIteration(walk, F, "foo.xml/bar.xml", attrs("xml"));
+ assertIteration(walk, D, "sub");
+ assertIteration(walk, F, "sub/a.txt");
+ assertIteration(walk, F, "sub/b.jar", attrs("jar"));
+ assertIteration(walk, F, "sub/b.xml", attrs("xml"));
+ assertFalse("Not all files tested", walk.next());
+ }
}
@Test
@@ -314,18 +338,19 @@ public void testNestedMatch() throws Exception {
writeTrashFile("sub/b.jar", "bj");
writeTrashFile("sub/b.xml", "bx");
writeTrashFile("sub/foo/b.jar", "bf");
- walk = beginWalk();
- assertIteration(F, ".gitattributes");
- assertIteration(D, "foo", attrs("xml"));
- assertIteration(F, "foo/bar.jar", attrs("jar"));
- assertIteration(F, "foo/bar.xml");
- assertIteration(D, "sub");
- assertIteration(F, "sub/a.txt");
- assertIteration(F, "sub/b.jar", attrs("jar"));
- assertIteration(F, "sub/b.xml");
- assertIteration(D, "sub/foo", attrs("sub xml"));
- assertIteration(F, "sub/foo/b.jar", attrs("jar"));
- endWalk();
+ try (TreeWalk walk = beginWalk()) {
+ assertIteration(walk, F, ".gitattributes");
+ assertIteration(walk, D, "foo", attrs("xml"));
+ assertIteration(walk, F, "foo/bar.jar", attrs("jar"));
+ assertIteration(walk, F, "foo/bar.xml");
+ assertIteration(walk, D, "sub");
+ assertIteration(walk, F, "sub/a.txt");
+ assertIteration(walk, F, "sub/b.jar", attrs("jar"));
+ assertIteration(walk, F, "sub/b.xml");
+ assertIteration(walk, D, "sub/foo", attrs("sub xml"));
+ assertIteration(walk, F, "sub/foo/b.jar", attrs("jar"));
+ assertFalse("Not all files tested", walk.next());
+ }
}
@Test
@@ -337,18 +362,19 @@ public void testNestedMatchRecursive() throws Exception {
writeTrashFile("sub/b.xml", "bx");
writeTrashFile("sub/foo/b.jar", "bf");
// On foo.xml/bar.jar we must not have 'xml'
- walk = beginWalk();
- assertIteration(F, ".gitattributes");
- assertIteration(D, "foo");
- assertIteration(F, "foo/bar.jar", attrs("jar xml"));
- assertIteration(F, "foo/bar.xml", attrs("xml"));
- assertIteration(D, "sub");
- assertIteration(F, "sub/a.txt");
- assertIteration(F, "sub/b.jar", attrs("jar"));
- assertIteration(F, "sub/b.xml");
- assertIteration(D, "sub/foo");
- assertIteration(F, "sub/foo/b.jar", attrs("jar"));
- endWalk();
+ try (TreeWalk walk = beginWalk()) {
+ assertIteration(walk, F, ".gitattributes");
+ assertIteration(walk, D, "foo");
+ assertIteration(walk, F, "foo/bar.jar", attrs("jar xml"));
+ assertIteration(walk, F, "foo/bar.xml", attrs("xml"));
+ assertIteration(walk, D, "sub");
+ assertIteration(walk, F, "sub/a.txt");
+ assertIteration(walk, F, "sub/b.jar", attrs("jar"));
+ assertIteration(walk, F, "sub/b.xml");
+ assertIteration(walk, D, "sub/foo");
+ assertIteration(walk, F, "sub/foo/b.jar", attrs("jar"));
+ assertFalse("Not all files tested", walk.next());
+ }
}
@Test
@@ -357,27 +383,29 @@ public void testStarMatchOnSlashNot() throws Exception {
writeTrashFile("sub/a.txt", "1");
writeTrashFile("foo/sext", "2");
writeTrashFile("foo/s.txt", "3");
- walk = beginWalk();
- assertIteration(F, ".gitattributes");
- assertIteration(D, "foo");
- assertIteration(F, "foo/s.txt", attrs("bar"));
- assertIteration(F, "foo/sext", attrs("bar"));
- assertIteration(D, "sub");
- assertIteration(F, "sub/a.txt");
- endWalk();
+ try (TreeWalk walk = beginWalk()) {
+ assertIteration(walk, F, ".gitattributes");
+ assertIteration(walk, D, "foo");
+ assertIteration(walk, F, "foo/s.txt", attrs("bar"));
+ assertIteration(walk, F, "foo/sext", attrs("bar"));
+ assertIteration(walk, D, "sub");
+ assertIteration(walk, F, "sub/a.txt");
+ assertFalse("Not all files tested", walk.next());
+ }
}
@Test
public void testPrefixMatchNot() throws Exception {
setupRepo(null, null, "sub/new bar", null);
writeTrashFile("sub/new/foo.txt", "1");
- walk = beginWalk();
- assertIteration(F, ".gitattributes");
- assertIteration(D, "sub");
- assertIteration(F, "sub/a.txt");
- assertIteration(D, "sub/new", attrs("bar"));
- assertIteration(F, "sub/new/foo.txt");
- endWalk();
+ try (TreeWalk walk = beginWalk()) {
+ assertIteration(walk, F, ".gitattributes");
+ assertIteration(walk, D, "sub");
+ assertIteration(walk, F, "sub/a.txt");
+ assertIteration(walk, D, "sub/new", attrs("bar"));
+ assertIteration(walk, F, "sub/new/foo.txt");
+ assertFalse("Not all files tested", walk.next());
+ }
}
@Test
@@ -385,14 +413,15 @@ public void testComplexPathMatch() throws Exception {
setupRepo(null, null, "s[t-v]b/n[de]w bar", null);
writeTrashFile("sub/new/foo.txt", "1");
writeTrashFile("sub/ndw", "2");
- walk = beginWalk();
- assertIteration(F, ".gitattributes");
- assertIteration(D, "sub");
- assertIteration(F, "sub/a.txt");
- assertIteration(F, "sub/ndw", attrs("bar"));
- assertIteration(D, "sub/new", attrs("bar"));
- assertIteration(F, "sub/new/foo.txt");
- endWalk();
+ try (TreeWalk walk = beginWalk()) {
+ assertIteration(walk, F, ".gitattributes");
+ assertIteration(walk, D, "sub");
+ assertIteration(walk, F, "sub/a.txt");
+ assertIteration(walk, F, "sub/ndw", attrs("bar"));
+ assertIteration(walk, D, "sub/new", attrs("bar"));
+ assertIteration(walk, F, "sub/new/foo.txt");
+ assertFalse("Not all files tested", walk.next());
+ }
}
@Test
@@ -400,15 +429,16 @@ public void testStarPathMatch() throws Exception {
setupRepo(null, null, "sub/new/* bar", null);
writeTrashFile("sub/new/foo.txt", "1");
writeTrashFile("sub/new/lower/foo.txt", "2");
- walk = beginWalk();
- assertIteration(F, ".gitattributes");
- assertIteration(D, "sub");
- assertIteration(F, "sub/a.txt");
- assertIteration(D, "sub/new");
- assertIteration(F, "sub/new/foo.txt", attrs("bar"));
- assertIteration(D, "sub/new/lower", attrs("bar"));
- assertIteration(F, "sub/new/lower/foo.txt");
- endWalk();
+ try (TreeWalk walk = beginWalk()) {
+ assertIteration(walk, F, ".gitattributes");
+ assertIteration(walk, D, "sub");
+ assertIteration(walk, F, "sub/a.txt");
+ assertIteration(walk, D, "sub/new");
+ assertIteration(walk, F, "sub/new/foo.txt", attrs("bar"));
+ assertIteration(walk, D, "sub/new/lower", attrs("bar"));
+ assertIteration(walk, F, "sub/new/lower/foo.txt");
+ assertFalse("Not all files tested", walk.next());
+ }
}
@Test
@@ -417,20 +447,21 @@ public void testDirectoryMatchSubSimple() throws Exception {
writeTrashFile("sub/new/foo.txt", "1");
writeTrashFile("foo/sub/new/foo.txt", "2");
writeTrashFile("sub/sub/new/foo.txt", "3");
- walk = beginWalk();
- assertIteration(F, ".gitattributes");
- assertIteration(D, "foo");
- assertIteration(D, "foo/sub");
- assertIteration(D, "foo/sub/new");
- assertIteration(F, "foo/sub/new/foo.txt");
- assertIteration(D, "sub");
- assertIteration(F, "sub/a.txt");
- assertIteration(D, "sub/new", attrs("bar"));
- assertIteration(F, "sub/new/foo.txt");
- assertIteration(D, "sub/sub");
- assertIteration(D, "sub/sub/new");
- assertIteration(F, "sub/sub/new/foo.txt");
- endWalk();
+ try (TreeWalk walk = beginWalk()) {
+ assertIteration(walk, F, ".gitattributes");
+ assertIteration(walk, D, "foo");
+ assertIteration(walk, D, "foo/sub");
+ assertIteration(walk, D, "foo/sub/new");
+ assertIteration(walk, F, "foo/sub/new/foo.txt");
+ assertIteration(walk, D, "sub");
+ assertIteration(walk, F, "sub/a.txt");
+ assertIteration(walk, D, "sub/new", attrs("bar"));
+ assertIteration(walk, F, "sub/new/foo.txt");
+ assertIteration(walk, D, "sub/sub");
+ assertIteration(walk, D, "sub/sub/new");
+ assertIteration(walk, F, "sub/sub/new/foo.txt");
+ assertFalse("Not all files tested", walk.next());
+ }
}
@Test
@@ -438,17 +469,18 @@ public void testDirectoryMatchSubRecursive() throws Exception {
setupRepo(null, null, "**/sub/new/ bar", null);
writeTrashFile("sub/new/foo.txt", "1");
writeTrashFile("foo/sub/new/foo.txt", "2");
- walk = beginWalk();
- assertIteration(F, ".gitattributes");
- assertIteration(D, "foo");
- assertIteration(D, "foo/sub");
- assertIteration(D, "foo/sub/new", attrs("bar"));
- assertIteration(F, "foo/sub/new/foo.txt");
- assertIteration(D, "sub");
- assertIteration(F, "sub/a.txt");
- assertIteration(D, "sub/new", attrs("bar"));
- assertIteration(F, "sub/new/foo.txt");
- endWalk();
+ try (TreeWalk walk = beginWalk()) {
+ assertIteration(walk, F, ".gitattributes");
+ assertIteration(walk, D, "foo");
+ assertIteration(walk, D, "foo/sub");
+ assertIteration(walk, D, "foo/sub/new", attrs("bar"));
+ assertIteration(walk, F, "foo/sub/new/foo.txt");
+ assertIteration(walk, D, "sub");
+ assertIteration(walk, F, "sub/a.txt");
+ assertIteration(walk, D, "sub/new", attrs("bar"));
+ assertIteration(walk, F, "sub/new/foo.txt");
+ assertFalse("Not all files tested", walk.next());
+ }
}
@Test
@@ -457,20 +489,21 @@ public void testDirectoryMatchSubRecursiveBacktrack() throws Exception {
writeTrashFile("sub/new/foo.txt", "1");
writeTrashFile("foo/sub/new/foo.txt", "2");
writeTrashFile("sub/sub/new/foo.txt", "3");
- walk = beginWalk();
- assertIteration(F, ".gitattributes");
- assertIteration(D, "foo");
- assertIteration(D, "foo/sub");
- assertIteration(D, "foo/sub/new", attrs("bar"));
- assertIteration(F, "foo/sub/new/foo.txt");
- assertIteration(D, "sub");
- assertIteration(F, "sub/a.txt");
- assertIteration(D, "sub/new", attrs("bar"));
- assertIteration(F, "sub/new/foo.txt");
- assertIteration(D, "sub/sub");
- assertIteration(D, "sub/sub/new", attrs("bar"));
- assertIteration(F, "sub/sub/new/foo.txt");
- endWalk();
+ try (TreeWalk walk = beginWalk()) {
+ assertIteration(walk, F, ".gitattributes");
+ assertIteration(walk, D, "foo");
+ assertIteration(walk, D, "foo/sub");
+ assertIteration(walk, D, "foo/sub/new", attrs("bar"));
+ assertIteration(walk, F, "foo/sub/new/foo.txt");
+ assertIteration(walk, D, "sub");
+ assertIteration(walk, F, "sub/a.txt");
+ assertIteration(walk, D, "sub/new", attrs("bar"));
+ assertIteration(walk, F, "sub/new/foo.txt");
+ assertIteration(walk, D, "sub/sub");
+ assertIteration(walk, D, "sub/sub/new", attrs("bar"));
+ assertIteration(walk, F, "sub/sub/new/foo.txt");
+ assertFalse("Not all files tested", walk.next());
+ }
}
@Test
@@ -479,20 +512,21 @@ public void testDirectoryMatchSubRecursiveBacktrack2() throws Exception {
writeTrashFile("sub/new/foo.txt", "1");
writeTrashFile("foo/sub/new/foo.txt", "2");
writeTrashFile("sub/sub/new/foo.txt", "3");
- walk = beginWalk();
- assertIteration(F, ".gitattributes");
- assertIteration(D, "foo");
- assertIteration(D, "foo/sub");
- assertIteration(D, "foo/sub/new", attrs("bar"));
- assertIteration(F, "foo/sub/new/foo.txt");
- assertIteration(D, "sub");
- assertIteration(F, "sub/a.txt");
- assertIteration(D, "sub/new", attrs("bar"));
- assertIteration(F, "sub/new/foo.txt");
- assertIteration(D, "sub/sub");
- assertIteration(D, "sub/sub/new", attrs("bar"));
- assertIteration(F, "sub/sub/new/foo.txt");
- endWalk();
+ try (TreeWalk walk = beginWalk()) {
+ assertIteration(walk, F, ".gitattributes");
+ assertIteration(walk, D, "foo");
+ assertIteration(walk, D, "foo/sub");
+ assertIteration(walk, D, "foo/sub/new", attrs("bar"));
+ assertIteration(walk, F, "foo/sub/new/foo.txt");
+ assertIteration(walk, D, "sub");
+ assertIteration(walk, F, "sub/a.txt");
+ assertIteration(walk, D, "sub/new", attrs("bar"));
+ assertIteration(walk, F, "sub/new/foo.txt");
+ assertIteration(walk, D, "sub/sub");
+ assertIteration(walk, D, "sub/sub/new", attrs("bar"));
+ assertIteration(walk, F, "sub/sub/new/foo.txt");
+ assertFalse("Not all files tested", walk.next());
+ }
}
@Test
@@ -500,17 +534,18 @@ public void testDirectoryMatchSubComplex() throws Exception {
setupRepo(null, null, "s[uv]b/n*/ bar", null);
writeTrashFile("sub/new/foo.txt", "1");
writeTrashFile("foo/sub/new/foo.txt", "2");
- walk = beginWalk();
- assertIteration(F, ".gitattributes");
- assertIteration(D, "foo");
- assertIteration(D, "foo/sub");
- assertIteration(D, "foo/sub/new");
- assertIteration(F, "foo/sub/new/foo.txt");
- assertIteration(D, "sub");
- assertIteration(F, "sub/a.txt");
- assertIteration(D, "sub/new", attrs("bar"));
- assertIteration(F, "sub/new/foo.txt");
- endWalk();
+ try (TreeWalk walk = beginWalk()) {
+ assertIteration(walk, F, ".gitattributes");
+ assertIteration(walk, D, "foo");
+ assertIteration(walk, D, "foo/sub");
+ assertIteration(walk, D, "foo/sub/new");
+ assertIteration(walk, F, "foo/sub/new/foo.txt");
+ assertIteration(walk, D, "sub");
+ assertIteration(walk, F, "sub/a.txt");
+ assertIteration(walk, D, "sub/new", attrs("bar"));
+ assertIteration(walk, F, "sub/new/foo.txt");
+ assertFalse("Not all files tested", walk.next());
+ }
}
@Test
@@ -519,30 +554,32 @@ public void testDirectoryMatch() throws Exception {
writeTrashFile("sub/new/foo.txt", "1");
writeTrashFile("foo/sub/new/foo.txt", "2");
writeTrashFile("foo/new", "3");
- walk = beginWalk();
- assertIteration(F, ".gitattributes");
- assertIteration(D, "foo");
- assertIteration(F, "foo/new");
- assertIteration(D, "foo/sub");
- assertIteration(D, "foo/sub/new", attrs("bar"));
- assertIteration(F, "foo/sub/new/foo.txt");
- assertIteration(D, "sub");
- assertIteration(F, "sub/a.txt");
- assertIteration(D, "sub/new", attrs("bar"));
- assertIteration(F, "sub/new/foo.txt");
- endWalk();
+ try (TreeWalk walk = beginWalk()) {
+ assertIteration(walk, F, ".gitattributes");
+ assertIteration(walk, D, "foo");
+ assertIteration(walk, F, "foo/new");
+ assertIteration(walk, D, "foo/sub");
+ assertIteration(walk, D, "foo/sub/new", attrs("bar"));
+ assertIteration(walk, F, "foo/sub/new/foo.txt");
+ assertIteration(walk, D, "sub");
+ assertIteration(walk, F, "sub/a.txt");
+ assertIteration(walk, D, "sub/new", attrs("bar"));
+ assertIteration(walk, F, "sub/new/foo.txt");
+ assertFalse("Not all files tested", walk.next());
+ }
}
private static Collection<Attribute> attrs(String s) {
return new AttributesRule("*", s).getAttributes();
}
- private void assertIteration(FileMode type, String pathName)
+ private void assertIteration(TreeWalk walk, FileMode type, String pathName)
throws IOException {
- assertIteration(type, pathName, Collections.<Attribute> emptyList());
+ assertIteration(walk, type, pathName,
+ Collections.<Attribute> emptyList());
}
- private void assertIteration(FileMode type, String pathName,
+ private void assertIteration(TreeWalk walk, FileMode type, String pathName,
Collection<Attribute> expectedAttrs) throws IOException {
assertTrue("walk has entry", walk.next());
assertEquals(pathName, walk.getPathString());
@@ -611,8 +648,4 @@ private TreeWalk beginWalk() {
newWalk.addTree(new FileTreeIterator(db));
return newWalk;
}
-
- private void endWalk() throws IOException {
- assertFalse("Not all files tested", walk.next());
- }
}
diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/attributes/AttributesNodeDirCacheIteratorTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/attributes/AttributesNodeDirCacheIteratorTest.java
index 837de74..cb37d89 100644
--- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/attributes/AttributesNodeDirCacheIteratorTest.java
+++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/attributes/AttributesNodeDirCacheIteratorTest.java
@@ -78,8 +78,6 @@ public class AttributesNodeDirCacheIteratorTest extends RepositoryTestCase {
private Git git;
- private TreeWalk walk;
-
@Override
@Before
public void setUp() throws Exception {
@@ -105,23 +103,25 @@ public void testRules() throws Exception {
// Adds file to index
git.add().addFilepattern(".").call();
- walk = beginWalk();
+ try (TreeWalk walk = beginWalk()) {
+ assertIteration(walk, F, ".gitattributes");
+ assertIteration(walk, F, "readme.txt", asList(EOL_LF));
- assertIteration(F, ".gitattributes");
- assertIteration(F, "readme.txt", asList(EOL_LF));
+ assertIteration(walk, D, "src");
- assertIteration(D, "src");
+ assertIteration(walk, D, "src/config");
+ assertIteration(walk, F, "src/config/.gitattributes");
+ assertIteration(walk, F, "src/config/readme.txt",
+ asList(DELTA_UNSET));
+ assertIteration(walk, F, "src/config/windows.file", null);
+ assertIteration(walk, F, "src/config/windows.txt",
+ asList(DELTA_UNSET));
- assertIteration(D, "src/config");
- assertIteration(F, "src/config/.gitattributes");
- assertIteration(F, "src/config/readme.txt", asList(DELTA_UNSET));
- assertIteration(F, "src/config/windows.file", null);
- assertIteration(F, "src/config/windows.txt", asList(DELTA_UNSET));
+ assertIteration(walk, F, "windows.file", null);
+ assertIteration(walk, F, "windows.txt", asList(EOL_LF));
- assertIteration(F, "windows.file", null);
- assertIteration(F, "windows.txt", asList(EOL_LF));
-
- endWalk();
+ assertFalse("Not all files tested", walk.next());
+ }
}
/**
@@ -138,17 +138,18 @@ public void testNoAttributes() throws Exception {
// Adds file to index
git.add().addFilepattern(".").call();
- walk = beginWalk();
- assertIteration(F, "l0.txt");
+ try (TreeWalk walk = beginWalk()) {
+ assertIteration(walk, F, "l0.txt");
- assertIteration(D, "level1");
- assertIteration(F, "level1/l1.txt");
+ assertIteration(walk, D, "level1");
+ assertIteration(walk, F, "level1/l1.txt");
- assertIteration(D, "level1/level2");
- assertIteration(F, "level1/level2/l2.txt");
+ assertIteration(walk, D, "level1/level2");
+ assertIteration(walk, F, "level1/level2/l2.txt");
- endWalk();
+ assertFalse("Not all files tested", walk.next());
+ }
}
/**
@@ -166,18 +167,19 @@ public void testEmptyGitAttributeFile() throws Exception {
// Adds file to index
git.add().addFilepattern(".").call();
- walk = beginWalk();
- assertIteration(F, ".gitattributes");
- assertIteration(F, "l0.txt");
+ try (TreeWalk walk = beginWalk()) {
+ assertIteration(walk, F, ".gitattributes");
+ assertIteration(walk, F, "l0.txt");
- assertIteration(D, "level1");
- assertIteration(F, "level1/l1.txt");
+ assertIteration(walk, D, "level1");
+ assertIteration(walk, F, "level1/l1.txt");
- assertIteration(D, "level1/level2");
- assertIteration(F, "level1/level2/l2.txt");
+ assertIteration(walk, D, "level1/level2");
+ assertIteration(walk, F, "level1/level2/l2.txt");
- endWalk();
+ assertFalse("Not all files tested", walk.next());
+ }
}
@Test
@@ -191,18 +193,19 @@ public void testNoMatchingAttributes() throws Exception {
// Adds file to index
git.add().addFilepattern(".").call();
- walk = beginWalk();
- assertIteration(F, ".gitattributes");
+ try (TreeWalk walk = beginWalk()) {
+ assertIteration(walk, F, ".gitattributes");
- assertIteration(D, "levelA");
- assertIteration(F, "levelA/.gitattributes");
- assertIteration(F, "levelA/lA.txt");
+ assertIteration(walk, D, "levelA");
+ assertIteration(walk, F, "levelA/.gitattributes");
+ assertIteration(walk, F, "levelA/lA.txt");
- assertIteration(D, "levelB");
- assertIteration(F, "levelB/.gitattributes");
+ assertIteration(walk, D, "levelB");
+ assertIteration(walk, F, "levelB/.gitattributes");
- endWalk();
+ assertFalse("Not all files tested", walk.next());
+ }
}
@Test
@@ -215,25 +218,27 @@ public void testIncorrectAttributeFileName() throws Exception {
// Adds file to index
git.add().addFilepattern(".").call();
- walk = beginWalk();
- assertIteration(F, "gitattributes");
+ try (TreeWalk walk = beginWalk()) {
+ assertIteration(walk, F, "gitattributes");
- assertIteration(F, "l0.txt");
+ assertIteration(walk, F, "l0.txt");
- assertIteration(D, "levelA");
- assertIteration(F, "levelA/file.gitattributes");
- assertIteration(F, "levelA/lA.txt");
+ assertIteration(walk, D, "levelA");
+ assertIteration(walk, F, "levelA/file.gitattributes");
+ assertIteration(walk, F, "levelA/lA.txt");
- endWalk();
+ assertFalse("Not all files tested", walk.next());
+ }
}
- private void assertIteration(FileMode type, String pathName)
+ private void assertIteration(TreeWalk walk, FileMode type, String pathName)
throws IOException {
- assertIteration(type, pathName, Collections.<Attribute> emptyList());
+ assertIteration(walk, type, pathName,
+ Collections.<Attribute> emptyList());
}
- private void assertIteration(FileMode type, String pathName,
+ private void assertIteration(TreeWalk walk, FileMode type, String pathName,
List<Attribute> nodeAttrs) throws IOException {
assertTrue("walk has entry", walk.next());
assertEquals(pathName, walk.getPathString());
@@ -243,14 +248,14 @@ private void assertIteration(FileMode type, String pathName,
AttributesNode attributesNode = itr.getEntryAttributesNode(db
.newObjectReader());
- assertAttributesNode(pathName, attributesNode, nodeAttrs);
+ assertAttributesNode(walk, pathName, attributesNode, nodeAttrs);
if (D.equals(type))
walk.enterSubtree();
}
- private void assertAttributesNode(String pathName,
+ private void assertAttributesNode(TreeWalk walk, String pathName,
AttributesNode attributesNode, List<Attribute> nodeAttrs)
throws IOException {
if (attributesNode == null)
@@ -292,8 +297,4 @@ private TreeWalk beginWalk() throws Exception {
newWalk.addTree(new DirCacheIterator(db.readDirCache()));
return newWalk;
}
-
- private void endWalk() throws IOException {
- assertFalse("Not all files tested", walk.next());
- }
}
diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/attributes/AttributesNodeWorkingTreeIteratorTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/attributes/AttributesNodeWorkingTreeIteratorTest.java
index b159cca..9991ae5 100644
--- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/attributes/AttributesNodeWorkingTreeIteratorTest.java
+++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/attributes/AttributesNodeWorkingTreeIteratorTest.java
@@ -77,8 +77,6 @@ public class AttributesNodeWorkingTreeIteratorTest extends RepositoryTestCase {
private static Attribute DELTA_UNSET = new Attribute("delta", State.UNSET);
- private TreeWalk walk;
-
@Test
public void testRules() throws Exception {
@@ -102,24 +100,26 @@ public void testRules() throws Exception {
writeTrashFile("src/config/windows.file", "");
writeTrashFile("src/config/windows.txt", "");
- walk = beginWalk();
+ try (TreeWalk walk = beginWalk()) {
+ assertIteration(walk, F, ".gitattributes");
+ assertIteration(walk, F, "global.txt", asList(EOL_LF));
+ assertIteration(walk, F, "readme.txt", asList(EOL_LF));
- assertIteration(F, ".gitattributes");
- assertIteration(F, "global.txt", asList(EOL_LF));
- assertIteration(F, "readme.txt", asList(EOL_LF));
+ assertIteration(walk, D, "src");
- assertIteration(D, "src");
+ assertIteration(walk, D, "src/config");
+ assertIteration(walk, F, "src/config/.gitattributes");
+ assertIteration(walk, F, "src/config/readme.txt",
+ asList(DELTA_UNSET));
+ assertIteration(walk, F, "src/config/windows.file", null);
+ assertIteration(walk, F, "src/config/windows.txt",
+ asList(DELTA_UNSET));
- assertIteration(D, "src/config");
- assertIteration(F, "src/config/.gitattributes");
- assertIteration(F, "src/config/readme.txt", asList(DELTA_UNSET));
- assertIteration(F, "src/config/windows.file", null);
- assertIteration(F, "src/config/windows.txt", asList(DELTA_UNSET));
+ assertIteration(walk, F, "windows.file", null);
+ assertIteration(walk, F, "windows.txt", asList(EOL_LF));
- assertIteration(F, "windows.file", null);
- assertIteration(F, "windows.txt", asList(EOL_LF));
-
- endWalk();
+ assertFalse("Not all files tested", walk.next());
+ }
}
/**
@@ -134,17 +134,17 @@ public void testNoAttributes() throws Exception {
writeTrashFile("level1/l1.txt", "");
writeTrashFile("level1/level2/l2.txt", "");
- walk = beginWalk();
+ try (TreeWalk walk = beginWalk()) {
+ assertIteration(walk, F, "l0.txt");
- assertIteration(F, "l0.txt");
+ assertIteration(walk, D, "level1");
+ assertIteration(walk, F, "level1/l1.txt");
- assertIteration(D, "level1");
- assertIteration(F, "level1/l1.txt");
+ assertIteration(walk, D, "level1/level2");
+ assertIteration(walk, F, "level1/level2/l2.txt");
- assertIteration(D, "level1/level2");
- assertIteration(F, "level1/level2/l2.txt");
-
- endWalk();
+ assertFalse("Not all files tested", walk.next());
+ }
}
/**
@@ -160,18 +160,18 @@ public void testEmptyGitAttributeFile() throws Exception {
writeTrashFile("level1/l1.txt", "");
writeTrashFile("level1/level2/l2.txt", "");
- walk = beginWalk();
+ try (TreeWalk walk = beginWalk()) {
+ assertIteration(walk, F, ".gitattributes");
+ assertIteration(walk, F, "l0.txt");
- assertIteration(F, ".gitattributes");
- assertIteration(F, "l0.txt");
+ assertIteration(walk, D, "level1");
+ assertIteration(walk, F, "level1/l1.txt");
- assertIteration(D, "level1");
- assertIteration(F, "level1/l1.txt");
+ assertIteration(walk, D, "level1/level2");
+ assertIteration(walk, F, "level1/level2/l2.txt");
- assertIteration(D, "level1/level2");
- assertIteration(F, "level1/level2/l2.txt");
-
- endWalk();
+ assertFalse("Not all files tested", walk.next());
+ }
}
@Test
@@ -183,26 +183,27 @@ public void testNoMatchingAttributes() throws Exception {
writeTrashFile("levelA/lA.txt", "");
- walk = beginWalk();
+ try (TreeWalk walk = beginWalk()) {
+ assertIteration(walk, F, ".gitattributes");
- assertIteration(F, ".gitattributes");
+ assertIteration(walk, D, "levelA");
+ assertIteration(walk, F, "levelA/.gitattributes");
+ assertIteration(walk, F, "levelA/lA.txt");
- assertIteration(D, "levelA");
- assertIteration(F, "levelA/.gitattributes");
- assertIteration(F, "levelA/lA.txt");
+ assertIteration(walk, D, "levelB");
+ assertIteration(walk, F, "levelB/.gitattributes");
- assertIteration(D, "levelB");
- assertIteration(F, "levelB/.gitattributes");
-
- endWalk();
+ assertFalse("Not all files tested", walk.next());
+ }
}
- private void assertIteration(FileMode type, String pathName)
+ private void assertIteration(TreeWalk walk, FileMode type, String pathName)
throws IOException {
- assertIteration(type, pathName, Collections.<Attribute> emptyList());
+ assertIteration(walk, type, pathName,
+ Collections.<Attribute> emptyList());
}
- private void assertIteration(FileMode type, String pathName,
+ private void assertIteration(TreeWalk walk, FileMode type, String pathName,
List<Attribute> nodeAttrs)
throws IOException {
assertTrue("walk has entry", walk.next());
@@ -212,13 +213,13 @@ private void assertIteration(FileMode type, String pathName,
assertNotNull("has tree", itr);
AttributesNode attributesNode = itr.getEntryAttributesNode();
- assertAttributesNode(pathName, attributesNode, nodeAttrs);
+ assertAttributesNode(walk, pathName, attributesNode, nodeAttrs);
if (D.equals(type))
walk.enterSubtree();
}
- private void assertAttributesNode(String pathName,
+ private void assertAttributesNode(TreeWalk walk, String pathName,
AttributesNode attributesNode, List<Attribute> nodeAttrs)
throws IOException {
if (attributesNode == null)
@@ -259,8 +260,4 @@ private TreeWalk beginWalk() {
newWalk.addTree(new FileTreeIterator(db));
return newWalk;
}
-
- private void endWalk() throws IOException {
- assertFalse("Not all files tested", walk.next());
- }
}
diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/attributes/TreeWalkAttributeTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/attributes/TreeWalkAttributeTest.java
index d6aead4..0291fcc 100644
--- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/attributes/TreeWalkAttributeTest.java
+++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/attributes/TreeWalkAttributeTest.java
@@ -131,6 +131,12 @@ public void setUp() throws Exception {
@Override
@After
public void tearDown() throws Exception {
+ if (walk != null) {
+ walk.close();
+ }
+ if (ci_walk != null) {
+ ci_walk.close();
+ }
super.tearDown();
if (customAttributeFile != null)
customAttributeFile.delete();
diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/ignore/IgnoreNodeTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/ignore/IgnoreNodeTest.java
index cbc0761..45046a3 100644
--- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/ignore/IgnoreNodeTest.java
+++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/ignore/IgnoreNodeTest.java
@@ -63,6 +63,7 @@
import org.eclipse.jgit.treewalk.WorkingTreeIterator;
import org.eclipse.jgit.util.FileUtils;
import org.eclipse.jgit.util.SystemReader;
+import org.junit.After;
import org.junit.Test;
/**
@@ -79,6 +80,13 @@ public class IgnoreNodeTest extends RepositoryTestCase {
private TreeWalk walk;
+ @After
+ public void closeWalk() {
+ if (walk != null) {
+ walk.close();
+ }
+ }
+
@Test
public void testSimpleRootGitIgnoreGlobalIgnore() throws IOException {
writeIgnoreFile(".gitignore", "x");
diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/dfs/DfsGarbageCollectorTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/dfs/DfsGarbageCollectorTest.java
index 858f5b9..1d7e283 100644
--- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/dfs/DfsGarbageCollectorTest.java
+++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/dfs/DfsGarbageCollectorTest.java
@@ -722,7 +722,7 @@ public void leavesNonGcReftablesIfNotConfigured() throws Exception {
DfsPackDescription t1 = odb.newPack(INSERT);
try (DfsOutputStream out = odb.writeFile(t1, REFTABLE)) {
- new ReftableWriter().begin(out).finish();
+ new ReftableWriter(out).begin().finish();
t1.addFileExt(REFTABLE);
}
odb.commitPack(Collections.singleton(t1), null);
@@ -754,7 +754,7 @@ public void prunesNonGcReftables() throws Exception {
DfsPackDescription t1 = odb.newPack(INSERT);
try (DfsOutputStream out = odb.writeFile(t1, REFTABLE)) {
- new ReftableWriter().begin(out).finish();
+ new ReftableWriter(out).begin().finish();
t1.addFileExt(REFTABLE);
}
odb.commitPack(Collections.singleton(t1), null);
@@ -794,10 +794,10 @@ public void compactsReftables() throws Exception {
Ref next = new ObjectIdRef.PeeledNonTag(Ref.Storage.LOOSE,
"refs/heads/next", commit0.copy());
try (DfsOutputStream out = odb.writeFile(t1, REFTABLE)) {
- ReftableWriter w = new ReftableWriter();
+ ReftableWriter w = new ReftableWriter(out);
w.setMinUpdateIndex(42);
w.setMaxUpdateIndex(42);
- w.begin(out);
+ w.begin();
w.sortAndWriteRefs(Collections.singleton(next));
w.finish();
t1.addFileExt(REFTABLE);
@@ -876,10 +876,10 @@ public void reftableWithoutTombstoneResurrected() throws Exception {
Ref newNext = new ObjectIdRef.PeeledNonTag(Ref.Storage.LOOSE, NEXT,
commit1);
try (DfsOutputStream out = odb.writeFile(t1, REFTABLE)) {
- ReftableWriter w = new ReftableWriter();
- w.setMinUpdateIndex(1);
- w.setMaxUpdateIndex(1);
- w.begin(out);
+ ReftableWriter w = new ReftableWriter(out)
+ .setMinUpdateIndex(1)
+ .setMaxUpdateIndex(1)
+ .begin();
w.writeRef(newNext, 1);
w.finish();
t1.addFileExt(REFTABLE);
@@ -928,10 +928,10 @@ public void reftableWithTombstoneNotResurrected() throws Exception {
Ref newNext = new ObjectIdRef.PeeledNonTag(Ref.Storage.LOOSE, NEXT,
commit1);
try (DfsOutputStream out = odb.writeFile(t1, REFTABLE)) {
- ReftableWriter w = new ReftableWriter();
- w.setMinUpdateIndex(1);
- w.setMaxUpdateIndex(1);
- w.begin(out);
+ ReftableWriter w = new ReftableWriter(out)
+ .setMinUpdateIndex(1)
+ .setMaxUpdateIndex(1)
+ .begin();
w.writeRef(newNext, 1);
w.finish();
t1.addFileExt(REFTABLE);
diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/dfs/DfsInserterTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/dfs/DfsInserterTest.java
index e71ee6d..4d36144 100644
--- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/dfs/DfsInserterTest.java
+++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/dfs/DfsInserterTest.java
@@ -92,18 +92,22 @@ public void testInserterDiscardsPack() throws IOException {
@Test
public void testReadFromInserterSmallObjects() throws IOException {
- ObjectInserter ins = db.newObjectInserter();
- ObjectId id1 = ins.insert(Constants.OBJ_BLOB, Constants.encode("foo"));
- ObjectId id2 = ins.insert(Constants.OBJ_BLOB, Constants.encode("bar"));
- assertEquals(0, db.getObjectDatabase().listPacks().size());
+ try (ObjectInserter ins = db.newObjectInserter()) {
+ ObjectId id1 = ins.insert(Constants.OBJ_BLOB,
+ Constants.encode("foo"));
+ ObjectId id2 = ins.insert(Constants.OBJ_BLOB,
+ Constants.encode("bar"));
+ assertEquals(0, db.getObjectDatabase().listPacks().size());
- ObjectReader reader = ins.newReader();
- assertSame(ins, reader.getCreatedFromInserter());
- assertEquals("foo", readString(reader.open(id1)));
- assertEquals("bar", readString(reader.open(id2)));
- assertEquals(0, db.getObjectDatabase().listPacks().size());
- ins.flush();
- assertEquals(1, db.getObjectDatabase().listPacks().size());
+ try (ObjectReader reader = ins.newReader()) {
+ assertSame(ins, reader.getCreatedFromInserter());
+ assertEquals("foo", readString(reader.open(id1)));
+ assertEquals("bar", readString(reader.open(id2)));
+ assertEquals(0, db.getObjectDatabase().listPacks().size());
+ ins.flush();
+ assertEquals(1, db.getObjectDatabase().listPacks().size());
+ }
+ }
}
@Test
@@ -114,17 +118,19 @@ public void testReadFromInserterLargerObjects() throws IOException {
.setBlockLimit(2048));
byte[] data = new TestRng(JGitTestUtil.getName()).nextBytes(8192);
- DfsInserter ins = (DfsInserter) db.newObjectInserter();
- ins.setCompressionLevel(Deflater.NO_COMPRESSION);
- ObjectId id1 = ins.insert(Constants.OBJ_BLOB, data);
- assertEquals(0, db.getObjectDatabase().listPacks().size());
+ try (DfsInserter ins = (DfsInserter) db.newObjectInserter()) {
+ ins.setCompressionLevel(Deflater.NO_COMPRESSION);
+ ObjectId id1 = ins.insert(Constants.OBJ_BLOB, data);
+ assertEquals(0, db.getObjectDatabase().listPacks().size());
- ObjectReader reader = ins.newReader();
- assertSame(ins, reader.getCreatedFromInserter());
- assertTrue(Arrays.equals(data, readStream(reader.open(id1))));
- assertEquals(0, db.getObjectDatabase().listPacks().size());
- ins.flush();
+ try (ObjectReader reader = ins.newReader()) {
+ assertSame(ins, reader.getCreatedFromInserter());
+ assertTrue(Arrays.equals(data, readStream(reader.open(id1))));
+ assertEquals(0, db.getObjectDatabase().listPacks().size());
+ }
+ ins.flush();
+ }
List<DfsPackDescription> packs = db.getObjectDatabase().listPacks();
assertEquals(1, packs.size());
assertTrue(packs.get(0).getFileSize(PackExt.PACK) > 2048);
@@ -132,48 +138,58 @@ public void testReadFromInserterLargerObjects() throws IOException {
@Test
public void testReadFromFallback() throws IOException {
- ObjectInserter ins = db.newObjectInserter();
- ObjectId id1 = ins.insert(Constants.OBJ_BLOB, Constants.encode("foo"));
- ins.flush();
- ObjectId id2 = ins.insert(Constants.OBJ_BLOB, Constants.encode("bar"));
- assertEquals(1, db.getObjectDatabase().listPacks().size());
+ try (ObjectInserter ins = db.newObjectInserter()) {
+ ObjectId id1 = ins.insert(Constants.OBJ_BLOB,
+ Constants.encode("foo"));
+ ins.flush();
+ ObjectId id2 = ins.insert(Constants.OBJ_BLOB,
+ Constants.encode("bar"));
+ assertEquals(1, db.getObjectDatabase().listPacks().size());
- ObjectReader reader = ins.newReader();
- assertSame(ins, reader.getCreatedFromInserter());
- assertEquals("foo", readString(reader.open(id1)));
- assertEquals("bar", readString(reader.open(id2)));
- assertEquals(1, db.getObjectDatabase().listPacks().size());
- ins.flush();
- assertEquals(2, db.getObjectDatabase().listPacks().size());
+ try (ObjectReader reader = ins.newReader()) {
+ assertSame(ins, reader.getCreatedFromInserter());
+ assertEquals("foo", readString(reader.open(id1)));
+ assertEquals("bar", readString(reader.open(id2)));
+ assertEquals(1, db.getObjectDatabase().listPacks().size());
+ }
+ ins.flush();
+ assertEquals(2, db.getObjectDatabase().listPacks().size());
+ }
}
@Test
public void testReaderResolve() throws IOException {
- ObjectInserter ins = db.newObjectInserter();
- ObjectId id1 = ins.insert(Constants.OBJ_BLOB, Constants.encode("foo"));
- ins.flush();
- ObjectId id2 = ins.insert(Constants.OBJ_BLOB, Constants.encode("bar"));
- String abbr1 = ObjectId.toString(id1).substring(0, 4);
- String abbr2 = ObjectId.toString(id2).substring(0, 4);
- assertFalse(abbr1.equals(abbr2));
+ try (ObjectInserter ins = db.newObjectInserter()) {
+ ObjectId id1 = ins.insert(Constants.OBJ_BLOB,
+ Constants.encode("foo"));
+ ins.flush();
+ ObjectId id2 = ins.insert(Constants.OBJ_BLOB,
+ Constants.encode("bar"));
+ String abbr1 = ObjectId.toString(id1).substring(0, 4);
+ String abbr2 = ObjectId.toString(id2).substring(0, 4);
+ assertFalse(abbr1.equals(abbr2));
- ObjectReader reader = ins.newReader();
- assertSame(ins, reader.getCreatedFromInserter());
- Collection<ObjectId> objs;
- objs = reader.resolve(AbbreviatedObjectId.fromString(abbr1));
- assertEquals(1, objs.size());
- assertEquals(id1, objs.iterator().next());
+ try (ObjectReader reader = ins.newReader()) {
+ assertSame(ins, reader.getCreatedFromInserter());
+ Collection<ObjectId> objs;
+ objs = reader.resolve(AbbreviatedObjectId.fromString(abbr1));
+ assertEquals(1, objs.size());
+ assertEquals(id1, objs.iterator().next());
- objs = reader.resolve(AbbreviatedObjectId.fromString(abbr2));
- assertEquals(1, objs.size());
- assertEquals(id2, objs.iterator().next());
+ objs = reader.resolve(AbbreviatedObjectId.fromString(abbr2));
+ assertEquals(1, objs.size());
+ assertEquals(id2, objs.iterator().next());
+ }
+ }
}
@Test
public void testGarbageSelectivelyVisible() throws IOException {
- ObjectInserter ins = db.newObjectInserter();
- ObjectId fooId = ins.insert(Constants.OBJ_BLOB, Constants.encode("foo"));
- ins.flush();
+ ObjectId fooId;
+ try (ObjectInserter ins = db.newObjectInserter()) {
+ fooId = ins.insert(Constants.OBJ_BLOB, Constants.encode("foo"));
+ ins.flush();
+ }
assertEquals(1, db.getObjectDatabase().listPacks().size());
// Make pack 0 garbage.
@@ -187,36 +203,40 @@ public void testGarbageSelectivelyVisible() throws IOException {
@Test
public void testInserterIgnoresUnreachable() throws IOException {
- ObjectInserter ins = db.newObjectInserter();
- ObjectId fooId = ins.insert(Constants.OBJ_BLOB, Constants.encode("foo"));
- ins.flush();
- assertEquals(1, db.getObjectDatabase().listPacks().size());
+ ObjectId fooId;
+ try (ObjectInserter ins = db.newObjectInserter()) {
+ fooId = ins.insert(Constants.OBJ_BLOB, Constants.encode("foo"));
+ ins.flush();
+ assertEquals(1, db.getObjectDatabase().listPacks().size());
- // Make pack 0 garbage.
- db.getObjectDatabase().listPacks().get(0).setPackSource(PackSource.UNREACHABLE_GARBAGE);
+ // Make pack 0 garbage.
+ db.getObjectDatabase().listPacks().get(0)
+ .setPackSource(PackSource.UNREACHABLE_GARBAGE);
- // We shouldn't be able to see foo because it's garbage.
- assertFalse(db.getObjectDatabase().has(fooId, true));
+ // We shouldn't be able to see foo because it's garbage.
+ assertFalse(db.getObjectDatabase().has(fooId, true));
- // But if we re-insert foo, it should become visible again.
- ins.insert(Constants.OBJ_BLOB, Constants.encode("foo"));
- ins.flush();
+ // But if we re-insert foo, it should become visible again.
+ ins.insert(Constants.OBJ_BLOB, Constants.encode("foo"));
+ ins.flush();
+ }
assertTrue(db.getObjectDatabase().has(fooId, true));
// Verify that we have a foo in both packs, and 1 of them is garbage.
- DfsReader reader = new DfsReader(db.getObjectDatabase());
- DfsPackFile packs[] = db.getObjectDatabase().getPacks();
- Set<PackSource> pack_sources = new HashSet<>();
+ try (DfsReader reader = new DfsReader(db.getObjectDatabase())) {
+ DfsPackFile packs[] = db.getObjectDatabase().getPacks();
+ Set<PackSource> pack_sources = new HashSet<>();
- assertEquals(2, packs.length);
+ assertEquals(2, packs.length);
- pack_sources.add(packs[0].getPackDescription().getPackSource());
- pack_sources.add(packs[1].getPackDescription().getPackSource());
+ pack_sources.add(packs[0].getPackDescription().getPackSource());
+ pack_sources.add(packs[1].getPackDescription().getPackSource());
- assertTrue(packs[0].hasObject(reader, fooId));
- assertTrue(packs[1].hasObject(reader, fooId));
- assertTrue(pack_sources.contains(PackSource.UNREACHABLE_GARBAGE));
- assertTrue(pack_sources.contains(PackSource.INSERT));
+ assertTrue(packs[0].hasObject(reader, fooId));
+ assertTrue(packs[1].hasObject(reader, fooId));
+ assertTrue(pack_sources.contains(PackSource.UNREACHABLE_GARBAGE));
+ assertTrue(pack_sources.contains(PackSource.INSERT));
+ }
}
@Test
@@ -237,17 +257,20 @@ public void testNoCheckExisting() throws IOException {
assertEquals(2, db.getObjectDatabase().listPacks().size());
// Verify that we have a foo in both INSERT packs.
- DfsReader reader = new DfsReader(db.getObjectDatabase());
- DfsPackFile packs[] = db.getObjectDatabase().getPacks();
+ try (DfsReader reader = new DfsReader(db.getObjectDatabase())) {
+ DfsPackFile packs[] = db.getObjectDatabase().getPacks();
- assertEquals(2, packs.length);
- DfsPackFile p1 = packs[0];
- assertEquals(PackSource.INSERT, p1.getPackDescription().getPackSource());
- assertTrue(p1.hasObject(reader, fooId));
+ assertEquals(2, packs.length);
+ DfsPackFile p1 = packs[0];
+ assertEquals(PackSource.INSERT,
+ p1.getPackDescription().getPackSource());
+ assertTrue(p1.hasObject(reader, fooId));
- DfsPackFile p2 = packs[1];
- assertEquals(PackSource.INSERT, p2.getPackDescription().getPackSource());
- assertTrue(p2.hasObject(reader, fooId));
+ DfsPackFile p2 = packs[1];
+ assertEquals(PackSource.INSERT,
+ p2.getPackDescription().getPackSource());
+ assertTrue(p2.hasObject(reader, fooId));
+ }
}
private static String readString(ObjectLoader loader) throws IOException {
diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/file/BatchRefUpdateTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/file/BatchRefUpdateTest.java
index c211eab..32513c9 100644
--- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/file/BatchRefUpdateTest.java
+++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/file/BatchRefUpdateTest.java
@@ -61,6 +61,7 @@
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
+import static org.junit.Assume.assumeFalse;
import static org.junit.Assume.assumeTrue;
import java.io.File;
@@ -109,19 +110,29 @@
@SuppressWarnings("boxing")
@RunWith(Parameterized.class)
public class BatchRefUpdateTest extends LocalDiskRepositoryTestCase {
- @Parameter
+ @Parameter(0)
public boolean atomic;
- @Parameters(name = "atomic={0}")
+ @Parameter(1)
+ public boolean useReftable;
+
+ @Parameters(name = "atomic={0} reftable={1}")
public static Collection<Object[]> data() {
- return Arrays.asList(new Object[][]{ {Boolean.FALSE}, {Boolean.TRUE} });
+ return Arrays.asList(new Object[][] { { Boolean.FALSE, Boolean.FALSE },
+ { Boolean.TRUE, Boolean.FALSE },
+ { Boolean.FALSE, Boolean.TRUE },
+ { Boolean.TRUE, Boolean.TRUE }, });
}
private Repository diskRepo;
+
private TestRepository<Repository> repo;
+
private RefDirectory refdir;
+
private RevCommit A;
- private RevCommit B;
+
+ private RevCommit B; // B descends from A.
/**
* When asserting the number of RefsChangedEvents you must account for one
@@ -143,11 +154,18 @@ public class BatchRefUpdateTest extends LocalDiskRepositoryTestCase {
public void setUp() throws Exception {
super.setUp();
- diskRepo = createBareRepository();
+ FileRepository fileRepo = createBareRepository();
+ if (useReftable) {
+ fileRepo.convertToReftable(false, false);
+ }
+
+ diskRepo = fileRepo;
setLogAllRefUpdates(true);
- refdir = (RefDirectory) diskRepo.getRefDatabase();
- refdir.setRetrySleepMs(Arrays.asList(0, 0));
+ if (!useReftable) {
+ refdir = (RefDirectory) diskRepo.getRefDatabase();
+ refdir.setRetrySleepMs(Arrays.asList(0, 0));
+ }
repo = new TestRepository<>(diskRepo);
A = repo.commit().create();
@@ -166,11 +184,12 @@ public void removeListener() {
@Test
public void packedRefsFileIsSorted() throws IOException {
assumeTrue(atomic);
+ assumeFalse(useReftable);
for (int i = 0; i < 2; i++) {
BatchRefUpdate bu = diskRepo.getRefDatabase().newBatchUpdate();
- String b1 = String.format("refs/heads/a%d",i);
- String b2 = String.format("refs/heads/b%d",i);
+ String b1 = String.format("refs/heads/a%d", i);
+ String b2 = String.format("refs/heads/b%d", i);
bu.setAtomic(atomic);
ReceiveCommand c1 = new ReceiveCommand(ObjectId.zeroId(), A, b1);
ReceiveCommand c2 = new ReceiveCommand(ObjectId.zeroId(), B, b2);
@@ -183,42 +202,36 @@ public void packedRefsFileIsSorted() throws IOException {
}
File packed = new File(diskRepo.getDirectory(), "packed-refs");
- String packedStr = new String(Files.readAllBytes(packed.toPath()), UTF_8);
+ String packedStr = new String(Files.readAllBytes(packed.toPath()),
+ UTF_8);
int a2 = packedStr.indexOf("refs/heads/a1");
int b1 = packedStr.indexOf("refs/heads/b0");
- assertTrue(a2 < b1);
+ assertTrue(a2 < b1);
}
@Test
public void simpleNoForce() throws IOException {
- writeLooseRef("refs/heads/master", A);
- writeLooseRef("refs/heads/masters", B);
+ writeLooseRefs("refs/heads/master", A, "refs/heads/masters", B);
List<ReceiveCommand> cmds = Arrays.asList(
new ReceiveCommand(A, B, "refs/heads/master", UPDATE),
- new ReceiveCommand(B, A, "refs/heads/masters", UPDATE_NONFASTFORWARD));
+ new ReceiveCommand(B, A, "refs/heads/masters",
+ UPDATE_NONFASTFORWARD));
execute(newBatchUpdate(cmds));
if (atomic) {
assertResults(cmds, TRANSACTION_ABORTED, REJECTED_NONFASTFORWARD);
- assertRefs(
- "refs/heads/master", A,
- "refs/heads/masters", B);
+ assertRefs("refs/heads/master", A, "refs/heads/masters", B);
} else {
assertResults(cmds, OK, REJECTED_NONFASTFORWARD);
- assertRefs(
- "refs/heads/master", B,
- "refs/heads/masters", B);
+ assertRefs("refs/heads/master", B, "refs/heads/masters", B);
}
}
@Test
public void simpleNoForceRefsChangedEvents() throws IOException {
- writeLooseRef("refs/heads/master", A);
- writeLooseRef("refs/heads/masters", B);
- refdir.exactRef("refs/heads/master");
- refdir.exactRef("refs/heads/masters");
+ writeLooseRefs("refs/heads/master", A, "refs/heads/masters", B);
int initialRefsChangedEvents = refsChangedEvents;
List<ReceiveCommand> cmds = Arrays.asList(
@@ -233,26 +246,21 @@ public void simpleNoForceRefsChangedEvents() throws IOException {
@Test
public void simpleForce() throws IOException {
- writeLooseRef("refs/heads/master", A);
- writeLooseRef("refs/heads/masters", B);
+ writeLooseRefs("refs/heads/master", A, "refs/heads/masters", B);
List<ReceiveCommand> cmds = Arrays.asList(
new ReceiveCommand(A, B, "refs/heads/master", UPDATE),
- new ReceiveCommand(B, A, "refs/heads/masters", UPDATE_NONFASTFORWARD));
+ new ReceiveCommand(B, A, "refs/heads/masters",
+ UPDATE_NONFASTFORWARD));
execute(newBatchUpdate(cmds).setAllowNonFastForwards(true));
assertResults(cmds, OK, OK);
- assertRefs(
- "refs/heads/master", B,
- "refs/heads/masters", A);
+ assertRefs("refs/heads/master", B, "refs/heads/masters", A);
}
@Test
public void simpleForceRefsChangedEvents() throws IOException {
- writeLooseRef("refs/heads/master", A);
- writeLooseRef("refs/heads/masters", B);
- refdir.exactRef("refs/heads/master");
- refdir.exactRef("refs/heads/masters");
+ writeLooseRefs("refs/heads/master", A, "refs/heads/masters", B);
int initialRefsChangedEvents = refsChangedEvents;
List<ReceiveCommand> cmds = Arrays.asList(
@@ -261,25 +269,25 @@ public void simpleForceRefsChangedEvents() throws IOException {
UPDATE_NONFASTFORWARD));
execute(newBatchUpdate(cmds).setAllowNonFastForwards(true));
- assertEquals(atomic ? initialRefsChangedEvents + 1
+ assertEquals(batchesRefUpdates() ? initialRefsChangedEvents + 1
: initialRefsChangedEvents + 2, refsChangedEvents);
}
@Test
- public void nonFastForwardDoesNotDoExpensiveMergeCheck() throws IOException {
+ public void nonFastForwardDoesNotDoExpensiveMergeCheck()
+ throws IOException {
writeLooseRef("refs/heads/master", B);
- List<ReceiveCommand> cmds = Arrays.asList(
- new ReceiveCommand(B, A, "refs/heads/master", UPDATE_NONFASTFORWARD));
+ List<ReceiveCommand> cmds = Arrays.asList(new ReceiveCommand(B, A,
+ "refs/heads/master", UPDATE_NONFASTFORWARD));
try (RevWalk rw = new RevWalk(diskRepo) {
- @Override
- public boolean isMergedInto(RevCommit base, RevCommit tip) {
- throw new AssertionError("isMergedInto() should not be called");
- }
- }) {
- newBatchUpdate(cmds)
- .setAllowNonFastForwards(true)
- .execute(rw, new StrictWorkMonitor());
+ @Override
+ public boolean isMergedInto(RevCommit base, RevCommit tip) {
+ throw new AssertionError("isMergedInto() should not be called");
+ }
+ }) {
+ newBatchUpdate(cmds).setAllowNonFastForwards(true).execute(rw,
+ new StrictWorkMonitor());
}
assertResults(cmds, OK);
@@ -290,7 +298,6 @@ public boolean isMergedInto(RevCommit base, RevCommit tip) {
public void nonFastForwardDoesNotDoExpensiveMergeCheckRefsChangedEvents()
throws IOException {
writeLooseRef("refs/heads/master", B);
- refdir.exactRef("refs/heads/master");
int initialRefsChangedEvents = refsChangedEvents;
List<ReceiveCommand> cmds = Arrays.asList(new ReceiveCommand(B, A,
@@ -310,8 +317,7 @@ public boolean isMergedInto(RevCommit base, RevCommit tip) {
@Test
public void fileDirectoryConflict() throws IOException {
- writeLooseRef("refs/heads/master", A);
- writeLooseRef("refs/heads/masters", B);
+ writeLooseRefs("refs/heads/master", A, "refs/heads/masters", B);
List<ReceiveCommand> cmds = Arrays.asList(
new ReceiveCommand(A, B, "refs/heads/master", UPDATE),
@@ -320,29 +326,22 @@ public void fileDirectoryConflict() throws IOException {
execute(newBatchUpdate(cmds).setAllowNonFastForwards(true), false);
if (atomic) {
- // Atomic update sees that master and master/x are conflicting, then marks
- // the first one in the list as LOCK_FAILURE and aborts the rest.
- assertResults(cmds,
- LOCK_FAILURE, TRANSACTION_ABORTED, TRANSACTION_ABORTED);
- assertRefs(
- "refs/heads/master", A,
- "refs/heads/masters", B);
+ // Atomic update sees that master and master/x are conflicting, then
+ // marks the first one in the list as LOCK_FAILURE and aborts the rest.
+ assertResults(cmds, LOCK_FAILURE, TRANSACTION_ABORTED,
+ TRANSACTION_ABORTED);
+ assertRefs("refs/heads/master", A, "refs/heads/masters", B);
} else {
- // Non-atomic updates are applied in order: master succeeds, then master/x
- // fails due to conflict.
+ // Non-atomic updates are applied in order: master succeeds, then
+ // master/x fails due to conflict.
assertResults(cmds, OK, LOCK_FAILURE, LOCK_FAILURE);
- assertRefs(
- "refs/heads/master", B,
- "refs/heads/masters", B);
+ assertRefs("refs/heads/master", B, "refs/heads/masters", B);
}
}
@Test
public void fileDirectoryConflictRefsChangedEvents() throws IOException {
- writeLooseRef("refs/heads/master", A);
- writeLooseRef("refs/heads/masters", B);
- refdir.exactRef("refs/heads/master");
- refdir.exactRef("refs/heads/masters");
+ writeLooseRefs("refs/heads/master", A, "refs/heads/masters", B);
int initialRefsChangedEvents = refsChangedEvents;
List<ReceiveCommand> cmds = Arrays.asList(
@@ -357,8 +356,7 @@ public void fileDirectoryConflictRefsChangedEvents() throws IOException {
@Test
public void conflictThanksToDelete() throws IOException {
- writeLooseRef("refs/heads/master", A);
- writeLooseRef("refs/heads/masters", B);
+ writeLooseRefs("refs/heads/master", A, "refs/heads/masters", B);
List<ReceiveCommand> cmds = Arrays.asList(
new ReceiveCommand(A, B, "refs/heads/master", UPDATE),
@@ -367,17 +365,12 @@ public void conflictThanksToDelete() throws IOException {
execute(newBatchUpdate(cmds).setAllowNonFastForwards(true));
assertResults(cmds, OK, OK, OK);
- assertRefs(
- "refs/heads/master", B,
- "refs/heads/masters/x", A);
+ assertRefs("refs/heads/master", B, "refs/heads/masters/x", A);
}
@Test
public void conflictThanksToDeleteRefsChangedEvents() throws IOException {
- writeLooseRef("refs/heads/master", A);
- writeLooseRef("refs/heads/masters", B);
- refdir.exactRef("refs/heads/master");
- refdir.exactRef("refs/heads/masters");
+ writeLooseRefs("refs/heads/master", A, "refs/heads/masters", B);
int initialRefsChangedEvents = refsChangedEvents;
List<ReceiveCommand> cmds = Arrays.asList(
@@ -386,7 +379,7 @@ public void conflictThanksToDeleteRefsChangedEvents() throws IOException {
new ReceiveCommand(B, zeroId(), "refs/heads/masters", DELETE));
execute(newBatchUpdate(cmds).setAllowNonFastForwards(true));
- assertEquals(atomic ? initialRefsChangedEvents + 1
+ assertEquals(batchesRefUpdates() ? initialRefsChangedEvents + 1
: initialRefsChangedEvents + 3, refsChangedEvents);
}
@@ -394,8 +387,8 @@ public void conflictThanksToDeleteRefsChangedEvents() throws IOException {
public void updateToMissingObject() throws IOException {
writeLooseRef("refs/heads/master", A);
- ObjectId bad =
- ObjectId.fromString("deadbeefdeadbeefdeadbeefdeadbeefdeadbeef");
+ ObjectId bad = ObjectId
+ .fromString("deadbeefdeadbeefdeadbeefdeadbeefdeadbeef");
List<ReceiveCommand> cmds = Arrays.asList(
new ReceiveCommand(A, bad, "refs/heads/master", UPDATE),
new ReceiveCommand(zeroId(), B, "refs/heads/foo2", CREATE));
@@ -406,16 +399,13 @@ public void updateToMissingObject() throws IOException {
assertRefs("refs/heads/master", A);
} else {
assertResults(cmds, REJECTED_MISSING_OBJECT, OK);
- assertRefs(
- "refs/heads/master", A,
- "refs/heads/foo2", B);
+ assertRefs("refs/heads/master", A, "refs/heads/foo2", B);
}
}
@Test
public void updateToMissingObjectRefsChangedEvents() throws IOException {
writeLooseRef("refs/heads/master", A);
- refdir.exactRef("refs/heads/master");
int initialRefsChangedEvents = refsChangedEvents;
ObjectId bad = ObjectId
@@ -433,8 +423,8 @@ public void updateToMissingObjectRefsChangedEvents() throws IOException {
public void addMissingObject() throws IOException {
writeLooseRef("refs/heads/master", A);
- ObjectId bad =
- ObjectId.fromString("deadbeefdeadbeefdeadbeefdeadbeefdeadbeef");
+ ObjectId bad = ObjectId
+ .fromString("deadbeefdeadbeefdeadbeefdeadbeefdeadbeef");
List<ReceiveCommand> cmds = Arrays.asList(
new ReceiveCommand(A, B, "refs/heads/master", UPDATE),
new ReceiveCommand(zeroId(), bad, "refs/heads/foo2", CREATE));
@@ -452,7 +442,6 @@ public void addMissingObject() throws IOException {
@Test
public void addMissingObjectRefsChangedEvents() throws IOException {
writeLooseRef("refs/heads/master", A);
- refdir.exactRef("refs/heads/master");
int initialRefsChangedEvents = refsChangedEvents;
ObjectId bad = ObjectId
@@ -498,16 +487,13 @@ public void oneRefWrongOldValue() throws IOException {
assertRefs("refs/heads/master", A);
} else {
assertResults(cmds, LOCK_FAILURE, OK);
- assertRefs(
- "refs/heads/master", A,
- "refs/heads/foo2", B);
+ assertRefs("refs/heads/master", A, "refs/heads/foo2", B);
}
}
@Test
public void oneRefWrongOldValueRefsChangedEvents() throws IOException {
writeLooseRef("refs/heads/master", A);
- refdir.exactRef("refs/heads/master");
int initialRefsChangedEvents = refsChangedEvents;
List<ReceiveCommand> cmds = Arrays.asList(
@@ -540,7 +526,7 @@ public void nonExistentRef() throws IOException {
@Test
public void nonExistentRefRefsChangedEvents() throws IOException {
writeLooseRef("refs/heads/master", A);
- refdir.exactRef("refs/heads/master");
+
int initialRefsChangedEvents = refsChangedEvents;
List<ReceiveCommand> cmds = Arrays.asList(
@@ -557,9 +543,10 @@ public void noRefLog() throws IOException {
writeRef("refs/heads/master", A);
int initialRefsChangedEvents = refsChangedEvents;
- Map<String, ReflogEntry> oldLogs =
- getLastReflogs("refs/heads/master", "refs/heads/branch");
- assertEquals(Collections.singleton("refs/heads/master"), oldLogs.keySet());
+ Map<String, ReflogEntry> oldLogs = getLastReflogs("refs/heads/master",
+ "refs/heads/branch");
+ assertEquals(Collections.singleton("refs/heads/master"),
+ oldLogs.keySet());
List<ReceiveCommand> cmds = Arrays.asList(
new ReceiveCommand(A, B, "refs/heads/master", UPDATE),
@@ -567,10 +554,8 @@ public void noRefLog() throws IOException {
execute(newBatchUpdate(cmds).setAllowNonFastForwards(true));
assertResults(cmds, OK, OK);
- assertRefs(
- "refs/heads/master", B,
- "refs/heads/branch", B);
- assertEquals(atomic ? initialRefsChangedEvents + 1
+ assertRefs("refs/heads/master", B, "refs/heads/branch", B);
+ assertEquals(batchesRefUpdates() ? initialRefsChangedEvents + 1
: initialRefsChangedEvents + 2, refsChangedEvents);
assertReflogUnchanged(oldLogs, "refs/heads/master");
assertReflogUnchanged(oldLogs, "refs/heads/branch");
@@ -582,25 +567,20 @@ public void reflogDefaultIdent() throws IOException {
writeRef("refs/heads/branch2", A);
int initialRefsChangedEvents = refsChangedEvents;
- Map<String, ReflogEntry> oldLogs = getLastReflogs(
- "refs/heads/master", "refs/heads/branch1", "refs/heads/branch2");
+ Map<String, ReflogEntry> oldLogs = getLastReflogs("refs/heads/master",
+ "refs/heads/branch1", "refs/heads/branch2");
List<ReceiveCommand> cmds = Arrays.asList(
new ReceiveCommand(A, B, "refs/heads/master", UPDATE),
new ReceiveCommand(zeroId(), B, "refs/heads/branch1", CREATE));
- execute(
- newBatchUpdate(cmds)
- .setAllowNonFastForwards(true)
- .setRefLogMessage("a reflog", false));
+ execute(newBatchUpdate(cmds).setAllowNonFastForwards(true)
+ .setRefLogMessage("a reflog", false));
assertResults(cmds, OK, OK);
- assertRefs(
- "refs/heads/master", B,
- "refs/heads/branch1", B,
+ assertRefs("refs/heads/master", B, "refs/heads/branch1", B,
"refs/heads/branch2", A);
- assertEquals(atomic ? initialRefsChangedEvents + 1
+ assertEquals(batchesRefUpdates() ? initialRefsChangedEvents + 1
: initialRefsChangedEvents + 2, refsChangedEvents);
- assertReflogEquals(
- reflog(A, B, new PersonIdent(diskRepo), "a reflog"),
+ assertReflogEquals(reflog(A, B, new PersonIdent(diskRepo), "a reflog"),
getLastReflog("refs/heads/master"));
assertReflogEquals(
reflog(zeroId(), B, new PersonIdent(diskRepo), "a reflog"),
@@ -616,23 +596,20 @@ public void reflogAppendStatusNoMessage() throws IOException {
List<ReceiveCommand> cmds = Arrays.asList(
new ReceiveCommand(A, B, "refs/heads/master", UPDATE),
- new ReceiveCommand(B, A, "refs/heads/branch1", UPDATE_NONFASTFORWARD),
+ new ReceiveCommand(B, A, "refs/heads/branch1",
+ UPDATE_NONFASTFORWARD),
new ReceiveCommand(zeroId(), A, "refs/heads/branch2", CREATE));
- execute(
- newBatchUpdate(cmds)
- .setAllowNonFastForwards(true)
- .setRefLogMessage(null, true));
+ execute(newBatchUpdate(cmds).setAllowNonFastForwards(true)
+ .setRefLogMessage(null, true));
assertResults(cmds, OK, OK, OK);
- assertRefs(
- "refs/heads/master", B,
- "refs/heads/branch1", A,
+ assertRefs("refs/heads/master", B, "refs/heads/branch1", A,
"refs/heads/branch2", A);
- assertEquals(atomic ? initialRefsChangedEvents + 1
- : initialRefsChangedEvents + 3,
- refsChangedEvents);
+ assertEquals(batchesRefUpdates() ? initialRefsChangedEvents + 1
+ : initialRefsChangedEvents + 3, refsChangedEvents);
assertReflogEquals(
- // Always forced; setAllowNonFastForwards(true) bypasses the check.
+ // Always forced; setAllowNonFastForwards(true) bypasses the
+ // check.
reflog(A, B, new PersonIdent(diskRepo), "forced-update"),
getLastReflog("refs/heads/master"));
assertReflogEquals(
@@ -648,8 +625,8 @@ public void reflogAppendStatusFastForward() throws IOException {
writeRef("refs/heads/master", A);
int initialRefsChangedEvents = refsChangedEvents;
- List<ReceiveCommand> cmds = Arrays.asList(
- new ReceiveCommand(A, B, "refs/heads/master", UPDATE));
+ List<ReceiveCommand> cmds = Arrays
+ .asList(new ReceiveCommand(A, B, "refs/heads/master", UPDATE));
execute(newBatchUpdate(cmds).setRefLogMessage(null, true));
assertResults(cmds, OK);
@@ -671,16 +648,16 @@ public void reflogAppendStatusWithMessage() throws IOException {
execute(newBatchUpdate(cmds).setRefLogMessage("a reflog", true));
assertResults(cmds, OK, OK);
- assertRefs(
- "refs/heads/master", B,
- "refs/heads/branch", A);
- assertEquals(atomic ? initialRefsChangedEvents + 1
+ assertRefs("refs/heads/master", B, "refs/heads/branch", A);
+ assertEquals(batchesRefUpdates() ? initialRefsChangedEvents + 1
: initialRefsChangedEvents + 2, refsChangedEvents);
assertReflogEquals(
- reflog(A, B, new PersonIdent(diskRepo), "a reflog: fast-forward"),
+ reflog(A, B, new PersonIdent(diskRepo),
+ "a reflog: fast-forward"),
getLastReflog("refs/heads/master"));
assertReflogEquals(
- reflog(zeroId(), A, new PersonIdent(diskRepo), "a reflog: created"),
+ reflog(zeroId(), A, new PersonIdent(diskRepo),
+ "a reflog: created"),
getLastReflog("refs/heads/branch"));
}
@@ -692,26 +669,19 @@ public void reflogCustomIdent() throws IOException {
List<ReceiveCommand> cmds = Arrays.asList(
new ReceiveCommand(A, B, "refs/heads/master", UPDATE),
new ReceiveCommand(zeroId(), B, "refs/heads/branch", CREATE));
- PersonIdent ident = new PersonIdent("A Reflog User", "reflog@example.com");
- execute(
- newBatchUpdate(cmds)
- .setRefLogMessage("a reflog", false)
- .setRefLogIdent(ident));
+ PersonIdent ident = new PersonIdent("A Reflog User",
+ "reflog@example.com");
+ execute(newBatchUpdate(cmds).setRefLogMessage("a reflog", false)
+ .setRefLogIdent(ident));
assertResults(cmds, OK, OK);
- assertEquals(atomic ? initialRefsChangedEvents + 1
+ assertEquals(batchesRefUpdates() ? initialRefsChangedEvents + 1
: initialRefsChangedEvents + 2, refsChangedEvents);
- assertRefs(
- "refs/heads/master", B,
- "refs/heads/branch", B);
- assertReflogEquals(
- reflog(A, B, ident, "a reflog"),
- getLastReflog("refs/heads/master"),
- true);
- assertReflogEquals(
- reflog(zeroId(), B, ident, "a reflog"),
- getLastReflog("refs/heads/branch"),
- true);
+ assertRefs("refs/heads/master", B, "refs/heads/branch", B);
+ assertReflogEquals(reflog(A, B, ident, "a reflog"),
+ getLastReflog("refs/heads/master"), true);
+ assertReflogEquals(reflog(zeroId(), B, ident, "a reflog"),
+ getLastReflog("refs/heads/branch"), true);
}
@Test
@@ -719,9 +689,8 @@ public void reflogDelete() throws IOException {
writeRef("refs/heads/master", A);
writeRef("refs/heads/branch", A);
int initialRefsChangedEvents = refsChangedEvents;
-
- assertEquals(
- 2, getLastReflogs("refs/heads/master", "refs/heads/branch").size());
+ assertEquals(2, getLastReflogs("refs/heads/master", "refs/heads/branch")
+ .size());
List<ReceiveCommand> cmds = Arrays.asList(
new ReceiveCommand(A, zeroId(), "refs/heads/master", DELETE),
@@ -730,11 +699,17 @@ public void reflogDelete() throws IOException {
assertResults(cmds, OK, OK);
assertRefs("refs/heads/branch", B);
- assertEquals(atomic ? initialRefsChangedEvents + 1
+ assertEquals(batchesRefUpdates() ? initialRefsChangedEvents + 1
: initialRefsChangedEvents + 2, refsChangedEvents);
- assertNull(getLastReflog("refs/heads/master"));
- assertReflogEquals(
- reflog(A, B, new PersonIdent(diskRepo), "a reflog"),
+ if (useReftable) {
+ // reftable retains reflog entries for deleted branches.
+ assertReflogEquals(
+ reflog(A, zeroId(), new PersonIdent(diskRepo), "a reflog"),
+ getLastReflog("refs/heads/master"));
+ } else {
+ assertNull(getLastReflog("refs/heads/master"));
+ }
+ assertReflogEquals(reflog(A, B, new PersonIdent(diskRepo), "a reflog"),
getLastReflog("refs/heads/branch"));
}
@@ -750,9 +725,12 @@ public void reflogFileDirectoryConflict() throws IOException {
assertResults(cmds, OK, OK);
assertRefs("refs/heads/master/x", A);
- assertEquals(atomic ? initialRefsChangedEvents + 1
+ assertEquals(batchesRefUpdates() ? initialRefsChangedEvents + 1
: initialRefsChangedEvents + 2, refsChangedEvents);
- assertNull(getLastReflog("refs/heads/master"));
+ if (!useReftable) {
+ // reftable retains reflog entries for deleted branches.
+ assertNull(getLastReflog("refs/heads/master"));
+ }
assertReflogEquals(
reflog(zeroId(), A, new PersonIdent(diskRepo), "a reflog"),
getLastReflog("refs/heads/master/x"));
@@ -763,8 +741,8 @@ public void reflogOnLockFailure() throws IOException {
writeRef("refs/heads/master", A);
int initialRefsChangedEvents = refsChangedEvents;
- Map<String, ReflogEntry> oldLogs =
- getLastReflogs("refs/heads/master", "refs/heads/branch");
+ Map<String, ReflogEntry> oldLogs = getLastReflogs("refs/heads/master",
+ "refs/heads/branch");
List<ReceiveCommand> cmds = Arrays.asList(
new ReceiveCommand(A, B, "refs/heads/master", UPDATE),
@@ -796,22 +774,16 @@ public void overrideRefLogMessage() throws Exception {
new ReceiveCommand(zeroId(), B, "refs/heads/branch", CREATE));
cmds.get(0).setRefLogMessage("custom log", false);
PersonIdent ident = new PersonIdent(diskRepo);
- execute(
- newBatchUpdate(cmds)
- .setRefLogIdent(ident)
- .setRefLogMessage("a reflog", true));
+ execute(newBatchUpdate(cmds).setRefLogIdent(ident)
+ .setRefLogMessage("a reflog", true));
assertResults(cmds, OK, OK);
- assertEquals(atomic ? initialRefsChangedEvents + 1
+ assertEquals(batchesRefUpdates() ? initialRefsChangedEvents + 1
: initialRefsChangedEvents + 2, refsChangedEvents);
- assertReflogEquals(
- reflog(A, B, ident, "custom log"),
- getLastReflog("refs/heads/master"),
- true);
- assertReflogEquals(
- reflog(zeroId(), B, ident, "a reflog: created"),
- getLastReflog("refs/heads/branch"),
- true);
+ assertReflogEquals(reflog(A, B, ident, "custom log"),
+ getLastReflog("refs/heads/master"), true);
+ assertReflogEquals(reflog(zeroId(), B, ident, "a reflog: created"),
+ getLastReflog("refs/heads/branch"), true);
}
@Test
@@ -819,8 +791,8 @@ public void overrideDisableRefLog() throws Exception {
writeRef("refs/heads/master", A);
int initialRefsChangedEvents = refsChangedEvents;
- Map<String, ReflogEntry> oldLogs =
- getLastReflogs("refs/heads/master", "refs/heads/branch");
+ Map<String, ReflogEntry> oldLogs = getLastReflogs("refs/heads/master",
+ "refs/heads/branch");
List<ReceiveCommand> cmds = Arrays.asList(
new ReceiveCommand(A, B, "refs/heads/master", UPDATE),
@@ -829,21 +801,24 @@ public void overrideDisableRefLog() throws Exception {
execute(newBatchUpdate(cmds).setRefLogMessage("a reflog", true));
assertResults(cmds, OK, OK);
- assertEquals(atomic ? initialRefsChangedEvents + 1
+ assertEquals(batchesRefUpdates() ? initialRefsChangedEvents + 1
: initialRefsChangedEvents + 2, refsChangedEvents);
assertReflogUnchanged(oldLogs, "refs/heads/master");
assertReflogEquals(
- reflog(zeroId(), B, new PersonIdent(diskRepo), "a reflog: created"),
+ reflog(zeroId(), B, new PersonIdent(diskRepo),
+ "a reflog: created"),
getLastReflog("refs/heads/branch"));
}
@Test
public void refLogNotWrittenWithoutConfigOption() throws Exception {
+ assumeFalse(useReftable);
+
setLogAllRefUpdates(false);
writeRef("refs/heads/master", A);
- Map<String, ReflogEntry> oldLogs =
- getLastReflogs("refs/heads/master", "refs/heads/branch");
+ Map<String, ReflogEntry> oldLogs = getLastReflogs("refs/heads/master",
+ "refs/heads/branch");
assertTrue(oldLogs.isEmpty());
List<ReceiveCommand> cmds = Arrays.asList(
@@ -858,22 +833,21 @@ public void refLogNotWrittenWithoutConfigOption() throws Exception {
@Test
public void forceRefLogInUpdate() throws Exception {
+ assumeFalse(useReftable);
+
setLogAllRefUpdates(false);
writeRef("refs/heads/master", A);
- assertTrue(
- getLastReflogs("refs/heads/master", "refs/heads/branch").isEmpty());
+ assertTrue(getLastReflogs("refs/heads/master", "refs/heads/branch")
+ .isEmpty());
List<ReceiveCommand> cmds = Arrays.asList(
new ReceiveCommand(A, B, "refs/heads/master", UPDATE),
new ReceiveCommand(zeroId(), B, "refs/heads/branch", CREATE));
- execute(
- newBatchUpdate(cmds)
- .setRefLogMessage("a reflog", false)
- .setForceRefLog(true));
+ execute(newBatchUpdate(cmds).setRefLogMessage("a reflog", false)
+ .setForceRefLog(true));
assertResults(cmds, OK, OK);
- assertReflogEquals(
- reflog(A, B, new PersonIdent(diskRepo), "a reflog"),
+ assertReflogEquals(reflog(A, B, new PersonIdent(diskRepo), "a reflog"),
getLastReflog("refs/heads/master"));
assertReflogEquals(
reflog(zeroId(), B, new PersonIdent(diskRepo), "a reflog"),
@@ -882,11 +856,13 @@ public void forceRefLogInUpdate() throws Exception {
@Test
public void forceRefLogInCommand() throws Exception {
+ assumeFalse(useReftable);
+
setLogAllRefUpdates(false);
writeRef("refs/heads/master", A);
- Map<String, ReflogEntry> oldLogs =
- getLastReflogs("refs/heads/master", "refs/heads/branch");
+ Map<String, ReflogEntry> oldLogs = getLastReflogs("refs/heads/master",
+ "refs/heads/branch");
assertTrue(oldLogs.isEmpty());
List<ReceiveCommand> cmds = Arrays.asList(
@@ -904,6 +880,8 @@ public void forceRefLogInCommand() throws Exception {
@Test
public void packedRefsLockFailure() throws Exception {
+ assumeFalse(useReftable);
+
writeLooseRef("refs/heads/master", A);
List<ReceiveCommand> cmds = Arrays.asList(
@@ -921,11 +899,10 @@ public void packedRefsLockFailure() throws Exception {
assertResults(cmds, LOCK_FAILURE, TRANSACTION_ABORTED);
assertRefs("refs/heads/master", A);
} else {
- // Only operates on loose refs, doesn't care that packed-refs is locked.
+ // Only operates on loose refs, doesn't care that packed-refs is
+ // locked.
assertResults(cmds, OK, OK);
- assertRefs(
- "refs/heads/master", B,
- "refs/heads/branch", B);
+ assertRefs("refs/heads/master", B, "refs/heads/branch", B);
}
} finally {
myLock.unlock();
@@ -934,8 +911,9 @@ public void packedRefsLockFailure() throws Exception {
@Test
public void packedRefsLockFailureRefsChangedEvents() throws Exception {
+ assumeFalse(useReftable);
+
writeLooseRef("refs/heads/master", A);
- refdir.exactRef("refs/heads/master");
int initialRefsChangedEvents = refsChangedEvents;
List<ReceiveCommand> cmds = Arrays.asList(
@@ -946,10 +924,8 @@ public void packedRefsLockFailureRefsChangedEvents() throws Exception {
try {
execute(newBatchUpdate(cmds).setAllowNonFastForwards(true));
- assertEquals(
- atomic ? initialRefsChangedEvents
- : initialRefsChangedEvents + 2,
- refsChangedEvents);
+ assertEquals(atomic ? initialRefsChangedEvents
+ : initialRefsChangedEvents + 2, refsChangedEvents);
} finally {
myLock.unlock();
}
@@ -957,6 +933,8 @@ public void packedRefsLockFailureRefsChangedEvents() throws Exception {
@Test
public void oneRefLockFailure() throws Exception {
+ assumeFalse(useReftable);
+
writeLooseRef("refs/heads/master", A);
List<ReceiveCommand> cmds = Arrays.asList(
@@ -976,9 +954,7 @@ public void oneRefLockFailure() throws Exception {
assertRefs("refs/heads/master", A);
} else {
assertResults(cmds, OK, LOCK_FAILURE);
- assertRefs(
- "refs/heads/branch", B,
- "refs/heads/master", A);
+ assertRefs("refs/heads/branch", B, "refs/heads/master", A);
}
} finally {
myLock.unlock();
@@ -987,8 +963,9 @@ public void oneRefLockFailure() throws Exception {
@Test
public void oneRefLockFailureRefsChangedEvents() throws Exception {
+ assumeFalse(useReftable);
+
writeLooseRef("refs/heads/master", A);
- refdir.exactRef("refs/heads/master");
int initialRefsChangedEvents = refsChangedEvents;
List<ReceiveCommand> cmds = Arrays.asList(
@@ -1000,10 +977,8 @@ public void oneRefLockFailureRefsChangedEvents() throws Exception {
try {
execute(newBatchUpdate(cmds).setAllowNonFastForwards(true));
- assertEquals(
- atomic ? initialRefsChangedEvents
- : initialRefsChangedEvents + 1,
- refsChangedEvents);
+ assertEquals(atomic ? initialRefsChangedEvents
+ : initialRefsChangedEvents + 1, refsChangedEvents);
} finally {
myLock.unlock();
}
@@ -1011,10 +986,12 @@ public void oneRefLockFailureRefsChangedEvents() throws Exception {
@Test
public void singleRefUpdateDoesNotRequirePackedRefsLock() throws Exception {
+ assumeFalse(useReftable);
+
writeLooseRef("refs/heads/master", A);
- List<ReceiveCommand> cmds = Arrays.asList(
- new ReceiveCommand(A, B, "refs/heads/master", UPDATE));
+ List<ReceiveCommand> cmds = Arrays
+ .asList(new ReceiveCommand(A, B, "refs/heads/master", UPDATE));
LockFile myLock = refdir.lockPackedRefs();
try {
@@ -1031,8 +1008,9 @@ public void singleRefUpdateDoesNotRequirePackedRefsLock() throws Exception {
@Test
public void singleRefUpdateDoesNotRequirePackedRefsLockRefsChangedEvents()
throws Exception {
+ assumeFalse(useReftable);
+
writeLooseRef("refs/heads/master", A);
- refdir.exactRef("refs/heads/master");
int initialRefsChangedEvents = refsChangedEvents;
List<ReceiveCommand> cmds = Arrays
@@ -1051,6 +1029,7 @@ public void singleRefUpdateDoesNotRequirePackedRefsLockRefsChangedEvents()
@Test
public void atomicUpdateRespectsInProcessLock() throws Exception {
assumeTrue(atomic);
+ assumeFalse(useReftable);
writeLooseRef("refs/heads/master", A);
@@ -1073,7 +1052,8 @@ public void atomicUpdateRespectsInProcessLock() throws Exception {
long timeoutSecs = 10;
long startNanos = System.nanoTime();
- // Hold onto the lock until we observe the worker thread has attempted to
+ // Hold onto the lock until we observe the worker thread has
+ // attempted to
// acquire it.
while (l.getQueueLength() == 0) {
long elapsedNanos = System.nanoTime() - startNanos;
@@ -1083,7 +1063,8 @@ public void atomicUpdateRespectsInProcessLock() throws Exception {
Thread.sleep(3);
}
- // Once we unlock, the worker thread should finish the update promptly.
+ // Once we unlock, the worker thread should finish the update
+ // promptly.
l.unlock();
t.join(SECONDS.toMillis(timeoutSecs));
assertFalse(t.isAlive());
@@ -1094,19 +1075,16 @@ public void atomicUpdateRespectsInProcessLock() throws Exception {
}
assertResults(cmds, OK, OK);
- assertEquals(2, refsChangedEvents);
- assertRefs(
- "refs/heads/master", B,
- "refs/heads/branch", B);
+ assertRefs("refs/heads/master", B, "refs/heads/branch", B);
}
@Test
public void atomicUpdateRespectsInProcessLockRefsChangedEvents()
throws Exception {
assumeTrue(atomic);
+ assumeFalse(useReftable);
writeLooseRef("refs/heads/master", A);
- refdir.exactRef("refs/heads/master");
int initialRefsChangedEvents = refsChangedEvents;
List<ReceiveCommand> cmds = Arrays.asList(
@@ -1156,7 +1134,43 @@ private void setLogAllRefUpdates(boolean enable) throws Exception {
}
private void writeLooseRef(String name, AnyObjectId id) throws IOException {
- write(new File(diskRepo.getDirectory(), name), id.name() + "\n");
+ if (useReftable) {
+ writeRef(name, id);
+ } else {
+ write(new File(diskRepo.getDirectory(), name), id.name() + "\n");
+ // force the refs-changed event to be fired for the loose ref that
+ // was created. We do this to get the events fired during the test
+ // 'setup' out of the way and this allows us to now accurately
+ // assert only for the new events fired during the BatchRefUpdate.
+ refdir.exactRef(name);
+ }
+ }
+
+ private void writeLooseRefs(String name1, AnyObjectId id1, String name2,
+ AnyObjectId id2) throws IOException {
+ if (useReftable) {
+ BatchRefUpdate bru = diskRepo.getRefDatabase().newBatchUpdate();
+
+ Ref r1 = diskRepo.exactRef(name1);
+ ReceiveCommand c1 = new ReceiveCommand(
+ r1 != null ? r1.getObjectId() : ObjectId.zeroId(),
+ id1.toObjectId(), name1, r1 == null ? CREATE : UPDATE);
+
+ Ref r2 = diskRepo.exactRef(name2);
+ ReceiveCommand c2 = new ReceiveCommand(
+ r2 != null ? r2.getObjectId() : ObjectId.zeroId(),
+ id2.toObjectId(), name2, r2 == null ? CREATE : UPDATE);
+
+ bru.addCommand(c1, c2);
+ try (RevWalk rw = new RevWalk(diskRepo)) {
+ bru.execute(rw, NullProgressMonitor.INSTANCE);
+ }
+ assertEquals(c2.getResult(), ReceiveCommand.Result.OK);
+ assertEquals(c1.getResult(), ReceiveCommand.Result.OK);
+ } else {
+ writeLooseRef(name1, id1);
+ writeLooseRef(name2, id2);
+ }
}
private void writeRef(String name, AnyObjectId id) throws IOException {
@@ -1166,16 +1180,16 @@ private void writeRef(String name, AnyObjectId id) throws IOException {
u.setNewObjectId(id);
RefUpdate.Result r = u.update();
switch (r) {
- case NEW:
- case FORCED:
- return;
- default:
- throw new IOException("Got " + r + " while updating " + name);
+ case NEW:
+ case FORCED:
+ return;
+ default:
+ throw new IOException("Got " + r + " while updating " + name);
}
}
private BatchRefUpdate newBatchUpdate(List<ReceiveCommand> cmds) {
- BatchRefUpdate u = refdir.newBatchUpdate();
+ BatchRefUpdate u = diskRepo.getRefDatabase().newBatchUpdate();
if (atomic) {
assertTrue(u.isAtomic());
} else {
@@ -1189,10 +1203,11 @@ private void execute(BatchRefUpdate u) throws IOException {
execute(u, false);
}
- private void execute(BatchRefUpdate u, boolean strictWork) throws IOException {
+ private void execute(BatchRefUpdate u, boolean strictWork)
+ throws IOException {
try (RevWalk rw = new RevWalk(diskRepo)) {
- u.execute(rw,
- strictWork ? new StrictWorkMonitor() : NullProgressMonitor.INSTANCE);
+ u.execute(rw, strictWork ? new StrictWorkMonitor()
+ : NullProgressMonitor.INSTANCE);
}
}
@@ -1207,15 +1222,18 @@ private void assertRefs(Object... args) throws IOException {
expected.put((String) args[i], (AnyObjectId) args[i + 1]);
}
- Map<String, Ref> refs = refdir.getRefs(RefDatabase.ALL);
+ Map<String, Ref> refs = diskRepo.getRefDatabase()
+ .getRefs(RefDatabase.ALL);
Ref actualHead = refs.remove(Constants.HEAD);
if (actualHead != null) {
String actualLeafName = actualHead.getLeaf().getName();
assertEquals(
- "expected HEAD to point to refs/heads/master, got: " + actualLeafName,
+ "expected HEAD to point to refs/heads/master, got: "
+ + actualLeafName,
"refs/heads/master", actualLeafName);
AnyObjectId expectedMaster = expected.get("refs/heads/master");
- assertNotNull("expected master ref since HEAD exists", expectedMaster);
+ assertNotNull("expected master ref since HEAD exists",
+ expectedMaster);
assertEquals(expectedMaster, actualHead.getObjectId());
}
@@ -1245,8 +1263,7 @@ private Result(ReceiveCommand.Result result) {
}
}
- private void assertResults(
- List<ReceiveCommand> cmds, Result... expected) {
+ private void assertResults(List<ReceiveCommand> cmds, Result... expected) {
if (expected.length != cmds.size()) {
throw new IllegalArgumentException(
"expected " + cmds.size() + " result args");
@@ -1254,12 +1271,10 @@ private void assertResults(
for (int i = 0; i < cmds.size(); i++) {
ReceiveCommand c = cmds.get(i);
Result r = expected[i];
- assertTrue(
- String.format(
- "result of command (%d) should be %s: %s %s%s",
- Integer.valueOf(i), r, c,
- c.getResult(),
- c.getMessage() != null ? " (" + c.getMessage() + ")" : ""),
+ assertTrue(String.format(
+ "result of command (%d) should be %s, got %s %s%s",
+ Integer.valueOf(i), r, c, c.getResult(),
+ c.getMessage() != null ? " (" + c.getMessage() + ")" : ""),
r.p.test(c));
}
}
@@ -1288,18 +1303,18 @@ private File getLockFile(String refName) {
return LockFile.getLockFile(refdir.fileFor(refName));
}
- private void assertReflogUnchanged(
- Map<String, ReflogEntry> old, String name) throws IOException {
+ private void assertReflogUnchanged(Map<String, ReflogEntry> old,
+ String name) throws IOException {
assertReflogEquals(old.get(name), getLastReflog(name), true);
}
- private static void assertReflogEquals(
- ReflogEntry expected, ReflogEntry actual) {
+ private static void assertReflogEquals(ReflogEntry expected,
+ ReflogEntry actual) {
assertReflogEquals(expected, actual, false);
}
- private static void assertReflogEquals(
- ReflogEntry expected, ReflogEntry actual, boolean strictTime) {
+ private static void assertReflogEquals(ReflogEntry expected,
+ ReflogEntry actual, boolean strictTime) {
if (expected == null) {
assertNull(actual);
return;
@@ -1310,9 +1325,9 @@ private static void assertReflogEquals(
if (strictTime) {
assertEquals(expected.getWho(), actual.getWho());
} else {
- assertEquals(expected.getWho().getName(), actual.getWho().getName());
- assertEquals(
- expected.getWho().getEmailAddress(),
+ assertEquals(expected.getWho().getName(),
+ actual.getWho().getName());
+ assertEquals(expected.getWho().getEmailAddress(),
actual.getWho().getEmailAddress());
}
assertEquals(expected.getComment(), actual.getComment());
@@ -1347,4 +1362,8 @@ public CheckoutEntry parseCheckout() {
}
};
}
+
+ private boolean batchesRefUpdates() {
+ return atomic || useReftable;
+ }
}
diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/file/FileReftableStackTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/file/FileReftableStackTest.java
new file mode 100644
index 0000000..a2710e1
--- /dev/null
+++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/file/FileReftableStackTest.java
@@ -0,0 +1,203 @@
+/*
+ * 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.internal.storage.file;
+
+import static org.eclipse.jgit.lib.Ref.Storage.PACKED;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.List;
+import java.util.stream.Collectors;
+import org.eclipse.jgit.internal.storage.file.FileReftableStack.Segment;
+import org.eclipse.jgit.internal.storage.reftable.MergedReftable;
+import org.eclipse.jgit.internal.storage.reftable.RefCursor;
+import org.eclipse.jgit.lib.Config;
+import org.eclipse.jgit.lib.ObjectId;
+import org.eclipse.jgit.lib.ObjectIdRef;
+import org.eclipse.jgit.lib.Ref;
+import org.eclipse.jgit.util.FileUtils;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.rules.ExpectedException;
+
+public class FileReftableStackTest {
+
+ private static Ref newRef(String name, ObjectId id) {
+ return new ObjectIdRef.PeeledNonTag(PACKED, name, id);
+ }
+
+ private File reftableDir;
+
+ @Before
+ public void setup() throws Exception {
+ reftableDir = FileUtils.createTempDir("rtstack", "", null);
+ }
+
+ @After
+ public void tearDown() throws Exception {
+ if (reftableDir != null) {
+ FileUtils.delete(reftableDir, FileUtils.RECURSIVE);
+ }
+ }
+
+ void writeBranches(FileReftableStack stack, String template, int start,
+ int N) throws IOException {
+ for (int i = 0; i < N; i++) {
+ while (true) {
+ final long next = stack.getMergedReftable().maxUpdateIndex()
+ + 1;
+
+ String name = String.format(template,
+ Integer.valueOf(start + i));
+ Ref r = newRef(name, ObjectId.zeroId());
+ boolean ok = stack.addReftable(rw -> {
+ rw.setMinUpdateIndex(next).setMaxUpdateIndex(next).begin()
+ .writeRef(r);
+ });
+ if (ok) {
+ break;
+ }
+ }
+ }
+ }
+
+ public void testCompaction(int N) throws Exception {
+ try (FileReftableStack stack = new FileReftableStack(
+ new File(reftableDir, "refs"), reftableDir, null,
+ () -> new Config())) {
+ writeBranches(stack, "refs/heads/branch%d", 0, N);
+ MergedReftable table = stack.getMergedReftable();
+ for (int i = 1; i < N; i++) {
+ String name = String.format("refs/heads/branch%d",
+ Integer.valueOf(i));
+ RefCursor c = table.seekRef(name);
+ assertTrue(c.next());
+ assertEquals(ObjectId.zeroId(), c.getRef().getObjectId());
+ }
+
+ List<String> files = Arrays.asList(reftableDir.listFiles()).stream()
+ .map(File::getName).collect(Collectors.toList());
+ Collections.sort(files);
+
+ assertTrue(files.size() < 20);
+
+ FileReftableStack.CompactionStats stats = stack.getStats();
+ assertEquals(0, stats.failed);
+ assertTrue(stats.attempted < N);
+ assertTrue(stats.refCount < FileReftableStack.log(N) * N);
+ }
+ }
+
+ @Test
+ public void testCompaction9() throws Exception {
+ testCompaction(9);
+ }
+
+ @Test
+ public void testCompaction1024() throws Exception {
+ testCompaction(1024);
+ }
+
+ @Rule
+ public final ExpectedException thrown = ExpectedException.none();
+
+ @SuppressWarnings({ "resource", "unused" })
+ @Test
+ public void missingReftable() throws Exception {
+ try (FileReftableStack stack = new FileReftableStack(
+ new File(reftableDir, "refs"), reftableDir, null,
+ () -> new Config())) {
+ outer: for (int i = 0; i < 10; i++) {
+ final long next = stack.getMergedReftable().maxUpdateIndex()
+ + 1;
+ String name = String.format("branch%d", Integer.valueOf(i));
+ Ref r = newRef(name, ObjectId.zeroId());
+ boolean ok = stack.addReftable(rw -> {
+ rw.setMinUpdateIndex(next).setMaxUpdateIndex(next).begin()
+ .writeRef(r);
+ });
+ assertTrue(ok);
+
+ List<File> files = Arrays.asList(reftableDir.listFiles());
+ for (int j = 0; j < files.size(); j++) {
+ File f = files.get(j);
+ if (f.getName().endsWith(".ref")) {
+ assertTrue(f.delete());
+ break outer;
+ }
+ }
+ }
+ }
+ thrown.expect(FileNotFoundException.class);
+ new FileReftableStack(new File(reftableDir, "refs"), reftableDir, null,
+ () -> new Config());
+ }
+
+ @Test
+ public void testSegments() {
+ long in[] = { 1024, 1024, 1536, 100, 64, 50, 25, 24 };
+ List<Segment> got = FileReftableStack.segmentSizes(in);
+ Segment want[] = { new Segment(0, 3, 10, 3584),
+ new Segment(3, 5, 6, 164), new Segment(5, 6, 5, 50),
+ new Segment(6, 8, 4, 49), };
+ assertEquals(got.size(), want.length);
+ for (int i = 0; i < want.length; i++) {
+ assertTrue(want[i].equals(got.get(i)));
+ }
+ }
+
+ @Test
+ public void testLog2() throws Exception {
+ assertEquals(10, FileReftableStack.log(1024));
+ assertEquals(10, FileReftableStack.log(1025));
+ assertEquals(10, FileReftableStack.log(2047));
+ }
+}
diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/file/FileReftableTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/file/FileReftableTest.java
new file mode 100644
index 0000000..4907073
--- /dev/null
+++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/file/FileReftableTest.java
@@ -0,0 +1,635 @@
+/*
+ * Copyright (C) 2019, Google Inc.
+ * 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.storage.file;
+
+import static org.eclipse.jgit.lib.RefUpdate.Result.FAST_FORWARD;
+import static org.eclipse.jgit.lib.RefUpdate.Result.FORCED;
+import static org.eclipse.jgit.lib.RefUpdate.Result.IO_FAILURE;
+import static org.eclipse.jgit.lib.RefUpdate.Result.LOCK_FAILURE;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNotSame;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertSame;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.OutputStream;
+import java.security.SecureRandom;
+import java.util.ArrayList;
+import java.util.List;
+
+import org.eclipse.jgit.lib.AnyObjectId;
+import org.eclipse.jgit.lib.Constants;
+import org.eclipse.jgit.lib.NullProgressMonitor;
+import org.eclipse.jgit.lib.ObjectId;
+import org.eclipse.jgit.lib.PersonIdent;
+import org.eclipse.jgit.lib.Ref;
+import org.eclipse.jgit.lib.RefRename;
+import org.eclipse.jgit.lib.RefUpdate;
+import org.eclipse.jgit.lib.RefUpdate.Result;
+import org.eclipse.jgit.lib.ReflogEntry;
+import org.eclipse.jgit.lib.ReflogReader;
+import org.eclipse.jgit.lib.RepositoryCache;
+import org.eclipse.jgit.revwalk.RevWalk;
+import org.eclipse.jgit.test.resources.SampleDataRepositoryTestCase;
+import org.eclipse.jgit.transport.ReceiveCommand;
+import org.junit.Test;
+
+public class FileReftableTest extends SampleDataRepositoryTestCase {
+ String bCommit;
+
+ @Override
+ public void setUp() throws Exception {
+ super.setUp();
+ Ref b = db.exactRef("refs/heads/b");
+ bCommit = b.getObjectId().getName();
+ db.convertToReftable(false, false);
+ }
+
+ @SuppressWarnings("boxing")
+ @Test
+ public void testRacyReload() throws Exception {
+ ObjectId id = db.resolve("master");
+ int retry = 0;
+ try (FileRepository repo1 = new FileRepository(db.getDirectory());
+ FileRepository repo2 = new FileRepository(db.getDirectory())) {
+ FileRepository repos[] = { repo1, repo2 };
+ for (int i = 0; i < 10; i++) {
+ for (int j = 0; j < 2; j++) {
+ FileRepository repo = repos[j];
+ RefUpdate u = repo.getRefDatabase().newUpdate(
+ String.format("branch%d", i * 10 + j), false);
+
+ u.setNewObjectId(id);
+ RefUpdate.Result r = u.update();
+ if (!r.equals(Result.NEW)) {
+ retry++;
+ u = repo.getRefDatabase().newUpdate(
+ String.format("branch%d", i * 10 + j), false);
+
+ u.setNewObjectId(id);
+ r = u.update();
+ assertEquals(r, Result.NEW);
+ }
+ }
+ }
+
+ // only the first one succeeds
+ assertEquals(retry, 19);
+ }
+ }
+
+ @Test
+ public void testCompactFully() throws Exception {
+ ObjectId c1 = db.resolve("master^^");
+ ObjectId c2 = db.resolve("master^");
+ for (int i = 0; i < 5; i++) {
+ RefUpdate u = db.updateRef("refs/heads/master");
+ u.setForceUpdate(true);
+ u.setNewObjectId((i%2) == 0 ? c1 : c2);
+ assertEquals(u.update(), FORCED);
+ }
+
+ File tableDir = new File(db.getDirectory(), Constants.REFTABLE);
+ assertTrue(tableDir.listFiles().length > 2);
+ ((FileReftableDatabase)db.getRefDatabase()).compactFully();
+ assertEquals(tableDir.listFiles().length,2);
+ }
+
+ @Test
+ public void testOpenConvert() throws Exception {
+ try (FileRepository repo = new FileRepository(db.getDirectory())) {
+ assertTrue(repo.getRefDatabase() instanceof FileReftableDatabase);
+ }
+ }
+
+ @Test
+ public void testConvert() throws Exception {
+ Ref h = db.exactRef("HEAD");
+ assertTrue(h.isSymbolic());
+ assertEquals("refs/heads/master", h.getTarget().getName());
+
+ Ref b = db.exactRef("refs/heads/b");
+ assertFalse(b.isSymbolic());
+ assertTrue(b.isPeeled());
+ assertEquals(bCommit, b.getObjectId().name());
+
+ assertTrue(db.getRefDatabase().hasFastTipsWithSha1());
+ }
+
+
+ @Test
+ public void testConvertBrokenObjectId() throws Exception {
+ db.convertToPackedRefs(false, false);
+ new File(db.getDirectory(), "refs/heads").mkdirs();
+
+ String invalidId = "deadbeefdeadbeefdeadbeefdeadbeefdeadbeef";
+ File headFile = new File(db.getDirectory(), "refs/heads/broken");
+ try (OutputStream os = new FileOutputStream(headFile)) {
+ os.write(Constants.encodeASCII(invalidId + "\n"));
+ }
+
+ Ref r = db.exactRef("refs/heads/broken");
+ assertNotNull(r);
+ db.convertToReftable(true, false);
+ }
+
+ @Test
+ public void testConvertToRefdirReflog() throws Exception {
+ Ref a = db.exactRef("refs/heads/a");
+ String aCommit = a.getObjectId().getName();
+ RefUpdate u = db.updateRef("refs/heads/master");
+ u.setForceUpdate(true);
+ u.setNewObjectId(ObjectId.fromString(aCommit));
+ u.setForceRefLog(true);
+ u.setRefLogMessage("apple", false);
+ u.update();
+
+ RefUpdate v = db.updateRef("refs/heads/master");
+ v.setForceUpdate(true);
+ v.setNewObjectId(ObjectId.fromString(bCommit));
+ v.setForceRefLog(true);
+ v.setRefLogMessage("banana", false);
+ v.update();
+
+ db.convertToPackedRefs(true, false);
+ List<ReflogEntry> logs = db.getReflogReader("refs/heads/master").getReverseEntries(2);
+ assertEquals(logs.get(0).getComment(), "banana");
+ assertEquals(logs.get(1).getComment(), "apple");
+ }
+
+ @Test
+ public void testBatchrefUpdate() throws Exception {
+ ObjectId cur = db.resolve("master");
+ ObjectId prev = db.resolve("master^");
+
+ PersonIdent person = new PersonIdent("name", "mail@example.com");
+ ReceiveCommand rc1 = new ReceiveCommand(ObjectId.zeroId(), cur, "refs/heads/batch1");
+ ReceiveCommand rc2 = new ReceiveCommand(ObjectId.zeroId(), prev, "refs/heads/batch2");
+ String msg = "message";
+ try (RevWalk rw = new RevWalk(db)) {
+ db.getRefDatabase().newBatchUpdate()
+ .addCommand(rc1, rc2)
+ .setAtomic(true)
+ .setRefLogIdent(person)
+ .setRefLogMessage(msg, false)
+ .execute(rw, NullProgressMonitor.INSTANCE);
+ }
+
+ assertEquals(rc1.getResult(), ReceiveCommand.Result.OK);
+ assertEquals(rc2.getResult(), ReceiveCommand.Result.OK);
+
+ ReflogEntry e = db.getReflogReader("refs/heads/batch1").getLastEntry();
+ assertEquals(msg, e.getComment());
+ assertEquals(person, e.getWho());
+ assertEquals(cur, e.getNewId());
+
+ e = db.getReflogReader("refs/heads/batch2").getLastEntry();
+ assertEquals(msg, e.getComment());
+ assertEquals(person, e.getWho());
+ assertEquals(prev, e.getNewId());
+
+ assertEquals(cur, db.exactRef("refs/heads/batch1").getObjectId());
+ assertEquals(prev, db.exactRef("refs/heads/batch2").getObjectId());
+ }
+
+ @Test
+ public void testFastforwardStatus() throws Exception {
+ ObjectId cur = db.resolve("master");
+ ObjectId prev = db.resolve("master^");
+ RefUpdate u = db.updateRef("refs/heads/master");
+
+ u.setNewObjectId(prev);
+ u.setForceUpdate(true);
+ assertEquals(FORCED, u.update());
+
+ RefUpdate u2 = db.updateRef("refs/heads/master");
+
+ u2.setNewObjectId(cur);
+ assertEquals(FAST_FORWARD, u2.update());
+ }
+
+ @Test
+ public void testUpdateChecksOldValue() throws Exception {
+ ObjectId cur = db.resolve("master");
+ ObjectId prev = db.resolve("master^");
+ RefUpdate u1 = db.updateRef("refs/heads/master");
+ RefUpdate u2 = db.updateRef("refs/heads/master");
+
+ u1.setExpectedOldObjectId(cur);
+ u1.setNewObjectId(prev);
+ u1.setForceUpdate(true);
+
+ u2.setExpectedOldObjectId(cur);
+ u2.setNewObjectId(prev);
+ u2.setForceUpdate(true);
+
+ assertEquals(FORCED, u1.update());
+ assertEquals(LOCK_FAILURE, u2.update());
+ }
+
+ @Test
+ public void testWritesymref() throws Exception {
+ writeSymref(Constants.HEAD, "refs/heads/a");
+ assertNotNull(db.exactRef("refs/heads/b"));
+ }
+
+ @Test
+ public void testFastforwardStatus2() throws Exception {
+ writeSymref(Constants.HEAD, "refs/heads/a");
+ ObjectId bId = db.exactRef("refs/heads/b").getObjectId();
+ RefUpdate u = db.updateRef("refs/heads/a");
+ u.setNewObjectId(bId);
+ u.setRefLogMessage("Setup", false);
+ assertEquals(FAST_FORWARD, u.update());
+ }
+
+ @Test
+ public void testDelete() throws Exception {
+ RefUpdate up = db.getRefDatabase().newUpdate("refs/heads/a", false);
+ up.setForceUpdate(true);
+ RefUpdate.Result res = up.delete();
+ assertEquals(res, FORCED);
+ assertNull(db.exactRef("refs/heads/a"));
+ }
+
+ @Test
+ public void testDeleteWithoutHead() throws IOException {
+ // Prepare repository without HEAD
+ RefUpdate refUpdate = db.updateRef(Constants.HEAD, true);
+ refUpdate.setForceUpdate(true);
+ refUpdate.setNewObjectId(ObjectId.zeroId());
+
+ RefUpdate.Result updateResult = refUpdate.update();
+ assertEquals(FORCED, updateResult);
+
+ Ref r = db.exactRef("HEAD");
+ assertEquals(ObjectId.zeroId(), r.getObjectId());
+ RefUpdate.Result deleteHeadResult = db.updateRef(Constants.HEAD)
+ .delete();
+
+ // why does doDelete say NEW ?
+ assertEquals(RefUpdate.Result.NO_CHANGE, deleteHeadResult);
+
+ // Any result is ok as long as it's not an NPE
+ db.updateRef(Constants.R_HEADS + "master").delete();
+ }
+
+ @Test
+ public void testUpdateRefDetached() throws Exception {
+ ObjectId pid = db.resolve("refs/heads/master");
+ ObjectId ppid = db.resolve("refs/heads/master^");
+ RefUpdate updateRef = db.updateRef("HEAD", true);
+ updateRef.setForceUpdate(true);
+ updateRef.setNewObjectId(ppid);
+ RefUpdate.Result update = updateRef.update();
+ assertEquals(FORCED, update);
+ assertEquals(ppid, db.resolve("HEAD"));
+ Ref ref = db.exactRef("HEAD");
+ assertEquals("HEAD", ref.getName());
+ assertTrue("is detached", !ref.isSymbolic());
+
+ // the branch HEAD referred to is left untouched
+ assertEquals(pid, db.resolve("refs/heads/master"));
+ ReflogReader reflogReader = db.getReflogReader("HEAD");
+ ReflogEntry e = reflogReader.getReverseEntries().get(0);
+ assertEquals(ppid, e.getNewId());
+ assertEquals("GIT_COMMITTER_EMAIL", e.getWho().getEmailAddress());
+ assertEquals("GIT_COMMITTER_NAME", e.getWho().getName());
+ assertEquals(1250379778000L, e.getWho().getWhen().getTime());
+ assertEquals(pid, e.getOldId());
+ }
+
+ @Test
+ public void testWriteReflog() throws Exception {
+ ObjectId pid = db.resolve("refs/heads/master^");
+ RefUpdate updateRef = db.updateRef("refs/heads/master");
+ updateRef.setNewObjectId(pid);
+ String msg = "REFLOG!";
+ updateRef.setRefLogMessage(msg, true);
+ PersonIdent person = new PersonIdent("name", "mail@example.com");
+ updateRef.setRefLogIdent(person);
+ updateRef.setForceUpdate(true);
+ RefUpdate.Result update = updateRef.update();
+ assertEquals(FORCED, update); // internal
+ ReflogReader r = db.getReflogReader("refs/heads/master");
+
+ ReflogEntry e = r.getLastEntry();
+ assertEquals(e.getNewId(), pid);
+ assertEquals(e.getComment(), "REFLOG!: FORCED");
+ assertEquals(e.getWho(), person);
+ }
+
+ @Test
+ public void testLooseDelete() throws IOException {
+ final String newRef = "refs/heads/abc";
+ assertNull(db.exactRef(newRef));
+
+ RefUpdate ref = db.updateRef(newRef);
+ ObjectId nonZero = db.resolve(Constants.HEAD);
+ assertNotEquals(nonZero, ObjectId.zeroId());
+ ref.setNewObjectId(nonZero);
+ assertEquals(RefUpdate.Result.NEW, ref.update());
+
+ ref = db.updateRef(newRef);
+ ref.setNewObjectId(db.resolve(Constants.HEAD));
+
+ assertEquals(ref.delete(), RefUpdate.Result.NO_CHANGE);
+
+ // Differs from RefupdateTest. Deleting a loose ref leaves reflog trail.
+ ReflogReader reader = db.getReflogReader("refs/heads/abc");
+ assertEquals(ObjectId.zeroId(), reader.getReverseEntry(1).getOldId());
+ assertEquals(nonZero, reader.getReverseEntry(1).getNewId());
+ assertEquals(nonZero, reader.getReverseEntry(0).getOldId());
+ assertEquals(ObjectId.zeroId(), reader.getReverseEntry(0).getNewId());
+ }
+
+ private static class SubclassedId extends ObjectId {
+ SubclassedId(AnyObjectId src) {
+ super(src);
+ }
+ }
+
+ @Test
+ public void testNoCacheObjectIdSubclass() throws IOException {
+ final String newRef = "refs/heads/abc";
+ final RefUpdate ru = updateRef(newRef);
+ final SubclassedId newid = new SubclassedId(ru.getNewObjectId());
+ ru.setNewObjectId(newid);
+ RefUpdate.Result update = ru.update();
+ assertEquals(RefUpdate.Result.NEW, update);
+ Ref r = db.exactRef(newRef);
+ assertEquals(newRef, r.getName());
+ assertNotNull(r.getObjectId());
+ assertNotSame(newid, r.getObjectId());
+ assertSame(ObjectId.class, r.getObjectId().getClass());
+ assertEquals(newid, r.getObjectId());
+ List<ReflogEntry> reverseEntries1 = db.getReflogReader("refs/heads/abc")
+ .getReverseEntries();
+ ReflogEntry entry1 = reverseEntries1.get(0);
+ assertEquals(1, reverseEntries1.size());
+ assertEquals(ObjectId.zeroId(), entry1.getOldId());
+ assertEquals(r.getObjectId(), entry1.getNewId());
+
+ assertEquals(new PersonIdent(db).toString(),
+ entry1.getWho().toString());
+ assertEquals("", entry1.getComment());
+ List<ReflogEntry> reverseEntries2 = db.getReflogReader("HEAD")
+ .getReverseEntries();
+ assertEquals(0, reverseEntries2.size());
+ }
+
+ @Test
+ public void testDeleteSymref() throws IOException {
+ RefUpdate dst = updateRef("refs/heads/abc");
+ assertEquals(RefUpdate.Result.NEW, dst.update());
+ ObjectId id = dst.getNewObjectId();
+
+ RefUpdate u = db.updateRef("refs/symref");
+ assertEquals(RefUpdate.Result.NEW, u.link(dst.getName()));
+
+ Ref ref = db.exactRef(u.getName());
+ assertNotNull(ref);
+ assertTrue(ref.isSymbolic());
+ assertEquals(dst.getName(), ref.getLeaf().getName());
+ assertEquals(id, ref.getLeaf().getObjectId());
+
+ u = db.updateRef(u.getName());
+ u.setDetachingSymbolicRef();
+ u.setForceUpdate(true);
+ assertEquals(FORCED, u.delete());
+
+ assertNull(db.exactRef(u.getName()));
+ ref = db.exactRef(dst.getName());
+ assertNotNull(ref);
+ assertFalse(ref.isSymbolic());
+ assertEquals(id, ref.getObjectId());
+ }
+
+ @Test
+ public void writeUnbornHead() throws Exception {
+ RefUpdate.Result r = db.updateRef("HEAD").link("refs/heads/unborn");
+ assertEquals(FORCED, r);
+
+ Ref head = db.exactRef("HEAD");
+ assertTrue(head.isSymbolic());
+ assertEquals(head.getTarget().getName(), "refs/heads/unborn");
+ }
+
+ /**
+ * Update the HEAD ref when the referenced branch is unborn
+ *
+ * @throws Exception
+ */
+ @Test
+ public void testUpdateRefDetachedUnbornHead() throws Exception {
+ ObjectId ppid = db.resolve("refs/heads/master^");
+ writeSymref("HEAD", "refs/heads/unborn");
+ RefUpdate updateRef = db.updateRef("HEAD", true);
+ updateRef.setForceUpdate(true);
+ updateRef.setNewObjectId(ppid);
+ RefUpdate.Result update = updateRef.update();
+ assertEquals(RefUpdate.Result.NEW, update);
+ assertEquals(ppid, db.resolve("HEAD"));
+ Ref ref = db.exactRef("HEAD");
+ assertEquals("HEAD", ref.getName());
+ assertTrue("is detached", !ref.isSymbolic());
+
+ // the branch HEAD referred to is left untouched
+ assertNull(db.resolve("refs/heads/unborn"));
+ ReflogReader reflogReader = db.getReflogReader("HEAD");
+ ReflogEntry e = reflogReader.getReverseEntries().get(0);
+ assertEquals(ObjectId.zeroId(), e.getOldId());
+ assertEquals(ppid, e.getNewId());
+ assertEquals("GIT_COMMITTER_EMAIL", e.getWho().getEmailAddress());
+ assertEquals("GIT_COMMITTER_NAME", e.getWho().getName());
+ assertEquals(1250379778000L, e.getWho().getWhen().getTime());
+ }
+
+ @Test
+ public void testDeleteNotFound() throws IOException {
+ RefUpdate ref = updateRef("refs/heads/doesnotexist");
+ assertNull(db.exactRef(ref.getName()));
+ assertEquals(RefUpdate.Result.NEW, ref.delete());
+ assertNull(db.exactRef(ref.getName()));
+ }
+
+ @Test
+ public void testRenameSymref() throws IOException {
+ db.resolve("HEAD");
+ RefRename r = db.renameRef("HEAD", "KOPF");
+ assertEquals(IO_FAILURE, r.rename());
+ }
+
+ @Test
+ public void testRenameCurrentBranch() throws IOException {
+ ObjectId rb = db.resolve("refs/heads/b");
+ writeSymref(Constants.HEAD, "refs/heads/b");
+ ObjectId oldHead = db.resolve(Constants.HEAD);
+ assertEquals("internal test condition, b == HEAD", oldHead, rb);
+ RefRename renameRef = db.renameRef("refs/heads/b",
+ "refs/heads/new/name");
+ RefUpdate.Result result = renameRef.rename();
+ assertEquals(RefUpdate.Result.RENAMED, result);
+ assertEquals(rb, db.resolve("refs/heads/new/name"));
+ assertNull(db.resolve("refs/heads/b"));
+ assertEquals(rb, db.resolve(Constants.HEAD));
+
+ List<String> names = new ArrayList<>();
+ names.add("HEAD");
+ names.add("refs/heads/b");
+ names.add("refs/heads/new/name");
+
+ for (String nm : names) {
+ ReflogReader rd = db.getReflogReader(nm);
+ assertNotNull(rd);
+ ReflogEntry last = rd.getLastEntry();
+ ObjectId id = last.getNewId();
+ assertTrue(ObjectId.zeroId().equals(id) || rb.equals(id));
+
+ id = last.getNewId();
+ assertTrue(ObjectId.zeroId().equals(id) || rb.equals(id));
+
+ String want = "Branch: renamed b to new/name";
+ assertEquals(want, last.getComment());
+ }
+ }
+
+ @Test
+ public void isGitRepository() {
+ assertTrue(RepositoryCache.FileKey.isGitRepository(db.getDirectory(), db.getFS()));
+ }
+
+ @Test
+ public void testRenameDestExists() throws IOException {
+ ObjectId rb = db.resolve("refs/heads/b");
+ writeSymref(Constants.HEAD, "refs/heads/b");
+ ObjectId oldHead = db.resolve(Constants.HEAD);
+ assertEquals("internal test condition, b == HEAD", oldHead, rb);
+ RefRename renameRef = db.renameRef("refs/heads/b", "refs/heads/a");
+ RefUpdate.Result result = renameRef.rename();
+ assertEquals(RefUpdate.Result.LOCK_FAILURE, result);
+ }
+
+ @Test
+ public void testRenameAtomic() throws IOException {
+ ObjectId prevId = db.resolve("refs/heads/master^");
+
+ RefRename rename = db.renameRef("refs/heads/master",
+ "refs/heads/newmaster");
+
+ RefUpdate updateRef = db.updateRef("refs/heads/master");
+ updateRef.setNewObjectId(prevId);
+ updateRef.setForceUpdate(true);
+ assertEquals(FORCED, updateRef.update());
+ assertEquals(RefUpdate.Result.LOCK_FAILURE, rename.rename());
+ }
+
+ @Test
+ public void compactFully() throws Exception {
+ FileReftableDatabase refDb = (FileReftableDatabase) db.getRefDatabase();
+ PersonIdent person = new PersonIdent("jane", "jane@invalid");
+
+ ObjectId aId = db.exactRef("refs/heads/a").getObjectId();
+ ObjectId bId = db.exactRef("refs/heads/b").getObjectId();
+
+ SecureRandom random = new SecureRandom();
+ List<String> strs = new ArrayList<>();
+ for (int i = 0; i < 1024; i++) {
+ strs.add(String.format("%02x",
+ Integer.valueOf(random.nextInt(256))));
+ }
+
+ String randomStr = String.join("", strs);
+ String refName = "branch";
+ for (long i = 0; i < 2; i++) {
+ RefUpdate ru = refDb.newUpdate(refName, false);
+ ru.setNewObjectId(i % 2 == 0 ? aId : bId);
+ ru.setForceUpdate(true);
+ // Only write a large string in the first table, so it becomes much larger
+ // than the second, and the result is not autocompacted.
+ ru.setRefLogMessage(i == 0 ? randomStr : "short", false);
+ ru.setRefLogIdent(person);
+
+ RefUpdate.Result res = ru.update();
+ assertTrue(res == Result.NEW || res == FORCED);
+ }
+
+ assertEquals(refDb.exactRef(refName).getObjectId(), bId);
+ assertTrue(randomStr.equals(refDb.getReflogReader(refName).getReverseEntry(1).getComment()));
+ refDb.compactFully();
+ assertEquals(refDb.exactRef(refName).getObjectId(), bId);
+ assertTrue(randomStr.equals(refDb.getReflogReader(refName).getReverseEntry(1).getComment()));
+ }
+
+ @Test
+ public void reftableRefsStorageClass() throws IOException {
+ Ref b = db.exactRef("refs/heads/b");
+ assertEquals(Ref.Storage.PACKED, b.getStorage());
+ }
+
+ private RefUpdate updateRef(String name) throws IOException {
+ final RefUpdate ref = db.updateRef(name);
+ ref.setNewObjectId(db.resolve(Constants.HEAD));
+ return ref;
+ }
+
+ private void writeSymref(String src, String dst) throws IOException {
+ RefUpdate u = db.updateRef(src);
+ switch (u.link(dst)) {
+ case NEW:
+ case FORCED:
+ case NO_CHANGE:
+ break;
+ default:
+ fail("link " + src + " to " + dst);
+ }
+ }
+}
diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/file/GcOrphanFilesTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/file/GcOrphanFilesTest.java
index e54c4ad..bbbe3b9 100644
--- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/file/GcOrphanFilesTest.java
+++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/file/GcOrphanFilesTest.java
@@ -53,21 +53,21 @@
import org.junit.Test;
public class GcOrphanFilesTest extends GcTestCase {
- private final static String PACK = "pack";
+ private static final String PACK = "pack";
- private final static String BITMAP_File_1 = PACK + "-1.bitmap";
+ private static final String BITMAP_File_1 = PACK + "-1.bitmap";
private static final String BITMAP_File_2 = PACK + "-2.bitmap";
private static final String IDX_File_2 = PACK + "-2.idx";
- private final static String IDX_File_malformed = PACK + "-1234idx";
+ private static final String IDX_File_malformed = PACK + "-1234idx";
private static final String KEEP_File_2 = PACK + "-2.keep";
private static final String PACK_File_2 = PACK + "-2.pack";
- private final static String PACK_File_3 = PACK + "-3.pack";
+ private static final String PACK_File_3 = PACK + "-3.pack";
private File packDir;
diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/file/LockFileTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/file/LockFileTest.java
index 3bfd047..4e123f4 100644
--- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/file/LockFileTest.java
+++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/file/LockFileTest.java
@@ -1,51 +1,23 @@
/*
- * Copyright (C) 2012, GitHub Inc.
- * and other copyright owners as documented in the project's IP log.
+ * Copyright (C) 2012, 2021 GitHub Inc. and others
*
- * This program and the accompanying materials are made available
- * under the terms of the Eclipse Distribution License v1.0 which
- * accompanies this distribution, is reproduced below, and is
- * available at http://www.eclipse.org/org/documents/edl-v10.php
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Distribution License v. 1.0 which is available at
+ * https://www.eclipse.org/org/documents/edl-v10.php.
*
- * 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.
+ * SPDX-License-Identifier: BSD-3-Clause
*/
package org.eclipse.jgit.internal.storage.file;
+import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
+import java.io.File;
+import java.io.OutputStream;
+import java.nio.charset.StandardCharsets;
+
import org.eclipse.jgit.api.Git;
import org.eclipse.jgit.api.errors.JGitInternalException;
import org.eclipse.jgit.errors.LockFailedException;
@@ -82,4 +54,167 @@ public void lockFailedExceptionRecovery() throws Exception {
}
}
}
+
+ @Test
+ public void testLockTwice() throws Exception {
+ File f = writeTrashFile("somefile", "content");
+ LockFile lock = new LockFile(f);
+ assertTrue(lock.lock());
+ lock.write("other".getBytes(StandardCharsets.US_ASCII));
+ lock.commit();
+ assertFalse(lock.isLocked());
+ checkFile(f, "other");
+ assertTrue(lock.lock());
+ assertTrue(lock.isLocked());
+ try (OutputStream out = lock.getOutputStream()) {
+ out.write("second".getBytes(StandardCharsets.US_ASCII));
+ }
+ lock.commit();
+ assertFalse(lock.isLocked());
+ checkFile(f, "second");
+ }
+
+ @Test
+ public void testLockTwiceUnlock() throws Exception {
+ File f = writeTrashFile("somefile", "content");
+ LockFile lock = new LockFile(f);
+ assertTrue(lock.lock());
+ assertTrue(lock.isLocked());
+ lock.write("other".getBytes(StandardCharsets.US_ASCII));
+ lock.unlock();
+ assertFalse(lock.isLocked());
+ checkFile(f, "content");
+ assertTrue(lock.lock());
+ assertTrue(lock.isLocked());
+ try (OutputStream out = lock.getOutputStream()) {
+ out.write("second".getBytes(StandardCharsets.US_ASCII));
+ }
+ lock.commit();
+ assertFalse(lock.isLocked());
+ checkFile(f, "second");
+ }
+
+ @Test
+ public void testLockWriteTwiceThrows1() throws Exception {
+ File f = writeTrashFile("somefile", "content");
+ LockFile lock = new LockFile(f);
+ assertTrue(lock.lock());
+ assertTrue(lock.isLocked());
+ lock.write("other".getBytes(StandardCharsets.US_ASCII));
+ try {
+ lock.write("second".getBytes(StandardCharsets.US_ASCII));
+ fail();
+ } catch (Exception e) {
+ // expected
+ }
+ lock.unlock();
+ }
+
+ @Test
+ public void testLockWriteTwiceThrows2() throws Exception {
+ File f = writeTrashFile("somefile", "content");
+ LockFile lock = new LockFile(f);
+ assertTrue(lock.lock());
+ assertTrue(lock.isLocked());
+ try (OutputStream out = lock.getOutputStream()) {
+ out.write("other".getBytes(StandardCharsets.US_ASCII));
+ }
+ try {
+ lock.write("second".getBytes(StandardCharsets.US_ASCII));
+ fail();
+ } catch (Exception e) {
+ // expected
+ }
+ lock.unlock();
+ }
+
+ @Test
+ public void testLockWriteTwiceThrows3() throws Exception {
+ File f = writeTrashFile("somefile", "content");
+ LockFile lock = new LockFile(f);
+ assertTrue(lock.lock());
+ assertTrue(lock.isLocked());
+ lock.write("other".getBytes(StandardCharsets.US_ASCII));
+ try (OutputStream out = lock.getOutputStream()) {
+ out.write("second".getBytes(StandardCharsets.US_ASCII));
+ fail();
+ } catch (Exception e) {
+ // expected
+ }
+ lock.unlock();
+ }
+
+ @Test
+ public void testLockWriteTwiceThrows4() throws Exception {
+ File f = writeTrashFile("somefile", "content");
+ LockFile lock = new LockFile(f);
+ assertTrue(lock.lock());
+ assertTrue(lock.isLocked());
+ try (OutputStream out = lock.getOutputStream()) {
+ out.write("other".getBytes(StandardCharsets.US_ASCII));
+ }
+ try (OutputStream out = lock.getOutputStream()) {
+ out.write("second".getBytes(StandardCharsets.US_ASCII));
+ fail();
+ } catch (Exception e) {
+ // expected
+ }
+ lock.unlock();
+ }
+
+ @Test
+ public void testLockUnclosedCommitThrows() throws Exception {
+ File f = writeTrashFile("somefile", "content");
+ LockFile lock = new LockFile(f);
+ assertTrue(lock.lock());
+ assertTrue(lock.isLocked());
+ try (OutputStream out = lock.getOutputStream()) {
+ out.write("other".getBytes(StandardCharsets.US_ASCII));
+ lock.commit();
+ fail();
+ } catch (Exception e) {
+ // expected
+ }
+ }
+
+ @Test
+ public void testLockNested() throws Exception {
+ File f = writeTrashFile("somefile", "content");
+ LockFile lock = new LockFile(f);
+ assertTrue(lock.lock());
+ assertTrue(lock.isLocked());
+ try {
+ lock.lock();
+ fail();
+ } catch (IllegalStateException e) {
+ // expected
+ }
+ assertTrue(lock.isLocked());
+ lock.unlock();
+ }
+
+ @Test
+ public void testLockHeld() throws Exception {
+ File f = writeTrashFile("somefile", "content");
+ LockFile lock = new LockFile(f);
+ assertTrue(lock.lock());
+ assertTrue(lock.isLocked());
+ LockFile lock2 = new LockFile(f);
+ assertFalse(lock2.lock());
+ assertFalse(lock2.isLocked());
+ assertTrue(lock.isLocked());
+ lock.unlock();
+ }
+
+ @Test
+ public void testLockForAppend() throws Exception {
+ File f = writeTrashFile("somefile", "content");
+ LockFile lock = new LockFile(f);
+ assertTrue(lock.lockForAppend());
+ assertTrue(lock.isLocked());
+ lock.write("other".getBytes(StandardCharsets.US_ASCII));
+ lock.commit();
+ assertFalse(lock.isLocked());
+ checkFile(f, "contentother");
+ }
}
diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/file/PackFileSnapshotTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/file/PackFileSnapshotTest.java
index d5bc61a..9016a02 100644
--- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/file/PackFileSnapshotTest.java
+++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/file/PackFileSnapshotTest.java
@@ -295,9 +295,8 @@ private Path copyFile(Path src, Path dst) throws IOException {
Files.copy(src, dstOut);
return dst;
}
- } else {
- return Files.copy(src, dst, StandardCopyOption.REPLACE_EXISTING);
}
+ return Files.copy(src, dst, StandardCopyOption.REPLACE_EXISTING);
}
private Path copyPack(Path base, String srcSuffix, String dstSuffix)
diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/file/PackWriterTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/file/PackWriterTest.java
index 1e2341b..3f281c4 100644
--- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/file/PackWriterTest.java
+++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/file/PackWriterTest.java
@@ -468,22 +468,22 @@ public void testWritePack4SizeThinVsNoThin() throws Exception {
@Test
public void testDeltaStatistics() throws Exception {
config.setDeltaCompress(true);
+ // TestRepository will close repo
FileRepository repo = createBareRepository();
ArrayList<RevObject> blobs = new ArrayList<>();
try (TestRepository<FileRepository> testRepo = new TestRepository<>(
repo)) {
blobs.add(testRepo.blob(genDeltableData(1000)));
blobs.add(testRepo.blob(genDeltableData(1005)));
- }
-
- try (PackWriter pw = new PackWriter(repo)) {
- NullProgressMonitor m = NullProgressMonitor.INSTANCE;
- pw.preparePack(blobs.iterator());
- pw.writePack(m, m, os);
- PackStatistics stats = pw.getStatistics();
- assertEquals(1, stats.getTotalDeltas());
- assertTrue("Delta bytes not set.",
- stats.byObjectType(OBJ_BLOB).getDeltaBytes() > 0);
+ try (PackWriter pw = new PackWriter(repo)) {
+ NullProgressMonitor m = NullProgressMonitor.INSTANCE;
+ pw.preparePack(blobs.iterator());
+ pw.writePack(m, m, os);
+ PackStatistics stats = pw.getStatistics();
+ assertEquals(1, stats.getTotalDeltas());
+ assertTrue("Delta bytes not set.",
+ stats.byObjectType(OBJ_BLOB).getDeltaBytes() > 0);
+ }
}
}
@@ -535,6 +535,7 @@ public void testWriteIndex() throws Exception {
@Test
public void testExclude() throws Exception {
+ // TestRepository closes repo
FileRepository repo = createBareRepository();
try (TestRepository<FileRepository> testRepo = new TestRepository<>(
@@ -568,98 +569,102 @@ private static void assertContent(PackIndex pi, List<ObjectId> expected) {
@Test
public void testShallowIsMinimalDepth1() throws Exception {
- FileRepository repo = setupRepoForShallowFetch();
+ try (FileRepository repo = setupRepoForShallowFetch()) {
+ PackIndex idx = writeShallowPack(repo, 1, wants(c2), NONE, NONE);
+ assertContent(idx, Arrays.asList(c2.getId(), c2.getTree().getId(),
+ contentA.getId(), contentB.getId()));
- PackIndex idx = writeShallowPack(repo, 1, wants(c2), NONE, NONE);
- assertContent(idx, Arrays.asList(c2.getId(), c2.getTree().getId(),
- contentA.getId(), contentB.getId()));
-
- // Client already has blobs A and B, verify those are not packed.
- idx = writeShallowPack(repo, 1, wants(c5), haves(c2), shallows(c2));
- assertContent(idx, Arrays.asList(c5.getId(), c5.getTree().getId(),
- contentC.getId(), contentD.getId(), contentE.getId()));
+ // Client already has blobs A and B, verify those are not packed.
+ idx = writeShallowPack(repo, 1, wants(c5), haves(c2), shallows(c2));
+ assertContent(idx, Arrays.asList(c5.getId(), c5.getTree().getId(),
+ contentC.getId(), contentD.getId(), contentE.getId()));
+ }
}
@Test
public void testShallowIsMinimalDepth2() throws Exception {
- FileRepository repo = setupRepoForShallowFetch();
+ try (FileRepository repo = setupRepoForShallowFetch()) {
+ PackIndex idx = writeShallowPack(repo, 2, wants(c2), NONE, NONE);
+ assertContent(idx,
+ Arrays.asList(c1.getId(), c2.getId(), c1.getTree().getId(),
+ c2.getTree().getId(), contentA.getId(),
+ contentB.getId()));
- PackIndex idx = writeShallowPack(repo, 2, wants(c2), NONE, NONE);
- assertContent(idx,
- Arrays.asList(c1.getId(), c2.getId(), c1.getTree().getId(),
- c2.getTree().getId(), contentA.getId(),
- contentB.getId()));
-
- // Client already has blobs A and B, verify those are not packed.
- idx = writeShallowPack(repo, 2, wants(c5), haves(c1, c2), shallows(c1));
- assertContent(idx,
- Arrays.asList(c4.getId(), c5.getId(), c4.getTree().getId(),
- c5.getTree().getId(), contentC.getId(),
- contentD.getId(), contentE.getId()));
+ // Client already has blobs A and B, verify those are not packed.
+ idx = writeShallowPack(repo, 2, wants(c5), haves(c1, c2),
+ shallows(c1));
+ assertContent(idx,
+ Arrays.asList(c4.getId(), c5.getId(), c4.getTree().getId(),
+ c5.getTree().getId(), contentC.getId(),
+ contentD.getId(), contentE.getId()));
+ }
}
@Test
public void testShallowFetchShallowParentDepth1() throws Exception {
- FileRepository repo = setupRepoForShallowFetch();
+ try (FileRepository repo = setupRepoForShallowFetch()) {
+ PackIndex idx = writeShallowPack(repo, 1, wants(c5), NONE, NONE);
+ assertContent(idx, Arrays.asList(c5.getId(), c5.getTree().getId(),
+ contentA.getId(), contentB.getId(), contentC.getId(),
+ contentD.getId(), contentE.getId()));
- PackIndex idx = writeShallowPack(repo, 1, wants(c5), NONE, NONE);
- assertContent(idx,
- Arrays.asList(c5.getId(), c5.getTree().getId(),
- contentA.getId(), contentB.getId(), contentC.getId(),
- contentD.getId(), contentE.getId()));
-
- idx = writeShallowPack(repo, 1, wants(c4), haves(c5), shallows(c5));
- assertContent(idx, Arrays.asList(c4.getId(), c4.getTree().getId()));
+ idx = writeShallowPack(repo, 1, wants(c4), haves(c5), shallows(c5));
+ assertContent(idx, Arrays.asList(c4.getId(), c4.getTree().getId()));
+ }
}
@Test
public void testShallowFetchShallowParentDepth2() throws Exception {
- FileRepository repo = setupRepoForShallowFetch();
+ try (FileRepository repo = setupRepoForShallowFetch()) {
+ PackIndex idx = writeShallowPack(repo, 2, wants(c5), NONE, NONE);
+ assertContent(idx,
+ Arrays.asList(c4.getId(), c5.getId(), c4.getTree().getId(),
+ c5.getTree().getId(), contentA.getId(),
+ contentB.getId(), contentC.getId(),
+ contentD.getId(), contentE.getId()));
- PackIndex idx = writeShallowPack(repo, 2, wants(c5), NONE, NONE);
- assertContent(idx,
- Arrays.asList(c4.getId(), c5.getId(), c4.getTree().getId(),
- c5.getTree().getId(), contentA.getId(),
- contentB.getId(), contentC.getId(), contentD.getId(),
- contentE.getId()));
-
- idx = writeShallowPack(repo, 2, wants(c3), haves(c4, c5), shallows(c4));
- assertContent(idx, Arrays.asList(c2.getId(), c3.getId(),
- c2.getTree().getId(), c3.getTree().getId()));
+ idx = writeShallowPack(repo, 2, wants(c3), haves(c4, c5),
+ shallows(c4));
+ assertContent(idx, Arrays.asList(c2.getId(), c3.getId(),
+ c2.getTree().getId(), c3.getTree().getId()));
+ }
}
@Test
public void testShallowFetchShallowAncestorDepth1() throws Exception {
- FileRepository repo = setupRepoForShallowFetch();
+ try (FileRepository repo = setupRepoForShallowFetch()) {
+ PackIndex idx = writeShallowPack(repo, 1, wants(c5), NONE, NONE);
+ assertContent(idx, Arrays.asList(c5.getId(), c5.getTree().getId(),
+ contentA.getId(), contentB.getId(), contentC.getId(),
+ contentD.getId(), contentE.getId()));
- PackIndex idx = writeShallowPack(repo, 1, wants(c5), NONE, NONE);
- assertContent(idx,
- Arrays.asList(c5.getId(), c5.getTree().getId(),
- contentA.getId(), contentB.getId(), contentC.getId(),
- contentD.getId(), contentE.getId()));
-
- idx = writeShallowPack(repo, 1, wants(c3), haves(c5), shallows(c5));
- assertContent(idx, Arrays.asList(c3.getId(), c3.getTree().getId()));
+ idx = writeShallowPack(repo, 1, wants(c3), haves(c5), shallows(c5));
+ assertContent(idx, Arrays.asList(c3.getId(), c3.getTree().getId()));
+ }
}
@Test
public void testShallowFetchShallowAncestorDepth2() throws Exception {
- FileRepository repo = setupRepoForShallowFetch();
+ try (FileRepository repo = setupRepoForShallowFetch()) {
+ PackIndex idx = writeShallowPack(repo, 2, wants(c5), NONE, NONE);
+ assertContent(idx,
+ Arrays.asList(c4.getId(), c5.getId(), c4.getTree().getId(),
+ c5.getTree().getId(), contentA.getId(),
+ contentB.getId(), contentC.getId(),
+ contentD.getId(), contentE.getId()));
- PackIndex idx = writeShallowPack(repo, 2, wants(c5), NONE, NONE);
- assertContent(idx,
- Arrays.asList(c4.getId(), c5.getId(), c4.getTree().getId(),
- c5.getTree().getId(), contentA.getId(),
- contentB.getId(), contentC.getId(), contentD.getId(),
- contentE.getId()));
-
- idx = writeShallowPack(repo, 2, wants(c2), haves(c4, c5), shallows(c4));
- assertContent(idx, Arrays.asList(c1.getId(), c2.getId(),
- c1.getTree().getId(), c2.getTree().getId()));
+ idx = writeShallowPack(repo, 2, wants(c2), haves(c4, c5),
+ shallows(c4));
+ assertContent(idx, Arrays.asList(c1.getId(), c2.getId(),
+ c1.getTree().getId(), c2.getTree().getId()));
+ }
}
private FileRepository setupRepoForShallowFetch() throws Exception {
FileRepository repo = createBareRepository();
+ // TestRepository will close the repo, but we need to return an open
+ // one!
+ repo.incrementOpen();
try (TestRepository<Repository> r = new TestRepository<>(repo)) {
BranchBuilder bb = r.branch("refs/heads/master");
contentA = r.blob("A");
@@ -680,8 +685,9 @@ private FileRepository setupRepoForShallowFetch() throws Exception {
private static PackIndex writePack(FileRepository repo,
Set<? extends ObjectId> want, Set<ObjectIdSet> excludeObjects)
throws IOException {
- RevWalk walk = new RevWalk(repo);
- return writePack(repo, walk, 0, want, NONE, excludeObjects);
+ try (RevWalk walk = new RevWalk(repo)) {
+ return writePack(repo, walk, 0, want, NONE, excludeObjects);
+ }
}
private static PackIndex writeShallowPack(FileRepository repo, int depth,
@@ -689,9 +695,10 @@ private static PackIndex writeShallowPack(FileRepository repo, int depth,
Set<? extends ObjectId> shallow) throws IOException {
// During negotiation, UploadPack would have set up a DepthWalk and
// marked the client's "shallow" commits. Emulate that here.
- DepthWalk.RevWalk walk = new DepthWalk.RevWalk(repo, depth - 1);
- walk.assumeShallow(shallow);
- return writePack(repo, walk, depth, want, have, EMPTY_ID_SET);
+ try (DepthWalk.RevWalk walk = new DepthWalk.RevWalk(repo, depth - 1)) {
+ walk.assumeShallow(shallow);
+ return writePack(repo, walk, depth, want, have, EMPTY_ID_SET);
+ }
}
private static PackIndex writePack(FileRepository repo, RevWalk walk,
@@ -707,6 +714,7 @@ private static PackIndex writePack(FileRepository repo, RevWalk walk,
if (depth > 0) {
pw.setShallowPack(depth, null);
}
+ // ow doesn't need to be closed; caller closes walk.
ObjectWalk ow = walk.toObjectWalkWithSameObjects();
pw.preparePack(NullProgressMonitor.INSTANCE, ow, want, have, NONE);
diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/file/RefUpdateTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/file/RefUpdateTest.java
index 3a43564..bd2c203 100644
--- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/file/RefUpdateTest.java
+++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/file/RefUpdateTest.java
@@ -45,9 +45,12 @@
package org.eclipse.jgit.internal.storage.file;
-import static org.eclipse.jgit.junit.Assert.assertEquals;
import static java.nio.charset.StandardCharsets.UTF_8;
+import static org.eclipse.jgit.junit.Assert.assertEquals;
import static org.eclipse.jgit.lib.Constants.LOCK_SUFFIX;
+import static org.eclipse.jgit.lib.RefUpdate.Result.FORCED;
+import static org.eclipse.jgit.lib.RefUpdate.Result.IO_FAILURE;
+import static org.eclipse.jgit.lib.RefUpdate.Result.LOCK_FAILURE;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
@@ -82,7 +85,6 @@
import org.junit.Test;
public class RefUpdateTest extends SampleDataRepositoryTestCase {
-
private void writeSymref(String src, String dst) throws IOException {
RefUpdate u = db.updateRef(src);
switch (u.link(dst)) {
@@ -233,6 +235,17 @@ public void testDeleteHEADreferencedRef() throws IOException {
}
@Test
+ public void testWriteReflog() throws IOException {
+ ObjectId pid = db.resolve("refs/heads/master^");
+ RefUpdate updateRef = db.updateRef("refs/heads/master");
+ updateRef.setNewObjectId(pid);
+ updateRef.setForceUpdate(true);
+ Result update = updateRef.update();
+ assertEquals(Result.FORCED, update);
+ assertEquals(1,db.getReflogReader("refs/heads/master").getReverseEntries().size());
+ }
+
+ @Test
public void testLooseDelete() throws IOException {
final String newRef = "refs/heads/abc";
RefUpdate ref = updateRef(newRef);
@@ -379,6 +392,8 @@ public void testDeleteWithoutHead() throws IOException {
refUpdate.setNewObjectId(ObjectId.zeroId());
Result updateResult = refUpdate.update();
assertEquals(Result.FORCED, updateResult);
+
+ assertEquals(ObjectId.zeroId(), db.exactRef("HEAD").getObjectId());
Result deleteHeadResult = db.updateRef(Constants.HEAD).delete();
assertEquals(Result.NO_CHANGE, deleteHeadResult);
@@ -903,6 +918,45 @@ public void testRenameBranchCannotLockAFileHEADisOtherLockTo()
}
@Test
+ public void testUpdateChecksOldValue() throws Exception {
+ ObjectId cur = db.resolve("master");
+ ObjectId prev = db.resolve("master^");
+ RefUpdate u1 = db.updateRef("refs/heads/master");
+ RefUpdate u2 = db.updateRef("refs/heads/master");
+
+ u1.setExpectedOldObjectId(cur);
+ u1.setNewObjectId(prev);
+ u1.setForceUpdate(true);
+
+ u2.setExpectedOldObjectId(cur);
+ u2.setNewObjectId(prev);
+ u2.setForceUpdate(true);
+
+ assertEquals(FORCED, u1.update());
+ assertEquals(LOCK_FAILURE, u2.update());
+ }
+
+ @Test
+ public void testRenameAtomic() throws IOException {
+ ObjectId prevId = db.resolve("refs/heads/master^");
+
+ RefRename rename = db.renameRef("refs/heads/master", "refs/heads/newmaster");
+
+ RefUpdate updateRef = db.updateRef("refs/heads/master");
+ updateRef.setNewObjectId(prevId);
+ updateRef.setForceUpdate(true);
+ assertEquals(FORCED, updateRef.update());
+ assertEquals(RefUpdate.Result.LOCK_FAILURE, rename.rename());
+ }
+
+ @Test
+ public void testRenameSymref() throws IOException {
+ db.resolve("HEAD");
+ RefRename r = db.renameRef("HEAD", "KOPF");
+ assertEquals(IO_FAILURE, r.rename());
+ }
+
+ @Test
public void testRenameRefNameColission1avoided() throws IOException {
// setup
ObjectId rb = db.resolve("refs/heads/b");
diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/file/T0003_BasicTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/file/T0003_BasicTest.java
index 43f30d8..5100c1c 100644
--- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/file/T0003_BasicTest.java
+++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/file/T0003_BasicTest.java
@@ -145,13 +145,14 @@ public void test000_openrepo_default_gitDirSet() throws IOException {
}
File theDir = new File(repo1Parent, Constants.DOT_GIT);
- FileRepository r = (FileRepository) new FileRepositoryBuilder()
- .setGitDir(theDir).build();
- assertEqualsPath(theDir, r.getDirectory());
- assertEqualsPath(repo1Parent, r.getWorkTree());
- assertEqualsPath(new File(theDir, "index"), r.getIndexFile());
- assertEqualsPath(new File(theDir, Constants.OBJECTS), r.getObjectDatabase()
- .getDirectory());
+ try (FileRepository r = (FileRepository) new FileRepositoryBuilder()
+ .setGitDir(theDir).build()) {
+ assertEqualsPath(theDir, r.getDirectory());
+ assertEqualsPath(repo1Parent, r.getWorkTree());
+ assertEqualsPath(new File(theDir, "index"), r.getIndexFile());
+ assertEqualsPath(new File(theDir, Constants.OBJECTS),
+ r.getObjectDatabase().getDirectory());
+ }
}
/**
@@ -170,14 +171,15 @@ public void test000_openrepo_default_gitDirAndWorkTreeSet()
}
File theDir = new File(repo1Parent, Constants.DOT_GIT);
- FileRepository r = (FileRepository) new FileRepositoryBuilder()
+ try (FileRepository r = (FileRepository) new FileRepositoryBuilder()
.setGitDir(theDir).setWorkTree(repo1Parent.getParentFile())
- .build();
- assertEqualsPath(theDir, r.getDirectory());
- assertEqualsPath(repo1Parent.getParentFile(), r.getWorkTree());
- assertEqualsPath(new File(theDir, "index"), r.getIndexFile());
- assertEqualsPath(new File(theDir, Constants.OBJECTS), r.getObjectDatabase()
- .getDirectory());
+ .build()) {
+ assertEqualsPath(theDir, r.getDirectory());
+ assertEqualsPath(repo1Parent.getParentFile(), r.getWorkTree());
+ assertEqualsPath(new File(theDir, "index"), r.getIndexFile());
+ assertEqualsPath(new File(theDir, Constants.OBJECTS),
+ r.getObjectDatabase().getDirectory());
+ }
}
/**
@@ -195,13 +197,14 @@ public void test000_openrepo_default_workDirSet() throws IOException {
}
File theDir = new File(repo1Parent, Constants.DOT_GIT);
- FileRepository r = (FileRepository) new FileRepositoryBuilder()
- .setWorkTree(repo1Parent).build();
- assertEqualsPath(theDir, r.getDirectory());
- assertEqualsPath(repo1Parent, r.getWorkTree());
- assertEqualsPath(new File(theDir, "index"), r.getIndexFile());
- assertEqualsPath(new File(theDir, Constants.OBJECTS), r.getObjectDatabase()
- .getDirectory());
+ try (FileRepository r = (FileRepository) new FileRepositoryBuilder()
+ .setWorkTree(repo1Parent).build()) {
+ assertEqualsPath(theDir, r.getDirectory());
+ assertEqualsPath(repo1Parent, r.getWorkTree());
+ assertEqualsPath(new File(theDir, "index"), r.getIndexFile());
+ assertEqualsPath(new File(theDir, Constants.OBJECTS),
+ r.getObjectDatabase().getDirectory());
+ }
}
/**
@@ -224,13 +227,14 @@ public void test000_openrepo_default_absolute_workdirconfig()
}
File theDir = new File(repo1Parent, Constants.DOT_GIT);
- FileRepository r = (FileRepository) new FileRepositoryBuilder()
- .setGitDir(theDir).build();
- assertEqualsPath(theDir, r.getDirectory());
- assertEqualsPath(workdir, r.getWorkTree());
- assertEqualsPath(new File(theDir, "index"), r.getIndexFile());
- assertEqualsPath(new File(theDir, Constants.OBJECTS), r.getObjectDatabase()
- .getDirectory());
+ try (FileRepository r = (FileRepository) new FileRepositoryBuilder()
+ .setGitDir(theDir).build()) {
+ assertEqualsPath(theDir, r.getDirectory());
+ assertEqualsPath(workdir, r.getWorkTree());
+ assertEqualsPath(new File(theDir, "index"), r.getIndexFile());
+ assertEqualsPath(new File(theDir, Constants.OBJECTS),
+ r.getObjectDatabase().getDirectory());
+ }
}
/**
@@ -253,13 +257,14 @@ public void test000_openrepo_default_relative_workdirconfig()
}
File theDir = new File(repo1Parent, Constants.DOT_GIT);
- FileRepository r = (FileRepository) new FileRepositoryBuilder()
- .setGitDir(theDir).build();
- assertEqualsPath(theDir, r.getDirectory());
- assertEqualsPath(workdir, r.getWorkTree());
- assertEqualsPath(new File(theDir, "index"), r.getIndexFile());
- assertEqualsPath(new File(theDir, Constants.OBJECTS), r.getObjectDatabase()
- .getDirectory());
+ try (FileRepository r = (FileRepository) new FileRepositoryBuilder()
+ .setGitDir(theDir).build()) {
+ assertEqualsPath(theDir, r.getDirectory());
+ assertEqualsPath(workdir, r.getWorkTree());
+ assertEqualsPath(new File(theDir, "index"), r.getIndexFile());
+ assertEqualsPath(new File(theDir, Constants.OBJECTS),
+ r.getObjectDatabase().getDirectory());
+ }
}
/**
@@ -306,17 +311,20 @@ public void test002_WriteEmptyTree() throws IOException {
// open when we create it we won't write the object file out as a loose
// object (as it already exists in the pack).
//
- final Repository newdb = createBareRepository();
- try (ObjectInserter oi = newdb.newObjectInserter()) {
- final ObjectId treeId = oi.insert(new TreeFormatter());
- assertEquals("4b825dc642cb6eb9a060e54bf8d69288fbee4904",
- treeId.name());
- }
+ try (Repository newdb = createBareRepository()) {
+ try (ObjectInserter oi = newdb.newObjectInserter()) {
+ final ObjectId treeId = oi.insert(new TreeFormatter());
+ assertEquals("4b825dc642cb6eb9a060e54bf8d69288fbee4904",
+ treeId.name());
+ }
- final File o = new File(new File(new File(newdb.getDirectory(),
- Constants.OBJECTS), "4b"), "825dc642cb6eb9a060e54bf8d69288fbee4904");
- assertTrue("Exists " + o, o.isFile());
- assertTrue("Read-only " + o, !o.canWrite());
+ final File o = new File(
+ new File(new File(newdb.getDirectory(), Constants.OBJECTS),
+ "4b"),
+ "825dc642cb6eb9a060e54bf8d69288fbee4904");
+ assertTrue("Exists " + o, o.isFile());
+ assertTrue("Read-only " + o, !o.canWrite());
+ }
}
@Test
diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/reftable/MergedReftableTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/reftable/MergedReftableTest.java
index 11d6439..53d13f1 100644
--- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/reftable/MergedReftableTest.java
+++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/reftable/MergedReftableTest.java
@@ -187,6 +187,19 @@ public void twoTableById() throws IOException {
}
}
+ @Test
+ public void tableByIDDeletion() throws IOException {
+ List<Ref> delta1 = Arrays.asList(
+ ref("refs/heads/apple", 1),
+ ref("refs/heads/master", 2));
+ List<Ref> delta2 = Arrays.asList(ref("refs/heads/master", 3));
+
+ MergedReftable mr = merge(write(delta1), write(delta2));
+ try (RefCursor rc = mr.byObjectId(id(2))) {
+ assertFalse(rc.next());
+ }
+ }
+
@SuppressWarnings("boxing")
@Test
public void fourTableScan() throws IOException {
@@ -225,29 +238,6 @@ public void fourTableScan() throws IOException {
}
@Test
- public void scanDuplicates() throws IOException {
- List<Ref> delta1 = Arrays.asList(
- ref("refs/heads/apple", 1),
- ref("refs/heads/banana", 2));
- List<Ref> delta2 = Arrays.asList(
- ref("refs/heads/apple", 3),
- ref("refs/heads/apple", 4));
-
- MergedReftable mr = merge(write(delta1, 1000), write(delta2, 2000));
- try (RefCursor rc = mr.allRefs()) {
- assertTrue(rc.next());
- assertEquals("refs/heads/apple", rc.getRef().getName());
- assertEquals(id(3), rc.getRef().getObjectId());
- assertEquals(2000, rc.getRef().getUpdateIndex());
- assertTrue(rc.next());
- assertEquals("refs/heads/banana", rc.getRef().getName());
- assertEquals(id(2), rc.getRef().getObjectId());
- assertEquals(1000, rc.getRef().getUpdateIndex());
- assertFalse(rc.next());
- }
- }
-
- @Test
public void scanIncludeDeletes() throws IOException {
List<Ref> delta1 = Arrays.asList(ref("refs/heads/next", 4));
List<Ref> delta2 = Arrays.asList(delete("refs/heads/next"));
@@ -297,10 +287,10 @@ public void oneTableSeek() throws IOException {
@Test
public void missedUpdate() throws IOException {
ByteArrayOutputStream buf = new ByteArrayOutputStream();
- ReftableWriter writer = new ReftableWriter()
+ ReftableWriter writer = new ReftableWriter(buf)
.setMinUpdateIndex(1)
.setMaxUpdateIndex(3)
- .begin(buf);
+ .begin();
writer.writeRef(ref("refs/heads/a", 1), 1);
writer.writeRef(ref("refs/heads/c", 3), 3);
writer.finish();
@@ -337,13 +327,13 @@ public void compaction() throws IOException {
List<Ref> delta2 = Arrays.asList(delete("refs/heads/next"));
List<Ref> delta3 = Arrays.asList(ref("refs/heads/master", 8));
- ReftableCompactor compactor = new ReftableCompactor();
+ ByteArrayOutputStream out = new ByteArrayOutputStream();
+ ReftableCompactor compactor = new ReftableCompactor(out);
compactor.addAll(Arrays.asList(
read(write(delta1)),
read(write(delta2)),
read(write(delta3))));
- ByteArrayOutputStream out = new ByteArrayOutputStream();
- compactor.compact(out);
+ compactor.compact();
byte[] table = out.toByteArray();
ReftableReader reader = read(table);
@@ -414,7 +404,7 @@ public void versioningResolveRef() throws IOException {
}
private static MergedReftable merge(byte[]... table) {
- List<Reftable> stack = new ArrayList<>(table.length);
+ List<ReftableReader> stack = new ArrayList<>(table.length);
for (byte[] b : table) {
stack.add(read(b));
}
@@ -461,10 +451,10 @@ private static ObjectId id(int i) {
private byte[] write(Collection<Ref> refs, long updateIndex)
throws IOException {
ByteArrayOutputStream buffer = new ByteArrayOutputStream();
- new ReftableWriter()
+ new ReftableWriter(buffer)
.setMinUpdateIndex(updateIndex)
.setMaxUpdateIndex(updateIndex)
- .begin(buffer)
+ .begin()
.sortAndWriteRefs(refs)
.finish();
return buffer.toByteArray();
diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/reftable/ReftableCompactorTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/reftable/ReftableCompactorTest.java
index 1ea7309..0947dd2 100644
--- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/reftable/ReftableCompactorTest.java
+++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/reftable/ReftableCompactorTest.java
@@ -52,7 +52,9 @@
import java.io.ByteArrayOutputStream;
import java.io.IOException;
+import java.util.ArrayList;
import java.util.Arrays;
+import java.util.List;
import org.eclipse.jgit.internal.storage.io.BlockSource;
import org.eclipse.jgit.internal.storage.reftable.ReftableWriter.Stats;
@@ -67,9 +69,10 @@ public class ReftableCompactorTest {
@Test
public void noTables() throws IOException {
- ReftableCompactor compactor = new ReftableCompactor();
+ ReftableCompactor compactor;
try (ByteArrayOutputStream out = new ByteArrayOutputStream()) {
- compactor.compact(out);
+ compactor = new ReftableCompactor(out);
+ compactor.compact();
}
Stats stats = compactor.getStats();
assertEquals(0, stats.minUpdateIndex());
@@ -81,10 +84,10 @@ public void noTables() throws IOException {
public void oneTable() throws IOException {
byte[] inTab;
try (ByteArrayOutputStream inBuf = new ByteArrayOutputStream()) {
- ReftableWriter writer = new ReftableWriter()
+ ReftableWriter writer = new ReftableWriter(inBuf)
.setMinUpdateIndex(0)
.setMaxUpdateIndex(0)
- .begin(inBuf);
+ .begin();
writer.writeRef(ref(MASTER, 1));
writer.finish();
@@ -92,10 +95,13 @@ public void oneTable() throws IOException {
}
byte[] outTab;
- ReftableCompactor compactor = new ReftableCompactor();
+ ReftableCompactor compactor;
try (ByteArrayOutputStream outBuf = new ByteArrayOutputStream()) {
- compactor.tryAddFirst(read(inTab));
- compactor.compact(outBuf);
+ compactor = new ReftableCompactor(outBuf);
+ List<ReftableReader> readers = new ArrayList<>();
+ readers.add(read(inTab));
+ compactor.addAll(readers);
+ compactor.compact();
outTab = outBuf.toByteArray();
}
Stats stats = compactor.getStats();
@@ -116,10 +122,10 @@ public void oneTable() throws IOException {
public void twoTablesOneRef() throws IOException {
byte[] inTab1;
try (ByteArrayOutputStream inBuf = new ByteArrayOutputStream()) {
- ReftableWriter writer = new ReftableWriter()
+ ReftableWriter writer = new ReftableWriter(inBuf)
.setMinUpdateIndex(0)
.setMaxUpdateIndex(0)
- .begin(inBuf);
+ .begin();
writer.writeRef(ref(MASTER, 1));
writer.finish();
@@ -128,10 +134,10 @@ public void twoTablesOneRef() throws IOException {
byte[] inTab2;
try (ByteArrayOutputStream inBuf = new ByteArrayOutputStream()) {
- ReftableWriter writer = new ReftableWriter()
+ ReftableWriter writer = new ReftableWriter(inBuf)
.setMinUpdateIndex(1)
.setMaxUpdateIndex(1)
- .begin(inBuf);
+ .begin();
writer.writeRef(ref(MASTER, 2));
writer.finish();
@@ -139,10 +145,11 @@ public void twoTablesOneRef() throws IOException {
}
byte[] outTab;
- ReftableCompactor compactor = new ReftableCompactor();
+ ReftableCompactor compactor;
try (ByteArrayOutputStream outBuf = new ByteArrayOutputStream()) {
+ compactor = new ReftableCompactor(outBuf);
compactor.addAll(Arrays.asList(read(inTab1), read(inTab2)));
- compactor.compact(outBuf);
+ compactor.compact();
outTab = outBuf.toByteArray();
}
Stats stats = compactor.getStats();
@@ -163,10 +170,10 @@ public void twoTablesOneRef() throws IOException {
public void twoTablesTwoRefs() throws IOException {
byte[] inTab1;
try (ByteArrayOutputStream inBuf = new ByteArrayOutputStream()) {
- ReftableWriter writer = new ReftableWriter()
+ ReftableWriter writer = new ReftableWriter(inBuf)
.setMinUpdateIndex(0)
.setMaxUpdateIndex(0)
- .begin(inBuf);
+ .begin();
writer.writeRef(ref(MASTER, 1));
writer.writeRef(ref(NEXT, 2));
@@ -176,10 +183,10 @@ public void twoTablesTwoRefs() throws IOException {
byte[] inTab2;
try (ByteArrayOutputStream inBuf = new ByteArrayOutputStream()) {
- ReftableWriter writer = new ReftableWriter()
+ ReftableWriter writer = new ReftableWriter(inBuf)
.setMinUpdateIndex(1)
.setMaxUpdateIndex(1)
- .begin(inBuf);
+ .begin();
writer.writeRef(ref(MASTER, 3));
writer.finish();
@@ -187,10 +194,11 @@ public void twoTablesTwoRefs() throws IOException {
}
byte[] outTab;
- ReftableCompactor compactor = new ReftableCompactor();
+ ReftableCompactor compactor;
try (ByteArrayOutputStream outBuf = new ByteArrayOutputStream()) {
+ compactor = new ReftableCompactor(outBuf);
compactor.addAll(Arrays.asList(read(inTab1), read(inTab2)));
- compactor.compact(outBuf);
+ compactor.compact();
outTab = outBuf.toByteArray();
}
Stats stats = compactor.getStats();
@@ -216,10 +224,10 @@ public void twoTablesTwoRefs() throws IOException {
public void twoTablesIncludeOneDelete() throws IOException {
byte[] inTab1;
try (ByteArrayOutputStream inBuf = new ByteArrayOutputStream()) {
- ReftableWriter writer = new ReftableWriter()
+ ReftableWriter writer = new ReftableWriter(inBuf)
.setMinUpdateIndex(0)
.setMaxUpdateIndex(0)
- .begin(inBuf);
+ .begin();
writer.writeRef(ref(MASTER, 1));
writer.finish();
@@ -228,10 +236,10 @@ public void twoTablesIncludeOneDelete() throws IOException {
byte[] inTab2;
try (ByteArrayOutputStream inBuf = new ByteArrayOutputStream()) {
- ReftableWriter writer = new ReftableWriter()
+ ReftableWriter writer = new ReftableWriter(inBuf)
.setMinUpdateIndex(1)
.setMaxUpdateIndex(1)
- .begin(inBuf);
+ .begin();
writer.writeRef(tombstone(MASTER));
writer.finish();
@@ -239,11 +247,12 @@ public void twoTablesIncludeOneDelete() throws IOException {
}
byte[] outTab;
- ReftableCompactor compactor = new ReftableCompactor();
+ ReftableCompactor compactor;
try (ByteArrayOutputStream outBuf = new ByteArrayOutputStream()) {
+ compactor = new ReftableCompactor(outBuf);
compactor.setIncludeDeletes(true);
compactor.addAll(Arrays.asList(read(inTab1), read(inTab2)));
- compactor.compact(outBuf);
+ compactor.compact();
outTab = outBuf.toByteArray();
}
Stats stats = compactor.getStats();
@@ -261,10 +270,10 @@ public void twoTablesIncludeOneDelete() throws IOException {
public void twoTablesNotIncludeOneDelete() throws IOException {
byte[] inTab1;
try (ByteArrayOutputStream inBuf = new ByteArrayOutputStream()) {
- ReftableWriter writer = new ReftableWriter()
+ ReftableWriter writer = new ReftableWriter(inBuf)
.setMinUpdateIndex(0)
.setMaxUpdateIndex(0)
- .begin(inBuf);
+ .begin();
writer.writeRef(ref(MASTER, 1));
writer.finish();
@@ -273,10 +282,10 @@ public void twoTablesNotIncludeOneDelete() throws IOException {
byte[] inTab2;
try (ByteArrayOutputStream inBuf = new ByteArrayOutputStream()) {
- ReftableWriter writer = new ReftableWriter()
+ ReftableWriter writer = new ReftableWriter(inBuf)
.setMinUpdateIndex(1)
.setMaxUpdateIndex(1)
- .begin(inBuf);
+ .begin();
writer.writeRef(tombstone(MASTER));
writer.finish();
@@ -284,11 +293,12 @@ public void twoTablesNotIncludeOneDelete() throws IOException {
}
byte[] outTab;
- ReftableCompactor compactor = new ReftableCompactor();
+ ReftableCompactor compactor;
try (ByteArrayOutputStream outBuf = new ByteArrayOutputStream()) {
+ compactor = new ReftableCompactor(outBuf);
compactor.setIncludeDeletes(false);
compactor.addAll(Arrays.asList(read(inTab1), read(inTab2)));
- compactor.compact(outBuf);
+ compactor.compact();
outTab = outBuf.toByteArray();
}
Stats stats = compactor.getStats();
diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/reftable/ReftableTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/reftable/ReftableTest.java
index 0e33fa6..229c753 100644
--- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/reftable/ReftableTest.java
+++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/reftable/ReftableTest.java
@@ -66,6 +66,8 @@
import java.util.Collection;
import java.util.Collections;
import java.util.List;
+import java.util.concurrent.locks.ReentrantLock;
+import java.util.stream.Collectors;
import org.eclipse.jgit.internal.JGitText;
import org.eclipse.jgit.internal.storage.io.BlockSource;
@@ -76,6 +78,7 @@
import org.eclipse.jgit.lib.Ref;
import org.eclipse.jgit.lib.ReflogEntry;
import org.eclipse.jgit.lib.SymbolicRef;
+import org.hamcrest.Matchers;
import org.junit.Test;
public class ReftableTest {
@@ -134,9 +137,9 @@ public void estimateCurrentBytesOneRef() throws IOException {
byte[] table;
ReftableConfig cfg = new ReftableConfig();
cfg.setIndexObjects(false);
- ReftableWriter writer = new ReftableWriter().setConfig(cfg);
try (ByteArrayOutputStream buf = new ByteArrayOutputStream()) {
- writer.begin(buf);
+ ReftableWriter writer = new ReftableWriter(buf).setConfig(cfg);
+ writer.begin();
assertEquals(92, writer.estimateTotalBytes());
writer.writeRef(exp);
assertEquals(expBytes, writer.estimateTotalBytes());
@@ -146,12 +149,13 @@ public void estimateCurrentBytesOneRef() throws IOException {
assertEquals(expBytes, table.length);
}
- @SuppressWarnings("boxing")
@Test
public void estimateCurrentBytesWithIndex() throws IOException {
List<Ref> refs = new ArrayList<>();
for (int i = 1; i <= 5670; i++) {
- refs.add(ref(String.format("refs/heads/%04d", i), i));
+ @SuppressWarnings("boxing")
+ Ref ref = ref(String.format("refs/heads/%04d", i), i);
+ refs.add(ref);
}
ReftableConfig cfg = new ReftableConfig();
@@ -160,9 +164,9 @@ public void estimateCurrentBytesWithIndex() throws IOException {
int expBytes = 147860;
byte[] table;
- ReftableWriter writer = new ReftableWriter().setConfig(cfg);
try (ByteArrayOutputStream buf = new ByteArrayOutputStream()) {
- writer.begin(buf);
+ ReftableWriter writer = new ReftableWriter(buf).setConfig(cfg);
+ writer.begin();
writer.sortAndWriteRefs(refs);
assertEquals(expBytes, writer.estimateTotalBytes());
writer.finish();
@@ -174,6 +178,69 @@ public void estimateCurrentBytesWithIndex() throws IOException {
}
@Test
+ public void hasObjMapRefs() throws IOException {
+ ArrayList<Ref> refs = new ArrayList<>();
+ refs.add(ref(MASTER, 1));
+ byte[] table = write(refs);
+ ReftableReader t = read(table);
+ assertTrue(t.hasObjectMap());
+ }
+
+ @Test
+ public void hasObjMapRefsSmallTable() throws IOException {
+ ArrayList<Ref> refs = new ArrayList<>();
+ ReftableConfig cfg = new ReftableConfig();
+ cfg.setIndexObjects(false);
+ refs.add(ref(MASTER, 1));
+ byte[] table = write(refs);
+ ReftableReader t = read(table);
+ assertTrue(t.hasObjectMap());
+ }
+
+ @Test
+ public void hasObjLogs() throws IOException {
+ PersonIdent who = new PersonIdent("Log", "Ger", 1500079709, -8 * 60);
+ String msg = "test";
+ ReftableConfig cfg = new ReftableConfig();
+ cfg.setIndexObjects(false);
+
+ ByteArrayOutputStream buffer = new ByteArrayOutputStream();
+ ReftableWriter writer = new ReftableWriter(buffer)
+ .setMinUpdateIndex(1)
+ .setConfig(cfg)
+ .setMaxUpdateIndex(1)
+ .begin();
+
+ writer.writeLog("master", 1, who, ObjectId.zeroId(), id(1), msg);
+ writer.finish();
+ byte[] table = buffer.toByteArray();
+
+ ReftableReader t = read(table);
+ assertTrue(t.hasObjectMap());
+ }
+
+ @Test
+ public void hasObjMapRefsNoIndexObjects() throws IOException {
+ ArrayList<Ref> refs = new ArrayList<>();
+ ReftableConfig cfg = new ReftableConfig();
+ cfg.setIndexObjects(false);
+ cfg.setRefBlockSize(256);
+ cfg.setAlignBlocks(true);
+
+ // Fill up 5 blocks.
+ int N = 256 * 5 / 25;
+ for (int i= 0; i < N; i++) {
+ @SuppressWarnings("boxing")
+ Ref ref = ref(String.format("%02d/xxxxxxxxxx", i), i);
+ refs.add(ref);
+ }
+ byte[] table = write(refs, cfg);
+
+ ReftableReader t = read(table);
+ assertFalse(t.hasObjectMap());
+ }
+
+ @Test
public void oneIdRef() throws IOException {
Ref exp = ref(MASTER, 1);
byte[] table = write(exp);
@@ -361,12 +428,13 @@ public void namespaceHeads() throws IOException {
}
}
- @SuppressWarnings("boxing")
@Test
public void indexScan() throws IOException {
List<Ref> refs = new ArrayList<>();
for (int i = 1; i <= 5670; i++) {
- refs.add(ref(String.format("refs/heads/%04d", i), i));
+ @SuppressWarnings("boxing")
+ Ref ref = ref(String.format("refs/heads/%04d", i), i);
+ refs.add(ref);
}
byte[] table = write(refs);
@@ -375,12 +443,13 @@ public void indexScan() throws IOException {
assertScan(refs, read(table));
}
- @SuppressWarnings("boxing")
@Test
public void indexSeek() throws IOException {
List<Ref> refs = new ArrayList<>();
for (int i = 1; i <= 5670; i++) {
- refs.add(ref(String.format("refs/heads/%04d", i), i));
+ @SuppressWarnings("boxing")
+ Ref ref = ref(String.format("refs/heads/%04d", i), i);
+ refs.add(ref);
}
byte[] table = write(refs);
@@ -389,12 +458,13 @@ public void indexSeek() throws IOException {
assertSeek(refs, read(table));
}
- @SuppressWarnings("boxing")
@Test
public void noIndexScan() throws IOException {
List<Ref> refs = new ArrayList<>();
for (int i = 1; i <= 567; i++) {
- refs.add(ref(String.format("refs/heads/%03d", i), i));
+ @SuppressWarnings("boxing")
+ Ref ref = ref(String.format("refs/heads/%03d", i), i);
+ refs.add(ref);
}
byte[] table = write(refs);
@@ -404,12 +474,13 @@ public void noIndexScan() throws IOException {
assertScan(refs, read(table));
}
- @SuppressWarnings("boxing")
@Test
public void noIndexSeek() throws IOException {
List<Ref> refs = new ArrayList<>();
for (int i = 1; i <= 567; i++) {
- refs.add(ref(String.format("refs/heads/%03d", i), i));
+ @SuppressWarnings("boxing")
+ Ref ref = ref(String.format("refs/heads/%03d", i), i);
+ refs.add(ref);
}
byte[] table = write(refs);
@@ -418,27 +489,29 @@ public void noIndexSeek() throws IOException {
}
@Test
- public void invalidRefWriteOrder() throws IOException {
+ public void invalidRefWriteOrderSortAndWrite() {
Ref master = ref(MASTER, 1);
- Ref next = ref(NEXT, 2);
- ReftableWriter writer = new ReftableWriter()
+ ReftableWriter writer = new ReftableWriter(new ByteArrayOutputStream())
.setMinUpdateIndex(1)
.setMaxUpdateIndex(1)
- .begin(new ByteArrayOutputStream());
+ .begin();
- writer.writeRef(next);
+ List<Ref> refs = new ArrayList<>();
+ refs.add(master);
+ refs.add(master);
+
IllegalArgumentException e = assertThrows(
IllegalArgumentException.class,
- () -> writer.writeRef(master));
+ () -> writer.sortAndWriteRefs(refs));
assertThat(e.getMessage(), containsString("records must be increasing"));
}
@Test
public void invalidReflogWriteOrderUpdateIndex() throws IOException {
- ReftableWriter writer = new ReftableWriter()
+ ReftableWriter writer = new ReftableWriter(new ByteArrayOutputStream())
.setMinUpdateIndex(1)
.setMaxUpdateIndex(2)
- .begin(new ByteArrayOutputStream());
+ .begin();
PersonIdent who = new PersonIdent("Log", "Ger", 1500079709, -8 * 60);
String msg = "test";
@@ -451,10 +524,10 @@ public void invalidReflogWriteOrderUpdateIndex() throws IOException {
@Test
public void invalidReflogWriteOrderName() throws IOException {
- ReftableWriter writer = new ReftableWriter()
+ ReftableWriter writer = new ReftableWriter(new ByteArrayOutputStream())
.setMinUpdateIndex(1)
.setMaxUpdateIndex(1)
- .begin(new ByteArrayOutputStream());
+ .begin();
PersonIdent who = new PersonIdent("Log", "Ger", 1500079709, -8 * 60);
String msg = "test";
@@ -473,10 +546,10 @@ public void withReflog() throws IOException {
String msg = "test";
ByteArrayOutputStream buffer = new ByteArrayOutputStream();
- ReftableWriter writer = new ReftableWriter()
+ ReftableWriter writer = new ReftableWriter(buffer)
.setMinUpdateIndex(1)
.setMaxUpdateIndex(1)
- .begin(buffer);
+ .begin();
writer.writeRef(master);
writer.writeRef(next);
@@ -523,16 +596,96 @@ public void withReflog() throws IOException {
}
@Test
+ public void reflogReader() throws IOException {
+ Ref master = ref(MASTER, 1);
+ Ref next = ref(NEXT, 2);
+
+ ByteArrayOutputStream buffer = new ByteArrayOutputStream();
+ ReftableWriter writer = new ReftableWriter(buffer).setMinUpdateIndex(1)
+ .setMaxUpdateIndex(1).begin();
+
+ writer.writeRef(master);
+ writer.writeRef(next);
+
+ PersonIdent who1 = new PersonIdent("Log", "Ger", 1500079709, -8 * 60);
+ writer.writeLog(MASTER, 3, who1, ObjectId.zeroId(), id(1), "1");
+ PersonIdent who2 = new PersonIdent("Log", "Ger", 1500079710, -8 * 60);
+ writer.writeLog(MASTER, 2, who2, id(1), id(2), "2");
+ PersonIdent who3 = new PersonIdent("Log", "Ger", 1500079711, -8 * 60);
+ writer.writeLog(MASTER, 1, who3, id(2), id(3), "3");
+
+ writer.finish();
+ byte[] table = buffer.toByteArray();
+
+ ReentrantLock lock = new ReentrantLock();
+ ReftableReader t = read(table);
+ ReftableReflogReader rlr = new ReftableReflogReader(lock, t, MASTER);
+
+ assertEquals(rlr.getLastEntry().getWho(), who1);
+ List<PersonIdent> all = rlr.getReverseEntries().stream()
+ .map(x -> x.getWho()).collect(Collectors.toList());
+ Matchers.contains(all, who3, who2, who1);
+
+ assertEquals(rlr.getReverseEntry(1).getWho(), who2);
+
+ List<ReflogEntry> reverse2 = rlr.getReverseEntries(2);
+ Matchers.contains(reverse2, who3, who2);
+
+ List<PersonIdent> more = rlr.getReverseEntries(4).stream()
+ .map(x -> x.getWho()).collect(Collectors.toList());
+ assertEquals(all, more);
+ }
+
+ @Test
+ public void allRefs() throws IOException {
+ ByteArrayOutputStream buffer = new ByteArrayOutputStream();
+ ReftableConfig cfg = new ReftableConfig();
+ cfg.setRefBlockSize(1024);
+ cfg.setLogBlockSize(1024);
+ cfg.setAlignBlocks(true);
+ ReftableWriter writer = new ReftableWriter(buffer)
+ .setMinUpdateIndex(1)
+ .setMaxUpdateIndex(1)
+ .setConfig(cfg)
+ .begin();
+ PersonIdent who = new PersonIdent("Log", "Ger", 1500079709, -8 * 60);
+
+ // Fill out the 1st ref block.
+ List<String> names = new ArrayList<>();
+ for (int i = 0; i < 4; i++) {
+ @SuppressWarnings("boxing")
+ String name = new String(new char[220]).replace("\0", String.format("%c", i + 'a'));
+ names.add(name);
+ writer.writeRef(ref(name, i));
+ }
+
+ // Add some log data.
+ writer.writeLog(MASTER, 1, who, ObjectId.zeroId(), id(1), "msg");
+ writer.finish();
+ byte[] table = buffer.toByteArray();
+
+ ReftableReader t = read(table);
+ RefCursor c = t.allRefs();
+
+ int j = 0;
+ while (c.next()) {
+ assertEquals(names.get(j), c.getRef().getName());
+ j++;
+ }
+ }
+
+
+ @Test
public void reflogSeek() throws IOException {
PersonIdent who = new PersonIdent("Log", "Ger", 1500079709, -8 * 60);
String msg = "test";
String msgNext = "test next";
ByteArrayOutputStream buffer = new ByteArrayOutputStream();
- ReftableWriter writer = new ReftableWriter()
+ ReftableWriter writer = new ReftableWriter(buffer)
.setMinUpdateIndex(1)
.setMaxUpdateIndex(1)
- .begin(buffer);
+ .begin();
writer.writeLog(MASTER, 1, who, ObjectId.zeroId(), id(1), msg);
writer.writeLog(NEXT, 1, who, ObjectId.zeroId(), id(2), msgNext);
@@ -572,10 +725,10 @@ public void reflogSeekPrefix() throws IOException {
PersonIdent who = new PersonIdent("Log", "Ger", 1500079709, -8 * 60);
ByteArrayOutputStream buffer = new ByteArrayOutputStream();
- ReftableWriter writer = new ReftableWriter()
+ ReftableWriter writer = new ReftableWriter(buffer)
.setMinUpdateIndex(1)
.setMaxUpdateIndex(1)
- .begin(buffer);
+ .begin();
writer.writeLog("branchname", 1, who, ObjectId.zeroId(), id(1), "branchname");
@@ -596,10 +749,10 @@ public void onlyReflog() throws IOException {
String msg = "test";
ByteArrayOutputStream buffer = new ByteArrayOutputStream();
- ReftableWriter writer = new ReftableWriter()
+ ReftableWriter writer = new ReftableWriter(buffer)
.setMinUpdateIndex(1)
.setMaxUpdateIndex(1)
- .begin(buffer);
+ .begin();
writer.writeLog(MASTER, 1, who, ObjectId.zeroId(), id(1), msg);
writer.writeLog(NEXT, 1, who, ObjectId.zeroId(), id(2), msg);
writer.finish();
@@ -640,7 +793,6 @@ public void onlyReflog() throws IOException {
}
}
- @SuppressWarnings("boxing")
@Test
public void logScan() throws IOException {
ReftableConfig cfg = new ReftableConfig();
@@ -648,11 +800,12 @@ public void logScan() throws IOException {
cfg.setLogBlockSize(2048);
ByteArrayOutputStream buffer = new ByteArrayOutputStream();
- ReftableWriter writer = new ReftableWriter(cfg);
- writer.setMinUpdateIndex(1).setMaxUpdateIndex(1).begin(buffer);
+ ReftableWriter writer = new ReftableWriter(cfg, buffer);
+ writer.setMinUpdateIndex(1).setMaxUpdateIndex(1).begin();
List<Ref> refs = new ArrayList<>();
for (int i = 1; i <= 5670; i++) {
+ @SuppressWarnings("boxing")
Ref ref = ref(String.format("refs/heads/%04d", i), i);
refs.add(ref);
writer.writeRef(ref);
@@ -683,14 +836,21 @@ public void logScan() throws IOException {
}
assertFalse(lc.next());
}
+
+ for (Ref exp : refs) {
+ try (LogCursor lc = t.seekLog(exp.getName())) {
+ assertTrue("has " + exp.getName(), lc.next());
+ }
+ }
}
- @SuppressWarnings("boxing")
@Test
public void byObjectIdOneRefNoIndex() throws IOException {
List<Ref> refs = new ArrayList<>();
for (int i = 1; i <= 200; i++) {
- refs.add(ref(String.format("refs/heads/%02d", i), i));
+ @SuppressWarnings("boxing")
+ Ref ref = ref(String.format("refs/heads/%02d", i), i);
+ refs.add(ref);
}
refs.add(ref("refs/heads/master", 100));
@@ -718,12 +878,13 @@ public void byObjectIdOneRefNoIndex() throws IOException {
}
}
- @SuppressWarnings("boxing")
@Test
public void byObjectIdOneRefWithIndex() throws IOException {
List<Ref> refs = new ArrayList<>();
for (int i = 1; i <= 5200; i++) {
- refs.add(ref(String.format("refs/heads/%02d", i), i));
+ @SuppressWarnings("boxing")
+ Ref ref = ref(String.format("refs/heads/%02d", i), i);
+ refs.add(ref);
}
refs.add(ref("refs/heads/master", 100));
@@ -768,7 +929,7 @@ public void nameTooLongDoesNotWrite() throws IOException {
cfg.setRefBlockSize(64);
ByteArrayOutputStream buffer = new ByteArrayOutputStream();
- ReftableWriter writer = new ReftableWriter(cfg).begin(buffer);
+ ReftableWriter writer = new ReftableWriter(cfg, buffer).begin();
writer.writeRef(ref("refs/heads/i-am-not-a-teapot", 1));
writer.finish();
fail("expected BlockSizeTooSmallException");
@@ -852,9 +1013,14 @@ private static ReftableReader read(byte[] table) {
}
private byte[] write(Collection<Ref> refs) throws IOException {
+ return write(refs, new ReftableConfig());
+ }
+
+ private byte[] write(Collection<Ref> refs, ReftableConfig cfg) throws IOException {
ByteArrayOutputStream buffer = new ByteArrayOutputStream();
- stats = new ReftableWriter()
- .begin(buffer)
+ stats = new ReftableWriter(buffer)
+ .setConfig(cfg)
+ .begin()
.sortAndWriteRefs(refs)
.finish()
.getStats();
diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/reftree/RefTreeDatabaseTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/reftree/RefTreeDatabaseTest.java
index c3f5baa..50e0ed2 100644
--- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/reftree/RefTreeDatabaseTest.java
+++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/reftree/RefTreeDatabaseTest.java
@@ -441,8 +441,9 @@ public void testUpdate_RefusesRefsTxnNamespace() throws IOException {
ReceiveCommand cmd = command(null, B, "refs/txn/tmp");
BatchRefUpdate batch = refdb.newBatchUpdate();
batch.addCommand(cmd);
- batch.execute(new RevWalk(repo), NullProgressMonitor.INSTANCE);
-
+ try (RevWalk rw = new RevWalk(repo)) {
+ batch.execute(rw, NullProgressMonitor.INSTANCE);
+ }
assertEquals(REJECTED_OTHER_REASON, cmd.getResult());
assertEquals(MessageFormat.format(JGitText.get().invalidRefName,
"refs/txn/tmp"), cmd.getMessage());
@@ -461,8 +462,9 @@ public void testUpdate_RefusesDotLockInRefName() throws IOException {
ReceiveCommand cmd = command(null, B, "refs/heads/pu.lock");
BatchRefUpdate batch = refdb.newBatchUpdate();
batch.addCommand(cmd);
- batch.execute(new RevWalk(repo), NullProgressMonitor.INSTANCE);
-
+ try (RevWalk rw = new RevWalk(repo)) {
+ batch.execute(rw, NullProgressMonitor.INSTANCE);
+ }
assertEquals(REJECTED_OTHER_REASON, cmd.getResult());
assertEquals(JGitText.get().funnyRefname, cmd.getMessage());
assertEquals(txnId, getTxnCommitted());
@@ -481,7 +483,9 @@ public void testUpdate_RefusesOrigHeadOnBare() throws IOException {
ReceiveCommand cmd = command(null, B, ORIG_HEAD);
BatchRefUpdate batch = refdb.newBatchUpdate();
batch.addCommand(cmd);
- batch.execute(new RevWalk(repo), NullProgressMonitor.INSTANCE);
+ try (RevWalk rw = new RevWalk(repo)) {
+ batch.execute(rw, NullProgressMonitor.INSTANCE);
+ }
assertEquals(REJECTED_OTHER_REASON, cmd.getResult());
assertEquals(
MessageFormat.format(JGitText.get().invalidRefName, ORIG_HEAD),
@@ -500,7 +504,9 @@ public void testBatchRefUpdate_NonFastForwardAborts() throws IOException {
command(B, A, "refs/heads/masters"));
BatchRefUpdate batchUpdate = refdb.newBatchUpdate();
batchUpdate.addCommand(commands);
- batchUpdate.execute(new RevWalk(repo), NullProgressMonitor.INSTANCE);
+ try (RevWalk rw = new RevWalk(repo)) {
+ batchUpdate.execute(rw, NullProgressMonitor.INSTANCE);
+ }
assertEquals(txnId, getTxnCommitted());
assertEquals(REJECTED_NONFASTFORWARD,
@@ -523,7 +529,9 @@ public void testBatchRefUpdate_ForceUpdate() throws IOException {
BatchRefUpdate batchUpdate = refdb.newBatchUpdate();
batchUpdate.setAllowNonFastForwards(true);
batchUpdate.addCommand(commands);
- batchUpdate.execute(new RevWalk(repo), NullProgressMonitor.INSTANCE);
+ try (RevWalk rw = new RevWalk(repo)) {
+ batchUpdate.execute(rw, NullProgressMonitor.INSTANCE);
+ }
assertNotEquals(txnId, getTxnCommitted());
Map<String, Ref> refs = refdb.getRefs(ALL);
@@ -547,13 +555,15 @@ public void testBatchRefUpdate_NonFastForwardDoesNotDoExpensiveMergeCheck()
BatchRefUpdate batchUpdate = refdb.newBatchUpdate();
batchUpdate.setAllowNonFastForwards(true);
batchUpdate.addCommand(commands);
- batchUpdate.execute(new RevWalk(repo) {
+ try (RevWalk rw = new RevWalk(repo) {
@Override
public boolean isMergedInto(RevCommit base, RevCommit tip) {
fail("isMergedInto() should not be called");
return false;
}
- }, NullProgressMonitor.INSTANCE);
+ }) {
+ batchUpdate.execute(rw, NullProgressMonitor.INSTANCE);
+ }
assertNotEquals(txnId, getTxnCommitted());
Map<String, Ref> refs = refdb.getRefs(ALL);
@@ -574,7 +584,9 @@ public void testBatchRefUpdate_ConflictCausesAbort() throws IOException {
BatchRefUpdate batchUpdate = refdb.newBatchUpdate();
batchUpdate.setAllowNonFastForwards(true);
batchUpdate.addCommand(commands);
- batchUpdate.execute(new RevWalk(repo), NullProgressMonitor.INSTANCE);
+ try (RevWalk rw = new RevWalk(repo)) {
+ batchUpdate.execute(rw, NullProgressMonitor.INSTANCE);
+ }
assertEquals(txnId, getTxnCommitted());
assertEquals(LOCK_FAILURE, commands.get(0).getResult());
@@ -601,7 +613,9 @@ public void testBatchRefUpdate_NoConflictIfDeleted() throws IOException {
BatchRefUpdate batchUpdate = refdb.newBatchUpdate();
batchUpdate.setAllowNonFastForwards(true);
batchUpdate.addCommand(commands);
- batchUpdate.execute(new RevWalk(repo), NullProgressMonitor.INSTANCE);
+ try (RevWalk rw = new RevWalk(repo)) {
+ batchUpdate.execute(rw, NullProgressMonitor.INSTANCE);
+ }
assertNotEquals(txnId, getTxnCommitted());
assertEquals(OK, commands.get(0).getResult());
diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/lib/ConfigTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/lib/ConfigTest.java
index e839545..5eb4e6b 100644
--- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/lib/ConfigTest.java
+++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/lib/ConfigTest.java
@@ -341,7 +341,7 @@ public void testReadBoolean_OnOff2() throws ConfigInvalidException {
assertFalse(c.getBoolean("s", "b", true));
}
- static enum TestEnum {
+ enum TestEnum {
ONE_TWO;
}
diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/lib/DirCacheCheckoutMaliciousPathTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/lib/DirCacheCheckoutMaliciousPathTest.java
index 057e0c8..46fd902 100644
--- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/lib/DirCacheCheckoutMaliciousPathTest.java
+++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/lib/DirCacheCheckoutMaliciousPathTest.java
@@ -341,48 +341,56 @@ private void testMaliciousPath(boolean good, boolean secondCheckout,
String... path) throws GitAPIException, IOException {
try (Git git = new Git(db);
RevWalk revWalk = new RevWalk(git.getRepository())) {
- ObjectInserter newObjectInserter;
- newObjectInserter = git.getRepository().newObjectInserter();
- ObjectId blobId = newObjectInserter.insert(Constants.OBJ_BLOB,
+ ObjectId blobId;
+ try (ObjectInserter newObjectInserter = git.getRepository()
+ .newObjectInserter()) {
+ blobId = newObjectInserter.insert(Constants.OBJ_BLOB,
"data".getBytes(UTF_8));
- newObjectInserter = git.getRepository().newObjectInserter();
+ }
FileMode mode = FileMode.REGULAR_FILE;
ObjectId insertId = blobId;
- for (int i = path.length - 1; i >= 0; --i) {
- TreeFormatter treeFormatter = new TreeFormatter();
- treeFormatter.append("goodpath", mode, insertId);
- insertId = newObjectInserter.insert(treeFormatter);
- mode = FileMode.TREE;
+ try (ObjectInserter newObjectInserter = git.getRepository()
+ .newObjectInserter()) {
+ for (int i = path.length - 1; i >= 0; --i) {
+ TreeFormatter treeFormatter = new TreeFormatter();
+ treeFormatter.append("goodpath", mode, insertId);
+ insertId = newObjectInserter.insert(treeFormatter);
+ mode = FileMode.TREE;
+ }
}
- newObjectInserter = git.getRepository().newObjectInserter();
- CommitBuilder commitBuilder = new CommitBuilder();
- commitBuilder.setAuthor(author);
- commitBuilder.setCommitter(committer);
- commitBuilder.setMessage("foo#1");
- commitBuilder.setTreeId(insertId);
- ObjectId firstCommitId = newObjectInserter.insert(commitBuilder);
-
- newObjectInserter = git.getRepository().newObjectInserter();
- mode = FileMode.REGULAR_FILE;
- insertId = blobId;
- for (int i = path.length - 1; i >= 0; --i) {
- TreeFormatter treeFormatter = new TreeFormatter();
- treeFormatter.append(path[i].getBytes(UTF_8), 0,
- path[i].getBytes(UTF_8).length,
- mode, insertId, true);
- insertId = newObjectInserter.insert(treeFormatter);
- mode = FileMode.TREE;
+ ObjectId firstCommitId;
+ try (ObjectInserter newObjectInserter = git.getRepository()
+ .newObjectInserter()) {
+ CommitBuilder commitBuilder = new CommitBuilder();
+ commitBuilder.setAuthor(author);
+ commitBuilder.setCommitter(committer);
+ commitBuilder.setMessage("foo#1");
+ commitBuilder.setTreeId(insertId);
+ firstCommitId = newObjectInserter.insert(commitBuilder);
}
+ ObjectId commitId;
+ try (ObjectInserter newObjectInserter = git.getRepository()
+ .newObjectInserter()) {
+ mode = FileMode.REGULAR_FILE;
+ insertId = blobId;
+ for (int i = path.length - 1; i >= 0; --i) {
+ TreeFormatter treeFormatter = new TreeFormatter();
+ treeFormatter.append(path[i].getBytes(UTF_8), 0,
+ path[i].getBytes(UTF_8).length, mode, insertId,
+ true);
+ insertId = newObjectInserter.insert(treeFormatter);
+ mode = FileMode.TREE;
+ }
- // Create another commit
- commitBuilder = new CommitBuilder();
- commitBuilder.setAuthor(author);
- commitBuilder.setCommitter(committer);
- commitBuilder.setMessage("foo#2");
- commitBuilder.setTreeId(insertId);
- commitBuilder.setParentId(firstCommitId);
- ObjectId commitId = newObjectInserter.insert(commitBuilder);
-
+ // Create another commit
+ CommitBuilder commitBuilder = new CommitBuilder();
+ commitBuilder.setAuthor(author);
+ commitBuilder.setCommitter(committer);
+ commitBuilder.setMessage("foo#2");
+ commitBuilder.setTreeId(insertId);
+ commitBuilder.setParentId(firstCommitId);
+ commitId = newObjectInserter.insert(commitBuilder);
+ }
if (!secondCheckout)
git.checkout().setStartPoint(revWalk.parseCommit(firstCommitId))
.setName("refs/heads/master").setCreateBranch(true).call();
diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/lib/DirCacheCheckoutTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/lib/DirCacheCheckoutTest.java
index 8092c31..a272c8f 100644
--- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/lib/DirCacheCheckoutTest.java
+++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/lib/DirCacheCheckoutTest.java
@@ -349,9 +349,11 @@ private void buildIndex(HashMap<String, String> indexEntries) throws IOException
DirCacheEditor editor = dirCache.editor();
for (java.util.Map.Entry<String,String> e : indexEntries.entrySet()) {
writeTrashFile(e.getKey(), e.getValue());
- ObjectInserter inserter = db.newObjectInserter();
- final ObjectId id = inserter.insert(Constants.OBJ_BLOB,
+ ObjectId id;
+ try (ObjectInserter inserter = db.newObjectInserter()) {
+ id = inserter.insert(Constants.OBJ_BLOB,
Constants.encode(e.getValue()));
+ }
editor.add(new DirCacheEditor.DeletePath(e.getKey()));
editor.add(new DirCacheEditor.PathEdit(e.getKey()) {
@Override
diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/lib/IndexDiffSubmoduleTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/lib/IndexDiffSubmoduleTest.java
index fa7f5ab..014a587 100644
--- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/lib/IndexDiffSubmoduleTest.java
+++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/lib/IndexDiffSubmoduleTest.java
@@ -60,9 +60,11 @@
import org.eclipse.jgit.internal.storage.file.FileRepository;
import org.eclipse.jgit.junit.JGitTestUtil;
import org.eclipse.jgit.junit.RepositoryTestCase;
+import org.eclipse.jgit.storage.file.FileBasedConfig;
import org.eclipse.jgit.submodule.SubmoduleWalk.IgnoreSubmoduleMode;
import org.eclipse.jgit.treewalk.FileTreeIterator;
import org.junit.Before;
+import org.junit.Test;
import org.junit.experimental.theories.DataPoints;
import org.junit.experimental.theories.Theories;
import org.junit.experimental.theories.Theory;
@@ -295,4 +297,79 @@ public void testSubmoduleReplacedByMovedFile(IgnoreSubmoduleMode mode)
indexDiff.getAdded().toString());
}
+ @Test
+ public void testIndexDiffTwoSubmodules() throws Exception {
+ // Create a second submodule
+ try (Repository submodule2 = createWorkRepository()) {
+ JGitTestUtil.writeTrashFile(submodule2, "fileInSubmodule2",
+ "submodule2");
+ Git subGit = Git.wrap(submodule2);
+ subGit.add().addFilepattern("fileInSubmodule2").call();
+ subGit.commit().setMessage("add file to submodule2").call();
+
+ try (Repository sub2 = Git.wrap(db)
+ .submoduleAdd().setPath("modules/submodule2")
+ .setURI(submodule2.getDirectory().toURI().toString())
+ .call()) {
+ writeTrashFile("fileInRoot", "root+");
+ Git rootGit = Git.wrap(db);
+ rootGit.add().addFilepattern("fileInRoot").call();
+ rootGit.commit().setMessage("add submodule2 and root file")
+ .call();
+ // Now change files in both submodules
+ JGitTestUtil.writeTrashFile(submodule_db, "fileInSubmodule",
+ "submodule changed");
+ JGitTestUtil.writeTrashFile(sub2, "fileInSubmodule2",
+ "submodule2 changed");
+ // Set up .gitmodules
+ FileBasedConfig gitmodules = new FileBasedConfig(
+ new File(db.getWorkTree(), Constants.DOT_GIT_MODULES),
+ db.getFS());
+ gitmodules.load();
+ gitmodules.setString(ConfigConstants.CONFIG_SUBMODULE_SECTION,
+ "modules/submodule", ConfigConstants.CONFIG_KEY_IGNORE,
+ "all");
+ gitmodules.setString(ConfigConstants.CONFIG_SUBMODULE_SECTION,
+ "modules/submodule2", ConfigConstants.CONFIG_KEY_IGNORE,
+ "none");
+ gitmodules.save();
+ IndexDiff indexDiff = new IndexDiff(db, Constants.HEAD,
+ new FileTreeIterator(db));
+ assertTrue(indexDiff.diff());
+ String[] modified = indexDiff.getModified()
+ .toArray(new String[0]);
+ Arrays.sort(modified);
+ assertEquals("[.gitmodules, modules/submodule2]",
+ Arrays.toString(modified));
+ // Try again with "dirty"
+ gitmodules.setString(ConfigConstants.CONFIG_SUBMODULE_SECTION,
+ "modules/submodule", ConfigConstants.CONFIG_KEY_IGNORE,
+ "dirty");
+ gitmodules.save();
+ indexDiff = new IndexDiff(db, Constants.HEAD,
+ new FileTreeIterator(db));
+ assertTrue(indexDiff.diff());
+ modified = indexDiff.getModified().toArray(new String[0]);
+ Arrays.sort(modified);
+ assertEquals("[.gitmodules, modules/submodule2]",
+ Arrays.toString(modified));
+ // Test the config override
+ StoredConfig cfg = db.getConfig();
+ cfg.setString(ConfigConstants.CONFIG_SUBMODULE_SECTION,
+ "modules/submodule", ConfigConstants.CONFIG_KEY_IGNORE,
+ "none");
+ cfg.setString(ConfigConstants.CONFIG_SUBMODULE_SECTION,
+ "modules/submodule2", ConfigConstants.CONFIG_KEY_IGNORE,
+ "all");
+ cfg.save();
+ indexDiff = new IndexDiff(db, Constants.HEAD,
+ new FileTreeIterator(db));
+ assertTrue(indexDiff.diff());
+ modified = indexDiff.getModified().toArray(new String[0]);
+ Arrays.sort(modified);
+ assertEquals("[.gitmodules, modules/submodule]",
+ Arrays.toString(modified));
+ }
+ }
+ }
}
diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/lib/IndexDiffTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/lib/IndexDiffTest.java
index ba5aaf1..cf95407 100644
--- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/lib/IndexDiffTest.java
+++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/lib/IndexDiffTest.java
@@ -81,10 +81,12 @@ public class IndexDiffTest extends RepositoryTestCase {
static PathEdit add(final Repository db, final File workdir,
final String path) throws FileNotFoundException, IOException {
- ObjectInserter inserter = db.newObjectInserter();
final File f = new File(workdir, path);
- final ObjectId id = inserter.insert(Constants.OBJ_BLOB,
+ ObjectId id;
+ try (ObjectInserter inserter = db.newObjectInserter()) {
+ id = inserter.insert(Constants.OBJ_BLOB,
IO.readFully(f));
+ }
return new PathEdit(path) {
@Override
public void apply(DirCacheEntry ent) {
@@ -122,9 +124,11 @@ public void testAdded() throws IOException {
public void testMissing() throws Exception {
File file2 = writeTrashFile("file2", "file2");
File file3 = writeTrashFile("dir/file3", "dir/file3");
- Git git = Git.wrap(db);
- git.add().addFilepattern("file2").addFilepattern("dir/file3").call();
- git.commit().setMessage("commit").call();
+ try (Git git = new Git(db)) {
+ git.add().addFilepattern("file2").addFilepattern("dir/file3")
+ .call();
+ git.commit().setMessage("commit").call();
+ }
assertTrue(file2.delete());
assertTrue(file3.delete());
IndexDiff diff = new IndexDiff(db, Constants.HEAD,
diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/lib/ObjectIdSerializerTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/lib/ObjectIdSerializerTest.java
index d98b792..f0733f4 100644
--- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/lib/ObjectIdSerializerTest.java
+++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/lib/ObjectIdSerializerTest.java
@@ -88,9 +88,8 @@ private ObjectId writeAndReadBackFromTempFile(ObjectId objectId)
try (InputStream in = new FileInputStream(file)) {
if (objectId == null) {
return ObjectIdSerializer.read(in);
- } else {
- return ObjectIdSerializer.readWithoutMarker(in);
}
+ return ObjectIdSerializer.readWithoutMarker(in);
}
}
}
diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/lib/RefDatabaseConflictingNamesTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/lib/RefDatabaseConflictingNamesTest.java
index cbb47fa..3f77ca2 100644
--- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/lib/RefDatabaseConflictingNamesTest.java
+++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/lib/RefDatabaseConflictingNamesTest.java
@@ -67,9 +67,8 @@ public Map<String, Ref> getRefs(String prefix) throws IOException {
existing.put("refs/heads/a/b", null /* not used */);
existing.put("refs/heads/q", null /* not used */);
return existing;
- } else {
- return Collections.emptyMap();
}
+ return Collections.emptyMap();
}
@Override
diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/lib/ReflogConfigTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/lib/ReflogConfigTest.java
index f2f277c6e..9be71c3 100644
--- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/lib/ReflogConfigTest.java
+++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/lib/ReflogConfigTest.java
@@ -45,7 +45,7 @@
package org.eclipse.jgit.lib;
-import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
import java.io.IOException;
@@ -78,7 +78,10 @@ public void testlogAllRefUpdates() throws Exception {
// set the logAllRefUpdates parameter to true and check it
cfg.setBoolean("core", null, "logallrefupdates", true);
cfg.save();
- assertTrue(cfg.get(CoreConfig.KEY).isLogAllRefUpdates());
+ assertEquals(CoreConfig.LogRefUpdates.TRUE,
+ cfg.getEnum(ConfigConstants.CONFIG_CORE_SECTION, null,
+ ConfigConstants.CONFIG_KEY_LOGALLREFUPDATES,
+ CoreConfig.LogRefUpdates.FALSE));
// do one commit and check that reflog size is increased to 1
commit("A Commit\n", commitTime, tz);
@@ -90,13 +93,32 @@ public void testlogAllRefUpdates() throws Exception {
// set the logAllRefUpdates parameter to false and check it
cfg.setBoolean("core", null, "logallrefupdates", false);
cfg.save();
- assertFalse(cfg.get(CoreConfig.KEY).isLogAllRefUpdates());
+ assertEquals(CoreConfig.LogRefUpdates.FALSE,
+ cfg.getEnum(ConfigConstants.CONFIG_CORE_SECTION, null,
+ ConfigConstants.CONFIG_KEY_LOGALLREFUPDATES,
+ CoreConfig.LogRefUpdates.TRUE));
// do one commit and check that reflog size is 2
commit("A Commit\n", commitTime, tz);
+ commitTime += 60 * 1000;
assertTrue(
"Reflog for HEAD should contain two entries",
db.getReflogReader(Constants.HEAD).getReverseEntries().size() == 2);
+
+ // set the logAllRefUpdates parameter to false and check it
+ cfg.setEnum("core", null, "logallrefupdates",
+ CoreConfig.LogRefUpdates.ALWAYS);
+ cfg.save();
+ assertEquals(CoreConfig.LogRefUpdates.ALWAYS,
+ cfg.getEnum(ConfigConstants.CONFIG_CORE_SECTION, null,
+ ConfigConstants.CONFIG_KEY_LOGALLREFUPDATES,
+ CoreConfig.LogRefUpdates.FALSE));
+
+ // do one commit and check that reflog size is 3
+ commit("A Commit\n", commitTime, tz);
+ assertTrue("Reflog for HEAD should contain three entries",
+ db.getReflogReader(Constants.HEAD).getReverseEntries()
+ .size() == 3);
}
private void commit(String commitMsg, long commitTime, int tz)
diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/lib/internal/BouncyCastleGpgKeyLocatorTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/lib/internal/BouncyCastleGpgKeyLocatorTest.java
new file mode 100644
index 0000000..220b2be
--- /dev/null
+++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/lib/internal/BouncyCastleGpgKeyLocatorTest.java
@@ -0,0 +1,167 @@
+/*
+ * 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.internal;
+
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+
+import java.util.Locale;
+
+import org.junit.Test;
+
+public class BouncyCastleGpgKeyLocatorTest {
+
+ private static final String USER_ID = "Heinrich Heine <heinrichh@uni-duesseldorf.de>";
+
+ private static boolean match(String userId, String pattern) {
+ return BouncyCastleGpgKeyLocator.containsSigningKey(userId, pattern);
+ }
+
+ @Test
+ public void testFullMatch() throws Exception {
+ assertTrue(match(USER_ID,
+ "=Heinrich Heine <heinrichh@uni-duesseldorf.de>"));
+ assertFalse(match(USER_ID, "=Heinrich Heine"));
+ assertFalse(match(USER_ID, "= "));
+ assertFalse(match(USER_ID, "=heinrichh@uni-duesseldorf.de"));
+ }
+
+ @Test
+ public void testEmpty() throws Exception {
+ assertFalse(match(USER_ID, ""));
+ assertFalse(match(USER_ID, null));
+ assertFalse(match("", ""));
+ assertFalse(match(null, ""));
+ assertFalse(match(null, null));
+ assertFalse(match("", "something"));
+ assertFalse(match(null, "something"));
+ }
+
+ @Test
+ public void testFullEmail() throws Exception {
+ assertTrue(match(USER_ID, "<heinrichh@uni-duesseldorf.de>"));
+ assertTrue(match(USER_ID + " ", "<heinrichh@uni-duesseldorf.de>"));
+ assertFalse(match(USER_ID, "<>"));
+ assertFalse(match(USER_ID, "<h>"));
+ assertFalse(match(USER_ID, "<heinrichh>"));
+ assertFalse(match(USER_ID, "<uni-duesseldorf>"));
+ assertFalse(match(USER_ID, "<h@u>"));
+ assertFalse(match(USER_ID, "<HeinrichH@uni-duesseldorf.de>"));
+ assertFalse(match(USER_ID.substring(0, USER_ID.length() - 1),
+ "<heinrichh@uni-duesseldorf.de>"));
+ assertFalse(match("", "<>"));
+ assertFalse(match("", "<heinrichh@uni-duesseldorf.de>"));
+ }
+
+ @Test
+ public void testPartialEmail() throws Exception {
+ assertTrue(match(USER_ID, "@heinrichh@uni-duesseldorf.de"));
+ assertTrue(match(USER_ID, "@heinrichh"));
+ assertTrue(match(USER_ID, "@duesseldorf"));
+ assertTrue(match(USER_ID, "@uni-d"));
+ assertTrue(match(USER_ID, "@h"));
+ assertTrue(match(USER_ID, "@."));
+ assertTrue(match(USER_ID, "@h@u"));
+ assertFalse(match(USER_ID, "@ "));
+ assertFalse(match(USER_ID, "@"));
+ assertFalse(match(USER_ID, "@Heine"));
+ assertFalse(match(USER_ID, "@HeinrichH"));
+ assertFalse(match(USER_ID, "@Heinrich"));
+ assertFalse(match("", "@"));
+ assertFalse(match("", "@h"));
+ }
+
+ private void substringTests(String prefix) throws Exception {
+ assertTrue(match(USER_ID, prefix + "heinrichh@uni-duesseldorf.de"));
+ assertTrue(match(USER_ID, prefix + "heinrich"));
+ assertTrue(match(USER_ID, prefix + "HEIN"));
+ assertTrue(match(USER_ID, prefix + "Heine <"));
+ assertTrue(match(USER_ID, prefix + "UNI"));
+ assertTrue(match(USER_ID, prefix + "uni"));
+ assertTrue(match(USER_ID, prefix + "rich He"));
+ assertTrue(match(USER_ID, prefix + "h@u"));
+ assertTrue(match(USER_ID, prefix + USER_ID));
+ assertTrue(match(USER_ID, prefix + USER_ID.toUpperCase(Locale.ROOT)));
+ assertFalse(match(USER_ID, prefix + ""));
+ assertFalse(match(USER_ID, prefix + " "));
+ assertFalse(match(USER_ID, prefix + "yy"));
+ assertFalse(match("", prefix + ""));
+ assertFalse(match("", prefix + "uni"));
+ }
+
+ @Test
+ public void testSubstringPlain() throws Exception {
+ substringTests("");
+ }
+
+ @Test
+ public void testSubstringAsterisk() throws Exception {
+ substringTests("*");
+ }
+
+ @Test
+ public void testExplicitFingerprint() throws Exception {
+ assertFalse(match("John Fade <j.fade@example.com>", "0xfade"));
+ assertFalse(match("John Fade <0xfade@example.com>", "0xfade"));
+ assertFalse(match("", "0xfade"));
+ }
+
+ @Test
+ public void testImplicitFingerprint() throws Exception {
+ assertTrue(match("John Fade <j.fade@example.com>", "fade"));
+ assertTrue(match("John Fade <0xfade@example.com>", "fade"));
+ assertTrue(match("John Fade <j.fade@example.com>", "FADE"));
+ assertTrue(match("John Fade <0xfade@example.com>", "FADE"));
+ }
+
+ @Test
+ public void testZeroX() throws Exception {
+ assertTrue(match("John Fade <0xfade@example.com>", "0x"));
+ assertTrue(match("John Fade <0xfade@example.com>", "*0x"));
+ assertTrue(match("John Fade <0xfade@example.com>", "*0xfade"));
+ assertTrue(match("John Fade <0xfade@example.com>", "*0xFADE"));
+ assertTrue(match("John Fade <0xfade@example.com>", "@0xfade"));
+ assertFalse(match("John Fade <0xfade@example.com>", "@0xFADE"));
+ assertFalse(match("", "0x"));
+ }
+}
diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/merge/CherryPickTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/merge/CherryPickTest.java
index 19f6dcb..aa4392f 100644
--- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/merge/CherryPickTest.java
+++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/merge/CherryPickTest.java
@@ -106,23 +106,24 @@ public void testPick() throws Exception {
boolean merge = twm.merge(new ObjectId[] { O, T });
assertTrue(merge);
- final TreeWalk tw = new TreeWalk(db);
- tw.setRecursive(true);
- tw.reset(twm.getResultTreeId());
+ try (TreeWalk tw = new TreeWalk(db)) {
+ tw.setRecursive(true);
+ tw.reset(twm.getResultTreeId());
- assertTrue(tw.next());
- assertEquals("a", tw.getPathString());
- assertCorrectId(treeO, tw);
+ assertTrue(tw.next());
+ assertEquals("a", tw.getPathString());
+ assertCorrectId(treeO, tw);
- assertTrue(tw.next());
- assertEquals("o", tw.getPathString());
- assertCorrectId(treeO, tw);
+ assertTrue(tw.next());
+ assertEquals("o", tw.getPathString());
+ assertCorrectId(treeO, tw);
- assertTrue(tw.next());
- assertEquals("t", tw.getPathString());
- assertCorrectId(treeT, tw);
+ assertTrue(tw.next());
+ assertEquals("t", tw.getPathString());
+ assertCorrectId(treeT, tw);
- assertFalse(tw.next());
+ assertFalse(tw.next());
+ }
}
@Test
@@ -168,19 +169,20 @@ public void testRevert() throws Exception {
boolean merge = twm.merge(new ObjectId[] { B, T });
assertTrue(merge);
- final TreeWalk tw = new TreeWalk(db);
- tw.setRecursive(true);
- tw.reset(twm.getResultTreeId());
+ try (TreeWalk tw = new TreeWalk(db)) {
+ tw.setRecursive(true);
+ tw.reset(twm.getResultTreeId());
- assertTrue(tw.next());
- assertEquals("a", tw.getPathString());
- assertCorrectId(treeB, tw);
+ assertTrue(tw.next());
+ assertEquals("a", tw.getPathString());
+ assertCorrectId(treeB, tw);
- assertTrue(tw.next());
- assertEquals("t", tw.getPathString());
- assertCorrectId(treeT, tw);
+ assertTrue(tw.next());
+ assertEquals("t", tw.getPathString());
+ assertCorrectId(treeT, tw);
- assertFalse(tw.next());
+ assertFalse(tw.next());
+ }
}
private static void assertCorrectId(DirCache treeT, TreeWalk tw) {
diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/merge/CrissCrossMergeTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/merge/CrissCrossMergeTest.java
index a67c750..5c6636c 100644
--- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/merge/CrissCrossMergeTest.java
+++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/merge/CrissCrossMergeTest.java
@@ -881,9 +881,9 @@ private String contentAsString(Repository r, ObjectId treeId, String path)
}
StringBuilder result = new StringBuilder();
- ObjectReader or = r.newObjectReader();
- try (BufferedReader br = new BufferedReader(
- new InputStreamReader(or.open(blobId).openStream(), UTF_8))) {
+ try (ObjectReader or = r.newObjectReader();
+ BufferedReader br = new BufferedReader(new InputStreamReader(
+ or.open(blobId).openStream(), UTF_8))) {
String line;
boolean first = true;
while ((line = br.readLine()) != null) {
diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/merge/MergerTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/merge/MergerTest.java
index 62495fb..3379a25 100644
--- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/merge/MergerTest.java
+++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/merge/MergerTest.java
@@ -1365,8 +1365,8 @@ private void checkModificationTimeStampOrder(String... pathes) {
}
private String readBlob(ObjectId treeish, String path) throws Exception {
- try (TestRepository<?> tr = new TestRepository<>(db)) {
- RevWalk rw = tr.getRevWalk();
+ try (TestRepository<?> tr = new TestRepository<>(db);
+ RevWalk rw = tr.getRevWalk()) {
RevTree tree = rw.parseTree(treeish);
RevObject obj = tr.get(tree, path);
if (obj == null) {
diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/merge/SimpleMergeTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/merge/SimpleMergeTest.java
index dd2c2e8..6c0b165 100644
--- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/merge/SimpleMergeTest.java
+++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/merge/SimpleMergeTest.java
@@ -174,23 +174,24 @@ public void testTrivialTwoWay_validSubtreeSort() throws Exception {
boolean merge = ourMerger.merge(new ObjectId[] { o, t });
assertTrue(merge);
- final TreeWalk tw = new TreeWalk(db);
- tw.setRecursive(true);
- tw.reset(ourMerger.getResultTreeId());
+ try (TreeWalk tw = new TreeWalk(db)) {
+ tw.setRecursive(true);
+ tw.reset(ourMerger.getResultTreeId());
- assertTrue(tw.next());
- assertEquals("Makefile", tw.getPathString());
- assertCorrectId(treeO, tw);
+ assertTrue(tw.next());
+ assertEquals("Makefile", tw.getPathString());
+ assertCorrectId(treeO, tw);
- assertTrue(tw.next());
- assertEquals("libelf-po/a", tw.getPathString());
- assertCorrectId(treeO, tw);
+ assertTrue(tw.next());
+ assertEquals("libelf-po/a", tw.getPathString());
+ assertCorrectId(treeO, tw);
- assertTrue(tw.next());
- assertEquals("libelf/c", tw.getPathString());
- assertCorrectId(treeT, tw);
+ assertTrue(tw.next());
+ assertEquals("libelf/c", tw.getPathString());
+ assertCorrectId(treeT, tw);
- assertFalse(tw.next());
+ assertFalse(tw.next());
+ }
}
@Test
@@ -226,19 +227,20 @@ public void testTrivialTwoWay_concurrentSubtreeChange() throws Exception {
boolean merge = ourMerger.merge(new ObjectId[] { o, t });
assertTrue(merge);
- final TreeWalk tw = new TreeWalk(db);
- tw.setRecursive(true);
- tw.reset(ourMerger.getResultTreeId());
+ try (TreeWalk tw = new TreeWalk(db)) {
+ tw.setRecursive(true);
+ tw.reset(ourMerger.getResultTreeId());
- assertTrue(tw.next());
- assertEquals("d/o", tw.getPathString());
- assertCorrectId(treeO, tw);
+ assertTrue(tw.next());
+ assertEquals("d/o", tw.getPathString());
+ assertCorrectId(treeO, tw);
- assertTrue(tw.next());
- assertEquals("d/t", tw.getPathString());
- assertCorrectId(treeT, tw);
+ assertTrue(tw.next());
+ assertEquals("d/t", tw.getPathString());
+ assertCorrectId(treeT, tw);
- assertFalse(tw.next());
+ assertFalse(tw.next());
+ }
}
@Test
diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/revplot/AbstractPlotRendererTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/revplot/AbstractPlotRendererTest.java
index f265315..ac157b6 100644
--- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/revplot/AbstractPlotRendererTest.java
+++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/revplot/AbstractPlotRendererTest.java
@@ -44,7 +44,6 @@
import static org.junit.Assert.assertEquals;
-import java.io.IOException;
import java.util.LinkedList;
import java.util.List;
@@ -55,7 +54,6 @@
import org.eclipse.jgit.junit.RepositoryTestCase;
import org.eclipse.jgit.lib.ObjectId;
import org.eclipse.jgit.lib.Ref;
-import org.eclipse.jgit.lib.Repository;
import org.junit.Before;
import org.junit.Test;
@@ -83,23 +81,18 @@ public void testDrawTextAlignment() throws Exception {
git.commit().setMessage("commit on master").call();
MergeResult mergeCall = merge(db.resolve("topic"));
ObjectId start = mergeCall.getNewHead();
- PlotCommitList<PlotLane> commitList = createCommitList(start);
+ try (PlotWalk walk = new PlotWalk(db)) {
+ walk.markStart(walk.parseCommit(start));
+ PlotCommitList<PlotLane> commitList = new PlotCommitList<>();
+ commitList.source(walk);
+ commitList.fillTo(1000);
- for (int i = 0; i < commitList.size(); i++)
- plotRenderer.paintCommit(commitList.get(i), 30);
+ for (int i = 0; i < commitList.size(); i++)
+ plotRenderer.paintCommit(commitList.get(i), 30);
- List<Integer> indentations = plotRenderer.indentations;
- assertEquals(indentations.get(2), indentations.get(3));
- }
-
- private PlotCommitList<PlotLane> createCommitList(ObjectId start)
- throws IOException {
- TestPlotWalk walk = new TestPlotWalk(db);
- walk.markStart(walk.parseCommit(start));
- PlotCommitList<PlotLane> commitList = new PlotCommitList<>();
- commitList.source(walk);
- commitList.fillTo(1000);
- return commitList;
+ List<Integer> indentations = plotRenderer.indentations;
+ assertEquals(indentations.get(2), indentations.get(3));
+ }
}
private MergeResult merge(ObjectId includeId) throws GitAPIException {
@@ -107,12 +100,6 @@ private MergeResult merge(ObjectId includeId) throws GitAPIException {
.include(includeId).call();
}
- private static class TestPlotWalk extends PlotWalk {
- public TestPlotWalk(Repository repo) {
- super(repo);
- }
- }
-
private static class TestPlotRenderer extends
AbstractPlotRenderer<PlotLane, Object> {
diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/revplot/PlotCommitListTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/revplot/PlotCommitListTest.java
index 7297de3..0c367f4 100644
--- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/revplot/PlotCommitListTest.java
+++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/revplot/PlotCommitListTest.java
@@ -135,18 +135,19 @@ public void testLinear() throws Exception {
final RevCommit b = commit(a);
final RevCommit c = commit(b);
- PlotWalk pw = new PlotWalk(db);
- pw.markStart(pw.lookupCommit(c.getId()));
+ try (PlotWalk pw = new PlotWalk(db)) {
+ pw.markStart(pw.lookupCommit(c.getId()));
- PlotCommitList<PlotLane> pcl = new PlotCommitList<>();
- pcl.source(pw);
- pcl.fillTo(Integer.MAX_VALUE);
+ PlotCommitList<PlotLane> pcl = new PlotCommitList<>();
+ pcl.source(pw);
+ pcl.fillTo(Integer.MAX_VALUE);
- CommitListAssert test = new CommitListAssert(pcl);
- test.commit(c).lanePos(0).parents(b);
- test.commit(b).lanePos(0).parents(a);
- test.commit(a).lanePos(0).parents();
- test.noMoreCommits();
+ CommitListAssert test = new CommitListAssert(pcl);
+ test.commit(c).lanePos(0).parents(b);
+ test.commit(b).lanePos(0).parents(a);
+ test.commit(a).lanePos(0).parents();
+ test.noMoreCommits();
+ }
}
@Test
@@ -156,19 +157,20 @@ public void testMerged() throws Exception {
final RevCommit c = commit(a);
final RevCommit d = commit(b, c);
- PlotWalk pw = new PlotWalk(db);
- pw.markStart(pw.lookupCommit(d.getId()));
+ try (PlotWalk pw = new PlotWalk(db)) {
+ pw.markStart(pw.lookupCommit(d.getId()));
- PlotCommitList<PlotLane> pcl = new PlotCommitList<>();
- pcl.source(pw);
- pcl.fillTo(Integer.MAX_VALUE);
+ PlotCommitList<PlotLane> pcl = new PlotCommitList<>();
+ pcl.source(pw);
+ pcl.fillTo(Integer.MAX_VALUE);
- CommitListAssert test = new CommitListAssert(pcl);
- test.commit(d).lanePos(0).parents(b, c);
- test.commit(c).lanePos(1).parents(a);
- test.commit(b).lanePos(0).parents(a);
- test.commit(a).lanePos(0).parents();
- test.noMoreCommits();
+ CommitListAssert test = new CommitListAssert(pcl);
+ test.commit(d).lanePos(0).parents(b, c);
+ test.commit(c).lanePos(1).parents(a);
+ test.commit(b).lanePos(0).parents(a);
+ test.commit(a).lanePos(0).parents();
+ test.noMoreCommits();
+ }
}
@Test
@@ -177,20 +179,21 @@ public void testSideBranch() throws Exception {
final RevCommit b = commit(a);
final RevCommit c = commit(a);
- PlotWalk pw = new PlotWalk(db);
- pw.markStart(pw.lookupCommit(b.getId()));
- pw.markStart(pw.lookupCommit(c.getId()));
+ try (PlotWalk pw = new PlotWalk(db)) {
+ pw.markStart(pw.lookupCommit(b.getId()));
+ pw.markStart(pw.lookupCommit(c.getId()));
- PlotCommitList<PlotLane> pcl = new PlotCommitList<>();
- pcl.source(pw);
- pcl.fillTo(Integer.MAX_VALUE);
+ PlotCommitList<PlotLane> pcl = new PlotCommitList<>();
+ pcl.source(pw);
+ pcl.fillTo(Integer.MAX_VALUE);
- Set<Integer> childPositions = asSet(0, 1);
- CommitListAssert test = new CommitListAssert(pcl);
- test.commit(c).lanePos(childPositions).parents(a);
- test.commit(b).lanePos(childPositions).parents(a);
- test.commit(a).lanePos(0).parents();
- test.noMoreCommits();
+ Set<Integer> childPositions = asSet(0, 1);
+ CommitListAssert test = new CommitListAssert(pcl);
+ test.commit(c).lanePos(childPositions).parents(a);
+ test.commit(b).lanePos(childPositions).parents(a);
+ test.commit(a).lanePos(0).parents();
+ test.noMoreCommits();
+ }
}
@Test
@@ -200,22 +203,23 @@ public void test2SideBranches() throws Exception {
final RevCommit c = commit(a);
final RevCommit d = commit(a);
- PlotWalk pw = new PlotWalk(db);
- pw.markStart(pw.lookupCommit(b.getId()));
- pw.markStart(pw.lookupCommit(c.getId()));
- pw.markStart(pw.lookupCommit(d.getId()));
+ try (PlotWalk pw = new PlotWalk(db)) {
+ pw.markStart(pw.lookupCommit(b.getId()));
+ pw.markStart(pw.lookupCommit(c.getId()));
+ pw.markStart(pw.lookupCommit(d.getId()));
- PlotCommitList<PlotLane> pcl = new PlotCommitList<>();
- pcl.source(pw);
- pcl.fillTo(Integer.MAX_VALUE);
+ PlotCommitList<PlotLane> pcl = new PlotCommitList<>();
+ pcl.source(pw);
+ pcl.fillTo(Integer.MAX_VALUE);
- Set<Integer> childPositions = asSet(0, 1, 2);
- CommitListAssert test = new CommitListAssert(pcl);
- test.commit(d).lanePos(childPositions).parents(a);
- test.commit(c).lanePos(childPositions).parents(a);
- test.commit(b).lanePos(childPositions).parents(a);
- test.commit(a).lanePos(0).parents();
- test.noMoreCommits();
+ Set<Integer> childPositions = asSet(0, 1, 2);
+ CommitListAssert test = new CommitListAssert(pcl);
+ test.commit(d).lanePos(childPositions).parents(a);
+ test.commit(c).lanePos(childPositions).parents(a);
+ test.commit(b).lanePos(childPositions).parents(a);
+ test.commit(a).lanePos(0).parents();
+ test.noMoreCommits();
+ }
}
@Test
@@ -228,34 +232,35 @@ public void testBug300282_1() throws Exception {
final RevCommit f = commit(a);
final RevCommit g = commit(f);
- PlotWalk pw = new PlotWalk(db);
- // TODO: when we add unnecessary commit's as tips (e.g. a commit which
- // is a parent of another tip) the walk will return those commits twice.
- // Find out why!
- // pw.markStart(pw.lookupCommit(a.getId()));
- pw.markStart(pw.lookupCommit(b.getId()));
- pw.markStart(pw.lookupCommit(c.getId()));
- pw.markStart(pw.lookupCommit(d.getId()));
- pw.markStart(pw.lookupCommit(e.getId()));
- // pw.markStart(pw.lookupCommit(f.getId()));
- pw.markStart(pw.lookupCommit(g.getId()));
+ try (PlotWalk pw = new PlotWalk(db)) {
+ // TODO: when we add unnecessary commit's as tips (e.g. a commit
+ // which is a parent of another tip) the walk will return those
+ // commits twice. Find out why!
+ // pw.markStart(pw.lookupCommit(a.getId()));
+ pw.markStart(pw.lookupCommit(b.getId()));
+ pw.markStart(pw.lookupCommit(c.getId()));
+ pw.markStart(pw.lookupCommit(d.getId()));
+ pw.markStart(pw.lookupCommit(e.getId()));
+ // pw.markStart(pw.lookupCommit(f.getId()));
+ pw.markStart(pw.lookupCommit(g.getId()));
- PlotCommitList<PlotLane> pcl = new PlotCommitList<>();
- pcl.source(pw);
- pcl.fillTo(Integer.MAX_VALUE);
+ PlotCommitList<PlotLane> pcl = new PlotCommitList<>();
+ pcl.source(pw);
+ pcl.fillTo(Integer.MAX_VALUE);
- Set<Integer> childPositions = asSet(0, 1, 2, 3, 4);
- CommitListAssert test = new CommitListAssert(pcl);
- int posG = test.commit(g).lanePos(childPositions).parents(f)
- .getLanePos();
- test.commit(f).lanePos(posG).parents(a);
+ Set<Integer> childPositions = asSet(0, 1, 2, 3, 4);
+ CommitListAssert test = new CommitListAssert(pcl);
+ int posG = test.commit(g).lanePos(childPositions).parents(f)
+ .getLanePos();
+ test.commit(f).lanePos(posG).parents(a);
- test.commit(e).lanePos(childPositions).parents(a);
- test.commit(d).lanePos(childPositions).parents(a);
- test.commit(c).lanePos(childPositions).parents(a);
- test.commit(b).lanePos(childPositions).parents(a);
- test.commit(a).lanePos(0).parents();
- test.noMoreCommits();
+ test.commit(e).lanePos(childPositions).parents(a);
+ test.commit(d).lanePos(childPositions).parents(a);
+ test.commit(c).lanePos(childPositions).parents(a);
+ test.commit(b).lanePos(childPositions).parents(a);
+ test.commit(a).lanePos(0).parents();
+ test.noMoreCommits();
+ }
}
@Test
@@ -270,25 +275,26 @@ public void testBug368927() throws Exception {
final RevCommit h = commit(f);
final RevCommit i = commit(h);
- PlotWalk pw = new PlotWalk(db);
- pw.markStart(pw.lookupCommit(i.getId()));
- pw.markStart(pw.lookupCommit(g.getId()));
+ try (PlotWalk pw = new PlotWalk(db)) {
+ pw.markStart(pw.lookupCommit(i.getId()));
+ pw.markStart(pw.lookupCommit(g.getId()));
- PlotCommitList<PlotLane> pcl = new PlotCommitList<>();
- pcl.source(pw);
- pcl.fillTo(Integer.MAX_VALUE);
- Set<Integer> childPositions = asSet(0, 1);
- CommitListAssert test = new CommitListAssert(pcl);
- int posI = test.commit(i).lanePos(childPositions).parents(h)
- .getLanePos();
- test.commit(h).lanePos(posI).parents(f);
- test.commit(g).lanePos(childPositions).parents(a);
- test.commit(f).lanePos(posI).parents(e, d);
- test.commit(e).lanePos(posI).parents(c);
- test.commit(d).lanePos(2).parents(b);
- test.commit(c).lanePos(posI).parents(b);
- test.commit(b).lanePos(posI).parents(a);
- test.commit(a).lanePos(0).parents();
+ PlotCommitList<PlotLane> pcl = new PlotCommitList<>();
+ pcl.source(pw);
+ pcl.fillTo(Integer.MAX_VALUE);
+ Set<Integer> childPositions = asSet(0, 1);
+ CommitListAssert test = new CommitListAssert(pcl);
+ int posI = test.commit(i).lanePos(childPositions).parents(h)
+ .getLanePos();
+ test.commit(h).lanePos(posI).parents(f);
+ test.commit(g).lanePos(childPositions).parents(a);
+ test.commit(f).lanePos(posI).parents(e, d);
+ test.commit(e).lanePos(posI).parents(c);
+ test.commit(d).lanePos(2).parents(b);
+ test.commit(c).lanePos(posI).parents(b);
+ test.commit(b).lanePos(posI).parents(a);
+ test.commit(a).lanePos(0).parents();
+ }
}
// test the history of the egit project between 9fdaf3c1 and e76ad9170f
@@ -330,67 +336,71 @@ public void testEgitHistory() throws Exception {
final RevCommit merge_fixed_logged_npe = commit(sort_roots,
fix_logged_npe);
- PlotWalk pw = new PlotWalk(db);
- pw.markStart(pw.lookupCommit(merge_fixed_logged_npe.getId()));
+ try (PlotWalk pw = new PlotWalk(db)) {
+ pw.markStart(pw.lookupCommit(merge_fixed_logged_npe.getId()));
- PlotCommitList<PlotLane> pcl = new PlotCommitList<>();
- pcl.source(pw);
- pcl.fillTo(Integer.MAX_VALUE);
+ PlotCommitList<PlotLane> pcl = new PlotCommitList<>();
+ pcl.source(pw);
+ pcl.fillTo(Integer.MAX_VALUE);
- CommitListAssert test = new CommitListAssert(pcl);
+ CommitListAssert test = new CommitListAssert(pcl);
- // Note: all positions of side branches are rather arbitrary, but some
- // may not overlap. Testing for the positions yielded by the current
- // implementation, which was manually checked to not overlap.
- final int mainPos = 0;
- test.commit(merge_fixed_logged_npe).parents(sort_roots, fix_logged_npe)
- .lanePos(mainPos);
- test.commit(fix_logged_npe).parents(merge_changeset_implementation)
- .lanePos(1);
- test.commit(sort_roots).parents(merge_update_eclipse).lanePos(mainPos);
- test.commit(merge_update_eclipse).parents(add_a_clear, update_eclipse)
- .lanePos(mainPos);
- test.commit(add_a_clear).parents(fix_broken).lanePos(mainPos);
- test.commit(fix_broken).parents(merge_disable_comment).lanePos(mainPos);
- test.commit(merge_disable_comment)
- .parents(merge_resolve_handler, disable_comment)
- .lanePos(mainPos);
- test.commit(disable_comment).parents(clone_operation).lanePos(2);
- test.commit(merge_resolve_handler)
- .parents(clone_operation, resolve_handler).lanePos(mainPos);
- test.commit(update_eclipse).parents(add_Maven).lanePos(3);
- test.commit(clone_operation).parents(merge_changeset_implementation)
- .lanePos(mainPos);
- test.commit(merge_changeset_implementation)
- .parents(merge_disable_source, changeset_implementation)
- .lanePos(mainPos);
- test.commit(merge_disable_source)
- .parents(update_eclipse_iplog2, disable_source)
- .lanePos(mainPos);
- test.commit(update_eclipse_iplog2).parents(merge_use_remote)
- .lanePos(mainPos);
- test.commit(disable_source).parents(merge_use_remote).lanePos(1);
- test.commit(merge_use_remote).parents(update_eclipse_iplog, use_remote)
- .lanePos(mainPos);
- test.commit(changeset_implementation).parents(clear_repositorycache)
- .lanePos(2);
- test.commit(update_eclipse_iplog).parents(merge_add_Maven)
- .lanePos(mainPos);
- test.commit(merge_add_Maven).parents(findToolBar_layout, add_Maven)
- .lanePos(mainPos);
- test.commit(findToolBar_layout).parents(clear_repositorycache)
- .lanePos(mainPos);
- test.commit(use_remote).parents(clear_repositorycache).lanePos(1);
- test.commit(add_Maven).parents(clear_repositorycache).lanePos(3);
- test.commit(clear_repositorycache).parents(merge_remove)
- .lanePos(mainPos);
- test.commit(resolve_handler).parents(merge_fix).lanePos(4);
- test.commit(merge_remove).parents(add_simple, remove_unused)
- .lanePos(mainPos);
- test.commit(remove_unused).parents(merge_fix).lanePos(1);
- test.commit(add_simple).parents(merge_fix).lanePos(mainPos);
- test.commit(merge_fix).parents().lanePos(mainPos);
- test.noMoreCommits();
+ // Note: all positions of side branches are rather arbitrary, but
+ // some
+ // may not overlap. Testing for the positions yielded by the current
+ // implementation, which was manually checked to not overlap.
+ final int mainPos = 0;
+ test.commit(merge_fixed_logged_npe)
+ .parents(sort_roots, fix_logged_npe).lanePos(mainPos);
+ test.commit(fix_logged_npe).parents(merge_changeset_implementation)
+ .lanePos(1);
+ test.commit(sort_roots).parents(merge_update_eclipse)
+ .lanePos(mainPos);
+ test.commit(merge_update_eclipse)
+ .parents(add_a_clear, update_eclipse).lanePos(mainPos);
+ test.commit(add_a_clear).parents(fix_broken).lanePos(mainPos);
+ test.commit(fix_broken).parents(merge_disable_comment)
+ .lanePos(mainPos);
+ test.commit(merge_disable_comment)
+ .parents(merge_resolve_handler, disable_comment)
+ .lanePos(mainPos);
+ test.commit(disable_comment).parents(clone_operation).lanePos(2);
+ test.commit(merge_resolve_handler)
+ .parents(clone_operation, resolve_handler).lanePos(mainPos);
+ test.commit(update_eclipse).parents(add_Maven).lanePos(3);
+ test.commit(clone_operation).parents(merge_changeset_implementation)
+ .lanePos(mainPos);
+ test.commit(merge_changeset_implementation)
+ .parents(merge_disable_source, changeset_implementation)
+ .lanePos(mainPos);
+ test.commit(merge_disable_source)
+ .parents(update_eclipse_iplog2, disable_source)
+ .lanePos(mainPos);
+ test.commit(update_eclipse_iplog2).parents(merge_use_remote)
+ .lanePos(mainPos);
+ test.commit(disable_source).parents(merge_use_remote).lanePos(1);
+ test.commit(merge_use_remote)
+ .parents(update_eclipse_iplog, use_remote).lanePos(mainPos);
+ test.commit(changeset_implementation).parents(clear_repositorycache)
+ .lanePos(2);
+ test.commit(update_eclipse_iplog).parents(merge_add_Maven)
+ .lanePos(mainPos);
+ test.commit(merge_add_Maven).parents(findToolBar_layout, add_Maven)
+ .lanePos(mainPos);
+ test.commit(findToolBar_layout).parents(clear_repositorycache)
+ .lanePos(mainPos);
+ test.commit(use_remote).parents(clear_repositorycache).lanePos(1);
+ test.commit(add_Maven).parents(clear_repositorycache).lanePos(3);
+ test.commit(clear_repositorycache).parents(merge_remove)
+ .lanePos(mainPos);
+ test.commit(resolve_handler).parents(merge_fix).lanePos(4);
+ test.commit(merge_remove).parents(add_simple, remove_unused)
+ .lanePos(mainPos);
+ test.commit(remove_unused).parents(merge_fix).lanePos(1);
+ test.commit(add_simple).parents(merge_fix).lanePos(mainPos);
+ test.commit(merge_fix).parents().lanePos(mainPos);
+ test.noMoreCommits();
+ }
}
// test a history where a merge commit has two time the same parent
@@ -403,20 +413,21 @@ public void testDuplicateParents() throws Exception {
final RevCommit s1 = commit(m2);
final RevCommit s2 = commit(s1);
- PlotWalk pw = new PlotWalk(db);
- pw.markStart(pw.lookupCommit(m3));
- pw.markStart(pw.lookupCommit(s2));
- PlotCommitList<PlotLane> pcl = new PlotCommitList<>();
- pcl.source(pw);
- pcl.fillTo(Integer.MAX_VALUE);
+ try (PlotWalk pw = new PlotWalk(db)) {
+ pw.markStart(pw.lookupCommit(m3));
+ pw.markStart(pw.lookupCommit(s2));
+ PlotCommitList<PlotLane> pcl = new PlotCommitList<>();
+ pcl.source(pw);
+ pcl.fillTo(Integer.MAX_VALUE);
- CommitListAssert test = new CommitListAssert(pcl);
- test.commit(s2).nrOfPassingLanes(0);
- test.commit(s1).nrOfPassingLanes(0);
- test.commit(m3).nrOfPassingLanes(1);
- test.commit(m2).nrOfPassingLanes(0);
- test.commit(m1).nrOfPassingLanes(0);
- test.noMoreCommits();
+ CommitListAssert test = new CommitListAssert(pcl);
+ test.commit(s2).nrOfPassingLanes(0);
+ test.commit(s1).nrOfPassingLanes(0);
+ test.commit(m3).nrOfPassingLanes(1);
+ test.commit(m2).nrOfPassingLanes(0);
+ test.commit(m1).nrOfPassingLanes(0);
+ test.noMoreCommits();
+ }
}
/**
@@ -465,30 +476,31 @@ public void testBug419359() throws Exception {
final RevCommit a4 = commit(a3);
final RevCommit a5 = commit(a3, a4);
- PlotWalk pw = new PlotWalk(db);
- pw.markStart(pw.lookupCommit(b3.getId()));
- pw.markStart(pw.lookupCommit(c.getId()));
- pw.markStart(pw.lookupCommit(e.getId()));
- pw.markStart(pw.lookupCommit(a5.getId()));
+ try (PlotWalk pw = new PlotWalk(db)) {
+ pw.markStart(pw.lookupCommit(b3.getId()));
+ pw.markStart(pw.lookupCommit(c.getId()));
+ pw.markStart(pw.lookupCommit(e.getId()));
+ pw.markStart(pw.lookupCommit(a5.getId()));
- PlotCommitList<PlotLane> pcl = new PlotCommitList<>();
- pcl.source(pw);
- pcl.fillTo(Integer.MAX_VALUE);
+ PlotCommitList<PlotLane> pcl = new PlotCommitList<>();
+ pcl.source(pw);
+ pcl.fillTo(Integer.MAX_VALUE);
- // test that the commits b1, b2 and b3 are on the same position
- int bPos = pcl.get(9).lane.position; // b1
- assertEquals("b2 is an a different position", bPos,
- pcl.get(7).lane.position);
- assertEquals("b3 is on a different position", bPos,
- pcl.get(4).lane.position);
+ // test that the commits b1, b2 and b3 are on the same position
+ int bPos = pcl.get(9).lane.position; // b1
+ assertEquals("b2 is an a different position", bPos,
+ pcl.get(7).lane.position);
+ assertEquals("b3 is on a different position", bPos,
+ pcl.get(4).lane.position);
- // test that nothing blocks the connections between b1, b2 and b3
- assertNotEquals("b lane is blocked by c", bPos,
- pcl.get(8).lane.position);
- assertNotEquals("b lane is blocked by a2", bPos,
- pcl.get(6).lane.position);
- assertNotEquals("b lane is blocked by d", bPos,
- pcl.get(5).lane.position);
+ // test that nothing blocks the connections between b1, b2 and b3
+ assertNotEquals("b lane is blocked by c", bPos,
+ pcl.get(8).lane.position);
+ assertNotEquals("b lane is blocked by a2", bPos,
+ pcl.get(6).lane.position);
+ assertNotEquals("b lane is blocked by d", bPos,
+ pcl.get(5).lane.position);
+ }
}
/**
@@ -517,23 +529,24 @@ public void testMultipleMerges() throws Exception {
final RevCommit a4 = commit(a3, b2);
final RevCommit b3 = commit(b2);
- PlotWalk pw = new PlotWalk(db);
- pw.markStart(pw.lookupCommit(a4));
- pw.markStart(pw.lookupCommit(b3));
- PlotCommitList<PlotLane> pcl = new PlotCommitList<>();
- pcl.source(pw);
- pcl.fillTo(Integer.MAX_VALUE);
+ try (PlotWalk pw = new PlotWalk(db)) {
+ pw.markStart(pw.lookupCommit(a4));
+ pw.markStart(pw.lookupCommit(b3));
+ PlotCommitList<PlotLane> pcl = new PlotCommitList<>();
+ pcl.source(pw);
+ pcl.fillTo(Integer.MAX_VALUE);
- Set<Integer> positions = asSet(0, 1);
- CommitListAssert test = new CommitListAssert(pcl);
- int posB = test.commit(b3).lanePos(positions).getLanePos();
- int posA = test.commit(a4).lanePos(positions).getLanePos();
- test.commit(b2).lanePos(posB);
- test.commit(a3).lanePos(posA);
- test.commit(a2).lanePos(posA);
- test.commit(b1).lanePos(posB);
- test.commit(a1).lanePos(posA);
- test.noMoreCommits();
+ Set<Integer> positions = asSet(0, 1);
+ CommitListAssert test = new CommitListAssert(pcl);
+ int posB = test.commit(b3).lanePos(positions).getLanePos();
+ int posA = test.commit(a4).lanePos(positions).getLanePos();
+ test.commit(b2).lanePos(posB);
+ test.commit(a3).lanePos(posA);
+ test.commit(a2).lanePos(posA);
+ test.commit(b1).lanePos(posB);
+ test.commit(a1).lanePos(posA);
+ test.noMoreCommits();
+ }
}
/**
@@ -562,25 +575,26 @@ public void testMergeBlockedBySelf() throws Exception {
final RevCommit b3 = commit(b2);
final RevCommit a4 = commit(a3);
- PlotWalk pw = new PlotWalk(db);
- pw.markStart(pw.lookupCommit(a4));
- pw.markStart(pw.lookupCommit(b3));
- PlotCommitList<PlotLane> pcl = new PlotCommitList<>();
- pcl.source(pw);
- pcl.fillTo(Integer.MAX_VALUE);
+ try (PlotWalk pw = new PlotWalk(db)) {
+ pw.markStart(pw.lookupCommit(a4));
+ pw.markStart(pw.lookupCommit(b3));
+ PlotCommitList<PlotLane> pcl = new PlotCommitList<>();
+ pcl.source(pw);
+ pcl.fillTo(Integer.MAX_VALUE);
- Set<Integer> positions = asSet(0, 1);
- CommitListAssert test = new CommitListAssert(pcl);
- int posA = test.commit(a4).lanePos(positions).getLanePos();
- int posB = test.commit(b3).lanePos(positions).getLanePos();
- test.commit(a3).lanePos(posA);
- test.commit(b2).lanePos(posB);
- test.commit(a2).lanePos(posA);
- // b1 is not repositioned, uses "detour lane"
- // (drawn as a double arc in the ascii graph above)
- test.commit(b1).lanePos(posB);
- test.commit(a1).lanePos(posA);
- test.noMoreCommits();
+ Set<Integer> positions = asSet(0, 1);
+ CommitListAssert test = new CommitListAssert(pcl);
+ int posA = test.commit(a4).lanePos(positions).getLanePos();
+ int posB = test.commit(b3).lanePos(positions).getLanePos();
+ test.commit(a3).lanePos(posA);
+ test.commit(b2).lanePos(posB);
+ test.commit(a2).lanePos(posA);
+ // b1 is not repositioned, uses "detour lane"
+ // (drawn as a double arc in the ascii graph above)
+ test.commit(b1).lanePos(posB);
+ test.commit(a1).lanePos(posA);
+ test.noMoreCommits();
+ }
}
/**
@@ -611,24 +625,25 @@ public void testMergeBlockedByOther() throws Exception {
final RevCommit a4 = commit(a3, b1);
final RevCommit b2 = commit(b1);
- PlotWalk pw = new PlotWalk(db);
- pw.markStart(pw.lookupCommit(a4));
- pw.markStart(pw.lookupCommit(b2));
- pw.markStart(pw.lookupCommit(c));
- PlotCommitList<PlotLane> pcl = new PlotCommitList<>();
- pcl.source(pw);
- pcl.fillTo(Integer.MAX_VALUE);
+ try (PlotWalk pw = new PlotWalk(db)) {
+ pw.markStart(pw.lookupCommit(a4));
+ pw.markStart(pw.lookupCommit(b2));
+ pw.markStart(pw.lookupCommit(c));
+ PlotCommitList<PlotLane> pcl = new PlotCommitList<>();
+ pcl.source(pw);
+ pcl.fillTo(Integer.MAX_VALUE);
- Set<Integer> positions = asSet(0, 1, 2);
- CommitListAssert test = new CommitListAssert(pcl);
- int posB = test.commit(b2).lanePos(positions).getLanePos();
- int posA = test.commit(a4).lanePos(positions).getLanePos();
- test.commit(a3).lanePos(posA);
- test.commit(c).lanePos(positions);
- test.commit(a2).lanePos(posA);
- test.commit(b1).lanePos(posB); // repositioned to go around c
- test.commit(a1).lanePos(posA);
- test.noMoreCommits();
+ Set<Integer> positions = asSet(0, 1, 2);
+ CommitListAssert test = new CommitListAssert(pcl);
+ int posB = test.commit(b2).lanePos(positions).getLanePos();
+ int posA = test.commit(a4).lanePos(positions).getLanePos();
+ test.commit(a3).lanePos(posA);
+ test.commit(c).lanePos(positions);
+ test.commit(a2).lanePos(posA);
+ test.commit(b1).lanePos(posB); // repositioned to go around c
+ test.commit(a1).lanePos(posA);
+ test.noMoreCommits();
+ }
}
/**
@@ -651,22 +666,24 @@ public void testDanglingCommitShouldContinueLane() throws Exception {
final RevCommit a3 = commit(a2);
final RevCommit b1 = commit(a1);
- PlotWalk pw = new PlotWalk(db);
- pw.markStart(pw.lookupCommit(a3));
- pw.markStart(pw.lookupCommit(b1));
- PlotCommitList<PlotLane> pcl = new PlotCommitList<>();
- pcl.source(pw);
- pcl.fillTo(2); // don't process a1
+ try (PlotWalk pw = new PlotWalk(db)) {
+ pw.markStart(pw.lookupCommit(a3));
+ pw.markStart(pw.lookupCommit(b1));
+ PlotCommitList<PlotLane> pcl = new PlotCommitList<>();
+ pcl.source(pw);
+ pcl.fillTo(2); // don't process a1
- Set<Integer> positions = asSet(0, 1);
- CommitListAssert test = new CommitListAssert(pcl);
- PlotLane laneB = test.commit(b1).lanePos(positions).current.getLane();
- int posA = test.commit(a3).lanePos(positions).getLanePos();
- test.commit(a2).lanePos(posA);
- assertArrayEquals(
- "Although the parent of b1, a1, is not processed yet, the b lane should still be drawn",
- new PlotLane[] { laneB }, test.current.passingLanes);
- test.noMoreCommits();
+ Set<Integer> positions = asSet(0, 1);
+ CommitListAssert test = new CommitListAssert(pcl);
+ PlotLane laneB = test.commit(b1).lanePos(positions).current
+ .getLane();
+ int posA = test.commit(a3).lanePos(positions).getLanePos();
+ test.commit(a2).lanePos(posA);
+ assertArrayEquals(
+ "Although the parent of b1, a1, is not processed yet, the b lane should still be drawn",
+ new PlotLane[] { laneB }, test.current.passingLanes);
+ test.noMoreCommits();
+ }
}
@Test
@@ -674,17 +691,18 @@ public void testTwoRoots1() throws Exception {
final RevCommit a = commit();
final RevCommit b = commit();
- PlotWalk pw = new PlotWalk(db);
- pw.markStart(pw.lookupCommit(a));
- pw.markStart(pw.lookupCommit(b));
- PlotCommitList<PlotLane> pcl = new PlotCommitList<>();
- pcl.source(pw);
- pcl.fillTo(Integer.MAX_VALUE);
+ try (PlotWalk pw = new PlotWalk(db)) {
+ pw.markStart(pw.lookupCommit(a));
+ pw.markStart(pw.lookupCommit(b));
+ PlotCommitList<PlotLane> pcl = new PlotCommitList<>();
+ pcl.source(pw);
+ pcl.fillTo(Integer.MAX_VALUE);
- CommitListAssert test = new CommitListAssert(pcl);
- test.commit(b).lanePos(0);
- test.commit(a).lanePos(0);
- test.noMoreCommits();
+ CommitListAssert test = new CommitListAssert(pcl);
+ test.commit(b).lanePos(0);
+ test.commit(a).lanePos(0);
+ test.noMoreCommits();
+ }
}
@Test
@@ -693,17 +711,18 @@ public void testTwoRoots2() throws Exception {
final RevCommit b1 = commit();
final RevCommit b2 = commit(b1);
- PlotWalk pw = new PlotWalk(db);
- pw.markStart(pw.lookupCommit(a));
- pw.markStart(pw.lookupCommit(b2));
- PlotCommitList<PlotLane> pcl = new PlotCommitList<>();
- pcl.source(pw);
- pcl.fillTo(Integer.MAX_VALUE);
+ try (PlotWalk pw = new PlotWalk(db)) {
+ pw.markStart(pw.lookupCommit(a));
+ pw.markStart(pw.lookupCommit(b2));
+ PlotCommitList<PlotLane> pcl = new PlotCommitList<>();
+ pcl.source(pw);
+ pcl.fillTo(Integer.MAX_VALUE);
- CommitListAssert test = new CommitListAssert(pcl);
- test.commit(b2).lanePos(0);
- test.commit(b1).lanePos(0);
- test.commit(a).lanePos(0);
- test.noMoreCommits();
+ CommitListAssert test = new CommitListAssert(pcl);
+ test.commit(b2).lanePos(0);
+ test.commit(b1).lanePos(0);
+ test.commit(a).lanePos(0);
+ test.noMoreCommits();
+ }
}
}
diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/revwalk/BitmapCalculatorTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/revwalk/BitmapCalculatorTest.java
deleted file mode 100644
index c5d4d42..0000000
--- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/revwalk/BitmapCalculatorTest.java
+++ /dev/null
@@ -1,181 +0,0 @@
-/*
- * 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;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertTrue;
-
-import org.eclipse.jgit.internal.storage.file.FileRepository;
-import org.eclipse.jgit.internal.storage.file.GC;
-import org.eclipse.jgit.junit.LocalDiskRepositoryTestCase;
-import org.eclipse.jgit.junit.TestRepository;
-import org.eclipse.jgit.lib.BitmapIndex.BitmapBuilder;
-import org.eclipse.jgit.lib.NullProgressMonitor;
-import org.eclipse.jgit.lib.ProgressMonitor;
-import org.junit.Before;
-import org.junit.Test;
-
-public class BitmapCalculatorTest extends LocalDiskRepositoryTestCase {
- TestRepository<FileRepository> repo;
-
- /** {@inheritDoc} */
- @Override
- @Before
- public void setUp() throws Exception {
- super.setUp();
- FileRepository db = createWorkRepository();
- repo = new TestRepository<>(db);
- }
-
- @Test
- public void addOnlyCommits() throws Exception {
- RevBlob abBlob = repo.blob("a_b_content");
- RevCommit root = repo.commit().add("a/b", abBlob).create();
- repo.update("refs/heads/master", root);
-
- // GC creates bitmap index with ALL objects
- GC gc = new GC(repo.getRepository());
- gc.setAuto(false);
- gc.gc();
-
- // These objects are not in the bitmap index.
- RevBlob acBlob = repo.blob("a_c_content");
- RevCommit head = repo.commit().parent(root).add("a/c", acBlob).create();
- repo.update("refs/heads/master", head);
-
- BitmapCalculator bitmapWalker = new BitmapCalculator(repo.getRevWalk());
- BitmapBuilder bitmap = bitmapWalker
- .getBitmap(head, NullProgressMonitor.INSTANCE);
-
- assertTrue(bitmap.contains(root.getId()));
- assertTrue(bitmap.contains(root.getTree().getId()));
- assertTrue(bitmap.contains(abBlob.getId()));
-
- // BitmapCalculator added only the commit, no other objects.
- assertTrue(bitmap.contains(head.getId()));
- assertFalse(bitmap.contains(head.getTree().getId()));
- assertFalse(bitmap.contains(acBlob.getId()));
- }
-
- @Test
- public void walkUntilBitmap() throws Exception {
- RevCommit root = repo.commit().create();
- repo.update("refs/heads/master", root);
-
- // GC creates bitmap index with ALL objects
- GC gc = new GC(repo.getRepository());
- gc.setAuto(false);
- gc.gc();
-
- // These objects are not in the bitmap index.
- RevCommit commit1 = repo.commit(root);
- RevCommit commit2 = repo.commit(commit1);
- repo.update("refs/heads/master", commit2);
-
- CounterProgressMonitor monitor = new CounterProgressMonitor();
- BitmapCalculator bitmapWalker = new BitmapCalculator(repo.getRevWalk());
- BitmapBuilder bitmap = bitmapWalker.getBitmap(commit2, monitor);
-
- assertTrue(bitmap.contains(root));
- assertTrue(bitmap.contains(commit1));
- assertTrue(bitmap.contains(commit2));
- assertEquals(2, monitor.getUpdates());
- }
-
- @Test
- public void noNeedToWalk() throws Exception {
- RevCommit root = repo.commit().create();
- RevCommit commit1 = repo.commit(root);
- RevCommit commit2 = repo.commit(commit1);
- repo.update("refs/heads/master", commit2);
-
- // GC creates bitmap index with ALL objects
- GC gc = new GC(repo.getRepository());
- gc.setAuto(false);
- gc.gc();
-
- CounterProgressMonitor monitor = new CounterProgressMonitor();
- BitmapCalculator bitmapWalker = new BitmapCalculator(repo.getRevWalk());
- BitmapBuilder bitmap = bitmapWalker.getBitmap(commit2, monitor);
-
- assertTrue(bitmap.contains(root));
- assertTrue(bitmap.contains(commit1));
- assertTrue(bitmap.contains(commit2));
- assertEquals(0, monitor.getUpdates());
- }
-
- private static class CounterProgressMonitor implements ProgressMonitor {
-
- private int counter;
-
- @Override
- public void start(int totalTasks) {
- // Nothing to do in tests
- }
-
- @Override
- public void beginTask(String title, int totalWork) {
- // Nothing to to in tests
- }
-
- @Override
- public void update(int completed) {
- counter += 1;
- }
-
- @Override
- public void endTask() {
- // Nothing to do in tests
- }
-
- @Override
- public boolean isCancelled() {
- return false;
- }
-
- int getUpdates() {
- return counter;
- }
- }
-}
\ No newline at end of file
diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/revwalk/FirstParentRevWalkTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/revwalk/FirstParentRevWalkTest.java
index 1fc7a55..d46f48b 100644
--- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/revwalk/FirstParentRevWalkTest.java
+++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/revwalk/FirstParentRevWalkTest.java
@@ -49,6 +49,7 @@
import org.eclipse.jgit.lib.ObjectId;
import org.eclipse.jgit.revwalk.filter.MessageRevFilter;
import org.eclipse.jgit.revwalk.filter.RevFilter;
+import org.eclipse.jgit.treewalk.filter.PathFilterGroup;
import org.junit.Test;
public class FirstParentRevWalkTest extends RevWalkTestCase {
@@ -425,4 +426,39 @@ public void testMergeBaseWithFirstParentNotAllowed() throws Exception {
markStart(a);
assertNull(rw.next());
}
+
+ @Test
+ public void testWithTopoSortAndTreeFilter() throws Exception {
+ RevCommit a = commit();
+ RevCommit b = commit(tree(file("0", blob("b"))), a);
+ RevCommit c = commit(tree(file("0", blob("c"))), b, a);
+ RevCommit d = commit(tree(file("0", blob("d"))), c);
+
+ rw.reset();
+ rw.setFirstParent(true);
+ rw.sort(RevSort.TOPO, true);
+ rw.setTreeFilter(PathFilterGroup.createFromStrings("0"));
+ markStart(d);
+ assertCommit(d, rw.next());
+ assertCommit(c, rw.next());
+ assertCommit(b, rw.next());
+ assertNull(rw.next());
+ }
+
+ @Test
+ public void testWithTopoSortAndTreeFilter2() throws Exception {
+ RevCommit a = commit();
+ RevCommit b = commit(tree(file("0", blob("b"))), a);
+ RevCommit c = commit(tree(file("0", blob("c"))), a, b);
+ RevCommit d = commit(tree(file("0", blob("d"))), c);
+
+ rw.reset();
+ rw.setFirstParent(true);
+ rw.sort(RevSort.TOPO, true);
+ rw.setTreeFilter(PathFilterGroup.createFromStrings("0"));
+ markStart(d);
+ assertCommit(d, rw.next());
+ assertCommit(c, rw.next());
+ assertNull(rw.next());
+ }
}
diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/revwalk/ReachabilityCheckerTestCase.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/revwalk/ReachabilityCheckerTestCase.java
index dd73e35..a4411e5 100644
--- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/revwalk/ReachabilityCheckerTestCase.java
+++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/revwalk/ReachabilityCheckerTestCase.java
@@ -47,6 +47,7 @@
import java.util.Arrays;
import java.util.Optional;
+import java.util.stream.Stream;
import org.eclipse.jgit.internal.storage.file.FileRepository;
import org.eclipse.jgit.junit.LocalDiskRepositoryTestCase;
@@ -83,11 +84,11 @@ public void reachable() throws Exception {
ReachabilityChecker checker = getChecker(repo);
assertReachable("reachable from one tip",
- checker.areAllReachable(Arrays.asList(a), Arrays.asList(c2)));
+ checker.areAllReachable(Arrays.asList(a), Stream.of(c2)));
assertReachable("reachable from another tip",
- checker.areAllReachable(Arrays.asList(a), Arrays.asList(b2)));
+ checker.areAllReachable(Arrays.asList(a), Stream.of(b2)));
assertReachable("reachable from itself",
- checker.areAllReachable(Arrays.asList(a), Arrays.asList(b2)));
+ checker.areAllReachable(Arrays.asList(a), Stream.of(a)));
}
@Test
@@ -104,13 +105,13 @@ public void reachable_merge() throws Exception {
assertReachable("reachable through one branch",
checker.areAllReachable(Arrays.asList(b1),
- Arrays.asList(merge)));
+ Stream.of(merge)));
assertReachable("reachable through another branch",
checker.areAllReachable(Arrays.asList(c1),
- Arrays.asList(merge)));
+ Stream.of(merge)));
assertReachable("reachable, before the branching",
checker.areAllReachable(Arrays.asList(a),
- Arrays.asList(merge)));
+ Stream.of(merge)));
}
@Test
@@ -123,7 +124,7 @@ public void unreachable_isLaterCommit() throws Exception {
ReachabilityChecker checker = getChecker(repo);
assertUnreachable("unreachable from the future",
- checker.areAllReachable(Arrays.asList(b2), Arrays.asList(b1)));
+ checker.areAllReachable(Arrays.asList(b2), Stream.of(b1)));
}
@Test
@@ -137,7 +138,7 @@ public void unreachable_differentBranch() throws Exception {
ReachabilityChecker checker = getChecker(repo);
assertUnreachable("unreachable from different branch",
- checker.areAllReachable(Arrays.asList(c1), Arrays.asList(b2)));
+ checker.areAllReachable(Arrays.asList(c1), Stream.of(b2)));
}
@Test
@@ -152,7 +153,7 @@ public void reachable_longChain() throws Exception {
ReachabilityChecker checker = getChecker(repo);
assertReachable("reachable with long chain in the middle", checker
- .areAllReachable(Arrays.asList(root), Arrays.asList(head)));
+ .areAllReachable(Arrays.asList(root), Stream.of(head)));
}
private static void assertReachable(String msg,
@@ -164,5 +165,4 @@ private static void assertUnreachable(String msg,
Optional<RevCommit> result) {
assertTrue(msg, result.isPresent());
}
-
}
diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/revwalk/RevCommitParseTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/revwalk/RevCommitParseTest.java
index b814984..d6b63ab 100644
--- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/revwalk/RevCommitParseTest.java
+++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/revwalk/RevCommitParseTest.java
@@ -107,18 +107,18 @@ public void testParse_NoParents() throws Exception {
body.append("\n");
- final RevWalk rw = new RevWalk(db);
final RevCommit c;
c = new RevCommit(id("9473095c4cb2f12aefe1db8a355fe3fafba42f67"));
assertNull(c.getTree());
assertNull(c.parents);
- c.parseCanonical(rw, body.toString().getBytes(UTF_8));
- assertNotNull(c.getTree());
- assertEquals(treeId, c.getTree().getId());
- assertSame(rw.lookupTree(treeId), c.getTree());
-
+ try (RevWalk rw = new RevWalk(db)) {
+ c.parseCanonical(rw, body.toString().getBytes(UTF_8));
+ assertNotNull(c.getTree());
+ assertEquals(treeId, c.getTree().getId());
+ assertSame(rw.lookupTree(treeId), c.getTree());
+ }
assertNotNull(c.parents);
assertEquals(0, c.parents.length);
assertEquals("", c.getFullMessage());
@@ -148,8 +148,10 @@ private RevCommit create(String msg) throws Exception {
final RevCommit c;
c = new RevCommit(id("9473095c4cb2f12aefe1db8a355fe3fafba42f67"));
- c.parseCanonical(new RevWalk(db), b.toString().getBytes(UTF_8));
- return c;
+ try (RevWalk rw = new RevWalk(db)) {
+ c.parseCanonical(rw, b.toString().getBytes(UTF_8));
+ return c;
+ }
}
@Test
@@ -161,8 +163,9 @@ public void testParse_WeirdHeaderOnlyCommit() throws Exception {
final RevCommit c;
c = new RevCommit(id("9473095c4cb2f12aefe1db8a355fe3fafba42f67"));
- c.parseCanonical(new RevWalk(db), b.toString().getBytes(UTF_8));
-
+ try (RevWalk rw = new RevWalk(db)) {
+ c.parseCanonical(rw, b.toString().getBytes(UTF_8));
+ }
assertEquals("", c.getFullMessage());
assertEquals("", c.getShortMessage());
}
@@ -176,8 +179,9 @@ public void testParse_incompleteAuthorAndCommitter() throws Exception {
final RevCommit c;
c = new RevCommit(id("9473095c4cb2f12aefe1db8a355fe3fafba42f67"));
- c.parseCanonical(new RevWalk(db), b.toString().getBytes(UTF_8));
-
+ try (RevWalk rw = new RevWalk(db)) {
+ c.parseCanonical(rw, b.toString().getBytes(UTF_8));
+ }
assertEquals(new PersonIdent("", "a_u_thor@example.com", 1218123387000l, 7), c.getAuthorIdent());
assertEquals(new PersonIdent("", "", 1218123390000l, -5), c.getCommitterIdent());
}
@@ -194,8 +198,9 @@ public void testParse_implicit_UTF8_encoded() throws Exception {
b.write("\u304d\u308c\u3044\n".getBytes(UTF_8));
final RevCommit c;
c = new RevCommit(id("9473095c4cb2f12aefe1db8a355fe3fafba42f67")); // bogus id
- c.parseCanonical(new RevWalk(db), b.toByteArray());
-
+ try (RevWalk rw = new RevWalk(db)) {
+ c.parseCanonical(rw, b.toByteArray());
+ }
assertSame(UTF_8, c.getEncoding());
assertEquals("F\u00f6r fattare", c.getAuthorIdent().getName());
assertEquals("Sm\u00f6rg\u00e5sbord", c.getShortMessage());
@@ -214,8 +219,9 @@ public void testParse_implicit_mixed_encoded() throws Exception {
b.write("\u304d\u308c\u3044\n".getBytes(UTF_8));
final RevCommit c;
c = new RevCommit(id("9473095c4cb2f12aefe1db8a355fe3fafba42f67")); // bogus id
- c.parseCanonical(new RevWalk(db), b.toByteArray());
-
+ try (RevWalk rw = new RevWalk(db)) {
+ c.parseCanonical(rw, b.toByteArray());
+ }
assertSame(UTF_8, c.getEncoding());
assertEquals("F\u00f6r fattare", c.getAuthorIdent().getName());
assertEquals("Sm\u00f6rg\u00e5sbord", c.getShortMessage());
@@ -240,7 +246,9 @@ public void testParse_explicit_encoded() throws Exception {
b.write("Hi\n".getBytes("EUC-JP"));
final RevCommit c;
c = new RevCommit(id("9473095c4cb2f12aefe1db8a355fe3fafba42f67")); // bogus id
- c.parseCanonical(new RevWalk(db), b.toByteArray());
+ try (RevWalk rw = new RevWalk(db)) {
+ c.parseCanonical(rw, b.toByteArray());
+ }
assertEquals("EUC-JP", c.getEncoding().name());
assertEquals("F\u00f6r fattare", c.getAuthorIdent().getName());
@@ -270,7 +278,9 @@ public void testParse_explicit_bad_encoded() throws Exception {
b.write("Hi\n".getBytes(UTF_8));
final RevCommit c;
c = new RevCommit(id("9473095c4cb2f12aefe1db8a355fe3fafba42f67")); // bogus id
- c.parseCanonical(new RevWalk(db), b.toByteArray());
+ try (RevWalk rw = new RevWalk(db)) {
+ c.parseCanonical(rw, b.toByteArray());
+ }
assertEquals("EUC-JP", c.getEncoding().name());
assertEquals("F\u00f6r fattare", c.getAuthorIdent().getName());
@@ -301,7 +311,9 @@ public void testParse_explicit_bad_encoded2() throws Exception {
b.write("Hi\n".getBytes(UTF_8));
final RevCommit c;
c = new RevCommit(id("9473095c4cb2f12aefe1db8a355fe3fafba42f67")); // bogus id
- c.parseCanonical(new RevWalk(db), b.toByteArray());
+ try (RevWalk rw = new RevWalk(db)) {
+ c.parseCanonical(rw, b.toByteArray());
+ }
assertEquals("ISO-8859-1", c.getEncoding().name());
assertEquals("F\u00f6r fattare", c.getAuthorIdent().getName());
@@ -323,7 +335,9 @@ public void testParse_incorrectUtf8Name() throws Exception {
RevCommit c = new RevCommit(
id("9473095c4cb2f12aefe1db8a355fe3fafba42f67"));
- c.parseCanonical(new RevWalk(db), b.toByteArray());
+ try (RevWalk rw = new RevWalk(db)) {
+ c.parseCanonical(rw, b.toByteArray());
+ }
assertEquals("'utf8'", c.getEncodingName());
assertEquals("Sm\u00f6rg\u00e5sbord\n", c.getFullMessage());
@@ -347,7 +361,9 @@ public void testParse_illegalEncoding() throws Exception {
RevCommit c = new RevCommit(
id("9473095c4cb2f12aefe1db8a355fe3fafba42f67"));
- c.parseCanonical(new RevWalk(db), b.toByteArray());
+ try (RevWalk rw = new RevWalk(db)) {
+ c.parseCanonical(rw, b.toByteArray());
+ }
assertEquals("utf-8logoutputencoding=gbk", c.getEncodingName());
assertEquals("message\n", c.getFullMessage());
assertEquals("message", c.getShortMessage());
@@ -374,7 +390,9 @@ public void testParse_unsupportedEncoding() throws Exception {
RevCommit c = new RevCommit(
id("9473095c4cb2f12aefe1db8a355fe3fafba42f67"));
- c.parseCanonical(new RevWalk(db), b.toByteArray());
+ try (RevWalk rw = new RevWalk(db)) {
+ c.parseCanonical(rw, b.toByteArray());
+ }
assertEquals("it_IT.UTF8", c.getEncodingName());
assertEquals("message\n", c.getFullMessage());
assertEquals("message", c.getShortMessage());
@@ -507,7 +525,9 @@ public void testParse_gpgSig() throws Exception {
final RevCommit c;
c = new RevCommit(id("9473095c4cb2f12aefe1db8a355fe3fafba42f67"));
- c.parseCanonical(new RevWalk(db), commit.getBytes(UTF_8));
+ try (RevWalk rw = new RevWalk(db)) {
+ c.parseCanonical(rw, commit.getBytes(UTF_8));
+ }
String gpgSig = new String(c.getRawGpgSignature(), UTF_8);
assertTrue(gpgSig.startsWith("-----BEGIN"));
assertTrue(gpgSig.endsWith("END PGP SIGNATURE-----"));
diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/revwalk/RevTagParseTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/revwalk/RevTagParseTest.java
index 1b45473..bbc559b 100644
--- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/revwalk/RevTagParseTest.java
+++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/revwalk/RevTagParseTest.java
@@ -91,17 +91,18 @@ private void testOneType(int typeCode) throws Exception {
b.append("tagger A U. Thor <a_u_thor@example.com> 1218123387 +0700\n");
b.append("\n");
- final RevWalk rw = new RevWalk(db);
final RevTag c;
c = new RevTag(id("9473095c4cb2f12aefe1db8a355fe3fafba42f67"));
assertNull(c.getObject());
assertNull(c.getTagName());
- c.parseCanonical(rw, b.toString().getBytes(UTF_8));
- assertNotNull(c.getObject());
- assertEquals(id, c.getObject().getId());
- assertSame(rw.lookupAny(id, typeCode), c.getObject());
+ try (RevWalk rw = new RevWalk(db)) {
+ c.parseCanonical(rw, b.toString().getBytes(UTF_8));
+ assertNotNull(c.getObject());
+ assertEquals(id, c.getObject().getId());
+ assertSame(rw.lookupAny(id, typeCode), c.getObject());
+ }
}
@Test
@@ -134,18 +135,18 @@ public void testParseAllFields() throws Exception {
body.append("\n");
- final RevWalk rw = new RevWalk(db);
final RevTag c;
c = new RevTag(id("9473095c4cb2f12aefe1db8a355fe3fafba42f67"));
assertNull(c.getObject());
assertNull(c.getTagName());
- c.parseCanonical(rw, body.toString().getBytes(UTF_8));
- assertNotNull(c.getObject());
- assertEquals(treeId, c.getObject().getId());
- assertSame(rw.lookupTree(treeId), c.getObject());
-
+ try (RevWalk rw = new RevWalk(db)) {
+ c.parseCanonical(rw, body.toString().getBytes(UTF_8));
+ assertNotNull(c.getObject());
+ assertEquals(treeId, c.getObject().getId());
+ assertSame(rw.lookupTree(treeId), c.getObject());
+ }
assertNotNull(c.getTagName());
assertEquals(name, c.getTagName());
assertEquals("", c.getFullMessage());
@@ -182,17 +183,18 @@ public void testParseOldStyleNoTagger() throws Exception {
body.append("\n");
body.append(message);
- final RevWalk rw = new RevWalk(db);
final RevTag c;
c = new RevTag(id("9473095c4cb2f12aefe1db8a355fe3fafba42f67"));
assertNull(c.getObject());
assertNull(c.getTagName());
- c.parseCanonical(rw, body.toString().getBytes(UTF_8));
- assertNotNull(c.getObject());
- assertEquals(treeId, c.getObject().getId());
- assertSame(rw.lookupTree(treeId), c.getObject());
+ try (RevWalk rw = new RevWalk(db)) {
+ c.parseCanonical(rw, body.toString().getBytes(UTF_8));
+ assertNotNull(c.getObject());
+ assertEquals(treeId, c.getObject().getId());
+ assertSame(rw.lookupTree(treeId), c.getObject());
+ }
assertNotNull(c.getTagName());
assertEquals(name, c.getTagName());
@@ -213,7 +215,9 @@ private RevTag create(String msg) throws Exception {
final RevTag c;
c = new RevTag(id("9473095c4cb2f12aefe1db8a355fe3fafba42f67"));
- c.parseCanonical(new RevWalk(db), b.toString().getBytes(UTF_8));
+ try (RevWalk rw = new RevWalk(db)) {
+ c.parseCanonical(rw, b.toString().getBytes(UTF_8));
+ }
return c;
}
@@ -234,7 +238,9 @@ public void testParse_implicit_UTF8_encoded() throws Exception {
b.write("\u304d\u308c\u3044\n".getBytes(UTF_8));
final RevTag c;
c = new RevTag(id("9473095c4cb2f12aefe1db8a355fe3fafba42f67"));
- c.parseCanonical(new RevWalk(db), b.toByteArray());
+ try (RevWalk rw = new RevWalk(db)) {
+ c.parseCanonical(rw, b.toByteArray());
+ }
assertEquals("F\u00f6r fattare", c.getTaggerIdent().getName());
assertEquals("Sm\u00f6rg\u00e5sbord", c.getShortMessage());
@@ -257,7 +263,9 @@ public void testParse_implicit_mixed_encoded() throws Exception {
b.write("\u304d\u308c\u3044\n".getBytes(UTF_8));
final RevTag c;
c = new RevTag(id("9473095c4cb2f12aefe1db8a355fe3fafba42f67"));
- c.parseCanonical(new RevWalk(db), b.toByteArray());
+ try (RevWalk rw = new RevWalk(db)) {
+ c.parseCanonical(rw, b.toByteArray());
+ }
assertEquals("F\u00f6r fattare", c.getTaggerIdent().getName());
assertEquals("Sm\u00f6rg\u00e5sbord", c.getShortMessage());
@@ -287,7 +295,9 @@ public void testParse_explicit_encoded() throws Exception {
b.write("Hi\n".getBytes("EUC-JP"));
final RevTag c;
c = new RevTag(id("9473095c4cb2f12aefe1db8a355fe3fafba42f67"));
- c.parseCanonical(new RevWalk(db), b.toByteArray());
+ try (RevWalk rw = new RevWalk(db)) {
+ c.parseCanonical(rw, b.toByteArray());
+ }
assertEquals("F\u00f6r fattare", c.getTaggerIdent().getName());
assertEquals("\u304d\u308c\u3044", c.getShortMessage());
@@ -320,7 +330,9 @@ public void testParse_explicit_bad_encoded() throws Exception {
b.write("Hi\n".getBytes(UTF_8));
final RevTag c;
c = new RevTag(id("9473095c4cb2f12aefe1db8a355fe3fafba42f67"));
- c.parseCanonical(new RevWalk(db), b.toByteArray());
+ try (RevWalk rw = new RevWalk(db)) {
+ c.parseCanonical(rw, b.toByteArray());
+ }
assertEquals("F\u00f6r fattare", c.getTaggerIdent().getName());
assertEquals("\u304d\u308c\u3044", c.getShortMessage());
@@ -355,7 +367,9 @@ public void testParse_explicit_bad_encoded2() throws Exception {
b.write("Hi\n".getBytes(UTF_8));
final RevTag c;
c = new RevTag(id("9473095c4cb2f12aefe1db8a355fe3fafba42f67"));
- c.parseCanonical(new RevWalk(db), b.toByteArray());
+ try (RevWalk rw = new RevWalk(db)) {
+ c.parseCanonical(rw, b.toByteArray());
+ }
assertEquals("F\u00f6r fattare", c.getTaggerIdent().getName());
assertEquals("\u304d\u308c\u3044", c.getShortMessage());
@@ -374,7 +388,9 @@ public void testParse_illegalEncoding() throws Exception {
b.write("message\n".getBytes(UTF_8));
RevTag t = new RevTag(id("9473095c4cb2f12aefe1db8a355fe3fafba42f67"));
- t.parseCanonical(new RevWalk(db), b.toByteArray());
+ try (RevWalk rw = new RevWalk(db)) {
+ t.parseCanonical(rw, b.toByteArray());
+ }
assertEquals("t", t.getTaggerIdent().getName());
assertEquals("message", t.getShortMessage());
@@ -393,7 +409,9 @@ public void testParse_unsupportedEncoding() throws Exception {
b.write("message\n".getBytes(UTF_8));
RevTag t = new RevTag(id("9473095c4cb2f12aefe1db8a355fe3fafba42f67"));
- t.parseCanonical(new RevWalk(db), b.toByteArray());
+ try (RevWalk rw = new RevWalk(db)) {
+ t.parseCanonical(rw, b.toByteArray());
+ }
assertEquals("t", t.getTaggerIdent().getName());
assertEquals("message", t.getShortMessage());
diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/revwalk/TreeRevFilterTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/revwalk/TreeRevFilterTest.java
index 9548992..a345459 100644
--- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/revwalk/TreeRevFilterTest.java
+++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/revwalk/TreeRevFilterTest.java
@@ -46,25 +46,15 @@
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNull;
-import java.util.Collections;
-
import org.eclipse.jgit.revwalk.filter.OrRevFilter;
import org.eclipse.jgit.revwalk.filter.RevFilter;
import org.eclipse.jgit.revwalk.filter.SkipRevFilter;
-import org.eclipse.jgit.treewalk.filter.AndTreeFilter;
-import org.eclipse.jgit.treewalk.filter.PathFilterGroup;
import org.eclipse.jgit.treewalk.filter.TreeFilter;
import org.junit.Test;
public class TreeRevFilterTest extends RevWalkTestCase {
- private RevFilter treeRevFilter(String path) {
- return new TreeRevFilter(rw, treeFilter(path));
- }
-
- private static TreeFilter treeFilter(String path) {
- return AndTreeFilter.create(
- PathFilterGroup.createFromStrings(Collections.singleton(path)),
- TreeFilter.ANY_DIFF);
+ private RevFilter treeRevFilter() {
+ return new TreeRevFilter(rw, TreeFilter.ANY_DIFF);
}
@Test
@@ -73,7 +63,7 @@ public void testStringOfPearls_FilePath1()
RevCommit a = commit(tree(file("d/f", blob("a"))));
RevCommit b = commit(tree(file("d/f", blob("a"))), a);
RevCommit c = commit(tree(file("d/f", blob("b"))), b);
- rw.setRevFilter(treeRevFilter("d/f"));
+ rw.setRevFilter(treeRevFilter());
markStart(c);
assertCommit(c, rw.next());
@@ -91,7 +81,7 @@ public void testStringOfPearls_FilePath2() throws Exception {
RevCommit b = commit(tree(file("d/f", blob("a"))), a);
RevCommit c = commit(tree(file("d/f", blob("b"))), b);
RevCommit d = commit(tree(file("d/f", blob("b"))), c);
- rw.setRevFilter(treeRevFilter("d/f"));
+ rw.setRevFilter(treeRevFilter());
markStart(d);
// d was skipped
@@ -111,7 +101,7 @@ public void testStringOfPearls_DirPath2() throws Exception {
RevCommit b = commit(tree(file("d/f", blob("a"))), a);
RevCommit c = commit(tree(file("d/f", blob("b"))), b);
RevCommit d = commit(tree(file("d/f", blob("b"))), c);
- rw.setRevFilter(treeRevFilter("d"));
+ rw.setRevFilter(treeRevFilter());
markStart(d);
// d was skipped
@@ -136,7 +126,7 @@ public void testStringOfPearls_FilePath3() throws Exception {
RevCommit g = commit(tree(file("d/f", blob("b"))), f);
RevCommit h = commit(tree(file("d/f", blob("b"))), g);
RevCommit i = commit(tree(file("d/f", blob("c"))), h);
- rw.setRevFilter(treeRevFilter("d/f"));
+ rw.setRevFilter(treeRevFilter());
markStart(i);
assertCommit(i, rw.next());
@@ -156,7 +146,7 @@ public void testStringOfPearls_FilePath3() throws Exception {
@Test
public void testPathFilterOrOtherFilter() throws Exception {
- RevFilter pathFilter = treeRevFilter("d/f");
+ RevFilter pathFilter = treeRevFilter();
RevFilter skipFilter = SkipRevFilter.create(1);
RevFilter orFilter = OrRevFilter.create(skipFilter, pathFilter);
diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/submodule/SubmoduleAddTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/submodule/SubmoduleAddTest.java
index 1ff64a2..80e9e6b 100644
--- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/submodule/SubmoduleAddTest.java
+++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/submodule/SubmoduleAddTest.java
@@ -135,20 +135,20 @@ public void addSubmodule() throws Exception {
subCommit = repo.resolve(Constants.HEAD);
}
- SubmoduleWalk generator = SubmoduleWalk.forIndex(db);
- generator.loadModulesConfig();
- assertTrue(generator.next());
- assertEquals(path, generator.getModuleName());
- assertEquals(path, generator.getPath());
- assertEquals(commit, generator.getObjectId());
- assertEquals(uri, generator.getModulesUrl());
- assertEquals(path, generator.getModulesPath());
- assertEquals(uri, generator.getConfigUrl());
- try (Repository subModRepo = generator.getRepository()) {
- assertNotNull(subModRepo);
- assertEquals(subCommit, commit);
+ try (SubmoduleWalk generator = SubmoduleWalk.forIndex(db)) {
+ generator.loadModulesConfig();
+ assertTrue(generator.next());
+ assertEquals(path, generator.getModuleName());
+ assertEquals(path, generator.getPath());
+ assertEquals(commit, generator.getObjectId());
+ assertEquals(uri, generator.getModulesUrl());
+ assertEquals(path, generator.getModulesPath());
+ assertEquals(uri, generator.getConfigUrl());
+ try (Repository subModRepo = generator.getRepository()) {
+ assertNotNull(subModRepo);
+ assertEquals(subCommit, commit);
+ }
}
-
Status status = Git.wrap(db).status().call();
assertTrue(status.getAdded().contains(Constants.DOT_GIT_MODULES));
assertTrue(status.getAdded().contains(path));
@@ -175,20 +175,20 @@ public void addSubmoduleWithName() throws Exception {
subCommit = repo.resolve(Constants.HEAD);
}
- SubmoduleWalk generator = SubmoduleWalk.forIndex(db);
- generator.loadModulesConfig();
- assertTrue(generator.next());
- assertEquals(name, generator.getModuleName());
- assertEquals(path, generator.getPath());
- assertEquals(commit, generator.getObjectId());
- assertEquals(uri, generator.getModulesUrl());
- assertEquals(path, generator.getModulesPath());
- assertEquals(uri, generator.getConfigUrl());
- try (Repository subModRepo = generator.getRepository()) {
- assertNotNull(subModRepo);
- assertEquals(subCommit, commit);
+ try (SubmoduleWalk generator = SubmoduleWalk.forIndex(db)) {
+ generator.loadModulesConfig();
+ assertTrue(generator.next());
+ assertEquals(name, generator.getModuleName());
+ assertEquals(path, generator.getPath());
+ assertEquals(commit, generator.getObjectId());
+ assertEquals(uri, generator.getModulesUrl());
+ assertEquals(path, generator.getModulesPath());
+ assertEquals(uri, generator.getConfigUrl());
+ try (Repository subModRepo = generator.getRepository()) {
+ assertNotNull(subModRepo);
+ assertEquals(subCommit, commit);
+ }
}
-
Status status = Git.wrap(db).status().call();
assertTrue(status.getAdded().contains(Constants.DOT_GIT_MODULES));
assertTrue(status.getAdded().contains(path));
@@ -269,24 +269,25 @@ public void addSubmoduleWithRelativeUri() throws Exception {
assertNotNull(repo);
addRepoToClose(repo);
- SubmoduleWalk generator = SubmoduleWalk.forIndex(db);
- assertTrue(generator.next());
- assertEquals(path, generator.getPath());
- assertEquals(commit, generator.getObjectId());
- assertEquals(uri, generator.getModulesUrl());
- assertEquals(path, generator.getModulesPath());
- String fullUri = db.getDirectory().getAbsolutePath();
- if (File.separatorChar == '\\') {
- fullUri = fullUri.replace('\\', '/');
- }
- assertEquals(fullUri, generator.getConfigUrl());
- try (Repository subModRepo = generator.getRepository()) {
- assertNotNull(subModRepo);
- assertEquals(fullUri,
- subModRepo.getConfig().getString(
- ConfigConstants.CONFIG_REMOTE_SECTION,
- Constants.DEFAULT_REMOTE_NAME,
- ConfigConstants.CONFIG_KEY_URL));
+ try (SubmoduleWalk generator = SubmoduleWalk.forIndex(db)) {
+ assertTrue(generator.next());
+ assertEquals(path, generator.getPath());
+ assertEquals(commit, generator.getObjectId());
+ assertEquals(uri, generator.getModulesUrl());
+ assertEquals(path, generator.getModulesPath());
+ String fullUri = db.getDirectory().getAbsolutePath();
+ if (File.separatorChar == '\\') {
+ fullUri = fullUri.replace('\\', '/');
+ }
+ assertEquals(fullUri, generator.getConfigUrl());
+ try (Repository subModRepo = generator.getRepository()) {
+ assertNotNull(subModRepo);
+ assertEquals(fullUri,
+ subModRepo.getConfig().getString(
+ ConfigConstants.CONFIG_REMOTE_SECTION,
+ Constants.DEFAULT_REMOTE_NAME,
+ ConfigConstants.CONFIG_KEY_URL));
+ }
}
assertEquals(commit, repo.resolve(Constants.HEAD));
diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/submodule/SubmoduleDeinitTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/submodule/SubmoduleDeinitTest.java
index 815ce9b..bb00851 100644
--- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/submodule/SubmoduleDeinitTest.java
+++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/submodule/SubmoduleDeinitTest.java
@@ -107,7 +107,6 @@ public void dirtySubmoduleBecauseUntracked() throws Exception {
assertEquals(1, updated.size());
File submoduleDir = assertSubmoduleIsInitialized();
- SubmoduleWalk generator;
write(new File(submoduleDir, "untracked"), "untracked");
@@ -115,8 +114,9 @@ public void dirtySubmoduleBecauseUntracked() throws Exception {
assertEquals(path, result.getPath());
assertEquals(SubmoduleDeinitCommand.SubmoduleDeinitStatus.DIRTY, result.getStatus());
- generator = SubmoduleWalk.forIndex(db);
- assertTrue(generator.next());
+ try (SubmoduleWalk generator = SubmoduleWalk.forIndex(db)) {
+ assertTrue(generator.next());
+ }
assertTrue(submoduleDir.isDirectory());
assertNotEquals(0, submoduleDir.list().length);
}
@@ -132,33 +132,36 @@ public void dirtySubmoduleBecauseNewCommit() throws Exception {
assertEquals(1, updated.size());
File submoduleDir = assertSubmoduleIsInitialized();
- SubmoduleWalk generator = SubmoduleWalk.forIndex(db);
- generator.next();
+ try (SubmoduleWalk generator = SubmoduleWalk.forIndex(db)) {
+ generator.next();
- //want to create a commit inside the repo...
- try (Repository submoduleLocalRepo = generator.getRepository()) {
- JGitTestUtil.writeTrashFile(submoduleLocalRepo, "file.txt",
- "new data");
- Git.wrap(submoduleLocalRepo).commit().setAll(true)
- .setMessage("local commit").call();
+ // want to create a commit inside the repo...
+ try (Repository submoduleLocalRepo = generator.getRepository()) {
+ JGitTestUtil.writeTrashFile(submoduleLocalRepo, "file.txt",
+ "new data");
+ Git.wrap(submoduleLocalRepo).commit().setAll(true)
+ .setMessage("local commit").call();
+ }
}
SubmoduleDeinitResult result = runDeinit(new SubmoduleDeinitCommand(db).addPath("sub"));
assertEquals(path, result.getPath());
assertEquals(SubmoduleDeinitCommand.SubmoduleDeinitStatus.DIRTY, result.getStatus());
- generator = SubmoduleWalk.forIndex(db);
- assertTrue(generator.next());
+ try (SubmoduleWalk generator = SubmoduleWalk.forIndex(db)) {
+ assertTrue(generator.next());
+ }
assertTrue(submoduleDir.isDirectory());
assertNotEquals(0, submoduleDir.list().length);
}
private File assertSubmoduleIsInitialized() throws IOException {
- SubmoduleWalk generator = SubmoduleWalk.forIndex(db);
- assertTrue(generator.next());
- File submoduleDir = new File(db.getWorkTree(), generator.getPath());
- assertTrue(submoduleDir.isDirectory());
- assertNotEquals(0, submoduleDir.list().length);
- return submoduleDir;
+ try (SubmoduleWalk generator = SubmoduleWalk.forIndex(db)) {
+ assertTrue(generator.next());
+ File submoduleDir = new File(db.getWorkTree(), generator.getPath());
+ assertTrue(submoduleDir.isDirectory());
+ assertNotEquals(0, submoduleDir.list().length);
+ return submoduleDir;
+ }
}
@Test
@@ -180,8 +183,9 @@ public void dirtySubmoduleWithForce() throws Exception {
assertEquals(path, result.getPath());
assertEquals(SubmoduleDeinitCommand.SubmoduleDeinitStatus.FORCED, result.getStatus());
- SubmoduleWalk generator = SubmoduleWalk.forIndex(db);
- assertTrue(generator.next());
+ try (SubmoduleWalk generator = SubmoduleWalk.forIndex(db)) {
+ assertTrue(generator.next());
+ }
assertTrue(submoduleDir.isDirectory());
assertEquals(0, submoduleDir.list().length);
}
@@ -202,8 +206,9 @@ public void cleanSubmodule() throws Exception {
assertEquals(path, result.getPath());
assertEquals(SubmoduleDeinitCommand.SubmoduleDeinitStatus.SUCCESS, result.getStatus());
- SubmoduleWalk generator = SubmoduleWalk.forIndex(db);
- assertTrue(generator.next());
+ try (SubmoduleWalk generator = SubmoduleWalk.forIndex(db)) {
+ assertTrue(generator.next());
+ }
assertTrue(submoduleDir.isDirectory());
assertEquals(0, submoduleDir.list().length);
}
diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/submodule/SubmoduleInitTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/submodule/SubmoduleInitTest.java
index c7a009c..9fe2fc6 100644
--- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/submodule/SubmoduleInitTest.java
+++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/submodule/SubmoduleInitTest.java
@@ -86,11 +86,11 @@ public void repositoryWithUninitializedModule() throws IOException,
ConfigInvalidException, GitAPIException {
final String path = addSubmoduleToIndex();
- SubmoduleWalk generator = SubmoduleWalk.forIndex(db);
- assertTrue(generator.next());
- assertNull(generator.getConfigUrl());
- assertNull(generator.getConfigUpdate());
-
+ try (SubmoduleWalk generator = SubmoduleWalk.forIndex(db)) {
+ assertTrue(generator.next());
+ assertNull(generator.getConfigUrl());
+ assertNull(generator.getConfigUpdate());
+ }
FileBasedConfig modulesConfig = new FileBasedConfig(new File(
db.getWorkTree(), Constants.DOT_GIT_MODULES), db.getFS());
modulesConfig.setString(ConfigConstants.CONFIG_SUBMODULE_SECTION, path,
@@ -109,10 +109,11 @@ public void repositoryWithUninitializedModule() throws IOException,
assertEquals(1, modules.size());
assertEquals(path, modules.iterator().next());
- generator = SubmoduleWalk.forIndex(db);
- assertTrue(generator.next());
- assertEquals(url, generator.getConfigUrl());
- assertEquals(update, generator.getConfigUpdate());
+ try (SubmoduleWalk generator = SubmoduleWalk.forIndex(db)) {
+ assertTrue(generator.next());
+ assertEquals(url, generator.getConfigUrl());
+ assertEquals(update, generator.getConfigUpdate());
+ }
}
@Test
@@ -126,11 +127,11 @@ public void resolveSameLevelRelativeUrl() throws Exception {
base);
config.save();
- SubmoduleWalk generator = SubmoduleWalk.forIndex(db);
- assertTrue(generator.next());
- assertNull(generator.getConfigUrl());
- assertNull(generator.getConfigUpdate());
-
+ try (SubmoduleWalk generator = SubmoduleWalk.forIndex(db)) {
+ assertTrue(generator.next());
+ assertNull(generator.getConfigUrl());
+ assertNull(generator.getConfigUpdate());
+ }
FileBasedConfig modulesConfig = new FileBasedConfig(new File(
db.getWorkTree(), Constants.DOT_GIT_MODULES), db.getFS());
modulesConfig.setString(ConfigConstants.CONFIG_SUBMODULE_SECTION, path,
@@ -149,10 +150,12 @@ public void resolveSameLevelRelativeUrl() throws Exception {
assertEquals(1, modules.size());
assertEquals(path, modules.iterator().next());
- generator = SubmoduleWalk.forIndex(db);
- assertTrue(generator.next());
- assertEquals("git://server/repo.git/sub.git", generator.getConfigUrl());
- assertEquals(update, generator.getConfigUpdate());
+ try (SubmoduleWalk generator = SubmoduleWalk.forIndex(db)) {
+ assertTrue(generator.next());
+ assertEquals("git://server/repo.git/sub.git",
+ generator.getConfigUrl());
+ assertEquals(update, generator.getConfigUpdate());
+ }
}
@Test
@@ -167,11 +170,11 @@ public void resolveOneLevelHigherRelativeUrl() throws IOException,
base);
config.save();
- SubmoduleWalk generator = SubmoduleWalk.forIndex(db);
- assertTrue(generator.next());
- assertNull(generator.getConfigUrl());
- assertNull(generator.getConfigUpdate());
-
+ try (SubmoduleWalk generator = SubmoduleWalk.forIndex(db)) {
+ assertTrue(generator.next());
+ assertNull(generator.getConfigUrl());
+ assertNull(generator.getConfigUpdate());
+ }
FileBasedConfig modulesConfig = new FileBasedConfig(new File(
db.getWorkTree(), Constants.DOT_GIT_MODULES), db.getFS());
modulesConfig.setString(ConfigConstants.CONFIG_SUBMODULE_SECTION, path,
@@ -190,10 +193,11 @@ public void resolveOneLevelHigherRelativeUrl() throws IOException,
assertEquals(1, modules.size());
assertEquals(path, modules.iterator().next());
- generator = SubmoduleWalk.forIndex(db);
- assertTrue(generator.next());
- assertEquals("git://server/sub.git", generator.getConfigUrl());
- assertEquals(update, generator.getConfigUpdate());
+ try (SubmoduleWalk generator = SubmoduleWalk.forIndex(db)) {
+ assertTrue(generator.next());
+ assertEquals("git://server/sub.git", generator.getConfigUrl());
+ assertEquals(update, generator.getConfigUpdate());
+ }
}
@Test
@@ -208,11 +212,11 @@ public void resolveTwoLevelHigherRelativeUrl() throws IOException,
base);
config.save();
- SubmoduleWalk generator = SubmoduleWalk.forIndex(db);
- assertTrue(generator.next());
- assertNull(generator.getConfigUrl());
- assertNull(generator.getConfigUpdate());
-
+ try (SubmoduleWalk generator = SubmoduleWalk.forIndex(db)) {
+ assertTrue(generator.next());
+ assertNull(generator.getConfigUrl());
+ assertNull(generator.getConfigUpdate());
+ }
FileBasedConfig modulesConfig = new FileBasedConfig(new File(
db.getWorkTree(), Constants.DOT_GIT_MODULES), db.getFS());
modulesConfig.setString(ConfigConstants.CONFIG_SUBMODULE_SECTION, path,
@@ -231,10 +235,11 @@ public void resolveTwoLevelHigherRelativeUrl() throws IOException,
assertEquals(1, modules.size());
assertEquals(path, modules.iterator().next());
- generator = SubmoduleWalk.forIndex(db);
- assertTrue(generator.next());
- assertEquals("git://server2/sub.git", generator.getConfigUrl());
- assertEquals(update, generator.getConfigUpdate());
+ try (SubmoduleWalk generator = SubmoduleWalk.forIndex(db)) {
+ assertTrue(generator.next());
+ assertEquals("git://server2/sub.git", generator.getConfigUrl());
+ assertEquals(update, generator.getConfigUpdate());
+ }
}
@Test
@@ -250,11 +255,11 @@ public void resolveWorkingDirectoryRelativeUrl() throws IOException,
Constants.DEFAULT_REMOTE_NAME, ConfigConstants.CONFIG_KEY_URL);
config.save();
- SubmoduleWalk generator = SubmoduleWalk.forIndex(db);
- assertTrue(generator.next());
- assertNull(generator.getConfigUrl());
- assertNull(generator.getConfigUpdate());
-
+ try (SubmoduleWalk generator = SubmoduleWalk.forIndex(db)) {
+ assertTrue(generator.next());
+ assertNull(generator.getConfigUrl());
+ assertNull(generator.getConfigUpdate());
+ }
FileBasedConfig modulesConfig = new FileBasedConfig(new File(
db.getWorkTree(), Constants.DOT_GIT_MODULES), db.getFS());
modulesConfig.setString(ConfigConstants.CONFIG_SUBMODULE_SECTION, path,
@@ -273,10 +278,11 @@ public void resolveWorkingDirectoryRelativeUrl() throws IOException,
assertEquals(1, modules.size());
assertEquals(path, modules.iterator().next());
- generator = SubmoduleWalk.forIndex(db);
- assertTrue(generator.next());
- assertEquals(base + "/sub.git", generator.getConfigUrl());
- assertEquals(update, generator.getConfigUpdate());
+ try (SubmoduleWalk generator = SubmoduleWalk.forIndex(db)) {
+ assertTrue(generator.next());
+ assertEquals(base + "/sub.git", generator.getConfigUrl());
+ assertEquals(update, generator.getConfigUpdate());
+ }
}
@Test
@@ -291,11 +297,11 @@ public void resolveInvalidParentUrl() throws IOException,
base);
config.save();
- SubmoduleWalk generator = SubmoduleWalk.forIndex(db);
- assertTrue(generator.next());
- assertNull(generator.getConfigUrl());
- assertNull(generator.getConfigUpdate());
-
+ try (SubmoduleWalk generator = SubmoduleWalk.forIndex(db)) {
+ assertTrue(generator.next());
+ assertNull(generator.getConfigUrl());
+ assertNull(generator.getConfigUpdate());
+ }
FileBasedConfig modulesConfig = new FileBasedConfig(new File(
db.getWorkTree(), Constants.DOT_GIT_MODULES), db.getFS());
modulesConfig.setString(ConfigConstants.CONFIG_SUBMODULE_SECTION, path,
diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/submodule/SubmoduleSyncTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/submodule/SubmoduleSyncTest.java
index 6f3b52f..1053e31 100644
--- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/submodule/SubmoduleSyncTest.java
+++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/submodule/SubmoduleSyncTest.java
@@ -119,11 +119,11 @@ public void apply(DirCacheEntry ent) {
addRepoToClose(subRepo);
assertNotNull(subRepo);
- SubmoduleWalk generator = SubmoduleWalk.forIndex(db);
- assertTrue(generator.next());
- assertNull(generator.getConfigUrl());
- assertEquals(url, generator.getModulesUrl());
-
+ try (SubmoduleWalk generator = SubmoduleWalk.forIndex(db)) {
+ assertTrue(generator.next());
+ assertNull(generator.getConfigUrl());
+ assertEquals(url, generator.getModulesUrl());
+ }
SubmoduleSyncCommand command = new SubmoduleSyncCommand(db);
Map<String, String> synced = command.call();
assertNotNull(synced);
@@ -132,16 +132,17 @@ public void apply(DirCacheEntry ent) {
assertEquals(path, module.getKey());
assertEquals(url, module.getValue());
- generator = SubmoduleWalk.forIndex(db);
- assertTrue(generator.next());
- assertEquals(url, generator.getConfigUrl());
- try (Repository subModRepository = generator.getRepository()) {
- StoredConfig submoduleConfig = subModRepository.getConfig();
- assertEquals(url,
- submoduleConfig.getString(
- ConfigConstants.CONFIG_REMOTE_SECTION,
- Constants.DEFAULT_REMOTE_NAME,
- ConfigConstants.CONFIG_KEY_URL));
+ try (SubmoduleWalk generator = SubmoduleWalk.forIndex(db)) {
+ assertTrue(generator.next());
+ assertEquals(url, generator.getConfigUrl());
+ try (Repository subModRepository = generator.getRepository()) {
+ StoredConfig submoduleConfig = subModRepository.getConfig();
+ assertEquals(url,
+ submoduleConfig.getString(
+ ConfigConstants.CONFIG_REMOTE_SECTION,
+ Constants.DEFAULT_REMOTE_NAME,
+ ConfigConstants.CONFIG_KEY_URL));
+ }
}
}
@@ -190,11 +191,11 @@ public void apply(DirCacheEntry ent) {
assertNotNull(subRepo);
addRepoToClose(subRepo);
- SubmoduleWalk generator = SubmoduleWalk.forIndex(db);
- assertTrue(generator.next());
- assertNull(generator.getConfigUrl());
- assertEquals(current, generator.getModulesUrl());
-
+ try (SubmoduleWalk generator = SubmoduleWalk.forIndex(db)) {
+ assertTrue(generator.next());
+ assertNull(generator.getConfigUrl());
+ assertEquals(current, generator.getModulesUrl());
+ }
modulesConfig.setString(ConfigConstants.CONFIG_SUBMODULE_SECTION, path,
ConfigConstants.CONFIG_KEY_URL, "../sub.git");
modulesConfig.save();
@@ -207,16 +208,17 @@ public void apply(DirCacheEntry ent) {
assertEquals(path, module.getKey());
assertEquals("git://server/sub.git", module.getValue());
- generator = SubmoduleWalk.forIndex(db);
- assertTrue(generator.next());
- assertEquals("git://server/sub.git", generator.getConfigUrl());
- try (Repository subModRepository1 = generator.getRepository()) {
- StoredConfig submoduleConfig = subModRepository1.getConfig();
- assertEquals("git://server/sub.git",
- submoduleConfig.getString(
- ConfigConstants.CONFIG_REMOTE_SECTION,
- Constants.DEFAULT_REMOTE_NAME,
- ConfigConstants.CONFIG_KEY_URL));
+ try (SubmoduleWalk generator = SubmoduleWalk.forIndex(db)) {
+ assertTrue(generator.next());
+ assertEquals("git://server/sub.git", generator.getConfigUrl());
+ try (Repository subModRepository1 = generator.getRepository()) {
+ StoredConfig submoduleConfig = subModRepository1.getConfig();
+ assertEquals("git://server/sub.git",
+ submoduleConfig.getString(
+ ConfigConstants.CONFIG_REMOTE_SECTION,
+ Constants.DEFAULT_REMOTE_NAME,
+ ConfigConstants.CONFIG_KEY_URL));
+ }
}
}
}
diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/submodule/SubmoduleUpdateTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/submodule/SubmoduleUpdateTest.java
index bbce413..6f358b4 100644
--- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/submodule/SubmoduleUpdateTest.java
+++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/submodule/SubmoduleUpdateTest.java
@@ -119,11 +119,12 @@ public void apply(DirCacheEntry ent) {
assertEquals(1, updated.size());
assertEquals(path, updated.iterator().next());
- SubmoduleWalk generator = SubmoduleWalk.forIndex(db);
- assertTrue(generator.next());
- try (Repository subRepo = generator.getRepository()) {
- assertNotNull(subRepo);
- assertEquals(commit, subRepo.resolve(Constants.HEAD));
+ try (SubmoduleWalk generator = SubmoduleWalk.forIndex(db)) {
+ assertTrue(generator.next());
+ try (Repository subRepo = generator.getRepository()) {
+ assertNotNull(subRepo);
+ assertEquals(commit, subRepo.resolve(Constants.HEAD));
+ }
}
}
@@ -181,10 +182,11 @@ public void apply(DirCacheEntry ent) {
});
editor.commit();
- Repository subRepo = Git.init().setBare(false)
+ try (Repository subRepo = Git.init().setBare(false)
.setDirectory(new File(db.getWorkTree(), path)).call()
- .getRepository();
- assertNotNull(subRepo);
+ .getRepository()) {
+ assertNotNull(subRepo);
+ }
SubmoduleUpdateCommand command = new SubmoduleUpdateCommand(db);
Collection<String> updated = command.call();
diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/submodule/SubmoduleWalkTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/submodule/SubmoduleWalkTest.java
index ea1ace3..0b6047f 100644
--- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/submodule/SubmoduleWalkTest.java
+++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/submodule/SubmoduleWalkTest.java
@@ -98,10 +98,11 @@ public void setUp() throws Exception {
@Test
public void repositoryWithNoSubmodules() throws IOException {
- SubmoduleWalk gen = SubmoduleWalk.forIndex(db);
- assertFalse(gen.next());
- assertNull(gen.getPath());
- assertEquals(ObjectId.zeroId(), gen.getObjectId());
+ try (SubmoduleWalk gen = SubmoduleWalk.forIndex(db)) {
+ assertFalse(gen.next());
+ assertNull(gen.getPath());
+ assertEquals(ObjectId.zeroId(), gen.getObjectId());
+ }
}
@Test
@@ -129,20 +130,21 @@ public void apply(DirCacheEntry ent) {
});
editor.commit();
- SubmoduleWalk gen = SubmoduleWalk.forIndex(db);
- assertTrue(gen.next());
- assertEquals(path, gen.getPath());
- assertEquals(id, gen.getObjectId());
- assertEquals(new File(db.getWorkTree(), path), gen.getDirectory());
- assertNull(gen.getConfigUpdate());
- assertNull(gen.getConfigUrl());
- assertNull(gen.getModulesPath());
- assertNull(gen.getModulesUpdate());
- assertNull(gen.getModulesUrl());
- assertNull(gen.getRepository());
+ try (SubmoduleWalk gen = SubmoduleWalk.forIndex(db)) {
+ assertTrue(gen.next());
+ assertEquals(path, gen.getPath());
+ assertEquals(id, gen.getObjectId());
+ assertEquals(new File(db.getWorkTree(), path), gen.getDirectory());
+ assertNull(gen.getConfigUpdate());
+ assertNull(gen.getConfigUrl());
+ assertNull(gen.getModulesPath());
+ assertNull(gen.getModulesUpdate());
+ assertNull(gen.getModulesUrl());
+ assertNull(gen.getRepository());
+ assertFalse(gen.next());
+ }
Status status = Git.wrap(db).status().call();
- assertTrue(!status.isClean());
- assertFalse(gen.next());
+ assertFalse(status.isClean());
}
@Test
@@ -178,24 +180,25 @@ public void apply(DirCacheEntry ent) {
});
editor.commit();
- SubmoduleWalk gen = SubmoduleWalk.forIndex(db);
- assertTrue(gen.next());
- assertEquals(path, gen.getPath());
- assertEquals(id, gen.getObjectId());
- assertEquals(new File(db.getWorkTree(), path), gen.getDirectory());
- assertNull(gen.getConfigUpdate());
- assertNull(gen.getConfigUrl());
- assertNull(gen.getModulesPath());
- assertNull(gen.getModulesUpdate());
- assertNull(gen.getModulesUrl());
- try (Repository subRepo = gen.getRepository()) {
- assertNotNull(subRepo);
- assertEquals(modulesGitDir.getAbsolutePath(),
- subRepo.getDirectory().getAbsolutePath());
- assertEquals(new File(db.getWorkTree(), path).getAbsolutePath(),
- subRepo.getWorkTree().getAbsolutePath());
+ try (SubmoduleWalk gen = SubmoduleWalk.forIndex(db)) {
+ assertTrue(gen.next());
+ assertEquals(path, gen.getPath());
+ assertEquals(id, gen.getObjectId());
+ assertEquals(new File(db.getWorkTree(), path), gen.getDirectory());
+ assertNull(gen.getConfigUpdate());
+ assertNull(gen.getConfigUrl());
+ assertNull(gen.getModulesPath());
+ assertNull(gen.getModulesUpdate());
+ assertNull(gen.getModulesUrl());
+ try (Repository subRepo = gen.getRepository()) {
+ assertNotNull(subRepo);
+ assertEquals(modulesGitDir.getAbsolutePath(),
+ subRepo.getDirectory().getAbsolutePath());
+ assertEquals(new File(db.getWorkTree(), path).getAbsolutePath(),
+ subRepo.getWorkTree().getAbsolutePath());
+ }
+ assertFalse(gen.next());
}
- assertFalse(gen.next());
}
@Test
@@ -232,23 +235,24 @@ public void apply(DirCacheEntry ent) {
});
editor.commit();
- SubmoduleWalk gen = SubmoduleWalk.forIndex(db);
- assertTrue(gen.next());
- assertEquals(path, gen.getPath());
- assertEquals(id, gen.getObjectId());
- assertEquals(new File(db.getWorkTree(), path), gen.getDirectory());
- assertNull(gen.getConfigUpdate());
- assertNull(gen.getConfigUrl());
- assertNull(gen.getModulesPath());
- assertNull(gen.getModulesUpdate());
- assertNull(gen.getModulesUrl());
- try (Repository subRepo = gen.getRepository()) {
- assertNotNull(subRepo);
- assertEqualsFile(modulesGitDir, subRepo.getDirectory());
- assertEqualsFile(new File(db.getWorkTree(), path),
- subRepo.getWorkTree());
- subRepo.close();
- assertFalse(gen.next());
+ try (SubmoduleWalk gen = SubmoduleWalk.forIndex(db)) {
+ assertTrue(gen.next());
+ assertEquals(path, gen.getPath());
+ assertEquals(id, gen.getObjectId());
+ assertEquals(new File(db.getWorkTree(), path), gen.getDirectory());
+ assertNull(gen.getConfigUpdate());
+ assertNull(gen.getConfigUrl());
+ assertNull(gen.getModulesPath());
+ assertNull(gen.getModulesUpdate());
+ assertNull(gen.getModulesUrl());
+ try (Repository subRepo = gen.getRepository()) {
+ assertNotNull(subRepo);
+ assertEqualsFile(modulesGitDir, subRepo.getDirectory());
+ assertEqualsFile(new File(db.getWorkTree(), path),
+ subRepo.getWorkTree());
+ subRepo.close();
+ assertFalse(gen.next());
+ }
}
}
@@ -270,18 +274,19 @@ public void apply(DirCacheEntry ent) {
});
editor.commit();
- SubmoduleWalk gen = SubmoduleWalk.forIndex(db);
- assertTrue(gen.next());
- assertEquals(path, gen.getPath());
- assertEquals(id, gen.getObjectId());
- assertEquals(new File(db.getWorkTree(), path), gen.getDirectory());
- assertNull(gen.getConfigUpdate());
- assertNull(gen.getConfigUrl());
- assertNull(gen.getModulesPath());
- assertNull(gen.getModulesUpdate());
- assertNull(gen.getModulesUrl());
- assertNull(gen.getRepository());
- assertFalse(gen.next());
+ try (SubmoduleWalk gen = SubmoduleWalk.forIndex(db)) {
+ assertTrue(gen.next());
+ assertEquals(path, gen.getPath());
+ assertEquals(id, gen.getObjectId());
+ assertEquals(new File(db.getWorkTree(), path), gen.getDirectory());
+ assertNull(gen.getConfigUpdate());
+ assertNull(gen.getConfigUrl());
+ assertNull(gen.getModulesPath());
+ assertNull(gen.getModulesUpdate());
+ assertNull(gen.getModulesUrl());
+ assertNull(gen.getRepository());
+ assertFalse(gen.next());
+ }
}
@Test
@@ -312,12 +317,13 @@ public void apply(DirCacheEntry ent) {
});
editor.commit();
- SubmoduleWalk gen = SubmoduleWalk.forIndex(db);
- gen.setFilter(PathFilter.create(path1));
- assertTrue(gen.next());
- assertEquals(path1, gen.getPath());
- assertEquals(id1, gen.getObjectId());
- assertFalse(gen.next());
+ try (SubmoduleWalk gen = SubmoduleWalk.forIndex(db)) {
+ gen.setFilter(PathFilter.create(path1));
+ assertTrue(gen.next());
+ assertEquals(path1, gen.getPath());
+ assertEquals(id1, gen.getObjectId());
+ assertFalse(gen.next());
+ }
}
@Test
@@ -358,18 +364,19 @@ public void apply(DirCacheEntry ent) {
});
editor.commit();
- SubmoduleWalk gen = SubmoduleWalk.forIndex(db);
- assertTrue(gen.next());
- assertEquals(path, gen.getPath());
- assertEquals(subId, gen.getObjectId());
- assertEquals(new File(db.getWorkTree(), path), gen.getDirectory());
- assertNull(gen.getConfigUpdate());
- assertNull(gen.getConfigUrl());
- assertEquals("sub", gen.getModulesPath());
- assertNull(gen.getModulesUpdate());
- assertEquals("git://example.com/sub", gen.getModulesUrl());
- assertNull(gen.getRepository());
- assertFalse(gen.next());
+ try (SubmoduleWalk gen = SubmoduleWalk.forIndex(db)) {
+ assertTrue(gen.next());
+ assertEquals(path, gen.getPath());
+ assertEquals(subId, gen.getObjectId());
+ assertEquals(new File(db.getWorkTree(), path), gen.getDirectory());
+ assertNull(gen.getConfigUpdate());
+ assertNull(gen.getConfigUrl());
+ assertEquals("sub", gen.getModulesPath());
+ assertNull(gen.getModulesUpdate());
+ assertEquals("git://example.com/sub", gen.getModulesUrl());
+ assertNull(gen.getRepository());
+ assertFalse(gen.next());
+ }
}
@Test
@@ -397,17 +404,19 @@ public void apply(DirCacheEntry ent) {
})
.create());
- SubmoduleWalk gen = SubmoduleWalk.forPath(db, commit.getTree(), "sub");
- assertEquals(path, gen.getPath());
- assertEquals(subId, gen.getObjectId());
- assertEquals(new File(db.getWorkTree(), path), gen.getDirectory());
- assertNull(gen.getConfigUpdate());
- assertNull(gen.getConfigUrl());
- assertEquals("sub", gen.getModulesPath());
- assertNull(gen.getModulesUpdate());
- assertEquals("git://example.com/sub", gen.getModulesUrl());
- assertNull(gen.getRepository());
- assertFalse(gen.next());
+ try (SubmoduleWalk gen = SubmoduleWalk.forPath(db, commit.getTree(),
+ "sub")) {
+ assertEquals(path, gen.getPath());
+ assertEquals(subId, gen.getObjectId());
+ assertEquals(new File(db.getWorkTree(), path), gen.getDirectory());
+ assertNull(gen.getConfigUpdate());
+ assertNull(gen.getConfigUrl());
+ assertEquals("sub", gen.getModulesPath());
+ assertNull(gen.getModulesUpdate());
+ assertEquals("git://example.com/sub", gen.getModulesUrl());
+ assertNull(gen.getRepository());
+ assertFalse(gen.next());
+ }
}
@Test
@@ -437,17 +446,18 @@ public void apply(DirCacheEntry ent) {
final CanonicalTreeParser p = new CanonicalTreeParser();
p.reset(testDb.getRevWalk().getObjectReader(), commit.getTree());
- SubmoduleWalk gen = SubmoduleWalk.forPath(db, p, "sub");
- assertEquals(path, gen.getPath());
- assertEquals(subId, gen.getObjectId());
- assertEquals(new File(db.getWorkTree(), path), gen.getDirectory());
- assertNull(gen.getConfigUpdate());
- assertNull(gen.getConfigUrl());
- assertEquals("sub", gen.getModulesPath());
- assertNull(gen.getModulesUpdate());
- assertEquals("git://example.com/sub", gen.getModulesUrl());
- assertNull(gen.getRepository());
- assertFalse(gen.next());
+ try (SubmoduleWalk gen = SubmoduleWalk.forPath(db, p, "sub")) {
+ assertEquals(path, gen.getPath());
+ assertEquals(subId, gen.getObjectId());
+ assertEquals(new File(db.getWorkTree(), path), gen.getDirectory());
+ assertNull(gen.getConfigUpdate());
+ assertNull(gen.getConfigUrl());
+ assertEquals("sub", gen.getModulesPath());
+ assertNull(gen.getModulesUpdate());
+ assertEquals("git://example.com/sub", gen.getModulesUrl());
+ assertNull(gen.getRepository());
+ assertFalse(gen.next());
+ }
}
@Test
@@ -477,16 +487,17 @@ public void apply(DirCacheEntry ent) {
final CanonicalTreeParser p = new CanonicalTreeParser();
p.reset(testDb.getRevWalk().getObjectReader(), commit.getTree());
- SubmoduleWalk gen = SubmoduleWalk.forPath(db, p, "sub");
- assertEquals(path, gen.getPath());
- assertEquals(subId, gen.getObjectId());
- assertEquals(new File(db.getWorkTree(), path), gen.getDirectory());
- assertNull(gen.getConfigUpdate());
- assertNull(gen.getConfigUrl());
- assertEquals("sub", gen.getModulesPath());
- assertNull(gen.getModulesUpdate());
- assertEquals("git://example.com/sub", gen.getModulesUrl());
- assertNull(gen.getRepository());
- assertFalse(gen.next());
+ try (SubmoduleWalk gen = SubmoduleWalk.forPath(db, p, "sub")) {
+ assertEquals(path, gen.getPath());
+ assertEquals(subId, gen.getObjectId());
+ assertEquals(new File(db.getWorkTree(), path), gen.getDirectory());
+ assertNull(gen.getConfigUpdate());
+ assertNull(gen.getConfigUrl());
+ assertEquals("sub", gen.getModulesPath());
+ assertNull(gen.getModulesUpdate());
+ assertEquals("git://example.com/sub", gen.getModulesUrl());
+ assertNull(gen.getRepository());
+ assertFalse(gen.next());
+ }
}
}
diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/transport/AtomicPushTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/transport/AtomicPushTest.java
index c1e078d..d6c7a61 100644
--- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/transport/AtomicPushTest.java
+++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/transport/AtomicPushTest.java
@@ -55,10 +55,9 @@
import org.eclipse.jgit.internal.JGitText;
import org.eclipse.jgit.internal.storage.dfs.DfsRepositoryDescription;
import org.eclipse.jgit.internal.storage.dfs.InMemoryRepository;
-import org.eclipse.jgit.lib.Constants;
+import org.eclipse.jgit.junit.TestRepository;
import org.eclipse.jgit.lib.NullProgressMonitor;
import org.eclipse.jgit.lib.ObjectId;
-import org.eclipse.jgit.lib.ObjectInserter;
import org.eclipse.jgit.lib.Repository;
import org.eclipse.jgit.transport.resolver.ReceivePackFactory;
import org.eclipse.jgit.transport.resolver.ServiceNotAuthorizedException;
@@ -73,8 +72,8 @@ public class AtomicPushTest {
private Object ctx = new Object();
private InMemoryRepository server;
private InMemoryRepository client;
- private ObjectId obj1;
- private ObjectId obj2;
+ private ObjectId commit1;
+ private ObjectId commit2;
@Before
public void setUp() throws Exception {
@@ -92,10 +91,11 @@ public ReceivePack create(Object req, Repository db)
});
uri = testProtocol.register(ctx, server);
- try (ObjectInserter ins = client.newObjectInserter()) {
- obj1 = ins.insert(Constants.OBJ_BLOB, Constants.encode("test"));
- obj2 = ins.insert(Constants.OBJ_BLOB, Constants.encode("file"));
- ins.flush();
+ try (TestRepository<?> clientRepo = new TestRepository<>(client)) {
+ commit1 = clientRepo.commit().noFiles().message("test commit 1")
+ .create();
+ commit2 = clientRepo.commit().noFiles().message("test commit 2")
+ .create();
}
}
@@ -149,13 +149,13 @@ public void pushAtomicDisabled() throws Exception {
List<RemoteRefUpdate> cmds = new ArrayList<>();
cmds.add(new RemoteRefUpdate(
null, null,
- obj1, "refs/heads/one",
+ commit1, "refs/heads/one",
true /* force update */,
null /* no local tracking ref */,
ObjectId.zeroId()));
cmds.add(new RemoteRefUpdate(
null, null,
- obj2, "refs/heads/two",
+ commit2, "refs/heads/two",
true /* force update */,
null /* no local tracking ref */,
ObjectId.zeroId()));
@@ -176,16 +176,16 @@ private List<RemoteRefUpdate> commands() throws IOException {
List<RemoteRefUpdate> cmds = new ArrayList<>();
cmds.add(new RemoteRefUpdate(
null, null,
- obj1, "refs/heads/one",
+ commit1, "refs/heads/one",
true /* force update */,
null /* no local tracking ref */,
ObjectId.zeroId()));
cmds.add(new RemoteRefUpdate(
null, null,
- obj2, "refs/heads/two",
+ commit2, "refs/heads/two",
true /* force update */,
null /* no local tracking ref */,
- obj1));
+ commit1));
return cmds;
}
}
diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/transport/HttpAuthTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/transport/HttpAuthTest.java
index ea15ebe..947ca97 100644
--- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/transport/HttpAuthTest.java
+++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/transport/HttpAuthTest.java
@@ -133,16 +133,15 @@ public void connect() throws IOException {
@Override
public String getHeaderField(String name) {
- if (!headerFields.containsKey(name))
+ if (!headerFields.containsKey(name)) {
return null;
- else {
- int n = headerFields.get(name).size();
-
- if (n > 0)
- return headerFields.get(name).get(n - 1);
- else
- return null;
}
+ int n = headerFields.get(name).size();
+
+ if (n > 0) {
+ return headerFields.get(name).get(n - 1);
+ }
+ return null;
}
@Override
diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/transport/PushCertificateParserTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/transport/PushCertificateParserTest.java
index 4bf26b6..5db4563 100644
--- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/transport/PushCertificateParserTest.java
+++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/transport/PushCertificateParserTest.java
@@ -145,7 +145,7 @@ public void noCert() throws Exception {
ObjectId newId =
ObjectId.fromString("deadbeefdeadbeefdeadbeefdeadbeefdeadbeef");
String line = oldId.name() + " " + newId.name() + " refs/heads/master";
- ReceiveCommand cmd = BaseReceivePack.parseCommand(line);
+ ReceiveCommand cmd = ReceivePack.parseCommand(line);
parser.addCommand(cmd);
parser.addCommand(line);
diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/transport/PushOptionsTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/transport/PushOptionsTest.java
index fd1c3bf..18946e0 100644
--- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/transport/PushOptionsTest.java
+++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/transport/PushOptionsTest.java
@@ -62,10 +62,9 @@
import org.eclipse.jgit.internal.storage.dfs.DfsRepositoryDescription;
import org.eclipse.jgit.internal.storage.dfs.InMemoryRepository;
import org.eclipse.jgit.junit.RepositoryTestCase;
-import org.eclipse.jgit.lib.Constants;
+import org.eclipse.jgit.junit.TestRepository;
import org.eclipse.jgit.lib.NullProgressMonitor;
import org.eclipse.jgit.lib.ObjectId;
-import org.eclipse.jgit.lib.ObjectInserter;
import org.eclipse.jgit.lib.Repository;
import org.eclipse.jgit.lib.StoredConfig;
import org.eclipse.jgit.revwalk.RevCommit;
@@ -79,8 +78,8 @@ public class PushOptionsTest extends RepositoryTestCase {
private Object ctx = new Object();
private InMemoryRepository server;
private InMemoryRepository client;
- private ObjectId obj1;
- private ObjectId obj2;
+ private ObjectId commit1;
+ private ObjectId commit2;
private ReceivePack receivePack;
@Override
@@ -101,10 +100,11 @@ public void setUp() throws Exception {
uri = testProtocol.register(ctx, server);
- try (ObjectInserter ins = client.newObjectInserter()) {
- obj1 = ins.insert(Constants.OBJ_BLOB, Constants.encode("test"));
- obj2 = ins.insert(Constants.OBJ_BLOB, Constants.encode("file"));
- ins.flush();
+ try (TestRepository<?> clientRepo = new TestRepository<>(client)) {
+ commit1 = clientRepo.commit().noFiles().message("test commit 1")
+ .create();
+ commit2 = clientRepo.commit().noFiles().message("test commit 2")
+ .create();
}
}
@@ -121,12 +121,12 @@ private static InMemoryRepository newRepo(String name) {
private List<RemoteRefUpdate> commands(boolean atomicSafe)
throws IOException {
List<RemoteRefUpdate> cmds = new ArrayList<>();
- cmds.add(new RemoteRefUpdate(null, null, obj1, "refs/heads/one",
+ cmds.add(new RemoteRefUpdate(null, null, commit1, "refs/heads/one",
true /* force update */, null /* no local tracking ref */,
ObjectId.zeroId()));
- cmds.add(new RemoteRefUpdate(null, null, obj2, "refs/heads/two",
+ cmds.add(new RemoteRefUpdate(null, null, commit2, "refs/heads/two",
true /* force update */, null /* no local tracking ref */,
- atomicSafe ? ObjectId.zeroId() : obj1));
+ atomicSafe ? ObjectId.zeroId() : commit1));
return cmds;
}
diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/transport/ReachableCommitRequestValidatorTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/transport/ReachableCommitRequestValidatorTest.java
new file mode 100644
index 0000000..20b490b
--- /dev/null
+++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/transport/ReachableCommitRequestValidatorTest.java
@@ -0,0 +1,92 @@
+/*
+ * 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.transport;
+
+import org.eclipse.jgit.transport.UploadPack.RequestValidator;
+
+/**
+ * Client may ask for any commit reachable from a reference advertised by
+ * the server.
+ */
+public class ReachableCommitRequestValidatorTest extends RequestValidatorTestCase {
+
+ @Override
+ protected RequestValidator createValidator() {
+ return new UploadPack.ReachableCommitRequestValidator();
+ }
+
+ @Override
+ protected boolean isReachableCommitValid() {
+ return true;
+ }
+
+ @Override
+ protected boolean isUnreachableCommitValid() {
+ return false;
+ }
+
+ @Override
+ protected boolean isReachableBlobValid_withBitmaps() {
+ return true;
+ }
+
+ @Override
+ protected boolean isReachableBlobValid_withoutBitmaps() {
+ return false;
+ }
+
+ @Override
+ protected boolean isUnreachableBlobValid() {
+ return false;
+ }
+
+ @Override
+ protected boolean isAdvertisedTipValid() {
+ return true;
+ }
+
+ @Override
+ protected boolean isUnadvertisedTipCommitValid() {
+ return false;
+ }
+}
diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/transport/ReachableCommitTipRequestValidatorTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/transport/ReachableCommitTipRequestValidatorTest.java
new file mode 100644
index 0000000..5e5391d
--- /dev/null
+++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/transport/ReachableCommitTipRequestValidatorTest.java
@@ -0,0 +1,94 @@
+/*
+ * 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.transport;
+
+import org.eclipse.jgit.transport.UploadPack.RequestValidator;
+
+/**
+ * Client may ask for any commit reachable from any reference, even if that
+ * reference wasn't advertised.
+ */
+public class ReachableCommitTipRequestValidatorTest
+ extends RequestValidatorTestCase {
+
+ @Override
+ protected RequestValidator createValidator() {
+ return new UploadPack.ReachableCommitTipRequestValidator();
+ }
+
+ @Override
+ protected boolean isReachableCommitValid() {
+ return true;
+ }
+
+ @Override
+ protected boolean isUnreachableCommitValid() {
+ return false;
+ }
+
+ @Override
+ protected boolean isAdvertisedTipValid() {
+ return true;
+ }
+
+ @Override
+ protected boolean isReachableBlobValid_withBitmaps() {
+ return true;
+ }
+
+ @Override
+ protected boolean isReachableBlobValid_withoutBitmaps() {
+ return false;
+ }
+
+ @Override
+ protected boolean isUnreachableBlobValid() {
+ return false;
+ }
+
+ @Override
+ protected boolean isUnadvertisedTipCommitValid() {
+ return true;
+ }
+
+}
diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/transport/ReceivePackAdvertiseRefsHookTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/transport/ReceivePackAdvertiseRefsHookTest.java
index 5d208ee..89ac2fe 100644
--- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/transport/ReceivePackAdvertiseRefsHookTest.java
+++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/transport/ReceivePackAdvertiseRefsHookTest.java
@@ -174,7 +174,7 @@ ReceivePack createReceivePack(Repository db) {
ReceivePack rp = super.createReceivePack(dst);
rp.setAdvertiseRefsHook(new AdvertiseRefsHook() {
@Override
- public void advertiseRefs(BaseReceivePack rp2)
+ public void advertiseRefs(ReceivePack rp2)
throws ServiceMayNotContinueException {
rp.setAdvertisedRefs(rp.getRepository().getAllRefs(),
null);
diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/transport/BaseReceivePackTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/transport/ReceivePackTest.java
similarity index 94%
rename from org.eclipse.jgit.test/tst/org/eclipse/jgit/transport/BaseReceivePackTest.java
rename to org.eclipse.jgit.test/tst/org/eclipse/jgit/transport/ReceivePackTest.java
index 7578c6e..156746d 100644
--- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/transport/BaseReceivePackTest.java
+++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/transport/ReceivePackTest.java
@@ -49,14 +49,14 @@
import org.eclipse.jgit.lib.ObjectId;
import org.junit.Test;
-/** Tests for base receive-pack utilities. */
-public class BaseReceivePackTest {
+/** Tests for receive-pack utilities. */
+public class ReceivePackTest {
@Test
public void parseCommand() throws Exception {
String o = "0000000000000000000000000000000000000000";
String n = "deadbeefdeadbeefdeadbeefdeadbeefdeadbeef";
String r = "refs/heads/master";
- ReceiveCommand cmd = BaseReceivePack.parseCommand(o + " " + n + " " + r);
+ ReceiveCommand cmd = ReceivePack.parseCommand(o + " " + n + " " + r);
assertEquals(ObjectId.zeroId(), cmd.getOldId());
assertEquals("deadbeefdeadbeefdeadbeefdeadbeefdeadbeef",
cmd.getNewId().name());
@@ -76,7 +76,7 @@ public void parseCommand() throws Exception {
private void assertParseCommandFails(String input) {
try {
- BaseReceivePack.parseCommand(input);
+ ReceivePack.parseCommand(input);
fail();
} catch (PackProtocolException e) {
// Expected.
diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/transport/RequestValidatorTestCase.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/transport/RequestValidatorTestCase.java
new file mode 100644
index 0000000..c1e7bcf
--- /dev/null
+++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/transport/RequestValidatorTestCase.java
@@ -0,0 +1,319 @@
+/*
+ * 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.transport;
+
+import java.io.IOException;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.Map;
+
+import org.eclipse.jgit.errors.PackProtocolException;
+import org.eclipse.jgit.errors.TransportException;
+import org.eclipse.jgit.internal.storage.dfs.DfsGarbageCollector;
+import org.eclipse.jgit.internal.storage.dfs.DfsRepositoryDescription;
+import org.eclipse.jgit.internal.storage.dfs.InMemoryRepository;
+import org.eclipse.jgit.junit.TestRepository;
+import org.eclipse.jgit.lib.Ref;
+import org.eclipse.jgit.lib.Repository;
+import org.eclipse.jgit.revwalk.RevBlob;
+import org.eclipse.jgit.revwalk.RevCommit;
+import org.eclipse.jgit.transport.UploadPack.RequestValidator;
+import org.hamcrest.Matchers;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.rules.ExpectedException;
+
+public abstract class RequestValidatorTestCase {
+
+ @Rule
+ public ExpectedException thrown = ExpectedException.none();
+
+ private RevCommit reachableCommit;
+
+ private RevCommit tipAdvertisedCommit;
+
+ private RevCommit tipUnadvertisedCommit;
+
+ private RevCommit unreachableCommit;
+
+ private RevBlob reachableBlob;
+
+ private RevBlob unreachableBlob;
+
+ private InMemoryRepository repo;
+
+ protected abstract RequestValidator createValidator();
+
+ @Before
+ public void setUp() throws Exception {
+ repo = new InMemoryRepository(new DfsRepositoryDescription());
+ try (TestRepository<InMemoryRepository> git = new TestRepository<>(
+ repo)) {
+ reachableBlob = git.blob("foo");
+ reachableCommit = git
+ .commit(git.tree(git.file("foo", reachableBlob)));
+ tipAdvertisedCommit = git.commit(reachableCommit);
+ git.update("advertised", tipAdvertisedCommit);
+
+ tipUnadvertisedCommit = git.commit(reachableCommit);
+ git.update("unadvertised", tipUnadvertisedCommit);
+
+ unreachableBlob = git.blob("unreachableFoo");
+ unreachableCommit = git
+ .commit(git.tree(git.file("foo", unreachableBlob)));
+ }
+ }
+
+ /**
+ * @return true if a commit reachable from a visible tip (but not directly
+ * the tip) is valid
+ */
+ protected abstract boolean isReachableCommitValid();
+
+ /** @return true if a commit not reachable from any tip is valid */
+ protected abstract boolean isUnreachableCommitValid();
+
+ /**
+ * @return true if the commit directly pointed by an advertised ref is valid
+ */
+ protected abstract boolean isAdvertisedTipValid();
+
+ /**
+ * @return true if the object directly pointed by a non-advertised ref is
+ * valid
+ */
+ protected abstract boolean isUnadvertisedTipCommitValid();
+
+ // UploadPack doesn't allow to ask for blobs when there is no
+ // bitmap. Test both cases separately.
+ /**
+ * @return true if a reachable blob is valid (and the repo has bitmaps)
+ */
+ protected abstract boolean isReachableBlobValid_withBitmaps();
+
+ /**
+ * @return true if a reachable blob is valid (and the repo does NOT have
+ * bitmaps)
+ */
+ protected abstract boolean isReachableBlobValid_withoutBitmaps();
+
+ /**
+ * @return true if a blob unreachable from any tip is valid
+ */
+ protected abstract boolean isUnreachableBlobValid();
+
+ @Test
+ public void validateReachableCommitWithBitmaps()
+ throws PackProtocolException, IOException {
+ if (!isReachableCommitValid()) {
+ thrown.expect(TransportException.class);
+ thrown.expectMessage(Matchers
+ .containsString(
+ "want " + reachableCommit.name() + " not valid"));
+
+ }
+ createValidator().checkWants(getUploadPack(getRepoWithBitmaps()),
+ Arrays.asList(reachableCommit));
+ }
+
+ @Test
+ public void validateReachableCommitWithoutBitmaps()
+ throws PackProtocolException, IOException {
+ if (!isReachableCommitValid()) {
+ thrown.expect(TransportException.class);
+ thrown.expectMessage(Matchers.containsString(
+ "want " + reachableCommit.name() + " not valid"));
+
+ }
+ createValidator().checkWants(getUploadPack(getRepoWithoutBitmaps()),
+ Arrays.asList(reachableCommit));
+ }
+
+ @Test
+ public void validateAdvertisedTipWithBitmaps()
+ throws PackProtocolException, IOException {
+ if (!isAdvertisedTipValid()) {
+ thrown.expect(TransportException.class);
+ thrown.expectMessage(Matchers.containsString(
+ "want " + tipAdvertisedCommit.name() + " not valid"));
+
+ }
+ createValidator().checkWants(getUploadPack(getRepoWithBitmaps()),
+ Arrays.asList(tipAdvertisedCommit));
+ }
+
+ @Test
+ public void validateAdvertisedTipWithoutBitmaps()
+ throws PackProtocolException, IOException {
+ if (!isAdvertisedTipValid()) {
+ thrown.expect(TransportException.class);
+ thrown.expectMessage(Matchers.containsString(
+ "want " + tipAdvertisedCommit.name() + " not valid"));
+
+ }
+ createValidator().checkWants(getUploadPack(getRepoWithoutBitmaps()),
+ Arrays.asList(tipAdvertisedCommit));
+ }
+
+ @Test
+ public void validateUnadvertisedTipWithBitmaps()
+ throws PackProtocolException, IOException {
+ if (!isUnadvertisedTipCommitValid()) {
+ thrown.expect(TransportException.class);
+ thrown.expectMessage(Matchers.containsString(
+ "want " + tipUnadvertisedCommit.name() + " not valid"));
+
+ }
+ createValidator().checkWants(getUploadPack(getRepoWithBitmaps()),
+ Arrays.asList(tipUnadvertisedCommit));
+ }
+
+ @Test
+ public void validateUnadvertisedTipWithoutBitmaps()
+ throws PackProtocolException, IOException {
+ if (!isUnadvertisedTipCommitValid()) {
+ thrown.expect(TransportException.class);
+ thrown.expectMessage(Matchers.containsString(
+ "want " + tipUnadvertisedCommit.name() + " not valid"));
+
+ }
+ createValidator().checkWants(getUploadPack(getRepoWithoutBitmaps()),
+ Arrays.asList(tipUnadvertisedCommit));
+ }
+
+ @Test
+ public void validateUnreachableCommitWithBitmaps()
+ throws PackProtocolException, IOException {
+ if (!isUnreachableCommitValid()) {
+ thrown.expect(TransportException.class);
+ thrown.expectMessage(Matchers.containsString(
+ "want " + unreachableCommit.name() + " not valid"));
+
+ }
+ createValidator().checkWants(getUploadPack(getRepoWithBitmaps()),
+ Arrays.asList(unreachableCommit));
+ }
+
+ @Test
+ public void validateUnreachableCommitWithoutBitmaps()
+ throws PackProtocolException, IOException {
+ if (!isUnreachableCommitValid()) {
+ thrown.expect(TransportException.class);
+ thrown.expectMessage(Matchers.containsString(
+ "want " + unreachableCommit.name() + " not valid"));
+
+ }
+ createValidator().checkWants(getUploadPack(getRepoWithoutBitmaps()),
+ Arrays.asList(unreachableCommit));
+ }
+
+ @Test
+ public void validateReachableBlobWithBitmaps()
+ throws PackProtocolException, IOException {
+ if (!isReachableBlobValid_withBitmaps()) {
+ thrown.expect(TransportException.class);
+ thrown.expectMessage(Matchers.containsString(
+ "want " + reachableBlob.name() + " not valid"));
+ }
+ createValidator().checkWants(getUploadPack(getRepoWithBitmaps()),
+ Arrays.asList(reachableBlob));
+ }
+
+ @Test
+ public void validateReachableBlobWithoutBitmaps()
+ throws PackProtocolException, IOException {
+ if (!isReachableBlobValid_withoutBitmaps()) {
+ thrown.expect(TransportException.class);
+ thrown.expectMessage(Matchers.containsString(
+ "want " + reachableBlob.name() + " not valid"));
+ }
+ createValidator().checkWants(getUploadPack(getRepoWithoutBitmaps()),
+ Arrays.asList(reachableBlob));
+ }
+
+ @Test
+ public void validateUnreachableBlobWithBitmaps()
+ throws PackProtocolException, IOException {
+ if (!isUnreachableBlobValid()) {
+ thrown.expect(TransportException.class);
+ thrown.expectMessage(Matchers.containsString(
+ "want " + unreachableBlob.name() + " not valid"));
+ }
+ createValidator().checkWants(getUploadPack(getRepoWithBitmaps()),
+ Arrays.asList(unreachableBlob));
+ }
+
+ @Test
+ public void validateUnreachableBlobWithoutBitmaps()
+ throws PackProtocolException, IOException {
+ if (!isUnreachableBlobValid()) {
+ thrown.expect(TransportException.class);
+ thrown.expectMessage(Matchers.containsString(
+ "want " + unreachableBlob.name() + " not valid"));
+ }
+ createValidator().checkWants(getUploadPack(getRepoWithoutBitmaps()),
+ Arrays.asList(unreachableBlob));
+ }
+
+ private UploadPack getUploadPack(Repository repository) throws IOException {
+ UploadPack uploadPack = new UploadPack(repository);
+
+ Ref advertisedRef = repo.getRefDatabase().findRef("advertised");
+ Map<String, Ref> advertisedRefs = new HashMap<>();
+ advertisedRefs.put(advertisedRef.getName(), advertisedRef);
+
+ uploadPack.setAdvertisedRefs(advertisedRefs);
+ return uploadPack;
+ }
+
+ private Repository getRepoWithBitmaps() throws IOException {
+ new DfsGarbageCollector(repo).pack(null);
+ repo.scanForRepoChanges();
+ return repo;
+ }
+
+ private Repository getRepoWithoutBitmaps() {
+ return repo;
+ }
+}
diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/transport/TipRequestValidatorTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/transport/TipRequestValidatorTest.java
new file mode 100644
index 0000000..565d0e6
--- /dev/null
+++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/transport/TipRequestValidatorTest.java
@@ -0,0 +1,93 @@
+/*
+ * 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.transport;
+
+import org.eclipse.jgit.transport.UploadPack.RequestValidator;
+
+/**
+ * Client may ask for objects that are the tip of any reference, even if not
+ * advertised.
+ */
+public class TipRequestValidatorTest extends RequestValidatorTestCase {
+
+ @Override
+ protected RequestValidator createValidator() {
+ return new UploadPack.TipRequestValidator();
+ }
+
+ @Override
+ protected boolean isReachableCommitValid() {
+ return false;
+ }
+
+ @Override
+ protected boolean isUnreachableCommitValid() {
+ return false;
+ }
+
+ @Override
+ protected boolean isReachableBlobValid_withBitmaps() {
+ return false;
+ }
+
+ @Override
+ protected boolean isReachableBlobValid_withoutBitmaps() {
+ return false;
+ }
+
+ @Override
+ protected boolean isUnreachableBlobValid() {
+ return false;
+ }
+
+ @Override
+ protected boolean isAdvertisedTipValid() {
+ return true;
+ }
+
+ @Override
+ protected boolean isUnadvertisedTipCommitValid() {
+ return true;
+ }
+
+}
diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/transport/UploadPackReachabilityTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/transport/UploadPackReachabilityTest.java
new file mode 100644
index 0000000..7122082
--- /dev/null
+++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/transport/UploadPackReachabilityTest.java
@@ -0,0 +1,316 @@
+/*
+ * 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.transport;
+
+import static org.eclipse.jgit.lib.MoreAsserts.assertThrows;
+import static org.hamcrest.Matchers.containsString;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertThat;
+import static org.junit.Assert.assertTrue;
+
+import java.util.Collections;
+
+import org.eclipse.jgit.errors.TransportException;
+import org.eclipse.jgit.internal.storage.dfs.DfsGarbageCollector;
+import org.eclipse.jgit.internal.storage.dfs.DfsRepositoryDescription;
+import org.eclipse.jgit.internal.storage.dfs.InMemoryRepository;
+import org.eclipse.jgit.junit.TestRepository;
+import org.eclipse.jgit.lib.NullProgressMonitor;
+import org.eclipse.jgit.lib.Repository;
+import org.eclipse.jgit.revwalk.RevBlob;
+import org.eclipse.jgit.revwalk.RevCommit;
+import org.eclipse.jgit.transport.UploadPack.RequestPolicy;
+import org.eclipse.jgit.transport.resolver.ServiceNotAuthorizedException;
+import org.eclipse.jgit.transport.resolver.ServiceNotEnabledException;
+import org.eclipse.jgit.transport.resolver.UploadPackFactory;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.rules.ExpectedException;
+
+/**
+ * Test combinations of:
+ * <ul>
+ * <li>Fetch a blob or a commit</li>
+ * <li>Fetched object is reachable or not</li>
+ * <li>With and without bitmaps</li>
+ * </ul>
+ */
+public class UploadPackReachabilityTest {
+
+ @Rule
+ public ExpectedException thrown = ExpectedException.none();
+
+ private URIish uri;
+
+ private TestProtocol<Object> testProtocol;
+
+ private Object ctx = new Object();
+
+ private InMemoryRepository server;
+
+ private InMemoryRepository client;
+
+ private TestRepository<InMemoryRepository> remote;
+
+ @Before
+ public void setUp() throws Exception {
+ server = newRepo("server");
+ client = newRepo("client");
+
+ remote = new TestRepository<>(server);
+ }
+
+ @After
+ public void tearDown() {
+ Transport.unregister(testProtocol);
+ }
+
+ @Test
+ public void testFetchUnreachableBlobWithBitmap() throws Exception {
+ RevBlob blob = remote.blob("foo");
+ remote.commit(remote.tree(remote.file("foo", blob)));
+ generateBitmaps(server);
+
+ testProtocol = generateReachableCommitUploadPackProtocol();
+ uri = testProtocol.register(ctx, server);
+
+ assertFalse(client.getObjectDatabase().has(blob.toObjectId()));
+
+ try (Transport tn = testProtocol.open(uri, client, "server")) {
+ TransportException e = assertThrows(TransportException.class,
+ () -> tn.fetch(NullProgressMonitor.INSTANCE, Collections
+ .singletonList(new RefSpec(blob.name()))));
+ assertThat(e.getMessage(),
+ containsString("want " + blob.name() + " not valid"));
+ }
+ }
+
+ @Test
+ public void testFetchReachableBlobWithoutBitmap() throws Exception {
+ RevBlob blob = remote.blob("foo");
+ RevCommit commit = remote.commit(remote.tree(remote.file("foo", blob)));
+ remote.update("master", commit);
+
+ testProtocol = generateReachableCommitUploadPackProtocol();
+ uri = testProtocol.register(ctx, server);
+
+ assertFalse(client.getObjectDatabase().has(blob.toObjectId()));
+
+ try (Transport tn = testProtocol.open(uri, client, "server")) {
+ TransportException e = assertThrows(TransportException.class,
+ () -> tn.fetch(NullProgressMonitor.INSTANCE, Collections
+ .singletonList(new RefSpec(blob.name()))));
+ assertThat(e.getMessage(),
+ containsString(
+ "want " + blob.name() + " not valid"));
+ }
+ }
+
+ @Test
+ public void testFetchReachableBlobWithoutBitmapButFilterAllowed() throws Exception {
+ InMemoryRepository server2 = newRepo("server2");
+ try (TestRepository<InMemoryRepository> remote2 = new TestRepository<>(
+ server2)) {
+ RevBlob blob = remote2.blob("foo");
+ RevCommit commit = remote2.commit(remote2.tree(remote2.file("foo", blob)));
+ remote2.update("master", commit);
+
+ server2.getConfig().setBoolean("uploadpack", null, "allowfilter",
+ true);
+
+ testProtocol = new TestProtocol<>((Object req, Repository db) -> {
+ UploadPack up = new UploadPack(db);
+ up.setRequestPolicy(RequestPolicy.REACHABLE_COMMIT);
+ return up;
+ }, null);
+ uri = testProtocol.register(ctx, server2);
+
+ assertFalse(client.getObjectDatabase().has(blob.toObjectId()));
+
+ try (Transport tn = testProtocol.open(uri, client, "server2")) {
+ tn.fetch(NullProgressMonitor.INSTANCE,
+ Collections.singletonList(new RefSpec(blob.name())));
+ assertTrue(client.getObjectDatabase().has(blob.toObjectId()));
+ }
+ }
+ }
+
+ @Test
+ public void testFetchUnreachableBlobWithoutBitmap() throws Exception {
+ RevBlob blob = remote.blob("foo");
+ remote.commit(remote.tree(remote.file("foo", blob)));
+
+ testProtocol = generateReachableCommitUploadPackProtocol();
+ uri = testProtocol.register(ctx, server);
+
+ assertFalse(client.getObjectDatabase().has(blob.toObjectId()));
+
+ try (Transport tn = testProtocol.open(uri, client, "server")) {
+ TransportException e = assertThrows(TransportException.class, () ->
+ tn.fetch(NullProgressMonitor.INSTANCE,
+ Collections.singletonList(new RefSpec(blob.name()))));
+ assertThat(e.getMessage(),
+ containsString("want " + blob.name() + " not valid"));
+ }
+ }
+
+ @Test
+ public void testFetchReachableBlobWithBitmap() throws Exception {
+ RevBlob blob = remote.blob("foo");
+ RevCommit commit = remote.commit(remote.tree(remote.file("foo", blob)));
+ remote.update("master", commit);
+ generateBitmaps(server);
+
+ testProtocol = generateReachableCommitUploadPackProtocol();
+ uri = testProtocol.register(ctx, server);
+
+ assertFalse(client.getObjectDatabase().has(blob.toObjectId()));
+
+ try (Transport tn = testProtocol.open(uri, client, "server")) {
+ tn.fetch(NullProgressMonitor.INSTANCE,
+ Collections.singletonList(new RefSpec(blob.name())));
+ assertTrue(client.getObjectDatabase().has(blob.toObjectId()));
+ }
+ }
+
+ @Test
+ public void testFetchReachableCommitWithBitmap() throws Exception {
+ RevCommit commit = remote
+ .commit(remote.tree(remote.file("foo", remote.blob("foo"))));
+ remote.update("master", commit);
+ generateBitmaps(server);
+
+ testProtocol = generateReachableCommitUploadPackProtocol();
+ uri = testProtocol.register(ctx, server);
+
+ assertFalse(client.getObjectDatabase().has(commit.toObjectId()));
+
+ try (Transport tn = testProtocol.open(uri, client, "server")) {
+ tn.fetch(NullProgressMonitor.INSTANCE,
+ Collections.singletonList(new RefSpec(commit.name())));
+ assertTrue(client.getObjectDatabase().has(commit.toObjectId()));
+ }
+ }
+
+ @Test
+ public void testFetchReachableCommitWithoutBitmap() throws Exception {
+ RevCommit commit = remote
+ .commit(remote.tree(remote.file("foo", remote.blob("foo"))));
+ remote.update("master", commit);
+ generateBitmaps(server);
+
+ testProtocol = generateReachableCommitUploadPackProtocol();
+ uri = testProtocol.register(ctx, server);
+
+ assertFalse(client.getObjectDatabase().has(commit.toObjectId()));
+
+ try (Transport tn = testProtocol.open(uri, client, "server")) {
+ tn.fetch(NullProgressMonitor.INSTANCE,
+ Collections.singletonList(new RefSpec(commit.name())));
+ assertTrue(client.getObjectDatabase().has(commit.toObjectId()));
+ }
+ }
+
+ @Test
+ public void testFetchUnreachableCommitWithBitmap() throws Exception {
+ RevCommit commit = remote
+ .commit(remote.tree(remote.file("foo", remote.blob("foo"))));
+ generateBitmaps(server);
+
+ testProtocol = generateReachableCommitUploadPackProtocol();
+ uri = testProtocol.register(ctx, server);
+
+ assertFalse(client.getObjectDatabase().has(commit.toObjectId()));
+
+ try (Transport tn = testProtocol.open(uri, client, "server")) {
+ TransportException e = assertThrows(TransportException.class,
+ () -> tn.fetch(NullProgressMonitor.INSTANCE,
+ Collections.singletonList(new RefSpec(commit.name()))));
+ assertThat(e.getMessage(),
+ containsString("want " + commit.name() + " not valid"));
+ }
+ }
+
+ @Test
+ public void testFetchUnreachableCommitWithoutBitmap() throws Exception {
+ RevCommit commit = remote
+ .commit(remote.tree(remote.file("foo", remote.blob("foo"))));
+
+ testProtocol = generateReachableCommitUploadPackProtocol();
+ uri = testProtocol.register(ctx, server);
+
+ assertFalse(client.getObjectDatabase().has(commit.toObjectId()));
+
+ try (Transport tn = testProtocol.open(uri, client, "server")) {
+ TransportException e = assertThrows(TransportException.class,
+ () -> tn.fetch(NullProgressMonitor.INSTANCE, Collections
+ .singletonList(new RefSpec(commit.name()))));
+ assertThat(e.getMessage(),
+ containsString("want " + commit.name() + " not valid"));
+ }
+ }
+
+ private static InMemoryRepository newRepo(String name) {
+ return new InMemoryRepository(new DfsRepositoryDescription(name));
+ }
+
+ private void generateBitmaps(InMemoryRepository repo) throws Exception {
+ new DfsGarbageCollector(repo).pack(null);
+ repo.scanForRepoChanges();
+ }
+
+ private static TestProtocol<Object> generateReachableCommitUploadPackProtocol() {
+ return new TestProtocol<>(new UploadPackFactory<Object>() {
+ @Override
+ public UploadPack create(Object req, Repository db)
+ throws ServiceNotEnabledException,
+ ServiceNotAuthorizedException {
+ UploadPack up = new UploadPack(db);
+ up.setRequestPolicy(RequestPolicy.REACHABLE_COMMIT);
+ return up;
+ }
+ }, null);
+ }
+}
diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/transport/UploadPackRefSortingForReachabilityTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/transport/UploadPackRefSortingForReachabilityTest.java
new file mode 100644
index 0000000..0875a33
--- /dev/null
+++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/transport/UploadPackRefSortingForReachabilityTest.java
@@ -0,0 +1,76 @@
+/*
+ * 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.transport;
+
+import static org.hamcrest.Matchers.contains;
+import static org.junit.Assert.assertThat;
+
+import java.util.List;
+import java.util.stream.Collectors;
+import java.util.stream.Stream;
+
+import org.eclipse.jgit.lib.ObjectId;
+import org.eclipse.jgit.lib.ObjectIdRef.Unpeeled;
+import org.eclipse.jgit.lib.Ref;
+import org.eclipse.jgit.lib.Ref.Storage;
+import org.junit.Test;
+
+public class UploadPackRefSortingForReachabilityTest {
+
+ @Test
+ public void sortReferences() {
+ List<Ref> refs = Stream.of("refs/changes/12/12", "refs/changes/12/1",
+ "refs/heads/master", "refs/heads/something",
+ "refs/changes/55/1", "refs/tags/v1.1")
+ .map(s -> new Unpeeled(Storage.LOOSE, s, ObjectId.zeroId()))
+ .collect(Collectors.toList());
+ Stream<Ref> sorted = UploadPack.importantRefsFirst(refs);
+ List<String> collected = sorted.map(Ref::getName)
+ .collect(Collectors.toList());
+ assertThat(collected,
+ contains("refs/heads/master", "refs/heads/something",
+ "refs/tags/v1.1", "refs/changes/12/12",
+ "refs/changes/12/1", "refs/changes/55/1"));
+ }
+}
diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/transport/UploadPackTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/transport/UploadPackTest.java
index 528a63f..108e5ed 100644
--- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/transport/UploadPackTest.java
+++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/transport/UploadPackTest.java
@@ -98,14 +98,6 @@ private void generateBitmaps(InMemoryRepository repo) throws Exception {
repo.scanForRepoChanges();
}
- private static TestProtocol<Object> generateReachableCommitUploadPackProtocol() {
- return new TestProtocol<>((Object req, Repository db) -> {
- UploadPack up = new UploadPack(db);
- up.setRequestPolicy(RequestPolicy.REACHABLE_COMMIT);
- return up;
- }, null);
- }
-
@Test
public void testFetchParentOfShallowCommit() throws Exception {
RevCommit commit0 = remote.commit().message("0").create();
@@ -134,95 +126,6 @@ public void testFetchParentOfShallowCommit() throws Exception {
}
@Test
- public void testFetchUnreachableBlobWithBitmap() throws Exception {
- RevBlob blob = remote.blob("foo");
- remote.commit(remote.tree(remote.file("foo", blob)));
- generateBitmaps(server);
-
- testProtocol = generateReachableCommitUploadPackProtocol();
- uri = testProtocol.register(ctx, server);
-
- assertFalse(client.getObjectDatabase().has(blob.toObjectId()));
-
- try (Transport tn = testProtocol.open(uri, client, "server")) {
- TransportException e = assertThrows(TransportException.class,
- () -> tn.fetch(NullProgressMonitor.INSTANCE, Collections
- .singletonList(new RefSpec(blob.name()))));
- assertThat(e.getMessage(),
- containsString("want " + blob.name() + " not valid"));
- }
- }
-
- @Test
- public void testFetchReachableBlobWithBitmap() throws Exception {
- RevBlob blob = remote.blob("foo");
- RevCommit commit = remote.commit(remote.tree(remote.file("foo", blob)));
- remote.update("master", commit);
- generateBitmaps(server);
-
- testProtocol = generateReachableCommitUploadPackProtocol();
- uri = testProtocol.register(ctx, server);
-
- assertFalse(client.getObjectDatabase().has(blob.toObjectId()));
-
- try (Transport tn = testProtocol.open(uri, client, "server")) {
- tn.fetch(NullProgressMonitor.INSTANCE,
- Collections.singletonList(new RefSpec(blob.name())));
- assertTrue(client.getObjectDatabase().has(blob.toObjectId()));
- }
- }
-
- @Test
- public void testFetchReachableBlobWithoutBitmap() throws Exception {
- RevBlob blob = remote.blob("foo");
- RevCommit commit = remote.commit(remote.tree(remote.file("foo", blob)));
- remote.update("master", commit);
-
- testProtocol = generateReachableCommitUploadPackProtocol();
- uri = testProtocol.register(ctx, server);
-
- assertFalse(client.getObjectDatabase().has(blob.toObjectId()));
-
- try (Transport tn = testProtocol.open(uri, client, "server")) {
- TransportException e = assertThrows(TransportException.class,
- () -> tn.fetch(NullProgressMonitor.INSTANCE, Collections
- .singletonList(new RefSpec(blob.name()))));
- assertThat(e.getMessage(),
- containsString(
- "want " + blob.name() + " not valid"));
- }
- }
-
- @Test
- public void testFetchReachableBlobWithoutBitmapButFilterAllowed() throws Exception {
- InMemoryRepository server2 = newRepo("server2");
- try (TestRepository<InMemoryRepository> remote2 = new TestRepository<>(
- server2)) {
- RevBlob blob = remote2.blob("foo");
- RevCommit commit = remote2.commit(remote2.tree(remote2.file("foo", blob)));
- remote2.update("master", commit);
-
- server2.getConfig().setBoolean("uploadpack", null, "allowfilter",
- true);
-
- testProtocol = new TestProtocol<>((Object req, Repository db) -> {
- UploadPack up = new UploadPack(db);
- up.setRequestPolicy(RequestPolicy.REACHABLE_COMMIT);
- return up;
- }, null);
- uri = testProtocol.register(ctx, server2);
-
- assertFalse(client.getObjectDatabase().has(blob.toObjectId()));
-
- try (Transport tn = testProtocol.open(uri, client, "server2")) {
- tn.fetch(NullProgressMonitor.INSTANCE,
- Collections.singletonList(new RefSpec(blob.name())));
- assertTrue(client.getObjectDatabase().has(blob.toObjectId()));
- }
- }
- }
-
- @Test
public void testFetchWithBlobNoneFilter() throws Exception {
InMemoryRepository server2 = newRepo("server2");
try (TestRepository<InMemoryRepository> remote2 = new TestRepository<>(
@@ -559,7 +462,9 @@ private void checkAdvertisedIfAllowed(String configSection, String configName,
assertThat(lines, containsInAnyOrder("ls-refs", "fetch", "server-option"));
}
- private void checkUnadvertisedIfUnallowed(String fetchCapability) throws Exception {
+ private void checkUnadvertisedIfUnallowed(String configSection,
+ String configName, String fetchCapability) throws Exception {
+ server.getConfig().setBoolean(configSection, null, configName, false);
ByteArrayInputStream recvStream =
uploadPackV2Setup(null, PacketLineIn.end());
PacketLineIn pckIn = new PacketLineIn(recvStream);
@@ -570,9 +475,9 @@ private void checkUnadvertisedIfUnallowed(String fetchCapability) throws Excepti
String line;
while (!PacketLineIn.isEnd((line = pckIn.readString()))) {
if (line.startsWith("fetch=")) {
- assertThat(
- Arrays.asList(line.substring(6).split(" ")),
- hasItems("shallow"));
+ List<String> fetchItems = Arrays.asList(line.substring(6).split(" "));
+ assertThat(fetchItems, hasItems("shallow"));
+ assertFalse(fetchItems.contains(fetchCapability));
lines.add("fetch");
} else {
lines.add(line);
@@ -584,7 +489,7 @@ private void checkUnadvertisedIfUnallowed(String fetchCapability) throws Excepti
@Test
public void testV2CapabilitiesAllowFilter() throws Exception {
checkAdvertisedIfAllowed("uploadpack", "allowfilter", "filter");
- checkUnadvertisedIfUnallowed("filter");
+ checkUnadvertisedIfUnallowed("uploadpack", "allowfilter", "filter");
}
@Test
@@ -594,13 +499,18 @@ public void testV2CapabilitiesRefInWant() throws Exception {
@Test
public void testV2CapabilitiesRefInWantNotAdvertisedIfUnallowed() throws Exception {
- checkUnadvertisedIfUnallowed("ref-in-want");
+ checkUnadvertisedIfUnallowed("uploadpack", "allowrefinwant",
+ "ref-in-want");
}
@Test
- public void testV2CapabilitiesAllowSidebandAll() throws Exception {
- checkAdvertisedIfAllowed("uploadpack", "allowsidebandall", "sideband-all");
- checkUnadvertisedIfUnallowed("sideband-all");
+ public void testV2CapabilitiesAdvertiseSidebandAll() throws Exception {
+ server.getConfig().setBoolean("uploadpack", null, "allowsidebandall",
+ true);
+ checkAdvertisedIfAllowed("uploadpack", "advertisesidebandall",
+ "sideband-all");
+ checkUnadvertisedIfUnallowed("uploadpack", "advertisesidebandall",
+ "sideband-all");
}
@Test
@@ -2112,12 +2022,12 @@ public void testV2FetchSidebandAllNoPackfile() throws Exception {
ByteArrayInputStream recvStream = uploadPackV2(
"command=fetch\n",
- PacketLineIn.DELIM,
+ PacketLineIn.delimiter(),
"sideband-all\n",
"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("\001acknowledgments"));
@@ -2133,11 +2043,11 @@ public void testV2FetchSidebandAllPackfile() throws Exception {
server.getConfig().setBoolean("uploadpack", null, "allowsidebandall", true);
ByteArrayInputStream recvStream = uploadPackV2("command=fetch\n",
- PacketLineIn.DELIM,
+ PacketLineIn.delimiter(),
"want " + commit.getName() + "\n",
"sideband-all\n",
"done\n",
- PacketLineIn.END);
+ PacketLineIn.end());
PacketLineIn pckIn = new PacketLineIn(recvStream);
String s;
@@ -2174,18 +2084,18 @@ public PackInfo getInfo(CachedPack pack,
assertThat(protocolsSupported, hasItems("https"));
if (!protocolsSupported.contains("https"))
return null;
- return new PackInfo("myhash", "myuri");
+ return new PackInfo("myhash", "myuri", 100);
}
});
},
"command=fetch\n",
- PacketLineIn.DELIM,
+ PacketLineIn.delimiter(),
"want " + commit2.getName() + "\n",
"sideband-all\n",
"packfile-uris https\n",
"done\n",
- PacketLineIn.END);
+ PacketLineIn.end());
PacketLineIn pckIn = new PacketLineIn(recvStream);
String s;
diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/transport/WalkEncryptionTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/transport/WalkEncryptionTest.java
index 4750d15..d1d7a1d 100644
--- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/transport/WalkEncryptionTest.java
+++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/transport/WalkEncryptionTest.java
@@ -239,9 +239,8 @@ && haveEnvVar(ENV_BUCKET_NAME)) {
loadEnvVar(ENV_SECRET_KEY, SECRET_KEY, props);
loadEnvVar(ENV_BUCKET_NAME, TEST_BUCKET, props);
return props;
- } else {
- return null;
}
+ return null;
}
static Properties fromEnvFile() throws Exception {
@@ -250,12 +249,10 @@ static Properties fromEnvFile() throws Exception {
props.load(new FileInputStream(ENV_CONFIG_FILE));
if (checkTestProps(props)) {
return props;
- } else {
- throw new Error("Environment config file is incomplete.");
}
- } else {
- return null;
+ throw new Error("Environment config file is incomplete.");
}
+ return null;
}
static Properties fromSysProps() {
@@ -266,9 +263,8 @@ && haveSysProp(SYS_BUCKET_NAME)) {
loadSysProp(SYS_SECRET_KEY, SECRET_KEY, props);
loadSysProp(SYS_BUCKET_NAME, TEST_BUCKET, props);
return props;
- } else {
- return null;
}
+ return null;
}
static Properties fromSysFile() throws Exception {
@@ -277,12 +273,10 @@ static Properties fromSysFile() throws Exception {
props.load(new FileInputStream(SYS_CONFIG_FILE));
if (checkTestProps(props)) {
return props;
- } else {
- throw new Error("System props config file is incomplete.");
}
- } else {
- return null;
+ throw new Error("System props config file is incomplete.");
}
+ return null;
}
static Properties fromConfigFile(String path) throws Exception {
@@ -292,12 +286,10 @@ static Properties fromConfigFile(String path) throws Exception {
props.load(new FileInputStream(file));
if (checkTestProps(props)) {
return props;
- } else {
- throw new Error("Props config file is incomplete: " + path);
}
- } else {
- return null;
+ throw new Error("Props config file is incomplete: " + path);
}
+ return null;
}
/**
diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/treewalk/EmptyTreeIteratorTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/treewalk/EmptyTreeIteratorTest.java
index 58aa608..4deb188 100644
--- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/treewalk/EmptyTreeIteratorTest.java
+++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/treewalk/EmptyTreeIteratorTest.java
@@ -65,12 +65,13 @@ public void testAtEOF() throws Exception {
@Test
public void testCreateSubtreeIterator() throws Exception {
final EmptyTreeIterator etp = new EmptyTreeIterator();
- final ObjectReader reader = db.newObjectReader();
- final AbstractTreeIterator sub = etp.createSubtreeIterator(reader);
- assertNotNull(sub);
- assertTrue(sub.first());
- assertTrue(sub.eof());
- assertTrue(sub instanceof EmptyTreeIterator);
+ try (ObjectReader reader = db.newObjectReader()) {
+ final AbstractTreeIterator sub = etp.createSubtreeIterator(reader);
+ assertNotNull(sub);
+ assertTrue(sub.first());
+ assertTrue(sub.eof());
+ assertTrue(sub instanceof EmptyTreeIterator);
+ }
}
@Test
@@ -121,8 +122,9 @@ public void stopWalk() {
called[0] = true;
}
};
- final ObjectReader reader = db.newObjectReader();
- parent.createSubtreeIterator(reader).stopWalk();
+ try (ObjectReader reader = db.newObjectReader()) {
+ parent.createSubtreeIterator(reader).stopWalk();
+ }
assertTrue(called[0]);
}
}
diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/treewalk/FileTreeIteratorTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/treewalk/FileTreeIteratorTest.java
index a3ce4ae..ffa6e5d 100644
--- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/treewalk/FileTreeIteratorTest.java
+++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/treewalk/FileTreeIteratorTest.java
@@ -217,29 +217,29 @@ public void testSimpleIterate() throws Exception {
assertFalse(top.eof());
assertEquals(FileMode.TREE.getBits(), top.mode);
- final ObjectReader reader = db.newObjectReader();
- final AbstractTreeIterator sub = top.createSubtreeIterator(reader);
- assertTrue(sub instanceof FileTreeIterator);
- final FileTreeIterator subfti = (FileTreeIterator) sub;
- assertTrue(sub.first());
- assertFalse(sub.eof());
- assertEquals(paths[2], nameOf(sub));
- assertEquals(paths[2].length(), subfti.getEntryLength());
- assertEquals(mtime[2], subfti.getEntryLastModifiedInstant());
+ try (ObjectReader reader = db.newObjectReader()) {
+ final AbstractTreeIterator sub = top.createSubtreeIterator(reader);
+ assertTrue(sub instanceof FileTreeIterator);
+ final FileTreeIterator subfti = (FileTreeIterator) sub;
+ assertTrue(sub.first());
+ assertFalse(sub.eof());
+ assertEquals(paths[2], nameOf(sub));
+ assertEquals(paths[2].length(), subfti.getEntryLength());
+ assertEquals(mtime[2], subfti.getEntryLastModifiedInstant());
- sub.next(1);
- assertTrue(sub.eof());
+ sub.next(1);
+ assertTrue(sub.eof());
+ top.next(1);
+ assertFalse(top.first());
+ assertFalse(top.eof());
+ assertEquals(FileMode.REGULAR_FILE.getBits(), top.mode);
+ assertEquals(paths[3], nameOf(top));
+ assertEquals(paths[3].length(), top.getEntryLength());
+ assertEquals(mtime[3], top.getEntryLastModifiedInstant());
- top.next(1);
- assertFalse(top.first());
- assertFalse(top.eof());
- assertEquals(FileMode.REGULAR_FILE.getBits(), top.mode);
- assertEquals(paths[3], nameOf(top));
- assertEquals(paths[3].length(), top.getEntryLength());
- assertEquals(mtime[3], top.getEntryLastModifiedInstant());
-
- top.next(1);
- assertTrue(top.eof());
+ top.next(1);
+ assertTrue(top.eof());
+ }
}
@Test
@@ -272,22 +272,23 @@ public void testDirCacheMatchingId() throws Exception {
git.add().addFilepattern("file").call();
}
DirCacheEntry dce = db.readDirCache().getEntry("file");
- TreeWalk tw = new TreeWalk(db);
- FileTreeIterator fti = new FileTreeIterator(trash, db.getFS(), db
- .getConfig().get(WorkingTreeOptions.KEY));
- tw.addTree(fti);
- DirCacheIterator dci = new DirCacheIterator(db.readDirCache());
- tw.addTree(dci);
- fti.setDirCacheIterator(tw, 1);
- while (tw.next() && !tw.getPathString().equals("file")) {
- //
- }
- assertEquals(MetadataDiff.EQUAL, fti.compareMetadata(dce));
- ObjectId fromRaw = ObjectId.fromRaw(fti.idBuffer(), fti.idOffset());
- assertEquals("6b584e8ece562ebffc15d38808cd6b98fc3d97ea",
- fromRaw.getName());
- try (ObjectReader objectReader = db.newObjectReader()) {
- assertFalse(fti.isModified(dce, false, objectReader));
+ try (TreeWalk tw = new TreeWalk(db)) {
+ FileTreeIterator fti = new FileTreeIterator(trash, db.getFS(),
+ db.getConfig().get(WorkingTreeOptions.KEY));
+ tw.addTree(fti);
+ DirCacheIterator dci = new DirCacheIterator(db.readDirCache());
+ tw.addTree(dci);
+ fti.setDirCacheIterator(tw, 1);
+ while (tw.next() && !tw.getPathString().equals("file")) {
+ //
+ }
+ assertEquals(MetadataDiff.EQUAL, fti.compareMetadata(dce));
+ ObjectId fromRaw = ObjectId.fromRaw(fti.idBuffer(), fti.idOffset());
+ assertEquals("6b584e8ece562ebffc15d38808cd6b98fc3d97ea",
+ fromRaw.getName());
+ try (ObjectReader objectReader = db.newObjectReader()) {
+ assertFalse(fti.isModified(dce, false, objectReader));
+ }
}
}
@@ -624,9 +625,8 @@ private Repository createNestedRepo() throws IOException {
@Test
public void testCustomFileModeStrategy() throws Exception {
- Repository nestedRepo = createNestedRepo();
-
- try (Git git = new Git(nestedRepo)) {
+ try (Repository nestedRepo = createNestedRepo();
+ Git git = new Git(nestedRepo)) {
// validate that our custom strategy is honored
WorkingTreeIterator customIterator = new FileTreeIterator(
nestedRepo, NO_GITLINKS_STRATEGY);
@@ -641,9 +641,8 @@ public void testCustomFileModeStrategy() throws Exception {
@Test
public void testCustomFileModeStrategyFromParentIterator() throws Exception {
- Repository nestedRepo = createNestedRepo();
-
- try (Git git = new Git(nestedRepo)) {
+ try (Repository nestedRepo = createNestedRepo();
+ Git git = new Git(nestedRepo)) {
FileTreeIterator customIterator = new FileTreeIterator(nestedRepo,
NO_GITLINKS_STRATEGY);
File r = new File(nestedRepo.getWorkTree(), "sub");
diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/treewalk/NameConflictTreeWalkTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/treewalk/NameConflictTreeWalkTest.java
index 54c2172..e6a5322 100644
--- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/treewalk/NameConflictTreeWalkTest.java
+++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/treewalk/NameConflictTreeWalkTest.java
@@ -84,16 +84,17 @@ public void testNoDF_NoGap() throws Exception {
assertEquals(1, tree1.getEntryCount());
}
- final TreeWalk tw = new TreeWalk(db);
- tw.addTree(new DirCacheIterator(tree0));
- tw.addTree(new DirCacheIterator(tree1));
+ try (TreeWalk tw = new TreeWalk(db)) {
+ tw.addTree(new DirCacheIterator(tree0));
+ tw.addTree(new DirCacheIterator(tree1));
- assertModes("a", REGULAR_FILE, MISSING, tw);
- assertModes("a.b", EXECUTABLE_FILE, MISSING, tw);
- assertModes("a", MISSING, TREE, tw);
- tw.enterSubtree();
- assertModes("a/b", MISSING, REGULAR_FILE, tw);
- assertModes("a0b", SYMLINK, MISSING, tw);
+ assertModes("a", REGULAR_FILE, MISSING, tw);
+ assertModes("a.b", EXECUTABLE_FILE, MISSING, tw);
+ assertModes("a", MISSING, TREE, tw);
+ tw.enterSubtree();
+ assertModes("a/b", MISSING, REGULAR_FILE, tw);
+ assertModes("a0b", SYMLINK, MISSING, tw);
+ }
}
@Test
@@ -115,20 +116,21 @@ public void testDF_NoGap() throws Exception {
assertEquals(1, tree1.getEntryCount());
}
- final NameConflictTreeWalk tw = new NameConflictTreeWalk(db);
- tw.addTree(new DirCacheIterator(tree0));
- tw.addTree(new DirCacheIterator(tree1));
+ try (NameConflictTreeWalk tw = new NameConflictTreeWalk(db)) {
+ tw.addTree(new DirCacheIterator(tree0));
+ tw.addTree(new DirCacheIterator(tree1));
- assertModes("a", REGULAR_FILE, TREE, tw);
- assertTrue(tw.isDirectoryFileConflict());
- assertTrue(tw.isSubtree());
- tw.enterSubtree();
- assertModes("a/b", MISSING, REGULAR_FILE, tw);
- assertTrue(tw.isDirectoryFileConflict());
- assertModes("a.b", EXECUTABLE_FILE, MISSING, tw);
- assertFalse(tw.isDirectoryFileConflict());
- assertModes("a0b", SYMLINK, MISSING, tw);
- assertFalse(tw.isDirectoryFileConflict());
+ assertModes("a", REGULAR_FILE, TREE, tw);
+ assertTrue(tw.isDirectoryFileConflict());
+ assertTrue(tw.isSubtree());
+ tw.enterSubtree();
+ assertModes("a/b", MISSING, REGULAR_FILE, tw);
+ assertTrue(tw.isDirectoryFileConflict());
+ assertModes("a.b", EXECUTABLE_FILE, MISSING, tw);
+ assertFalse(tw.isDirectoryFileConflict());
+ assertModes("a0b", SYMLINK, MISSING, tw);
+ assertFalse(tw.isDirectoryFileConflict());
+ }
}
@Test
@@ -151,20 +153,21 @@ public void testDF_GapByOne() throws Exception {
assertEquals(2, tree1.getEntryCount());
}
- final NameConflictTreeWalk tw = new NameConflictTreeWalk(db);
- tw.addTree(new DirCacheIterator(tree0));
- tw.addTree(new DirCacheIterator(tree1));
+ try (NameConflictTreeWalk tw = new NameConflictTreeWalk(db)) {
+ tw.addTree(new DirCacheIterator(tree0));
+ tw.addTree(new DirCacheIterator(tree1));
- assertModes("a", REGULAR_FILE, TREE, tw);
- assertTrue(tw.isSubtree());
- assertTrue(tw.isDirectoryFileConflict());
- tw.enterSubtree();
- assertModes("a/b", MISSING, REGULAR_FILE, tw);
- assertTrue(tw.isDirectoryFileConflict());
- assertModes("a.b", EXECUTABLE_FILE, EXECUTABLE_FILE, tw);
- assertFalse(tw.isDirectoryFileConflict());
- assertModes("a0b", SYMLINK, MISSING, tw);
- assertFalse(tw.isDirectoryFileConflict());
+ assertModes("a", REGULAR_FILE, TREE, tw);
+ assertTrue(tw.isSubtree());
+ assertTrue(tw.isDirectoryFileConflict());
+ tw.enterSubtree();
+ assertModes("a/b", MISSING, REGULAR_FILE, tw);
+ assertTrue(tw.isDirectoryFileConflict());
+ assertModes("a.b", EXECUTABLE_FILE, EXECUTABLE_FILE, tw);
+ assertFalse(tw.isDirectoryFileConflict());
+ assertModes("a0b", SYMLINK, MISSING, tw);
+ assertFalse(tw.isDirectoryFileConflict());
+ }
}
@Test
@@ -187,20 +190,21 @@ public void testDF_SkipsSeenSubtree() throws Exception {
assertEquals(3, tree1.getEntryCount());
}
- final NameConflictTreeWalk tw = new NameConflictTreeWalk(db);
- tw.addTree(new DirCacheIterator(tree0));
- tw.addTree(new DirCacheIterator(tree1));
+ try (NameConflictTreeWalk tw = new NameConflictTreeWalk(db)) {
+ tw.addTree(new DirCacheIterator(tree0));
+ tw.addTree(new DirCacheIterator(tree1));
- assertModes("a", REGULAR_FILE, TREE, tw);
- assertTrue(tw.isSubtree());
- assertTrue(tw.isDirectoryFileConflict());
- tw.enterSubtree();
- assertModes("a/b", MISSING, REGULAR_FILE, tw);
- assertTrue(tw.isDirectoryFileConflict());
- assertModes("a.b", MISSING, EXECUTABLE_FILE, tw);
- assertFalse(tw.isDirectoryFileConflict());
- assertModes("a0b", SYMLINK, SYMLINK, tw);
- assertFalse(tw.isDirectoryFileConflict());
+ assertModes("a", REGULAR_FILE, TREE, tw);
+ assertTrue(tw.isSubtree());
+ assertTrue(tw.isDirectoryFileConflict());
+ tw.enterSubtree();
+ assertModes("a/b", MISSING, REGULAR_FILE, tw);
+ assertTrue(tw.isDirectoryFileConflict());
+ assertModes("a.b", MISSING, EXECUTABLE_FILE, tw);
+ assertFalse(tw.isDirectoryFileConflict());
+ assertModes("a0b", SYMLINK, SYMLINK, tw);
+ assertFalse(tw.isDirectoryFileConflict());
+ }
}
@Test
@@ -224,26 +228,27 @@ public void testDF_DetectConflict() throws Exception {
assertEquals(4, tree1.getEntryCount());
}
- final NameConflictTreeWalk tw = new NameConflictTreeWalk(db);
- tw.addTree(new DirCacheIterator(tree0));
- tw.addTree(new DirCacheIterator(tree1));
+ try (NameConflictTreeWalk tw = new NameConflictTreeWalk(db)) {
+ tw.addTree(new DirCacheIterator(tree0));
+ tw.addTree(new DirCacheIterator(tree1));
- assertModes("0", REGULAR_FILE, REGULAR_FILE, tw);
- assertFalse(tw.isDirectoryFileConflict());
- assertModes("a", REGULAR_FILE, TREE, tw);
- assertTrue(tw.isSubtree());
- assertTrue(tw.isDirectoryFileConflict());
- tw.enterSubtree();
- assertModes("a/b", MISSING, REGULAR_FILE, tw);
- assertTrue(tw.isDirectoryFileConflict());
- assertModes("a/c", MISSING, TREE, tw);
- assertTrue(tw.isDirectoryFileConflict());
- tw.enterSubtree();
- assertModes("a/c/e", MISSING, REGULAR_FILE, tw);
- assertTrue(tw.isDirectoryFileConflict());
+ assertModes("0", REGULAR_FILE, REGULAR_FILE, tw);
+ assertFalse(tw.isDirectoryFileConflict());
+ assertModes("a", REGULAR_FILE, TREE, tw);
+ assertTrue(tw.isSubtree());
+ assertTrue(tw.isDirectoryFileConflict());
+ tw.enterSubtree();
+ assertModes("a/b", MISSING, REGULAR_FILE, tw);
+ assertTrue(tw.isDirectoryFileConflict());
+ assertModes("a/c", MISSING, TREE, tw);
+ assertTrue(tw.isDirectoryFileConflict());
+ tw.enterSubtree();
+ assertModes("a/c/e", MISSING, REGULAR_FILE, tw);
+ assertTrue(tw.isDirectoryFileConflict());
- assertModes("a.b", MISSING, REGULAR_FILE, tw);
- assertFalse(tw.isDirectoryFileConflict());
+ assertModes("a.b", MISSING, REGULAR_FILE, tw);
+ assertFalse(tw.isDirectoryFileConflict());
+ }
}
private static void assertModes(final String path, final FileMode mode0,
diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/treewalk/filter/IndexDiffFilterTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/treewalk/filter/IndexDiffFilterTest.java
index 2f797e3..964ffca 100644
--- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/treewalk/filter/IndexDiffFilterTest.java
+++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/treewalk/filter/IndexDiffFilterTest.java
@@ -101,13 +101,14 @@ public void testRecursiveTreeWalk() throws Exception {
RevCommit commit = writeFileInFolderAndCommit();
deleteAll();
writeFileWithFolderName();
- TreeWalk treeWalk = createTreeWalk(commit);
- assertTrue(treeWalk.next());
- assertEquals("folder", treeWalk.getPathString());
- assertTrue(treeWalk.next());
- assertEquals("folder/file", treeWalk.getPathString());
- assertFalse(treeWalk.next());
+ try (TreeWalk treeWalk = createTreeWalk(commit)) {
+ assertTrue(treeWalk.next());
+ assertEquals("folder", treeWalk.getPathString());
+ assertTrue(treeWalk.next());
+ assertEquals("folder/file", treeWalk.getPathString());
+ assertFalse(treeWalk.next());
+ }
}
@Test
@@ -115,24 +116,26 @@ public void testNonRecursiveTreeWalk() throws Exception {
RevCommit commit = writeFileInFolderAndCommit();
deleteAll();
writeFileWithFolderName();
- TreeWalk treeWalk = createNonRecursiveTreeWalk(commit);
- assertTrue(treeWalk.next());
- assertEquals("folder", treeWalk.getPathString());
- assertTrue(treeWalk.next());
- assertEquals("folder", treeWalk.getPathString());
- assertTrue(treeWalk.isSubtree());
- treeWalk.enterSubtree();
- assertTrue(treeWalk.next());
- assertEquals("folder/file", treeWalk.getPathString());
- assertFalse(treeWalk.next());
+ try (TreeWalk treeWalk = createNonRecursiveTreeWalk(commit)) {
+ assertTrue(treeWalk.next());
+ assertEquals("folder", treeWalk.getPathString());
+ assertTrue(treeWalk.next());
+ assertEquals("folder", treeWalk.getPathString());
+ assertTrue(treeWalk.isSubtree());
+ treeWalk.enterSubtree();
+ assertTrue(treeWalk.next());
+ assertEquals("folder/file", treeWalk.getPathString());
+ assertFalse(treeWalk.next());
+ }
}
@Test
public void testFileCommitted() throws Exception {
RevCommit commit = writeFileAndCommit();
- TreeWalk treeWalk = createTreeWalk(commit);
- assertFalse(treeWalk.next());
+ try (TreeWalk treeWalk = createTreeWalk(commit)) {
+ assertFalse(treeWalk.next());
+ }
}
@Test
@@ -153,89 +156,100 @@ public void testConflicts() throws Exception {
"<<<<<<< HEAD\nside\n=======\nmaster\n>>>>>>> master\n");
writeTrashFile(FILE, "master");
- TreeWalk treeWalk = createTreeWalk(side);
- int count = 0;
- while (treeWalk.next())
- count++;
- assertEquals(2, count);
+ try (TreeWalk treeWalk = createTreeWalk(side)) {
+ int count = 0;
+ while (treeWalk.next())
+ count++;
+ assertEquals(2, count);
+ }
}
@Test
public void testFileInFolderCommitted() throws Exception {
RevCommit commit = writeFileInFolderAndCommit();
- TreeWalk treeWalk = createTreeWalk(commit);
- assertFalse(treeWalk.next());
+ try (TreeWalk treeWalk = createTreeWalk(commit)) {
+ assertFalse(treeWalk.next());
+ }
}
@Test
public void testEmptyFolderCommitted() throws Exception {
RevCommit commit = createEmptyFolderAndCommit();
- TreeWalk treeWalk = createTreeWalk(commit);
- assertFalse(treeWalk.next());
+ try (TreeWalk treeWalk = createTreeWalk(commit)) {
+ assertFalse(treeWalk.next());
+ }
}
@Test
public void testFileCommittedChangedNotModified() throws Exception {
RevCommit commit = writeFileAndCommit();
writeFile();
- TreeWalk treeWalk = createTreeWalk(commit);
- assertFalse(treeWalk.next());
+ try (TreeWalk treeWalk = createTreeWalk(commit)) {
+ assertFalse(treeWalk.next());
+ }
}
@Test
public void testFileInFolderCommittedChangedNotModified() throws Exception {
RevCommit commit = writeFileInFolderAndCommit();
writeFileInFolder();
- TreeWalk treeWalk = createTreeWalk(commit);
- assertFalse(treeWalk.next());
+ try (TreeWalk treeWalk = createTreeWalk(commit)) {
+ assertFalse(treeWalk.next());
+ }
}
@Test
public void testFileCommittedModified() throws Exception {
RevCommit commit = writeFileAndCommit();
writeFileModified();
- TreeWalk treeWalk = createTreeWalk(commit);
- assertPaths(treeWalk, FILE);
+ try (TreeWalk treeWalk = createTreeWalk(commit)) {
+ assertPaths(treeWalk, FILE);
+ }
}
@Test
public void testFileInFolderCommittedModified() throws Exception {
RevCommit commit = writeFileInFolderAndCommit();
writeFileInFolderModified();
- TreeWalk treeWalk = createTreeWalk(commit);
- assertPaths(treeWalk, FILE_IN_FOLDER);
+ try (TreeWalk treeWalk = createTreeWalk(commit)) {
+ assertPaths(treeWalk, FILE_IN_FOLDER);
+ }
}
@Test
public void testFileCommittedDeleted() throws Exception {
RevCommit commit = writeFileAndCommit();
deleteFile();
- TreeWalk treeWalk = createTreeWalk(commit);
- assertPaths(treeWalk, FILE);
+ try (TreeWalk treeWalk = createTreeWalk(commit)) {
+ assertPaths(treeWalk, FILE);
+ }
}
@Test
public void testFileInFolderCommittedDeleted() throws Exception {
RevCommit commit = writeFileInFolderAndCommit();
deleteFileInFolder();
- TreeWalk treeWalk = createTreeWalk(commit);
- assertPaths(treeWalk, FILE_IN_FOLDER);
+ try (TreeWalk treeWalk = createTreeWalk(commit)) {
+ assertPaths(treeWalk, FILE_IN_FOLDER);
+ }
}
@Test
public void testFileInFolderCommittedAllDeleted() throws Exception {
RevCommit commit = writeFileInFolderAndCommit();
deleteAll();
- TreeWalk treeWalk = createTreeWalk(commit);
- assertPaths(treeWalk, FILE_IN_FOLDER);
+ try (TreeWalk treeWalk = createTreeWalk(commit)) {
+ assertPaths(treeWalk, FILE_IN_FOLDER);
+ }
}
@Test
public void testEmptyFolderCommittedDeleted() throws Exception {
RevCommit commit = createEmptyFolderAndCommit();
deleteFolder();
- TreeWalk treeWalk = createTreeWalk(commit);
- assertFalse(treeWalk.next());
+ try (TreeWalk treeWalk = createTreeWalk(commit)) {
+ assertFalse(treeWalk.next());
+ }
}
@Test
@@ -243,8 +257,9 @@ public void testFileCommittedModifiedCommittedComparedWithInitialCommit()
throws Exception {
RevCommit commit = writeFileAndCommit();
writeFileModifiedAndCommit();
- TreeWalk treeWalk = createTreeWalk(commit);
- assertPaths(treeWalk, FILE);
+ try (TreeWalk treeWalk = createTreeWalk(commit)) {
+ assertPaths(treeWalk, FILE);
+ }
}
@Test
@@ -252,8 +267,9 @@ public void testFileInFolderCommittedModifiedCommittedComparedWithInitialCommit(
throws Exception {
RevCommit commit = writeFileInFolderAndCommit();
writeFileInFolderModifiedAndCommit();
- TreeWalk treeWalk = createTreeWalk(commit);
- assertPaths(treeWalk, FILE_IN_FOLDER);
+ try (TreeWalk treeWalk = createTreeWalk(commit)) {
+ assertPaths(treeWalk, FILE_IN_FOLDER);
+ }
}
@Test
@@ -261,8 +277,9 @@ public void testFileCommittedDeletedCommittedComparedWithInitialCommit()
throws Exception {
RevCommit commit = writeFileAndCommit();
deleteFileAndCommit();
- TreeWalk treeWalk = createTreeWalk(commit);
- assertPaths(treeWalk, FILE);
+ try (TreeWalk treeWalk = createTreeWalk(commit)) {
+ assertPaths(treeWalk, FILE);
+ }
}
@Test
@@ -270,8 +287,9 @@ public void testFileInFolderCommittedDeletedCommittedComparedWithInitialCommit()
throws Exception {
RevCommit commit = writeFileInFolderAndCommit();
deleteFileInFolderAndCommit();
- TreeWalk treeWalk = createTreeWalk(commit);
- assertPaths(treeWalk, FILE_IN_FOLDER);
+ try (TreeWalk treeWalk = createTreeWalk(commit)) {
+ assertPaths(treeWalk, FILE_IN_FOLDER);
+ }
}
@Test
@@ -279,8 +297,9 @@ public void testFileInFolderCommittedAllDeletedCommittedComparedWithInitialCommi
throws Exception {
RevCommit commit = writeFileInFolderAndCommit();
deleteAllAndCommit();
- TreeWalk treeWalk = createTreeWalk(commit);
- assertPaths(treeWalk, FILE_IN_FOLDER);
+ try (TreeWalk treeWalk = createTreeWalk(commit)) {
+ assertPaths(treeWalk, FILE_IN_FOLDER);
+ }
}
@Test
@@ -288,96 +307,108 @@ public void testEmptyFolderCommittedDeletedCommittedComparedWithInitialCommit()
throws Exception {
RevCommit commit = createEmptyFolderAndCommit();
deleteFolderAndCommit();
- TreeWalk treeWalk = createTreeWalk(commit);
- assertFalse(treeWalk.next());
+ try (TreeWalk treeWalk = createTreeWalk(commit)) {
+ assertFalse(treeWalk.next());
+ }
}
@Test
public void testFileUntracked() throws Exception {
RevCommit commit = writeFileAndCommit();
writeFileUntracked();
- TreeWalk treeWalk = createTreeWalk(commit);
- assertPaths(treeWalk, UNTRACKED_FILE);
+ try (TreeWalk treeWalk = createTreeWalk(commit)) {
+ assertPaths(treeWalk, UNTRACKED_FILE);
+ }
}
@Test
public void testFileInFolderUntracked() throws Exception {
RevCommit commit = writeFileInFolderAndCommit();
writeFileInFolderUntracked();
- TreeWalk treeWalk = createTreeWalk(commit);
- assertPaths(treeWalk, UNTRACKED_FILE_IN_FOLDER);
+ try (TreeWalk treeWalk = createTreeWalk(commit)) {
+ assertPaths(treeWalk, UNTRACKED_FILE_IN_FOLDER);
+ }
}
@Test
public void testEmptyFolderUntracked() throws Exception {
RevCommit commit = createEmptyFolderAndCommit();
createEmptyFolderUntracked();
- TreeWalk treeWalk = createTreeWalk(commit);
- assertFalse(treeWalk.next());
+ try (TreeWalk treeWalk = createTreeWalk(commit)) {
+ assertFalse(treeWalk.next());
+ }
}
@Test
public void testFileIgnored() throws Exception {
RevCommit commit = writeFileAndCommit();
writeFileIgnored();
- TreeWalk treeWalk = createTreeWalk(commit);
- assertFalse(treeWalk.next());
+ try (TreeWalk treeWalk = createTreeWalk(commit)) {
+ assertFalse(treeWalk.next());
+ }
}
@Test
public void testFileInFolderIgnored() throws Exception {
RevCommit commit = writeFileInFolderAndCommit();
writeFileInFolderIgnored();
- TreeWalk treeWalk = createTreeWalk(commit);
- assertFalse(treeWalk.next());
+ try (TreeWalk treeWalk = createTreeWalk(commit)) {
+ assertFalse(treeWalk.next());
+ }
}
@Test
public void testFileInFolderAllIgnored() throws Exception {
RevCommit commit = writeFileInFolderAndCommit();
writeFileInFolderAllIgnored();
- TreeWalk treeWalk = createTreeWalk(commit);
- assertFalse(treeWalk.next());
+ try (TreeWalk treeWalk = createTreeWalk(commit)) {
+ assertFalse(treeWalk.next());
+ }
}
@Test
public void testEmptyFolderIgnored() throws Exception {
RevCommit commit = createEmptyFolderAndCommit();
createEmptyFolderIgnored();
- TreeWalk treeWalk = createTreeWalk(commit);
- assertFalse(treeWalk.next());
+ try (TreeWalk treeWalk = createTreeWalk(commit)) {
+ assertFalse(treeWalk.next());
+ }
}
@Test
public void testFileIgnoredNotHonored() throws Exception {
RevCommit commit = writeFileAndCommit();
writeFileIgnored();
- TreeWalk treeWalk = createTreeWalkDishonorIgnores(commit);
- assertPaths(treeWalk, IGNORED_FILE, GITIGNORE);
+ try (TreeWalk treeWalk = createTreeWalkDishonorIgnores(commit)) {
+ assertPaths(treeWalk, IGNORED_FILE, GITIGNORE);
+ }
}
@Test
public void testFileCommittedModifiedIgnored() throws Exception {
RevCommit commit = writeFileAndCommit();
writeFileModifiedIgnored();
- TreeWalk treeWalk = createTreeWalk(commit);
- assertPaths(treeWalk, FILE);
+ try (TreeWalk treeWalk = createTreeWalk(commit)) {
+ assertPaths(treeWalk, FILE);
+ }
}
@Test
public void testFileInFolderCommittedModifiedIgnored() throws Exception {
RevCommit commit = writeFileInFolderAndCommit();
writeFileInFolderModifiedIgnored();
- TreeWalk treeWalk = createTreeWalk(commit);
- assertPaths(treeWalk, FILE_IN_FOLDER);
+ try (TreeWalk treeWalk = createTreeWalk(commit)) {
+ assertPaths(treeWalk, FILE_IN_FOLDER);
+ }
}
@Test
public void testFileInFolderCommittedModifiedAllIgnored() throws Exception {
RevCommit commit = writeFileInFolderAndCommit();
writeFileInFolderModifiedAllIgnored();
- TreeWalk treeWalk = createTreeWalk(commit);
- assertPaths(treeWalk, FILE_IN_FOLDER);
+ try (TreeWalk treeWalk = createTreeWalk(commit)) {
+ assertPaths(treeWalk, FILE_IN_FOLDER);
+ }
}
@Test
@@ -386,8 +417,9 @@ public void testFileCommittedDeletedCommittedIgnoredComparedWithInitialCommit()
RevCommit commit = writeFileAndCommit();
deleteFileAndCommit();
rewriteFileIgnored();
- TreeWalk treeWalk = createTreeWalk(commit);
- assertPaths(treeWalk, FILE);
+ try (TreeWalk treeWalk = createTreeWalk(commit)) {
+ assertPaths(treeWalk, FILE);
+ }
}
@Test
@@ -396,8 +428,9 @@ public void testFileInFolderCommittedDeletedCommittedIgnoredComparedWithInitialC
RevCommit commit = writeFileInFolderAndCommit();
deleteFileInFolderAndCommit();
rewriteFileInFolderIgnored();
- TreeWalk treeWalk = createTreeWalk(commit);
- assertPaths(treeWalk, FILE_IN_FOLDER);
+ try (TreeWalk treeWalk = createTreeWalk(commit)) {
+ assertPaths(treeWalk, FILE_IN_FOLDER);
+ }
}
@Test
@@ -406,8 +439,9 @@ public void testFileInFolderCommittedAllDeletedCommittedAllIgnoredComparedWithIn
RevCommit commit = writeFileInFolderAndCommit();
deleteAllAndCommit();
rewriteFileInFolderAllIgnored();
- TreeWalk treeWalk = createTreeWalk(commit);
- assertPaths(treeWalk, FILE_IN_FOLDER);
+ try (TreeWalk treeWalk = createTreeWalk(commit)) {
+ assertPaths(treeWalk, FILE_IN_FOLDER);
+ }
}
@Test
@@ -416,15 +450,17 @@ public void testEmptyFolderCommittedDeletedCommittedIgnoredComparedWithInitialCo
RevCommit commit = createEmptyFolderAndCommit();
deleteFolderAndCommit();
recreateEmptyFolderIgnored();
- TreeWalk treeWalk = createTreeWalk(commit);
- assertFalse(treeWalk.next());
+ try (TreeWalk treeWalk = createTreeWalk(commit)) {
+ assertFalse(treeWalk.next());
+ }
}
@Test
public void testFileInFolderCommittedNonRecursive() throws Exception {
RevCommit commit = writeFileInFolderAndCommit();
- TreeWalk treeWalk = createNonRecursiveTreeWalk(commit);
- assertPaths(treeWalk, FOLDER);
+ try (TreeWalk treeWalk = createNonRecursiveTreeWalk(commit)) {
+ assertPaths(treeWalk, FOLDER);
+ }
}
@Test
@@ -432,8 +468,9 @@ public void testFolderChangedToFile() throws Exception {
RevCommit commit = writeFileInFolderAndCommit();
deleteAll();
writeFileWithFolderName();
- TreeWalk treeWalk = createTreeWalk(commit);
- assertPaths(treeWalk, FOLDER, FILE_IN_FOLDER);
+ try (TreeWalk treeWalk = createTreeWalk(commit)) {
+ assertPaths(treeWalk, FOLDER, FILE_IN_FOLDER);
+ }
}
@Test
@@ -442,8 +479,9 @@ public void testFolderChangedToFileCommittedComparedWithInitialCommit()
RevCommit commit = writeFileInFolderAndCommit();
deleteAll();
writeFileWithFolderNameAndCommit();
- TreeWalk treeWalk = createTreeWalk(commit);
- assertPaths(treeWalk, FOLDER, FILE_IN_FOLDER);
+ try (TreeWalk treeWalk = createTreeWalk(commit)) {
+ assertPaths(treeWalk, FOLDER, FILE_IN_FOLDER);
+ }
}
private void writeFile() throws Exception {
diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/util/FSTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/util/FSTest.java
index 89a2fc4..c9a3393 100644
--- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/util/FSTest.java
+++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/util/FSTest.java
@@ -254,7 +254,9 @@ public void testFsTimestampResolution() throws Exception {
formatter.format(t1.toInstant()),
Long.valueOf(resolutionNs)), t2.compareTo(t1) > 0);
} finally {
- Files.delete(f);
+ if (f != null) {
+ Files.delete(f);
+ }
}
}
}
diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/util/GitDateParserBadlyFormattedTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/util/GitDateParserBadlyFormattedTest.java
index a6af3a5..57d2c5e 100644
--- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/util/GitDateParserBadlyFormattedTest.java
+++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/util/GitDateParserBadlyFormattedTest.java
@@ -79,7 +79,7 @@ public GitDateParserBadlyFormattedTest(String dateStr) {
}
@DataPoints
- static public String[] getDataPoints() {
+ public static String[] getDataPoints() {
return new String[] { "", "1970", "3000.3000.3000", "3 yesterday ago",
"now yesterday ago", "yesterdays", "3.day. 2.week.ago",
"day ago", "Gra Feb 21 15:35:00 2007 +0100",
diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/util/HookTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/util/HookTest.java
index e5fcbf9..26653db 100644
--- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/util/HookTest.java
+++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/util/HookTest.java
@@ -58,6 +58,8 @@
import org.eclipse.jgit.hooks.PreCommitHook;
import org.eclipse.jgit.junit.JGitTestUtil;
import org.eclipse.jgit.junit.RepositoryTestCase;
+import org.eclipse.jgit.lib.ConfigConstants;
+import org.eclipse.jgit.lib.StoredConfig;
import org.eclipse.jgit.revwalk.RevCommit;
import org.junit.Assume;
import org.junit.Test;
@@ -221,6 +223,107 @@ public void testRunHook() throws Exception {
}
@Test
+ public void testRunHookHooksPathRelative() throws Exception {
+ assumeSupportedPlatform();
+
+ writeHookFile(PreCommitHook.NAME,
+ "#!/bin/sh\necho \"Wrong hook $1 $2\"\nread INPUT\necho $INPUT\n"
+ + "echo $GIT_DIR\necho $GIT_WORK_TREE\necho 1>&2 \"stderr\"");
+ writeHookFile("../../" + PreCommitHook.NAME,
+ "#!/bin/sh\necho \"test $1 $2\"\nread INPUT\necho $INPUT\n"
+ + "echo $GIT_DIR\necho $GIT_WORK_TREE\necho 1>&2 \"stderr\"");
+ StoredConfig cfg = db.getConfig();
+ cfg.load();
+ cfg.setString(ConfigConstants.CONFIG_CORE_SECTION, null,
+ ConfigConstants.CONFIG_KEY_HOOKS_PATH, ".");
+ cfg.save();
+ try (ByteArrayOutputStream out = new ByteArrayOutputStream();
+ ByteArrayOutputStream err = new ByteArrayOutputStream()) {
+ ProcessResult res = FS.DETECTED.runHookIfPresent(db,
+ PreCommitHook.NAME, new String[] { "arg1", "arg2" },
+ new PrintStream(out), new PrintStream(err), "stdin");
+
+ assertEquals("unexpected hook output",
+ "test arg1 arg2\nstdin\n"
+ + db.getDirectory().getAbsolutePath() + '\n'
+ + db.getWorkTree().getAbsolutePath() + '\n',
+ out.toString("UTF-8"));
+ assertEquals("unexpected output on stderr stream", "stderr\n",
+ err.toString("UTF-8"));
+ assertEquals("unexpected exit code", 0, res.getExitCode());
+ assertEquals("unexpected process status", ProcessResult.Status.OK,
+ res.getStatus());
+ }
+ }
+
+ @Test
+ public void testRunHookHooksPathAbsolute() throws Exception {
+ assumeSupportedPlatform();
+
+ writeHookFile(PreCommitHook.NAME,
+ "#!/bin/sh\necho \"Wrong hook $1 $2\"\nread INPUT\necho $INPUT\n"
+ + "echo $GIT_DIR\necho $GIT_WORK_TREE\necho 1>&2 \"stderr\"");
+ writeHookFile("../../" + PreCommitHook.NAME,
+ "#!/bin/sh\necho \"test $1 $2\"\nread INPUT\necho $INPUT\n"
+ + "echo $GIT_DIR\necho $GIT_WORK_TREE\necho 1>&2 \"stderr\"");
+ StoredConfig cfg = db.getConfig();
+ cfg.load();
+ cfg.setString(ConfigConstants.CONFIG_CORE_SECTION, null,
+ ConfigConstants.CONFIG_KEY_HOOKS_PATH,
+ db.getWorkTree().getAbsolutePath());
+ cfg.save();
+ try (ByteArrayOutputStream out = new ByteArrayOutputStream();
+ ByteArrayOutputStream err = new ByteArrayOutputStream()) {
+ ProcessResult res = FS.DETECTED.runHookIfPresent(db,
+ PreCommitHook.NAME, new String[] { "arg1", "arg2" },
+ new PrintStream(out), new PrintStream(err), "stdin");
+
+ assertEquals("unexpected hook output",
+ "test arg1 arg2\nstdin\n"
+ + db.getDirectory().getAbsolutePath() + '\n'
+ + db.getWorkTree().getAbsolutePath() + '\n',
+ out.toString("UTF-8"));
+ assertEquals("unexpected output on stderr stream", "stderr\n",
+ err.toString("UTF-8"));
+ assertEquals("unexpected exit code", 0, res.getExitCode());
+ assertEquals("unexpected process status", ProcessResult.Status.OK,
+ res.getStatus());
+ }
+ }
+
+ @Test
+ public void testHookPathWithBlank() throws Exception {
+ assumeSupportedPlatform();
+
+ File file = writeHookFile("../../a directory/" + PreCommitHook.NAME,
+ "#!/bin/sh\necho \"test $1 $2\"\nread INPUT\necho $INPUT\n"
+ + "echo $GIT_DIR\necho $GIT_WORK_TREE\necho 1>&2 \"stderr\"");
+ StoredConfig cfg = db.getConfig();
+ cfg.load();
+ cfg.setString(ConfigConstants.CONFIG_CORE_SECTION, null,
+ ConfigConstants.CONFIG_KEY_HOOKS_PATH,
+ file.getParentFile().getAbsolutePath());
+ cfg.save();
+ try (ByteArrayOutputStream out = new ByteArrayOutputStream();
+ ByteArrayOutputStream err = new ByteArrayOutputStream()) {
+ ProcessResult res = FS.DETECTED.runHookIfPresent(db,
+ PreCommitHook.NAME, new String[] { "arg1", "arg2" },
+ new PrintStream(out), new PrintStream(err), "stdin");
+
+ assertEquals("unexpected hook output",
+ "test arg1 arg2\nstdin\n"
+ + db.getDirectory().getAbsolutePath() + '\n'
+ + db.getWorkTree().getAbsolutePath() + '\n',
+ out.toString("UTF-8"));
+ assertEquals("unexpected output on stderr stream", "stderr\n",
+ err.toString("UTF-8"));
+ assertEquals("unexpected exit code", 0, res.getExitCode());
+ assertEquals("unexpected process status", ProcessResult.Status.OK,
+ res.getStatus());
+ }
+ }
+
+ @Test
public void testFailedPreCommitHookBlockCommit() throws Exception {
assumeSupportedPlatform();
diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/util/HttpSupportTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/util/HttpSupportTest.java
new file mode 100644
index 0000000..cbe4eb2
--- /dev/null
+++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/util/HttpSupportTest.java
@@ -0,0 +1,69 @@
+/*
+ * Copyright (c) 2019, Thomas Wolf <thomas.wolf@paranor.ch> and others
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+package org.eclipse.jgit.util;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+
+import java.io.IOException;
+import java.net.InetSocketAddress;
+import java.net.Proxy;
+import java.net.ProxySelector;
+import java.net.SocketAddress;
+import java.net.URI;
+import java.net.URL;
+import java.util.Collections;
+import java.util.List;
+
+import org.junit.Test;
+
+public class HttpSupportTest {
+
+ private static class TestProxySelector extends ProxySelector {
+
+ private static final Proxy DUMMY = new Proxy(Proxy.Type.HTTP,
+ InetSocketAddress.createUnresolved("localhost", 0));
+
+ @Override
+ public List<Proxy> select(URI uri) {
+ if ("http".equals(uri.getScheme())
+ && "somehost".equals(uri.getHost())) {
+ return Collections.singletonList(DUMMY);
+ }
+ return Collections.singletonList(Proxy.NO_PROXY);
+ }
+
+ @Override
+ public void connectFailed(URI uri, SocketAddress sa, IOException ioe) {
+ // Empty
+ }
+ }
+
+ @Test
+ public void testMalformedUri() throws Exception {
+ // Valid URL, but backslash is not allowed in a URI in the userinfo part
+ // per RFC 3986: https://tools.ietf.org/html/rfc3986#section-3.2.1 .
+ // Test that conversion to URI to call the ProxySelector does not throw
+ // an exception.
+ Proxy proxy = HttpSupport.proxyFor(new TestProxySelector(), new URL(
+ "http://infor\\c.jones@somehost/somewhere/someproject.git"));
+ assertNotNull(proxy);
+ assertEquals(Proxy.Type.HTTP, proxy.type());
+ }
+
+ @Test
+ public void testCorrectUri() throws Exception {
+ // Backslash escaped as %5C is correct.
+ Proxy proxy = HttpSupport.proxyFor(new TestProxySelector(), new URL(
+ "http://infor%5Cc.jones@somehost/somewhere/someproject.git"));
+ assertNotNull(proxy);
+ assertEquals(Proxy.Type.HTTP, proxy.type());
+ }
+}
diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/util/QuotedStringGitPathStyleTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/util/QuotedStringGitPathStyleTest.java
index 9a0c96e..c09b136 100644
--- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/util/QuotedStringGitPathStyleTest.java
+++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/util/QuotedStringGitPathStyleTest.java
@@ -45,6 +45,7 @@
import static java.nio.charset.StandardCharsets.ISO_8859_1;
import static org.eclipse.jgit.util.QuotedString.GIT_PATH;
+import static org.eclipse.jgit.util.QuotedString.GIT_PATH_MINIMAL;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotSame;
@@ -67,6 +68,12 @@ private static void assertDequote(String exp, String in) {
assertEquals(exp, r);
}
+ private static void assertDequoteMinimal(String exp, String in) {
+ final byte[] b = ('"' + in + '"').getBytes(ISO_8859_1);
+ final String r = GIT_PATH_MINIMAL.dequote(b, 0, b.length);
+ assertEquals(exp, r);
+ }
+
@Test
public void testQuote_Empty() {
assertEquals("\"\"", GIT_PATH.quote(""));
@@ -206,4 +213,75 @@ public void testQuoteAtAndNumber() {
assertSame("abc@2x.png", GIT_PATH.quote("abc@2x.png"));
assertDequote("abc@2x.png", "abc\\1002x.png");
}
+
+ @Test
+ public void testNoQuote() {
+ assertSame("\u00c5ngstr\u00f6m",
+ GIT_PATH_MINIMAL.quote("\u00c5ngstr\u00f6m"));
+ }
+
+ @Test
+ public void testQuoteMinimal() {
+ assertEquals("\"\u00c5n\\\\str\u00f6m\"",
+ GIT_PATH_MINIMAL.quote("\u00c5n\\str\u00f6m"));
+ }
+
+ @Test
+ public void testDequoteMinimal() {
+ assertEquals("\u00c5n\\str\u00f6m", GIT_PATH_MINIMAL
+ .dequote(GIT_PATH_MINIMAL.quote("\u00c5n\\str\u00f6m")));
+
+ }
+
+ @Test
+ public void testRoundtripMinimal() {
+ assertEquals("\u00c5ngstr\u00f6m", GIT_PATH_MINIMAL
+ .dequote(GIT_PATH_MINIMAL.quote("\u00c5ngstr\u00f6m")));
+
+ }
+
+ @Test
+ public void testQuoteMinimalDequoteNormal() {
+ assertEquals("\u00c5n\\str\u00f6m", GIT_PATH
+ .dequote(GIT_PATH_MINIMAL.quote("\u00c5n\\str\u00f6m")));
+
+ }
+
+ @Test
+ public void testQuoteNormalDequoteMinimal() {
+ assertEquals("\u00c5n\\str\u00f6m", GIT_PATH_MINIMAL
+ .dequote(GIT_PATH.quote("\u00c5n\\str\u00f6m")));
+
+ }
+
+ @Test
+ public void testRoundtripMinimalDequoteNormal() {
+ assertEquals("\u00c5ngstr\u00f6m",
+ GIT_PATH.dequote(GIT_PATH_MINIMAL.quote("\u00c5ngstr\u00f6m")));
+
+ }
+
+ @Test
+ public void testRoundtripNormalDequoteMinimal() {
+ assertEquals("\u00c5ngstr\u00f6m",
+ GIT_PATH_MINIMAL.dequote(GIT_PATH.quote("\u00c5ngstr\u00f6m")));
+
+ }
+
+ @Test
+ public void testDequote_UTF8_Minimal() {
+ assertDequoteMinimal("\u00c5ngstr\u00f6m",
+ "\\303\\205ngstr\\303\\266m");
+ }
+
+ @Test
+ public void testDequote_RawUTF8_Minimal() {
+ assertDequoteMinimal("\u00c5ngstr\u00f6m", "\303\205ngstr\303\266m");
+ }
+
+ @Test
+ public void testDequote_RawLatin1_Minimal() {
+ assertDequoteMinimal("\u00c5ngstr\u00f6m", "\305ngstr\366m");
+ }
+
}
diff --git a/org.eclipse.jgit.ui/.settings/org.eclipse.jdt.core.prefs b/org.eclipse.jgit.ui/.settings/org.eclipse.jdt.core.prefs
index 525ac67..9fd92b1 100644
--- a/org.eclipse.jgit.ui/.settings/org.eclipse.jdt.core.prefs
+++ b/org.eclipse.jgit.ui/.settings/org.eclipse.jdt.core.prefs
@@ -92,7 +92,7 @@
org.eclipse.jdt.core.compiler.problem.unclosedCloseable=warning
org.eclipse.jdt.core.compiler.problem.undocumentedEmptyBlock=warning
org.eclipse.jdt.core.compiler.problem.unhandledWarningToken=ignore
-org.eclipse.jdt.core.compiler.problem.unnecessaryElse=ignore
+org.eclipse.jdt.core.compiler.problem.unnecessaryElse=warning
org.eclipse.jdt.core.compiler.problem.unnecessaryTypeCheck=error
org.eclipse.jdt.core.compiler.problem.unqualifiedFieldAccess=ignore
org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownException=warning
diff --git a/org.eclipse.jgit.ui/META-INF/MANIFEST.MF b/org.eclipse.jgit.ui/META-INF/MANIFEST.MF
index b143d51..60395c4 100644
--- a/org.eclipse.jgit.ui/META-INF/MANIFEST.MF
+++ b/org.eclipse.jgit.ui/META-INF/MANIFEST.MF
@@ -4,14 +4,14 @@
Bundle-Name: %Bundle-Name
Automatic-Module-Name: org.eclipse.jgit.ui
Bundle-SymbolicName: org.eclipse.jgit.ui
-Bundle-Version: 5.5.2.qualifier
+Bundle-Version: 5.6.2.qualifier
Bundle-Vendor: %Bundle-Vendor
Bundle-RequiredExecutionEnvironment: JavaSE-1.8
-Export-Package: org.eclipse.jgit.awtui;version="5.5.2"
-Import-Package: org.eclipse.jgit.errors;version="[5.5.2,5.6.0)",
- org.eclipse.jgit.lib;version="[5.5.2,5.6.0)",
- org.eclipse.jgit.nls;version="[5.5.2,5.6.0)",
- org.eclipse.jgit.revplot;version="[5.5.2,5.6.0)",
- org.eclipse.jgit.revwalk;version="[5.5.2,5.6.0)",
- org.eclipse.jgit.transport;version="[5.5.2,5.6.0)",
- org.eclipse.jgit.util;version="[5.5.2,5.6.0)"
+Export-Package: org.eclipse.jgit.awtui;version="5.6.2"
+Import-Package: org.eclipse.jgit.errors;version="[5.6.2,5.7.0)",
+ org.eclipse.jgit.lib;version="[5.6.2,5.7.0)",
+ org.eclipse.jgit.nls;version="[5.6.2,5.7.0)",
+ org.eclipse.jgit.revplot;version="[5.6.2,5.7.0)",
+ org.eclipse.jgit.revwalk;version="[5.6.2,5.7.0)",
+ org.eclipse.jgit.transport;version="[5.6.2,5.7.0)",
+ org.eclipse.jgit.util;version="[5.6.2,5.7.0)"
diff --git a/org.eclipse.jgit.ui/META-INF/SOURCE-MANIFEST.MF b/org.eclipse.jgit.ui/META-INF/SOURCE-MANIFEST.MF
index 5e75347..d87804d 100644
--- a/org.eclipse.jgit.ui/META-INF/SOURCE-MANIFEST.MF
+++ b/org.eclipse.jgit.ui/META-INF/SOURCE-MANIFEST.MF
@@ -3,5 +3,5 @@
Bundle-Name: org.eclipse.jgit.ui - Sources
Bundle-SymbolicName: org.eclipse.jgit.ui.source
Bundle-Vendor: Eclipse.org - JGit
-Bundle-Version: 5.5.2.qualifier
-Eclipse-SourceBundle: org.eclipse.jgit.ui;version="5.5.2.qualifier";roots="."
+Bundle-Version: 5.6.2.qualifier
+Eclipse-SourceBundle: org.eclipse.jgit.ui;version="5.6.2.qualifier";roots="."
diff --git a/org.eclipse.jgit.ui/pom.xml b/org.eclipse.jgit.ui/pom.xml
index fe7af76..822bd51 100644
--- a/org.eclipse.jgit.ui/pom.xml
+++ b/org.eclipse.jgit.ui/pom.xml
@@ -52,7 +52,7 @@
<parent>
<groupId>org.eclipse.jgit</groupId>
<artifactId>org.eclipse.jgit-parent</artifactId>
- <version>5.5.2-SNAPSHOT</version>
+ <version>5.6.2-SNAPSHOT</version>
</parent>
<artifactId>org.eclipse.jgit.ui</artifactId>
diff --git a/org.eclipse.jgit/.settings/.api_filters b/org.eclipse.jgit/.settings/.api_filters
index a2066ec..eb652a2 100644
--- a/org.eclipse.jgit/.settings/.api_filters
+++ b/org.eclipse.jgit/.settings/.api_filters
@@ -1,31 +1,10 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<component id="org.eclipse.jgit" version="2">
- <resource path="src/org/eclipse/jgit/dircache/DirCacheEntry.java" type="org.eclipse.jgit.dircache.DirCacheEntry">
- <filter id="1142947843">
+ <resource path="META-INF/MANIFEST.MF" type="org.eclipse.jgit.transport.BaseReceivePack">
+ <filter id="305324134">
<message_arguments>
- <message_argument value="5.1.9"/>
- <message_argument value="getLastModifiedInstant()"/>
- </message_arguments>
- </filter>
- <filter id="1142947843">
- <message_arguments>
- <message_argument value="5.1.9"/>
- <message_argument value="mightBeRacilyClean(Instant)"/>
- </message_arguments>
- </filter>
- <filter id="1142947843">
- <message_arguments>
- <message_argument value="5.1.9"/>
- <message_argument value="setLastModified(Instant)"/>
- </message_arguments>
- </filter>
- </resource>
- <resource path="src/org/eclipse/jgit/lib/AnyObjectId.java" type="org.eclipse.jgit.lib.AnyObjectId">
- <filter id="1141899266">
- <message_arguments>
- <message_argument value="5.4"/>
- <message_argument value="5.5"/>
- <message_argument value="isEqual(AnyObjectId, AnyObjectId)"/>
+ <message_argument value="org.eclipse.jgit.transport.BaseReceivePack"/>
+ <message_argument value="org.eclipse.jgit_5.6.2"/>
</message_arguments>
</filter>
</resource>
@@ -76,20 +55,20 @@
</filter>
<filter id="1142947843">
<message_arguments>
- <message_argument value="5.1.9"/>
- <message_argument value="CONFIG_FILESYSTEM_SECTION"/>
+ <message_argument value="5.6.2"/>
+ <message_argument value="CONFIG_EXTENSIONS_SECTION"/>
</message_arguments>
</filter>
<filter id="1142947843">
<message_arguments>
- <message_argument value="5.1.9"/>
- <message_argument value="CONFIG_KEY_MIN_RACY_THRESHOLD"/>
+ <message_argument value="5.6.2"/>
+ <message_argument value="CONFIG_KEY_REF_STORAGE"/>
</message_arguments>
</filter>
<filter id="1142947843">
<message_arguments>
- <message_argument value="5.1.9"/>
- <message_argument value="CONFIG_KEY_TIMESTAMP_RESOLUTION"/>
+ <message_argument value="5.6.2"/>
+ <message_argument value="CONFIG_REF_STORAGE_REFTABLE"/>
</message_arguments>
</filter>
</resource>
@@ -100,6 +79,20 @@
<message_argument value="XDG_CONFIG_HOME"/>
</message_arguments>
</filter>
+ <filter id="1142947843">
+ <message_arguments>
+ <message_argument value="5.6.2"/>
+ <message_argument value="TABLES_LIST"/>
+ </message_arguments>
+ </filter>
+ </resource>
+ <resource path="src/org/eclipse/jgit/revwalk/ReachabilityChecker.java" type="org.eclipse.jgit.revwalk.ReachabilityChecker">
+ <filter id="403804204">
+ <message_arguments>
+ <message_argument value="org.eclipse.jgit.revwalk.ReachabilityChecker"/>
+ <message_argument value="areAllReachable(Collection<RevCommit>, Stream<RevCommit>)"/>
+ </message_arguments>
+ </filter>
</resource>
<resource path="src/org/eclipse/jgit/storage/file/WindowCacheConfig.java" type="org.eclipse.jgit.storage.file.WindowCacheConfig">
<filter id="1142947843">
@@ -124,79 +117,82 @@
</message_arguments>
</filter>
</resource>
- <resource path="src/org/eclipse/jgit/treewalk/WorkingTreeIterator.java" type="org.eclipse.jgit.treewalk.WorkingTreeIterator">
- <filter id="1142947843">
+ <resource path="src/org/eclipse/jgit/storage/pack/PackStatistics.java" type="org.eclipse.jgit.storage.pack.PackStatistics$Accumulator">
+ <filter id="336658481">
<message_arguments>
- <message_argument value="5.1.9"/>
- <message_argument value="getEntryLastModifiedInstant()"/>
+ <message_argument value="org.eclipse.jgit.storage.pack.PackStatistics.Accumulator"/>
+ <message_argument value="offloadedPackfileSize"/>
+ </message_arguments>
+ </filter>
+ <filter id="336658481">
+ <message_arguments>
+ <message_argument value="org.eclipse.jgit.storage.pack.PackStatistics.Accumulator"/>
+ <message_argument value="offloadedPackfiles"/>
</message_arguments>
</filter>
</resource>
- <resource path="src/org/eclipse/jgit/treewalk/WorkingTreeIterator.java" type="org.eclipse.jgit.treewalk.WorkingTreeIterator$Entry">
- <filter id="336695337">
+ <resource path="src/org/eclipse/jgit/transport/AbstractAdvertiseRefsHook.java" type="org.eclipse.jgit.transport.AbstractAdvertiseRefsHook">
+ <filter comment="Merged BaseReceivePack into ReceivePack, replace BaseReceivePack with ReceivePack" id="338792546">
<message_arguments>
- <message_argument value="org.eclipse.jgit.treewalk.WorkingTreeIterator.Entry"/>
- <message_argument value="getLastModifiedInstant()"/>
- </message_arguments>
- </filter>
- <filter id="1142947843">
- <message_arguments>
- <message_argument value="5.1.9"/>
- <message_argument value="getLastModifiedInstant()"/>
+ <message_argument value="org.eclipse.jgit.transport.AbstractAdvertiseRefsHook"/>
+ <message_argument value="advertiseRefs(BaseReceivePack)"/>
</message_arguments>
</filter>
</resource>
- <resource path="src/org/eclipse/jgit/util/FS.java" type="org.eclipse.jgit.util.FS">
- <filter id="338792546">
+ <resource path="src/org/eclipse/jgit/transport/AdvertiseRefsHook.java" type="org.eclipse.jgit.transport.AdvertiseRefsHook">
+ <filter comment="Merged BaseReceivePack into ReceivePack, replace BaseReceivePack with ReceivePack" id="403804204">
<message_arguments>
- <message_argument value="org.eclipse.jgit.util.FS"/>
- <message_argument value="getFsTimerResolution(Path)"/>
+ <message_argument value="org.eclipse.jgit.transport.AdvertiseRefsHook"/>
+ <message_argument value="advertiseRefs(ReceivePack)"/>
</message_arguments>
</filter>
- <filter id="1142947843">
+ <filter comment="Merged BaseReceivePack into ReceivePack, replace BaseReceivePack with ReceivePack" id="405901410">
<message_arguments>
- <message_argument value="5.1.9"/>
- <message_argument value="getFileStoreAttributes(Path)"/>
- </message_arguments>
- </filter>
- <filter id="1142947843">
- <message_arguments>
- <message_argument value="5.1.9"/>
- <message_argument value="lastModifiedInstant(File)"/>
- </message_arguments>
- </filter>
- <filter id="1142947843">
- <message_arguments>
- <message_argument value="5.1.9"/>
- <message_argument value="lastModifiedInstant(Path)"/>
- </message_arguments>
- </filter>
- <filter id="1142947843">
- <message_arguments>
- <message_argument value="5.1.9"/>
- <message_argument value="setAsyncFileStoreAttributes(boolean)"/>
- </message_arguments>
- </filter>
- <filter id="1142947843">
- <message_arguments>
- <message_argument value="5.1.9"/>
- <message_argument value="setLastModified(Path, Instant)"/>
+ <message_argument value="org.eclipse.jgit.transport.AdvertiseRefsHook"/>
+ <message_argument value="advertiseRefs(BaseReceivePack)"/>
</message_arguments>
</filter>
</resource>
- <resource path="src/org/eclipse/jgit/util/FS.java" type="org.eclipse.jgit.util.FS$Attributes">
- <filter id="1142947843">
+ <resource path="src/org/eclipse/jgit/transport/AdvertiseRefsHookChain.java" type="org.eclipse.jgit.transport.AdvertiseRefsHookChain">
+ <filter comment="Merged BaseReceivePack into ReceivePack, replace BaseReceivePack with ReceivePack" id="338792546">
<message_arguments>
- <message_argument value="5.1.9"/>
- <message_argument value="getLastModifiedInstant()"/>
+ <message_argument value="org.eclipse.jgit.transport.AdvertiseRefsHookChain"/>
+ <message_argument value="advertiseRefs(BaseReceivePack)"/>
+ </message_arguments>
+ </filter>
+ </resource>
+ <resource path="src/org/eclipse/jgit/transport/ReceiveCommand.java" type="org.eclipse.jgit.transport.ReceiveCommand">
+ <filter comment="Merged BaseReceivePack into ReceivePack, replace BaseReceivePack with ReceivePack" id="338792546">
+ <message_arguments>
+ <message_argument value="org.eclipse.jgit.transport.ReceiveCommand"/>
+ <message_argument value="execute(BaseReceivePack)"/>
+ </message_arguments>
+ </filter>
+ </resource>
+ <resource path="src/org/eclipse/jgit/transport/ReceivePack.java" type="org.eclipse.jgit.transport.ReceivePack">
+ <filter comment="Merged BaseReceivePack into ReceivePack, replace BaseReceivePack with ReceivePack" id="338792546">
+ <message_arguments>
+ <message_argument value="org.eclipse.jgit.transport.ReceivePack"/>
+ <message_argument value="getLockMessageProcessName()"/>
+ </message_arguments>
+ </filter>
+ <filter comment="Merged BaseReceivePack into ReceivePack, replace BaseReceivePack with ReceivePack" id="338849923">
+ <message_arguments>
+ <message_argument value="org.eclipse.jgit.transport.ReceivePack"/>
+ </message_arguments>
+ </filter>
+ <filter id="421572723">
+ <message_arguments>
+ <message_argument value="org.eclipse.jgit.transport.ReceivePack"/>
+ <message_argument value="enableCapabilities()"/>
</message_arguments>
</filter>
</resource>
<resource path="src/org/eclipse/jgit/util/FS.java" type="org.eclipse.jgit.util.FS$FileStoreAttributes">
- <filter id="1142947843">
+ <filter id="1226833923">
<message_arguments>
- <message_argument value="5.1.9"/>
- <message_argument value="FileStoreAttributes"/>
+ <message_argument value="5.6.2"/>
+ <message_argument value="setBackground(boolean)"/>
</message_arguments>
</filter>
</resource>
@@ -208,28 +204,11 @@
</message_arguments>
</filter>
</resource>
- <resource path="src/org/eclipse/jgit/util/References.java" type="org.eclipse.jgit.util.References">
- <filter id="1108344834">
+ <resource path="src/org/eclipse/jgit/util/QuotedString.java" type="org.eclipse.jgit.util.QuotedString">
+ <filter id="336658481">
<message_arguments>
- <message_argument value="5.4"/>
- <message_argument value="5.5"/>
- <message_argument value="org.eclipse.jgit.util.References"/>
- </message_arguments>
- </filter>
- </resource>
- <resource path="src/org/eclipse/jgit/util/SimpleLruCache.java" type="org.eclipse.jgit.util.SimpleLruCache">
- <filter id="1109393411">
- <message_arguments>
- <message_argument value="5.1.9"/>
- <message_argument value="org.eclipse.jgit.util.SimpleLruCache"/>
- </message_arguments>
- </filter>
- </resource>
- <resource path="src/org/eclipse/jgit/util/Stats.java" type="org.eclipse.jgit.util.Stats">
- <filter id="1109393411">
- <message_arguments>
- <message_argument value="5.1.9"/>
- <message_argument value="org.eclipse.jgit.util.Stats"/>
+ <message_argument value="org.eclipse.jgit.util.QuotedString"/>
+ <message_argument value="GIT_PATH_MINIMAL"/>
</message_arguments>
</filter>
</resource>
@@ -242,18 +221,6 @@
</filter>
<filter id="1142947843">
<message_arguments>
- <message_argument value="5.1.9"/>
- <message_argument value="getSystemConfig()"/>
- </message_arguments>
- </filter>
- <filter id="1142947843">
- <message_arguments>
- <message_argument value="5.1.9"/>
- <message_argument value="getUserConfig()"/>
- </message_arguments>
- </filter>
- <filter id="1142947843">
- <message_arguments>
<message_argument value="5.5.2"/>
<message_argument value="getJGitConfig()"/>
</message_arguments>
diff --git a/org.eclipse.jgit/.settings/org.eclipse.jdt.core.prefs b/org.eclipse.jgit/.settings/org.eclipse.jdt.core.prefs
index ef6f5e7..bc7ba1e 100644
--- a/org.eclipse.jgit/.settings/org.eclipse.jdt.core.prefs
+++ b/org.eclipse.jgit/.settings/org.eclipse.jdt.core.prefs
@@ -92,7 +92,7 @@
org.eclipse.jdt.core.compiler.problem.unclosedCloseable=warning
org.eclipse.jdt.core.compiler.problem.undocumentedEmptyBlock=warning
org.eclipse.jdt.core.compiler.problem.unhandledWarningToken=ignore
-org.eclipse.jdt.core.compiler.problem.unnecessaryElse=ignore
+org.eclipse.jdt.core.compiler.problem.unnecessaryElse=warning
org.eclipse.jdt.core.compiler.problem.unnecessaryTypeCheck=error
org.eclipse.jdt.core.compiler.problem.unqualifiedFieldAccess=ignore
org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownException=warning
diff --git a/org.eclipse.jgit/META-INF/MANIFEST.MF b/org.eclipse.jgit/META-INF/MANIFEST.MF
index 69cdf30..3d8f8e4 100644
--- a/org.eclipse.jgit/META-INF/MANIFEST.MF
+++ b/org.eclipse.jgit/META-INF/MANIFEST.MF
@@ -3,12 +3,12 @@
Bundle-Name: %Bundle-Name
Automatic-Module-Name: org.eclipse.jgit
Bundle-SymbolicName: org.eclipse.jgit
-Bundle-Version: 5.5.2.qualifier
+Bundle-Version: 5.6.2.qualifier
Bundle-Localization: plugin
Bundle-Vendor: %Bundle-Vendor
Bundle-ActivationPolicy: lazy
-Export-Package: org.eclipse.jgit.annotations;version="5.5.2",
- org.eclipse.jgit.api;version="5.5.2";
+Export-Package: org.eclipse.jgit.annotations;version="5.6.2",
+ org.eclipse.jgit.api;version="5.6.2";
uses:="org.eclipse.jgit.revwalk,
org.eclipse.jgit.treewalk.filter,
org.eclipse.jgit.diff,
@@ -22,53 +22,53 @@
org.eclipse.jgit.submodule,
org.eclipse.jgit.transport,
org.eclipse.jgit.merge",
- org.eclipse.jgit.api.errors;version="5.5.2";uses:="org.eclipse.jgit.lib,org.eclipse.jgit.errors",
- org.eclipse.jgit.attributes;version="5.5.2",
- org.eclipse.jgit.blame;version="5.5.2";
+ org.eclipse.jgit.api.errors;version="5.6.2";uses:="org.eclipse.jgit.lib,org.eclipse.jgit.errors",
+ org.eclipse.jgit.attributes;version="5.6.2",
+ org.eclipse.jgit.blame;version="5.6.2";
uses:="org.eclipse.jgit.lib,
org.eclipse.jgit.revwalk,
org.eclipse.jgit.treewalk.filter,
org.eclipse.jgit.diff",
- org.eclipse.jgit.diff;version="5.5.2";
+ org.eclipse.jgit.diff;version="5.6.2";
uses:="org.eclipse.jgit.patch,
org.eclipse.jgit.lib,
org.eclipse.jgit.treewalk,
org.eclipse.jgit.revwalk,
org.eclipse.jgit.treewalk.filter,
org.eclipse.jgit.util",
- org.eclipse.jgit.dircache;version="5.5.2";
+ org.eclipse.jgit.dircache;version="5.6.2";
uses:="org.eclipse.jgit.lib,
org.eclipse.jgit.treewalk,
org.eclipse.jgit.util,
org.eclipse.jgit.events,
org.eclipse.jgit.attributes",
- org.eclipse.jgit.errors;version="5.5.2";
+ org.eclipse.jgit.errors;version="5.6.2";
uses:="org.eclipse.jgit.lib,
org.eclipse.jgit.internal.storage.pack,
org.eclipse.jgit.transport,
org.eclipse.jgit.dircache",
- org.eclipse.jgit.events;version="5.5.2";uses:="org.eclipse.jgit.lib",
- org.eclipse.jgit.fnmatch;version="5.5.2",
- org.eclipse.jgit.gitrepo;version="5.5.2";
+ org.eclipse.jgit.events;version="5.6.2";uses:="org.eclipse.jgit.lib",
+ org.eclipse.jgit.fnmatch;version="5.6.2",
+ org.eclipse.jgit.gitrepo;version="5.6.2";
uses:="org.eclipse.jgit.api,
org.eclipse.jgit.lib,
org.eclipse.jgit.revwalk,
org.xml.sax.helpers,
org.xml.sax",
- org.eclipse.jgit.gitrepo.internal;version="5.5.2";x-internal:=true,
- org.eclipse.jgit.hooks;version="5.5.2";uses:="org.eclipse.jgit.lib",
- org.eclipse.jgit.ignore;version="5.5.2",
- org.eclipse.jgit.ignore.internal;version="5.5.2";x-friends:="org.eclipse.jgit.test",
- org.eclipse.jgit.internal;version="5.5.2";x-friends:="org.eclipse.jgit.test,org.eclipse.jgit.http.test",
- org.eclipse.jgit.internal.fsck;version="5.5.2";x-friends:="org.eclipse.jgit.test",
- org.eclipse.jgit.internal.ketch;version="5.5.2";x-friends:="org.eclipse.jgit.junit,org.eclipse.jgit.test,org.eclipse.jgit.pgm",
- org.eclipse.jgit.internal.revwalk;version="5.5.2";x-internal:=true,
- org.eclipse.jgit.internal.storage.dfs;version="5.5.2";
+ org.eclipse.jgit.gitrepo.internal;version="5.6.2";x-internal:=true,
+ org.eclipse.jgit.hooks;version="5.6.2";uses:="org.eclipse.jgit.lib",
+ org.eclipse.jgit.ignore;version="5.6.2",
+ org.eclipse.jgit.ignore.internal;version="5.6.2";x-friends:="org.eclipse.jgit.test",
+ org.eclipse.jgit.internal;version="5.6.2";x-friends:="org.eclipse.jgit.test,org.eclipse.jgit.http.test",
+ org.eclipse.jgit.internal.fsck;version="5.6.2";x-friends:="org.eclipse.jgit.test",
+ org.eclipse.jgit.internal.ketch;version="5.6.2";x-friends:="org.eclipse.jgit.junit,org.eclipse.jgit.test,org.eclipse.jgit.pgm",
+ org.eclipse.jgit.internal.revwalk;version="5.6.2";x-internal:=true,
+ org.eclipse.jgit.internal.storage.dfs;version="5.6.2";
x-friends:="org.eclipse.jgit.test,
org.eclipse.jgit.http.server,
org.eclipse.jgit.http.test,
org.eclipse.jgit.lfs.test",
- org.eclipse.jgit.internal.storage.file;version="5.5.2";
+ org.eclipse.jgit.internal.storage.file;version="5.6.2";
x-friends:="org.eclipse.jgit.test,
org.eclipse.jgit.junit,
org.eclipse.jgit.junit.http,
@@ -77,19 +77,19 @@
org.eclipse.jgit.pgm,
org.eclipse.jgit.pgm.test,
org.eclipse.jgit.ssh.apache",
- org.eclipse.jgit.internal.storage.io;version="5.5.2";x-friends:="org.eclipse.jgit.junit,org.eclipse.jgit.test,org.eclipse.jgit.pgm",
- org.eclipse.jgit.internal.storage.pack;version="5.5.2";x-friends:="org.eclipse.jgit.junit,org.eclipse.jgit.test,org.eclipse.jgit.pgm",
- org.eclipse.jgit.internal.storage.reftable;version="5.5.2";
+ org.eclipse.jgit.internal.storage.io;version="5.6.2";x-friends:="org.eclipse.jgit.junit,org.eclipse.jgit.test,org.eclipse.jgit.pgm",
+ org.eclipse.jgit.internal.storage.pack;version="5.6.2";x-friends:="org.eclipse.jgit.junit,org.eclipse.jgit.test,org.eclipse.jgit.pgm",
+ org.eclipse.jgit.internal.storage.reftable;version="5.6.2";
x-friends:="org.eclipse.jgit.http.test,
org.eclipse.jgit.junit,
org.eclipse.jgit.test,
org.eclipse.jgit.pgm",
- org.eclipse.jgit.internal.storage.reftree;version="5.5.2";x-friends:="org.eclipse.jgit.junit,org.eclipse.jgit.test,org.eclipse.jgit.pgm",
- org.eclipse.jgit.internal.submodule;version="5.5.2";x-internal:=true,
- org.eclipse.jgit.internal.transport.http;version="5.5.2";x-friends:="org.eclipse.jgit.test",
- org.eclipse.jgit.internal.transport.parser;version="5.5.2";x-friends:="org.eclipse.jgit.http.server,org.eclipse.jgit.test",
- org.eclipse.jgit.internal.transport.ssh;version="5.5.2";x-friends:="org.eclipse.jgit.ssh.apache",
- org.eclipse.jgit.lib;version="5.5.2";
+ org.eclipse.jgit.internal.storage.reftree;version="5.6.2";x-friends:="org.eclipse.jgit.junit,org.eclipse.jgit.test,org.eclipse.jgit.pgm",
+ org.eclipse.jgit.internal.submodule;version="5.6.2";x-internal:=true,
+ org.eclipse.jgit.internal.transport.http;version="5.6.2";x-friends:="org.eclipse.jgit.test",
+ org.eclipse.jgit.internal.transport.parser;version="5.6.2";x-friends:="org.eclipse.jgit.http.server,org.eclipse.jgit.test",
+ org.eclipse.jgit.internal.transport.ssh;version="5.6.2";x-friends:="org.eclipse.jgit.ssh.apache",
+ org.eclipse.jgit.lib;version="5.6.2";
uses:="org.eclipse.jgit.revwalk,
org.eclipse.jgit.treewalk.filter,
org.eclipse.jgit.util,
@@ -99,33 +99,33 @@
org.eclipse.jgit.treewalk,
org.eclipse.jgit.transport,
org.eclipse.jgit.submodule",
- org.eclipse.jgit.lib.internal;version="5.5.2";x-internal:=true,
- org.eclipse.jgit.merge;version="5.5.2";
+ org.eclipse.jgit.lib.internal;version="5.6.2";x-friends:="org.eclipse.jgit.test",
+ org.eclipse.jgit.merge;version="5.6.2";
uses:="org.eclipse.jgit.lib,
org.eclipse.jgit.treewalk,
org.eclipse.jgit.revwalk,
org.eclipse.jgit.diff,
org.eclipse.jgit.dircache,
org.eclipse.jgit.api",
- org.eclipse.jgit.nls;version="5.5.2",
- org.eclipse.jgit.notes;version="5.5.2";
+ org.eclipse.jgit.nls;version="5.6.2",
+ org.eclipse.jgit.notes;version="5.6.2";
uses:="org.eclipse.jgit.lib,
org.eclipse.jgit.treewalk,
org.eclipse.jgit.revwalk,
org.eclipse.jgit.merge",
- org.eclipse.jgit.patch;version="5.5.2";uses:="org.eclipse.jgit.lib,org.eclipse.jgit.diff",
- org.eclipse.jgit.revplot;version="5.5.2";uses:="org.eclipse.jgit.lib,org.eclipse.jgit.revwalk",
- org.eclipse.jgit.revwalk;version="5.5.2";
+ org.eclipse.jgit.patch;version="5.6.2";uses:="org.eclipse.jgit.lib,org.eclipse.jgit.diff",
+ org.eclipse.jgit.revplot;version="5.6.2";uses:="org.eclipse.jgit.lib,org.eclipse.jgit.revwalk",
+ org.eclipse.jgit.revwalk;version="5.6.2";
uses:="org.eclipse.jgit.lib,
org.eclipse.jgit.treewalk,
org.eclipse.jgit.treewalk.filter,
org.eclipse.jgit.diff,
org.eclipse.jgit.revwalk.filter",
- org.eclipse.jgit.revwalk.filter;version="5.5.2";uses:="org.eclipse.jgit.revwalk,org.eclipse.jgit.lib,org.eclipse.jgit.util",
- org.eclipse.jgit.storage.file;version="5.5.2";uses:="org.eclipse.jgit.lib,org.eclipse.jgit.util",
- org.eclipse.jgit.storage.pack;version="5.5.2";uses:="org.eclipse.jgit.lib",
- org.eclipse.jgit.submodule;version="5.5.2";uses:="org.eclipse.jgit.lib,org.eclipse.jgit.treewalk.filter,org.eclipse.jgit.treewalk",
- org.eclipse.jgit.transport;version="5.5.2";
+ org.eclipse.jgit.revwalk.filter;version="5.6.2";uses:="org.eclipse.jgit.revwalk,org.eclipse.jgit.lib,org.eclipse.jgit.util",
+ org.eclipse.jgit.storage.file;version="5.6.2";uses:="org.eclipse.jgit.lib,org.eclipse.jgit.util",
+ org.eclipse.jgit.storage.pack;version="5.6.2";uses:="org.eclipse.jgit.lib",
+ org.eclipse.jgit.submodule;version="5.6.2";uses:="org.eclipse.jgit.lib,org.eclipse.jgit.treewalk.filter,org.eclipse.jgit.treewalk",
+ org.eclipse.jgit.transport;version="5.6.2";
uses:="org.eclipse.jgit.transport.resolver,
org.eclipse.jgit.revwalk,
org.eclipse.jgit.internal.storage.pack,
@@ -138,24 +138,24 @@
org.eclipse.jgit.transport.http,
org.eclipse.jgit.errors,
org.eclipse.jgit.storage.pack",
- org.eclipse.jgit.transport.http;version="5.5.2";uses:="javax.net.ssl",
- org.eclipse.jgit.transport.resolver;version="5.5.2";uses:="org.eclipse.jgit.lib,org.eclipse.jgit.transport",
- org.eclipse.jgit.treewalk;version="5.5.2";
+ org.eclipse.jgit.transport.http;version="5.6.2";uses:="javax.net.ssl",
+ org.eclipse.jgit.transport.resolver;version="5.6.2";uses:="org.eclipse.jgit.lib,org.eclipse.jgit.transport",
+ org.eclipse.jgit.treewalk;version="5.6.2";
uses:="org.eclipse.jgit.lib,
org.eclipse.jgit.revwalk,
org.eclipse.jgit.attributes,
org.eclipse.jgit.treewalk.filter,
org.eclipse.jgit.util,
org.eclipse.jgit.dircache",
- org.eclipse.jgit.treewalk.filter;version="5.5.2";uses:="org.eclipse.jgit.treewalk",
- org.eclipse.jgit.util;version="5.5.2";
+ org.eclipse.jgit.treewalk.filter;version="5.6.2";uses:="org.eclipse.jgit.treewalk",
+ org.eclipse.jgit.util;version="5.6.2";
uses:="org.eclipse.jgit.lib,
org.eclipse.jgit.transport.http,
org.eclipse.jgit.storage.file,
org.ietf.jgss",
- org.eclipse.jgit.util.io;version="5.5.2",
- org.eclipse.jgit.util.sha1;version="5.5.2",
- org.eclipse.jgit.util.time;version="5.5.2"
+ org.eclipse.jgit.util.io;version="5.6.2",
+ org.eclipse.jgit.util.sha1;version="5.6.2",
+ org.eclipse.jgit.util.time;version="5.6.2"
Bundle-RequiredExecutionEnvironment: JavaSE-1.8
Import-Package: com.googlecode.javaewah;version="[1.1.6,2.0.0)",
com.jcraft.jsch;version="[0.1.37,0.2.0)",
@@ -172,6 +172,7 @@
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.bouncycastle.util.io;version="[1.61.0,2.0.0)",
org.slf4j;version="[1.7.0,2.0.0)",
org.xml.sax,
org.xml.sax.helpers
diff --git a/org.eclipse.jgit/META-INF/SOURCE-MANIFEST.MF b/org.eclipse.jgit/META-INF/SOURCE-MANIFEST.MF
index 29db604..75494ff 100644
--- a/org.eclipse.jgit/META-INF/SOURCE-MANIFEST.MF
+++ b/org.eclipse.jgit/META-INF/SOURCE-MANIFEST.MF
@@ -3,5 +3,5 @@
Bundle-Name: org.eclipse.jgit - Sources
Bundle-SymbolicName: org.eclipse.jgit.source
Bundle-Vendor: Eclipse.org - JGit
-Bundle-Version: 5.5.2.qualifier
-Eclipse-SourceBundle: org.eclipse.jgit;version="5.5.2.qualifier";roots="."
+Bundle-Version: 5.6.2.qualifier
+Eclipse-SourceBundle: org.eclipse.jgit;version="5.6.2.qualifier";roots="."
diff --git a/org.eclipse.jgit/pom.xml b/org.eclipse.jgit/pom.xml
index 656d4ff..517dc16 100644
--- a/org.eclipse.jgit/pom.xml
+++ b/org.eclipse.jgit/pom.xml
@@ -53,7 +53,7 @@
<parent>
<groupId>org.eclipse.jgit</groupId>
<artifactId>org.eclipse.jgit-parent</artifactId>
- <version>5.5.2-SNAPSHOT</version>
+ <version>5.6.2-SNAPSHOT</version>
</parent>
<artifactId>org.eclipse.jgit</artifactId>
diff --git a/org.eclipse.jgit/resources/org/eclipse/jgit/internal/JGitText.properties b/org.eclipse.jgit/resources/org/eclipse/jgit/internal/JGitText.properties
index 14ab51c..70a0d80 100644
--- a/org.eclipse.jgit/resources/org/eclipse/jgit/internal/JGitText.properties
+++ b/org.eclipse.jgit/resources/org/eclipse/jgit/internal/JGitText.properties
@@ -283,11 +283,13 @@
expectedReportForRefNotReceived={0}: expected report for ref {1} not received
failedAtomicFileCreation=Atomic file creation failed, number of hard links to file {0} was not 2 but {1}
failedCreateLockFile=Creating lock file {} failed
+failedToConvert=Failed to convert rest: %s
failedToDetermineFilterDefinition=An exception occurred while determining filter definitions
failedUpdatingRefs=failed updating refs
failureDueToOneOfTheFollowing=Failure due to one of the following:
failureUpdatingFETCH_HEAD=Failure updating FETCH_HEAD: {0}
failureUpdatingTrackingRef=Failure updating tracking ref {0}: {1}
+fileAlreadyExists=File already exists: {0}
fileCannotBeDeleted=File cannot be deleted: {0}
fileIsTooLarge=File is too large: {0}
fileModeNotSetForPath=FileMode not set for path {0}
@@ -300,7 +302,7 @@
flagsAlreadyCreated={0} flags already created.
funnyRefname=funny refname
gcFailed=Garbage collection failed.
-gcTooManyUnpruned=Too many loose, unpruneable objects after garbage collection. Consider adjusting gc.auto or gc.pruneExpire.
+gcTooManyUnpruned=Too many loose, unpruneable objects after garbage collection. Consider adjusting gc.auto or gc.pruneExpire.
gpgFailedToParseSecretKey=Failed to parse secret key file in directory: {0}. Is the entered passphrase correct?
gpgNoCredentialsProvider=missing credentials provider
gpgNoKeyring=neither pubring.kbx nor secring.gpg files found
@@ -326,6 +328,7 @@
incorrectOBJECT_ID_LENGTH=Incorrect OBJECT_ID_LENGTH.
indexFileCorruptedNegativeBucketCount=Invalid negative bucket count read from pack v2 index file: {0}
indexFileIsTooLargeForJgit=Index file is too large for jgit
+indexNumbersNotIncreasing=index numbers not increasing: ''{0}'': min {1}, last max {2}
indexWriteException=Modified index could not be written
initFailedBareRepoDifferentDirs=When initializing a bare repo with directory {0} and separate git-dir {1} specified both folders must point to the same location
initFailedDirIsNoDirectory=Cannot set directory to ''{0}'' which is not a directory
@@ -351,6 +354,7 @@
invalidGitdirRef = Invalid .git reference in file ''{0}''
invalidGitModules=Invalid .gitmodules file
invalidGitType=invalid git type: {0}
+invalidHooksPath=Invalid git config core.hooksPath = {0}
invalidId=Invalid id: {0}
invalidId0=Invalid id
invalidIdLength=Invalid id length {0}; should be {1}
@@ -404,11 +408,14 @@
localObjectsIncomplete=Local objects incomplete.
localRefIsMissingObjects=Local ref {0} is missing object(s).
localRepository=local repository
+lockAlreadyHeld=Lock on {0} already held
lockCountMustBeGreaterOrEqual1=lockCount must be >= 1
lockError=lock error: {0}
lockFailedRetry=locking {0} failed after {1} retries
lockOnNotClosed=Lock on {0} not closed.
lockOnNotHeld=Lock on {0} not held.
+lockStreamClosed=Output to lock on {0} already closed
+lockStreamMultiple=Output to lock on {0} already opened
maxCountMustBeNonNegative=max count must be >= 0
mergeConflictOnNonNoteEntries=Merge conflict on non-note entries: base = {0}, ours = {1}, theirs = {2}
mergeConflictOnNotes=Merge conflict on note {0}. base = {1}, ours = {2}, theirs = {2}
@@ -451,8 +458,10 @@
noMergeBase=No merge base could be determined. Reason={0}. {1}
noMergeHeadSpecified=No merge head specified
nonBareLinkFilesNotSupported=Link files are not supported with nonbare repos
+nonCommitToHeads=Cannot point a branch to a non-commit object
noPathAttributesFound=No Attributes found for {0}.
noSuchRef=no such ref
+noSuchRefKnown=no such ref: {0}
noSuchSubmodule=no such submodule {0}
notABoolean=Not a boolean: {0}
notABundle=not a bundle
@@ -551,7 +560,8 @@
refAlreadyExists1=Ref {0} already exists
reflogEntryNotFound=Entry {0} not found in reflog for ''{1}''
refNotResolved=Ref {0} cannot be resolved
-refTableRecordsMustIncrease=records must be increasing: last {0}, this {1}
+reftableDirExists=reftable dir exists and is nonempty
+reftableRecordsMustIncrease=records must be increasing: last {0}, this {1}
refUpdateReturnCodeWas=RefUpdate return code was: {0}
remoteConfigHasNoURIAssociated=Remote config "{0}" has no URIs associated
remoteDoesNotHaveSpec=Remote does not have {0} available for fetch.
@@ -580,7 +590,7 @@
repositoryState_merged=Merged
repositoryState_normal=Normal
repositoryState_rebase=Rebase
-repositoryState_rebaseInteractive=Rebase interactive
+repositoryState_rebaseInteractive=Interactive rebase
repositoryState_rebaseOrApplyMailbox=Rebase/Apply mailbox
repositoryState_rebaseWithMerge=Rebase w/merge
requiredHashFunctionNotAvailable=Required hash function {0} not available.
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/api/BlameCommand.java b/org.eclipse.jgit/src/org/eclipse/jgit/api/BlameCommand.java
index f7576e9..a69aa70 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/api/BlameCommand.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/api/BlameCommand.java
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2011, GitHub Inc.
+ * Copyright (C) 2011, 2019 GitHub Inc.
* and other copyright owners as documented in the project's IP log.
*
* This program and the accompanying materials are made available
@@ -42,11 +42,7 @@
*/
package org.eclipse.jgit.api;
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.FileNotFoundException;
import java.io.IOException;
-import java.io.InputStream;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
@@ -56,17 +52,10 @@
import org.eclipse.jgit.blame.BlameGenerator;
import org.eclipse.jgit.blame.BlameResult;
import org.eclipse.jgit.diff.DiffAlgorithm;
-import org.eclipse.jgit.diff.RawText;
import org.eclipse.jgit.diff.RawTextComparator;
-import org.eclipse.jgit.dircache.DirCache;
import org.eclipse.jgit.lib.AnyObjectId;
-import org.eclipse.jgit.lib.Constants;
-import org.eclipse.jgit.lib.CoreConfig.AutoCRLF;
import org.eclipse.jgit.lib.ObjectId;
import org.eclipse.jgit.lib.Repository;
-import org.eclipse.jgit.treewalk.WorkingTreeOptions;
-import org.eclipse.jgit.util.IO;
-import org.eclipse.jgit.util.io.AutoLFInputStream;
/**
* Blame command for building a {@link org.eclipse.jgit.blame.BlameResult} for a
@@ -221,69 +210,11 @@ public BlameResult call() throws GitAPIException {
else if (startCommit != null)
gen.push(null, startCommit);
else {
- gen.push(null, repo.resolve(Constants.HEAD));
- if (!repo.isBare()) {
- DirCache dc = repo.readDirCache();
- int entry = dc.findEntry(path);
- if (0 <= entry)
- gen.push(null, dc.getEntry(entry).getObjectId());
-
- File inTree = new File(repo.getWorkTree(), path);
- if (repo.getFS().isFile(inTree)) {
- RawText rawText = getRawText(inTree);
- gen.push(null, rawText);
- }
- }
+ gen.prepareHead();
}
return gen.computeBlameResult();
} catch (IOException e) {
throw new JGitInternalException(e.getMessage(), e);
}
}
-
- private RawText getRawText(File inTree) throws IOException,
- FileNotFoundException {
- RawText rawText;
-
- WorkingTreeOptions workingTreeOptions = getRepository().getConfig()
- .get(WorkingTreeOptions.KEY);
- AutoCRLF autoCRLF = workingTreeOptions.getAutoCRLF();
- switch (autoCRLF) {
- case FALSE:
- case INPUT:
- // Git used the repo format on checkout, but other tools
- // may change the format to CRLF. We ignore that here.
- rawText = new RawText(inTree);
- break;
- case TRUE:
- try (AutoLFInputStream in = new AutoLFInputStream(
- new FileInputStream(inTree), true)) {
- // Canonicalization should lead to same or shorter length
- // (CRLF to LF), so the file size on disk is an upper size bound
- rawText = new RawText(toByteArray(in, (int) inTree.length()));
- }
- break;
- default:
- throw new IllegalArgumentException(
- "Unknown autocrlf option " + autoCRLF); //$NON-NLS-1$
- }
- return rawText;
- }
-
- private static byte[] toByteArray(InputStream source, int upperSizeLimit)
- throws IOException {
- byte[] buffer = new byte[upperSizeLimit];
- try {
- int read = IO.readFully(source, buffer, 0);
- if (read == upperSizeLimit)
- return buffer;
- else {
- byte[] copy = new byte[read];
- System.arraycopy(buffer, 0, copy, 0, read);
- return copy;
- }
- } finally {
- source.close();
- }
- }
}
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/api/CheckoutCommand.java b/org.eclipse.jgit/src/org/eclipse/jgit/api/CheckoutCommand.java
index e05f6f1..6d157bd 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/api/CheckoutCommand.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/api/CheckoutCommand.java
@@ -137,7 +137,7 @@ public class CheckoutCommand extends GitCommand<Ref> {
/**
* Stage to check out, see {@link CheckoutCommand#setStage(Stage)}.
*/
- public static enum Stage {
+ public enum Stage {
/**
* Base stage (#1)
*/
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/api/CherryPickCommand.java b/org.eclipse.jgit/src/org/eclipse/jgit/api/CherryPickCommand.java
index c9dd547..aa63725 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/api/CherryPickCommand.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/api/CherryPickCommand.java
@@ -57,6 +57,7 @@
import org.eclipse.jgit.api.errors.WrongRepositoryStateException;
import org.eclipse.jgit.dircache.DirCacheCheckout;
import org.eclipse.jgit.errors.MissingObjectException;
+import org.eclipse.jgit.events.WorkingTreeModifiedEvent;
import org.eclipse.jgit.internal.JGitText;
import org.eclipse.jgit.lib.AnyObjectId;
import org.eclipse.jgit.lib.Constants;
@@ -129,9 +130,10 @@ public CherryPickResult call() throws GitAPIException, NoMessageException,
// get the head commit
Ref headRef = repo.exactRef(Constants.HEAD);
- if (headRef == null)
+ if (headRef == null) {
throw new NoHeadException(
JGitText.get().commitOnRepoWithoutHEADCurrentlyNotSupported);
+ }
newHead = revWalk.parseCommit(headRef.getObjectId());
@@ -140,8 +142,9 @@ public CherryPickResult call() throws GitAPIException, NoMessageException,
// get the commit to be cherry-picked
// handle annotated tags
ObjectId srcObjectId = src.getPeeledObjectId();
- if (srcObjectId == null)
+ if (srcObjectId == null) {
srcObjectId = src.getObjectId();
+ }
RevCommit srcCommit = revWalk.parseCommit(srcObjectId);
// get the parent of the commit to cherry-pick
@@ -157,26 +160,33 @@ public CherryPickResult call() throws GitAPIException, NoMessageException,
merger.setCommitNames(new String[] { "BASE", ourName, //$NON-NLS-1$
cherryPickName });
if (merger.merge(newHead, srcCommit)) {
+ if (!merger.getModifiedFiles().isEmpty()) {
+ repo.fireEvent(new WorkingTreeModifiedEvent(
+ merger.getModifiedFiles(), null));
+ }
if (AnyObjectId.isEqual(newHead.getTree().getId(),
- merger.getResultTreeId()))
+ merger.getResultTreeId())) {
continue;
+ }
DirCacheCheckout dco = new DirCacheCheckout(repo,
newHead.getTree(), repo.lockDirCache(),
merger.getResultTreeId());
dco.setFailOnConflict(true);
dco.setProgressMonitor(monitor);
dco.checkout();
- if (!noCommit)
+ if (!noCommit) {
newHead = new Git(getRepository()).commit()
.setMessage(srcCommit.getFullMessage())
.setReflogComment(reflogPrefix + " " //$NON-NLS-1$
+ srcCommit.getShortMessage())
.setAuthor(srcCommit.getAuthorIdent())
.setNoVerify(true).call();
+ }
cherryPickedRefs.add(src);
} else {
- if (merger.failed())
+ if (merger.failed()) {
return new CherryPickResult(merger.getFailingPaths());
+ }
// there are merge conflicts
@@ -184,10 +194,14 @@ public CherryPickResult call() throws GitAPIException, NoMessageException,
.formatWithConflicts(srcCommit.getFullMessage(),
merger.getUnmergedPaths());
- if (!noCommit)
+ if (!noCommit) {
repo.writeCherryPickHead(srcCommit.getId());
+ }
repo.writeMergeCommitMsg(message);
+ repo.fireEvent(new WorkingTreeModifiedEvent(
+ merger.getModifiedFiles(), null));
+
return CherryPickResult.CONFLICT;
}
}
@@ -213,10 +227,11 @@ private RevCommit getParentCommit(RevCommit srcCommit, RevWalk revWalk)
Integer.valueOf(srcCommit.getParentCount())));
srcParent = srcCommit.getParent(0);
} else {
- if (mainlineParentNumber.intValue() > srcCommit.getParentCount())
+ if (mainlineParentNumber.intValue() > srcCommit.getParentCount()) {
throw new JGitInternalException(MessageFormat.format(
JGitText.get().commitDoesNotHaveGivenParent, srcCommit,
mainlineParentNumber));
+ }
srcParent = srcCommit
.getParent(mainlineParentNumber.intValue() - 1);
}
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/api/CloneCommand.java b/org.eclipse.jgit/src/org/eclipse/jgit/api/CloneCommand.java
index 9f63d0f..7008cd4 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/api/CloneCommand.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/api/CloneCommand.java
@@ -77,8 +77,8 @@
import org.eclipse.jgit.transport.RemoteConfig;
import org.eclipse.jgit.transport.TagOpt;
import org.eclipse.jgit.transport.URIish;
-import org.eclipse.jgit.util.FileUtils;
import org.eclipse.jgit.util.FS;
+import org.eclipse.jgit.util.FileUtils;
/**
* Clone a repository into a new working directory
@@ -106,6 +106,8 @@ public class CloneCommand extends TransportCommand<CloneCommand, Git> {
private boolean cloneAllBranches;
+ private boolean mirror;
+
private boolean cloneSubmodules;
private boolean noCheckout;
@@ -118,6 +120,12 @@ public class CloneCommand extends TransportCommand<CloneCommand, Git> {
private boolean gitDirExistsInitially;
+ private FETCH_TYPE fetchType;
+
+ private enum FETCH_TYPE {
+ MULTIPLE_BRANCHES, ALL_BRANCHES, MIRROR
+ }
+
/**
* Callback for status of clone operation.
*
@@ -191,6 +199,7 @@ public Git call() throws GitAPIException, InvalidRemoteException,
throw new InvalidRemoteException(
MessageFormat.format(JGitText.get().invalidURL, uri));
}
+ setFetchType();
@SuppressWarnings("resource") // Closed by caller
Repository repository = init();
FetchResult fetchResult = null;
@@ -234,6 +243,20 @@ public Git call() throws GitAPIException, InvalidRemoteException,
return new Git(repository, true);
}
+ private void setFetchType() {
+ if (mirror) {
+ fetchType = FETCH_TYPE.MIRROR;
+ setBare(true);
+ } else if (cloneAllBranches) {
+ fetchType = FETCH_TYPE.ALL_BRANCHES;
+ } else if (branchesToClone != null && !branchesToClone.isEmpty()) {
+ fetchType = FETCH_TYPE.MULTIPLE_BRANCHES;
+ } else {
+ // Default: neither mirror nor all nor specific refs given
+ fetchType = FETCH_TYPE.ALL_BRANCHES;
+ }
+ }
+
private static boolean isNonEmptyDirectory(File dir) {
if (dir != null && dir.exists()) {
File[] files = dir.listFiles();
@@ -282,12 +305,11 @@ private FetchResult fetch(Repository clonedRepo, URIish u)
RemoteConfig config = new RemoteConfig(clonedRepo.getConfig(), remote);
config.addURI(u);
- final String dst = (bare ? Constants.R_HEADS : Constants.R_REMOTES
- + config.getName() + '/') + '*';
- boolean fetchAll = cloneAllBranches || branchesToClone == null
- || branchesToClone.isEmpty();
+ boolean fetchAll = fetchType == FETCH_TYPE.ALL_BRANCHES
+ || fetchType == FETCH_TYPE.MIRROR;
- config.setFetchRefSpecs(calculateRefSpecs(fetchAll, dst));
+ config.setFetchRefSpecs(calculateRefSpecs(fetchType, config.getName()));
+ config.setMirror(fetchType == FETCH_TYPE.MIRROR);
config.update(clonedRepo.getConfig());
clonedRepo.getConfig().save();
@@ -302,26 +324,33 @@ private FetchResult fetch(Repository clonedRepo, URIish u)
return command.call();
}
- private List<RefSpec> calculateRefSpecs(boolean fetchAll, String dst) {
- RefSpec heads = new RefSpec();
- heads = heads.setForceUpdate(true);
- heads = heads.setSourceDestination(Constants.R_HEADS + '*', dst);
+ private List<RefSpec> calculateRefSpecs(FETCH_TYPE type,
+ String remoteName) {
List<RefSpec> specs = new ArrayList<>();
- if (!fetchAll) {
- RefSpec tags = new RefSpec();
- tags = tags.setForceUpdate(true);
- tags = tags.setSourceDestination(Constants.R_TAGS + '*',
- Constants.R_TAGS + '*');
- for (String selectedRef : branchesToClone) {
- if (heads.matchSource(selectedRef)) {
- specs.add(heads.expandFromSource(selectedRef));
- } else if (tags.matchSource(selectedRef)) {
- specs.add(tags.expandFromSource(selectedRef));
- }
- }
+ if (type == FETCH_TYPE.MIRROR) {
+ specs.add(new RefSpec().setForceUpdate(true).setSourceDestination(
+ Constants.R_REFS + '*', Constants.R_REFS + '*'));
} else {
- // We'll fetch the tags anyway.
- specs.add(heads);
+ RefSpec heads = new RefSpec();
+ heads = heads.setForceUpdate(true);
+ final String dst = (bare ? Constants.R_HEADS
+ : Constants.R_REMOTES + remoteName + '/') + '*';
+ heads = heads.setSourceDestination(Constants.R_HEADS + '*', dst);
+ if (type == FETCH_TYPE.MULTIPLE_BRANCHES) {
+ RefSpec tags = new RefSpec().setForceUpdate(true)
+ .setSourceDestination(Constants.R_TAGS + '*',
+ Constants.R_TAGS + '*');
+ for (String selectedRef : branchesToClone) {
+ if (heads.matchSource(selectedRef)) {
+ specs.add(heads.expandFromSource(selectedRef));
+ } else if (tags.matchSource(selectedRef)) {
+ specs.add(tags.expandFromSource(selectedRef));
+ }
+ }
+ } else {
+ // We'll fetch the tags anyway.
+ specs.add(heads);
+ }
}
return specs;
}
@@ -614,6 +643,26 @@ public CloneCommand setCloneAllBranches(boolean cloneAllBranches) {
}
/**
+ * Set up a mirror of the source repository. This implies that a bare
+ * repository will be created. Compared to {@link #setBare},
+ * {@code #setMirror} not only maps local branches of the source to local
+ * branches of the target, it maps all refs (including remote-tracking
+ * branches, notes etc.) and sets up a refspec configuration such that all
+ * these refs are overwritten by a git remote update in the target
+ * repository.
+ *
+ * @param mirror
+ * whether to mirror all refs from the source repository
+ *
+ * @return {@code this}
+ * @since 5.6
+ */
+ public CloneCommand setMirror(boolean mirror) {
+ this.mirror = mirror;
+ return this;
+ }
+
+ /**
* Set whether to clone submodules
*
* @param cloneSubmodules
@@ -630,8 +679,9 @@ public CloneCommand setCloneSubmodules(boolean cloneSubmodules) {
* Set the branches or tags to clone.
* <p>
* This is ignored if {@link #setCloneAllBranches(boolean)
- * setCloneAllBranches(true)} is used. If {@code branchesToClone} is
- * {@code null} or empty, it's also ignored and all branches will be cloned.
+ * setCloneAllBranches(true)} or {@link #setMirror(boolean) setMirror(true)}
+ * is used. If {@code branchesToClone} is {@code null} or empty, it's also
+ * ignored.
* </p>
*
* @param branchesToClone
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/api/CommitCommand.java b/org.eclipse.jgit/src/org/eclipse/jgit/api/CommitCommand.java
index b55987e..b32f7ab 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/api/CommitCommand.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/api/CommitCommand.java
@@ -143,6 +143,8 @@ public class CommitCommand extends GitCommand<RevCommit> {
private HashMap<String, PrintStream> hookOutRedirect = new HashMap<>(3);
+ private HashMap<String, PrintStream> hookErrRedirect = new HashMap<>(3);
+
private Boolean allowEmpty;
private Boolean signCommit;
@@ -188,7 +190,8 @@ public RevCommit call() throws GitAPIException, NoHeadException,
state.name()));
if (!noVerify) {
- Hooks.preCommit(repo, hookOutRedirect.get(PreCommitHook.NAME))
+ Hooks.preCommit(repo, hookOutRedirect.get(PreCommitHook.NAME),
+ hookErrRedirect.get(PreCommitHook.NAME))
.call();
}
@@ -230,7 +233,8 @@ public RevCommit call() throws GitAPIException, NoHeadException,
if (!noVerify) {
message = Hooks
.commitMsg(repo,
- hookOutRedirect.get(CommitMsgHook.NAME))
+ hookOutRedirect.get(CommitMsgHook.NAME),
+ hookErrRedirect.get(CommitMsgHook.NAME))
.setCommitMessage(message).call();
}
@@ -311,7 +315,8 @@ public RevCommit call() throws GitAPIException, NoHeadException,
repo.writeRevertHead(null);
}
Hooks.postCommit(repo,
- hookOutRedirect.get(PostCommitHook.NAME)).call();
+ hookOutRedirect.get(PostCommitHook.NAME),
+ hookErrRedirect.get(PostCommitHook.NAME)).call();
return revCommit;
}
@@ -519,7 +524,7 @@ private int lookupOnly(String pathString) {
int position = Collections.binarySearch(only, p);
if (position >= 0)
return position;
- int l = p.lastIndexOf("/"); //$NON-NLS-1$
+ int l = p.lastIndexOf('/');
if (l < 1)
break;
p = p.substring(0, l);
@@ -891,6 +896,23 @@ public CommitCommand setHookOutputStream(PrintStream hookStdOut) {
}
/**
+ * Set the error stream for all hook scripts executed by this command
+ * (pre-commit, commit-msg, post-commit). If not set it defaults to
+ * {@code System.err}.
+ *
+ * @param hookStdErr
+ * the error stream for hook scripts executed by this command
+ * @return {@code this}
+ * @since 5.6
+ */
+ public CommitCommand setHookErrorStream(PrintStream hookStdErr) {
+ setHookErrorStream(PreCommitHook.NAME, hookStdErr);
+ setHookErrorStream(CommitMsgHook.NAME, hookStdErr);
+ setHookErrorStream(PostCommitHook.NAME, hookStdErr);
+ return this;
+ }
+
+ /**
* Set the output stream for a selected hook script executed by this command
* (pre-commit, commit-msg, post-commit). If not set it defaults to
* {@code System.out}.
@@ -916,6 +938,30 @@ public CommitCommand setHookOutputStream(String hookName,
}
/**
+ * Set the error stream for a selected hook script executed by this command
+ * (pre-commit, commit-msg, post-commit). If not set it defaults to
+ * {@code System.err}.
+ *
+ * @param hookName
+ * name of the hook to set the output stream for
+ * @param hookStdErr
+ * the output stream to use for the selected hook
+ * @return {@code this}
+ * @since 5.6
+ */
+ public CommitCommand setHookErrorStream(String hookName,
+ PrintStream hookStdErr) {
+ if (!(PreCommitHook.NAME.equals(hookName)
+ || CommitMsgHook.NAME.equals(hookName)
+ || PostCommitHook.NAME.equals(hookName))) {
+ throw new IllegalArgumentException(MessageFormat
+ .format(JGitText.get().illegalHookName, hookName));
+ }
+ hookErrRedirect.put(hookName, hookStdErr);
+ return this;
+ }
+
+ /**
* Sets the signing key
* <p>
* Per spec of user.signingKey: this will be sent to the GPG program as is,
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/api/DiffCommand.java b/org.eclipse.jgit/src/org/eclipse/jgit/api/DiffCommand.java
index f65b573..1c3c790 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/api/DiffCommand.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/api/DiffCommand.java
@@ -136,28 +136,32 @@ public List<DiffEntry> call() throws GitAPIException {
}
newTree = new DirCacheIterator(repo.readDirCache());
} else {
- if (oldTree == null)
+ if (oldTree == null) {
oldTree = new DirCacheIterator(repo.readDirCache());
- if (newTree == null)
+ }
+ if (newTree == null) {
newTree = new FileTreeIterator(repo);
+ }
}
diffFmt.setPathFilter(pathFilter);
List<DiffEntry> result = diffFmt.scan(oldTree, newTree);
- if (showNameAndStatusOnly)
- return result;
- else {
- if (contextLines >= 0)
- diffFmt.setContext(contextLines);
- if (destinationPrefix != null)
- diffFmt.setNewPrefix(destinationPrefix);
- if (sourcePrefix != null)
- diffFmt.setOldPrefix(sourcePrefix);
- diffFmt.format(result);
- diffFmt.flush();
+ if (showNameAndStatusOnly) {
return result;
}
+ if (contextLines >= 0) {
+ diffFmt.setContext(contextLines);
+ }
+ if (destinationPrefix != null) {
+ diffFmt.setNewPrefix(destinationPrefix);
+ }
+ if (sourcePrefix != null) {
+ diffFmt.setOldPrefix(sourcePrefix);
+ }
+ diffFmt.format(result);
+ diffFmt.flush();
+ return result;
} catch (IOException e) {
throw new JGitInternalException(e.getMessage(), e);
}
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/api/FetchCommand.java b/org.eclipse.jgit/src/org/eclipse/jgit/api/FetchCommand.java
index 2c9c5f2..9020c58 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/api/FetchCommand.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/api/FetchCommand.java
@@ -360,17 +360,17 @@ public FetchCommand setCheckFetchedObjects(boolean checkFetchedObjects) {
* @return whether to remove refs which no longer exist in the source
*/
public boolean isRemoveDeletedRefs() {
- if (removeDeletedRefs != null)
+ if (removeDeletedRefs != null) {
return removeDeletedRefs.booleanValue();
- else { // fall back to configuration
- boolean result = false;
- StoredConfig config = repo.getConfig();
- result = config.getBoolean(ConfigConstants.CONFIG_FETCH_SECTION,
- null, ConfigConstants.CONFIG_KEY_PRUNE, result);
- result = config.getBoolean(ConfigConstants.CONFIG_REMOTE_SECTION,
- remote, ConfigConstants.CONFIG_KEY_PRUNE, result);
- return result;
}
+ // fall back to configuration
+ boolean result = false;
+ StoredConfig config = repo.getConfig();
+ result = config.getBoolean(ConfigConstants.CONFIG_FETCH_SECTION, null,
+ ConfigConstants.CONFIG_KEY_PRUNE, result);
+ result = config.getBoolean(ConfigConstants.CONFIG_REMOTE_SECTION,
+ remote, ConfigConstants.CONFIG_KEY_PRUNE, result);
+ return result;
}
/**
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/api/GarbageCollectCommand.java b/org.eclipse.jgit/src/org/eclipse/jgit/api/GarbageCollectCommand.java
index 7ea2771..474e2f5 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/api/GarbageCollectCommand.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/api/GarbageCollectCommand.java
@@ -243,9 +243,8 @@ public Properties getStatistics() throws GitAPIException {
if (repo instanceof FileRepository) {
GC gc = new GC((FileRepository) repo);
return toProperties(gc.getStatistics());
- } else {
- return new Properties();
}
+ return new Properties();
} catch (IOException e) {
throw new JGitInternalException(
JGitText.get().couldNotGetRepoStatistics, e);
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/api/LogCommand.java b/org.eclipse.jgit/src/org/eclipse/jgit/api/LogCommand.java
index 66de8ae..217785d 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/api/LogCommand.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/api/LogCommand.java
@@ -105,6 +105,7 @@ public class LogCommand extends GitCommand<Iterable<RevCommit>> {
private RevFilter revFilter;
private final List<PathFilter> pathFilters = new ArrayList<>();
+ private final List<TreeFilter> excludeTreeFilters = new ArrayList<>();
private int maxCount = -1;
@@ -133,9 +134,22 @@ protected LogCommand(Repository repo) {
@Override
public Iterable<RevCommit> call() throws GitAPIException, NoHeadException {
checkCallable();
- if (!pathFilters.isEmpty())
- walk.setTreeFilter(AndTreeFilter.create(
- PathFilterGroup.create(pathFilters), TreeFilter.ANY_DIFF));
+ List<TreeFilter> filters = new ArrayList<>();
+ if (!pathFilters.isEmpty()) {
+ filters.add(AndTreeFilter.create(PathFilterGroup.create(pathFilters), TreeFilter.ANY_DIFF));
+ }
+ if (!excludeTreeFilters.isEmpty()) {
+ for (TreeFilter f : excludeTreeFilters) {
+ filters.add(AndTreeFilter.create(f, TreeFilter.ANY_DIFF));
+ }
+ }
+ if (!filters.isEmpty()) {
+ if (filters.size() == 1) {
+ filters.add(TreeFilter.ANY_DIFF);
+ }
+ walk.setTreeFilter(AndTreeFilter.create(filters));
+
+ }
if (skip > -1 && maxCount > -1)
walk.setRevFilter(AndRevFilter.create(SkipRevFilter.create(skip),
MaxCountRevFilter.create(maxCount)));
@@ -310,6 +324,24 @@ public LogCommand addPath(String path) {
}
/**
+ * Show all commits that are not within any of the specified paths. The path
+ * must either name a file or a directory exactly and use <code>/</code>
+ * (slash) as separator. Note that regular expressions or wildcards are not
+ * yet supported. If a path is both added and excluded from the search, then
+ * the exclusion wins.
+ *
+ * @param path
+ * a repository-relative path (with <code>/</code> as separator)
+ * @return {@code this}
+ * @since 5.6
+ */
+ public LogCommand excludePath(String path) {
+ checkCallable();
+ excludeTreeFilters.add(PathFilter.create(path).negate());
+ return this;
+ }
+
+ /**
* Skip the number of commits before starting to show the commit output.
*
* @param skip
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/api/MergeCommand.java b/org.eclipse.jgit/src/org/eclipse/jgit/api/MergeCommand.java
index f9a9baf..9a843f6 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/api/MergeCommand.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/api/MergeCommand.java
@@ -409,27 +409,24 @@ public MergeResult call() throws GitAPIException, NoHeadException,
new ObjectId[] { headCommit.getId(),
srcCommit.getId() }, mergeStatus,
mergeStrategy, null, msg);
- } else {
- if (failingPaths != null) {
- repo.writeMergeCommitMsg(null);
- repo.writeMergeHeads(null);
- return new MergeResult(null, merger.getBaseCommitId(),
- new ObjectId[] {
- headCommit.getId(), srcCommit.getId() },
- MergeStatus.FAILED, mergeStrategy,
- lowLevelResults, failingPaths, null);
- } else {
- String mergeMessageWithConflicts = new MergeMessageFormatter()
- .formatWithConflicts(mergeMessage,
- unmergedPaths);
- repo.writeMergeCommitMsg(mergeMessageWithConflicts);
- return new MergeResult(null, merger.getBaseCommitId(),
- new ObjectId[] { headCommit.getId(),
- srcCommit.getId() },
- MergeStatus.CONFLICTING, mergeStrategy,
- lowLevelResults, null);
- }
}
+ if (failingPaths != null) {
+ repo.writeMergeCommitMsg(null);
+ repo.writeMergeHeads(null);
+ return new MergeResult(null, merger.getBaseCommitId(),
+ new ObjectId[] { headCommit.getId(),
+ srcCommit.getId() },
+ MergeStatus.FAILED, mergeStrategy, lowLevelResults,
+ failingPaths, null);
+ }
+ String mergeMessageWithConflicts = new MergeMessageFormatter()
+ .formatWithConflicts(mergeMessage, unmergedPaths);
+ repo.writeMergeCommitMsg(mergeMessageWithConflicts);
+ return new MergeResult(null, merger.getBaseCommitId(),
+ new ObjectId[] { headCommit.getId(),
+ srcCommit.getId() },
+ MergeStatus.CONFLICTING, mergeStrategy, lowLevelResults,
+ null);
}
} catch (org.eclipse.jgit.errors.CheckoutConflictException e) {
List<String> conflicts = (dco == null) ? Collections
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/api/PullCommand.java b/org.eclipse.jgit/src/org/eclipse/jgit/api/PullCommand.java
index bdb2d1bb..ea3e2d9 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/api/PullCommand.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/api/PullCommand.java
@@ -90,7 +90,7 @@
*/
public class PullCommand extends TransportCommand<PullCommand, PullResult> {
- private final static String DOT = "."; //$NON-NLS-1$
+ private static final String DOT = "."; //$NON-NLS-1$
private ProgressMonitor monitor = NullProgressMonitor.INSTANCE;
@@ -315,23 +315,24 @@ public PullResult call() throws GitAPIException,
Ref r = null;
if (fetchRes != null) {
r = fetchRes.getAdvertisedRef(remoteBranchName);
- if (r == null)
+ if (r == null) {
r = fetchRes.getAdvertisedRef(Constants.R_HEADS
+ remoteBranchName);
+ }
}
if (r == null) {
throw new RefNotAdvertisedException(MessageFormat.format(
JGitText.get().couldNotGetAdvertisedRef, remote,
remoteBranchName));
- } else {
- commitToMerge = r.getObjectId();
}
+ commitToMerge = r.getObjectId();
} else {
try {
commitToMerge = repo.resolve(remoteBranchName);
- if (commitToMerge == null)
+ if (commitToMerge == null) {
throw new RefNotFoundException(MessageFormat.format(
JGitText.get().refNotResolved, remoteBranchName));
+ }
} catch (IOException e) {
throw new JGitInternalException(
JGitText.get().exceptionCaughtDuringExecutionOfPullCommand,
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/api/RebaseCommand.java b/org.eclipse.jgit/src/org/eclipse/jgit/api/RebaseCommand.java
index 0dacd4d..6eed0b3 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/api/RebaseCommand.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/api/RebaseCommand.java
@@ -509,10 +509,10 @@ private RebaseResult cherryPickCommit(RevCommit commitToPick)
monitor.beginTask(MessageFormat.format(
JGitText.get().applyingCommit,
commitToPick.getShortMessage()), ProgressMonitor.UNKNOWN);
- if (preserveMerges)
+ if (preserveMerges) {
return cherryPickCommitPreservingMerges(commitToPick);
- else
- return cherryPickCommitFlattening(commitToPick);
+ }
+ return cherryPickCommitFlattening(commitToPick);
} finally {
monitor.endTask();
}
@@ -539,11 +539,11 @@ private RebaseResult cherryPickCommitFlattening(RevCommit commitToPick)
.call();
switch (cherryPickResult.getStatus()) {
case FAILED:
- if (operation == Operation.BEGIN)
+ if (operation == Operation.BEGIN) {
return abort(RebaseResult
.failed(cherryPickResult.getFailingPaths()));
- else
- return stop(commitToPick, Status.STOPPED);
+ }
+ return stop(commitToPick, Status.STOPPED);
case CONFLICTING:
return stop(commitToPick, Status.STOPPED);
case OK:
@@ -599,11 +599,11 @@ private RebaseResult cherryPickCommitPreservingMerges(RevCommit commitToPick)
CherryPickResult cherryPickResult = pickCommand.call();
switch (cherryPickResult.getStatus()) {
case FAILED:
- if (operation == Operation.BEGIN)
+ if (operation == Operation.BEGIN) {
return abort(RebaseResult.failed(
cherryPickResult.getFailingPaths()));
- else
- return stop(commitToPick, Status.STOPPED);
+ }
+ return stop(commitToPick, Status.STOPPED);
case CONFLICTING:
return stop(commitToPick, Status.STOPPED);
case OK:
@@ -833,7 +833,8 @@ private static String composeSquashMessage(boolean isSquash,
sb.append("# This is a combination of ").append(count)
.append(" commits.\n");
// Add the previous message without header (i.e first line)
- sb.append(currSquashMessage.substring(currSquashMessage.indexOf("\n") + 1));
+ sb.append(currSquashMessage
+ .substring(currSquashMessage.indexOf('\n') + 1));
sb.append("\n");
if (isSquash) {
sb.append("# This is the ").append(count).append(ordinal)
@@ -871,7 +872,7 @@ private static String getOrdinal(int count) {
static int parseSquashFixupSequenceCount(String currSquashMessage) {
String regex = "This is a combination of (.*) commits"; //$NON-NLS-1$
String firstLine = currSquashMessage.substring(0,
- currSquashMessage.indexOf("\n")); //$NON-NLS-1$
+ currSquashMessage.indexOf('\n'));
Pattern pattern = Pattern.compile(regex);
Matcher matcher = pattern.matcher(firstLine);
if (!matcher.find())
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/api/ResetCommand.java b/org.eclipse.jgit/src/org/eclipse/jgit/api/ResetCommand.java
index d7c9ad5..3031a19 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/api/ResetCommand.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/api/ResetCommand.java
@@ -334,10 +334,10 @@ public boolean isReflogDisabled() {
}
private String getRefOrHEAD() {
- if (ref != null)
+ if (ref != null) {
return ref;
- else
- return Constants.HEAD;
+ }
+ return Constants.HEAD;
}
/**
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/api/RevertCommand.java b/org.eclipse.jgit/src/org/eclipse/jgit/api/RevertCommand.java
index ddd60b6..aa0055f 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/api/RevertCommand.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/api/RevertCommand.java
@@ -58,6 +58,7 @@
import org.eclipse.jgit.api.errors.UnmergedPathsException;
import org.eclipse.jgit.api.errors.WrongRepositoryStateException;
import org.eclipse.jgit.dircache.DirCacheCheckout;
+import org.eclipse.jgit.events.WorkingTreeModifiedEvent;
import org.eclipse.jgit.internal.JGitText;
import org.eclipse.jgit.lib.AnyObjectId;
import org.eclipse.jgit.lib.Constants;
@@ -175,6 +176,10 @@ public RevCommit call() throws NoMessageException, UnmergedPathsException,
+ "This reverts commit " + srcCommit.getId().getName() //$NON-NLS-1$
+ ".\n"; //$NON-NLS-1$
if (merger.merge(headCommit, srcParent)) {
+ if (!merger.getModifiedFiles().isEmpty()) {
+ repo.fireEvent(new WorkingTreeModifiedEvent(
+ merger.getModifiedFiles(), null));
+ }
if (AnyObjectId.isEqual(headCommit.getTree().getId(),
merger.getResultTreeId()))
continue;
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/api/SubmoduleSyncCommand.java b/org.eclipse.jgit/src/org/eclipse/jgit/api/SubmoduleSyncCommand.java
index 5239369..74def9e 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/api/SubmoduleSyncCommand.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/api/SubmoduleSyncCommand.java
@@ -106,10 +106,10 @@ public SubmoduleSyncCommand addPath(String path) {
*/
protected String getHeadBranch(Repository subRepo) throws IOException {
Ref head = subRepo.exactRef(Constants.HEAD);
- if (head != null && head.isSymbolic())
+ if (head != null && head.isSymbolic()) {
return Repository.shortenRefName(head.getLeaf().getName());
- else
- return null;
+ }
+ return null;
}
/** {@inheritDoc} */
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/api/errors/AbortedByHookException.java b/org.eclipse.jgit/src/org/eclipse/jgit/api/errors/AbortedByHookException.java
index db6440b..30a2d62 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/api/errors/AbortedByHookException.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/api/errors/AbortedByHookException.java
@@ -67,19 +67,26 @@ public class AbortedByHookException extends GitAPIException {
private final int returnCode;
/**
+ * The stderr output of the hook.
+ */
+ private final String hookStdErr;
+
+ /**
* Constructor for AbortedByHookException
*
- * @param message
- * The error details.
+ * @param hookStdErr
+ * The error details from the stderr output of the hook
* @param hookName
* The name of the hook that interrupted the command, must not be
* null.
* @param returnCode
* The return code of the hook process that has been run.
*/
- public AbortedByHookException(String message, String hookName,
+ public AbortedByHookException(String hookStdErr, String hookName,
int returnCode) {
- super(message);
+ super(MessageFormat.format(JGitText.get().commandRejectedByHook,
+ hookName, hookStdErr));
+ this.hookStdErr = hookStdErr;
this.hookName = hookName;
this.returnCode = returnCode;
}
@@ -102,10 +109,13 @@ public int getReturnCode() {
return returnCode;
}
- /** {@inheritDoc} */
- @Override
- public String getMessage() {
- return MessageFormat.format(JGitText.get().commandRejectedByHook,
- hookName, super.getMessage());
+ /**
+ * Get the stderr output of the hook.
+ *
+ * @return A string containing the complete stderr output of the hook.
+ * @since 5.6
+ */
+ public String getHookStdErr() {
+ return hookStdErr;
}
}
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/attributes/Attribute.java b/org.eclipse.jgit/src/org/eclipse/jgit/attributes/Attribute.java
index f1df0da..b732050 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/attributes/Attribute.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/attributes/Attribute.java
@@ -67,7 +67,7 @@ public final class Attribute {
* The attribute value state
* see also https://www.kernel.org/pub/software/scm/git/docs/gitattributes.html
*/
- public static enum State {
+ public enum State {
/** the attribute is set */
SET,
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/attributes/AttributesRule.java b/org.eclipse.jgit/src/org/eclipse/jgit/attributes/AttributesRule.java
index a91d8c2..ead99c7 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/attributes/AttributesRule.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/attributes/AttributesRule.java
@@ -91,7 +91,7 @@ private static List<Attribute> parseAttributes(String attributesLine) {
continue;
}
- final int equalsIndex = attribute.indexOf("="); //$NON-NLS-1$
+ final int equalsIndex = attribute.indexOf('=');
if (equalsIndex == -1)
result.add(new Attribute(attribute, State.SET));
else {
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/blame/BlameGenerator.java b/org.eclipse.jgit/src/org/eclipse/jgit/blame/BlameGenerator.java
index 9cec645..d0aa292 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/blame/BlameGenerator.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/blame/BlameGenerator.java
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2011, Google Inc.
+ * Copyright (C) 2011, 2019 Google Inc.
* and other copyright owners as documented in the project's IP log.
*
* This program and the accompanying materials are made available
@@ -48,11 +48,17 @@
import static org.eclipse.jgit.lib.FileMode.TYPE_MASK;
import java.io.IOException;
+import java.io.InputStream;
+import java.text.MessageFormat;
+import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
+import java.util.List;
import org.eclipse.jgit.annotations.Nullable;
+import org.eclipse.jgit.api.errors.NoHeadException;
import org.eclipse.jgit.blame.Candidate.BlobCandidate;
+import org.eclipse.jgit.blame.Candidate.HeadCandidate;
import org.eclipse.jgit.blame.Candidate.ReverseCandidate;
import org.eclipse.jgit.blame.ReverseWalk.ReverseCommit;
import org.eclipse.jgit.diff.DiffAlgorithm;
@@ -63,8 +69,13 @@
import org.eclipse.jgit.diff.RawText;
import org.eclipse.jgit.diff.RawTextComparator;
import org.eclipse.jgit.diff.RenameDetector;
+import org.eclipse.jgit.dircache.DirCache;
+import org.eclipse.jgit.dircache.DirCacheEntry;
+import org.eclipse.jgit.dircache.DirCacheIterator;
+import org.eclipse.jgit.errors.NoWorkTreeException;
import org.eclipse.jgit.internal.JGitText;
import org.eclipse.jgit.lib.AnyObjectId;
+import org.eclipse.jgit.lib.Constants;
import org.eclipse.jgit.lib.MutableObjectId;
import org.eclipse.jgit.lib.ObjectId;
import org.eclipse.jgit.lib.ObjectLoader;
@@ -74,9 +85,12 @@
import org.eclipse.jgit.revwalk.RevCommit;
import org.eclipse.jgit.revwalk.RevFlag;
import org.eclipse.jgit.revwalk.RevWalk;
+import org.eclipse.jgit.treewalk.FileTreeIterator;
import org.eclipse.jgit.treewalk.TreeWalk;
+import org.eclipse.jgit.treewalk.TreeWalk.OperationType;
import org.eclipse.jgit.treewalk.filter.PathFilter;
import org.eclipse.jgit.treewalk.filter.TreeFilter;
+import org.eclipse.jgit.util.IO;
/**
* Generate author information for lines based on a provided file.
@@ -313,6 +327,107 @@ public BlameGenerator push(String description, RawText contents)
}
/**
+ * Pushes HEAD, index, and working tree as appropriate for blaming the file
+ * given in the constructor {@link #BlameGenerator(Repository, String)}
+ * against HEAD. Includes special handling in case the file is in conflict
+ * state from an unresolved merge conflict.
+ *
+ * @return {@code this}
+ * @throws NoHeadException
+ * if the repository has no HEAD
+ * @throws IOException
+ * if an error occurs
+ * @since 5.6
+ */
+ public BlameGenerator prepareHead() throws NoHeadException, IOException {
+ Repository repo = getRepository();
+ ObjectId head = repo.resolve(Constants.HEAD);
+ if (head == null) {
+ throw new NoHeadException(MessageFormat
+ .format(JGitText.get().noSuchRefKnown, Constants.HEAD));
+ }
+ if (repo.isBare()) {
+ return push(null, head);
+ }
+ DirCache dc = repo.readDirCache();
+ try (TreeWalk walk = new TreeWalk(repo)) {
+ walk.setOperationType(OperationType.CHECKIN_OP);
+ FileTreeIterator iter = new FileTreeIterator(repo);
+ int fileTree = walk.addTree(iter);
+ int indexTree = walk.addTree(new DirCacheIterator(dc));
+ iter.setDirCacheIterator(walk, indexTree);
+ walk.setFilter(resultPath);
+ walk.setRecursive(true);
+ if (!walk.next()) {
+ return this;
+ }
+ DirCacheIterator dcIter = walk.getTree(indexTree,
+ DirCacheIterator.class);
+ if (dcIter == null) {
+ // Not found in index
+ return this;
+ }
+ iter = walk.getTree(fileTree, FileTreeIterator.class);
+ if (iter == null || !isFile(iter.getEntryRawMode())) {
+ return this;
+ }
+ RawText inTree;
+ long filteredLength = iter.getEntryContentLength();
+ try (InputStream stream = iter.openEntryStream()) {
+ inTree = new RawText(getBytes(iter.getEntryFile().getPath(),
+ stream, filteredLength));
+ }
+ DirCacheEntry indexEntry = dcIter.getDirCacheEntry();
+ if (indexEntry.getStage() == DirCacheEntry.STAGE_0) {
+ push(null, head);
+ push(null, indexEntry.getObjectId());
+ push(null, inTree);
+ } else {
+ // Create a special candidate using the working tree file as
+ // blob and HEAD and the MERGE_HEADs as parents.
+ HeadCandidate c = new HeadCandidate(getRepository(), resultPath,
+ getHeads(repo, head));
+ c.sourceText = inTree;
+ c.regionList = new Region(0, 0, inTree.size());
+ remaining = inTree.size();
+ push(c);
+ }
+ }
+ return this;
+ }
+
+ private List<RevCommit> getHeads(Repository repo, ObjectId head)
+ throws NoWorkTreeException, IOException {
+ List<ObjectId> mergeIds = repo.readMergeHeads();
+ if (mergeIds == null || mergeIds.isEmpty()) {
+ return Collections.singletonList(revPool.parseCommit(head));
+ }
+ List<RevCommit> heads = new ArrayList<>(mergeIds.size() + 1);
+ heads.add(revPool.parseCommit(head));
+ for (ObjectId id : mergeIds) {
+ heads.add(revPool.parseCommit(id));
+ }
+ return heads;
+ }
+
+ private static byte[] getBytes(String path, InputStream in, long maxLength)
+ throws IOException {
+ if (maxLength > Integer.MAX_VALUE) {
+ throw new IOException(
+ MessageFormat.format(JGitText.get().fileIsTooLarge, path));
+ }
+ int max = (int) maxLength;
+ byte[] buffer = new byte[max];
+ int read = IO.readFully(in, buffer, 0);
+ if (read == max) {
+ return buffer;
+ }
+ byte[] copy = new byte[read];
+ System.arraycopy(buffer, 0, copy, 0, read);
+ return copy;
+ }
+
+ /**
* Push a candidate object onto the generator's traversal stack.
* <p>
* Candidates should be pushed in history order from oldest-to-newest.
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/blame/BlameResult.java b/org.eclipse.jgit/src/org/eclipse/jgit/blame/BlameResult.java
index 5fb7750..394aba6 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/blame/BlameResult.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/blame/BlameResult.java
@@ -267,18 +267,18 @@ public void computeAll() throws IOException {
*/
public int computeNext() throws IOException {
BlameGenerator gen = generator;
- if (gen == null)
+ if (gen == null) {
return -1;
+ }
if (gen.next()) {
loadFrom(gen);
lastLength = gen.getRegionLength();
return gen.getResultStart();
- } else {
- gen.close();
- generator = null;
- return -1;
}
+ gen.close();
+ generator = null;
+ return -1;
}
/**
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/blame/Candidate.java b/org.eclipse.jgit/src/org/eclipse/jgit/blame/Candidate.java
index 457d1d2..3ef4943 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/blame/Candidate.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/blame/Candidate.java
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2011, Google Inc.
+ * Copyright (C) 2011, 2019 Google Inc.
* and other copyright owners as documented in the project's IP log.
*
* This program and the accompanying materials are made available
@@ -44,12 +44,14 @@
package org.eclipse.jgit.blame;
import java.io.IOException;
+import java.util.List;
import org.eclipse.jgit.blame.ReverseWalk.ReverseCommit;
import org.eclipse.jgit.diff.Edit;
import org.eclipse.jgit.diff.EditList;
import org.eclipse.jgit.diff.RawText;
import org.eclipse.jgit.errors.MissingObjectException;
+import org.eclipse.jgit.internal.JGitText;
import org.eclipse.jgit.lib.Constants;
import org.eclipse.jgit.lib.ObjectId;
import org.eclipse.jgit.lib.ObjectLoader;
@@ -392,6 +394,66 @@ public String toString() {
}
/**
+ * A {@link Candidate} to blame a working tree file in conflict state.
+ * <p>
+ * Contrary to {@link BlobCandidate}, it expects to be given the parent
+ * commits (typically HEAD and the MERGE_HEADs) and behaves like a merge
+ * commit during blame. It does <em>not</em> consider a previously pushed
+ * Candidate as its parent.
+ * </p>
+ */
+ static final class HeadCandidate extends Candidate {
+
+ private List<RevCommit> parents;
+
+ HeadCandidate(Repository repo, PathFilter path,
+ List<RevCommit> parents) {
+ super(repo, null, path);
+ this.parents = parents;
+ }
+
+ @Override
+ void beginResult(RevWalk rw) {
+ // Blob candidates have nothing to prepare.
+ }
+
+ @Override
+ int getParentCount() {
+ return parents.size();
+ }
+
+ @Override
+ RevCommit getParent(int idx) {
+ return parents.get(idx);
+ }
+
+ @Override
+ boolean has(RevFlag flag) {
+ return true; // Pretend flag was added; sourceCommit is null.
+ }
+
+ @Override
+ void add(RevFlag flag) {
+ // Do nothing, sourceCommit is null.
+ }
+
+ @Override
+ void remove(RevFlag flag) {
+ // Do nothing, sourceCommit is null.
+ }
+
+ @Override
+ int getTime() {
+ return Integer.MAX_VALUE;
+ }
+
+ @Override
+ PersonIdent getAuthor() {
+ return new PersonIdent(JGitText.get().blameNotCommittedYet, ""); //$NON-NLS-1$
+ }
+ }
+
+ /**
* Candidate loaded from a file source, and not a commit.
* <p>
* The {@link Candidate#sourceCommit} field is always null on this type of
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/diff/DiffConfig.java b/org.eclipse.jgit/src/org/eclipse/jgit/diff/DiffConfig.java
index ca37a10..9071aeb 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/diff/DiffConfig.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/diff/DiffConfig.java
@@ -59,7 +59,7 @@ public class DiffConfig {
public static final Config.SectionParser<DiffConfig> KEY = DiffConfig::new;
/** Permissible values for {@code diff.renames}. */
- public static enum RenameDetectionType {
+ public enum RenameDetectionType {
/** Rename detection is disabled. */
FALSE,
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/diff/DiffEntry.java b/org.eclipse.jgit/src/org/eclipse/jgit/diff/DiffEntry.java
index 5c8343f..9f660ec 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/diff/DiffEntry.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/diff/DiffEntry.java
@@ -72,7 +72,7 @@ public class DiffEntry {
public static final String DEV_NULL = "/dev/null"; //$NON-NLS-1$
/** General type of change a single file-level patch describes. */
- public static enum ChangeType {
+ public enum ChangeType {
/** Add a new file to the project */
ADD,
@@ -90,7 +90,7 @@ public static enum ChangeType {
}
/** Specify the old or new side for more generalized access. */
- public static enum Side {
+ public enum Side {
/** The old side of a DiffEntry. */
OLD,
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/diff/DiffFormatter.java b/org.eclipse.jgit/src/org/eclipse/jgit/diff/DiffFormatter.java
index 1cecff6..d764499 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/diff/DiffFormatter.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/diff/DiffFormatter.java
@@ -145,6 +145,8 @@ public class DiffFormatter implements AutoCloseable {
private Repository repository;
+ private Boolean quotePaths;
+
/**
* Create a new formatter with a default level of context.
*
@@ -199,6 +201,11 @@ private void setReader(ObjectReader reader, Config cfg, boolean closeReader) {
this.closeReader = closeReader;
this.reader = reader;
this.diffCfg = cfg.get(DiffConfig.KEY);
+ if (quotePaths == null) {
+ quotePaths = Boolean
+ .valueOf(cfg.getBoolean(ConfigConstants.CONFIG_CORE_SECTION,
+ ConfigConstants.CONFIG_KEY_QUOTE_PATH, true));
+ }
ContentSource cs = ContentSource.create(reader);
source = new ContentSource.Pair(cs, cs);
@@ -379,6 +386,21 @@ public void setProgressMonitor(ProgressMonitor pm) {
}
/**
+ * Sets whether or not path names should be quoted.
+ * <p>
+ * By default the setting of git config {@code core.quotePath} is active,
+ * but this can be overridden through this method.
+ * </p>
+ *
+ * @param quote
+ * whether to quote path names
+ * @since 5.6
+ */
+ public void setQuotePaths(boolean quote) {
+ quotePaths = Boolean.valueOf(quote);
+ }
+
+ /**
* Set the filter to produce only specific paths.
*
* If the filter is an instance of
@@ -489,8 +511,8 @@ private AbstractTreeIterator makeIteratorFromTreeOrNull(RevTree tree)
CanonicalTreeParser parser = new CanonicalTreeParser();
parser.reset(reader, tree);
return parser;
- } else
- return new EmptyTreeIterator();
+ }
+ return new EmptyTreeIterator();
}
/**
@@ -726,8 +748,11 @@ private String format(AbbreviatedObjectId id) {
return id.name();
}
- private static String quotePath(String name) {
- return QuotedString.GIT_PATH.quote(name);
+ private String quotePath(String path) {
+ if (quotePaths == null || quotePaths.booleanValue()) {
+ return QuotedString.GIT_PATH.quote(path);
+ }
+ return QuotedString.GIT_PATH_MINIMAL.quote(path);
}
/**
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/diff/Edit.java b/org.eclipse.jgit/src/org/eclipse/jgit/diff/Edit.java
index 5c876e8..b4e0963 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/diff/Edit.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/diff/Edit.java
@@ -64,7 +64,7 @@
*/
public class Edit {
/** Type of edit */
- public static enum Type {
+ public enum Type {
/** Sequence B has inserted the region. */
INSERT,
@@ -125,17 +125,17 @@ public Edit(int as, int ae, int bs, int be) {
*/
public final Type getType() {
if (beginA < endA) {
- if (beginB < endB)
+ if (beginB < endB) {
return Type.REPLACE;
- else /* if (beginB == endB) */
- return Type.DELETE;
+ }
+ return Type.DELETE;
- } else /* if (beginA == endA) */{
- if (beginB < endB)
- return Type.INSERT;
- else /* if (beginB == endB) */
- return Type.EMPTY;
}
+ if (beginB < endB) {
+ return Type.INSERT;
+ }
+ // beginB == endB)
+ return Type.EMPTY;
}
/**
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/diff/RawText.java b/org.eclipse.jgit/src/org/eclipse/jgit/diff/RawText.java
index 6c0d90e..4e79fc9 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/diff/RawText.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/diff/RawText.java
@@ -383,15 +383,17 @@ public static boolean isCrLfText(byte[] raw, int length) {
* @return the line delimiter or <code>null</code>
*/
public String getLineDelimiter() {
- if (size() == 0)
+ if (size() == 0) {
return null;
+ }
int e = getEnd(0);
- if (content[e - 1] != '\n')
+ if (content[e - 1] != '\n') {
return null;
- if (content.length > 1 && e > 1 && content[e - 2] == '\r')
+ }
+ if (content.length > 1 && e > 1 && content[e - 2] == '\r') {
return "\r\n"; //$NON-NLS-1$
- else
- return "\n"; //$NON-NLS-1$
+ }
+ return "\n"; //$NON-NLS-1$
}
/**
@@ -446,7 +448,7 @@ public static RawText load(ObjectLoader ldr, int threshold)
}
}
- byte data[];
+ byte[] data;
try {
data = new byte[(int)sz];
} catch (OutOfMemoryError e) {
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/diff/SimilarityRenameDetector.java b/org.eclipse.jgit/src/org/eclipse/jgit/diff/SimilarityRenameDetector.java
index d8a05c3..1b7babc 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/diff/SimilarityRenameDetector.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/diff/SimilarityRenameDetector.java
@@ -335,14 +335,14 @@ private int buildMatrix(ProgressMonitor pm)
}
static int nameScore(String a, String b) {
- int aDirLen = a.lastIndexOf("/") + 1; //$NON-NLS-1$
- int bDirLen = b.lastIndexOf("/") + 1; //$NON-NLS-1$
+ int aDirLen = a.lastIndexOf('/') + 1;
+ int bDirLen = b.lastIndexOf('/') + 1;
- int dirMin = Math.min(aDirLen, bDirLen);
- int dirMax = Math.max(aDirLen, bDirLen);
+ int dirMin = Math.min(aDirLen, bDirLen);
+ int dirMax = Math.max(aDirLen, bDirLen);
- final int dirScoreLtr;
- final int dirScoreRtl;
+ final int dirScoreLtr;
+ final int dirScoreRtl;
if (dirMax == 0) {
dirScoreLtr = 100;
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/dircache/DirCacheCheckout.java b/org.eclipse.jgit/src/org/eclipse/jgit/dircache/DirCacheCheckout.java
index 6bc2946..3502d7a 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/dircache/DirCacheCheckout.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/dircache/DirCacheCheckout.java
@@ -53,9 +53,11 @@
import java.time.Instant;
import java.util.ArrayList;
import java.util.HashMap;
+import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
+import java.util.Set;
import org.eclipse.jgit.api.errors.CanceledException;
import org.eclipse.jgit.api.errors.FilterFailedException;
@@ -104,7 +106,8 @@
* This class handles checking out one or two trees merging with the index.
*/
public class DirCacheCheckout {
- private static Logger LOG = LoggerFactory.getLogger(DirCacheCheckout.class);
+ private static final Logger LOG = LoggerFactory
+ .getLogger(DirCacheCheckout.class);
private static final int MAX_EXCEPTION_TEXT_SIZE = 10 * 1024;
@@ -142,6 +145,8 @@ public CheckoutMetadata(EolStreamType eolStreamType,
private ArrayList<String> removed = new ArrayList<>();
+ private ArrayList<String> kept = new ArrayList<>();
+
private ObjectId mergeCommitTree;
private DirCache dc;
@@ -432,11 +437,11 @@ void processEntry(CanonicalTreeParser m, DirCacheBuildIterator i,
if (mtime == null || mtime.equals(Instant.EPOCH)) {
entry.setLastModified(f.getEntryLastModifiedInstant());
}
- keep(entry, f);
+ keep(i.getEntryPathString(), entry, f);
}
} else
// The index contains a folder
- keep(i.getDirCacheEntry(), f);
+ keep(i.getEntryPathString(), i.getDirCacheEntry(), f);
} else {
// There is no entry in the merge commit. Means: we want to delete
// what's currently in the index and working tree
@@ -496,8 +501,11 @@ public boolean checkout() throws IOException {
dc.unlock();
} finally {
if (performingCheckout) {
+ Set<String> touched = new HashSet<>(conflicts);
+ touched.addAll(getUpdated().keySet());
+ touched.addAll(kept);
WorkingTreeModifiedEvent event = new WorkingTreeModifiedEvent(
- getUpdated().keySet(), getRemoved());
+ touched, getRemoved());
if (!event.isEmpty()) {
repo.fireEvent(event);
}
@@ -517,10 +525,10 @@ private boolean doCheckout() throws CorruptObjectException, IOException,
prescanOneTree();
if (!conflicts.isEmpty()) {
- if (failOnConflict)
+ if (failOnConflict) {
throw new CheckoutConflictException(conflicts.toArray(new String[0]));
- else
- cleanUpConflicts();
+ }
+ cleanUpConflicts();
}
// update our index
@@ -826,14 +834,14 @@ void processEntry(CanonicalTreeParser h, CanonicalTreeParser m,
break;
case 0xDFD: // 3 4
- keep(dce, f);
+ keep(name, dce, f);
break;
case 0xF0D: // 18
remove(name);
break;
case 0xDFF: // 5 5b 6 6b
if (equalIdAndMode(iId, iMode, mId, mMode))
- keep(dce, f); // 5 6
+ keep(name, dce, f); // 5 6
else
conflict(name, dce, h, m); // 5b 6b
break;
@@ -863,7 +871,7 @@ void processEntry(CanonicalTreeParser h, CanonicalTreeParser m,
conflict(name, dce, h, m); // 9
break;
case 0xFD0: // keep without a rule
- keep(dce, f);
+ keep(name, dce, f);
break;
case 0xFFD: // 12 13 14
if (equalIdAndMode(hId, hMode, iId, iMode))
@@ -883,7 +891,7 @@ void processEntry(CanonicalTreeParser h, CanonicalTreeParser m,
conflict(name, dce, h, m);
break;
default:
- keep(dce, f);
+ keep(name, dce, f);
}
return;
}
@@ -895,15 +903,14 @@ void processEntry(CanonicalTreeParser h, CanonicalTreeParser m,
// the workingtree entry doesn't exist or also contains a folder
// -> no problem
return;
- } else {
- // the workingtree entry exists and is not a folder
- if (!idEqual(h, m)) {
- // Because HEAD and MERGE differ we will try to update the
- // workingtree with a folder -> return a conflict
- conflict(name, null, null, null);
- }
- return;
}
+ // the workingtree entry exists and is not a folder
+ if (!idEqual(h, m)) {
+ // Because HEAD and MERGE differ we will try to update the
+ // workingtree with a folder -> return a conflict
+ conflict(name, null, null, null);
+ }
+ return;
}
if ((ffMask == 0x00F) && f != null && FileMode.TREE.equals(f.getEntryFileMode())) {
@@ -969,7 +976,7 @@ else if (m == null)
if (initialCheckout)
update(name, mId, mMode);
else
- keep(dce, f);
+ keep(name, dce, f);
} else
conflict(name, dce, h, m);
}
@@ -1032,7 +1039,7 @@ else if (m == null)
// Nothing in Head
// Something in Index
// -> Merge contains nothing new. Keep the index.
- keep(dce, f);
+ keep(name, dce, f);
} else
// Merge contains something and it is not the same as Index
// Nothing in Head
@@ -1083,15 +1090,15 @@ else if (m == null)
// Something in Head
if (!FileMode.TREE.equals(f.getEntryFileMode())
- && FileMode.TREE.equals(iMode))
+ && FileMode.TREE.equals(iMode)) {
// The workingtree contains a file and the index semantically contains a folder.
// Git considers the workingtree file as untracked. Just keep the untracked file.
return;
- else
- // -> file is dirty and tracked but is should be
- // removed. That's a conflict
- conflict(name, dce, h, m);
- } else
+ }
+ // -> file is dirty and tracked but is should be
+ // removed. That's a conflict
+ conflict(name, dce, h, m);
+ } else {
// file doesn't exist or is clean
// Index contains the same as Head
// Something different from a submodule in Index
@@ -1099,7 +1106,8 @@ else if (m == null)
// Something in Head
// -> Remove from index and delete the file
remove(name);
- } else
+ }
+ } else {
// Index contains something different from Head
// Something different from a submodule in Index
// Nothing in Merge
@@ -1108,6 +1116,7 @@ else if (m == null)
// filesystem). But Merge wants the path to be removed.
// Report a conflict
conflict(name, dce, h, m);
+ }
}
} else {
// Something in Merge
@@ -1181,7 +1190,7 @@ && isModified_IndexTree(name, iId, iMode, mId, mMode,
// to the other one.
// -> In all three cases we don't touch index and file.
- keep(dce, f);
+ keep(name, dce, f);
}
}
}
@@ -1230,13 +1239,17 @@ private void conflict(String path, DirCacheEntry e, AbstractTreeIterator h, Abst
}
}
- private void keep(DirCacheEntry e, WorkingTreeIterator f)
+ private void keep(String path, DirCacheEntry e, WorkingTreeIterator f)
throws IOException {
if (e != null && !FileMode.TREE.equals(e.getFileMode()))
builder.add(e);
if (force) {
- if (f.isModified(e, true, this.walk.getObjectReader())) {
- checkoutEntry(repo, e, this.walk.getObjectReader());
+ if (f.isModified(e, true, walk.getObjectReader())) {
+ kept.add(path);
+ checkoutEntry(repo, e, walk.getObjectReader(), false,
+ new CheckoutMetadata(walk.getEolStreamType(CHECKOUT_OP),
+ walk.getFilterCommand(
+ Constants.ATTR_FILTER_TYPE_SMUDGE)));
}
}
}
@@ -1340,13 +1353,14 @@ private boolean isModifiedSubtree_IndexWorkingtree(String path)
private boolean isModified_IndexTree(String path, ObjectId iId,
FileMode iMode, ObjectId tId, FileMode tMode, ObjectId rootTree)
throws CorruptObjectException, IOException {
- if (iMode != tMode)
+ if (iMode != tMode) {
return true;
+ }
if (FileMode.TREE.equals(iMode)
- && (iId == null || ObjectId.zeroId().equals(iId)))
+ && (iId == null || ObjectId.zeroId().equals(iId))) {
return isModifiedSubtree_IndexTree(path, rootTree);
- else
- return !equalIdAndMode(iId, iMode, tId, tMode);
+ }
+ return !equalIdAndMode(iId, iMode, tId, tMode);
}
/**
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/dircache/DirCacheEntry.java b/org.eclipse.jgit/src/org/eclipse/jgit/dircache/DirCacheEntry.java
index 0e91f0d..cbf96e4 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/dircache/DirCacheEntry.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/dircache/DirCacheEntry.java
@@ -824,10 +824,10 @@ private void encodeTS(int pIdx, Instant when) {
}
private int getExtendedFlags() {
- if (isExtended())
+ if (isExtended()) {
return NB.decodeUInt16(info, infoOffset + P_FLAGS2) << 16;
- else
- return 0;
+ }
+ return 0;
}
private static void checkPath(byte[] path) {
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/errors/NoMergeBaseException.java b/org.eclipse.jgit/src/org/eclipse/jgit/errors/NoMergeBaseException.java
index 97214b0..023dfe9 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/errors/NoMergeBaseException.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/errors/NoMergeBaseException.java
@@ -63,7 +63,7 @@ public class NoMergeBaseException extends IOException {
* An enum listing the different reason why no merge base could be
* determined.
*/
- public static enum MergeBaseFailureReason {
+ public enum MergeBaseFailureReason {
/**
* Multiple merge bases have been found (e.g. the commits to be merged
* have multiple common predecessors) but the merge strategy doesn't
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/errors/TranslationBundleException.java b/org.eclipse.jgit/src/org/eclipse/jgit/errors/TranslationBundleException.java
index 70760f3..6d18c7c 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/errors/TranslationBundleException.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/errors/TranslationBundleException.java
@@ -78,7 +78,7 @@ protected TranslationBundleException(String message, Class bundleClass, Locale l
*
* @return bundle class for which the exception occurred
*/
- final public Class getBundleClass() {
+ public final Class getBundleClass() {
return bundleClass;
}
@@ -87,7 +87,7 @@ final public Class getBundleClass() {
*
* @return locale for which the exception occurred
*/
- final public Locale getLocale() {
+ public final Locale getLocale() {
return locale;
}
}
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/fnmatch/AbstractHead.java b/org.eclipse.jgit/src/org/eclipse/jgit/fnmatch/AbstractHead.java
index 60669bb..2c93d55 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/fnmatch/AbstractHead.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/fnmatch/AbstractHead.java
@@ -82,10 +82,10 @@ public final void setNewHeads(List<Head> newHeads) {
/** {@inheritDoc} */
@Override
public List<Head> getNextHeads(char c) {
- if (matches(c))
+ if (matches(c)) {
return newHeads;
- else
- return FileNameMatcher.EMPTY_HEAD_LIST;
+ }
+ return FileNameMatcher.EMPTY_HEAD_LIST;
}
boolean isStar() {
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/fnmatch/FileNameMatcher.java b/org.eclipse.jgit/src/org/eclipse/jgit/fnmatch/FileNameMatcher.java
index bfcc580..8125c35 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/fnmatch/FileNameMatcher.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/fnmatch/FileNameMatcher.java
@@ -304,11 +304,11 @@ private static List<AbstractHead> createSimpleHeads(
private static AbstractHead createWildCardHead(
final Character invalidWildgetCharacter, final boolean star) {
- if (invalidWildgetCharacter != null)
+ if (invalidWildgetCharacter != null) {
return new RestrictedWildCardHead(invalidWildgetCharacter
.charValue(), star);
- else
- return new WildCardHead(star);
+ }
+ return new WildCardHead(star);
}
/**
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/gitrepo/ManifestParser.java b/org.eclipse.jgit/src/org/eclipse/jgit/gitrepo/ManifestParser.java
index 8e46341..febdb92 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/gitrepo/ManifestParser.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/gitrepo/ManifestParser.java
@@ -293,13 +293,12 @@ public void endDocument() throws SAXException {
String revision = defaultRevision;
if (remote == null) {
if (defaultRemote == null) {
- if (filename != null)
+ if (filename != null) {
throw new SAXException(MessageFormat.format(
RepoText.get().errorNoDefaultFilename,
filename));
- else
- throw new SAXException(
- RepoText.get().errorNoDefault);
+ }
+ throw new SAXException(RepoText.get().errorNoDefault);
}
remote = defaultRemote;
} else {
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/gitrepo/RepoCommand.java b/org.eclipse.jgit/src/org/eclipse/jgit/gitrepo/RepoCommand.java
index cb62925..7288678 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/gitrepo/RepoCommand.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/gitrepo/RepoCommand.java
@@ -761,18 +761,17 @@ public RevCommit call() throws GitAPIException {
} catch (GitAPIException | IOException e) {
throw new ManifestErrorException(e);
}
- } else {
- try (Git git = new Git(repo)) {
- for (RepoProject proj : filteredProjects) {
- addSubmodule(proj.getName(), proj.getUrl(), proj.getPath(),
- proj.getRevision(), proj.getCopyFiles(),
- proj.getLinkFiles(), git);
- }
- return git.commit().setMessage(RepoText.get().repoCommitMessage)
- .call();
- } catch (GitAPIException | IOException e) {
- throw new ManifestErrorException(e);
+ }
+ try (Git git = new Git(repo)) {
+ for (RepoProject proj : filteredProjects) {
+ addSubmodule(proj.getName(), proj.getUrl(), proj.getPath(),
+ proj.getRevision(), proj.getCopyFiles(),
+ proj.getLinkFiles(), git);
}
+ return git.commit().setMessage(RepoText.get().repoCommitMessage)
+ .call();
+ } catch (GitAPIException | IOException e) {
+ throw new ManifestErrorException(e);
}
}
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/gitrepo/RepoProject.java b/org.eclipse.jgit/src/org/eclipse/jgit/gitrepo/RepoProject.java
index d79dfa8..684d1e4 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/gitrepo/RepoProject.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/gitrepo/RepoProject.java
@@ -422,10 +422,10 @@ public void clearLinkFiles() {
}
private String getPathWithSlash() {
- if (path.endsWith("/")) //$NON-NLS-1$
+ if (path.endsWith("/")) { //$NON-NLS-1$
return path;
- else
- return path + "/"; //$NON-NLS-1$
+ }
+ return path + "/"; //$NON-NLS-1$
}
/**
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/hooks/CommitMsgHook.java b/org.eclipse.jgit/src/org/eclipse/jgit/hooks/CommitMsgHook.java
index f33168d..6dbe0a6 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/hooks/CommitMsgHook.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/hooks/CommitMsgHook.java
@@ -72,6 +72,9 @@ public class CommitMsgHook extends GitHook<String> {
/**
* Constructor for CommitMsgHook
+ * <p>
+ * This constructor will use the default error stream.
+ * </p>
*
* @param repo
* The repository
@@ -83,6 +86,24 @@ protected CommitMsgHook(Repository repo, PrintStream outputStream) {
super(repo, outputStream);
}
+ /**
+ * Constructor for CommitMsgHook
+ *
+ * @param repo
+ * The repository
+ * @param outputStream
+ * The output stream the hook must use. {@code null} is allowed,
+ * in which case the hook will use {@code System.out}.
+ * @param errorStream
+ * The error stream the hook must use. {@code null} is allowed,
+ * in which case the hook will use {@code System.err}.
+ * @since 5.6
+ */
+ protected CommitMsgHook(Repository repo, PrintStream outputStream,
+ PrintStream errorStream) {
+ super(repo, outputStream, errorStream);
+ }
+
/** {@inheritDoc} */
@Override
public String call() throws IOException, AbortedByHookException {
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/hooks/GitHook.java b/org.eclipse.jgit/src/org/eclipse/jgit/hooks/GitHook.java
index ad43e2c..aa307c9 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/hooks/GitHook.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/hooks/GitHook.java
@@ -50,6 +50,7 @@
import java.io.UnsupportedEncodingException;
import java.util.concurrent.Callable;
+import org.bouncycastle.util.io.TeeOutputStream;
import org.eclipse.jgit.api.errors.AbortedByHookException;
import org.eclipse.jgit.lib.Repository;
import org.eclipse.jgit.util.FS;
@@ -79,7 +80,15 @@ abstract class GitHook<T> implements Callable<T> {
protected final PrintStream outputStream;
/**
- * Constructor for GitHook
+ * The error stream to be used by the hook.
+ */
+ protected final PrintStream errorStream;
+
+ /**
+ * Constructor for GitHook.
+ * <p>
+ * This constructor will use stderr for the error stream.
+ * </p>
*
* @param repo
* a {@link org.eclipse.jgit.lib.Repository} object.
@@ -88,8 +97,26 @@ abstract class GitHook<T> implements Callable<T> {
* in which case the hook will use {@code System.out}.
*/
protected GitHook(Repository repo, PrintStream outputStream) {
+ this(repo, outputStream, null);
+ }
+
+ /**
+ * Constructor for GitHook
+ *
+ * @param repo
+ * a {@link org.eclipse.jgit.lib.Repository} object.
+ * @param outputStream
+ * The output stream the hook must use. {@code null} is allowed,
+ * in which case the hook will use {@code System.out}.
+ * @param errorStream
+ * The error stream the hook must use. {@code null} is allowed,
+ * in which case the hook will use {@code System.err}.
+ */
+ protected GitHook(Repository repo, PrintStream outputStream,
+ PrintStream errorStream) {
this.repo = repo;
this.outputStream = outputStream;
+ this.errorStream = errorStream;
}
/**
@@ -148,6 +175,16 @@ protected PrintStream getOutputStream() {
}
/**
+ * Get error stream
+ *
+ * @return The error stream the hook must use. Never {@code null},
+ * {@code System.err} is returned by default.
+ */
+ protected PrintStream getErrorStream() {
+ return errorStream == null ? System.err : errorStream;
+ }
+
+ /**
* Runs the hook, without performing any validity checks.
*
* @throws org.eclipse.jgit.api.errors.AbortedByHookException
@@ -155,16 +192,23 @@ protected PrintStream getOutputStream() {
*/
protected void doRun() throws AbortedByHookException {
final ByteArrayOutputStream errorByteArray = new ByteArrayOutputStream();
+ final TeeOutputStream stderrStream = new TeeOutputStream(errorByteArray,
+ getErrorStream());
PrintStream hookErrRedirect = null;
try {
- hookErrRedirect = new PrintStream(errorByteArray, false,
+ hookErrRedirect = new PrintStream(stderrStream, false,
UTF_8.name());
} catch (UnsupportedEncodingException e) {
// UTF-8 is guaranteed to be available
}
- ProcessResult result = FS.DETECTED.runHookIfPresent(getRepository(),
- getHookName(), getParameters(), getOutputStream(),
- hookErrRedirect, getStdinArgs());
+ Repository repository = getRepository();
+ FS fs = repository.getFS();
+ if (fs == null) {
+ fs = FS.DETECTED;
+ }
+ ProcessResult result = fs.runHookIfPresent(repository, getHookName(),
+ getParameters(), getOutputStream(), hookErrRedirect,
+ getStdinArgs());
if (result.isExecutedWithError()) {
throw new AbortedByHookException(
new String(errorByteArray.toByteArray(), UTF_8),
@@ -180,7 +224,11 @@ protected void doRun() throws AbortedByHookException {
* @since 4.11
*/
public boolean isNativeHookPresent() {
- return FS.DETECTED.findHook(getRepository(), getHookName()) != null;
+ FS fs = getRepository().getFS();
+ if (fs == null) {
+ fs = FS.DETECTED;
+ }
+ return fs.findHook(getRepository(), getHookName()) != null;
}
}
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/hooks/Hooks.java b/org.eclipse.jgit/src/org/eclipse/jgit/hooks/Hooks.java
index b801d68..f29dcd1 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/hooks/Hooks.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/hooks/Hooks.java
@@ -57,7 +57,8 @@
public class Hooks {
/**
- * Create pre-commit hook for the given repository
+ * Create pre-commit hook for the given repository with the default error
+ * stream
*
* @param repo
* a {@link org.eclipse.jgit.lib.Repository} object.
@@ -71,7 +72,25 @@ public static PreCommitHook preCommit(Repository repo,
}
/**
- * Create post-commit hook for the given repository
+ * Create pre-commit hook for the given repository
+ *
+ * @param repo
+ * a {@link org.eclipse.jgit.lib.Repository} object.
+ * @param outputStream
+ * The output stream, or {@code null} to use {@code System.out}
+ * @param errorStream
+ * The error stream, or {@code null} to use {@code System.err}
+ * @return The pre-commit hook for the given repository.
+ * @since 5.6
+ */
+ public static PreCommitHook preCommit(Repository repo,
+ PrintStream outputStream, PrintStream errorStream) {
+ return new PreCommitHook(repo, outputStream, errorStream);
+ }
+
+ /**
+ * Create post-commit hook for the given repository with the default error
+ * stream
*
* @param repo
* a {@link org.eclipse.jgit.lib.Repository} object.
@@ -86,7 +105,25 @@ public static PostCommitHook postCommit(Repository repo,
}
/**
- * Create commit-msg hook for the given repository
+ * Create post-commit hook for the given repository
+ *
+ * @param repo
+ * a {@link org.eclipse.jgit.lib.Repository} object.
+ * @param outputStream
+ * The output stream, or {@code null} to use {@code System.out}
+ * @param errorStream
+ * The error stream, or {@code null} to use {@code System.err}
+ * @return The pre-commit hook for the given repository.
+ * @since 5.6
+ */
+ public static PostCommitHook postCommit(Repository repo,
+ PrintStream outputStream, PrintStream errorStream) {
+ return new PostCommitHook(repo, outputStream, errorStream);
+ }
+
+ /**
+ * Create commit-msg hook for the given repository with the default error
+ * stream
*
* @param repo
* a {@link org.eclipse.jgit.lib.Repository} object.
@@ -100,7 +137,25 @@ public static CommitMsgHook commitMsg(Repository repo,
}
/**
- * Create pre-push hook for the given repository
+ * Create commit-msg hook for the given repository
+ *
+ * @param repo
+ * a {@link org.eclipse.jgit.lib.Repository} object.
+ * @param outputStream
+ * The output stream, or {@code null} to use {@code System.out}
+ * @param errorStream
+ * The error stream, or {@code null} to use {@code System.err}
+ * @return The pre-commit hook for the given repository.
+ * @since 5.6
+ */
+ public static CommitMsgHook commitMsg(Repository repo,
+ PrintStream outputStream, PrintStream errorStream) {
+ return new CommitMsgHook(repo, outputStream, errorStream);
+ }
+
+ /**
+ * Create pre-push hook for the given repository with the default error
+ * stream
*
* @param repo
* a {@link org.eclipse.jgit.lib.Repository} object.
@@ -127,4 +182,36 @@ public static PrePushHook prePush(Repository repo, PrintStream outputStream) {
}
return new PrePushHook(repo, outputStream);
}
+
+ /**
+ * Create pre-push hook for the given repository
+ *
+ * @param repo
+ * a {@link org.eclipse.jgit.lib.Repository} object.
+ * @param outputStream
+ * The output stream, or {@code null} to use {@code System.out}
+ * @param errorStream
+ * The error stream, or {@code null} to use {@code System.err}
+ * @return The pre-push hook for the given repository.
+ * @since 5.6
+ */
+ public static PrePushHook prePush(Repository repo, PrintStream outputStream,
+ PrintStream errorStream) {
+ if (LfsFactory.getInstance().isAvailable()) {
+ PrePushHook hook = LfsFactory.getInstance().getPrePushHook(repo,
+ outputStream, errorStream);
+ if (hook != null) {
+ if (hook.isNativeHookPresent()) {
+ PrintStream ps = outputStream;
+ if (ps == null) {
+ ps = System.out;
+ }
+ ps.println(MessageFormat
+ .format(JGitText.get().lfsHookConflict, repo));
+ }
+ return hook;
+ }
+ }
+ return new PrePushHook(repo, outputStream, errorStream);
+ }
}
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/hooks/PostCommitHook.java b/org.eclipse.jgit/src/org/eclipse/jgit/hooks/PostCommitHook.java
index 24bad16..b6e576f 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/hooks/PostCommitHook.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/hooks/PostCommitHook.java
@@ -61,6 +61,9 @@ public class PostCommitHook extends GitHook<Void> {
/**
* Constructor for PostCommitHook
+ * <p>
+ * This constructor will use the default error stream.
+ * </p>
*
* @param repo
* The repository
@@ -72,6 +75,24 @@ protected PostCommitHook(Repository repo, PrintStream outputStream) {
super(repo, outputStream);
}
+ /**
+ * Constructor for PostCommitHook
+ *
+ * @param repo
+ * The repository
+ * @param outputStream
+ * The output stream the hook must use. {@code null} is allowed,
+ * in which case the hook will use {@code System.out}.
+ * @param errorStream
+ * The error stream the hook must use. {@code null} is allowed,
+ * in which case the hook will use {@code System.err}.
+ * @since 5.6
+ */
+ protected PostCommitHook(Repository repo, PrintStream outputStream,
+ PrintStream errorStream) {
+ super(repo, outputStream, errorStream);
+ }
+
/** {@inheritDoc} */
@Override
public Void call() throws IOException, AbortedByHookException {
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/hooks/PreCommitHook.java b/org.eclipse.jgit/src/org/eclipse/jgit/hooks/PreCommitHook.java
index 0d9290d..dbdaf86 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/hooks/PreCommitHook.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/hooks/PreCommitHook.java
@@ -61,6 +61,9 @@ public class PreCommitHook extends GitHook<Void> {
/**
* Constructor for PreCommitHook
+ * <p>
+ * This constructor will use the default error stream.
+ * </p>
*
* @param repo
* The repository
@@ -72,6 +75,24 @@ protected PreCommitHook(Repository repo, PrintStream outputStream) {
super(repo, outputStream);
}
+ /**
+ * Constructor for PreCommitHook
+ *
+ * @param repo
+ * The repository
+ * @param outputStream
+ * The output stream the hook must use. {@code null} is allowed,
+ * in which case the hook will use {@code System.out}.
+ * @param errorStream
+ * The error stream the hook must use. {@code null} is allowed,
+ * in which case the hook will use {@code System.err}.
+ * @since 5.6
+ */
+ protected PreCommitHook(Repository repo, PrintStream outputStream,
+ PrintStream errorStream) {
+ super(repo, outputStream, errorStream);
+ }
+
/** {@inheritDoc} */
@Override
public Void call() throws IOException, AbortedByHookException {
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/hooks/PrePushHook.java b/org.eclipse.jgit/src/org/eclipse/jgit/hooks/PrePushHook.java
index 431944f..61180fd 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/hooks/PrePushHook.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/hooks/PrePushHook.java
@@ -73,6 +73,9 @@ public class PrePushHook extends GitHook<String> {
/**
* Constructor for PrePushHook
+ * <p>
+ * This constructor will use the default error stream.
+ * </p>
*
* @param repo
* The repository
@@ -84,6 +87,24 @@ protected PrePushHook(Repository repo, PrintStream outputStream) {
super(repo, outputStream);
}
+ /**
+ * Constructor for PrePushHook
+ *
+ * @param repo
+ * The repository
+ * @param outputStream
+ * The output stream the hook must use. {@code null} is allowed,
+ * in which case the hook will use {@code System.out}.
+ * @param errorStream
+ * The error stream the hook must use. {@code null} is allowed,
+ * in which case the hook will use {@code System.err}.
+ * @since 5.6
+ */
+ protected PrePushHook(Repository repo, PrintStream outputStream,
+ PrintStream errorStream) {
+ super(repo, outputStream, errorStream);
+ }
+
/** {@inheritDoc} */
@Override
protected String getStdinArgs() {
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/ignore/FastIgnoreRule.java b/org.eclipse.jgit/src/org/eclipse/jgit/ignore/FastIgnoreRule.java
index 31e173b..4bc926a 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/ignore/FastIgnoreRule.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/ignore/FastIgnoreRule.java
@@ -62,7 +62,7 @@
* @since 3.6
*/
public class FastIgnoreRule {
- private final static Logger LOG = LoggerFactory
+ private static final Logger LOG = LoggerFactory
.getLogger(FastIgnoreRule.class);
/**
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/ignore/IgnoreNode.java b/org.eclipse.jgit/src/org/eclipse/jgit/ignore/IgnoreNode.java
index 864f8bf..d47ffc2 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/ignore/IgnoreNode.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/ignore/IgnoreNode.java
@@ -59,7 +59,7 @@
*/
public class IgnoreNode {
/** Result from {@link IgnoreNode#isIgnored(String, boolean)}. */
- public static enum MatchResult {
+ public enum MatchResult {
/** The file is not ignored, due to a rule saying its not ignored. */
NOT_IGNORED,
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/ignore/internal/PathMatcher.java b/org.eclipse.jgit/src/org/eclipse/jgit/ignore/internal/PathMatcher.java
index 3c0f17a..b7d6acc 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/ignore/internal/PathMatcher.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/ignore/internal/PathMatcher.java
@@ -291,26 +291,25 @@ && isWild(matchers.get(matcher))) {
// We had a prefix match here.
if (!pathMatch) {
return true;
+ }
+ if (right == endExcl - 1) {
+ // Extra slash at the end: actually a full match.
+ // Must meet directory expectations
+ return !dirOnly || assumeDirectory;
+ }
+ // Prefix matches only if pattern ended with /**
+ if (wasWild) {
+ return true;
+ }
+ if (lastWildmatch >= 0) {
+ // Consider pattern **/x and input x/x.
+ // We've matched the prefix x/ so far: we
+ // must try to extend the **!
+ matcher = lastWildmatch + 1;
+ right = wildmatchBacktrackPos;
+ wildmatchBacktrackPos = -1;
} else {
- if (right == endExcl - 1) {
- // Extra slash at the end: actually a full match.
- // Must meet directory expectations
- return !dirOnly || assumeDirectory;
- }
- // Prefix matches only if pattern ended with /**
- if (wasWild) {
- return true;
- }
- if (lastWildmatch >= 0) {
- // Consider pattern **/x and input x/x.
- // We've matched the prefix x/ so far: we
- // must try to extend the **!
- matcher = lastWildmatch + 1;
- right = wildmatchBacktrackPos;
- wildmatchBacktrackPos = -1;
- } else {
- return false;
- }
+ return false;
}
}
} else if (lastWildmatch != -1) {
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/ignore/internal/Strings.java b/org.eclipse.jgit/src/org/eclipse/jgit/ignore/internal/Strings.java
index 41923ee..132109b 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/ignore/internal/Strings.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/ignore/internal/Strings.java
@@ -192,22 +192,20 @@ private static boolean isComplexWildcard(String pattern) {
}
if (pattern.indexOf('?') != -1) {
return true;
- } else {
- // check if the backslash escapes one of the glob special characters
- // if not, backslash is not part of a regex and treated literally
- int backSlash = pattern.indexOf('\\');
- if (backSlash >= 0) {
- int nextIdx = backSlash + 1;
- if (pattern.length() == nextIdx) {
- return false;
- }
- char nextChar = pattern.charAt(nextIdx);
- if (escapedByBackslash(nextChar)) {
- return true;
- } else {
- return false;
- }
+ }
+ // check if the backslash escapes one of the glob special characters
+ // if not, backslash is not part of a regex and treated literally
+ int backSlash = pattern.indexOf('\\');
+ if (backSlash >= 0) {
+ int nextIdx = backSlash + 1;
+ if (pattern.length() == nextIdx) {
+ return false;
}
+ char nextChar = pattern.charAt(nextIdx);
+ if (escapedByBackslash(nextChar)) {
+ return true;
+ }
+ return false;
}
return false;
}
@@ -231,11 +229,11 @@ static PatternState checkWildCards(String pattern) {
return PatternState.COMPLEX;
}
- static enum PatternState {
+ enum PatternState {
LEADING_ASTERISK_ONLY, TRAILING_ASTERISK_ONLY, COMPLEX, NONE
}
- final static List<String> POSIX_CHAR_CLASSES = Arrays.asList(
+ static final List<String> POSIX_CHAR_CLASSES = Arrays.asList(
"alnum", "alpha", "blank", "cntrl", //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$
// [:alnum:] [:alpha:] [:blank:] [:cntrl:]
"digit", "graph", "lower", "print", //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$
@@ -250,7 +248,7 @@ static enum PatternState {
private static final String DL = "\\p{javaDigit}\\p{javaLetter}"; //$NON-NLS-1$
- final static List<String> JAVA_CHAR_CLASSES = Arrays
+ static final List<String> JAVA_CHAR_CLASSES = Arrays
.asList("\\p{Alnum}", "\\p{javaLetter}", "\\p{Blank}", "\\p{Cntrl}", //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$
// [:alnum:] [:alpha:] [:blank:] [:cntrl:]
"\\p{javaDigit}", "[\\p{Graph}" + DL + "]", "\\p{Ll}", "[\\p{Print}" + DL + "]", //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ //$NON-NLS-5$ //$NON-NLS-6$
@@ -263,7 +261,7 @@ static enum PatternState {
// Collating symbols [[.a.]] or equivalence class expressions [[=a=]] are
// not supported by CLI git (at least not by 1.9.1)
- final static Pattern UNSUPPORTED = Pattern
+ static final Pattern UNSUPPORTED = Pattern
.compile("\\[\\[[.=]\\w+[.=]\\]\\]"); //$NON-NLS-1$
/**
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/internal/JGitText.java b/org.eclipse.jgit/src/org/eclipse/jgit/internal/JGitText.java
index cd7d1e5..37a7c7d9 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/internal/JGitText.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/internal/JGitText.java
@@ -1,45 +1,12 @@
/*
* Copyright (C) 2010, 2013 Sasa Zivkov <sasa.zivkov@sap.com>
- * Copyright (C) 2012, Research In Motion Limited
- * and other copyright owners as documented in the project's IP log.
+ * Copyright (C) 2012, 2021 Research In Motion Limited and others
*
- * 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
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Distribution License v. 1.0 which is available at
+ * https://www.eclipse.org/org/documents/edl-v10.php.
*
- * 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.
+ * SPDX-License-Identifier: BSD-3-Clause
*/
package org.eclipse.jgit.internal;
@@ -345,10 +312,12 @@ public static JGitText get() {
/***/ public String failedAtomicFileCreation;
/***/ public String failedCreateLockFile;
/***/ public String failedToDetermineFilterDefinition;
+ /***/ public String failedToConvert;
/***/ public String failedUpdatingRefs;
/***/ public String failureDueToOneOfTheFollowing;
/***/ public String failureUpdatingFETCH_HEAD;
/***/ public String failureUpdatingTrackingRef;
+ /***/ public String fileAlreadyExists;
/***/ public String fileCannotBeDeleted;
/***/ public String fileIsTooLarge;
/***/ public String fileModeNotSetForPath;
@@ -387,6 +356,7 @@ public static JGitText get() {
/***/ public String incorrectOBJECT_ID_LENGTH;
/***/ public String indexFileCorruptedNegativeBucketCount;
/***/ public String indexFileIsTooLargeForJgit;
+ /***/ public String indexNumbersNotIncreasing;
/***/ public String indexWriteException;
/***/ public String initFailedBareRepoDifferentDirs;
/***/ public String initFailedDirIsNoDirectory;
@@ -412,6 +382,7 @@ public static JGitText get() {
/***/ public String invalidGitdirRef;
/***/ public String invalidGitModules;
/***/ public String invalidGitType;
+ /***/ public String invalidHooksPath;
/***/ public String invalidId;
/***/ public String invalidId0;
/***/ public String invalidIdLength;
@@ -466,10 +437,13 @@ public static JGitText get() {
/***/ public String localRefIsMissingObjects;
/***/ public String localRepository;
/***/ public String lockCountMustBeGreaterOrEqual1;
+ /***/ public String lockAlreadyHeld;
/***/ public String lockError;
/***/ public String lockFailedRetry;
/***/ public String lockOnNotClosed;
/***/ public String lockOnNotHeld;
+ /***/ public String lockStreamClosed;
+ /***/ public String lockStreamMultiple;
/***/ public String maxCountMustBeNonNegative;
/***/ public String mergeConflictOnNonNoteEntries;
/***/ public String mergeConflictOnNotes;
@@ -512,8 +486,10 @@ public static JGitText get() {
/***/ public String noMergeBase;
/***/ public String noMergeHeadSpecified;
/***/ public String nonBareLinkFilesNotSupported;
+ /***/ public String nonCommitToHeads;
/***/ public String noPathAttributesFound;
/***/ public String noSuchRef;
+ /***/ public String noSuchRefKnown;
/***/ public String noSuchSubmodule;
/***/ public String notABoolean;
/***/ public String notABundle;
@@ -612,7 +588,8 @@ public static JGitText get() {
/***/ public String refAlreadyExists1;
/***/ public String reflogEntryNotFound;
/***/ public String refNotResolved;
- /***/ public String refTableRecordsMustIncrease;
+ /***/ public String reftableDirExists;
+ /***/ public String reftableRecordsMustIncrease;
/***/ public String refUpdateReturnCodeWas;
/***/ public String remoteConfigHasNoURIAssociated;
/***/ public String remoteDoesNotHaveSpec;
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/internal/ketch/KetchLeader.java b/org.eclipse.jgit/src/org/eclipse/jgit/internal/ketch/KetchLeader.java
index c0364ac..67cb2f6 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/internal/ketch/KetchLeader.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/internal/ketch/KetchLeader.java
@@ -126,7 +126,7 @@ public abstract class KetchLeader {
private static final Logger log = LoggerFactory.getLogger(KetchLeader.class);
/** Current state of the leader instance. */
- public static enum State {
+ public enum State {
/** Newly created instance trying to elect itself leader. */
CANDIDATE,
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/internal/ketch/KetchReplica.java b/org.eclipse.jgit/src/org/eclipse/jgit/internal/ketch/KetchReplica.java
index 0e8377d..52c8f29 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/internal/ketch/KetchReplica.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/internal/ketch/KetchReplica.java
@@ -77,6 +77,7 @@
import org.eclipse.jgit.revwalk.RevWalk;
import org.eclipse.jgit.transport.ReceiveCommand;
import org.eclipse.jgit.treewalk.TreeWalk;
+import org.eclipse.jgit.util.FileUtils;
import org.eclipse.jgit.util.SystemReader;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -532,9 +533,8 @@ private void retryLater(ReplicaPushRequest req) {
queued.add(0, new ReplicaPushRequest(this, cmds));
if (!waitingForRetry()) {
- long delay = KetchSystem.delay(
- lastRetryMillis,
- minRetryMillis, maxRetryMillis);
+ long delay = FileUtils
+ .delay(lastRetryMillis, minRetryMillis, maxRetryMillis);
if (log.isDebugEnabled()) {
log.debug("Retrying {} after {} ms", //$NON-NLS-1$
describeForLog(), Long.valueOf(delay));
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/internal/ketch/KetchSystem.java b/org.eclipse.jgit/src/org/eclipse/jgit/internal/ketch/KetchSystem.java
index d1d4f67..fd334f1 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/internal/ketch/KetchSystem.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/internal/ketch/KetchSystem.java
@@ -350,25 +350,4 @@ private DefaultExecutorHolder() {
}
}
- /**
- * Compute a delay in a {@code min..max} interval with random jitter.
- *
- * @param last
- * amount of delay waited before the last attempt. This is used
- * to seed the next delay interval. Should be 0 if there was no
- * prior delay.
- * @param min
- * shortest amount of allowable delay between attempts.
- * @param max
- * longest amount of allowable delay between attempts.
- * @return new amount of delay to wait before the next attempt.
- */
- static long delay(long last, long min, long max) {
- long r = Math.max(0, last * 3 - min);
- if (r > 0) {
- int c = (int) Math.min(r + 1, Integer.MAX_VALUE);
- r = RNG.nextInt(c);
- }
- return Math.max(Math.min(min + r, max), min);
- }
}
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/internal/ketch/LagCheck.java b/org.eclipse.jgit/src/org/eclipse/jgit/internal/ketch/LagCheck.java
index 53fd198..a27a9bc 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/internal/ketch/LagCheck.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/internal/ketch/LagCheck.java
@@ -132,9 +132,8 @@ KetchReplica.State check(ObjectId acceptId, ReceiveCommand acceptCmd) {
// TODO(sop) Check term to see if my leader was deposed.
if (rw.isMergedInto(head, remote)) {
return AHEAD;
- } else {
- return DIVERGENT;
}
+ return DIVERGENT;
} catch (IOException err) {
KetchReplica.log.error(String.format(
"Cannot compare %s", //$NON-NLS-1$
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/dfs/DfsBlockCache.java b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/dfs/DfsBlockCache.java
index c6e2fae..16e7a0d 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/dfs/DfsBlockCache.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/dfs/DfsBlockCache.java
@@ -412,8 +412,7 @@ DfsBlock getOrLoad(BlockBasedFile file, long position, DfsReader ctx,
getStat(statMiss, key).incrementAndGet();
boolean credit = true;
try {
- v = file.readOneBlock(requestedPosition, ctx,
- fileChannel.get());
+ v = file.readOneBlock(position, ctx, fileChannel.get());
credit = false;
} finally {
if (credit) {
@@ -450,7 +449,7 @@ DfsBlock getOrLoad(BlockBasedFile file, long position, DfsReader ctx,
}
@SuppressWarnings("unchecked")
- private void reserveSpace(int reserve, DfsStreamKey key) {
+ private void reserveSpace(long reserve, DfsStreamKey key) {
clockLock.lock();
try {
long live = LongStream.of(getCurrentSize()).sum() + reserve;
@@ -487,7 +486,7 @@ private void reserveSpace(int reserve, DfsStreamKey key) {
}
}
- private void creditSpace(int credit, DfsStreamKey key) {
+ private void creditSpace(long credit, DfsStreamKey key) {
clockLock.lock();
try {
getStat(liveBytes, key).addAndGet(-credit);
@@ -497,7 +496,7 @@ private void creditSpace(int credit, DfsStreamKey key) {
}
@SuppressWarnings("unchecked")
- private void addToClock(Ref ref, int credit) {
+ private void addToClock(Ref ref, long credit) {
clockLock.lock();
try {
if (credit != 0) {
@@ -521,17 +520,20 @@ void put(DfsBlock v) {
*
* @param key
* the stream key of the pack.
+ * @param position
+ * the position in the key. The default should be 0.
* @param loader
* the function to load the reference.
* @return the object reference.
* @throws IOException
* the reference was not in the cache and could not be loaded.
*/
- <T> Ref<T> getOrLoadRef(DfsStreamKey key, RefLoader<T> loader)
+ <T> Ref<T> getOrLoadRef(
+ DfsStreamKey key, long position, RefLoader<T> loader)
throws IOException {
- int slot = slot(key, 0);
+ int slot = slot(key, position);
HashEntry e1 = table.get(slot);
- Ref<T> ref = scanRef(e1, key, 0);
+ Ref<T> ref = scanRef(e1, key, position);
if (ref != null) {
getStat(statHit, key).incrementAndGet();
return ref;
@@ -543,7 +545,7 @@ <T> Ref<T> getOrLoadRef(DfsStreamKey key, RefLoader<T> loader)
try {
HashEntry e2 = table.get(slot);
if (e2 != e1) {
- ref = scanRef(e2, key, 0);
+ ref = scanRef(e2, key, position);
if (ref != null) {
getStat(statHit, key).incrementAndGet();
return ref;
@@ -574,10 +576,10 @@ <T> Ref<T> getOrLoadRef(DfsStreamKey key, RefLoader<T> loader)
}
<T> Ref<T> putRef(DfsStreamKey key, long size, T v) {
- return put(key, 0, (int) Math.min(size, Integer.MAX_VALUE), v);
+ return put(key, 0, size, v);
}
- <T> Ref<T> put(DfsStreamKey key, long pos, int size, T v) {
+ <T> Ref<T> put(DfsStreamKey key, long pos, long size, T v) {
int slot = slot(key, pos);
HashEntry e1 = table.get(slot);
Ref<T> ref = scanRef(e1, key, pos);
@@ -720,12 +722,12 @@ private static final class HashEntry {
static final class Ref<T> {
final DfsStreamKey key;
final long position;
- final int size;
+ final long size;
volatile T value;
Ref next;
volatile boolean hot;
- Ref(DfsStreamKey key, long position, int size, T v) {
+ Ref(DfsStreamKey key, long position, long size, T v) {
this.key = key;
this.position = position;
this.size = size;
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/dfs/DfsCachedPack.java b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/dfs/DfsCachedPack.java
index 3605236e..9b28074 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/dfs/DfsCachedPack.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/dfs/DfsCachedPack.java
@@ -61,6 +61,13 @@ public class DfsCachedPack extends CachedPack {
}
/**
+ * @return the pack passed to the constructor
+ */
+ public DfsPackFile getPackFile() {
+ return pack;
+ }
+
+ /**
* Get the description of the pack.
*
* @return the description of the pack.
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/dfs/DfsGarbageCollector.java b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/dfs/DfsGarbageCollector.java
index f10a1d8..3e71d07 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/dfs/DfsGarbageCollector.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/dfs/DfsGarbageCollector.java
@@ -744,11 +744,15 @@ private void writeReftable(DfsPackDescription pack) throws IOException {
return;
}
- try (ReftableStack stack = ReftableStack.open(ctx, reftablesBefore)) {
- ReftableCompactor compact = new ReftableCompactor();
+ try (DfsReftableStack stack = DfsReftableStack.open(ctx, reftablesBefore);
+ DfsOutputStream out = objdb.writeFile(pack, REFTABLE)) {
+ ReftableCompactor compact = new ReftableCompactor(out);
compact.addAll(stack.readers());
compact.setIncludeDeletes(includeDeletes);
- compactReftable(pack, compact);
+ compact.setConfig(configureReftable(reftableConfig, out));
+ compact.compact();
+ pack.addFileExt(REFTABLE);
+ pack.setReftableStats(compact.getStats());
}
}
@@ -765,24 +769,12 @@ private void writeReftable(DfsPackDescription pack, Collection<Ref> refs)
throws IOException {
try (DfsOutputStream out = objdb.writeFile(pack, REFTABLE)) {
ReftableConfig cfg = configureReftable(reftableConfig, out);
- ReftableWriter writer = new ReftableWriter(cfg)
+ ReftableWriter writer = new ReftableWriter(cfg, out)
.setMinUpdateIndex(reftableInitialMinUpdateIndex)
- .setMaxUpdateIndex(reftableInitialMaxUpdateIndex)
- .begin(out)
- .sortAndWriteRefs(refs)
- .finish();
+ .setMaxUpdateIndex(reftableInitialMaxUpdateIndex).begin()
+ .sortAndWriteRefs(refs).finish();
pack.addFileExt(REFTABLE);
pack.setReftableStats(writer.getStats());
}
}
-
- private void compactReftable(DfsPackDescription pack,
- ReftableCompactor compact) throws IOException {
- try (DfsOutputStream out = objdb.writeFile(pack, REFTABLE)) {
- compact.setConfig(configureReftable(reftableConfig, out));
- compact.compact(out);
- pack.addFileExt(REFTABLE);
- pack.setReftableStats(compact.getStats());
- }
- }
}
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/dfs/DfsObjDatabase.java b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/dfs/DfsObjDatabase.java
index 09d5937..0ee8135 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/dfs/DfsObjDatabase.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/dfs/DfsObjDatabase.java
@@ -97,7 +97,7 @@ public void markDirty() {
* comparator based on {@link Enum#compareTo}. Prefer {@link
* #DEFAULT_COMPARATOR} or your own {@link ComparatorBuilder}.
*/
- public static enum PackSource {
+ public enum PackSource {
/** The pack is created by ObjectInserter due to local activity. */
INSERT,
@@ -705,7 +705,7 @@ public void close() {
}
/** Snapshot of packs scanned in a single pass. */
- public static abstract class PackList {
+ public abstract static class PackList {
/** All known packs, sorted. */
public final DfsPackFile[] packs;
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/dfs/DfsPackCompactor.java b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/dfs/DfsPackCompactor.java
index 6f3f2bd..083124e 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/dfs/DfsPackCompactor.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/dfs/DfsPackCompactor.java
@@ -311,12 +311,16 @@ private void compactReftables(DfsReader ctx) throws IOException {
DfsObjDatabase objdb = repo.getObjectDatabase();
Collections.sort(srcReftables, objdb.reftableComparator());
- try (ReftableStack stack = ReftableStack.open(ctx, srcReftables)) {
- initOutDesc(objdb);
- ReftableCompactor compact = new ReftableCompactor();
+ initOutDesc(objdb);
+ try (DfsReftableStack stack = DfsReftableStack.open(ctx, srcReftables);
+ DfsOutputStream out = objdb.writeFile(outDesc, REFTABLE)) {
+ ReftableCompactor compact = new ReftableCompactor(out);
compact.addAll(stack.readers());
compact.setIncludeDeletes(true);
- writeReftable(objdb, outDesc, compact);
+ compact.setConfig(configureReftable(reftableConfig, out));
+ compact.compact();
+ outDesc.addFileExt(REFTABLE);
+ outDesc.setReftableStats(compact.getStats());
}
}
@@ -497,16 +501,6 @@ private static void writeIndex(DfsObjDatabase objdb,
}
}
- private void writeReftable(DfsObjDatabase objdb, DfsPackDescription pack,
- ReftableCompactor compact) throws IOException {
- try (DfsOutputStream out = objdb.writeFile(pack, REFTABLE)) {
- compact.setConfig(configureReftable(reftableConfig, out));
- compact.compact(out);
- pack.addFileExt(REFTABLE);
- pack.setReftableStats(compact.getStats());
- }
- }
-
static ReftableConfig configureReftable(ReftableConfig cfg,
DfsOutputStream out) {
int bs = out.blockSize();
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/dfs/DfsPackFile.java b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/dfs/DfsPackFile.java
index be1387e..d0f9b1c 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/dfs/DfsPackFile.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/dfs/DfsPackFile.java
@@ -89,6 +89,7 @@
*/
public final class DfsPackFile extends BlockBasedFile {
private static final int REC_SIZE = Constants.OBJECT_ID_LENGTH + 8;
+ private static final long REF_POSITION = 0;
/**
* Lock for initialization of {@link #index} and {@link #corruptObjects}.
@@ -194,45 +195,10 @@ private PackIndex idx(DfsReader ctx) throws IOException {
try {
DfsStreamKey idxKey = desc.getStreamKey(INDEX);
- DfsBlockCache.Ref<PackIndex> idxref = cache.getOrLoadRef(idxKey,
- () -> {
- try {
- ctx.stats.readIdx++;
- long start = System.nanoTime();
- try (ReadableChannel rc = ctx.db.openFile(desc,
- INDEX)) {
- InputStream in = Channels
- .newInputStream(rc);
- int wantSize = 8192;
- int bs = rc.blockSize();
- if (0 < bs && bs < wantSize) {
- bs = (wantSize / bs) * bs;
- } else if (bs <= 0) {
- bs = wantSize;
- }
- PackIndex idx = PackIndex.read(
- new BufferedInputStream(in, bs));
- int sz = (int) Math.min(
- idx.getObjectCount() * REC_SIZE,
- Integer.MAX_VALUE);
- ctx.stats.readIdxBytes += rc.position();
- index = idx;
- return new DfsBlockCache.Ref<>(idxKey, 0,
- sz, idx);
- } finally {
- ctx.stats.readIdxMicros += elapsedMicros(
- start);
- }
- } catch (EOFException e) {
- throw new IOException(MessageFormat.format(
- DfsText.get().shortReadOfIndex,
- desc.getFileName(INDEX)), e);
- } catch (IOException e) {
- throw new IOException(MessageFormat.format(
- DfsText.get().cannotReadIndex,
- desc.getFileName(INDEX)), e);
- }
- });
+ DfsBlockCache.Ref<PackIndex> idxref = cache.getOrLoadRef(
+ idxKey,
+ REF_POSITION,
+ () -> loadPackIndex(ctx, idxKey));
PackIndex idx = idxref.get();
if (index == null && idx != null) {
index = idx;
@@ -267,44 +233,10 @@ PackBitmapIndex getBitmapIndex(DfsReader ctx) throws IOException {
PackIndex idx = idx(ctx);
PackReverseIndex revidx = getReverseIdx(ctx);
DfsStreamKey bitmapKey = desc.getStreamKey(BITMAP_INDEX);
- DfsBlockCache.Ref<PackBitmapIndex> idxref = cache
- .getOrLoadRef(bitmapKey, () -> {
- ctx.stats.readBitmap++;
- long start = System.nanoTime();
- try (ReadableChannel rc = ctx.db.openFile(desc,
- BITMAP_INDEX)) {
- long size;
- PackBitmapIndex bmidx;
- try {
- InputStream in = Channels.newInputStream(rc);
- int wantSize = 8192;
- int bs = rc.blockSize();
- if (0 < bs && bs < wantSize) {
- bs = (wantSize / bs) * bs;
- } else if (bs <= 0) {
- bs = wantSize;
- }
- in = new BufferedInputStream(in, bs);
- bmidx = PackBitmapIndex.read(in, idx, revidx);
- } finally {
- size = rc.position();
- ctx.stats.readIdxBytes += size;
- ctx.stats.readIdxMicros += elapsedMicros(start);
- }
- int sz = (int) Math.min(size, Integer.MAX_VALUE);
- bitmapIndex = bmidx;
- return new DfsBlockCache.Ref<>(bitmapKey, 0, sz,
- bmidx);
- } catch (EOFException e) {
- throw new IOException(MessageFormat.format(
- DfsText.get().shortReadOfIndex,
- desc.getFileName(BITMAP_INDEX)), e);
- } catch (IOException e) {
- throw new IOException(MessageFormat.format(
- DfsText.get().cannotReadIndex,
- desc.getFileName(BITMAP_INDEX)), e);
- }
- });
+ DfsBlockCache.Ref<PackBitmapIndex> idxref = cache.getOrLoadRef(
+ bitmapKey,
+ REF_POSITION,
+ () -> loadBitmapIndex(ctx, bitmapKey, idx, revidx));
PackBitmapIndex bmidx = idxref.get();
if (bitmapIndex == null && bmidx != null) {
bitmapIndex = bmidx;
@@ -326,14 +258,10 @@ PackReverseIndex getReverseIdx(DfsReader ctx) throws IOException {
PackIndex idx = idx(ctx);
DfsStreamKey revKey = new DfsStreamKey.ForReverseIndex(
desc.getStreamKey(INDEX));
- DfsBlockCache.Ref<PackReverseIndex> revref = cache
- .getOrLoadRef(revKey, () -> {
- PackReverseIndex revidx = new PackReverseIndex(idx);
- int sz = (int) Math.min(idx.getObjectCount() * 8,
- Integer.MAX_VALUE);
- reverseIndex = revidx;
- return new DfsBlockCache.Ref<>(revKey, 0, sz, revidx);
- });
+ DfsBlockCache.Ref<PackReverseIndex> revref = cache.getOrLoadRef(
+ revKey,
+ REF_POSITION,
+ () -> loadReverseIdx(revKey, idx));
PackReverseIndex revidx = revref.get();
if (reverseIndex == null && revidx != null) {
reverseIndex = revidx;
@@ -1091,4 +1019,91 @@ private void setCorrupt(long offset) {
list.add(offset);
}
}
+
+ private DfsBlockCache.Ref<PackIndex> loadPackIndex(
+ DfsReader ctx, DfsStreamKey idxKey) throws IOException {
+ try {
+ ctx.stats.readIdx++;
+ long start = System.nanoTime();
+ try (ReadableChannel rc = ctx.db.openFile(desc, INDEX)) {
+ InputStream in = Channels.newInputStream(rc);
+ int wantSize = 8192;
+ int bs = rc.blockSize();
+ if (0 < bs && bs < wantSize) {
+ bs = (wantSize / bs) * bs;
+ } else if (bs <= 0) {
+ bs = wantSize;
+ }
+ PackIndex idx = PackIndex.read(new BufferedInputStream(in, bs));
+ ctx.stats.readIdxBytes += rc.position();
+ index = idx;
+ return new DfsBlockCache.Ref<>(
+ idxKey,
+ REF_POSITION,
+ idx.getObjectCount() * REC_SIZE,
+ idx);
+ } finally {
+ ctx.stats.readIdxMicros += elapsedMicros(start);
+ }
+ } catch (EOFException e) {
+ throw new IOException(MessageFormat.format(
+ DfsText.get().shortReadOfIndex,
+ desc.getFileName(INDEX)), e);
+ } catch (IOException e) {
+ throw new IOException(MessageFormat.format(
+ DfsText.get().cannotReadIndex,
+ desc.getFileName(INDEX)), e);
+ }
+ }
+
+ private DfsBlockCache.Ref<PackReverseIndex> loadReverseIdx(
+ DfsStreamKey revKey, PackIndex idx) {
+ PackReverseIndex revidx = new PackReverseIndex(idx);
+ reverseIndex = revidx;
+ return new DfsBlockCache.Ref<>(
+ revKey,
+ REF_POSITION,
+ idx.getObjectCount() * 8,
+ revidx);
+ }
+
+ private DfsBlockCache.Ref<PackBitmapIndex> loadBitmapIndex(
+ DfsReader ctx,
+ DfsStreamKey bitmapKey,
+ PackIndex idx,
+ PackReverseIndex revidx) throws IOException {
+ ctx.stats.readBitmap++;
+ long start = System.nanoTime();
+ try (ReadableChannel rc = ctx.db.openFile(desc, BITMAP_INDEX)) {
+ long size;
+ PackBitmapIndex bmidx;
+ try {
+ InputStream in = Channels.newInputStream(rc);
+ int wantSize = 8192;
+ int bs = rc.blockSize();
+ if (0 < bs && bs < wantSize) {
+ bs = (wantSize / bs) * bs;
+ } else if (bs <= 0) {
+ bs = wantSize;
+ }
+ in = new BufferedInputStream(in, bs);
+ bmidx = PackBitmapIndex.read(in, idx, revidx);
+ } finally {
+ size = rc.position();
+ ctx.stats.readIdxBytes += size;
+ ctx.stats.readIdxMicros += elapsedMicros(start);
+ }
+ bitmapIndex = bmidx;
+ return new DfsBlockCache.Ref<>(
+ bitmapKey, REF_POSITION, size, bmidx);
+ } catch (EOFException e) {
+ throw new IOException(MessageFormat.format(
+ DfsText.get().shortReadOfIndex,
+ desc.getFileName(BITMAP_INDEX)), e);
+ } catch (IOException e) {
+ throw new IOException(MessageFormat.format(
+ DfsText.get().cannotReadIndex,
+ desc.getFileName(BITMAP_INDEX)), e);
+ }
+ }
}
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/dfs/DfsRefDatabase.java b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/dfs/DfsRefDatabase.java
index 732cd4d..b3b9e39 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/dfs/DfsRefDatabase.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/dfs/DfsRefDatabase.java
@@ -191,14 +191,11 @@ Ref doPeel(Ref leaf) throws MissingObjectException,
rw.peel(obj).copy(),
hasVersioning() ? leaf.getUpdateIndex()
: UNDEFINED_UPDATE_INDEX);
- } else {
- return new ObjectIdRef.PeeledNonTag(
- leaf.getStorage(),
- leaf.getName(),
- leaf.getObjectId(),
- hasVersioning() ? leaf.getUpdateIndex()
- : UNDEFINED_UPDATE_INDEX);
}
+ return new ObjectIdRef.PeeledNonTag(leaf.getStorage(),
+ leaf.getName(), leaf.getObjectId(),
+ hasVersioning() ? leaf.getUpdateIndex()
+ : UNDEFINED_UPDATE_INDEX);
}
}
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/dfs/DfsReftableBatchRefUpdate.java b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/dfs/DfsReftableBatchRefUpdate.java
new file mode 100644
index 0000000..124630e
--- /dev/null
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/dfs/DfsReftableBatchRefUpdate.java
@@ -0,0 +1,196 @@
+/*
+ * Copyright (C) 2019, Google Inc.
+ * 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.storage.dfs;
+
+import org.eclipse.jgit.internal.storage.dfs.DfsObjDatabase.PackSource;
+import org.eclipse.jgit.internal.storage.io.BlockSource;
+import org.eclipse.jgit.internal.storage.pack.PackExt;
+import org.eclipse.jgit.internal.storage.reftable.ReftableBatchRefUpdate;
+import org.eclipse.jgit.internal.storage.reftable.ReftableCompactor;
+import org.eclipse.jgit.internal.storage.reftable.ReftableConfig;
+import org.eclipse.jgit.internal.storage.reftable.ReftableReader;
+import org.eclipse.jgit.internal.storage.reftable.ReftableWriter;
+import org.eclipse.jgit.lib.Ref;
+import org.eclipse.jgit.transport.ReceiveCommand;
+
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.OutputStream;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+import java.util.Set;
+
+import static org.eclipse.jgit.internal.storage.pack.PackExt.REFTABLE;
+
+/**
+ * {@link org.eclipse.jgit.lib.BatchRefUpdate} for
+ * {@link org.eclipse.jgit.internal.storage.dfs.DfsReftableDatabase}.
+ */
+public class DfsReftableBatchRefUpdate extends ReftableBatchRefUpdate {
+ private static final int AVG_BYTES = 36;
+
+ private final DfsReftableDatabase refdb;
+
+ private final DfsObjDatabase odb;
+
+ /**
+ * Initialize batch update.
+ *
+ * @param refdb
+ * database the update will modify.
+ * @param odb
+ * object database to store the reftable.
+ */
+ protected DfsReftableBatchRefUpdate(DfsReftableDatabase refdb,
+ DfsObjDatabase odb) {
+ super(refdb, refdb.reftableDatabase, refdb.getLock(), refdb.getRepository());
+ this.refdb = refdb;
+ this.odb = odb;
+ }
+
+ @Override
+ protected void applyUpdates(List<Ref> newRefs, List<ReceiveCommand> pending)
+ throws IOException {
+ Set<DfsPackDescription> prune = Collections.emptySet();
+ DfsPackDescription pack = odb.newPack(PackSource.INSERT);
+ try (DfsOutputStream out = odb.writeFile(pack, REFTABLE)) {
+ ReftableConfig cfg = DfsPackCompactor
+ .configureReftable(refdb.getReftableConfig(), out);
+
+ ReftableWriter.Stats stats;
+ if (refdb.compactDuringCommit()
+ && newRefs.size() * AVG_BYTES <= cfg.getRefBlockSize()
+ && canCompactTopOfStack(cfg)) {
+ ByteArrayOutputStream tmp = new ByteArrayOutputStream();
+ ReftableWriter rw = new ReftableWriter(cfg, tmp);
+ write(rw, newRefs, pending);
+ rw.finish();
+ stats = compactTopOfStack(out, cfg, tmp.toByteArray());
+ prune = toPruneTopOfStack();
+ } else {
+ ReftableWriter rw = new ReftableWriter(cfg, out);
+ write(rw, newRefs, pending);
+ rw.finish();
+ stats = rw.getStats();
+ }
+ pack.addFileExt(REFTABLE);
+ pack.setReftableStats(stats);
+ }
+
+ odb.commitPack(Collections.singleton(pack), prune);
+ odb.addReftable(pack, prune);
+ refdb.clearCache();
+ }
+
+ private boolean canCompactTopOfStack(ReftableConfig cfg)
+ throws IOException {
+ refdb.getLock().lock();
+ try {
+ DfsReftableStack stack = refdb.stack();
+ List<ReftableReader> readers = stack.readers();
+ if (readers.isEmpty()) {
+ return false;
+ }
+
+ int lastIdx = readers.size() - 1;
+ DfsReftable last = stack.files().get(lastIdx);
+ DfsPackDescription desc = last.getPackDescription();
+ if (desc.getPackSource() != PackSource.INSERT
+ || !packOnlyContainsReftable(desc)) {
+ return false;
+ }
+
+ ReftableReader table = readers.get(lastIdx);
+ int bs = cfg.getRefBlockSize();
+ return table.size() <= 3 * bs;
+ } finally {
+ refdb.getLock().unlock();
+ }
+ }
+
+ private ReftableWriter.Stats compactTopOfStack(OutputStream out,
+ ReftableConfig cfg, byte[] newTable) throws IOException {
+ refdb.getLock().lock();
+ try {
+ List<ReftableReader> stack = refdb.stack().readers();
+
+ ReftableReader last = stack.get(stack.size() - 1);
+
+ List<ReftableReader> tables = new ArrayList<>(2);
+ tables.add(last);
+ tables.add(new ReftableReader(BlockSource.from(newTable)));
+
+ ReftableCompactor compactor = new ReftableCompactor(out);
+ compactor.setConfig(cfg);
+ compactor.setIncludeDeletes(true);
+ compactor.addAll(tables);
+ compactor.compact();
+ return compactor.getStats();
+ } finally {
+ refdb.getLock().unlock();
+ }
+ }
+
+ private Set<DfsPackDescription> toPruneTopOfStack() throws IOException {
+ refdb.getLock().lock();
+ try {
+ List<DfsReftable> stack = refdb.stack().files();
+
+ DfsReftable last = stack.get(stack.size() - 1);
+ return Collections.singleton(last.getPackDescription());
+ } finally {
+ refdb.getLock().unlock();
+ }
+ }
+
+ private boolean packOnlyContainsReftable(DfsPackDescription desc) {
+ for (PackExt ext : PackExt.values()) {
+ if (ext != REFTABLE && desc.hasFileExt(ext)) {
+ return false;
+ }
+ }
+ return true;
+ }
+}
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/dfs/DfsReftableDatabase.java b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/dfs/DfsReftableDatabase.java
index 6050c15..124131d 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/dfs/DfsReftableDatabase.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/dfs/DfsReftableDatabase.java
@@ -45,19 +45,17 @@
import java.io.IOException;
import java.util.Arrays;
-import java.util.ArrayList;
-import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
+import java.util.TreeSet;
import java.util.concurrent.locks.ReentrantLock;
import org.eclipse.jgit.annotations.Nullable;
import org.eclipse.jgit.internal.storage.reftable.MergedReftable;
-import org.eclipse.jgit.internal.storage.reftable.RefCursor;
-import org.eclipse.jgit.internal.storage.reftable.Reftable;
import org.eclipse.jgit.internal.storage.reftable.ReftableConfig;
+import org.eclipse.jgit.internal.storage.reftable.ReftableDatabase;
import org.eclipse.jgit.lib.BatchRefUpdate;
import org.eclipse.jgit.lib.NullProgressMonitor;
import org.eclipse.jgit.lib.ObjectId;
@@ -81,13 +79,10 @@
* and one will fail.
*/
public class DfsReftableDatabase extends DfsRefDatabase {
- private final ReentrantLock lock = new ReentrantLock(true);
+ final ReftableDatabase reftableDatabase;
private DfsReader ctx;
-
- private ReftableStack tableStack;
-
- private MergedReftable mergedTables;
+ private DfsReftableStack stack;
/**
* Initialize the reference database for a repository.
@@ -97,6 +92,18 @@ public class DfsReftableDatabase extends DfsRefDatabase {
*/
protected DfsReftableDatabase(DfsRepository repo) {
super(repo);
+ reftableDatabase = new ReftableDatabase() {
+ @Override
+ public MergedReftable openMergedReftable() throws IOException {
+ DfsReftableDatabase.this.getLock().lock();
+ try {
+ return new MergedReftable(stack().readers());
+ } finally {
+ DfsReftableDatabase.this.getLock().unlock();
+ }
+ }
+ };
+ stack = null;
}
/** {@inheritDoc} */
@@ -115,7 +122,7 @@ public boolean performsAtomicTransactions() {
@Override
public BatchRefUpdate newBatchUpdate() {
DfsObjDatabase odb = getRepository().getObjectDatabase();
- return new ReftableBatchRefUpdate(this, odb);
+ return new DfsReftableBatchRefUpdate(this, odb);
}
/**
@@ -124,7 +131,7 @@ public BatchRefUpdate newBatchUpdate() {
* @return configuration to write new reftables with.
*/
public ReftableConfig getReftableConfig() {
- return new ReftableConfig(getRepository().getConfig());
+ return new ReftableConfig(getRepository());
}
/**
@@ -133,7 +140,7 @@ public ReftableConfig getReftableConfig() {
* @return the lock protecting this instance's state.
*/
protected ReentrantLock getLock() {
- return lock;
+ return reftableDatabase.getLock();
}
/**
@@ -147,134 +154,57 @@ protected boolean compactDuringCommit() {
return true;
}
- /**
- * Obtain a handle to the merged reader.
- *
- * @return (possibly cached) handle to the merged reader.
- * @throws java.io.IOException
- * if tables cannot be opened.
- */
- protected Reftable reader() throws IOException {
- lock.lock();
- try {
- if (mergedTables == null) {
- mergedTables = new MergedReftable(stack().readers());
- }
- return mergedTables;
- } finally {
- lock.unlock();
- }
- }
/**
- * Obtain a handle to the stack of reftables.
+ * Obtain a handle to the stack of reftables. Must hold lock.
*
* @return (possibly cached) handle to the stack.
* @throws java.io.IOException
* if tables cannot be opened.
*/
- protected ReftableStack stack() throws IOException {
- lock.lock();
- try {
- if (tableStack == null) {
- DfsObjDatabase odb = getRepository().getObjectDatabase();
- if (ctx == null) {
- ctx = odb.newReader();
- }
- tableStack = ReftableStack.open(ctx,
- Arrays.asList(odb.getReftables()));
- }
- return tableStack;
- } finally {
- lock.unlock();
+ protected DfsReftableStack stack() throws IOException {
+ if (!getLock().isLocked()) {
+ throw new IllegalStateException("most hold lock to access stack"); //$NON-NLS-1$
}
+ DfsObjDatabase odb = getRepository().getObjectDatabase();
+
+ if (ctx == null) {
+ ctx = odb.newReader();
+ }
+ if (stack == null) {
+ stack = DfsReftableStack.open(ctx, Arrays.asList(odb.getReftables()));
+ }
+ return stack;
}
- /** {@inheritDoc} */
@Override
public boolean isNameConflicting(String refName) throws IOException {
- lock.lock();
- try {
- Reftable table = reader();
-
- // Cannot be nested within an existing reference.
- int lastSlash = refName.lastIndexOf('/');
- while (0 < lastSlash) {
- if (table.hasRef(refName.substring(0, lastSlash))) {
- return true;
- }
- lastSlash = refName.lastIndexOf('/', lastSlash - 1);
- }
-
- // Cannot be the container of an existing reference.
- return table.hasRefsWithPrefix(refName + '/');
- } finally {
- lock.unlock();
- }
+ return reftableDatabase.isNameConflicting(refName, new TreeSet<>(), new HashSet<>());
}
/** {@inheritDoc} */
@Override
public Ref exactRef(String name) throws IOException {
- lock.lock();
- try {
- Reftable table = reader();
- Ref ref = table.exactRef(name);
- if (ref != null && ref.isSymbolic()) {
- return table.resolve(ref);
- }
- return ref;
- } finally {
- lock.unlock();
- }
+ return reftableDatabase.exactRef(name);
}
/** {@inheritDoc} */
@Override
public Map<String, Ref> getRefs(String prefix) throws IOException {
- RefList.Builder<Ref> all = new RefList.Builder<>();
- lock.lock();
- try {
- Reftable table = reader();
- try (RefCursor rc = ALL.equals(prefix) ? table.allRefs()
- : (prefix.endsWith("/") ? table.seekRefsWithPrefix(prefix) //$NON-NLS-1$
- : table.seekRef(prefix))) {
- while (rc.next()) {
- Ref ref = table.resolve(rc.getRef());
- if (ref != null && ref.getObjectId() != null) {
- all.add(ref);
- }
- }
- }
- } finally {
- lock.unlock();
+ List<Ref> refs = reftableDatabase.getRefsByPrefix(prefix);
+ RefList.Builder<Ref> builder = new RefList.Builder<>(refs.size());
+ for (Ref r : refs) {
+ builder.add(r);
}
-
- RefList<Ref> none = RefList.emptyList();
- return new RefMap(prefix, all.toRefList(), none, none);
+ return new RefMap(prefix, builder.toRefList(), RefList.emptyList(),
+ RefList.emptyList());
}
/** {@inheritDoc} */
@Override
public List<Ref> getRefsByPrefix(String prefix) throws IOException {
- List<Ref> all = new ArrayList<>();
- lock.lock();
- try {
- Reftable table = reader();
- try (RefCursor rc = ALL.equals(prefix) ? table.allRefs()
- : table.seekRefsWithPrefix(prefix)) {
- while (rc.next()) {
- Ref ref = table.resolve(rc.getRef());
- if (ref != null && ref.getObjectId() != null) {
- all.add(ref);
- }
- }
- }
- } finally {
- lock.unlock();
- }
- return Collections.unmodifiableList(all);
+ return reftableDatabase.getRefsByPrefix(prefix);
}
/** {@inheritDoc} */
@@ -283,17 +213,13 @@ public Set<Ref> getTipsWithSha1(ObjectId id) throws IOException {
if (!getReftableConfig().isIndexObjects()) {
return super.getTipsWithSha1(id);
}
- lock.lock();
- try {
- RefCursor cursor = reader().byObjectId(id);
- Set<Ref> refs = new HashSet<>();
- while (cursor.next()) {
- refs.add(cursor.getRef());
- }
- return refs;
- } finally {
- lock.unlock();
- }
+ return reftableDatabase.getTipsWithSha1(id);
+ }
+
+ /** {@inheritDoc} */
+ @Override
+ public boolean hasFastTipsWithSha1() throws IOException {
+ return reftableDatabase.hasFastTipsWithSha1();
}
/** {@inheritDoc} */
@@ -314,19 +240,19 @@ boolean exists() throws IOException {
@Override
void clearCache() {
- lock.lock();
+ getLock().lock();
try {
- if (tableStack != null) {
- tableStack.close();
- tableStack = null;
- }
if (ctx != null) {
ctx.close();
ctx = null;
}
- mergedTables = null;
+ reftableDatabase.clearCache();
+ if (stack != null) {
+ stack.close();
+ stack = null;
+ }
} finally {
- lock.unlock();
+ getLock().unlock();
}
}
@@ -334,7 +260,7 @@ void clearCache() {
@Override
protected boolean compareAndPut(Ref oldRef, @Nullable Ref newRef)
throws IOException {
- ReceiveCommand cmd = toCommand(oldRef, newRef);
+ ReceiveCommand cmd = ReftableDatabase.toCommand(oldRef, newRef);
try (RevWalk rw = new RevWalk(getRepository())) {
rw.setRetainBody(false);
newBatchUpdate().setAllowNonFastForwards(true).addCommand(cmd)
@@ -351,58 +277,6 @@ protected boolean compareAndPut(Ref oldRef, @Nullable Ref newRef)
}
}
- private static ReceiveCommand toCommand(Ref oldRef, Ref newRef) {
- ObjectId oldId = toId(oldRef);
- ObjectId newId = toId(newRef);
- String name = toName(oldRef, newRef);
-
- if (oldRef != null && oldRef.isSymbolic()) {
- if (newRef != null) {
- if (newRef.isSymbolic()) {
- return ReceiveCommand.link(oldRef.getTarget().getName(),
- newRef.getTarget().getName(), name);
- } else {
- return ReceiveCommand.unlink(oldRef.getTarget().getName(),
- newId, name);
- }
- } else {
- return ReceiveCommand.unlink(oldRef.getTarget().getName(),
- ObjectId.zeroId(), name);
- }
- }
-
- if (newRef != null && newRef.isSymbolic()) {
- if (oldRef != null) {
- if (oldRef.isSymbolic()) {
- return ReceiveCommand.link(oldRef.getTarget().getName(),
- newRef.getTarget().getName(), name);
- } else {
- return ReceiveCommand.link(oldId,
- newRef.getTarget().getName(), name);
- }
- } else {
- return ReceiveCommand.link(ObjectId.zeroId(),
- newRef.getTarget().getName(), name);
- }
- }
-
- return new ReceiveCommand(oldId, newId, name);
- }
-
- private static ObjectId toId(Ref ref) {
- if (ref != null) {
- ObjectId id = ref.getObjectId();
- if (id != null) {
- return id;
- }
- }
- return ObjectId.zeroId();
- }
-
- private static String toName(Ref oldRef, Ref newRef) {
- return oldRef != null ? oldRef.getName() : newRef.getName();
- }
-
/** {@inheritDoc} */
@Override
protected boolean compareAndRemove(Ref oldRef) throws IOException {
@@ -417,12 +291,12 @@ protected RefCache scanAllRefs() throws IOException {
@Override
void stored(Ref ref) {
- // Unnecessary; ReftableBatchRefUpdate calls clearCache().
+ // Unnecessary; DfsReftableBatchRefUpdate calls clearCache().
}
@Override
void removed(String refName) {
- // Unnecessary; ReftableBatchRefUpdate calls clearCache().
+ // Unnecessary; DfsReftableBatchRefUpdate calls clearCache().
}
/** {@inheritDoc} */
@@ -430,4 +304,5 @@ void removed(String refName) {
protected void cachePeeledState(Ref oldLeaf, Ref newLeaf) {
// Do not cache peeled state in reftable.
}
+
}
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/dfs/ReftableStack.java b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/dfs/DfsReftableStack.java
similarity index 87%
rename from org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/dfs/ReftableStack.java
rename to org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/dfs/DfsReftableStack.java
index 50ba0e0..59621a4 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/dfs/ReftableStack.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/dfs/DfsReftableStack.java
@@ -48,13 +48,13 @@
import java.util.Collections;
import java.util.List;
-import org.eclipse.jgit.internal.storage.reftable.Reftable;
+import org.eclipse.jgit.internal.storage.reftable.ReftableReader;
/**
* Tracks multiple open
- * {@link org.eclipse.jgit.internal.storage.reftable.Reftable} instances.
+ * {@link org.eclipse.jgit.internal.storage.reftable.ReftableReader} instances.
*/
-public class ReftableStack implements AutoCloseable {
+public class DfsReftableStack implements AutoCloseable {
/**
* Opens a stack of tables for reading.
*
@@ -67,9 +67,9 @@ public class ReftableStack implements AutoCloseable {
* @throws java.io.IOException
* a table could not be opened
*/
- public static ReftableStack open(DfsReader ctx, List<DfsReftable> files)
+ public static DfsReftableStack open(DfsReader ctx, List<DfsReftable> files)
throws IOException {
- ReftableStack stack = new ReftableStack(files.size());
+ DfsReftableStack stack = new DfsReftableStack(files.size());
boolean close = true;
try {
for (DfsReftable t : files) {
@@ -86,9 +86,9 @@ public static ReftableStack open(DfsReader ctx, List<DfsReftable> files)
}
private final List<DfsReftable> files;
- private final List<Reftable> tables;
+ private final List<ReftableReader> tables;
- private ReftableStack(int tableCnt) {
+ private DfsReftableStack(int tableCnt) {
this.files = new ArrayList<>(tableCnt);
this.tables = new ArrayList<>(tableCnt);
}
@@ -109,14 +109,14 @@ public List<DfsReftable> files() {
* @return unmodifiable list of tables, in the same order the files were
* passed to {@link #open(DfsReader, List)}.
*/
- public List<Reftable> readers() {
+ public List<ReftableReader> readers() {
return Collections.unmodifiableList(tables);
}
/** {@inheritDoc} */
@Override
public void close() {
- for (Reftable t : tables) {
+ for (ReftableReader t : tables) {
try {
t.close();
} catch (IOException e) {
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/dfs/ReftableBatchRefUpdate.java b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/dfs/ReftableBatchRefUpdate.java
deleted file mode 100644
index 07fd00f..0000000
--- a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/dfs/ReftableBatchRefUpdate.java
+++ /dev/null
@@ -1,460 +0,0 @@
-/*
- * Copyright (C) 2017, Google Inc.
- * 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.storage.dfs;
-
-import static org.eclipse.jgit.internal.storage.pack.PackExt.REFTABLE;
-import static org.eclipse.jgit.lib.Ref.Storage.NEW;
-import static org.eclipse.jgit.lib.Ref.Storage.PACKED;
-import static org.eclipse.jgit.transport.ReceiveCommand.Result.LOCK_FAILURE;
-import static org.eclipse.jgit.transport.ReceiveCommand.Result.NOT_ATTEMPTED;
-import static org.eclipse.jgit.transport.ReceiveCommand.Result.OK;
-import static org.eclipse.jgit.transport.ReceiveCommand.Result.REJECTED_MISSING_OBJECT;
-import static org.eclipse.jgit.transport.ReceiveCommand.Result.REJECTED_NONFASTFORWARD;
-import static org.eclipse.jgit.transport.ReceiveCommand.Type.UPDATE_NONFASTFORWARD;
-
-import java.io.ByteArrayOutputStream;
-import java.io.IOException;
-import java.io.OutputStream;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-import java.util.concurrent.locks.ReentrantLock;
-
-import org.eclipse.jgit.annotations.Nullable;
-import org.eclipse.jgit.errors.MissingObjectException;
-import org.eclipse.jgit.internal.storage.dfs.DfsObjDatabase.PackSource;
-import org.eclipse.jgit.internal.storage.io.BlockSource;
-import org.eclipse.jgit.internal.storage.pack.PackExt;
-import org.eclipse.jgit.internal.storage.reftable.Reftable;
-import org.eclipse.jgit.internal.storage.reftable.ReftableCompactor;
-import org.eclipse.jgit.internal.storage.reftable.ReftableConfig;
-import org.eclipse.jgit.internal.storage.reftable.ReftableReader;
-import org.eclipse.jgit.internal.storage.reftable.ReftableWriter;
-import org.eclipse.jgit.lib.AnyObjectId;
-import org.eclipse.jgit.lib.BatchRefUpdate;
-import org.eclipse.jgit.lib.ObjectId;
-import org.eclipse.jgit.lib.ObjectIdRef;
-import org.eclipse.jgit.lib.PersonIdent;
-import org.eclipse.jgit.lib.ProgressMonitor;
-import org.eclipse.jgit.lib.Ref;
-import org.eclipse.jgit.lib.ReflogEntry;
-import org.eclipse.jgit.lib.SymbolicRef;
-import org.eclipse.jgit.revwalk.RevObject;
-import org.eclipse.jgit.revwalk.RevTag;
-import org.eclipse.jgit.revwalk.RevWalk;
-import org.eclipse.jgit.transport.ReceiveCommand;
-
-/**
- * {@link org.eclipse.jgit.lib.BatchRefUpdate} for
- * {@link org.eclipse.jgit.internal.storage.dfs.DfsReftableDatabase}.
- */
-public class ReftableBatchRefUpdate extends BatchRefUpdate {
- private static final int AVG_BYTES = 36;
-
- private final DfsReftableDatabase refdb;
-
- private final DfsObjDatabase odb;
-
- private final ReentrantLock lock;
-
- private final ReftableConfig reftableConfig;
-
- /**
- * Initialize batch update.
- *
- * @param refdb
- * database the update will modify.
- * @param odb
- * object database to store the reftable.
- */
- protected ReftableBatchRefUpdate(DfsReftableDatabase refdb,
- DfsObjDatabase odb) {
- super(refdb);
- this.refdb = refdb;
- this.odb = odb;
- lock = refdb.getLock();
- reftableConfig = refdb.getReftableConfig();
- }
-
- /** {@inheritDoc} */
- @Override
- public void execute(RevWalk rw, ProgressMonitor pm, List<String> options) {
- List<ReceiveCommand> pending = getPending();
- if (pending.isEmpty()) {
- return;
- }
- if (options != null) {
- setPushOptions(options);
- }
- try {
- if (!checkObjectExistence(rw, pending)) {
- return;
- }
- if (!checkNonFastForwards(rw, pending)) {
- return;
- }
-
- lock.lock();
- try {
- Reftable table = refdb.reader();
- if (!checkExpected(table, pending)) {
- return;
- }
- if (!checkConflicting(pending)) {
- return;
- }
- if (!blockUntilTimestamps(MAX_WAIT)) {
- return;
- }
- applyUpdates(rw, pending);
- for (ReceiveCommand cmd : pending) {
- cmd.setResult(OK);
- }
- } finally {
- lock.unlock();
- }
- } catch (IOException e) {
- pending.get(0).setResult(LOCK_FAILURE, "io error"); //$NON-NLS-1$
- ReceiveCommand.abort(pending);
- }
- }
-
- private List<ReceiveCommand> getPending() {
- return ReceiveCommand.filter(getCommands(), NOT_ATTEMPTED);
- }
-
- private boolean checkObjectExistence(RevWalk rw,
- List<ReceiveCommand> pending) throws IOException {
- for (ReceiveCommand cmd : pending) {
- try {
- if (!cmd.getNewId().equals(ObjectId.zeroId())) {
- rw.parseAny(cmd.getNewId());
- }
- } catch (MissingObjectException e) {
- // ReceiveCommand#setResult(Result) converts REJECTED to
- // REJECTED_NONFASTFORWARD, even though that result is also
- // used for a missing object. Eagerly handle this case so we
- // can set the right result.
- cmd.setResult(REJECTED_MISSING_OBJECT);
- ReceiveCommand.abort(pending);
- return false;
- }
- }
- return true;
- }
-
- private boolean checkNonFastForwards(RevWalk rw,
- List<ReceiveCommand> pending) throws IOException {
- if (isAllowNonFastForwards()) {
- return true;
- }
- for (ReceiveCommand cmd : pending) {
- cmd.updateType(rw);
- if (cmd.getType() == UPDATE_NONFASTFORWARD) {
- cmd.setResult(REJECTED_NONFASTFORWARD);
- ReceiveCommand.abort(pending);
- return false;
- }
- }
- return true;
- }
-
- private boolean checkConflicting(List<ReceiveCommand> pending)
- throws IOException {
- Set<String> names = new HashSet<>();
- for (ReceiveCommand cmd : pending) {
- names.add(cmd.getRefName());
- }
-
- boolean ok = true;
- for (ReceiveCommand cmd : pending) {
- String name = cmd.getRefName();
- if (refdb.isNameConflicting(name)) {
- cmd.setResult(LOCK_FAILURE);
- ok = false;
- } else {
- int s = name.lastIndexOf('/');
- while (0 < s) {
- if (names.contains(name.substring(0, s))) {
- cmd.setResult(LOCK_FAILURE);
- ok = false;
- break;
- }
- s = name.lastIndexOf('/', s - 1);
- }
- }
- }
- if (!ok && isAtomic()) {
- ReceiveCommand.abort(pending);
- return false;
- }
- return ok;
- }
-
- private boolean checkExpected(Reftable table, List<ReceiveCommand> pending)
- throws IOException {
- for (ReceiveCommand cmd : pending) {
- if (!matchOld(cmd, table.exactRef(cmd.getRefName()))) {
- cmd.setResult(LOCK_FAILURE);
- if (isAtomic()) {
- ReceiveCommand.abort(pending);
- return false;
- }
- }
- }
- return true;
- }
-
- private static boolean matchOld(ReceiveCommand cmd, @Nullable Ref ref) {
- if (ref == null) {
- return AnyObjectId.isEqual(ObjectId.zeroId(), cmd.getOldId())
- && cmd.getOldSymref() == null;
- } else if (ref.isSymbolic()) {
- return ref.getTarget().getName().equals(cmd.getOldSymref());
- }
- ObjectId id = ref.getObjectId();
- if (id == null) {
- id = ObjectId.zeroId();
- }
- return cmd.getOldId().equals(id);
- }
-
- private void applyUpdates(RevWalk rw, List<ReceiveCommand> pending)
- throws IOException {
- List<Ref> newRefs = toNewRefs(rw, pending);
- long updateIndex = nextUpdateIndex();
- Set<DfsPackDescription> prune = Collections.emptySet();
- DfsPackDescription pack = odb.newPack(PackSource.INSERT);
- try (DfsOutputStream out = odb.writeFile(pack, REFTABLE)) {
- ReftableConfig cfg = DfsPackCompactor
- .configureReftable(reftableConfig, out);
-
- ReftableWriter.Stats stats;
- if (refdb.compactDuringCommit()
- && newRefs.size() * AVG_BYTES <= cfg.getRefBlockSize()
- && canCompactTopOfStack(cfg)) {
- ByteArrayOutputStream tmp = new ByteArrayOutputStream();
- write(tmp, cfg, updateIndex, newRefs, pending);
- stats = compactTopOfStack(out, cfg, tmp.toByteArray());
- prune = toPruneTopOfStack();
- } else {
- stats = write(out, cfg, updateIndex, newRefs, pending);
- }
- pack.addFileExt(REFTABLE);
- pack.setReftableStats(stats);
- }
-
- odb.commitPack(Collections.singleton(pack), prune);
- odb.addReftable(pack, prune);
- refdb.clearCache();
- }
-
- private ReftableWriter.Stats write(OutputStream os, ReftableConfig cfg,
- long updateIndex, List<Ref> newRefs, List<ReceiveCommand> pending)
- throws IOException {
- ReftableWriter writer = new ReftableWriter(cfg)
- .setMinUpdateIndex(updateIndex).setMaxUpdateIndex(updateIndex)
- .begin(os).sortAndWriteRefs(newRefs);
- if (!isRefLogDisabled()) {
- writeLog(writer, updateIndex, pending);
- }
- writer.finish();
- return writer.getStats();
- }
-
- private void writeLog(ReftableWriter writer, long updateIndex,
- List<ReceiveCommand> pending) throws IOException {
- Map<String, ReceiveCommand> cmds = new HashMap<>();
- List<String> byName = new ArrayList<>(pending.size());
- for (ReceiveCommand cmd : pending) {
- cmds.put(cmd.getRefName(), cmd);
- byName.add(cmd.getRefName());
- }
- Collections.sort(byName);
-
- PersonIdent ident = getRefLogIdent();
- if (ident == null) {
- ident = new PersonIdent(refdb.getRepository());
- }
- for (String name : byName) {
- ReceiveCommand cmd = cmds.get(name);
- if (isRefLogDisabled(cmd)) {
- continue;
- }
- String msg = getRefLogMessage(cmd);
- if (isRefLogIncludingResult(cmd)) {
- String strResult = toResultString(cmd);
- if (strResult != null) {
- msg = msg.isEmpty() ? strResult : msg + ": " + strResult; //$NON-NLS-1$
- }
- }
- writer.writeLog(name, updateIndex, ident, cmd.getOldId(),
- cmd.getNewId(), msg);
- }
- }
-
- private String toResultString(ReceiveCommand cmd) {
- switch (cmd.getType()) {
- case CREATE:
- return ReflogEntry.PREFIX_CREATED;
- case UPDATE:
- // Match the behavior of a single RefUpdate. In that case, setting
- // the force bit completely bypasses the potentially expensive
- // isMergedInto check, by design, so the reflog message may be
- // inaccurate.
- //
- // Similarly, this class bypasses the isMergedInto checks when the
- // force bit is set, meaning we can't actually distinguish between
- // UPDATE and UPDATE_NONFASTFORWARD when isAllowNonFastForwards()
- // returns true.
- return isAllowNonFastForwards() ? ReflogEntry.PREFIX_FORCED_UPDATE
- : ReflogEntry.PREFIX_FAST_FORWARD;
- case UPDATE_NONFASTFORWARD:
- return ReflogEntry.PREFIX_FORCED_UPDATE;
- default:
- return null;
- }
- }
-
- private static List<Ref> toNewRefs(RevWalk rw, List<ReceiveCommand> pending)
- throws IOException {
- List<Ref> refs = new ArrayList<>(pending.size());
- for (ReceiveCommand cmd : pending) {
- String name = cmd.getRefName();
- ObjectId newId = cmd.getNewId();
- String newSymref = cmd.getNewSymref();
- if (AnyObjectId.isEqual(ObjectId.zeroId(), newId)
- && newSymref == null) {
- refs.add(new ObjectIdRef.Unpeeled(NEW, name, null));
- continue;
- } else if (newSymref != null) {
- refs.add(new SymbolicRef(name,
- new ObjectIdRef.Unpeeled(NEW, newSymref, null)));
- continue;
- }
-
- RevObject obj = rw.parseAny(newId);
- RevObject peel = null;
- if (obj instanceof RevTag) {
- peel = rw.peel(obj);
- }
- if (peel != null) {
- refs.add(new ObjectIdRef.PeeledTag(PACKED, name, newId,
- peel.copy()));
- } else {
- refs.add(new ObjectIdRef.PeeledNonTag(PACKED, name, newId));
- }
- }
- return refs;
- }
-
- private long nextUpdateIndex() throws IOException {
- long updateIndex = 0;
- for (Reftable r : refdb.stack().readers()) {
- if (r instanceof ReftableReader) {
- updateIndex = Math.max(updateIndex,
- ((ReftableReader) r).maxUpdateIndex());
- }
- }
- return updateIndex + 1;
- }
-
- private boolean canCompactTopOfStack(ReftableConfig cfg)
- throws IOException {
- ReftableStack stack = refdb.stack();
- List<Reftable> readers = stack.readers();
- if (readers.isEmpty()) {
- return false;
- }
-
- int lastIdx = readers.size() - 1;
- DfsReftable last = stack.files().get(lastIdx);
- DfsPackDescription desc = last.getPackDescription();
- if (desc.getPackSource() != PackSource.INSERT
- || !packOnlyContainsReftable(desc)) {
- return false;
- }
-
- Reftable table = readers.get(lastIdx);
- int bs = cfg.getRefBlockSize();
- return table instanceof ReftableReader
- && ((ReftableReader) table).size() <= 3 * bs;
- }
-
- private ReftableWriter.Stats compactTopOfStack(OutputStream out,
- ReftableConfig cfg, byte[] newTable) throws IOException {
- List<Reftable> stack = refdb.stack().readers();
- Reftable last = stack.get(stack.size() - 1);
-
- List<Reftable> tables = new ArrayList<>(2);
- tables.add(last);
- tables.add(new ReftableReader(BlockSource.from(newTable)));
-
- ReftableCompactor compactor = new ReftableCompactor();
- compactor.setConfig(cfg);
- compactor.setIncludeDeletes(true);
- compactor.addAll(tables);
- compactor.compact(out);
- return compactor.getStats();
- }
-
- private Set<DfsPackDescription> toPruneTopOfStack() throws IOException {
- List<DfsReftable> stack = refdb.stack().files();
- DfsReftable last = stack.get(stack.size() - 1);
- return Collections.singleton(last.getPackDescription());
- }
-
- private boolean packOnlyContainsReftable(DfsPackDescription desc) {
- for (PackExt ext : PackExt.values()) {
- if (ext != REFTABLE && desc.hasFileExt(ext)) {
- return false;
- }
- }
- return true;
- }
-}
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/FileObjectDatabase.java b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/FileObjectDatabase.java
index 1f6b20a..db5b127 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/FileObjectDatabase.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/FileObjectDatabase.java
@@ -60,7 +60,7 @@
import org.eclipse.jgit.util.FS;
abstract class FileObjectDatabase extends ObjectDatabase {
- static enum InsertLooseObjectResult {
+ enum InsertLooseObjectResult {
INSERTED, EXISTS_PACKED, EXISTS_LOOSE, FAILURE;
}
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/FileReftableDatabase.java b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/FileReftableDatabase.java
new file mode 100644
index 0000000..e5ffd77
--- /dev/null
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/FileReftableDatabase.java
@@ -0,0 +1,669 @@
+/*
+ * 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.internal.storage.file;
+
+import static org.eclipse.jgit.lib.Ref.UNDEFINED_UPDATE_INDEX;
+import static org.eclipse.jgit.lib.Ref.Storage.NEW;
+import static org.eclipse.jgit.lib.Ref.Storage.PACKED;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.TreeSet;
+import java.util.concurrent.locks.ReentrantLock;
+import java.util.stream.Collectors;
+
+import org.eclipse.jgit.annotations.NonNull;
+import org.eclipse.jgit.errors.MissingObjectException;
+import org.eclipse.jgit.events.RefsChangedEvent;
+import org.eclipse.jgit.internal.storage.reftable.MergedReftable;
+import org.eclipse.jgit.internal.storage.reftable.ReftableBatchRefUpdate;
+import org.eclipse.jgit.internal.storage.reftable.ReftableDatabase;
+import org.eclipse.jgit.internal.storage.reftable.ReftableWriter;
+import org.eclipse.jgit.lib.BatchRefUpdate;
+import org.eclipse.jgit.lib.Constants;
+import org.eclipse.jgit.lib.ObjectId;
+import org.eclipse.jgit.lib.ObjectIdRef;
+import org.eclipse.jgit.lib.PersonIdent;
+import org.eclipse.jgit.lib.Ref;
+import org.eclipse.jgit.lib.RefDatabase;
+import org.eclipse.jgit.lib.RefRename;
+import org.eclipse.jgit.lib.RefUpdate;
+import org.eclipse.jgit.lib.ReflogEntry;
+import org.eclipse.jgit.lib.ReflogReader;
+import org.eclipse.jgit.lib.Repository;
+import org.eclipse.jgit.lib.SymbolicRef;
+import org.eclipse.jgit.revwalk.RevObject;
+import org.eclipse.jgit.revwalk.RevTag;
+import org.eclipse.jgit.revwalk.RevWalk;
+import org.eclipse.jgit.transport.ReceiveCommand;
+import org.eclipse.jgit.util.FileUtils;
+import org.eclipse.jgit.util.RefList;
+import org.eclipse.jgit.util.RefMap;
+
+/**
+ * Implements RefDatabase using reftable for storage.
+ *
+ * This class is threadsafe.
+ */
+public class FileReftableDatabase extends RefDatabase {
+ private final ReftableDatabase reftableDatabase;
+
+ private final FileRepository fileRepository;
+
+ private final FileReftableStack reftableStack;
+
+ FileReftableDatabase(FileRepository repo) throws IOException {
+ this(repo, new File(new File(repo.getDirectory(), Constants.REFTABLE),
+ Constants.TABLES_LIST));
+ }
+
+ FileReftableDatabase(FileRepository repo, File refstackName) throws IOException {
+ this.fileRepository = repo;
+ this.reftableStack = new FileReftableStack(refstackName,
+ new File(fileRepository.getDirectory(), Constants.REFTABLE),
+ () -> fileRepository.fireEvent(new RefsChangedEvent()),
+ () -> fileRepository.getConfig());
+ this.reftableDatabase = new ReftableDatabase() {
+
+ @Override
+ public MergedReftable openMergedReftable() throws IOException {
+ return reftableStack.getMergedReftable();
+ }
+ };
+ }
+
+ ReflogReader getReflogReader(String refname) throws IOException {
+ return reftableDatabase.getReflogReader(refname);
+ }
+
+ /**
+ * @param repoDir
+ * @return whether the given repo uses reftable for refdb storage.
+ */
+ public static boolean isReftable(File repoDir) {
+ return new File(repoDir, Constants.REFTABLE).isDirectory();
+ }
+
+ /** {@inheritDoc} */
+ @Override
+ public boolean hasFastTipsWithSha1() throws IOException {
+ return reftableDatabase.hasFastTipsWithSha1();
+ }
+
+ /**
+ * Runs a full compaction for GC purposes.
+ * @throws IOException on I/O errors
+ */
+ public void compactFully() throws IOException {
+ reftableDatabase.getLock().lock();
+ try {
+ reftableStack.compactFully();
+ reftableDatabase.clearCache();
+ } finally {
+ reftableDatabase.getLock().unlock();
+ }
+ }
+
+ private ReentrantLock getLock() {
+ return reftableDatabase.getLock();
+ }
+
+ /** {@inheritDoc} */
+ @Override
+ public boolean performsAtomicTransactions() {
+ return true;
+ }
+
+ /** {@inheritDoc} */
+ @NonNull
+ @Override
+ public BatchRefUpdate newBatchUpdate() {
+ return new FileReftableBatchRefUpdate(this, fileRepository);
+ }
+
+ /** {@inheritDoc} */
+ @Override
+ public RefUpdate newUpdate(String refName, boolean detach)
+ throws IOException {
+ boolean detachingSymbolicRef = false;
+ Ref ref = exactRef(refName);
+
+ if (ref == null) {
+ ref = new ObjectIdRef.Unpeeled(NEW, refName, null);
+ } else {
+ detachingSymbolicRef = detach && ref.isSymbolic();
+ }
+
+ RefUpdate update = new FileReftableRefUpdate(ref);
+ if (detachingSymbolicRef) {
+ update.setDetachingSymbolicRef();
+ }
+ return update;
+ }
+
+ /** {@inheritDoc} */
+ @Override
+ public Ref exactRef(String name) throws IOException {
+ return reftableDatabase.exactRef(name);
+ }
+
+ /** {@inheritDoc} */
+ @Override
+ public List<Ref> getRefs() throws IOException {
+ return super.getRefs();
+ }
+
+ /** {@inheritDoc} */
+ @Override
+ public Map<String, Ref> getRefs(String prefix) throws IOException {
+ List<Ref> refs = reftableDatabase.getRefsByPrefix(prefix);
+ RefList.Builder<Ref> builder = new RefList.Builder<>(refs.size());
+ for (Ref r : refs) {
+ builder.add(r);
+ }
+ return new RefMap(prefix, builder.toRefList(), RefList.emptyList(),
+ RefList.emptyList());
+ }
+
+ /** {@inheritDoc} */
+ @Override
+ public List<Ref> getAdditionalRefs() throws IOException {
+ return Collections.emptyList();
+ }
+
+ /** {@inheritDoc} */
+ @Override
+ public Ref peel(Ref ref) throws IOException {
+ Ref oldLeaf = ref.getLeaf();
+ if (oldLeaf.isPeeled() || oldLeaf.getObjectId() == null) {
+ return ref;
+ }
+ return recreate(ref, doPeel(oldLeaf), hasVersioning());
+
+ }
+
+ private Ref doPeel(Ref leaf) throws IOException {
+ try (RevWalk rw = new RevWalk(fileRepository)) {
+ RevObject obj = rw.parseAny(leaf.getObjectId());
+ if (obj instanceof RevTag) {
+ return new ObjectIdRef.PeeledTag(leaf.getStorage(),
+ leaf.getName(), leaf.getObjectId(), rw.peel(obj).copy(),
+ hasVersioning() ? leaf.getUpdateIndex()
+ : UNDEFINED_UPDATE_INDEX);
+ }
+ return new ObjectIdRef.PeeledNonTag(leaf.getStorage(),
+ leaf.getName(), leaf.getObjectId(),
+ hasVersioning() ? leaf.getUpdateIndex()
+ : UNDEFINED_UPDATE_INDEX);
+
+ }
+ }
+
+ private static Ref recreate(Ref old, Ref leaf, boolean hasVersioning) {
+ if (old.isSymbolic()) {
+ Ref dst = recreate(old.getTarget(), leaf, hasVersioning);
+ return new SymbolicRef(old.getName(), dst,
+ hasVersioning ? old.getUpdateIndex()
+ : UNDEFINED_UPDATE_INDEX);
+ }
+ return leaf;
+ }
+
+ private class FileRefRename extends RefRename {
+ FileRefRename(RefUpdate src, RefUpdate dst) {
+ super(src, dst);
+ }
+
+ void writeRename(ReftableWriter w) throws IOException {
+ long idx = reftableDatabase.nextUpdateIndex();
+ w.setMinUpdateIndex(idx).setMaxUpdateIndex(idx).begin();
+ List<Ref> refs = new ArrayList<>(3);
+
+ Ref dest = destination.getRef();
+ Ref head = exactRef(Constants.HEAD);
+ if (head != null && head.isSymbolic()
+ && head.getLeaf().getName().equals(source.getName())) {
+ head = new SymbolicRef(Constants.HEAD, dest, idx);
+ refs.add(head);
+ }
+
+ ObjectId objId = source.getRef().getObjectId();
+
+ // XXX should we check if the source is a Tag vs. NonTag?
+ refs.add(new ObjectIdRef.PeeledNonTag(Ref.Storage.NEW,
+ destination.getName(), objId));
+ refs.add(new ObjectIdRef.Unpeeled(Ref.Storage.NEW, source.getName(),
+ null));
+
+ w.sortAndWriteRefs(refs);
+ PersonIdent who = destination.getRefLogIdent();
+ if (who == null) {
+ who = new PersonIdent(fileRepository);
+ }
+
+ if (!destination.getRefLogMessage().isEmpty()) {
+ List<String> refnames = refs.stream().map(r -> r.getName())
+ .collect(Collectors.toList());
+ Collections.sort(refnames);
+ for (String s : refnames) {
+ ObjectId old = (Constants.HEAD.equals(s)
+ || s.equals(source.getName())) ? objId
+ : ObjectId.zeroId();
+ ObjectId newId = (Constants.HEAD.equals(s)
+ || s.equals(destination.getName())) ? objId
+ : ObjectId.zeroId();
+
+ w.writeLog(s, idx, who, old, newId,
+ destination.getRefLogMessage());
+ }
+ }
+ }
+
+ @Override
+ protected RefUpdate.Result doRename() throws IOException {
+ Ref src = exactRef(source.getName());
+ if (exactRef(destination.getName()) != null || src == null
+ || !source.getOldObjectId().equals(src.getObjectId())) {
+ return RefUpdate.Result.LOCK_FAILURE;
+ }
+
+ if (src.isSymbolic()) {
+ // We could support this, but this is easier and compatible.
+ return RefUpdate.Result.IO_FAILURE;
+ }
+
+ if (!addReftable(this::writeRename)) {
+ return RefUpdate.Result.LOCK_FAILURE;
+ }
+
+ return RefUpdate.Result.RENAMED;
+ }
+ }
+
+ /** {@inheritDoc} */
+ @Override
+ public RefRename newRename(String fromName, String toName)
+ throws IOException {
+ RefUpdate src = newUpdate(fromName, true);
+ RefUpdate dst = newUpdate(toName, true);
+ return new FileRefRename(src, dst);
+ }
+
+ /** {@inheritDoc} */
+ @Override
+ public boolean isNameConflicting(String name) throws IOException {
+ return reftableDatabase.isNameConflicting(name, new TreeSet<>(),
+ new HashSet<>());
+ }
+
+ /** {@inheritDoc} */
+ @Override
+ public void close() {
+ reftableStack.close();
+ }
+
+ /** {@inheritDoc} */
+ @Override
+ public void create() throws IOException {
+ FileUtils.mkdir(
+ new File(fileRepository.getDirectory(), Constants.REFTABLE),
+ true);
+ }
+
+ private boolean addReftable(FileReftableStack.Writer w) throws IOException {
+ if (!reftableStack.addReftable(w)) {
+ reftableStack.reload();
+ reftableDatabase.clearCache();
+ return false;
+ }
+ reftableDatabase.clearCache();
+
+ return true;
+ }
+
+ private class FileReftableBatchRefUpdate extends ReftableBatchRefUpdate {
+ FileReftableBatchRefUpdate(FileReftableDatabase db,
+ Repository repository) {
+ super(db, db.reftableDatabase, db.getLock(), repository);
+ }
+
+ @Override
+ protected void applyUpdates(List<Ref> newRefs,
+ List<ReceiveCommand> pending) throws IOException {
+ if (!addReftable(rw -> write(rw, newRefs, pending))) {
+ for (ReceiveCommand c : pending) {
+ if (c.getResult() == ReceiveCommand.Result.NOT_ATTEMPTED) {
+ c.setResult(RefUpdate.Result.LOCK_FAILURE);
+ }
+ }
+ }
+ }
+ }
+
+ private class FileReftableRefUpdate extends RefUpdate {
+ FileReftableRefUpdate(Ref ref) {
+ super(ref);
+ }
+
+ @Override
+ protected RefDatabase getRefDatabase() {
+ return FileReftableDatabase.this;
+ }
+
+ @Override
+ protected Repository getRepository() {
+ return FileReftableDatabase.this.fileRepository;
+ }
+
+ @Override
+ protected void unlock() {
+ // nop.
+ }
+
+ private RevWalk rw;
+
+ private Ref dstRef;
+
+ @Override
+ public Result update(RevWalk walk) throws IOException {
+ try {
+ rw = walk;
+ return super.update(walk);
+ } finally {
+ rw = null;
+ }
+ }
+
+ @Override
+ protected boolean tryLock(boolean deref) throws IOException {
+ dstRef = getRef();
+ if (deref) {
+ dstRef = dstRef.getLeaf();
+ }
+
+ Ref derefed = exactRef(dstRef.getName());
+ if (derefed != null) {
+ setOldObjectId(derefed.getObjectId());
+ }
+
+ return true;
+ }
+
+ void writeUpdate(ReftableWriter w) throws IOException {
+ Ref newRef = null;
+ if (rw != null && !ObjectId.zeroId().equals(getNewObjectId())) {
+ RevObject obj = rw.parseAny(getNewObjectId());
+ if (obj instanceof RevTag) {
+ newRef = new ObjectIdRef.PeeledTag(Ref.Storage.PACKED,
+ dstRef.getName(), getNewObjectId(),
+ rw.peel(obj).copy());
+ }
+ }
+ if (newRef == null) {
+ newRef = new ObjectIdRef.PeeledNonTag(Ref.Storage.PACKED,
+ dstRef.getName(), getNewObjectId());
+ }
+
+ long idx = reftableDatabase.nextUpdateIndex();
+ w.setMinUpdateIndex(idx).setMaxUpdateIndex(idx).begin()
+ .writeRef(newRef);
+
+ ObjectId oldId = getOldObjectId();
+ if (oldId == null) {
+ oldId = ObjectId.zeroId();
+ }
+ w.writeLog(dstRef.getName(), idx, getRefLogIdent(), oldId,
+ getNewObjectId(), getRefLogMessage());
+ }
+
+ @Override
+ public PersonIdent getRefLogIdent() {
+ PersonIdent who = super.getRefLogIdent();
+ if (who == null) {
+ who = new PersonIdent(getRepository());
+ }
+ return who;
+ }
+
+ void writeDelete(ReftableWriter w) throws IOException {
+ Ref newRef = new ObjectIdRef.Unpeeled(Ref.Storage.NEW,
+ dstRef.getName(), null);
+ long idx = reftableDatabase.nextUpdateIndex();
+ w.setMinUpdateIndex(idx).setMaxUpdateIndex(idx).begin()
+ .writeRef(newRef);
+
+ ObjectId oldId = ObjectId.zeroId();
+ Ref old = exactRef(dstRef.getName());
+ if (old != null) {
+ old = old.getLeaf();
+ if (old.getObjectId() != null) {
+ oldId = old.getObjectId();
+ }
+ }
+
+ w.writeLog(dstRef.getName(), idx, getRefLogIdent(), oldId,
+ ObjectId.zeroId(), getRefLogMessage());
+ }
+
+ @Override
+ protected Result doUpdate(Result desiredResult) throws IOException {
+ if (isRefLogIncludingResult()) {
+ setRefLogMessage(
+ getRefLogMessage() + ": " + desiredResult.toString(), //$NON-NLS-1$
+ false);
+ }
+
+ if (!addReftable(this::writeUpdate)) {
+ return Result.LOCK_FAILURE;
+ }
+
+ return desiredResult;
+ }
+
+ @Override
+ protected Result doDelete(Result desiredResult) throws IOException {
+
+ if (isRefLogIncludingResult()) {
+ setRefLogMessage(
+ getRefLogMessage() + ": " + desiredResult.toString(), //$NON-NLS-1$
+ false);
+ }
+
+ if (!addReftable(this::writeDelete)) {
+ return Result.LOCK_FAILURE;
+ }
+
+ return desiredResult;
+ }
+
+ void writeLink(ReftableWriter w) throws IOException {
+ long idx = reftableDatabase.nextUpdateIndex();
+ w.setMinUpdateIndex(idx).setMaxUpdateIndex(idx).begin()
+ .writeRef(dstRef);
+
+ ObjectId beforeId = ObjectId.zeroId();
+ Ref before = exactRef(dstRef.getName());
+ if (before != null) {
+ before = before.getLeaf();
+ if (before.getObjectId() != null) {
+ beforeId = before.getObjectId();
+ }
+ }
+
+ Ref after = dstRef.getLeaf();
+ ObjectId afterId = ObjectId.zeroId();
+ if (after.getObjectId() != null) {
+ afterId = after.getObjectId();
+ }
+
+ w.writeLog(dstRef.getName(), idx, getRefLogIdent(), beforeId,
+ afterId, getRefLogMessage());
+ }
+
+ @Override
+ protected Result doLink(String target) throws IOException {
+ if (isRefLogIncludingResult()) {
+ setRefLogMessage(
+ getRefLogMessage() + ": " + Result.FORCED.toString(), //$NON-NLS-1$
+ false);
+ }
+
+ boolean exists = exactRef(getName()) != null;
+ dstRef = new SymbolicRef(getName(),
+ new ObjectIdRef.Unpeeled(Ref.Storage.NEW, target, null),
+ reftableDatabase.nextUpdateIndex());
+
+ if (!addReftable(this::writeLink)) {
+ return Result.LOCK_FAILURE;
+ }
+ // XXX unclear if we should support FORCED here. Baseclass says
+ // NEW is OK ?
+ return exists ? Result.FORCED : Result.NEW;
+ }
+ }
+
+ private static void writeConvertTable(Repository repo, ReftableWriter w,
+ boolean writeLogs) throws IOException {
+ int size = 0;
+ List<Ref> refs = repo.getRefDatabase().getRefs();
+ if (writeLogs) {
+ for (Ref r : refs) {
+ ReflogReader rlr = repo.getReflogReader(r.getName());
+ if (rlr != null) {
+ size = Math.max(rlr.getReverseEntries().size(), size);
+ }
+ }
+ }
+ // We must use 1 here, nextUpdateIndex() on the empty stack is 1.
+ w.setMinUpdateIndex(1).setMaxUpdateIndex(size + 1).begin();
+
+ // The spec says to write the logs in the first table, and put refs in a
+ // separate table, but this complicates the compaction (when we can we drop
+ // deletions? Can we compact the .log table and the .ref table together?)
+ try (RevWalk rw = new RevWalk(repo)) {
+ List<Ref> toWrite = new ArrayList<>(refs.size());
+ for (Ref r : refs) {
+ toWrite.add(refForWrite(rw, r));
+ }
+ w.sortAndWriteRefs(toWrite);
+ }
+
+ if (writeLogs) {
+ for (Ref r : refs) {
+ long idx = size;
+ ReflogReader reader = repo.getReflogReader(r.getName());
+ if (reader == null) {
+ continue;
+ }
+ for (ReflogEntry e : reader.getReverseEntries()) {
+ w.writeLog(r.getName(), idx, e.getWho(), e.getOldId(),
+ e.getNewId(), e.getComment());
+ idx--;
+ }
+ }
+ }
+ }
+
+ private static Ref refForWrite(RevWalk rw, Ref r) throws IOException {
+ if (r.isSymbolic()) {
+ return new SymbolicRef(r.getName(), new ObjectIdRef.Unpeeled(NEW,
+ r.getTarget().getName(), null));
+ }
+ ObjectId newId = r.getObjectId();
+ RevObject peel = null;
+ try {
+ RevObject obj = rw.parseAny(newId);
+ if (obj instanceof RevTag) {
+ peel = rw.peel(obj);
+ }
+ } catch (MissingObjectException e) {
+ /* ignore this error and copy the dangling object ID into reftable too. */
+ }
+ if (peel != null) {
+ return new ObjectIdRef.PeeledTag(PACKED, r.getName(), newId,
+ peel.copy());
+ }
+
+ return new ObjectIdRef.PeeledNonTag(PACKED, r.getName(), newId);
+ }
+
+ /**
+ * @param repo
+ * the repository
+ * @param writeLogs
+ * whether to write reflogs
+ * @return a reftable based RefDB from an existing repository.
+ * @throws IOException
+ * on IO error
+ */
+ public static FileReftableDatabase convertFrom(FileRepository repo,
+ boolean writeLogs) throws IOException {
+ FileReftableDatabase newDb = null;
+ File reftableList = null;
+ try {
+ File reftableDir = new File(repo.getDirectory(),
+ Constants.REFTABLE);
+ reftableList = new File(reftableDir, Constants.TABLES_LIST);
+ if (!reftableDir.isDirectory()) {
+ reftableDir.mkdir();
+ }
+
+ try (FileReftableStack stack = new FileReftableStack(reftableList,
+ reftableDir, null, () -> repo.getConfig())) {
+ stack.addReftable(rw -> writeConvertTable(repo, rw, writeLogs));
+ }
+ reftableList = null;
+ } finally {
+ if (reftableList != null) {
+ reftableList.delete();
+ }
+ }
+ return newDb;
+ }
+}
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/FileReftableStack.java b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/FileReftableStack.java
new file mode 100644
index 0000000..68d82c2
--- /dev/null
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/FileReftableStack.java
@@ -0,0 +1,766 @@
+/*
+ * 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.internal.storage.file;
+
+import static java.nio.charset.StandardCharsets.UTF_8;
+
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.nio.file.Files;
+import java.nio.file.StandardCopyOption;
+import java.util.ArrayList;
+import java.util.Comparator;
+import java.util.List;
+import java.util.Map;
+import java.util.Optional;
+import java.util.function.Supplier;
+import java.util.stream.Collectors;
+
+import org.eclipse.jgit.annotations.Nullable;
+import org.eclipse.jgit.errors.LockFailedException;
+import org.eclipse.jgit.internal.storage.io.BlockSource;
+import org.eclipse.jgit.internal.storage.reftable.MergedReftable;
+import org.eclipse.jgit.internal.storage.reftable.ReftableCompactor;
+import org.eclipse.jgit.internal.storage.reftable.ReftableConfig;
+import org.eclipse.jgit.internal.storage.reftable.ReftableReader;
+import org.eclipse.jgit.internal.storage.reftable.ReftableWriter;
+import org.eclipse.jgit.lib.Config;
+import org.eclipse.jgit.util.FileUtils;
+
+/**
+ * A mutable stack of reftables on local filesystem storage. Not thread-safe.
+ * This is an AutoCloseable because this object owns the file handles to the
+ * open reftables.
+ */
+public class FileReftableStack implements AutoCloseable {
+ private static class StackEntry {
+
+ String name;
+
+ ReftableReader reftableReader;
+ }
+
+ private MergedReftable mergedReftable;
+
+ private List<StackEntry> stack;
+
+ private long lastNextUpdateIndex;
+
+ private final File stackPath;
+
+ private final File reftableDir;
+
+ private final Runnable onChange;
+
+ private final Supplier<Config> configSupplier;
+
+ // Used for stats & testing.
+ static class CompactionStats {
+
+ long tables;
+
+ long bytes;
+
+ int attempted;
+
+ int failed;
+
+ long refCount;
+
+ long logCount;
+
+ CompactionStats() {
+ tables = 0;
+ bytes = 0;
+ attempted = 0;
+ failed = 0;
+ logCount = 0;
+ refCount = 0;
+ }
+ }
+
+ private final CompactionStats stats;
+
+ /**
+ * Creates a stack corresponding to the list of reftables in the argument
+ *
+ * @param stackPath
+ * the filename for the stack.
+ * @param reftableDir
+ * the dir holding the tables.
+ * @param onChange
+ * hook to call if we notice a new write
+ * @param configSupplier
+ * Config supplier
+ * @throws IOException
+ * on I/O problems
+ */
+ public FileReftableStack(File stackPath, File reftableDir,
+ @Nullable Runnable onChange, Supplier<Config> configSupplier)
+ throws IOException {
+ this.stackPath = stackPath;
+ this.reftableDir = reftableDir;
+ this.stack = new ArrayList<>();
+ this.configSupplier = configSupplier;
+ this.onChange = onChange;
+
+ // skip event notification
+ lastNextUpdateIndex = 0;
+ reload();
+
+ stats = new CompactionStats();
+ }
+
+ CompactionStats getStats() {
+ return stats;
+ }
+
+ /** Thrown if the update indices in the stack are not monotonic */
+ public static class ReftableNumbersNotIncreasingException
+ extends RuntimeException {
+ private static final long serialVersionUID = 1L;
+
+ String name;
+
+ long lastMax;
+
+ long min;
+
+ ReftableNumbersNotIncreasingException(String name, long lastMax,
+ long min) {
+ this.name = name;
+ this.lastMax = lastMax;
+ this.min = min;
+ }
+ }
+
+ /**
+ * Reloads the stack, potentially reusing opened reftableReaders.
+ *
+ * @param names
+ * holds the names of the tables to load.
+ * @throws FileNotFoundException
+ * load must be retried.
+ * @throws IOException
+ * on other IO errors.
+ */
+ private void reloadOnce(List<String> names)
+ throws IOException, FileNotFoundException {
+ Map<String, ReftableReader> current = stack.stream()
+ .collect(Collectors.toMap(e -> e.name, e -> e.reftableReader));
+
+ List<ReftableReader> newTables = new ArrayList<>();
+ List<StackEntry> newStack = new ArrayList<>(stack.size() + 1);
+ try {
+ ReftableReader last = null;
+ for (String name : names) {
+ StackEntry entry = new StackEntry();
+ entry.name = name;
+
+ ReftableReader t = null;
+ if (current.containsKey(name)) {
+ t = current.remove(name);
+ } else {
+ File subtable = new File(reftableDir, name);
+ FileInputStream is;
+
+ is = new FileInputStream(subtable);
+
+ t = new ReftableReader(BlockSource.from(is));
+ newTables.add(t);
+ }
+
+ if (last != null) {
+ // TODO: move this to MergedReftable
+ if (last.maxUpdateIndex() >= t.minUpdateIndex()) {
+ throw new ReftableNumbersNotIncreasingException(name,
+ last.maxUpdateIndex(), t.minUpdateIndex());
+ }
+ }
+ last = t;
+
+ entry.reftableReader = t;
+ newStack.add(entry);
+ }
+ // survived without exceptions: swap in new stack, and close
+ // dangling tables.
+ stack = newStack;
+ newTables.clear();
+
+ current.values().forEach(r -> {
+ try {
+ r.close();
+ } catch (IOException e) {
+ throw new AssertionError(e);
+ }
+ });
+ } finally {
+ newTables.forEach(t -> {
+ try {
+ t.close();
+ } catch (IOException ioe) {
+ // reader close should not generate errors.
+ throw new AssertionError(ioe);
+ }
+ });
+ }
+ }
+
+ void reload() throws IOException {
+ // Try for 2.5 seconds.
+ long deadline = System.currentTimeMillis() + 2500;
+ // A successful reftable transaction is 2 atomic file writes
+ // (open, write, close, rename), which a fast Linux system should be
+ // able to do in about ~200us. So 1 ms should be ample time.
+ long min = 1;
+ long max = 1000;
+ long delay = 0;
+ boolean success = false;
+
+ // Don't check deadline for the first 3 retries, so we can step with a
+ // debugger without worrying about deadlines.
+ int tries = 0;
+ while (tries < 3 || System.currentTimeMillis() < deadline) {
+ List<String> names = readTableNames();
+ tries++;
+ try {
+ reloadOnce(names);
+ success = true;
+ break;
+ } catch (FileNotFoundException e) {
+ List<String> changed = readTableNames();
+ if (changed.equals(names)) {
+ throw e;
+ }
+ }
+
+ delay = FileUtils.delay(delay, min, max);
+ try {
+ Thread.sleep(delay);
+ } catch (InterruptedException e) {
+ Thread.currentThread().interrupt();
+ throw new RuntimeException(e);
+ }
+ }
+
+ if (!success) {
+ throw new LockFailedException(stackPath);
+ }
+
+ mergedReftable = new MergedReftable(stack.stream()
+ .map(x -> x.reftableReader).collect(Collectors.toList()));
+ long curr = nextUpdateIndex();
+ if (lastNextUpdateIndex > 0 && lastNextUpdateIndex != curr
+ && onChange != null) {
+ onChange.run();
+ }
+ lastNextUpdateIndex = curr;
+ }
+
+ /**
+ * @return the merged reftable
+ */
+ public MergedReftable getMergedReftable() {
+ return mergedReftable;
+ }
+
+ /**
+ * Writer is a callable that writes data to a reftable under construction.
+ * It should set the min/max update index, and then write refs and/or logs.
+ * It should not call finish() on the writer.
+ */
+ public interface Writer {
+ /**
+ * Write data to reftable
+ *
+ * @param w
+ * writer to use
+ * @throws IOException
+ */
+ void call(ReftableWriter w) throws IOException;
+ }
+
+ private List<String> readTableNames() throws IOException {
+ List<String> names = new ArrayList<>(stack.size() + 1);
+
+ try (BufferedReader br = new BufferedReader(
+ new InputStreamReader(new FileInputStream(stackPath), UTF_8))) {
+ String line;
+ while ((line = br.readLine()) != null) {
+ if (!line.isEmpty()) {
+ names.add(line);
+ }
+ }
+ } catch (FileNotFoundException e) {
+ // file isn't there: empty repository.
+ }
+ return names;
+ }
+
+ /**
+ * @return true if the on-disk file corresponds to the in-memory data.
+ * @throws IOException
+ * on IO problem
+ */
+ boolean isUpToDate() throws IOException {
+ // We could use FileSnapshot to avoid reading the file, but the file is
+ // small so it's probably a minor optimization.
+ try {
+ List<String> names = readTableNames();
+ if (names.size() != stack.size()) {
+ return false;
+ }
+ for (int i = 0; i < names.size(); i++) {
+ if (!names.get(i).equals(stack.get(i).name)) {
+ return false;
+ }
+ }
+ } catch (FileNotFoundException e) {
+ return stack.isEmpty();
+ }
+ return true;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public void close() {
+ for (StackEntry entry : stack) {
+ try {
+ entry.reftableReader.close();
+ } catch (Exception e) {
+ // we are reading; this should never fail.
+ throw new AssertionError(e);
+ }
+ }
+ }
+
+ private long nextUpdateIndex() throws IOException {
+ return stack.size() > 0
+ ? stack.get(stack.size() - 1).reftableReader.maxUpdateIndex()
+ + 1
+ : 1;
+ }
+
+ private String filename(long low, long high) {
+ return String.format("%012x-%012x", //$NON-NLS-1$
+ Long.valueOf(low), Long.valueOf(high));
+ }
+
+ /**
+ * Tries to add a new reftable to the stack. Returns true if it succeeded,
+ * or false if there was a lock failure, due to races with other processes.
+ * This is package private so FileReftableDatabase can call into here.
+ *
+ * @param w
+ * writer to write data to a reftable under construction
+ * @return true if the transaction was successful.
+ * @throws IOException
+ * on I/O problems
+ */
+ @SuppressWarnings("nls")
+ public boolean addReftable(Writer w) throws IOException {
+ LockFile lock = new LockFile(stackPath);
+ try {
+ if (!lock.lockForAppend()) {
+ return false;
+ }
+ if (!isUpToDate()) {
+ return false;
+ }
+
+ String fn = filename(nextUpdateIndex(), nextUpdateIndex());
+
+ File tmpTable = File.createTempFile(fn + "_", ".ref",
+ stackPath.getParentFile());
+
+ ReftableWriter.Stats s;
+ try (FileOutputStream fos = new FileOutputStream(tmpTable)) {
+ ReftableWriter rw = new ReftableWriter(reftableConfig(), fos);
+ w.call(rw);
+ rw.finish();
+ s = rw.getStats();
+ }
+
+ if (s.minUpdateIndex() < nextUpdateIndex()) {
+ return false;
+ }
+
+ // The spec says to name log-only files with .log, which is somewhat
+ // pointless given compaction, but we do so anyway.
+ fn += s.refCount() > 0 ? ".ref" : ".log";
+ File dest = new File(reftableDir, fn);
+
+ FileUtils.rename(tmpTable, dest, StandardCopyOption.ATOMIC_MOVE);
+ lock.write((fn + "\n").getBytes(UTF_8));
+ if (!lock.commit()) {
+ FileUtils.delete(dest);
+ return false;
+ }
+
+ reload();
+
+ autoCompact();
+ } finally {
+ lock.unlock();
+ }
+ return true;
+ }
+
+ private ReftableConfig reftableConfig() {
+ return new ReftableConfig(configSupplier.get());
+ }
+
+ /**
+ * Write the reftable for the given range into a temp file.
+ *
+ * @param first
+ * index of first stack entry to be written
+ * @param last
+ * index of last stack entry to be written
+ * @return the file holding the replacement table.
+ * @throws IOException
+ * on I/O problem
+ */
+ private File compactLocked(int first, int last) throws IOException {
+ String fn = filename(first, last);
+
+ File tmpTable = File.createTempFile(fn + "_", ".ref", //$NON-NLS-1$//$NON-NLS-2$
+ stackPath.getParentFile());
+ try (FileOutputStream fos = new FileOutputStream(tmpTable)) {
+ ReftableCompactor c = new ReftableCompactor(fos)
+ .setConfig(reftableConfig())
+ .setIncludeDeletes(first > 0);
+
+ List<ReftableReader> compactMe = new ArrayList<>();
+ long totalBytes = 0;
+ for (int i = first; i <= last; i++) {
+ compactMe.add(stack.get(i).reftableReader);
+ totalBytes += stack.get(i).reftableReader.size();
+ }
+ c.addAll(compactMe);
+
+ c.compact();
+
+ // Even though the compaction did not definitely succeed, we keep
+ // tally here as we've expended the effort.
+ stats.bytes += totalBytes;
+ stats.tables += first - last + 1;
+ stats.attempted++;
+ stats.refCount += c.getStats().refCount();
+ stats.logCount += c.getStats().logCount();
+ }
+
+ return tmpTable;
+ }
+
+ /**
+ * Compacts a range of the stack, following the file locking protocol
+ * documented in the spec.
+ *
+ * @param first
+ * index of first stack entry to be considered in compaction
+ * @param last
+ * index of last stack entry to be considered in compaction
+ * @return true if a compaction was successfully applied.
+ * @throws IOException
+ * on I/O problem
+ */
+ boolean compactRange(int first, int last) throws IOException {
+ if (first >= last) {
+ return true;
+ }
+ LockFile lock = new LockFile(stackPath);
+
+ File tmpTable = null;
+ List<LockFile> subtableLocks = new ArrayList<>();
+
+ try {
+ if (!lock.lock()) {
+ return false;
+ }
+ if (!isUpToDate()) {
+ return false;
+ }
+
+ List<File> deleteOnSuccess = new ArrayList<>();
+ for (int i = first; i <= last; i++) {
+ File f = new File(reftableDir, stack.get(i).name);
+ LockFile lf = new LockFile(f);
+ if (!lf.lock()) {
+ return false;
+ }
+ subtableLocks.add(lf);
+ deleteOnSuccess.add(f);
+ }
+
+ lock.unlock();
+ lock = null;
+
+ tmpTable = compactLocked(first, last);
+
+ lock = new LockFile(stackPath);
+ if (!lock.lock()) {
+ return false;
+ }
+ if (!isUpToDate()) {
+ return false;
+ }
+
+ String fn = filename(
+ stack.get(first).reftableReader.minUpdateIndex(),
+ stack.get(last).reftableReader.maxUpdateIndex());
+
+ // The spec suggests to use .log for log-only tables, and collect
+ // all log entries in a single file at the bottom of the stack. That would
+ // require supporting overlapping ranges for the different tables. For the
+ // sake of simplicity, we simply ignore this and always produce a log +
+ // ref combined table.
+ fn += ".ref"; //$NON-NLS-1$
+ File dest = new File(reftableDir, fn);
+
+ FileUtils.rename(tmpTable, dest, StandardCopyOption.ATOMIC_MOVE);
+ tmpTable = null;
+
+ StringBuilder sb = new StringBuilder();
+
+ for (int i = 0; i < first; i++) {
+ sb.append(stack.get(i).name + "\n"); //$NON-NLS-1$
+ }
+ sb.append(fn + "\n"); //$NON-NLS-1$
+ for (int i = last + 1; i < stack.size(); i++) {
+ sb.append(stack.get(i).name + "\n"); //$NON-NLS-1$
+ }
+
+ lock.write(sb.toString().getBytes(UTF_8));
+ if (!lock.commit()) {
+ dest.delete();
+ return false;
+ }
+
+ for (File f : deleteOnSuccess) {
+ Files.delete(f.toPath());
+ }
+
+ reload();
+ return true;
+ } finally {
+ if (tmpTable != null) {
+ tmpTable.delete();
+ }
+ for (LockFile lf : subtableLocks) {
+ lf.unlock();
+ }
+ if (lock != null) {
+ lock.unlock();
+ }
+ }
+ }
+
+ /**
+ * Calculate an approximate log2.
+ *
+ * @param sz
+ * @return log2
+ */
+ static int log(long sz) {
+ long base = 2;
+ if (sz <= 0) {
+ throw new IllegalArgumentException("log2 negative"); //$NON-NLS-1$
+ }
+ int l = 0;
+ while (sz > 0) {
+ l++;
+ sz /= base;
+ }
+
+ return l - 1;
+ }
+
+ /**
+ * A segment is a consecutive list of reftables of the same approximate
+ * size.
+ */
+ static class Segment {
+ // the approximate log_2 of the size.
+ int log;
+
+ // The total bytes in this segment
+ long bytes;
+
+ int start;
+
+ int end; // exclusive.
+
+ int size() {
+ return end - start;
+ }
+
+ Segment(int start, int end, int log, long bytes) {
+ this.log = log;
+ this.start = start;
+ this.end = end;
+ this.bytes = bytes;
+ }
+
+ Segment() {
+ this(0, 0, 0, 0);
+ }
+
+ @Override
+ public int hashCode() {
+ return 0; // appease error-prone
+ }
+
+ @Override
+ public boolean equals(Object other) {
+ Segment o = (Segment) other;
+ return o.bytes == bytes && o.log == log && o.start == start
+ && o.end == end;
+ }
+
+ @SuppressWarnings("boxing")
+ @Override
+ public String toString() {
+ return String.format("{ [%d,%d) l=%d sz=%d }", start, end, log, //$NON-NLS-1$
+ bytes);
+ }
+ }
+
+ static List<Segment> segmentSizes(long[] sizes) {
+ List<Segment> segments = new ArrayList<>();
+ Segment cur = new Segment();
+ for (int i = 0; i < sizes.length; i++) {
+ int l = log(sizes[i]);
+ if (l != cur.log && cur.bytes > 0) {
+ segments.add(cur);
+ cur = new Segment();
+ cur.start = i;
+ cur.log = l;
+ }
+
+ cur.log = l;
+ cur.end = i + 1;
+ cur.bytes += sizes[i];
+ }
+ segments.add(cur);
+ return segments;
+ }
+
+ private static Optional<Segment> autoCompactCandidate(long[] sizes) {
+ if (sizes.length == 0) {
+ return Optional.empty();
+ }
+
+ // The cost of compaction is proportional to the size, and we want to
+ // avoid frequent large compactions. We do this by playing the game 2048
+ // here: first compact together the smallest tables if there are more
+ // than one. Then try to see if the result will be big enough to match
+ // up with next up.
+
+ List<Segment> segments = segmentSizes(sizes);
+ segments = segments.stream().filter(s -> s.size() > 1)
+ .collect(Collectors.toList());
+ if (segments.isEmpty()) {
+ return Optional.empty();
+ }
+
+ Optional<Segment> optMinSeg = segments.stream()
+ .min(Comparator.comparing(s -> Integer.valueOf(s.log)));
+ // Input is non-empty, so always present.
+ Segment smallCollected = optMinSeg.get();
+ while (smallCollected.start > 0) {
+ int prev = smallCollected.start - 1;
+ long prevSize = sizes[prev];
+ if (log(smallCollected.bytes) < log(prevSize)) {
+ break;
+ }
+ smallCollected.start = prev;
+ smallCollected.bytes += prevSize;
+ }
+
+ return Optional.of(smallCollected);
+ }
+
+ /**
+ * Heuristically tries to compact the stack if the stack has a suitable
+ * shape.
+ *
+ * @throws IOException
+ */
+ private void autoCompact() throws IOException {
+ Optional<Segment> cand = autoCompactCandidate(tableSizes());
+ if (cand.isPresent()) {
+ if (!compactRange(cand.get().start, cand.get().end - 1)) {
+ stats.failed++;
+ }
+ }
+ }
+
+ // 68b footer, 24b header = 92.
+ private static long OVERHEAD = 91;
+
+ private long[] tableSizes() throws IOException {
+ long[] sizes = new long[stack.size()];
+ for (int i = 0; i < stack.size(); i++) {
+ // If we don't subtract the overhead, the file size isn't
+ // proportional to the number of entries. This will cause us to
+ // compact too often, which is expensive.
+ sizes[i] = stack.get(i).reftableReader.size() - OVERHEAD;
+ }
+ return sizes;
+ }
+
+ void compactFully() throws IOException {
+ if (!compactRange(0, stack.size() - 1)) {
+ stats.failed++;
+ }
+ }
+}
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/FileRepository.java b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/FileRepository.java
index 4f5f8a6..9929c46 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/FileRepository.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/FileRepository.java
@@ -46,13 +46,20 @@
package org.eclipse.jgit.internal.storage.file;
+import static java.util.stream.Collectors.toList;
+
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
import java.io.IOException;
+import java.io.OutputStream;
import java.text.MessageFormat;
import java.text.ParseException;
+import java.util.ArrayList;
+import java.util.Collections;
import java.util.HashSet;
+import java.util.List;
import java.util.Locale;
import java.util.Objects;
import java.util.Set;
@@ -68,21 +75,26 @@
import org.eclipse.jgit.internal.storage.file.ObjectDirectory.AlternateRepository;
import org.eclipse.jgit.internal.storage.reftree.RefTreeDatabase;
import org.eclipse.jgit.lib.BaseRepositoryBuilder;
+import org.eclipse.jgit.lib.BatchRefUpdate;
import org.eclipse.jgit.lib.ConfigConstants;
import org.eclipse.jgit.lib.Constants;
import org.eclipse.jgit.lib.CoreConfig.HideDotFiles;
import org.eclipse.jgit.lib.CoreConfig.SymLinks;
+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.RefDatabase;
import org.eclipse.jgit.lib.RefUpdate;
+import org.eclipse.jgit.lib.ReflogEntry;
import org.eclipse.jgit.lib.ReflogReader;
import org.eclipse.jgit.lib.Repository;
import org.eclipse.jgit.lib.StoredConfig;
+import org.eclipse.jgit.revwalk.RevWalk;
import org.eclipse.jgit.storage.file.FileBasedConfig;
import org.eclipse.jgit.storage.file.FileRepositoryBuilder;
import org.eclipse.jgit.storage.pack.PackConfig;
+import org.eclipse.jgit.transport.ReceiveCommand;
import org.eclipse.jgit.util.FileUtils;
import org.eclipse.jgit.util.IO;
import org.eclipse.jgit.util.RawParseUtils;
@@ -121,7 +133,7 @@ public class FileRepository extends Repository {
private static final String UNNAMED = "Unnamed repository; edit this file to name it for gitweb."; //$NON-NLS-1$
private final FileBasedConfig repoConfig;
- private final RefDatabase refs;
+ private RefDatabase refs;
private final ObjectDirectory objectDatabase;
private final Object snapshotLock = new Object();
@@ -197,9 +209,13 @@ public FileRepository(BaseRepositoryBuilder options) throws IOException {
ConfigConstants.CONFIG_KEY_REPO_FORMAT_VERSION, 0);
String reftype = repoConfig.getString(
- "extensions", null, "refStorage"); //$NON-NLS-1$ //$NON-NLS-2$
+ ConfigConstants.CONFIG_EXTENSIONS_SECTION, null,
+ ConfigConstants.CONFIG_KEY_REF_STORAGE);
if (repositoryFormatVersion >= 1 && reftype != null) {
- if (StringUtils.equalsIgnoreCase(reftype, "reftree")) { //$NON-NLS-1$
+ if (StringUtils.equalsIgnoreCase(reftype,
+ ConfigConstants.CONFIG_REF_STORAGE_REFTABLE)) {
+ refs = new FileReftableDatabase(this);
+ } else if (StringUtils.equalsIgnoreCase(reftype, "reftree")) { //$NON-NLS-1$
refs = new RefTreeDatabase(this, new RefDirectory(this));
} else {
throw new IOException(JGitText.get().unknownRepositoryFormat);
@@ -358,9 +374,8 @@ public String getIdentifier() {
File directory = getDirectory();
if (directory != null) {
return directory.getPath();
- } else {
- throw new IllegalStateException();
}
+ throw new IllegalStateException();
}
/** {@inheritDoc} */
@@ -531,10 +546,19 @@ public void notifyIndexChanged(boolean internal) {
/** {@inheritDoc} */
@Override
public ReflogReader getReflogReader(String refName) throws IOException {
+ if (refs instanceof FileReftableDatabase) {
+ // Cannot use findRef: reftable stores log data for deleted or renamed
+ // branches.
+ return ((FileReftableDatabase)refs).getReflogReader(refName);
+ }
+
+ // TODO: use exactRef here, which offers more predictable and therefore preferable
+ // behavior.
Ref ref = findRef(refName);
- if (ref != null)
- return new ReflogReaderImpl(this, ref.getName());
- return null;
+ if (ref == null) {
+ return null;
+ }
+ return new ReflogReaderImpl(this, ref.getName());
}
/** {@inheritDoc} */
@@ -614,4 +638,218 @@ public void autoGC(ProgressMonitor monitor) {
throw new JGitInternalException(JGitText.get().gcFailed, e);
}
}
+
+ /**
+ * Converts the RefDatabase from reftable to RefDirectory. This operation is
+ * not atomic.
+ *
+ * @param writeLogs
+ * whether to write reflogs
+ * @param backup
+ * whether to rename or delete the old storage files. If set to
+ * {@code true}, the reftable list is left in {@code refs.old},
+ * and the {@code reftable/} dir is left alone. If set to
+ * {@code false}, the {@code reftable/} dir is removed, and
+ * {@code refs} file is removed.
+ * @throws IOException
+ * on IO problem
+ */
+ void convertToPackedRefs(boolean writeLogs, boolean backup) throws IOException {
+ List<Ref> all = refs.getRefs();
+ File packedRefs = new File(getDirectory(), Constants.PACKED_REFS);
+ if (packedRefs.exists()) {
+ throw new IOException(MessageFormat.format(JGitText.get().fileAlreadyExists,
+ packedRefs.getName()));
+ }
+
+ File refsFile = new File(getDirectory(), "refs"); //$NON-NLS-1$
+ File refsHeadsFile = new File(refsFile, "heads");//$NON-NLS-1$
+ File headFile = new File(getDirectory(), Constants.HEAD);
+ FileReftableDatabase oldDb = (FileReftableDatabase) refs;
+
+ // Remove the dummy files that ensure compatibility with older git
+ // versions (see convertToReftable). First make room for refs/heads/
+ refsHeadsFile.delete();
+ // RefDirectory wants to create the refs/ directory from scratch, so
+ // remove that too.
+ refsFile.delete();
+ // remove HEAD so its previous invalid value doesn't cause issues.
+ headFile.delete();
+
+ // This is not atomic, but there is no way to instantiate a RefDirectory
+ // that is disconnected from the current repo.
+ RefDirectory refDir = new RefDirectory(this);
+ refs = refDir;
+ refs.create();
+
+ ReflogWriter logWriter = refDir.newLogWriter(true);
+ List<Ref> symrefs = new ArrayList<>();
+ BatchRefUpdate bru = refs.newBatchUpdate();
+ for (Ref r : all) {
+ if (r.isSymbolic()) {
+ symrefs.add(r);
+ } else {
+ bru.addCommand(new ReceiveCommand(ObjectId.zeroId(),
+ r.getObjectId(), r.getName()));
+ }
+
+ if (writeLogs) {
+ List<ReflogEntry> logs = oldDb.getReflogReader(r.getName())
+ .getReverseEntries();
+ Collections.reverse(logs);
+ for (ReflogEntry e : logs) {
+ logWriter.log(r.getName(), e);
+ }
+ }
+ }
+
+ try (RevWalk rw = new RevWalk(this)) {
+ bru.execute(rw, NullProgressMonitor.INSTANCE);
+ }
+
+ List<String> failed = new ArrayList<>();
+ for (ReceiveCommand cmd : bru.getCommands()) {
+ if (cmd.getResult() != ReceiveCommand.Result.OK) {
+ failed.add(cmd.getRefName() + ": " + cmd.getResult()); //$NON-NLS-1$
+ }
+ }
+
+ if (!failed.isEmpty()) {
+ throw new IOException(String.format("%s: %s", //$NON-NLS-1$
+ JGitText.get().failedToConvert,
+ StringUtils.join(failed, ", "))); //$NON-NLS-1$
+ }
+
+ for (Ref s : symrefs) {
+ RefUpdate up = refs.newUpdate(s.getName(), false);
+ up.setForceUpdate(true);
+ RefUpdate.Result res = up.link(s.getTarget().getName());
+ if (res != RefUpdate.Result.NEW
+ && res != RefUpdate.Result.NO_CHANGE) {
+ throw new IOException(
+ String.format("ref %s: %s", s.getName(), res)); //$NON-NLS-1$
+ }
+ }
+
+ if (!backup) {
+ File reftableDir = new File(getDirectory(), Constants.REFTABLE);
+ FileUtils.delete(reftableDir,
+ FileUtils.RECURSIVE | FileUtils.IGNORE_ERRORS);
+ }
+ repoConfig.unset(ConfigConstants.CONFIG_EXTENSIONS_SECTION, null,
+ ConfigConstants.CONFIG_KEY_REF_STORAGE);
+ }
+
+ /**
+ * Converts the RefDatabase from RefDirectory to reftable. This operation is
+ * not atomic.
+ *
+ * @param writeLogs
+ * whether to write reflogs
+ * @param backup
+ * whether to rename or delete the old storage files. If set to
+ * {@code true}, the loose refs are left in {@code refs.old}, the
+ * packed-refs in {@code packed-refs.old} and reflogs in
+ * {@code refs.old/}. HEAD is left in {@code HEAD.old} and also
+ * {@code .log} is appended to additional refs. If set to
+ * {@code false}, the {@code refs/} and {@code logs/} directories
+ * and {@code HEAD} and additional symbolic refs are removed.
+ * @throws IOException
+ * on IO problem
+ */
+ @SuppressWarnings("nls")
+ void convertToReftable(boolean writeLogs, boolean backup)
+ throws IOException {
+ File reftableDir = new File(getDirectory(), Constants.REFTABLE);
+ File headFile = new File(getDirectory(), Constants.HEAD);
+ if (reftableDir.exists() && reftableDir.listFiles().length > 0) {
+ throw new IOException(JGitText.get().reftableDirExists);
+ }
+
+ // Ignore return value, as it is tied to temporary newRefs file.
+ FileReftableDatabase.convertFrom(this, writeLogs);
+
+ File refsFile = new File(getDirectory(), "refs");
+
+ // non-atomic: remove old data.
+ File packedRefs = new File(getDirectory(), Constants.PACKED_REFS);
+ File logsDir = new File(getDirectory(), Constants.LOGS);
+
+ List<String> additional = getRefDatabase().getAdditionalRefs().stream()
+ .map(Ref::getName).collect(toList());
+ additional.add(Constants.HEAD);
+ if (backup) {
+ FileUtils.rename(refsFile, new File(getDirectory(), "refs.old"));
+ if (packedRefs.exists()) {
+ FileUtils.rename(packedRefs, new File(getDirectory(),
+ Constants.PACKED_REFS + ".old"));
+ }
+ if (logsDir.exists()) {
+ FileUtils.rename(logsDir,
+ new File(getDirectory(), Constants.LOGS + ".old"));
+ }
+ for (String r : additional) {
+ FileUtils.rename(new File(getDirectory(), r),
+ new File(getDirectory(), r + ".old"));
+ }
+ } else {
+ FileUtils.delete(packedRefs, FileUtils.SKIP_MISSING);
+ FileUtils.delete(headFile);
+ FileUtils.delete(logsDir, FileUtils.RECURSIVE);
+ FileUtils.delete(refsFile, FileUtils.RECURSIVE);
+ for (String r : additional) {
+ new File(getDirectory(), r).delete();
+ }
+ }
+
+ FileUtils.mkdir(refsFile, true);
+
+ // By putting in a dummy HEAD, old versions of Git still detect a repo
+ // (that they can't read)
+ try (OutputStream os = new FileOutputStream(headFile)) {
+ os.write(Constants.encodeASCII("ref: refs/heads/.invalid"));
+ }
+
+ // Some tools might write directly into .git/refs/heads/BRANCH. By
+ // putting a file here, this fails spectacularly.
+ FileUtils.createNewFile(new File(refsFile, "heads"));
+
+ repoConfig.setString(ConfigConstants.CONFIG_EXTENSIONS_SECTION, null,
+ ConfigConstants.CONFIG_KEY_REF_STORAGE,
+ ConfigConstants.CONFIG_REF_STORAGE_REFTABLE);
+ repoConfig.setLong(ConfigConstants.CONFIG_CORE_SECTION, null,
+ ConfigConstants.CONFIG_KEY_REPO_FORMAT_VERSION, 1);
+ repoConfig.save();
+ refs.close();
+ refs = new FileReftableDatabase(this);
+ }
+
+ /**
+ * Converts between ref storage formats.
+ *
+ * @param format
+ * the format to convert to, either "reftable" or "refdir"
+ * @param writeLogs
+ * whether to write reflogs
+ * @param backup
+ * whether to make a backup of the old data
+ * @throws IOException
+ * on I/O problems.
+ */
+ @SuppressWarnings("nls")
+ public void convertRefStorage(String format, boolean writeLogs,
+ boolean backup) throws IOException {
+ if (format.equals("reftable")) { //$NON-NLS-1$
+ if (refs instanceof RefDirectory) {
+ convertToReftable(writeLogs, backup);
+ }
+ } else if (format.equals("refdir")) {//$NON-NLS-1$
+ if (refs instanceof FileReftableDatabase) {
+ convertToPackedRefs(writeLogs, backup);
+ }
+ } else {
+ throw new IOException(String.format(
+ "unknown supported ref storage format '%s'", format));
+ }
+ }
}
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/GC.java b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/GC.java
index 0ff3f61..5edcf37 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/GC.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/GC.java
@@ -131,7 +131,7 @@
* adapted to FileRepositories.
*/
public class GC {
- private final static Logger LOG = LoggerFactory
+ private static final Logger LOG = LoggerFactory
.getLogger(GC.class);
private static final String PRUNE_EXPIRE_DEFAULT = "2.weeks.ago"; //$NON-NLS-1$
@@ -773,13 +773,26 @@ private static boolean equals(Ref r1, Ref r2) {
}
/**
- * Packs all non-symbolic, loose refs into packed-refs.
+ * Pack ref storage. For a RefDirectory database, this packs all
+ * non-symbolic, loose refs into packed-refs. For Reftable, all of the data
+ * is compacted into a single table.
*
* @throws java.io.IOException
*/
public void packRefs() throws IOException {
- Collection<Ref> refs = repo.getRefDatabase()
- .getRefsByPrefix(Constants.R_REFS);
+ RefDatabase refDb = repo.getRefDatabase();
+ if (refDb instanceof FileReftableDatabase) {
+ // TODO: abstract this more cleanly.
+ pm.beginTask(JGitText.get().packRefs, 1);
+ try {
+ ((FileReftableDatabase) refDb).compactFully();
+ } finally {
+ pm.endTask();
+ }
+ return;
+ }
+
+ Collection<Ref> refs = refDb.getRefsByPrefix(Constants.R_REFS);
List<String> refsToBePacked = new ArrayList<>(refs.size());
pm.beginTask(JGitText.get().packRefs, refs.size());
try {
@@ -897,7 +910,10 @@ public Collection<PackFile> repack() throws IOException {
throw new IOException(e);
}
prunePacked();
- deleteEmptyRefsFolders();
+ if (repo.getRefDatabase() instanceof RefDirectory) {
+ // TODO: abstract this more cleanly.
+ deleteEmptyRefsFolders();
+ }
deleteOrphans();
deleteTempPacksIdx();
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/GcLog.java b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/GcLog.java
index 82458c1..13b9e79 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/GcLog.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/GcLog.java
@@ -152,11 +152,10 @@ void unlock() {
boolean commit() {
if (nonEmpty) {
return lock.commit();
- } else {
- logFile.delete();
- lock.unlock();
- return true;
}
+ logFile.delete();
+ lock.unlock();
+ return true;
}
/**
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/LockFile.java b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/LockFile.java
index 6af4125..78262e9 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/LockFile.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/LockFile.java
@@ -1,45 +1,12 @@
/*
* Copyright (C) 2007, Robin Rosenberg <robin.rosenberg@dewire.com>
- * Copyright (C) 2006-2008, Shawn O. Pearce <spearce@spearce.org>
- * and other copyright owners as documented in the project's IP log.
+ * Copyright (C) 2006-2021, Shawn O. Pearce <spearce@spearce.org> and others
*
- * This program and the accompanying materials are made available
- * under the terms of the Eclipse Distribution License v1.0 which
- * accompanies this distribution, is reproduced below, and is
- * available at http://www.eclipse.org/org/documents/edl-v10.php
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Distribution License v. 1.0 which is available at
+ * https://www.eclipse.org/org/documents/edl-v10.php.
*
- * 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.
+ * SPDX-License-Identifier: BSD-3-Clause
*/
package org.eclipse.jgit.internal.storage.file;
@@ -83,7 +50,7 @@
* name.
*/
public class LockFile {
- private final static Logger LOG = LoggerFactory.getLogger(LockFile.class);
+ private static final Logger LOG = LoggerFactory.getLogger(LockFile.class);
/**
* Unlock the given file.
@@ -129,11 +96,15 @@ static File getLockFile(File file) {
private boolean haveLck;
- FileOutputStream os;
+ private FileOutputStream os;
private boolean needSnapshot;
- boolean fsync;
+ private boolean fsync;
+
+ private boolean isAppend;
+
+ private boolean written;
private FileSnapshot commitSnapshot;
@@ -160,6 +131,10 @@ public LockFile(File f) {
* does not hold the lock.
*/
public boolean lock() throws IOException {
+ if (haveLck) {
+ throw new IllegalStateException(
+ MessageFormat.format(JGitText.get().lockAlreadyHeld, ref));
+ }
FileUtils.mkdirs(lck.getParentFile(), true);
try {
token = FS.DETECTED.createNewFileAtomic(lck);
@@ -167,18 +142,15 @@ public boolean lock() throws IOException {
LOG.error(JGitText.get().failedCreateLockFile, lck, e);
throw e;
}
- if (token.isCreated()) {
+ boolean obtainedLock = token.isCreated();
+ if (obtainedLock) {
haveLck = true;
- try {
- os = new FileOutputStream(lck);
- } catch (IOException ioe) {
- unlock();
- throw ioe;
- }
+ isAppend = false;
+ written = false;
} else {
closeToken();
}
- return haveLck;
+ return obtainedLock;
}
/**
@@ -191,12 +163,24 @@ public boolean lock() throws IOException {
* does not hold the lock.
*/
public boolean lockForAppend() throws IOException {
- if (!lock())
+ if (!lock()) {
return false;
+ }
copyCurrentContent();
+ isAppend = true;
+ written = false;
return true;
}
+ // For tests only
+ boolean isLocked() {
+ return haveLck;
+ }
+
+ private FileOutputStream getStream() throws IOException {
+ return new FileOutputStream(lck, isAppend);
+ }
+
/**
* Copy the current file content into the temporary file.
* <p>
@@ -218,32 +202,31 @@ public boolean lockForAppend() throws IOException {
*/
public void copyCurrentContent() throws IOException {
requireLock();
- try {
+ try (FileOutputStream out = getStream()) {
try (FileInputStream fis = new FileInputStream(ref)) {
if (fsync) {
FileChannel in = fis.getChannel();
long pos = 0;
long cnt = in.size();
while (0 < cnt) {
- long r = os.getChannel().transferFrom(in, pos, cnt);
+ long r = out.getChannel().transferFrom(in, pos, cnt);
pos += r;
cnt -= r;
}
} else {
final byte[] buf = new byte[2048];
int r;
- while ((r = fis.read(buf)) >= 0)
- os.write(buf, 0, r);
+ while ((r = fis.read(buf)) >= 0) {
+ out.write(buf, 0, r);
+ }
}
+ } catch (FileNotFoundException fnfe) {
+ if (ref.exists()) {
+ throw fnfe;
+ }
+ // Don't worry about a file that doesn't exist yet, it
+ // conceptually has no current content to copy.
}
- } catch (FileNotFoundException fnfe) {
- if (ref.exists()) {
- unlock();
- throw fnfe;
- }
- // Don't worry about a file that doesn't exist yet, it
- // conceptually has no current content to copy.
- //
} catch (IOException | RuntimeException | Error ioe) {
unlock();
throw ioe;
@@ -286,18 +269,22 @@ public void write(ObjectId id) throws IOException {
*/
public void write(byte[] content) throws IOException {
requireLock();
- try {
+ try (FileOutputStream out = getStream()) {
+ if (written) {
+ throw new IOException(MessageFormat
+ .format(JGitText.get().lockStreamClosed, ref));
+ }
if (fsync) {
- FileChannel fc = os.getChannel();
+ FileChannel fc = out.getChannel();
ByteBuffer buf = ByteBuffer.wrap(content);
- while (0 < buf.remaining())
+ while (0 < buf.remaining()) {
fc.write(buf);
+ }
fc.force(true);
} else {
- os.write(content);
+ out.write(content);
}
- os.close();
- os = null;
+ written = true;
} catch (IOException | RuntimeException | Error ioe) {
unlock();
throw ioe;
@@ -316,36 +303,67 @@ public void write(byte[] content) throws IOException {
public OutputStream getOutputStream() {
requireLock();
- final OutputStream out;
- if (fsync)
- out = Channels.newOutputStream(os.getChannel());
- else
- out = os;
+ if (written || os != null) {
+ throw new IllegalStateException(MessageFormat
+ .format(JGitText.get().lockStreamMultiple, ref));
+ }
return new OutputStream() {
+
+ private OutputStream out;
+
+ private boolean closed;
+
+ private OutputStream get() throws IOException {
+ if (written) {
+ throw new IOException(MessageFormat
+ .format(JGitText.get().lockStreamMultiple, ref));
+ }
+ if (out == null) {
+ os = getStream();
+ if (fsync) {
+ out = Channels.newOutputStream(os.getChannel());
+ } else {
+ out = os;
+ }
+ }
+ return out;
+ }
+
@Override
- public void write(byte[] b, int o, int n)
- throws IOException {
- out.write(b, o, n);
+ public void write(byte[] b, int o, int n) throws IOException {
+ get().write(b, o, n);
}
@Override
public void write(byte[] b) throws IOException {
- out.write(b);
+ get().write(b);
}
@Override
public void write(int b) throws IOException {
- out.write(b);
+ get().write(b);
}
@Override
public void close() throws IOException {
+ if (closed) {
+ return;
+ }
+ closed = true;
try {
- if (fsync)
- os.getChannel().force(true);
- out.close();
- os = null;
+ if (written) {
+ throw new IOException(MessageFormat
+ .format(JGitText.get().lockStreamClosed, ref));
+ }
+ if (out != null) {
+ if (fsync) {
+ os.getChannel().force(true);
+ }
+ out.close();
+ os = null;
+ }
+ written = true;
} catch (IOException | RuntimeException | Error ioe) {
unlock();
throw ioe;
@@ -355,7 +373,7 @@ public void close() throws IOException {
}
void requireLock() {
- if (os == null) {
+ if (!haveLck) {
unlock();
throw new IllegalStateException(MessageFormat.format(JGitText.get().lockOnNotHeld, ref));
}
@@ -444,6 +462,8 @@ public boolean commit() {
try {
FileUtils.rename(lck, ref, StandardCopyOption.ATOMIC_MOVE);
haveLck = false;
+ isAppend = false;
+ written = false;
closeToken();
return true;
} catch (IOException e) {
@@ -530,6 +550,8 @@ public void unlock() {
closeToken();
}
}
+ isAppend = false;
+ written = false;
}
/** {@inheritDoc} */
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/ObjectDirectory.java b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/ObjectDirectory.java
index 968ade6..b4cad35 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/ObjectDirectory.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/ObjectDirectory.java
@@ -109,7 +109,7 @@
* considered.
*/
public class ObjectDirectory extends FileObjectDatabase {
- private final static Logger LOG = LoggerFactory
+ private static final Logger LOG = LoggerFactory
.getLogger(ObjectDirectory.class);
private static final PackList NO_PACKS = new PackList(
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/ObjectDirectoryInserter.java b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/ObjectDirectoryInserter.java
index e5a54e3..09f2021 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/ObjectDirectoryInserter.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/ObjectDirectoryInserter.java
@@ -109,10 +109,9 @@ private ObjectId insert(
ObjectId id = idFor(type, data, off, len);
if (!createDuplicate && db.has(id)) {
return id;
- } else {
- File tmp = toTemp(type, data, off, len);
- return insertOneObject(tmp, id, createDuplicate);
}
+ File tmp = toTemp(type, data, off, len);
+ return insertOneObject(tmp, id, createDuplicate);
}
/** {@inheritDoc} */
@@ -141,12 +140,11 @@ ObjectId insert(int type, long len, InputStream is, boolean createDuplicate)
int actLen = IO.readFully(is, buf, 0);
return insert(type, buf, 0, actLen, createDuplicate);
- } else {
- SHA1 md = digest();
- File tmp = toTemp(md, type, len, is);
- ObjectId id = md.toObjectId();
- return insertOneObject(tmp, id, createDuplicate);
}
+ SHA1 md = digest();
+ File tmp = toTemp(md, type, len, is);
+ ObjectId id = md.toObjectId();
+ return insertOneObject(tmp, id, createDuplicate);
}
private ObjectId insertOneObject(
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/PackFile.java b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/PackFile.java
index 86e90c6..e7d917b 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/PackFile.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/PackFile.java
@@ -103,7 +103,7 @@
* objects are similar.
*/
public class PackFile implements Iterable<PackIndex.MutableEntry> {
- private final static Logger LOG = LoggerFactory.getLogger(PackFile.class);
+ private static final Logger LOG = LoggerFactory.getLogger(PackFile.class);
/** Sorts PackFiles to be most recently created to least recently created. */
public static final Comparator<PackFile> SORT = new Comparator<PackFile>() {
@Override
@@ -845,19 +845,20 @@ ObjectLoader load(WindowCursor curs, long pos)
case Constants.OBJ_TREE:
case Constants.OBJ_BLOB:
case Constants.OBJ_TAG: {
- if (delta != null || sz < curs.getStreamFileThreshold())
+ if (delta != null || sz < curs.getStreamFileThreshold()) {
data = decompress(pos + p, (int) sz, curs);
+ }
if (delta != null) {
type = typeCode;
break SEARCH;
}
- if (data != null)
+ if (data != null) {
return new ObjectLoader.SmallObject(typeCode, data);
- else
- return new LargePackedWholeObject(typeCode, sz, pos, p,
- this, curs.db);
+ }
+ return new LargePackedWholeObject(typeCode, sz, pos, p,
+ this, curs.db);
}
case Constants.OBJ_OFS_DELTA: {
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/PackedBatchRefUpdate.java b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/PackedBatchRefUpdate.java
index e45b53e..9023570 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/PackedBatchRefUpdate.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/PackedBatchRefUpdate.java
@@ -366,12 +366,8 @@ private static RefList<Ref> applyUpdates(RevWalk walk, RefList<Ref> refs,
List<ReceiveCommand> commands) throws IOException {
// Construct a new RefList by merging the old list with the updates.
// This assumes that each ref occurs at most once as a ReceiveCommand.
- Collections.sort(commands, new Comparator<ReceiveCommand>() {
- @Override
- public int compare(ReceiveCommand a, ReceiveCommand b) {
- return a.getRefName().compareTo(b.getRefName());
- }
- });
+ Collections.sort(commands,
+ Comparator.comparing(ReceiveCommand::getRefName));
int delta = 0;
for (ReceiveCommand c : commands) {
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/RefDirectory.java b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/RefDirectory.java
index 8cc9383..7fdf8bf 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/RefDirectory.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/RefDirectory.java
@@ -130,7 +130,7 @@
* overall size of a Git repository on disk.
*/
public class RefDirectory extends RefDatabase {
- private final static Logger LOG = LoggerFactory
+ private static final Logger LOG = LoggerFactory
.getLogger(RefDirectory.class);
/** Magic string denoting the start of a symbolic reference file. */
@@ -565,10 +565,9 @@ private ObjectIdRef doPeel(Ref leaf) throws MissingObjectException,
if (obj instanceof RevTag) {
return new ObjectIdRef.PeeledTag(leaf.getStorage(), leaf
.getName(), leaf.getObjectId(), rw.peel(obj).copy());
- } else {
- return new ObjectIdRef.PeeledNonTag(leaf.getStorage(), leaf
- .getName(), leaf.getObjectId());
}
+ return new ObjectIdRef.PeeledNonTag(leaf.getStorage(),
+ leaf.getName(), leaf.getObjectId());
}
}
@@ -865,10 +864,9 @@ private Ref peeledPackedRef(Ref f)
if (peeledObjectId != null) {
return new ObjectIdRef.PeeledTag(PACKED, f.getName(),
f.getObjectId(), peeledObjectId);
- } else {
- return new ObjectIdRef.PeeledNonTag(PACKED, f.getName(),
- f.getObjectId());
}
+ return new ObjectIdRef.PeeledNonTag(PACKED, f.getName(),
+ f.getObjectId());
}
void log(boolean force, RefUpdate update, String msg, boolean deref)
@@ -1379,7 +1377,7 @@ private static interface LooseRef extends Ref {
LooseRef peel(ObjectIdRef newLeaf);
}
- private final static class LoosePeeledTag extends ObjectIdRef.PeeledTag
+ private static final class LoosePeeledTag extends ObjectIdRef.PeeledTag
implements LooseRef {
private final FileSnapshot snapShot;
@@ -1400,7 +1398,7 @@ public LooseRef peel(ObjectIdRef newLeaf) {
}
}
- private final static class LooseNonTag extends ObjectIdRef.PeeledNonTag
+ private static final class LooseNonTag extends ObjectIdRef.PeeledNonTag
implements LooseRef {
private final FileSnapshot snapShot;
@@ -1421,7 +1419,7 @@ public LooseRef peel(ObjectIdRef newLeaf) {
}
}
- private final static class LooseUnpeeled extends ObjectIdRef.Unpeeled
+ private static final class LooseUnpeeled extends ObjectIdRef.Unpeeled
implements LooseRef {
private FileSnapshot snapShot;
@@ -1451,14 +1449,12 @@ public LooseRef peel(ObjectIdRef newLeaf) {
if (peeledObjectId != null) {
return new LoosePeeledTag(snapShot, getName(),
objectId, peeledObjectId);
- } else {
- return new LooseNonTag(snapShot, getName(),
- objectId);
}
+ return new LooseNonTag(snapShot, getName(), objectId);
}
}
- private final static class LooseSymbolicRef extends SymbolicRef implements
+ private static final class LooseSymbolicRef extends SymbolicRef implements
LooseRef {
private final FileSnapshot snapShot;
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/RefDirectoryUpdate.java b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/RefDirectoryUpdate.java
index 1a0d695..dc4967f 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/RefDirectoryUpdate.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/RefDirectoryUpdate.java
@@ -90,9 +90,8 @@ protected boolean tryLock(boolean deref) throws IOException {
dst = database.findRef(name);
setOldObjectId(dst != null ? dst.getObjectId() : null);
return true;
- } else {
- return false;
}
+ return false;
}
/** {@inheritDoc} */
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/ReflogEntryImpl.java b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/ReflogEntryImpl.java
index 08a14b2..3cdd904 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/ReflogEntryImpl.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/ReflogEntryImpl.java
@@ -140,9 +140,9 @@ public String toString() {
/** {@inheritDoc} */
@Override
public CheckoutEntry parseCheckout() {
- if (getComment().startsWith(CheckoutEntryImpl.CHECKOUT_MOVING_FROM))
+ if (getComment().startsWith(CheckoutEntryImpl.CHECKOUT_MOVING_FROM)) {
return new CheckoutEntryImpl(this);
- else
- return null;
+ }
+ return null;
}
}
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/ReflogWriter.java b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/ReflogWriter.java
index 131f716..98d6ea0 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/ReflogWriter.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/ReflogWriter.java
@@ -61,6 +61,7 @@
import java.text.MessageFormat;
import org.eclipse.jgit.internal.JGitText;
+import org.eclipse.jgit.lib.ConfigConstants;
import org.eclipse.jgit.lib.Constants;
import org.eclipse.jgit.lib.CoreConfig;
import org.eclipse.jgit.lib.ObjectId;
@@ -68,6 +69,7 @@
import org.eclipse.jgit.lib.Ref;
import org.eclipse.jgit.lib.RefUpdate;
import org.eclipse.jgit.lib.ReflogEntry;
+import org.eclipse.jgit.lib.Repository;
import org.eclipse.jgit.util.FileUtils;
/**
@@ -239,7 +241,7 @@ private FileOutputStream getFileOutputStream(File log) throws IOException {
private ReflogWriter log(String refName, byte[] rec) throws IOException {
File log = refdb.logFor(refName);
boolean write = forceWrite
- || (isLogAllRefUpdates() && shouldAutoCreateLog(refName))
+ || shouldAutoCreateLog(refName)
|| log.isFile();
if (!write)
return this;
@@ -260,15 +262,27 @@ private ReflogWriter log(String refName, byte[] rec) throws IOException {
return this;
}
- private boolean isLogAllRefUpdates() {
- return refdb.getRepository().getConfig().get(CoreConfig.KEY)
- .isLogAllRefUpdates();
- }
-
private boolean shouldAutoCreateLog(String refName) {
- return refName.equals(HEAD)
- || refName.startsWith(R_HEADS)
- || refName.startsWith(R_REMOTES)
- || refName.startsWith(R_NOTES);
+ Repository repo = refdb.getRepository();
+ CoreConfig.LogRefUpdates value = repo.isBare()
+ ? CoreConfig.LogRefUpdates.FALSE
+ : CoreConfig.LogRefUpdates.TRUE;
+ value = repo.getConfig().getEnum(ConfigConstants.CONFIG_CORE_SECTION,
+ null, ConfigConstants.CONFIG_KEY_LOGALLREFUPDATES, value);
+ if (value != null) {
+ switch (value) {
+ case FALSE:
+ break;
+ case TRUE:
+ return refName.equals(HEAD) || refName.startsWith(R_HEADS)
+ || refName.startsWith(R_REMOTES)
+ || refName.startsWith(R_NOTES);
+ case ALWAYS:
+ return refName.equals(HEAD) || refName.startsWith(R_REFS);
+ default:
+ break;
+ }
+ }
+ return false;
}
}
\ No newline at end of file
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/UnpackedObject.java b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/UnpackedObject.java
index 79f1307..fb06623 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/UnpackedObject.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/UnpackedObject.java
@@ -139,49 +139,48 @@ static ObjectLoader open(InputStream in, File path, AnyObjectId id,
}
return new LargeObject(type, size, path, id, wc.db);
- } else {
- readSome(in, hdr, 2, 18);
- int c = hdr[0] & 0xff;
- int type = (c >> 4) & 7;
- long size = c & 15;
- int shift = 4;
- int p = 1;
- while ((c & 0x80) != 0) {
- c = hdr[p++] & 0xff;
- size += ((long) (c & 0x7f)) << shift;
- shift += 7;
- }
-
- switch (type) {
- case Constants.OBJ_COMMIT:
- case Constants.OBJ_TREE:
- case Constants.OBJ_BLOB:
- case Constants.OBJ_TAG:
- // Acceptable types for a loose object.
- break;
- default:
- throw new CorruptObjectException(id,
- JGitText.get().corruptObjectInvalidType);
- }
-
- if (path == null && Integer.MAX_VALUE < size) {
- LargeObjectException.ExceedsByteArrayLimit e;
- e = new LargeObjectException.ExceedsByteArrayLimit();
- e.setObjectId(id);
- throw e;
- }
- if (size < wc.getStreamFileThreshold() || path == null) {
- in.reset();
- IO.skipFully(in, p);
- Inflater inf = wc.inflater();
- InputStream zIn = inflate(in, inf);
- byte[] data = new byte[(int) size];
- IO.readFully(zIn, data, 0, data.length);
- checkValidEndOfStream(in, inf, id, hdr);
- return new ObjectLoader.SmallObject(type, data);
- }
- return new LargeObject(type, size, path, id, wc.db);
}
+ readSome(in, hdr, 2, 18);
+ int c = hdr[0] & 0xff;
+ int type = (c >> 4) & 7;
+ long size = c & 15;
+ int shift = 4;
+ int p = 1;
+ while ((c & 0x80) != 0) {
+ c = hdr[p++] & 0xff;
+ size += ((long) (c & 0x7f)) << shift;
+ shift += 7;
+ }
+
+ switch (type) {
+ case Constants.OBJ_COMMIT:
+ case Constants.OBJ_TREE:
+ case Constants.OBJ_BLOB:
+ case Constants.OBJ_TAG:
+ // Acceptable types for a loose object.
+ break;
+ default:
+ throw new CorruptObjectException(id,
+ JGitText.get().corruptObjectInvalidType);
+ }
+
+ if (path == null && Integer.MAX_VALUE < size) {
+ LargeObjectException.ExceedsByteArrayLimit e;
+ e = new LargeObjectException.ExceedsByteArrayLimit();
+ e.setObjectId(id);
+ throw e;
+ }
+ if (size < wc.getStreamFileThreshold() || path == null) {
+ in.reset();
+ IO.skipFully(in, p);
+ Inflater inf = wc.inflater();
+ InputStream zIn = inflate(in, inf);
+ byte[] data = new byte[(int) size];
+ IO.readFully(zIn, data, 0, data.length);
+ checkValidEndOfStream(in, inf, id, hdr);
+ return new ObjectLoader.SmallObject(type, data);
+ }
+ return new LargeObject(type, size, path, id, wc.db);
} catch (ZipException badStream) {
throw new CorruptObjectException(id,
JGitText.get().corruptObjectBadStream);
@@ -213,19 +212,18 @@ static long getSize(InputStream in, AnyObjectId id, WindowCursor wc)
JGitText.get().corruptObjectNegativeSize);
return size;
- } else {
- readSome(in, hdr, 2, 18);
- int c = hdr[0] & 0xff;
- long size = c & 15;
- int shift = 4;
- int p = 1;
- while ((c & 0x80) != 0) {
- c = hdr[p++] & 0xff;
- size += ((long) (c & 0x7f)) << shift;
- shift += 7;
- }
- return size;
}
+ readSome(in, hdr, 2, 18);
+ int c = hdr[0] & 0xff;
+ long size = c & 15;
+ int shift = 4;
+ int p = 1;
+ while ((c & 0x80) != 0) {
+ c = hdr[p++] & 0xff;
+ size += ((long) (c & 0x7f)) << shift;
+ shift += 7;
+ }
+ return size;
} catch (ZipException badStream) {
throw new CorruptObjectException(id,
JGitText.get().corruptObjectBadStream);
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/UnpackedObjectCache.java b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/UnpackedObjectCache.java
index ea0d269..616447a 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/UnpackedObjectCache.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/UnpackedObjectCache.java
@@ -126,17 +126,19 @@ boolean add(AnyObjectId toAdd) {
for (int n = 0; n < MAX_CHAIN;) {
ObjectId obj = ids.get(i);
if (obj == null) {
- if (ids.compareAndSet(i, null, toAdd.copy()))
+ if (ids.compareAndSet(i, null, toAdd.copy())) {
return true;
- else
- continue;
+ }
+ continue;
}
- if (AnyObjectId.isEqual(obj, toAdd))
+ if (AnyObjectId.isEqual(obj, toAdd)) {
return true;
+ }
- if (++i == ids.length())
+ if (++i == ids.length()) {
i = 0;
+ }
n++;
}
return false;
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/pack/CachedPackUriProvider.java b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/pack/CachedPackUriProvider.java
index 5cbc2ba..9496d78 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/pack/CachedPackUriProvider.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/pack/CachedPackUriProvider.java
@@ -76,14 +76,22 @@ public static class PackInfo {
private final String hash;
private final String uri;
+ private final long size;
+
/**
* Constructs an object containing information about a packfile.
- * @param hash the hash of the packfile as a hexadecimal string
- * @param uri the URI corresponding to the packfile
+ *
+ * @param hash
+ * the hash of the packfile as a hexadecimal string
+ * @param uri
+ * the URI corresponding to the packfile
+ * @param size
+ * the size of the packfile in bytes
*/
- public PackInfo(String hash, String uri) {
+ public PackInfo(String hash, String uri, long size) {
this.hash = hash;
this.uri = uri;
+ this.size = size;
}
/**
@@ -99,5 +107,12 @@ public String getHash() {
public String getUri() {
return uri;
}
+
+ /**
+ * @return the size of the packfile in bytes (-1 if unknown)
+ */
+ public long getSize() {
+ return size;
+ }
}
}
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/pack/PackExt.java b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/pack/PackExt.java
index 292fd36..b4143c9 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/pack/PackExt.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/pack/PackExt.java
@@ -81,7 +81,7 @@ public class PackExt {
* the file extension.
* @return the PackExt for the ext
*/
- public synchronized static PackExt newPackExt(String ext) {
+ public static synchronized PackExt newPackExt(String ext) {
PackExt[] dst = new PackExt[VALUES.length + 1];
for (int i = 0; i < VALUES.length; i++) {
PackExt packExt = VALUES[i];
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/pack/PackWriter.java b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/pack/PackWriter.java
index 43067d3..fcf9ca5 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/pack/PackWriter.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/pack/PackWriter.java
@@ -225,7 +225,7 @@ public static Iterable<PackWriter> getInstances() {
}
@SuppressWarnings("unchecked")
- BlockList<ObjectToPack> objectsLists[] = new BlockList[OBJ_TAG + 1];
+ BlockList<ObjectToPack>[] objectsLists = new BlockList[OBJ_TAG + 1];
{
objectsLists[OBJ_COMMIT] = new BlockList<>();
objectsLists[OBJ_TREE] = new BlockList<>();
@@ -270,7 +270,7 @@ public static Iterable<PackWriter> getInstances() {
private List<ObjectToPack> sortedByName;
- private byte packcsum[];
+ private byte[] packcsum;
private boolean deltaBaseAsOffset;
@@ -1230,6 +1230,8 @@ public void writePack(ProgressMonitor compressMonitor,
if (packInfo != null) {
o.writeString(packInfo.getHash() + ' ' +
packInfo.getUri() + '\n');
+ stats.offloadedPackfiles += 1;
+ stats.offloadedPackfileSize += packInfo.getSize();
} else {
unwrittenCachedPacks.add(pack);
}
@@ -1749,23 +1751,23 @@ private void writeObjectImpl(PackOutputStream out, ObjectToPack otp)
NullProgressMonitor.INSTANCE,
Collections.singleton(otp));
continue;
- } else {
- // Object writing already started, we cannot recover.
- //
- CorruptObjectException coe;
- coe = new CorruptObjectException(otp, ""); //$NON-NLS-1$
- coe.initCause(gone);
- throw coe;
}
+ // Object writing already started, we cannot recover.
+ //
+ CorruptObjectException coe;
+ coe = new CorruptObjectException(otp, ""); //$NON-NLS-1$
+ coe.initCause(gone);
+ throw coe;
}
}
// If we reached here, reuse wasn't possible.
//
- if (otp.isDeltaRepresentation())
+ if (otp.isDeltaRepresentation()) {
writeDeltaObjectDeflate(out, otp);
- else
+ } else {
writeWholeObjectDeflate(out, otp);
+ }
out.endObject();
otp.setCRC((int) crc32.getValue());
}
@@ -2430,7 +2432,7 @@ State snapshot() {
}
/** Possible states that a PackWriter can be in. */
- public static enum PackingPhase {
+ public enum PackingPhase {
/** Counting objects phase. */
COUNTING,
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/reftable/BlockReader.java b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/reftable/BlockReader.java
index b66751b..6ae7e45 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/reftable/BlockReader.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/reftable/BlockReader.java
@@ -92,7 +92,6 @@
class BlockReader {
private byte blockType;
private long endPosition;
- private boolean truncated;
private byte[] buf;
private int bufLen;
@@ -112,10 +111,6 @@ byte type() {
return blockType;
}
- boolean truncated() {
- return truncated;
- }
-
long endPosition() {
return endPosition;
}
@@ -331,16 +326,8 @@ private void parseBlockStart(BlockSource src, long pos, int fileBlockSize)
// Log blocks must be inflated after the header.
long deflatedSize = inflateBuf(src, pos, blockLen, fileBlockSize);
endPosition = pos + 4 + deflatedSize;
- }
- if (bufLen < blockLen) {
- if (blockType != INDEX_BLOCK_TYPE) {
- throw invalidBlock();
- }
- // Its OK during sequential scan for an index block to have been
- // partially read and be truncated in-memory. This happens when
- // the index block is larger than the file's blockSize. Caller
- // will break out of its scan loop once it sees the blockType.
- truncated = true;
+ } else if (bufLen < blockLen) {
+ readBlockIntoBuf(src, pos, blockLen);
} else if (bufLen > blockLen) {
bufLen = blockLen;
}
@@ -405,7 +392,7 @@ private void setupEmptyFileBlock() {
}
void verifyIndex() throws IOException {
- if (blockType != INDEX_BLOCK_TYPE || truncated) {
+ if (blockType != INDEX_BLOCK_TYPE) {
throw invalidBlock();
}
}
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/reftable/BlockWriter.java b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/reftable/BlockWriter.java
index b3173e8..1ed1801 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/reftable/BlockWriter.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/reftable/BlockWriter.java
@@ -286,7 +286,7 @@ static int compare(
return aLen - bLen;
}
- static abstract class Entry {
+ abstract static class Entry {
static int compare(Entry ea, Entry eb) {
byte[] a = ea.key;
byte[] b = eb.key;
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/reftable/LogCursor.java b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/reftable/LogCursor.java
index 486fd28..5c98242 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/reftable/LogCursor.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/reftable/LogCursor.java
@@ -45,6 +45,7 @@
import java.io.IOException;
+import org.eclipse.jgit.annotations.Nullable;
import org.eclipse.jgit.lib.ReflogEntry;
/**
@@ -78,8 +79,9 @@ public abstract class LogCursor implements AutoCloseable {
/**
* Get current log entry.
*
- * @return current log entry.
+ * @return current log entry. Maybe null if we are producing deletions.
*/
+ @Nullable
public abstract ReflogEntry getReflogEntry();
/** {@inheritDoc} */
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/reftable/MergedReftable.java b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/reftable/MergedReftable.java
index c740bf2..d272d09 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/reftable/MergedReftable.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/reftable/MergedReftable.java
@@ -67,13 +67,11 @@
* A {@code MergedReftable} is not thread-safe.
*/
public class MergedReftable extends Reftable {
- private final Reftable[] tables;
+ private final ReftableReader[] tables;
/**
* Initialize a merged table reader.
* <p>
- * The tables in {@code tableStack} will be closed when this
- * {@code MergedReftable} is closed.
*
* @param tableStack
* stack of tables to read from. The base of the stack is at
@@ -81,16 +79,44 @@ public class MergedReftable extends Reftable {
* {@code tableStack.size() - 1}. The top of the stack (higher
* index) shadows the base of the stack (lower index).
*/
- public MergedReftable(List<Reftable> tableStack) {
- tables = tableStack.toArray(new Reftable[0]);
+ public MergedReftable(List<ReftableReader> tableStack) {
+ tables = tableStack.toArray(new ReftableReader[0]);
// Tables must expose deletes to this instance to correctly
// shadow references from lower tables.
- for (Reftable t : tables) {
+ for (ReftableReader t : tables) {
t.setIncludeDeletes(true);
}
}
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public long maxUpdateIndex() throws IOException {
+ return tables.length > 0 ? tables[tables.length - 1].maxUpdateIndex()
+ : 0;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public long minUpdateIndex() throws IOException {
+ return tables.length > 0 ? tables[0].minUpdateIndex()
+ : 0;
+ }
+
+ /** {@inheritDoc} */
+ @Override
+ public boolean hasObjectMap() throws IOException {
+ boolean has = true;
+ for (int i = 0; has && i < tables.length; i++) {
+ has = has && tables[i].hasObjectMap();
+ }
+ return has;
+ }
+
/** {@inheritDoc} */
@Override
public RefCursor allRefs() throws IOException {
@@ -124,7 +150,7 @@ public RefCursor seekRefsWithPrefix(String prefix) throws IOException {
/** {@inheritDoc} */
@Override
public RefCursor byObjectId(AnyObjectId name) throws IOException {
- MergedRefCursor m = new MergedRefCursor();
+ MergedRefCursor m = new FilteringMergedRefCursor(name);
for (int i = 0; i < tables.length; i++) {
m.add(new RefQueueEntry(tables[i].byObjectId(name), i));
}
@@ -152,14 +178,6 @@ public LogCursor seekLog(String refName, long updateIdx)
return m;
}
- /** {@inheritDoc} */
- @Override
- public void close() throws IOException {
- for (Reftable t : tables) {
- t.close();
- }
- }
-
int queueSize() {
return Math.max(1, tables.length);
}
@@ -251,6 +269,42 @@ public void close() {
}
}
+ private class FilteringMergedRefCursor extends MergedRefCursor {
+ final AnyObjectId filterId;
+ Ref filteredRef;
+
+ FilteringMergedRefCursor(AnyObjectId id) {
+ filterId = id;
+ filteredRef = null;
+ }
+
+ @Override
+ public Ref getRef() {
+ return filteredRef;
+ }
+
+ @Override
+ public boolean next() throws IOException {
+ for (;;) {
+ boolean ok = super.next();
+ if (!ok) {
+ return false;
+ }
+
+ String name = super.getRef().getName();
+
+ try (RefCursor c = seekRef(name)) {
+ if (c.next()) {
+ if (filterId.equals(c.getRef().getObjectId())) {
+ filteredRef = c.getRef();
+ return true;
+ }
+ }
+ }
+ }
+ }
+ }
+
private static class RefQueueEntry {
static int compare(RefQueueEntry a, RefQueueEntry b) {
int cmp = a.name().compareTo(b.name());
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/reftable/Reftable.java b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/reftable/Reftable.java
index cb02628..a7e8252 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/reftable/Reftable.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/reftable/Reftable.java
@@ -58,7 +58,7 @@
/**
* Abstract table of references.
*/
-public abstract class Reftable implements AutoCloseable {
+public abstract class Reftable {
/**
* References to convert into a reftable
*
@@ -72,9 +72,9 @@ public static Reftable from(Collection<Ref> refs) {
cfg.setIndexObjects(false);
cfg.setAlignBlocks(false);
ByteArrayOutputStream buf = new ByteArrayOutputStream();
- new ReftableWriter()
+ new ReftableWriter(buf)
.setConfig(cfg)
- .begin(buf)
+ .begin()
.sortAndWriteRefs(refs)
.finish();
return new ReftableReader(BlockSource.from(buf.toByteArray()));
@@ -99,6 +99,28 @@ public void setIncludeDeletes(boolean deletes) {
}
/**
+ * Get the maximum update index for ref entries that appear in this
+ * reftable.
+ *
+ * @return the maximum update index for ref entries that appear in this
+ * reftable.
+ * @throws java.io.IOException
+ * file cannot be read.
+ */
+ public abstract long maxUpdateIndex() throws IOException;
+
+ /**
+ * Get the minimum update index for ref entries that appear in this
+ * reftable.
+ *
+ * @return the minimum update index for ref entries that appear in this
+ * reftable.
+ * @throws java.io.IOException
+ * file cannot be read.
+ */
+ public abstract long minUpdateIndex() throws IOException;
+
+ /**
* Seek to the first reference, to iterate in order.
*
* @return cursor to iterate.
@@ -149,6 +171,12 @@ public void setIncludeDeletes(boolean deletes) {
public abstract RefCursor byObjectId(AnyObjectId id) throws IOException;
/**
+ * @return whether this reftable can do a fast SHA1 => ref lookup.
+ * @throws IOException on I/O problems.
+ */
+ public abstract boolean hasObjectMap() throws IOException;
+
+ /**
* Seek reader to read log records.
*
* @return cursor to iterate; empty cursor if no logs are present.
@@ -282,8 +310,4 @@ private Ref resolve(Ref ref, int depth) throws IOException {
}
return new SymbolicRef(ref.getName(), dst, ref.getUpdateIndex());
}
-
- /** {@inheritDoc} */
- @Override
- public abstract void close() throws IOException;
}
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/reftable/ReftableBatchRefUpdate.java b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/reftable/ReftableBatchRefUpdate.java
new file mode 100644
index 0000000..592120d
--- /dev/null
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/reftable/ReftableBatchRefUpdate.java
@@ -0,0 +1,415 @@
+/*
+ * Copyright (C) 2019, Google Inc.
+ * 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.storage.reftable;
+
+import org.eclipse.jgit.annotations.Nullable;
+import org.eclipse.jgit.errors.MissingObjectException;
+import org.eclipse.jgit.internal.JGitText;
+import org.eclipse.jgit.lib.AnyObjectId;
+import org.eclipse.jgit.lib.BatchRefUpdate;
+import org.eclipse.jgit.lib.ObjectId;
+import org.eclipse.jgit.lib.ObjectIdRef;
+import org.eclipse.jgit.lib.PersonIdent;
+import org.eclipse.jgit.lib.ProgressMonitor;
+import org.eclipse.jgit.lib.Ref;
+import org.eclipse.jgit.lib.RefDatabase;
+import org.eclipse.jgit.lib.ReflogEntry;
+import org.eclipse.jgit.lib.Repository;
+import org.eclipse.jgit.lib.SymbolicRef;
+import org.eclipse.jgit.revwalk.RevObject;
+import org.eclipse.jgit.revwalk.RevTag;
+import org.eclipse.jgit.revwalk.RevWalk;
+import org.eclipse.jgit.transport.ReceiveCommand;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.TreeSet;
+import java.util.concurrent.locks.Lock;
+import java.util.stream.Collectors;
+
+import static org.eclipse.jgit.lib.Ref.Storage.NEW;
+import static org.eclipse.jgit.lib.Ref.Storage.PACKED;
+
+import static org.eclipse.jgit.transport.ReceiveCommand.Result.LOCK_FAILURE;
+import static org.eclipse.jgit.transport.ReceiveCommand.Result.NOT_ATTEMPTED;
+import static org.eclipse.jgit.transport.ReceiveCommand.Result.OK;
+import static org.eclipse.jgit.transport.ReceiveCommand.Result.REJECTED_MISSING_OBJECT;
+import static org.eclipse.jgit.transport.ReceiveCommand.Result.REJECTED_NONFASTFORWARD;
+import static org.eclipse.jgit.transport.ReceiveCommand.Type.DELETE;
+import static org.eclipse.jgit.transport.ReceiveCommand.Type.UPDATE_NONFASTFORWARD;
+
+/**
+ * {@link org.eclipse.jgit.lib.BatchRefUpdate} for Reftable based RefDatabase.
+ */
+public abstract class ReftableBatchRefUpdate extends BatchRefUpdate {
+ private final Lock lock;
+
+ private final ReftableDatabase refDb;
+
+ private final Repository repository;
+
+ /**
+ * Initialize.
+ *
+ * @param refdb
+ * The RefDatabase
+ * @param reftableDb
+ * The ReftableDatabase
+ * @param lock
+ * A lock protecting the refdatabase's state
+ * @param repository
+ * The repository on which this update will run
+ */
+ protected ReftableBatchRefUpdate(RefDatabase refdb, ReftableDatabase reftableDb, Lock lock,
+ Repository repository) {
+ super(refdb);
+ this.refDb = reftableDb;
+ this.lock = lock;
+ this.repository = repository;
+ }
+
+ /** {@inheritDoc} */
+ @Override
+ public void execute(RevWalk rw, ProgressMonitor pm, List<String> options) {
+ List<ReceiveCommand> pending = getPending();
+ if (pending.isEmpty()) {
+ return;
+ }
+ if (options != null) {
+ setPushOptions(options);
+ }
+ try {
+ if (!checkObjectExistence(rw, pending)) {
+ return;
+ }
+ // if we are here, checkObjectExistence might have flagged some problems
+ // but the transaction is not atomic, so we should proceed with the other
+ // pending commands.
+ pending = getPending();
+ if (!checkNonFastForwards(rw, pending)) {
+ return;
+ }
+ pending = getPending();
+
+ lock.lock();
+ try {
+ if (!checkExpected(pending)) {
+ return;
+ }
+ pending = getPending();
+ if (!checkConflicting(pending)) {
+ return;
+ }
+ pending = getPending();
+ if (!blockUntilTimestamps(MAX_WAIT)) {
+ return;
+ }
+
+ List<Ref> newRefs = toNewRefs(rw, pending);
+ applyUpdates(newRefs, pending);
+ for (ReceiveCommand cmd : pending) {
+ if (cmd.getResult() == NOT_ATTEMPTED) {
+ // XXX this is a bug in DFS ?
+ cmd.setResult(OK);
+ }
+ }
+ } finally {
+ lock.unlock();
+ }
+ } catch (IOException e) {
+ pending.get(0).setResult(LOCK_FAILURE, "io error"); //$NON-NLS-1$
+ ReceiveCommand.abort(pending);
+ }
+ }
+
+ /**
+ * Implements the storage-specific part of the update.
+ *
+ * @param newRefs
+ * the new refs to create
+ * @param pending
+ * the pending receive commands to be executed
+ * @throws IOException
+ * if any of the writes fail.
+ */
+ protected abstract void applyUpdates(List<Ref> newRefs,
+ List<ReceiveCommand> pending) throws IOException;
+
+ private List<ReceiveCommand> getPending() {
+ return ReceiveCommand.filter(getCommands(), NOT_ATTEMPTED);
+ }
+
+ private boolean checkObjectExistence(RevWalk rw,
+ List<ReceiveCommand> pending) throws IOException {
+ for (ReceiveCommand cmd : pending) {
+ try {
+ if (!cmd.getNewId().equals(ObjectId.zeroId())) {
+ rw.parseAny(cmd.getNewId());
+ }
+ } catch (MissingObjectException e) {
+ // ReceiveCommand#setResult(Result) converts REJECTED to
+ // REJECTED_NONFASTFORWARD, even though that result is also
+ // used for a missing object. Eagerly handle this case so we
+ // can set the right result.
+ cmd.setResult(REJECTED_MISSING_OBJECT);
+ if (isAtomic()) {
+ ReceiveCommand.abort(pending);
+ return false;
+ }
+ }
+ }
+ return true;
+ }
+
+ private boolean checkNonFastForwards(RevWalk rw,
+ List<ReceiveCommand> pending) throws IOException {
+ if (isAllowNonFastForwards()) {
+ return true;
+ }
+ for (ReceiveCommand cmd : pending) {
+ cmd.updateType(rw);
+ if (cmd.getType() == UPDATE_NONFASTFORWARD) {
+ cmd.setResult(REJECTED_NONFASTFORWARD);
+ if (isAtomic()) {
+ ReceiveCommand.abort(pending);
+ return false;
+ }
+ }
+ }
+ return true;
+ }
+
+ private boolean checkConflicting(List<ReceiveCommand> pending)
+ throws IOException {
+ TreeSet<String> added = new TreeSet<>();
+ Set<String> deleted =
+ pending.stream()
+ .filter(cmd -> cmd.getType() == DELETE)
+ .map(c -> c.getRefName())
+ .collect(Collectors.toSet());
+
+ boolean ok = true;
+ for (ReceiveCommand cmd : pending) {
+ if (cmd.getType() == DELETE) {
+ continue;
+ }
+
+ String name = cmd.getRefName();
+ if (refDb.isNameConflicting(name, added, deleted)) {
+ if (isAtomic()) {
+ cmd.setResult(
+ ReceiveCommand.Result.REJECTED_OTHER_REASON, JGitText.get().transactionAborted);
+ } else {
+ cmd.setResult(LOCK_FAILURE);
+ }
+
+ ok = false;
+ }
+ added.add(name);
+ }
+
+ if (isAtomic()) {
+ if (!ok) {
+ pending.stream()
+ .filter(cmd -> cmd.getResult() == NOT_ATTEMPTED)
+ .forEach(cmd -> cmd.setResult(LOCK_FAILURE));
+ }
+ return ok;
+ }
+
+ for (ReceiveCommand cmd : pending) {
+ if (cmd.getResult() == NOT_ATTEMPTED) {
+ return true;
+ }
+ }
+
+ return false;
+ }
+
+ private boolean checkExpected(List<ReceiveCommand> pending)
+ throws IOException {
+ for (ReceiveCommand cmd : pending) {
+ if (!matchOld(cmd, refDb.exactRef(cmd.getRefName()))) {
+ cmd.setResult(LOCK_FAILURE);
+ if (isAtomic()) {
+ ReceiveCommand.abort(pending);
+ return false;
+ }
+ }
+ }
+ return true;
+ }
+
+ private static boolean matchOld(ReceiveCommand cmd, @Nullable Ref ref) {
+ if (ref == null) {
+ return AnyObjectId.isEqual(ObjectId.zeroId(), cmd.getOldId())
+ && cmd.getOldSymref() == null;
+ } else if (ref.isSymbolic()) {
+ return ref.getTarget().getName().equals(cmd.getOldSymref());
+ }
+ ObjectId id = ref.getObjectId();
+ if (id == null) {
+ id = ObjectId.zeroId();
+ }
+ return cmd.getOldId().equals(id);
+ }
+
+ /**
+ * Writes the refs to the writer, and calls finish.
+ *
+ * @param writer
+ * the writer on which we should write.
+ * @param newRefs
+ * the ref data to write..
+ * @param pending
+ * the log data to write.
+ * @throws IOException
+ * in case of problems.
+ */
+ protected void write(ReftableWriter writer, List<Ref> newRefs,
+ List<ReceiveCommand> pending) throws IOException {
+ long updateIndex = refDb.nextUpdateIndex();
+ writer.setMinUpdateIndex(updateIndex).setMaxUpdateIndex(updateIndex)
+ .begin().sortAndWriteRefs(newRefs);
+ if (!isRefLogDisabled()) {
+ writeLog(writer, updateIndex, pending);
+ }
+ }
+
+ private void writeLog(ReftableWriter writer, long updateIndex,
+ List<ReceiveCommand> pending) throws IOException {
+ Map<String, ReceiveCommand> cmds = new HashMap<>();
+ List<String> byName = new ArrayList<>(pending.size());
+ for (ReceiveCommand cmd : pending) {
+ cmds.put(cmd.getRefName(), cmd);
+ byName.add(cmd.getRefName());
+ }
+ Collections.sort(byName);
+
+ PersonIdent ident = getRefLogIdent();
+ if (ident == null) {
+ ident = new PersonIdent(repository);
+ }
+ for (String name : byName) {
+ ReceiveCommand cmd = cmds.get(name);
+ if (isRefLogDisabled(cmd)) {
+ continue;
+ }
+ String msg = getRefLogMessage(cmd);
+ if (isRefLogIncludingResult(cmd)) {
+ String strResult = toResultString(cmd);
+ if (strResult != null) {
+ msg = msg.isEmpty() ? strResult : msg + ": " + strResult; //$NON-NLS-1$
+ }
+ }
+ writer.writeLog(name, updateIndex, ident, cmd.getOldId(),
+ cmd.getNewId(), msg);
+ }
+ }
+
+ private String toResultString(ReceiveCommand cmd) {
+ switch (cmd.getType()) {
+ case CREATE:
+ return ReflogEntry.PREFIX_CREATED;
+ case UPDATE:
+ // Match the behavior of a single RefUpdate. In that case, setting
+ // the force bit completely bypasses the potentially expensive
+ // isMergedInto check, by design, so the reflog message may be
+ // inaccurate.
+ //
+ // Similarly, this class bypasses the isMergedInto checks when the
+ // force bit is set, meaning we can't actually distinguish between
+ // UPDATE and UPDATE_NONFASTFORWARD when isAllowNonFastForwards()
+ // returns true.
+ return isAllowNonFastForwards() ? ReflogEntry.PREFIX_FORCED_UPDATE
+ : ReflogEntry.PREFIX_FAST_FORWARD;
+ case UPDATE_NONFASTFORWARD:
+ return ReflogEntry.PREFIX_FORCED_UPDATE;
+ default:
+ return null;
+ }
+ }
+
+ // Extracts and peels the refs out of the ReceiveCommands
+ private static List<Ref> toNewRefs(RevWalk rw, List<ReceiveCommand> pending)
+ throws IOException {
+ List<Ref> refs = new ArrayList<>(pending.size());
+ for (ReceiveCommand cmd : pending) {
+ if (cmd.getResult() != NOT_ATTEMPTED) {
+ continue;
+ }
+
+ String name = cmd.getRefName();
+ ObjectId newId = cmd.getNewId();
+ String newSymref = cmd.getNewSymref();
+ if (AnyObjectId.isEqual(ObjectId.zeroId(), newId)
+ && newSymref == null) {
+ refs.add(new ObjectIdRef.Unpeeled(NEW, name, null));
+ continue;
+ } else if (newSymref != null) {
+ refs.add(new SymbolicRef(name,
+ new ObjectIdRef.Unpeeled(NEW, newSymref, null)));
+ continue;
+ }
+
+ RevObject obj = rw.parseAny(newId);
+ RevObject peel = null;
+ if (obj instanceof RevTag) {
+ peel = rw.peel(obj);
+ }
+ if (peel != null) {
+ refs.add(new ObjectIdRef.PeeledTag(PACKED, name, newId,
+ peel.copy()));
+ } else {
+ refs.add(new ObjectIdRef.PeeledNonTag(PACKED, name, newId));
+ }
+ }
+ return refs;
+ }
+}
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/reftable/ReftableCompactor.java b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/reftable/ReftableCompactor.java
index c4e8f69..a586d42 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/reftable/ReftableCompactor.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/reftable/ReftableCompactor.java
@@ -61,25 +61,34 @@
* to shadow any lower reftable that may have the reference present.
* <p>
* By default all log entries within the range defined by
- * {@link #setMinUpdateIndex(long)} and {@link #setMaxUpdateIndex(long)} are
+ * {@link #setReflogExpireMinUpdateIndex(long)} and {@link #setReflogExpireMaxUpdateIndex(long)} are
* copied, even if no references in the output file match the log records.
* Callers may truncate the log to a more recent time horizon with
- * {@link #setOldestReflogTimeMillis(long)}, or disable the log altogether with
+ * {@link #setReflogExpireOldestReflogTimeMillis(long)}, or disable the log altogether with
* {@code setOldestReflogTimeMillis(Long.MAX_VALUE)}.
*/
public class ReftableCompactor {
- private final ReftableWriter writer = new ReftableWriter();
- private final ArrayDeque<Reftable> tables = new ArrayDeque<>();
+ private final ReftableWriter writer;
+ private final ArrayDeque<ReftableReader> tables = new ArrayDeque<>();
- private long compactBytesLimit;
- private long bytesToCompact;
private boolean includeDeletes;
- private long minUpdateIndex = -1;
- private long maxUpdateIndex;
- private long oldestReflogTimeMillis;
+ private long reflogExpireMinUpdateIndex = 0;
+ private long reflogExpireMaxUpdateIndex = Long.MAX_VALUE;
+ private long reflogExpireOldestReflogTimeMillis;
private Stats stats;
/**
+ * Creates a new compactor.
+ *
+ * @param out
+ * stream to write the compacted tables to. Caller is responsible
+ * for closing {@code out}.
+ */
+ public ReftableCompactor(OutputStream out) {
+ writer = new ReftableWriter(out);
+ }
+
+ /**
* Set configuration for the reftable.
*
* @param cfg
@@ -92,18 +101,6 @@ public ReftableCompactor setConfig(ReftableConfig cfg) {
}
/**
- * Set limit on number of bytes from source tables to compact.
- *
- * @param bytes
- * limit on number of bytes from source tables to compact.
- * @return {@code this}
- */
- public ReftableCompactor setCompactBytesLimit(long bytes) {
- compactBytesLimit = bytes;
- return this;
- }
-
- /**
* Whether to include deletions in the output, which may be necessary for
* partial compaction.
*
@@ -128,8 +125,8 @@ public ReftableCompactor setIncludeDeletes(boolean deletes) {
* in a stack.
* @return {@code this}
*/
- public ReftableCompactor setMinUpdateIndex(long min) {
- minUpdateIndex = min;
+ public ReftableCompactor setReflogExpireMinUpdateIndex(long min) {
+ reflogExpireMinUpdateIndex = min;
return this;
}
@@ -144,8 +141,8 @@ public ReftableCompactor setMinUpdateIndex(long min) {
* used in a stack.
* @return {@code this}
*/
- public ReftableCompactor setMaxUpdateIndex(long max) {
- maxUpdateIndex = max;
+ public ReftableCompactor setReflogExpireMaxUpdateIndex(long max) {
+ reflogExpireMaxUpdateIndex = max;
return this;
}
@@ -159,16 +156,13 @@ public ReftableCompactor setMaxUpdateIndex(long max) {
* Specified in Java standard milliseconds since the epoch.
* @return {@code this}
*/
- public ReftableCompactor setOldestReflogTimeMillis(long timeMillis) {
- oldestReflogTimeMillis = timeMillis;
+ public ReftableCompactor setReflogExpireOldestReflogTimeMillis(long timeMillis) {
+ reflogExpireOldestReflogTimeMillis = timeMillis;
return this;
}
/**
* Add all of the tables, in the specified order.
- * <p>
- * Unconditionally adds all tables, ignoring the
- * {@link #setCompactBytesLimit(long)}.
*
* @param readers
* tables to compact. Tables should be ordered oldest first/most
@@ -177,67 +171,26 @@ public ReftableCompactor setOldestReflogTimeMillis(long timeMillis) {
* @throws java.io.IOException
* update indexes of a reader cannot be accessed.
*/
- public void addAll(List<? extends Reftable> readers) throws IOException {
- tables.addAll(readers);
- for (Reftable r : readers) {
- if (r instanceof ReftableReader) {
- adjustUpdateIndexes((ReftableReader) r);
- }
+ public void addAll(List<ReftableReader> readers) throws IOException {
+ for (ReftableReader r : readers) {
+ tables.add(r);
}
}
/**
- * Try to add this reader at the bottom of the stack.
- * <p>
- * A reader may be rejected by returning {@code false} if the compactor is
- * already rewriting its {@link #setCompactBytesLimit(long)}. When this
- * happens the caller should stop trying to add tables, and execute the
- * compaction.
- *
- * @param reader
- * the reader to insert at the bottom of the stack. Caller is
- * responsible for closing the reader.
- * @return {@code true} if the compactor accepted this table; {@code false}
- * if the compactor has reached its limit.
- * @throws java.io.IOException
- * if size of {@code reader}, or its update indexes cannot be read.
- */
- public boolean tryAddFirst(ReftableReader reader) throws IOException {
- long sz = reader.size();
- if (compactBytesLimit > 0 && bytesToCompact + sz > compactBytesLimit) {
- return false;
- }
- bytesToCompact += sz;
- adjustUpdateIndexes(reader);
- tables.addFirst(reader);
- return true;
- }
-
- private void adjustUpdateIndexes(ReftableReader reader) throws IOException {
- if (minUpdateIndex == -1) {
- minUpdateIndex = reader.minUpdateIndex();
- } else {
- minUpdateIndex = Math.min(minUpdateIndex, reader.minUpdateIndex());
- }
- maxUpdateIndex = Math.max(maxUpdateIndex, reader.maxUpdateIndex());
- }
-
- /**
* Write a compaction to {@code out}.
*
- * @param out
- * stream to write the compacted tables to. Caller is responsible
- * for closing {@code out}.
* @throws java.io.IOException
* if tables cannot be read, or cannot be written.
*/
- public void compact(OutputStream out) throws IOException {
+ public void compact() throws IOException {
MergedReftable mr = new MergedReftable(new ArrayList<>(tables));
mr.setIncludeDeletes(includeDeletes);
- writer.setMinUpdateIndex(Math.max(minUpdateIndex, 0));
- writer.setMaxUpdateIndex(maxUpdateIndex);
- writer.begin(out);
+ writer.setMaxUpdateIndex(mr.maxUpdateIndex());
+ writer.setMinUpdateIndex(mr.minUpdateIndex());
+
+ writer.begin();
mergeRefs(mr);
mergeLogs(mr);
writer.finish();
@@ -262,16 +215,14 @@ private void mergeRefs(MergedReftable mr) throws IOException {
}
private void mergeLogs(MergedReftable mr) throws IOException {
- if (oldestReflogTimeMillis == Long.MAX_VALUE) {
+ if (reflogExpireOldestReflogTimeMillis == Long.MAX_VALUE) {
return;
}
try (LogCursor lc = mr.allLogs()) {
while (lc.next()) {
long updateIndex = lc.getUpdateIndex();
- if (updateIndex < minUpdateIndex
- || updateIndex > maxUpdateIndex) {
- // Cannot merge log records outside the header's range.
+ if (updateIndex > reflogExpireMaxUpdateIndex || updateIndex < reflogExpireMinUpdateIndex) {
continue;
}
@@ -285,7 +236,7 @@ private void mergeLogs(MergedReftable mr) throws IOException {
}
PersonIdent who = log.getWho();
- if (who.getWhen().getTime() >= oldestReflogTimeMillis) {
+ if (who.getWhen().getTime() >= reflogExpireOldestReflogTimeMillis) {
writer.writeLog(
refName,
updateIndex,
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/reftable/ReftableDatabase.java b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/reftable/ReftableDatabase.java
new file mode 100644
index 0000000..696347e
--- /dev/null
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/reftable/ReftableDatabase.java
@@ -0,0 +1,350 @@
+/*
+ * Copyright (C) 2017, 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.internal.storage.reftable;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+import java.util.TreeSet;
+import java.util.concurrent.locks.ReentrantLock;
+
+import org.eclipse.jgit.annotations.Nullable;
+import org.eclipse.jgit.lib.ObjectId;
+import org.eclipse.jgit.lib.Ref;
+import org.eclipse.jgit.lib.RefDatabase;
+import org.eclipse.jgit.lib.ReflogReader;
+import org.eclipse.jgit.transport.ReceiveCommand;
+
+/**
+ * Operations on {@link MergedReftable} that is common to various reftable-using
+ * subclasses of {@link RefDatabase}. See
+ * {@link org.eclipse.jgit.internal.storage.dfs.DfsReftableDatabase} for an
+ * example.
+ */
+public abstract class ReftableDatabase {
+ // Protects mergedTables.
+ private final ReentrantLock lock = new ReentrantLock(true);
+
+ private Reftable mergedTables;
+
+ /**
+ * ReftableDatabase lazily initializes its merged reftable on the first read after
+ * construction or clearCache() call. This function should always instantiate a new
+ * MergedReftable based on the list of reftables specified by the underlying storage.
+ *
+ * @return the ReftableStack for this instance
+ * @throws IOException
+ * on I/O problems.
+ */
+ protected abstract MergedReftable openMergedReftable() throws IOException;
+
+ /**
+ * @return the next available logical timestamp for an additional reftable
+ * in the stack.
+ * @throws java.io.IOException
+ * on I/O problems.
+ */
+ public long nextUpdateIndex() throws IOException {
+ lock.lock();
+ try {
+ return reader().maxUpdateIndex() + 1;
+ } finally {
+ lock.unlock();
+ }
+ }
+
+ /**
+ * @return a ReflogReader for the given ref
+ * @param refname
+ * the name of the ref.
+ * @throws IOException
+ * on I/O problems
+ */
+ public ReflogReader getReflogReader(String refname) throws IOException {
+ lock.lock();
+ try {
+ return new ReftableReflogReader(lock, reader(), refname);
+ } finally {
+ lock.unlock();
+ }
+ }
+
+ /**
+ * @return a ReceiveCommand for the change from oldRef to newRef
+ * @param oldRef
+ * a ref
+ * @param newRef
+ * a ref
+ */
+ public static ReceiveCommand toCommand(Ref oldRef, Ref newRef) {
+ ObjectId oldId = toId(oldRef);
+ ObjectId newId = toId(newRef);
+ String name = oldRef != null ? oldRef.getName() : newRef.getName();
+
+ if (oldRef != null && oldRef.isSymbolic()) {
+ if (newRef != null) {
+ if (newRef.isSymbolic()) {
+ return ReceiveCommand.link(oldRef.getTarget().getName(),
+ newRef.getTarget().getName(), name);
+ }
+ // This should pass in oldId for compat with
+ // RefDirectoryUpdate
+ return ReceiveCommand.unlink(oldRef.getTarget().getName(),
+ newId, name);
+ }
+ return ReceiveCommand.unlink(oldRef.getTarget().getName(),
+ ObjectId.zeroId(), name);
+ }
+
+ if (newRef != null && newRef.isSymbolic()) {
+ if (oldRef != null) {
+ if (oldRef.isSymbolic()) {
+ return ReceiveCommand.link(oldRef.getTarget().getName(),
+ newRef.getTarget().getName(), name);
+ }
+ return ReceiveCommand.link(oldId,
+ newRef.getTarget().getName(), name);
+ }
+ return ReceiveCommand.link(ObjectId.zeroId(),
+ newRef.getTarget().getName(), name);
+ }
+
+ return new ReceiveCommand(oldId, newId, name);
+ }
+
+ private static ObjectId toId(Ref ref) {
+ if (ref != null) {
+ ObjectId id = ref.getObjectId();
+ if (id != null) {
+ return id;
+ }
+ }
+ return ObjectId.zeroId();
+ }
+
+ /**
+ * @return the lock protecting underlying ReftableReaders against concurrent
+ * reads.
+ */
+ public ReentrantLock getLock() {
+ return lock;
+ }
+
+ /**
+ * @return the merged reftable that is implemented by the stack of
+ * reftables. Return value must be accessed under lock.
+ * @throws IOException
+ * on I/O problems
+ */
+ private Reftable reader() throws IOException {
+ if (!lock.isLocked()) {
+ throw new IllegalStateException(
+ "must hold lock to access merged table"); //$NON-NLS-1$
+ }
+ if (mergedTables == null) {
+ mergedTables = openMergedReftable();
+ }
+ return mergedTables;
+ }
+
+ /**
+ * @return whether the given refName would be illegal in a repository that
+ * uses loose refs.
+ * @param refName
+ * the name to check
+ * @param added
+ * a sorted set of refs we pretend have been added to the
+ * database.
+ * @param deleted
+ * a set of refs we pretend have been removed from the database.
+ * @throws IOException
+ * on I/O problems
+ */
+ public boolean isNameConflicting(String refName, TreeSet<String> added,
+ Set<String> deleted) throws IOException {
+ lock.lock();
+ try {
+ Reftable table = reader();
+
+ // Cannot be nested within an existing reference.
+ int lastSlash = refName.lastIndexOf('/');
+ while (0 < lastSlash) {
+ String prefix = refName.substring(0, lastSlash);
+ if (!deleted.contains(prefix)
+ && (table.hasRef(prefix) || added.contains(prefix))) {
+ return true;
+ }
+ lastSlash = refName.lastIndexOf('/', lastSlash - 1);
+ }
+
+ // Cannot be the container of an existing reference.
+ String prefix = refName + '/';
+ RefCursor c = table.seekRefsWithPrefix(prefix);
+ while (c.next()) {
+ if (!deleted.contains(c.getRef().getName())) {
+ return true;
+ }
+ }
+
+ String it = added.ceiling(refName + '/');
+ if (it != null && it.startsWith(prefix)) {
+ return true;
+ }
+ return false;
+ } finally {
+ lock.unlock();
+ }
+ }
+
+ /**
+ * Read a single reference.
+ * <p>
+ * This method expects an unshortened reference name and does not search
+ * using the standard search path.
+ *
+ * @param name
+ * the unabbreviated name of the reference.
+ * @return the reference (if it exists); else {@code null}.
+ * @throws java.io.IOException
+ * the reference space cannot be accessed.
+ */
+ @Nullable
+ public Ref exactRef(String name) throws IOException {
+ lock.lock();
+ try {
+ Reftable table = reader();
+ Ref ref = table.exactRef(name);
+ if (ref != null && ref.isSymbolic()) {
+ return table.resolve(ref);
+ }
+ return ref;
+ } finally {
+ lock.unlock();
+ }
+ }
+
+ /**
+ * Returns refs whose names start with a given prefix.
+ *
+ * @param prefix
+ * string that names of refs should start with; may be empty (to
+ * return all refs).
+ * @return immutable list of refs whose names start with {@code prefix}.
+ * @throws java.io.IOException
+ * the reference space cannot be accessed.
+ */
+ public List<Ref> getRefsByPrefix(String prefix) throws IOException {
+ List<Ref> all = new ArrayList<>();
+ lock.lock();
+ try {
+ Reftable table = reader();
+ try (RefCursor rc = RefDatabase.ALL.equals(prefix) ? table.allRefs()
+ : table.seekRefsWithPrefix(prefix)) {
+ while (rc.next()) {
+ Ref ref = table.resolve(rc.getRef());
+ if (ref != null && ref.getObjectId() != null) {
+ all.add(ref);
+ }
+ }
+ }
+ } finally {
+ lock.unlock();
+ }
+
+ return Collections.unmodifiableList(all);
+ }
+
+ /**
+ * @return whether there is a fast SHA1 to ref map.
+ * @throws IOException in case of I/O problems.
+ */
+ public boolean hasFastTipsWithSha1() throws IOException {
+ lock.lock();
+ try {
+ return reader().hasObjectMap();
+ } finally {
+ lock.unlock();
+ }
+ }
+
+ /**
+ * Returns all refs that resolve directly to the given {@link ObjectId}.
+ * Includes peeled {@linkObjectId}s.
+ *
+ * @param id
+ * {@link ObjectId} to resolve
+ * @return a {@link Set} of {@link Ref}s whose tips point to the provided
+ * id.
+ * @throws java.io.IOException
+ * on I/O errors.
+ */
+ public Set<Ref> getTipsWithSha1(ObjectId id) throws IOException {
+ lock.lock();
+ try {
+ RefCursor cursor = reader().byObjectId(id);
+ Set<Ref> refs = new HashSet<>();
+ while (cursor.next()) {
+ refs.add(cursor.getRef());
+ }
+ return refs;
+ } finally {
+ lock.unlock();
+ }
+ }
+
+ /**
+ * Drops all data that might be cached in memory.
+ */
+ public void clearCache() {
+ lock.lock();
+ try {
+ mergedTables = null;
+ } finally {
+ lock.unlock();
+ }
+ }
+}
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/reftable/ReftableReader.java b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/reftable/ReftableReader.java
index 4f0ff2d..3b912ea 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/reftable/ReftableReader.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/reftable/ReftableReader.java
@@ -78,7 +78,7 @@
* {@code ReftableReader} is not thread-safe. Concurrent readers need their own
* instance to read from the same file.
*/
-public class ReftableReader extends Reftable {
+public class ReftableReader extends Reftable implements AutoCloseable {
private final BlockSource src;
private int blockSize = -1;
@@ -128,16 +128,20 @@ public int blockSize() throws IOException {
return blockSize;
}
+ @Override
+ public boolean hasObjectMap() throws IOException {
+ if (objIndexPosition == -1) {
+ readFileFooter();
+ }
+
+ // We have the map, we have no refs, or the table is small.
+ return (objPosition > 0 || refEnd == 24 || refIndexPosition == 0);
+ }
+
/**
- * Get the minimum update index for log entries that appear in this
- * reftable.
- *
- * @return the minimum update index for log entries that appear in this
- * reftable. This should be 1 higher than the prior reftable's
- * {@code maxUpdateIndex} if this table is used in a stack.
- * @throws java.io.IOException
- * file cannot be read.
+ * {@inheritDoc}
*/
+ @Override
public long minUpdateIndex() throws IOException {
if (blockSize == -1) {
readFileHeader();
@@ -146,15 +150,9 @@ public long minUpdateIndex() throws IOException {
}
/**
- * Get the maximum update index for log entries that appear in this
- * reftable.
- *
- * @return the maximum update index for log entries that appear in this
- * reftable. This should be 1 higher than the prior reftable's
- * {@code maxUpdateIndex} if this table is used in a stack.
- * @throws java.io.IOException
- * file cannot be read.
+ * {@inheritDoc}
*/
+ @Override
public long maxUpdateIndex() throws IOException {
if (blockSize == -1) {
readFileHeader();
@@ -169,11 +167,13 @@ public RefCursor allRefs() throws IOException {
readFileHeader();
}
- long end = refEnd > 0 ? refEnd : (src.size() - FILE_FOOTER_LEN);
- src.adviseSequentialRead(0, end);
+ if (refEnd == 0) {
+ readFileFooter();
+ }
+ src.adviseSequentialRead(0, refEnd);
- RefCursorImpl i = new RefCursorImpl(end, null, false);
- i.block = readBlock(0, end);
+ RefCursorImpl i = new RefCursorImpl(refEnd, null, false);
+ i.block = readBlock(0, refEnd);
return i;
}
@@ -468,7 +468,7 @@ private BlockReader readBlock(long pos, long end) throws IOException {
BlockReader b = new BlockReader();
b.readBlock(src, pos, sz);
- if (b.type() == INDEX_BLOCK_TYPE && !b.truncated()) {
+ if (b.type() == INDEX_BLOCK_TYPE) {
if (indexCache == null) {
indexCache = new LongMap<>();
}
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/reftable/ReftableReflogReader.java b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/reftable/ReftableReflogReader.java
new file mode 100644
index 0000000..c75d3cf
--- /dev/null
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/reftable/ReftableReflogReader.java
@@ -0,0 +1,125 @@
+/*
+ * 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.internal.storage.reftable;
+
+import org.eclipse.jgit.lib.ReflogEntry;
+import org.eclipse.jgit.lib.ReflogReader;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.concurrent.locks.Lock;
+
+/**
+ * Implement the ReflogReader interface for a reflog stored in reftable.
+ */
+public class ReftableReflogReader implements ReflogReader {
+ private final Lock lock;
+
+ private final Reftable reftable;
+
+ private final String refname;
+
+ ReftableReflogReader(Lock lock, Reftable merged, String refname) {
+ this.lock = lock;
+ this.reftable = merged;
+ this.refname = refname;
+ }
+
+ /** {@inheritDoc} */
+ @Override
+ public ReflogEntry getLastEntry() throws IOException {
+ lock.lock();
+ try {
+ LogCursor cursor = reftable.seekLog(refname);
+ return cursor.next() ? cursor.getReflogEntry() : null;
+ } finally {
+ lock.unlock();
+ }
+ }
+
+ /** {@inheritDoc} */
+ @Override
+ public List<ReflogEntry> getReverseEntries() throws IOException {
+ return getReverseEntries(Integer.MAX_VALUE);
+ }
+
+ /** {@inheritDoc} */
+ @Override
+ public ReflogEntry getReverseEntry(int number) throws IOException {
+ lock.lock();
+ try {
+ LogCursor cursor = reftable.seekLog(refname);
+ while (true) {
+ if (!cursor.next() || number < 0) {
+ return null;
+ }
+ if (number == 0) {
+ return cursor.getReflogEntry();
+ }
+ number--;
+ }
+ } finally {
+ lock.unlock();
+ }
+ }
+
+ /** {@inheritDoc} */
+ @Override
+ public List<ReflogEntry> getReverseEntries(int max) throws IOException {
+ lock.lock();
+ try {
+ LogCursor cursor = reftable.seekLog(refname);
+
+ List<ReflogEntry> result = new ArrayList<>();
+ while (cursor.next() && result.size() < max) {
+ result.add(cursor.getReflogEntry());
+ }
+
+ return result;
+ } finally {
+ lock.unlock();
+ }
+ }
+}
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/reftable/ReftableWriter.java b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/reftable/ReftableWriter.java
index 6459c27..96f8cb1 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/reftable/ReftableWriter.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/reftable/ReftableWriter.java
@@ -108,6 +108,7 @@ public class ReftableWriter {
private long minUpdateIndex;
private long maxUpdateIndex;
+ private OutputStream outputStream;
private ReftableOutputStream out;
private ObjectIdSubclassMap<RefList> obj2ref;
@@ -122,21 +123,27 @@ public class ReftableWriter {
/**
* Initialize a writer with a default configuration.
+ *
+ * @param os
+ * output stream.
*/
- public ReftableWriter() {
- this(new ReftableConfig());
+ public ReftableWriter(OutputStream os) {
+ this(new ReftableConfig(), os);
lastRef = null;
lastLog = null;
}
/**
- * Initialize a writer with a specific configuration.
+ * Initialize a writer with a configuration.
*
* @param cfg
- * configuration for the writer.
+ * configuration for the writer
+ * @param os
+ * output stream.
*/
- public ReftableWriter(ReftableConfig cfg) {
+ public ReftableWriter(ReftableConfig cfg, OutputStream os) {
config = cfg;
+ outputStream = os;
}
/**
@@ -183,16 +190,16 @@ public ReftableWriter setMaxUpdateIndex(long max) {
}
/**
- * Begin writing the reftable.
+ * Begin writing the reftable. Should be called only once. Call this
+ * if a stream was passed to the constructor.
*
- * @param os
- * stream to write the table to. Caller is responsible for
- * closing the stream after invoking {@link #finish()}.
* @return {@code this}
- * @throws java.io.IOException
- * if reftable header cannot be written.
*/
- public ReftableWriter begin(OutputStream os) throws IOException {
+ public ReftableWriter begin() {
+ if (out != null) {
+ throw new IllegalStateException("begin() called twice.");//$NON-NLS-1$
+ }
+
refBlockSize = config.getRefBlockSize();
logBlockSize = config.getLogBlockSize();
restartInterval = config.getRestartInterval();
@@ -212,7 +219,7 @@ public ReftableWriter begin(OutputStream os) throws IOException {
restartInterval = refBlockSize < (60 << 10) ? 16 : 64;
}
- out = new ReftableOutputStream(os, refBlockSize, alignBlocks);
+ out = new ReftableOutputStream(outputStream, refBlockSize, alignBlocks);
refs = new Section(REF_BLOCK_TYPE);
if (indexObjects) {
obj2ref = new ObjectIdSubclassMap<>();
@@ -223,6 +230,7 @@ public ReftableWriter begin(OutputStream os) throws IOException {
/**
* Sort a collection of references and write them to the reftable.
+ * The input refs may not have duplicate names.
*
* @param refsToPack
* references to sort and write.
@@ -236,10 +244,16 @@ public ReftableWriter sortAndWriteRefs(Collection<Ref> refsToPack)
.map(r -> new RefEntry(r, maxUpdateIndex - minUpdateIndex))
.sorted(Entry::compare)
.iterator();
+ RefEntry last = null;
while (itr.hasNext()) {
RefEntry entry = itr.next();
+ if (last != null && Entry.compare(last, entry) == 0) {
+ throwIllegalEntry(last, entry);
+ }
+
long blockPos = refs.write(entry);
indexRef(entry.ref, blockPos);
+ last = entry;
}
return this;
}
@@ -288,7 +302,7 @@ public void writeRef(Ref ref, long updateIndex) throws IOException {
private void throwIllegalEntry(Entry last, Entry now) {
throw new IllegalArgumentException(MessageFormat.format(
- JGitText.get().refTableRecordsMustIncrease,
+ JGitText.get().reftableRecordsMustIncrease,
new String(last.key, UTF_8), new String(now.key, UTF_8)));
}
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/reftree/RefTreeBatch.java b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/reftree/RefTreeBatch.java
index da98e3f..9c5423f 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/reftree/RefTreeBatch.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/reftree/RefTreeBatch.java
@@ -102,9 +102,8 @@ public void execute(RevWalk rw, ProgressMonitor monitor)
if (isAtomic()) {
ReceiveCommand.abort(getCommands());
return;
- } else {
- continue;
}
+ continue;
}
}
todo.add(new Command(rw, c));
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/internal/transport/http/NetscapeCookieFileCache.java b/org.eclipse.jgit/src/org/eclipse/jgit/internal/transport/http/NetscapeCookieFileCache.java
index 882b2d0..39a67af 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/internal/transport/http/NetscapeCookieFileCache.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/internal/transport/http/NetscapeCookieFileCache.java
@@ -82,9 +82,8 @@ private NetscapeCookieFileCache(HttpConfig config) {
public static NetscapeCookieFileCache getInstance(HttpConfig config) {
if (instance == null) {
return new NetscapeCookieFileCache(config);
- } else {
- return instance;
}
+ return instance;
}
/**
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/internal/transport/ssh/OpenSshConfigFile.java b/org.eclipse.jgit/src/org/eclipse/jgit/internal/transport/ssh/OpenSshConfigFile.java
index c1e94a0..ee6adee 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/internal/transport/ssh/OpenSshConfigFile.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/internal/transport/ssh/OpenSshConfigFile.java
@@ -384,9 +384,8 @@ protected List<String> validate(String key, List<String> value) {
private static boolean isHostMatch(String pattern, String name) {
if (pattern.startsWith("!")) { //$NON-NLS-1$
return !patternMatchesHost(pattern.substring(1), name);
- } else {
- return patternMatchesHost(pattern, name);
}
+ return patternMatchesHost(pattern, name);
}
private static boolean patternMatchesHost(String pattern, String name) {
@@ -399,10 +398,9 @@ private static boolean patternMatchesHost(String pattern, String name) {
}
fn.append(name);
return fn.isMatch();
- } else {
- // Not a pattern but a full host name
- return pattern.equals(name);
}
+ // Not a pattern but a full host name
+ return pattern.equals(name);
}
private static String dequote(String value) {
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/lib/AnyObjectId.java b/org.eclipse.jgit/src/org/eclipse/jgit/lib/AnyObjectId.java
index 4f90e69..24850ee 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/lib/AnyObjectId.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/lib/AnyObjectId.java
@@ -302,10 +302,10 @@ public final boolean equals(AnyObjectId other) {
/** {@inheritDoc} */
@Override
public final boolean equals(Object o) {
- if (o instanceof AnyObjectId)
+ if (o instanceof AnyObjectId) {
return equals((AnyObjectId) o);
- else
- return false;
+ }
+ return false;
}
/**
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/lib/BaseRepositoryBuilder.java b/org.eclipse.jgit/src/org/eclipse/jgit/lib/BaseRepositoryBuilder.java
index 96e5066..98a46f3 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/lib/BaseRepositoryBuilder.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/lib/BaseRepositoryBuilder.java
@@ -103,25 +103,29 @@ private static boolean isSymRef(byte[] ref) {
private static File getSymRef(File workTree, File dotGit, FS fs)
throws IOException {
byte[] content = IO.readFully(dotGit);
- if (!isSymRef(content))
+ if (!isSymRef(content)) {
throw new IOException(MessageFormat.format(
JGitText.get().invalidGitdirRef, dotGit.getAbsolutePath()));
+ }
int pathStart = 8;
int lineEnd = RawParseUtils.nextLF(content, pathStart);
while (content[lineEnd - 1] == '\n' ||
- (content[lineEnd - 1] == '\r' && SystemReader.getInstance().isWindows()))
+ (content[lineEnd - 1] == '\r'
+ && SystemReader.getInstance().isWindows())) {
lineEnd--;
- if (lineEnd == pathStart)
+ }
+ if (lineEnd == pathStart) {
throw new IOException(MessageFormat.format(
JGitText.get().invalidGitdirRef, dotGit.getAbsolutePath()));
+ }
String gitdirPath = RawParseUtils.decode(content, pathStart, lineEnd);
File gitdirFile = fs.resolve(workTree, gitdirPath);
- if (gitdirFile.isAbsolute())
+ if (gitdirFile.isAbsolute()) {
return gitdirFile;
- else
- return new File(workTree, gitdirPath).getCanonicalFile();
+ }
+ return new File(workTree, gitdirPath).getCanonicalFile();
}
private FS fs;
@@ -723,9 +727,8 @@ protected Config loadConfig() throws IOException {
.getAbsolutePath(), err.getMessage()));
}
return cfg;
- } else {
- return new Config();
}
+ return new Config();
}
private File guessWorkTreeOrFail() throws IOException {
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/lib/BranchConfig.java b/org.eclipse.jgit/src/org/eclipse/jgit/lib/BranchConfig.java
index be53c4b..cad747b 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/lib/BranchConfig.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/lib/BranchConfig.java
@@ -232,9 +232,9 @@ private String findRemoteTrackingBranch(String remote, String mergeRef) {
private String getRemoteOrDefault() {
String remote = getRemote();
- if (remote == null)
+ if (remote == null) {
return Constants.DEFAULT_REMOTE_NAME;
- else
- return remote;
+ }
+ return remote;
}
}
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/lib/Config.java b/org.eclipse.jgit/src/org/eclipse/jgit/lib/Config.java
index d26b7fd..2ef3653 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/lib/Config.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/lib/Config.java
@@ -1407,12 +1407,11 @@ private static String readValue(StringReader in)
}
trailingSpaces.append(cc);
continue;
- } else {
- inLeadingSpace = false;
- if (trailingSpaces != null) {
- value.append(trailingSpaces);
- trailingSpaces.setLength(0);
- }
+ }
+ inLeadingSpace = false;
+ if (trailingSpaces != null) {
+ value.append(trailingSpaces);
+ trailingSpaces.setLength(0);
}
if ('\\' == c) {
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/lib/ConfigConstants.java b/org.eclipse.jgit/src/org/eclipse/jgit/lib/ConfigConstants.java
index 078bf78..99512a6 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/lib/ConfigConstants.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/lib/ConfigConstants.java
@@ -149,6 +149,18 @@ public final class ConfigConstants {
*/
public static final String CONFIG_KEY_GPGSIGN = "gpgSign";
+ /**
+ * The "hooksPath" key.
+ * @since 5.6
+ */
+ public static final String CONFIG_KEY_HOOKS_PATH = "hooksPath";
+
+ /**
+ * The "quotePath" key.
+ * @since 5.6
+ */
+ public static final String CONFIG_KEY_QUOTE_PATH = "quotePath";
+
/** The "algorithm" key */
public static final String CONFIG_KEY_ALGORITHM = "algorithm";
@@ -432,6 +444,12 @@ public final class ConfigConstants {
public static final String CONFIG_RENAMELIMIT_COPIES = "copies";
/**
+ * A "refStorage" value in the "extensions".
+ * @since 5.6.2
+ */
+ public static final String CONFIG_REF_STORAGE_REFTABLE = "reftable";
+
+ /**
* The "renames" key in the "diff" section
* @since 3.0
*/
@@ -526,9 +544,24 @@ public final class ConfigConstants {
*/
public static final String CONFIG_KEY_MIN_RACY_THRESHOLD = "minRacyThreshold";
+
+ /**
+ * The "refStorage" key
+ *
+ * @since 5.6.2
+ */
+ public static final String CONFIG_KEY_REF_STORAGE = "refStorage";
+
/**
* The "jmx" section
* @since 5.1.13
*/
public static final String CONFIG_JMX_SECTION = "jmx";
+
+ /**
+ * The "extensions" section
+ *
+ * @since 5.6.2
+ */
+ public static final String CONFIG_EXTENSIONS_SECTION = "extensions";
}
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/lib/Constants.java b/org.eclipse.jgit/src/org/eclipse/jgit/lib/Constants.java
index 9274fc6..3c05cab 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/lib/Constants.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/lib/Constants.java
@@ -281,6 +281,18 @@ public final class Constants {
*/
public static final String OBJECTS = "objects";
+ /**
+ * Reftable folder name
+ * @since 5.6
+ */
+ public static final String REFTABLE = "reftable";
+
+ /**
+ * Reftable table list name.
+ * @since 5.6.2
+ */
+ public static final String TABLES_LIST = "tables.list";
+
/** Info refs folder */
public static final String INFO_REFS = "info/refs";
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/lib/CoreConfig.java b/org.eclipse.jgit/src/org/eclipse/jgit/lib/CoreConfig.java
index 98de3a9..0056ad7 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/lib/CoreConfig.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/lib/CoreConfig.java
@@ -60,7 +60,7 @@ public class CoreConfig {
public static final Config.SectionParser<CoreConfig> KEY = CoreConfig::new;
/** Permissible values for {@code core.autocrlf}. */
- public static enum AutoCRLF {
+ public enum AutoCRLF {
/** Automatic CRLF->LF conversion is disabled. */
FALSE,
@@ -78,45 +78,45 @@ public static enum AutoCRLF {
*
* @since 4.3
*/
- public static enum EOL {
- /** checkin with LF, checkout with CRLF. */
+ public enum EOL {
+ /** Check in with LF, check out with CRLF. */
CRLF,
- /** checkin with LF, checkout without conversion. */
+ /** Check in with LF, check out without conversion. */
LF,
- /** use the platform's native line ending. */
+ /** Use the platform's native line ending. */
NATIVE;
}
/**
- * EOL stream conversion protocol
+ * EOL stream conversion protocol.
*
* @since 4.3
*/
- public static enum EolStreamType {
- /** convert to CRLF without binary detection */
+ public enum EolStreamType {
+ /** Convert to CRLF without binary detection. */
TEXT_CRLF,
- /** convert to LF without binary detection */
+ /** Convert to LF without binary detection. */
TEXT_LF,
- /** convert to CRLF with binary detection */
+ /** Convert to CRLF with binary detection. */
AUTO_CRLF,
- /** convert to LF with binary detection */
+ /** Convert to LF with binary detection. */
AUTO_LF,
- /** do not convert */
+ /** Do not convert. */
DIRECT;
}
/**
- * Permissible values for {@code core.checkstat}
+ * Permissible values for {@code core.checkstat}.
*
* @since 3.0
*/
- public static enum CheckStat {
+ public enum CheckStat {
/**
* Only check the size and whole second part of time stamp when
* comparing the stat info in the dircache with actual file stat info.
@@ -130,11 +130,30 @@ public static enum CheckStat {
DEFAULT
}
+ /**
+ * Permissible values for {@code core.logAllRefUpdates}.
+ *
+ * @since 5.6
+ */
+ public enum LogRefUpdates {
+ /** Don't create ref logs; default for bare repositories. */
+ FALSE,
+
+ /**
+ * Create ref logs for refs/heads/**, refs/remotes/**, refs/notes/**,
+ * and for HEAD. Default for non-bare repositories.
+ */
+ TRUE,
+
+ /** Create ref logs for all refs/** and for HEAD. */
+ ALWAYS
+ }
+
private final int compression;
private final int packIndexVersion;
- private final boolean logAllRefUpdates;
+ private final LogRefUpdates logAllRefUpdates;
private final String excludesfile;
@@ -145,24 +164,27 @@ public static enum CheckStat {
*
* @since 3.3
*/
- public static enum SymLinks {
- /** Checkout symbolic links as plain files */
+ public enum SymLinks {
+ /** Check out symbolic links as plain files . */
FALSE,
- /** Checkout symbolic links as links */
+
+ /** Check out symbolic links as links. */
TRUE
}
/**
- * Options for hiding files whose names start with a period
+ * Options for hiding files whose names start with a period.
*
* @since 3.5
*/
- public static enum HideDotFiles {
- /** Do not hide .files */
+ public enum HideDotFiles {
+ /** Do not hide .files. */
FALSE,
- /** Hide add .files */
+
+ /** Hide add .files. */
TRUE,
- /** Hide only .git */
+
+ /** Hide only .git. */
DOTGITONLY
}
@@ -171,8 +193,9 @@ private CoreConfig(Config rc) {
ConfigConstants.CONFIG_KEY_COMPRESSION, DEFAULT_COMPRESSION);
packIndexVersion = rc.getInt(ConfigConstants.CONFIG_PACK_SECTION,
ConfigConstants.CONFIG_KEY_INDEXVERSION, 2);
- logAllRefUpdates = rc.getBoolean(ConfigConstants.CONFIG_CORE_SECTION,
- ConfigConstants.CONFIG_KEY_LOGALLREFUPDATES, true);
+ logAllRefUpdates = rc.getEnum(ConfigConstants.CONFIG_CORE_SECTION, null,
+ ConfigConstants.CONFIG_KEY_LOGALLREFUPDATES,
+ LogRefUpdates.TRUE);
excludesfile = rc.getString(ConfigConstants.CONFIG_CORE_SECTION, null,
ConfigConstants.CONFIG_KEY_EXCLUDESFILE);
attributesfile = rc.getString(ConfigConstants.CONFIG_CORE_SECTION,
@@ -201,9 +224,14 @@ public int getPackIndexVersion() {
* Whether to log all refUpdates
*
* @return whether to log all refUpdates
+ * @deprecated since 5.6; default value depends on whether the repository is
+ * bare. Use
+ * {@link Config#getEnum(String, String, String, Enum)}
+ * directly.
*/
+ @Deprecated
public boolean isLogAllRefUpdates() {
- return logAllRefUpdates;
+ return !LogRefUpdates.FALSE.equals(logAllRefUpdates);
}
/**
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/lib/DefaultTypedConfigGetter.java b/org.eclipse.jgit/src/org/eclipse/jgit/lib/DefaultTypedConfigGetter.java
index e865da8..23e8de0 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/lib/DefaultTypedConfigGetter.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/lib/DefaultTypedConfigGetter.java
@@ -134,11 +134,9 @@ public <T extends Enum<?>> T getEnum(Config config, T[] all, String section,
throw new IllegalArgumentException(
MessageFormat.format(JGitText.get().enumValueNotSupported3,
section, subsection, name, value));
- } else {
- throw new IllegalArgumentException(
- MessageFormat.format(JGitText.get().enumValueNotSupported2,
- section, name, value));
}
+ throw new IllegalArgumentException(MessageFormat.format(
+ JGitText.get().enumValueNotSupported2, section, name, value));
}
/** {@inheritDoc} */
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/lib/IndexDiff.java b/org.eclipse.jgit/src/org/eclipse/jgit/lib/IndexDiff.java
index ce1eb59..cbb3e54 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/lib/IndexDiff.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/lib/IndexDiff.java
@@ -108,7 +108,7 @@ public class IndexDiff {
* @see IndexDiff#getConflictingStageStates()
* @since 3.0
*/
- public static enum StageState {
+ public enum StageState {
/**
* Exists in base, but neither in ours nor in theirs.
*/
@@ -243,11 +243,11 @@ public TreeFilter clone() {
}
}
- private final static int TREE = 0;
+ private static final int TREE = 0;
- private final static int INDEX = 1;
+ private static final int INDEX = 1;
- private final static int WORKDIR = 2;
+ private static final int WORKDIR = 2;
private final Repository repository;
@@ -384,7 +384,32 @@ public void setFilter(TreeFilter filter) {
* @throws java.io.IOException
*/
public boolean diff() throws IOException {
- return diff(null, 0, 0, ""); //$NON-NLS-1$
+ return diff(null);
+ }
+
+ /**
+ * Run the diff operation. Until this is called, all lists will be empty.
+ * Use
+ * {@link #diff(ProgressMonitor, int, int, String, RepositoryBuilderFactory)}
+ * if a progress monitor is required.
+ * <p>
+ * The operation may create repositories for submodules using builders
+ * provided by the given {@code factory}, if any, and will also close these
+ * submodule repositories again.
+ * </p>
+ *
+ * @param factory
+ * the {@link RepositoryBuilderFactory} to use to create builders
+ * to create submodule repositories, if needed; if {@code null},
+ * submodule repositories will be built using a plain
+ * {@link RepositoryBuilder}.
+ * @return if anything is different between index, tree, and workdir
+ * @throws java.io.IOException
+ * @since 5.6
+ */
+ public boolean diff(RepositoryBuilderFactory factory)
+ throws IOException {
+ return diff(null, 0, 0, "", factory); //$NON-NLS-1$
}
/**
@@ -410,6 +435,45 @@ public boolean diff() throws IOException {
public boolean diff(final ProgressMonitor monitor, int estWorkTreeSize,
int estIndexSize, final String title)
throws IOException {
+ return diff(monitor, estWorkTreeSize, estIndexSize, title, null);
+ }
+
+ /**
+ * Run the diff operation. Until this is called, all lists will be empty.
+ * <p>
+ * The operation may be aborted by the progress monitor. In that event it
+ * will report what was found before the cancel operation was detected.
+ * Callers should ignore the result if monitor.isCancelled() is true. If a
+ * progress monitor is not needed, callers should use {@link #diff()}
+ * instead. Progress reporting is crude and approximate and only intended
+ * for informing the user.
+ * </p>
+ * <p>
+ * The operation may create repositories for submodules using builders
+ * provided by the given {@code factory}, if any, and will also close these
+ * submodule repositories again.
+ * </p>
+ *
+ * @param monitor
+ * for reporting progress, may be null
+ * @param estWorkTreeSize
+ * number or estimated files in the working tree
+ * @param estIndexSize
+ * number of estimated entries in the cache
+ * @param title
+ * a {@link java.lang.String} object.
+ * @param factory
+ * the {@link RepositoryBuilderFactory} to use to create builders
+ * to create submodule repositories, if needed; if {@code null},
+ * submodule repositories will be built using a plain
+ * {@link RepositoryBuilder}.
+ * @return if anything is different between index, tree, and workdir
+ * @throws java.io.IOException
+ * @since 5.6
+ */
+ public boolean diff(ProgressMonitor monitor, int estWorkTreeSize,
+ int estIndexSize, String title, RepositoryBuilderFactory factory)
+ throws IOException {
dirCache = repository.readDirCache();
try (TreeWalk treeWalk = new TreeWalk(repository)) {
@@ -535,64 +599,69 @@ public boolean diff(final ProgressMonitor monitor, int estWorkTreeSize,
}
if (ignoreSubmoduleMode != IgnoreSubmoduleMode.ALL) {
- IgnoreSubmoduleMode localIgnoreSubmoduleMode = ignoreSubmoduleMode;
- SubmoduleWalk smw = SubmoduleWalk.forIndex(repository);
- while (smw.next()) {
- try {
- if (localIgnoreSubmoduleMode == null)
- localIgnoreSubmoduleMode = smw.getModulesIgnore();
- if (IgnoreSubmoduleMode.ALL
- .equals(localIgnoreSubmoduleMode))
- continue;
- } catch (ConfigInvalidException e) {
- throw new IOException(MessageFormat.format(
- JGitText.get().invalidIgnoreParamSubmodule,
- smw.getPath()), e);
- }
- try (Repository subRepo = smw.getRepository()) {
- String subRepoPath = smw.getPath();
- if (subRepo != null) {
- ObjectId subHead = subRepo.resolve("HEAD"); //$NON-NLS-1$
- if (subHead != null
- && !subHead.equals(smw.getObjectId())) {
- modified.add(subRepoPath);
- recordFileMode(subRepoPath, FileMode.GITLINK);
- } else if (ignoreSubmoduleMode != IgnoreSubmoduleMode.DIRTY) {
- IndexDiff smid = submoduleIndexDiffs.get(smw
- .getPath());
- if (smid == null) {
- smid = new IndexDiff(subRepo,
- smw.getObjectId(),
- wTreeIt.getWorkingTreeIterator(subRepo));
- submoduleIndexDiffs.put(subRepoPath, smid);
- }
- if (smid.diff()) {
- if (ignoreSubmoduleMode == IgnoreSubmoduleMode.UNTRACKED
- && smid.getAdded().isEmpty()
- && smid.getChanged().isEmpty()
- && smid.getConflicting().isEmpty()
- && smid.getMissing().isEmpty()
- && smid.getModified().isEmpty()
- && smid.getRemoved().isEmpty()) {
- continue;
- }
+ try (SubmoduleWalk smw = new SubmoduleWalk(repository)) {
+ smw.setTree(new DirCacheIterator(dirCache));
+ smw.setBuilderFactory(factory);
+ while (smw.next()) {
+ IgnoreSubmoduleMode localIgnoreSubmoduleMode = ignoreSubmoduleMode;
+ try {
+ if (localIgnoreSubmoduleMode == null)
+ localIgnoreSubmoduleMode = smw.getModulesIgnore();
+ if (IgnoreSubmoduleMode.ALL
+ .equals(localIgnoreSubmoduleMode))
+ continue;
+ } catch (ConfigInvalidException e) {
+ throw new IOException(MessageFormat.format(
+ JGitText.get().invalidIgnoreParamSubmodule,
+ smw.getPath()), e);
+ }
+ try (Repository subRepo = smw.getRepository()) {
+ String subRepoPath = smw.getPath();
+ if (subRepo != null) {
+ ObjectId subHead = subRepo.resolve("HEAD"); //$NON-NLS-1$
+ if (subHead != null
+ && !subHead.equals(smw.getObjectId())) {
modified.add(subRepoPath);
recordFileMode(subRepoPath, FileMode.GITLINK);
+ } else if (localIgnoreSubmoduleMode != IgnoreSubmoduleMode.DIRTY) {
+ IndexDiff smid = submoduleIndexDiffs
+ .get(smw.getPath());
+ if (smid == null) {
+ smid = new IndexDiff(subRepo,
+ smw.getObjectId(),
+ wTreeIt.getWorkingTreeIterator(
+ subRepo));
+ submoduleIndexDiffs.put(subRepoPath, smid);
+ }
+ if (smid.diff(factory)) {
+ if (localIgnoreSubmoduleMode == IgnoreSubmoduleMode.UNTRACKED
+ && smid.getAdded().isEmpty()
+ && smid.getChanged().isEmpty()
+ && smid.getConflicting().isEmpty()
+ && smid.getMissing().isEmpty()
+ && smid.getModified().isEmpty()
+ && smid.getRemoved().isEmpty()) {
+ continue;
+ }
+ modified.add(subRepoPath);
+ recordFileMode(subRepoPath,
+ FileMode.GITLINK);
+ }
}
- }
- } else if (missingSubmodules.remove(subRepoPath)) {
- // If the directory is there and empty but the submodule
- // repository in .git/modules doesn't exist yet it isn't
- // "missing".
- File gitDir = new File(
- new File(repository.getDirectory(),
- Constants.MODULES),
- subRepoPath);
- if (!gitDir.isDirectory()) {
- File dir = SubmoduleWalk.getSubmoduleDirectory(
- repository, subRepoPath);
- if (dir.isDirectory() && !hasFiles(dir)) {
- missing.remove(subRepoPath);
+ } else if (missingSubmodules.remove(subRepoPath)) {
+ // If the directory is there and empty but the
+ // submodule repository in .git/modules doesn't
+ // exist yet it isn't "missing".
+ File gitDir = new File(
+ new File(repository.getDirectory(),
+ Constants.MODULES),
+ subRepoPath);
+ if (!gitDir.isDirectory()) {
+ File dir = SubmoduleWalk.getSubmoduleDirectory(
+ repository, subRepoPath);
+ if (dir.isDirectory() && !hasFiles(dir)) {
+ missing.remove(subRepoPath);
+ }
}
}
}
@@ -602,16 +671,17 @@ public boolean diff(final ProgressMonitor monitor, int estWorkTreeSize,
}
// consume the remaining work
- if (monitor != null)
+ if (monitor != null) {
monitor.endTask();
+ }
ignored = indexDiffFilter.getIgnoredPaths();
if (added.isEmpty() && changed.isEmpty() && removed.isEmpty()
&& missing.isEmpty() && modified.isEmpty()
- && untracked.isEmpty())
+ && untracked.isEmpty()) {
return false;
- else
- return true;
+ }
+ return true;
}
private boolean hasFiles(File directory) {
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/lib/InflaterCache.java b/org.eclipse.jgit/src/org/eclipse/jgit/lib/InflaterCache.java
index dd0f18e..314bde2 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/lib/InflaterCache.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/lib/InflaterCache.java
@@ -73,7 +73,7 @@ public static Inflater get() {
return r != null ? r : new Inflater(false);
}
- private synchronized static Inflater getImpl() {
+ private static synchronized Inflater getImpl() {
if (openInflaterCount > 0) {
final Inflater r = inflaterCache[--openInflaterCount];
inflaterCache[openInflaterCount] = null;
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/lib/ObjectIdOwnerMap.java b/org.eclipse.jgit/src/org/eclipse/jgit/lib/ObjectIdOwnerMap.java
index 74c712c..8730d66 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/lib/ObjectIdOwnerMap.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/lib/ObjectIdOwnerMap.java
@@ -355,7 +355,7 @@ private static final boolean equals(AnyObjectId firstObjectId,
}
/** Type of entry stored in the {@link ObjectIdOwnerMap}. */
- public static abstract class Entry extends ObjectId {
+ public abstract static class Entry extends ObjectId {
transient Entry next;
/**
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/lib/ObjectInserter.java b/org.eclipse.jgit/src/org/eclipse/jgit/lib/ObjectInserter.java
index 77fa1b2..edbb4b1 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/lib/ObjectInserter.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/lib/ObjectInserter.java
@@ -98,7 +98,7 @@ public void close() {
}
/** Wraps a delegate ObjectInserter. */
- public static abstract class Filter extends ObjectInserter {
+ public abstract static class Filter extends ObjectInserter {
/** @return delegate ObjectInserter to handle all processing. */
protected abstract ObjectInserter delegate();
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/lib/ObjectLoader.java b/org.eclipse.jgit/src/org/eclipse/jgit/lib/ObjectLoader.java
index 2e52f03..b473421 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/lib/ObjectLoader.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/lib/ObjectLoader.java
@@ -333,7 +333,7 @@ public ObjectStream openStream() {
*
* @since 4.10
*/
- public static abstract class Filter extends ObjectLoader {
+ public abstract static class Filter extends ObjectLoader {
/**
* @return delegate ObjectLoader to handle all processing.
* @since 4.10
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/lib/ObjectReader.java b/org.eclipse.jgit/src/org/eclipse/jgit/lib/ObjectReader.java
index 700b9db..6d54467 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/lib/ObjectReader.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/lib/ObjectReader.java
@@ -293,9 +293,8 @@ public boolean next() throws MissingObjectException, IOException {
if (idItr.hasNext()) {
cur = idItr.next();
return true;
- } else {
- return false;
}
+ return false;
}
@Override
@@ -383,9 +382,8 @@ public boolean next() throws MissingObjectException, IOException {
cur = idItr.next();
sz = getObjectSize(cur, OBJ_ANY);
return true;
- } else {
- return false;
}
+ return false;
}
@Override
@@ -497,7 +495,7 @@ public int getStreamFileThreshold() {
*
* @since 4.4
*/
- public static abstract class Filter extends ObjectReader {
+ public abstract static class Filter extends ObjectReader {
/**
* @return delegate ObjectReader to handle all processing.
* @since 4.4
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/lib/RebaseTodoLine.java b/org.eclipse.jgit/src/org/eclipse/jgit/lib/RebaseTodoLine.java
index 4e235b0..f893fd1 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/lib/RebaseTodoLine.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/lib/RebaseTodoLine.java
@@ -58,7 +58,7 @@ public class RebaseTodoLine {
* Describes rebase actions
*/
@SuppressWarnings("nls")
- public static enum Action {
+ public enum Action {
/** Use commit */
PICK("pick", "p"),
@@ -105,7 +105,7 @@ public String toString() {
* @param token
* @return the Action
*/
- static public Action parse(String token) {
+ public static Action parse(String token) {
for (Action action : Action.values()) {
if (action.token.equals(token)
|| action.shortToken.equals(token))
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/lib/RefDatabase.java b/org.eclipse.jgit/src/org/eclipse/jgit/lib/RefDatabase.java
index 4d9450e..9b5a1fd 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/lib/RefDatabase.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/lib/RefDatabase.java
@@ -497,6 +497,20 @@ public Set<Ref> getTipsWithSha1(ObjectId id) throws IOException {
}
/**
+ * If the ref database does not support fast inverse queries, it may
+ * be advantageous to build a complete SHA1 to ref map in advance for
+ * multiple uses. To let applications decide on this decision,
+ * this function indicates whether the inverse map is available.
+ *
+ * @return whether this RefDatabase supports fast inverse ref queries.
+ * @throws IOException on I/O problems.
+ * @since 5.6
+ */
+ public boolean hasFastTipsWithSha1() throws IOException {
+ return false;
+ }
+
+ /**
* Check if any refs exist in the ref database.
* <p>
* This uses the same definition of refs as {@link #getRefs()}. In
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/lib/RefUpdate.java b/org.eclipse.jgit/src/org/eclipse/jgit/lib/RefUpdate.java
index eca15c0..eb5e139 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/lib/RefUpdate.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/lib/RefUpdate.java
@@ -66,7 +66,7 @@ public abstract class RefUpdate {
* unknown values are failures, and may generally treat them the same as
* {@link #REJECTED_OTHER_REASON}.
*/
- public static enum Result {
+ public enum Result {
/** The ref update/delete has not been attempted by the caller. */
NOT_ATTEMPTED,
@@ -827,7 +827,7 @@ private static RevObject safeParseOld(RevWalk rw, AnyObjectId oldId)
* Handle the abstraction of storing a ref update. This is because both
* updating and deleting of a ref have merge testing in common.
*/
- private static abstract class Store {
+ private abstract static class Store {
abstract Result execute(Result status) throws IOException;
}
}
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/lib/Repository.java b/org.eclipse.jgit/src/org/eclipse/jgit/lib/Repository.java
index 68866ea..0e9cf58 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/lib/Repository.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/lib/Repository.java
@@ -503,9 +503,8 @@ public ObjectId resolve(String revstr)
if (resolved instanceof String) {
final Ref ref = findRef((String) resolved);
return ref != null ? ref.getLeaf().getObjectId() : null;
- } else {
- return (ObjectId) resolved;
}
+ return (ObjectId) resolved;
}
}
@@ -527,11 +526,12 @@ public String simplify(String revstr)
try (RevWalk rw = new RevWalk(this)) {
rw.setRetainBody(true);
Object resolved = resolve(rw, revstr);
- if (resolved != null)
- if (resolved instanceof String)
+ if (resolved != null) {
+ if (resolved instanceof String) {
return (String) resolved;
- else
- return ((AnyObjectId) resolved).getName();
+ }
+ return ((AnyObjectId) resolved).getName();
+ }
return null;
}
}
@@ -760,15 +760,15 @@ private Object resolve(RevWalk rw, String revstr)
if (name == null)
throw new RevisionSyntaxException(revstr);
} else if (time.matches("^-\\d+$")) { //$NON-NLS-1$
- if (name != null)
+ if (name != null) {
throw new RevisionSyntaxException(revstr);
- else {
- String previousCheckout = resolveReflogCheckout(-Integer
- .parseInt(time));
- if (ObjectId.isId(previousCheckout))
- rev = parseSimple(rw, previousCheckout);
- else
- name = previousCheckout;
+ }
+ String previousCheckout = resolveReflogCheckout(
+ -Integer.parseInt(time));
+ if (ObjectId.isId(previousCheckout)) {
+ rev = parseSimple(rw, previousCheckout);
+ } else {
+ name = previousCheckout;
}
} else {
if (name == null)
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/lib/RepositoryBuilderFactory.java b/org.eclipse.jgit/src/org/eclipse/jgit/lib/RepositoryBuilderFactory.java
new file mode 100644
index 0000000..fc12516
--- /dev/null
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/lib/RepositoryBuilderFactory.java
@@ -0,0 +1,27 @@
+/*
+ * Copyright (c) 2019, Thomas Wolf <thomas.wolf@paranor.ch> and others
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+package org.eclipse.jgit.lib;
+
+import java.util.function.Supplier;
+
+/**
+ * A factory for {@link BaseRepositoryBuilder}s.
+ * <p>
+ * Note that a {@link BaseRepositoryBuilder} should be used only once to build a
+ * repository. Otherwise subsequently built repositories may be built using
+ * settings made for earlier built repositories.
+ * </p>
+ *
+ * @since 5.6
+ */
+public interface RepositoryBuilderFactory extends
+ Supplier<BaseRepositoryBuilder<? extends BaseRepositoryBuilder, ? extends Repository>> {
+ // Empty
+}
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/lib/RepositoryCache.java b/org.eclipse.jgit/src/org/eclipse/jgit/lib/RepositoryCache.java
index fa113bf..5a6063e 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/lib/RepositoryCache.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/lib/RepositoryCache.java
@@ -66,7 +66,7 @@
* Cache of active {@link org.eclipse.jgit.lib.Repository} instances.
*/
public class RepositoryCache {
- private final static Logger LOG = LoggerFactory
+ private static final Logger LOG = LoggerFactory
.getLogger(RepositoryCache.class);
private static final RepositoryCache cache = new RepositoryCache();
@@ -476,7 +476,8 @@ public String toString() {
public static boolean isGitRepository(File dir, FS fs) {
return fs.resolve(dir, Constants.OBJECTS).exists()
&& fs.resolve(dir, "refs").exists() //$NON-NLS-1$
- && isValidHead(new File(dir, Constants.HEAD));
+ && (fs.resolve(dir, Constants.REFTABLE).exists()
+ || isValidHead(new File(dir, Constants.HEAD)));
}
private static boolean isValidHead(File head) {
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/lib/internal/BouncyCastleGpgKeyLocator.java b/org.eclipse.jgit/src/org/eclipse/jgit/lib/internal/BouncyCastleGpgKeyLocator.java
index 11db7c5..f28334c 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/lib/internal/BouncyCastleGpgKeyLocator.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/lib/internal/BouncyCastleGpgKeyLocator.java
@@ -72,12 +72,14 @@
import org.bouncycastle.gpg.keybox.UserID;
import org.bouncycastle.gpg.keybox.jcajce.JcaKeyBoxBuilder;
import org.bouncycastle.openpgp.PGPException;
+import org.bouncycastle.openpgp.PGPKeyFlags;
import org.bouncycastle.openpgp.PGPPublicKey;
import org.bouncycastle.openpgp.PGPPublicKeyRing;
import org.bouncycastle.openpgp.PGPPublicKeyRingCollection;
import org.bouncycastle.openpgp.PGPSecretKey;
import org.bouncycastle.openpgp.PGPSecretKeyRing;
import org.bouncycastle.openpgp.PGPSecretKeyRingCollection;
+import org.bouncycastle.openpgp.PGPSignature;
import org.bouncycastle.openpgp.PGPUtil;
import org.bouncycastle.openpgp.operator.PBEProtectionRemoverFactory;
import org.bouncycastle.openpgp.operator.PGPDigestCalculatorProvider;
@@ -90,6 +92,7 @@
import org.eclipse.jgit.errors.UnsupportedCredentialItem;
import org.eclipse.jgit.internal.JGitText;
import org.eclipse.jgit.util.FS;
+import org.eclipse.jgit.util.StringUtils;
import org.eclipse.jgit.util.SystemReader;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -190,19 +193,92 @@ private PGPSecretKey attemptParseSecretKey(Path keyFile,
}
}
- private boolean containsSigningKey(String userId) {
- return userId.toLowerCase(Locale.ROOT)
- .contains(signingKey.toLowerCase(Locale.ROOT));
+ /**
+ * Checks whether a given OpenPGP {@code userId} matches a given
+ * {@code signingKeySpec}, which is supposed to have one of the formats
+ * defined by GPG.
+ * <p>
+ * Not all formats are supported; only formats starting with '=', '<',
+ * '@', and '*' are handled. Any other format results in a case-insensitive
+ * substring match.
+ * </p>
+ *
+ * @param userId
+ * of a key
+ * @param signingKeySpec
+ * GPG key identification
+ * @return whether the {@code userId} matches
+ * @see <a href=
+ * "https://www.gnupg.org/documentation/manuals/gnupg/Specify-a-User-ID.html">GPG
+ * Documentation: How to Specify a User ID</a>
+ */
+ static boolean containsSigningKey(String userId, String signingKeySpec) {
+ if (StringUtils.isEmptyOrNull(userId)
+ || StringUtils.isEmptyOrNull(signingKeySpec)) {
+ return false;
+ }
+ String toMatch = signingKeySpec;
+ if (toMatch.startsWith("0x") && toMatch.trim().length() > 2) { //$NON-NLS-1$
+ return false; // Explicit fingerprint
+ }
+ int command = toMatch.charAt(0);
+ switch (command) {
+ case '=':
+ case '<':
+ case '@':
+ case '*':
+ toMatch = toMatch.substring(1);
+ if (toMatch.isEmpty()) {
+ return false;
+ }
+ break;
+ default:
+ break;
+ }
+ switch (command) {
+ case '=':
+ return userId.equals(toMatch);
+ case '<': {
+ int begin = userId.indexOf('<');
+ int end = userId.indexOf('>', begin + 1);
+ int stop = toMatch.indexOf('>');
+ return begin >= 0 && end > begin + 1 && stop > 0
+ && userId.substring(begin + 1, end)
+ .equals(toMatch.substring(0, stop));
+ }
+ case '@': {
+ int begin = userId.indexOf('<');
+ int end = userId.indexOf('>', begin + 1);
+ return begin >= 0 && end > begin + 1
+ && userId.substring(begin + 1, end).contains(toMatch);
+ }
+ default:
+ if (toMatch.trim().isEmpty()) {
+ return false;
+ }
+ return userId.toLowerCase(Locale.ROOT)
+ .contains(toMatch.toLowerCase(Locale.ROOT));
+ }
+ }
+
+ private String toFingerprint(String keyId) {
+ if (keyId.startsWith("0x")) { //$NON-NLS-1$
+ return keyId.substring(2);
+ }
+ return keyId;
}
private PGPPublicKey findPublicKeyByKeyId(KeyBlob keyBlob)
throws IOException {
- String keyId = signingKey.toLowerCase(Locale.ROOT);
+ String keyId = toFingerprint(signingKey).toLowerCase(Locale.ROOT);
+ if (keyId.isEmpty()) {
+ return null;
+ }
for (KeyInformation keyInfo : keyBlob.getKeyInformation()) {
String fingerprint = Hex.toHexString(keyInfo.getFingerprint())
.toLowerCase(Locale.ROOT);
if (fingerprint.endsWith(keyId)) {
- return getFirstPublicKey(keyBlob);
+ return getPublicKey(keyBlob, keyInfo.getFingerprint());
}
}
return null;
@@ -211,8 +287,8 @@ private PGPPublicKey findPublicKeyByKeyId(KeyBlob keyBlob)
private PGPPublicKey findPublicKeyByUserId(KeyBlob keyBlob)
throws IOException {
for (UserID userID : keyBlob.getUserIds()) {
- if (containsSigningKey(userID.getUserIDAsString())) {
- return getFirstPublicKey(keyBlob);
+ if (containsSigningKey(userID.getUserIDAsString(), signingKey)) {
+ return getSigningPublicKey(keyBlob);
}
}
return null;
@@ -444,7 +520,7 @@ private PGPSecretKey findSecretKeyInLegacySecring(String signingkey,
PGPUtil.getDecoderStream(new BufferedInputStream(in)),
new JcaKeyFingerprintCalculator());
- String keyId = signingkey.toLowerCase(Locale.ROOT);
+ String keyId = toFingerprint(signingkey).toLowerCase(Locale.ROOT);
Iterator<PGPSecretKeyRing> keyrings = pgpSec.getKeyRings();
while (keyrings.hasNext()) {
PGPSecretKeyRing keyRing = keyrings.next();
@@ -462,7 +538,7 @@ private PGPSecretKey findSecretKeyInLegacySecring(String signingkey,
Iterator<String> userIDs = key.getUserIDs();
while (userIDs.hasNext()) {
String userId = userIDs.next();
- if (containsSigningKey(userId)) {
+ if (containsSigningKey(userId, signingKey)) {
return key;
}
}
@@ -490,7 +566,7 @@ private PGPPublicKey findPublicKeyInPubring(Path pubringFile)
new BufferedInputStream(in),
new JcaKeyFingerprintCalculator());
- String keyId = signingKey.toLowerCase(Locale.ROOT);
+ String keyId = toFingerprint(signingKey).toLowerCase(Locale.ROOT);
Iterator<PGPPublicKeyRing> keyrings = pgpPub.getKeyRings();
while (keyrings.hasNext()) {
PGPPublicKeyRing keyRing = keyrings.next();
@@ -507,7 +583,7 @@ private PGPPublicKey findPublicKeyInPubring(Path pubringFile)
Iterator<String> userIDs = key.getUserIDs();
while (userIDs.hasNext()) {
String userId = userIDs.next();
- if (containsSigningKey(userId)) {
+ if (containsSigningKey(userId, signingKey)) {
return key;
}
}
@@ -517,9 +593,42 @@ private PGPPublicKey findPublicKeyInPubring(Path pubringFile)
return null;
}
- private PGPPublicKey getFirstPublicKey(KeyBlob keyBlob) throws IOException {
- return ((PublicKeyRingBlob) keyBlob).getPGPPublicKeyRing()
- .getPublicKey();
+ private PGPPublicKey getPublicKey(KeyBlob blob, byte[] fingerprint)
+ throws IOException {
+ return ((PublicKeyRingBlob) blob).getPGPPublicKeyRing()
+ .getPublicKey(fingerprint);
+ }
+
+ private PGPPublicKey getSigningPublicKey(KeyBlob blob) throws IOException {
+ PGPPublicKey masterKey = null;
+ Iterator<PGPPublicKey> keys = ((PublicKeyRingBlob) blob)
+ .getPGPPublicKeyRing().getPublicKeys();
+ while (keys.hasNext()) {
+ PGPPublicKey key = keys.next();
+ // only consider keys that have the [S] usage flag set
+ if (isSigningKey(key)) {
+ if (key.isMasterKey()) {
+ masterKey = key;
+ } else {
+ return key;
+ }
+ }
+ }
+ // return the master key if no other signing key was found or null if
+ // the master key did not have the signing flag set
+ return masterKey;
+ }
+
+ private boolean isSigningKey(PGPPublicKey key) {
+ Iterator signatures = key.getSignatures();
+ while (signatures.hasNext()) {
+ PGPSignature sig = (PGPSignature) signatures.next();
+ if ((sig.getHashedSubPackets().getKeyFlags()
+ & PGPKeyFlags.CAN_SIGN) > 0) {
+ return true;
+ }
+ }
+ return false;
}
private KeyBox readKeyBoxFile(Path keyboxFile) throws IOException,
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/lib/internal/BouncyCastleGpgSigner.java b/org.eclipse.jgit/src/org/eclipse/jgit/lib/internal/BouncyCastleGpgSigner.java
index cfe0931..cfa67ee 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/lib/internal/BouncyCastleGpgSigner.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/lib/internal/BouncyCastleGpgSigner.java
@@ -115,7 +115,7 @@ private BouncyCastleGpgKey locateSigningKey(@Nullable String gpgSigningKey,
NoSuchAlgorithmException, NoSuchProviderException, PGPException,
URISyntaxException {
if (gpgSigningKey == null || gpgSigningKey.isEmpty()) {
- gpgSigningKey = committer.getEmailAddress();
+ gpgSigningKey = '<' + committer.getEmailAddress() + '>';
}
BouncyCastleGpgKeyLocator keyHelper = new BouncyCastleGpgKeyLocator(
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/merge/MergeAlgorithm.java b/org.eclipse.jgit/src/org/eclipse/jgit/merge/MergeAlgorithm.java
index a77cb4f..3ff38dc 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/merge/MergeAlgorithm.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/merge/MergeAlgorithm.java
@@ -83,7 +83,7 @@ public MergeAlgorithm(DiffAlgorithm diff) {
// An special edit which acts as a sentinel value by marking the end the
// list of edits
- private final static Edit END_EDIT = new Edit(Integer.MAX_VALUE,
+ private static final Edit END_EDIT = new Edit(Integer.MAX_VALUE,
Integer.MAX_VALUE);
@SuppressWarnings("ReferenceEquality")
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/merge/MergeConfig.java b/org.eclipse.jgit/src/org/eclipse/jgit/merge/MergeConfig.java
index cdbe3cd..12f353e 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/merge/MergeConfig.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/merge/MergeConfig.java
@@ -166,10 +166,10 @@ private static boolean isMergeConfigOptionSet(String optionToLookFor,
String mergeOptions = config.getString(
ConfigConstants.CONFIG_BRANCH_SECTION, branch,
ConfigConstants.CONFIG_KEY_MERGEOPTIONS);
- if (mergeOptions != null)
+ if (mergeOptions != null) {
return mergeOptions.split("\\s"); //$NON-NLS-1$
- else
- return new String[0];
+ }
+ return new String[0];
}
private static class MergeConfigSectionParser implements
@@ -188,10 +188,10 @@ public MergeConfig parse(Config cfg) {
@Override
public boolean equals(Object obj) {
- if (obj instanceof MergeConfigSectionParser)
+ if (obj instanceof MergeConfigSectionParser) {
return branch.equals(((MergeConfigSectionParser) obj).branch);
- else
- return false;
+ }
+ return false;
}
@Override
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/merge/MergeMessageFormatter.java b/org.eclipse.jgit/src/org/eclipse/jgit/merge/MergeMessageFormatter.java
index ca0e18a..ca2f37a 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/merge/MergeMessageFormatter.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/merge/MergeMessageFormatter.java
@@ -153,15 +153,16 @@ public String formatWithConflicts(String message,
private static void addConflictsMessage(List<String> conflictingPaths,
StringBuilder sb) {
sb.append("Conflicts:\n"); //$NON-NLS-1$
- for (String conflictingPath : conflictingPaths)
+ for (String conflictingPath : conflictingPaths) {
sb.append('\t').append(conflictingPath).append('\n');
+ }
}
private static String joinNames(List<String> names, String singular,
String plural) {
- if (names.size() == 1)
+ if (names.size() == 1) {
return singular + " " + names.get(0); //$NON-NLS-1$
- else
- return plural + " " + StringUtils.join(names, ", ", " and "); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+ }
+ return plural + " " + StringUtils.join(names, ", ", " and "); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
}
}
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/merge/ResolveMerger.java b/org.eclipse.jgit/src/org/eclipse/jgit/merge/ResolveMerger.java
index 0b423fb..34b521e 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/merge/ResolveMerger.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/merge/ResolveMerger.java
@@ -143,7 +143,7 @@ public enum MergeFailureReason {
*
* @since 3.0
*/
- protected String commitNames[];
+ protected String[] commitNames;
/**
* Index of the base tree within the {@link #tw tree walk}.
@@ -652,42 +652,40 @@ protected boolean processEntry(CanonicalTreeParser base,
keep(ourDce);
// no checkout needed!
return true;
- } else {
- // same content but different mode on OURS and THEIRS.
- // Try to merge the mode and report an error if this is
- // not possible.
- int newMode = mergeFileModes(modeB, modeO, modeT);
- if (newMode != FileMode.MISSING.getBits()) {
- if (newMode == modeO)
- // ours version is preferred
- keep(ourDce);
- else {
- // the preferred version THEIRS has a different mode
- // than ours. Check it out!
- if (isWorktreeDirty(work, ourDce))
- return false;
- // we know about length and lastMod only after we have written the new content.
- // This will happen later. Set these values to 0 for know.
- DirCacheEntry e = add(tw.getRawPath(), theirs,
- DirCacheEntry.STAGE_0, EPOCH, 0);
- addToCheckout(tw.getPathString(), e, attributes);
- }
- return true;
+ }
+ // same content but different mode on OURS and THEIRS.
+ // Try to merge the mode and report an error if this is
+ // not possible.
+ int newMode = mergeFileModes(modeB, modeO, modeT);
+ if (newMode != FileMode.MISSING.getBits()) {
+ if (newMode == modeO) {
+ // ours version is preferred
+ keep(ourDce);
} else {
- // FileModes are not mergeable. We found a conflict on modes.
- // For conflicting entries we don't know lastModified and length.
- add(tw.getRawPath(), base, DirCacheEntry.STAGE_1, EPOCH, 0);
- add(tw.getRawPath(), ours, DirCacheEntry.STAGE_2, EPOCH, 0);
- add(tw.getRawPath(), theirs, DirCacheEntry.STAGE_3, EPOCH,
- 0);
- unmergedPaths.add(tw.getPathString());
- mergeResults.put(
- tw.getPathString(),
- new MergeResult<>(Collections
- .<RawText> emptyList()));
+ // the preferred version THEIRS has a different mode
+ // than ours. Check it out!
+ if (isWorktreeDirty(work, ourDce)) {
+ return false;
+ }
+ // we know about length and lastMod only after we have
+ // written the new content.
+ // This will happen later. Set these values to 0 for know.
+ DirCacheEntry e = add(tw.getRawPath(), theirs,
+ DirCacheEntry.STAGE_0, EPOCH, 0);
+ addToCheckout(tw.getPathString(), e, attributes);
}
return true;
}
+ // FileModes are not mergeable. We found a conflict on modes.
+ // For conflicting entries we don't know lastModified and
+ // length.
+ add(tw.getRawPath(), base, DirCacheEntry.STAGE_1, EPOCH, 0);
+ add(tw.getRawPath(), ours, DirCacheEntry.STAGE_2, EPOCH, 0);
+ add(tw.getRawPath(), theirs, DirCacheEntry.STAGE_3, EPOCH, 0);
+ unmergedPaths.add(tw.getPathString());
+ mergeResults.put(tw.getPathString(),
+ new MergeResult<>(Collections.<RawText> emptyList()));
+ return true;
}
if (modeB == modeT && tw.idEqual(T_BASE, T_THEIRS)) {
@@ -716,21 +714,20 @@ protected boolean processEntry(CanonicalTreeParser base,
addToCheckout(tw.getPathString(), e, attributes);
}
return true;
- } else {
- // we want THEIRS ... but THEIRS contains a folder or the
- // deletion of the path. Delete what's in the working tree,
- // which we know to be clean.
- if (tw.getTreeCount() > T_FILE && tw.getRawMode(T_FILE) == 0) {
- // Not present in working tree, so nothing to delete
- return true;
- }
- if (modeT != 0 && modeT == modeB) {
- // Base, ours, and theirs all contain a folder: don't delete
- return true;
- }
- addDeletion(tw.getPathString(), nonTree(modeO), attributes);
+ }
+ // we want THEIRS ... but THEIRS contains a folder or the
+ // deletion of the path. Delete what's in the working tree,
+ // which we know to be clean.
+ if (tw.getTreeCount() > T_FILE && tw.getRawMode(T_FILE) == 0) {
+ // Not present in working tree, so nothing to delete
return true;
}
+ if (modeT != 0 && modeT == modeB) {
+ // Base, ours, and theirs all contain a folder: don't delete
+ return true;
+ }
+ addDeletion(tw.getPathString(), nonTree(modeO), attributes);
+ return true;
}
if (tw.isSubtree()) {
@@ -1310,10 +1307,9 @@ protected boolean mergeTrees(AbstractTreeIterator baseTree,
if (getUnmergedPaths().isEmpty() && !failed()) {
resultTree = dircache.writeTree(getObjectInserter());
return true;
- } else {
- resultTree = null;
- return false;
}
+ resultTree = null;
+ return false;
}
/**
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/merge/ThreeWayMerger.java b/org.eclipse.jgit/src/org/eclipse/jgit/merge/ThreeWayMerger.java
index 2fc0f4f..d56e5c0 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/merge/ThreeWayMerger.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/merge/ThreeWayMerger.java
@@ -143,17 +143,17 @@ public ObjectId getBaseCommitId() {
* @throws java.io.IOException
*/
protected AbstractTreeIterator mergeBase() throws IOException {
- if (baseTree != null)
+ if (baseTree != null) {
return openTree(baseTree);
+ }
RevCommit baseCommit = (baseCommitId != null) ? walk
.parseCommit(baseCommitId) : getBaseCommit(sourceCommits[0],
sourceCommits[1]);
if (baseCommit == null) {
baseCommitId = null;
return new EmptyTreeIterator();
- } else {
- baseCommitId = baseCommit.toObjectId();
- return openTree(baseCommit.getTree());
}
+ baseCommitId = baseCommit.toObjectId();
+ return openTree(baseCommit.getTree());
}
}
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/nls/NLS.java b/org.eclipse.jgit/src/org/eclipse/jgit/nls/NLS.java
index 375cd32..d9fb1b3 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/nls/NLS.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/nls/NLS.java
@@ -133,8 +133,8 @@ public static <T extends TranslationBundle> T getBundleFor(Class<T> type) {
return b.get(type);
}
- final private Locale locale;
- final private ConcurrentHashMap<Class, TranslationBundle> map = new ConcurrentHashMap<>();
+ private final Locale locale;
+ private final ConcurrentHashMap<Class, TranslationBundle> map = new ConcurrentHashMap<>();
private NLS(Locale locale) {
this.locale = locale;
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/notes/FanoutBucket.java b/org.eclipse.jgit/src/org/eclipse/jgit/notes/FanoutBucket.java
index 7827a9a..c1616b3 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/notes/FanoutBucket.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/notes/FanoutBucket.java
@@ -167,10 +167,10 @@ public boolean hasNext() {
@Override
public Note next() {
- if (hasNext())
+ if (hasNext()) {
return itr.next();
- else
- throw new NoSuchElementException();
+ }
+ throw new NoSuchElementException();
}
@Override
@@ -214,30 +214,31 @@ InMemoryNoteBucket set(AnyObjectId noteOn, AnyObjectId noteData,
NoteBucket b = table[cell];
if (b == null) {
- if (noteData == null)
+ if (noteData == null) {
return this;
+ }
LeafBucket n = new LeafBucket(prefixLen + 2);
table[cell] = n.set(noteOn, noteData, or);
cnt++;
return this;
- } else {
- NoteBucket n = b.set(noteOn, noteData, or);
- if (n == null) {
- table[cell] = null;
- cnt--;
-
- if (cnt == 0)
- return null;
-
- return contractIfTooSmall(noteOn, or);
-
- } else if (n != b) {
- table[cell] = n;
- }
- return this;
}
+ NoteBucket n = b.set(noteOn, noteData, or);
+ if (n == null) {
+ table[cell] = null;
+ cnt--;
+
+ if (cnt == 0) {
+ return null;
+ }
+
+ return contractIfTooSmall(noteOn, or);
+
+ } else if (n != b) {
+ table[cell] = n;
+ }
+ return this;
}
InMemoryNoteBucket contractIfTooSmall(AnyObjectId noteOn, ObjectReader or)
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/notes/LeafBucket.java b/org.eclipse.jgit/src/org/eclipse/jgit/notes/LeafBucket.java
index 6723b63..0fa2a63 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/notes/LeafBucket.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/notes/LeafBucket.java
@@ -129,10 +129,10 @@ public boolean hasNext() {
@Override
public Note next() {
- if (hasNext())
+ if (hasNext()) {
return notes[idx++];
- else
- throw new NoSuchElementException();
+ }
+ throw new NoSuchElementException();
}
@Override
@@ -156,25 +156,23 @@ InMemoryNoteBucket set(AnyObjectId noteOn, AnyObjectId noteData,
notes[p].setData(noteData.copy());
return this;
- } else {
- System.arraycopy(notes, p + 1, notes, p, cnt - p - 1);
- cnt--;
- return 0 < cnt ? this : null;
}
+ System.arraycopy(notes, p + 1, notes, p, cnt - p - 1);
+ cnt--;
+ return 0 < cnt ? this : null;
} else if (noteData != null) {
if (shouldSplit()) {
return split().set(noteOn, noteData, or);
-
- } else {
- growIfFull();
- p = -(p + 1);
- if (p < cnt)
- System.arraycopy(notes, p, notes, p + 1, cnt - p);
- notes[p] = new Note(noteOn, noteData.copy());
- cnt++;
- return this;
}
+ growIfFull();
+ p = -(p + 1);
+ if (p < cnt) {
+ System.arraycopy(notes, p, notes, p + 1, cnt - p);
+ }
+ notes[p] = new Note(noteOn, noteData.copy());
+ cnt++;
+ return this;
} else {
return this;
@@ -234,12 +232,10 @@ void parseOneEntry(AnyObjectId noteOn, AnyObjectId noteData) {
InMemoryNoteBucket append(Note note) {
if (shouldSplit()) {
return split().append(note);
-
- } else {
- growIfFull();
- notes[cnt++] = note;
- return this;
}
+ growIfFull();
+ notes[cnt++] = note;
+ return this;
}
private void growIfFull() {
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/notes/NoteMap.java b/org.eclipse.jgit/src/org/eclipse/jgit/notes/NoteMap.java
index cbef613..e4eef43 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/notes/NoteMap.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/notes/NoteMap.java
@@ -278,10 +278,10 @@ public boolean contains(AnyObjectId id) throws IOException {
public byte[] getCachedBytes(AnyObjectId id, int sizeLimit)
throws LargeObjectException, MissingObjectException, IOException {
ObjectId dataId = get(id);
- if (dataId != null)
+ if (dataId != null) {
return reader.open(dataId).getCachedBytes(sizeLimit);
- else
- return null;
+ }
+ return null;
}
/**
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/notes/NoteMapMerger.java b/org.eclipse.jgit/src/org/eclipse/jgit/notes/NoteMapMerger.java
index ba7223b..6ff1402 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/notes/NoteMapMerger.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/notes/NoteMapMerger.java
@@ -307,10 +307,10 @@ private static boolean sameContent(Note a, Note b) {
private static InMemoryNoteBucket addIfNotNull(InMemoryNoteBucket result,
Note note) {
- if (note != null)
+ if (note != null) {
return result.append(note);
- else
- return result;
+ }
+ return result;
}
private NonNoteEntry mergeNonNotes(NonNoteEntry baseList,
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/notes/NoteParser.java b/org.eclipse.jgit/src/org/eclipse/jgit/notes/NoteParser.java
index 8ef3af1..7dfc47d 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/notes/NoteParser.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/notes/NoteParser.java
@@ -181,9 +181,8 @@ private int parseFanoutCell() {
} catch (ArrayIndexOutOfBoundsException notHex) {
return -1;
}
- } else {
- return -1;
}
+ return -1;
}
private void storeNonNote() {
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/patch/BinaryHunk.java b/org.eclipse.jgit/src/org/eclipse/jgit/patch/BinaryHunk.java
index 95391ec..c1ee701 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/patch/BinaryHunk.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/patch/BinaryHunk.java
@@ -58,7 +58,7 @@ public class BinaryHunk {
private static final byte[] DELTA = encodeASCII("delta "); //$NON-NLS-1$
/** Type of information stored in a binary hunk. */
- public static enum Type {
+ public enum Type {
/** The full content is stored, deflated. */
LITERAL_DEFLATED,
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/patch/CombinedHunkHeader.java b/org.eclipse.jgit/src/org/eclipse/jgit/patch/CombinedHunkHeader.java
index 74eec81..244f804 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/patch/CombinedHunkHeader.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/patch/CombinedHunkHeader.java
@@ -58,7 +58,7 @@
* Hunk header for a hunk appearing in a "diff --cc" style patch.
*/
public class CombinedHunkHeader extends HunkHeader {
- private static abstract class CombinedOldImage extends OldImage {
+ private abstract static class CombinedOldImage extends OldImage {
int nContext;
}
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/patch/FileHeader.java b/org.eclipse.jgit/src/org/eclipse/jgit/patch/FileHeader.java
index 1f4beb0..959109c 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/patch/FileHeader.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/patch/FileHeader.java
@@ -104,7 +104,7 @@ public class FileHeader extends DiffEntry {
static final byte[] NEW_NAME = encodeASCII("+++ "); //$NON-NLS-1$
/** Type of patch used by this file. */
- public static enum PatchType {
+ public enum PatchType {
/** A traditional unified diff style patch of a text file. */
UNIFIED,
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/patch/FormatError.java b/org.eclipse.jgit/src/org/eclipse/jgit/patch/FormatError.java
index 10ea778..3896687 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/patch/FormatError.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/patch/FormatError.java
@@ -54,7 +54,7 @@
*/
public class FormatError {
/** Classification of an error. */
- public static enum Severity {
+ public enum Severity {
/** The error is unexpected, but can be worked around. */
WARNING,
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/revplot/PlotCommitList.java b/org.eclipse.jgit/src/org/eclipse/jgit/revplot/PlotCommitList.java
index 45508ce..2bb45c5 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/revplot/PlotCommitList.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/revplot/PlotCommitList.java
@@ -391,11 +391,10 @@ private int getFreePosition(BitSet blockedPositions) {
return pos.intValue();
}
return positionsAllocated++;
- } else {
- final Integer min = freePositions.first();
- freePositions.remove(min);
- return min.intValue();
}
+ final Integer min = freePositions.first();
+ freePositions.remove(min);
+ return min.intValue();
}
/**
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/revplot/PlotWalk.java b/org.eclipse.jgit/src/org/eclipse/jgit/revplot/PlotWalk.java
index ee18fe7..19e40b5 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/revplot/PlotWalk.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/revplot/PlotWalk.java
@@ -176,11 +176,10 @@ public RevCommit next() throws MissingObjectException,
Collection<Ref> list = reverseRefMap.get(commitId);
if (list == null) {
return PlotCommit.NO_REFS;
- } else {
- Ref[] tags = list.toArray(new Ref[0]);
- Arrays.sort(tags, new PlotRefComparator());
- return tags;
}
+ Ref[] tags = list.toArray(new Ref[0]);
+ Arrays.sort(tags, new PlotRefComparator());
+ return tags;
}
class PlotRefComparator implements Comparator<Ref> {
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/BitmapCalculator.java b/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/BitmapCalculator.java
deleted file mode 100644
index 14e9567..0000000
--- a/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/BitmapCalculator.java
+++ /dev/null
@@ -1,136 +0,0 @@
-/*
- * 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;
-
-import java.io.IOException;
-
-import org.eclipse.jgit.errors.IncorrectObjectTypeException;
-import org.eclipse.jgit.errors.MissingObjectException;
-import org.eclipse.jgit.internal.revwalk.AddToBitmapFilter;
-import org.eclipse.jgit.lib.BitmapIndex;
-import org.eclipse.jgit.lib.BitmapIndex.Bitmap;
-import org.eclipse.jgit.lib.BitmapIndex.BitmapBuilder;
-import org.eclipse.jgit.lib.ProgressMonitor;
-
-/**
- * Calculate the bitmap indicating what other commits are reachable from certain
- * commit.
- * <p>
- * This bitmap refers only to commits. For a bitmap with ALL objects reachable
- * from certain object, see {@code BitmapWalker}.
- */
-class BitmapCalculator {
-
- private final RevWalk walk;
- private final BitmapIndex bitmapIndex;
-
- BitmapCalculator(RevWalk walk) throws IOException {
- this.walk = walk;
- this.bitmapIndex = requireNonNull(
- walk.getObjectReader().getBitmapIndex());
- }
-
- /**
- * Get the reachability bitmap from certain commit to other commits.
- * <p>
- * This will return a precalculated bitmap if available or walk building one
- * until finding a precalculated bitmap (and returning the union).
- * <p>
- * Beware that the returned bitmap it is guaranteed to include ONLY the
- * commits reachable from the initial commit. It COULD include other objects
- * (because precalculated bitmaps have them) but caller shouldn't count on
- * that. See {@link BitmapWalker} for a full reachability bitmap.
- *
- * @param start
- * the commit. Use {@code walk.parseCommit(objectId)} to get this
- * object from the id.
- * @param pm
- * progress monitor. Updated by one per commit browsed in the
- * graph
- * @return the bitmap of reachable commits (and maybe some extra objects)
- * for the commit
- * @throws MissingObjectException
- * the supplied id doesn't exist
- * @throws IncorrectObjectTypeException
- * 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,
- IncorrectObjectTypeException, IOException {
- Bitmap precalculatedBitmap = bitmapIndex.getBitmap(start);
- if (precalculatedBitmap != null) {
- return asBitmapBuilder(precalculatedBitmap);
- }
-
- walk.reset();
- walk.sort(RevSort.TOPO);
- walk.markStart(start);
- // Unbounded walk. If the repo has bitmaps, it should bump into one at
- // some point.
-
- BitmapBuilder bitmapResult = bitmapIndex.newBitmapBuilder();
- walk.setRevFilter(new AddToBitmapFilter(bitmapResult));
- while (walk.next() != null) {
- // Iterate through all of the commits. The BitmapRevFilter does
- // the work.
- //
- // filter.include returns true for commits that do not have
- // a bitmap in bitmapIndex and are not reachable from a
- // bitmap in bitmapIndex encountered earlier in the walk.
- // Thus the number of commits returned by next() measures how
- // much history was traversed without being able to make use
- // of bitmaps.
- pm.update(1);
- }
-
- return bitmapResult;
- }
-
- private BitmapBuilder asBitmapBuilder(Bitmap bitmap) {
- return bitmapIndex.newBitmapBuilder().or(bitmap);
- }
-}
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/BitmappedReachabilityChecker.java b/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/BitmappedReachabilityChecker.java
index 6e510f6..bf831e3 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/BitmappedReachabilityChecker.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/BitmappedReachabilityChecker.java
@@ -45,13 +45,18 @@
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collection;
+import java.util.Iterator;
import java.util.List;
import java.util.Optional;
+import java.util.stream.Stream;
import org.eclipse.jgit.errors.IncorrectObjectTypeException;
import org.eclipse.jgit.errors.MissingObjectException;
+import org.eclipse.jgit.lib.BitmapIndex;
+import org.eclipse.jgit.lib.BitmapIndex.Bitmap;
import org.eclipse.jgit.lib.BitmapIndex.BitmapBuilder;
-import org.eclipse.jgit.lib.NullProgressMonitor;
+import org.eclipse.jgit.lib.Constants;
+import org.eclipse.jgit.revwalk.filter.RevFilter;
/**
* Checks the reachability using bitmaps.
@@ -84,37 +89,108 @@ public BitmappedReachabilityChecker(RevWalk walk)
* Check all targets are reachable from the starters.
* <p>
* In this implementation, it is recommended to put the most popular
- * starters (e.g. refs/heads tips) at the beginning of the collection
+ * starters (e.g. refs/heads tips) at the beginning.
*/
@Override
public Optional<RevCommit> areAllReachable(Collection<RevCommit> targets,
- Collection<RevCommit> starters) throws MissingObjectException,
+ Stream<RevCommit> starters) throws MissingObjectException,
IncorrectObjectTypeException, IOException {
- BitmapCalculator calculator = new BitmapCalculator(walk);
- /**
- * Iterate over starters bitmaps and remove targets as they become
- * reachable.
- *
- * Building the total starters bitmap has the same cost (iterating over
- * all starters adding the bitmaps) and this gives us the chance to
- * shorcut the loop.
- *
- * This is based on the assuption that most of the starters will have
- * the reachability bitmap precalculated. If many require a walk, the
- * walk.reset() could start to take too much time.
- */
List<RevCommit> remainingTargets = new ArrayList<>(targets);
- for (RevCommit starter : starters) {
- BitmapBuilder starterBitmap = calculator.getBitmap(starter,
- NullProgressMonitor.INSTANCE);
- remainingTargets.removeIf(starterBitmap::contains);
- if (remainingTargets.isEmpty()) {
- return Optional.empty();
+
+ walk.reset();
+ walk.sort(RevSort.TOPO);
+
+ // Filter emits only commits that are unreachable from previously
+ // visited commits. Internally it keeps a bitmap of everything
+ // reachable so far, which we use to discard reachable targets.
+ BitmapIndex repoBitmaps = walk.getObjectReader().getBitmapIndex();
+ ReachedFilter reachedFilter = new ReachedFilter(repoBitmaps);
+ walk.setRevFilter(reachedFilter);
+
+ Iterator<RevCommit> startersIter = starters.iterator();
+ while (startersIter.hasNext()) {
+ walk.markStart(startersIter.next());
+ while (walk.next() != null) {
+ remainingTargets.removeIf(reachedFilter::isReachable);
+
+ if (remainingTargets.isEmpty()) {
+ return Optional.empty();
+ }
}
+ walk.reset();
}
return Optional.of(remainingTargets.get(0));
}
+ /**
+ * This filter emits commits that were not bitmap-reachable from anything
+ * visited before. Or in other words, commits that add something (themselves
+ * or their bitmap) to the "reached" bitmap.
+ *
+ * Current progress can be queried via {@link #isReachable(RevCommit)}.
+ */
+ private static class ReachedFilter extends RevFilter {
+
+ private final BitmapIndex repoBitmaps;
+ private final BitmapBuilder reached;
+
+ /**
+ * Create a filter that emits only previously unreachable commits.
+ *
+ * @param repoBitmaps
+ * bitmap index of the repo
+ */
+ public ReachedFilter(BitmapIndex repoBitmaps) {
+ this.repoBitmaps = repoBitmaps;
+ this.reached = repoBitmaps.newBitmapBuilder();
+ }
+
+ /** {@inheritDoc} */
+ @Override
+ public final boolean include(RevWalk walker, RevCommit cmit) {
+ Bitmap commitBitmap;
+
+ if (reached.contains(cmit)) {
+ // already seen or included
+ dontFollow(cmit);
+ return false;
+ }
+
+ if ((commitBitmap = repoBitmaps.getBitmap(cmit)) != null) {
+ reached.or(commitBitmap);
+ // Emit the commit because there are new contents in the bitmap
+ // but don't follow parents (they are already in the bitmap)
+ dontFollow(cmit);
+ return true;
+ }
+
+ // No bitmaps, keep going
+ reached.addObject(cmit, Constants.OBJ_COMMIT);
+ return true;
+ }
+
+ private static final void dontFollow(RevCommit cmit) {
+ for (RevCommit p : cmit.getParents()) {
+ p.add(RevFlag.SEEN);
+ }
+ }
+
+ /** {@inheritDoc} */
+ @Override
+ public final RevFilter clone() {
+ throw new UnsupportedOperationException();
+ }
+
+ /** {@inheritDoc} */
+ @Override
+ public final boolean requiresCommitBody() {
+ return false;
+ }
+
+ boolean isReachable(RevCommit commit) {
+ return reached.contains(commit);
+ }
+ }
}
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/PedestrianReachabilityChecker.java b/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/PedestrianReachabilityChecker.java
index bba3c5c..da9e759 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/PedestrianReachabilityChecker.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/PedestrianReachabilityChecker.java
@@ -44,7 +44,9 @@
import java.io.IOException;
import java.util.Collection;
+import java.util.Iterator;
import java.util.Optional;
+import java.util.stream.Stream;
import org.eclipse.jgit.errors.IncorrectObjectTypeException;
import org.eclipse.jgit.errors.MissingObjectException;
@@ -75,7 +77,7 @@ public PedestrianReachabilityChecker(boolean topoSort,
@Override
public Optional<RevCommit> areAllReachable(Collection<RevCommit> targets,
- Collection<RevCommit> starters)
+ Stream<RevCommit> starters)
throws MissingObjectException, IncorrectObjectTypeException,
IOException {
walk.reset();
@@ -87,8 +89,9 @@ public Optional<RevCommit> areAllReachable(Collection<RevCommit> targets,
walk.markStart(target);
}
- for (RevCommit starter : starters) {
- walk.markUninteresting(starter);
+ Iterator<RevCommit> iterator = starters.iterator();
+ while (iterator.hasNext()) {
+ walk.markUninteresting(iterator.next());
}
return Optional.ofNullable(walk.next());
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/ReachabilityChecker.java b/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/ReachabilityChecker.java
index 2ed06d1..6a9c641 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/ReachabilityChecker.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/ReachabilityChecker.java
@@ -45,6 +45,7 @@
import java.io.IOException;
import java.util.Collection;
import java.util.Optional;
+import java.util.stream.Stream;
import org.eclipse.jgit.errors.IncorrectObjectTypeException;
import org.eclipse.jgit.errors.MissingObjectException;
@@ -82,9 +83,43 @@ public interface ReachabilityChecker {
* @throws IOException
* if any of the underlying indexes or readers can not be
* opened.
+ *
+ * @deprecated see {{@link #areAllReachable(Collection, Stream)}
+ */
+ @Deprecated
+ default Optional<RevCommit> areAllReachable(Collection<RevCommit> targets,
+ Collection<RevCommit> starters) throws MissingObjectException,
+ IncorrectObjectTypeException, IOException {
+ return areAllReachable(targets, starters.stream());
+ }
+
+ /**
+ * Check if all targets are reachable from the {@code starter} commits.
+ * <p>
+ * Caller should parse the objectIds (preferably with
+ * {@code walk.parseCommit()} and handle missing/incorrect type objects
+ * before calling this method.
+ *
+ * @param targets
+ * commits to reach.
+ * @param starters
+ * known starting points.
+ * @return An unreachable target if at least one of the targets is
+ * unreachable. An empty optional if all targets are reachable from
+ * the starters.
+ *
+ * @throws MissingObjectException
+ * if any of the incoming objects doesn't exist in the
+ * repository.
+ * @throws IncorrectObjectTypeException
+ * if any of the incoming objects is not a commit or a tag.
+ * @throws IOException
+ * if any of the underlying indexes or readers can not be
+ * opened.
+ * @since 5.6
*/
Optional<RevCommit> areAllReachable(Collection<RevCommit> targets,
- Collection<RevCommit> starters)
+ Stream<RevCommit> starters)
throws MissingObjectException, IncorrectObjectTypeException,
IOException;
}
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/RewriteGenerator.java b/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/RewriteGenerator.java
index 2e26641..b77407b 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/RewriteGenerator.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/RewriteGenerator.java
@@ -103,11 +103,15 @@ RevCommit next() throws MissingObjectException,
final int nParents = pList.length;
for (int i = 0; i < nParents; i++) {
final RevCommit oldp = pList[i];
- if (firstParent && i > 0) {
- c.parents = new RevCommit[] { rewrite(oldp) };
+ final RevCommit newp = rewrite(oldp);
+ if (firstParent) {
+ if (newp == null) {
+ c.parents = RevCommit.NO_PARENTS;
+ } else {
+ c.parents = new RevCommit[] { newp };
+ }
return c;
}
- final RevCommit newp = rewrite(oldp);
if (oldp != newp) {
pList[i] = newp;
rewrote = true;
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/TopoSortGenerator.java b/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/TopoSortGenerator.java
index a2c9ef6..e0325c2 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/TopoSortGenerator.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/TopoSortGenerator.java
@@ -80,11 +80,11 @@ class TopoSortGenerator extends Generator {
if (c == null) {
break;
}
- for (int i = 0; i < c.parents.length; i++) {
- if (firstParent && i > 0) {
+ for (RevCommit p : c.parents) {
+ p.inDegree++;
+ if (firstParent) {
break;
}
- c.parents[i].inDegree++;
}
pending.add(c);
}
@@ -119,11 +119,7 @@ RevCommit next() throws MissingObjectException,
// All of our children have already produced,
// so it is OK for us to produce now as well.
//
- for (int i = 0; i < c.parents.length; i++) {
- if (firstParent && i > 0) {
- break;
- }
- RevCommit p = c.parents[i];
+ for (RevCommit p : c.parents) {
if (--p.inDegree == 0 && (p.flags & TOPO_DELAY) != 0) {
// This parent tried to come before us, but we are
// his last child. unpop the parent so it goes right
@@ -132,6 +128,9 @@ RevCommit next() throws MissingObjectException,
p.flags &= ~TOPO_DELAY;
pending.unpop(p);
}
+ if (firstParent) {
+ break;
+ }
}
return c;
}
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/TreeRevFilter.java b/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/TreeRevFilter.java
index f7c3218..090d1e1 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/TreeRevFilter.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/TreeRevFilter.java
@@ -169,19 +169,19 @@ public boolean include(RevWalk walker, RevCommit c)
//
c.flags |= rewriteFlag;
return false;
- } else {
- // We have interesting items, but neither of the special
- // cases denoted above.
- //
- if (adds > 0 && tw.getFilter() instanceof FollowFilter) {
- // One of the paths we care about was added in this
- // commit. We need to update our filter to its older
- // name, if we can discover it. Find out what that is.
- //
- updateFollowFilter(trees, ((FollowFilter) tw.getFilter()).cfg);
- }
- return true;
}
+
+ // We have interesting items, but neither of the special
+ // cases denoted above.
+ //
+ if (adds > 0 && tw.getFilter() instanceof FollowFilter) {
+ // One of the paths we care about was added in this
+ // commit. We need to update our filter to its older
+ // name, if we can discover it. Find out what that is.
+ //
+ updateFollowFilter(trees, ((FollowFilter) tw.getFilter()).cfg);
+ }
+ return true;
} else if (nParents == 0) {
// We have no parents to compare against. Consider us to be
// REWRITE only if we have no paths matching our filter.
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/storage/file/FileBasedConfig.java b/org.eclipse.jgit/src/org/eclipse/jgit/storage/file/FileBasedConfig.java
index 5bb8153..f1ff9e6 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/storage/file/FileBasedConfig.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/storage/file/FileBasedConfig.java
@@ -77,7 +77,7 @@
* The configuration file that is stored in the file of the file system.
*/
public class FileBasedConfig extends StoredConfig {
- private final static Logger LOG = LoggerFactory
+ private static final Logger LOG = LoggerFactory
.getLogger(FileBasedConfig.class);
private final File configFile;
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/storage/pack/PackStatistics.java b/org.eclipse.jgit/src/org/eclipse/jgit/storage/pack/PackStatistics.java
index e6e3d4f..645da0a 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/storage/pack/PackStatistics.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/storage/pack/PackStatistics.java
@@ -271,6 +271,20 @@ public static class Accumulator {
public long treesTraversed;
/**
+ * Amount of packfile uris sent to the client to download via HTTP.
+ *
+ * @since 5.6
+ */
+ public long offloadedPackfiles;
+
+ /**
+ * Total size (in bytes) offloaded to HTTP downloads.
+ *
+ * @since 5.6
+ */
+ public long offloadedPackfileSize;
+
+ /**
* Statistics about each object type in the pack (commits, tags, trees
* and blobs.)
*/
@@ -598,6 +612,22 @@ public long getTreesTraversed() {
}
/**
+ * @return amount of packfiles offloaded (sent as "packfile-uri")/
+ * @since 5.6
+ */
+ public long getOffloadedPackfiles() {
+ return statistics.offloadedPackfiles;
+ }
+
+ /**
+ * @return total size (in bytes) offloaded to HTTP downloads.
+ * @since 5.6
+ */
+ public long getOffloadedPackfilesSize() {
+ return statistics.offloadedPackfileSize;
+ }
+
+ /**
* Get total time spent processing this pack.
*
* @return total time spent processing this pack.
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/submodule/SubmoduleWalk.java b/org.eclipse.jgit/src/org/eclipse/jgit/submodule/SubmoduleWalk.java
index e5559de..2e5776d 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/submodule/SubmoduleWalk.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/submodule/SubmoduleWalk.java
@@ -57,6 +57,7 @@
import org.eclipse.jgit.errors.RepositoryNotFoundException;
import org.eclipse.jgit.internal.JGitText;
import org.eclipse.jgit.lib.AnyObjectId;
+import org.eclipse.jgit.lib.BaseRepositoryBuilder;
import org.eclipse.jgit.lib.BlobBasedConfig;
import org.eclipse.jgit.lib.Config;
import org.eclipse.jgit.lib.ConfigConstants;
@@ -66,6 +67,7 @@
import org.eclipse.jgit.lib.Ref;
import org.eclipse.jgit.lib.Repository;
import org.eclipse.jgit.lib.RepositoryBuilder;
+import org.eclipse.jgit.lib.RepositoryBuilderFactory;
import org.eclipse.jgit.lib.StoredConfig;
import org.eclipse.jgit.storage.file.FileBasedConfig;
import org.eclipse.jgit.treewalk.AbstractTreeIterator;
@@ -260,15 +262,41 @@ public static Repository getSubmoduleRepository(final File parent,
*/
public static Repository getSubmoduleRepository(final File parent,
final String path, FS fs) throws IOException {
+ return getSubmoduleRepository(parent, path, fs,
+ new RepositoryBuilder());
+ }
+
+ /**
+ * Get submodule repository at path, using the specified file system
+ * abstraction and the specified builder
+ *
+ * @param parent
+ * {@link Repository} that contains the submodule
+ * @param path
+ * of the working tree of the submodule
+ * @param fs
+ * {@link FS} to use
+ * @param builder
+ * {@link BaseRepositoryBuilder} to use to build the submodule
+ * repository
+ * @return the {@link Repository} of the submodule, or {@code null} if it
+ * doesn't exist
+ * @throws IOException
+ * on errors
+ * @since 5.6
+ */
+ public static Repository getSubmoduleRepository(File parent, String path,
+ FS fs, BaseRepositoryBuilder<?, ? extends Repository> builder)
+ throws IOException {
File subWorkTree = new File(parent, path);
- if (!subWorkTree.isDirectory())
+ if (!subWorkTree.isDirectory()) {
return null;
- File workTree = new File(parent, path);
+ }
try {
- return new RepositoryBuilder() //
+ return builder //
.setMustExist(true) //
.setFS(fs) //
- .setWorkTree(workTree) //
+ .setWorkTree(subWorkTree) //
.build();
} catch (RepositoryNotFoundException e) {
return null;
@@ -366,6 +394,8 @@ else if (submoduleUrl.startsWith("../")) { //$NON-NLS-1$
private Map<String, String> pathToName;
+ private RepositoryBuilderFactory factory;
+
/**
* Create submodule generator
*
@@ -639,7 +669,25 @@ public String getPath() {
}
/**
- * The module name for the current submodule entry (used for the section name of .git/config)
+ * Sets the {@link RepositoryBuilderFactory} to use for creating submodule
+ * repositories. If none is set, a plain {@link RepositoryBuilder} is used.
+ *
+ * @param factory
+ * to set
+ * @since 5.6
+ */
+ public void setBuilderFactory(RepositoryBuilderFactory factory) {
+ this.factory = factory;
+ }
+
+ private BaseRepositoryBuilder<?, ? extends Repository> getBuilder() {
+ return factory != null ? factory.get() : new RepositoryBuilder();
+ }
+
+ /**
+ * The module name for the current submodule entry (used for the section
+ * name of .git/config)
+ *
* @since 4.10
* @return name
*/
@@ -735,6 +783,13 @@ public String getModulesUpdate() throws IOException, ConfigInvalidException {
*/
public IgnoreSubmoduleMode getModulesIgnore() throws IOException,
ConfigInvalidException {
+ IgnoreSubmoduleMode mode = repoConfig.getEnum(
+ IgnoreSubmoduleMode.values(),
+ ConfigConstants.CONFIG_SUBMODULE_SECTION, getModuleName(),
+ ConfigConstants.CONFIG_KEY_IGNORE, null);
+ if (mode != null) {
+ return mode;
+ }
lazyLoadModulesConfig();
return modulesConfig.getEnum(IgnoreSubmoduleMode.values(),
ConfigConstants.CONFIG_SUBMODULE_SECTION, getModuleName(),
@@ -748,7 +803,8 @@ ConfigConstants.CONFIG_SUBMODULE_SECTION, getModuleName(),
* @throws java.io.IOException
*/
public Repository getRepository() throws IOException {
- return getSubmoduleRepository(repository, path);
+ return getSubmoduleRepository(repository.getWorkTree(), path,
+ repository.getFS(), getBuilder());
}
/**
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/transport/AbstractAdvertiseRefsHook.java b/org.eclipse.jgit/src/org/eclipse/jgit/transport/AbstractAdvertiseRefsHook.java
index 4bf0d26..ed90012 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/transport/AbstractAdvertiseRefsHook.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/transport/AbstractAdvertiseRefsHook.java
@@ -67,7 +67,7 @@ public void advertiseRefs(UploadPack uploadPack)
/** {@inheritDoc} */
@Override
- public void advertiseRefs(BaseReceivePack receivePack)
+ public void advertiseRefs(ReceivePack receivePack)
throws ServiceMayNotContinueException {
Map<String, Ref> refs = getAdvertisedRefs(receivePack.getRepository(),
receivePack.getRevWalk());
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/transport/AdvertiseRefsHook.java b/org.eclipse.jgit/src/org/eclipse/jgit/transport/AdvertiseRefsHook.java
index 8512f2d..eb1aef9 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/transport/AdvertiseRefsHook.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/transport/AdvertiseRefsHook.java
@@ -51,8 +51,8 @@ public interface AdvertiseRefsHook {
/**
* A simple hook that advertises the default refs.
* <p>
- * The method implementations do nothing to preserve the default behavior; see
- * {@link UploadPack#setAdvertisedRefs(java.util.Map)} and
+ * The method implementations do nothing to preserve the default behavior;
+ * see {@link UploadPack#setAdvertisedRefs(java.util.Map)} and
* {@link ReceivePack#setAdvertisedRefs(java.util.Map,java.util.Set)}.
*/
AdvertiseRefsHook DEFAULT = new AdvertiseRefsHook() {
@@ -62,7 +62,7 @@ public void advertiseRefs(UploadPack uploadPack) {
}
@Override
- public void advertiseRefs(BaseReceivePack receivePack) {
+ public void advertiseRefs(ReceivePack receivePack) {
// Do nothing.
}
};
@@ -89,7 +89,8 @@ void advertiseRefs(UploadPack uploadPack)
* if necessary.
* @throws org.eclipse.jgit.transport.ServiceMayNotContinueException
* abort; the message will be sent to the user.
+ * @since 5.6
*/
- void advertiseRefs(BaseReceivePack receivePack)
+ void advertiseRefs(ReceivePack receivePack)
throws ServiceMayNotContinueException;
}
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/transport/AdvertiseRefsHookChain.java b/org.eclipse.jgit/src/org/eclipse/jgit/transport/AdvertiseRefsHookChain.java
index 12238a1..54c1978 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/transport/AdvertiseRefsHookChain.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/transport/AdvertiseRefsHookChain.java
@@ -53,7 +53,7 @@
* modify the results of the previous hooks in the chain by calling
* {@link org.eclipse.jgit.transport.UploadPack#getAdvertisedRefs()}, or
* {@link org.eclipse.jgit.transport.ReceivePack#getAdvertisedRefs()} or
- * {@link org.eclipse.jgit.transport.BaseReceivePack#getAdvertisedObjects()}.
+ * {@link org.eclipse.jgit.transport.ReceivePack#getAdvertisedObjects()}.
*/
public class AdvertiseRefsHookChain implements AdvertiseRefsHook {
private final AdvertiseRefsHook[] hooks;
@@ -82,7 +82,7 @@ else if (i == 1)
/** {@inheritDoc} */
@Override
- public void advertiseRefs(BaseReceivePack rp)
+ public void advertiseRefs(ReceivePack rp)
throws ServiceMayNotContinueException {
for (int i = 0; i < count; i++)
hooks[i].advertiseRefs(rp);
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/transport/BasePackPushConnection.java b/org.eclipse.jgit/src/org/eclipse/jgit/transport/BasePackPushConnection.java
index 35ea35e..12ade4d 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/transport/BasePackPushConnection.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/transport/BasePackPushConnection.java
@@ -391,7 +391,7 @@ private void readStatusReport(Map<String, RemoteRefUpdate> refUpdates)
refNameEnd = refLine.length();
} else if (refLine.startsWith("ng ")) { //$NON-NLS-1$
ok = false;
- refNameEnd = refLine.indexOf(" ", 3); //$NON-NLS-1$
+ refNameEnd = refLine.indexOf(' ', 3);
}
if (refNameEnd == -1)
throw new PackProtocolException(MessageFormat.format(JGitText.get().unexpectedReportLine2
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/transport/BaseReceivePack.java b/org.eclipse.jgit/src/org/eclipse/jgit/transport/BaseReceivePack.java
deleted file mode 100644
index 36a10cc..0000000
--- a/org.eclipse.jgit/src/org/eclipse/jgit/transport/BaseReceivePack.java
+++ /dev/null
@@ -1,1971 +0,0 @@
-/*
- * Copyright (C) 2008-2010, Google Inc.
- * 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 static java.nio.charset.StandardCharsets.UTF_8;
-import static org.eclipse.jgit.transport.GitProtocolConstants.CAPABILITY_ATOMIC;
-import static org.eclipse.jgit.transport.GitProtocolConstants.CAPABILITY_DELETE_REFS;
-import static org.eclipse.jgit.transport.GitProtocolConstants.CAPABILITY_OFS_DELTA;
-import static org.eclipse.jgit.transport.GitProtocolConstants.CAPABILITY_PUSH_OPTIONS;
-import static org.eclipse.jgit.transport.GitProtocolConstants.CAPABILITY_QUIET;
-import static org.eclipse.jgit.transport.GitProtocolConstants.CAPABILITY_REPORT_STATUS;
-import static org.eclipse.jgit.transport.GitProtocolConstants.CAPABILITY_SIDE_BAND_64K;
-import static org.eclipse.jgit.transport.GitProtocolConstants.OPTION_AGENT;
-import static org.eclipse.jgit.transport.SideBandOutputStream.CH_DATA;
-import static org.eclipse.jgit.transport.SideBandOutputStream.CH_ERROR;
-import static org.eclipse.jgit.transport.SideBandOutputStream.CH_PROGRESS;
-import static org.eclipse.jgit.transport.SideBandOutputStream.MAX_BUF;
-
-import java.io.EOFException;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.OutputStream;
-import java.text.MessageFormat;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-import java.util.concurrent.TimeUnit;
-
-import org.eclipse.jgit.annotations.Nullable;
-import org.eclipse.jgit.errors.InvalidObjectIdException;
-import org.eclipse.jgit.errors.LargeObjectException;
-import org.eclipse.jgit.errors.MissingObjectException;
-import org.eclipse.jgit.errors.PackProtocolException;
-import org.eclipse.jgit.errors.TooLargePackException;
-import org.eclipse.jgit.internal.JGitText;
-import org.eclipse.jgit.internal.storage.file.PackLock;
-import org.eclipse.jgit.internal.submodule.SubmoduleValidator;
-import org.eclipse.jgit.internal.submodule.SubmoduleValidator.SubmoduleValidationException;
-import org.eclipse.jgit.internal.transport.parser.FirstCommand;
-import org.eclipse.jgit.lib.AnyObjectId;
-import org.eclipse.jgit.lib.BatchRefUpdate;
-import org.eclipse.jgit.lib.Config;
-import org.eclipse.jgit.lib.Constants;
-import org.eclipse.jgit.lib.GitmoduleEntry;
-import org.eclipse.jgit.lib.NullProgressMonitor;
-import org.eclipse.jgit.lib.ObjectChecker;
-import org.eclipse.jgit.lib.ObjectDatabase;
-import org.eclipse.jgit.lib.ObjectId;
-import org.eclipse.jgit.lib.ObjectIdSubclassMap;
-import org.eclipse.jgit.lib.ObjectInserter;
-import org.eclipse.jgit.lib.ObjectLoader;
-import org.eclipse.jgit.lib.PersonIdent;
-import org.eclipse.jgit.lib.ProgressMonitor;
-import org.eclipse.jgit.lib.Ref;
-import org.eclipse.jgit.lib.Repository;
-import org.eclipse.jgit.revwalk.ObjectWalk;
-import org.eclipse.jgit.revwalk.RevBlob;
-import org.eclipse.jgit.revwalk.RevCommit;
-import org.eclipse.jgit.revwalk.RevFlag;
-import org.eclipse.jgit.revwalk.RevObject;
-import org.eclipse.jgit.revwalk.RevSort;
-import org.eclipse.jgit.revwalk.RevTree;
-import org.eclipse.jgit.revwalk.RevWalk;
-import org.eclipse.jgit.transport.PacketLineIn.InputOverLimitIOException;
-import org.eclipse.jgit.transport.ReceiveCommand.Result;
-import org.eclipse.jgit.util.io.InterruptTimer;
-import org.eclipse.jgit.util.io.LimitedInputStream;
-import org.eclipse.jgit.util.io.TimeoutInputStream;
-import org.eclipse.jgit.util.io.TimeoutOutputStream;
-
-/**
- * Base implementation of the side of a push connection that receives objects.
- * <p>
- * Contains high-level operations for initializing and closing streams,
- * advertising refs, reading commands, and receiving and applying a pack.
- * Subclasses compose these operations into full service implementations.
- */
-public abstract class BaseReceivePack {
- /**
- * Data in the first line of a request, the line itself plus capabilities.
- *
- * @deprecated Use {@link FirstCommand} instead.
- */
- @Deprecated
- public static class FirstLine {
- private final FirstCommand command;
-
- /**
- * Parse the first line of a receive-pack request.
- *
- * @param line
- * line from the client.
- */
- public FirstLine(String line) {
- command = FirstCommand.fromLine(line);
- }
-
- /** @return non-capabilities part of the line. */
- public String getLine() {
- return command.getLine();
- }
-
- /** @return capabilities parsed from the line. */
- public Set<String> getCapabilities() {
- return command.getCapabilities();
- }
- }
-
- /** Database we write the stored objects into. */
- final Repository db;
-
- /** Revision traversal support over {@link #db}. */
- final RevWalk walk;
-
- /**
- * Is the client connection a bi-directional socket or pipe?
- * <p>
- * If true, this class assumes it can perform multiple read and write cycles
- * with the client over the input and output streams. This matches the
- * functionality available with a standard TCP/IP connection, or a local
- * operating system or in-memory pipe.
- * <p>
- * If false, this class runs in a read everything then output results mode,
- * making it suitable for single round-trip systems RPCs such as HTTP.
- */
- private boolean biDirectionalPipe = true;
-
- /** Expecting data after the pack footer */
- private boolean expectDataAfterPackFooter;
-
- /** Should an incoming transfer validate objects? */
- private ObjectChecker objectChecker;
-
- /** Should an incoming transfer permit create requests? */
- private boolean allowCreates;
-
- /** Should an incoming transfer permit delete requests? */
- private boolean allowAnyDeletes;
- private boolean allowBranchDeletes;
-
- /** Should an incoming transfer permit non-fast-forward requests? */
- private boolean allowNonFastForwards;
-
- /** Should an incoming transfer permit push options? **/
- private boolean allowPushOptions;
-
- /**
- * Should the requested ref updates be performed as a single atomic
- * transaction?
- */
- private boolean atomic;
-
- private boolean allowOfsDelta;
- private boolean allowQuiet = true;
-
- /** Identity to record action as within the reflog. */
- private PersonIdent refLogIdent;
-
- /** Hook used while advertising the refs to the client. */
- private AdvertiseRefsHook advertiseRefsHook;
-
- /** Filter used while advertising the refs to the client. */
- RefFilter refFilter;
-
- /** Timeout in seconds to wait for client interaction. */
- private int timeout;
-
- /** Timer to manage {@link #timeout}. */
- private InterruptTimer timer;
-
- private TimeoutInputStream timeoutIn;
-
- // Original stream passed to init(), since rawOut may be wrapped in a
- // sideband.
- private OutputStream origOut;
-
- /** Raw input stream. */
- protected InputStream rawIn;
-
- /** Raw output stream. */
- protected OutputStream rawOut;
-
- /** Optional message output stream. */
- protected OutputStream msgOut;
- private SideBandOutputStream errOut;
-
- /** Packet line input stream around {@link #rawIn}. */
- protected PacketLineIn pckIn;
-
- /** Packet line output stream around {@link #rawOut}. */
- protected PacketLineOut pckOut;
-
- private final MessageOutputWrapper msgOutWrapper = new MessageOutputWrapper();
-
- private PackParser parser;
-
- /** The refs we advertised as existing at the start of the connection. */
- Map<String, Ref> refs;
-
- /** All SHA-1s shown to the client, which can be possible edges. */
- Set<ObjectId> advertisedHaves;
-
- /** Capabilities requested by the client. */
- private Set<String> enabledCapabilities;
- String userAgent;
- private Set<ObjectId> clientShallowCommits;
- private List<ReceiveCommand> commands;
- private long maxCommandBytes;
- private long maxDiscardBytes;
-
- private StringBuilder advertiseError;
-
- /** If {@link BasePackPushConnection#CAPABILITY_SIDE_BAND_64K} is enabled. */
- private boolean sideBand;
-
- private boolean quiet;
-
- /** Lock around the received pack file, while updating refs. */
- private PackLock packLock;
-
- private boolean checkReferencedIsReachable;
-
- /** Git object size limit */
- private long maxObjectSizeLimit;
-
- /** Total pack size limit */
- private long maxPackSizeLimit = -1;
-
- /** The size of the received pack, including index size */
- private Long packSize;
-
- private PushCertificateParser pushCertificateParser;
- private SignedPushConfig signedPushConfig;
- PushCertificate pushCert;
- private ReceivedPackStatistics stats;
-
- /**
- * Get the push certificate used to verify the pusher's identity.
- * <p>
- * Only valid after commands are read from the wire.
- *
- * @return the parsed certificate, or null if push certificates are disabled
- * or no cert was presented by the client.
- * @since 4.1
- * @deprecated use {@link ReceivePack#getPushCertificate}.
- */
- @Deprecated
- public abstract PushCertificate getPushCertificate();
-
- /**
- * Set the push certificate used to verify the pusher's identity.
- * <p>
- * Should only be called if reconstructing an instance without going through
- * the normal {@link #recvCommands()} flow.
- *
- * @param cert
- * the push certificate to set.
- * @since 4.1
- * @deprecated use {@link ReceivePack#setPushCertificate(PushCertificate)}.
- */
- @Deprecated
- public abstract void setPushCertificate(PushCertificate cert);
-
- /**
- * Create a new pack receive for an open repository.
- *
- * @param into
- * the destination repository.
- */
- protected BaseReceivePack(Repository into) {
- db = into;
- walk = new RevWalk(db);
- walk.setRetainBody(false);
-
- TransferConfig tc = db.getConfig().get(TransferConfig.KEY);
- objectChecker = tc.newReceiveObjectChecker();
-
- ReceiveConfig rc = db.getConfig().get(ReceiveConfig::new);
- allowCreates = rc.allowCreates;
- allowAnyDeletes = true;
- allowBranchDeletes = rc.allowDeletes;
- allowNonFastForwards = rc.allowNonFastForwards;
- allowOfsDelta = rc.allowOfsDelta;
- allowPushOptions = rc.allowPushOptions;
- maxCommandBytes = rc.maxCommandBytes;
- maxDiscardBytes = rc.maxDiscardBytes;
- advertiseRefsHook = AdvertiseRefsHook.DEFAULT;
- refFilter = RefFilter.DEFAULT;
- advertisedHaves = new HashSet<>();
- clientShallowCommits = new HashSet<>();
- signedPushConfig = rc.signedPush;
- }
-
- /** Configuration for receive operations. */
- protected static class ReceiveConfig {
- final boolean allowCreates;
- final boolean allowDeletes;
- final boolean allowNonFastForwards;
- final boolean allowOfsDelta;
- final boolean allowPushOptions;
- final long maxCommandBytes;
- final long maxDiscardBytes;
- final SignedPushConfig signedPush;
-
- ReceiveConfig(Config config) {
- allowCreates = true;
- allowDeletes = !config.getBoolean("receive", "denydeletes", false); //$NON-NLS-1$ //$NON-NLS-2$
- allowNonFastForwards = !config.getBoolean("receive", //$NON-NLS-1$
- "denynonfastforwards", false); //$NON-NLS-1$
- allowOfsDelta = config.getBoolean("repack", "usedeltabaseoffset", //$NON-NLS-1$ //$NON-NLS-2$
- true);
- allowPushOptions = config.getBoolean("receive", "pushoptions", //$NON-NLS-1$ //$NON-NLS-2$
- false);
- maxCommandBytes = config.getLong("receive", //$NON-NLS-1$
- "maxCommandBytes", //$NON-NLS-1$
- 3 << 20);
- maxDiscardBytes = config.getLong("receive", //$NON-NLS-1$
- "maxCommandDiscardBytes", //$NON-NLS-1$
- -1);
- signedPush = SignedPushConfig.KEY.parse(config);
- }
- }
-
- /**
- * Output stream that wraps the current {@link #msgOut}.
- * <p>
- * We don't want to expose {@link #msgOut} directly because it can change
- * several times over the course of a session.
- */
- class MessageOutputWrapper extends OutputStream {
- @Override
- public void write(int ch) {
- if (msgOut != null) {
- try {
- msgOut.write(ch);
- } catch (IOException e) {
- // Ignore write failures.
- }
- }
- }
-
- @Override
- public void write(byte[] b, int off, int len) {
- if (msgOut != null) {
- try {
- msgOut.write(b, off, len);
- } catch (IOException e) {
- // Ignore write failures.
- }
- }
- }
-
- @Override
- public void write(byte[] b) {
- write(b, 0, b.length);
- }
-
- @Override
- public void flush() {
- if (msgOut != null) {
- try {
- msgOut.flush();
- } catch (IOException e) {
- // Ignore write failures.
- }
- }
- }
- }
-
- /**
- * Get the process name used for pack lock messages.
- *
- * @return the process name used for pack lock messages.
- */
- protected abstract String getLockMessageProcessName();
-
- /**
- * Get the repository this receive completes into.
- *
- * @return the repository this receive completes into.
- * @deprecated use {@link ReceivePack#getRepository}
- */
- @Deprecated
- public abstract Repository getRepository();
-
- /**
- * Get the RevWalk instance used by this connection.
- *
- * @return the RevWalk instance used by this connection.
- * @deprecated use {@link ReceivePack#getRevWalk}
- */
- @Deprecated
- public abstract RevWalk getRevWalk();
-
- /**
- * Get refs which were advertised to the client.
- *
- * @return all refs which were advertised to the client, or null if
- * {@link #setAdvertisedRefs(Map, Set)} has not been called yet.
- * @deprecated use {@link ReceivePack#getAdvertisedRefs}
- */
- @Deprecated
- public abstract Map<String, Ref> getAdvertisedRefs();
-
- /**
- * Set the refs advertised by this ReceivePack.
- * <p>
- * Intended to be called from a
- * {@link org.eclipse.jgit.transport.PreReceiveHook}.
- *
- * @param allRefs
- * explicit set of references to claim as advertised by this
- * ReceivePack instance. This overrides any references that may
- * exist in the source repository. The map is passed to the
- * configured {@link #getRefFilter()}. If null, assumes all refs
- * were advertised.
- * @param additionalHaves
- * explicit set of additional haves to claim as advertised. If
- * null, assumes the default set of additional haves from the
- * repository.
- * @deprecated use {@link ReceivePack#setAdvertisedRefs}
- */
- @Deprecated
- public abstract void setAdvertisedRefs(Map<String, Ref> allRefs, Set<ObjectId> additionalHaves);
-
- /**
- * Get objects advertised to the client.
- *
- * @return the set of objects advertised to the as present in this repository,
- * or null if {@link #setAdvertisedRefs(Map, Set)} has not been called
- * yet.
- */
- public final Set<ObjectId> getAdvertisedObjects() {
- return advertisedHaves;
- }
-
- /**
- * Whether this instance will validate all referenced, but not supplied by
- * the client, objects are reachable from another reference.
- *
- * @return true if this instance will validate all referenced, but not
- * supplied by the client, objects are reachable from another
- * reference.
- */
- public boolean isCheckReferencedObjectsAreReachable() {
- return checkReferencedIsReachable;
- }
-
- /**
- * Validate all referenced but not supplied objects are reachable.
- * <p>
- * If enabled, this instance will verify that references to objects not
- * contained within the received pack are already reachable through at least
- * one other reference displayed as part of {@link #getAdvertisedRefs()}.
- * <p>
- * This feature is useful when the application doesn't trust the client to
- * not provide a forged SHA-1 reference to an object, in an attempt to
- * access parts of the DAG that they aren't allowed to see and which have
- * been hidden from them via the configured
- * {@link org.eclipse.jgit.transport.AdvertiseRefsHook} or
- * {@link org.eclipse.jgit.transport.RefFilter}.
- * <p>
- * Enabling this feature may imply at least some, if not all, of the same
- * functionality performed by {@link #setCheckReceivedObjects(boolean)}.
- * Applications are encouraged to enable both features, if desired.
- *
- * @param b
- * {@code true} to enable the additional check.
- */
- public void setCheckReferencedObjectsAreReachable(boolean b) {
- this.checkReferencedIsReachable = b;
- }
-
- /**
- * Whether this class expects a bi-directional pipe opened between the
- * client and itself.
- *
- * @return true if this class expects a bi-directional pipe opened between
- * the client and itself. The default is true.
- */
- public boolean isBiDirectionalPipe() {
- return biDirectionalPipe;
- }
-
- /**
- * Whether this class will assume the socket is a fully bidirectional pipe
- * between the two peers and takes advantage of that by first transmitting
- * the known refs, then waiting to read commands.
- *
- * @param twoWay
- * if true, this class will assume the socket is a fully
- * bidirectional pipe between the two peers and takes advantage
- * of that by first transmitting the known refs, then waiting to
- * read commands. If false, this class assumes it must read the
- * commands before writing output and does not perform the
- * initial advertising.
- */
- public void setBiDirectionalPipe(boolean twoWay) {
- biDirectionalPipe = twoWay;
- }
-
- /**
- * Whether there is data expected after the pack footer.
- *
- * @return {@code true} if there is data expected after the pack footer.
- */
- public boolean isExpectDataAfterPackFooter() {
- return expectDataAfterPackFooter;
- }
-
- /**
- * Whether there is additional data in InputStream after pack.
- *
- * @param e
- * {@code true} if there is additional data in InputStream after
- * pack.
- */
- public void setExpectDataAfterPackFooter(boolean e) {
- expectDataAfterPackFooter = e;
- }
-
- /**
- * Whether this instance will verify received objects are formatted
- * correctly.
- *
- * @return {@code true} if this instance will verify received objects are
- * formatted correctly. Validating objects requires more CPU time on
- * this side of the connection.
- */
- public boolean isCheckReceivedObjects() {
- return objectChecker != null;
- }
-
- /**
- * Whether to enable checking received objects
- *
- * @param check
- * {@code true} to enable checking received objects; false to
- * assume all received objects are valid.
- * @see #setObjectChecker(ObjectChecker)
- */
- public void setCheckReceivedObjects(boolean check) {
- if (check && objectChecker == null)
- setObjectChecker(new ObjectChecker());
- else if (!check && objectChecker != null)
- setObjectChecker(null);
- }
-
- /**
- * Set the object checking instance to verify each received object with
- *
- * @param impl
- * if non-null the object checking instance to verify each
- * received object with; null to disable object checking.
- * @since 3.4
- */
- public void setObjectChecker(ObjectChecker impl) {
- objectChecker = impl;
- }
-
- /**
- * Whether the client can request refs to be created.
- *
- * @return {@code true} if the client can request refs to be created.
- */
- public boolean isAllowCreates() {
- return allowCreates;
- }
-
- /**
- * Whether to permit create ref commands to be processed.
- *
- * @param canCreate
- * {@code true} to permit create ref commands to be processed.
- */
- public void setAllowCreates(boolean canCreate) {
- allowCreates = canCreate;
- }
-
- /**
- * Whether the client can request refs to be deleted.
- *
- * @return {@code true} if the client can request refs to be deleted.
- */
- public boolean isAllowDeletes() {
- return allowAnyDeletes;
- }
-
- /**
- * Whether to permit delete ref commands to be processed.
- *
- * @param canDelete
- * {@code true} to permit delete ref commands to be processed.
- */
- public void setAllowDeletes(boolean canDelete) {
- allowAnyDeletes = canDelete;
- }
-
- /**
- * Whether the client can delete from {@code refs/heads/}.
- *
- * @return {@code true} if the client can delete from {@code refs/heads/}.
- * @since 3.6
- */
- public boolean isAllowBranchDeletes() {
- return allowBranchDeletes;
- }
-
- /**
- * Configure whether to permit deletion of branches from the
- * {@code refs/heads/} namespace.
- *
- * @param canDelete
- * {@code true} to permit deletion of branches from the
- * {@code refs/heads/} namespace.
- * @since 3.6
- */
- public void setAllowBranchDeletes(boolean canDelete) {
- allowBranchDeletes = canDelete;
- }
-
- /**
- * Whether the client can request non-fast-forward updates of a ref,
- * possibly making objects unreachable.
- *
- * @return {@code true} if the client can request non-fast-forward updates
- * of a ref, possibly making objects unreachable.
- */
- public boolean isAllowNonFastForwards() {
- return allowNonFastForwards;
- }
-
- /**
- * Configure whether to permit the client to ask for non-fast-forward
- * updates of an existing ref.
- *
- * @param canRewind
- * {@code true} to permit the client to ask for non-fast-forward
- * updates of an existing ref.
- */
- public void setAllowNonFastForwards(boolean canRewind) {
- allowNonFastForwards = canRewind;
- }
-
- /**
- * Whether the client's commands should be performed as a single atomic
- * transaction.
- *
- * @return {@code true} if the client's commands should be performed as a
- * single atomic transaction.
- * @since 4.4
- */
- public boolean isAtomic() {
- return atomic;
- }
-
- /**
- * Configure whether to perform the client's commands as a single atomic
- * transaction.
- *
- * @param atomic
- * {@code true} to perform the client's commands as a single
- * atomic transaction.
- * @since 4.4
- */
- public void setAtomic(boolean atomic) {
- this.atomic = atomic;
- }
-
- /**
- * Get identity of the user making the changes in the reflog.
- *
- * @return identity of the user making the changes in the reflog.
- */
- public PersonIdent getRefLogIdent() {
- return refLogIdent;
- }
-
- /**
- * Set the identity of the user appearing in the affected reflogs.
- * <p>
- * The timestamp portion of the identity is ignored. A new identity with the
- * current timestamp will be created automatically when the updates occur
- * and the log records are written.
- *
- * @param pi
- * identity of the user. If null the identity will be
- * automatically determined based on the repository
- * configuration.
- */
- public void setRefLogIdent(PersonIdent pi) {
- refLogIdent = pi;
- }
-
- /**
- * Get the hook used while advertising the refs to the client
- *
- * @return the hook used while advertising the refs to the client
- */
- public AdvertiseRefsHook getAdvertiseRefsHook() {
- return advertiseRefsHook;
- }
-
- /**
- * Get the filter used while advertising the refs to the client
- *
- * @return the filter used while advertising the refs to the client
- */
- public RefFilter getRefFilter() {
- return refFilter;
- }
-
- /**
- * Set the hook used while advertising the refs to the client.
- * <p>
- * If the {@link org.eclipse.jgit.transport.AdvertiseRefsHook} chooses to
- * call {@link #setAdvertisedRefs(Map,Set)}, only refs set by this hook
- * <em>and</em> selected by the {@link org.eclipse.jgit.transport.RefFilter}
- * will be shown to the client. Clients may still attempt to create or
- * update a reference not advertised by the configured
- * {@link org.eclipse.jgit.transport.AdvertiseRefsHook}. These attempts
- * should be rejected by a matching
- * {@link org.eclipse.jgit.transport.PreReceiveHook}.
- *
- * @param advertiseRefsHook
- * the hook; may be null to show all refs.
- */
- public void setAdvertiseRefsHook(AdvertiseRefsHook advertiseRefsHook) {
- if (advertiseRefsHook != null)
- this.advertiseRefsHook = advertiseRefsHook;
- else
- this.advertiseRefsHook = AdvertiseRefsHook.DEFAULT;
- }
-
- /**
- * Set the filter used while advertising the refs to the client.
- * <p>
- * Only refs allowed by this filter will be shown to the client. The filter
- * is run against the refs specified by the
- * {@link org.eclipse.jgit.transport.AdvertiseRefsHook} (if applicable).
- *
- * @param refFilter
- * the filter; may be null to show all refs.
- */
- public void setRefFilter(RefFilter refFilter) {
- this.refFilter = refFilter != null ? refFilter : RefFilter.DEFAULT;
- }
-
- /**
- * Get timeout (in seconds) before aborting an IO operation.
- *
- * @return timeout (in seconds) before aborting an IO operation.
- */
- public int getTimeout() {
- return timeout;
- }
-
- /**
- * Set the timeout before willing to abort an IO call.
- *
- * @param seconds
- * number of seconds to wait (with no data transfer occurring)
- * before aborting an IO read or write operation with the
- * connected client.
- */
- public void setTimeout(int seconds) {
- timeout = seconds;
- }
-
- /**
- * Set the maximum number of command bytes to read from the client.
- *
- * @param limit
- * command limit in bytes; if 0 there is no limit.
- * @since 4.7
- */
- public void setMaxCommandBytes(long limit) {
- maxCommandBytes = limit;
- }
-
- /**
- * Set the maximum number of command bytes to discard from the client.
- * <p>
- * Discarding remaining bytes allows this instance to consume the rest of
- * the command block and send a human readable over-limit error via the
- * side-band channel. If the client sends an excessive number of bytes this
- * limit kicks in and the instance disconnects, resulting in a non-specific
- * 'pipe closed', 'end of stream', or similar generic error at the client.
- * <p>
- * When the limit is set to {@code -1} the implementation will default to
- * the larger of {@code 3 * maxCommandBytes} or {@code 3 MiB}.
- *
- * @param limit
- * discard limit in bytes; if 0 there is no limit; if -1 the
- * implementation tries to set a reasonable default.
- * @since 4.7
- */
- public void setMaxCommandDiscardBytes(long limit) {
- maxDiscardBytes = limit;
- }
-
- /**
- * Set the maximum allowed Git object size.
- * <p>
- * If an object is larger than the given size the pack-parsing will throw an
- * exception aborting the receive-pack operation.
- *
- * @param limit
- * the Git object size limit. If zero then there is not limit.
- */
- public void setMaxObjectSizeLimit(long limit) {
- maxObjectSizeLimit = limit;
- }
-
- /**
- * Set the maximum allowed pack size.
- * <p>
- * A pack exceeding this size will be rejected.
- *
- * @param limit
- * the pack size limit, in bytes
- * @since 3.3
- */
- public void setMaxPackSizeLimit(long limit) {
- if (limit < 0)
- throw new IllegalArgumentException(MessageFormat.format(
- JGitText.get().receivePackInvalidLimit, Long.valueOf(limit)));
- maxPackSizeLimit = limit;
- }
-
- /**
- * Check whether the client expects a side-band stream.
- *
- * @return true if the client has advertised a side-band capability, false
- * otherwise.
- * @throws org.eclipse.jgit.transport.RequestNotYetReadException
- * if the client's request has not yet been read from the wire, so
- * we do not know if they expect side-band. Note that the client
- * may have already written the request, it just has not been
- * read.
- */
- public boolean isSideBand() throws RequestNotYetReadException {
- checkRequestWasRead();
- return enabledCapabilities.contains(CAPABILITY_SIDE_BAND_64K);
- }
-
- /**
- * Whether clients may request avoiding noisy progress messages.
- *
- * @return true if clients may request avoiding noisy progress messages.
- * @since 4.0
- */
- public boolean isAllowQuiet() {
- return allowQuiet;
- }
-
- /**
- * Configure if clients may request the server skip noisy messages.
- *
- * @param allow
- * true to allow clients to request quiet behavior; false to
- * refuse quiet behavior and send messages anyway. This may be
- * necessary if processing is slow and the client-server network
- * connection can timeout.
- * @since 4.0
- */
- public void setAllowQuiet(boolean allow) {
- allowQuiet = allow;
- }
-
- /**
- * Whether the server supports receiving push options.
- *
- * @return true if the server supports receiving push options.
- * @since 4.5
- */
- public boolean isAllowPushOptions() {
- return allowPushOptions;
- }
-
- /**
- * Configure if the server supports receiving push options.
- *
- * @param allow
- * true to optionally accept option strings from the client.
- * @since 4.5
- */
- public void setAllowPushOptions(boolean allow) {
- allowPushOptions = allow;
- }
-
- /**
- * True if the client wants less verbose output.
- *
- * @return true if the client has requested the server to be less verbose.
- * @throws org.eclipse.jgit.transport.RequestNotYetReadException
- * if the client's request has not yet been read from the wire,
- * so we do not know if they expect side-band. Note that the
- * client may have already written the request, it just has not
- * been read.
- * @since 4.0
- */
- public boolean isQuiet() throws RequestNotYetReadException {
- checkRequestWasRead();
- return quiet;
- }
-
- /**
- * Set the configuration for push certificate verification.
- *
- * @param cfg
- * new configuration; if this object is null or its {@link
- * SignedPushConfig#getCertNonceSeed()} is null, push certificate
- * verification will be disabled.
- * @since 4.1
- */
- public void setSignedPushConfig(SignedPushConfig cfg) {
- signedPushConfig = cfg;
- }
-
- private PushCertificateParser getPushCertificateParser() {
- if (pushCertificateParser == null) {
- pushCertificateParser = new PushCertificateParser(db, signedPushConfig);
- }
- return pushCertificateParser;
- }
-
- /**
- * Get the user agent of the client.
- * <p>
- * If the client is new enough to use {@code agent=} capability that value
- * will be returned. Older HTTP clients may also supply their version using
- * the HTTP {@code User-Agent} header. The capability overrides the HTTP
- * header if both are available.
- * <p>
- * When an HTTP request has been received this method returns the HTTP
- * {@code User-Agent} header value until capabilities have been parsed.
- *
- * @return user agent supplied by the client. Available only if the client
- * is new enough to advertise its user agent.
- * @since 4.0
- */
- public String getPeerUserAgent() {
- return UserAgent.getAgent(enabledCapabilities, userAgent);
- }
-
- /**
- * Get all of the command received by the current request.
- *
- * @return all of the command received by the current request.
- */
- public List<ReceiveCommand> getAllCommands() {
- return Collections.unmodifiableList(commands);
- }
-
- /**
- * Send an error message to the client.
- * <p>
- * If any error messages are sent before the references are advertised to
- * the client, the errors will be sent instead of the advertisement and the
- * receive operation will be aborted. All clients should receive and display
- * such early stage errors.
- * <p>
- * If the reference advertisements have already been sent, messages are sent
- * in a side channel. If the client doesn't support receiving messages, the
- * message will be discarded, with no other indication to the caller or to
- * the client.
- * <p>
- * {@link org.eclipse.jgit.transport.PreReceiveHook}s should always try to
- * use
- * {@link org.eclipse.jgit.transport.ReceiveCommand#setResult(Result, String)}
- * with a result status of
- * {@link org.eclipse.jgit.transport.ReceiveCommand.Result#REJECTED_OTHER_REASON}
- * to indicate any reasons for rejecting an update. Messages attached to a
- * command are much more likely to be returned to the client.
- *
- * @param what
- * string describing the problem identified by the hook. The
- * string must not end with an LF, and must not contain an LF.
- */
- public void sendError(String what) {
- if (refs == null) {
- if (advertiseError == null)
- advertiseError = new StringBuilder();
- advertiseError.append(what).append('\n');
- } else {
- msgOutWrapper.write(Constants.encode("error: " + what + "\n")); //$NON-NLS-1$ //$NON-NLS-2$
- }
- }
-
- private void fatalError(String msg) {
- if (errOut != null) {
- try {
- errOut.write(Constants.encode(msg));
- errOut.flush();
- } catch (IOException e) {
- // Ignore write failures
- }
- } else {
- sendError(msg);
- }
- }
-
- /**
- * Send a message to the client, if it supports receiving them.
- * <p>
- * If the client doesn't support receiving messages, the message will be
- * discarded, with no other indication to the caller or to the client.
- *
- * @param what
- * string describing the problem identified by the hook. The
- * string must not end with an LF, and must not contain an LF.
- */
- public void sendMessage(String what) {
- msgOutWrapper.write(Constants.encode(what + "\n")); //$NON-NLS-1$
- }
-
- /**
- * Get an underlying stream for sending messages to the client.
- *
- * @return an underlying stream for sending messages to the client.
- */
- public OutputStream getMessageOutputStream() {
- return msgOutWrapper;
- }
-
- /**
- * Get the size of the received pack file including the index size.
- *
- * This can only be called if the pack is already received.
- *
- * @return the size of the received pack including index size
- * @throws java.lang.IllegalStateException
- * if called before the pack has been received
- * @since 3.3
- */
- public long getPackSize() {
- if (packSize != null)
- return packSize.longValue();
- throw new IllegalStateException(JGitText.get().packSizeNotSetYet);
- }
-
- /**
- * Get the commits from the client's shallow file.
- *
- * @return if the client is a shallow repository, the list of edge commits
- * that define the client's shallow boundary. Empty set if the client
- * is earlier than Git 1.9, or is a full clone.
- * @since 3.5
- */
- protected Set<ObjectId> getClientShallowCommits() {
- return clientShallowCommits;
- }
-
- /**
- * Whether any commands to be executed have been read.
- *
- * @return {@code true} if any commands to be executed have been read.
- */
- protected boolean hasCommands() {
- return !commands.isEmpty();
- }
-
- /**
- * Whether an error occurred that should be advertised.
- *
- * @return true if an error occurred that should be advertised.
- */
- protected boolean hasError() {
- return advertiseError != null;
- }
-
- /**
- * Initialize the instance with the given streams.
- *
- * @param input
- * raw input to read client commands and pack data from. Caller
- * must ensure the input is buffered, otherwise read performance
- * may suffer.
- * @param output
- * response back to the Git network client. Caller must ensure
- * the output is buffered, otherwise write performance may
- * suffer.
- * @param messages
- * secondary "notice" channel to send additional messages out
- * through. When run over SSH this should be tied back to the
- * standard error channel of the command execution. For most
- * other network connections this should be null.
- */
- protected void init(final InputStream input, final OutputStream output,
- final OutputStream messages) {
- origOut = output;
- rawIn = input;
- rawOut = output;
- msgOut = messages;
-
- if (timeout > 0) {
- final Thread caller = Thread.currentThread();
- timer = new InterruptTimer(caller.getName() + "-Timer"); //$NON-NLS-1$
- timeoutIn = new TimeoutInputStream(rawIn, timer);
- TimeoutOutputStream o = new TimeoutOutputStream(rawOut, timer);
- timeoutIn.setTimeout(timeout * 1000);
- o.setTimeout(timeout * 1000);
- rawIn = timeoutIn;
- rawOut = o;
- }
-
- pckIn = new PacketLineIn(rawIn);
- pckOut = new PacketLineOut(rawOut);
- pckOut.setFlushOnEnd(false);
-
- enabledCapabilities = new HashSet<>();
- commands = new ArrayList<>();
- }
-
- /**
- * Get advertised refs, or the default if not explicitly advertised.
- *
- * @return advertised refs, or the default if not explicitly advertised.
- */
- protected Map<String, Ref> getAdvertisedOrDefaultRefs() {
- if (refs == null)
- setAdvertisedRefs(null, null);
- return refs;
- }
-
- /**
- * Receive a pack from the stream and check connectivity if necessary.
- *
- * @throws java.io.IOException
- * an error occurred during unpacking or connectivity checking.
- */
- protected void receivePackAndCheckConnectivity() throws IOException {
- receivePack();
- if (needCheckConnectivity()) {
- checkSubmodules();
- checkConnectivity();
- }
- parser = null;
- }
-
- /**
- * Unlock the pack written by this object.
- *
- * @throws java.io.IOException
- * the pack could not be unlocked.
- */
- protected void unlockPack() throws IOException {
- if (packLock != null) {
- packLock.unlock();
- packLock = null;
- }
- }
-
- /**
- * Generate an advertisement of available refs and capabilities.
- *
- * @param adv
- * the advertisement formatter.
- * @throws java.io.IOException
- * the formatter failed to write an advertisement.
- * @throws org.eclipse.jgit.transport.ServiceMayNotContinueException
- * the hook denied advertisement.
- */
- public void sendAdvertisedRefs(RefAdvertiser adv)
- throws IOException, ServiceMayNotContinueException {
- if (advertiseError != null) {
- adv.writeOne("ERR " + advertiseError); //$NON-NLS-1$
- return;
- }
-
- try {
- advertiseRefsHook.advertiseRefs(this);
- } catch (ServiceMayNotContinueException fail) {
- if (fail.getMessage() != null) {
- adv.writeOne("ERR " + fail.getMessage()); //$NON-NLS-1$
- fail.setOutput();
- }
- throw fail;
- }
-
- adv.init(db);
- adv.advertiseCapability(CAPABILITY_SIDE_BAND_64K);
- adv.advertiseCapability(CAPABILITY_DELETE_REFS);
- adv.advertiseCapability(CAPABILITY_REPORT_STATUS);
- if (allowQuiet)
- adv.advertiseCapability(CAPABILITY_QUIET);
- String nonce = getPushCertificateParser().getAdvertiseNonce();
- if (nonce != null) {
- adv.advertiseCapability(nonce);
- }
- if (db.getRefDatabase().performsAtomicTransactions())
- adv.advertiseCapability(CAPABILITY_ATOMIC);
- if (allowOfsDelta)
- adv.advertiseCapability(CAPABILITY_OFS_DELTA);
- if (allowPushOptions) {
- adv.advertiseCapability(CAPABILITY_PUSH_OPTIONS);
- }
- adv.advertiseCapability(OPTION_AGENT, UserAgent.get());
- adv.send(getAdvertisedOrDefaultRefs().values());
- for (ObjectId obj : advertisedHaves)
- adv.advertiseHave(obj);
- if (adv.isEmpty())
- adv.advertiseId(ObjectId.zeroId(), "capabilities^{}"); //$NON-NLS-1$
- adv.end();
- }
-
- /**
- * Returns the statistics on the received pack if available. This should be
- * called after {@link #receivePack} is called.
- *
- * @return ReceivedPackStatistics
- * @since 4.6
- */
- @Nullable
- public ReceivedPackStatistics getReceivedPackStatistics() {
- return stats;
- }
-
- /**
- * Receive a list of commands from the input.
- *
- * @throws java.io.IOException
- */
- protected void recvCommands() throws IOException {
- PacketLineIn pck = maxCommandBytes > 0
- ? new PacketLineIn(rawIn, maxCommandBytes)
- : pckIn;
- PushCertificateParser certParser = getPushCertificateParser();
- boolean firstPkt = true;
- try {
- for (;;) {
- String line;
- try {
- line = pck.readString();
- } catch (EOFException eof) {
- if (commands.isEmpty())
- return;
- throw eof;
- }
- if (PacketLineIn.isEnd(line)) {
- break;
- }
-
- if (line.length() >= 48 && line.startsWith("shallow ")) { //$NON-NLS-1$
- parseShallow(line.substring(8, 48));
- continue;
- }
-
- if (firstPkt) {
- firstPkt = false;
- FirstCommand firstLine = FirstCommand.fromLine(line);
- enabledCapabilities = firstLine.getCapabilities();
- line = firstLine.getLine();
- enableCapabilities();
-
- if (line.equals(GitProtocolConstants.OPTION_PUSH_CERT)) {
- certParser.receiveHeader(pck, !isBiDirectionalPipe());
- continue;
- }
- }
-
- if (line.equals(PushCertificateParser.BEGIN_SIGNATURE)) {
- certParser.receiveSignature(pck);
- continue;
- }
-
- ReceiveCommand cmd = parseCommand(line);
- if (cmd.getRefName().equals(Constants.HEAD)) {
- cmd.setResult(Result.REJECTED_CURRENT_BRANCH);
- } else {
- cmd.setRef(refs.get(cmd.getRefName()));
- }
- commands.add(cmd);
- if (certParser.enabled()) {
- certParser.addCommand(cmd);
- }
- }
- pushCert = certParser.build();
- if (hasCommands()) {
- readPostCommands(pck);
- }
- } catch (PackProtocolException e) {
- discardCommands();
- fatalError(e.getMessage());
- throw e;
- } catch (InputOverLimitIOException e) {
- String msg = JGitText.get().tooManyCommands;
- discardCommands();
- fatalError(msg);
- throw new PackProtocolException(msg);
- }
- }
-
- private void discardCommands() {
- if (sideBand) {
- long max = maxDiscardBytes;
- if (max < 0) {
- max = Math.max(3 * maxCommandBytes, 3L << 20);
- }
- try {
- new PacketLineIn(rawIn, max).discardUntilEnd();
- } catch (IOException e) {
- // Ignore read failures attempting to discard.
- }
- }
- }
-
- private void parseShallow(String idStr) throws PackProtocolException {
- ObjectId id;
- try {
- id = ObjectId.fromString(idStr);
- } catch (InvalidObjectIdException e) {
- throw new PackProtocolException(e.getMessage(), e);
- }
- clientShallowCommits.add(id);
- }
-
- static ReceiveCommand parseCommand(String line) throws PackProtocolException {
- if (line == null || line.length() < 83) {
- throw new PackProtocolException(
- JGitText.get().errorInvalidProtocolWantedOldNewRef);
- }
- String oldStr = line.substring(0, 40);
- String newStr = line.substring(41, 81);
- ObjectId oldId, newId;
- try {
- oldId = ObjectId.fromString(oldStr);
- newId = ObjectId.fromString(newStr);
- } catch (InvalidObjectIdException e) {
- throw new PackProtocolException(
- JGitText.get().errorInvalidProtocolWantedOldNewRef, e);
- }
- String name = line.substring(82);
- if (!Repository.isValidRefName(name)) {
- throw new PackProtocolException(
- JGitText.get().errorInvalidProtocolWantedOldNewRef);
- }
- return new ReceiveCommand(oldId, newId, name);
- }
-
- /**
- * @param in
- * request stream.
- * @throws IOException
- * request line cannot be read.
- */
- void readPostCommands(PacketLineIn in) throws IOException {
- // Do nothing by default.
- }
-
- /**
- * Enable capabilities based on a previously read capabilities line.
- */
- protected void enableCapabilities() {
- sideBand = isCapabilityEnabled(CAPABILITY_SIDE_BAND_64K);
- quiet = allowQuiet && isCapabilityEnabled(CAPABILITY_QUIET);
- if (sideBand) {
- OutputStream out = rawOut;
-
- rawOut = new SideBandOutputStream(CH_DATA, MAX_BUF, out);
- msgOut = new SideBandOutputStream(CH_PROGRESS, MAX_BUF, out);
- errOut = new SideBandOutputStream(CH_ERROR, MAX_BUF, out);
-
- pckOut = new PacketLineOut(rawOut);
- pckOut.setFlushOnEnd(false);
- }
- }
-
- /**
- * Check if the peer requested a capability.
- *
- * @param name
- * protocol name identifying the capability.
- * @return true if the peer requested the capability to be enabled.
- */
- protected boolean isCapabilityEnabled(String name) {
- return enabledCapabilities.contains(name);
- }
-
- void checkRequestWasRead() {
- if (enabledCapabilities == null)
- throw new RequestNotYetReadException();
- }
-
- /**
- * Whether a pack is expected based on the list of commands.
- *
- * @return {@code true} if a pack is expected based on the list of commands.
- */
- protected boolean needPack() {
- for (ReceiveCommand cmd : commands) {
- if (cmd.getType() != ReceiveCommand.Type.DELETE)
- return true;
- }
- return false;
- }
-
- /**
- * Receive a pack from the input and store it in the repository.
- *
- * @throws IOException
- * an error occurred reading or indexing the pack.
- */
- private void receivePack() throws IOException {
- // It might take the client a while to pack the objects it needs
- // to send to us. We should increase our timeout so we don't
- // abort while the client is computing.
- //
- if (timeoutIn != null)
- timeoutIn.setTimeout(10 * timeout * 1000);
-
- ProgressMonitor receiving = NullProgressMonitor.INSTANCE;
- ProgressMonitor resolving = NullProgressMonitor.INSTANCE;
- if (sideBand && !quiet)
- resolving = new SideBandProgressMonitor(msgOut);
-
- try (ObjectInserter ins = db.newObjectInserter()) {
- String lockMsg = "jgit receive-pack"; //$NON-NLS-1$
- if (getRefLogIdent() != null)
- lockMsg += " from " + getRefLogIdent().toExternalString(); //$NON-NLS-1$
-
- parser = ins.newPackParser(packInputStream());
- parser.setAllowThin(true);
- parser.setNeedNewObjectIds(checkReferencedIsReachable);
- parser.setNeedBaseObjectIds(checkReferencedIsReachable);
- parser.setCheckEofAfterPackFooter(!biDirectionalPipe
- && !isExpectDataAfterPackFooter());
- parser.setExpectDataAfterPackFooter(isExpectDataAfterPackFooter());
- parser.setObjectChecker(objectChecker);
- parser.setLockMessage(lockMsg);
- parser.setMaxObjectSizeLimit(maxObjectSizeLimit);
- packLock = parser.parse(receiving, resolving);
- packSize = Long.valueOf(parser.getPackSize());
- stats = parser.getReceivedPackStatistics();
- ins.flush();
- }
-
- if (timeoutIn != null)
- timeoutIn.setTimeout(timeout * 1000);
- }
-
- private InputStream packInputStream() {
- InputStream packIn = rawIn;
- if (maxPackSizeLimit >= 0) {
- packIn = new LimitedInputStream(packIn, maxPackSizeLimit) {
- @Override
- protected void limitExceeded() throws TooLargePackException {
- throw new TooLargePackException(limit);
- }
- };
- }
- return packIn;
- }
-
- private boolean needCheckConnectivity() {
- return isCheckReceivedObjects()
- || isCheckReferencedObjectsAreReachable()
- || !getClientShallowCommits().isEmpty();
- }
-
- private void checkSubmodules()
- throws IOException {
- ObjectDatabase odb = db.getObjectDatabase();
- if (objectChecker == null) {
- return;
- }
- for (GitmoduleEntry entry : objectChecker.getGitsubmodules()) {
- AnyObjectId blobId = entry.getBlobId();
- ObjectLoader blob = odb.open(blobId, Constants.OBJ_BLOB);
-
- try {
- SubmoduleValidator.assertValidGitModulesFile(
- new String(blob.getBytes(), UTF_8));
- } catch (LargeObjectException | SubmoduleValidationException e) {
- throw new IOException(e);
- }
- }
- }
-
- private void checkConnectivity() throws IOException {
- ObjectIdSubclassMap<ObjectId> baseObjects = null;
- ObjectIdSubclassMap<ObjectId> providedObjects = null;
- ProgressMonitor checking = NullProgressMonitor.INSTANCE;
- if (sideBand && !quiet) {
- SideBandProgressMonitor m = new SideBandProgressMonitor(msgOut);
- m.setDelayStart(750, TimeUnit.MILLISECONDS);
- checking = m;
- }
-
- if (checkReferencedIsReachable) {
- baseObjects = parser.getBaseObjectIds();
- providedObjects = parser.getNewObjectIds();
- }
- parser = null;
-
- try (ObjectWalk ow = new ObjectWalk(db)) {
- if (baseObjects != null) {
- ow.sort(RevSort.TOPO);
- if (!baseObjects.isEmpty())
- ow.sort(RevSort.BOUNDARY, true);
- }
-
- for (ReceiveCommand cmd : commands) {
- if (cmd.getResult() != Result.NOT_ATTEMPTED)
- continue;
- if (cmd.getType() == ReceiveCommand.Type.DELETE)
- continue;
- ow.markStart(ow.parseAny(cmd.getNewId()));
- }
- for (ObjectId have : advertisedHaves) {
- RevObject o = ow.parseAny(have);
- ow.markUninteresting(o);
-
- if (baseObjects != null && !baseObjects.isEmpty()) {
- o = ow.peel(o);
- if (o instanceof RevCommit)
- o = ((RevCommit) o).getTree();
- if (o instanceof RevTree)
- ow.markUninteresting(o);
- }
- }
-
- checking.beginTask(JGitText.get().countingObjects,
- ProgressMonitor.UNKNOWN);
- RevCommit c;
- while ((c = ow.next()) != null) {
- checking.update(1);
- if (providedObjects != null //
- && !c.has(RevFlag.UNINTERESTING) //
- && !providedObjects.contains(c))
- throw new MissingObjectException(c, Constants.TYPE_COMMIT);
- }
-
- RevObject o;
- while ((o = ow.nextObject()) != null) {
- checking.update(1);
- if (o.has(RevFlag.UNINTERESTING))
- continue;
-
- if (providedObjects != null) {
- if (providedObjects.contains(o))
- continue;
- else
- throw new MissingObjectException(o, o.getType());
- }
-
- if (o instanceof RevBlob && !db.getObjectDatabase().has(o))
- throw new MissingObjectException(o, Constants.TYPE_BLOB);
- }
- checking.endTask();
-
- if (baseObjects != null) {
- for (ObjectId id : baseObjects) {
- o = ow.parseAny(id);
- if (!o.has(RevFlag.UNINTERESTING))
- throw new MissingObjectException(o, o.getType());
- }
- }
- }
- }
-
- /**
- * Validate the command list.
- */
- protected void validateCommands() {
- for (ReceiveCommand cmd : commands) {
- final Ref ref = cmd.getRef();
- if (cmd.getResult() != Result.NOT_ATTEMPTED)
- continue;
-
- if (cmd.getType() == ReceiveCommand.Type.DELETE) {
- if (!isAllowDeletes()) {
- // Deletes are not supported on this repository.
- cmd.setResult(Result.REJECTED_NODELETE);
- continue;
- }
- if (!isAllowBranchDeletes()
- && ref.getName().startsWith(Constants.R_HEADS)) {
- // Branches cannot be deleted, but other refs can.
- cmd.setResult(Result.REJECTED_NODELETE);
- continue;
- }
- }
-
- if (cmd.getType() == ReceiveCommand.Type.CREATE) {
- if (!isAllowCreates()) {
- cmd.setResult(Result.REJECTED_NOCREATE);
- continue;
- }
-
- if (ref != null && !isAllowNonFastForwards()) {
- // Creation over an existing ref is certainly not going
- // to be a fast-forward update. We can reject it early.
- //
- cmd.setResult(Result.REJECTED_NONFASTFORWARD);
- continue;
- }
-
- if (ref != null) {
- // A well behaved client shouldn't have sent us a
- // create command for a ref we advertised to it.
- //
- cmd.setResult(Result.REJECTED_OTHER_REASON,
- JGitText.get().refAlreadyExists);
- continue;
- }
- }
-
- if (cmd.getType() == ReceiveCommand.Type.DELETE && ref != null) {
- ObjectId id = ref.getObjectId();
- if (id == null) {
- id = ObjectId.zeroId();
- }
- if (!ObjectId.zeroId().equals(cmd.getOldId())
- && !id.equals(cmd.getOldId())) {
- // Delete commands can be sent with the old id matching our
- // advertised value, *OR* with the old id being 0{40}. Any
- // other requested old id is invalid.
- //
- cmd.setResult(Result.REJECTED_OTHER_REASON,
- JGitText.get().invalidOldIdSent);
- continue;
- }
- }
-
- if (cmd.getType() == ReceiveCommand.Type.UPDATE) {
- if (ref == null) {
- // The ref must have been advertised in order to be updated.
- //
- cmd.setResult(Result.REJECTED_OTHER_REASON, JGitText.get().noSuchRef);
- continue;
- }
- ObjectId id = ref.getObjectId();
- if (id == null) {
- // We cannot update unborn branch
- cmd.setResult(Result.REJECTED_OTHER_REASON,
- JGitText.get().cannotUpdateUnbornBranch);
- continue;
- }
-
- if (!id.equals(cmd.getOldId())) {
- // A properly functioning client will send the same
- // object id we advertised.
- //
- cmd.setResult(Result.REJECTED_OTHER_REASON,
- JGitText.get().invalidOldIdSent);
- continue;
- }
-
- // Is this possibly a non-fast-forward style update?
- //
- RevObject oldObj, newObj;
- try {
- oldObj = walk.parseAny(cmd.getOldId());
- } catch (IOException e) {
- cmd.setResult(Result.REJECTED_MISSING_OBJECT, cmd
- .getOldId().name());
- continue;
- }
-
- try {
- newObj = walk.parseAny(cmd.getNewId());
- } catch (IOException e) {
- cmd.setResult(Result.REJECTED_MISSING_OBJECT, cmd
- .getNewId().name());
- continue;
- }
-
- if (oldObj instanceof RevCommit && newObj instanceof RevCommit) {
- try {
- if (walk.isMergedInto((RevCommit) oldObj,
- (RevCommit) newObj))
- cmd.setTypeFastForwardUpdate();
- else
- cmd.setType(ReceiveCommand.Type.UPDATE_NONFASTFORWARD);
- } catch (MissingObjectException e) {
- cmd.setResult(Result.REJECTED_MISSING_OBJECT, e
- .getMessage());
- } catch (IOException e) {
- cmd.setResult(Result.REJECTED_OTHER_REASON);
- }
- } else {
- cmd.setType(ReceiveCommand.Type.UPDATE_NONFASTFORWARD);
- }
-
- if (cmd.getType() == ReceiveCommand.Type.UPDATE_NONFASTFORWARD
- && !isAllowNonFastForwards()) {
- cmd.setResult(Result.REJECTED_NONFASTFORWARD);
- continue;
- }
- }
-
- if (!cmd.getRefName().startsWith(Constants.R_REFS)
- || !Repository.isValidRefName(cmd.getRefName())) {
- cmd.setResult(Result.REJECTED_OTHER_REASON, JGitText.get().funnyRefname);
- }
- }
- }
-
- /**
- * Whether any commands have been rejected so far.
- *
- * @return if any commands have been rejected so far.
- * @since 3.6
- */
- protected boolean anyRejects() {
- for (ReceiveCommand cmd : commands) {
- if (cmd.getResult() != Result.NOT_ATTEMPTED && cmd.getResult() != Result.OK)
- return true;
- }
- return false;
- }
-
- /**
- * Set the result to fail for any command that was not processed yet.
- *
- * @since 3.6
- */
- protected void failPendingCommands() {
- ReceiveCommand.abort(commands);
- }
-
- /**
- * Filter the list of commands according to result.
- *
- * @param want
- * desired status to filter by.
- * @return a copy of the command list containing only those commands with the
- * desired status.
- */
- protected List<ReceiveCommand> filterCommands(Result want) {
- return ReceiveCommand.filter(commands, want);
- }
-
- /**
- * Execute commands to update references.
- */
- protected void executeCommands() {
- List<ReceiveCommand> toApply = filterCommands(Result.NOT_ATTEMPTED);
- if (toApply.isEmpty())
- return;
-
- ProgressMonitor updating = NullProgressMonitor.INSTANCE;
- if (sideBand) {
- SideBandProgressMonitor pm = new SideBandProgressMonitor(msgOut);
- pm.setDelayStart(250, TimeUnit.MILLISECONDS);
- updating = pm;
- }
-
- BatchRefUpdate batch = db.getRefDatabase().newBatchUpdate();
- batch.setAllowNonFastForwards(isAllowNonFastForwards());
- batch.setAtomic(isAtomic());
- batch.setRefLogIdent(getRefLogIdent());
- batch.setRefLogMessage("push", true); //$NON-NLS-1$
- batch.addCommand(toApply);
- try {
- batch.setPushCertificate(getPushCertificate());
- batch.execute(walk, updating);
- } catch (IOException err) {
- for (ReceiveCommand cmd : toApply) {
- if (cmd.getResult() == Result.NOT_ATTEMPTED)
- cmd.reject(err);
- }
- }
- }
-
- /**
- * Send a status report.
- *
- * @param forClient
- * true if this report is for a Git client, false if it is for an
- * end-user.
- * @param unpackError
- * an error that occurred during unpacking, or {@code null}
- * @param out
- * the reporter for sending the status strings.
- * @throws java.io.IOException
- * an error occurred writing the status report.
- */
- protected void sendStatusReport(final boolean forClient,
- final Throwable unpackError, final Reporter out) throws IOException {
- if (unpackError != null) {
- out.sendString("unpack error " + unpackError.getMessage()); //$NON-NLS-1$
- if (forClient) {
- for (ReceiveCommand cmd : commands) {
- out.sendString("ng " + cmd.getRefName() //$NON-NLS-1$
- + " n/a (unpacker error)"); //$NON-NLS-1$
- }
- }
- return;
- }
-
- if (forClient)
- out.sendString("unpack ok"); //$NON-NLS-1$
- for (ReceiveCommand cmd : commands) {
- if (cmd.getResult() == Result.OK) {
- if (forClient)
- out.sendString("ok " + cmd.getRefName()); //$NON-NLS-1$
- continue;
- }
-
- final StringBuilder r = new StringBuilder();
- if (forClient)
- r.append("ng ").append(cmd.getRefName()).append(" "); //$NON-NLS-1$ //$NON-NLS-2$
- else
- r.append(" ! [rejected] ").append(cmd.getRefName()).append(" ("); //$NON-NLS-1$ //$NON-NLS-2$
-
- switch (cmd.getResult()) {
- case NOT_ATTEMPTED:
- r.append("server bug; ref not processed"); //$NON-NLS-1$
- break;
-
- case REJECTED_NOCREATE:
- r.append("creation prohibited"); //$NON-NLS-1$
- break;
-
- case REJECTED_NODELETE:
- r.append("deletion prohibited"); //$NON-NLS-1$
- break;
-
- case REJECTED_NONFASTFORWARD:
- r.append("non-fast forward"); //$NON-NLS-1$
- break;
-
- case REJECTED_CURRENT_BRANCH:
- r.append("branch is currently checked out"); //$NON-NLS-1$
- break;
-
- case REJECTED_MISSING_OBJECT:
- if (cmd.getMessage() == null)
- r.append("missing object(s)"); //$NON-NLS-1$
- else if (cmd.getMessage().length() == Constants.OBJECT_ID_STRING_LENGTH) {
- r.append("object "); //$NON-NLS-1$
- r.append(cmd.getMessage());
- r.append(" missing"); //$NON-NLS-1$
- } else
- r.append(cmd.getMessage());
- break;
-
- case REJECTED_OTHER_REASON:
- if (cmd.getMessage() == null)
- r.append("unspecified reason"); //$NON-NLS-1$
- else
- r.append(cmd.getMessage());
- break;
-
- case LOCK_FAILURE:
- r.append("failed to lock"); //$NON-NLS-1$
- break;
-
- case OK:
- // We shouldn't have reached this case (see 'ok' case above).
- continue;
- }
- if (!forClient)
- r.append(")"); //$NON-NLS-1$
- out.sendString(r.toString());
- }
- }
-
- /**
- * Close and flush (if necessary) the underlying streams.
- *
- * @throws java.io.IOException
- */
- protected void close() throws IOException {
- if (sideBand) {
- // If we are using side band, we need to send a final
- // flush-pkt to tell the remote peer the side band is
- // complete and it should stop decoding. We need to
- // use the original output stream as rawOut is now the
- // side band data channel.
- //
- ((SideBandOutputStream) msgOut).flushBuffer();
- ((SideBandOutputStream) rawOut).flushBuffer();
-
- PacketLineOut plo = new PacketLineOut(origOut);
- plo.setFlushOnEnd(false);
- plo.end();
- }
-
- if (biDirectionalPipe) {
- // If this was a native git connection, flush the pipe for
- // the caller. For smart HTTP we don't do this flush and
- // instead let the higher level HTTP servlet code do it.
- //
- if (!sideBand && msgOut != null)
- msgOut.flush();
- rawOut.flush();
- }
- }
-
- /**
- * Release any resources used by this object.
- *
- * @throws java.io.IOException
- * the pack could not be unlocked.
- */
- protected void release() throws IOException {
- walk.close();
- unlockPack();
- timeoutIn = null;
- rawIn = null;
- rawOut = null;
- msgOut = null;
- pckIn = null;
- pckOut = null;
- refs = null;
- // Keep the capabilities. If responses are sent after this release
- // we need to remember at least whether sideband communication has to be
- // used
- commands = null;
- if (timer != null) {
- try {
- timer.terminate();
- } finally {
- timer = null;
- }
- }
- }
-
- /** Interface for reporting status messages. */
- static abstract class Reporter {
- abstract void sendString(String s) throws IOException;
- }
-}
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/transport/CredentialsProviderUserInfo.java b/org.eclipse.jgit/src/org/eclipse/jgit/transport/CredentialsProviderUserInfo.java
index d901021..6325a23 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/transport/CredentialsProviderUserInfo.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/transport/CredentialsProviderUserInfo.java
@@ -107,10 +107,9 @@ public boolean promptPassphrase(String msg) {
if (provider.get(uri, v)) {
passphrase = v.getValue();
return true;
- } else {
- passphrase = null;
- return false;
}
+ passphrase = null;
+ return false;
}
/** {@inheritDoc} */
@@ -120,10 +119,9 @@ public boolean promptPassword(String msg) {
if (provider.get(uri, p)) {
password = new String(p.getValue());
return true;
- } else {
- password = null;
- return false;
}
+ password = null;
+ return false;
}
private CredentialItem.StringType newPrompt(String msg) {
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/transport/GitProtocolConstants.java b/org.eclipse.jgit/src/org/eclipse/jgit/transport/GitProtocolConstants.java
index e3c0bc6..2fd0746 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/transport/GitProtocolConstants.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/transport/GitProtocolConstants.java
@@ -280,7 +280,7 @@ public final class GitProtocolConstants {
*/
public static final String COMMAND_FETCH = "fetch"; //$NON-NLS-1$
- static enum MultiAck {
+ enum MultiAck {
OFF, CONTINUE, DETAILED;
}
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/transport/HMACSHA1NonceGenerator.java b/org.eclipse.jgit/src/org/eclipse/jgit/transport/HMACSHA1NonceGenerator.java
index 01f6fec..72e95e6 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/transport/HMACSHA1NonceGenerator.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/transport/HMACSHA1NonceGenerator.java
@@ -135,9 +135,8 @@ public NonceStatus verify(String received, String sent,
if (nonceStampSlop <= slop) {
return NonceStatus.OK;
- } else {
- return NonceStatus.SLOP;
}
+ return NonceStatus.SLOP;
}
private static final String HEX = "0123456789ABCDEF"; //$NON-NLS-1$
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/transport/PackParser.java b/org.eclipse.jgit/src/org/eclipse/jgit/transport/PackParser.java
index 2b2795f..a9cd677 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/transport/PackParser.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/transport/PackParser.java
@@ -103,7 +103,7 @@ public abstract class PackParser {
private static final int BUFFER_SIZE = 8192;
/** Location data is being obtained from. */
- public static enum Source {
+ public enum Source {
/** Data is read from the incoming stream. */
INPUT,
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/transport/PacketLineIn.java b/org.eclipse.jgit/src/org/eclipse/jgit/transport/PacketLineIn.java
index d73e193..bbdd555 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/transport/PacketLineIn.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/transport/PacketLineIn.java
@@ -95,7 +95,7 @@ public class PacketLineIn {
@Deprecated
public static final String DELIM = new StringBuilder(0).toString(); /* must not string pool */
- static enum AckNackResult {
+ enum AckNackResult {
/** NAK */
NAK,
/** ACK */
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/transport/ProtocolV2Parser.java b/org.eclipse.jgit/src/org/eclipse/jgit/transport/ProtocolV2Parser.java
index 14ccddf..c2f69e2 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/transport/ProtocolV2Parser.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/transport/ProtocolV2Parser.java
@@ -215,7 +215,7 @@ FetchV2Request parseFetchRequest(PacketLineIn pckIn)
&& line2.equals(OPTION_SIDEBAND_ALL)) {
reqBuilder.setSidebandAll(true);
} else if (line2.startsWith("packfile-uris ")) { //$NON-NLS-1$
- for (String s : line2.substring(14).split(",")) {
+ for (String s : line2.substring(14).split(",")) { //$NON-NLS-1$
reqBuilder.addPackfileUriProtocol(s);
}
} else {
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/transport/PushCertificateParser.java b/org.eclipse.jgit/src/org/eclipse/jgit/transport/PushCertificateParser.java
index 89c1a93..3653879 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/transport/PushCertificateParser.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/transport/PushCertificateParser.java
@@ -43,7 +43,7 @@
package org.eclipse.jgit.transport;
-import static org.eclipse.jgit.transport.BaseReceivePack.parseCommand;
+import static org.eclipse.jgit.transport.ReceivePack.parseCommand;
import static org.eclipse.jgit.transport.GitProtocolConstants.CAPABILITY_PUSH_CERT;
import java.io.EOFException;
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/transport/ReceiveCommand.java b/org.eclipse.jgit/src/org/eclipse/jgit/transport/ReceiveCommand.java
index a9a995c..d58bc69 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/transport/ReceiveCommand.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/transport/ReceiveCommand.java
@@ -65,14 +65,14 @@
/**
* A command being processed by
- * {@link org.eclipse.jgit.transport.BaseReceivePack}.
+ * {@link org.eclipse.jgit.transport.ReceivePack}.
* <p>
* This command instance roughly translates to the server side representation of
* the {@link org.eclipse.jgit.transport.RemoteRefUpdate} created by the client.
*/
public class ReceiveCommand {
/** Type of operation requested. */
- public static enum Type {
+ public enum Type {
/** Create a new ref; the ref must not already exist. */
CREATE,
@@ -98,7 +98,7 @@ public static enum Type {
}
/** Result of the update command. */
- public static enum Result {
+ public enum Result {
/** The command has not yet been attempted by the server. */
NOT_ATTEMPTED,
@@ -290,7 +290,7 @@ public static ReceiveCommand unlink(@NonNull String oldTarget,
/**
* Create a new command for
- * {@link org.eclipse.jgit.transport.BaseReceivePack}.
+ * {@link org.eclipse.jgit.transport.ReceivePack}.
*
* @param oldId
* the expected old object id; must not be null. Use
@@ -334,7 +334,7 @@ public ReceiveCommand(final ObjectId oldId, final ObjectId newId,
/**
* Create a new command for
- * {@link org.eclipse.jgit.transport.BaseReceivePack}.
+ * {@link org.eclipse.jgit.transport.ReceivePack}.
*
* @param oldId
* the old object id; must not be null. Use
@@ -768,9 +768,9 @@ public void updateType(RevWalk walk) throws IOException {
*
* @param rp
* receive-pack session.
- * @since 2.0
+ * @since 5.6
*/
- public void execute(BaseReceivePack rp) {
+ public void execute(ReceivePack rp) {
try {
String expTarget = getOldSymref();
boolean detach = getNewSymref() != null
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/transport/ReceivePack.java b/org.eclipse.jgit/src/org/eclipse/jgit/transport/ReceivePack.java
index d6adf1e..fab9890 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/transport/ReceivePack.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/transport/ReceivePack.java
@@ -43,36 +43,255 @@
package org.eclipse.jgit.transport;
+import static java.nio.charset.StandardCharsets.UTF_8;
import static org.eclipse.jgit.lib.Constants.HEAD;
import static org.eclipse.jgit.transport.GitProtocolConstants.CAPABILITY_ATOMIC;
+import static org.eclipse.jgit.transport.GitProtocolConstants.CAPABILITY_DELETE_REFS;
+import static org.eclipse.jgit.transport.GitProtocolConstants.CAPABILITY_OFS_DELTA;
import static org.eclipse.jgit.transport.GitProtocolConstants.CAPABILITY_PUSH_OPTIONS;
+import static org.eclipse.jgit.transport.GitProtocolConstants.CAPABILITY_QUIET;
import static org.eclipse.jgit.transport.GitProtocolConstants.CAPABILITY_REPORT_STATUS;
+import static org.eclipse.jgit.transport.GitProtocolConstants.CAPABILITY_SIDE_BAND_64K;
+import static org.eclipse.jgit.transport.GitProtocolConstants.OPTION_AGENT;
+import static org.eclipse.jgit.transport.SideBandOutputStream.CH_DATA;
+import static org.eclipse.jgit.transport.SideBandOutputStream.CH_ERROR;
+import static org.eclipse.jgit.transport.SideBandOutputStream.CH_PROGRESS;
+import static org.eclipse.jgit.transport.SideBandOutputStream.MAX_BUF;
+import java.io.EOFException;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
+import java.text.MessageFormat;
import java.util.ArrayList;
import java.util.Collections;
+import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
+import java.util.concurrent.TimeUnit;
import org.eclipse.jgit.annotations.Nullable;
+import org.eclipse.jgit.errors.InvalidObjectIdException;
+import org.eclipse.jgit.errors.LargeObjectException;
+import org.eclipse.jgit.errors.MissingObjectException;
+import org.eclipse.jgit.errors.PackProtocolException;
+import org.eclipse.jgit.errors.TooLargePackException;
import org.eclipse.jgit.errors.UnpackException;
+import org.eclipse.jgit.internal.JGitText;
+import org.eclipse.jgit.internal.storage.file.PackLock;
+import org.eclipse.jgit.internal.submodule.SubmoduleValidator;
+import org.eclipse.jgit.internal.submodule.SubmoduleValidator.SubmoduleValidationException;
+import org.eclipse.jgit.internal.transport.parser.FirstCommand;
+import org.eclipse.jgit.lib.AnyObjectId;
+import org.eclipse.jgit.lib.BatchRefUpdate;
+import org.eclipse.jgit.lib.Config;
import org.eclipse.jgit.lib.ConfigConstants;
import org.eclipse.jgit.lib.Constants;
+import org.eclipse.jgit.lib.GitmoduleEntry;
import org.eclipse.jgit.lib.NullProgressMonitor;
+import org.eclipse.jgit.lib.ObjectChecker;
+import org.eclipse.jgit.lib.ObjectDatabase;
import org.eclipse.jgit.lib.ObjectId;
+import org.eclipse.jgit.lib.ObjectIdSubclassMap;
+import org.eclipse.jgit.lib.ObjectInserter;
+import org.eclipse.jgit.lib.ObjectLoader;
+import org.eclipse.jgit.lib.PersonIdent;
+import org.eclipse.jgit.lib.ProgressMonitor;
import org.eclipse.jgit.lib.Ref;
import org.eclipse.jgit.lib.Repository;
+import org.eclipse.jgit.revwalk.ObjectWalk;
+import org.eclipse.jgit.revwalk.RevBlob;
+import org.eclipse.jgit.revwalk.RevCommit;
+import org.eclipse.jgit.revwalk.RevFlag;
+import org.eclipse.jgit.revwalk.RevObject;
+import org.eclipse.jgit.revwalk.RevSort;
+import org.eclipse.jgit.revwalk.RevTree;
import org.eclipse.jgit.revwalk.RevWalk;
+import org.eclipse.jgit.transport.PacketLineIn.InputOverLimitIOException;
import org.eclipse.jgit.transport.ReceiveCommand.Result;
import org.eclipse.jgit.transport.RefAdvertiser.PacketLineOutRefAdvertiser;
+import org.eclipse.jgit.util.io.InterruptTimer;
+import org.eclipse.jgit.util.io.LimitedInputStream;
+import org.eclipse.jgit.util.io.TimeoutInputStream;
+import org.eclipse.jgit.util.io.TimeoutOutputStream;
/**
* Implements the server side of a push connection, receiving objects.
*/
-public class ReceivePack extends BaseReceivePack {
+public class ReceivePack {
+ /**
+ * Data in the first line of a request, the line itself plus capabilities.
+ *
+ * @deprecated Use {@link FirstCommand} instead.
+ * @since 5.6
+ */
+ @Deprecated
+ public static class FirstLine {
+ private final FirstCommand command;
+
+ /**
+ * Parse the first line of a receive-pack request.
+ *
+ * @param line
+ * line from the client.
+ */
+ public FirstLine(String line) {
+ command = FirstCommand.fromLine(line);
+ }
+
+ /** @return non-capabilities part of the line. */
+ public String getLine() {
+ return command.getLine();
+ }
+
+ /** @return capabilities parsed from the line. */
+ public Set<String> getCapabilities() {
+ return command.getCapabilities();
+ }
+ }
+
+ /** Database we write the stored objects into. */
+ private final Repository db;
+
+ /** Revision traversal support over {@link #db}. */
+ private final RevWalk walk;
+
+ /**
+ * Is the client connection a bi-directional socket or pipe?
+ * <p>
+ * If true, this class assumes it can perform multiple read and write cycles
+ * with the client over the input and output streams. This matches the
+ * functionality available with a standard TCP/IP connection, or a local
+ * operating system or in-memory pipe.
+ * <p>
+ * If false, this class runs in a read everything then output results mode,
+ * making it suitable for single round-trip systems RPCs such as HTTP.
+ */
+ private boolean biDirectionalPipe = true;
+
+ /** Expecting data after the pack footer */
+ private boolean expectDataAfterPackFooter;
+
+ /** Should an incoming transfer validate objects? */
+ private ObjectChecker objectChecker;
+
+ /** Should an incoming transfer permit create requests? */
+ private boolean allowCreates;
+
+ /** Should an incoming transfer permit delete requests? */
+ private boolean allowAnyDeletes;
+
+ private boolean allowBranchDeletes;
+
+ /** Should an incoming transfer permit non-fast-forward requests? */
+ private boolean allowNonFastForwards;
+
+ /** Should an incoming transfer permit push options? **/
+ private boolean allowPushOptions;
+
+ /**
+ * Should the requested ref updates be performed as a single atomic
+ * transaction?
+ */
+ private boolean atomic;
+
+ private boolean allowOfsDelta;
+
+ private boolean allowQuiet = true;
+
+ /** Identity to record action as within the reflog. */
+ private PersonIdent refLogIdent;
+
+ /** Hook used while advertising the refs to the client. */
+ private AdvertiseRefsHook advertiseRefsHook;
+
+ /** Filter used while advertising the refs to the client. */
+ private RefFilter refFilter;
+
+ /** Timeout in seconds to wait for client interaction. */
+ private int timeout;
+
+ /** Timer to manage {@link #timeout}. */
+ private InterruptTimer timer;
+
+ private TimeoutInputStream timeoutIn;
+
+ // Original stream passed to init(), since rawOut may be wrapped in a
+ // sideband.
+ private OutputStream origOut;
+
+ /** Raw input stream. */
+ private InputStream rawIn;
+
+ /** Raw output stream. */
+ private OutputStream rawOut;
+
+ /** Optional message output stream. */
+ private OutputStream msgOut;
+
+ private SideBandOutputStream errOut;
+
+ /** Packet line input stream around {@link #rawIn}. */
+ private PacketLineIn pckIn;
+
+ /** Packet line output stream around {@link #rawOut}. */
+ private PacketLineOut pckOut;
+
+ private final MessageOutputWrapper msgOutWrapper = new MessageOutputWrapper();
+
+ private PackParser parser;
+
+ /** The refs we advertised as existing at the start of the connection. */
+ private Map<String, Ref> refs;
+
+ /** All SHA-1s shown to the client, which can be possible edges. */
+ private Set<ObjectId> advertisedHaves;
+
+ /** Capabilities requested by the client. */
+ private Set<String> enabledCapabilities;
+
+ String userAgent;
+
+ private Set<ObjectId> clientShallowCommits;
+
+ private List<ReceiveCommand> commands;
+
+ private long maxCommandBytes;
+
+ private long maxDiscardBytes;
+
+ private StringBuilder advertiseError;
+
+ /**
+ * If {@link BasePackPushConnection#CAPABILITY_SIDE_BAND_64K} is enabled.
+ */
+ private boolean sideBand;
+
+ private boolean quiet;
+
+ /** Lock around the received pack file, while updating refs. */
+ private PackLock packLock;
+
+ private boolean checkReferencedIsReachable;
+
+ /** Git object size limit */
+ private long maxObjectSizeLimit;
+
+ /** Total pack size limit */
+ private long maxPackSizeLimit = -1;
+
+ /** The size of the received pack, including index size */
+ private Long packSize;
+
+ private PushCertificateParser pushCertificateParser;
+
+ private SignedPushConfig signedPushConfig;
+
+ private PushCertificate pushCert;
+
+ private ReceivedPackStatistics stats;
+
/** Hook to validate the update commands before execution. */
private PreReceiveHook preReceive;
@@ -93,18 +312,120 @@ public class ReceivePack extends BaseReceivePack {
* the destination repository.
*/
public ReceivePack(Repository into) {
- super(into);
+ db = into;
+ walk = new RevWalk(db);
+ walk.setRetainBody(false);
+
+ TransferConfig tc = db.getConfig().get(TransferConfig.KEY);
+ objectChecker = tc.newReceiveObjectChecker();
+
+ ReceiveConfig rc = db.getConfig().get(ReceiveConfig::new);
+ allowCreates = rc.allowCreates;
+ allowAnyDeletes = true;
+ allowBranchDeletes = rc.allowDeletes;
+ allowNonFastForwards = rc.allowNonFastForwards;
+ allowOfsDelta = rc.allowOfsDelta;
+ allowPushOptions = rc.allowPushOptions;
+ maxCommandBytes = rc.maxCommandBytes;
+ maxDiscardBytes = rc.maxDiscardBytes;
+ advertiseRefsHook = AdvertiseRefsHook.DEFAULT;
+ refFilter = RefFilter.DEFAULT;
+ advertisedHaves = new HashSet<>();
+ clientShallowCommits = new HashSet<>();
+ signedPushConfig = rc.signedPush;
preReceive = PreReceiveHook.NULL;
postReceive = PostReceiveHook.NULL;
}
+ /** Configuration for receive operations. */
+ private static class ReceiveConfig {
+ final boolean allowCreates;
+
+ final boolean allowDeletes;
+
+ final boolean allowNonFastForwards;
+
+ final boolean allowOfsDelta;
+
+ final boolean allowPushOptions;
+
+ final long maxCommandBytes;
+
+ final long maxDiscardBytes;
+
+ final SignedPushConfig signedPush;
+
+ ReceiveConfig(Config config) {
+ allowCreates = true;
+ allowDeletes = !config.getBoolean("receive", "denydeletes", false); //$NON-NLS-1$ //$NON-NLS-2$
+ allowNonFastForwards = !config.getBoolean("receive", //$NON-NLS-1$
+ "denynonfastforwards", false); //$NON-NLS-1$
+ allowOfsDelta = config.getBoolean("repack", "usedeltabaseoffset", //$NON-NLS-1$ //$NON-NLS-2$
+ true);
+ allowPushOptions = config.getBoolean("receive", "pushoptions", //$NON-NLS-1$ //$NON-NLS-2$
+ false);
+ maxCommandBytes = config.getLong("receive", //$NON-NLS-1$
+ "maxCommandBytes", //$NON-NLS-1$
+ 3 << 20);
+ maxDiscardBytes = config.getLong("receive", //$NON-NLS-1$
+ "maxCommandDiscardBytes", //$NON-NLS-1$
+ -1);
+ signedPush = SignedPushConfig.KEY.parse(config);
+ }
+ }
+
+ /**
+ * Output stream that wraps the current {@link #msgOut}.
+ * <p>
+ * We don't want to expose {@link #msgOut} directly because it can change
+ * several times over the course of a session.
+ */
+ class MessageOutputWrapper extends OutputStream {
+ @Override
+ public void write(int ch) {
+ if (msgOut != null) {
+ try {
+ msgOut.write(ch);
+ } catch (IOException e) {
+ // Ignore write failures.
+ }
+ }
+ }
+
+ @Override
+ public void write(byte[] b, int off, int len) {
+ if (msgOut != null) {
+ try {
+ msgOut.write(b, off, len);
+ } catch (IOException e) {
+ // Ignore write failures.
+ }
+ }
+ }
+
+ @Override
+ public void write(byte[] b) {
+ write(b, 0, b.length);
+ }
+
+ @Override
+ public void flush() {
+ if (msgOut != null) {
+ try {
+ msgOut.flush();
+ } catch (IOException e) {
+ // Ignore write failures.
+ }
+ }
+ }
+ }
+
/**
* Get the repository this receive completes into.
*
* @return the repository this receive completes into.
*/
- @Override
- public final Repository getRepository() {
+ public Repository getRepository() {
return db;
}
@@ -113,8 +434,7 @@ public final Repository getRepository() {
*
* @return the RevWalk instance used by this connection.
*/
- @Override
- public final RevWalk getRevWalk() {
+ public RevWalk getRevWalk() {
return walk;
}
@@ -124,8 +444,7 @@ public final RevWalk getRevWalk() {
* @return all refs which were advertised to the client, or null if
* {@link #setAdvertisedRefs(Map, Set)} has not been called yet.
*/
- @Override
- public final Map<String, Ref> getAdvertisedRefs() {
+ public Map<String, Ref> getAdvertisedRefs() {
return refs;
}
@@ -146,8 +465,8 @@ public final Map<String, Ref> getAdvertisedRefs() {
* null, assumes the default set of additional haves from the
* repository.
*/
- @Override
- public void setAdvertisedRefs(Map<String, Ref> allRefs, Set<ObjectId> additionalHaves) {
+ public void setAdvertisedRefs(Map<String, Ref> allRefs,
+ Set<ObjectId> additionalHaves) {
refs = allRefs != null ? allRefs : db.getAllRefs();
refs = refFilter.filter(refs);
advertisedHaves.clear();
@@ -170,6 +489,1525 @@ public void setAdvertisedRefs(Map<String, Ref> allRefs, Set<ObjectId> additional
}
/**
+ * Get objects advertised to the client.
+ *
+ * @return the set of objects advertised to the as present in this
+ * repository, or null if {@link #setAdvertisedRefs(Map, Set)} has
+ * not been called yet.
+ */
+ public final Set<ObjectId> getAdvertisedObjects() {
+ return advertisedHaves;
+ }
+
+ /**
+ * Whether this instance will validate all referenced, but not supplied by
+ * the client, objects are reachable from another reference.
+ *
+ * @return true if this instance will validate all referenced, but not
+ * supplied by the client, objects are reachable from another
+ * reference.
+ */
+ public boolean isCheckReferencedObjectsAreReachable() {
+ return checkReferencedIsReachable;
+ }
+
+ /**
+ * Validate all referenced but not supplied objects are reachable.
+ * <p>
+ * If enabled, this instance will verify that references to objects not
+ * contained within the received pack are already reachable through at least
+ * one other reference displayed as part of {@link #getAdvertisedRefs()}.
+ * <p>
+ * This feature is useful when the application doesn't trust the client to
+ * not provide a forged SHA-1 reference to an object, in an attempt to
+ * access parts of the DAG that they aren't allowed to see and which have
+ * been hidden from them via the configured
+ * {@link org.eclipse.jgit.transport.AdvertiseRefsHook} or
+ * {@link org.eclipse.jgit.transport.RefFilter}.
+ * <p>
+ * Enabling this feature may imply at least some, if not all, of the same
+ * functionality performed by {@link #setCheckReceivedObjects(boolean)}.
+ * Applications are encouraged to enable both features, if desired.
+ *
+ * @param b
+ * {@code true} to enable the additional check.
+ */
+ public void setCheckReferencedObjectsAreReachable(boolean b) {
+ this.checkReferencedIsReachable = b;
+ }
+
+ /**
+ * Whether this class expects a bi-directional pipe opened between the
+ * client and itself.
+ *
+ * @return true if this class expects a bi-directional pipe opened between
+ * the client and itself. The default is true.
+ */
+ public boolean isBiDirectionalPipe() {
+ return biDirectionalPipe;
+ }
+
+ /**
+ * Whether this class will assume the socket is a fully bidirectional pipe
+ * between the two peers and takes advantage of that by first transmitting
+ * the known refs, then waiting to read commands.
+ *
+ * @param twoWay
+ * if true, this class will assume the socket is a fully
+ * bidirectional pipe between the two peers and takes advantage
+ * of that by first transmitting the known refs, then waiting to
+ * read commands. If false, this class assumes it must read the
+ * commands before writing output and does not perform the
+ * initial advertising.
+ */
+ public void setBiDirectionalPipe(boolean twoWay) {
+ biDirectionalPipe = twoWay;
+ }
+
+ /**
+ * Whether there is data expected after the pack footer.
+ *
+ * @return {@code true} if there is data expected after the pack footer.
+ */
+ public boolean isExpectDataAfterPackFooter() {
+ return expectDataAfterPackFooter;
+ }
+
+ /**
+ * Whether there is additional data in InputStream after pack.
+ *
+ * @param e
+ * {@code true} if there is additional data in InputStream after
+ * pack.
+ */
+ public void setExpectDataAfterPackFooter(boolean e) {
+ expectDataAfterPackFooter = e;
+ }
+
+ /**
+ * Whether this instance will verify received objects are formatted
+ * correctly.
+ *
+ * @return {@code true} if this instance will verify received objects are
+ * formatted correctly. Validating objects requires more CPU time on
+ * this side of the connection.
+ */
+ public boolean isCheckReceivedObjects() {
+ return objectChecker != null;
+ }
+
+ /**
+ * Whether to enable checking received objects
+ *
+ * @param check
+ * {@code true} to enable checking received objects; false to
+ * assume all received objects are valid.
+ * @see #setObjectChecker(ObjectChecker)
+ */
+ public void setCheckReceivedObjects(boolean check) {
+ if (check && objectChecker == null)
+ setObjectChecker(new ObjectChecker());
+ else if (!check && objectChecker != null)
+ setObjectChecker(null);
+ }
+
+ /**
+ * Set the object checking instance to verify each received object with
+ *
+ * @param impl
+ * if non-null the object checking instance to verify each
+ * received object with; null to disable object checking.
+ * @since 3.4
+ */
+ public void setObjectChecker(ObjectChecker impl) {
+ objectChecker = impl;
+ }
+
+ /**
+ * Whether the client can request refs to be created.
+ *
+ * @return {@code true} if the client can request refs to be created.
+ */
+ public boolean isAllowCreates() {
+ return allowCreates;
+ }
+
+ /**
+ * Whether to permit create ref commands to be processed.
+ *
+ * @param canCreate
+ * {@code true} to permit create ref commands to be processed.
+ */
+ public void setAllowCreates(boolean canCreate) {
+ allowCreates = canCreate;
+ }
+
+ /**
+ * Whether the client can request refs to be deleted.
+ *
+ * @return {@code true} if the client can request refs to be deleted.
+ */
+ public boolean isAllowDeletes() {
+ return allowAnyDeletes;
+ }
+
+ /**
+ * Whether to permit delete ref commands to be processed.
+ *
+ * @param canDelete
+ * {@code true} to permit delete ref commands to be processed.
+ */
+ public void setAllowDeletes(boolean canDelete) {
+ allowAnyDeletes = canDelete;
+ }
+
+ /**
+ * Whether the client can delete from {@code refs/heads/}.
+ *
+ * @return {@code true} if the client can delete from {@code refs/heads/}.
+ * @since 3.6
+ */
+ public boolean isAllowBranchDeletes() {
+ return allowBranchDeletes;
+ }
+
+ /**
+ * Configure whether to permit deletion of branches from the
+ * {@code refs/heads/} namespace.
+ *
+ * @param canDelete
+ * {@code true} to permit deletion of branches from the
+ * {@code refs/heads/} namespace.
+ * @since 3.6
+ */
+ public void setAllowBranchDeletes(boolean canDelete) {
+ allowBranchDeletes = canDelete;
+ }
+
+ /**
+ * Whether the client can request non-fast-forward updates of a ref,
+ * possibly making objects unreachable.
+ *
+ * @return {@code true} if the client can request non-fast-forward updates
+ * of a ref, possibly making objects unreachable.
+ */
+ public boolean isAllowNonFastForwards() {
+ return allowNonFastForwards;
+ }
+
+ /**
+ * Configure whether to permit the client to ask for non-fast-forward
+ * updates of an existing ref.
+ *
+ * @param canRewind
+ * {@code true} to permit the client to ask for non-fast-forward
+ * updates of an existing ref.
+ */
+ public void setAllowNonFastForwards(boolean canRewind) {
+ allowNonFastForwards = canRewind;
+ }
+
+ /**
+ * Whether the client's commands should be performed as a single atomic
+ * transaction.
+ *
+ * @return {@code true} if the client's commands should be performed as a
+ * single atomic transaction.
+ * @since 4.4
+ */
+ public boolean isAtomic() {
+ return atomic;
+ }
+
+ /**
+ * Configure whether to perform the client's commands as a single atomic
+ * transaction.
+ *
+ * @param atomic
+ * {@code true} to perform the client's commands as a single
+ * atomic transaction.
+ * @since 4.4
+ */
+ public void setAtomic(boolean atomic) {
+ this.atomic = atomic;
+ }
+
+ /**
+ * Get identity of the user making the changes in the reflog.
+ *
+ * @return identity of the user making the changes in the reflog.
+ */
+ public PersonIdent getRefLogIdent() {
+ return refLogIdent;
+ }
+
+ /**
+ * Set the identity of the user appearing in the affected reflogs.
+ * <p>
+ * The timestamp portion of the identity is ignored. A new identity with the
+ * current timestamp will be created automatically when the updates occur
+ * and the log records are written.
+ *
+ * @param pi
+ * identity of the user. If null the identity will be
+ * automatically determined based on the repository
+ * configuration.
+ */
+ public void setRefLogIdent(PersonIdent pi) {
+ refLogIdent = pi;
+ }
+
+ /**
+ * Get the hook used while advertising the refs to the client
+ *
+ * @return the hook used while advertising the refs to the client
+ */
+ public AdvertiseRefsHook getAdvertiseRefsHook() {
+ return advertiseRefsHook;
+ }
+
+ /**
+ * Get the filter used while advertising the refs to the client
+ *
+ * @return the filter used while advertising the refs to the client
+ */
+ public RefFilter getRefFilter() {
+ return refFilter;
+ }
+
+ /**
+ * Set the hook used while advertising the refs to the client.
+ * <p>
+ * If the {@link org.eclipse.jgit.transport.AdvertiseRefsHook} chooses to
+ * call {@link #setAdvertisedRefs(Map,Set)}, only refs set by this hook
+ * <em>and</em> selected by the {@link org.eclipse.jgit.transport.RefFilter}
+ * will be shown to the client. Clients may still attempt to create or
+ * update a reference not advertised by the configured
+ * {@link org.eclipse.jgit.transport.AdvertiseRefsHook}. These attempts
+ * should be rejected by a matching
+ * {@link org.eclipse.jgit.transport.PreReceiveHook}.
+ *
+ * @param advertiseRefsHook
+ * the hook; may be null to show all refs.
+ */
+ public void setAdvertiseRefsHook(AdvertiseRefsHook advertiseRefsHook) {
+ if (advertiseRefsHook != null)
+ this.advertiseRefsHook = advertiseRefsHook;
+ else
+ this.advertiseRefsHook = AdvertiseRefsHook.DEFAULT;
+ }
+
+ /**
+ * Set the filter used while advertising the refs to the client.
+ * <p>
+ * Only refs allowed by this filter will be shown to the client. The filter
+ * is run against the refs specified by the
+ * {@link org.eclipse.jgit.transport.AdvertiseRefsHook} (if applicable).
+ *
+ * @param refFilter
+ * the filter; may be null to show all refs.
+ */
+ public void setRefFilter(RefFilter refFilter) {
+ this.refFilter = refFilter != null ? refFilter : RefFilter.DEFAULT;
+ }
+
+ /**
+ * Get timeout (in seconds) before aborting an IO operation.
+ *
+ * @return timeout (in seconds) before aborting an IO operation.
+ */
+ public int getTimeout() {
+ return timeout;
+ }
+
+ /**
+ * Set the timeout before willing to abort an IO call.
+ *
+ * @param seconds
+ * number of seconds to wait (with no data transfer occurring)
+ * before aborting an IO read or write operation with the
+ * connected client.
+ */
+ public void setTimeout(int seconds) {
+ timeout = seconds;
+ }
+
+ /**
+ * Set the maximum number of command bytes to read from the client.
+ *
+ * @param limit
+ * command limit in bytes; if 0 there is no limit.
+ * @since 4.7
+ */
+ public void setMaxCommandBytes(long limit) {
+ maxCommandBytes = limit;
+ }
+
+ /**
+ * Set the maximum number of command bytes to discard from the client.
+ * <p>
+ * Discarding remaining bytes allows this instance to consume the rest of
+ * the command block and send a human readable over-limit error via the
+ * side-band channel. If the client sends an excessive number of bytes this
+ * limit kicks in and the instance disconnects, resulting in a non-specific
+ * 'pipe closed', 'end of stream', or similar generic error at the client.
+ * <p>
+ * When the limit is set to {@code -1} the implementation will default to
+ * the larger of {@code 3 * maxCommandBytes} or {@code 3 MiB}.
+ *
+ * @param limit
+ * discard limit in bytes; if 0 there is no limit; if -1 the
+ * implementation tries to set a reasonable default.
+ * @since 4.7
+ */
+ public void setMaxCommandDiscardBytes(long limit) {
+ maxDiscardBytes = limit;
+ }
+
+ /**
+ * Set the maximum allowed Git object size.
+ * <p>
+ * If an object is larger than the given size the pack-parsing will throw an
+ * exception aborting the receive-pack operation.
+ *
+ * @param limit
+ * the Git object size limit. If zero then there is not limit.
+ */
+ public void setMaxObjectSizeLimit(long limit) {
+ maxObjectSizeLimit = limit;
+ }
+
+ /**
+ * Set the maximum allowed pack size.
+ * <p>
+ * A pack exceeding this size will be rejected.
+ *
+ * @param limit
+ * the pack size limit, in bytes
+ * @since 3.3
+ */
+ public void setMaxPackSizeLimit(long limit) {
+ if (limit < 0)
+ throw new IllegalArgumentException(
+ MessageFormat.format(JGitText.get().receivePackInvalidLimit,
+ Long.valueOf(limit)));
+ maxPackSizeLimit = limit;
+ }
+
+ /**
+ * Check whether the client expects a side-band stream.
+ *
+ * @return true if the client has advertised a side-band capability, false
+ * otherwise.
+ * @throws org.eclipse.jgit.transport.RequestNotYetReadException
+ * if the client's request has not yet been read from the wire,
+ * so we do not know if they expect side-band. Note that the
+ * client may have already written the request, it just has not
+ * been read.
+ */
+ public boolean isSideBand() throws RequestNotYetReadException {
+ checkRequestWasRead();
+ return enabledCapabilities.contains(CAPABILITY_SIDE_BAND_64K);
+ }
+
+ /**
+ * Whether clients may request avoiding noisy progress messages.
+ *
+ * @return true if clients may request avoiding noisy progress messages.
+ * @since 4.0
+ */
+ public boolean isAllowQuiet() {
+ return allowQuiet;
+ }
+
+ /**
+ * Configure if clients may request the server skip noisy messages.
+ *
+ * @param allow
+ * true to allow clients to request quiet behavior; false to
+ * refuse quiet behavior and send messages anyway. This may be
+ * necessary if processing is slow and the client-server network
+ * connection can timeout.
+ * @since 4.0
+ */
+ public void setAllowQuiet(boolean allow) {
+ allowQuiet = allow;
+ }
+
+ /**
+ * Whether the server supports receiving push options.
+ *
+ * @return true if the server supports receiving push options.
+ * @since 4.5
+ */
+ public boolean isAllowPushOptions() {
+ return allowPushOptions;
+ }
+
+ /**
+ * Configure if the server supports receiving push options.
+ *
+ * @param allow
+ * true to optionally accept option strings from the client.
+ * @since 4.5
+ */
+ public void setAllowPushOptions(boolean allow) {
+ allowPushOptions = allow;
+ }
+
+ /**
+ * True if the client wants less verbose output.
+ *
+ * @return true if the client has requested the server to be less verbose.
+ * @throws org.eclipse.jgit.transport.RequestNotYetReadException
+ * if the client's request has not yet been read from the wire,
+ * so we do not know if they expect side-band. Note that the
+ * client may have already written the request, it just has not
+ * been read.
+ * @since 4.0
+ */
+ public boolean isQuiet() throws RequestNotYetReadException {
+ checkRequestWasRead();
+ return quiet;
+ }
+
+ /**
+ * Set the configuration for push certificate verification.
+ *
+ * @param cfg
+ * new configuration; if this object is null or its
+ * {@link SignedPushConfig#getCertNonceSeed()} is null, push
+ * certificate verification will be disabled.
+ * @since 4.1
+ */
+ public void setSignedPushConfig(SignedPushConfig cfg) {
+ signedPushConfig = cfg;
+ }
+
+ private PushCertificateParser getPushCertificateParser() {
+ if (pushCertificateParser == null) {
+ pushCertificateParser = new PushCertificateParser(db,
+ signedPushConfig);
+ }
+ return pushCertificateParser;
+ }
+
+ /**
+ * Get the user agent of the client.
+ * <p>
+ * If the client is new enough to use {@code agent=} capability that value
+ * will be returned. Older HTTP clients may also supply their version using
+ * the HTTP {@code User-Agent} header. The capability overrides the HTTP
+ * header if both are available.
+ * <p>
+ * When an HTTP request has been received this method returns the HTTP
+ * {@code User-Agent} header value until capabilities have been parsed.
+ *
+ * @return user agent supplied by the client. Available only if the client
+ * is new enough to advertise its user agent.
+ * @since 4.0
+ */
+ public String getPeerUserAgent() {
+ return UserAgent.getAgent(enabledCapabilities, userAgent);
+ }
+
+ /**
+ * Get all of the command received by the current request.
+ *
+ * @return all of the command received by the current request.
+ */
+ public List<ReceiveCommand> getAllCommands() {
+ return Collections.unmodifiableList(commands);
+ }
+
+ /**
+ * Send an error message to the client.
+ * <p>
+ * If any error messages are sent before the references are advertised to
+ * the client, the errors will be sent instead of the advertisement and the
+ * receive operation will be aborted. All clients should receive and display
+ * such early stage errors.
+ * <p>
+ * If the reference advertisements have already been sent, messages are sent
+ * in a side channel. If the client doesn't support receiving messages, the
+ * message will be discarded, with no other indication to the caller or to
+ * the client.
+ * <p>
+ * {@link org.eclipse.jgit.transport.PreReceiveHook}s should always try to
+ * use
+ * {@link org.eclipse.jgit.transport.ReceiveCommand#setResult(Result, String)}
+ * with a result status of
+ * {@link org.eclipse.jgit.transport.ReceiveCommand.Result#REJECTED_OTHER_REASON}
+ * to indicate any reasons for rejecting an update. Messages attached to a
+ * command are much more likely to be returned to the client.
+ *
+ * @param what
+ * string describing the problem identified by the hook. The
+ * string must not end with an LF, and must not contain an LF.
+ */
+ public void sendError(String what) {
+ if (refs == null) {
+ if (advertiseError == null)
+ advertiseError = new StringBuilder();
+ advertiseError.append(what).append('\n');
+ } else {
+ msgOutWrapper.write(Constants.encode("error: " + what + "\n")); //$NON-NLS-1$ //$NON-NLS-2$
+ }
+ }
+
+ private void fatalError(String msg) {
+ if (errOut != null) {
+ try {
+ errOut.write(Constants.encode(msg));
+ errOut.flush();
+ } catch (IOException e) {
+ // Ignore write failures
+ }
+ } else {
+ sendError(msg);
+ }
+ }
+
+ /**
+ * Send a message to the client, if it supports receiving them.
+ * <p>
+ * If the client doesn't support receiving messages, the message will be
+ * discarded, with no other indication to the caller or to the client.
+ *
+ * @param what
+ * string describing the problem identified by the hook. The
+ * string must not end with an LF, and must not contain an LF.
+ */
+ public void sendMessage(String what) {
+ msgOutWrapper.write(Constants.encode(what + "\n")); //$NON-NLS-1$
+ }
+
+ /**
+ * Get an underlying stream for sending messages to the client.
+ *
+ * @return an underlying stream for sending messages to the client.
+ */
+ public OutputStream getMessageOutputStream() {
+ return msgOutWrapper;
+ }
+
+ /**
+ * Get whether or not a pack has been received.
+ *
+ * This can be called before calling {@link #getPackSize()} to avoid causing
+ * {@code IllegalStateException} when the pack size was not set because no
+ * pack was received.
+ *
+ * @return true if a pack has been received.
+ * @since 5.6
+ */
+ public boolean hasReceivedPack() {
+ return packSize != null;
+ }
+
+ /**
+ * Get the size of the received pack file including the index size.
+ *
+ * This can only be called if the pack is already received.
+ *
+ * @return the size of the received pack including index size
+ * @throws java.lang.IllegalStateException
+ * if called before the pack has been received
+ * @since 3.3
+ */
+ public long getPackSize() {
+ if (packSize != null)
+ return packSize.longValue();
+ throw new IllegalStateException(JGitText.get().packSizeNotSetYet);
+ }
+
+ /**
+ * Get the commits from the client's shallow file.
+ *
+ * @return if the client is a shallow repository, the list of edge commits
+ * that define the client's shallow boundary. Empty set if the
+ * client is earlier than Git 1.9, or is a full clone.
+ */
+ private Set<ObjectId> getClientShallowCommits() {
+ return clientShallowCommits;
+ }
+
+ /**
+ * Whether any commands to be executed have been read.
+ *
+ * @return {@code true} if any commands to be executed have been read.
+ */
+ private boolean hasCommands() {
+ return !commands.isEmpty();
+ }
+
+ /**
+ * Whether an error occurred that should be advertised.
+ *
+ * @return true if an error occurred that should be advertised.
+ */
+ private boolean hasError() {
+ return advertiseError != null;
+ }
+
+ /**
+ * Initialize the instance with the given streams.
+ *
+ * Visible for out-of-tree subclasses (e.g. tests that need to set the
+ * streams without going through the {@link #service()} method).
+ *
+ * @param input
+ * raw input to read client commands and pack data from. Caller
+ * must ensure the input is buffered, otherwise read performance
+ * may suffer.
+ * @param output
+ * response back to the Git network client. Caller must ensure
+ * the output is buffered, otherwise write performance may
+ * suffer.
+ * @param messages
+ * secondary "notice" channel to send additional messages out
+ * through. When run over SSH this should be tied back to the
+ * standard error channel of the command execution. For most
+ * other network connections this should be null.
+ */
+ protected void init(final InputStream input, final OutputStream output,
+ final OutputStream messages) {
+ origOut = output;
+ rawIn = input;
+ rawOut = output;
+ msgOut = messages;
+
+ if (timeout > 0) {
+ final Thread caller = Thread.currentThread();
+ timer = new InterruptTimer(caller.getName() + "-Timer"); //$NON-NLS-1$
+ timeoutIn = new TimeoutInputStream(rawIn, timer);
+ TimeoutOutputStream o = new TimeoutOutputStream(rawOut, timer);
+ timeoutIn.setTimeout(timeout * 1000);
+ o.setTimeout(timeout * 1000);
+ rawIn = timeoutIn;
+ rawOut = o;
+ }
+
+ pckIn = new PacketLineIn(rawIn);
+ pckOut = new PacketLineOut(rawOut);
+ pckOut.setFlushOnEnd(false);
+
+ enabledCapabilities = new HashSet<>();
+ commands = new ArrayList<>();
+ }
+
+ /**
+ * Get advertised refs, or the default if not explicitly advertised.
+ *
+ * @return advertised refs, or the default if not explicitly advertised.
+ */
+ private Map<String, Ref> getAdvertisedOrDefaultRefs() {
+ if (refs == null)
+ setAdvertisedRefs(null, null);
+ return refs;
+ }
+
+ /**
+ * Receive a pack from the stream and check connectivity if necessary.
+ *
+ * Visible for out-of-tree subclasses. Subclasses overriding this method
+ * should invoke this implementation, as it alters the instance state (e.g.
+ * it reads the pack from the input and parses it before running the
+ * connectivity checks).
+ *
+ * @throws java.io.IOException
+ * an error occurred during unpacking or connectivity checking.
+ */
+ protected void receivePackAndCheckConnectivity() throws IOException {
+ receivePack();
+ if (needCheckConnectivity()) {
+ checkSubmodules();
+ checkConnectivity();
+ }
+ parser = null;
+ }
+
+ /**
+ * Unlock the pack written by this object.
+ *
+ * @throws java.io.IOException
+ * the pack could not be unlocked.
+ */
+ private void unlockPack() throws IOException {
+ if (packLock != null) {
+ packLock.unlock();
+ packLock = null;
+ }
+ }
+
+ /**
+ * Generate an advertisement of available refs and capabilities.
+ *
+ * @param adv
+ * the advertisement formatter.
+ * @throws java.io.IOException
+ * the formatter failed to write an advertisement.
+ * @throws org.eclipse.jgit.transport.ServiceMayNotContinueException
+ * the hook denied advertisement.
+ */
+ public void sendAdvertisedRefs(RefAdvertiser adv)
+ throws IOException, ServiceMayNotContinueException {
+ if (advertiseError != null) {
+ adv.writeOne("ERR " + advertiseError); //$NON-NLS-1$
+ return;
+ }
+
+ try {
+ advertiseRefsHook.advertiseRefs(this);
+ } catch (ServiceMayNotContinueException fail) {
+ if (fail.getMessage() != null) {
+ adv.writeOne("ERR " + fail.getMessage()); //$NON-NLS-1$
+ fail.setOutput();
+ }
+ throw fail;
+ }
+
+ adv.init(db);
+ adv.advertiseCapability(CAPABILITY_SIDE_BAND_64K);
+ adv.advertiseCapability(CAPABILITY_DELETE_REFS);
+ adv.advertiseCapability(CAPABILITY_REPORT_STATUS);
+ if (allowQuiet)
+ adv.advertiseCapability(CAPABILITY_QUIET);
+ String nonce = getPushCertificateParser().getAdvertiseNonce();
+ if (nonce != null) {
+ adv.advertiseCapability(nonce);
+ }
+ if (db.getRefDatabase().performsAtomicTransactions())
+ adv.advertiseCapability(CAPABILITY_ATOMIC);
+ if (allowOfsDelta)
+ adv.advertiseCapability(CAPABILITY_OFS_DELTA);
+ if (allowPushOptions) {
+ adv.advertiseCapability(CAPABILITY_PUSH_OPTIONS);
+ }
+ adv.advertiseCapability(OPTION_AGENT, UserAgent.get());
+ adv.send(getAdvertisedOrDefaultRefs().values());
+ for (ObjectId obj : advertisedHaves)
+ adv.advertiseHave(obj);
+ if (adv.isEmpty())
+ adv.advertiseId(ObjectId.zeroId(), "capabilities^{}"); //$NON-NLS-1$
+ adv.end();
+ }
+
+ /**
+ * Returns the statistics on the received pack if available. This should be
+ * called after {@link #receivePack} is called.
+ *
+ * @return ReceivedPackStatistics
+ * @since 4.6
+ */
+ @Nullable
+ public ReceivedPackStatistics getReceivedPackStatistics() {
+ return stats;
+ }
+
+ /**
+ * Receive a list of commands from the input.
+ *
+ * @throws java.io.IOException
+ */
+ private void recvCommands() throws IOException {
+ PacketLineIn pck = maxCommandBytes > 0
+ ? new PacketLineIn(rawIn, maxCommandBytes)
+ : pckIn;
+ PushCertificateParser certParser = getPushCertificateParser();
+ boolean firstPkt = true;
+ try {
+ for (;;) {
+ String line;
+ try {
+ line = pck.readString();
+ } catch (EOFException eof) {
+ if (commands.isEmpty())
+ return;
+ throw eof;
+ }
+ if (PacketLineIn.isEnd(line)) {
+ break;
+ }
+
+ if (line.length() >= 48 && line.startsWith("shallow ")) { //$NON-NLS-1$
+ parseShallow(line.substring(8, 48));
+ continue;
+ }
+
+ if (firstPkt) {
+ firstPkt = false;
+ FirstCommand firstLine = FirstCommand.fromLine(line);
+ enabledCapabilities = firstLine.getCapabilities();
+ line = firstLine.getLine();
+ enableCapabilities();
+
+ if (line.equals(GitProtocolConstants.OPTION_PUSH_CERT)) {
+ certParser.receiveHeader(pck, !isBiDirectionalPipe());
+ continue;
+ }
+ }
+
+ if (line.equals(PushCertificateParser.BEGIN_SIGNATURE)) {
+ certParser.receiveSignature(pck);
+ continue;
+ }
+
+ ReceiveCommand cmd = parseCommand(line);
+ if (cmd.getRefName().equals(Constants.HEAD)) {
+ cmd.setResult(Result.REJECTED_CURRENT_BRANCH);
+ } else {
+ cmd.setRef(refs.get(cmd.getRefName()));
+ }
+ commands.add(cmd);
+ if (certParser.enabled()) {
+ certParser.addCommand(cmd);
+ }
+ }
+ pushCert = certParser.build();
+ if (hasCommands()) {
+ readPostCommands(pck);
+ }
+ } catch (PackProtocolException e) {
+ discardCommands();
+ fatalError(e.getMessage());
+ throw e;
+ } catch (InputOverLimitIOException e) {
+ String msg = JGitText.get().tooManyCommands;
+ discardCommands();
+ fatalError(msg);
+ throw new PackProtocolException(msg);
+ }
+ }
+
+ private void discardCommands() {
+ if (sideBand) {
+ long max = maxDiscardBytes;
+ if (max < 0) {
+ max = Math.max(3 * maxCommandBytes, 3L << 20);
+ }
+ try {
+ new PacketLineIn(rawIn, max).discardUntilEnd();
+ } catch (IOException e) {
+ // Ignore read failures attempting to discard.
+ }
+ }
+ }
+
+ private void parseShallow(String idStr) throws PackProtocolException {
+ ObjectId id;
+ try {
+ id = ObjectId.fromString(idStr);
+ } catch (InvalidObjectIdException e) {
+ throw new PackProtocolException(e.getMessage(), e);
+ }
+ clientShallowCommits.add(id);
+ }
+
+ /**
+ * @param in
+ * request stream.
+ * @throws IOException
+ * request line cannot be read.
+ */
+ void readPostCommands(PacketLineIn in) throws IOException {
+ if (usePushOptions) {
+ pushOptions = new ArrayList<>(4);
+ for (;;) {
+ String option = in.readString();
+ if (PacketLineIn.isEnd(option)) {
+ break;
+ }
+ pushOptions.add(option);
+ }
+ }
+ }
+
+ /**
+ * Enable capabilities based on a previously read capabilities line.
+ */
+ private void enableCapabilities() {
+ reportStatus = isCapabilityEnabled(CAPABILITY_REPORT_STATUS);
+ usePushOptions = isCapabilityEnabled(CAPABILITY_PUSH_OPTIONS);
+ sideBand = isCapabilityEnabled(CAPABILITY_SIDE_BAND_64K);
+ quiet = allowQuiet && isCapabilityEnabled(CAPABILITY_QUIET);
+ if (sideBand) {
+ OutputStream out = rawOut;
+
+ rawOut = new SideBandOutputStream(CH_DATA, MAX_BUF, out);
+ msgOut = new SideBandOutputStream(CH_PROGRESS, MAX_BUF, out);
+ errOut = new SideBandOutputStream(CH_ERROR, MAX_BUF, out);
+
+ pckOut = new PacketLineOut(rawOut);
+ pckOut.setFlushOnEnd(false);
+ }
+ }
+
+ /**
+ * Check if the peer requested a capability.
+ *
+ * @param name
+ * protocol name identifying the capability.
+ * @return true if the peer requested the capability to be enabled.
+ */
+ private boolean isCapabilityEnabled(String name) {
+ return enabledCapabilities.contains(name);
+ }
+
+ private void checkRequestWasRead() {
+ if (enabledCapabilities == null)
+ throw new RequestNotYetReadException();
+ }
+
+ /**
+ * Whether a pack is expected based on the list of commands.
+ *
+ * @return {@code true} if a pack is expected based on the list of commands.
+ */
+ private boolean needPack() {
+ for (ReceiveCommand cmd : commands) {
+ if (cmd.getType() != ReceiveCommand.Type.DELETE)
+ return true;
+ }
+ return false;
+ }
+
+ /**
+ * Receive a pack from the input and store it in the repository.
+ *
+ * @throws IOException
+ * an error occurred reading or indexing the pack.
+ */
+ private void receivePack() throws IOException {
+ // It might take the client a while to pack the objects it needs
+ // to send to us. We should increase our timeout so we don't
+ // abort while the client is computing.
+ //
+ if (timeoutIn != null)
+ timeoutIn.setTimeout(10 * timeout * 1000);
+
+ ProgressMonitor receiving = NullProgressMonitor.INSTANCE;
+ ProgressMonitor resolving = NullProgressMonitor.INSTANCE;
+ if (sideBand && !quiet)
+ resolving = new SideBandProgressMonitor(msgOut);
+
+ try (ObjectInserter ins = db.newObjectInserter()) {
+ String lockMsg = "jgit receive-pack"; //$NON-NLS-1$
+ if (getRefLogIdent() != null)
+ lockMsg += " from " + getRefLogIdent().toExternalString(); //$NON-NLS-1$
+
+ parser = ins.newPackParser(packInputStream());
+ parser.setAllowThin(true);
+ parser.setNeedNewObjectIds(checkReferencedIsReachable);
+ parser.setNeedBaseObjectIds(checkReferencedIsReachable);
+ parser.setCheckEofAfterPackFooter(
+ !biDirectionalPipe && !isExpectDataAfterPackFooter());
+ parser.setExpectDataAfterPackFooter(isExpectDataAfterPackFooter());
+ parser.setObjectChecker(objectChecker);
+ parser.setLockMessage(lockMsg);
+ parser.setMaxObjectSizeLimit(maxObjectSizeLimit);
+ packLock = parser.parse(receiving, resolving);
+ packSize = Long.valueOf(parser.getPackSize());
+ stats = parser.getReceivedPackStatistics();
+ ins.flush();
+ }
+
+ if (timeoutIn != null)
+ timeoutIn.setTimeout(timeout * 1000);
+ }
+
+ private InputStream packInputStream() {
+ InputStream packIn = rawIn;
+ if (maxPackSizeLimit >= 0) {
+ packIn = new LimitedInputStream(packIn, maxPackSizeLimit) {
+ @Override
+ protected void limitExceeded() throws TooLargePackException {
+ throw new TooLargePackException(limit);
+ }
+ };
+ }
+ return packIn;
+ }
+
+ private boolean needCheckConnectivity() {
+ return isCheckReceivedObjects()
+ || isCheckReferencedObjectsAreReachable()
+ || !getClientShallowCommits().isEmpty();
+ }
+
+ private void checkSubmodules() throws IOException {
+ ObjectDatabase odb = db.getObjectDatabase();
+ if (objectChecker == null) {
+ return;
+ }
+ for (GitmoduleEntry entry : objectChecker.getGitsubmodules()) {
+ AnyObjectId blobId = entry.getBlobId();
+ ObjectLoader blob = odb.open(blobId, Constants.OBJ_BLOB);
+
+ try {
+ SubmoduleValidator.assertValidGitModulesFile(
+ new String(blob.getBytes(), UTF_8));
+ } catch (LargeObjectException | SubmoduleValidationException e) {
+ throw new IOException(e);
+ }
+ }
+ }
+
+ private void checkConnectivity() throws IOException {
+ ObjectIdSubclassMap<ObjectId> baseObjects = null;
+ ObjectIdSubclassMap<ObjectId> providedObjects = null;
+ ProgressMonitor checking = NullProgressMonitor.INSTANCE;
+ if (sideBand && !quiet) {
+ SideBandProgressMonitor m = new SideBandProgressMonitor(msgOut);
+ m.setDelayStart(750, TimeUnit.MILLISECONDS);
+ checking = m;
+ }
+
+ if (checkReferencedIsReachable) {
+ baseObjects = parser.getBaseObjectIds();
+ providedObjects = parser.getNewObjectIds();
+ }
+ parser = null;
+
+ try (ObjectWalk ow = new ObjectWalk(db)) {
+ if (baseObjects != null) {
+ ow.sort(RevSort.TOPO);
+ if (!baseObjects.isEmpty())
+ ow.sort(RevSort.BOUNDARY, true);
+ }
+
+ for (ReceiveCommand cmd : commands) {
+ if (cmd.getResult() != Result.NOT_ATTEMPTED)
+ continue;
+ if (cmd.getType() == ReceiveCommand.Type.DELETE)
+ continue;
+ ow.markStart(ow.parseAny(cmd.getNewId()));
+ }
+ for (ObjectId have : advertisedHaves) {
+ RevObject o = ow.parseAny(have);
+ ow.markUninteresting(o);
+
+ if (baseObjects != null && !baseObjects.isEmpty()) {
+ o = ow.peel(o);
+ if (o instanceof RevCommit)
+ o = ((RevCommit) o).getTree();
+ if (o instanceof RevTree)
+ ow.markUninteresting(o);
+ }
+ }
+
+ checking.beginTask(JGitText.get().countingObjects,
+ ProgressMonitor.UNKNOWN);
+ RevCommit c;
+ while ((c = ow.next()) != null) {
+ checking.update(1);
+ if (providedObjects != null //
+ && !c.has(RevFlag.UNINTERESTING) //
+ && !providedObjects.contains(c))
+ throw new MissingObjectException(c, Constants.TYPE_COMMIT);
+ }
+
+ RevObject o;
+ while ((o = ow.nextObject()) != null) {
+ checking.update(1);
+ if (o.has(RevFlag.UNINTERESTING))
+ continue;
+
+ if (providedObjects != null) {
+ if (providedObjects.contains(o)) {
+ continue;
+ }
+ throw new MissingObjectException(o, o.getType());
+ }
+
+ if (o instanceof RevBlob && !db.getObjectDatabase().has(o))
+ throw new MissingObjectException(o, Constants.TYPE_BLOB);
+ }
+ checking.endTask();
+
+ if (baseObjects != null) {
+ for (ObjectId id : baseObjects) {
+ o = ow.parseAny(id);
+ if (!o.has(RevFlag.UNINTERESTING))
+ throw new MissingObjectException(o, o.getType());
+ }
+ }
+ }
+ }
+
+ /**
+ * Validate the command list.
+ */
+ private void validateCommands() {
+ for (ReceiveCommand cmd : commands) {
+ final Ref ref = cmd.getRef();
+ if (cmd.getResult() != Result.NOT_ATTEMPTED)
+ continue;
+
+ if (cmd.getType() == ReceiveCommand.Type.DELETE) {
+ if (!isAllowDeletes()) {
+ // Deletes are not supported on this repository.
+ cmd.setResult(Result.REJECTED_NODELETE);
+ continue;
+ }
+ if (!isAllowBranchDeletes()
+ && ref.getName().startsWith(Constants.R_HEADS)) {
+ // Branches cannot be deleted, but other refs can.
+ cmd.setResult(Result.REJECTED_NODELETE);
+ continue;
+ }
+ }
+
+ if (cmd.getType() == ReceiveCommand.Type.CREATE) {
+ if (!isAllowCreates()) {
+ cmd.setResult(Result.REJECTED_NOCREATE);
+ continue;
+ }
+
+ if (ref != null && !isAllowNonFastForwards()) {
+ // Creation over an existing ref is certainly not going
+ // to be a fast-forward update. We can reject it early.
+ //
+ cmd.setResult(Result.REJECTED_NONFASTFORWARD);
+ continue;
+ }
+
+ if (ref != null) {
+ // A well behaved client shouldn't have sent us a
+ // create command for a ref we advertised to it.
+ //
+ cmd.setResult(Result.REJECTED_OTHER_REASON,
+ JGitText.get().refAlreadyExists);
+ continue;
+ }
+ }
+
+ if (cmd.getType() == ReceiveCommand.Type.DELETE && ref != null) {
+ ObjectId id = ref.getObjectId();
+ if (id == null) {
+ id = ObjectId.zeroId();
+ }
+ if (!ObjectId.zeroId().equals(cmd.getOldId())
+ && !id.equals(cmd.getOldId())) {
+ // Delete commands can be sent with the old id matching our
+ // advertised value, *OR* with the old id being 0{40}. Any
+ // other requested old id is invalid.
+ //
+ cmd.setResult(Result.REJECTED_OTHER_REASON,
+ JGitText.get().invalidOldIdSent);
+ continue;
+ }
+ }
+
+ if (cmd.getType() == ReceiveCommand.Type.UPDATE) {
+ if (ref == null) {
+ // The ref must have been advertised in order to be updated.
+ //
+ cmd.setResult(Result.REJECTED_OTHER_REASON,
+ JGitText.get().noSuchRef);
+ continue;
+ }
+ ObjectId id = ref.getObjectId();
+ if (id == null) {
+ // We cannot update unborn branch
+ cmd.setResult(Result.REJECTED_OTHER_REASON,
+ JGitText.get().cannotUpdateUnbornBranch);
+ continue;
+ }
+
+ if (!id.equals(cmd.getOldId())) {
+ // A properly functioning client will send the same
+ // object id we advertised.
+ //
+ cmd.setResult(Result.REJECTED_OTHER_REASON,
+ JGitText.get().invalidOldIdSent);
+ continue;
+ }
+
+ // Is this possibly a non-fast-forward style update?
+ //
+ RevObject oldObj, newObj;
+ try {
+ oldObj = walk.parseAny(cmd.getOldId());
+ } catch (IOException e) {
+ cmd.setResult(Result.REJECTED_MISSING_OBJECT,
+ cmd.getOldId().name());
+ continue;
+ }
+
+ try {
+ newObj = walk.parseAny(cmd.getNewId());
+ } catch (IOException e) {
+ cmd.setResult(Result.REJECTED_MISSING_OBJECT,
+ cmd.getNewId().name());
+ continue;
+ }
+
+ if (oldObj instanceof RevCommit
+ && newObj instanceof RevCommit) {
+ try {
+ if (walk.isMergedInto((RevCommit) oldObj,
+ (RevCommit) newObj))
+ cmd.setTypeFastForwardUpdate();
+ else
+ cmd.setType(
+ ReceiveCommand.Type.UPDATE_NONFASTFORWARD);
+ } catch (MissingObjectException e) {
+ cmd.setResult(Result.REJECTED_MISSING_OBJECT,
+ e.getMessage());
+ } catch (IOException e) {
+ cmd.setResult(Result.REJECTED_OTHER_REASON);
+ }
+ } else {
+ cmd.setType(ReceiveCommand.Type.UPDATE_NONFASTFORWARD);
+ }
+
+ if (cmd.getType() == ReceiveCommand.Type.UPDATE_NONFASTFORWARD
+ && !isAllowNonFastForwards()) {
+ cmd.setResult(Result.REJECTED_NONFASTFORWARD);
+ continue;
+ }
+ }
+
+ if (!cmd.getRefName().startsWith(Constants.R_REFS)
+ || !Repository.isValidRefName(cmd.getRefName())) {
+ cmd.setResult(Result.REJECTED_OTHER_REASON,
+ JGitText.get().funnyRefname);
+ }
+ }
+ }
+
+ /**
+ * Whether any commands have been rejected so far.
+ *
+ * @return if any commands have been rejected so far.
+ */
+ private boolean anyRejects() {
+ for (ReceiveCommand cmd : commands) {
+ if (cmd.getResult() != Result.NOT_ATTEMPTED
+ && cmd.getResult() != Result.OK)
+ return true;
+ }
+ return false;
+ }
+
+ /**
+ * Set the result to fail for any command that was not processed yet.
+ *
+ */
+ private void failPendingCommands() {
+ ReceiveCommand.abort(commands);
+ }
+
+ /**
+ * Filter the list of commands according to result.
+ *
+ * @param want
+ * desired status to filter by.
+ * @return a copy of the command list containing only those commands with
+ * the desired status.
+ */
+ private List<ReceiveCommand> filterCommands(Result want) {
+ return ReceiveCommand.filter(commands, want);
+ }
+
+ /**
+ * Execute commands to update references.
+ */
+ private void executeCommands() {
+ List<ReceiveCommand> toApply = filterCommands(Result.NOT_ATTEMPTED);
+ if (toApply.isEmpty())
+ return;
+
+ ProgressMonitor updating = NullProgressMonitor.INSTANCE;
+ if (sideBand) {
+ SideBandProgressMonitor pm = new SideBandProgressMonitor(msgOut);
+ pm.setDelayStart(250, TimeUnit.MILLISECONDS);
+ updating = pm;
+ }
+
+ BatchRefUpdate batch = db.getRefDatabase().newBatchUpdate();
+ batch.setAllowNonFastForwards(isAllowNonFastForwards());
+ batch.setAtomic(isAtomic());
+ batch.setRefLogIdent(getRefLogIdent());
+ batch.setRefLogMessage("push", true); //$NON-NLS-1$
+ batch.addCommand(toApply);
+ try {
+ batch.setPushCertificate(getPushCertificate());
+ batch.execute(walk, updating);
+ } catch (IOException err) {
+ for (ReceiveCommand cmd : toApply) {
+ if (cmd.getResult() == Result.NOT_ATTEMPTED)
+ cmd.reject(err);
+ }
+ }
+ }
+
+ /**
+ * Send a status report.
+ *
+ * @param forClient
+ * true if this report is for a Git client, false if it is for an
+ * end-user.
+ * @param unpackError
+ * an error that occurred during unpacking, or {@code null}
+ * @param out
+ * the reporter for sending the status strings.
+ * @throws java.io.IOException
+ * an error occurred writing the status report.
+ * @since 5.6
+ */
+ private void sendStatusReport(final boolean forClient,
+ final Throwable unpackError, final Reporter out)
+ throws IOException {
+ if (unpackError != null) {
+ out.sendString("unpack error " + unpackError.getMessage()); //$NON-NLS-1$
+ if (forClient) {
+ for (ReceiveCommand cmd : commands) {
+ out.sendString("ng " + cmd.getRefName() //$NON-NLS-1$
+ + " n/a (unpacker error)"); //$NON-NLS-1$
+ }
+ }
+ return;
+ }
+
+ if (forClient)
+ out.sendString("unpack ok"); //$NON-NLS-1$
+ for (ReceiveCommand cmd : commands) {
+ if (cmd.getResult() == Result.OK) {
+ if (forClient)
+ out.sendString("ok " + cmd.getRefName()); //$NON-NLS-1$
+ continue;
+ }
+
+ final StringBuilder r = new StringBuilder();
+ if (forClient)
+ r.append("ng ").append(cmd.getRefName()).append(" "); //$NON-NLS-1$ //$NON-NLS-2$
+ else
+ r.append(" ! [rejected] ").append(cmd.getRefName()) //$NON-NLS-1$
+ .append(" ("); //$NON-NLS-1$
+
+ switch (cmd.getResult()) {
+ case NOT_ATTEMPTED:
+ r.append("server bug; ref not processed"); //$NON-NLS-1$
+ break;
+
+ case REJECTED_NOCREATE:
+ r.append("creation prohibited"); //$NON-NLS-1$
+ break;
+
+ case REJECTED_NODELETE:
+ r.append("deletion prohibited"); //$NON-NLS-1$
+ break;
+
+ case REJECTED_NONFASTFORWARD:
+ r.append("non-fast forward"); //$NON-NLS-1$
+ break;
+
+ case REJECTED_CURRENT_BRANCH:
+ r.append("branch is currently checked out"); //$NON-NLS-1$
+ break;
+
+ case REJECTED_MISSING_OBJECT:
+ if (cmd.getMessage() == null)
+ r.append("missing object(s)"); //$NON-NLS-1$
+ else if (cmd.getMessage()
+ .length() == Constants.OBJECT_ID_STRING_LENGTH) {
+ r.append("object "); //$NON-NLS-1$
+ r.append(cmd.getMessage());
+ r.append(" missing"); //$NON-NLS-1$
+ } else
+ r.append(cmd.getMessage());
+ break;
+
+ case REJECTED_OTHER_REASON:
+ if (cmd.getMessage() == null)
+ r.append("unspecified reason"); //$NON-NLS-1$
+ else
+ r.append(cmd.getMessage());
+ break;
+
+ case LOCK_FAILURE:
+ r.append("failed to lock"); //$NON-NLS-1$
+ break;
+
+ case OK:
+ // We shouldn't have reached this case (see 'ok' case above).
+ continue;
+ }
+ if (!forClient)
+ r.append(")"); //$NON-NLS-1$
+ out.sendString(r.toString());
+ }
+ }
+
+ /**
+ * Close and flush (if necessary) the underlying streams.
+ *
+ * @throws java.io.IOException
+ */
+ private void close() throws IOException {
+ if (sideBand) {
+ // If we are using side band, we need to send a final
+ // flush-pkt to tell the remote peer the side band is
+ // complete and it should stop decoding. We need to
+ // use the original output stream as rawOut is now the
+ // side band data channel.
+ //
+ ((SideBandOutputStream) msgOut).flushBuffer();
+ ((SideBandOutputStream) rawOut).flushBuffer();
+
+ PacketLineOut plo = new PacketLineOut(origOut);
+ plo.setFlushOnEnd(false);
+ plo.end();
+ }
+
+ if (biDirectionalPipe) {
+ // If this was a native git connection, flush the pipe for
+ // the caller. For smart HTTP we don't do this flush and
+ // instead let the higher level HTTP servlet code do it.
+ //
+ if (!sideBand && msgOut != null)
+ msgOut.flush();
+ rawOut.flush();
+ }
+ }
+
+ /**
+ * Release any resources used by this object.
+ *
+ * @throws java.io.IOException
+ * the pack could not be unlocked.
+ */
+ private void release() throws IOException {
+ walk.close();
+ unlockPack();
+ timeoutIn = null;
+ rawIn = null;
+ rawOut = null;
+ msgOut = null;
+ pckIn = null;
+ pckOut = null;
+ refs = null;
+ // Keep the capabilities. If responses are sent after this release
+ // we need to remember at least whether sideband communication has to be
+ // used
+ commands = null;
+ if (timer != null) {
+ try {
+ timer.terminate();
+ } finally {
+ timer = null;
+ }
+ }
+ }
+
+ /** Interface for reporting status messages. */
+ abstract static class Reporter {
+ abstract void sendString(String s) throws IOException;
+ }
+
+ /**
* Get the push certificate used to verify the pusher's identity.
* <p>
* Only valid after commands are read from the wire.
@@ -178,7 +2016,6 @@ public void setAdvertisedRefs(Map<String, Ref> allRefs, Set<ObjectId> additional
* or no cert was presented by the client.
* @since 4.1
*/
- @Override
public PushCertificate getPushCertificate() {
return pushCert;
}
@@ -193,7 +2030,6 @@ public PushCertificate getPushCertificate() {
* the push certificate to set.
* @since 4.1
*/
- @Override
public void setPushCertificate(PushCertificate cert) {
pushCert = cert;
}
@@ -334,28 +2170,6 @@ public void receive(final InputStream input, final OutputStream output,
}
}
- /** {@inheritDoc} */
- @Override
- protected void enableCapabilities() {
- reportStatus = isCapabilityEnabled(CAPABILITY_REPORT_STATUS);
- usePushOptions = isCapabilityEnabled(CAPABILITY_PUSH_OPTIONS);
- super.enableCapabilities();
- }
-
- @Override
- void readPostCommands(PacketLineIn in) throws IOException {
- if (usePushOptions) {
- pushOptions = new ArrayList<>(4);
- for (;;) {
- String option = in.readString();
- if (PacketLineIn.isEnd(option)) {
- break;
- }
- pushOptions.add(option);
- }
- }
- }
-
private void service() throws IOException {
if (isBiDirectionalPipe()) {
sendAdvertisedRefs(new PacketLineOutRefAdvertiser(pckOut));
@@ -377,8 +2191,7 @@ private void service() throws IOException {
try {
if (unpackError == null) {
- boolean atomic = isCapabilityEnabled(CAPABILITY_ATOMIC);
- setAtomic(atomic);
+ setAtomic(isCapabilityEnabled(CAPABILITY_ATOMIC));
validateCommands();
if (atomic && anyRejects()) {
@@ -437,9 +2250,27 @@ private void autoGc() {
repo.autoGC(NullProgressMonitor.INSTANCE);
}
- /** {@inheritDoc} */
- @Override
- protected String getLockMessageProcessName() {
- return "jgit receive-pack"; //$NON-NLS-1$
+ static ReceiveCommand parseCommand(String line)
+ throws PackProtocolException {
+ if (line == null || line.length() < 83) {
+ throw new PackProtocolException(
+ JGitText.get().errorInvalidProtocolWantedOldNewRef);
+ }
+ String oldStr = line.substring(0, 40);
+ String newStr = line.substring(41, 81);
+ ObjectId oldId, newId;
+ try {
+ oldId = ObjectId.fromString(oldStr);
+ newId = ObjectId.fromString(newStr);
+ } catch (InvalidObjectIdException e) {
+ throw new PackProtocolException(
+ JGitText.get().errorInvalidProtocolWantedOldNewRef, e);
+ }
+ String name = line.substring(82);
+ if (!Repository.isValidRefName(name)) {
+ throw new PackProtocolException(
+ JGitText.get().errorInvalidProtocolWantedOldNewRef);
+ }
+ return new ReceiveCommand(oldId, newId, name);
}
}
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/transport/RemoteConfig.java b/org.eclipse.jgit/src/org/eclipse/jgit/transport/RemoteConfig.java
index 0a621f1..4474d1a 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/transport/RemoteConfig.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/transport/RemoteConfig.java
@@ -292,22 +292,26 @@ private Map<String, String> getReplacements(final Config config,
private String replaceUri(final String uri,
final Map<String, String> replacements) {
- if (replacements.isEmpty())
+ if (replacements.isEmpty()) {
return uri;
+ }
Entry<String, String> match = null;
for (Entry<String, String> replacement : replacements.entrySet()) {
// Ignore current entry if not longer than previous match
if (match != null
- && match.getKey().length() > replacement.getKey().length())
+ && match.getKey().length() > replacement.getKey()
+ .length()) {
continue;
- if (!uri.startsWith(replacement.getKey()))
+ }
+ if (!uri.startsWith(replacement.getKey())) {
continue;
+ }
match = replacement;
}
- if (match != null)
+ if (match != null) {
return match.getValue() + uri.substring(match.getKey().length());
- else
- return uri;
+ }
+ return uri;
}
/**
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/transport/RemoteRefUpdate.java b/org.eclipse.jgit/src/org/eclipse/jgit/transport/RemoteRefUpdate.java
index c34e3b8..faa2c76 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/transport/RemoteRefUpdate.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/transport/RemoteRefUpdate.java
@@ -72,7 +72,7 @@ public class RemoteRefUpdate {
/**
* Represent current status of a remote ref update.
*/
- public static enum Status {
+ public enum Status {
/**
* Push process hasn't yet attempted to update this ref. This is the
* default status, prior to push process execution.
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/transport/TransferConfig.java b/org.eclipse.jgit/src/org/eclipse/jgit/transport/TransferConfig.java
index 758d74c..100b433 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/transport/TransferConfig.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/transport/TransferConfig.java
@@ -132,6 +132,7 @@ static ProtocolVersion parse(@Nullable String name) {
private final boolean allowReachableSha1InWant;
private final boolean allowFilter;
private final boolean allowSidebandAll;
+ private final boolean advertiseSidebandAll;
final @Nullable ProtocolVersion protocolVersion;
final String[] hideRefs;
@@ -213,6 +214,8 @@ public TransferConfig(Config rc) {
hideRefs = rc.getStringList("uploadpack", null, "hiderefs");
allowSidebandAll = rc.getBoolean(
"uploadpack", "allowsidebandall", false);
+ advertiseSidebandAll = rc.getBoolean("uploadpack",
+ "advertisesidebandall", false);
}
/**
@@ -295,7 +298,8 @@ public boolean isAllowRefInWant() {
}
/**
- * @return true if clients are allowed to specify a "sideband-all" line
+ * @return true if the server accepts sideband-all requests (see
+ * {{@link #isAdvertiseSidebandAll()} for the advertisement)
* @since 5.5
*/
public boolean isAllowSidebandAll() {
@@ -303,6 +307,14 @@ public boolean isAllowSidebandAll() {
}
/**
+ * @return true to advertise sideband all to the clients
+ * @since 5.6
+ */
+ public boolean isAdvertiseSidebandAll() {
+ return advertiseSidebandAll && allowSidebandAll;
+ }
+
+ /**
* Get {@link org.eclipse.jgit.transport.RefFilter} respecting configured
* hidden refs.
*
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/transport/Transport.java b/org.eclipse.jgit/src/org/eclipse/jgit/transport/Transport.java
index 0b79070..2382f4c 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/transport/Transport.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/transport/Transport.java
@@ -302,11 +302,12 @@ public static Transport open(final Repository local, final String remote,
URISyntaxException, TransportException {
if (local != null) {
final RemoteConfig cfg = new RemoteConfig(local.getConfig(), remote);
- if (doesNotExist(cfg))
+ if (doesNotExist(cfg)) {
return open(local, new URIish(remote), null);
+ }
return open(local, cfg, op);
- } else
- return open(new URIish(remote));
+ }
+ return open(new URIish(remote));
}
@@ -708,11 +709,11 @@ private static String findTrackingRefName(final String remoteName,
// try to find matching tracking refs
for (RefSpec fetchSpec : fetchSpecs) {
if (fetchSpec.matchSource(remoteName)) {
- if (fetchSpec.isWildcard())
+ if (fetchSpec.isWildcard()) {
return fetchSpec.expandFromSource(remoteName)
.getDestination();
- else
- return fetchSpec.getDestination();
+ }
+ return fetchSpec.getDestination();
}
}
return null;
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/transport/TransportHttp.java b/org.eclipse.jgit/src/org/eclipse/jgit/transport/TransportHttp.java
index 3029327..2637a02 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/transport/TransportHttp.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/transport/TransportHttp.java
@@ -698,9 +698,8 @@ private static class CredentialItems {
public CredentialItem[] items() {
if (forRepo == null) {
return new CredentialItem[] { message, now, always };
- } else {
- return new CredentialItem[] { message, now, forRepo, always };
}
+ return new CredentialItem[] { message, now, forRepo, always };
}
}
@@ -1076,13 +1075,11 @@ static boolean matchesCookieDomain(String host, String cookieDomain) {
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) == '.';
}
+ if (!host.endsWith(cookieDomain)) {
+ return false;
+ }
+ return host.charAt(host.length() - cookieDomain.length() - 1) == '.';
}
/**
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/transport/TransportProtocol.java b/org.eclipse.jgit/src/org/eclipse/jgit/transport/TransportProtocol.java
index de58aa9..5a8cd32 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/transport/TransportProtocol.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/transport/TransportProtocol.java
@@ -90,7 +90,7 @@
*/
public abstract class TransportProtocol {
/** Fields within a {@link URIish} that a transport uses. */
- public static enum URIishField {
+ public enum URIishField {
/** the user field */
USER,
/** the pass (aka password) field */
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/transport/URIish.java b/org.eclipse.jgit/src/org/eclipse/jgit/transport/URIish.java
index 7ca9cc1..d5e03eb 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/transport/URIish.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/transport/URIish.java
@@ -351,10 +351,7 @@ private static String escape(String s, boolean escapeReservedChars,
}
private String n2e(String s) {
- if (s == null)
- return ""; //$NON-NLS-1$
- else
- return s;
+ return s == null ? "" : s; //$NON-NLS-1$
}
// takes care to cut of a leading slash if a windows drive letter or a
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/transport/UploadPack.java b/org.eclipse.jgit/src/org/eclipse/jgit/transport/UploadPack.java
index 20b4588..8a88e17 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/transport/UploadPack.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/transport/UploadPack.java
@@ -44,6 +44,7 @@
package org.eclipse.jgit.transport;
import static java.util.Collections.unmodifiableMap;
+import static java.util.Objects.requireNonNull;
import static org.eclipse.jgit.lib.Constants.R_TAGS;
import static org.eclipse.jgit.transport.GitProtocolConstants.CAPABILITY_REF_IN_WANT;
import static org.eclipse.jgit.transport.GitProtocolConstants.CAPABILITY_SERVER_OPTION;
@@ -84,7 +85,9 @@
import java.util.Optional;
import java.util.Set;
import java.util.TreeMap;
+import java.util.function.Predicate;
import java.util.stream.Collectors;
+import java.util.stream.Stream;
import org.eclipse.jgit.annotations.NonNull;
import org.eclipse.jgit.annotations.Nullable;
@@ -134,7 +137,7 @@
*/
public class UploadPack {
/** Policy the server uses to validate client requests */
- public static enum RequestPolicy {
+ public enum RequestPolicy {
/** Client may only ask for objects the server advertised a reference for. */
ADVERTISED,
@@ -282,6 +285,8 @@ private static interface IOConsumer<R> {
private OutputStream msgOut = NullOutputStream.INSTANCE;
+ private ErrorWriter errOut = new PackProtocolErrorWriter();
+
/**
* Refs eligible for advertising to the client, set using
* {@link #setAdvertisedRefs}.
@@ -756,9 +761,59 @@ private boolean useProtocolV2() {
/**
* Execute the upload task on the socket.
*
- * <p>If the client passed extra parameters (e.g., "version=2") through a
- * side channel, the caller must call setExtraParameters first to supply
- * them.
+ * <p>
+ * Same as {@link #uploadWithExceptionPropagation} except that the thrown
+ * exceptions are handled in the method, and the error messages are sent to
+ * the clients.
+ *
+ * <p>
+ * Call this method if the caller does not have an error handling mechanism.
+ * Call {@link #uploadWithExceptionPropagation} if the caller wants to have
+ * its own error handling mechanism.
+ *
+ * @param input
+ * @param output
+ * @param messages
+ * @throws java.io.IOException
+ */
+ public void upload(InputStream input, OutputStream output,
+ @Nullable OutputStream messages) throws IOException {
+ try {
+ uploadWithExceptionPropagation(input, output, messages);
+ } catch (ServiceMayNotContinueException err) {
+ if (!err.isOutput() && err.getMessage() != null) {
+ try {
+ errOut.writeError(err.getMessage());
+ } catch (IOException e) {
+ err.addSuppressed(e);
+ throw err;
+ }
+ err.setOutput();
+ }
+ throw err;
+ } catch (IOException | RuntimeException | Error err) {
+ if (rawOut != null) {
+ String msg = err instanceof PackProtocolException
+ ? err.getMessage()
+ : JGitText.get().internalServerError;
+ try {
+ errOut.writeError(msg);
+ } catch (IOException e) {
+ err.addSuppressed(e);
+ throw err;
+ }
+ throw new UploadPackInternalServerErrorException(err);
+ }
+ throw err;
+ }
+ }
+
+ /**
+ * Execute the upload task on the socket.
+ *
+ * <p>
+ * If the client passed extra parameters (e.g., "version=2") through a side
+ * channel, the caller must call setExtraParameters first to supply them.
*
* @param input
* raw input to read client commands from. Caller must ensure the
@@ -772,15 +827,21 @@ private boolean useProtocolV2() {
* through. When run over SSH this should be tied back to the
* standard error channel of the command execution. For most
* other network connections this should be null.
- * @throws java.io.IOException
+ * @throws ServiceMayNotContinueException
+ * thrown if one of the hooks throws this.
+ * @throws IOException
+ * thrown if the server or the client I/O fails, or there's an
+ * internal server error.
+ * @since 5.6
*/
- public void upload(InputStream input, OutputStream output,
- @Nullable OutputStream messages) throws IOException {
- PacketLineOut pckOut = null;
+ public void uploadWithExceptionPropagation(InputStream input,
+ OutputStream output, @Nullable OutputStream messages)
+ throws ServiceMayNotContinueException, IOException {
try {
rawIn = input;
- if (messages != null)
+ if (messages != null) {
msgOut = messages;
+ }
if (timeout > 0) {
final Thread caller = Thread.currentThread();
@@ -800,42 +861,12 @@ public void upload(InputStream input, OutputStream output,
}
pckIn = new PacketLineIn(rawIn);
- pckOut = new PacketLineOut(rawOut);
+ PacketLineOut pckOut = new PacketLineOut(rawOut);
if (useProtocolV2()) {
serviceV2(pckOut);
} else {
service(pckOut);
}
- } catch (UploadPackInternalServerErrorException err) {
- // UploadPackInternalServerErrorException is a special exception
- // that indicates an error is already written to the client. Do
- // nothing.
- throw err;
- } catch (ServiceMayNotContinueException err) {
- if (!err.isOutput() && err.getMessage() != null && pckOut != null) {
- try {
- pckOut.writeString("ERR " + err.getMessage() + "\n"); //$NON-NLS-1$ //$NON-NLS-2$
- } catch (IOException e) {
- err.addSuppressed(e);
- throw err;
- }
- err.setOutput();
- }
- throw err;
- } catch (IOException | RuntimeException | Error err) {
- if (pckOut != null) {
- String msg = err instanceof PackProtocolException
- ? err.getMessage()
- : JGitText.get().internalServerError;
- try {
- pckOut.writeString("ERR " + msg + "\n"); //$NON-NLS-1$ //$NON-NLS-2$
- } catch (IOException e) {
- err.addSuppressed(e);
- throw err;
- }
- throw new UploadPackInternalServerErrorException(err);
- }
- throw err;
} finally {
msgOut = NullOutputStream.INSTANCE;
walk.close();
@@ -1296,7 +1327,7 @@ private List<String> getV2CapabilityAdvertisement() {
caps.add(COMMAND_FETCH + '='
+ (transferConfig.isAllowFilter() ? OPTION_FILTER + ' ' : "")
+ (advertiseRefInWant ? CAPABILITY_REF_IN_WANT + ' ' : "")
- + (transferConfig.isAllowSidebandAll()
+ + (transferConfig.isAdvertiseSidebandAll()
? OPTION_SIDEBAND_ALL + ' '
: "")
+ (cachedPackUriProvider != null ? "packfile-uris " : "")
@@ -1844,8 +1875,7 @@ public static final class ReachableCommitRequestValidator
@Override
public void checkWants(UploadPack up, List<ObjectId> wants)
throws PackProtocolException, IOException {
- checkNotAdvertisedWants(up, wants,
- refIdSet(up.getAdvertisedRefs().values()));
+ checkNotAdvertisedWants(up, wants, up.getAdvertisedRefs().values());
}
}
@@ -1882,7 +1912,7 @@ public static final class ReachableCommitTipRequestValidator
public void checkWants(UploadPack up, List<ObjectId> wants)
throws PackProtocolException, IOException {
checkNotAdvertisedWants(up, wants,
- refIdSet(up.getRepository().getRefDatabase().getRefs()));
+ up.getRepository().getRefDatabase().getRefs());
}
}
@@ -1942,12 +1972,14 @@ private static void checkReachabilityByWalkingObjects(ObjectWalk walk,
}
private static void checkNotAdvertisedWants(UploadPack up,
- List<ObjectId> notAdvertisedWants, Set<ObjectId> reachableFrom)
+ List<ObjectId> notAdvertisedWants, Collection<Ref> visibleRefs)
throws IOException {
ObjectReader reader = up.getRevWalk().getObjectReader();
+
try (RevWalk walk = new RevWalk(reader)) {
walk.setRetainBody(false);
+ Set<ObjectId> reachableFrom = refIdSet(visibleRefs);
// Missing "wants" throw exception here
List<RevObject> wantsAsObjs = objectIdsToRevObjects(walk,
notAdvertisedWants);
@@ -1994,10 +2026,13 @@ private static void checkNotAdvertisedWants(UploadPack up,
ReachabilityChecker reachabilityChecker = walk
.createReachabilityChecker();
- List<RevCommit> starters = objectIdsToRevCommits(walk,
- reachableFrom);
+ Stream<RevCommit> reachableCommits = importantRefsFirst(visibleRefs)
+ .map(UploadPack::refToObjectId)
+ .map(objId -> objectIdToRevCommit(walk, objId))
+ .filter(Objects::nonNull); // Ignore missing tips
+
Optional<RevCommit> unreachable = reachabilityChecker
- .areAllReachable(wantsAsCommits, starters);
+ .areAllReachable(wantsAsCommits, reachableCommits);
if (unreachable.isPresent()) {
throw new WantNotValidException(unreachable.get());
}
@@ -2007,6 +2042,50 @@ private static void checkNotAdvertisedWants(UploadPack up,
}
}
+ static Stream<Ref> importantRefsFirst(
+ Collection<Ref> visibleRefs) {
+ Predicate<Ref> startsWithRefsHeads = ref -> ref.getName()
+ .startsWith(Constants.R_HEADS);
+ Predicate<Ref> startsWithRefsTags = ref -> ref.getName()
+ .startsWith(Constants.R_TAGS);
+ Predicate<Ref> allOther = ref -> !startsWithRefsHeads.test(ref)
+ && !startsWithRefsTags.test(ref);
+
+ return Stream.concat(
+ visibleRefs.stream().filter(startsWithRefsHeads),
+ Stream.concat(
+ visibleRefs.stream().filter(startsWithRefsTags),
+ visibleRefs.stream().filter(allOther)));
+ }
+
+ private static ObjectId refToObjectId(Ref ref) {
+ return ref.getObjectId() != null ? ref.getObjectId()
+ : ref.getPeeledObjectId();
+ }
+
+ /**
+ * Translate an object id to a RevCommit.
+ *
+ * @param walk
+ * walk on the relevant object storae
+ * @param objectId
+ * Object Id
+ * @return RevCommit instance or null if the object is missing
+ */
+ @Nullable
+ private static RevCommit objectIdToRevCommit(RevWalk walk,
+ ObjectId objectId) {
+ if (objectId == null) {
+ return null;
+ }
+
+ try {
+ return walk.parseCommit(objectId);
+ } catch (IOException e) {
+ return null;
+ }
+ }
+
// Resolve the ObjectIds into RevObjects. Any missing object raises an
// exception
private static List<RevObject> objectIdsToRevObjects(RevWalk walk,
@@ -2019,23 +2098,6 @@ private static List<RevObject> objectIdsToRevObjects(RevWalk walk,
return result;
}
- // Get commits from object ids. If the id is not a commit, ignore it. If the
- // id doesn't exist, report the missing object in a exception.
- private static List<RevCommit> objectIdsToRevCommits(RevWalk walk,
- Iterable<ObjectId> objectIds)
- throws MissingObjectException, IOException {
- List<RevCommit> result = new ArrayList<>();
- for (ObjectId objectId : objectIds) {
- try {
- result.add(walk.parseCommit(objectId));
- } catch (IncorrectObjectTypeException e) {
- continue;
- }
- }
- return result;
- }
-
-
private void addCommonBase(RevObject o) {
if (!o.has(COMMON)) {
o.add(COMMON);
@@ -2114,54 +2176,42 @@ private void sendPack(PackStatistics.Accumulator accumulator,
Set<String> caps = req.getClientCapabilities();
boolean sideband = caps.contains(OPTION_SIDE_BAND)
|| caps.contains(OPTION_SIDE_BAND_64K);
- if (sideband) {
- try {
- sendPack(true, req, accumulator, allTags, unshallowCommits,
- deepenNots, pckOut);
- } catch (ServiceMayNotContinueException err) {
- String message = err.getMessage();
- if (message == null) {
- message = JGitText.get().internalServerError;
- }
- try {
- reportInternalServerErrorOverSideband(message);
- } catch (IOException e) {
- err.addSuppressed(e);
- throw err;
- }
- throw new UploadPackInternalServerErrorException(err);
- } catch (IOException | RuntimeException | Error err) {
- try {
- reportInternalServerErrorOverSideband(
- JGitText.get().internalServerError);
- } catch (IOException e) {
- err.addSuppressed(e);
- throw err;
- }
- throw new UploadPackInternalServerErrorException(err);
- }
- } else {
- sendPack(false, req, accumulator, allTags, unshallowCommits, deepenNots,
- pckOut);
- }
- }
- private void reportInternalServerErrorOverSideband(String message)
- throws IOException {
- @SuppressWarnings("resource" /* java 7 */)
- SideBandOutputStream err = new SideBandOutputStream(
- SideBandOutputStream.CH_ERROR, SideBandOutputStream.SMALL_BUF,
- rawOut);
- err.write(Constants.encode(message));
- err.flush();
+ if (sideband) {
+ errOut = new SideBandErrorWriter();
+
+ int bufsz = SideBandOutputStream.SMALL_BUF;
+ if (req.getClientCapabilities().contains(OPTION_SIDE_BAND_64K)) {
+ bufsz = SideBandOutputStream.MAX_BUF;
+ }
+ OutputStream packOut = new SideBandOutputStream(
+ SideBandOutputStream.CH_DATA, bufsz, rawOut);
+
+ ProgressMonitor pm = NullProgressMonitor.INSTANCE;
+ if (!req.getClientCapabilities().contains(OPTION_NO_PROGRESS)) {
+ msgOut = new SideBandOutputStream(
+ SideBandOutputStream.CH_PROGRESS, bufsz, rawOut);
+ pm = new SideBandProgressMonitor(msgOut);
+ }
+
+ sendPack(pm, pckOut, packOut, req, accumulator, allTags,
+ unshallowCommits, deepenNots);
+ pckOut.end();
+ } else {
+ sendPack(NullProgressMonitor.INSTANCE, pckOut, rawOut, req,
+ accumulator, allTags, unshallowCommits, deepenNots);
+ }
}
/**
* Send the requested objects to the client.
*
- * @param sideband
- * whether to wrap the pack in side-band pkt-lines, interleaved
- * with progress messages and errors.
+ * @param pm
+ * progress monitor
+ * @param pckOut
+ * PacketLineOut that shares the output with packOut
+ * @param packOut
+ * packfile output
* @param req
* request being processed
* @param accumulator
@@ -2173,35 +2223,14 @@ private void reportInternalServerErrorOverSideband(String message)
* shallow commits on the client that are now becoming unshallow
* @param deepenNots
* objects that the client specified using --shallow-exclude
- * @param pckOut
- * output writer
* @throws IOException
* if an error occurred while generating or writing the pack.
*/
- private void sendPack(final boolean sideband,
- FetchRequest req,
+ private void sendPack(ProgressMonitor pm, PacketLineOut pckOut,
+ OutputStream packOut, FetchRequest req,
PackStatistics.Accumulator accumulator,
- @Nullable Collection<Ref> allTags,
- List<ObjectId> unshallowCommits,
- List<ObjectId> deepenNots,
- PacketLineOut pckOut) throws IOException {
- ProgressMonitor pm = NullProgressMonitor.INSTANCE;
- OutputStream packOut = rawOut;
-
- if (sideband) {
- int bufsz = SideBandOutputStream.SMALL_BUF;
- if (req.getClientCapabilities().contains(OPTION_SIDE_BAND_64K))
- bufsz = SideBandOutputStream.MAX_BUF;
-
- packOut = new SideBandOutputStream(SideBandOutputStream.CH_DATA,
- bufsz, rawOut);
- if (!req.getClientCapabilities().contains(OPTION_NO_PROGRESS)) {
- msgOut = new SideBandOutputStream(
- SideBandOutputStream.CH_PROGRESS, bufsz, rawOut);
- pm = new SideBandProgressMonitor(msgOut);
- }
- }
-
+ @Nullable Collection<Ref> allTags, List<ObjectId> unshallowCommits,
+ List<ObjectId> deepenNots) throws IOException {
if (wantAll.isEmpty()) {
preUploadHook.onSendPack(this, wantIds, commonBase);
} else {
@@ -2344,9 +2373,6 @@ else if (ref.getName().startsWith(Constants.R_HEADS))
}
pw.close();
}
-
- if (sideband)
- pckOut.end();
}
private static void findSymrefs(
@@ -2385,12 +2411,12 @@ public void write(int b) throws IOException {
}
@Override
- public void write(byte b[]) throws IOException {
+ public void write(byte[] b) throws IOException {
out.write(b);
}
@Override
- public void write(byte b[], int off, int len) throws IOException {
+ public void write(byte[] b, int off, int len) throws IOException {
out.write(b, off, len);
}
@@ -2411,4 +2437,28 @@ void stopBuffering() throws IOException {
}
}
}
+
+ private interface ErrorWriter {
+ void writeError(String message) throws IOException;
+ }
+
+ private class SideBandErrorWriter implements ErrorWriter {
+ @Override
+ public void writeError(String message) throws IOException {
+ @SuppressWarnings("resource" /* java 7 */)
+ SideBandOutputStream err = new SideBandOutputStream(
+ SideBandOutputStream.CH_ERROR,
+ SideBandOutputStream.SMALL_BUF, requireNonNull(rawOut));
+ err.write(Constants.encode(message));
+ err.flush();
+ }
+ }
+
+ private class PackProtocolErrorWriter implements ErrorWriter {
+ @Override
+ public void writeError(String message) throws IOException {
+ new PacketLineOut(requireNonNull(rawOut))
+ .writeString("ERR " + message + '\n'); //$NON-NLS-1$
+ }
+ }
}
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/transport/WalkEncryption.java b/org.eclipse.jgit/src/org/eclipse/jgit/transport/WalkEncryption.java
index 7a973af..fb8a55f 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/transport/WalkEncryption.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/transport/WalkEncryption.java
@@ -324,7 +324,7 @@ static GeneralSecurityException securityError(String message) {
* Base implementation of JGit symmetric encryption. Supports V2 properties
* format.
*/
- static abstract class SymmetricEncryption extends WalkEncryption
+ abstract static class SymmetricEncryption extends WalkEncryption
implements Keys, Vals {
/** Encryption profile, root name of group of related properties. */
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/transport/resolver/FileResolver.java b/org.eclipse.jgit/src/org/eclipse/jgit/transport/resolver/FileResolver.java
index b4a7af0..9a08c08 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/transport/resolver/FileResolver.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/transport/resolver/FileResolver.java
@@ -124,8 +124,8 @@ public Repository open(C req, String name)
// are responsible for closing the repository if we
// complete successfully.
return db;
- } else
- throw new ServiceNotEnabledException();
+ }
+ throw new ServiceNotEnabledException();
} catch (RuntimeException | IOException e) {
db.close();
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/treewalk/FileTreeIterator.java b/org.eclipse.jgit/src/org/eclipse/jgit/treewalk/FileTreeIterator.java
index 4f3eb05..5f5da58 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/treewalk/FileTreeIterator.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/treewalk/FileTreeIterator.java
@@ -275,7 +275,7 @@ public static class DefaultFileModeStrategy implements FileModeStrategy {
/**
* a singleton instance of the default FileModeStrategy
*/
- public final static DefaultFileModeStrategy INSTANCE =
+ public static final DefaultFileModeStrategy INSTANCE =
new DefaultFileModeStrategy();
@Override
@@ -285,9 +285,8 @@ public FileMode getMode(File f, FS.Attributes attributes) {
} else if (attributes.isDirectory()) {
if (new File(f, Constants.DOT_GIT).exists()) {
return FileMode.GITLINK;
- } else {
- return FileMode.TREE;
}
+ return FileMode.TREE;
} else if (attributes.isExecutable()) {
return FileMode.EXECUTABLE_FILE;
} else {
@@ -309,7 +308,7 @@ public static class NoGitlinksStrategy implements FileModeStrategy {
/**
* a singleton instance of the default FileModeStrategy
*/
- public final static NoGitlinksStrategy INSTANCE = new NoGitlinksStrategy();
+ public static final NoGitlinksStrategy INSTANCE = new NoGitlinksStrategy();
@Override
public FileMode getMode(File f, FS.Attributes attributes) {
@@ -425,9 +424,8 @@ public InputStream openInputStream() throws IOException {
if (attributes.isSymbolicLink()) {
return new ByteArrayInputStream(fs.readSymLink(getFile())
.getBytes(UTF_8));
- } else {
- return new FileInputStream(getFile());
}
+ return new FileInputStream(getFile());
}
/**
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/treewalk/TreeWalk.java b/org.eclipse.jgit/src/org/eclipse/jgit/treewalk/TreeWalk.java
index 65d8512..e545565 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/treewalk/TreeWalk.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/treewalk/TreeWalk.java
@@ -111,7 +111,7 @@ public class TreeWalk implements AutoCloseable, AttributesProvider {
/**
* @since 4.2
*/
- public static enum OperationType {
+ public enum OperationType {
/**
* Represents a checkout operation (for example a checkout or reset
* operation).
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/treewalk/WorkingTreeIterator.java b/org.eclipse.jgit/src/org/eclipse/jgit/treewalk/WorkingTreeIterator.java
index 8bb68dc..35d6e41 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/treewalk/WorkingTreeIterator.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/treewalk/WorkingTreeIterator.java
@@ -101,7 +101,6 @@
import org.eclipse.jgit.util.RawParseUtils;
import org.eclipse.jgit.util.TemporaryBuffer;
import org.eclipse.jgit.util.TemporaryBuffer.LocalFile;
-import org.eclipse.jgit.util.io.AutoLFInputStream;
import org.eclipse.jgit.util.io.EolStreamTypeUtil;
import org.eclipse.jgit.util.sha1.SHA1;
@@ -686,10 +685,10 @@ public Instant getEntryLastModifiedInstant() {
public InputStream openEntryStream() throws IOException {
InputStream rawis = current().openInputStream();
if (getCleanFilterCommand() == null
- && getEolStreamType() == EolStreamType.DIRECT)
+ && getEolStreamType() == EolStreamType.DIRECT) {
return rawis;
- else
- return filterClean(rawis);
+ }
+ return filterClean(rawis);
}
/**
@@ -980,13 +979,13 @@ public boolean isModified(DirCacheEntry entry, boolean forceContentCheck,
MetadataDiff diff = compareMetadata(entry);
switch (diff) {
case DIFFER_BY_TIMESTAMP:
- if (forceContentCheck)
+ if (forceContentCheck) {
// But we are told to look at content even though timestamps
// tell us about modification
return contentCheck(entry, reader);
- else
- // We are told to assume a modification if timestamps differs
- return true;
+ }
+ // We are told to assume a modification if timestamps differs
+ return true;
case SMUDGED:
// The file is clean by timestamps but the entry was smudged.
// Lets do a content check
@@ -1087,47 +1086,13 @@ private boolean contentCheck(DirCacheEntry entry, ObjectReader reader)
entry.setLength((int) getEntryLength());
return false;
- } else {
- if (mode == FileMode.SYMLINK.getBits()) {
- return !new File(readSymlinkTarget(current())).equals(
- new File(readContentAsNormalizedString(entry, reader)));
- }
- // Content differs: that's a real change, perhaps
- if (reader == null) // deprecated use, do no further checks
- return true;
-
- switch (getEolStreamType()) {
- case DIRECT:
- return true;
- default:
- try {
- ObjectLoader loader = reader.open(entry.getObjectId());
- if (loader == null)
- return true;
-
- // We need to compute the length, but only if it is not
- // a binary stream.
- long dcInLen;
- try (InputStream dcIn = new AutoLFInputStream(
- loader.openStream(), true,
- true /* abort if binary */)) {
- dcInLen = computeLength(dcIn);
- } catch (AutoLFInputStream.IsBinaryException e) {
- return true;
- }
-
- try (InputStream dcIn = new AutoLFInputStream(
- loader.openStream(), true)) {
- byte[] autoCrLfHash = computeHash(dcIn, dcInLen);
- boolean changed = getEntryObjectId()
- .compareTo(autoCrLfHash, 0) != 0;
- return changed;
- }
- } catch (IOException e) {
- return true;
- }
- }
}
+ if (mode == FileMode.SYMLINK.getBits()) {
+ return !new File(readSymlinkTarget(current())).equals(
+ new File(readContentAsNormalizedString(entry, reader)));
+ }
+ // Content differs: that's a real change
+ return true;
}
private static String readContentAsNormalizedString(DirCacheEntry entry,
@@ -1215,7 +1180,7 @@ private static long computeLength(InputStream in) throws IOException {
*
* @since 5.0
*/
- public static abstract class Entry {
+ public abstract static class Entry {
byte[] encodedName;
int encodedNameLen;
@@ -1535,7 +1500,7 @@ private boolean hasCrLfInIndex(DirCacheIterator dirCache) {
}
// Read blob from index and check for CR/LF-delimited text.
DirCacheEntry entry = dirCache.getDirCacheEntry();
- if (FileMode.REGULAR_FILE.equals(entry.getFileMode())) {
+ if ((entry.getRawMode() & FileMode.TYPE_MASK) == FileMode.TYPE_FILE) {
ObjectId blobId = entry.getObjectId();
if (entry.getStage() > 0
&& entry.getStage() != DirCacheEntry.STAGE_2) {
@@ -1552,7 +1517,10 @@ private boolean hasCrLfInIndex(DirCacheIterator dirCache) {
break;
}
if (entry.getStage() == DirCacheEntry.STAGE_2) {
- blobId = entry.getObjectId();
+ if ((entry.getRawMode()
+ & FileMode.TYPE_MASK) == FileMode.TYPE_FILE) {
+ blobId = entry.getObjectId();
+ }
break;
}
}
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/treewalk/filter/IndexDiffFilter.java b/org.eclipse.jgit/src/org/eclipse/jgit/treewalk/filter/IndexDiffFilter.java
index 6cca582..52fb888 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/treewalk/filter/IndexDiffFilter.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/treewalk/filter/IndexDiffFilter.java
@@ -212,10 +212,9 @@ public boolean include(TreeWalk tw) throws MissingObjectException,
// If i is cnt then the path does not appear in any other tree,
// and this working tree entry can be safely ignored.
return i != cnt;
- } else {
- // In working tree and not ignored, and not in DirCache.
- return true;
}
+ // In working tree and not ignored, and not in DirCache.
+ return true;
}
// Always include subtrees as WorkingTreeIterator cannot provide
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/treewalk/filter/PathSuffixFilter.java b/org.eclipse.jgit/src/org/eclipse/jgit/treewalk/filter/PathSuffixFilter.java
index 3d9f875..11896e4 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/treewalk/filter/PathSuffixFilter.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/treewalk/filter/PathSuffixFilter.java
@@ -99,10 +99,10 @@ public TreeFilter clone() {
@Override
public boolean include(TreeWalk walker) throws MissingObjectException,
IncorrectObjectTypeException, IOException {
- if (walker.isSubtree())
+ if (walker.isSubtree()) {
return true;
- else
- return walker.isPathSuffix(pathRaw, pathRaw.length);
+ }
+ return walker.isPathSuffix(pathRaw, pathRaw.length);
}
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/util/Base64.java b/org.eclipse.jgit/src/org/eclipse/jgit/util/Base64.java
index 69f8547..119c96e 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/util/Base64.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/util/Base64.java
@@ -28,26 +28,26 @@
*/
public class Base64 {
/** The equals sign (=) as a byte. */
- private final static byte EQUALS_SIGN = (byte) '=';
+ private static final byte EQUALS_SIGN = (byte) '=';
/** Indicates equals sign in encoding. */
- private final static byte EQUALS_SIGN_DEC = -1;
+ private static final byte EQUALS_SIGN_DEC = -1;
/** Indicates white space in encoding. */
- private final static byte WHITE_SPACE_DEC = -2;
+ private static final byte WHITE_SPACE_DEC = -2;
/** Indicates an invalid byte during decoding. */
- private final static byte INVALID_DEC = -3;
+ private static final byte INVALID_DEC = -3;
/** The 64 valid Base64 values. */
- private final static byte[] ENC;
+ private static final byte[] ENC;
/**
* Translates a Base64 value to either its 6-bit reconstruction value or a
* negative number indicating some other meaning. The table is only 7 bits
* wide, as the 8th bit is discarded during decoding.
*/
- private final static byte[] DEC;
+ private static final byte[] DEC;
static {
ENC = ("ABCDEFGHIJKLMNOPQRSTUVWXYZ" // //$NON-NLS-1$
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/util/ChangeIdUtil.java b/org.eclipse.jgit/src/org/eclipse/jgit/util/ChangeIdUtil.java
index c8e6645..957cb5a 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/util/ChangeIdUtil.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/util/ChangeIdUtil.java
@@ -173,20 +173,19 @@ public static String insertId(String message, ObjectId changeId,
boolean replaceExisting) {
int indexOfChangeId = indexOfChangeId(message, "\n"); //$NON-NLS-1$
if (indexOfChangeId > 0) {
- if (!replaceExisting)
+ if (!replaceExisting) {
return message;
- else {
- StringBuilder ret = new StringBuilder(message.substring(0,
- indexOfChangeId));
- ret.append(CHANGE_ID);
- ret.append(" I"); //$NON-NLS-1$
- ret.append(ObjectId.toString(changeId));
- int indexOfNextLineBreak = message.indexOf("\n", //$NON-NLS-1$
- indexOfChangeId);
- if (indexOfNextLineBreak > 0)
- ret.append(message.substring(indexOfNextLineBreak));
- return ret.toString();
}
+ StringBuilder ret = new StringBuilder(
+ message.substring(0, indexOfChangeId));
+ ret.append(CHANGE_ID);
+ ret.append(" I"); //$NON-NLS-1$
+ ret.append(ObjectId.toString(changeId));
+ int indexOfNextLineBreak = message.indexOf('\n',
+ indexOfChangeId);
+ if (indexOfNextLineBreak > 0)
+ ret.append(message.substring(indexOfNextLineBreak));
+ return ret.toString();
}
String[] lines = message.split("\n"); //$NON-NLS-1$
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/util/FS.java b/org.eclipse.jgit/src/org/eclipse/jgit/util/FS.java
index 0aa0e36..41bfde9 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/util/FS.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/util/FS.java
@@ -61,6 +61,7 @@
import java.nio.file.AccessDeniedException;
import java.nio.file.FileStore;
import java.nio.file.Files;
+import java.nio.file.InvalidPathException;
import java.nio.file.Path;
import java.nio.file.attribute.BasicFileAttributes;
import java.nio.file.attribute.FileTime;
@@ -98,6 +99,7 @@
import org.eclipse.jgit.errors.LockFailedException;
import org.eclipse.jgit.internal.JGitText;
import org.eclipse.jgit.internal.storage.file.FileSnapshot;
+import org.eclipse.jgit.lib.Config;
import org.eclipse.jgit.lib.ConfigConstants;
import org.eclipse.jgit.lib.Constants;
import org.eclipse.jgit.lib.Repository;
@@ -147,15 +149,15 @@ protected FSFactory() {
*/
public FS detect(Boolean cygwinUsed) {
if (SystemReader.getInstance().isWindows()) {
- if (cygwinUsed == null)
+ if (cygwinUsed == null) {
cygwinUsed = Boolean.valueOf(FS_Win32_Cygwin.isCygwin());
- if (cygwinUsed.booleanValue())
+ }
+ if (cygwinUsed.booleanValue()) {
return new FS_Win32_Cygwin();
- else
- return new FS_Win32();
- } else {
- return new FS_POSIX();
+ }
+ return new FS_Win32();
}
+ return new FS_POSIX();
}
}
@@ -211,7 +213,7 @@ public int getRc() {
*
* @since 5.1.9
*/
- public final static class FileStoreAttributes {
+ public static final class FileStoreAttributes {
private static final Duration UNDEFINED_DURATION = Duration
.ofNanos(Long.MAX_VALUE);
@@ -240,13 +242,21 @@ public final static class FileStoreAttributes {
private static Map<FileStore, Lock> locks = new ConcurrentHashMap<>();
- private static void setBackground(boolean async) {
+ /**
+ * Whether FileStore attributes should be determined asynchronously
+ *
+ * @param async
+ * whether FileStore attributes should be determined
+ * asynchronously. If false access to cached attributes may block
+ * for some seconds for the first call per FileStore
+ * @since 5.6.2
+ */
+ public static void setBackground(boolean async) {
background.set(async);
}
- private static final String javaVersionPrefix = SystemReader
- .getInstance().getHostname() + '|'
- + System.getProperty("java.vendor") + '|' //$NON-NLS-1$
+ private static final String javaVersionPrefix = System
+ .getProperty("java.vendor") + '|' //$NON-NLS-1$
+ System.getProperty("java.version") + '|'; //$NON-NLS-1$
private static final Duration FALLBACK_MIN_RACY_INTERVAL = Duration
@@ -689,7 +699,7 @@ public String toString() {
/** The auto-detected implementation selected for this operating system and JRE. */
public static final FS DETECTED = detect();
- private volatile static FSFactory factory;
+ private static volatile FSFactory factory;
/**
* Auto-detect the appropriate file system abstraction.
@@ -708,7 +718,9 @@ public static FS detect() {
* asynchronously. If false access to cached attributes may block
* for some seconds for the first call per FileStore
* @since 5.1.9
+ * @deprecated Use {@link FileStoreAttributes#setBackground} instead
*/
+ @Deprecated
public static void setAsyncFileStoreAttributes(boolean asynch) {
FileStoreAttributes.setBackground(asynch);
}
@@ -837,7 +849,7 @@ private void detectSymlinkSupport() {
try {
FileUtils.delete(tempFile);
} catch (IOException e) {
- throw new RuntimeException(e); // panic
+ LOG.error(JGitText.get().cannotDeleteFile, tempFile);
}
}
}
@@ -1192,14 +1204,13 @@ protected static String readPipe(File dir, String[] command,
gobbler.join();
if (rc == 0 && !gobbler.fail.get()) {
return r;
- } else {
- if (debug) {
- LOG.debug("readpipe rc=" + rc); //$NON-NLS-1$
- }
- throw new CommandFailedException(rc,
- gobbler.errorMessage.get(),
- gobbler.exception.get());
}
+ if (debug) {
+ LOG.debug("readpipe rc=" + rc); //$NON-NLS-1$
+ }
+ throw new CommandFailedException(rc,
+ gobbler.errorMessage.get(),
+ gobbler.exception.get());
} catch (InterruptedException ie) {
// Stop bothering me, I have a zombie to reap.
}
@@ -1726,20 +1737,18 @@ protected ProcessResult internalRunHookIfPresent(Repository repository,
final String hookName, String[] args, PrintStream outRedirect,
PrintStream errRedirect, String stdinArgs)
throws JGitInternalException {
- final File hookFile = findHook(repository, hookName);
- if (hookFile == null)
+ File hookFile = findHook(repository, hookName);
+ if (hookFile == null || hookName == null) {
return new ProcessResult(Status.NOT_PRESENT);
+ }
- final String hookPath = hookFile.getAbsolutePath();
- final File runDirectory;
- if (repository.isBare())
- runDirectory = repository.getDirectory();
- else
- runDirectory = repository.getWorkTree();
- final String cmd = relativize(runDirectory.getAbsolutePath(),
- hookPath);
- ProcessBuilder hookProcess = runInShell(cmd, args);
- hookProcess.directory(runDirectory);
+ File runDirectory = getRunDirectory(repository, hookName);
+ if (runDirectory == null) {
+ return new ProcessResult(Status.NOT_PRESENT);
+ }
+ String cmd = hookFile.getAbsolutePath();
+ ProcessBuilder hookProcess = runInShell(shellQuote(cmd), args);
+ hookProcess.directory(runDirectory.getAbsoluteFile());
Map<String, String> environment = hookProcess.environment();
environment.put(Constants.GIT_DIR_KEY,
repository.getDirectory().getAbsolutePath());
@@ -1761,6 +1770,21 @@ protected ProcessResult internalRunHookIfPresent(Repository repository,
}
}
+ /**
+ * Quote a string (such as a file system path obtained from a Java
+ * {@link File} or {@link Path} object) such that it can be passed as first
+ * argument to {@link #runInShell(String, String[])}.
+ * <p>
+ * This default implementation returns the string unchanged.
+ * </p>
+ *
+ * @param cmd
+ * the String to quote
+ * @return the quoted string
+ */
+ String shellQuote(String cmd) {
+ return cmd;
+ }
/**
* Tries to find a hook matching the given one in the given repository.
@@ -1774,12 +1798,71 @@ protected ProcessResult internalRunHookIfPresent(Repository repository,
* @since 4.0
*/
public File findHook(Repository repository, String hookName) {
- File gitDir = repository.getDirectory();
- if (gitDir == null)
+ if (hookName == null) {
return null;
- final File hookFile = new File(new File(gitDir,
- Constants.HOOKS), hookName);
- return hookFile.isFile() ? hookFile : null;
+ }
+ File hookDir = getHooksDirectory(repository);
+ if (hookDir == null) {
+ return null;
+ }
+ File hookFile = new File(hookDir, hookName);
+ if (hookFile.isAbsolute()) {
+ if (!hookFile.exists() || (FS.DETECTED.supportsExecute()
+ && !FS.DETECTED.canExecute(hookFile))) {
+ return null;
+ }
+ } else {
+ try {
+ File runDirectory = getRunDirectory(repository, hookName);
+ if (runDirectory == null) {
+ return null;
+ }
+ Path hookPath = runDirectory.getAbsoluteFile().toPath()
+ .resolve(hookFile.toPath());
+ FS fs = repository.getFS();
+ if (fs == null) {
+ fs = FS.DETECTED;
+ }
+ if (!Files.exists(hookPath) || (fs.supportsExecute()
+ && !fs.canExecute(hookPath.toFile()))) {
+ return null;
+ }
+ hookFile = hookPath.toFile();
+ } catch (InvalidPathException e) {
+ LOG.warn(MessageFormat.format(JGitText.get().invalidHooksPath,
+ hookFile));
+ return null;
+ }
+ }
+ return hookFile;
+ }
+
+ private File getRunDirectory(Repository repository,
+ @NonNull String hookName) {
+ if (repository.isBare()) {
+ return repository.getDirectory();
+ }
+ switch (hookName) {
+ case "pre-receive": //$NON-NLS-1$
+ case "update": //$NON-NLS-1$
+ case "post-receive": //$NON-NLS-1$
+ case "post-update": //$NON-NLS-1$
+ case "push-to-checkout": //$NON-NLS-1$
+ return repository.getDirectory();
+ default:
+ return repository.getWorkTree();
+ }
+ }
+
+ private File getHooksDirectory(Repository repository) {
+ Config config = repository.getConfig();
+ String hooksDir = config.getString(ConfigConstants.CONFIG_CORE_SECTION,
+ null, ConfigConstants.CONFIG_KEY_HOOKS_PATH);
+ if (hooksDir != null) {
+ return new File(hooksDir);
+ }
+ File dir = repository.getDirectory();
+ return dir == null ? null : new File(dir, Constants.HOOKS);
}
/**
@@ -2213,7 +2296,7 @@ public void run() {
void copy() throws IOException {
boolean writeFailure = false;
- byte buffer[] = new byte[4096];
+ byte[] buffer = new byte[4096];
int readBytes;
while ((readBytes = in.read(buffer)) != -1) {
// Do not try to write again after a failure, but keep
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/util/FS_POSIX.java b/org.eclipse.jgit/src/org/eclipse/jgit/util/FS_POSIX.java
index 6a1eef2..9c8dab6 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/util/FS_POSIX.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/util/FS_POSIX.java
@@ -74,7 +74,6 @@
import org.eclipse.jgit.errors.CommandFailedException;
import org.eclipse.jgit.errors.ConfigInvalidException;
import org.eclipse.jgit.internal.JGitText;
-import org.eclipse.jgit.lib.Constants;
import org.eclipse.jgit.lib.Repository;
import org.eclipse.jgit.lib.StoredConfig;
import org.slf4j.Logger;
@@ -86,7 +85,7 @@
* @since 3.0
*/
public class FS_POSIX extends FS {
- private final static Logger LOG = LoggerFactory.getLogger(FS_POSIX.class);
+ private static final Logger LOG = LoggerFactory.getLogger(FS_POSIX.class);
private static final int DEFAULT_UMASK = 0022;
private volatile int umask = -1;
@@ -270,6 +269,11 @@ public ProcessBuilder runInShell(String cmd, String[] args) {
return proc;
}
+ @Override
+ String shellQuote(String cmd) {
+ return QuotedString.BOURNE.quote(cmd);
+ }
+
/** {@inheritDoc} */
@Override
public ProcessResult runHookIfPresent(Repository repository, String hookName,
@@ -311,20 +315,6 @@ public String normalize(String name) {
/** {@inheritDoc} */
@Override
- public File findHook(Repository repository, String hookName) {
- final File gitdir = repository.getDirectory();
- if (gitdir == null) {
- return null;
- }
- final Path hookPath = gitdir.toPath().resolve(Constants.HOOKS)
- .resolve(hookName);
- if (Files.isExecutable(hookPath))
- return hookPath.toFile();
- return null;
- }
-
- /** {@inheritDoc} */
- @Override
public boolean supportsAtomicCreateNewFile() {
if (supportsAtomicFileCreation == AtomicFileCreation.UNDEFINED) {
try {
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/util/FS_Win32.java b/org.eclipse.jgit/src/org/eclipse/jgit/util/FS_Win32.java
index 1e64a38..aedf43c 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/util/FS_Win32.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/util/FS_Win32.java
@@ -72,7 +72,7 @@
* @since 3.0
*/
public class FS_Win32 extends FS {
- private final static Logger LOG = LoggerFactory.getLogger(FS_Win32.class);
+ private static final Logger LOG = LoggerFactory.getLogger(FS_Win32.class);
/**
* Constructor
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/util/FS_Win32_Cygwin.java b/org.eclipse.jgit/src/org/eclipse/jgit/util/FS_Win32_Cygwin.java
index 9a163e8..ac788a6 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/util/FS_Win32_Cygwin.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/util/FS_Win32_Cygwin.java
@@ -47,8 +47,6 @@
import java.io.File;
import java.io.PrintStream;
-import java.nio.file.Files;
-import java.nio.file.Path;
import java.security.AccessController;
import java.security.PrivilegedAction;
import java.util.ArrayList;
@@ -57,7 +55,6 @@
import org.eclipse.jgit.api.errors.JGitInternalException;
import org.eclipse.jgit.errors.CommandFailedException;
-import org.eclipse.jgit.lib.Constants;
import org.eclipse.jgit.lib.Repository;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -68,7 +65,7 @@
* @since 3.0
*/
public class FS_Win32_Cygwin extends FS_Win32 {
- private final static Logger LOG = LoggerFactory
+ private static final Logger LOG = LoggerFactory
.getLogger(FS_Win32_Cygwin.class);
private static String cygpath;
@@ -160,6 +157,11 @@ public ProcessBuilder runInShell(String cmd, String[] args) {
return proc;
}
+ @Override
+ String shellQuote(String cmd) {
+ return QuotedString.BOURNE.quote(cmd.replace(File.separatorChar, '/'));
+ }
+
/** {@inheritDoc} */
@Override
public String relativize(String base, String other) {
@@ -175,18 +177,4 @@ public ProcessResult runHookIfPresent(Repository repository, String hookName,
return internalRunHookIfPresent(repository, hookName, args, outRedirect,
errRedirect, stdinArgs);
}
-
- /** {@inheritDoc} */
- @Override
- public File findHook(Repository repository, String hookName) {
- final File gitdir = repository.getDirectory();
- if (gitdir == null) {
- return null;
- }
- final Path hookPath = gitdir.toPath().resolve(Constants.HOOKS)
- .resolve(hookName);
- if (Files.isExecutable(hookPath))
- return hookPath.toFile();
- return null;
- }
}
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/util/FileUtils.java b/org.eclipse.jgit/src/org/eclipse/jgit/util/FileUtils.java
index 4d791e4..e026e92 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/util/FileUtils.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/util/FileUtils.java
@@ -73,6 +73,7 @@
import java.util.ArrayList;
import java.util.List;
import java.util.Locale;
+import java.util.Random;
import java.util.regex.Pattern;
import org.eclipse.jgit.internal.JGitText;
@@ -87,6 +88,8 @@
public class FileUtils {
private static final Logger LOG = LoggerFactory.getLogger(FileUtils.class);
+ private static final Random RNG = new Random();
+
/**
* Option to delete given {@code File}
*/
@@ -986,4 +989,28 @@ public static void touch(Path f) throws IOException {
}
Files.setLastModifiedTime(f, FileTime.from(Instant.now()));
}
+
+ /**
+ * Compute a delay in a {@code min..max} interval with random jitter.
+ *
+ * @param last
+ * amount of delay waited before the last attempt. This is used
+ * to seed the next delay interval. Should be 0 if there was no
+ * prior delay.
+ * @param min
+ * shortest amount of allowable delay between attempts.
+ * @param max
+ * longest amount of allowable delay between attempts.
+ * @return new amount of delay to wait before the next attempt.
+ *
+ * @since 5.6
+ */
+ public static long delay(long last, long min, long max) {
+ long r = Math.max(0, last * 3 - min);
+ if (r > 0) {
+ int c = (int) Math.min(r + 1, Integer.MAX_VALUE);
+ r = RNG.nextInt(c);
+ }
+ return Math.max(Math.min(min + r, max), min);
+ }
}
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/util/GitDateFormatter.java b/org.eclipse.jgit/src/org/eclipse/jgit/util/GitDateFormatter.java
index e461902..e9f65d2 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/util/GitDateFormatter.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/util/GitDateFormatter.java
@@ -68,7 +68,7 @@ public class GitDateFormatter {
/**
* Git and JGit formats
*/
- static public enum Format {
+ public enum Format {
/**
* Git format: Time and original time zone
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/util/GitDateParser.java b/org.eclipse.jgit/src/org/eclipse/jgit/util/GitDateParser.java
index 56a1731..c6a6899 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/util/GitDateParser.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/util/GitDateParser.java
@@ -144,7 +144,7 @@ private ParseableSimpleDateFormat(String formatStr) {
* <li>"yesterday"</li>
* <li>"(x) years|months|weeks|days|hours|minutes|seconds ago"<br>
* Multiple specs can be combined like in "2 weeks 3 days ago". Instead of '
- * ' one can use '.' to seperate the words</li>
+ * ' one can use '.' to separate the words</li>
* <li>"yyyy-MM-dd HH:mm:ss Z" (ISO)</li>
* <li>"EEE, dd MMM yyyy HH:mm:ss Z" (RFC)</li>
* <li>"yyyy-MM-dd"</li>
@@ -186,7 +186,7 @@ public static Date parse(String dateStr, Calendar now)
* <li>"yesterday"</li>
* <li>"(x) years|months|weeks|days|hours|minutes|seconds ago"<br>
* Multiple specs can be combined like in "2 weeks 3 days ago". Instead of '
- * ' one can use '.' to seperate the words</li>
+ * ' one can use '.' to separate the words</li>
* <li>"yyyy-MM-dd HH:mm:ss Z" (ISO)</li>
* <li>"EEE, dd MMM yyyy HH:mm:ss Z" (RFC)</li>
* <li>"yyyy-MM-dd"</li>
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/util/HttpSupport.java b/org.eclipse.jgit/src/org/eclipse/jgit/util/HttpSupport.java
index 640670d..d897255 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/util/HttpSupport.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/util/HttpSupport.java
@@ -51,6 +51,7 @@
import java.net.ConnectException;
import java.net.Proxy;
import java.net.ProxySelector;
+import java.net.URI;
import java.net.URISyntaxException;
import java.net.URL;
import java.net.URLEncoder;
@@ -299,7 +300,9 @@ public static String responseHeader(final HttpConnection c,
public static Proxy proxyFor(ProxySelector proxySelector, URL u)
throws ConnectException {
try {
- return proxySelector.select(u.toURI()).get(0);
+ URI uri = new URI(u.getProtocol(), null, u.getHost(), u.getPort(),
+ null, null, null);
+ return proxySelector.select(uri).get(0);
} catch (URISyntaxException e) {
final ConnectException err;
err = new ConnectException(MessageFormat.format(JGitText.get().cannotDetermineProxyFor, u));
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/util/IO.java b/org.eclipse.jgit/src/org/eclipse/jgit/util/IO.java
index a07a4fd..391598d 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/util/IO.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/util/IO.java
@@ -345,13 +345,14 @@ public static List<String> readLines(String s) {
c = s.charAt(++i);
l.add(sb.toString());
sb.setLength(0);
- if (c != '\n')
+ if (c != '\n') {
sb.append(c);
+ }
continue;
- } else { // EOF
- l.add(sb.toString());
- break;
}
+ // EOF
+ l.add(sb.toString());
+ break;
}
sb.append(c);
}
@@ -401,20 +402,18 @@ public static String readLine(Reader in, int sizeHint) throws IOException {
}
resetAndSkipFully(in, n);
}
- } else {
- StringBuilder buf = sizeHint > 0
- ? new StringBuilder(sizeHint)
- : new StringBuilder();
- int i;
- while ((i = in.read()) != -1) {
- char c = (char) i;
- buf.append(c);
- if (c == '\n') {
- break;
- }
- }
- return buf.toString();
}
+ StringBuilder buf = sizeHint > 0 ? new StringBuilder(sizeHint)
+ : new StringBuilder();
+ int i;
+ while ((i = in.read()) != -1) {
+ char c = (char) i;
+ buf.append(c);
+ if (c == '\n') {
+ break;
+ }
+ }
+ return buf.toString();
}
private static void resetAndSkipFully(Reader fd, long toSkip) throws IOException {
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/util/LfsFactory.java b/org.eclipse.jgit/src/org/eclipse/jgit/util/LfsFactory.java
index 96636b7..0f6620e 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/util/LfsFactory.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/util/LfsFactory.java
@@ -145,7 +145,7 @@ public ObjectLoader applySmudgeFilter(Repository db,
}
/**
- * Retrieve a pre-push hook to be applied.
+ * Retrieve a pre-push hook to be applied using the default error stream.
*
* @param repo
* the {@link Repository} the hook is applied to.
@@ -159,6 +159,22 @@ public PrePushHook getPrePushHook(Repository repo,
}
/**
+ * Retrieve a pre-push hook to be applied.
+ *
+ * @param repo
+ * the {@link Repository} the hook is applied to.
+ * @param outputStream
+ * @param errorStream
+ * @return a {@link PrePushHook} implementation or <code>null</code>
+ * @since 5.6
+ */
+ @Nullable
+ public PrePushHook getPrePushHook(Repository repo, PrintStream outputStream,
+ PrintStream errorStream) {
+ return getPrePushHook(repo, outputStream);
+ }
+
+ /**
* Retrieve an {@link LfsInstallCommand} which can be used to enable LFS
* support (if available) either per repository or for the user.
*
@@ -297,7 +313,7 @@ public int read() throws IOException {
}
@Override
- public int read(byte b[], int off, int len) throws IOException {
+ public int read(byte[] b, int off, int len) throws IOException {
return stream.read(b, off, len);
}
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/util/Monitoring.java b/org.eclipse.jgit/src/org/eclipse/jgit/util/Monitoring.java
index 83bf695..500c236 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/util/Monitoring.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/util/Monitoring.java
@@ -33,7 +33,7 @@
* @since 5.1.13
*/
public class Monitoring {
- private final static Logger LOG = LoggerFactory.getLogger(Monitoring.class);
+ private static final Logger LOG = LoggerFactory.getLogger(Monitoring.class);
/**
* Register a MBean with the platform MBean server
@@ -49,7 +49,7 @@ public class Monitoring {
String metricName) {
boolean register = false;
try {
- Class<?> interfaces[] = mbean.getClass().getInterfaces();
+ Class<?>[] interfaces = mbean.getClass().getInterfaces();
for (Class<?> i : interfaces) {
register = SystemReader.getInstance().getUserConfig()
.getBoolean(
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/util/ProcessResult.java b/org.eclipse.jgit/src/org/eclipse/jgit/util/ProcessResult.java
index 9267a32..1180d4c 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/util/ProcessResult.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/util/ProcessResult.java
@@ -51,7 +51,7 @@ public class ProcessResult {
/**
* Status of a process' execution.
*/
- public static enum Status {
+ public enum Status {
/**
* The script was found and launched properly. It may still have exited
* with a non-zero {@link #exitCode}.
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/util/QuotedString.java b/org.eclipse.jgit/src/org/eclipse/jgit/util/QuotedString.java
index a55cad3..2b2358a 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/util/QuotedString.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/util/QuotedString.java
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2008, Google Inc.
+ * Copyright (C) 2008, 2019 Google Inc.
* and other copyright owners as documented in the project's IP log.
*
* This program and the accompanying materials are made available
@@ -54,7 +54,15 @@
*/
public abstract class QuotedString {
/** Quoting style that obeys the rules Git applies to file names */
- public static final GitPathStyle GIT_PATH = new GitPathStyle();
+ public static final GitPathStyle GIT_PATH = new GitPathStyle(true);
+
+ /**
+ * Quoting style that obeys the rules Git applies to file names when
+ * {@code core.quotePath = false}.
+ *
+ * @since 5.6
+ */
+ public static final QuotedString GIT_PATH_MINIMAL = new GitPathStyle(false);
/**
* Quoting style used by the Bourne shell.
@@ -256,40 +264,48 @@ public static final class GitPathStyle extends QuotedString {
quote['"'] = '"';
}
+ private final boolean quoteHigh;
+
@Override
public String quote(String instr) {
- if (instr.length() == 0)
+ if (instr.isEmpty()) {
return "\"\""; //$NON-NLS-1$
+ }
boolean reuse = true;
final byte[] in = Constants.encode(instr);
- final StringBuilder r = new StringBuilder(2 + in.length);
- r.append('"');
+ final byte[] out = new byte[4 * in.length + 2];
+ int o = 0;
+ out[o++] = '"';
for (int i = 0; i < in.length; i++) {
final int c = in[i] & 0xff;
if (c < quote.length) {
final byte style = quote[c];
if (style == 0) {
- r.append((char) c);
+ out[o++] = (byte) c;
continue;
}
if (style > 0) {
reuse = false;
- r.append('\\');
- r.append((char) style);
+ out[o++] = '\\';
+ out[o++] = style;
continue;
}
+ } else if (!quoteHigh) {
+ out[o++] = (byte) c;
+ continue;
}
reuse = false;
- r.append('\\');
- r.append((char) (((c >> 6) & 03) + '0'));
- r.append((char) (((c >> 3) & 07) + '0'));
- r.append((char) (((c >> 0) & 07) + '0'));
+ out[o++] = '\\';
+ out[o++] = (byte) (((c >> 6) & 03) + '0');
+ out[o++] = (byte) (((c >> 3) & 07) + '0');
+ out[o++] = (byte) (((c >> 0) & 07) + '0');
}
- if (reuse)
+ if (reuse) {
return instr;
- r.append('"');
- return r.toString();
+ }
+ out[o++] = '"';
+ return new String(out, 0, o, UTF_8);
}
@Override
@@ -375,8 +391,8 @@ private static String dq(byte[] in, int inPtr, int inEnd) {
return RawParseUtils.decode(UTF_8, r, 0, rPtr);
}
- private GitPathStyle() {
- // Singleton
+ private GitPathStyle(boolean doQuote) {
+ quoteHigh = doQuote;
}
}
}
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/util/RefMap.java b/org.eclipse.jgit/src/org/eclipse/jgit/util/RefMap.java
index 9663e3c..ce1308f 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/util/RefMap.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/util/RefMap.java
@@ -191,12 +191,11 @@ public Ref put(String keyName, Ref value) {
Ref prior = loose.get(name);
loose = loose.set(idx, value);
return prior;
- } else {
- Ref prior = get(keyName);
- loose = loose.add(idx, value);
- sizeIsValid = false;
- return prior;
}
+ Ref prior = get(keyName);
+ loose = loose.add(idx, value);
+ sizeIsValid = false;
+ return prior;
}
/** {@inheritDoc} */
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/util/RelativeDateFormatter.java b/org.eclipse.jgit/src/org/eclipse/jgit/util/RelativeDateFormatter.java
index 83c60c6..55f39c2 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/util/RelativeDateFormatter.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/util/RelativeDateFormatter.java
@@ -52,19 +52,19 @@
* in the format defined by {@code git log --relative-date}.
*/
public class RelativeDateFormatter {
- final static long SECOND_IN_MILLIS = 1000;
+ static final long SECOND_IN_MILLIS = 1000;
- final static long MINUTE_IN_MILLIS = 60 * SECOND_IN_MILLIS;
+ static final long MINUTE_IN_MILLIS = 60 * SECOND_IN_MILLIS;
- final static long HOUR_IN_MILLIS = 60 * MINUTE_IN_MILLIS;
+ static final long HOUR_IN_MILLIS = 60 * MINUTE_IN_MILLIS;
- final static long DAY_IN_MILLIS = 24 * HOUR_IN_MILLIS;
+ static final long DAY_IN_MILLIS = 24 * HOUR_IN_MILLIS;
- final static long WEEK_IN_MILLIS = 7 * DAY_IN_MILLIS;
+ static final long WEEK_IN_MILLIS = 7 * DAY_IN_MILLIS;
- final static long MONTH_IN_MILLIS = 30 * DAY_IN_MILLIS;
+ static final long MONTH_IN_MILLIS = 30 * DAY_IN_MILLIS;
- final static long YEAR_IN_MILLIS = 365 * DAY_IN_MILLIS;
+ static final long YEAR_IN_MILLIS = 365 * DAY_IN_MILLIS;
/**
* Get age of given {@link java.util.Date} compared to now formatted in the
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/util/SystemReader.java b/org.eclipse.jgit/src/org/eclipse/jgit/util/SystemReader.java
index e16a886..87ce475 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/util/SystemReader.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/util/SystemReader.java
@@ -85,7 +85,7 @@
*/
public abstract class SystemReader {
- private final static Logger LOG = LoggerFactory
+ private static final Logger LOG = LoggerFactory
.getLogger(SystemReader.class);
private static final SystemReader DEFAULT;
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/util/io/LimitedInputStream.java b/org.eclipse.jgit/src/org/eclipse/jgit/util/io/LimitedInputStream.java
index 9ab2caa..e437c11 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/util/io/LimitedInputStream.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/util/io/LimitedInputStream.java
@@ -98,15 +98,16 @@ public synchronized void mark(int readLimit) {
@Override
public int read() throws IOException {
if (left == 0) {
- if (in.available() == 0)
+ if (in.available() == 0) {
return -1;
- else
- limitExceeded();
+ }
+ limitExceeded();
}
int result = in.read();
- if (result != -1)
+ if (result != -1) {
--left;
+ }
return result;
}
@@ -114,16 +115,17 @@ public int read() throws IOException {
@Override
public int read(byte[] b, int off, int len) throws IOException {
if (left == 0) {
- if (in.available() == 0)
+ if (in.available() == 0) {
return -1;
- else
- limitExceeded();
+ }
+ limitExceeded();
}
len = (int) Math.min(len, left);
int result = in.read(b, off, len);
- if (result != -1)
+ if (result != -1) {
left -= result;
+ }
return result;
}
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/util/sha1/SHA1.java b/org.eclipse.jgit/src/org/eclipse/jgit/util/sha1/SHA1.java
index 1ad6602..e6971ee 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/util/sha1/SHA1.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/util/sha1/SHA1.java
@@ -78,7 +78,7 @@
* @since 4.7
*/
public class SHA1 {
- private static Logger LOG = LoggerFactory.getLogger(SHA1.class);
+ private static final Logger LOG = LoggerFactory.getLogger(SHA1.class);
private static final boolean DETECT_COLLISIONS;
static {
diff --git a/pom.xml b/pom.xml
index d0335b0..7d2d40f 100644
--- a/pom.xml
+++ b/pom.xml
@@ -51,7 +51,7 @@
<groupId>org.eclipse.jgit</groupId>
<artifactId>org.eclipse.jgit-parent</artifactId>
<packaging>pom</packaging>
- <version>5.5.2-SNAPSHOT</version>
+ <version>5.6.2-SNAPSHOT</version>
<name>JGit - Parent</name>
<url>${jgit-url}</url>
@@ -180,6 +180,8 @@
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<maven.build.timestamp.format>yyyyMMddHHmm</maven.build.timestamp.format>
+ <maven.compiler.source>1.8</maven.compiler.source>
+ <maven.compiler.target>1.8</maven.compiler.target>
<bundle-manifest>${project.build.directory}/META-INF/MANIFEST.MF</bundle-manifest>
<jgit-last-release-version>5.4.0.201906121030-r</jgit-last-release-version>
@@ -193,7 +195,7 @@
<commons-compress-version>1.18</commons-compress-version>
<osgi-core-version>4.3.1</osgi-core-version>
<servlet-api-version>3.1.0</servlet-api-version>
- <jetty-version>9.4.20.v20190813</jetty-version>
+ <jetty-version>9.4.22.v20191022</jetty-version>
<japicmp-version>0.14.1</japicmp-version>
<httpclient-version>4.5.6</httpclient-version>
<httpcore-version>4.4.10</httpcore-version>
@@ -202,7 +204,7 @@
<maven-javadoc-plugin-version>3.3.1</maven-javadoc-plugin-version>
<tycho-extras-version>1.7.0</tycho-extras-version>
<gson-version>2.8.2</gson-version>
- <bouncycastle-version>1.61</bouncycastle-version>
+ <bouncycastle-version>1.64</bouncycastle-version>
<maven-project-info-reports-plugin-version>3.1.2</maven-project-info-reports-plugin-version>
<maven-jxr-plugin-version>3.1.1</maven-jxr-plugin-version>
<maven-surefire-plugin-version>3.0.0-M5</maven-surefire-plugin-version>
@@ -378,7 +380,7 @@
<dependency><!-- add support for ssh/scp -->
<groupId>org.apache.maven.wagon</groupId>
<artifactId>wagon-ssh</artifactId>
- <version>3.3.3</version>
+ <version>3.3.4</version>
</dependency>
</dependencies>
</plugin>
@@ -439,7 +441,7 @@
<configuration>
<rules>
<requireMavenVersion>
- <version>3.5.2</version>
+ <version>3.6.2</version>
</requireMavenVersion>
</rules>
</configuration>
@@ -925,7 +927,7 @@
<dependency>
<groupId>org.eclipse.jdt</groupId>
<artifactId>ecj</artifactId>
- <version>3.18.0</version>
+ <version>3.19.0</version>
</dependency>
</dependencies>
</plugin>
diff --git a/tools/bazelisk_version.bzl b/tools/bazelisk_version.bzl
new file mode 100644
index 0000000..d8b3d10
--- /dev/null
+++ b/tools/bazelisk_version.bzl
@@ -0,0 +1,16 @@
+_template = """
+load("@bazel_skylib//lib:versions.bzl", "versions")
+
+def check_bazel_version():
+ versions.check(minimum_bazel_version = "{version}")
+""".strip()
+
+def _impl(repository_ctx):
+ repository_ctx.symlink(Label("@//:.bazelversion"), ".bazelversion")
+ bazelversion = repository_ctx.read(".bazelversion").strip()
+
+ repository_ctx.file("BUILD", executable = False)
+
+ repository_ctx.file("check.bzl", executable = False, content = _template.format(version = bazelversion))
+
+bazelisk_version = repository_rule(implementation = _impl)