Merge branch 'stable-4.6' into stable-4.7 * stable-4.6: Prepare 4.4.2-SNAPSHOT builds JGit v4.0.3.201509231615-r Change-Id: I3e1a870a225447e761368298ce9b65dbec2c2a82 Signed-off-by: David Pursehouse <david.pursehouse@gmail.com>
diff --git a/.buckconfig b/.buckconfig deleted file mode 100644 index 7986494..0000000 --- a/.buckconfig +++ /dev/null
@@ -1,26 +0,0 @@ -[alias] - all = //:all - jgit = //org.eclipse.jgit:jgit - jgit-archive = //org.eclipse.jgit.archive:jgit-archive - jgit_bin = //:jgit_bin - jgit-lfs = //org.eclipse.jgit.lfs:jgit-lfs - jgit-lfs-server = //org.eclipse.jgit.lfs.server:jgit-lfs-server - jgit-servlet = //org.eclipse.jgit.http.server:jgit-servlet - -[buildfile] - includes = //tools/default.defs - -[java] - src_roots = src, resources, tst - source_level = 8 - target_level = 8 - -[project] - ignore = .git - -[cache] - mode = dir - -[download] - maven_repo = http://repo1.maven.org/maven2 - in_build = true
diff --git a/.buckversion b/.buckversion deleted file mode 100644 index 7eb591f..0000000 --- a/.buckversion +++ /dev/null
@@ -1 +0,0 @@ -e27df656657f93f8d57a7aaac69a5ae0e298a292
diff --git a/.gitignore b/.gitignore index e78f8fd..963b8a4 100644 --- a/.gitignore +++ b/.gitignore
@@ -1,6 +1,9 @@ -/.buckd /.project -/buck-cache -/buck-out /target infer-out +bazel-bin +bazel-genfiles +bazel-jgit +bazel-out +bazel-testlogs +*~
diff --git a/.mailmap b/.mailmap index ab4c963..560baaa 100644 --- a/.mailmap +++ b/.mailmap
@@ -2,6 +2,7 @@ Roberto Tyley <roberto.tyley@guardian.co.uk> roberto <roberto.tyley@guardian.co.uk> Saša Živkov <sasa.zivkov@sap.com> Sasa Zivkov <sasa.zivkov@sap.com> Saša Živkov <sasa.zivkov@sap.com> Saša Živkov <zivkov@gmail.com> +Saša Živkov <sasa.zivkov@sap.com> Sasa Zivkov <zivkov@gmail.com> Shawn Pearce <spearce@spearce.org> Shawn O. Pearce <sop@google.com> Shawn Pearce <spearce@spearce.org> Shawn Pearce <sop@google.com> Shawn Pearce <spearce@spearce.org> Shawn O. Pearce <spearce@spearce.org>
diff --git a/BUCK b/BUCK deleted file mode 100644 index 4578e17..0000000 --- a/BUCK +++ /dev/null
@@ -1,18 +0,0 @@ -DEPS = [ - '//org.eclipse.jgit:jgit', - '//org.eclipse.jgit.archive:jgit-archive', - '//org.eclipse.jgit.http.server:jgit-servlet', - '//org.eclipse.jgit.lfs:jgit-lfs', - '//org.eclipse.jgit.lfs.server:jgit-lfs-server', - '//org.eclipse.jgit.pgm:jgit', -] - -zip_file( - name = 'all', - srcs = DEPS, -) - -sh_binary( - name = 'jgit_bin', - main = '//org.eclipse.jgit.pgm:jgit', -)
diff --git a/BUILD b/BUILD new file mode 100644 index 0000000..be6dd76 --- /dev/null +++ b/BUILD
@@ -0,0 +1,25 @@ +package(default_visibility = ["//visibility:public"]) + +genrule( + name = "all", + testonly = 1, + srcs = [ + "//org.eclipse.jgit:jgit", + "//org.eclipse.jgit.pgm:pgm", + "//org.eclipse.jgit.ui:ui", + "//org.eclipse.jgit.archive:jgit-archive", + "//org.eclipse.jgit.http.apache:http-apache", + "//org.eclipse.jgit.http.server:jgit-servlet", + "//org.eclipse.jgit.lfs:jgit-lfs", + "//org.eclipse.jgit.lfs.server:jgit-lfs-server", + "//org.eclipse.jgit.junit:junit", + ], + outs = ["all.zip"], + cmd = " && ".join([ + "p=$$PWD", + "t=$$(mktemp -d || mktemp -d -t bazel-tmp)", + "cp $(SRCS) $$t", + "cd $$t", + "zip -qr $$p/$@ .", + ]), +)
diff --git a/WORKSPACE b/WORKSPACE new file mode 100644 index 0000000..c5eae1d --- /dev/null +++ b/WORKSPACE
@@ -0,0 +1,150 @@ +workspace(name = "jgit") + +load("//tools:bazlets.bzl", "load_bazlets") + +load_bazlets(commit = "3afbeab55ece585dbfc7a980bf7214b24ddbbe86") + +load( + "@com_googlesource_gerrit_bazlets//tools:maven_jar.bzl", + "maven_jar", +) + +maven_jar( + name = "jsch", + artifact = "com.jcraft:jsch:0.1.53", + sha1 = "658b682d5c817b27ae795637dfec047c63d29935", +) + +maven_jar( + name = "javaewah", + artifact = "com.googlecode.javaewah:JavaEWAH:1.1.6", + sha1 = "94ad16d728b374d65bd897625f3fbb3da223a2b6", +) + +maven_jar( + name = "httpclient", + artifact = "org.apache.httpcomponents:httpclient:4.3.6", + sha1 = "4c47155e3e6c9a41a28db36680b828ced53b8af4", +) + +maven_jar( + name = "httpcore", + artifact = "org.apache.httpcomponents:httpcore:4.3.3", + sha1 = "f91b7a4aadc5cf486df6e4634748d7dd7a73f06d", +) + +maven_jar( + name = "commons-codec", + artifact = "commons-codec:commons-codec:1.4", + sha1 = "4216af16d38465bbab0f3dff8efa14204f7a399a", +) + +maven_jar( + name = "commons-logging", + artifact = "commons-logging:commons-logging:1.1.3", + sha1 = "f6f66e966c70a83ffbdb6f17a0919eaf7c8aca7f", +) + +maven_jar( + name = "log-api", + artifact = "org.slf4j:slf4j-api:1.7.2", + sha1 = "0081d61b7f33ebeab314e07de0cc596f8e858d97", +) + +maven_jar( + name = "slf4j-simple", + artifact = "org.slf4j:slf4j-simple:1.7.2", + sha1 = "760055906d7353ba4f7ce1b8908bc6b2e91f39fa", +) + +maven_jar( + name = "servlet-api-3_1", + artifact = "javax.servlet:javax.servlet-api:3.1.0", + sha1 = "3cd63d075497751784b2fa84be59432f4905bf7c", +) + +maven_jar( + name = "commons-compress", + artifact = "org.apache.commons:commons-compress:1.6", + sha1 = "c7d9b580aff9e9f1998361f16578e63e5c064699", +) + +maven_jar( + name = "tukaani-xz", + artifact = "org.tukaani:xz:1.3", + sha1 = "66db21c8484120cb6a51b5b3ea47b6f383942bec", +) + +maven_jar( + name = "args4j", + artifact = "args4j:args4j:2.0.15", + sha1 = "139441471327b9cc6d56436cb2a31e60eb6ed2ba", +) + +maven_jar( + name = "junit", + artifact = "junit:junit:4.11", + sha1 = "4e031bb61df09069aeb2bffb4019e7a5034a4ee0", +) + +maven_jar( + name = "hamcrest-library", + artifact = "org.hamcrest:hamcrest-library:1.3", + sha1 = "4785a3c21320980282f9f33d0d1264a69040538f", +) + +maven_jar( + name = "hamcrest-core", + artifact = "org.hamcrest:hamcrest-core:1.3", + sha1 = "42a25dc3219429f0e5d060061f71acb49bf010a0", +) + +maven_jar( + name = "gson", + artifact = "com.google.code.gson:gson:2.2.4", + sha1 = "a60a5e993c98c864010053cb901b7eab25306568", +) + +JETTY_VER = "9.3.17.v20170317" + +maven_jar( + name = "jetty-servlet", + artifact = "org.eclipse.jetty:jetty-servlet:" + JETTY_VER, + sha1 = "ed6986b0d0ca7b9b0f9015c9efb80442e3043a8e", + src_sha1 = "ee6b4784a00a92e5c1b6111033b7ae41ac6052a3", +) + +maven_jar( + name = "jetty-security", + artifact = "org.eclipse.jetty:jetty-security:" + JETTY_VER, + sha1 = "ca52535569445682d42aaa97c7039442719a0507", + src_sha1 = "2ff9f4fb18b320fd5a0272a427bacc4d5fe7bc86", +) + +maven_jar( + name = "jetty-server", + artifact = "org.eclipse.jetty:jetty-server:" + JETTY_VER, + sha1 = "194e9a02e6ba249ef4a3f4bd56b4993087992299", + src_sha1 = "0c9bd572f530c411592aefb71781ecca0b3719a9", +) + +maven_jar( + name = "jetty-http", + artifact = "org.eclipse.jetty:jetty-http:" + JETTY_VER, + sha1 = "6c02d728e15d4868486254039c867a1ac3e4a52e", + src_sha1 = "3c0a2a82792f268631b4fefd77be9f126ec974b1", +) + +maven_jar( + name = "jetty-io", + artifact = "org.eclipse.jetty:jetty-io:" + JETTY_VER, + sha1 = "756a8cd2a1cbfb84a94973b6332dd3eccd47c0cd", + src_sha1 = "a9afa99cccb19b441364fa805d027f457cbbb136", +) + +maven_jar( + name = "jetty-util", + artifact = "org.eclipse.jetty:jetty-util:" + JETTY_VER, + sha1 = "b8512ab02819de01f0f5a5c6026163041f579beb", + src_sha1 = "96f8e3dcdc3660a5c91f19c46695daa70ac95625", +)
diff --git a/lib/BUCK b/lib/BUCK deleted file mode 100644 index d89af5d..0000000 --- a/lib/BUCK +++ /dev/null
@@ -1,134 +0,0 @@ -maven_jar( - name = 'jsch', - bin_sha1 = '658b682d5c817b27ae795637dfec047c63d29935', - src_sha1 = '791359d94d6edcace686a56d0727ee093a2f7c33', - group = 'com.jcraft', - artifact = 'jsch', - version = '0.1.53', -) - -maven_jar( - name = 'javaewah', - bin_sha1 = '94ad16d728b374d65bd897625f3fbb3da223a2b6', - src_sha1 = 'ca2745e91c6a51f8e6809d1579bda36ad83f1f58', - group = 'com.googlecode.javaewah', - artifact = 'JavaEWAH', - version = '1.1.6', -) - -maven_jar( - name = 'httpcomponents', - bin_sha1 = '4c47155e3e6c9a41a28db36680b828ced53b8af4', - src_sha1 = 'af4d76be0c46ee26b0d9d1d4a34d244a633cac84', - group = 'org.apache.httpcomponents', - artifact = 'httpclient', - version = '4.3.6', -) - -maven_jar( - name = 'httpcore', - bin_sha1 = 'f91b7a4aadc5cf486df6e4634748d7dd7a73f06d', - src_sha1 = '1b0aa62a6a91e9fa00c16f0a4a2c874804ed3b1e', - group = 'org.apache.httpcomponents', - artifact = 'httpcore', - version = '4.3.3', -) - -maven_jar( - name = 'commons-logging', - bin_sha1 = 'f6f66e966c70a83ffbdb6f17a0919eaf7c8aca7f', - src_sha1 = '28bb0405fddaf04f15058fbfbe01fe2780d7d3b6', - group = 'commons-logging', - artifact = 'commons-logging', - version = '1.1.3', -) - -maven_jar( - name = 'slf4j-api', - bin_sha1 = '0081d61b7f33ebeab314e07de0cc596f8e858d97', - src_sha1 = '58d38f68d4a867d4552ae27960bb348d7eaa1297', - group = 'org.slf4j', - artifact = 'slf4j-api', - version = '1.7.2', -) - -maven_jar( - name = 'slf4j-simple', - bin_sha1 = '760055906d7353ba4f7ce1b8908bc6b2e91f39fa', - src_sha1 = '09474919128b3a7fcf21a5f9c907f5251f234544', - group = 'org.slf4j', - artifact = 'slf4j-simple', - version = '1.7.2', -) - -maven_jar( - name = 'servlet-api', - bin_sha1 = '3cd63d075497751784b2fa84be59432f4905bf7c', - src_sha1 = 'ab3976d4574c48d22dc1abf6a9e8bd0fdf928223', - group = 'javax.servlet', - artifact = 'javax.servlet-api', - version = '3.1.0', -) - -maven_jar( - name = 'commons-compress', - bin_sha1 = 'c7d9b580aff9e9f1998361f16578e63e5c064699', - src_sha1 = '396b81bdfd0fb617178e1707ef64832215307c78', - group = 'org.apache.commons', - artifact = 'commons-compress', - version = '1.6', -) - -maven_jar( - name = 'tukaani-xz', - bin_sha1 = '66db21c8484120cb6a51b5b3ea47b6f383942bec', - src_sha1 = '6396220725701d767c553902c41120d7bf38e9f5', - group = 'org.tukaani', - artifact = 'xz', - version = '1.3', -) - -maven_jar( - name = 'args4j', - bin_sha1 = '139441471327b9cc6d56436cb2a31e60eb6ed2ba', - src_sha1 = '22631b78cc8f60a6918557e8cbdb33e90f63a77f', - group = 'args4j', - artifact = 'args4j', - version = '2.0.15', -) - -maven_jar( - name = 'junit', - bin_sha1 = '4e031bb61df09069aeb2bffb4019e7a5034a4ee0', - src_sha1 = '28e0ad201304e4a4abf999ca0570b7cffc352c3c', - group = 'junit', - artifact = 'junit', - version = '4.11', -) - -maven_jar( - name = 'hamcrest-library', - bin_sha1 = '4785a3c21320980282f9f33d0d1264a69040538f', - src_sha1 = '047a7ee46628ab7133129cd7cef1e92657bc275e', - group = 'org.hamcrest', - artifact = 'hamcrest-library', - version = '1.3', -) - -maven_jar( - name = 'hamcrest-core', - bin_sha1 = '42a25dc3219429f0e5d060061f71acb49bf010a0', - src_sha1 = '1dc37250fbc78e23a65a67fbbaf71d2e9cbc3c0b', - group = 'org.hamcrest', - artifact = 'hamcrest-core', - version = '1.3', -) - -maven_jar( - name = 'gson', - bin_sha1 = 'a60a5e993c98c864010053cb901b7eab25306568', - src_sha1 = 'a6dc5db8a12928e583bd3f23e72d3ab611ecd58f', - group = 'com.google.code.gson', - artifact = 'gson', - version = '2.2.4', -)
diff --git a/lib/BUILD b/lib/BUILD new file mode 100644 index 0000000..346e1fd --- /dev/null +++ b/lib/BUILD
@@ -0,0 +1,156 @@ +java_library( + name = "args4j", + visibility = [ + "//org.eclipse.jgit.pgm:__pkg__", + "//org.eclipse.jgit.pgm.test:__pkg__", + ], + exports = ["@args4j//jar"], +) + +java_library( + name = "commons-compress", + visibility = [ + "//org.eclipse.jgit.archive:__pkg__", + "//org.eclipse.jgit.pgm.test:__pkg__", + ], + exports = ["@commons-compress//jar"], +) + +java_library( + name = "commons-codec", + exports = ["@commons-codec//jar"], +) + +java_library( + name = "commons-logging", + testonly = 1, + visibility = ["//visibility:public"], + exports = ["@commons-logging//jar"], +) + +java_library( + name = "gson", + visibility = ["//org.eclipse.jgit.lfs.server:__pkg__"], + exports = ["@gson//jar"], +) + +java_library( + name = "httpclient", + visibility = [ + "//org.eclipse.jgit.http.apache:__pkg__", + "//org.eclipse.jgit.lfs.server.test:__pkg__", + "//org.eclipse.jgit.pgm:__pkg__", + ], + exports = ["@httpclient//jar"], +) + +java_library( + name = "httpcore", + visibility = [ + "//org.eclipse.jgit.http.apache:__pkg__", + "//org.eclipse.jgit.lfs.server:__pkg__", + "//org.eclipse.jgit.lfs.server.test:__pkg__", + "//org.eclipse.jgit.pgm:__pkg__", + ], + exports = ["@httpcore//jar"], +) + +java_library( + name = "javaewah", + visibility = ["//visibility:public"], + exports = ["@javaewah//jar"], +) + +java_library( + name = "jetty-http", + # TODO: This should be testonly but org.eclipse.jgit.pgm depends on it. + visibility = ["//visibility:public"], + exports = ["@jetty-http//jar"], + runtime_deps = [":commons-codec"], +) + +java_library( + name = "jetty-io", + # TODO: This should be testonly but org.eclipse.jgit.pgm depends on it. + visibility = ["//visibility:public"], + exports = ["@jetty-io//jar"], +) + +java_library( + name = "jetty-security", + # TODO: This should be testonly but org.eclipse.jgit.pgm depends on it. + visibility = ["//visibility:public"], + exports = ["@jetty-security//jar"], +) + +java_library( + name = "jetty-server", + # TODO: This should be testonly but org.eclipse.jgit.pgm depends on it. + visibility = ["//visibility:public"], + exports = ["@jetty-server//jar"], +) + +java_library( + name = "jetty-servlet", + # TODO: This should be testonly but org.eclipse.jgit.pgm depends on it. + visibility = ["//visibility:public"], + exports = ["@jetty-servlet//jar"], +) + +java_library( + name = "jetty-util", + # TODO: This should be testonly but org.eclipse.jgit.pgm depends on it. + visibility = ["//visibility:public"], + exports = ["@jetty-util//jar"], +) + +java_library( + name = "jsch", + visibility = ["//org.eclipse.jgit:__pkg__"], + exports = ["@jsch//jar"], +) + +java_library( + name = "junit", + testonly = 1, + visibility = ["//visibility:public"], + exports = [ + "@hamcrest-core//jar", + "@hamcrest-library//jar", + "@junit//jar", + ], +) + +java_library( + name = "servlet-api", + visibility = [ + "//org.eclipse.jgit.http.apache:__pkg__", + "//org.eclipse.jgit.http.server:__pkg__", + "//org.eclipse.jgit.http.test:__pkg__", + "//org.eclipse.jgit.junit.http:__pkg__", + "//org.eclipse.jgit.lfs.server:__pkg__", + "//org.eclipse.jgit.lfs.server.test:__pkg__", + "//org.eclipse.jgit.pgm:__pkg__", + ], + exports = ["@servlet-api-3_1//jar"], +) + +java_library( + name = "slf4j-api", + visibility = ["//visibility:public"], + exports = ["@log-api//jar"], +) + +java_library( + name = "slf4j-simple", + testonly = 1, + visibility = ["//visibility:public"], + exports = ["@slf4j-simple//jar"], +) + +java_library( + name = "xz", + testonly = 1, + visibility = ["//visibility:public"], + exports = ["@tukaani-xz//jar"], +)
diff --git a/lib/jetty/BUCK b/lib/jetty/BUCK deleted file mode 100644 index fbb37c1..0000000 --- a/lib/jetty/BUCK +++ /dev/null
@@ -1,56 +0,0 @@ -VERSION = '9.3.17.v20170317' -GROUP = 'org.eclipse.jetty' - -maven_jar( - name = 'servlet', - bin_sha1 = 'ed6986b0d0ca7b9b0f9015c9efb80442e3043a8e', - src_sha1 = 'ee6b4784a00a92e5c1b6111033b7ae41ac6052a3', - group = GROUP, - artifact = 'jetty-servlet', - version = VERSION, -) - -maven_jar( - name = 'security', - bin_sha1 = 'ca52535569445682d42aaa97c7039442719a0507', - src_sha1 = '2ff9f4fb18b320fd5a0272a427bacc4d5fe7bc86', - group = GROUP, - artifact = 'jetty-security', - version = VERSION, -) - -maven_jar( - name = 'server', - bin_sha1 = '194e9a02e6ba249ef4a3f4bd56b4993087992299', - src_sha1 = '0c9bd572f530c411592aefb71781ecca0b3719a9', - group = GROUP, - artifact = 'jetty-server', - version = VERSION, -) - -maven_jar( - name = 'http', - bin_sha1 = '6c02d728e15d4868486254039c867a1ac3e4a52e', - src_sha1 = '3c0a2a82792f268631b4fefd77be9f126ec974b1', - group = GROUP, - artifact = 'jetty-http', - version = VERSION, -) - -maven_jar( - name = 'io', - bin_sha1 = '756a8cd2a1cbfb84a94973b6332dd3eccd47c0cd', - src_sha1 = 'a9afa99cccb19b441364fa805d027f457cbbb136', - group = GROUP, - artifact = 'jetty-io', - version = VERSION, -) - -maven_jar( - name = 'util', - bin_sha1 = 'b8512ab02819de01f0f5a5c6026163041f579beb', - src_sha1 = '96f8e3dcdc3660a5c91f19c46695daa70ac95625', - group = GROUP, - artifact = 'jetty-util', - version = VERSION, -)
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 10c29d5..64f7498 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
@@ -56,7 +56,7 @@ org.eclipse.jdt.core.compiler.problem.missingJavadocTagsMethodTypeParameters=disabled org.eclipse.jdt.core.compiler.problem.missingJavadocTagsOverriding=disabled org.eclipse.jdt.core.compiler.problem.missingJavadocTagsVisibility=private -org.eclipse.jdt.core.compiler.problem.missingOverrideAnnotation=ignore +org.eclipse.jdt.core.compiler.problem.missingOverrideAnnotation=warning org.eclipse.jdt.core.compiler.problem.missingOverrideAnnotationForInterfaceMethodImplementation=enabled org.eclipse.jdt.core.compiler.problem.missingSerialVersion=warning org.eclipse.jdt.core.compiler.problem.missingSynchronizedOnInheritedMethod=ignore @@ -76,7 +76,7 @@ org.eclipse.jdt.core.compiler.problem.rawTypeReference=ignore org.eclipse.jdt.core.compiler.problem.redundantNullAnnotation=warning org.eclipse.jdt.core.compiler.problem.redundantNullCheck=warning -org.eclipse.jdt.core.compiler.problem.redundantSpecificationOfTypeArguments=ignore +org.eclipse.jdt.core.compiler.problem.redundantSpecificationOfTypeArguments=warning org.eclipse.jdt.core.compiler.problem.redundantSuperinterface=error org.eclipse.jdt.core.compiler.problem.reportMethodCanBePotentiallyStatic=ignore org.eclipse.jdt.core.compiler.problem.reportMethodCanBeStatic=ignore
diff --git a/org.eclipse.jgit.ant.test/META-INF/MANIFEST.MF b/org.eclipse.jgit.ant.test/META-INF/MANIFEST.MF index 3bf69c3..74f5ed0 100644 --- a/org.eclipse.jgit.ant.test/META-INF/MANIFEST.MF +++ b/org.eclipse.jgit.ant.test/META-INF/MANIFEST.MF
@@ -3,14 +3,13 @@ Bundle-ManifestVersion: 2 Bundle-Name: %plugin_name Bundle-SymbolicName: org.eclipse.jgit.ant.test -Bundle-Version: 4.6.2.qualifier +Bundle-Version: 4.7.6.qualifier Bundle-ActivationPolicy: lazy Bundle-RequiredExecutionEnvironment: JavaSE-1.8 Import-Package: org.apache.tools.ant, - org.eclipse.jgit.ant.tasks;version="[4.6.2,4.7.0)", - org.eclipse.jgit.internal.storage.file;version="[4.6.2,4.7.0)", - org.eclipse.jgit.junit;version="[4.6.2,4.7.0)", - org.eclipse.jgit.lib;version="[4.6.2,4.7.0)", - org.eclipse.jgit.util;version="[4.6.2,4.7.0)", - org.hamcrest;version="[1.1.0,2.0.0)", + org.eclipse.jgit.ant.tasks;version="[4.7.6,4.8.0)", + org.eclipse.jgit.junit;version="[4.7.6,4.8.0)", + org.eclipse.jgit.lib;version="[4.7.6,4.8.0)", + org.eclipse.jgit.util;version="[4.7.6,4.8.0)", + org.hamcrest.core;version="[1.1.0,2.0.0)", org.junit;version="[4.0.0,5.0.0)"
diff --git a/org.eclipse.jgit.ant.test/pom.xml b/org.eclipse.jgit.ant.test/pom.xml index 9592841..eb88e2e 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>4.6.2-SNAPSHOT</version> + <version>4.7.6-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 80cfbbb..4d260cf 100644 --- a/org.eclipse.jgit.ant/.settings/org.eclipse.jdt.core.prefs +++ b/org.eclipse.jgit.ant/.settings/org.eclipse.jdt.core.prefs
@@ -56,7 +56,7 @@ org.eclipse.jdt.core.compiler.problem.missingJavadocTagsMethodTypeParameters=disabled org.eclipse.jdt.core.compiler.problem.missingJavadocTagsOverriding=disabled org.eclipse.jdt.core.compiler.problem.missingJavadocTagsVisibility=private -org.eclipse.jdt.core.compiler.problem.missingOverrideAnnotation=ignore +org.eclipse.jdt.core.compiler.problem.missingOverrideAnnotation=warning org.eclipse.jdt.core.compiler.problem.missingOverrideAnnotationForInterfaceMethodImplementation=enabled org.eclipse.jdt.core.compiler.problem.missingSerialVersion=warning org.eclipse.jdt.core.compiler.problem.missingSynchronizedOnInheritedMethod=ignore @@ -76,7 +76,7 @@ org.eclipse.jdt.core.compiler.problem.rawTypeReference=ignore org.eclipse.jdt.core.compiler.problem.redundantNullAnnotation=warning org.eclipse.jdt.core.compiler.problem.redundantNullCheck=warning -org.eclipse.jdt.core.compiler.problem.redundantSpecificationOfTypeArguments=ignore +org.eclipse.jdt.core.compiler.problem.redundantSpecificationOfTypeArguments=warning org.eclipse.jdt.core.compiler.problem.redundantSuperinterface=error org.eclipse.jdt.core.compiler.problem.reportMethodCanBePotentiallyStatic=ignore org.eclipse.jdt.core.compiler.problem.reportMethodCanBeStatic=ignore
diff --git a/org.eclipse.jgit.ant/META-INF/MANIFEST.MF b/org.eclipse.jgit.ant/META-INF/MANIFEST.MF index 6b008e1..aa2db30 100644 --- a/org.eclipse.jgit.ant/META-INF/MANIFEST.MF +++ b/org.eclipse.jgit.ant/META-INF/MANIFEST.MF
@@ -2,11 +2,11 @@ Bundle-ManifestVersion: 2 Bundle-Name: %Bundle-Name Bundle-SymbolicName: org.eclipse.jgit.ant -Bundle-Version: 4.6.2.qualifier +Bundle-Version: 4.7.6.qualifier Bundle-RequiredExecutionEnvironment: JavaSE-1.8 Import-Package: org.apache.tools.ant, - org.eclipse.jgit.storage.file;version="[4.6.2,4.7.0)" + org.eclipse.jgit.storage.file;version="[4.7.6,4.8.0)" Bundle-Localization: plugin Bundle-Vendor: %Provider-Name -Export-Package: org.eclipse.jgit.ant.tasks;version="4.6.2"; +Export-Package: org.eclipse.jgit.ant.tasks;version="4.7.6"; uses:="org.apache.tools.ant.types,org.apache.tools.ant"
diff --git a/org.eclipse.jgit.ant/pom.xml b/org.eclipse.jgit.ant/pom.xml index 194c9dd..7e623e8 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>4.6.2-SNAPSHOT</version> + <version>4.7.6-SNAPSHOT</version> </parent> <artifactId>org.eclipse.jgit.ant</artifactId>
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 4f1759f..06ddbab 100644 --- a/org.eclipse.jgit.archive/.settings/org.eclipse.jdt.core.prefs +++ b/org.eclipse.jgit.archive/.settings/org.eclipse.jdt.core.prefs
@@ -56,7 +56,7 @@ org.eclipse.jdt.core.compiler.problem.missingJavadocTagsMethodTypeParameters=disabled org.eclipse.jdt.core.compiler.problem.missingJavadocTagsOverriding=disabled org.eclipse.jdt.core.compiler.problem.missingJavadocTagsVisibility=private -org.eclipse.jdt.core.compiler.problem.missingOverrideAnnotation=ignore +org.eclipse.jdt.core.compiler.problem.missingOverrideAnnotation=warning org.eclipse.jdt.core.compiler.problem.missingOverrideAnnotationForInterfaceMethodImplementation=enabled org.eclipse.jdt.core.compiler.problem.missingSerialVersion=warning org.eclipse.jdt.core.compiler.problem.missingSynchronizedOnInheritedMethod=ignore @@ -76,7 +76,7 @@ org.eclipse.jdt.core.compiler.problem.rawTypeReference=ignore org.eclipse.jdt.core.compiler.problem.redundantNullAnnotation=warning org.eclipse.jdt.core.compiler.problem.redundantNullCheck=warning -org.eclipse.jdt.core.compiler.problem.redundantSpecificationOfTypeArguments=ignore +org.eclipse.jdt.core.compiler.problem.redundantSpecificationOfTypeArguments=warning org.eclipse.jdt.core.compiler.problem.redundantSuperinterface=error org.eclipse.jdt.core.compiler.problem.reportMethodCanBePotentiallyStatic=ignore org.eclipse.jdt.core.compiler.problem.reportMethodCanBeStatic=ignore
diff --git a/org.eclipse.jgit.archive/BUCK b/org.eclipse.jgit.archive/BUCK deleted file mode 100644 index ae17032..0000000 --- a/org.eclipse.jgit.archive/BUCK +++ /dev/null
@@ -1,13 +0,0 @@ -java_library( - name = 'jgit-archive', - srcs = glob( - ['src/**'], - excludes = ['src/org/eclipse/jgit/archive/FormatActivator.java'], - ), - resources = glob(['resources/**']), - provided_deps = [ - '//org.eclipse.jgit:jgit', - '//lib:commons-compress', - ], - visibility = ['PUBLIC'], -)
diff --git a/org.eclipse.jgit.archive/BUILD b/org.eclipse.jgit.archive/BUILD new file mode 100644 index 0000000..dfdbfdc --- /dev/null +++ b/org.eclipse.jgit.archive/BUILD
@@ -0,0 +1,16 @@ +package(default_visibility = ["//visibility:public"]) + +java_library( + name = "jgit-archive", + srcs = glob( + ["src/**"], + exclude = ["src/org/eclipse/jgit/archive/FormatActivator.java"], + ), + resource_strip_prefix = "org.eclipse.jgit.archive/resources", + resources = glob(["resources/**"]), + deps = [ + "//lib:commons-compress", + # We want these deps to be provided_deps + "//org.eclipse.jgit:jgit", + ], +)
diff --git a/org.eclipse.jgit.archive/META-INF/MANIFEST.MF b/org.eclipse.jgit.archive/META-INF/MANIFEST.MF index b2fe6b2..e1d44f4 100644 --- a/org.eclipse.jgit.archive/META-INF/MANIFEST.MF +++ b/org.eclipse.jgit.archive/META-INF/MANIFEST.MF
@@ -2,7 +2,7 @@ Bundle-ManifestVersion: 2 Bundle-Name: %plugin_name Bundle-SymbolicName: org.eclipse.jgit.archive -Bundle-Version: 4.6.2.qualifier +Bundle-Version: 4.7.6.qualifier Bundle-Vendor: %provider_name Bundle-Localization: plugin Bundle-RequiredExecutionEnvironment: JavaSE-1.8 @@ -12,14 +12,15 @@ 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="[4.6.2,4.7.0)", - org.eclipse.jgit.lib;version="[4.6.2,4.7.0)", - org.eclipse.jgit.nls;version="[4.6.2,4.7.0)", - org.eclipse.jgit.util;version="[4.6.2,4.7.0)", + org.eclipse.jgit.api;version="[4.7.6,4.8.0)", + org.eclipse.jgit.lib;version="[4.7.6,4.8.0)", + org.eclipse.jgit.nls;version="[4.7.6,4.8.0)", + org.eclipse.jgit.revwalk;version="[4.7.6,4.8.0)", + org.eclipse.jgit.util;version="[4.7.6,4.8.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="4.6.2"; +Export-Package: org.eclipse.jgit.archive;version="4.7.6"; uses:="org.eclipse.jgit.lib, org.eclipse.jgit.api, org.apache.commons.compress.archivers,
diff --git a/org.eclipse.jgit.archive/META-INF/SOURCE-MANIFEST.MF b/org.eclipse.jgit.archive/META-INF/SOURCE-MANIFEST.MF index 7d7477c..1fa37a7 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: 4.6.2.qualifier -Eclipse-SourceBundle: org.eclipse.jgit.archive;version="4.6.2.qualifier";roots="." +Bundle-Version: 4.7.6.qualifier +Eclipse-SourceBundle: org.eclipse.jgit.archive;version="4.7.6.qualifier";roots="."
diff --git a/org.eclipse.jgit.archive/pom.xml b/org.eclipse.jgit.archive/pom.xml index 9c38817..a6f412d 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>4.6.2-SNAPSHOT</version> + <version>4.7.6-SNAPSHOT</version> </parent> <artifactId>org.eclipse.jgit.archive</artifactId>
diff --git a/org.eclipse.jgit.archive/src/org/eclipse/jgit/archive/ArchiveFormats.java b/org.eclipse.jgit.archive/src/org/eclipse/jgit/archive/ArchiveFormats.java index 1be126a..9d3decd 100644 --- a/org.eclipse.jgit.archive/src/org/eclipse/jgit/archive/ArchiveFormats.java +++ b/org.eclipse.jgit.archive/src/org/eclipse/jgit/archive/ArchiveFormats.java
@@ -55,7 +55,7 @@ * that performs the same registration automatically. */ public class ArchiveFormats { - private static final List<String> myFormats = new ArrayList<String>(); + private static final List<String> myFormats = new ArrayList<>(); private static final void register(String name, ArchiveCommand.Format<?> fmt) { myFormats.add(name);
diff --git a/org.eclipse.jgit.archive/src/org/eclipse/jgit/archive/FormatActivator.java b/org.eclipse.jgit.archive/src/org/eclipse/jgit/archive/FormatActivator.java index a6a954f..aa4e4f5 100644 --- a/org.eclipse.jgit.archive/src/org/eclipse/jgit/archive/FormatActivator.java +++ b/org.eclipse.jgit.archive/src/org/eclipse/jgit/archive/FormatActivator.java
@@ -64,6 +64,7 @@ public class FormatActivator implements BundleActivator { * @param context * unused */ + @Override public void start(BundleContext context) { ArchiveFormats.registerAll(); } @@ -75,6 +76,7 @@ public void start(BundleContext context) { * @param context * unused */ + @Override public void stop(BundleContext context) { ArchiveFormats.unregisterAll(); }
diff --git a/org.eclipse.jgit.archive/src/org/eclipse/jgit/archive/TarFormat.java b/org.eclipse.jgit.archive/src/org/eclipse/jgit/archive/TarFormat.java index d56cb35..7b7fbcd 100644 --- a/org.eclipse.jgit.archive/src/org/eclipse/jgit/archive/TarFormat.java +++ b/org.eclipse.jgit.archive/src/org/eclipse/jgit/archive/TarFormat.java
@@ -57,7 +57,10 @@ import org.eclipse.jgit.api.ArchiveCommand; import org.eclipse.jgit.archive.internal.ArchiveText; import org.eclipse.jgit.lib.FileMode; +import org.eclipse.jgit.lib.ObjectId; import org.eclipse.jgit.lib.ObjectLoader; +import org.eclipse.jgit.revwalk.RevCommit; + /** * Unix TAR format (ustar + some PAX extensions). @@ -67,6 +70,7 @@ public final class TarFormat extends BaseFormat implements private static final List<String> SUFFIXES = Collections .unmodifiableList(Arrays.asList(".tar")); //$NON-NLS-1$ + @Override public ArchiveOutputStream createArchiveOutputStream(OutputStream s) throws IOException { return createArchiveOutputStream(s, @@ -76,6 +80,7 @@ public ArchiveOutputStream createArchiveOutputStream(OutputStream s) /** * @since 4.0 */ + @Override public ArchiveOutputStream createArchiveOutputStream(OutputStream s, Map<String, Object> o) throws IOException { TarArchiveOutputStream out = new TarArchiveOutputStream(s, "UTF-8"); //$NON-NLS-1$ @@ -84,9 +89,21 @@ public ArchiveOutputStream createArchiveOutputStream(OutputStream s, return applyFormatOptions(out, o); } + @Deprecated + @Override public void putEntry(ArchiveOutputStream out, String path, FileMode mode, ObjectLoader loader) throws IOException { + putEntry(out, null, path, mode,loader); + } + + /** + * @since 4.7 + */ + @Override + public void putEntry(ArchiveOutputStream out, + ObjectId tree, String path, FileMode mode, ObjectLoader loader) + throws IOException { if (mode == FileMode.SYMLINK) { final TarArchiveEntry entry = new TarArchiveEntry( path, TarConstants.LF_SYMLINK); @@ -106,6 +123,12 @@ public void putEntry(ArchiveOutputStream out, path = path + "/"; //$NON-NLS-1$ final TarArchiveEntry entry = new TarArchiveEntry(path); + + if (tree instanceof RevCommit) { + long t = ((RevCommit) tree).getCommitTime() * 1000L; + entry.setModTime(t); + } + if (mode == FileMode.TREE) { out.putArchiveEntry(entry); out.closeArchiveEntry(); @@ -127,6 +150,7 @@ public void putEntry(ArchiveOutputStream out, out.closeArchiveEntry(); } + @Override public Iterable<String> suffixes() { return SUFFIXES; }
diff --git a/org.eclipse.jgit.archive/src/org/eclipse/jgit/archive/Tbz2Format.java b/org.eclipse.jgit.archive/src/org/eclipse/jgit/archive/Tbz2Format.java index f3ab4da..5f194ec 100644 --- a/org.eclipse.jgit.archive/src/org/eclipse/jgit/archive/Tbz2Format.java +++ b/org.eclipse.jgit.archive/src/org/eclipse/jgit/archive/Tbz2Format.java
@@ -53,6 +53,7 @@ import org.apache.commons.compress.compressors.bzip2.BZip2CompressorOutputStream; import org.eclipse.jgit.api.ArchiveCommand; import org.eclipse.jgit.lib.FileMode; +import org.eclipse.jgit.lib.ObjectId; import org.eclipse.jgit.lib.ObjectLoader; /** @@ -65,6 +66,7 @@ public final class Tbz2Format extends BaseFormat implements private final ArchiveCommand.Format<ArchiveOutputStream> tarFormat = new TarFormat(); + @Override public ArchiveOutputStream createArchiveOutputStream(OutputStream s) throws IOException { return createArchiveOutputStream(s, @@ -74,18 +76,32 @@ public ArchiveOutputStream createArchiveOutputStream(OutputStream s) /** * @since 4.0 */ + @Override public ArchiveOutputStream createArchiveOutputStream(OutputStream s, Map<String, Object> o) throws IOException { BZip2CompressorOutputStream out = new BZip2CompressorOutputStream(s); return tarFormat.createArchiveOutputStream(out, o); } + @Deprecated + @Override public void putEntry(ArchiveOutputStream out, String path, FileMode mode, ObjectLoader loader) throws IOException { - tarFormat.putEntry(out, path, mode, loader); + putEntry(out, null, path, mode,loader); } + /** + * @since 4.7 + */ + @Override + public void putEntry(ArchiveOutputStream out, + ObjectId tree, String path, FileMode mode, ObjectLoader loader) + throws IOException { + tarFormat.putEntry(out, tree, path, mode, loader); + } + + @Override public Iterable<String> suffixes() { return SUFFIXES; }
diff --git a/org.eclipse.jgit.archive/src/org/eclipse/jgit/archive/TgzFormat.java b/org.eclipse.jgit.archive/src/org/eclipse/jgit/archive/TgzFormat.java index 06f09a4..a6d053e 100644 --- a/org.eclipse.jgit.archive/src/org/eclipse/jgit/archive/TgzFormat.java +++ b/org.eclipse.jgit.archive/src/org/eclipse/jgit/archive/TgzFormat.java
@@ -53,6 +53,7 @@ import org.apache.commons.compress.compressors.gzip.GzipCompressorOutputStream; import org.eclipse.jgit.api.ArchiveCommand; import org.eclipse.jgit.lib.FileMode; +import org.eclipse.jgit.lib.ObjectId; import org.eclipse.jgit.lib.ObjectLoader; /** @@ -65,6 +66,7 @@ public final class TgzFormat extends BaseFormat implements private final ArchiveCommand.Format<ArchiveOutputStream> tarFormat = new TarFormat(); + @Override public ArchiveOutputStream createArchiveOutputStream(OutputStream s) throws IOException { return createArchiveOutputStream(s, @@ -74,18 +76,32 @@ public ArchiveOutputStream createArchiveOutputStream(OutputStream s) /** * @since 4.0 */ + @Override public ArchiveOutputStream createArchiveOutputStream(OutputStream s, Map<String, Object> o) throws IOException { GzipCompressorOutputStream out = new GzipCompressorOutputStream(s); return tarFormat.createArchiveOutputStream(out, o); } + @Deprecated + @Override public void putEntry(ArchiveOutputStream out, String path, FileMode mode, ObjectLoader loader) throws IOException { - tarFormat.putEntry(out, path, mode, loader); + putEntry(out, null, path, mode,loader); } + /** + * @since 4.7 + */ + @Override + public void putEntry(ArchiveOutputStream out, + ObjectId tree, String path, FileMode mode, ObjectLoader loader) + throws IOException { + tarFormat.putEntry(out, tree, path, mode, loader); + } + + @Override public Iterable<String> suffixes() { return SUFFIXES; }
diff --git a/org.eclipse.jgit.archive/src/org/eclipse/jgit/archive/TxzFormat.java b/org.eclipse.jgit.archive/src/org/eclipse/jgit/archive/TxzFormat.java index 1483935..b6742ac 100644 --- a/org.eclipse.jgit.archive/src/org/eclipse/jgit/archive/TxzFormat.java +++ b/org.eclipse.jgit.archive/src/org/eclipse/jgit/archive/TxzFormat.java
@@ -53,6 +53,7 @@ import org.apache.commons.compress.compressors.xz.XZCompressorOutputStream; import org.eclipse.jgit.api.ArchiveCommand; import org.eclipse.jgit.lib.FileMode; +import org.eclipse.jgit.lib.ObjectId; import org.eclipse.jgit.lib.ObjectLoader; /** @@ -65,6 +66,7 @@ public final class TxzFormat extends BaseFormat implements private final ArchiveCommand.Format<ArchiveOutputStream> tarFormat = new TarFormat(); + @Override public ArchiveOutputStream createArchiveOutputStream(OutputStream s) throws IOException { return createArchiveOutputStream(s, @@ -74,18 +76,32 @@ public ArchiveOutputStream createArchiveOutputStream(OutputStream s) /** * @since 4.0 */ + @Override public ArchiveOutputStream createArchiveOutputStream(OutputStream s, Map<String, Object> o) throws IOException { XZCompressorOutputStream out = new XZCompressorOutputStream(s); return tarFormat.createArchiveOutputStream(out, o); } + @Deprecated + @Override public void putEntry(ArchiveOutputStream out, String path, FileMode mode, ObjectLoader loader) throws IOException { - tarFormat.putEntry(out, path, mode, loader); + putEntry(out, null, path, mode,loader); } + /** + * @since 4.7 + */ + @Override + public void putEntry(ArchiveOutputStream out, + ObjectId tree, String path, FileMode mode, ObjectLoader loader) + throws IOException { + tarFormat.putEntry(out, tree, path, mode, loader); + } + + @Override public Iterable<String> suffixes() { return SUFFIXES; }
diff --git a/org.eclipse.jgit.archive/src/org/eclipse/jgit/archive/ZipFormat.java b/org.eclipse.jgit.archive/src/org/eclipse/jgit/archive/ZipFormat.java index 0e1b253..46d918e 100644 --- a/org.eclipse.jgit.archive/src/org/eclipse/jgit/archive/ZipFormat.java +++ b/org.eclipse.jgit.archive/src/org/eclipse/jgit/archive/ZipFormat.java
@@ -56,7 +56,9 @@ import org.eclipse.jgit.api.ArchiveCommand; import org.eclipse.jgit.archive.internal.ArchiveText; import org.eclipse.jgit.lib.FileMode; +import org.eclipse.jgit.lib.ObjectId; import org.eclipse.jgit.lib.ObjectLoader; +import org.eclipse.jgit.revwalk.RevCommit; /** * PKWARE's ZIP format. @@ -66,6 +68,7 @@ public final class ZipFormat extends BaseFormat implements private static final List<String> SUFFIXES = Collections .unmodifiableList(Arrays.asList(".zip")); //$NON-NLS-1$ + @Override public ArchiveOutputStream createArchiveOutputStream(OutputStream s) throws IOException { return createArchiveOutputStream(s, @@ -75,14 +78,27 @@ public ArchiveOutputStream createArchiveOutputStream(OutputStream s) /** * @since 4.0 */ + @Override public ArchiveOutputStream createArchiveOutputStream(OutputStream s, Map<String, Object> o) throws IOException { return applyFormatOptions(new ZipArchiveOutputStream(s), o); } + @Deprecated + @Override public void putEntry(ArchiveOutputStream out, String path, FileMode mode, ObjectLoader loader) throws IOException { + putEntry(out, null, path, mode,loader); + } + + /** + * @since 4.7 + */ + @Override + public void putEntry(ArchiveOutputStream out, + ObjectId tree, String path, FileMode mode, ObjectLoader loader) + throws IOException { // ZipArchiveEntry detects directories by checking // for '/' at the end of the filename. if (path.endsWith("/") && mode != FileMode.TREE) //$NON-NLS-1$ @@ -92,6 +108,12 @@ public void putEntry(ArchiveOutputStream out, path = path + "/"; //$NON-NLS-1$ final ZipArchiveEntry entry = new ZipArchiveEntry(path); + + if (tree instanceof RevCommit) { + long t = ((RevCommit) tree).getCommitTime() * 1000L; + entry.setTime(t); + } + if (mode == FileMode.TREE) { out.putArchiveEntry(entry); out.closeArchiveEntry(); @@ -114,6 +136,7 @@ public void putEntry(ArchiveOutputStream out, out.closeArchiveEntry(); } + @Override public Iterable<String> suffixes() { return SUFFIXES; }
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 80cfbbb..4d260cf 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
@@ -56,7 +56,7 @@ org.eclipse.jdt.core.compiler.problem.missingJavadocTagsMethodTypeParameters=disabled org.eclipse.jdt.core.compiler.problem.missingJavadocTagsOverriding=disabled org.eclipse.jdt.core.compiler.problem.missingJavadocTagsVisibility=private -org.eclipse.jdt.core.compiler.problem.missingOverrideAnnotation=ignore +org.eclipse.jdt.core.compiler.problem.missingOverrideAnnotation=warning org.eclipse.jdt.core.compiler.problem.missingOverrideAnnotationForInterfaceMethodImplementation=enabled org.eclipse.jdt.core.compiler.problem.missingSerialVersion=warning org.eclipse.jdt.core.compiler.problem.missingSynchronizedOnInheritedMethod=ignore @@ -76,7 +76,7 @@ org.eclipse.jdt.core.compiler.problem.rawTypeReference=ignore org.eclipse.jdt.core.compiler.problem.redundantNullAnnotation=warning org.eclipse.jdt.core.compiler.problem.redundantNullCheck=warning -org.eclipse.jdt.core.compiler.problem.redundantSpecificationOfTypeArguments=ignore +org.eclipse.jdt.core.compiler.problem.redundantSpecificationOfTypeArguments=warning org.eclipse.jdt.core.compiler.problem.redundantSuperinterface=error org.eclipse.jdt.core.compiler.problem.reportMethodCanBePotentiallyStatic=ignore org.eclipse.jdt.core.compiler.problem.reportMethodCanBeStatic=ignore
diff --git a/org.eclipse.jgit.http.apache/BUCK b/org.eclipse.jgit.http.apache/BUCK deleted file mode 100644 index 3b7a823..0000000 --- a/org.eclipse.jgit.http.apache/BUCK +++ /dev/null
@@ -1,11 +0,0 @@ -java_library( - name = 'http-apache', - srcs = glob(['src/**']), - resources = glob(['resources/**']), - deps = [ - '//org.eclipse.jgit:jgit', - '//lib:httpcomponents', - '//lib:httpcore', - ], - visibility = ['PUBLIC'], -)
diff --git a/org.eclipse.jgit.http.apache/BUILD b/org.eclipse.jgit.http.apache/BUILD new file mode 100644 index 0000000..c1538ab --- /dev/null +++ b/org.eclipse.jgit.http.apache/BUILD
@@ -0,0 +1,13 @@ +package(default_visibility = ["//visibility:public"]) + +java_library( + name = "http-apache", + srcs = glob(["src/**"]), + resource_strip_prefix = "org.eclipse.jgit.http.apache/resources", + resources = glob(["resources/**"]), + deps = [ + "//lib:httpclient", + "//lib:httpcore", + "//org.eclipse.jgit:jgit", + ], +)
diff --git a/org.eclipse.jgit.http.apache/META-INF/MANIFEST.MF b/org.eclipse.jgit.http.apache/META-INF/MANIFEST.MF index 978be27..62883a9 100644 --- a/org.eclipse.jgit.http.apache/META-INF/MANIFEST.MF +++ b/org.eclipse.jgit.http.apache/META-INF/MANIFEST.MF
@@ -2,7 +2,7 @@ Bundle-ManifestVersion: 2 Bundle-Name: %Bundle-Name Bundle-SymbolicName: org.eclipse.jgit.http.apache -Bundle-Version: 4.6.2.qualifier +Bundle-Version: 4.7.6.qualifier Bundle-RequiredExecutionEnvironment: JavaSE-1.8 Bundle-Localization: plugin Bundle-Vendor: %Provider-Name @@ -20,13 +20,12 @@ org.apache.http.conn.ssl;version="[4.3.0,5.0.0)", org.apache.http.entity;version="[4.3.0,5.0.0)", org.apache.http.impl.client;version="[4.3.0,5.0.0)", - org.apache.http.impl.client.cache;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.nls;version="[4.6.2,4.7.0)", - org.eclipse.jgit.transport.http;version="[4.6.2,4.7.0)", - org.eclipse.jgit.util;version="[4.6.2,4.7.0)" -Export-Package: org.eclipse.jgit.transport.http.apache;version="4.6.2"; + org.eclipse.jgit.nls;version="[4.7.6,4.8.0)", + org.eclipse.jgit.transport.http;version="[4.7.6,4.8.0)", + org.eclipse.jgit.util;version="[4.7.6,4.8.0)" +Export-Package: org.eclipse.jgit.transport.http.apache;version="4.7.6"; uses:="org.apache.http.client, org.eclipse.jgit.transport.http, org.apache.http.entity,
diff --git a/org.eclipse.jgit.http.apache/pom.xml b/org.eclipse.jgit.http.apache/pom.xml index dfd8585..9c50de8 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>4.6.2-SNAPSHOT</version> + <version>4.7.6-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 281154f..945ecd5 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
@@ -223,15 +223,18 @@ public HttpClientConnection(String urlStr, Proxy proxy, HttpClient cl) this.proxy = proxy; } + @Override public int getResponseCode() throws IOException { execute(); return resp.getStatusLine().getStatusCode(); } + @Override public URL getURL() { return url; } + @Override public String getResponseMessage() throws IOException { execute(); return resp.getStatusLine().getReasonPhrase(); @@ -259,10 +262,11 @@ private void execute() throws IOException, ClientProtocolException { } } + @Override public Map<String, List<String>> getHeaderFields() { - Map<String, List<String>> ret = new HashMap<String, List<String>>(); + Map<String, List<String>> ret = new HashMap<>(); for (Header hdr : resp.getAllHeaders()) { - List<String> list = new LinkedList<String>(); + List<String> list = new LinkedList<>(); for (HeaderElement hdrElem : hdr.getElements()) list.add(hdrElem.toString()); ret.put(hdr.getName(), list); @@ -270,10 +274,12 @@ public Map<String, List<String>> getHeaderFields() { return ret; } + @Override public void setRequestProperty(String name, String value) { req.addHeader(name, value); } + @Override public void setRequestMethod(String method) throws ProtocolException { this.method = method; if (METHOD_GET.equalsIgnoreCase(method)) { @@ -290,18 +296,22 @@ public void setRequestMethod(String method) throws ProtocolException { } } + @Override public void setUseCaches(boolean usecaches) { // not needed } + @Override public void setConnectTimeout(int timeout) { this.timeout = Integer.valueOf(timeout); } + @Override public void setReadTimeout(int readTimeout) { this.readTimeout = Integer.valueOf(readTimeout); } + @Override public String getContentType() { HttpEntity responseEntity = resp.getEntity(); if (responseEntity != null) { @@ -312,16 +322,19 @@ public String getContentType() { return null; } + @Override public InputStream getInputStream() throws IOException { return resp.getEntity().getContent(); } // will return only the first field + @Override public String getHeaderField(String name) { Header header = resp.getFirstHeader(name); return (header == null) ? null : header.getValue(); } + @Override public int getContentLength() { Header contentLength = resp.getFirstHeader("content-length"); //$NON-NLS-1$ if (contentLength == null) { @@ -336,14 +349,17 @@ public int getContentLength() { } } + @Override public void setInstanceFollowRedirects(boolean followRedirects) { this.followRedirects = Boolean.valueOf(followRedirects); } + @Override public void setDoOutput(boolean dooutput) { // TODO: check whether we can really ignore this. } + @Override public void setFixedLengthStreamingMode(int contentLength) { if (entity != null) throw new IllegalArgumentException(); @@ -351,52 +367,63 @@ public void setFixedLengthStreamingMode(int contentLength) { entity.setContentLength(contentLength); } + @Override public OutputStream getOutputStream() throws IOException { if (entity == null) entity = new TemporaryBufferEntity(new LocalFile(null)); return entity.getBuffer(); } + @Override public void setChunkedStreamingMode(int chunklen) { if (entity == null) entity = new TemporaryBufferEntity(new LocalFile(null)); entity.setChunked(true); } + @Override public String getRequestMethod() { return method; } + @Override public boolean usingProxy() { return isUsingProxy; } + @Override public void connect() throws IOException { execute(); } + @Override public void setHostnameVerifier(final HostnameVerifier hostnameverifier) { this.hostnameverifier = new X509HostnameVerifier() { + @Override public boolean verify(String hostname, SSLSession session) { return hostnameverifier.verify(hostname, session); } + @Override public void verify(String host, String[] cns, String[] subjectAlts) throws SSLException { throw new UnsupportedOperationException(); // TODO message } + @Override public void verify(String host, X509Certificate cert) throws SSLException { throw new UnsupportedOperationException(); // TODO message } + @Override public void verify(String host, SSLSocket ssl) throws IOException { hostnameverifier.verify(host, ssl.getSession()); } }; } + @Override public void configure(KeyManager[] km, TrustManager[] tm, SecureRandom random) throws KeyManagementException { getSSLContext().init(km, tm, random);
diff --git a/org.eclipse.jgit.http.apache/src/org/eclipse/jgit/transport/http/apache/HttpClientConnectionFactory.java b/org.eclipse.jgit.http.apache/src/org/eclipse/jgit/transport/http/apache/HttpClientConnectionFactory.java index fe1eef4..f97d284 100644 --- a/org.eclipse.jgit.http.apache/src/org/eclipse/jgit/transport/http/apache/HttpClientConnectionFactory.java +++ b/org.eclipse.jgit.http.apache/src/org/eclipse/jgit/transport/http/apache/HttpClientConnectionFactory.java
@@ -55,10 +55,12 @@ * @since 3.3 */ public class HttpClientConnectionFactory implements HttpConnectionFactory { + @Override public HttpConnection create(URL url) throws IOException { return new HttpClientConnection(url.toString()); } + @Override public HttpConnection create(URL url, Proxy proxy) throws IOException { return new HttpClientConnection(url.toString(), proxy);
diff --git a/org.eclipse.jgit.http.apache/src/org/eclipse/jgit/transport/http/apache/TemporaryBufferEntity.java b/org.eclipse.jgit.http.apache/src/org/eclipse/jgit/transport/http/apache/TemporaryBufferEntity.java index 93328c9..3efff49 100644 --- a/org.eclipse.jgit.http.apache/src/org/eclipse/jgit/transport/http/apache/TemporaryBufferEntity.java +++ b/org.eclipse.jgit.http.apache/src/org/eclipse/jgit/transport/http/apache/TemporaryBufferEntity.java
@@ -78,25 +78,30 @@ public TemporaryBuffer getBuffer() { return buffer; } + @Override public boolean isRepeatable() { return true; } + @Override public long getContentLength() { if (contentLength != null) return contentLength.intValue(); return buffer.length(); } + @Override public InputStream getContent() throws IOException, IllegalStateException { return buffer.openInputStream(); } + @Override public void writeTo(OutputStream outstream) throws IOException { // TODO: dont we need a progressmonitor buffer.writeTo(outstream, null); } + @Override public boolean isStreaming() { return false; }
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 80cfbbb..4d260cf 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
@@ -56,7 +56,7 @@ org.eclipse.jdt.core.compiler.problem.missingJavadocTagsMethodTypeParameters=disabled org.eclipse.jdt.core.compiler.problem.missingJavadocTagsOverriding=disabled org.eclipse.jdt.core.compiler.problem.missingJavadocTagsVisibility=private -org.eclipse.jdt.core.compiler.problem.missingOverrideAnnotation=ignore +org.eclipse.jdt.core.compiler.problem.missingOverrideAnnotation=warning org.eclipse.jdt.core.compiler.problem.missingOverrideAnnotationForInterfaceMethodImplementation=enabled org.eclipse.jdt.core.compiler.problem.missingSerialVersion=warning org.eclipse.jdt.core.compiler.problem.missingSynchronizedOnInheritedMethod=ignore @@ -76,7 +76,7 @@ org.eclipse.jdt.core.compiler.problem.rawTypeReference=ignore org.eclipse.jdt.core.compiler.problem.redundantNullAnnotation=warning org.eclipse.jdt.core.compiler.problem.redundantNullCheck=warning -org.eclipse.jdt.core.compiler.problem.redundantSpecificationOfTypeArguments=ignore +org.eclipse.jdt.core.compiler.problem.redundantSpecificationOfTypeArguments=warning org.eclipse.jdt.core.compiler.problem.redundantSuperinterface=error org.eclipse.jdt.core.compiler.problem.reportMethodCanBePotentiallyStatic=ignore org.eclipse.jdt.core.compiler.problem.reportMethodCanBeStatic=ignore
diff --git a/org.eclipse.jgit.http.server/BUCK b/org.eclipse.jgit.http.server/BUCK deleted file mode 100644 index 3743557..0000000 --- a/org.eclipse.jgit.http.server/BUCK +++ /dev/null
@@ -1,10 +0,0 @@ -java_library( - name = 'jgit-servlet', - srcs = glob(['src/**']), - resources = glob(['resources/**']), - provided_deps = [ - '//org.eclipse.jgit:jgit', - '//lib:servlet-api', - ], - visibility = ['PUBLIC'], -)
diff --git a/org.eclipse.jgit.http.server/BUILD b/org.eclipse.jgit.http.server/BUILD new file mode 100644 index 0000000..876c5fa --- /dev/null +++ b/org.eclipse.jgit.http.server/BUILD
@@ -0,0 +1,13 @@ +package(default_visibility = ["//visibility:public"]) + +java_library( + name = "jgit-servlet", + srcs = glob(["src/**"]), + resource_strip_prefix = "org.eclipse.jgit.http.server/resources", + resources = glob(["resources/**"]), + deps = [ + "//lib:servlet-api", + # We want these deps to be provided_deps + "//org.eclipse.jgit:jgit", + ], +)
diff --git a/org.eclipse.jgit.http.server/META-INF/MANIFEST.MF b/org.eclipse.jgit.http.server/META-INF/MANIFEST.MF index be3bb33..20254a0 100644 --- a/org.eclipse.jgit.http.server/META-INF/MANIFEST.MF +++ b/org.eclipse.jgit.http.server/META-INF/MANIFEST.MF
@@ -2,13 +2,13 @@ Bundle-ManifestVersion: 2 Bundle-Name: %plugin_name Bundle-SymbolicName: org.eclipse.jgit.http.server -Bundle-Version: 4.6.2.qualifier +Bundle-Version: 4.7.6.qualifier Bundle-Localization: plugin Bundle-Vendor: %provider_name -Export-Package: org.eclipse.jgit.http.server;version="4.6.2", - org.eclipse.jgit.http.server.glue;version="4.6.2"; +Export-Package: org.eclipse.jgit.http.server;version="4.7.6", + org.eclipse.jgit.http.server.glue;version="4.7.6"; uses:="javax.servlet,javax.servlet.http", - org.eclipse.jgit.http.server.resolver;version="4.6.2"; + org.eclipse.jgit.http.server.resolver;version="4.7.6"; uses:="org.eclipse.jgit.transport.resolver, org.eclipse.jgit.lib, org.eclipse.jgit.transport, @@ -17,12 +17,12 @@ 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="[4.6.2,4.7.0)", - org.eclipse.jgit.internal.storage.dfs;version="[4.6.2,4.7.0)", - org.eclipse.jgit.internal.storage.file;version="[4.6.2,4.7.0)", - org.eclipse.jgit.lib;version="[4.6.2,4.7.0)", - org.eclipse.jgit.nls;version="[4.6.2,4.7.0)", - org.eclipse.jgit.revwalk;version="[4.6.2,4.7.0)", - org.eclipse.jgit.transport;version="[4.6.2,4.7.0)", - org.eclipse.jgit.transport.resolver;version="[4.6.2,4.7.0)", - org.eclipse.jgit.util;version="[4.6.2,4.7.0)" + org.eclipse.jgit.errors;version="[4.7.6,4.8.0)", + org.eclipse.jgit.internal.storage.dfs;version="[4.7.6,4.8.0)", + org.eclipse.jgit.internal.storage.file;version="[4.7.6,4.8.0)", + org.eclipse.jgit.lib;version="[4.7.6,4.8.0)", + org.eclipse.jgit.nls;version="[4.7.6,4.8.0)", + org.eclipse.jgit.revwalk;version="[4.7.6,4.8.0)", + org.eclipse.jgit.transport;version="[4.7.6,4.8.0)", + org.eclipse.jgit.transport.resolver;version="[4.7.6,4.8.0)", + org.eclipse.jgit.util;version="[4.7.6,4.8.0)"
diff --git a/org.eclipse.jgit.http.server/pom.xml b/org.eclipse.jgit.http.server/pom.xml index 843ec4b..1f71821 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>4.6.2-SNAPSHOT</version> + <version>4.7.6-SNAPSHOT</version> </parent> <artifactId>org.eclipse.jgit.http.server</artifactId>
diff --git a/org.eclipse.jgit.http.server/src/org/eclipse/jgit/http/server/AsIsFileFilter.java b/org.eclipse.jgit.http.server/src/org/eclipse/jgit/http/server/AsIsFileFilter.java index d33362b..05391eb 100644 --- a/org.eclipse.jgit.http.server/src/org/eclipse/jgit/http/server/AsIsFileFilter.java +++ b/org.eclipse.jgit.http.server/src/org/eclipse/jgit/http/server/AsIsFileFilter.java
@@ -70,14 +70,17 @@ class AsIsFileFilter implements Filter { this.asIs = getAnyFile; } + @Override public void init(FilterConfig config) throws ServletException { // Do nothing. } + @Override public void destroy() { // Do nothing. } + @Override public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { HttpServletRequest req = (HttpServletRequest) request;
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 529b839..8070371 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
@@ -95,9 +95,9 @@ public class GitFilter extends MetaFilter { private ReceivePackFactory<HttpServletRequest> receivePackFactory = new DefaultReceivePackFactory(); - private final List<Filter> uploadPackFilters = new LinkedList<Filter>(); + private final List<Filter> uploadPackFilters = new LinkedList<>(); - private final List<Filter> receivePackFilters = new LinkedList<Filter>(); + private final List<Filter> receivePackFilters = new LinkedList<>(); /** * New servlet that will load its base directory from {@code web.xml}.
diff --git a/org.eclipse.jgit.http.server/src/org/eclipse/jgit/http/server/GitServlet.java b/org.eclipse.jgit.http.server/src/org/eclipse/jgit/http/server/GitServlet.java index bca5210..3a5edee 100644 --- a/org.eclipse.jgit.http.server/src/org/eclipse/jgit/http/server/GitServlet.java +++ b/org.eclipse.jgit.http.server/src/org/eclipse/jgit/http/server/GitServlet.java
@@ -174,18 +174,22 @@ public void addReceivePackFilter(Filter filter) { @Override public void init(final ServletConfig config) throws ServletException { gitFilter.init(new FilterConfig() { + @Override public String getFilterName() { return gitFilter.getClass().getName(); } + @Override public String getInitParameter(String name) { return config.getInitParameter(name); } + @Override public Enumeration<String> getInitParameterNames() { return config.getInitParameterNames(); } + @Override public ServletContext getServletContext() { return config.getServletContext(); }
diff --git a/org.eclipse.jgit.http.server/src/org/eclipse/jgit/http/server/InfoPacksServlet.java b/org.eclipse.jgit.http.server/src/org/eclipse/jgit/http/server/InfoPacksServlet.java index bb6efb8..91c2f9f 100644 --- a/org.eclipse.jgit.http.server/src/org/eclipse/jgit/http/server/InfoPacksServlet.java +++ b/org.eclipse.jgit.http.server/src/org/eclipse/jgit/http/server/InfoPacksServlet.java
@@ -60,6 +60,7 @@ class InfoPacksServlet extends HttpServlet { private static final long serialVersionUID = 1L; + @Override public void doGet(final HttpServletRequest req, final HttpServletResponse rsp) throws IOException { sendPlainText(packList(req), req, rsp);
diff --git a/org.eclipse.jgit.http.server/src/org/eclipse/jgit/http/server/InfoRefsServlet.java b/org.eclipse.jgit.http.server/src/org/eclipse/jgit/http/server/InfoRefsServlet.java index 446f6a2..72c7136 100644 --- a/org.eclipse.jgit.http.server/src/org/eclipse/jgit/http/server/InfoRefsServlet.java +++ b/org.eclipse.jgit.http.server/src/org/eclipse/jgit/http/server/InfoRefsServlet.java
@@ -64,6 +64,7 @@ class InfoRefsServlet extends HttpServlet { private static final long serialVersionUID = 1L; + @Override public void doGet(final HttpServletRequest req, final HttpServletResponse rsp) throws IOException { // Assume a dumb client and send back the dumb client
diff --git a/org.eclipse.jgit.http.server/src/org/eclipse/jgit/http/server/IsLocalFilter.java b/org.eclipse.jgit.http.server/src/org/eclipse/jgit/http/server/IsLocalFilter.java index 511cdf1..223813f 100644 --- a/org.eclipse.jgit.http.server/src/org/eclipse/jgit/http/server/IsLocalFilter.java +++ b/org.eclipse.jgit.http.server/src/org/eclipse/jgit/http/server/IsLocalFilter.java
@@ -66,14 +66,17 @@ * downstream servlet can directly access its contents on disk. */ class IsLocalFilter implements Filter { + @Override public void init(FilterConfig config) throws ServletException { // Do nothing. } + @Override public void destroy() { // Do nothing. } + @Override public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { if (isLocal(getRepository(request)))
diff --git a/org.eclipse.jgit.http.server/src/org/eclipse/jgit/http/server/NoCacheFilter.java b/org.eclipse.jgit.http.server/src/org/eclipse/jgit/http/server/NoCacheFilter.java index 6a23cb9..bdc3420 100644 --- a/org.eclipse.jgit.http.server/src/org/eclipse/jgit/http/server/NoCacheFilter.java +++ b/org.eclipse.jgit.http.server/src/org/eclipse/jgit/http/server/NoCacheFilter.java
@@ -59,14 +59,17 @@ /** Adds HTTP response headers to prevent caching by proxies/browsers. */ class NoCacheFilter implements Filter { + @Override public void init(FilterConfig config) throws ServletException { // Do nothing. } + @Override public void destroy() { // Do nothing. } + @Override public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { HttpServletResponse rsp = (HttpServletResponse) response;
diff --git a/org.eclipse.jgit.http.server/src/org/eclipse/jgit/http/server/ReceivePackServlet.java b/org.eclipse.jgit.http.server/src/org/eclipse/jgit/http/server/ReceivePackServlet.java index c88670e..9d24bf7 100644 --- a/org.eclipse.jgit.http.server/src/org/eclipse/jgit/http/server/ReceivePackServlet.java +++ b/org.eclipse.jgit.http.server/src/org/eclipse/jgit/http/server/ReceivePackServlet.java
@@ -130,6 +130,7 @@ static class Factory implements Filter { this.receivePackFactory = receivePackFactory; } + @Override public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { HttpServletRequest req = (HttpServletRequest) request; @@ -153,10 +154,12 @@ public void doFilter(ServletRequest request, ServletResponse response, } } + @Override public void init(FilterConfig filterConfig) throws ServletException { // Nothing. } + @Override public void destroy() { // Nothing. }
diff --git a/org.eclipse.jgit.http.server/src/org/eclipse/jgit/http/server/RepositoryFilter.java b/org.eclipse.jgit.http.server/src/org/eclipse/jgit/http/server/RepositoryFilter.java index b3fad3d..de09c54 100644 --- a/org.eclipse.jgit.http.server/src/org/eclipse/jgit/http/server/RepositoryFilter.java +++ b/org.eclipse.jgit.http.server/src/org/eclipse/jgit/http/server/RepositoryFilter.java
@@ -100,14 +100,17 @@ public RepositoryFilter(final RepositoryResolver<HttpServletRequest> resolver) { this.resolver = resolver; } + @Override public void init(final FilterConfig config) throws ServletException { context = config.getServletContext(); } + @Override public void destroy() { context = null; } + @Override public void doFilter(final ServletRequest request, final ServletResponse response, final FilterChain chain) throws IOException, ServletException {
diff --git a/org.eclipse.jgit.http.server/src/org/eclipse/jgit/http/server/SmartOutputStream.java b/org.eclipse.jgit.http.server/src/org/eclipse/jgit/http/server/SmartOutputStream.java index 145c63b..08a5eba 100644 --- a/org.eclipse.jgit.http.server/src/org/eclipse/jgit/http/server/SmartOutputStream.java +++ b/org.eclipse.jgit.http.server/src/org/eclipse/jgit/http/server/SmartOutputStream.java
@@ -95,6 +95,7 @@ protected OutputStream overflow() throws IOException { return out; } + @Override public void close() throws IOException { super.close();
diff --git a/org.eclipse.jgit.http.server/src/org/eclipse/jgit/http/server/SmartServiceInfoRefs.java b/org.eclipse.jgit.http.server/src/org/eclipse/jgit/http/server/SmartServiceInfoRefs.java index a06bb1e..fe34f66 100644 --- a/org.eclipse.jgit.http.server/src/org/eclipse/jgit/http/server/SmartServiceInfoRefs.java +++ b/org.eclipse.jgit.http.server/src/org/eclipse/jgit/http/server/SmartServiceInfoRefs.java
@@ -80,14 +80,17 @@ abstract class SmartServiceInfoRefs implements Filter { this.filters = filters.toArray(new Filter[filters.size()]); } + @Override public void init(FilterConfig config) throws ServletException { // Do nothing. } + @Override public void destroy() { // Do nothing. } + @Override public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { final HttpServletRequest req = (HttpServletRequest) request; @@ -154,6 +157,7 @@ protected abstract void advertise(HttpServletRequest req, private class Chain implements FilterChain { private int filterIdx; + @Override public void doFilter(ServletRequest req, ServletResponse rsp) throws IOException, ServletException { if (filterIdx < filters.length)
diff --git a/org.eclipse.jgit.http.server/src/org/eclipse/jgit/http/server/TextFileServlet.java b/org.eclipse.jgit.http.server/src/org/eclipse/jgit/http/server/TextFileServlet.java index 650059b..28ee17d 100644 --- a/org.eclipse.jgit.http.server/src/org/eclipse/jgit/http/server/TextFileServlet.java +++ b/org.eclipse.jgit.http.server/src/org/eclipse/jgit/http/server/TextFileServlet.java
@@ -68,6 +68,7 @@ class TextFileServlet extends HttpServlet { this.fileName = name; } + @Override public void doGet(final HttpServletRequest req, final HttpServletResponse rsp) throws IOException { try {
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 a9a0c5b..97d00c1 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
@@ -129,6 +129,7 @@ static class Factory implements Filter { this.uploadPackFactory = uploadPackFactory; } + @Override public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { HttpServletRequest req = (HttpServletRequest) request; @@ -152,10 +153,12 @@ public void doFilter(ServletRequest request, ServletResponse response, } } + @Override public void init(FilterConfig filterConfig) throws ServletException { // Nothing. } + @Override public void destroy() { // Nothing. }
diff --git a/org.eclipse.jgit.http.server/src/org/eclipse/jgit/http/server/glue/MetaFilter.java b/org.eclipse.jgit.http.server/src/org/eclipse/jgit/http/server/glue/MetaFilter.java index 2187cfa..adb6c42 100644 --- a/org.eclipse.jgit.http.server/src/org/eclipse/jgit/http/server/glue/MetaFilter.java +++ b/org.eclipse.jgit.http.server/src/org/eclipse/jgit/http/server/glue/MetaFilter.java
@@ -89,7 +89,7 @@ public class MetaFilter implements Filter { /** Empty filter with no bindings. */ public MetaFilter() { - this.bindings = new ArrayList<ServletBinderImpl>(); + this.bindings = new ArrayList<>(); } /** @@ -128,10 +128,12 @@ public ServletBinder serveRegex(Pattern pattern) { return register(new RegexPipeline.Binder(pattern)); } + @Override public void init(FilterConfig filterConfig) throws ServletException { servletContext = filterConfig.getServletContext(); } + @Override public void destroy() { if (pipelines != null) { Set<Object> destroyed = newIdentitySet(); @@ -142,7 +144,7 @@ public void destroy() { } private static Set<Object> newIdentitySet() { - final Map<Object, Object> m = new IdentityHashMap<Object, Object>(); + final Map<Object, Object> m = new IdentityHashMap<>(); return new AbstractSet<Object>() { @Override public boolean add(Object o) { @@ -166,6 +168,7 @@ public int size() { }; } + @Override public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { HttpServletRequest req = (HttpServletRequest) request;
diff --git a/org.eclipse.jgit.http.server/src/org/eclipse/jgit/http/server/glue/MetaServlet.java b/org.eclipse.jgit.http.server/src/org/eclipse/jgit/http/server/glue/MetaServlet.java index 0506065..71365c8 100644 --- a/org.eclipse.jgit.http.server/src/org/eclipse/jgit/http/server/glue/MetaServlet.java +++ b/org.eclipse.jgit.http.server/src/org/eclipse/jgit/http/server/glue/MetaServlet.java
@@ -123,6 +123,7 @@ public void init(ServletConfig config) throws ServletException { filter.init(new NoParameterFilterConfig(name, ctx)); } + @Override public void destroy() { filter.destroy(); } @@ -131,6 +132,7 @@ public void destroy() { protected void service(HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException { filter.doFilter(req, res, new FilterChain() { + @Override public void doFilter(ServletRequest request, ServletResponse response) throws IOException, ServletException {
diff --git a/org.eclipse.jgit.http.server/src/org/eclipse/jgit/http/server/glue/NoParameterFilterConfig.java b/org.eclipse.jgit.http.server/src/org/eclipse/jgit/http/server/glue/NoParameterFilterConfig.java index 8dfcc4d..961f88e 100644 --- a/org.eclipse.jgit.http.server/src/org/eclipse/jgit/http/server/glue/NoParameterFilterConfig.java +++ b/org.eclipse.jgit.http.server/src/org/eclipse/jgit/http/server/glue/NoParameterFilterConfig.java
@@ -59,26 +59,32 @@ final class NoParameterFilterConfig implements FilterConfig { this.context = context; } + @Override public String getInitParameter(String name) { return null; } + @Override public Enumeration<String> getInitParameterNames() { return new Enumeration<String>() { + @Override public boolean hasMoreElements() { return false; } + @Override public String nextElement() { throw new NoSuchElementException(); } }; } + @Override public ServletContext getServletContext() { return context; } + @Override public String getFilterName() { return filterName; }
diff --git a/org.eclipse.jgit.http.server/src/org/eclipse/jgit/http/server/glue/RegexGroupFilter.java b/org.eclipse.jgit.http.server/src/org/eclipse/jgit/http/server/glue/RegexGroupFilter.java index 2414660..a402977 100644 --- a/org.eclipse.jgit.http.server/src/org/eclipse/jgit/http/server/glue/RegexGroupFilter.java +++ b/org.eclipse.jgit.http.server/src/org/eclipse/jgit/http/server/glue/RegexGroupFilter.java
@@ -79,14 +79,17 @@ public RegexGroupFilter(final int groupIdx) { this.groupIdx = groupIdx - 1; } + @Override public void init(FilterConfig config) throws ServletException { // Do nothing. } + @Override public void destroy() { // Do nothing. } + @Override public void doFilter(final ServletRequest request, final ServletResponse rsp, final FilterChain chain) throws IOException, ServletException {
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 2ef7136..f33243b 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
@@ -95,6 +95,7 @@ static class Binder extends ServletBinderImpl { pattern = p; } + @Override UrlPipeline create() { return new RegexPipeline(pattern, getFilters(), getServlet()); } @@ -108,6 +109,7 @@ UrlPipeline create() { this.pattern = pattern; } + @Override boolean match(final HttpServletRequest req) { final String pathInfo = req.getPathInfo(); return pathInfo != null && pattern.matcher(pathInfo).matches();
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 e96fc59..4e879a9 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
@@ -58,9 +58,10 @@ abstract class ServletBinderImpl implements ServletBinder { private HttpServlet httpServlet; ServletBinderImpl() { - this.filters = new ArrayList<Filter>(); + this.filters = new ArrayList<>(); } + @Override public ServletBinder through(Filter filter) { if (filter == null) throw new NullPointerException(HttpServerText.get().filterMustNotBeNull); @@ -68,6 +69,7 @@ public ServletBinder through(Filter filter) { return this; } + @Override public void with(HttpServlet servlet) { if (servlet == null) throw new NullPointerException(HttpServerText.get().servletMustNotBeNull);
diff --git a/org.eclipse.jgit.http.server/src/org/eclipse/jgit/http/server/glue/SuffixPipeline.java b/org.eclipse.jgit.http.server/src/org/eclipse/jgit/http/server/glue/SuffixPipeline.java index b942016..903de63 100644 --- a/org.eclipse.jgit.http.server/src/org/eclipse/jgit/http/server/glue/SuffixPipeline.java +++ b/org.eclipse.jgit.http.server/src/org/eclipse/jgit/http/server/glue/SuffixPipeline.java
@@ -71,6 +71,7 @@ static class Binder extends ServletBinderImpl { this.suffix = suffix; } + @Override UrlPipeline create() { return new SuffixPipeline(suffix, getFilters(), getServlet()); } @@ -87,6 +88,7 @@ UrlPipeline create() { this.suffixLen = suffix.length(); } + @Override boolean match(final HttpServletRequest req) { final String pathInfo = req.getPathInfo(); return pathInfo != null && pathInfo.endsWith(suffix);
diff --git a/org.eclipse.jgit.http.server/src/org/eclipse/jgit/http/server/glue/UrlPipeline.java b/org.eclipse.jgit.http.server/src/org/eclipse/jgit/http/server/glue/UrlPipeline.java index 2d0b844..56e4e22 100644 --- a/org.eclipse.jgit.http.server/src/org/eclipse/jgit/http/server/glue/UrlPipeline.java +++ b/org.eclipse.jgit.http.server/src/org/eclipse/jgit/http/server/glue/UrlPipeline.java
@@ -121,26 +121,32 @@ private static void initServlet(final HttpServlet ref, throws ServletException { if (!inited.contains(ref)) { ref.init(new ServletConfig() { + @Override public String getInitParameter(String name) { return null; } + @Override public Enumeration<String> getInitParameterNames() { return new Enumeration<String>() { + @Override public boolean hasMoreElements() { return false; } + @Override public String nextElement() { throw new NoSuchElementException(); } }; } + @Override public ServletContext getServletContext() { return context; } + @Override public String getServletName() { return ref.getClass().getName(); } @@ -229,6 +235,7 @@ private static class Chain implements FilterChain { this.servlet = servlet; } + @Override public void doFilter(ServletRequest req, ServletResponse rsp) throws IOException, ServletException { if (filterIdx < filters.length)
diff --git a/org.eclipse.jgit.http.server/src/org/eclipse/jgit/http/server/resolver/AsIsFileService.java b/org.eclipse.jgit.http.server/src/org/eclipse/jgit/http/server/resolver/AsIsFileService.java index 4ef2a7c..88ad472 100644 --- a/org.eclipse.jgit.http.server/src/org/eclipse/jgit/http/server/resolver/AsIsFileService.java +++ b/org.eclipse.jgit.http.server/src/org/eclipse/jgit/http/server/resolver/AsIsFileService.java
@@ -72,6 +72,7 @@ public void access(HttpServletRequest req, Repository db) }; private static final SectionParser<ServiceConfig> CONFIG = new SectionParser<ServiceConfig>() { + @Override public ServiceConfig parse(final Config cfg) { return new ServiceConfig(cfg); }
diff --git a/org.eclipse.jgit.http.server/src/org/eclipse/jgit/http/server/resolver/DefaultReceivePackFactory.java b/org.eclipse.jgit.http.server/src/org/eclipse/jgit/http/server/resolver/DefaultReceivePackFactory.java index 8c39b79..04e192b 100644 --- a/org.eclipse.jgit.http.server/src/org/eclipse/jgit/http/server/resolver/DefaultReceivePackFactory.java +++ b/org.eclipse.jgit.http.server/src/org/eclipse/jgit/http/server/resolver/DefaultReceivePackFactory.java
@@ -69,6 +69,7 @@ public class DefaultReceivePackFactory implements ReceivePackFactory<HttpServletRequest> { private static final SectionParser<ServiceConfig> CONFIG = new SectionParser<ServiceConfig>() { + @Override public ServiceConfig parse(final Config cfg) { return new ServiceConfig(cfg); } @@ -85,6 +86,7 @@ private static class ServiceConfig { } } + @Override public ReceivePack create(final HttpServletRequest req, final Repository db) throws ServiceNotEnabledException, ServiceNotAuthorizedException { final ServiceConfig cfg = db.getConfig().get(CONFIG);
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 34c069e..d01e2ef 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
@@ -62,6 +62,7 @@ public class DefaultUploadPackFactory implements UploadPackFactory<HttpServletRequest> { private static final SectionParser<ServiceConfig> CONFIG = new SectionParser<ServiceConfig>() { + @Override public ServiceConfig parse(final Config cfg) { return new ServiceConfig(cfg); } @@ -75,6 +76,7 @@ private static class ServiceConfig { } } + @Override public UploadPack create(final HttpServletRequest req, final Repository db) throws ServiceNotEnabledException, ServiceNotAuthorizedException { if (db.getConfig().get(CONFIG).enabled)
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 10c29d5..64f7498 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
@@ -56,7 +56,7 @@ org.eclipse.jdt.core.compiler.problem.missingJavadocTagsMethodTypeParameters=disabled org.eclipse.jdt.core.compiler.problem.missingJavadocTagsOverriding=disabled org.eclipse.jdt.core.compiler.problem.missingJavadocTagsVisibility=private -org.eclipse.jdt.core.compiler.problem.missingOverrideAnnotation=ignore +org.eclipse.jdt.core.compiler.problem.missingOverrideAnnotation=warning org.eclipse.jdt.core.compiler.problem.missingOverrideAnnotationForInterfaceMethodImplementation=enabled org.eclipse.jdt.core.compiler.problem.missingSerialVersion=warning org.eclipse.jdt.core.compiler.problem.missingSynchronizedOnInheritedMethod=ignore @@ -76,7 +76,7 @@ org.eclipse.jdt.core.compiler.problem.rawTypeReference=ignore org.eclipse.jdt.core.compiler.problem.redundantNullAnnotation=warning org.eclipse.jdt.core.compiler.problem.redundantNullCheck=warning -org.eclipse.jdt.core.compiler.problem.redundantSpecificationOfTypeArguments=ignore +org.eclipse.jdt.core.compiler.problem.redundantSpecificationOfTypeArguments=warning org.eclipse.jdt.core.compiler.problem.redundantSuperinterface=error org.eclipse.jdt.core.compiler.problem.reportMethodCanBePotentiallyStatic=ignore org.eclipse.jdt.core.compiler.problem.reportMethodCanBeStatic=ignore
diff --git a/org.eclipse.jgit.http.test/BUCK b/org.eclipse.jgit.http.test/BUCK deleted file mode 100644 index f5cd10e..0000000 --- a/org.eclipse.jgit.http.test/BUCK +++ /dev/null
@@ -1,41 +0,0 @@ -TESTS = glob(['tst/**/*.java']) - -for t in TESTS: - n = t[len('tst/'):len(t)-len('.java')].replace('/', '.') - java_test( - name = n, - labels = ['http'], - srcs = [t], - deps = [ - ':helpers', - '//org.eclipse.jgit:jgit', - '//org.eclipse.jgit.http.apache:http-apache', - '//org.eclipse.jgit.http.server:jgit-servlet', - '//org.eclipse.jgit.junit:junit', - '//org.eclipse.jgit.junit.http:junit-http', - '//lib:hamcrest-core', - '//lib:hamcrest-library', - '//lib:junit', - '//lib:servlet-api', - '//lib/jetty:http', - '//lib/jetty:io', - '//lib/jetty:server', - '//lib/jetty:servlet', - '//lib/jetty:security', - '//lib/jetty:util', - '//lib:commons-logging', - ], - vm_args = ['-Djava.io.tmpdir=buck-out'], - ) - -java_library( - name = 'helpers', - srcs = glob(['src/**/*.java']), - deps = [ - '//org.eclipse.jgit:jgit', - '//org.eclipse.jgit.http.server:jgit-servlet', - '//org.eclipse.jgit.junit:junit', - '//org.eclipse.jgit.junit.http:junit-http', - '//lib:junit', - ], -)
diff --git a/org.eclipse.jgit.http.test/BUILD b/org.eclipse.jgit.http.test/BUILD new file mode 100644 index 0000000..ce2d611 --- /dev/null +++ b/org.eclipse.jgit.http.test/BUILD
@@ -0,0 +1,42 @@ +load( + "@com_googlesource_gerrit_bazlets//tools:junit.bzl", + "junit_tests", +) + +junit_tests( + name = "http", + srcs = glob(["tst/**/*.java"]), + tags = ["http"], + deps = [ + ":helpers", + "//lib:commons-logging", + "//lib:jetty-http", + "//lib:jetty-io", + "//lib:jetty-security", + "//lib:jetty-server", + "//lib:jetty-servlet", + "//lib:jetty-util", + "//lib:junit", + "//lib:servlet-api", + "//lib:slf4j-api", + "//lib:slf4j-simple", + "//org.eclipse.jgit.http.apache:http-apache", + "//org.eclipse.jgit.http.server:jgit-servlet", + "//org.eclipse.jgit:jgit", + "//org.eclipse.jgit.junit.http:junit-http", + "//org.eclipse.jgit.junit:junit", + ], +) + +java_library( + name = "helpers", + testonly = 1, + srcs = glob(["src/**/*.java"]), + deps = [ + "//lib:junit", + "//org.eclipse.jgit.http.server:jgit-servlet", + "//org.eclipse.jgit:jgit", + "//org.eclipse.jgit.junit.http:junit-http", + "//org.eclipse.jgit.junit:junit", + ], +)
diff --git a/org.eclipse.jgit.http.test/META-INF/MANIFEST.MF b/org.eclipse.jgit.http.test/META-INF/MANIFEST.MF index 6effed6..5a739c4 100644 --- a/org.eclipse.jgit.http.test/META-INF/MANIFEST.MF +++ b/org.eclipse.jgit.http.test/META-INF/MANIFEST.MF
@@ -2,7 +2,7 @@ Bundle-ManifestVersion: 2 Bundle-Name: %plugin_name Bundle-SymbolicName: org.eclipse.jgit.http.test -Bundle-Version: 4.6.2.qualifier +Bundle-Version: 4.7.6.qualifier Bundle-Vendor: %provider_name Bundle-Localization: plugin Bundle-RequiredExecutionEnvironment: JavaSE-1.8 @@ -22,24 +22,24 @@ org.eclipse.jetty.util.log;version="[9.0.0,9.4.0)", org.eclipse.jetty.util.security;version="[9.0.0,9.4.0)", org.eclipse.jetty.util.thread;version="[9.0.0,9.4.0)", - org.eclipse.jgit.errors;version="[4.6.2,4.7.0)", - org.eclipse.jgit.http.server;version="[4.6.2,4.7.0)", - org.eclipse.jgit.http.server.glue;version="[4.6.2,4.7.0)", - org.eclipse.jgit.http.server.resolver;version="[4.6.2,4.7.0)", - org.eclipse.jgit.internal;version="[4.6.2,4.7.0)", - org.eclipse.jgit.internal.storage.dfs;version="[4.6.2,4.7.0)", - org.eclipse.jgit.internal.storage.file;version="[4.6.2,4.7.0)", - org.eclipse.jgit.junit;version="[4.6.2,4.7.0)", - org.eclipse.jgit.junit.http;version="[4.6.2,4.7.0)", - org.eclipse.jgit.lib;version="[4.6.2,4.7.0)", - org.eclipse.jgit.nls;version="[4.6.2,4.7.0)", - org.eclipse.jgit.revwalk;version="[4.6.2,4.7.0)", - org.eclipse.jgit.storage.file;version="[4.6.2,4.7.0)", - org.eclipse.jgit.transport;version="[4.6.2,4.7.0)", - org.eclipse.jgit.transport.http;version="[4.6.2,4.7.0)", - org.eclipse.jgit.transport.http.apache;version="[4.6.2,4.7.0)", - org.eclipse.jgit.transport.resolver;version="[4.6.2,4.7.0)", - org.eclipse.jgit.util;version="[4.6.2,4.7.0)", + org.eclipse.jgit.errors;version="[4.7.6,4.8.0)", + org.eclipse.jgit.http.server;version="[4.7.6,4.8.0)", + org.eclipse.jgit.http.server.glue;version="[4.7.6,4.8.0)", + org.eclipse.jgit.http.server.resolver;version="[4.7.6,4.8.0)", + org.eclipse.jgit.internal;version="[4.7.6,4.8.0)", + org.eclipse.jgit.internal.storage.dfs;version="[4.7.6,4.8.0)", + org.eclipse.jgit.internal.storage.file;version="[4.7.6,4.8.0)", + org.eclipse.jgit.junit;version="[4.7.6,4.8.0)", + org.eclipse.jgit.junit.http;version="[4.7.6,4.8.0)", + org.eclipse.jgit.lib;version="[4.7.6,4.8.0)", + org.eclipse.jgit.nls;version="[4.7.6,4.8.0)", + org.eclipse.jgit.revwalk;version="[4.7.6,4.8.0)", + org.eclipse.jgit.storage.file;version="[4.7.6,4.8.0)", + org.eclipse.jgit.transport;version="[4.7.6,4.8.0)", + org.eclipse.jgit.transport.http;version="[4.7.6,4.8.0)", + org.eclipse.jgit.transport.http.apache;version="[4.7.6,4.8.0)", + org.eclipse.jgit.transport.resolver;version="[4.7.6,4.8.0)", + org.eclipse.jgit.util;version="[4.7.6,4.8.0)", org.hamcrest.core;version="[1.1.0,2.0.0)", org.junit;version="[4.0.0,5.0.0)", org.junit.runner;version="[4.0.0,5.0.0)",
diff --git a/org.eclipse.jgit.http.test/pom.xml b/org.eclipse.jgit.http.test/pom.xml index 0366f75..4d69cd6 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>4.6.2-SNAPSHOT</version> + <version>4.7.6-SNAPSHOT</version> </parent> <artifactId>org.eclipse.jgit.http.test</artifactId>
diff --git a/org.eclipse.jgit.http.test/tst/org/eclipse/jgit/http/test/AdvertiseErrorTest.java b/org.eclipse.jgit.http.test/tst/org/eclipse/jgit/http/test/AdvertiseErrorTest.java index 0285bd1..0e92b14 100644 --- a/org.eclipse.jgit.http.test/tst/org/eclipse/jgit/http/test/AdvertiseErrorTest.java +++ b/org.eclipse.jgit.http.test/tst/org/eclipse/jgit/http/test/AdvertiseErrorTest.java
@@ -80,6 +80,7 @@ public class AdvertiseErrorTest extends HttpTestCase { private URIish remoteURI; + @Override @Before public void setUp() throws Exception { super.setUp(); @@ -90,6 +91,7 @@ public void setUp() throws Exception { ServletContextHandler app = server.addContext("/git"); GitServlet gs = new GitServlet(); gs.setRepositoryResolver(new RepositoryResolver<HttpServletRequest>() { + @Override public Repository open(HttpServletRequest req, String name) throws RepositoryNotFoundException, ServiceNotEnabledException { @@ -102,6 +104,7 @@ public Repository open(HttpServletRequest req, String name) } }); gs.setReceivePackFactory(new DefaultReceivePackFactory() { + @Override public ReceivePack create(HttpServletRequest req, Repository db) throws ServiceNotEnabledException, ServiceNotAuthorizedException {
diff --git a/org.eclipse.jgit.http.test/tst/org/eclipse/jgit/http/test/AsIsServiceTest.java b/org.eclipse.jgit.http.test/tst/org/eclipse/jgit/http/test/AsIsServiceTest.java index c6b8f09..e94a792 100644 --- a/org.eclipse.jgit.http.test/tst/org/eclipse/jgit/http/test/AsIsServiceTest.java +++ b/org.eclipse.jgit.http.test/tst/org/eclipse/jgit/http/test/AsIsServiceTest.java
@@ -64,6 +64,7 @@ public class AsIsServiceTest extends LocalDiskRepositoryTestCase { private AsIsFileService service; + @Override @Before public void setUp() throws Exception { super.setUp();
diff --git a/org.eclipse.jgit.http.test/tst/org/eclipse/jgit/http/test/DefaultReceivePackFactoryTest.java b/org.eclipse.jgit.http.test/tst/org/eclipse/jgit/http/test/DefaultReceivePackFactoryTest.java index f2879e0..b24e2df 100644 --- a/org.eclipse.jgit.http.test/tst/org/eclipse/jgit/http/test/DefaultReceivePackFactoryTest.java +++ b/org.eclipse.jgit.http.test/tst/org/eclipse/jgit/http/test/DefaultReceivePackFactoryTest.java
@@ -71,6 +71,7 @@ public class DefaultReceivePackFactoryTest extends LocalDiskRepositoryTestCase { private ReceivePackFactory<HttpServletRequest> factory; + @Override @Before public void setUp() throws Exception { super.setUp();
diff --git a/org.eclipse.jgit.http.test/tst/org/eclipse/jgit/http/test/DefaultUploadPackFactoryTest.java b/org.eclipse.jgit.http.test/tst/org/eclipse/jgit/http/test/DefaultUploadPackFactoryTest.java index 3bcb057..ce24d64 100644 --- a/org.eclipse.jgit.http.test/tst/org/eclipse/jgit/http/test/DefaultUploadPackFactoryTest.java +++ b/org.eclipse.jgit.http.test/tst/org/eclipse/jgit/http/test/DefaultUploadPackFactoryTest.java
@@ -69,6 +69,7 @@ public class DefaultUploadPackFactoryTest extends LocalDiskRepositoryTestCase { private UploadPackFactory<HttpServletRequest> factory; + @Override @Before public void setUp() throws Exception { super.setUp();
diff --git a/org.eclipse.jgit.http.test/tst/org/eclipse/jgit/http/test/DumbClientDumbServerTest.java b/org.eclipse.jgit.http.test/tst/org/eclipse/jgit/http/test/DumbClientDumbServerTest.java index 677132d..ab6dc35 100644 --- a/org.eclipse.jgit.http.test/tst/org/eclipse/jgit/http/test/DumbClientDumbServerTest.java +++ b/org.eclipse.jgit.http.test/tst/org/eclipse/jgit/http/test/DumbClientDumbServerTest.java
@@ -109,6 +109,7 @@ public DumbClientDumbServerTest(HttpConnectionFactory cf) { HttpTransport.setConnectionFactory(cf); } + @Override @Before public void setUp() throws Exception { super.setUp(); @@ -212,7 +213,7 @@ public void testInitialClone_Loose() throws Exception { @Test public void testInitialClone_Packed() throws Exception { - new TestRepository<Repository>(remoteRepository).packAndPrune(); + new TestRepository<>(remoteRepository).packAndPrune(); Repository dst = createBareRepository(); assertFalse(dst.hasObject(A_txt));
diff --git a/org.eclipse.jgit.http.test/tst/org/eclipse/jgit/http/test/DumbClientSmartServerTest.java b/org.eclipse.jgit.http.test/tst/org/eclipse/jgit/http/test/DumbClientSmartServerTest.java index bce44f9..06bfd79 100644 --- a/org.eclipse.jgit.http.test/tst/org/eclipse/jgit/http/test/DumbClientSmartServerTest.java +++ b/org.eclipse.jgit.http.test/tst/org/eclipse/jgit/http/test/DumbClientSmartServerTest.java
@@ -114,6 +114,7 @@ public DumbClientSmartServerTest(HttpConnectionFactory cf) { HttpTransport.setConnectionFactory(cf); } + @Override @Before public void setUp() throws Exception { super.setUp(); @@ -124,6 +125,7 @@ public void setUp() throws Exception { ServletContextHandler app = server.addContext("/git"); GitServlet gs = new GitServlet(); gs.setRepositoryResolver(new RepositoryResolver<HttpServletRequest>() { + @Override public Repository open(HttpServletRequest req, String name) throws RepositoryNotFoundException, ServiceNotEnabledException { @@ -239,7 +241,7 @@ public void testInitialClone_Small() throws Exception { @Test public void testInitialClone_Packed() throws Exception { - new TestRepository<Repository>(remoteRepository).packAndPrune(); + new TestRepository<>(remoteRepository).packAndPrune(); Repository dst = createBareRepository(); assertFalse(dst.hasObject(A_txt));
diff --git a/org.eclipse.jgit.http.test/tst/org/eclipse/jgit/http/test/FileResolverTest.java b/org.eclipse.jgit.http.test/tst/org/eclipse/jgit/http/test/FileResolverTest.java index 7c6d591..82e79b8 100644 --- a/org.eclipse.jgit.http.test/tst/org/eclipse/jgit/http/test/FileResolverTest.java +++ b/org.eclipse.jgit.http.test/tst/org/eclipse/jgit/http/test/FileResolverTest.java
@@ -83,7 +83,7 @@ public void testUnreasonableNames() throws ServiceNotEnabledException { private static void assertUnreasonable(String name) throws ServiceNotEnabledException { - FileResolver<RepositoryResolver> r = new FileResolver<RepositoryResolver>( + FileResolver<RepositoryResolver> r = new FileResolver<>( new File("."), false); try { r.open(null, name); @@ -103,7 +103,7 @@ public void testExportOk() throws IOException { FileResolver<RepositoryResolver> resolver; assertFalse("no git-daemon-export-ok", export.exists()); - resolver = new FileResolver<RepositoryResolver>(base, false /* + resolver = new FileResolver<>(base, false /* * require * flag */); @@ -114,7 +114,7 @@ public void testExportOk() throws IOException { assertEquals("Service not enabled", e.getMessage()); } - resolver = new FileResolver<RepositoryResolver>(base, true /* + resolver = new FileResolver<>(base, true /* * export * all */); @@ -125,7 +125,7 @@ public void testExportOk() throws IOException { } FileUtils.createNewFile(export); - resolver = new FileResolver<RepositoryResolver>(base, false /* + resolver = new FileResolver<>(base, false /* * require * flag */); @@ -142,7 +142,7 @@ public void testNotAGitRepository() throws IOException, final Repository a = createBareRepository(); final String name = a.getDirectory().getName() + "-not-a-git"; final File base = a.getDirectory().getParentFile(); - FileResolver<RepositoryResolver> resolver = new FileResolver<RepositoryResolver>( + FileResolver<RepositoryResolver> resolver = new FileResolver<>( base, false); try {
diff --git a/org.eclipse.jgit.http.test/tst/org/eclipse/jgit/http/test/GitServletResponseTests.java b/org.eclipse.jgit.http.test/tst/org/eclipse/jgit/http/test/GitServletResponseTests.java index 4b15d4b..de7891c 100644 --- a/org.eclipse.jgit.http.test/tst/org/eclipse/jgit/http/test/GitServletResponseTests.java +++ b/org.eclipse.jgit.http.test/tst/org/eclipse/jgit/http/test/GitServletResponseTests.java
@@ -107,6 +107,7 @@ public class GitServletResponseTests extends HttpTestCase { * configure the maximum pack file size, the object checker and custom hooks * just before they talk to the server. */ + @Override @Before public void setUp() throws Exception { super.setUp(); @@ -117,6 +118,7 @@ public void setUp() throws Exception { ServletContextHandler app = server.addContext("/git"); gs = new GitServlet(); gs.setRepositoryResolver(new RepositoryResolver<HttpServletRequest>() { + @Override public Repository open(HttpServletRequest req, String name) throws RepositoryNotFoundException, ServiceNotEnabledException { @@ -129,6 +131,7 @@ public Repository open(HttpServletRequest req, String name) } }); gs.setReceivePackFactory(new DefaultReceivePackFactory() { + @Override public ReceivePack create(HttpServletRequest req, Repository db) throws ServiceNotEnabledException, ServiceNotAuthorizedException { @@ -266,10 +269,11 @@ public void testUnpackErrorWithSubsequentExceptionInPostReceiveHook() Transport t; // this maxPackSize leads to an unPackError - maxPackSize = 400; + maxPackSize = 100; // this PostReceiveHook when called after an unsuccesfull unpack will // lead to an IllegalStateException postHook = new PostReceiveHook() { + @Override public void onPostReceive(ReceivePack rp, Collection<ReceiveCommand> commands) { // the maxPackSize setting caused that the packfile couldn't be
diff --git a/org.eclipse.jgit.http.test/tst/org/eclipse/jgit/http/test/HookMessageTest.java b/org.eclipse.jgit.http.test/tst/org/eclipse/jgit/http/test/HookMessageTest.java index d67c817..adb69ec 100644 --- a/org.eclipse.jgit.http.test/tst/org/eclipse/jgit/http/test/HookMessageTest.java +++ b/org.eclipse.jgit.http.test/tst/org/eclipse/jgit/http/test/HookMessageTest.java
@@ -88,6 +88,7 @@ public class HookMessageTest extends HttpTestCase { private URIish remoteURI; + @Override @Before public void setUp() throws Exception { super.setUp(); @@ -98,6 +99,7 @@ public void setUp() throws Exception { ServletContextHandler app = server.addContext("/git"); GitServlet gs = new GitServlet(); gs.setRepositoryResolver(new RepositoryResolver<HttpServletRequest>() { + @Override public Repository open(HttpServletRequest req, String name) throws RepositoryNotFoundException, ServiceNotEnabledException { @@ -110,11 +112,13 @@ public Repository open(HttpServletRequest req, String name) } }); gs.setReceivePackFactory(new DefaultReceivePackFactory() { + @Override public ReceivePack create(HttpServletRequest req, Repository db) throws ServiceNotEnabledException, ServiceNotAuthorizedException { ReceivePack recv = super.create(req, db); recv.setPreReceiveHook(new PreReceiveHook() { + @Override public void onPreReceive(ReceivePack rp, Collection<ReceiveCommand> commands) { rp.sendMessage("message line 1");
diff --git a/org.eclipse.jgit.http.test/tst/org/eclipse/jgit/http/test/HttpClientTests.java b/org.eclipse.jgit.http.test/tst/org/eclipse/jgit/http/test/HttpClientTests.java index ce78442..6dbe0e3 100644 --- a/org.eclipse.jgit.http.test/tst/org/eclipse/jgit/http/test/HttpClientTests.java +++ b/org.eclipse.jgit.http.test/tst/org/eclipse/jgit/http/test/HttpClientTests.java
@@ -94,6 +94,7 @@ public class HttpClientTests extends HttpTestCase { private URIish smartAuthBasicURI; + @Override @Before public void setUp() throws Exception { super.setUp(); @@ -132,6 +133,7 @@ private ServletContextHandler dumb(final String path) { private ServletContextHandler smart(final String path) { GitServlet gs = new GitServlet(); gs.setRepositoryResolver(new RepositoryResolver<HttpServletRequest>() { + @Override public Repository open(HttpServletRequest req, String name) throws RepositoryNotFoundException, ServiceNotEnabledException {
diff --git a/org.eclipse.jgit.http.test/tst/org/eclipse/jgit/http/test/MeasurePackSizeTest.java b/org.eclipse.jgit.http.test/tst/org/eclipse/jgit/http/test/MeasurePackSizeTest.java index 108e7bb..4c08ec2 100644 --- a/org.eclipse.jgit.http.test/tst/org/eclipse/jgit/http/test/MeasurePackSizeTest.java +++ b/org.eclipse.jgit.http.test/tst/org/eclipse/jgit/http/test/MeasurePackSizeTest.java
@@ -83,6 +83,7 @@ public class MeasurePackSizeTest extends HttpTestCase { long packSize = -1; + @Override @Before public void setUp() throws Exception { super.setUp(); @@ -93,6 +94,7 @@ public void setUp() throws Exception { ServletContextHandler app = server.addContext("/git"); GitServlet gs = new GitServlet(); gs.setRepositoryResolver(new RepositoryResolver<HttpServletRequest>() { + @Override public Repository open(HttpServletRequest req, String name) throws RepositoryNotFoundException, ServiceNotEnabledException { @@ -105,12 +107,14 @@ public Repository open(HttpServletRequest req, String name) } }); gs.setReceivePackFactory(new DefaultReceivePackFactory() { + @Override public ReceivePack create(HttpServletRequest req, Repository db) throws ServiceNotEnabledException, ServiceNotAuthorizedException { ReceivePack recv = super.create(req, db); recv.setPostReceiveHook(new PostReceiveHook() { + @Override public void onPostReceive(ReceivePack rp, Collection<ReceiveCommand> commands) { packSize = rp.getPackSize();
diff --git a/org.eclipse.jgit.http.test/tst/org/eclipse/jgit/http/test/ProtocolErrorTest.java b/org.eclipse.jgit.http.test/tst/org/eclipse/jgit/http/test/ProtocolErrorTest.java index 68c5a3a..87d0bad 100644 --- a/org.eclipse.jgit.http.test/tst/org/eclipse/jgit/http/test/ProtocolErrorTest.java +++ b/org.eclipse.jgit.http.test/tst/org/eclipse/jgit/http/test/ProtocolErrorTest.java
@@ -84,6 +84,7 @@ public class ProtocolErrorTest extends HttpTestCase { private RevBlob a_blob; + @Override @Before public void setUp() throws Exception { super.setUp(); @@ -94,6 +95,7 @@ public void setUp() throws Exception { ServletContextHandler app = server.addContext("/git"); GitServlet gs = new GitServlet(); gs.setRepositoryResolver(new RepositoryResolver<HttpServletRequest>() { + @Override public Repository open(HttpServletRequest req, String name) throws RepositoryNotFoundException, ServiceNotEnabledException {
diff --git a/org.eclipse.jgit.http.test/tst/org/eclipse/jgit/http/test/RegexPipelineTest.java b/org.eclipse.jgit.http.test/tst/org/eclipse/jgit/http/test/RegexPipelineTest.java index 64fbc01..725a590 100644 --- a/org.eclipse.jgit.http.test/tst/org/eclipse/jgit/http/test/RegexPipelineTest.java +++ b/org.eclipse.jgit.http.test/tst/org/eclipse/jgit/http/test/RegexPipelineTest.java
@@ -93,12 +93,14 @@ protected void doGet(HttpServletRequest req, HttpServletResponse res) } } + @Override @Before public void setUp() throws Exception { server = new AppServer(); ctx = server.addContext("/"); } + @Override @After public void tearDown() throws Exception { server.tearDown();
diff --git a/org.eclipse.jgit.http.test/tst/org/eclipse/jgit/http/test/SetAdditionalHeadersTest.java b/org.eclipse.jgit.http.test/tst/org/eclipse/jgit/http/test/SetAdditionalHeadersTest.java index 5be7834..ef8daec 100644 --- a/org.eclipse.jgit.http.test/tst/org/eclipse/jgit/http/test/SetAdditionalHeadersTest.java +++ b/org.eclipse.jgit.http.test/tst/org/eclipse/jgit/http/test/SetAdditionalHeadersTest.java
@@ -77,6 +77,7 @@ public class SetAdditionalHeadersTest extends HttpTestCase { private RevCommit A, B; + @Override @Before public void setUp() throws Exception { super.setUp(); @@ -111,7 +112,7 @@ public void testSetHeaders() throws IOException { assertTrue("isa TransportHttp", t instanceof TransportHttp); assertTrue("isa HttpTransport", t instanceof HttpTransport); - HashMap<String, String> headers = new HashMap<String, String>(); + HashMap<String, String> headers = new HashMap<>(); headers.put("Cookie", "someTokenValue=23gBog34"); headers.put("AnotherKey", "someValue"); ((TransportHttp) t).setAdditionalHeaders(headers);
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 3e88271..ed223c9 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
@@ -112,6 +112,7 @@ import org.eclipse.jgit.transport.http.apache.HttpClientConnectionFactory; import org.eclipse.jgit.transport.resolver.RepositoryResolver; import org.eclipse.jgit.transport.resolver.ServiceNotEnabledException; +import org.eclipse.jgit.util.HttpSupport; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; @@ -128,6 +129,8 @@ public class SmartClientSmartServerTest extends HttpTestCase { private URIish brokenURI; + private URIish redirectURI; + private RevBlob A_txt; private RevCommit A, B; @@ -144,6 +147,7 @@ public SmartClientSmartServerTest(HttpConnectionFactory cf) { HttpTransport.setConnectionFactory(cf); } + @Override @Before public void setUp() throws Exception { super.setUp(); @@ -155,13 +159,42 @@ public void setUp() throws Exception { .setBoolean(ConfigConstants.CONFIG_CORE_SECTION, null, ConfigConstants.CONFIG_KEY_LOGALLREFUPDATES, true); - ServletContextHandler app = server.addContext("/git"); GitServlet gs = new GitServlet(); + + ServletContextHandler app = addNormalContext(gs, src, srcName); + + ServletContextHandler broken = addBrokenContext(gs, src, srcName); + + ServletContextHandler redirect = addRedirectContext(gs, src, srcName); + + server.setUp(); + + remoteRepository = src.getRepository(); + remoteURI = toURIish(app, srcName); + brokenURI = toURIish(broken, srcName); + redirectURI = toURIish(redirect, srcName); + + A_txt = src.blob("A"); + A = src.commit().add("A_txt", A_txt).create(); + B = src.commit().parent(A).add("A_txt", "C").add("B", "B").create(); + src.update(master, B); + + src.update("refs/garbage/a/very/long/ref/name/to/compress", B); + } + + private ServletContextHandler addNormalContext(GitServlet gs, TestRepository<Repository> src, String srcName) { + ServletContextHandler app = server.addContext("/git"); gs.setRepositoryResolver(new TestRepoResolver(src, srcName)); app.addServlet(new ServletHolder(gs), "/*"); + return app; + } + @SuppressWarnings("unused") + private ServletContextHandler addBrokenContext(GitServlet gs, TestRepository<Repository> src, String srcName) { ServletContextHandler broken = server.addContext("/bad"); broken.addFilter(new FilterHolder(new Filter() { + + @Override public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { @@ -173,29 +206,58 @@ public void doFilter(ServletRequest request, w.close(); } - public void init(FilterConfig filterConfig) throws ServletException { - // + @Override + public void init(FilterConfig filterConfig) + throws ServletException { + // empty } + @Override public void destroy() { - // + // empty } }), "/" + srcName + "/git-upload-pack", EnumSet.of(DispatcherType.REQUEST)); broken.addServlet(new ServletHolder(gs), "/*"); + return broken; + } - server.setUp(); + @SuppressWarnings("unused") + private ServletContextHandler addRedirectContext(GitServlet gs, + TestRepository<Repository> src, String srcName) { + ServletContextHandler redirect = server.addContext("/redirect"); + redirect.addFilter(new FilterHolder(new Filter() { - remoteRepository = src.getRepository(); - remoteURI = toURIish(app, srcName); - brokenURI = toURIish(broken, srcName); + @Override + public void init(FilterConfig filterConfig) + throws ServletException { + // empty + } - A_txt = src.blob("A"); - A = src.commit().add("A_txt", A_txt).create(); - B = src.commit().parent(A).add("A_txt", "C").add("B", "B").create(); - src.update(master, B); + @Override + public void doFilter(ServletRequest request, + ServletResponse response, FilterChain chain) + throws IOException, ServletException { + final HttpServletResponse httpServletResponse = (HttpServletResponse) response; + final HttpServletRequest httpServletRequest = (HttpServletRequest) request; + final StringBuffer fullUrl = httpServletRequest.getRequestURL(); + if (httpServletRequest.getQueryString() != null) { + fullUrl.append("?") + .append(httpServletRequest.getQueryString()); + } + httpServletResponse + .setStatus(HttpServletResponse.SC_MOVED_PERMANENTLY); + httpServletResponse.setHeader(HttpSupport.HDR_LOCATION, + fullUrl.toString().replace("/redirect", "/git")); + } - src.update("refs/garbage/a/very/long/ref/name/to/compress", B); + @Override + public void destroy() { + // empty + } + }), "/*", EnumSet.of(DispatcherType.REQUEST)); + redirect.addServlet(new ServletHolder(gs), "/*"); + return redirect; } @Test @@ -312,6 +374,52 @@ public void testInitialClone_Small() throws Exception { } @Test + public void testInitialClone_RedirectSmall() throws Exception { + Repository dst = createBareRepository(); + assertFalse(dst.hasObject(A_txt)); + + try (Transport t = Transport.open(dst, redirectURI)) { + t.fetch(NullProgressMonitor.INSTANCE, mirror(master)); + } + + assertTrue(dst.hasObject(A_txt)); + assertEquals(B, dst.exactRef(master).getObjectId()); + fsck(dst, B); + + List<AccessEvent> requests = getRequests(); + assertEquals(4, requests.size()); + + AccessEvent firstRedirect = requests.get(0); + assertEquals(301, firstRedirect.getStatus()); + + AccessEvent info = requests.get(1); + assertEquals("GET", info.getMethod()); + assertEquals(join(remoteURI, "info/refs"), info.getPath()); + assertEquals(1, info.getParameters().size()); + assertEquals("git-upload-pack", info.getParameter("service")); + assertEquals(200, info.getStatus()); + assertEquals("application/x-git-upload-pack-advertisement", + info.getResponseHeader(HDR_CONTENT_TYPE)); + assertEquals("gzip", info.getResponseHeader(HDR_CONTENT_ENCODING)); + + AccessEvent secondRedirect = requests.get(2); + assertEquals(301, secondRedirect.getStatus()); + + AccessEvent service = requests.get(3); + assertEquals("POST", service.getMethod()); + assertEquals(join(remoteURI, "git-upload-pack"), service.getPath()); + assertEquals(0, service.getParameters().size()); + assertNotNull("has content-length", + service.getRequestHeader(HDR_CONTENT_LENGTH)); + assertNull("not chunked", + service.getRequestHeader(HDR_TRANSFER_ENCODING)); + + assertEquals(200, service.getStatus()); + assertEquals("application/x-git-upload-pack-result", + service.getResponseHeader(HDR_CONTENT_TYPE)); + } + + @Test public void testFetch_FewLocalCommits() throws Exception { // Bootstrap by doing the clone. // @@ -329,7 +437,7 @@ public void testFetch_FewLocalCommits() throws Exception { // Create a new commit on the remote. // - b = new TestRepository<Repository>(remoteRepository).branch(master); + b = new TestRepository<>(remoteRepository).branch(master); RevCommit Z = b.commit().message("Z").create(); // Now incrementally update. @@ -389,7 +497,7 @@ public void testFetch_TooManyLocalCommits() throws Exception { // Create a new commit on the remote. // - b = new TestRepository<Repository>(remoteRepository).branch(master); + b = new TestRepository<>(remoteRepository).branch(master); RevCommit Z = b.commit().message("Z").create(); // Now incrementally update. @@ -506,7 +614,7 @@ public void testFetch_RefsUnreadableOnUpload() throws Exception { final String repoName = "refs-unreadable"; RefsUnreadableInMemoryRepository badRefsRepo = new RefsUnreadableInMemoryRepository( new DfsRepositoryDescription(repoName)); - final TestRepository<Repository> repo = new TestRepository<Repository>( + final TestRepository<Repository> repo = new TestRepository<>( badRefsRepo); ServletContextHandler app = noRefServer.addContext("/git"); @@ -727,6 +835,7 @@ private TestRepoResolver(TestRepository<Repository> repo, this.repoName = repoName; } + @Override public Repository open(HttpServletRequest req, String name) throws RepositoryNotFoundException, ServiceNotEnabledException { if (!name.equals(repoName))
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 10c29d5..64f7498 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
@@ -56,7 +56,7 @@ org.eclipse.jdt.core.compiler.problem.missingJavadocTagsMethodTypeParameters=disabled org.eclipse.jdt.core.compiler.problem.missingJavadocTagsOverriding=disabled org.eclipse.jdt.core.compiler.problem.missingJavadocTagsVisibility=private -org.eclipse.jdt.core.compiler.problem.missingOverrideAnnotation=ignore +org.eclipse.jdt.core.compiler.problem.missingOverrideAnnotation=warning org.eclipse.jdt.core.compiler.problem.missingOverrideAnnotationForInterfaceMethodImplementation=enabled org.eclipse.jdt.core.compiler.problem.missingSerialVersion=warning org.eclipse.jdt.core.compiler.problem.missingSynchronizedOnInheritedMethod=ignore @@ -76,7 +76,7 @@ org.eclipse.jdt.core.compiler.problem.rawTypeReference=ignore org.eclipse.jdt.core.compiler.problem.redundantNullAnnotation=warning org.eclipse.jdt.core.compiler.problem.redundantNullCheck=warning -org.eclipse.jdt.core.compiler.problem.redundantSpecificationOfTypeArguments=ignore +org.eclipse.jdt.core.compiler.problem.redundantSpecificationOfTypeArguments=warning org.eclipse.jdt.core.compiler.problem.redundantSuperinterface=error org.eclipse.jdt.core.compiler.problem.reportMethodCanBePotentiallyStatic=ignore org.eclipse.jdt.core.compiler.problem.reportMethodCanBeStatic=ignore
diff --git a/org.eclipse.jgit.junit.http/BUCK b/org.eclipse.jgit.junit.http/BUCK deleted file mode 100644 index 68976a6..0000000 --- a/org.eclipse.jgit.junit.http/BUCK +++ /dev/null
@@ -1,18 +0,0 @@ -java_library( - name = 'junit-http', - srcs = glob(['src/**']), - resources = glob(['resources/**']), - provided_deps = [ - '//org.eclipse.jgit:jgit', - '//org.eclipse.jgit.http.server:jgit-servlet', - '//org.eclipse.jgit.junit:junit', - '//lib:junit', - '//lib:servlet-api', - '//lib/jetty:http', - '//lib/jetty:server', - '//lib/jetty:servlet', - '//lib/jetty:security', - '//lib/jetty:util', - ], - visibility = ['PUBLIC'], -)
diff --git a/org.eclipse.jgit.junit.http/BUILD b/org.eclipse.jgit.junit.http/BUILD new file mode 100644 index 0000000..be6e1ae --- /dev/null +++ b/org.eclipse.jgit.junit.http/BUILD
@@ -0,0 +1,22 @@ +package(default_visibility = ["//visibility:public"]) + +java_library( + name = "junit-http", + testonly = 1, + srcs = glob(["src/**"]), + resources = glob(["resources/**"]), + # TODO(davido): we want here provided deps + deps = [ + "//lib:jetty-http", + "//lib:jetty-security", + "//lib:jetty-server", + "//lib:jetty-servlet", + "//lib:jetty-util", + "//lib:junit", + "//lib:servlet-api", + "//lib:slf4j-api", + "//org.eclipse.jgit.http.server:jgit-servlet", + "//org.eclipse.jgit:jgit", + "//org.eclipse.jgit.junit:junit", + ], +)
diff --git a/org.eclipse.jgit.junit.http/META-INF/MANIFEST.MF b/org.eclipse.jgit.junit.http/META-INF/MANIFEST.MF index cd42e2c..3ffa29b 100644 --- a/org.eclipse.jgit.junit.http/META-INF/MANIFEST.MF +++ b/org.eclipse.jgit.junit.http/META-INF/MANIFEST.MF
@@ -2,7 +2,7 @@ Bundle-ManifestVersion: 2 Bundle-Name: %plugin_name Bundle-SymbolicName: org.eclipse.jgit.junit.http -Bundle-Version: 4.6.2.qualifier +Bundle-Version: 4.7.6.qualifier Bundle-Localization: plugin Bundle-Vendor: %provider_name Bundle-ActivationPolicy: lazy @@ -20,22 +20,23 @@ org.eclipse.jetty.util.component;version="[9.0.0,9.4.0)", org.eclipse.jetty.util.log;version="[9.0.0,9.4.0)", org.eclipse.jetty.util.security;version="[9.0.0,9.4.0)", - org.eclipse.jgit.errors;version="[4.6.2,4.7.0)", - org.eclipse.jgit.http.server;version="[4.6.2,4.7.0)", - org.eclipse.jgit.internal.storage.file;version="[4.6.2,4.7.0)", - org.eclipse.jgit.junit;version="[4.6.2,4.7.0)", - org.eclipse.jgit.lib;version="[4.6.2,4.7.0)", - org.eclipse.jgit.revwalk;version="[4.6.2,4.7.0)", - org.eclipse.jgit.transport;version="[4.6.2,4.7.0)", - org.eclipse.jgit.transport.resolver;version="[4.6.2,4.7.0)", + org.eclipse.jgit.errors;version="[4.7.6,4.8.0)", + org.eclipse.jgit.http.server;version="[4.7.6,4.8.0)", + org.eclipse.jgit.internal.storage.file;version="[4.7.6,4.8.0)", + org.eclipse.jgit.junit;version="[4.7.6,4.8.0)", + org.eclipse.jgit.lib;version="[4.7.6,4.8.0)", + org.eclipse.jgit.revwalk;version="[4.7.6,4.8.0)", + org.eclipse.jgit.transport;version="[4.7.6,4.8.0)", + org.eclipse.jgit.transport.resolver;version="[4.7.6,4.8.0)", org.junit;version="[4.0.0,5.0.0)" -Export-Package: org.eclipse.jgit.junit.http;version="4.6.2"; +Export-Package: org.eclipse.jgit.junit.http;version="4.7.6"; uses:="org.eclipse.jgit.transport, org.eclipse.jgit.junit, javax.servlet.http, org.eclipse.jgit.lib, org.eclipse.jgit.revwalk, org.eclipse.jetty.server.handler, + org.eclipse.jetty.security, javax.servlet, org.eclipse.jetty.server, org.eclipse.jetty.util.log,
diff --git a/org.eclipse.jgit.junit.http/pom.xml b/org.eclipse.jgit.junit.http/pom.xml index ced9c2c..83d58c5 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>4.6.2-SNAPSHOT</version> + <version>4.7.6-SNAPSHOT</version> </parent> <artifactId>org.eclipse.jgit.junit.http</artifactId>
diff --git a/org.eclipse.jgit.junit.http/src/org/eclipse/jgit/junit/http/AccessEvent.java b/org.eclipse.jgit.junit.http/src/org/eclipse/jgit/junit/http/AccessEvent.java index aaccc66..6b7853d 100644 --- a/org.eclipse.jgit.junit.http/src/org/eclipse/jgit/junit/http/AccessEvent.java +++ b/org.eclipse.jgit.junit.http/src/org/eclipse/jgit/junit/http/AccessEvent.java
@@ -76,7 +76,7 @@ public class AccessEvent { } private static Map<String, String> cloneHeaders(final Request req) { - Map<String, String> r = new TreeMap<String, String>(); + Map<String, String> r = new TreeMap<>(); Enumeration hn = req.getHeaderNames(); while (hn.hasMoreElements()) { String key = (String) hn.nextElement(); @@ -88,7 +88,7 @@ private static Map<String, String> cloneHeaders(final Request req) { } private static Map<String, String> cloneHeaders(final Response rsp) { - Map<String, String> r = new TreeMap<String, String>(); + Map<String, String> r = new TreeMap<>(); Enumeration<String> hn = rsp.getHttpFields().getFieldNames(); while (hn.hasMoreElements()) { String key = hn.nextElement(); @@ -153,6 +153,7 @@ public String getResponseHeader(String name) { return responseHeaders.get(name); } + @Override public String toString() { StringBuilder b = new StringBuilder(); b.append(method);
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 44c1977..a663484 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
@@ -269,7 +269,7 @@ public int getPort() { /** @return all requests since the server was started. */ public List<AccessEvent> getRequests() { - return new ArrayList<AccessEvent>(log.getEvents()); + return new ArrayList<>(log.getEvents()); } /** @@ -289,7 +289,7 @@ public List<AccessEvent> getRequests(URIish base, String path) { * @return all requests which match the given path. */ public List<AccessEvent> getRequests(String path) { - ArrayList<AccessEvent> r = new ArrayList<AccessEvent>(); + ArrayList<AccessEvent> r = new ArrayList<>(); for (AccessEvent event : log.getEvents()) { if (event.getPath().equals(path)) { r.add(event);
diff --git a/org.eclipse.jgit.junit.http/src/org/eclipse/jgit/junit/http/HttpTestCase.java b/org.eclipse.jgit.junit.http/src/org/eclipse/jgit/junit/http/HttpTestCase.java index ab5d3e1..1b94e02 100644 --- a/org.eclipse.jgit.junit.http/src/org/eclipse/jgit/junit/http/HttpTestCase.java +++ b/org.eclipse.jgit.junit.http/src/org/eclipse/jgit/junit/http/HttpTestCase.java
@@ -74,11 +74,13 @@ public abstract class HttpTestCase extends LocalDiskRepositoryTestCase { /** In-memory application server; subclass must start. */ protected AppServer server; + @Override public void setUp() throws Exception { super.setUp(); server = new AppServer(); } + @Override public void tearDown() throws Exception { server.tearDown(); super.tearDown(); @@ -86,7 +88,7 @@ public void tearDown() throws Exception { protected TestRepository<Repository> createTestRepository() throws IOException { - return new TestRepository<Repository>(createBareRepository()); + return new TestRepository<>(createBareRepository()); } protected URIish toURIish(String path) throws URISyntaxException { @@ -118,12 +120,12 @@ protected List<AccessEvent> getRequests(String path) { protected static void fsck(Repository db, RevObject... tips) throws Exception { TestRepository<? extends Repository> tr = - new TestRepository<Repository>(db); + new TestRepository<>(db); tr.fsck(tips); } protected static Set<RefSpec> mirror(String... refs) { - HashSet<RefSpec> r = new HashSet<RefSpec>(); + HashSet<RefSpec> r = new HashSet<>(); for (String name : refs) { RefSpec rs = new RefSpec(name); rs = rs.setDestination(name);
diff --git a/org.eclipse.jgit.junit.http/src/org/eclipse/jgit/junit/http/MockServletConfig.java b/org.eclipse.jgit.junit.http/src/org/eclipse/jgit/junit/http/MockServletConfig.java index 5976589..9defcd9 100644 --- a/org.eclipse.jgit.junit.http/src/org/eclipse/jgit/junit/http/MockServletConfig.java +++ b/org.eclipse.jgit.junit.http/src/org/eclipse/jgit/junit/http/MockServletConfig.java
@@ -52,33 +52,39 @@ import javax.servlet.ServletContext; public class MockServletConfig implements ServletConfig { - private final Map<String, String> parameters = new HashMap<String, String>(); + private final Map<String, String> parameters = new HashMap<>(); public void setInitParameter(String name, String value) { parameters.put(name, value); } + @Override public String getInitParameter(String name) { return parameters.get(name); } + @Override public Enumeration<String> getInitParameterNames() { final Iterator<String> i = parameters.keySet().iterator(); return new Enumeration<String>() { + @Override public boolean hasMoreElements() { return i.hasNext(); } + @Override public String nextElement() { return i.next(); } }; } + @Override public String getServletName() { return "MOCK_SERVLET"; } + @Override public ServletContext getServletContext() { return null; }
diff --git a/org.eclipse.jgit.junit.http/src/org/eclipse/jgit/junit/http/RecordingLogger.java b/org.eclipse.jgit.junit.http/src/org/eclipse/jgit/junit/http/RecordingLogger.java index 7600843..415398d 100644 --- a/org.eclipse.jgit.junit.http/src/org/eclipse/jgit/junit/http/RecordingLogger.java +++ b/org.eclipse.jgit.junit.http/src/org/eclipse/jgit/junit/http/RecordingLogger.java
@@ -52,7 +52,7 @@ /** Logs warnings into an array for later inspection. */ public class RecordingLogger implements Logger { - private static List<Warning> warnings = new ArrayList<Warning>(); + private static List<Warning> warnings = new ArrayList<>(); /** Clear the warnings, automatically done by {@link AppServer#setUp()} */ public static void clear() { @@ -64,7 +64,7 @@ public static void clear() { /** @return the warnings (if any) from the last execution */ public static List<Warning> getWarnings() { synchronized (warnings) { - ArrayList<Warning> copy = new ArrayList<Warning>(warnings); + ArrayList<Warning> copy = new ArrayList<>(warnings); return Collections.unmodifiableList(copy); } } @@ -94,10 +94,12 @@ public RecordingLogger(final String name) { this.name = name; } + @Override public Logger getLogger(@SuppressWarnings("hiding") String name) { return new RecordingLogger(name); } + @Override public String getName() { return name; } @@ -108,6 +110,7 @@ public void warn(String msg, Object arg0, Object arg1) { } } + @Override public void warn(String msg, Throwable th) { synchronized (warnings) { warnings.add(new Warning(msg, th)); @@ -126,6 +129,7 @@ public void debug(@SuppressWarnings("unused") String msg, // Ignore (not relevant to test failures) } + @Override public void debug(String msg, Throwable th) { // Ignore (not relevant to test failures) } @@ -144,46 +148,56 @@ public void info(@SuppressWarnings("unused") String msg) { // Ignore (not relevant to test failures) } + @Override public boolean isDebugEnabled() { return false; } + @Override public void setDebugEnabled(boolean enabled) { // Ignore (not relevant to test failures) } + @Override public void warn(String msg, Object... args) { synchronized (warnings) { warnings.add(new Warning(MessageFormat.format(msg, args))); } } + @Override public void warn(Throwable thrown) { synchronized (warnings) { warnings.add(new Warning(thrown)); } } + @Override public void info(String msg, Object... args) { // Ignore (not relevant to test failures) } + @Override public void info(Throwable thrown) { // Ignore (not relevant to test failures) } + @Override public void info(String msg, Throwable thrown) { // Ignore (not relevant to test failures) } + @Override public void debug(String msg, Object... args) { // Ignore (not relevant to test failures) } + @Override public void debug(Throwable thrown) { // Ignore (not relevant to test failures) } + @Override public void ignore(Throwable arg0) { // Ignore (not relevant to test failures) }
diff --git a/org.eclipse.jgit.junit.http/src/org/eclipse/jgit/junit/http/SimpleHttpServer.java b/org.eclipse.jgit.junit.http/src/org/eclipse/jgit/junit/http/SimpleHttpServer.java index e550e6c..605c69a 100644 --- a/org.eclipse.jgit.junit.http/src/org/eclipse/jgit/junit/http/SimpleHttpServer.java +++ b/org.eclipse.jgit.junit.http/src/org/eclipse/jgit/junit/http/SimpleHttpServer.java
@@ -92,6 +92,7 @@ public URIish getUri() { private ServletContextHandler smart(final String path) { GitServlet gs = new GitServlet(); gs.setRepositoryResolver(new RepositoryResolver<HttpServletRequest>() { + @Override public Repository open(HttpServletRequest req, String name) throws RepositoryNotFoundException, ServiceNotEnabledException {
diff --git a/org.eclipse.jgit.junit.http/src/org/eclipse/jgit/junit/http/TestRequestLog.java b/org.eclipse.jgit.junit.http/src/org/eclipse/jgit/junit/http/TestRequestLog.java index 14ea03a..c218c07 100644 --- a/org.eclipse.jgit.junit.http/src/org/eclipse/jgit/junit/http/TestRequestLog.java +++ b/org.eclipse.jgit.junit.http/src/org/eclipse/jgit/junit/http/TestRequestLog.java
@@ -61,7 +61,7 @@ class TestRequestLog extends HandlerWrapper { private static final int MAX = 16; - private final List<AccessEvent> events = new ArrayList<AccessEvent>(); + private final List<AccessEvent> events = new ArrayList<>(); private final Semaphore active = new Semaphore(MAX);
diff --git a/org.eclipse.jgit.junit/.settings/.api_filters b/org.eclipse.jgit.junit/.settings/.api_filters new file mode 100644 index 0000000..a70ce77 --- /dev/null +++ b/org.eclipse.jgit.junit/.settings/.api_filters
@@ -0,0 +1,35 @@ +<?xml version="1.0" encoding="UTF-8" standalone="no"?> +<component id="org.eclipse.jgit.junit" version="2"> + <resource path="src/org/eclipse/jgit/junit/LocalDiskRepositoryTestCase.java" type="org.eclipse.jgit.junit.LocalDiskRepositoryTestCase"> + <filter comment="OK to use internal implementation in tests" id="643842064"> + <message_arguments> + <message_argument value="FileRepository"/> + <message_argument value="LocalDiskRepositoryTestCase"/> + <message_argument value="createBareRepository()"/> + </message_arguments> + </filter> + <filter comment="OK to use internal implementation in tests" id="643842064"> + <message_arguments> + <message_argument value="FileRepository"/> + <message_argument value="LocalDiskRepositoryTestCase"/> + <message_argument value="createRepository(boolean, boolean)"/> + </message_arguments> + </filter> + <filter comment="OK to use internal implementation in tests" id="643842064"> + <message_arguments> + <message_argument value="FileRepository"/> + <message_argument value="LocalDiskRepositoryTestCase"/> + <message_argument value="createWorkRepository()"/> + </message_arguments> + </filter> + </resource> + <resource path="src/org/eclipse/jgit/junit/RepositoryTestCase.java" type="org.eclipse.jgit.junit.RepositoryTestCase"> + <filter comment="OK to use internal implementation in tests" id="627060751"> + <message_arguments> + <message_argument value="FileRepository"/> + <message_argument value="RepositoryTestCase"/> + <message_argument value="db"/> + </message_arguments> + </filter> + </resource> +</component>
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 10c29d5..64f7498 100644 --- a/org.eclipse.jgit.junit/.settings/org.eclipse.jdt.core.prefs +++ b/org.eclipse.jgit.junit/.settings/org.eclipse.jdt.core.prefs
@@ -56,7 +56,7 @@ org.eclipse.jdt.core.compiler.problem.missingJavadocTagsMethodTypeParameters=disabled org.eclipse.jdt.core.compiler.problem.missingJavadocTagsOverriding=disabled org.eclipse.jdt.core.compiler.problem.missingJavadocTagsVisibility=private -org.eclipse.jdt.core.compiler.problem.missingOverrideAnnotation=ignore +org.eclipse.jdt.core.compiler.problem.missingOverrideAnnotation=warning org.eclipse.jdt.core.compiler.problem.missingOverrideAnnotationForInterfaceMethodImplementation=enabled org.eclipse.jdt.core.compiler.problem.missingSerialVersion=warning org.eclipse.jdt.core.compiler.problem.missingSynchronizedOnInheritedMethod=ignore @@ -76,7 +76,7 @@ org.eclipse.jdt.core.compiler.problem.rawTypeReference=ignore org.eclipse.jdt.core.compiler.problem.redundantNullAnnotation=warning org.eclipse.jdt.core.compiler.problem.redundantNullCheck=warning -org.eclipse.jdt.core.compiler.problem.redundantSpecificationOfTypeArguments=ignore +org.eclipse.jdt.core.compiler.problem.redundantSpecificationOfTypeArguments=warning org.eclipse.jdt.core.compiler.problem.redundantSuperinterface=error org.eclipse.jdt.core.compiler.problem.reportMethodCanBePotentiallyStatic=ignore org.eclipse.jdt.core.compiler.problem.reportMethodCanBeStatic=ignore
diff --git a/org.eclipse.jgit.junit/BUCK b/org.eclipse.jgit.junit/BUCK deleted file mode 100644 index 7e25432..0000000 --- a/org.eclipse.jgit.junit/BUCK +++ /dev/null
@@ -1,10 +0,0 @@ -java_library( - name = 'junit', - srcs = glob(['src/**']), - resources = glob(['resources/**']), - provided_deps = [ - '//org.eclipse.jgit:jgit', - '//lib:junit', - ], - visibility = ['PUBLIC'], -)
diff --git a/org.eclipse.jgit.junit/BUILD b/org.eclipse.jgit.junit/BUILD new file mode 100644 index 0000000..350b25f --- /dev/null +++ b/org.eclipse.jgit.junit/BUILD
@@ -0,0 +1,14 @@ +package(default_visibility = ["//visibility:public"]) + +java_library( + name = "junit", + testonly = 1, + srcs = glob(["src/**"]), + resource_strip_prefix = "org.eclipse.jgit.junit/resources", + resources = glob(["resources/**"]), + deps = [ + "//lib:junit", + # We want these deps to be provided_deps + "//org.eclipse.jgit:jgit", + ], +)
diff --git a/org.eclipse.jgit.junit/META-INF/MANIFEST.MF b/org.eclipse.jgit.junit/META-INF/MANIFEST.MF index 9de6239..7087680 100644 --- a/org.eclipse.jgit.junit/META-INF/MANIFEST.MF +++ b/org.eclipse.jgit.junit/META-INF/MANIFEST.MF
@@ -2,31 +2,31 @@ Bundle-ManifestVersion: 2 Bundle-Name: %plugin_name Bundle-SymbolicName: org.eclipse.jgit.junit -Bundle-Version: 4.6.2.qualifier +Bundle-Version: 4.7.6.qualifier Bundle-Localization: plugin Bundle-Vendor: %provider_name Bundle-ActivationPolicy: lazy Bundle-RequiredExecutionEnvironment: JavaSE-1.8 -Import-Package: org.eclipse.jgit.api;version="[4.6.2,4.7.0)", - org.eclipse.jgit.api.errors;version="[4.6.2,4.7.0)", - org.eclipse.jgit.dircache;version="[4.6.2,4.7.0)", - org.eclipse.jgit.errors;version="[4.6.2,4.7.0)", - org.eclipse.jgit.internal.storage.file;version="[4.6.2,4.7.0)", - org.eclipse.jgit.internal.storage.pack;version="[4.6.2,4.7.0)", - org.eclipse.jgit.lib;version="[4.6.2,4.7.0)", - org.eclipse.jgit.merge;version="[4.6.2,4.7.0)", - org.eclipse.jgit.revwalk;version="[4.6.2,4.7.0)", - org.eclipse.jgit.storage.file;version="[4.6.2,4.7.0)", - org.eclipse.jgit.treewalk;version="[4.6.2,4.7.0)", - org.eclipse.jgit.treewalk.filter;version="[4.6.2,4.7.0)", - org.eclipse.jgit.util;version="[4.6.2,4.7.0)", - org.eclipse.jgit.util.io;version="[4.6.2,4.7.0)", - org.eclipse.jgit.util.time;version="[4.6.2,4.7.0)", +Import-Package: org.eclipse.jgit.api;version="[4.7.6,4.8.0)", + org.eclipse.jgit.api.errors;version="[4.7.6,4.8.0)", + org.eclipse.jgit.dircache;version="[4.7.6,4.8.0)", + org.eclipse.jgit.errors;version="[4.7.6,4.8.0)", + org.eclipse.jgit.internal.storage.file;version="[4.7.6,4.8.0)", + org.eclipse.jgit.internal.storage.pack;version="[4.7.6,4.8.0)", + org.eclipse.jgit.lib;version="[4.7.6,4.8.0)", + org.eclipse.jgit.merge;version="[4.7.6,4.8.0)", + org.eclipse.jgit.revwalk;version="[4.7.6,4.8.0)", + org.eclipse.jgit.storage.file;version="[4.7.6,4.8.0)", + org.eclipse.jgit.treewalk;version="[4.7.6,4.8.0)", + org.eclipse.jgit.treewalk.filter;version="[4.7.6,4.8.0)", + org.eclipse.jgit.util;version="[4.7.6,4.8.0)", + org.eclipse.jgit.util.io;version="[4.7.6,4.8.0)", + org.eclipse.jgit.util.time;version="[4.7.6,4.8.0)", org.junit;version="[4.0.0,5.0.0)", org.junit.rules;version="[4.9.0,5.0.0)", org.junit.runner;version="[4.0.0,5.0.0)", org.junit.runners.model;version="[4.5.0,5.0.0)" -Export-Package: org.eclipse.jgit.junit;version="4.6.2"; +Export-Package: org.eclipse.jgit.junit;version="4.7.6"; uses:="org.eclipse.jgit.dircache, org.eclipse.jgit.lib, org.eclipse.jgit.revwalk, @@ -35,4 +35,4 @@ org.eclipse.jgit.util, org.eclipse.jgit.storage.file, org.eclipse.jgit.api", - org.eclipse.jgit.junit.time;version="4.6.2" + org.eclipse.jgit.junit.time;version="4.7.6"
diff --git a/org.eclipse.jgit.junit/pom.xml b/org.eclipse.jgit.junit/pom.xml index ab757af..e97b6af 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>4.6.2-SNAPSHOT</version> + <version>4.7.6-SNAPSHOT</version> </parent> <artifactId>org.eclipse.jgit.junit</artifactId>
diff --git a/org.eclipse.jgit.junit/src/org/eclipse/jgit/junit/LocalDiskRepositoryTestCase.java b/org.eclipse.jgit.junit/src/org/eclipse/jgit/junit/LocalDiskRepositoryTestCase.java index dc2e8bf..6ace9fc 100644 --- a/org.eclipse.jgit.junit/src/org/eclipse/jgit/junit/LocalDiskRepositoryTestCase.java +++ b/org.eclipse.jgit.junit/src/org/eclipse/jgit/junit/LocalDiskRepositoryTestCase.java
@@ -53,13 +53,16 @@ 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.TreeSet; import org.eclipse.jgit.dircache.DirCache; import org.eclipse.jgit.dircache.DirCacheEntry; import org.eclipse.jgit.internal.storage.file.FileRepository; +import org.eclipse.jgit.lib.ConfigConstants; import org.eclipse.jgit.lib.Constants; import org.eclipse.jgit.lib.ObjectId; import org.eclipse.jgit.lib.PersonIdent; @@ -106,7 +109,7 @@ public abstract class LocalDiskRepositoryTestCase { */ protected MockSystemReader mockSystemReader; - private final List<Repository> toClose = new ArrayList<Repository>(); + private final Set<Repository> toClose = new HashSet<>(); private File tmp; @Before @@ -119,6 +122,12 @@ public void setUp() throws Exception { mockSystemReader = new MockSystemReader(); mockSystemReader.userGitConfig = new FileBasedConfig(new File(tmp, "usergitconfig"), FS.DETECTED); + // We have to set autoDetach to false for tests, because tests expect to be able + // to clean up by recursively removing the repository, and background GC might be + // in the middle of writing or deleting files, which would disrupt this. + mockSystemReader.userGitConfig.setBoolean(ConfigConstants.CONFIG_GC_SECTION, + null, ConfigConstants.CONFIG_KEY_AUTODETACH, false); + mockSystemReader.userGitConfig.save(); ceilTestDirectories(getCeilings()); SystemReader.setInstance(mockSystemReader); @@ -284,7 +293,7 @@ public static String indexState(Repository repo, int includedOptions) throws IllegalStateException, IOException { DirCache dc = repo.readDirCache(); StringBuilder sb = new StringBuilder(); - TreeSet<Long> timeStamps = new TreeSet<Long>(); + TreeSet<Long> timeStamps = new TreeSet<>(); // iterate once over the dircache just to collect all time stamps if (0 != (includedOptions & MOD_TIME)) { @@ -357,12 +366,32 @@ protected FileRepository createWorkRepository() throws IOException { * @throws IOException * the repository could not be created in the temporary area */ - private FileRepository createRepository(boolean bare) throws IOException { + private FileRepository createRepository(boolean bare) + throws IOException { + return createRepository(bare, true /* auto close */); + } + + /** + * Creates a new empty repository. + * + * @param bare + * true to create a bare repository; false to make a repository + * within its working directory + * @param autoClose + * auto close the repository in #tearDown + * @return the newly created repository, opened for access + * @throws IOException + * the repository could not be created in the temporary area + */ + public FileRepository createRepository(boolean bare, boolean autoClose) + throws IOException { File gitdir = createUniqueTestGitDir(bare); FileRepository db = new FileRepository(gitdir); assertFalse(gitdir.exists()); db.create(bare); - toClose.add(db); + if (autoClose) { + addRepoToClose(db); + } return db; } @@ -530,7 +559,7 @@ protected String read(final File f) throws IOException { } private static HashMap<String, String> cloneEnv() { - return new HashMap<String, String>(System.getenv()); + return new HashMap<>(System.getenv()); } private static final class CleanupThread extends Thread { @@ -552,7 +581,7 @@ static void removed(File tmp) { } } - private final List<File> toDelete = new ArrayList<File>(); + private final List<File> toDelete = new ArrayList<>(); @Override public void run() {
diff --git a/org.eclipse.jgit.junit/src/org/eclipse/jgit/junit/MockSystemReader.java b/org.eclipse.jgit.junit/src/org/eclipse/jgit/junit/MockSystemReader.java index 6faa2ec..68482c6 100644 --- a/org.eclipse.jgit.junit/src/org/eclipse/jgit/junit/MockSystemReader.java +++ b/org.eclipse.jgit.junit/src/org/eclipse/jgit/junit/MockSystemReader.java
@@ -88,7 +88,7 @@ public boolean isOutdated() { long now = 1250379778668L; // Sat Aug 15 20:12:58 GMT-03:30 2009 - final Map<String, String> values = new HashMap<String, String>(); + final Map<String, String> values = new HashMap<>(); FileBasedConfig userGitConfig;
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 a44e999..d1358ee 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
@@ -876,7 +876,7 @@ public void packAndPrune() throws Exception { final File pack, idx; try (PackWriter pw = new PackWriter(db)) { - Set<ObjectId> all = new HashSet<ObjectId>(); + Set<ObjectId> all = new HashSet<>(); for (Ref r : db.getAllRefs().values()) all.add(r.getObjectId()); pw.preparePack(m, all, PackWriter.NONE); @@ -992,7 +992,7 @@ public class CommitBuilder { private ObjectId topLevelTree; - private final List<RevCommit> parents = new ArrayList<RevCommit>(2); + private final List<RevCommit> parents = new ArrayList<>(2); private int tick = 1;
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 10c29d5..64f7498 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
@@ -56,7 +56,7 @@ org.eclipse.jdt.core.compiler.problem.missingJavadocTagsMethodTypeParameters=disabled org.eclipse.jdt.core.compiler.problem.missingJavadocTagsOverriding=disabled org.eclipse.jdt.core.compiler.problem.missingJavadocTagsVisibility=private -org.eclipse.jdt.core.compiler.problem.missingOverrideAnnotation=ignore +org.eclipse.jdt.core.compiler.problem.missingOverrideAnnotation=warning org.eclipse.jdt.core.compiler.problem.missingOverrideAnnotationForInterfaceMethodImplementation=enabled org.eclipse.jdt.core.compiler.problem.missingSerialVersion=warning org.eclipse.jdt.core.compiler.problem.missingSynchronizedOnInheritedMethod=ignore @@ -76,7 +76,7 @@ org.eclipse.jdt.core.compiler.problem.rawTypeReference=ignore org.eclipse.jdt.core.compiler.problem.redundantNullAnnotation=warning org.eclipse.jdt.core.compiler.problem.redundantNullCheck=warning -org.eclipse.jdt.core.compiler.problem.redundantSpecificationOfTypeArguments=ignore +org.eclipse.jdt.core.compiler.problem.redundantSpecificationOfTypeArguments=warning org.eclipse.jdt.core.compiler.problem.redundantSuperinterface=error org.eclipse.jdt.core.compiler.problem.reportMethodCanBePotentiallyStatic=ignore org.eclipse.jdt.core.compiler.problem.reportMethodCanBeStatic=ignore
diff --git a/org.eclipse.jgit.lfs.server.test/BUCK b/org.eclipse.jgit.lfs.server.test/BUCK deleted file mode 100644 index 25e9f09..0000000 --- a/org.eclipse.jgit.lfs.server.test/BUCK +++ /dev/null
@@ -1,34 +0,0 @@ -TEST_BASE = ['tst/org/eclipse/jgit/lfs/server/fs/LfsServerTest.java'] -TESTS = glob(['tst/**/*.java'], - excludes = TEST_BASE -) - -for t in TESTS: - n = t[len('tst/'):len(t)-len('.java')].replace('/', '.') - java_test( - name = n, - labels = ['lfs-server'], - srcs = [t] + TEST_BASE, - deps = [ - '//org.eclipse.jgit.lfs.test:helpers', - '//org.eclipse.jgit:jgit', - '//org.eclipse.jgit.junit:junit', - '//org.eclipse.jgit.junit.http:junit-http', - '//org.eclipse.jgit.lfs:jgit-lfs', - '//org.eclipse.jgit.lfs.server:jgit-lfs-server', - '//lib:hamcrest-core', - '//lib:hamcrest-library', - '//lib:httpcore', - '//lib:httpcomponents', - '//lib:junit', - '//lib/jetty:http', - '//lib/jetty:io', - '//lib/jetty:server', - '//lib/jetty:servlet', - '//lib/jetty:security', - '//lib/jetty:util', - '//lib:servlet-api', - '//lib:commons-logging', - ], - vm_args = ['-Xmx256m', '-Dfile.encoding=UTF-8'], - )
diff --git a/org.eclipse.jgit.lfs.server.test/BUILD b/org.eclipse.jgit.lfs.server.test/BUILD new file mode 100644 index 0000000..1341dd6 --- /dev/null +++ b/org.eclipse.jgit.lfs.server.test/BUILD
@@ -0,0 +1,49 @@ +load( + "@com_googlesource_gerrit_bazlets//tools:junit.bzl", + "junit_tests", +) + +TEST_BASE = ["tst/org/eclipse/jgit/lfs/server/fs/LfsServerTest.java"] + +DEPS = [ + "//org.eclipse.jgit.lfs.test:helpers", + "//org.eclipse.jgit:jgit", + "//org.eclipse.jgit.junit:junit", + "//org.eclipse.jgit.junit.http:junit-http", + "//org.eclipse.jgit.lfs:jgit-lfs", + "//org.eclipse.jgit.lfs.server:jgit-lfs-server", + "//lib:commons-logging", + "//lib:httpcore", + "//lib:httpclient", + "//lib:junit", + "//lib:jetty-http", + "//lib:jetty-io", + "//lib:jetty-server", + "//lib:jetty-servlet", + "//lib:jetty-security", + "//lib:jetty-util", + "//lib:servlet-api", +] + +junit_tests( + name = "lfs_server", + srcs = glob( + ["tst/**/*.java"], + exclude = TEST_BASE, + ), + jvm_flags = [ + "-Xmx256m", + "-Dfile.encoding=UTF-8", + ], + tags = ["lfs-server"], + deps = DEPS + [ + ":helpers", + ], +) + +java_library( + name = "helpers", + testonly = 1, + srcs = TEST_BASE, + deps = DEPS, +)
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 405e07a..bb84f82 100644 --- a/org.eclipse.jgit.lfs.server.test/META-INF/MANIFEST.MF +++ b/org.eclipse.jgit.lfs.server.test/META-INF/MANIFEST.MF
@@ -2,7 +2,7 @@ Bundle-ManifestVersion: 2 Bundle-Name: %plugin_name Bundle-SymbolicName: org.eclipse.jgit.lfs.server.test -Bundle-Version: 4.6.2.qualifier +Bundle-Version: 4.7.6.qualifier Bundle-Vendor: %provider_name Bundle-Localization: plugin Bundle-RequiredExecutionEnvironment: JavaSE-1.8 @@ -27,11 +27,11 @@ org.eclipse.jetty.util.log;version="[9.0.0,9.4.0)", org.eclipse.jetty.util.security;version="[9.0.0,9.4.0)", org.eclipse.jetty.util.thread;version="[9.0.0,9.4.0)", - org.eclipse.jgit.junit.http;version="[4.6.2,4.7.0)", - org.eclipse.jgit.lfs.lib;version="[4.6.2,4.7.0)", - org.eclipse.jgit.lfs.server.fs;version="[4.6.2,4.7.0)", - org.eclipse.jgit.lfs.test;version="[4.6.2,4.7.0)", - org.eclipse.jgit.util;version="[4.6.2,4.7.0)", + org.eclipse.jgit.junit.http;version="[4.7.6,4.8.0)", + org.eclipse.jgit.lfs.lib;version="[4.7.6,4.8.0)", + org.eclipse.jgit.lfs.server.fs;version="[4.7.6,4.8.0)", + org.eclipse.jgit.lfs.test;version="[4.7.6,4.8.0)", + org.eclipse.jgit.util;version="[4.7.6,4.8.0)", org.hamcrest.core;version="[1.1.0,2.0.0)", org.junit;version="[4.0.0,5.0.0)", org.junit.runner;version="[4.0.0,5.0.0)",
diff --git a/org.eclipse.jgit.lfs.server.test/pom.xml b/org.eclipse.jgit.lfs.server.test/pom.xml index d178fef..fa83d88 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>4.6.2-SNAPSHOT</version> + <version>4.7.6-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 808ec3a..ede0f7d 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
@@ -56,7 +56,7 @@ org.eclipse.jdt.core.compiler.problem.missingJavadocTagsMethodTypeParameters=disabled org.eclipse.jdt.core.compiler.problem.missingJavadocTagsOverriding=disabled org.eclipse.jdt.core.compiler.problem.missingJavadocTagsVisibility=private -org.eclipse.jdt.core.compiler.problem.missingOverrideAnnotation=ignore +org.eclipse.jdt.core.compiler.problem.missingOverrideAnnotation=warning org.eclipse.jdt.core.compiler.problem.missingOverrideAnnotationForInterfaceMethodImplementation=enabled org.eclipse.jdt.core.compiler.problem.missingSerialVersion=warning org.eclipse.jdt.core.compiler.problem.missingSynchronizedOnInheritedMethod=ignore @@ -76,7 +76,7 @@ org.eclipse.jdt.core.compiler.problem.rawTypeReference=ignore org.eclipse.jdt.core.compiler.problem.redundantNullAnnotation=warning org.eclipse.jdt.core.compiler.problem.redundantNullCheck=warning -org.eclipse.jdt.core.compiler.problem.redundantSpecificationOfTypeArguments=ignore +org.eclipse.jdt.core.compiler.problem.redundantSpecificationOfTypeArguments=warning org.eclipse.jdt.core.compiler.problem.redundantSuperinterface=error org.eclipse.jdt.core.compiler.problem.reportMethodCanBePotentiallyStatic=ignore org.eclipse.jdt.core.compiler.problem.reportMethodCanBeStatic=ignore
diff --git a/org.eclipse.jgit.lfs.server/BUCK b/org.eclipse.jgit.lfs.server/BUCK deleted file mode 100644 index 6b40b7c..0000000 --- a/org.eclipse.jgit.lfs.server/BUCK +++ /dev/null
@@ -1,22 +0,0 @@ -SRCS = glob(['src/**']) -RESOURCES = glob(['resources/**']) - -java_library( - name = 'jgit-lfs-server', - srcs = SRCS, - resources = RESOURCES, - deps = [ - '//org.eclipse.jgit.http.apache:http-apache', - '//org.eclipse.jgit:jgit', - '//org.eclipse.jgit.lfs:jgit-lfs', - '//lib:gson', - '//lib:httpcore', - '//lib:servlet-api' - ], - visibility = ['PUBLIC'], -) - -java_sources( - name = 'jgit-lfs-server_src', - srcs = SRCS + RESOURCES, -)
diff --git a/org.eclipse.jgit.lfs.server/BUILD b/org.eclipse.jgit.lfs.server/BUILD new file mode 100644 index 0000000..fa14e8a --- /dev/null +++ b/org.eclipse.jgit.lfs.server/BUILD
@@ -0,0 +1,17 @@ +package(default_visibility = ["//visibility:public"]) + +java_library( + name = "jgit-lfs-server", + srcs = glob(["src/**"]), + resource_strip_prefix = "org.eclipse.jgit.lfs.server/resources", + resources = glob(["resources/**"]), + deps = [ + "//lib:gson", + "//lib:httpcore", + "//lib:servlet-api", + "//lib:slf4j-api", + "//org.eclipse.jgit.http.apache:http-apache", + "//org.eclipse.jgit:jgit", + "//org.eclipse.jgit.lfs:jgit-lfs", + ], +)
diff --git a/org.eclipse.jgit.lfs.server/META-INF/MANIFEST.MF b/org.eclipse.jgit.lfs.server/META-INF/MANIFEST.MF index 3e8a9d1..9ca9e85 100644 --- a/org.eclipse.jgit.lfs.server/META-INF/MANIFEST.MF +++ b/org.eclipse.jgit.lfs.server/META-INF/MANIFEST.MF
@@ -2,19 +2,19 @@ Bundle-ManifestVersion: 2 Bundle-Name: %plugin_name Bundle-SymbolicName: org.eclipse.jgit.lfs.server -Bundle-Version: 4.6.2.qualifier +Bundle-Version: 4.7.6.qualifier Bundle-Localization: plugin Bundle-Vendor: %provider_name -Export-Package: org.eclipse.jgit.lfs.server;version="4.6.2"; +Export-Package: org.eclipse.jgit.lfs.server;version="4.7.6"; uses:="javax.servlet.http, org.eclipse.jgit.lfs.lib", - org.eclipse.jgit.lfs.server.fs;version="4.6.2"; + org.eclipse.jgit.lfs.server.fs;version="4.7.6"; uses:="javax.servlet, javax.servlet.http, org.eclipse.jgit.lfs.server, org.eclipse.jgit.lfs.lib", - org.eclipse.jgit.lfs.server.internal;version="4.6.2";x-internal:=true, - org.eclipse.jgit.lfs.server.s3;version="4.6.2"; + org.eclipse.jgit.lfs.server.internal;version="4.7.6";x-internal:=true, + org.eclipse.jgit.lfs.server.s3;version="4.7.6"; uses:="org.eclipse.jgit.lfs.server, org.eclipse.jgit.lfs.lib" Bundle-RequiredExecutionEnvironment: JavaSE-1.8 @@ -24,13 +24,14 @@ 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="[4.6.2,4.7.0)", - org.eclipse.jgit.internal;version="[4.6.2,4.7.0)", - org.eclipse.jgit.internal.storage.file;version="[4.6.2,4.7.0)", - org.eclipse.jgit.lfs.errors;version="[4.6.2,4.7.0)", - org.eclipse.jgit.lfs.internal;version="[4.6.2,4.7.0)", - org.eclipse.jgit.lfs.lib;version="[4.6.2,4.7.0)", - org.eclipse.jgit.nls;version="[4.6.2,4.7.0)", - org.eclipse.jgit.transport.http;version="[4.6.2,4.7.0)", - org.eclipse.jgit.transport.http.apache;version="[4.6.2,4.7.0)", - org.eclipse.jgit.util;version="[4.6.2,4.7.0)" + org.eclipse.jgit.annotations;version="[4.7.6,4.8.0)", + org.eclipse.jgit.internal;version="[4.7.6,4.8.0)", + org.eclipse.jgit.internal.storage.file;version="[4.7.6,4.8.0)", + org.eclipse.jgit.lfs.errors;version="[4.7.6,4.8.0)", + org.eclipse.jgit.lfs.internal;version="[4.7.6,4.8.0)", + org.eclipse.jgit.lfs.lib;version="[4.7.6,4.8.0)", + org.eclipse.jgit.nls;version="[4.7.6,4.8.0)", + org.eclipse.jgit.transport.http;version="[4.7.6,4.8.0)", + org.eclipse.jgit.transport.http.apache;version="[4.7.6,4.8.0)", + org.eclipse.jgit.util;version="[4.7.6,4.8.0)", + org.slf4j;version="[1.7.0,2.0.0)"
diff --git a/org.eclipse.jgit.lfs.server/pom.xml b/org.eclipse.jgit.lfs.server/pom.xml index cc84686..c3fa5ba 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>4.6.2-SNAPSHOT</version> + <version>4.7.6-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 841074b..2473dcd 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
@@ -49,7 +49,12 @@ import static org.apache.http.HttpStatus.SC_NOT_FOUND; import static org.apache.http.HttpStatus.SC_OK; import static org.apache.http.HttpStatus.SC_SERVICE_UNAVAILABLE; +import static org.apache.http.HttpStatus.SC_UNAUTHORIZED; import static org.apache.http.HttpStatus.SC_UNPROCESSABLE_ENTITY; +import static org.eclipse.jgit.lfs.lib.Constants.DOWNLOAD; +import static org.eclipse.jgit.lfs.lib.Constants.UPLOAD; +import static org.eclipse.jgit.lfs.lib.Constants.VERIFY; +import static org.eclipse.jgit.util.HttpSupport.HDR_AUTHORIZATION; import java.io.BufferedReader; import java.io.BufferedWriter; @@ -58,6 +63,7 @@ import java.io.OutputStreamWriter; import java.io.Reader; import java.io.Writer; +import java.text.MessageFormat; import java.util.List; import javax.servlet.ServletException; @@ -71,8 +77,12 @@ import org.eclipse.jgit.lfs.errors.LfsRateLimitExceeded; import org.eclipse.jgit.lfs.errors.LfsRepositoryNotFound; import org.eclipse.jgit.lfs.errors.LfsRepositoryReadOnly; +import org.eclipse.jgit.lfs.errors.LfsUnauthorized; import org.eclipse.jgit.lfs.errors.LfsUnavailable; import org.eclipse.jgit.lfs.errors.LfsValidationError; +import org.eclipse.jgit.lfs.internal.LfsText; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import com.google.gson.FieldNamingPolicy; import com.google.gson.Gson; @@ -86,6 +96,8 @@ * @since 4.3 */ public abstract class LfsProtocolServlet extends HttpServlet { + private static Logger LOG = LoggerFactory + .getLogger(LfsProtocolServlet.class); private static final long serialVersionUID = 1L; @@ -132,9 +144,54 @@ public abstract class LfsProtocolServlet extends HttpServlet { * <dd>when an unexpected internal server error occurred</dd> * </dl> * @since 4.5 + * @deprecated use + * {@link #getLargeFileRepository(LfsRequest, String, String)} + */ + @Deprecated + protected LargeFileRepository getLargeFileRepository(LfsRequest request, + String path) throws LfsException { + return getLargeFileRepository(request, path, null); + } + + /** + * Get the large file repository for the given request and path. + * + * @param request + * the request + * @param path + * the path + * @param auth + * the Authorization HTTP header + * + * @return the large file repository storing large files. + * @throws LfsException + * implementations should throw more specific exceptions to + * signal which type of error occurred: + * <dl> + * <dt>{@link LfsValidationError}</dt> + * <dd>when there is a validation error with one or more of the + * objects in the request</dd> + * <dt>{@link LfsRepositoryNotFound}</dt> + * <dd>when the repository does not exist for the user</dd> + * <dt>{@link LfsRepositoryReadOnly}</dt> + * <dd>when the user has read, but not write access. Only + * applicable when the operation in the request is "upload"</dd> + * <dt>{@link LfsRateLimitExceeded}</dt> + * <dd>when the user has hit a rate limit with the server</dd> + * <dt>{@link LfsBandwidthLimitExceeded}</dt> + * <dd>when the bandwidth limit for the user or repository has + * been exceeded</dd> + * <dt>{@link LfsInsufficientStorage}</dt> + * <dd>when there is insufficient storage on the server</dd> + * <dt>{@link LfsUnavailable}</dt> + * <dd>when LFS is not available</dd> + * <dt>{@link LfsException}</dt> + * <dd>when an unexpected internal server error occurred</dd> + * </dl> + * @since 4.7 */ protected abstract LargeFileRepository getLargeFileRepository( - LfsRequest request, String path) throws LfsException; + LfsRequest request, String path, String auth) throws LfsException; /** * LFS request. @@ -163,6 +220,30 @@ public String getOperation() { public List<LfsObject> getObjects() { return objects; } + + /** + * @return true if the operation is upload. + * @since 4.7 + */ + public boolean isUpload() { + return operation.equals(UPLOAD); + } + + /** + * @return true if the operation is download. + * @since 4.7 + */ + public boolean isDownload() { + return operation.equals(DOWNLOAD); + } + + /** + * @return true if the operation is verify. + * @since 4.7 + */ + public boolean isVerify() { + return operation.equals(VERIFY); + } } @Override @@ -179,9 +260,13 @@ protected void doPost(HttpServletRequest req, HttpServletResponse res) res.setContentType(CONTENTTYPE_VND_GIT_LFS_JSON); LargeFileRepository repo = null; try { - repo = getLargeFileRepository(request, path); + repo = getLargeFileRepository(request, path, + req.getHeader(HDR_AUTHORIZATION)); if (repo == null) { - throw new LfsException("unexpected error"); //$NON-NLS-1$ + String error = MessageFormat + .format(LfsText.get().lfsFailedToGetRepository, path); + LOG.error(error); + throw new LfsException(error); } res.setStatus(SC_OK); TransferHandler handler = TransferHandler @@ -201,6 +286,8 @@ protected void doPost(HttpServletRequest req, HttpServletResponse res) sendError(res, w, SC_INSUFFICIENT_STORAGE, e.getMessage()); } catch (LfsUnavailable e) { sendError(res, w, SC_SERVICE_UNAVAILABLE, e.getMessage()); + } catch (LfsUnauthorized e) { + sendError(res, w, SC_UNAUTHORIZED, e.getMessage()); } catch (LfsException e) { sendError(res, w, SC_INTERNAL_SERVER_ERROR, e.getMessage()); } finally {
diff --git a/org.eclipse.jgit.lfs.server/src/org/eclipse/jgit/lfs/server/TransferHandler.java b/org.eclipse.jgit.lfs.server/src/org/eclipse/jgit/lfs/server/TransferHandler.java index bf5b61c..86ca2d3 100644 --- a/org.eclipse.jgit.lfs.server/src/org/eclipse/jgit/lfs/server/TransferHandler.java +++ b/org.eclipse.jgit.lfs.server/src/org/eclipse/jgit/lfs/server/TransferHandler.java
@@ -44,6 +44,9 @@ package org.eclipse.jgit.lfs.server; import static javax.servlet.http.HttpServletResponse.SC_NOT_FOUND; +import static org.eclipse.jgit.lfs.lib.Constants.DOWNLOAD; +import static org.eclipse.jgit.lfs.lib.Constants.UPLOAD; +import static org.eclipse.jgit.lfs.lib.Constants.VERIFY; import java.io.IOException; import java.text.MessageFormat; @@ -58,18 +61,14 @@ abstract class TransferHandler { - private static final String DOWNLOAD = "download"; //$NON-NLS-1$ - private static final String UPLOAD = "upload"; //$NON-NLS-1$ - private static final String VERIFY = "verify"; //$NON-NLS-1$ - static TransferHandler forOperation(String operation, LargeFileRepository repository, List<LfsObject> objects) { switch (operation) { - case TransferHandler.UPLOAD: + case UPLOAD: return new Upload(repository, objects); - case TransferHandler.DOWNLOAD: + case DOWNLOAD: return new Download(repository, objects); - case TransferHandler.VERIFY: + case VERIFY: default: throw new UnsupportedOperationException(MessageFormat.format( LfsServerText.get().unsupportedOperation, operation));
diff --git a/org.eclipse.jgit.lfs.server/src/org/eclipse/jgit/lfs/server/fs/FileLfsServlet.java b/org.eclipse.jgit.lfs.server/src/org/eclipse/jgit/lfs/server/fs/FileLfsServlet.java index a8e3c11..15c4448 100644 --- a/org.eclipse.jgit.lfs.server/src/org/eclipse/jgit/lfs/server/fs/FileLfsServlet.java +++ b/org.eclipse.jgit.lfs.server/src/org/eclipse/jgit/lfs/server/fs/FileLfsServlet.java
@@ -202,6 +202,11 @@ static class Error { */ protected static void sendError(HttpServletResponse rsp, int status, String message) throws IOException { + if (rsp.isCommitted()) { + rsp.getOutputStream().close(); + return; + } + rsp.reset(); rsp.setStatus(status); PrintWriter writer = rsp.getWriter(); gson.toJson(new Error(message), writer);
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 f179b6c..a76f7ef 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
@@ -61,9 +61,11 @@ import org.eclipse.jgit.util.HttpSupport; /** - * Handle asynchronous large object download + * Handle asynchronous large object download. + * + * @since 4.7 */ -class ObjectDownloadListener implements WriteListener { +public class ObjectDownloadListener implements WriteListener { private static Logger LOG = Logger .getLogger(ObjectDownloadListener.class.getName()); @@ -78,7 +80,7 @@ class ObjectDownloadListener implements WriteListener { private final WritableByteChannel outChannel; - private final ByteBuffer buffer = ByteBuffer.allocateDirect(8192); + private ByteBuffer buffer = ByteBuffer.allocateDirect(8192); /** * @param repository @@ -113,19 +115,35 @@ public ObjectDownloadListener(FileLfsRepository repository, @Override public void onWritePossible() throws IOException { while (out.isReady()) { - if (in.read(buffer) != -1) { - buffer.flip(); - outChannel.write(buffer); - buffer.compact(); - } else { - in.close(); - buffer.flip(); - while (out.isReady()) { - if (buffer.hasRemaining()) { - outChannel.write(buffer); - } else { + try { + buffer.clear(); + if (in.read(buffer) < 0) { + buffer = null; + } else { + buffer.flip(); + } + } catch (Throwable t) { + LOG.log(Level.SEVERE, t.getMessage(), t); + buffer = null; + } finally { + if (buffer != null) { + outChannel.write(buffer); + } else { + try { + in.close(); + } catch (IOException e) { + LOG.log(Level.SEVERE, e.getMessage(), e); + } + try { + out.close(); + } finally { context.complete(); } + // This is need to avoid endless loop in recent Jetty versions. + // That's because out.isReady() is returning true for already + // closed streams and because out.close() doesn't throw any + // exception any more when trying to close already closed stream. + return; } } }
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 84e4e6f..da86880 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
@@ -150,7 +150,9 @@ protected void close() throws IOException { channel.close(); // TODO check if status 200 is ok for PUT request, HTTP foresees 204 // for successful PUT without response body - response.setStatus(HttpServletResponse.SC_OK); + if (!response.isCommitted()) { + response.setStatus(HttpServletResponse.SC_OK); + } } finally { context.complete(); }
diff --git a/org.eclipse.jgit.lfs.server/src/org/eclipse/jgit/lfs/server/s3/S3Repository.java b/org.eclipse.jgit.lfs.server/src/org/eclipse/jgit/lfs/server/s3/S3Repository.java index c229758..ed896ad 100644 --- a/org.eclipse.jgit.lfs.server/src/org/eclipse/jgit/lfs/server/s3/S3Repository.java +++ b/org.eclipse.jgit.lfs.server/src/org/eclipse/jgit/lfs/server/s3/S3Repository.java
@@ -94,10 +94,10 @@ public S3Repository(S3Config config) { @Override public Response.Action getDownloadAction(AnyLongObjectId oid) { URL endpointUrl = getObjectUrl(oid); - Map<String, String> queryParams = new HashMap<String, String>(); + Map<String, String> queryParams = new HashMap<>(); queryParams.put(X_AMZ_EXPIRES, Integer.toString(s3Config.getExpirationSeconds())); - Map<String, String> headers = new HashMap<String, String>(); + Map<String, String> headers = new HashMap<>(); String authorizationQueryParameters = SignerV4.createAuthorizationQuery( s3Config, endpointUrl, METHOD_GET, headers, queryParams, UNSIGNED_PAYLOAD); @@ -111,7 +111,7 @@ public Response.Action getDownloadAction(AnyLongObjectId oid) { public Response.Action getUploadAction(AnyLongObjectId oid, long size) { cacheObjectMetaData(oid, size); URL objectUrl = getObjectUrl(oid); - Map<String, String> headers = new HashMap<String, String>(); + Map<String, String> headers = new HashMap<>(); headers.put(X_AMZ_CONTENT_SHA256, oid.getName()); headers.put(HDR_CONTENT_LENGTH, Long.toString(size)); headers.put(X_AMZ_STORAGE_CLASS, s3Config.getStorageClass()); @@ -134,10 +134,10 @@ public Action getVerifyAction(AnyLongObjectId id) { @Override public long getSize(AnyLongObjectId oid) throws IOException { URL endpointUrl = getObjectUrl(oid); - Map<String, String> queryParams = new HashMap<String, String>(); + Map<String, String> queryParams = new HashMap<>(); queryParams.put(X_AMZ_EXPIRES, Integer.toString(s3Config.getExpirationSeconds())); - Map<String, String> headers = new HashMap<String, String>(); + Map<String, String> headers = new HashMap<>(); String authorizationQueryParameters = SignerV4.createAuthorizationQuery( s3Config, endpointUrl, METHOD_HEAD, headers, queryParams,
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 f95b605..a9b0ec4 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
@@ -57,6 +57,7 @@ import java.util.Date; import java.util.Iterator; import java.util.List; +import java.util.Locale; import java.util.Map; import java.util.SimpleTimeZone; import java.util.SortedMap; @@ -239,7 +240,7 @@ private static void addHostHeader(URL url, private static String canonicalizeHeaderNames( Map<String, String> headers) { - List<String> sortedHeaders = new ArrayList<String>(); + List<String> sortedHeaders = new ArrayList<>(); sortedHeaders.addAll(headers.keySet()); Collections.sort(sortedHeaders, String.CASE_INSENSITIVE_ORDER); @@ -247,7 +248,7 @@ private static String canonicalizeHeaderNames( for (String header : sortedHeaders) { if (buffer.length() > 0) buffer.append(";"); //$NON-NLS-1$ - buffer.append(header.toLowerCase()); + buffer.append(header.toLowerCase(Locale.ROOT)); } return buffer.toString(); @@ -259,13 +260,14 @@ private static String canonicalizeHeaderString( return ""; //$NON-NLS-1$ } - List<String> sortedHeaders = new ArrayList<String>(); + List<String> sortedHeaders = new ArrayList<>(); sortedHeaders.addAll(headers.keySet()); Collections.sort(sortedHeaders, String.CASE_INSENSITIVE_ORDER); StringBuilder buffer = new StringBuilder(); for (String key : sortedHeaders) { - buffer.append(key.toLowerCase().replaceAll("\\s+", " ") + ":" //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ + buffer.append( + key.toLowerCase(Locale.ROOT).replaceAll("\\s+", " ") + ":" //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ + headers.get(key).replaceAll("\\s+", " ")); //$NON-NLS-1$//$NON-NLS-2$ buffer.append("\n"); //$NON-NLS-1$ } @@ -303,7 +305,7 @@ private static String canonicalizeQueryString( return ""; //$NON-NLS-1$ } - SortedMap<String, String> sorted = new TreeMap<String, String>(); + SortedMap<String, String> sorted = new TreeMap<>(); Iterator<Map.Entry<String, String>> pairs = parameters.entrySet() .iterator();
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 10c29d5..64f7498 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
@@ -56,7 +56,7 @@ org.eclipse.jdt.core.compiler.problem.missingJavadocTagsMethodTypeParameters=disabled org.eclipse.jdt.core.compiler.problem.missingJavadocTagsOverriding=disabled org.eclipse.jdt.core.compiler.problem.missingJavadocTagsVisibility=private -org.eclipse.jdt.core.compiler.problem.missingOverrideAnnotation=ignore +org.eclipse.jdt.core.compiler.problem.missingOverrideAnnotation=warning org.eclipse.jdt.core.compiler.problem.missingOverrideAnnotationForInterfaceMethodImplementation=enabled org.eclipse.jdt.core.compiler.problem.missingSerialVersion=warning org.eclipse.jdt.core.compiler.problem.missingSynchronizedOnInheritedMethod=ignore @@ -76,7 +76,7 @@ org.eclipse.jdt.core.compiler.problem.rawTypeReference=ignore org.eclipse.jdt.core.compiler.problem.redundantNullAnnotation=warning org.eclipse.jdt.core.compiler.problem.redundantNullCheck=warning -org.eclipse.jdt.core.compiler.problem.redundantSpecificationOfTypeArguments=ignore +org.eclipse.jdt.core.compiler.problem.redundantSpecificationOfTypeArguments=warning org.eclipse.jdt.core.compiler.problem.redundantSuperinterface=error org.eclipse.jdt.core.compiler.problem.reportMethodCanBePotentiallyStatic=ignore org.eclipse.jdt.core.compiler.problem.reportMethodCanBeStatic=ignore
diff --git a/org.eclipse.jgit.lfs.test/BUCK b/org.eclipse.jgit.lfs.test/BUCK deleted file mode 100644 index 1298e16..0000000 --- a/org.eclipse.jgit.lfs.test/BUCK +++ /dev/null
@@ -1,30 +0,0 @@ -TESTS = glob(['tst/**/*.java']) - -for t in TESTS: - n = t[len('tst/'):len(t)-len('.java')].replace('/', '.') - java_test( - name = n, - labels = ['lfs'], - srcs = [t], - deps = [ - ':helpers', - '//org.eclipse.jgit.junit:junit', - '//org.eclipse.jgit.lfs:jgit-lfs', - '//org.eclipse.jgit:jgit', - '//lib:hamcrest-core', - '//lib:hamcrest-library', - '//lib:junit', - ], - ) - -java_library( - name = 'helpers', - srcs = glob(['src/**/*.java']), - deps = [ - '//org.eclipse.jgit:jgit', - '//org.eclipse.jgit.lfs:jgit-lfs', - '//org.eclipse.jgit.junit:junit', - '//lib:junit', - ], - visibility = ['PUBLIC'] -)
diff --git a/org.eclipse.jgit.lfs.test/BUILD b/org.eclipse.jgit.lfs.test/BUILD new file mode 100644 index 0000000..213ba57 --- /dev/null +++ b/org.eclipse.jgit.lfs.test/BUILD
@@ -0,0 +1,31 @@ +package(default_visibility = ["//visibility:public"]) + +load( + "@com_googlesource_gerrit_bazlets//tools:junit.bzl", + "junit_tests", +) + +junit_tests( + name = "lfs", + srcs = glob(["tst/**/*.java"]), + tags = ["lfs"], + deps = [ + ":helpers", + "//lib:junit", + "//org.eclipse.jgit:jgit", + "//org.eclipse.jgit.junit:junit", + "//org.eclipse.jgit.lfs:jgit-lfs", + ], +) + +java_library( + name = "helpers", + testonly = 1, + srcs = glob(["src/**/*.java"]), + deps = [ + "//lib:junit", + "//org.eclipse.jgit:jgit", + "//org.eclipse.jgit.junit:junit", + "//org.eclipse.jgit.lfs:jgit-lfs", + ], +)
diff --git a/org.eclipse.jgit.lfs.test/META-INF/MANIFEST.MF b/org.eclipse.jgit.lfs.test/META-INF/MANIFEST.MF index e859f63..6bd2adb 100644 --- a/org.eclipse.jgit.lfs.test/META-INF/MANIFEST.MF +++ b/org.eclipse.jgit.lfs.test/META-INF/MANIFEST.MF
@@ -2,19 +2,23 @@ Bundle-ManifestVersion: 2 Bundle-Name: %plugin_name Bundle-SymbolicName: org.eclipse.jgit.lfs.test -Bundle-Version: 4.6.2.qualifier +Bundle-Version: 4.7.6.qualifier Bundle-Vendor: %provider_name Bundle-Localization: plugin Bundle-RequiredExecutionEnvironment: JavaSE-1.8 -Import-Package: org.eclipse.jgit.junit;version="[4.6.2,4.7.0)", - org.eclipse.jgit.lfs;version="[4.6.2,4.7.0)", - org.eclipse.jgit.lfs.errors;version="[4.6.2,4.7.0)", - org.eclipse.jgit.lfs.lib;version="[4.6.2,4.7.0)", - org.eclipse.jgit.lib;version="[4.6.2,4.7.0)", - org.eclipse.jgit.util;version="[4.6.2,4.7.0)", +Import-Package: org.eclipse.jgit.internal.storage.dfs;version="[4.7.6,4.8.0)", + org.eclipse.jgit.junit;version="[4.7.6,4.8.0)", + org.eclipse.jgit.lfs;version="[4.7.6,4.8.0)", + org.eclipse.jgit.lfs.errors;version="[4.7.6,4.8.0)", + org.eclipse.jgit.lfs.lib;version="[4.7.6,4.8.0)", + org.eclipse.jgit.lib;version="[4.7.6,4.8.0)", + org.eclipse.jgit.revwalk;version="[4.7.6,4.8.0)", + org.eclipse.jgit.treewalk;version="[4.7.6,4.8.0)", + org.eclipse.jgit.treewalk.filter;version="[4.7.6,4.8.0)", + org.eclipse.jgit.util;version="[4.7.6,4.8.0)", org.hamcrest.core;version="[1.1.0,2.0.0)", org.junit;version="[4.0.0,5.0.0)", org.junit.runner;version="[4.0.0,5.0.0)", org.junit.runners;version="[4.0.0,5.0.0)" -Export-Package: org.eclipse.jgit.lfs.test;version="4.6.2";x-friends:="org.eclipse.jgit.lfs.server.test" +Export-Package: org.eclipse.jgit.lfs.test;version="4.7.6";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 a06aefc..2f52e7d 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>4.6.2-SNAPSHOT</version> + <version>4.7.6-SNAPSHOT</version> </parent> <artifactId>org.eclipse.jgit.lfs.test</artifactId>
diff --git a/org.eclipse.jgit.lfs.test/tst/org/eclipse/jgit/lfs/lib/LfsPointerFilterTest.java b/org.eclipse.jgit.lfs.test/tst/org/eclipse/jgit/lfs/lib/LfsPointerFilterTest.java new file mode 100644 index 0000000..a56f0df --- /dev/null +++ b/org.eclipse.jgit.lfs.test/tst/org/eclipse/jgit/lfs/lib/LfsPointerFilterTest.java
@@ -0,0 +1,214 @@ +/* + * Copyright (C) 2015, Dariusz Luksza <dariusz@luksza.org> + * 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.lfs.lib; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertNull; +import static org.junit.Assert.assertTrue; + +import 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.revwalk.ObjectWalk; +import org.eclipse.jgit.revwalk.RevCommit; +import org.eclipse.jgit.revwalk.RevTree; +import org.eclipse.jgit.treewalk.TreeWalk; +import org.junit.Test; + +public class LfsPointerFilterTest { + + private static final int SIZE = 12345; + + private static final String OID = "4d7a214614ab2935c943f9e0ff69d22eadbb8f32b1258daaa5e2ca24d17e2393"; + + private static final String[] NOT_VALID_LFS_FILES = { "", // empty file + // simulate java file + "package org.eclipse.jgit;", + // invalid LFS pointer, no oid and version + "version https://hawser.github.com/spec/v1\n", + // invalid LFS pointer, no version + "version https://hawser.github.com/spec/v1\n" + + "oid sha256:4d7a214614ab2935c943f9e0ff69d22eadbb8f32b1258daaa5e2ca24d17e2393\n", + // invalid LFS pointer, no id + "version https://hawser.github.com/spec/v1\n" + "size 12345\n", + // invalid LFS pointer, wrong order of oid and size + "version https://hawser.github.com/spec/v1\n" + "size 12345\n" + + "oid sha256:4d7a214614ab2935c943f9e0ff69d22eadbb8f32b1258daaa5e2ca24d17e2393\n" }; + + private static final String[] LFS_VERSION_DOMAINS = { + "hawser", "git-lfs" + }; + + private static final String[] VALID_LFS_FILES = { + // valid LFS pointer + "version https://%s.github.com/spec/v1\n" + + "oid sha256:" + OID + "\n" + + "size " + SIZE + "\n", + // valid LFS pointer with "custom" key + "version https://%s.github.com/spec/v1\n" + + "custom key with value\n" + + "oid sha256:" + OID + "\n" + + "size " + SIZE + "\n", + // valid LFS pointer with key with "." + "version https://%s.github.com/spec/v1\n" + + "oid sha256:" + OID + "\n" + + "r.key key with .\n" + + "size " + SIZE + "\n", + // valid LFS pointer with key with "-" + "version https://%s.github.com/spec/v1\n" + + "oid sha256:" + OID + "\n" + + "size " + SIZE + "\n" + + "valid-name another valid key\n" }; + + @Test + public void testRegularFilesInRepositoryRoot() throws Exception { + for (String file : NOT_VALID_LFS_FILES) { + assertLfs("file.bin", file).withRecursive(false).shouldBe(false); + } + } + + @Test + public void testNestedRegularFiles() throws Exception { + for (String file : NOT_VALID_LFS_FILES) { + assertLfs("a/file.bin", file).withRecursive(true).shouldBe(false); + } + } + + @Test + public void testValidPointersInRepositoryRoot() throws Exception { + for (String domain : LFS_VERSION_DOMAINS) { + for (String file : VALID_LFS_FILES) { + assertLfs("file.bin", String.format(file, domain)) + .withRecursive(true).shouldBe(true) + .check(); + } + } + } + + @Test + public void testValidNestedPointers() throws Exception { + for (String domain : LFS_VERSION_DOMAINS) { + for (String file : VALID_LFS_FILES) { + assertLfs("a/file.bin", String.format(file, domain)) + .withRecursive(true).shouldBe(true).check(); + } + } + } + + @Test + public void testValidNestedPointersWithoutRecurrence() throws Exception { + for (String domain : LFS_VERSION_DOMAINS) { + for (String file : VALID_LFS_FILES) { + assertLfs("file.bin", String.format(file, domain)) + .withRecursive(false).shouldBe(true).check(); + assertLfs("a/file.bin", String.format(file, domain)) + .withRecursive(false).shouldBe(false).check(); + } + } + } + + private static LfsTreeWalk assertLfs(String path, String content) { + return new LfsTreeWalk(path, content); + } + + private static class LfsTreeWalk { + private final String path; + + private final String content; + + private boolean state; + + private boolean recursive; + + private TestRepository<InMemoryRepository> tr; + + LfsTreeWalk(String path, String content) { + this.path = path; + this.content = content; + } + + LfsTreeWalk withRecursive(boolean shouldBeRecursive) { + this.recursive = shouldBeRecursive; + return this; + } + + LfsTreeWalk shouldBe(boolean shouldBeValid) { + this.state = shouldBeValid; + return this; + } + + void check() throws Exception { + tr = new TestRepository<>(new InMemoryRepository( + new DfsRepositoryDescription("test"))); + RevCommit commit = tr.branch("master").commit().add(path, content) + .message("initial commit").create(); + RevTree tree = parseCommit(commit); + LfsPointerFilter filter = new LfsPointerFilter(); + try (TreeWalk treeWalk = new TreeWalk(tr.getRepository())) { + treeWalk.addTree(tree); + treeWalk.setRecursive(recursive); + treeWalk.setFilter(filter); + + if (state) { + assertTrue(treeWalk.next()); + assertEquals(path, treeWalk.getPathString()); + assertNotNull(filter.getPointer()); + assertEquals(SIZE, filter.getPointer().getSize()); + assertEquals(OID, filter.getPointer().getOid().name()); + } else { + assertFalse(treeWalk.next()); + assertNull(filter.getPointer()); + } + } + } + + private RevTree parseCommit(RevCommit commit) throws Exception { + try (ObjectWalk ow = new ObjectWalk(tr.getRepository())) { + return ow.parseCommit(commit).getTree(); + } + } + } +}
diff --git a/org.eclipse.jgit.lfs.test/tst/org/eclipse/jgit/lfs/lib/LongObjectIdTest.java b/org.eclipse.jgit.lfs.test/tst/org/eclipse/jgit/lfs/lib/LongObjectIdTest.java index 435a2a3..e754d6f 100644 --- a/org.eclipse.jgit.lfs.test/tst/org/eclipse/jgit/lfs/lib/LongObjectIdTest.java +++ b/org.eclipse.jgit.lfs.test/tst/org/eclipse/jgit/lfs/lib/LongObjectIdTest.java
@@ -57,6 +57,7 @@ import java.nio.charset.StandardCharsets; import java.nio.file.Files; import java.nio.file.Path; +import java.util.Locale; import org.eclipse.jgit.junit.JGitTestUtil; import org.eclipse.jgit.lfs.errors.InvalidLongObjectIdException; @@ -152,7 +153,7 @@ public void test010_toString() { public void test011_toString() { final String x = "0123456789ABCDEFabcdef01234567890123456789ABCDEFabcdef0123456789"; final LongObjectId oid = LongObjectId.fromString(x); - assertEquals(x.toLowerCase(), oid.name()); + assertEquals(x.toLowerCase(Locale.ROOT), oid.name()); } @Test @@ -290,7 +291,6 @@ public void testCompareTo() { "0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef"); assertEquals(0, id1.compareTo(LongObjectId.fromString( "0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef"))); - assertEquals(0, id1.compareTo(id1)); assertEquals(-1, id1.compareTo(LongObjectId.fromString( "1123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef")));
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 808ec3a..ede0f7d 100644 --- a/org.eclipse.jgit.lfs/.settings/org.eclipse.jdt.core.prefs +++ b/org.eclipse.jgit.lfs/.settings/org.eclipse.jdt.core.prefs
@@ -56,7 +56,7 @@ org.eclipse.jdt.core.compiler.problem.missingJavadocTagsMethodTypeParameters=disabled org.eclipse.jdt.core.compiler.problem.missingJavadocTagsOverriding=disabled org.eclipse.jdt.core.compiler.problem.missingJavadocTagsVisibility=private -org.eclipse.jdt.core.compiler.problem.missingOverrideAnnotation=ignore +org.eclipse.jdt.core.compiler.problem.missingOverrideAnnotation=warning org.eclipse.jdt.core.compiler.problem.missingOverrideAnnotationForInterfaceMethodImplementation=enabled org.eclipse.jdt.core.compiler.problem.missingSerialVersion=warning org.eclipse.jdt.core.compiler.problem.missingSynchronizedOnInheritedMethod=ignore @@ -76,7 +76,7 @@ org.eclipse.jdt.core.compiler.problem.rawTypeReference=ignore org.eclipse.jdt.core.compiler.problem.redundantNullAnnotation=warning org.eclipse.jdt.core.compiler.problem.redundantNullCheck=warning -org.eclipse.jdt.core.compiler.problem.redundantSpecificationOfTypeArguments=ignore +org.eclipse.jdt.core.compiler.problem.redundantSpecificationOfTypeArguments=warning org.eclipse.jdt.core.compiler.problem.redundantSuperinterface=error org.eclipse.jdt.core.compiler.problem.reportMethodCanBePotentiallyStatic=ignore org.eclipse.jdt.core.compiler.problem.reportMethodCanBeStatic=ignore
diff --git a/org.eclipse.jgit.lfs/BUCK b/org.eclipse.jgit.lfs/BUCK deleted file mode 100644 index ddb3a10..0000000 --- a/org.eclipse.jgit.lfs/BUCK +++ /dev/null
@@ -1,17 +0,0 @@ -SRCS = glob(['src/**']) -RESOURCES = glob(['resources/**']) - -java_library( - name = 'jgit-lfs', - srcs = SRCS, - resources = RESOURCES, - deps = [ - '//org.eclipse.jgit:jgit' - ], - visibility = ['PUBLIC'], -) - -java_sources( - name = 'jgit-lfs_src', - srcs = SRCS + RESOURCES, -)
diff --git a/org.eclipse.jgit.lfs/BUILD b/org.eclipse.jgit.lfs/BUILD new file mode 100644 index 0000000..c4c9f8a --- /dev/null +++ b/org.eclipse.jgit.lfs/BUILD
@@ -0,0 +1,11 @@ +package(default_visibility = ["//visibility:public"]) + +java_library( + name = "jgit-lfs", + srcs = glob(["src/**"]), + resource_strip_prefix = "org.eclipse.jgit.lfs/resources", + resources = glob(["resources/**"]), + deps = [ + "//org.eclipse.jgit:jgit", + ], +)
diff --git a/org.eclipse.jgit.lfs/META-INF/MANIFEST.MF b/org.eclipse.jgit.lfs/META-INF/MANIFEST.MF index d5d1f7c..f46f6a0 100644 --- a/org.eclipse.jgit.lfs/META-INF/MANIFEST.MF +++ b/org.eclipse.jgit.lfs/META-INF/MANIFEST.MF
@@ -2,17 +2,20 @@ Bundle-ManifestVersion: 2 Bundle-Name: %plugin_name Bundle-SymbolicName: org.eclipse.jgit.lfs -Bundle-Version: 4.6.2.qualifier +Bundle-Version: 4.7.6.qualifier Bundle-Localization: plugin Bundle-Vendor: %provider_name -Export-Package: org.eclipse.jgit.lfs;version="4.6.2", - org.eclipse.jgit.lfs.errors;version="4.6.2", - org.eclipse.jgit.lfs.internal;version="4.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="4.6.2" +Export-Package: org.eclipse.jgit.lfs;version="4.7.6", + org.eclipse.jgit.lfs.errors;version="4.7.6", + org.eclipse.jgit.lfs.internal;version="4.7.6";x-friends:="org.eclipse.jgit.lfs.test,org.eclipse.jgit.lfs.server.fs,org.eclipse.jgit.lfs.server", + org.eclipse.jgit.lfs.lib;version="4.7.6" Bundle-RequiredExecutionEnvironment: JavaSE-1.8 -Import-Package: org.eclipse.jgit.annotations;version="[4.6.2,4.7.0)";resolution:=optional, - org.eclipse.jgit.attributes;version="[4.6.2,4.7.0)", - org.eclipse.jgit.internal.storage.file;version="[4.6.2,4.7.0)", - org.eclipse.jgit.lib;version="[4.6.2,4.7.0)", - org.eclipse.jgit.nls;version="[4.6.2,4.7.0)", - org.eclipse.jgit.util;version="[4.6.2,4.7.0)" +Import-Package: org.eclipse.jgit.annotations;version="[4.7.6,4.8.0)";resolution:=optional, + org.eclipse.jgit.attributes;version="[4.7.6,4.8.0)", + org.eclipse.jgit.errors;version="[4.7.6,4.8.0)", + org.eclipse.jgit.internal.storage.file;version="[4.7.6,4.8.0)", + org.eclipse.jgit.lib;version="[4.7.6,4.8.0)", + org.eclipse.jgit.nls;version="[4.7.6,4.8.0)", + org.eclipse.jgit.treewalk;version="[4.7.6,4.8.0)", + org.eclipse.jgit.treewalk.filter;version="[4.7.6,4.8.0)", + org.eclipse.jgit.util;version="[4.7.6,4.8.0)"
diff --git a/org.eclipse.jgit.lfs/pom.xml b/org.eclipse.jgit.lfs/pom.xml index 049b360..f276963 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>4.6.2-SNAPSHOT</version> + <version>4.7.6-SNAPSHOT</version> </parent> <artifactId>org.eclipse.jgit.lfs</artifactId>
diff --git a/org.eclipse.jgit.lfs/resources/org/eclipse/jgit/lfs/internal/LfsText.properties b/org.eclipse.jgit.lfs/resources/org/eclipse/jgit/lfs/internal/LfsText.properties index 5e52a78..e08e28c 100644 --- a/org.eclipse.jgit.lfs/resources/org/eclipse/jgit/lfs/internal/LfsText.properties +++ b/org.eclipse.jgit.lfs/resources/org/eclipse/jgit/lfs/internal/LfsText.properties
@@ -7,3 +7,5 @@ repositoryNotFound=Repository {0} not found repositoryReadOnly=Repository {0} is read-only lfsUnavailable=LFS is not available for repository {0} +lfsUnathorized=Not authorized to perform operation {0} on repository {1} +lfsFailedToGetRepository=failed to get repository {0}
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 66feca7..b78ee04 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
@@ -130,6 +130,7 @@ public CleanFilter(Repository db, InputStream in, OutputStream out) this.aOut = new AtomicObjectOutputStream(tmpFile.toAbsolutePath()); } + @Override public int run() throws IOException { try { byte[] buf = new byte[8192]; @@ -151,7 +152,10 @@ public int run() throws IOException { FileUtils.delete(tmpFile.toFile()); } } else { - FileUtils.mkdirs(mediaFile.getParent().toFile(), true); + Path parent = mediaFile.getParent(); + if (parent != null) { + FileUtils.mkdirs(parent.toFile(), true); + } FileUtils.rename(tmpFile.toFile(), mediaFile.toFile(), StandardCopyOption.ATOMIC_MOVE); }
diff --git a/org.eclipse.jgit.lfs/src/org/eclipse/jgit/lfs/LfsPointer.java b/org.eclipse.jgit.lfs/src/org/eclipse/jgit/lfs/LfsPointer.java index bbea535..0f62025 100644 --- a/org.eclipse.jgit.lfs/src/org/eclipse/jgit/lfs/LfsPointer.java +++ b/org.eclipse.jgit.lfs/src/org/eclipse/jgit/lfs/LfsPointer.java
@@ -51,6 +51,7 @@ import java.io.UnsupportedEncodingException; import java.nio.charset.StandardCharsets; import java.nio.charset.UnsupportedCharsetException; +import java.util.Locale; import org.eclipse.jgit.annotations.Nullable; import org.eclipse.jgit.lfs.lib.AnyLongObjectId; @@ -69,11 +70,17 @@ public class LfsPointer { public static final String VERSION = "https://git-lfs.github.com/spec/v1"; //$NON-NLS-1$ /** + * The version of the LfsPointer file format using legacy URL + * @since 4.7 + */ + public static final String VERSION_LEGACY = "https://hawser.github.com/spec/v1"; //$NON-NLS-1$ + + /** * The name of the hash function as used in the pointer files. This will * evaluate to "sha256" */ public static final String HASH_FUNCTION_NAME = Constants.LONG_HASH_FUNCTION - .toLowerCase().replace("-", ""); //$NON-NLS-1$ //$NON-NLS-2$ + .toLowerCase(Locale.ROOT).replace("-", ""); //$NON-NLS-1$ //$NON-NLS-2$ private AnyLongObjectId oid; @@ -150,14 +157,13 @@ public static LfsPointer parseLfsPointer(InputStream in) if (s.startsWith("#") || s.length() == 0) { //$NON-NLS-1$ continue; } else if (s.startsWith("version") && s.length() > 8 //$NON-NLS-1$ - && s.substring(8).trim().equals(VERSION)) { + && (s.substring(8).trim().equals(VERSION) || + s.substring(8).trim().equals(VERSION_LEGACY))) { versionLine = true; } else if (s.startsWith("oid sha256:")) { //$NON-NLS-1$ id = LongObjectId.fromString(s.substring(11).trim()); } else if (s.startsWith("size") && s.length() > 5) { //$NON-NLS-1$ sz = Long.parseLong(s.substring(5).trim()); - } else { - return null; } } if (versionLine && id != null && sz > -1) {
diff --git a/org.eclipse.jgit.lfs/src/org/eclipse/jgit/lfs/errors/LfsUnauthorized.java b/org.eclipse.jgit.lfs/src/org/eclipse/jgit/lfs/errors/LfsUnauthorized.java new file mode 100644 index 0000000..62b0cde --- /dev/null +++ b/org.eclipse.jgit.lfs/src/org/eclipse/jgit/lfs/errors/LfsUnauthorized.java
@@ -0,0 +1,68 @@ +/* + * Copyright (C) 2017, David Pursehouse <david.pursehouse@gmail.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.lfs.errors; + +import java.text.MessageFormat; + +import org.eclipse.jgit.lfs.internal.LfsText; + +/** + * Thrown when authorization was refused for an LFS operation. + * + * @since 4.7 + */ +public class LfsUnauthorized extends LfsException { + private static final long serialVersionUID = 1L; + + /** + * @param operation + * the operation that was attempted. + * @param name + * the repository name. + */ + public LfsUnauthorized(String operation, String name) { + super(MessageFormat.format(LfsText.get().lfsUnathorized, operation, + name)); + } +}
diff --git a/org.eclipse.jgit.lfs/src/org/eclipse/jgit/lfs/internal/LfsText.java b/org.eclipse.jgit.lfs/src/org/eclipse/jgit/lfs/internal/LfsText.java index c76df39..4459588 100644 --- a/org.eclipse.jgit.lfs/src/org/eclipse/jgit/lfs/internal/LfsText.java +++ b/org.eclipse.jgit.lfs/src/org/eclipse/jgit/lfs/internal/LfsText.java
@@ -67,4 +67,6 @@ public static LfsText get() { /***/ public String repositoryNotFound; /***/ public String repositoryReadOnly; /***/ public String lfsUnavailable; + /***/ public String lfsUnathorized; + /***/ public String lfsFailedToGetRepository; }
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 1f0df88..caf034d 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
@@ -171,6 +171,7 @@ public final int getByte(int index) { * @return < 0 if this id comes before other; 0 if this id is equal to * other; > 0 if this id comes after other. */ + @Override public final int compareTo(final AnyLongObjectId other) { if (this == other) return 0; @@ -262,6 +263,7 @@ public boolean startsWith(final AbbreviatedLongObjectId abbr) { return abbr.prefixCompare(this) == 0; } + @Override public final int hashCode() { return (int) (w1 >> 32); } @@ -277,6 +279,7 @@ public final boolean equals(final AnyLongObjectId other) { return other != null ? equals(this, other) : false; } + @Override public final boolean equals(final Object o) { if (o instanceof AnyLongObjectId) return equals((AnyLongObjectId) o);
diff --git a/org.eclipse.jgit.lfs/src/org/eclipse/jgit/lfs/lib/Constants.java b/org.eclipse.jgit.lfs/src/org/eclipse/jgit/lfs/lib/Constants.java index a88057a..0220743 100644 --- a/org.eclipse.jgit.lfs/src/org/eclipse/jgit/lfs/lib/Constants.java +++ b/org.eclipse.jgit.lfs/src/org/eclipse/jgit/lfs/lib/Constants.java
@@ -87,6 +87,27 @@ public final class Constants { * 2; /** + * LFS upload operation. + * + * @since 4.7 + */ + public static final String UPLOAD = "upload"; + + /** + * LFS download operation. + * + * @since 4.7 + */ + public static final String DOWNLOAD = "download"; + + /** + * LFS verify operation. + * + * @since 4.7 + */ + public static final String VERIFY = "verify"; + + /** * Create a new digest function for objects. * * @return a new digest object.
diff --git a/org.eclipse.jgit.lfs/src/org/eclipse/jgit/lfs/lib/LfsPointerFilter.java b/org.eclipse.jgit.lfs/src/org/eclipse/jgit/lfs/lib/LfsPointerFilter.java new file mode 100644 index 0000000..6f672b8 --- /dev/null +++ b/org.eclipse.jgit.lfs/src/org/eclipse/jgit/lfs/lib/LfsPointerFilter.java
@@ -0,0 +1,103 @@ +/* + * Copyright (C) 2015, 2017, Dariusz Luksza <dariusz@luksza.org> + * 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.lfs.lib; + +import java.io.IOException; + +import org.eclipse.jgit.errors.IncorrectObjectTypeException; +import org.eclipse.jgit.errors.MissingObjectException; +import org.eclipse.jgit.lfs.LfsPointer; +import org.eclipse.jgit.lib.ObjectId; +import org.eclipse.jgit.lib.ObjectLoader; +import org.eclipse.jgit.lib.ObjectStream; +import org.eclipse.jgit.treewalk.TreeWalk; +import org.eclipse.jgit.treewalk.filter.TreeFilter; + +/** + * Detects Large File pointers, as described in [1] in Git repository. + * + * [1] https://github.com/github/git-lfs/blob/master/docs/spec.md + * + * @since 4.7 + */ +public class LfsPointerFilter extends TreeFilter { + + private LfsPointer pointer; + + /** + * @return {@link LfsPointer} or {@code null} + */ + public LfsPointer getPointer() { + return pointer; + } + + @Override + public boolean include(TreeWalk walk) throws MissingObjectException, + IncorrectObjectTypeException, IOException { + pointer = null; + if (walk.isSubtree()) { + return walk.isRecursive(); + } + ObjectId objectId = walk.getObjectId(0); + ObjectLoader object = walk.getObjectReader().open(objectId); + if (object.getSize() > 1024) { + return false; + } + + try (ObjectStream stream = object.openStream()) { + pointer = LfsPointer.parseLfsPointer(stream); + return pointer != null; + } + } + + @Override + public boolean shouldBeRecursive() { + return false; + } + + @Override + public TreeFilter clone() { + return new LfsPointerFilter(); + } +}
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 85ac88b..5e899d2 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="4.6.2.qualifier" + version="4.7.6.qualifier" provider-name="%providerName"> <description url="http://www.eclipse.org/jgit/">
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 6f75186..4548227 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>4.6.2-SNAPSHOT</version> + <version>4.7.6-SNAPSHOT</version> </parent> <groupId>org.eclipse.jgit.feature</groupId>
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 e272c0b..6873ac5 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="4.6.2.qualifier" + version="4.7.6.qualifier" provider-name="%providerName"> <description url="http://www.eclipse.org/jgit/">
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 679f880..c161bd7 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>4.6.2-SNAPSHOT</version> + <version>4.7.6-SNAPSHOT</version> </parent> <groupId>org.eclipse.jgit.feature</groupId>
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 fe7e3ac..0c7f4a7 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="4.6.2.qualifier" + version="4.7.6.qualifier" provider-name="%providerName"> <description url="http://www.eclipse.org/jgit/">
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 0b0a335..38c5fe0 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>4.6.2-SNAPSHOT</version> + <version>4.7.6-SNAPSHOT</version> </parent> <groupId>org.eclipse.jgit.feature</groupId>
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 4aefd72..85e3bb2 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="4.6.2.qualifier" + version="4.7.6.qualifier" provider-name="%providerName"> <description url="http://www.eclipse.org/jgit/">
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 893c492..0e571e0 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>4.6.2-SNAPSHOT</version> + <version>4.7.6-SNAPSHOT</version> </parent> <groupId>org.eclipse.jgit.feature</groupId>
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 81f5e71..fe58884 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="4.6.2.qualifier" + version="4.7.6.qualifier" provider-name="%providerName"> <description url="http://www.eclipse.org/jgit/"> @@ -31,8 +31,8 @@ version="0.0.0"/> <requires> - <import feature="org.eclipse.jgit" version="4.6.1" match="equivalent"/> - <import feature="org.eclipse.jgit.lfs" version="4.6.1" match="equivalent"/> + <import feature="org.eclipse.jgit" version="4.7.1" match="equivalent"/> + <import feature="org.eclipse.jgit.lfs" version="4.7.1" match="equivalent"/> </requires> <plugin
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 b6c5846..c538ac4 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>4.6.2-SNAPSHOT</version> + <version>4.7.6-SNAPSHOT</version> </parent> <groupId>org.eclipse.jgit.feature</groupId>
diff --git a/org.eclipse.jgit.packaging/org.eclipse.jgit.pgm.source.feature/feature.xml b/org.eclipse.jgit.packaging/org.eclipse.jgit.pgm.source.feature/feature.xml index 444a872..554d6fa 100644 --- a/org.eclipse.jgit.packaging/org.eclipse.jgit.pgm.source.feature/feature.xml +++ b/org.eclipse.jgit.packaging/org.eclipse.jgit.pgm.source.feature/feature.xml
@@ -2,7 +2,7 @@ <feature id="org.eclipse.jgit.pgm.source" label="%featureName" - version="4.6.2.qualifier" + version="4.7.6.qualifier" provider-name="%providerName"> <description url="http://www.eclipse.org/jgit/">
diff --git a/org.eclipse.jgit.packaging/org.eclipse.jgit.pgm.source.feature/pom.xml b/org.eclipse.jgit.packaging/org.eclipse.jgit.pgm.source.feature/pom.xml index a35034a..6869841 100644 --- a/org.eclipse.jgit.packaging/org.eclipse.jgit.pgm.source.feature/pom.xml +++ b/org.eclipse.jgit.packaging/org.eclipse.jgit.pgm.source.feature/pom.xml
@@ -50,7 +50,7 @@ <parent> <groupId>org.eclipse.jgit</groupId> <artifactId>jgit.tycho.parent</artifactId> - <version>4.6.2-SNAPSHOT</version> + <version>4.7.6-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 d611d29..8dfce40 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>4.6.2-SNAPSHOT</version> + <version>4.7.6-SNAPSHOT</version> </parent> <artifactId>org.eclipse.jgit.repository</artifactId>
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 20ab58c..87e705c 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="4.6.2.qualifier" + version="4.7.6.qualifier" provider-name="%providerName"> <description url="http://www.eclipse.org/jgit/">
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 e11e042..d352919 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>4.6.2-SNAPSHOT</version> + <version>4.7.6-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 cd39231..99c41d9 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: 4.6.2.qualifier +Bundle-Version: 4.7.6.qualifier
diff --git a/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.5.target b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.5.target index d0da0c4..be02826 100644 --- a/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.5.target +++ b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.5.target
@@ -1,7 +1,7 @@ <?xml version="1.0" encoding="UTF-8" standalone="no"?> <?pde?> <!-- generated with https://github.com/mbarbero/fr.obeo.releng.targetplatform --> -<target name="jgit-4.5" sequenceNumber="1502746491"> +<target name="jgit-4.5" sequenceNumber="1502747250"> <locations> <location includeMode="slicer" includeAllPlatforms="false" includeSource="true" includeConfigurePhase="true" type="InstallableUnit"> <unit id="org.eclipse.jetty.client" version="9.3.17.v20170317"/>
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 065284d..bcef50b 100644 --- a/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.6.target +++ b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.6.target
@@ -1,7 +1,7 @@ <?xml version="1.0" encoding="UTF-8" standalone="no"?> <?pde?> <!-- generated with https://github.com/mbarbero/fr.obeo.releng.targetplatform --> -<target name="jgit-4.6" sequenceNumber="1502746433"> +<target name="jgit-4.6" sequenceNumber="1502747233"> <locations> <location includeMode="slicer" includeAllPlatforms="false" includeSource="true" includeConfigurePhase="true" type="InstallableUnit"> <unit id="org.eclipse.jetty.client" version="9.3.17.v20170317"/>
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 d3a1131..52ea6f8 100644 --- a/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.7.target +++ b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.7.target
@@ -1,7 +1,7 @@ <?xml version="1.0" encoding="UTF-8" standalone="no"?> <?pde?> <!-- generated with https://github.com/mbarbero/fr.obeo.releng.targetplatform --> -<target name="jgit-4.7" sequenceNumber="1502746477"> +<target name="jgit-4.7" sequenceNumber="1502747215"> <locations> <location includeMode="slicer" includeAllPlatforms="false" includeSource="true" includeConfigurePhase="true" type="InstallableUnit"> <unit id="org.eclipse.jetty.client" version="9.3.17.v20170317"/>
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 652b122..e84c4cc 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>4.6.2-SNAPSHOT</version> + <version>4.7.6-SNAPSHOT</version> </parent> <artifactId>org.eclipse.jgit.target</artifactId>
diff --git a/org.eclipse.jgit.packaging/org.eclipse.jgit.target/projects/jetty-9.3.9.tpd b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/projects/jetty-9.3.9.tpd new file mode 100644 index 0000000..d5621a0 --- /dev/null +++ b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/projects/jetty-9.3.9.tpd
@@ -0,0 +1,20 @@ +target "jetty-9.4.3" with source configurePhase + +location jetty-9.4.3 "http://download.eclipse.org/jetty/updates/jetty-bundles-9.x/9.3.9.v20160517/" { + org.eclipse.jetty.client [9.3.9.v20160517,9.3.9.v20160517] + org.eclipse.jetty.client.source [9.3.9.v20160517,9.3.9.v20160517] + org.eclipse.jetty.continuation [9.3.9.v20160517,9.3.9.v20160517] + org.eclipse.jetty.continuation.source [9.3.9.v20160517,9.3.9.v20160517] + org.eclipse.jetty.http [9.3.9.v20160517,9.3.9.v20160517] + org.eclipse.jetty.http.source [9.3.9.v20160517,9.3.9.v20160517] + org.eclipse.jetty.io [9.3.9.v20160517,9.3.9.v20160517] + org.eclipse.jetty.io.source [9.3.9.v20160517,9.3.9.v20160517] + org.eclipse.jetty.security [9.3.9.v20160517,9.3.9.v20160517] + org.eclipse.jetty.security.source [9.3.9.v20160517,9.3.9.v20160517] + org.eclipse.jetty.server [9.3.9.v20160517,9.3.9.v20160517] + org.eclipse.jetty.server.source [9.3.9.v20160517,9.3.9.v20160517] + org.eclipse.jetty.servlet [9.3.9.v20160517,9.3.9.v20160517] + org.eclipse.jetty.servlet.source [9.3.9.v20160517,9.3.9.v20160517] + org.eclipse.jetty.util [9.3.9.v20160517,9.3.9.v20160517] + org.eclipse.jetty.util.source [9.3.9.v20160517,9.3.9.v20160517] +}
diff --git a/org.eclipse.jgit.packaging/pom.xml b/org.eclipse.jgit.packaging/pom.xml index 583b128..be488bc 100644 --- a/org.eclipse.jgit.packaging/pom.xml +++ b/org.eclipse.jgit.packaging/pom.xml
@@ -53,7 +53,7 @@ <groupId>org.eclipse.jgit</groupId> <artifactId>jgit.tycho.parent</artifactId> - <version>4.6.2-SNAPSHOT</version> + <version>4.7.6-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 10c29d5..64f7498 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
@@ -56,7 +56,7 @@ org.eclipse.jdt.core.compiler.problem.missingJavadocTagsMethodTypeParameters=disabled org.eclipse.jdt.core.compiler.problem.missingJavadocTagsOverriding=disabled org.eclipse.jdt.core.compiler.problem.missingJavadocTagsVisibility=private -org.eclipse.jdt.core.compiler.problem.missingOverrideAnnotation=ignore +org.eclipse.jdt.core.compiler.problem.missingOverrideAnnotation=warning org.eclipse.jdt.core.compiler.problem.missingOverrideAnnotationForInterfaceMethodImplementation=enabled org.eclipse.jdt.core.compiler.problem.missingSerialVersion=warning org.eclipse.jdt.core.compiler.problem.missingSynchronizedOnInheritedMethod=ignore @@ -76,7 +76,7 @@ org.eclipse.jdt.core.compiler.problem.rawTypeReference=ignore org.eclipse.jdt.core.compiler.problem.redundantNullAnnotation=warning org.eclipse.jdt.core.compiler.problem.redundantNullCheck=warning -org.eclipse.jdt.core.compiler.problem.redundantSpecificationOfTypeArguments=ignore +org.eclipse.jdt.core.compiler.problem.redundantSpecificationOfTypeArguments=warning org.eclipse.jdt.core.compiler.problem.redundantSuperinterface=error org.eclipse.jdt.core.compiler.problem.reportMethodCanBePotentiallyStatic=ignore org.eclipse.jdt.core.compiler.problem.reportMethodCanBeStatic=ignore
diff --git a/org.eclipse.jgit.pgm.test/BUCK b/org.eclipse.jgit.pgm.test/BUCK deleted file mode 100644 index cd15510..0000000 --- a/org.eclipse.jgit.pgm.test/BUCK +++ /dev/null
@@ -1,37 +0,0 @@ -TESTS = glob(['tst/**/*.java']) - -for t in TESTS: - n = t[len('tst/'):len(t)-len('.java')].replace('/', '.') - java_test( - name = n, - labels = ['pgm'], - srcs = [t], - deps = [ - ':helpers', - '//org.eclipse.jgit:jgit', - '//org.eclipse.jgit.archive:jgit-archive', - '//org.eclipse.jgit.junit:junit', - '//org.eclipse.jgit.pgm:pgm', - '//lib:hamcrest-core', - '//lib:hamcrest-library', - '//lib:javaewah', - '//lib:junit', - '//lib:slf4j-api', - '//lib:slf4j-simple', - '//lib:commons-compress', - '//lib:tukaani-xz', - ], - vm_args = ['-Xmx256m', '-Dfile.encoding=UTF-8'], - ) - -java_library( - name = 'helpers', - srcs = glob(['src/**/*.java']), - deps = [ - '//org.eclipse.jgit:jgit', - '//org.eclipse.jgit.pgm:pgm', - '//org.eclipse.jgit.junit:junit', - '//lib:args4j', - '//lib:junit', - ], -)
diff --git a/org.eclipse.jgit.pgm.test/BUILD b/org.eclipse.jgit.pgm.test/BUILD new file mode 100644 index 0000000..5d4a175 --- /dev/null +++ b/org.eclipse.jgit.pgm.test/BUILD
@@ -0,0 +1,40 @@ +load( + "@com_googlesource_gerrit_bazlets//tools:junit.bzl", + "junit_tests", +) + +junit_tests( + name = "pgm", + srcs = glob(["tst/**/*.java"]), + jvm_flags = [ + "-Xmx256m", + "-Dfile.encoding=UTF-8", + ], + tags = ["pgm"], + deps = [ + ":helpers", + "//lib:commons-compress", + "//lib:javaewah", + "//lib:junit", + "//lib:slf4j-api", + "//lib:slf4j-simple", + "//lib:xz", + "//org.eclipse.jgit.archive:jgit-archive", + "//org.eclipse.jgit:jgit", + "//org.eclipse.jgit.junit:junit", + "//org.eclipse.jgit.pgm:pgm", + ], +) + +java_library( + name = "helpers", + testonly = 1, + srcs = glob(["src/**/*.java"]), + deps = [ + "//lib:args4j", + "//lib:junit", + "//org.eclipse.jgit:jgit", + "//org.eclipse.jgit.junit:junit", + "//org.eclipse.jgit.pgm:pgm", + ], +)
diff --git a/org.eclipse.jgit.pgm.test/META-INF/MANIFEST.MF b/org.eclipse.jgit.pgm.test/META-INF/MANIFEST.MF index 8e7d5ab..e0976b5 100644 --- a/org.eclipse.jgit.pgm.test/META-INF/MANIFEST.MF +++ b/org.eclipse.jgit.pgm.test/META-INF/MANIFEST.MF
@@ -2,28 +2,28 @@ Bundle-ManifestVersion: 2 Bundle-Name: %plugin_name Bundle-SymbolicName: org.eclipse.jgit.pgm.test -Bundle-Version: 4.6.2.qualifier +Bundle-Version: 4.7.6.qualifier Bundle-Vendor: %provider_name Bundle-Localization: plugin Bundle-ActivationPolicy: lazy Bundle-RequiredExecutionEnvironment: JavaSE-1.8 -Import-Package: org.eclipse.jgit.api;version="[4.6.2,4.7.0)", - org.eclipse.jgit.api.errors;version="[4.6.2,4.7.0)", - org.eclipse.jgit.diff;version="[4.6.2,4.7.0)", - org.eclipse.jgit.dircache;version="[4.6.2,4.7.0)", - org.eclipse.jgit.internal.storage.file;version="4.6.2", - org.eclipse.jgit.junit;version="[4.6.2,4.7.0)", - org.eclipse.jgit.lib;version="[4.6.2,4.7.0)", - org.eclipse.jgit.merge;version="[4.6.2,4.7.0)", - org.eclipse.jgit.pgm;version="[4.6.2,4.7.0)", - org.eclipse.jgit.pgm.internal;version="[4.6.2,4.7.0)", - org.eclipse.jgit.pgm.opt;version="[4.6.2,4.7.0)", - org.eclipse.jgit.revwalk;version="[4.6.2,4.7.0)", - org.eclipse.jgit.storage.file;version="[4.6.2,4.7.0)", - org.eclipse.jgit.transport;version="[4.6.2,4.7.0)", - org.eclipse.jgit.treewalk;version="[4.6.2,4.7.0)", - org.eclipse.jgit.util;version="[4.6.2,4.7.0)", - org.eclipse.jgit.util.io;version="[4.6.2,4.7.0)", +Import-Package: org.eclipse.jgit.api;version="[4.7.6,4.8.0)", + org.eclipse.jgit.api.errors;version="[4.7.6,4.8.0)", + org.eclipse.jgit.diff;version="[4.7.6,4.8.0)", + org.eclipse.jgit.dircache;version="[4.7.6,4.8.0)", + org.eclipse.jgit.internal.storage.file;version="4.7.6", + org.eclipse.jgit.junit;version="[4.7.6,4.8.0)", + org.eclipse.jgit.lib;version="[4.7.6,4.8.0)", + org.eclipse.jgit.merge;version="[4.7.6,4.8.0)", + org.eclipse.jgit.pgm;version="[4.7.6,4.8.0)", + org.eclipse.jgit.pgm.internal;version="[4.7.6,4.8.0)", + org.eclipse.jgit.pgm.opt;version="[4.7.6,4.8.0)", + org.eclipse.jgit.revwalk;version="[4.7.6,4.8.0)", + org.eclipse.jgit.storage.file;version="[4.7.6,4.8.0)", + org.eclipse.jgit.transport;version="[4.7.6,4.8.0)", + org.eclipse.jgit.treewalk;version="[4.7.6,4.8.0)", + org.eclipse.jgit.util;version="[4.7.6,4.8.0)", + org.eclipse.jgit.util.io;version="[4.7.6,4.8.0)", org.hamcrest.core;bundle-version="[1.1.0,2.0.0)", org.junit;version="[4.11.0,5.0.0)", org.junit.rules;version="[4.11.0,5.0.0)",
diff --git a/org.eclipse.jgit.pgm.test/pom.xml b/org.eclipse.jgit.pgm.test/pom.xml index c8188cb..4f86771 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>4.6.2-SNAPSHOT</version> + <version>4.7.6-SNAPSHOT</version> </parent> <artifactId>org.eclipse.jgit.pgm.test</artifactId>
diff --git a/org.eclipse.jgit.pgm.test/src/org/eclipse/jgit/lib/CLIRepositoryTestCase.java b/org.eclipse.jgit.pgm.test/src/org/eclipse/jgit/lib/CLIRepositoryTestCase.java index b675d3c..0eeabab 100644 --- a/org.eclipse.jgit.pgm.test/src/org/eclipse/jgit/lib/CLIRepositoryTestCase.java +++ b/org.eclipse.jgit.pgm.test/src/org/eclipse/jgit/lib/CLIRepositoryTestCase.java
@@ -79,7 +79,7 @@ public void setUp() throws Exception { * @throws Exception */ protected String[] executeUnchecked(String... cmds) throws Exception { - List<String> result = new ArrayList<String>(cmds.length); + List<String> result = new ArrayList<>(cmds.length); for (String cmd : cmds) { result.addAll(CLIGitCommand.executeUnchecked(cmd, db)); } @@ -97,7 +97,7 @@ public void setUp() throws Exception { * @throws Exception */ protected String[] execute(String... cmds) throws Exception { - List<String> result = new ArrayList<String>(cmds.length); + List<String> result = new ArrayList<>(cmds.length); for (String cmd : cmds) { Result r = CLIGitCommand.executeRaw(cmd, db); if (r.ex instanceof TerminatedByHelpException) { @@ -127,6 +127,7 @@ protected File writeTrashFile(final String name, final String data) return JGitTestUtil.writeTrashFile(db, name, data); } + @Override protected String read(final File file) throws IOException { return JGitTestUtil.read(file); }
diff --git a/org.eclipse.jgit.pgm.test/src/org/eclipse/jgit/pgm/CLIGitCommand.java b/org.eclipse.jgit.pgm.test/src/org/eclipse/jgit/pgm/CLIGitCommand.java index b08bc8a..69eb198 100644 --- a/org.eclipse.jgit.pgm.test/src/org/eclipse/jgit/pgm/CLIGitCommand.java +++ b/org.eclipse.jgit.pgm.test/src/org/eclipse/jgit/pgm/CLIGitCommand.java
@@ -156,6 +156,7 @@ PrintWriter createErrorWriter() { return new PrintWriter(result.err); } + @Override void init(final TextBuiltin cmd) throws IOException { cmd.outs = result.out; cmd.errs = result.err; @@ -188,7 +189,7 @@ void exit(int status, Exception t) throws Exception { * @return the array */ static String[] split(String commandLine) { - final List<String> list = new ArrayList<String>(); + final List<String> list = new ArrayList<>(); boolean inquote = false; boolean inDblQuote = false; StringBuilder r = new StringBuilder();
diff --git a/org.eclipse.jgit.pgm.test/tst/org/eclipse/jgit/pgm/ArchiveTest.java b/org.eclipse.jgit.pgm.test/tst/org/eclipse/jgit/pgm/ArchiveTest.java index 35467c6..6f32bfa 100644 --- a/org.eclipse.jgit.pgm.test/tst/org/eclipse/jgit/pgm/ArchiveTest.java +++ b/org.eclipse.jgit.pgm.test/tst/org/eclipse/jgit/pgm/ArchiveTest.java
@@ -348,7 +348,7 @@ public void testArchivePrefixOption() throws Exception { commitBazAndFooSlashBar(); byte[] result = CLIGitCommand.executeRaw( "git archive --prefix=x/ --format=zip master", db).outBytes(); - String[] expect = { "x/baz", "x/foo/", "x/foo/bar" }; + String[] expect = { "x/", "x/baz", "x/foo/", "x/foo/bar" }; String[] actual = listZipEntries(result); Arrays.sort(expect); @@ -361,7 +361,7 @@ public void testTarPrefixOption() throws Exception { commitBazAndFooSlashBar(); byte[] result = CLIGitCommand.executeRaw( "git archive --prefix=x/ --format=tar master", db).outBytes(); - String[] expect = { "x/baz", "x/foo/", "x/foo/bar" }; + String[] expect = { "x/", "x/baz", "x/foo/", "x/foo/bar" }; String[] actual = listTarEntries(result); Arrays.sort(expect); @@ -380,7 +380,7 @@ public void testPrefixDoesNotNormalizeDoubleSlash() throws Exception { commitFoo(); byte[] result = CLIGitCommand.executeRaw( "git archive --prefix=x// --format=zip master", db).outBytes(); - String[] expect = { "x//foo" }; + String[] expect = { "x/", "x//foo" }; assertArrayEquals(expect, listZipEntries(result)); } @@ -389,7 +389,7 @@ public void testPrefixDoesNotNormalizeDoubleSlashInTar() throws Exception { commitFoo(); byte[] result = CLIGitCommand.executeRaw( "git archive --prefix=x// --format=tar master", db).outBytes(); - String[] expect = { "x//foo" }; + String[] expect = { "x/", "x//foo" }; assertArrayEquals(expect, listTarEntries(result)); } @@ -529,7 +529,7 @@ public void testTarPreservesMode() throws Exception { @Test public void testArchiveWithLongFilename() throws Exception { StringBuilder filename = new StringBuilder(); - List<String> l = new ArrayList<String>(); + List<String> l = new ArrayList<>(); for (int i = 0; i < 20; i++) { filename.append("1234567890/"); l.add(filename.toString()); @@ -549,7 +549,7 @@ public void testArchiveWithLongFilename() throws Exception { @Test public void testTarWithLongFilename() throws Exception { StringBuilder filename = new StringBuilder(); - List<String> l = new ArrayList<String>(); + List<String> l = new ArrayList<>(); for (int i = 0; i < 20; i++) { filename.append("1234567890/"); l.add(filename.toString()); @@ -691,7 +691,7 @@ private void writeRaw(String filename, byte[] data) } private static String[] listZipEntries(byte[] zipData) throws IOException { - List<String> l = new ArrayList<String>(); + List<String> l = new ArrayList<>(); ZipInputStream in = new ZipInputStream( new ByteArrayInputStream(zipData)); @@ -706,6 +706,7 @@ private static Future<Object> writeAsync(final OutputStream stream, final byte[] ExecutorService executor = Executors.newSingleThreadExecutor(); return executor.submit(new Callable<Object>() { + @Override public Object call() throws IOException { try { stream.write(data); @@ -718,7 +719,7 @@ public Object call() throws IOException { } private String[] listTarEntries(byte[] tarData) throws Exception { - List<String> l = new ArrayList<String>(); + List<String> l = new ArrayList<>(); Process proc = spawnAssumingCommandPresent("tar", "tf", "-"); BufferedReader reader = readFromProcess(proc); OutputStream out = proc.getOutputStream(); @@ -749,7 +750,7 @@ public Object call() throws IOException { continue; // found! - List<String> l = new ArrayList<String>(); + List<String> l = new ArrayList<>(); BufferedReader reader = new BufferedReader( new InputStreamReader(in, "UTF-8")); String line; @@ -764,7 +765,7 @@ public Object call() throws IOException { private String[] tarEntryContent(byte[] tarData, String path) throws Exception { - List<String> l = new ArrayList<String>(); + List<String> l = new ArrayList<>(); Process proc = spawnAssumingCommandPresent("tar", "Oxf", "-", path); BufferedReader reader = readFromProcess(proc); OutputStream out = proc.getOutputStream();
diff --git a/org.eclipse.jgit.pgm.test/tst/org/eclipse/jgit/pgm/ConfigTest.java b/org.eclipse.jgit.pgm.test/tst/org/eclipse/jgit/pgm/ConfigTest.java index 23aa97e..0ce6451 100644 --- a/org.eclipse.jgit.pgm.test/tst/org/eclipse/jgit/pgm/ConfigTest.java +++ b/org.eclipse.jgit.pgm.test/tst/org/eclipse/jgit/pgm/ConfigTest.java
@@ -73,7 +73,8 @@ public void testListConfig() throws Exception { .equals("Mac OS X"); String[] output = execute("git config --list"); - List<String> expect = new ArrayList<String>(); + List<String> expect = new ArrayList<>(); + expect.add("gc.autoDetach=false"); expect.add("core.filemode=" + !isWindows); expect.add("core.logallrefupdates=true"); if (isMac)
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 4f1759f..06ddbab 100644 --- a/org.eclipse.jgit.pgm/.settings/org.eclipse.jdt.core.prefs +++ b/org.eclipse.jgit.pgm/.settings/org.eclipse.jdt.core.prefs
@@ -56,7 +56,7 @@ org.eclipse.jdt.core.compiler.problem.missingJavadocTagsMethodTypeParameters=disabled org.eclipse.jdt.core.compiler.problem.missingJavadocTagsOverriding=disabled org.eclipse.jdt.core.compiler.problem.missingJavadocTagsVisibility=private -org.eclipse.jdt.core.compiler.problem.missingOverrideAnnotation=ignore +org.eclipse.jdt.core.compiler.problem.missingOverrideAnnotation=warning org.eclipse.jdt.core.compiler.problem.missingOverrideAnnotationForInterfaceMethodImplementation=enabled org.eclipse.jdt.core.compiler.problem.missingSerialVersion=warning org.eclipse.jdt.core.compiler.problem.missingSynchronizedOnInheritedMethod=ignore @@ -76,7 +76,7 @@ org.eclipse.jdt.core.compiler.problem.rawTypeReference=ignore org.eclipse.jdt.core.compiler.problem.redundantNullAnnotation=warning org.eclipse.jdt.core.compiler.problem.redundantNullCheck=warning -org.eclipse.jdt.core.compiler.problem.redundantSpecificationOfTypeArguments=ignore +org.eclipse.jdt.core.compiler.problem.redundantSpecificationOfTypeArguments=warning org.eclipse.jdt.core.compiler.problem.redundantSuperinterface=error org.eclipse.jdt.core.compiler.problem.reportMethodCanBePotentiallyStatic=ignore org.eclipse.jdt.core.compiler.problem.reportMethodCanBeStatic=ignore
diff --git a/org.eclipse.jgit.pgm/BUCK b/org.eclipse.jgit.pgm/BUCK deleted file mode 100644 index 5d5e6f7..0000000 --- a/org.eclipse.jgit.pgm/BUCK +++ /dev/null
@@ -1,81 +0,0 @@ -include_defs('//tools/git.defs') - -java_library( - name = 'pgm', - srcs = glob(['src/**']), - resources = glob(['resources/**']), - deps = [ - ':services', - '//org.eclipse.jgit:jgit', - '//org.eclipse.jgit.archive:jgit-archive', - '//org.eclipse.jgit.http.apache:http-apache', - '//org.eclipse.jgit.lfs:jgit-lfs', - '//org.eclipse.jgit.lfs.server:jgit-lfs-server', - '//org.eclipse.jgit.ui:ui', - '//lib:args4j', - '//lib:httpcomponents', - '//lib:httpcore', - '//lib/jetty:http', - '//lib/jetty:io', - '//lib/jetty:server', - '//lib/jetty:servlet', - '//lib/jetty:security', - '//lib/jetty:util', - '//lib:servlet-api' - ], - visibility = ['PUBLIC'], -) - -prebuilt_jar( - name = 'services', - binary_jar = ':services__jar', -) - -genrule( - name = 'services__jar', - cmd = 'cd $SRCDIR ; zip -qr $OUT .', - srcs = glob(['META-INF/services/*']), - out = 'services.jar', -) - -genrule( - name = 'jgit', - cmd = ''.join([ - 'mkdir $TMP/META-INF &&', - 'cp $(location :binary_manifest) $TMP/META-INF/MANIFEST.MF &&', - 'cp $(location :jgit_jar) $TMP/jgit.jar &&', - 'cd $TMP && zip $TMP/jgit.jar META-INF/MANIFEST.MF &&', - 'cat $SRCDIR/jgit.sh $TMP/jgit.jar >$OUT &&', - 'chmod a+x $OUT', - ]), - srcs = ['jgit.sh'], - out = 'jgit', - visibility = ['PUBLIC'], -) - -java_binary( - name = 'jgit_jar', - deps = [ - ':pgm', - '//lib:slf4j-simple', - '//lib:tukaani-xz', - ], - blacklist = [ - 'META-INF/DEPENDENCIES', - 'META-INF/maven/.*', - ], -) - -genrule( - name = 'binary_manifest', - cmd = ';'.join(['echo "%s: %s" >>$OUT' % e for e in [ - ('Manifest-Version', '1.0'), - ('Main-Class', 'org.eclipse.jgit.pgm.Main'), - ('Bundle-Version', git_version()), - ('Implementation-Title', 'JGit Command Line Interface'), - ('Implementation-Vendor', 'Eclipse.org - JGit'), - ('Implementation-Vendor-URL', 'http://www.eclipse.org/jgit/'), - ('Implementation-Vendor-Id', 'org.eclipse.jgit'), - ]] + ['echo >>$OUT']), - out = 'MANIFEST.MF', -)
diff --git a/org.eclipse.jgit.pgm/BUILD b/org.eclipse.jgit.pgm/BUILD new file mode 100644 index 0000000..6d32790 --- /dev/null +++ b/org.eclipse.jgit.pgm/BUILD
@@ -0,0 +1,38 @@ +java_library( + name = "pgm", + srcs = glob(["src/**"]), + resource_strip_prefix = "org.eclipse.jgit.pgm/resources", + resources = glob(["resources/**"]), + visibility = ["//visibility:public"], + deps = [ + ":services", + "//lib:args4j", + "//lib:httpclient", + "//lib:httpcore", + "//lib:jetty-http", + "//lib:jetty-io", + "//lib:jetty-security", + "//lib:jetty-server", + "//lib:jetty-servlet", + "//lib:jetty-util", + "//lib:servlet-api", + "//org.eclipse.jgit.archive:jgit-archive", + "//org.eclipse.jgit.http.apache:http-apache", + "//org.eclipse.jgit:jgit", + "//org.eclipse.jgit.lfs:jgit-lfs", + "//org.eclipse.jgit.lfs.server:jgit-lfs-server", + "//org.eclipse.jgit.ui:ui", + ], +) + +java_import( + name = "services", + jars = [":services_jar"], +) + +genrule( + name = "services_jar", + srcs = glob(["META-INF/services/*"]), + outs = ["services_jar.jar"], + cmd = "r=$$PWD && cd org.eclipse.jgit.pgm && zip -qr $$r/$@ .", +)
diff --git a/org.eclipse.jgit.pgm/META-INF/MANIFEST.MF b/org.eclipse.jgit.pgm/META-INF/MANIFEST.MF index 5c30da7..5c361b8 100644 --- a/org.eclipse.jgit.pgm/META-INF/MANIFEST.MF +++ b/org.eclipse.jgit.pgm/META-INF/MANIFEST.MF
@@ -2,7 +2,7 @@ Bundle-ManifestVersion: 2 Bundle-Name: %plugin_name Bundle-SymbolicName: org.eclipse.jgit.pgm -Bundle-Version: 4.6.2.qualifier +Bundle-Version: 4.7.6.qualifier Bundle-Vendor: %provider_name Bundle-ActivationPolicy: lazy Bundle-Localization: plugin @@ -27,46 +27,46 @@ org.eclipse.jetty.util.log;version="[9.0.0,9.4.0)", org.eclipse.jetty.util.security;version="[9.0.0,9.4.0)", org.eclipse.jetty.util.thread;version="[9.0.0,9.4.0)", - org.eclipse.jgit.api;version="[4.6.2,4.7.0)", - org.eclipse.jgit.api.errors;version="[4.6.2,4.7.0)", - org.eclipse.jgit.archive;version="[4.6.2,4.7.0)", - org.eclipse.jgit.awtui;version="[4.6.2,4.7.0)", - org.eclipse.jgit.blame;version="[4.6.2,4.7.0)", - org.eclipse.jgit.diff;version="[4.6.2,4.7.0)", - org.eclipse.jgit.dircache;version="[4.6.2,4.7.0)", - org.eclipse.jgit.errors;version="[4.6.2,4.7.0)", - org.eclipse.jgit.gitrepo;version="[4.6.2,4.7.0)", - org.eclipse.jgit.internal.ketch;version="[4.6.2,4.7.0)", - org.eclipse.jgit.internal.storage.file;version="[4.6.2,4.7.0)", - org.eclipse.jgit.internal.storage.pack;version="[4.6.2,4.7.0)", - org.eclipse.jgit.internal.storage.reftree;version="[4.6.2,4.7.0)", - org.eclipse.jgit.lfs;version="[4.6.2,4.7.0)", - org.eclipse.jgit.lfs.lib;version="[4.6.2,4.7.0)", - org.eclipse.jgit.lfs.server;version="[4.6.2,4.7.0)", - org.eclipse.jgit.lfs.server.fs;version="[4.6.2,4.7.0)", - org.eclipse.jgit.lfs.server.s3;version="[4.6.2,4.7.0)", - org.eclipse.jgit.lib;version="[4.6.2,4.7.0)", - org.eclipse.jgit.merge;version="[4.6.2,4.7.0)", - org.eclipse.jgit.nls;version="[4.6.2,4.7.0)", - org.eclipse.jgit.notes;version="[4.6.2,4.7.0)", - org.eclipse.jgit.revplot;version="[4.6.2,4.7.0)", - org.eclipse.jgit.revwalk;version="[4.6.2,4.7.0)", - org.eclipse.jgit.revwalk.filter;version="[4.6.2,4.7.0)", - org.eclipse.jgit.storage.file;version="[4.6.2,4.7.0)", - org.eclipse.jgit.storage.pack;version="[4.6.2,4.7.0)", - org.eclipse.jgit.transport;version="[4.6.2,4.7.0)", - org.eclipse.jgit.transport.http.apache;version="[4.6.2,4.7.0)", - org.eclipse.jgit.transport.resolver;version="[4.6.2,4.7.0)", - org.eclipse.jgit.treewalk;version="[4.6.2,4.7.0)", - org.eclipse.jgit.treewalk.filter;version="[4.6.2,4.7.0)", - org.eclipse.jgit.util;version="[4.6.2,4.7.0)", - org.eclipse.jgit.util.io;version="[4.6.2,4.7.0)", + org.eclipse.jgit.api;version="[4.7.6,4.8.0)", + org.eclipse.jgit.api.errors;version="[4.7.6,4.8.0)", + org.eclipse.jgit.archive;version="[4.7.6,4.8.0)", + org.eclipse.jgit.awtui;version="[4.7.6,4.8.0)", + org.eclipse.jgit.blame;version="[4.7.6,4.8.0)", + org.eclipse.jgit.diff;version="[4.7.6,4.8.0)", + org.eclipse.jgit.dircache;version="[4.7.6,4.8.0)", + org.eclipse.jgit.errors;version="[4.7.6,4.8.0)", + org.eclipse.jgit.gitrepo;version="[4.7.6,4.8.0)", + org.eclipse.jgit.internal.ketch;version="[4.7.6,4.8.0)", + org.eclipse.jgit.internal.storage.file;version="[4.7.6,4.8.0)", + org.eclipse.jgit.internal.storage.pack;version="[4.7.6,4.8.0)", + org.eclipse.jgit.internal.storage.reftree;version="[4.7.6,4.8.0)", + org.eclipse.jgit.lfs;version="[4.7.6,4.8.0)", + org.eclipse.jgit.lfs.lib;version="[4.7.6,4.8.0)", + org.eclipse.jgit.lfs.server;version="[4.7.6,4.8.0)", + org.eclipse.jgit.lfs.server.fs;version="[4.7.6,4.8.0)", + org.eclipse.jgit.lfs.server.s3;version="[4.7.6,4.8.0)", + org.eclipse.jgit.lib;version="[4.7.6,4.8.0)", + org.eclipse.jgit.merge;version="[4.7.6,4.8.0)", + org.eclipse.jgit.nls;version="[4.7.6,4.8.0)", + org.eclipse.jgit.notes;version="[4.7.6,4.8.0)", + org.eclipse.jgit.revplot;version="[4.7.6,4.8.0)", + org.eclipse.jgit.revwalk;version="[4.7.6,4.8.0)", + org.eclipse.jgit.revwalk.filter;version="[4.7.6,4.8.0)", + org.eclipse.jgit.storage.file;version="[4.7.6,4.8.0)", + org.eclipse.jgit.storage.pack;version="[4.7.6,4.8.0)", + org.eclipse.jgit.transport;version="[4.7.6,4.8.0)", + org.eclipse.jgit.transport.http.apache;version="[4.7.6,4.8.0)", + org.eclipse.jgit.transport.resolver;version="[4.7.6,4.8.0)", + org.eclipse.jgit.treewalk;version="[4.7.6,4.8.0)", + org.eclipse.jgit.treewalk.filter;version="[4.7.6,4.8.0)", + org.eclipse.jgit.util;version="[4.7.6,4.8.0)", + org.eclipse.jgit.util.io;version="[4.7.6,4.8.0)", org.kohsuke.args4j;version="[2.0.12,2.1.0)", org.kohsuke.args4j.spi;version="[2.0.15,2.1.0)" -Export-Package: org.eclipse.jgit.console;version="4.6.2"; +Export-Package: org.eclipse.jgit.console;version="4.7.6"; uses:="org.eclipse.jgit.transport, org.eclipse.jgit.util", - org.eclipse.jgit.pgm;version="4.6.2"; + org.eclipse.jgit.pgm;version="4.7.6"; uses:="org.eclipse.jgit.revwalk, org.eclipse.jgit.treewalk.filter, org.eclipse.jgit.pgm.opt, @@ -77,11 +77,11 @@ org.eclipse.jgit.treewalk, javax.swing, org.eclipse.jgit.transport", - org.eclipse.jgit.pgm.debug;version="4.6.2"; + org.eclipse.jgit.pgm.debug;version="4.7.6"; uses:="org.eclipse.jgit.util.io, org.eclipse.jgit.pgm", - org.eclipse.jgit.pgm.internal;version="4.6.2";x-friends:="org.eclipse.jgit.pgm.test,org.eclipse.jgit.test", - org.eclipse.jgit.pgm.opt;version="4.6.2"; + org.eclipse.jgit.pgm.internal;version="4.7.6";x-friends:="org.eclipse.jgit.pgm.test,org.eclipse.jgit.test", + org.eclipse.jgit.pgm.opt;version="4.7.6"; 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 443ccc8..0340a7f 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: 4.6.2.qualifier -Eclipse-SourceBundle: org.eclipse.jgit.pgm;version="4.6.2.qualifier";roots="." +Bundle-Version: 4.7.6.qualifier +Eclipse-SourceBundle: org.eclipse.jgit.pgm;version="4.7.6.qualifier";roots="."
diff --git a/org.eclipse.jgit.pgm/pom.xml b/org.eclipse.jgit.pgm/pom.xml index c6f4aca..d21d56a 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>4.6.2-SNAPSHOT</version> + <version>4.7.6-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 1d4bf76..06e4d94 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
@@ -246,6 +246,8 @@ usage_MakeCacheTree=Show the current cache tree structure usage_MergeBase=Find as good common ancestors as possible for a merge usage_MergesTwoDevelopmentHistories=Merges two development histories +usage_PreserveOldPacks=Preserve old pack files by moving them into the preserved subdirectory instead of deleting them after repacking +usage_PrunePreserved=Remove the preserved subdirectory containing previously preserved old pack files before repacking, and before preserving more old pack files usage_ReadDirCache= Read the DirCache 100 times usage_RebuildCommitGraph=Recreate a repository from another one's commit graph usage_RebuildRefTree=Copy references into a RefTree
diff --git a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/Add.java b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/Add.java index c36c485..3c13590 100644 --- a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/Add.java +++ b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/Add.java
@@ -58,7 +58,7 @@ class Add extends TextBuiltin { private boolean update = false; @Argument(required = true, metaVar = "metaVar_filepattern", usage = "usage_filesToAddContentFrom") - private List<String> filepatterns = new ArrayList<String>(); + private List<String> filepatterns = new ArrayList<>(); @Override protected void run() throws Exception {
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 0f54171..4193254 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
@@ -114,7 +114,7 @@ void ignoreAllSpace(@SuppressWarnings("unused") boolean on) { private String rangeString; @Option(name = "--reverse", metaVar = "metaVar_blameReverse", usage = "usage_blameReverse") - private List<RevCommit> reverseRange = new ArrayList<RevCommit>(2); + private List<RevCommit> reverseRange = new ArrayList<>(2); @Argument(index = 0, required = false, metaVar = "metaVar_revision") private String revision; @@ -124,7 +124,7 @@ void ignoreAllSpace(@SuppressWarnings("unused") boolean on) { private ObjectReader reader; - private final Map<RevCommit, String> abbreviatedCommits = new HashMap<RevCommit, String>(); + private final Map<RevCommit, String> abbreviatedCommits = new HashMap<>(); private SimpleDateFormat dateFmt; @@ -163,7 +163,7 @@ protected void run() throws Exception { if (!reverseRange.isEmpty()) { RevCommit rangeStart = null; - List<RevCommit> rangeEnd = new ArrayList<RevCommit>(2); + List<RevCommit> rangeEnd = new ArrayList<>(2); for (RevCommit c : reverseRange) { if (c.has(RevFlag.UNINTERESTING)) rangeStart = c;
diff --git a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/Branch.java b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/Branch.java index 5f3740c..f6e3810 100644 --- a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/Branch.java +++ b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/Branch.java
@@ -149,7 +149,7 @@ public void moveRename(List<String> currentAndNew) { @Argument(metaVar = "metaVar_name") private String branch; - private final Map<String, Ref> printRefs = new LinkedHashMap<String, Ref>(); + private final Map<String, Ref> printRefs = new LinkedHashMap<>(); /** Only set for verbose branch listing at-the-moment */ private RevWalk rw;
diff --git a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/Checkout.java b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/Checkout.java index 0c3b720..c2f3c46 100644 --- a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/Checkout.java +++ b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/Checkout.java
@@ -78,7 +78,7 @@ class Checkout extends TextBuiltin { private String name; @Option(name = "--", metaVar = "metaVar_paths", multiValued = true, handler = RestOfArgumentsHandler.class) - private List<String> paths = new ArrayList<String>(); + private List<String> paths = new ArrayList<>(); @Override protected void run() throws Exception {
diff --git a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/CommandCatalog.java b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/CommandCatalog.java index 2673cc8..cf4c6e3 100644 --- a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/CommandCatalog.java +++ b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/CommandCatalog.java
@@ -100,7 +100,7 @@ public static CommandRef get(final String name) { * @return all common commands, sorted by command name. */ public static CommandRef[] common() { - final ArrayList<CommandRef> common = new ArrayList<CommandRef>(); + final ArrayList<CommandRef> common = new ArrayList<>(); for (final CommandRef c : INSTANCE.commands.values()) if (c.isCommon()) common.add(c); @@ -110,6 +110,7 @@ public static CommandRef get(final String name) { private static CommandRef[] toSortedArray(final Collection<CommandRef> c) { final CommandRef[] r = c.toArray(new CommandRef[c.size()]); Arrays.sort(r, new Comparator<CommandRef>() { + @Override public int compare(final CommandRef o1, final CommandRef o2) { return o1.getName().compareTo(o2.getName()); } @@ -123,7 +124,7 @@ public int compare(final CommandRef o1, final CommandRef o2) { private CommandCatalog() { ldr = Thread.currentThread().getContextClassLoader(); - commands = new HashMap<String, CommandRef>(); + commands = new HashMap<>(); final Enumeration<URL> catalogs = catalogs(); while (catalogs.hasMoreElements())
diff --git a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/Commit.java b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/Commit.java index 2cfbd86..befc4ec 100644 --- a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/Commit.java +++ b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/Commit.java
@@ -75,7 +75,7 @@ class Commit extends TextBuiltin { private boolean amend; @Argument(metaVar = "metaVar_commitPaths", usage = "usage_CommitPaths") - private List<String> paths = new ArrayList<String>(); + private List<String> paths = new ArrayList<>(); @Override protected void run() throws NoHeadException, NoMessageException,
diff --git a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/Daemon.java b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/Daemon.java index a7bdde9..1008593 100644 --- a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/Daemon.java +++ b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/Daemon.java
@@ -87,16 +87,16 @@ class Daemon extends TextBuiltin { int timeout = -1; @Option(name = "--enable", metaVar = "metaVar_service", usage = "usage_enableTheServiceInAllRepositories", multiValued = true) - final List<String> enable = new ArrayList<String>(); + final List<String> enable = new ArrayList<>(); @Option(name = "--disable", metaVar = "metaVar_service", usage = "usage_disableTheServiceInAllRepositories", multiValued = true) - final List<String> disable = new ArrayList<String>(); + final List<String> disable = new ArrayList<>(); @Option(name = "--allow-override", metaVar = "metaVar_service", usage = "usage_configureTheServiceInDaemonServicename", multiValued = true) - final List<String> canOverride = new ArrayList<String>(); + final List<String> canOverride = new ArrayList<>(); @Option(name = "--forbid-override", metaVar = "metaVar_service", usage = "usage_configureTheServiceInDaemonServicename", multiValued = true) - final List<String> forbidOverride = new ArrayList<String>(); + final List<String> forbidOverride = new ArrayList<>(); @Option(name = "--export-all", usage = "usage_exportWithoutGitDaemonExportOk") boolean exportAll; @@ -109,7 +109,7 @@ enum KetchServerType { } @Argument(required = true, metaVar = "metaVar_directory", usage = "usage_directoriesToExport") - final List<File> directory = new ArrayList<File>(); + final List<File> directory = new ArrayList<>(); @Override protected boolean requiresRepository() { @@ -139,7 +139,7 @@ protected void run() throws Exception { if (1 < threads) packConfig.setExecutor(Executors.newFixedThreadPool(threads)); - final FileResolver<DaemonClient> resolver = new FileResolver<DaemonClient>(); + final FileResolver<DaemonClient> resolver = new FileResolver<>(); for (final File f : directory) { outw.println(MessageFormat.format(CLIText.get().exporting, f.getAbsolutePath())); resolver.exportDirectory(f);
diff --git a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/DiffTree.java b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/DiffTree.java index 95c2132..56b6241 100644 --- a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/DiffTree.java +++ b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/DiffTree.java
@@ -67,7 +67,7 @@ void tree_0(final AbstractTreeIterator c) { } @Argument(index = 1, metaVar = "metaVar_treeish", required = true) - private final List<AbstractTreeIterator> trees = new ArrayList<AbstractTreeIterator>(); + private final List<AbstractTreeIterator> trees = new ArrayList<>(); @Option(name = "--", metaVar = "metaVar_path", multiValued = true, handler = PathTreeFilterHandler.class) private TreeFilter pathFilter = TreeFilter.ALL;
diff --git a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/Gc.java b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/Gc.java index bf45476..7289abb 100644 --- a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/Gc.java +++ b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/Gc.java
@@ -52,10 +52,18 @@ class Gc extends TextBuiltin { @Option(name = "--aggressive", usage = "usage_Aggressive") private boolean aggressive; + @Option(name = "--preserve-oldpacks", usage = "usage_PreserveOldPacks") + private boolean preserveOldPacks; + + @Option(name = "--prune-preserved", usage = "usage_PrunePreserved") + private boolean prunePreserved; + @Override protected void run() throws Exception { Git git = Git.wrap(db); git.gc().setAggressive(aggressive) + .setPreserveOldPacks(preserveOldPacks) + .setPrunePreserved(prunePreserved) .setProgressMonitor(new TextProgressMonitor(errw)).call(); } }
diff --git a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/Glog.java b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/Glog.java index f07c3ca..7b71575 100644 --- a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/Glog.java +++ b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/Glog.java
@@ -88,6 +88,7 @@ public void windowClosing(final WindowEvent e) { final JButton repaint = new JButton(); repaint.setText(CLIText.get().repaint); repaint.addActionListener(new ActionListener() { + @Override public void actionPerformed(ActionEvent e) { graphPane.repaint(); }
diff --git a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/Log.java b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/Log.java index 62e7728..1108ddd 100644 --- a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/Log.java +++ b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/Log.java
@@ -53,6 +53,7 @@ import java.util.Iterator; import java.util.LinkedHashMap; import java.util.List; +import java.util.Locale; import java.util.Map; import java.util.Set; @@ -93,7 +94,7 @@ class Log extends RevWalkTextBuiltin { @Option(name = "--no-standard-notes", usage = "usage_noShowStandardNotes") private boolean noStandardNotes; - private List<String> additionalNoteRefs = new ArrayList<String>(); + private List<String> additionalNoteRefs = new ArrayList<>(); @Option(name = "--show-notes", usage = "usage_showNotes", metaVar = "metaVar_ref") void addAdditionalNoteRef(String notesRef) { @@ -102,8 +103,8 @@ void addAdditionalNoteRef(String notesRef) { @Option(name = "--date", usage = "usage_date") void dateFormat(String date) { - if (date.toLowerCase().equals(date)) - date = date.toUpperCase(); + if (date.toLowerCase(Locale.ROOT).equals(date)) + date = date.toUpperCase(Locale.ROOT); dateFormatter = new GitDateFormatter(Format.valueOf(date)); } @@ -203,7 +204,7 @@ protected void run() throws Exception { if (!noStandardNotes || !additionalNoteRefs.isEmpty()) { createWalk(); - noteMaps = new LinkedHashMap<String, NoteMap>(); + noteMaps = new LinkedHashMap<>(); if (!noStandardNotes) { addNoteMap(Constants.R_NOTES_COMMITS); }
diff --git a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/LsRemote.java b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/LsRemote.java index 6262ad2..7a5f3d8 100644 --- a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/LsRemote.java +++ b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/LsRemote.java
@@ -74,8 +74,9 @@ class LsRemote extends TextBuiltin { protected void run() throws Exception { LsRemoteCommand command = Git.lsRemoteRepository().setRemote(remote) .setTimeout(timeout).setHeads(heads).setTags(tags); - TreeSet<Ref> refs = new TreeSet<Ref>(new Comparator<Ref>() { + TreeSet<Ref> refs = new TreeSet<>(new Comparator<Ref>() { + @Override public int compare(Ref r1, Ref r2) { return r1.getName().compareTo(r2.getName()); }
diff --git a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/LsTree.java b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/LsTree.java index 872ea67..02d61e5 100644 --- a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/LsTree.java +++ b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/LsTree.java
@@ -68,7 +68,7 @@ class LsTree extends TextBuiltin { @Argument(index = 1) @Option(name = "--", metaVar = "metaVar_paths", multiValued = true, handler = StopOptionHandler.class) - private List<String> paths = new ArrayList<String>(); + private List<String> paths = new ArrayList<>(); @Override protected void run() throws Exception {
diff --git a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/Main.java b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/Main.java index a0f4d06..3addecb 100644 --- a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/Main.java +++ b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/Main.java
@@ -53,6 +53,7 @@ import java.text.MessageFormat; import java.util.ArrayList; import java.util.List; +import java.util.Locale; import org.eclipse.jgit.awtui.AwtAuthenticator; import org.eclipse.jgit.awtui.AwtCredentialsProvider; @@ -90,7 +91,7 @@ public class Main { private TextBuiltin subcommand; @Argument(index = 1, metaVar = "metaVar_arg") - private List<String> arguments = new ArrayList<String>(); + private List<String> arguments = new ArrayList<>(); PrintWriter writer; @@ -240,7 +241,8 @@ private void execute(final String[] argv) throws Exception { } if (version) { - String cmdId = Version.class.getSimpleName().toLowerCase(); + String cmdId = Version.class.getSimpleName() + .toLowerCase(Locale.ROOT); subcommand = CommandCatalog.get(cmdId).create(); }
diff --git a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/MergeBase.java b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/MergeBase.java index 9dcd512..f8bae1d 100644 --- a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/MergeBase.java +++ b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/MergeBase.java
@@ -63,7 +63,7 @@ void commit_0(final RevCommit c) { } @Argument(index = 1, metaVar = "metaVar_commitish", required = true) - private final List<RevCommit> commits = new ArrayList<RevCommit>(); + private final List<RevCommit> commits = new ArrayList<>(); @Override protected void run() throws Exception {
diff --git a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/Push.java b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/Push.java index 98af186..1b805d1 100644 --- a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/Push.java +++ b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/Push.java
@@ -77,7 +77,7 @@ class Push extends TextBuiltin { private String remote = Constants.DEFAULT_REMOTE_NAME; @Argument(index = 1, metaVar = "metaVar_refspec") - private final List<RefSpec> refSpecs = new ArrayList<RefSpec>(); + private final List<RefSpec> refSpecs = new ArrayList<>(); @Option(name = "--all") private boolean all;
diff --git a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/RevParse.java b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/RevParse.java index 6833ad3..a66b7fa 100644 --- a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/RevParse.java +++ b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/RevParse.java
@@ -68,7 +68,7 @@ class RevParse extends TextBuiltin { boolean verify; @Argument(index = 0, metaVar = "metaVar_commitish") - private final List<ObjectId> commits = new ArrayList<ObjectId>(); + private final List<ObjectId> commits = new ArrayList<>(); @Override protected void run() throws Exception {
diff --git a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/RevWalkTextBuiltin.java b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/RevWalkTextBuiltin.java index 1543586..74135e4 100644 --- a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/RevWalkTextBuiltin.java +++ b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/RevWalkTextBuiltin.java
@@ -124,12 +124,12 @@ void enableBoundary(final boolean on) { private String followPath; @Argument(index = 0, metaVar = "metaVar_commitish") - private final List<RevCommit> commits = new ArrayList<RevCommit>(); + private final List<RevCommit> commits = new ArrayList<>(); @Option(name = "--", metaVar = "metaVar_path", multiValued = true, handler = PathTreeFilterHandler.class) protected TreeFilter pathFilter = TreeFilter.ALL; - private final List<RevFilter> revLimiter = new ArrayList<RevFilter>(); + private final List<RevFilter> revLimiter = new ArrayList<>(); @Option(name = "--author") void addAuthorRevFilter(final String who) {
diff --git a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/Rm.java b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/Rm.java index f4f864b..79c3f09 100644 --- a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/Rm.java +++ b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/Rm.java
@@ -58,7 +58,7 @@ class Rm extends TextBuiltin { @Argument(metaVar = "metaVar_path", usage = "usage_path", multiValued = true, required = true) @Option(name = "--", handler = StopOptionHandler.class) - private List<String> paths = new ArrayList<String>(); + private List<String> paths = new ArrayList<>(); @Override
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 43b292e..b7f5e58 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
@@ -117,7 +117,7 @@ private void printPorcelainStatus(org.eclipse.jgit.api.Status status) Map<String, StageState> conflicting = status.getConflictingStageState(); // build a sorted list of all paths except untracked and ignored - TreeSet<String> sorted = new TreeSet<String>(); + TreeSet<String> sorted = new TreeSet<>(); sorted.addAll(added); sorted.addAll(changed); sorted.addAll(removed); @@ -185,7 +185,7 @@ else if (missing.contains(path)) // untracked are always at the end of the list if ("all".equals(untrackedFilesMode)) { //$NON-NLS-1$ - TreeSet<String> untracked = new TreeSet<String>( + TreeSet<String> untracked = new TreeSet<>( status.getUntracked()); for (String path : untracked) printPorcelainLine('?', '?', path); @@ -221,7 +221,7 @@ private void printLongStatus(org.eclipse.jgit.api.Status status) Collection<String> untracked = status.getUntracked(); Map<String, StageState> unmergedStates = status .getConflictingStageState(); - Collection<String> toBeCommitted = new ArrayList<String>(added); + Collection<String> toBeCommitted = new ArrayList<>(added); toBeCommitted.addAll(changed); toBeCommitted.addAll(removed); int nbToBeCommitted = toBeCommitted.size(); @@ -232,7 +232,7 @@ private void printLongStatus(org.eclipse.jgit.api.Status status) toBeCommitted, added, changed, removed); firstHeader = false; } - Collection<String> notStagedForCommit = new ArrayList<String>(modified); + Collection<String> notStagedForCommit = new ArrayList<>(modified); notStagedForCommit.addAll(missing); int nbNotStagedForCommit = notStagedForCommit.size(); if (nbNotStagedForCommit > 0) { @@ -274,7 +274,7 @@ protected void printSectionHeader(String pattern, Object... arguments) protected int printList(Collection<String> list) throws IOException { if (!list.isEmpty()) { - List<String> sortedList = new ArrayList<String>(list); + List<String> sortedList = new ArrayList<>(list); java.util.Collections.sort(sortedList); for (String filename : sortedList) { outw.println(CLIText.formatLine(String.format( @@ -291,7 +291,7 @@ protected int printList(String status1, String status2, String status3, Collection<String> set2, @SuppressWarnings("unused") Collection<String> set3) throws IOException { - List<String> sortedList = new ArrayList<String>(list); + List<String> sortedList = new ArrayList<>(list); java.util.Collections.sort(sortedList); for (String filename : sortedList) { String prefix; @@ -311,7 +311,7 @@ else if (set2.contains(filename)) private void printUnmerged(Map<String, StageState> unmergedStates) throws IOException { - List<String> paths = new ArrayList<String>(unmergedStates.keySet()); + List<String> paths = new ArrayList<>(unmergedStates.keySet()); Collections.sort(paths); for (String path : paths) { StageState state = unmergedStates.get(path);
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 05d094f..44ec3f4 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
@@ -84,12 +84,14 @@ class DiffAlgorithms extends TextBuiltin { final Algorithm myers = new Algorithm() { + @Override DiffAlgorithm create() { return MyersDiff.INSTANCE; } }; final Algorithm histogram = new Algorithm() { + @Override DiffAlgorithm create() { HistogramDiff d = new HistogramDiff(); d.setFallbackAlgorithm(null); @@ -98,6 +100,7 @@ DiffAlgorithm create() { }; final Algorithm histogram_myers = new Algorithm() { + @Override DiffAlgorithm create() { HistogramDiff d = new HistogramDiff(); d.setFallbackAlgorithm(MyersDiff.INSTANCE); @@ -112,13 +115,13 @@ DiffAlgorithm create() { // @Option(name = "--algorithm", multiValued = true, metaVar = "NAME", usage = "Enable algorithm(s)") - List<String> algorithms = new ArrayList<String>(); + List<String> algorithms = new ArrayList<>(); @Option(name = "--text-limit", metaVar = "LIMIT", usage = "Maximum size in KiB to scan per file revision") int textLimit = 15 * 1024; // 15 MiB as later we do * 1024. @Option(name = "--repository", aliases = { "-r" }, multiValued = true, metaVar = "GIT_DIR", usage = "Repository to scan") - List<File> gitDirs = new ArrayList<File>(); + List<File> gitDirs = new ArrayList<>(); @Option(name = "--count", metaVar = "LIMIT", usage = "Number of file revisions to be compared") int count = 0; // unlimited @@ -234,6 +237,7 @@ private void run(Repository repo) throws Exception { } Collections.sort(all, new Comparator<Test>() { + @Override public int compare(Test a, Test b) { int result = Long.signum(a.runningTimeNanos - b.runningTimeNanos); if (result == 0) { @@ -320,7 +324,7 @@ private void testOne(Test test, RawText a, RawText b) { } private List<Test> init() { - List<Test> all = new ArrayList<Test>(); + List<Test> all = new ArrayList<>(); try { for (Field f : DiffAlgorithms.class.getDeclaredFields()) {
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 52b6d19..5839f33 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
@@ -219,6 +219,7 @@ protected boolean requiresRepository() { return false; } + @Override protected void run() throws Exception { AppServer server = new AppServer(port); URI baseURI = server.getURI(); @@ -254,7 +255,7 @@ protected void run() throws Exception { @Override protected LargeFileRepository getLargeFileRepository( - LfsRequest request, String path) { + LfsRequest request, String path, String auth) { return repository; } };
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 8cfcba9..da602d0 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
@@ -112,7 +112,7 @@ class RebuildCommitGraph extends TextBuiltin { private final ProgressMonitor pm = new TextProgressMonitor(errw); - private Map<ObjectId, ObjectId> rewrites = new HashMap<ObjectId, ObjectId>(); + private Map<ObjectId, ObjectId> rewrites = new HashMap<>(); @Override protected void run() throws Exception { @@ -137,8 +137,8 @@ protected void run() throws Exception { } private void recreateCommitGraph() throws IOException { - final Map<ObjectId, ToRewrite> toRewrite = new HashMap<ObjectId, ToRewrite>(); - List<ToRewrite> queue = new ArrayList<ToRewrite>(); + final Map<ObjectId, ToRewrite> toRewrite = new HashMap<>(); + List<ToRewrite> queue = new ArrayList<>(); try (RevWalk rw = new RevWalk(db); final BufferedReader br = new BufferedReader( new InputStreamReader(new FileInputStream(graph), @@ -176,7 +176,7 @@ private void recreateCommitGraph() throws IOException { while (!queue.isEmpty()) { final ListIterator<ToRewrite> itr = queue .listIterator(queue.size()); - queue = new ArrayList<ToRewrite>(); + queue = new ArrayList<>(); REWRITE: while (itr.hasPrevious()) { final ToRewrite t = itr.previous(); final ObjectId[] newParents = new ObjectId[t.oldParents.length]; @@ -278,7 +278,7 @@ protected void writeFile(final String name, final byte[] content) } private Map<String, Ref> computeNewRefs() throws IOException { - final Map<String, Ref> refs = new HashMap<String, Ref>(); + final Map<String, Ref> refs = new HashMap<>(); try (RevWalk rw = new RevWalk(db); BufferedReader br = new BufferedReader( new InputStreamReader(new FileInputStream(refList),
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 aa25807..415c7d3 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
@@ -85,6 +85,7 @@ protected void run() throws Exception { static enum Format { /** */ USAGE { + @Override void print(ThrowingPrintWriter err, final CommandRef c) throws IOException { String usage = c.getUsage(); if (usage != null && usage.length() > 0) @@ -94,6 +95,7 @@ void print(ThrowingPrintWriter err, final CommandRef c) throws IOException { /** */ CLASSES { + @Override void print(ThrowingPrintWriter err, final CommandRef c) throws IOException { err.print(c.getImplementationClassName()); } @@ -101,6 +103,7 @@ void print(ThrowingPrintWriter err, final CommandRef c) throws IOException { /** */ URLS { + @Override void print(ThrowingPrintWriter err, final CommandRef c) throws IOException { final ClassLoader ldr = c.getImplementationClassLoader();
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 28d92ae..0eb4e05 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
@@ -251,16 +251,16 @@ public int fold(int hash, int bits) { // @Option(name = "--hash", multiValued = true, metaVar = "NAME", usage = "Enable hash function(s)") - List<String> hashFunctions = new ArrayList<String>(); + List<String> hashFunctions = new ArrayList<>(); @Option(name = "--fold", multiValued = true, metaVar = "NAME", usage = "Enable fold function(s)") - List<String> foldFunctions = new ArrayList<String>(); + List<String> foldFunctions = new ArrayList<>(); @Option(name = "--text-limit", metaVar = "LIMIT", usage = "Maximum size in KiB to scan") int textLimit = 15 * 1024; // 15 MiB as later we do * 1024. @Option(name = "--repository", aliases = { "-r" }, multiValued = true, metaVar = "GIT_DIR", usage = "Repository to scan") - List<File> gitDirs = new ArrayList<File>(); + List<File> gitDirs = new ArrayList<>(); @Override protected boolean requiresRepository() { @@ -327,7 +327,7 @@ private void run(Repository repo) throws Exception { RawText txt = new RawText(raw); int[] lines = new int[txt.size()]; int cnt = 0; - HashSet<Line> u = new HashSet<Line>(); + HashSet<Line> u = new HashSet<>(); for (int i = 0; i < txt.size(); i++) { if (u.add(new Line(txt, i))) lines[cnt++] = i; @@ -386,8 +386,8 @@ private static void testOne(Function fun, RawText txt, int[] elements, } private List<Function> init() { - List<Hash> hashes = new ArrayList<Hash>(); - List<Fold> folds = new ArrayList<Fold>(); + List<Hash> hashes = new ArrayList<>(); + List<Fold> folds = new ArrayList<>(); try { for (Field f : TextHashFunctions.class.getDeclaredFields()) { @@ -410,7 +410,7 @@ private List<Function> init() { throw new RuntimeException("Cannot determine names", e); //$NON-NLS-1$ } - List<Function> all = new ArrayList<Function>(); + List<Function> all = new ArrayList<>(); for (Hash cmp : hashes) { if (include(cmp.name, hashFunctions)) { for (Fold f : folds) {
diff --git a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/internal/CLIText.java b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/internal/CLIText.java index 90c03e9..4842b98 100644 --- a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/internal/CLIText.java +++ b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/internal/CLIText.java
@@ -68,7 +68,6 @@ public static CLIText get() { * @param line * the line to format * @return the formatted line - * @since 2.2 */ public static String formatLine(String line) { return MessageFormat.format(get().lineFormat, line); @@ -81,7 +80,6 @@ public static String formatLine(String line) { * @param message * the message to format * @return the formatted line - * @since 4.2 */ public static String fatalError(String message) { return MessageFormat.format(get().fatalError, message);
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 b531ba6..020b625 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
@@ -141,7 +141,7 @@ public CmdLineParser(final Object bean, Repository repo) { @Override public void parseArgument(final String... args) throws CmdLineException { - final ArrayList<String> tmp = new ArrayList<String>(args.length); + final ArrayList<String> tmp = new ArrayList<>(args.length); for (int argi = 0; argi < args.length; argi++) { final String str = args[argi]; if (str.equals("--")) { //$NON-NLS-1$
diff --git a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/opt/PathTreeFilterHandler.java b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/opt/PathTreeFilterHandler.java index e468023..b873c3d 100644 --- a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/opt/PathTreeFilterHandler.java +++ b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/opt/PathTreeFilterHandler.java
@@ -81,7 +81,7 @@ public PathTreeFilterHandler(final CmdLineParser parser, @Override public int parseArguments(final Parameters params) throws CmdLineException { - final List<PathFilter> filters = new ArrayList<PathFilter>(); + final List<PathFilter> filters = new ArrayList<>(); for (int idx = 0;; idx++) { final String path; try {
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 10c29d5..64f7498 100644 --- a/org.eclipse.jgit.test/.settings/org.eclipse.jdt.core.prefs +++ b/org.eclipse.jgit.test/.settings/org.eclipse.jdt.core.prefs
@@ -56,7 +56,7 @@ org.eclipse.jdt.core.compiler.problem.missingJavadocTagsMethodTypeParameters=disabled org.eclipse.jdt.core.compiler.problem.missingJavadocTagsOverriding=disabled org.eclipse.jdt.core.compiler.problem.missingJavadocTagsVisibility=private -org.eclipse.jdt.core.compiler.problem.missingOverrideAnnotation=ignore +org.eclipse.jdt.core.compiler.problem.missingOverrideAnnotation=warning org.eclipse.jdt.core.compiler.problem.missingOverrideAnnotationForInterfaceMethodImplementation=enabled org.eclipse.jdt.core.compiler.problem.missingSerialVersion=warning org.eclipse.jdt.core.compiler.problem.missingSynchronizedOnInheritedMethod=ignore @@ -76,7 +76,7 @@ org.eclipse.jdt.core.compiler.problem.rawTypeReference=ignore org.eclipse.jdt.core.compiler.problem.redundantNullAnnotation=warning org.eclipse.jdt.core.compiler.problem.redundantNullCheck=warning -org.eclipse.jdt.core.compiler.problem.redundantSpecificationOfTypeArguments=ignore +org.eclipse.jdt.core.compiler.problem.redundantSpecificationOfTypeArguments=warning org.eclipse.jdt.core.compiler.problem.redundantSuperinterface=error org.eclipse.jdt.core.compiler.problem.reportMethodCanBePotentiallyStatic=ignore org.eclipse.jdt.core.compiler.problem.reportMethodCanBeStatic=ignore
diff --git a/org.eclipse.jgit.test/BUCK b/org.eclipse.jgit.test/BUCK deleted file mode 100644 index 5b7be89..0000000 --- a/org.eclipse.jgit.test/BUCK +++ /dev/null
@@ -1,95 +0,0 @@ -PKG = 'tst/org/eclipse/jgit/' -HELPERS = glob(['src/**/*.java']) + [PKG + c for c in [ - 'api/AbstractRemoteCommandTest.java', - 'diff/AbstractDiffTestCase.java', - 'internal/storage/file/GcTestCase.java', - 'internal/storage/file/PackIndexTestCase.java', - 'internal/storage/file/XInputStream.java', - 'nls/GermanTranslatedBundle.java', - 'nls/MissingPropertyBundle.java', - 'nls/NoPropertiesBundle.java', - 'nls/NonTranslatedBundle.java', - 'revwalk/RevQueueTestCase.java', - 'revwalk/RevWalkTestCase.java', - 'transport/SpiTransport.java', - 'treewalk/FileTreeIteratorWithTimeControl.java', - 'treewalk/filter/AlwaysCloneTreeFilter.java', - 'test/resources/SampleDataRepositoryTestCase.java', - 'util/CPUTimeStopWatch.java', - 'util/io/Strings.java', -]] - -DATA = [ - PKG + 'lib/empty.gitindex.dat', - PKG + 'lib/sorttest.gitindex.dat', -] - -TESTS = glob( - ['tst/**/*.java'], - excludes = HELPERS + DATA, -) - -DEPS = { - PKG + 'nls/RootLocaleTest.java': [ - '//org.eclipse.jgit.pgm:pgm', - '//org.eclipse.jgit.ui:ui', - ], -} - -for src in TESTS: - name = src[len('tst/'):len(src)-len('.java')].replace('/', '.') - labels = [] - if name.startswith('org.eclipse.jgit.'): - l = name[len('org.eclipse.jgit.'):] - if l.startswith('internal.storage.'): - l = l[len('internal.storage.'):] - i = l.find('.') - if i > 0: - labels.append(l[:i]) - else: - labels.append(i) - if 'lib' not in labels: - labels.append('lib') - - java_test( - name = name, - labels = labels, - srcs = [src], - deps = [ - ':helpers', - ':tst_rsrc', - '//org.eclipse.jgit:jgit', - '//org.eclipse.jgit.junit:junit', - '//org.eclipse.jgit.lfs:jgit-lfs', - '//lib:hamcrest-core', - '//lib:hamcrest-library', - '//lib:javaewah', - '//lib:junit', - '//lib:slf4j-api', - '//lib:slf4j-simple', - ] + DEPS.get(src, []), - vm_args = ['-Xmx256m', '-Dfile.encoding=UTF-8'], - ) - -java_library( - name = 'helpers', - srcs = HELPERS, - resources = DATA, - deps = [ - '//org.eclipse.jgit:jgit', - '//org.eclipse.jgit.junit:junit', - '//lib:junit', - ], -) - -prebuilt_jar( - name = 'tst_rsrc', - binary_jar = ':tst_rsrc_jar', -) - -genrule( - name = 'tst_rsrc_jar', - cmd = 'cd $SRCDIR/tst-rsrc ; zip -qr $OUT .', - srcs = glob(['tst-rsrc/**']), - out = 'tst_rsrc.jar', -)
diff --git a/org.eclipse.jgit.test/BUILD b/org.eclipse.jgit.test/BUILD new file mode 100644 index 0000000..bbda838 --- /dev/null +++ b/org.eclipse.jgit.test/BUILD
@@ -0,0 +1,61 @@ +load(":tests.bzl", "tests") +load( + "@com_googlesource_gerrit_bazlets//tools:genrule2.bzl", + "genrule2", +) + +PKG = "tst/org/eclipse/jgit/" + +HELPERS = glob(["src/**/*.java"]) + [PKG + c for c in [ + "api/AbstractRemoteCommandTest.java", + "diff/AbstractDiffTestCase.java", + "internal/storage/file/GcTestCase.java", + "internal/storage/file/PackIndexTestCase.java", + "internal/storage/file/XInputStream.java", + "nls/GermanTranslatedBundle.java", + "nls/MissingPropertyBundle.java", + "nls/NoPropertiesBundle.java", + "nls/NonTranslatedBundle.java", + "revwalk/RevQueueTestCase.java", + "revwalk/RevWalkTestCase.java", + "transport/SpiTransport.java", + "treewalk/FileTreeIteratorWithTimeControl.java", + "treewalk/filter/AlwaysCloneTreeFilter.java", + "test/resources/SampleDataRepositoryTestCase.java", + "util/CPUTimeStopWatch.java", + "util/io/Strings.java", +]] + +DATA = [ + PKG + "lib/empty.gitindex.dat", + PKG + "lib/sorttest.gitindex.dat", +] + +tests(glob( + ["tst/**/*.java"], + exclude = HELPERS + DATA, +)) + +java_library( + name = "helpers", + testonly = 1, + srcs = HELPERS, + resources = DATA, + deps = [ + "//lib:junit", + "//org.eclipse.jgit:jgit", + "//org.eclipse.jgit.junit:junit", + ], +) + +java_import( + name = "tst_rsrc", + jars = [":tst_rsrc_jar"], +) + +genrule2( + name = "tst_rsrc_jar", + srcs = glob(["tst-rsrc/**"]), + outs = ["tst_rsrc.jar"], + cmd = "o=$$PWD/$@ && tar cf - $(SRCS) | tar -C $$TMP --strip-components=2 -xf - && cd $$TMP && zip -qr $$o .", +)
diff --git a/org.eclipse.jgit.test/META-INF/MANIFEST.MF b/org.eclipse.jgit.test/META-INF/MANIFEST.MF index f48cae0..ef10d92 100644 --- a/org.eclipse.jgit.test/META-INF/MANIFEST.MF +++ b/org.eclipse.jgit.test/META-INF/MANIFEST.MF
@@ -2,53 +2,54 @@ Bundle-ManifestVersion: 2 Bundle-Name: %plugin_name Bundle-SymbolicName: org.eclipse.jgit.test -Bundle-Version: 4.6.2.qualifier +Bundle-Version: 4.7.6.qualifier Bundle-Localization: plugin Bundle-Vendor: %provider_name Bundle-ActivationPolicy: lazy Bundle-RequiredExecutionEnvironment: JavaSE-1.8 Import-Package: com.googlecode.javaewah;version="[1.1.6,2.0.0)", - org.eclipse.jgit.api;version="[4.6.2,4.7.0)", - org.eclipse.jgit.api.errors;version="[4.6.2,4.7.0)", - org.eclipse.jgit.attributes;version="[4.6.2,4.7.0)", - org.eclipse.jgit.awtui;version="[4.6.2,4.7.0)", - org.eclipse.jgit.blame;version="[4.6.2,4.7.0)", - org.eclipse.jgit.diff;version="[4.6.2,4.7.0)", - org.eclipse.jgit.dircache;version="[4.6.2,4.7.0)", - org.eclipse.jgit.errors;version="[4.6.2,4.7.0)", - org.eclipse.jgit.events;version="[4.6.2,4.7.0)", - org.eclipse.jgit.fnmatch;version="[4.6.2,4.7.0)", - org.eclipse.jgit.gitrepo;version="[4.6.2,4.7.0)", - org.eclipse.jgit.hooks;version="[4.6.2,4.7.0)", - org.eclipse.jgit.ignore;version="[4.6.2,4.7.0)", - org.eclipse.jgit.ignore.internal;version="[4.6.2,4.7.0)", - org.eclipse.jgit.internal;version="[4.6.2,4.7.0)", - org.eclipse.jgit.internal.storage.dfs;version="[4.6.2,4.7.0)", - org.eclipse.jgit.internal.storage.file;version="[4.6.2,4.7.0)", - org.eclipse.jgit.internal.storage.pack;version="[4.6.2,4.7.0)", - org.eclipse.jgit.internal.storage.reftree;version="[4.6.2,4.7.0)", - org.eclipse.jgit.junit;version="[4.6.2,4.7.0)", - org.eclipse.jgit.lfs;version="[4.6.2,4.7.0)", - org.eclipse.jgit.lib;version="[4.6.2,4.7.0)", - org.eclipse.jgit.merge;version="[4.6.2,4.7.0)", - org.eclipse.jgit.nls;version="[4.6.2,4.7.0)", - org.eclipse.jgit.notes;version="[4.6.2,4.7.0)", - org.eclipse.jgit.patch;version="[4.6.2,4.7.0)", - org.eclipse.jgit.pgm;version="[4.6.2,4.7.0)", - org.eclipse.jgit.pgm.internal;version="[4.6.2,4.7.0)", - org.eclipse.jgit.revplot;version="[4.6.2,4.7.0)", - org.eclipse.jgit.revwalk;version="[4.6.2,4.7.0)", - org.eclipse.jgit.revwalk.filter;version="[4.6.2,4.7.0)", - org.eclipse.jgit.storage.file;version="[4.6.2,4.7.0)", - org.eclipse.jgit.storage.pack;version="[4.6.2,4.7.0)", - org.eclipse.jgit.submodule;version="[4.6.2,4.7.0)", - org.eclipse.jgit.transport;version="[4.6.2,4.7.0)", - org.eclipse.jgit.transport.http;version="[4.6.2,4.7.0)", - org.eclipse.jgit.transport.resolver;version="[4.6.2,4.7.0)", - org.eclipse.jgit.treewalk;version="[4.6.2,4.7.0)", - org.eclipse.jgit.treewalk.filter;version="[4.6.2,4.7.0)", - org.eclipse.jgit.util;version="[4.6.2,4.7.0)", - org.eclipse.jgit.util.io;version="[4.6.2,4.7.0)", + org.eclipse.jgit.api;version="[4.7.6,4.8.0)", + org.eclipse.jgit.api.errors;version="[4.7.6,4.8.0)", + org.eclipse.jgit.attributes;version="[4.7.6,4.8.0)", + org.eclipse.jgit.awtui;version="[4.7.6,4.8.0)", + org.eclipse.jgit.blame;version="[4.7.6,4.8.0)", + org.eclipse.jgit.diff;version="[4.7.6,4.8.0)", + org.eclipse.jgit.dircache;version="[4.7.6,4.8.0)", + org.eclipse.jgit.errors;version="[4.7.6,4.8.0)", + org.eclipse.jgit.events;version="[4.7.6,4.8.0)", + org.eclipse.jgit.fnmatch;version="[4.7.6,4.8.0)", + org.eclipse.jgit.gitrepo;version="[4.7.6,4.8.0)", + org.eclipse.jgit.hooks;version="[4.7.6,4.8.0)", + org.eclipse.jgit.ignore;version="[4.7.6,4.8.0)", + org.eclipse.jgit.ignore.internal;version="[4.7.6,4.8.0)", + org.eclipse.jgit.internal;version="[4.7.6,4.8.0)", + org.eclipse.jgit.internal.storage.dfs;version="[4.7.6,4.8.0)", + org.eclipse.jgit.internal.storage.file;version="[4.7.6,4.8.0)", + org.eclipse.jgit.internal.storage.pack;version="[4.7.6,4.8.0)", + org.eclipse.jgit.internal.storage.reftree;version="[4.7.6,4.8.0)", + org.eclipse.jgit.junit;version="[4.7.6,4.8.0)", + org.eclipse.jgit.lfs;version="[4.7.6,4.8.0)", + org.eclipse.jgit.lib;version="[4.7.6,4.8.0)", + org.eclipse.jgit.merge;version="[4.7.6,4.8.0)", + org.eclipse.jgit.nls;version="[4.7.6,4.8.0)", + org.eclipse.jgit.notes;version="[4.7.6,4.8.0)", + org.eclipse.jgit.patch;version="[4.7.6,4.8.0)", + org.eclipse.jgit.pgm;version="[4.7.6,4.8.0)", + org.eclipse.jgit.pgm.internal;version="[4.7.6,4.8.0)", + org.eclipse.jgit.revplot;version="[4.7.6,4.8.0)", + org.eclipse.jgit.revwalk;version="[4.7.6,4.8.0)", + org.eclipse.jgit.revwalk.filter;version="[4.7.6,4.8.0)", + org.eclipse.jgit.storage.file;version="[4.7.6,4.8.0)", + org.eclipse.jgit.storage.pack;version="[4.7.6,4.8.0)", + org.eclipse.jgit.submodule;version="[4.7.6,4.8.0)", + org.eclipse.jgit.transport;version="[4.7.6,4.8.0)", + org.eclipse.jgit.transport.http;version="[4.7.6,4.8.0)", + org.eclipse.jgit.transport.resolver;version="[4.7.6,4.8.0)", + org.eclipse.jgit.treewalk;version="[4.7.6,4.8.0)", + org.eclipse.jgit.treewalk.filter;version="[4.7.6,4.8.0)", + org.eclipse.jgit.util;version="[4.7.6,4.8.0)", + org.eclipse.jgit.util.io;version="[4.7.6,4.8.0)", + org.eclipse.jgit.util.sha1;version="[4.7.6,4.8.0)", org.junit;version="[4.4.0,5.0.0)", org.junit.experimental.theories;version="[4.4.0,5.0.0)", org.junit.rules;version="[4.11.0,5.0.0)",
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 76930f2..7c0ea44 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
@@ -89,7 +89,7 @@ static class PatchReader extends CommitReader { super(new String[] { "-p" }); stats = s; - offBy1 = new HashSet<String>(); + offBy1 = new HashSet<>(); offBy1.add("9bda5ece6806cd797416eaa47c7b927cc6e9c3b2"); } @@ -158,7 +158,7 @@ private static void dump(final byte[] buf) { } static class NumStatReader extends CommitReader { - final HashMap<String, HashMap<String, StatInfo>> stats = new HashMap<String, HashMap<String, StatInfo>>(); + final HashMap<String, HashMap<String, StatInfo>> stats = new HashMap<>(); NumStatReader() throws IOException { super(new String[] { "--numstat" }); @@ -166,7 +166,7 @@ static class NumStatReader extends CommitReader { @Override void onCommit(String commitId, byte[] buf) { - final HashMap<String, StatInfo> files = new HashMap<String, StatInfo>(); + final HashMap<String, StatInfo> files = new HashMap<>(); final MutableInteger ptr = new MutableInteger(); while (ptr.value < buf.length) { if (buf[ptr.value] == '\n')
diff --git a/org.eclipse.jgit.test/pom.xml b/org.eclipse.jgit.test/pom.xml index 1aff289..42f2b86 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>4.6.2-SNAPSHOT</version> + <version>4.7.6-SNAPSHOT</version> </parent> <artifactId>org.eclipse.jgit.test</artifactId> @@ -155,6 +155,10 @@ <artifactId>maven-surefire-plugin</artifactId> <configuration> <argLine>-Xmx256m -Dfile.encoding=UTF-8 -Djava.io.tmpdir=${project.build.directory}</argLine> + <includes> + <include>**/*Test.java</include> + <include>**/*Tests.java</include> + </includes> </configuration> </plugin> </plugins>
diff --git a/org.eclipse.jgit.test/src/org/eclipse/jgit/lib/Sets.java b/org.eclipse.jgit.test/src/org/eclipse/jgit/lib/Sets.java index 4454e1a..5a01eae 100644 --- a/org.eclipse.jgit.test/src/org/eclipse/jgit/lib/Sets.java +++ b/org.eclipse.jgit.test/src/org/eclipse/jgit/lib/Sets.java
@@ -49,7 +49,7 @@ public class Sets { @SafeVarargs public static <T> Set<T> of(T... elements) { - Set<T> ret = new HashSet<T>(); + Set<T> ret = new HashSet<>(); for (T element : elements) ret.add(element); return ret;
diff --git a/org.eclipse.jgit.test/tests.bzl b/org.eclipse.jgit.test/tests.bzl new file mode 100644 index 0000000..8ae0065 --- /dev/null +++ b/org.eclipse.jgit.test/tests.bzl
@@ -0,0 +1,48 @@ +load( + "@com_googlesource_gerrit_bazlets//tools:junit.bzl", + "junit_tests", +) + +def tests(tests): + for src in tests: + name = src[len("tst/"):len(src) - len(".java")].replace("/", "_") + labels = [] + if name.startswith("org_eclipse_jgit_"): + l = name[len("org.eclipse.jgit_"):] + if l.startswith("internal_storage_"): + l = l[len("internal.storage_"):] + i = l.find("_") + if i > 0: + labels.append(l[:i]) + else: + labels.append(i) + if "lib" not in labels: + labels.append("lib") + + additional_deps = [] + if src.endswith("RootLocaleTest.java"): + additional_deps = [ + "//org.eclipse.jgit.pgm:pgm", + "//org.eclipse.jgit.ui:ui", + ] + if src.endswith("WalkEncryptionTest.java"): + additional_deps = [ + "//org.eclipse.jgit:insecure_cipher_factory", + ] + + junit_tests( + name = name, + tags = labels, + srcs = [src], + deps = additional_deps + [ + ":helpers", + ":tst_rsrc", + "//lib:javaewah", + "//lib:junit", + "//lib:slf4j-api", + "//org.eclipse.jgit:jgit", + "//org.eclipse.jgit.junit:junit", + "//org.eclipse.jgit.lfs:jgit-lfs", + ], + jvm_flags = ["-Xmx256m", "-Dfile.encoding=UTF-8"], + )
diff --git a/org.eclipse.jgit.test/tst-rsrc/org/eclipse/jgit/util/sha1/shattered-1.pdf b/org.eclipse.jgit.test/tst-rsrc/org/eclipse/jgit/util/sha1/shattered-1.pdf new file mode 100644 index 0000000..ba9aaa1 --- /dev/null +++ b/org.eclipse.jgit.test/tst-rsrc/org/eclipse/jgit/util/sha1/shattered-1.pdf Binary files differ
diff --git a/org.eclipse.jgit.test/tst-rsrc/org/eclipse/jgit/util/sha1/shattered-2.pdf b/org.eclipse.jgit.test/tst-rsrc/org/eclipse/jgit/util/sha1/shattered-2.pdf new file mode 100644 index 0000000..b621eec --- /dev/null +++ b/org.eclipse.jgit.test/tst-rsrc/org/eclipse/jgit/util/sha1/shattered-2.pdf Binary files differ
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 5ad73f1..ed3907e 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
@@ -1074,30 +1074,37 @@ public void testExecutableRetention() throws Exception { FS executableFs = new FS() { + @Override public boolean supportsExecute() { return true; } + @Override public boolean setExecute(File f, boolean canExec) { return true; } + @Override public ProcessBuilder runInShell(String cmd, String[] args) { return null; } + @Override public boolean retryFailedLockFileCommit() { return false; } + @Override public FS newInstance() { return this; } + @Override protected File discoverGitExe() { return null; } + @Override public boolean canExecute(File f) { try { return read(f).startsWith("binary:");
diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/ArchiveCommandTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/ArchiveCommandTest.java index fc8df42..edab96b 100644 --- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/ArchiveCommandTest.java +++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/ArchiveCommandTest.java
@@ -57,6 +57,7 @@ import org.eclipse.jgit.api.errors.GitAPIException; import org.eclipse.jgit.junit.RepositoryTestCase; import org.eclipse.jgit.lib.FileMode; +import org.eclipse.jgit.lib.ObjectId; import org.eclipse.jgit.lib.ObjectLoader; import org.eclipse.jgit.revwalk.RevCommit; import org.eclipse.jgit.util.StringUtils; @@ -78,6 +79,7 @@ public void setup() { ArchiveCommand.registerFormat(format.SUFFIXES.get(0), format); } + @Override @After public void tearDown() { ArchiveCommand.unregisterFormat(format.SUFFIXES.get(0)); @@ -190,7 +192,7 @@ public void archiveByDirectoryPath() throws GitAPIException, IOException { private class MockFormat implements ArchiveCommand.Format<MockOutputStream> { - private Map<String, String> entries = new HashMap<String, String>(); + private Map<String, String> entries = new HashMap<>(); private int size() { return entries.size(); @@ -203,12 +205,14 @@ private String getByPath(String path) { private final List<String> SUFFIXES = Collections .unmodifiableList(Arrays.asList(".mck")); + @Override public MockOutputStream createArchiveOutputStream(OutputStream s) throws IOException { return createArchiveOutputStream(s, Collections.<String, Object> emptyMap()); } + @Override public MockOutputStream createArchiveOutputStream(OutputStream s, Map<String, Object> o) throws IOException { for (Map.Entry<String, Object> p : o.entrySet()) { @@ -224,11 +228,18 @@ public MockOutputStream createArchiveOutputStream(OutputStream s, return new MockOutputStream(); } + @Override public void putEntry(MockOutputStream out, String path, FileMode mode, ObjectLoader loader) { + putEntry(out, null, path, mode, loader); + } + + @Override + public void putEntry(MockOutputStream out, ObjectId tree, String path, FileMode mode, ObjectLoader loader) { String content = mode != FileMode.TREE ? new String(loader.getBytes()) : null; entries.put(path, content); } + @Override public Iterable<String> suffixes() { return SUFFIXES; }
diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/CleanCommandTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/CleanCommandTest.java index 0e1cf02..85436db 100644 --- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/CleanCommandTest.java +++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/CleanCommandTest.java
@@ -64,6 +64,7 @@ public class CleanCommandTest extends RepositoryTestCase { private Git git; + @Override @Before public void setUp() throws Exception { super.setUp(); @@ -143,7 +144,7 @@ public void testCleanWithPaths() throws NoWorkTreeException, assertTrue(files.size() > 0); // run clean with setPaths - Set<String> paths = new TreeSet<String>(); + Set<String> paths = new TreeSet<>(); paths.add("File3.txt"); Set<String> cleanedFiles = git.clean().setPaths(paths).call();
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 8a728ca..ae0b8dd 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
@@ -85,9 +85,10 @@ public class CloneCommandTest extends RepositoryTestCase { private TestRepository<Repository> tr; + @Override public void setUp() throws Exception { super.setUp(); - tr = new TestRepository<Repository>(db); + tr = new TestRepository<>(db); git = new Git(db); // commit something
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 021c245..37fee40 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
@@ -93,30 +93,37 @@ public void testExecutableRetention() throws Exception { FS executableFs = new FS() { + @Override public boolean supportsExecute() { return true; } + @Override public boolean setExecute(File f, boolean canExec) { return true; } + @Override public ProcessBuilder runInShell(String cmd, String[] args) { return null; } + @Override public boolean retryFailedLockFileCommit() { return false; } + @Override public FS newInstance() { return this; } + @Override protected File discoverGitExe() { return null; } + @Override public boolean canExecute(File f) { return true; } @@ -138,30 +145,37 @@ public boolean isCaseSensitive() { FS nonExecutableFs = new FS() { + @Override public boolean supportsExecute() { return false; } + @Override public boolean setExecute(File f, boolean canExec) { return false; } + @Override public ProcessBuilder runInShell(String cmd, String[] args) { return null; } + @Override public boolean retryFailedLockFileCommit() { return false; } + @Override public FS newInstance() { return this; } + @Override protected File discoverGitExe() { return null; } + @Override public boolean canExecute(File f) { return false; }
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 5f10131..48d3733 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
@@ -623,6 +623,7 @@ private void setupGitAndDoHardReset(AutoCRLF autoCRLF, EOL eol, for (int i = 0; i < dc.getEntryCount(); i++) { editor.add(new DirCacheEditor.PathEdit( dc.getEntry(i).getPathString()) { + @Override public void apply(DirCacheEntry ent) { ent.smudgeRacilyClean(); }
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 new file mode 100644 index 0000000..73a705b --- /dev/null +++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/FetchAndPullCommandsRecurseSubmodulesTest.java
@@ -0,0 +1,361 @@ +/* + * Copyright (C) 2017 David Pursehouse <david.pursehouse@gmail.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 org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertTrue; + +import java.io.File; + +import org.eclipse.jgit.api.ResetCommand.ResetType; +import org.eclipse.jgit.junit.JGitTestUtil; +import org.eclipse.jgit.junit.RepositoryTestCase; +import org.eclipse.jgit.lib.ConfigConstants; +import org.eclipse.jgit.lib.Constants; +import org.eclipse.jgit.lib.ObjectId; +import org.eclipse.jgit.lib.Repository; +import org.eclipse.jgit.lib.StoredConfig; +import org.eclipse.jgit.lib.SubmoduleConfig.FetchRecurseSubmodulesMode; +import org.eclipse.jgit.revwalk.RevCommit; +import org.eclipse.jgit.submodule.SubmoduleStatus; +import org.eclipse.jgit.submodule.SubmoduleStatusType; +import org.eclipse.jgit.submodule.SubmoduleWalk; +import org.eclipse.jgit.transport.FetchResult; +import org.eclipse.jgit.transport.RefSpec; +import org.junit.Before; +import org.junit.experimental.theories.DataPoints; +import org.junit.experimental.theories.Theories; +import org.junit.experimental.theories.Theory; +import org.junit.runner.RunWith; + +@RunWith(Theories.class) +public class FetchAndPullCommandsRecurseSubmodulesTest extends RepositoryTestCase { + @DataPoints + public static boolean[] useFetch = { true, false }; + + private Git git; + + private Git git2; + + private Git sub1Git; + + private Git sub2Git; + + private RevCommit commit1; + + private RevCommit commit2; + + private ObjectId submodule1Head; + + private ObjectId submodule2Head; + + private final RefSpec REFSPEC = new RefSpec("refs/heads/master"); + + private final String REMOTE = "origin"; + + private final String PATH = "sub"; + + @Before + public void setUpSubmodules() throws Exception { + git = new Git(db); + + // Create submodule 1 + File submodule1 = createTempDirectory( + "testCloneRepositoryWithNestedSubmodules1"); + sub1Git = Git.init().setDirectory(submodule1).call(); + assertNotNull(sub1Git); + Repository sub1 = sub1Git.getRepository(); + assertNotNull(sub1); + addRepoToClose(sub1); + + String file = "file.txt"; + + write(new File(sub1.getWorkTree(), file), "content"); + sub1Git.add().addFilepattern(file).call(); + RevCommit commit = sub1Git.commit().setMessage("create file").call(); + assertNotNull(commit); + + // Create submodule 2 + File submodule2 = createTempDirectory( + "testCloneRepositoryWithNestedSubmodules2"); + sub2Git = Git.init().setDirectory(submodule2).call(); + assertNotNull(sub2Git); + Repository sub2 = sub2Git.getRepository(); + assertNotNull(sub2); + addRepoToClose(sub2); + + write(new File(sub2.getWorkTree(), file), "content"); + sub2Git.add().addFilepattern(file).call(); + RevCommit sub2Head = sub2Git.commit().setMessage("create file").call(); + assertNotNull(sub2Head); + + // Add submodule 2 to submodule 1 + Repository r2 = sub1Git.submoduleAdd().setPath(PATH) + .setURI(sub2.getDirectory().toURI().toString()).call(); + assertNotNull(r2); + addRepoToClose(r2); + RevCommit sub1Head = sub1Git.commit().setAll(true) + .setMessage("Adding submodule").call(); + assertNotNull(sub1Head); + + // Add submodule 1 to default repository + Repository r1 = git.submoduleAdd().setPath(PATH) + .setURI(sub1.getDirectory().toURI().toString()).call(); + assertNotNull(r1); + addRepoToClose(r1); + assertNotNull(git.commit().setAll(true).setMessage("Adding submodule") + .call()); + + // Clone default repository and include submodules + File directory = createTempDirectory( + "testCloneRepositoryWithNestedSubmodules"); + CloneCommand clone = Git.cloneRepository(); + clone.setDirectory(directory); + clone.setCloneSubmodules(true); + clone.setURI(git.getRepository().getDirectory().toURI().toString()); + git2 = clone.call(); + addRepoToClose(git2.getRepository()); + assertNotNull(git2); + + // Record current FETCH_HEAD of submodules + try (SubmoduleWalk walk = SubmoduleWalk + .forIndex(git2.getRepository())) { + assertTrue(walk.next()); + Repository r = walk.getRepository(); + submodule1Head = r.resolve(Constants.FETCH_HEAD); + + try (SubmoduleWalk walk2 = SubmoduleWalk.forIndex(r)) { + assertTrue(walk2.next()); + submodule2Head = walk2.getRepository() + .resolve(Constants.FETCH_HEAD); + } + } + + // Commit in submodule 1 + JGitTestUtil.writeTrashFile(r1, "f1.txt", "test"); + sub1Git.add().addFilepattern("f1.txt").call(); + commit1 = sub1Git.commit().setMessage("new commit").call(); + + // Commit in submodule 2 + JGitTestUtil.writeTrashFile(r2, "f2.txt", "test"); + sub2Git.add().addFilepattern("f2.txt").call(); + commit2 = sub2Git.commit().setMessage("new commit").call(); + } + + @Theory + public void shouldNotFetchSubmodulesWhenNo(boolean fetch) throws Exception { + FetchResult result = execute(FetchRecurseSubmodulesMode.NO, fetch); + assertTrue(result.submoduleResults().isEmpty()); + assertSubmoduleFetchHeads(submodule1Head, submodule2Head); + } + + @Theory + public void shouldFetchSubmodulesWhenYes(boolean fetch) throws Exception { + FetchResult result = execute(FetchRecurseSubmodulesMode.YES, fetch); + assertTrue(result.submoduleResults().containsKey("sub")); + FetchResult subResult = result.submoduleResults().get("sub"); + assertTrue(subResult.submoduleResults().containsKey("sub")); + assertSubmoduleFetchHeads(commit1, commit2); + } + + @Theory + public void shouldFetchSubmodulesWhenOnDemandAndRevisionChanged( + boolean fetch) throws Exception { + RevCommit update = updateSubmoduleRevision(); + FetchResult result = execute(FetchRecurseSubmodulesMode.ON_DEMAND, + fetch); + + // The first submodule should have been updated + assertTrue(result.submoduleResults().containsKey("sub")); + FetchResult subResult = result.submoduleResults().get("sub"); + + // The second submodule should not get updated + assertTrue(subResult.submoduleResults().isEmpty()); + assertSubmoduleFetchHeads(commit1, submodule2Head); + + // After fetch the parent repo's fetch head should be the commit + // that updated the submodule. + assertEquals(update, + git2.getRepository().resolve(Constants.FETCH_HEAD)); + } + + @Theory + public void shouldNotFetchSubmodulesWhenOnDemandAndRevisionNotChanged( + boolean fetch) throws Exception { + FetchResult result = execute(FetchRecurseSubmodulesMode.ON_DEMAND, + fetch); + assertTrue(result.submoduleResults().isEmpty()); + assertSubmoduleFetchHeads(submodule1Head, submodule2Head); + } + + @Theory + public void shouldNotFetchSubmodulesWhenSubmoduleConfigurationSetToNo( + boolean fetch) throws Exception { + StoredConfig config = git2.getRepository().getConfig(); + config.setEnum(ConfigConstants.CONFIG_SUBMODULE_SECTION, PATH, + ConfigConstants.CONFIG_KEY_FETCH_RECURSE_SUBMODULES, + FetchRecurseSubmodulesMode.NO); + config.save(); + updateSubmoduleRevision(); + FetchResult result = execute(null, fetch); + assertTrue(result.submoduleResults().isEmpty()); + assertSubmoduleFetchHeads(submodule1Head, submodule2Head); + } + + @Theory + public void shouldFetchSubmodulesWhenSubmoduleConfigurationSetToYes( + boolean fetch) throws Exception { + StoredConfig config = git2.getRepository().getConfig(); + config.setEnum(ConfigConstants.CONFIG_SUBMODULE_SECTION, PATH, + ConfigConstants.CONFIG_KEY_FETCH_RECURSE_SUBMODULES, + FetchRecurseSubmodulesMode.YES); + config.save(); + FetchResult result = execute(null, fetch); + assertTrue(result.submoduleResults().containsKey("sub")); + FetchResult subResult = result.submoduleResults().get("sub"); + assertTrue(subResult.submoduleResults().containsKey("sub")); + assertSubmoduleFetchHeads(commit1, commit2); + } + + @Theory + public void shouldNotFetchSubmodulesWhenFetchConfigurationSetToNo( + boolean fetch) throws Exception { + StoredConfig config = git2.getRepository().getConfig(); + config.setEnum(ConfigConstants.CONFIG_FETCH_SECTION, null, + ConfigConstants.CONFIG_KEY_RECURSE_SUBMODULES, + FetchRecurseSubmodulesMode.NO); + config.save(); + updateSubmoduleRevision(); + FetchResult result = execute(null, fetch); + assertTrue(result.submoduleResults().isEmpty()); + assertSubmoduleFetchHeads(submodule1Head, submodule2Head); + } + + @Theory + public void shouldFetchSubmodulesWhenFetchConfigurationSetToYes( + boolean fetch) throws Exception { + StoredConfig config = git2.getRepository().getConfig(); + config.setEnum(ConfigConstants.CONFIG_FETCH_SECTION, null, + ConfigConstants.CONFIG_KEY_RECURSE_SUBMODULES, + FetchRecurseSubmodulesMode.YES); + config.save(); + FetchResult result = execute(null, fetch); + assertTrue(result.submoduleResults().containsKey("sub")); + FetchResult subResult = result.submoduleResults().get("sub"); + assertTrue(subResult.submoduleResults().containsKey("sub")); + assertSubmoduleFetchHeads(commit1, commit2); + } + + private RevCommit updateSubmoduleRevision() throws Exception { + // Fetch the submodule in the original git and reset it to + // the commit that was created + try (SubmoduleWalk w = SubmoduleWalk.forIndex(git.getRepository())) { + assertTrue(w.next()); + try (Git g = new Git(w.getRepository())) { + g.fetch().setRemote(REMOTE).setRefSpecs(REFSPEC).call(); + g.reset().setMode(ResetType.HARD).setRef(commit1.name()).call(); + } + } + + // Submodule index Id should be same as before, but head Id should be + // updated to the new commit, and status should be "checked out". + SubmoduleStatus subStatus = git.submoduleStatus().call().get("sub"); + assertEquals(submodule1Head, subStatus.getIndexId()); + assertEquals(commit1, subStatus.getHeadId()); + assertEquals(SubmoduleStatusType.REV_CHECKED_OUT, subStatus.getType()); + + // Add and commit the submodule status + git.add().addFilepattern("sub").call(); + RevCommit update = git.commit().setMessage("update sub").call(); + + // Both submodule index and head should now be at the new commit, and + // the status should be "initialized". + subStatus = git.submoduleStatus().call().get("sub"); + assertEquals(commit1, subStatus.getIndexId()); + assertEquals(commit1, subStatus.getHeadId()); + assertEquals(SubmoduleStatusType.INITIALIZED, subStatus.getType()); + + return update; + } + + private FetchResult execute(FetchRecurseSubmodulesMode mode, boolean fetch) + throws Exception { + FetchResult result; + + if (fetch) { + result = git2.fetch().setRemote(REMOTE).setRefSpecs(REFSPEC) + .setRecurseSubmodules(mode).call(); + } else { + // For the purposes of this test we don't need to care about the + // pull result, or the result of pull with merge. We are only + // interested in checking whether or not the submodules were updated + // as expected. Setting to rebase makes it easier to assert about + // the state of the parent repository head, i.e. we know it should + // be at the submodule update commit, and don't need to consider a + // merge commit created by the pull. + result = git2.pull().setRemote(REMOTE).setRebase(true) + .setRecurseSubmodules(mode).call().getFetchResult(); + } + assertNotNull(result); + return result; + } + + private void assertSubmoduleFetchHeads(ObjectId expectedHead1, + ObjectId expectedHead2) throws Exception { + 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); + } + + assertEquals(expectedHead1, newHead1); + assertEquals(expectedHead2, newHead2); + } + } +}
diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/FetchCommandTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/FetchCommandTest.java index 56a1f38..a36f6c5 100644 --- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/FetchCommandTest.java +++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/FetchCommandTest.java
@@ -45,12 +45,8 @@ import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNull; -import java.io.IOException; -import java.net.URISyntaxException; import java.util.Collection; -import org.eclipse.jgit.api.errors.GitAPIException; -import org.eclipse.jgit.api.errors.JGitInternalException; import org.eclipse.jgit.junit.RepositoryTestCase; import org.eclipse.jgit.lib.Constants; import org.eclipse.jgit.lib.ObjectId; @@ -74,7 +70,7 @@ public class FetchCommandTest extends RepositoryTestCase { private Git remoteGit; @Before - public void setupRemoteRepository() throws IOException, URISyntaxException { + public void setupRemoteRepository() throws Exception { git = new Git(db); // create other repository @@ -91,8 +87,7 @@ public void setupRemoteRepository() throws IOException, URISyntaxException { } @Test - public void testFetch() throws JGitInternalException, IOException, - GitAPIException { + public void testFetch() throws Exception { // create some refs via commits and tag RevCommit commit = remoteGit.commit().setMessage("initial commit").call();
diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/GitConstructionTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/GitConstructionTest.java index 3bff8f2..a4e5574 100644 --- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/GitConstructionTest.java +++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/GitConstructionTest.java
@@ -55,7 +55,6 @@ import org.eclipse.jgit.junit.RepositoryTestCase; import org.eclipse.jgit.lib.Repository; import org.eclipse.jgit.util.FileUtils; -import org.junit.After; import org.junit.Before; import org.junit.Test; @@ -80,14 +79,6 @@ public void setUp() throws Exception { addRepoToClose(bareRepo); } - @Override - @After - public void tearDown() throws Exception { - db.close(); - bareRepo.close(); - super.tearDown(); - } - @Test public void testWrap() throws JGitInternalException, GitAPIException { Git git = Git.wrap(db); @@ -141,7 +132,6 @@ public void testOpen() throws IOException, JGitInternalException, public void testClose() throws IOException, JGitInternalException, GitAPIException { File workTree = db.getWorkTree(); - db.close(); Git git = Git.open(workTree); git.gc().setExpire(null).call(); git.checkout().setName(git.getRepository().resolve("HEAD^").getName())
diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/LogCommandTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/LogCommandTest.java index 1310625..38178bf 100644 --- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/LogCommandTest.java +++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/LogCommandTest.java
@@ -62,7 +62,7 @@ public class LogCommandTest extends RepositoryTestCase { @Test public void logAllCommits() throws Exception { - List<RevCommit> commits = new ArrayList<RevCommit>(); + List<RevCommit> commits = new ArrayList<>(); Git git = Git.wrap(db); writeTrashFile("Test.txt", "Hello world"); @@ -94,7 +94,7 @@ public void logAllCommits() throws Exception { @Test public void logAllCommitsWithTag() throws Exception { - List<RevCommit> commits = new ArrayList<RevCommit>(); + List<RevCommit> commits = new ArrayList<>(); Git git = Git.wrap(db); writeTrashFile("Test.txt", "Hello world"); @@ -123,7 +123,7 @@ public void logAllCommitsWithTag() throws Exception { } private List<RevCommit> createCommits(Git git) throws Exception { - List<RevCommit> commits = new ArrayList<RevCommit>(); + List<RevCommit> commits = new ArrayList<>(); writeTrashFile("Test.txt", "Hello world"); git.add().addFilepattern("Test.txt").call(); commits.add(git.commit().setMessage("commit#1").call());
diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/LsRemoteCommandTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/LsRemoteCommandTest.java index a853d6a..c9f77ea 100644 --- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/LsRemoteCommandTest.java +++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/LsRemoteCommandTest.java
@@ -58,6 +58,7 @@ public class LsRemoteCommandTest extends RepositoryTestCase { private Git git; + @Override public void setUp() throws Exception { super.setUp(); git = new Git(db);
diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/MergeCommandTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/MergeCommandTest.java index cb3dbf1..4b23349 100644 --- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/MergeCommandTest.java +++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/MergeCommandTest.java
@@ -1556,7 +1556,7 @@ public void testFastForwardOnlyNotPossible() throws Exception { @Test public void testRecursiveMergeWithConflict() throws Exception { - TestRepository<Repository> db_t = new TestRepository<Repository>(db); + TestRepository<Repository> db_t = new TestRepository<>(db); BranchBuilder master = db_t.branch("master"); RevCommit m0 = master.commit().add("f", "1\n2\n3\n4\n5\n6\n7\n8\n9\n") .message("m0").create();
diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/NameRevCommandTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/NameRevCommandTest.java index bd62200..138b7af 100644 --- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/NameRevCommandTest.java +++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/NameRevCommandTest.java
@@ -64,7 +64,7 @@ public class NameRevCommandTest extends RepositoryTestCase { @Before public void setUp() throws Exception { super.setUp(); - tr = new TestRepository<Repository>(db); + tr = new TestRepository<>(db); git = new Git(db); }
diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/PullCommandTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/PullCommandTest.java index a526fda..823516b 100644 --- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/PullCommandTest.java +++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/PullCommandTest.java
@@ -346,6 +346,7 @@ private enum TestPullMode { /** global rebase config should be respected */ public void testPullWithRebasePreserve1Config() throws Exception { Callable<PullResult> setup = new Callable<PullResult>() { + @Override public PullResult call() throws Exception { StoredConfig config = dbTarget.getConfig(); config.setString("pull", null, "rebase", "preserve"); @@ -360,6 +361,7 @@ public PullResult call() throws Exception { /** the branch-local config should win over the global config */ public void testPullWithRebasePreserveConfig2() throws Exception { Callable<PullResult> setup = new Callable<PullResult>() { + @Override public PullResult call() throws Exception { StoredConfig config = dbTarget.getConfig(); config.setString("pull", null, "rebase", "false"); @@ -375,6 +377,7 @@ public PullResult call() throws Exception { /** the branch-local config should be respected */ public void testPullWithRebasePreserveConfig3() throws Exception { Callable<PullResult> setup = new Callable<PullResult>() { + @Override public PullResult call() throws Exception { StoredConfig config = dbTarget.getConfig(); config.setString("branch", "master", "rebase", "preserve"); @@ -389,6 +392,7 @@ public PullResult call() throws Exception { /** global rebase config should be respected */ public void testPullWithRebaseConfig1() throws Exception { Callable<PullResult> setup = new Callable<PullResult>() { + @Override public PullResult call() throws Exception { StoredConfig config = dbTarget.getConfig(); config.setString("pull", null, "rebase", "true"); @@ -403,6 +407,7 @@ public PullResult call() throws Exception { /** the branch-local config should win over the global config */ public void testPullWithRebaseConfig2() throws Exception { Callable<PullResult> setup = new Callable<PullResult>() { + @Override public PullResult call() throws Exception { StoredConfig config = dbTarget.getConfig(); config.setString("pull", null, "rebase", "preserve"); @@ -418,6 +423,7 @@ public PullResult call() throws Exception { /** the branch-local config should be respected */ public void testPullWithRebaseConfig3() throws Exception { Callable<PullResult> setup = new Callable<PullResult>() { + @Override public PullResult call() throws Exception { StoredConfig config = dbTarget.getConfig(); config.setString("branch", "master", "rebase", "true"); @@ -432,6 +438,7 @@ public PullResult call() throws Exception { /** without config it should merge */ public void testPullWithoutConfig() throws Exception { Callable<PullResult> setup = new Callable<PullResult>() { + @Override public PullResult call() throws Exception { return target.pull().call(); } @@ -443,6 +450,7 @@ public PullResult call() throws Exception { /** the branch local config should win over the global config */ public void testPullWithMergeConfig() throws Exception { Callable<PullResult> setup = new Callable<PullResult>() { + @Override public PullResult call() throws Exception { StoredConfig config = dbTarget.getConfig(); config.setString("pull", null, "rebase", "true"); @@ -458,6 +466,7 @@ public PullResult call() throws Exception { /** the branch local config should win over the global config */ public void testPullWithMergeConfig2() throws Exception { Callable<PullResult> setup = new Callable<PullResult>() { + @Override public PullResult call() throws Exception { StoredConfig config = dbTarget.getConfig(); config.setString("pull", null, "rebase", "false");
diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/PushCommandTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/PushCommandTest.java index 2a32540..8c613ec 100644 --- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/PushCommandTest.java +++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/PushCommandTest.java
@@ -66,8 +66,10 @@ import org.eclipse.jgit.lib.StoredConfig; import org.eclipse.jgit.revwalk.RevCommit; import org.eclipse.jgit.transport.PushResult; +import org.eclipse.jgit.transport.RefLeaseSpec; import org.eclipse.jgit.transport.RefSpec; import org.eclipse.jgit.transport.RemoteConfig; +import org.eclipse.jgit.transport.RemoteRefUpdate; import org.eclipse.jgit.transport.TrackingRefUpdate; import org.eclipse.jgit.transport.URIish; import org.eclipse.jgit.util.FS; @@ -379,4 +381,56 @@ public void testPushAfterGC() throws Exception { db2.resolve(commit3.getId().getName() + "^{commit}")); } } + + @Test + public void testPushWithLease() throws JGitInternalException, IOException, + GitAPIException, URISyntaxException { + + // create other repository + Repository db2 = createWorkRepository(); + + // setup the first repository + final StoredConfig config = db.getConfig(); + RemoteConfig remoteConfig = new RemoteConfig(config, "test"); + URIish uri = new URIish(db2.getDirectory().toURI().toURL()); + remoteConfig.addURI(uri); + remoteConfig.update(config); + config.save(); + + try (Git git1 = new Git(db)) { + // create one commit and push it + RevCommit commit = git1.commit().setMessage("initial commit").call(); + git1.branchCreate().setName("initial").call(); + + RefSpec spec = new RefSpec("refs/heads/master:refs/heads/x"); + git1.push().setRemote("test").setRefSpecs(spec) + .call(); + + assertEquals(commit.getId(), + db2.resolve(commit.getId().getName() + "^{commit}")); + //now try to force-push a new commit, with a good lease + + git1.commit().setMessage("second commit").call(); + Iterable<PushResult> results = + git1.push().setRemote("test").setRefSpecs(spec) + .setRefLeaseSpecs(new RefLeaseSpec("refs/heads/x", "initial")) + .call(); + for (PushResult result : results) { + RemoteRefUpdate update = result.getRemoteUpdate("refs/heads/x"); + assertEquals(update.getStatus(), RemoteRefUpdate.Status.OK); + } + + git1.commit().setMessage("third commit").call(); + //now try to force-push a new commit, with a bad lease + + results = + git1.push().setRemote("test").setRefSpecs(spec) + .setRefLeaseSpecs(new RefLeaseSpec("refs/heads/x", "initial")) + .call(); + for (PushResult result : results) { + RemoteRefUpdate update = result.getRemoteUpdate("refs/heads/x"); + assertEquals(update.getStatus(), RemoteRefUpdate.Status.REJECTED_REMOTE_CHANGED); + } + } + } }
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 24cb522..0cc0816 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
@@ -2269,11 +2269,13 @@ public void testRebaseShouldNotFailIfUserAddCommentLinesInPrepareSteps() RebaseResult res = git.rebase().setUpstream("HEAD~2") .runInteractively(new InteractiveHandler() { + @Override public void prepareSteps(List<RebaseTodoLine> steps) { steps.add(0, new RebaseTodoLine( "# Comment that should not be processed")); } + @Override public String modifyCommitMessage(String commit) { fail("modifyCommitMessage() was not expected to be called"); return commit; @@ -2284,6 +2286,7 @@ public String modifyCommitMessage(String commit) { RebaseResult res2 = git.rebase().setUpstream("HEAD~2") .runInteractively(new InteractiveHandler() { + @Override public void prepareSteps(List<RebaseTodoLine> steps) { try { // delete RevCommit c4 @@ -2293,6 +2296,7 @@ public void prepareSteps(List<RebaseTodoLine> steps) { } } + @Override public String modifyCommitMessage(String commit) { fail("modifyCommitMessage() was not expected to be called"); return commit; @@ -2514,6 +2518,7 @@ public void testRebaseInteractiveReword() throws Exception { RebaseResult res = git.rebase().setUpstream("HEAD~2") .runInteractively(new InteractiveHandler() { + @Override public void prepareSteps(List<RebaseTodoLine> steps) { try { steps.get(0).setAction(Action.REWORD); @@ -2522,6 +2527,7 @@ public void prepareSteps(List<RebaseTodoLine> steps) { } } + @Override public String modifyCommitMessage(String commit) { return "rewritten commit message"; } @@ -2560,6 +2566,7 @@ public void testRebaseInteractiveEdit() throws Exception { RebaseResult res = git.rebase().setUpstream("HEAD~2") .runInteractively(new InteractiveHandler() { + @Override public void prepareSteps(List<RebaseTodoLine> steps) { try { steps.get(0).setAction(Action.EDIT); @@ -2568,6 +2575,7 @@ public void prepareSteps(List<RebaseTodoLine> steps) { } } + @Override public String modifyCommitMessage(String commit) { return ""; // not used } @@ -2624,6 +2632,7 @@ public void testRebaseInteractiveSingleSquashAndModifyMessage() throws Exception git.rebase().setUpstream("HEAD~3") .runInteractively(new InteractiveHandler() { + @Override public void prepareSteps(List<RebaseTodoLine> steps) { try { steps.get(1).setAction(Action.SQUASH); @@ -2632,6 +2641,7 @@ public void prepareSteps(List<RebaseTodoLine> steps) { } } + @Override public String modifyCommitMessage(String commit) { final File messageSquashFile = new File(db .getDirectory(), "rebase-merge/message-squash"); @@ -2704,6 +2714,7 @@ public void testRebaseInteractiveMultipleSquash() throws Exception { git.rebase().setUpstream("HEAD~4") .runInteractively(new InteractiveHandler() { + @Override public void prepareSteps(List<RebaseTodoLine> steps) { try { steps.get(1).setAction(Action.SQUASH); @@ -2713,6 +2724,7 @@ public void prepareSteps(List<RebaseTodoLine> steps) { } } + @Override public String modifyCommitMessage(String commit) { final File messageSquashFile = new File(db.getDirectory(), "rebase-merge/message-squash"); @@ -2786,6 +2798,7 @@ public void testRebaseInteractiveMixedSquashAndFixup() throws Exception { git.rebase().setUpstream("HEAD~4") .runInteractively(new InteractiveHandler() { + @Override public void prepareSteps(List<RebaseTodoLine> steps) { try { steps.get(1).setAction(Action.FIXUP); @@ -2795,6 +2808,7 @@ public void prepareSteps(List<RebaseTodoLine> steps) { } } + @Override public String modifyCommitMessage(String commit) { final File messageSquashFile = new File(db .getDirectory(), "rebase-merge/message-squash"); @@ -2861,6 +2875,7 @@ public void testRebaseInteractiveSingleFixup() throws Exception { git.rebase().setUpstream("HEAD~3") .runInteractively(new InteractiveHandler() { + @Override public void prepareSteps(List<RebaseTodoLine> steps) { try { steps.get(1).setAction(Action.FIXUP); @@ -2869,6 +2884,7 @@ public void prepareSteps(List<RebaseTodoLine> steps) { } } + @Override public String modifyCommitMessage(String commit) { fail("No callback to modify commit message expected for single fixup"); return commit; @@ -2910,6 +2926,7 @@ public void testRebaseInteractiveFixupWithBlankLines() throws Exception { git.rebase().setUpstream("HEAD~2") .runInteractively(new InteractiveHandler() { + @Override public void prepareSteps(List<RebaseTodoLine> steps) { try { steps.get(1).setAction(Action.FIXUP); @@ -2918,6 +2935,7 @@ public void prepareSteps(List<RebaseTodoLine> steps) { } } + @Override public String modifyCommitMessage(String commit) { fail("No callback to modify commit message expected for single fixup"); return commit; @@ -2950,6 +2968,7 @@ public void testRebaseInteractiveFixupFirstCommitShouldFail() git.rebase().setUpstream("HEAD~1") .runInteractively(new InteractiveHandler() { + @Override public void prepareSteps(List<RebaseTodoLine> steps) { try { steps.get(0).setAction(Action.FIXUP); @@ -2958,6 +2977,7 @@ public void prepareSteps(List<RebaseTodoLine> steps) { } } + @Override public String modifyCommitMessage(String commit) { return commit; } @@ -2982,6 +3002,7 @@ public void testRebaseInteractiveSquashFirstCommitShouldFail() git.rebase().setUpstream("HEAD~1") .runInteractively(new InteractiveHandler() { + @Override public void prepareSteps(List<RebaseTodoLine> steps) { try { steps.get(0).setAction(Action.SQUASH); @@ -2990,6 +3011,7 @@ public void prepareSteps(List<RebaseTodoLine> steps) { } } + @Override public String modifyCommitMessage(String commit) { return commit; } @@ -3013,6 +3035,7 @@ public void testRebaseEndsIfLastStepIsEdit() throws Exception { git.rebase().setUpstream("HEAD~1") .runInteractively(new InteractiveHandler() { + @Override public void prepareSteps(List<RebaseTodoLine> steps) { try { steps.get(0).setAction(Action.EDIT); @@ -3021,6 +3044,7 @@ public void prepareSteps(List<RebaseTodoLine> steps) { } } + @Override public String modifyCommitMessage(String commit) { return commit; } @@ -3055,6 +3079,7 @@ public void testRebaseShouldStopForEditInCaseOfConflict() RebaseResult result = git.rebase().setUpstream("HEAD~2") .runInteractively(new InteractiveHandler() { + @Override public void prepareSteps(List<RebaseTodoLine> steps) { steps.remove(0); try { @@ -3064,6 +3089,7 @@ public void prepareSteps(List<RebaseTodoLine> steps) { } } + @Override public String modifyCommitMessage(String commit) { return commit; } @@ -3097,6 +3123,7 @@ public void testRebaseShouldStopForRewordInCaseOfConflict() RebaseResult result = git.rebase().setUpstream("HEAD~2") .runInteractively(new InteractiveHandler() { + @Override public void prepareSteps(List<RebaseTodoLine> steps) { steps.remove(0); try { @@ -3106,6 +3133,7 @@ public void prepareSteps(List<RebaseTodoLine> steps) { } } + @Override public String modifyCommitMessage(String commit) { return "rewritten commit message"; } @@ -3114,6 +3142,7 @@ public String modifyCommitMessage(String commit) { git.add().addFilepattern(FILE1).call(); result = git.rebase().runInteractively(new InteractiveHandler() { + @Override public void prepareSteps(List<RebaseTodoLine> steps) { steps.remove(0); try { @@ -3123,6 +3152,7 @@ public void prepareSteps(List<RebaseTodoLine> steps) { } } + @Override public String modifyCommitMessage(String commit) { return "rewritten commit message"; } @@ -3160,6 +3190,7 @@ public void testRebaseShouldSquashInCaseOfConflict() throws Exception { RebaseResult result = git.rebase().setUpstream("HEAD~3") .runInteractively(new InteractiveHandler() { + @Override public void prepareSteps(List<RebaseTodoLine> steps) { try { steps.get(0).setAction(Action.PICK); @@ -3170,6 +3201,7 @@ public void prepareSteps(List<RebaseTodoLine> steps) { } } + @Override public String modifyCommitMessage(String commit) { return "squashed message"; } @@ -3178,6 +3210,7 @@ public String modifyCommitMessage(String commit) { git.add().addFilepattern(FILE1).call(); result = git.rebase().runInteractively(new InteractiveHandler() { + @Override public void prepareSteps(List<RebaseTodoLine> steps) { try { steps.get(0).setAction(Action.PICK); @@ -3188,6 +3221,7 @@ public void prepareSteps(List<RebaseTodoLine> steps) { } } + @Override public String modifyCommitMessage(String commit) { return "squashed message"; } @@ -3226,6 +3260,7 @@ public void testRebaseShouldFixupInCaseOfConflict() throws Exception { RebaseResult result = git.rebase().setUpstream("HEAD~3") .runInteractively(new InteractiveHandler() { + @Override public void prepareSteps(List<RebaseTodoLine> steps) { try { steps.get(0).setAction(Action.PICK); @@ -3236,6 +3271,7 @@ public void prepareSteps(List<RebaseTodoLine> steps) { } } + @Override public String modifyCommitMessage(String commit) { return commit; } @@ -3244,6 +3280,7 @@ public String modifyCommitMessage(String commit) { git.add().addFilepattern(FILE1).call(); result = git.rebase().runInteractively(new InteractiveHandler() { + @Override public void prepareSteps(List<RebaseTodoLine> steps) { try { steps.get(0).setAction(Action.PICK); @@ -3254,6 +3291,7 @@ public void prepareSteps(List<RebaseTodoLine> steps) { } } + @Override public String modifyCommitMessage(String commit) { return "commit"; } @@ -3297,6 +3335,7 @@ public void testInteractiveRebaseWithModificationShouldNotDeleteDataOnAbort() RebaseResult result = git.rebase().setUpstream("HEAD~2") .runInteractively(new InteractiveHandler() { + @Override public void prepareSteps(List<RebaseTodoLine> steps) { try { steps.get(0).setAction(Action.EDIT); @@ -3306,6 +3345,7 @@ public void prepareSteps(List<RebaseTodoLine> steps) { } } + @Override public String modifyCommitMessage(String commit) { return commit; }
diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/RenameBranchCommandTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/RenameBranchCommandTest.java index 4c09a82..5c437ac 100644 --- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/RenameBranchCommandTest.java +++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/RenameBranchCommandTest.java
@@ -69,6 +69,7 @@ public class RenameBranchCommandTest extends RepositoryTestCase { private Git git; + @Override @Before public void setUp() throws Exception { super.setUp();
diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/StashApplyCommandTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/StashApplyCommandTest.java index ce235a7..f2e4d5b 100644 --- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/StashApplyCommandTest.java +++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/StashApplyCommandTest.java
@@ -77,6 +77,7 @@ public class StashApplyCommandTest extends RepositoryTestCase { private File committedFile; + @Override @Before public void setUp() throws Exception { super.setUp(); @@ -736,4 +737,21 @@ public void untrackedFileConflictsWithWorkingDirectory() } assertEquals("working-directory", read(path)); } + + @Test + public void untrackedAndTrackedChanges() throws Exception { + writeTrashFile(PATH, "changed"); + String path = "untracked.txt"; + writeTrashFile(path, "untracked"); + git.stashCreate().setIncludeUntracked(true).call(); + assertTrue(PATH + " should exist", check(PATH)); + assertEquals(PATH + " should have been reset", "content", read(PATH)); + assertFalse(path + " should not exist", check(path)); + git.stashApply().setStashRef("stash@{0}").call(); + assertTrue(PATH + " should exist", check(PATH)); + assertEquals(PATH + " should have new content", "changed", read(PATH)); + assertTrue(path + " should exist", check(path)); + assertEquals(path + " should have new content", "untracked", + read(path)); + } }
diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/StashCreateCommandTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/StashCreateCommandTest.java index ae8551e..b9f9f5b 100644 --- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/StashCreateCommandTest.java +++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/StashCreateCommandTest.java
@@ -82,6 +82,7 @@ public class StashCreateCommandTest extends RepositoryTestCase { private File untrackedFile; + @Override @Before public void setUp() throws Exception { super.setUp();
diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/StashDropCommandTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/StashDropCommandTest.java index 859277e..5d5be5d 100644 --- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/StashDropCommandTest.java +++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/StashDropCommandTest.java
@@ -73,6 +73,7 @@ public class StashDropCommandTest extends RepositoryTestCase { private File committedFile; + @Override @Before public void setUp() throws Exception { super.setUp();
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 b044c01..1d9cd78 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
@@ -204,7 +204,7 @@ public void testCheckinCheckoutDifferences() throws IOException, @Test public void testIndexOnly() throws IOException, NoFilepatternException, GitAPIException { - List<File> attrFiles = new ArrayList<File>(); + List<File> attrFiles = new ArrayList<>(); attrFiles.add(writeGlobalAttributeFile("globalAttributesFile", "*.txt -custom2")); attrFiles.add(writeAttributesFile(".git/info/attributes", @@ -813,7 +813,7 @@ private void assertEntry(FileMode type, String pathName, } private static Set<Attribute> asSet(Collection<Attribute> attributes) { - Set<Attribute> ret = new HashSet<Attribute>(); + Set<Attribute> ret = new HashSet<>(); for (Attribute a : attributes) { ret.add(a); } @@ -853,7 +853,7 @@ private File writeGlobalAttributeFile(String fileName, String... attributes) } static Set<Attribute> asSet(Attribute... attrs) { - HashSet<Attribute> result = new HashSet<Attribute>(); + HashSet<Attribute> result = new HashSet<>(); for (Attribute attr : attrs) result.add(attr); return result;
diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/diff/DiffEntryTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/diff/DiffEntryTest.java index 443c956..73c230a 100644 --- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/diff/DiffEntryTest.java +++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/diff/DiffEntryTest.java
@@ -395,6 +395,7 @@ public void shouldReportFileModeChange() throws Exception { assertTrue(walk.next()); editor.add(new PathEdit("a.txt") { + @Override public void apply(DirCacheEntry ent) { ent.setFileMode(FileMode.EXECUTABLE_FILE); ent.setObjectId(walk.getObjectId(0));
diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/diff/DiffFormatterTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/diff/DiffFormatterTest.java index b4234dc..fabf034 100644 --- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/diff/DiffFormatterTest.java +++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/diff/DiffFormatterTest.java
@@ -89,7 +89,7 @@ public class DiffFormatterTest extends RepositoryTestCase { @Before public void setUp() throws Exception { super.setUp(); - testDb = new TestRepository<Repository>(db); + testDb = new TestRepository<>(db); df = new DiffFormatter(DisabledOutputStream.INSTANCE); df.setRepository(db); df.setAbbreviationLength(8);
diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/diff/RenameDetectorTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/diff/RenameDetectorTest.java index 4315be9..64eb1c9 100644 --- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/diff/RenameDetectorTest.java +++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/diff/RenameDetectorTest.java
@@ -75,7 +75,7 @@ public class RenameDetectorTest extends RepositoryTestCase { @Before public void setUp() throws Exception { super.setUp(); - testDb = new TestRepository<Repository>(db); + testDb = new TestRepository<>(db); rd = new RenameDetector(db); }
diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/dircache/DirCacheBuilderTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/dircache/DirCacheBuilderTest.java index 5408f76..d12f302 100644 --- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/dircache/DirCacheBuilderTest.java +++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/dircache/DirCacheBuilderTest.java
@@ -211,6 +211,7 @@ final class ReceivedEventMarkerException extends RuntimeException { DirCache dc = db.lockDirCache(); IndexChangedListener listener = new IndexChangedListener() { + @Override public void onIndexChanged(IndexChangedEvent event) { throw new ReceivedEventMarkerException(); } @@ -238,6 +239,7 @@ public void onIndexChanged(IndexChangedEvent event) { dc = db.lockDirCache(); listener = new IndexChangedListener() { + @Override public void onIndexChanged(IndexChangedEvent event) { throw new ReceivedEventMarkerException(); }
diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/dircache/DirCacheCGitCompatabilityTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/dircache/DirCacheCGitCompatabilityTest.java index 3e78046..92ce4e1 100644 --- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/dircache/DirCacheCGitCompatabilityTest.java +++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/dircache/DirCacheCGitCompatabilityTest.java
@@ -178,7 +178,7 @@ public void testReadIndex_DirCacheTree() throws Exception { .getObjectId()); assertEquals(cList.size(), jTree.getEntrySpan()); - final ArrayList<CGitLsTreeRecord> subtrees = new ArrayList<CGitLsTreeRecord>(); + final ArrayList<CGitLsTreeRecord> subtrees = new ArrayList<>(); for (final CGitLsTreeRecord r : cTree.values()) { if (FileMode.TREE.equals(r.mode)) subtrees.add(r); @@ -233,7 +233,7 @@ private static File pathOf(final String name) { } private static Map<String, CGitIndexRecord> readLsFiles() throws Exception { - final LinkedHashMap<String, CGitIndexRecord> r = new LinkedHashMap<String, CGitIndexRecord>(); + final LinkedHashMap<String, CGitIndexRecord> r = new LinkedHashMap<>(); final BufferedReader br = new BufferedReader(new InputStreamReader( new FileInputStream(pathOf("gitgit.lsfiles")), "UTF-8")); try { @@ -249,7 +249,7 @@ private static Map<String, CGitIndexRecord> readLsFiles() throws Exception { } private static Map<String, CGitLsTreeRecord> readLsTree() throws Exception { - final LinkedHashMap<String, CGitLsTreeRecord> r = new LinkedHashMap<String, CGitLsTreeRecord>(); + final LinkedHashMap<String, CGitLsTreeRecord> r = new LinkedHashMap<>(); final BufferedReader br = new BufferedReader(new InputStreamReader( new FileInputStream(pathOf("gitgit.lstree")), "UTF-8")); try {
diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/dircache/DirCachePathEditTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/dircache/DirCachePathEditTest.java index c85e156..20897a8 100644 --- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/dircache/DirCachePathEditTest.java +++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/dircache/DirCachePathEditTest.java
@@ -72,7 +72,7 @@ public void apply(DirCacheEntry ent) { } private static final class RecordingEdit extends PathEdit { - final List<DirCacheEntry> entries = new ArrayList<DirCacheEntry>(); + final List<DirCacheEntry> entries = new ArrayList<>(); public RecordingEdit(String entryPath) { super(entryPath);
diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/events/ConfigChangeEventTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/events/ConfigChangeEventTest.java index 3c1f231..3624100 100644 --- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/events/ConfigChangeEventTest.java +++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/events/ConfigChangeEventTest.java
@@ -56,6 +56,7 @@ public void testFileRepository_ChangeEventsOnlyOnSave() throws Exception { final ConfigChangedEvent[] events = new ConfigChangedEvent[1]; db.getListenerList().addConfigChangedListener( new ConfigChangedListener() { + @Override public void onConfigChanged(ConfigChangedEvent event) { events[0] = event; }
diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/gitrepo/ManifestParserTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/gitrepo/ManifestParserTest.java index b1138f0..c9673a6 100644 --- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/gitrepo/ManifestParserTest.java +++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/gitrepo/ManifestParserTest.java
@@ -44,12 +44,16 @@ import static java.nio.charset.StandardCharsets.UTF_8; import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; import java.io.ByteArrayInputStream; +import java.io.IOException; +import java.net.URI; import java.util.HashSet; import java.util.Set; import org.junit.Test; +import org.xml.sax.SAXException; public class ManifestParserTest { @@ -57,7 +61,7 @@ public class ManifestParserTest { public void testManifestParser() throws Exception { String baseUrl = "https://git.google.com/"; StringBuilder xmlContent = new StringBuilder(); - Set<String> results = new HashSet<String>(); + Set<String> results = new HashSet<>(); xmlContent.append("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n") .append("<manifest>") .append("<remote name=\"remote1\" fetch=\".\" />") @@ -110,4 +114,49 @@ public void testManifestParser() throws Exception { "Filtered projects shouldn't contain any unexpected results", results.isEmpty()); } + + @Test + public void testManifestParserWithMissingFetchOnRemote() throws Exception { + String baseUrl = "https://git.google.com/"; + StringBuilder xmlContent = new StringBuilder(); + xmlContent.append("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n") + .append("<manifest>") + .append("<remote name=\"remote1\" />") + .append("<default revision=\"master\" remote=\"remote1\" />") + .append("<project path=\"foo\" name=\"").append("foo") + .append("\" groups=\"a,test\" />") + .append("<project path=\"bar\" name=\"").append("bar") + .append("\" groups=\"notdefault\" />") + .append("<project path=\"foo/a\" name=\"").append("a") + .append("\" groups=\"a\" />") + .append("<project path=\"b\" name=\"").append("b") + .append("\" groups=\"b\" />").append("</manifest>"); + + ManifestParser parser = new ManifestParser(null, null, "master", + baseUrl, null, null); + try { + parser.read(new ByteArrayInputStream( + xmlContent.toString().getBytes(UTF_8))); + fail("ManifestParser did not throw exception for missing fetch"); + } catch (IOException e) { + assertTrue(e.getCause() instanceof SAXException); + assertTrue(e.getCause().getMessage() + .contains("is missing fetch attribute")); + } + } + + void testNormalize(String in, String want) { + URI got = ManifestParser.normalizeEmptyPath(URI.create(in)); + if (!got.toString().equals(want)) { + fail(String.format("normalize(%s) = %s want %s", in, got, want)); + } + } + + @Test + public void testNormalizeEmptyPath() { + testNormalize("http://a.b", "http://a.b/"); + testNormalize("http://a.b/", "http://a.b/"); + testNormalize("", ""); + testNormalize("a/b", "a/b"); + } }
diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/gitrepo/RepoCommandTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/gitrepo/RepoCommandTest.java index ccd15d0..9cf4569 100644 --- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/gitrepo/RepoCommandTest.java +++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/gitrepo/RepoCommandTest.java
@@ -48,15 +48,28 @@ import static org.junit.Assert.assertTrue; import java.io.BufferedReader; +import java.io.ByteArrayInputStream; import java.io.File; import java.io.FileReader; +import java.io.IOException; +import java.nio.charset.StandardCharsets; +import java.util.HashMap; +import java.util.Map; import org.eclipse.jgit.api.Git; +import org.eclipse.jgit.api.errors.GitAPIException; +import org.eclipse.jgit.api.errors.InvalidRemoteException; +import org.eclipse.jgit.api.errors.RefNotFoundException; import org.eclipse.jgit.junit.JGitTestUtil; import org.eclipse.jgit.junit.RepositoryTestCase; +import org.eclipse.jgit.lib.BlobBasedConfig; +import org.eclipse.jgit.lib.Config; import org.eclipse.jgit.lib.Constants; import org.eclipse.jgit.lib.ObjectId; +import org.eclipse.jgit.lib.ObjectReader; +import org.eclipse.jgit.lib.Ref; import org.eclipse.jgit.lib.Repository; +import org.eclipse.jgit.revwalk.RevCommit; import org.eclipse.jgit.storage.file.FileBasedConfig; import org.eclipse.jgit.util.FS; import org.junit.Test; @@ -79,6 +92,7 @@ public class RepoCommandTest extends RepositoryTestCase { private ObjectId oldCommitId; + @Override public void setUp() throws Exception { super.setUp(); @@ -123,6 +137,108 @@ public void setUp() throws Exception { resolveRelativeUris(); } + class IndexedRepos implements RepoCommand.RemoteReader { + Map<String, Repository> uriRepoMap; + IndexedRepos() { + uriRepoMap = new HashMap<>(); + } + + void put(String u, Repository r) { + uriRepoMap.put(u, r); + } + + @Override + public ObjectId sha1(String uri, String refname) throws GitAPIException { + if (!uriRepoMap.containsKey(uri)) { + return null; + } + + Repository r = uriRepoMap.get(uri); + try { + Ref ref = r.findRef(refname); + if (ref == null) return null; + + ref = r.peel(ref); + ObjectId id = ref.getObjectId(); + return id; + } catch (IOException e) { + throw new InvalidRemoteException("", e); + } + } + + @Override + public byte[] readFile(String uri, String refName, String path) + throws GitAPIException, IOException { + Repository repo = uriRepoMap.get(uri); + + String idStr = refName + ":" + path; + ObjectId id = repo.resolve(idStr); + if (id == null) { + throw new RefNotFoundException( + String.format("repo %s does not have %s", repo.toString(), idStr)); + } + try (ObjectReader reader = repo.newObjectReader()) { + return reader.open(id).getCachedBytes(Integer.MAX_VALUE); + } + } + } + + @Test + public void absoluteRemoteURL() throws Exception { + Repository child = + Git.cloneRepository().setURI(groupADb.getDirectory().toURI().toString()) + .setDirectory(createUniqueTestGitDir(true)) + .setBare(true).call().getRepository(); + Repository dest = Git.cloneRepository() + .setURI(db.getDirectory().toURI().toString()).setDirectory(createUniqueTestGitDir(true)) + .setBare(true).call().getRepository(); + String abs = "https://chromium.googlesource.com"; + String repoUrl = "https://chromium.googlesource.com/chromium/src"; + boolean fetchSlash = false; + boolean baseSlash = false; + do { + do { + String fetchUrl = fetchSlash ? abs + "/" : abs; + String baseUrl = baseSlash ? abs + "/" : abs; + + StringBuilder xmlContent = new StringBuilder(); + xmlContent.append("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n") + .append("<manifest>") + .append("<remote name=\"origin\" fetch=\"" + fetchUrl + "\" />") + .append("<default revision=\"master\" remote=\"origin\" />") + .append("<project path=\"src\" name=\"chromium/src\" />") + .append("</manifest>"); + RepoCommand cmd = new RepoCommand(dest); + + IndexedRepos repos = new IndexedRepos(); + repos.put(repoUrl, child); + + RevCommit commit = cmd + .setInputStream(new ByteArrayInputStream(xmlContent.toString().getBytes(StandardCharsets.UTF_8))) + .setRemoteReader(repos) + .setURI(baseUrl) + .setRecordRemoteBranch(true) + .setRecordSubmoduleLabels(true) + .call(); + + String idStr = commit.getId().name() + ":" + ".gitmodules"; + ObjectId modId = dest.resolve(idStr); + + try (ObjectReader reader = dest.newObjectReader()) { + byte[] bytes = reader.open(modId).getCachedBytes(Integer.MAX_VALUE); + Config base = new Config(); + BlobBasedConfig cfg = new BlobBasedConfig(base, bytes); + String subUrl = cfg.getString("submodule", "src", "url"); + assertEquals("https://chromium.googlesource.com/chromium/src", subUrl); + } + fetchSlash = !fetchSlash; + } while (fetchSlash); + baseSlash = !baseSlash; + } while (baseSlash); + child.close(); + dest.close(); + } + @Test public void testAddRepoManifest() throws Exception { StringBuilder xmlContent = new StringBuilder(); @@ -248,46 +364,42 @@ public void testRepoManifestCopyFile() throws Exception { @Test public void testBareRepo() throws Exception { - try ( - Repository remoteDb = createBareRepository(); - Repository tempDb = createWorkRepository()) { - StringBuilder xmlContent = new StringBuilder(); - xmlContent - .append("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n") - .append("<manifest>") - .append("<remote name=\"remote1\" fetch=\".\" />") - .append("<default revision=\"master\" remote=\"remote1\" />") - .append("<project path=\"foo\" name=\"").append(defaultUri) - .append("\" />").append("</manifest>"); - JGitTestUtil.writeTrashFile(tempDb, "manifest.xml", - xmlContent.toString()); - RepoCommand command = new RepoCommand(remoteDb); - command.setPath( - tempDb.getWorkTree().getAbsolutePath() + "/manifest.xml") - .setURI(rootUri).call(); - // Clone it - File directory = createTempDirectory("testBareRepo"); - Repository localDb = Git.cloneRepository().setDirectory(directory) - .setURI(remoteDb.getDirectory().toURI().toString()).call() - .getRepository(); - // The .gitmodules file should exist - File gitmodules = new File(localDb.getWorkTree(), ".gitmodules"); - assertTrue("The .gitmodules file should exist", gitmodules.exists()); - // The first line of .gitmodules file should be expected - BufferedReader reader = new BufferedReader(new FileReader( - gitmodules)); - String content = reader.readLine(); - reader.close(); - assertEquals( - "The first line of .gitmodules file should be as expected", - "[submodule \"foo\"]", content); - // The gitlink should be the same as remote head sha1 - String gitlink = localDb.resolve(Constants.HEAD + ":foo").name(); - localDb.close(); - String remote = defaultDb.resolve(Constants.HEAD).name(); - assertEquals("The gitlink should be the same as remote head", - remote, gitlink); - } + Repository remoteDb = createBareRepository(); + Repository tempDb = createWorkRepository(); + + StringBuilder xmlContent = new StringBuilder(); + xmlContent.append("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n") + .append("<manifest>") + .append("<remote name=\"remote1\" fetch=\".\" />") + .append("<default revision=\"master\" remote=\"remote1\" />") + .append("<project path=\"foo\" name=\"").append(defaultUri) + .append("\" />").append("</manifest>"); + JGitTestUtil.writeTrashFile(tempDb, "manifest.xml", + xmlContent.toString()); + RepoCommand command = new RepoCommand(remoteDb); + command.setPath( + tempDb.getWorkTree().getAbsolutePath() + "/manifest.xml") + .setURI(rootUri).call(); + // Clone it + File directory = createTempDirectory("testBareRepo"); + Repository localDb = Git.cloneRepository().setDirectory(directory) + .setURI(remoteDb.getDirectory().toURI().toString()).call() + .getRepository(); + // The .gitmodules file should exist + File gitmodules = new File(localDb.getWorkTree(), ".gitmodules"); + assertTrue("The .gitmodules file should exist", gitmodules.exists()); + // The first line of .gitmodules file should be expected + BufferedReader reader = new BufferedReader(new FileReader(gitmodules)); + String content = reader.readLine(); + reader.close(); + assertEquals("The first line of .gitmodules file should be as expected", + "[submodule \"foo\"]", content); + // The gitlink should be the same as remote head sha1 + String gitlink = localDb.resolve(Constants.HEAD + ":foo").name(); + localDb.close(); + String remote = defaultDb.resolve(Constants.HEAD).name(); + assertEquals("The gitlink should be the same as remote head", remote, + gitlink); } @Test @@ -370,208 +482,192 @@ public void testRevisionTag() throws Exception { @Test public void testRevisionBare() throws Exception { - try ( - Repository remoteDb = createBareRepository(); - Repository tempDb = createWorkRepository()) { - StringBuilder xmlContent = new StringBuilder(); - xmlContent.append("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n") - .append("<manifest>") - .append("<remote name=\"remote1\" fetch=\".\" />") - .append("<default revision=\"").append(BRANCH) - .append("\" remote=\"remote1\" />") - .append("<project path=\"foo\" name=\"").append(defaultUri) - .append("\" />").append("</manifest>"); - JGitTestUtil.writeTrashFile(tempDb, "manifest.xml", - xmlContent.toString()); - RepoCommand command = new RepoCommand(remoteDb); - command.setPath( - tempDb.getWorkTree().getAbsolutePath() + "/manifest.xml") - .setURI(rootUri).call(); - // Clone it - File directory = createTempDirectory("testRevisionBare"); - Repository localDb = Git.cloneRepository().setDirectory(directory) - .setURI(remoteDb.getDirectory().toURI().toString()).call() - .getRepository(); - // The gitlink should be the same as oldCommitId - String gitlink = localDb.resolve(Constants.HEAD + ":foo").name(); - localDb.close(); - assertEquals("The gitlink is same as remote head", - oldCommitId.name(), gitlink); - } + Repository remoteDb = createBareRepository(); + Repository tempDb = createWorkRepository(); + + StringBuilder xmlContent = new StringBuilder(); + xmlContent.append("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n") + .append("<manifest>") + .append("<remote name=\"remote1\" fetch=\".\" />") + .append("<default revision=\"").append(BRANCH) + .append("\" remote=\"remote1\" />") + .append("<project path=\"foo\" name=\"").append(defaultUri) + .append("\" />").append("</manifest>"); + JGitTestUtil.writeTrashFile(tempDb, "manifest.xml", + xmlContent.toString()); + RepoCommand command = new RepoCommand(remoteDb); + command.setPath( + tempDb.getWorkTree().getAbsolutePath() + "/manifest.xml") + .setURI(rootUri).call(); + // Clone it + File directory = createTempDirectory("testRevisionBare"); + Repository localDb = Git.cloneRepository().setDirectory(directory) + .setURI(remoteDb.getDirectory().toURI().toString()).call() + .getRepository(); + // The gitlink should be the same as oldCommitId + String gitlink = localDb.resolve(Constants.HEAD + ":foo").name(); + localDb.close(); + assertEquals("The gitlink is same as remote head", oldCommitId.name(), + gitlink); } @Test public void testCopyFileBare() throws Exception { - try ( - Repository remoteDb = createBareRepository(); - Repository tempDb = createWorkRepository()) { - StringBuilder xmlContent = new StringBuilder(); - xmlContent - .append("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n") - .append("<manifest>") - .append("<remote name=\"remote1\" fetch=\".\" />") - .append("<default revision=\"master\" remote=\"remote1\" />") - .append("<project path=\"foo\" name=\"").append(defaultUri) - .append("\" revision=\"").append(BRANCH).append("\" >") - .append("<copyfile src=\"hello.txt\" dest=\"Hello\" />") - .append("<copyfile src=\"hello.txt\" dest=\"foo/Hello\" />") - .append("</project>").append("</manifest>"); - JGitTestUtil.writeTrashFile(tempDb, "manifest.xml", - xmlContent.toString()); - RepoCommand command = new RepoCommand(remoteDb); - command.setPath( - tempDb.getWorkTree().getAbsolutePath() + "/manifest.xml") - .setURI(rootUri).call(); - // Clone it - File directory = createTempDirectory("testCopyFileBare"); - Repository localDb = Git.cloneRepository().setDirectory(directory) - .setURI(remoteDb.getDirectory().toURI().toString()).call() - .getRepository(); - // The Hello file should exist - File hello = new File(localDb.getWorkTree(), "Hello"); - assertTrue("The Hello file should exist", hello.exists()); - // The foo/Hello file should be skipped. - File foohello = new File(localDb.getWorkTree(), "foo/Hello"); - assertFalse( - "The foo/Hello file should be skipped", foohello.exists()); - localDb.close(); - // The content of Hello file should be expected - BufferedReader reader = new BufferedReader(new FileReader(hello)); - String content = reader.readLine(); - reader.close(); - assertEquals("The Hello file should have expected content", - "branch world", content); - } + Repository remoteDb = createBareRepository(); + Repository tempDb = createWorkRepository(); + + StringBuilder xmlContent = new StringBuilder(); + xmlContent.append("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n") + .append("<manifest>") + .append("<remote name=\"remote1\" fetch=\".\" />") + .append("<default revision=\"master\" remote=\"remote1\" />") + .append("<project path=\"foo\" name=\"").append(defaultUri) + .append("\" revision=\"").append(BRANCH).append("\" >") + .append("<copyfile src=\"hello.txt\" dest=\"Hello\" />") + .append("<copyfile src=\"hello.txt\" dest=\"foo/Hello\" />") + .append("</project>").append("</manifest>"); + JGitTestUtil.writeTrashFile(tempDb, "manifest.xml", + xmlContent.toString()); + RepoCommand command = new RepoCommand(remoteDb); + command.setPath( + tempDb.getWorkTree().getAbsolutePath() + "/manifest.xml") + .setURI(rootUri).call(); + // Clone it + File directory = createTempDirectory("testCopyFileBare"); + Repository localDb = Git.cloneRepository().setDirectory(directory) + .setURI(remoteDb.getDirectory().toURI().toString()).call() + .getRepository(); + // The Hello file should exist + File hello = new File(localDb.getWorkTree(), "Hello"); + assertTrue("The Hello file should exist", hello.exists()); + // The foo/Hello file should be skipped. + File foohello = new File(localDb.getWorkTree(), "foo/Hello"); + assertFalse("The foo/Hello file should be skipped", foohello.exists()); + localDb.close(); + // The content of Hello file should be expected + BufferedReader reader = new BufferedReader(new FileReader(hello)); + String content = reader.readLine(); + reader.close(); + assertEquals("The Hello file should have expected content", + "branch world", content); } @Test public void testReplaceManifestBare() throws Exception { - try ( - Repository remoteDb = createBareRepository(); - Repository tempDb = createWorkRepository()) { - StringBuilder xmlContent = new StringBuilder(); - xmlContent - .append("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n") - .append("<manifest>") - .append("<remote name=\"remote1\" fetch=\".\" />") - .append("<default revision=\"master\" remote=\"remote1\" />") - .append("<project path=\"foo\" name=\"").append(defaultUri) - .append("\" revision=\"").append(BRANCH).append("\" >") - .append("<copyfile src=\"hello.txt\" dest=\"Hello\" />") - .append("</project>").append("</manifest>"); - JGitTestUtil.writeTrashFile(tempDb, "old.xml", - xmlContent.toString()); - RepoCommand command = new RepoCommand(remoteDb); - command.setPath(tempDb.getWorkTree().getAbsolutePath() + "/old.xml") - .setURI(rootUri).call(); - xmlContent = new StringBuilder(); - xmlContent - .append("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n") - .append("<manifest>") - .append("<remote name=\"remote1\" fetch=\".\" />") - .append("<default revision=\"master\" remote=\"remote1\" />") - .append("<project path=\"bar\" name=\"") - .append(defaultUri) - .append("\" revision=\"") - .append(BRANCH) - .append("\" >") - .append("<copyfile src=\"hello.txt\" dest=\"Hello.txt\" />") - .append("</project>").append("</manifest>"); - JGitTestUtil.writeTrashFile(tempDb, "new.xml", - xmlContent.toString()); - command = new RepoCommand(remoteDb); - command.setPath(tempDb.getWorkTree().getAbsolutePath() + "/new.xml") - .setURI(rootUri).call(); - // Clone it - File directory = createTempDirectory("testReplaceManifestBare"); - Repository localDb = Git.cloneRepository().setDirectory(directory) - .setURI(remoteDb.getDirectory().toURI().toString()).call() - .getRepository(); - // The Hello file should not exist - File hello = new File(localDb.getWorkTree(), "Hello"); - assertFalse("The Hello file shouldn't exist", hello.exists()); - // The Hello.txt file should exist - File hellotxt = new File(localDb.getWorkTree(), "Hello.txt"); - assertTrue("The Hello.txt file should exist", hellotxt.exists()); - // The .gitmodules file should have 'submodule "bar"' and shouldn't - // have - // 'submodule "foo"' lines. - File dotmodules = new File(localDb.getWorkTree(), - Constants.DOT_GIT_MODULES); - localDb.close(); - BufferedReader reader = new BufferedReader(new FileReader( - dotmodules)); - boolean foo = false; - boolean bar = false; - while (true) { - String line = reader.readLine(); - if (line == null) - break; - if (line.contains("submodule \"foo\"")) - foo = true; - if (line.contains("submodule \"bar\"")) - bar = true; - } - reader.close(); - assertTrue("The bar submodule should exist", bar); - assertFalse("The foo submodule shouldn't exist", foo); + Repository remoteDb = createBareRepository(); + Repository tempDb = createWorkRepository(); + + StringBuilder xmlContent = new StringBuilder(); + xmlContent.append("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n") + .append("<manifest>") + .append("<remote name=\"remote1\" fetch=\".\" />") + .append("<default revision=\"master\" remote=\"remote1\" />") + .append("<project path=\"foo\" name=\"").append(defaultUri) + .append("\" revision=\"").append(BRANCH).append("\" >") + .append("<copyfile src=\"hello.txt\" dest=\"Hello\" />") + .append("</project>").append("</manifest>"); + JGitTestUtil.writeTrashFile(tempDb, "old.xml", xmlContent.toString()); + RepoCommand command = new RepoCommand(remoteDb); + command.setPath(tempDb.getWorkTree().getAbsolutePath() + "/old.xml") + .setURI(rootUri).call(); + xmlContent = new StringBuilder(); + xmlContent.append("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n") + .append("<manifest>") + .append("<remote name=\"remote1\" fetch=\".\" />") + .append("<default revision=\"master\" remote=\"remote1\" />") + .append("<project path=\"bar\" name=\"").append(defaultUri) + .append("\" revision=\"").append(BRANCH).append("\" >") + .append("<copyfile src=\"hello.txt\" dest=\"Hello.txt\" />") + .append("</project>").append("</manifest>"); + JGitTestUtil.writeTrashFile(tempDb, "new.xml", xmlContent.toString()); + command = new RepoCommand(remoteDb); + command.setPath(tempDb.getWorkTree().getAbsolutePath() + "/new.xml") + .setURI(rootUri).call(); + // Clone it + File directory = createTempDirectory("testReplaceManifestBare"); + Repository localDb = Git.cloneRepository().setDirectory(directory) + .setURI(remoteDb.getDirectory().toURI().toString()).call() + .getRepository(); + // The Hello file should not exist + File hello = new File(localDb.getWorkTree(), "Hello"); + assertFalse("The Hello file shouldn't exist", hello.exists()); + // The Hello.txt file should exist + File hellotxt = new File(localDb.getWorkTree(), "Hello.txt"); + assertTrue("The Hello.txt file should exist", hellotxt.exists()); + // The .gitmodules file should have 'submodule "bar"' and shouldn't + // have + // 'submodule "foo"' lines. + File dotmodules = new File(localDb.getWorkTree(), + Constants.DOT_GIT_MODULES); + localDb.close(); + BufferedReader reader = new BufferedReader(new FileReader(dotmodules)); + boolean foo = false; + boolean bar = false; + while (true) { + String line = reader.readLine(); + if (line == null) + break; + if (line.contains("submodule \"foo\"")) + foo = true; + if (line.contains("submodule \"bar\"")) + bar = true; } + reader.close(); + assertTrue("The bar submodule should exist", bar); + assertFalse("The foo submodule shouldn't exist", foo); } @Test public void testRemoveOverlappingBare() throws Exception { - try ( - Repository remoteDb = createBareRepository(); - Repository tempDb = createWorkRepository()) { - StringBuilder xmlContent = new StringBuilder(); - xmlContent - .append("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n") - .append("<manifest>") - .append("<remote name=\"remote1\" fetch=\".\" />") - .append("<default revision=\"master\" remote=\"remote1\" />") - .append("<project path=\"foo/bar\" name=\"") - .append(groupBUri).append("\" />") - .append("<project path=\"a\" name=\"").append(groupAUri) - .append("\" />").append("<project path=\"foo\" name=\"") - .append(defaultUri).append("\" />").append("</manifest>"); - JGitTestUtil.writeTrashFile(tempDb, "manifest.xml", - xmlContent.toString()); - RepoCommand command = new RepoCommand(remoteDb); - command.setPath( - tempDb.getWorkTree().getAbsolutePath() + "/manifest.xml") - .setURI(rootUri).call(); - // Clone it - File directory = createTempDirectory("testRemoveOverlappingBare"); - Repository localDb = Git.cloneRepository().setDirectory(directory) - .setURI(remoteDb.getDirectory().toURI().toString()).call() - .getRepository(); - // The .gitmodules file should have 'submodule "foo"' and shouldn't - // have - // 'submodule "foo/bar"' lines. - File dotmodules = new File(localDb.getWorkTree(), - Constants.DOT_GIT_MODULES); - localDb.close(); - BufferedReader reader = new BufferedReader(new FileReader( - dotmodules)); - boolean foo = false; - boolean foobar = false; - boolean a = false; - while (true) { - String line = reader.readLine(); - if (line == null) - break; - if (line.contains("submodule \"foo\"")) - foo = true; - if (line.contains("submodule \"foo/bar\"")) - foobar = true; - if (line.contains("submodule \"a\"")) - a = true; - } - reader.close(); - assertTrue("The foo submodule should exist", foo); - assertFalse("The foo/bar submodule shouldn't exist", foobar); - assertTrue("The a submodule should exist", a); + Repository remoteDb = createBareRepository(); + Repository tempDb = createWorkRepository(); + + StringBuilder xmlContent = new StringBuilder(); + xmlContent.append("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n") + .append("<manifest>") + .append("<remote name=\"remote1\" fetch=\".\" />") + .append("<default revision=\"master\" remote=\"remote1\" />") + .append("<project path=\"foo/bar\" name=\"").append(groupBUri) + .append("\" />").append("<project path=\"a\" name=\"") + .append(groupAUri).append("\" />") + .append("<project path=\"foo\" name=\"").append(defaultUri) + .append("\" />").append("</manifest>"); + JGitTestUtil.writeTrashFile(tempDb, "manifest.xml", + xmlContent.toString()); + RepoCommand command = new RepoCommand(remoteDb); + command.setPath( + tempDb.getWorkTree().getAbsolutePath() + "/manifest.xml") + .setURI(rootUri).call(); + // Clone it + File directory = createTempDirectory("testRemoveOverlappingBare"); + Repository localDb = Git.cloneRepository().setDirectory(directory) + .setURI(remoteDb.getDirectory().toURI().toString()).call() + .getRepository(); + // The .gitmodules file should have 'submodule "foo"' and shouldn't + // have + // 'submodule "foo/bar"' lines. + File dotmodules = new File(localDb.getWorkTree(), + Constants.DOT_GIT_MODULES); + localDb.close(); + BufferedReader reader = new BufferedReader(new FileReader(dotmodules)); + boolean foo = false; + boolean foobar = false; + boolean a = false; + while (true) { + String line = reader.readLine(); + if (line == null) + break; + if (line.contains("submodule \"foo\"")) + foo = true; + if (line.contains("submodule \"foo/bar\"")) + foobar = true; + if (line.contains("submodule \"a\"")) + a = true; } + reader.close(); + assertTrue("The foo submodule should exist", foo); + assertFalse("The foo/bar submodule shouldn't exist", foobar); + assertTrue("The a submodule should exist", a); } @Test @@ -670,178 +766,157 @@ public void testRemoteAlias() throws Exception { @Test public void testTargetBranch() throws Exception { - try ( - Repository remoteDb1 = createBareRepository(); - Repository remoteDb2 = createBareRepository(); - Repository tempDb = createWorkRepository()) { - StringBuilder xmlContent = new StringBuilder(); - xmlContent - .append("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n") - .append("<manifest>") - .append("<remote name=\"remote1\" fetch=\".\" />") - .append("<default revision=\"master\" remote=\"remote1\" />") - .append("<project path=\"foo\" name=\"").append(defaultUri) - .append("\" />").append("</manifest>"); - JGitTestUtil.writeTrashFile(tempDb, "manifest.xml", - xmlContent.toString()); - RepoCommand command = new RepoCommand(remoteDb1); - command - .setPath(tempDb.getWorkTree().getAbsolutePath() + "/manifest.xml") - .setURI(rootUri) - .setTargetBranch("test") - .call(); - ObjectId branchId = remoteDb1.resolve( - Constants.R_HEADS + "test^{tree}"); - command = new RepoCommand(remoteDb2); - command - .setPath(tempDb.getWorkTree().getAbsolutePath() + "/manifest.xml") - .setURI(rootUri) - .call(); - ObjectId defaultId = remoteDb2.resolve(Constants.HEAD + "^{tree}"); - assertEquals( + Repository remoteDb1 = createBareRepository(); + Repository remoteDb2 = createBareRepository(); + Repository tempDb = createWorkRepository(); + + StringBuilder xmlContent = new StringBuilder(); + xmlContent.append("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n") + .append("<manifest>") + .append("<remote name=\"remote1\" fetch=\".\" />") + .append("<default revision=\"master\" remote=\"remote1\" />") + .append("<project path=\"foo\" name=\"").append(defaultUri) + .append("\" />").append("</manifest>"); + JGitTestUtil.writeTrashFile(tempDb, "manifest.xml", + xmlContent.toString()); + RepoCommand command = new RepoCommand(remoteDb1); + command.setPath( + tempDb.getWorkTree().getAbsolutePath() + "/manifest.xml") + .setURI(rootUri).setTargetBranch("test").call(); + ObjectId branchId = remoteDb1 + .resolve(Constants.R_HEADS + "test^{tree}"); + command = new RepoCommand(remoteDb2); + command.setPath( + tempDb.getWorkTree().getAbsolutePath() + "/manifest.xml") + .setURI(rootUri).call(); + ObjectId defaultId = remoteDb2.resolve(Constants.HEAD + "^{tree}"); + assertEquals( "The tree id of branch db and default db should be the same", branchId, defaultId); - } } @Test public void testRecordRemoteBranch() throws Exception { - try ( - Repository remoteDb = createBareRepository(); - Repository tempDb = createWorkRepository()) { - StringBuilder xmlContent = new StringBuilder(); - xmlContent - .append("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n") + Repository remoteDb = createBareRepository(); + Repository tempDb = createWorkRepository(); + + StringBuilder xmlContent = new StringBuilder(); + xmlContent.append("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n") .append("<manifest>") .append("<remote name=\"remote1\" fetch=\".\" />") .append("<default revision=\"master\" remote=\"remote1\" />") .append("<project path=\"with-branch\" ") - .append("revision=\"master\" ") - .append("name=\"").append(notDefaultUri).append("\" />") + .append("revision=\"master\" ").append("name=\"") + .append(notDefaultUri).append("\" />") .append("<project path=\"with-long-branch\" ") - .append("revision=\"refs/heads/master\" ") - .append("name=\"").append(defaultUri).append("\" />") - .append("</manifest>"); - JGitTestUtil.writeTrashFile(tempDb, "manifest.xml", + .append("revision=\"refs/heads/master\" ").append("name=\"") + .append(defaultUri).append("\" />").append("</manifest>"); + JGitTestUtil.writeTrashFile(tempDb, "manifest.xml", xmlContent.toString()); - RepoCommand command = new RepoCommand(remoteDb); - command.setPath(tempDb.getWorkTree().getAbsolutePath() + "/manifest.xml") - .setURI(rootUri) - .setRecordRemoteBranch(true) - .call(); - // Clone it - File directory = createTempDirectory("testBareRepo"); - try (Repository localDb = Git.cloneRepository() - .setDirectory(directory) - .setURI(remoteDb.getDirectory().toURI().toString()).call() - .getRepository();) { - // The .gitmodules file should exist - File gitmodules = new File(localDb.getWorkTree(), - ".gitmodules"); - assertTrue("The .gitmodules file should exist", - gitmodules.exists()); - FileBasedConfig c = new FileBasedConfig(gitmodules, - FS.DETECTED); - c.load(); - assertEquals("Recording remote branches should work for short branch descriptions", "master", - c.getString("submodule", "with-branch", "branch")); - assertEquals("Recording remote branches should work for full ref specs", "refs/heads/master", - c.getString("submodule", "with-long-branch", "branch")); - } + RepoCommand command = new RepoCommand(remoteDb); + command.setPath( + tempDb.getWorkTree().getAbsolutePath() + "/manifest.xml") + .setURI(rootUri).setRecordRemoteBranch(true).call(); + // Clone it + File directory = createTempDirectory("testBareRepo"); + try (Repository localDb = Git.cloneRepository().setDirectory(directory) + .setURI(remoteDb.getDirectory().toURI().toString()).call() + .getRepository();) { + // The .gitmodules file should exist + File gitmodules = new File(localDb.getWorkTree(), ".gitmodules"); + assertTrue("The .gitmodules file should exist", + gitmodules.exists()); + FileBasedConfig c = new FileBasedConfig(gitmodules, FS.DETECTED); + c.load(); + assertEquals( + "Recording remote branches should work for short branch descriptions", + "master", + c.getString("submodule", "with-branch", "branch")); + assertEquals( + "Recording remote branches should work for full ref specs", + "refs/heads/master", + c.getString("submodule", "with-long-branch", "branch")); } } @Test public void testRecordSubmoduleLabels() throws Exception { - try ( - Repository remoteDb = createBareRepository(); - Repository tempDb = createWorkRepository()) { - StringBuilder xmlContent = new StringBuilder(); - xmlContent - .append("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n") + Repository remoteDb = createBareRepository(); + Repository tempDb = createWorkRepository(); + + StringBuilder xmlContent = new StringBuilder(); + xmlContent.append("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n") .append("<manifest>") .append("<remote name=\"remote1\" fetch=\".\" />") .append("<default revision=\"master\" remote=\"remote1\" />") .append("<project path=\"test\" ") - .append("revision=\"master\" ") - .append("name=\"").append(notDefaultUri).append("\" ") - .append("groups=\"a1,a2\" />") - .append("</manifest>"); - JGitTestUtil.writeTrashFile(tempDb, "manifest.xml", + .append("revision=\"master\" ").append("name=\"") + .append(notDefaultUri).append("\" ") + .append("groups=\"a1,a2\" />").append("</manifest>"); + JGitTestUtil.writeTrashFile(tempDb, "manifest.xml", xmlContent.toString()); - RepoCommand command = new RepoCommand(remoteDb); - command.setPath(tempDb.getWorkTree().getAbsolutePath() + "/manifest.xml") - .setURI(rootUri) - .setRecordSubmoduleLabels(true) - .call(); - // Clone it - File directory = createTempDirectory("testBareRepo"); - try (Repository localDb = Git.cloneRepository() - .setDirectory(directory) - .setURI(remoteDb.getDirectory().toURI().toString()).call() - .getRepository();) { - // The .gitattributes file should exist - File gitattributes = new File(localDb.getWorkTree(), + RepoCommand command = new RepoCommand(remoteDb); + command.setPath( + tempDb.getWorkTree().getAbsolutePath() + "/manifest.xml") + .setURI(rootUri).setRecordSubmoduleLabels(true).call(); + // Clone it + File directory = createTempDirectory("testBareRepo"); + try (Repository localDb = Git.cloneRepository().setDirectory(directory) + .setURI(remoteDb.getDirectory().toURI().toString()).call() + .getRepository();) { + // The .gitattributes file should exist + File gitattributes = new File(localDb.getWorkTree(), ".gitattributes"); - assertTrue("The .gitattributes file should exist", - gitattributes.exists()); - try (BufferedReader reader = new BufferedReader( - new FileReader(gitattributes));) { - String content = reader.readLine(); - assertEquals(".gitattributes content should be as expected", + assertTrue("The .gitattributes file should exist", + gitattributes.exists()); + try (BufferedReader reader = new BufferedReader( + new FileReader(gitattributes));) { + String content = reader.readLine(); + assertEquals(".gitattributes content should be as expected", "/test a1 a2", content); - } } } } @Test public void testRecordShallowRecommendation() throws Exception { - try ( - Repository remoteDb = createBareRepository(); - Repository tempDb = createWorkRepository()) { - StringBuilder xmlContent = new StringBuilder(); - xmlContent - .append("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n") + Repository remoteDb = createBareRepository(); + Repository tempDb = createWorkRepository(); + + StringBuilder xmlContent = new StringBuilder(); + xmlContent.append("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n") .append("<manifest>") .append("<remote name=\"remote1\" fetch=\".\" />") .append("<default revision=\"master\" remote=\"remote1\" />") - .append("<project path=\"shallow-please\" ") - .append("name=\"").append(defaultUri).append("\" ") - .append("clone-depth=\"1\" />") - .append("<project path=\"non-shallow\" ") - .append("name=\"").append(defaultUri).append("\" />") - .append("</manifest>"); - JGitTestUtil.writeTrashFile(tempDb, "manifest.xml", + .append("<project path=\"shallow-please\" ").append("name=\"") + .append(defaultUri).append("\" ").append("clone-depth=\"1\" />") + .append("<project path=\"non-shallow\" ").append("name=\"") + .append(defaultUri).append("\" />").append("</manifest>"); + JGitTestUtil.writeTrashFile(tempDb, "manifest.xml", xmlContent.toString()); - RepoCommand command = new RepoCommand(remoteDb); - command.setPath(tempDb.getWorkTree().getAbsolutePath() + "/manifest.xml") - .setURI(rootUri) - .setRecommendShallow(true) - .call(); - // Clone it - File directory = createTempDirectory("testBareRepo"); - try (Repository localDb = Git.cloneRepository() - .setDirectory(directory) - .setURI(remoteDb.getDirectory().toURI().toString()).call() - .getRepository();) { - // The .gitmodules file should exist - File gitmodules = new File(localDb.getWorkTree(), - ".gitmodules"); - assertTrue("The .gitmodules file should exist", - gitmodules.exists()); - FileBasedConfig c = new FileBasedConfig(gitmodules, - FS.DETECTED); - c.load(); - assertEquals("Recording shallow configuration should work", "true", - c.getString("submodule", "shallow-please", "shallow")); - assertNull("Recording non shallow configuration should work", - c.getString("submodule", "non-shallow", "shallow")); - } + RepoCommand command = new RepoCommand(remoteDb); + command.setPath( + tempDb.getWorkTree().getAbsolutePath() + "/manifest.xml") + .setURI(rootUri).setRecommendShallow(true).call(); + // Clone it + File directory = createTempDirectory("testBareRepo"); + try (Repository localDb = Git.cloneRepository().setDirectory(directory) + .setURI(remoteDb.getDirectory().toURI().toString()).call() + .getRepository();) { + // The .gitmodules file should exist + File gitmodules = new File(localDb.getWorkTree(), ".gitmodules"); + assertTrue("The .gitmodules file should exist", + gitmodules.exists()); + FileBasedConfig c = new FileBasedConfig(gitmodules, FS.DETECTED); + c.load(); + assertEquals("Recording shallow configuration should work", "true", + c.getString("submodule", "shallow-please", "shallow")); + assertNull("Recording non shallow configuration should work", + c.getString("submodule", "non-shallow", "shallow")); } }
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 c7125bb..c70b6f2 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
@@ -1,25 +1,34 @@ package org.eclipse.jgit.internal.storage.dfs; import static org.eclipse.jgit.internal.storage.dfs.DfsObjDatabase.PackSource.GC; +import static org.eclipse.jgit.internal.storage.dfs.DfsObjDatabase.PackSource.GC_REST; import static org.eclipse.jgit.internal.storage.dfs.DfsObjDatabase.PackSource.INSERT; import static org.eclipse.jgit.internal.storage.dfs.DfsObjDatabase.PackSource.UNREACHABLE_GARBAGE; +import static org.eclipse.jgit.internal.storage.pack.PackExt.PACK; 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.assertSame; import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; import java.io.IOException; +import java.util.Collections; import java.util.concurrent.TimeUnit; import org.eclipse.jgit.internal.storage.dfs.DfsObjDatabase.PackSource; +import org.eclipse.jgit.junit.MockSystemReader; import org.eclipse.jgit.junit.TestRepository; import org.eclipse.jgit.lib.AnyObjectId; 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.revwalk.RevWalk; +import org.eclipse.jgit.storage.pack.PackConfig; +import org.eclipse.jgit.util.SystemReader; +import org.junit.After; import org.junit.Before; import org.junit.Test; @@ -27,6 +36,7 @@ public class DfsGarbageCollectorTest { private TestRepository<InMemoryRepository> git; private InMemoryRepository repo; private DfsObjDatabase odb; + private MockSystemReader mockSystemReader; @Before public void setUp() throws IOException { @@ -34,6 +44,13 @@ public void setUp() throws IOException { git = new TestRepository<>(new InMemoryRepository(desc)); repo = git.getRepository(); odb = repo.getObjectDatabase(); + mockSystemReader = new MockSystemReader(); + SystemReader.setInstance(mockSystemReader); + } + + @After + public void tearDown() { + SystemReader.setInstance(null); } @Test @@ -62,6 +79,70 @@ public void testCollectionWithNoGarbage() throws Exception { } @Test + public void testRacyNoReusePrefersSmaller() throws Exception { + StringBuilder msg = new StringBuilder(); + for (int i = 0; i < 100; i++) { + msg.append(i).append(": i am a teapot\n"); + } + RevBlob a = git.blob(msg.toString()); + RevCommit c0 = git.commit() + .add("tea", a) + .message("0") + .create(); + + msg.append("short and stout\n"); + RevBlob b = git.blob(msg.toString()); + RevCommit c1 = git.commit().parent(c0).tick(1) + .add("tea", b) + .message("1") + .create(); + git.update("master", c1); + + PackConfig cfg = new PackConfig(); + cfg.setReuseObjects(false); + cfg.setReuseDeltas(false); + cfg.setDeltaCompress(false); + cfg.setThreads(1); + DfsGarbageCollector gc = new DfsGarbageCollector(repo); + gc.setGarbageTtl(0, TimeUnit.MILLISECONDS); // disable TTL + gc.setPackConfig(cfg); + run(gc); + + assertEquals(1, odb.getPacks().length); + DfsPackDescription large = odb.getPacks()[0].getPackDescription(); + assertSame(PackSource.GC, large.getPackSource()); + + cfg.setDeltaCompress(true); + gc = new DfsGarbageCollector(repo); + gc.setGarbageTtl(0, TimeUnit.MILLISECONDS); // disable TTL + gc.setPackConfig(cfg); + run(gc); + + assertEquals(1, odb.getPacks().length); + DfsPackDescription small = odb.getPacks()[0].getPackDescription(); + assertSame(PackSource.GC, small.getPackSource()); + assertTrue( + "delta compression pack is smaller", + small.getFileSize(PACK) < large.getFileSize(PACK)); + assertTrue( + "large pack is older", + large.getLastModified() < small.getLastModified()); + + // Forcefully reinsert the older larger GC pack. + odb.commitPack(Collections.singleton(large), null); + odb.clearCache(); + assertEquals(2, odb.getPacks().length); + + gc = new DfsGarbageCollector(repo); + gc.setGarbageTtl(0, TimeUnit.MILLISECONDS); // disable TTL + run(gc); + + assertEquals(1, odb.getPacks().length); + DfsPackDescription rebuilt = odb.getPacks()[0].getPackDescription(); + assertEquals(small.getFileSize(PACK), rebuilt.getFileSize(PACK)); + } + + @Test public void testCollectionWithGarbage() throws Exception { RevCommit commit0 = commit().message("0").create(); RevCommit commit1 = commit().message("1").parent(commit0).create(); @@ -169,6 +250,297 @@ public void testCollectionWithGarbageNoCoalescence() throws Exception { } } + @Test + public void testCollectionWithGarbageCoalescenceWithShortTtl() + throws Exception { + RevCommit commit0 = commit().message("0").create(); + RevCommit commit1 = commit().message("1").parent(commit0).create(); + git.update("master", commit0); + + // Create commits at 1 minute intervals with 1 hour ttl. + for (int i = 0; i < 100; i++) { + mockSystemReader.tick(60); + commit1 = commit().message("g" + i).parent(commit1).create(); + + DfsGarbageCollector gc = new DfsGarbageCollector(repo); + gc.setGarbageTtl(1, TimeUnit.HOURS); + run(gc); + + // Make sure we don't have more than 4 UNREACHABLE_GARBAGE packs + // because all the packs that are created in a 20 minutes interval + // should be coalesced and the packs older than 60 minutes should be + // removed due to ttl. + int count = countPacks(UNREACHABLE_GARBAGE); + assertTrue("Garbage pack count should not exceed 4, but found " + + count, count <= 4); + } + } + + @Test + public void testCollectionWithGarbageCoalescenceWithLongTtl() + throws Exception { + RevCommit commit0 = commit().message("0").create(); + RevCommit commit1 = commit().message("1").parent(commit0).create(); + git.update("master", commit0); + + // Create commits at 1 hour intervals with 2 days ttl. + for (int i = 0; i < 100; i++) { + mockSystemReader.tick(3600); + commit1 = commit().message("g" + i).parent(commit1).create(); + + DfsGarbageCollector gc = new DfsGarbageCollector(repo); + gc.setGarbageTtl(2, TimeUnit.DAYS); + run(gc); + + // Make sure we don't have more than 3 UNREACHABLE_GARBAGE packs + // because all the packs that are created in a single day should + // be coalesced and the packs older than 2 days should be + // removed due to ttl. + int count = countPacks(UNREACHABLE_GARBAGE); + assertTrue("Garbage pack count should not exceed 3, but found " + + count, count <= 3); + } + } + + @Test + public void testEstimateGcPackSizeInNewRepo() throws Exception { + RevCommit commit0 = commit().message("0").create(); + RevCommit commit1 = commit().message("1").parent(commit0).create(); + git.update("master", commit1); + + // Packs start out as INSERT. + long inputPacksSize = 32; + assertEquals(2, odb.getPacks().length); + for (DfsPackFile pack : odb.getPacks()) { + assertEquals(INSERT, pack.getPackDescription().getPackSource()); + inputPacksSize += pack.getPackDescription().getFileSize(PACK) - 32; + } + + gcNoTtl(); + + // INSERT packs are combined into a single GC pack. + assertEquals(1, odb.getPacks().length); + DfsPackFile pack = odb.getPacks()[0]; + assertEquals(GC, pack.getPackDescription().getPackSource()); + assertEquals(inputPacksSize, + pack.getPackDescription().getEstimatedPackSize()); + } + + @Test + public void testEstimateGcPackSizeWithAnExistingGcPack() throws Exception { + RevCommit commit0 = commit().message("0").create(); + RevCommit commit1 = commit().message("1").parent(commit0).create(); + git.update("master", commit1); + + gcNoTtl(); + + RevCommit commit2 = commit().message("2").parent(commit1).create(); + git.update("master", commit2); + + // There will be one INSERT pack and one GC pack. + assertEquals(2, odb.getPacks().length); + boolean gcPackFound = false; + boolean insertPackFound = false; + long inputPacksSize = 32; + for (DfsPackFile pack : odb.getPacks()) { + DfsPackDescription d = pack.getPackDescription(); + if (d.getPackSource() == GC) { + gcPackFound = true; + } else if (d.getPackSource() == INSERT) { + insertPackFound = true; + } else { + fail("unexpected " + d.getPackSource()); + } + inputPacksSize += d.getFileSize(PACK) - 32; + } + assertTrue(gcPackFound); + assertTrue(insertPackFound); + + gcNoTtl(); + + // INSERT pack is combined into the GC pack. + DfsPackFile pack = odb.getPacks()[0]; + assertEquals(GC, pack.getPackDescription().getPackSource()); + assertEquals(inputPacksSize, + pack.getPackDescription().getEstimatedPackSize()); + } + + @Test + public void testEstimateGcRestPackSizeInNewRepo() throws Exception { + RevCommit commit0 = commit().message("0").create(); + RevCommit commit1 = commit().message("1").parent(commit0).create(); + git.update("refs/notes/note1", commit1); + + // Packs start out as INSERT. + long inputPacksSize = 32; + assertEquals(2, odb.getPacks().length); + for (DfsPackFile pack : odb.getPacks()) { + assertEquals(INSERT, pack.getPackDescription().getPackSource()); + inputPacksSize += pack.getPackDescription().getFileSize(PACK) - 32; + } + + gcNoTtl(); + + // INSERT packs are combined into a single GC_REST pack. + assertEquals(1, odb.getPacks().length); + DfsPackFile pack = odb.getPacks()[0]; + assertEquals(GC_REST, pack.getPackDescription().getPackSource()); + assertEquals(inputPacksSize, + pack.getPackDescription().getEstimatedPackSize()); + } + + @Test + public void testEstimateGcRestPackSizeWithAnExistingGcPack() + throws Exception { + RevCommit commit0 = commit().message("0").create(); + RevCommit commit1 = commit().message("1").parent(commit0).create(); + git.update("refs/notes/note1", commit1); + + gcNoTtl(); + + RevCommit commit2 = commit().message("2").parent(commit1).create(); + git.update("refs/notes/note2", commit2); + + // There will be one INSERT pack and one GC_REST pack. + assertEquals(2, odb.getPacks().length); + boolean gcRestPackFound = false; + boolean insertPackFound = false; + long inputPacksSize = 32; + for (DfsPackFile pack : odb.getPacks()) { + DfsPackDescription d = pack.getPackDescription(); + if (d.getPackSource() == GC_REST) { + gcRestPackFound = true; + } else if (d.getPackSource() == INSERT) { + insertPackFound = true; + } else { + fail("unexpected " + d.getPackSource()); + } + inputPacksSize += d.getFileSize(PACK) - 32; + } + assertTrue(gcRestPackFound); + assertTrue(insertPackFound); + + gcNoTtl(); + + // INSERT pack is combined into the GC_REST pack. + DfsPackFile pack = odb.getPacks()[0]; + assertEquals(GC_REST, pack.getPackDescription().getPackSource()); + assertEquals(inputPacksSize, + pack.getPackDescription().getEstimatedPackSize()); + } + + @Test + public void testEstimateGcPackSizesWithGcAndGcRestPacks() throws Exception { + RevCommit commit0 = commit().message("0").create(); + git.update("head", commit0); + RevCommit commit1 = commit().message("1").parent(commit0).create(); + git.update("refs/notes/note1", commit1); + + gcNoTtl(); + + RevCommit commit2 = commit().message("2").parent(commit1).create(); + git.update("refs/notes/note2", commit2); + + // There will be one INSERT, one GC and one GC_REST packs. + assertEquals(3, odb.getPacks().length); + boolean gcPackFound = false; + boolean gcRestPackFound = false; + boolean insertPackFound = false; + long gcPackSize = 0; + long gcRestPackSize = 0; + long insertPackSize = 0; + for (DfsPackFile pack : odb.getPacks()) { + DfsPackDescription d = pack.getPackDescription(); + if (d.getPackSource() == GC) { + gcPackFound = true; + gcPackSize = d.getFileSize(PACK); + } else if (d.getPackSource() == GC_REST) { + gcRestPackFound = true; + gcRestPackSize = d.getFileSize(PACK); + } else if (d.getPackSource() == INSERT) { + insertPackFound = true; + insertPackSize = d.getFileSize(PACK); + } else { + fail("unexpected " + d.getPackSource()); + } + } + assertTrue(gcPackFound); + assertTrue(gcRestPackFound); + assertTrue(insertPackFound); + + gcNoTtl(); + + // In this test INSERT pack would be combined into the GC_REST pack. + // But, as there is no good heuristic to know whether the new packs will + // be combined into a GC pack or GC_REST packs, the new pick size is + // considered while estimating both the GC and GC_REST packs. + assertEquals(2, odb.getPacks().length); + gcPackFound = false; + gcRestPackFound = false; + for (DfsPackFile pack : odb.getPacks()) { + DfsPackDescription d = pack.getPackDescription(); + if (d.getPackSource() == GC) { + gcPackFound = true; + assertEquals(gcPackSize + insertPackSize - 32, + pack.getPackDescription().getEstimatedPackSize()); + } else if (d.getPackSource() == GC_REST) { + gcRestPackFound = true; + assertEquals(gcRestPackSize + insertPackSize - 32, + pack.getPackDescription().getEstimatedPackSize()); + } else { + fail("unexpected " + d.getPackSource()); + } + } + assertTrue(gcPackFound); + assertTrue(gcRestPackFound); + } + + @Test + public void testEstimateUnreachableGarbagePackSize() throws Exception { + RevCommit commit0 = commit().message("0").create(); + RevCommit commit1 = commit().message("1").parent(commit0).create(); + git.update("master", commit0); + + assertTrue("commit0 reachable", isReachable(repo, commit0)); + assertFalse("commit1 garbage", isReachable(repo, commit1)); + + // Packs start out as INSERT. + long packSize0 = 0; + long packSize1 = 0; + assertEquals(2, odb.getPacks().length); + for (DfsPackFile pack : odb.getPacks()) { + DfsPackDescription d = pack.getPackDescription(); + assertEquals(INSERT, d.getPackSource()); + if (isObjectInPack(commit0, pack)) { + packSize0 = d.getFileSize(PACK); + } else if (isObjectInPack(commit1, pack)) { + packSize1 = d.getFileSize(PACK); + } else { + fail("expected object not found in the pack"); + } + } + + gcNoTtl(); + + assertEquals(2, odb.getPacks().length); + for (DfsPackFile pack : odb.getPacks()) { + DfsPackDescription d = pack.getPackDescription(); + if (d.getPackSource() == GC) { + // Even though just commit0 will end up in GC pack, because + // there is no good way to know that up front, both the pack + // sizes are considered while computing the estimated size of GC + // pack. + assertEquals(packSize0 + packSize1 - 32, + d.getEstimatedPackSize()); + } else if (d.getPackSource() == UNREACHABLE_GARBAGE) { + // commit1 is moved to UNREACHABLE_GARBAGE pack. + assertEquals(packSize1, d.getEstimatedPackSize()); + } else { + fail("unexpected " + d.getPackSource()); + } + } + } + private TestRepository<InMemoryRepository>.CommitBuilder commit() { return git.commit(); } @@ -179,20 +551,17 @@ private void gcNoTtl() throws IOException { run(gc); } - private void gcWithTtl() throws InterruptedException, IOException { - // Wait for the system clock to move by at least 1 millisecond. - // This allows the DfsGarbageCollector to recognize the boundary. - long start = System.currentTimeMillis(); - do { - Thread.sleep(10); - } while (System.currentTimeMillis() <= start); - + private void gcWithTtl() throws IOException { + // Move the clock forward by 1 minute and use the same as ttl. + mockSystemReader.tick(60); DfsGarbageCollector gc = new DfsGarbageCollector(repo); - gc.setGarbageTtl(1, TimeUnit.MILLISECONDS); + gc.setGarbageTtl(1, TimeUnit.MINUTES); run(gc); } private void run(DfsGarbageCollector gc) throws IOException { + // adjust the current time that will be used by the gc operation. + mockSystemReader.tick(1); assertTrue("gc repacked", gc.pack(null)); odb.clearCache(); }
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 b738f7e..e71ee6d 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
@@ -206,7 +206,7 @@ public void testInserterIgnoresUnreachable() throws IOException { // 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<PackSource>(); + Set<PackSource> pack_sources = new HashSet<>(); assertEquals(2, packs.length);
diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/dfs/DfsPackCompacterTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/dfs/DfsPackCompacterTest.java new file mode 100644 index 0000000..db5b24a --- /dev/null +++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/dfs/DfsPackCompacterTest.java
@@ -0,0 +1,144 @@ +/* + * 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.dfs.DfsObjDatabase.PackSource.COMPACT; +import static org.eclipse.jgit.internal.storage.dfs.DfsObjDatabase.PackSource.INSERT; +import static org.eclipse.jgit.internal.storage.pack.PackExt.PACK; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; + +import java.io.IOException; + +import org.eclipse.jgit.junit.TestRepository; +import org.eclipse.jgit.revwalk.RevCommit; +import org.junit.Before; +import org.junit.Test; + +public class DfsPackCompacterTest { + private TestRepository<InMemoryRepository> git; + private InMemoryRepository repo; + private DfsObjDatabase odb; + + @Before + public void setUp() throws IOException { + DfsRepositoryDescription desc = new DfsRepositoryDescription("test"); + git = new TestRepository<>(new InMemoryRepository(desc)); + repo = git.getRepository(); + odb = repo.getObjectDatabase(); + } + + @Test + public void testEstimateCompactPackSizeInNewRepo() throws Exception { + RevCommit commit0 = commit().message("0").create(); + RevCommit commit1 = commit().message("1").parent(commit0).create(); + git.update("master", commit1); + + // Packs start out as INSERT. + long inputPacksSize = 32; + assertEquals(2, odb.getPacks().length); + for (DfsPackFile pack : odb.getPacks()) { + assertEquals(INSERT, pack.getPackDescription().getPackSource()); + inputPacksSize += pack.getPackDescription().getFileSize(PACK) - 32; + } + + compact(); + + // INSERT packs are compacted into a single COMPACT pack. + assertEquals(1, odb.getPacks().length); + DfsPackFile pack = odb.getPacks()[0]; + assertEquals(COMPACT, pack.getPackDescription().getPackSource()); + assertEquals(inputPacksSize, + pack.getPackDescription().getEstimatedPackSize()); + } + + @Test + public void testEstimateGcPackSizeWithAnExistingGcPack() throws Exception { + RevCommit commit0 = commit().message("0").create(); + RevCommit commit1 = commit().message("1").parent(commit0).create(); + git.update("master", commit1); + + compact(); + + RevCommit commit2 = commit().message("2").parent(commit1).create(); + git.update("master", commit2); + + // There will be one INSERT pack and one COMPACT pack. + assertEquals(2, odb.getPacks().length); + boolean compactPackFound = false; + boolean insertPackFound = false; + long inputPacksSize = 32; + for (DfsPackFile pack : odb.getPacks()) { + DfsPackDescription packDescription = pack.getPackDescription(); + if (packDescription.getPackSource() == COMPACT) { + compactPackFound = true; + } + if (packDescription.getPackSource() == INSERT) { + insertPackFound = true; + } + inputPacksSize += packDescription.getFileSize(PACK) - 32; + } + assertTrue(compactPackFound); + assertTrue(insertPackFound); + + compact(); + + // INSERT pack is combined into the COMPACT pack. + DfsPackFile pack = odb.getPacks()[0]; + assertEquals(COMPACT, pack.getPackDescription().getPackSource()); + assertEquals(inputPacksSize, + pack.getPackDescription().getEstimatedPackSize()); + } + + private TestRepository<InMemoryRepository>.CommitBuilder commit() { + return git.commit(); + } + + private void compact() throws IOException { + DfsPackCompactor compactor = new DfsPackCompactor(repo); + compactor.autoAdd(); + compactor.compact(null); + odb.clearCache(); + } +}
diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/file/AbbreviationTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/file/AbbreviationTest.java index ece8f67..343120e 100644 --- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/file/AbbreviationTest.java +++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/file/AbbreviationTest.java
@@ -81,14 +81,16 @@ public class AbbreviationTest extends LocalDiskRepositoryTestCase { private TestRepository<Repository> test; + @Override @Before public void setUp() throws Exception { super.setUp(); db = createBareRepository(); reader = db.newObjectReader(); - test = new TestRepository<Repository>(db); + test = new TestRepository<>(db); } + @Override @After public void tearDown() throws Exception { if (reader != null) { @@ -169,7 +171,7 @@ public void testAbbreviateIsActuallyUnique() throws Exception { ObjectId id = id("9d5b926ed164e8ee88d3b8b1e525d699adda01ba"); byte[] idBuf = toByteArray(id); - List<PackedObjectInfo> objects = new ArrayList<PackedObjectInfo>(); + List<PackedObjectInfo> objects = new ArrayList<>(); for (int i = 0; i < 256; i++) { idBuf[9] = (byte) i; objects.add(new PackedObjectInfo(ObjectId.fromRaw(idBuf)));
diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/file/ConcurrentRepackTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/file/ConcurrentRepackTest.java index 1d71cb3..09438e96 100644 --- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/file/ConcurrentRepackTest.java +++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/file/ConcurrentRepackTest.java
@@ -77,6 +77,7 @@ import org.junit.Test; public class ConcurrentRepackTest extends RepositoryTestCase { + @Override @Before public void setUp() throws Exception { WindowCacheConfig windowCacheConfig = new WindowCacheConfig(); @@ -85,6 +86,7 @@ public void setUp() throws Exception { super.setUp(); } + @Override @After public void tearDown() throws Exception { super.tearDown();
diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/file/FileSnapshotTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/file/FileSnapshotTest.java index 98a9501..9998666 100644 --- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/file/FileSnapshotTest.java +++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/file/FileSnapshotTest.java
@@ -57,7 +57,7 @@ public class FileSnapshotTest { - private List<File> files = new ArrayList<File>(); + private List<File> files = new ArrayList<>(); private File trash;
diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/file/GcBasicPackingTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/file/GcBasicPackingTest.java index 41a1a5d..a2e1305 100644 --- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/file/GcBasicPackingTest.java +++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/file/GcBasicPackingTest.java
@@ -44,15 +44,21 @@ package org.eclipse.jgit.internal.storage.file; import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; import java.io.File; import java.io.IOException; +import java.util.ArrayList; import java.util.Collection; import java.util.Date; -import java.util.Iterator; +import java.util.List; import org.eclipse.jgit.junit.TestRepository.BranchBuilder; +import org.eclipse.jgit.lib.ConfigConstants; +import org.eclipse.jgit.lib.RefUpdate; import org.eclipse.jgit.revwalk.RevCommit; +import org.eclipse.jgit.storage.file.FileBasedConfig; import org.eclipse.jgit.storage.pack.PackConfig; import org.junit.Test; import org.junit.experimental.theories.DataPoints; @@ -175,14 +181,9 @@ public void testNotPackTwice(boolean aggressive) throws Exception { stats = gc.getStatistics(); assertEquals(0, stats.numberOfLooseObjects); - Iterator<PackFile> pIt = repo.getObjectDatabase().getPacks().iterator(); - long c = pIt.next().getObjectCount(); - if (c == 9) - assertEquals(2, pIt.next().getObjectCount()); - else { - assertEquals(2, c); - assertEquals(9, pIt.next().getObjectCount()); - } + List<PackFile> packs = new ArrayList<>( + repo.getObjectDatabase().getPacks()); + assertEquals(11, packs.get(0).getObjectCount()); } @Test @@ -190,16 +191,26 @@ public void testDonePruneTooYoungPacks() throws Exception { BranchBuilder bb = tr.branch("refs/heads/master"); bb.commit().message("M").add("M", "M").create(); + String tempRef = "refs/heads/soon-to-be-unreferenced"; + BranchBuilder bb2 = tr.branch(tempRef); + bb2.commit().message("M").add("M", "M").create(); + gc.setExpireAgeMillis(0); gc.gc(); stats = gc.getStatistics(); assertEquals(0, stats.numberOfLooseObjects); - assertEquals(3, stats.numberOfPackedObjects); + assertEquals(4, stats.numberOfPackedObjects); assertEquals(1, stats.numberOfPackFiles); File oldPackfile = tr.getRepository().getObjectDatabase().getPacks() .iterator().next().getPackFile(); fsTick(); + + // delete the temp ref, orphaning its commit + RefUpdate update = tr.getRepository().getRefDatabase().newUpdate(tempRef, false); + update.setForceUpdate(true); + update.delete(); + bb.commit().message("B").add("B", "Q").create(); // The old packfile is too young to be deleted. We should end up with @@ -210,7 +221,7 @@ public void testDonePruneTooYoungPacks() throws Exception { assertEquals(0, stats.numberOfLooseObjects); // if objects exist in multiple packFiles then they are counted multiple // times - assertEquals(9, stats.numberOfPackedObjects); + assertEquals(10, stats.numberOfPackedObjects); assertEquals(2, stats.numberOfPackFiles); // repack again but now without a grace period for loose objects. Since @@ -221,23 +232,102 @@ public void testDonePruneTooYoungPacks() throws Exception { assertEquals(0, stats.numberOfLooseObjects); // if objects exist in multiple packFiles then they are counted multiple // times - assertEquals(9, stats.numberOfPackedObjects); + assertEquals(10, stats.numberOfPackedObjects); assertEquals(2, stats.numberOfPackFiles); // repack again but now without a grace period for packfiles. We should // end up with one packfile gc.setPackExpireAgeMillis(0); + + // we want to keep newly-loosened objects though + gc.setExpireAgeMillis(-1); + gc.gc(); stats = gc.getStatistics(); - assertEquals(0, stats.numberOfLooseObjects); + assertEquals(1, stats.numberOfLooseObjects); // if objects exist in multiple packFiles then they are counted multiple // times assertEquals(6, stats.numberOfPackedObjects); assertEquals(1, stats.numberOfPackFiles); - } - private void configureGc(GC myGc, boolean aggressive) { + @Test + public void testImmediatePruning() throws Exception { + BranchBuilder bb = tr.branch("refs/heads/master"); + bb.commit().message("M").add("M", "M").create(); + + String tempRef = "refs/heads/soon-to-be-unreferenced"; + BranchBuilder bb2 = tr.branch(tempRef); + bb2.commit().message("M").add("M", "M").create(); + + gc.setExpireAgeMillis(0); + gc.gc(); + stats = gc.getStatistics(); + + fsTick(); + + // delete the temp ref, orphaning its commit + RefUpdate update = tr.getRepository().getRefDatabase().newUpdate(tempRef, false); + update.setForceUpdate(true); + update.delete(); + + bb.commit().message("B").add("B", "Q").create(); + + // We want to immediately prune deleted objects + FileBasedConfig config = repo.getConfig(); + config.setString(ConfigConstants.CONFIG_GC_SECTION, null, + ConfigConstants.CONFIG_KEY_PRUNEEXPIRE, "now"); + config.save(); + + //And we don't want to keep packs full of dead objects + gc.setPackExpireAgeMillis(0); + + gc.gc(); + stats = gc.getStatistics(); + assertEquals(0, stats.numberOfLooseObjects); + assertEquals(6, stats.numberOfPackedObjects); + assertEquals(1, stats.numberOfPackFiles); + } + + @Test + public void testPreserveAndPruneOldPacks() throws Exception { + testPreserveOldPacks(); + configureGc(gc, false).setPrunePreserved(true); + gc.gc(); + + assertFalse(repo.getObjectDatabase().getPreservedDirectory().exists()); + } + + private void testPreserveOldPacks() throws Exception { + BranchBuilder bb = tr.branch("refs/heads/master"); + bb.commit().message("P").add("P", "P").create(); + + // pack loose object into packfile + gc.setExpireAgeMillis(0); + gc.gc(); + File oldPackfile = tr.getRepository().getObjectDatabase().getPacks() + .iterator().next().getPackFile(); + assertTrue(oldPackfile.exists()); + + fsTick(); + bb.commit().message("B").add("B", "Q").create(); + + // repack again but now without a grace period for packfiles. We should + // end up with a new packfile and the old one should be placed in the + // preserved directory + gc.setPackExpireAgeMillis(0); + configureGc(gc, false).setPreserveOldPacks(true); + gc.gc(); + + File oldPackDir = repo.getObjectDatabase().getPreservedDirectory(); + String oldPackFileName = oldPackfile.getName(); + String oldPackName = oldPackFileName.substring(0, + oldPackFileName.lastIndexOf('.')) + ".old-pack"; //$NON-NLS-1$ + File preservePackFile = new File(oldPackDir, oldPackName); + assertTrue(preservePackFile.exists()); + } + + private PackConfig configureGc(GC myGc, boolean aggressive) { PackConfig pconfig = new PackConfig(repo); if (aggressive) { pconfig.setDeltaSearchWindowSize(250); @@ -246,5 +336,6 @@ private void configureGc(GC myGc, boolean aggressive) { } else pconfig = new PackConfig(repo); myGc.setPackConfig(pconfig); + return pconfig; } }
diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/file/GcConcurrentTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/file/GcConcurrentTest.java index 776226b..643bb49 100644 --- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/file/GcConcurrentTest.java +++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/file/GcConcurrentTest.java
@@ -78,6 +78,7 @@ public void concurrentRepack() throws Exception { class DoRepack extends EmptyProgressMonitor implements Callable<Integer> { + @Override public void beginTask(String title, int totalWork) { if (title.equals(JGitText.get().writingObjects)) { try { @@ -91,6 +92,7 @@ public void beginTask(String title, int totalWork) { } /** @return 0 for success, 1 in case of error when writing pack */ + @Override public Integer call() throws Exception { try { gc.setProgressMonitor(this);
diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/file/GcDeleteEmptyRefsFoldersTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/file/GcDeleteEmptyRefsFoldersTest.java new file mode 100644 index 0000000..b37cd7a --- /dev/null +++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/file/GcDeleteEmptyRefsFoldersTest.java
@@ -0,0 +1,132 @@ +/* + * Copyright (C) 2018 Ericsson + * 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.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; + +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.nio.file.attribute.FileTime; +import java.time.Instant; + +import org.junit.Before; +import org.junit.Test; + +public class GcDeleteEmptyRefsFoldersTest extends GcTestCase { + private static final String REF_FOLDER_01 = "A/B/01"; + private static final String REF_FOLDER_02 = "C/D/02"; + + private Path refsDir; + private Path heads; + + @Override + @Before + public void setUp() throws Exception { + super.setUp(); + refsDir = Paths.get(repo.getDirectory().getAbsolutePath()) + .resolve("refs"); + heads = refsDir.resolve("heads"); + } + + @Test + public void emptyRefFoldersAreDeleted() throws Exception { + FileTime fileTime = FileTime.from(Instant.now().minusSeconds(31)); + Path refDir01 = Files.createDirectories(heads.resolve(REF_FOLDER_01)); + Path refDir02 = Files.createDirectories(heads.resolve(REF_FOLDER_02)); + setLastModifiedTime(fileTime, heads, REF_FOLDER_01); + setLastModifiedTime(fileTime, heads, REF_FOLDER_02); + assertTrue(refDir01.toFile().exists()); + assertTrue(refDir02.toFile().exists()); + gc.gc(); + + assertFalse(refDir01.toFile().exists()); + assertFalse(refDir01.getParent().toFile().exists()); + assertFalse(refDir01.getParent().getParent().toFile().exists()); + assertFalse(refDir02.toFile().exists()); + assertFalse(refDir02.getParent().toFile().exists()); + assertFalse(refDir02.getParent().getParent().toFile().exists()); + } + + private void setLastModifiedTime(FileTime fileTime, Path path, String folder) throws IOException { + long numParents = folder.chars().filter(c -> c == '/').count(); + Path folderPath = path.resolve(folder); + for(int folderLevel = 0; folderLevel <= numParents; folderLevel ++ ) { + Files.setLastModifiedTime(folderPath, fileTime); + folderPath = folderPath.getParent(); + } + } + + @Test + public void emptyRefFoldersAreKeptIfTheyAreTooRecent() + throws Exception { + Path refDir01 = Files.createDirectories(heads.resolve(REF_FOLDER_01)); + Path refDir02 = Files.createDirectories(heads.resolve(REF_FOLDER_02)); + assertTrue(refDir01.toFile().exists()); + assertTrue(refDir02.toFile().exists()); + gc.gc(); + + assertTrue(refDir01.toFile().exists()); + assertTrue(refDir02.toFile().exists()); + } + + @Test + public void nonEmptyRefsFoldersAreKept() throws Exception { + Path refDir01 = Files.createDirectories(heads.resolve(REF_FOLDER_01)); + Path refDir02 = Files.createDirectories(heads.resolve(REF_FOLDER_02)); + Path ref01 = Files.createFile(refDir01.resolve("ref01")); + Path ref02 = Files.createFile(refDir01.resolve("ref02")); + assertTrue(refDir01.toFile().exists()); + assertTrue(refDir02.toFile().exists()); + assertTrue(ref01.toFile().exists()); + assertTrue(ref02.toFile().exists()); + gc.gc(); + assertTrue(refDir01.toFile().exists()); + assertTrue(refDir02.toFile().exists()); + assertTrue(ref01.toFile().exists()); + assertTrue(ref02.toFile().exists()); + } +}
diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/file/GcKeepFilesTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/file/GcKeepFilesTest.java index 9e28298..1a50844 100644 --- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/file/GcKeepFilesTest.java +++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/file/GcKeepFilesTest.java
@@ -73,7 +73,10 @@ public void testKeepFiles() throws Exception { .iterator(); PackFile singlePack = packIt.next(); assertFalse(packIt.hasNext()); - File keepFile = new File(singlePack.getPackFile().getPath() + ".keep"); + String packFileName = singlePack.getPackFile().getPath(); + String keepFileName = packFileName.substring(0, + packFileName.lastIndexOf('.')) + ".keep"; + File keepFile = new File(keepFileName); assertFalse(keepFile.exists()); assertTrue(keepFile.createNewFile()); bb.commit().add("A", "A2").add("B", "B2").create();
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 d9317b8..5393987 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
@@ -67,6 +67,7 @@ public class GcOrphanFilesTest extends GcTestCase { private File packDir; + @Override @Before public void setUp() throws Exception { super.setUp();
diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/file/GcPackRefsTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/file/GcPackRefsTest.java index ea8dfa2..11a2a22 100644 --- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/file/GcPackRefsTest.java +++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/file/GcPackRefsTest.java
@@ -46,6 +46,7 @@ import static java.lang.Integer.valueOf; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertNull; import static org.junit.Assert.assertSame; @@ -89,7 +90,7 @@ public void emptyRefDirectoryDeleted() throws Exception { tr.branch(ref).commit().create(); String name = repo.findRef(ref).getName(); Path dir = repo.getDirectory().toPath().resolve(name).getParent(); - + assertNotNull(dir); gc.packRefs(); assertFalse(Files.exists(dir)); } @@ -104,6 +105,7 @@ public void concurrentOnlyOneWritesPackedRefs() throws Exception { Callable<Integer> packRefs = new Callable<Integer>() { /** @return 0 for success, 1 in case of error when writing pack */ + @Override public Integer call() throws Exception { syncPoint.await(); try { @@ -157,6 +159,7 @@ public void whileRefUpdatedRefUpdateSucceeds() try { Future<Result> result = pool.submit(new Callable<Result>() { + @Override public Result call() throws Exception { RefUpdate update = new RefDirectoryUpdate( (RefDirectory) repo.getRefDatabase(), @@ -181,6 +184,7 @@ public boolean isForceUpdate() { }); pool.submit(new Callable<Void>() { + @Override public Void call() throws Exception { refUpdateLockedRef.await(); gc.packRefs();
diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/file/GcTestCase.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/file/GcTestCase.java index 90c1152..d16998d 100644 --- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/file/GcTestCase.java +++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/file/GcTestCase.java
@@ -62,15 +62,17 @@ public abstract class GcTestCase extends LocalDiskRepositoryTestCase { protected GC gc; protected RepoStatistics stats; + @Override @Before public void setUp() throws Exception { super.setUp(); repo = createWorkRepository(); - tr = new TestRepository<FileRepository>(repo, new RevWalk(repo), + tr = new TestRepository<>(repo, new RevWalk(repo), mockSystemReader); gc = new GC(repo); } + @Override @After public void tearDown() throws Exception { super.tearDown();
diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/file/ObjectDirectoryTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/file/ObjectDirectoryTest.java index 87554ae..f1cbb99 100644 --- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/file/ObjectDirectoryTest.java +++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/file/ObjectDirectoryTest.java
@@ -47,13 +47,18 @@ import java.io.File; import java.io.FilenameFilter; +import java.io.IOException; +import java.io.PrintWriter; +import java.text.MessageFormat; import java.util.Collection; import java.util.Collections; +import java.util.Set; import java.util.concurrent.Callable; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.Future; +import org.eclipse.jgit.internal.JGitText; import org.eclipse.jgit.junit.RepositoryTestCase; import org.eclipse.jgit.lib.ConfigConstants; import org.eclipse.jgit.lib.Constants; @@ -61,10 +66,15 @@ import org.eclipse.jgit.revwalk.RevCommit; import org.eclipse.jgit.storage.file.FileBasedConfig; import org.junit.Assume; +import org.junit.Rule; import org.junit.Test; +import org.junit.rules.ExpectedException; public class ObjectDirectoryTest extends RepositoryTestCase { + @Rule + public ExpectedException expectedEx = ExpectedException.none(); + @Test public void testConcurrentInsertionOfBlobsToTheSameNewFanOutDirectory() throws Exception { @@ -162,7 +172,7 @@ public boolean accept(File dir, String name) { return name.endsWith(".pack"); } }); - assertTrue(ret.length == 1); + assertTrue(ret != null && ret.length == 1); Assume.assumeTrue(tmpFile.lastModified() == ret[0].lastModified()); // all objects are in a new packfile but we will not detect it @@ -171,9 +181,44 @@ public boolean accept(File dir, String name) { } } + @Test + public void testShallowFile() + throws Exception { + FileRepository repository = createBareRepository(); + ObjectDirectory dir = repository.getObjectDatabase(); + + String commit = "d3148f9410b071edd4a4c85d2a43d1fa2574b0d2"; + try (PrintWriter writer = new PrintWriter( + new File(repository.getDirectory(), Constants.SHALLOW))) { + writer.println(commit); + } + Set<ObjectId> shallowCommits = dir.getShallowCommits(); + assertTrue(shallowCommits.remove(ObjectId.fromString(commit))); + assertTrue(shallowCommits.isEmpty()); + } + + @Test + public void testShallowFileCorrupt() + throws Exception { + FileRepository repository = createBareRepository(); + ObjectDirectory dir = repository.getObjectDatabase(); + + String commit = "X3148f9410b071edd4a4c85d2a43d1fa2574b0d2"; + try (PrintWriter writer = new PrintWriter( + new File(repository.getDirectory(), Constants.SHALLOW))) { + writer.println(commit); + } + + expectedEx.expect(IOException.class); + expectedEx.expectMessage(MessageFormat + .format(JGitText.get().badShallowLine, commit)); + dir.getShallowCommits(); + } + private Collection<Callable<ObjectId>> blobInsertersForTheSameFanOutDir( final ObjectDirectory dir) { Callable<ObjectId> callable = new Callable<ObjectId>() { + @Override public ObjectId call() throws Exception { return dir.newInserter().insert(Constants.OBJ_BLOB, new byte[0]); }
diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/file/PackFileTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/file/PackFileTest.java index 1c10bb3..91bd523 100644 --- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/file/PackFileTest.java +++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/file/PackFileTest.java
@@ -107,6 +107,7 @@ private TestRng getRng() { return rng; } + @Override @Before public void setUp() throws Exception { super.setUp(); @@ -116,10 +117,11 @@ public void setUp() throws Exception { cfg.install(); repo = createBareRepository(); - tr = new TestRepository<Repository>(repo); + tr = new TestRepository<>(repo); wc = (WindowCursor) repo.newObjectReader(); } + @Override @After public void tearDown() throws Exception { if (wc != null) @@ -289,7 +291,7 @@ public void testDelta_FailsOver2GiB() throws Exception { f = new FileOutputStream(idxName); try { - List<PackedObjectInfo> list = new ArrayList<PackedObjectInfo>(); + List<PackedObjectInfo> list = new ArrayList<>(); list.add(a); list.add(b); Collections.sort(list);
diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/file/PackIndexTestCase.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/file/PackIndexTestCase.java index b6aa4bc..9a43742 100644 --- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/file/PackIndexTestCase.java +++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/file/PackIndexTestCase.java
@@ -62,6 +62,7 @@ public abstract class PackIndexTestCase extends RepositoryTestCase { PackIndex denseIdx; + @Override public void setUp() throws Exception { super.setUp(); smallIdx = PackIndex.open(getFileForPack34be9032());
diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/file/PackReverseIndexTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/file/PackReverseIndexTest.java index a4aa8bc..91dac09 100644 --- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/file/PackReverseIndexTest.java +++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/file/PackReverseIndexTest.java
@@ -65,6 +65,7 @@ public class PackReverseIndexTest extends RepositoryTestCase { /** * Set up tested class instance, test constructor by the way. */ + @Override @Before public void setUp() throws Exception { super.setUp();
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 2e57952..c817dc3 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
@@ -131,6 +131,7 @@ public class PackWriterTest extends SampleDataRepositoryTestCase { private RevCommit c5; + @Override @Before public void setUp() throws Exception { super.setUp(); @@ -143,6 +144,7 @@ public void setUp() throws Exception { write(alt, db.getObjectDatabase().getDirectory().getAbsolutePath() + "\n"); } + @Override @After public void tearDown() throws Exception { if (writer != null) { @@ -364,8 +366,8 @@ public void testWritePack3() throws MissingObjectException, IOException { ObjectId.fromString("c59759f143fb1fe21c197981df75a7ee00290799"), ObjectId.fromString("aabf2ffaec9b497f0950352b3e582d73035c2035"), ObjectId.fromString("902d5476fa249b7abc9d84c611577a81381f0327"), - ObjectId.fromString("5b6e7c66c276e7610d4a73c70ec1a1f7c1003259"), - ObjectId.fromString("6ff87c4664981e4397625791c8ea3bbb5f2279a3") }; + ObjectId.fromString("6ff87c4664981e4397625791c8ea3bbb5f2279a3") , + ObjectId.fromString("5b6e7c66c276e7610d4a73c70ec1a1f7c1003259") }; try (final RevWalk parser = new RevWalk(db)) { final RevObject forcedOrderRevs[] = new RevObject[forcedOrder.length]; for (int i = 0; i < forcedOrder.length; i++) @@ -412,6 +414,8 @@ public void testWritePack4ThinPack() throws IOException { */ @Test public void testWritePack2SizeDeltasVsNoDeltas() throws Exception { + config.setReuseDeltas(false); + config.setDeltaCompress(false); testWritePack2(); final long sizePack2NoDeltas = os.size(); tearDown(); @@ -465,7 +469,7 @@ public void testWritePack4SizeThinVsNoThin() throws Exception { public void testDeltaStatistics() throws Exception { config.setDeltaCompress(true); FileRepository repo = createBareRepository(); - TestRepository<FileRepository> testRepo = new TestRepository<FileRepository>(repo); + TestRepository<FileRepository> testRepo = new TestRepository<>(repo); ArrayList<RevObject> blobs = new ArrayList<>(); blobs.add(testRepo.blob(genDeltableData(1000))); blobs.add(testRepo.blob(genDeltableData(1005))); @@ -534,7 +538,7 @@ public void testWriteIndex() throws Exception { public void testExclude() throws Exception { FileRepository repo = createBareRepository(); - TestRepository<FileRepository> testRepo = new TestRepository<FileRepository>( + TestRepository<FileRepository> testRepo = new TestRepository<>( repo); BranchBuilder bb = testRepo.branch("refs/heads/master"); contentA = testRepo.blob("A"); @@ -659,7 +663,7 @@ public void testShallowFetchShallowAncestorDepth2() throws Exception { private FileRepository setupRepoForShallowFetch() throws Exception { FileRepository repo = createBareRepository(); - TestRepository<Repository> r = new TestRepository<Repository>(repo); + TestRepository<Repository> r = new TestRepository<>(repo); BranchBuilder bb = r.branch("refs/heads/master"); contentA = r.blob("A"); contentB = r.blob("B"); @@ -727,7 +731,7 @@ private static PackIndex writePack(FileRepository repo, RevWalk walk, // TODO: testWritePackDeltasDepth() private void writeVerifyPack1() throws IOException { - final HashSet<ObjectId> interestings = new HashSet<ObjectId>(); + final HashSet<ObjectId> interestings = new HashSet<>(); interestings.add(ObjectId .fromString("82c6b885ff600be425b4ea96dee75dca255b69e7")); createVerifyOpenPack(interestings, NONE, false, false); @@ -739,8 +743,8 @@ private void writeVerifyPack1() throws IOException { ObjectId.fromString("aabf2ffaec9b497f0950352b3e582d73035c2035"), ObjectId.fromString("902d5476fa249b7abc9d84c611577a81381f0327"), ObjectId.fromString("4b825dc642cb6eb9a060e54bf8d69288fbee4904"), - ObjectId.fromString("5b6e7c66c276e7610d4a73c70ec1a1f7c1003259"), - ObjectId.fromString("6ff87c4664981e4397625791c8ea3bbb5f2279a3") }; + ObjectId.fromString("6ff87c4664981e4397625791c8ea3bbb5f2279a3"), + ObjectId.fromString("5b6e7c66c276e7610d4a73c70ec1a1f7c1003259") }; assertEquals(expectedOrder.length, writer.getObjectCount()); verifyObjectsOrder(expectedOrder); @@ -750,10 +754,10 @@ private void writeVerifyPack1() throws IOException { private void writeVerifyPack2(boolean deltaReuse) throws IOException { config.setReuseDeltas(deltaReuse); - final HashSet<ObjectId> interestings = new HashSet<ObjectId>(); + final HashSet<ObjectId> interestings = new HashSet<>(); interestings.add(ObjectId .fromString("82c6b885ff600be425b4ea96dee75dca255b69e7")); - final HashSet<ObjectId> uninterestings = new HashSet<ObjectId>(); + final HashSet<ObjectId> uninterestings = new HashSet<>(); uninterestings.add(ObjectId .fromString("540a36d136cf413e4b064c2b0e0a4db60f77feab")); createVerifyOpenPack(interestings, uninterestings, false, false); @@ -763,13 +767,11 @@ private void writeVerifyPack2(boolean deltaReuse) throws IOException { ObjectId.fromString("c59759f143fb1fe21c197981df75a7ee00290799"), ObjectId.fromString("aabf2ffaec9b497f0950352b3e582d73035c2035"), ObjectId.fromString("902d5476fa249b7abc9d84c611577a81381f0327"), - ObjectId.fromString("5b6e7c66c276e7610d4a73c70ec1a1f7c1003259"), - ObjectId.fromString("6ff87c4664981e4397625791c8ea3bbb5f2279a3") }; - if (deltaReuse) { - // objects order influenced (swapped) by delta-base first rule - ObjectId temp = expectedOrder[4]; - expectedOrder[4] = expectedOrder[5]; - expectedOrder[5] = temp; + ObjectId.fromString("6ff87c4664981e4397625791c8ea3bbb5f2279a3") , + ObjectId.fromString("5b6e7c66c276e7610d4a73c70ec1a1f7c1003259") }; + if (!config.isReuseDeltas() && !config.isDeltaCompress()) { + // If no deltas are in the file the final two entries swap places. + swap(expectedOrder, 4, 5); } assertEquals(expectedOrder.length, writer.getObjectCount()); verifyObjectsOrder(expectedOrder); @@ -777,11 +779,17 @@ private void writeVerifyPack2(boolean deltaReuse) throws IOException { .computeName().name()); } + private static void swap(ObjectId[] arr, int a, int b) { + ObjectId tmp = arr[a]; + arr[a] = arr[b]; + arr[b] = tmp; + } + private void writeVerifyPack4(final boolean thin) throws IOException { - final HashSet<ObjectId> interestings = new HashSet<ObjectId>(); + final HashSet<ObjectId> interestings = new HashSet<>(); interestings.add(ObjectId .fromString("82c6b885ff600be425b4ea96dee75dca255b69e7")); - final HashSet<ObjectId> uninterestings = new HashSet<ObjectId>(); + final HashSet<ObjectId> uninterestings = new HashSet<>(); uninterestings.add(ObjectId .fromString("c59759f143fb1fe21c197981df75a7ee00290799")); createVerifyOpenPack(interestings, uninterestings, thin, false); @@ -870,12 +878,13 @@ private PackParser index(final byte[] packData) throws IOException { } private void verifyObjectsOrder(final ObjectId objectsOrder[]) { - final List<PackIndex.MutableEntry> entries = new ArrayList<PackIndex.MutableEntry>(); + final List<PackIndex.MutableEntry> entries = new ArrayList<>(); for (MutableEntry me : pack) { entries.add(me.cloneEntry()); } Collections.sort(entries, new Comparator<PackIndex.MutableEntry>() { + @Override public int compare(MutableEntry o1, MutableEntry o2) { return Long.signum(o1.getOffset() - o2.getOffset()); }
diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/file/RefDirectoryTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/file/RefDirectoryTest.java index 5999acf..53db123 100644 --- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/file/RefDirectoryTest.java +++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/file/RefDirectoryTest.java
@@ -100,6 +100,7 @@ public class RefDirectoryTest extends LocalDiskRepositoryTestCase { private RevTag v1_0; + @Override @Before public void setUp() throws Exception { super.setUp(); @@ -107,7 +108,7 @@ public void setUp() throws Exception { diskRepo = createBareRepository(); refdir = (RefDirectory) diskRepo.getRefDatabase(); - repo = new TestRepository<Repository>(diskRepo); + repo = new TestRepository<>(diskRepo); A = repo.commit().create(); B = repo.commit(repo.getRevWalk().parseCommit(A)); v1_0 = repo.tag("v1_0", B); @@ -547,6 +548,7 @@ public void testGetRefs_LooseSorting_Bug_348834() throws IOException { ListenerHandle listener = Repository.getGlobalListenerList() .addRefsChangedListener(new RefsChangedListener() { + @Override public void onRefsChanged(RefsChangedEvent event) { count[0]++; } @@ -1021,7 +1023,7 @@ public void test_repack() throws Exception { assertEquals(v0_1.getId(), all.get("refs/tags/v0.1").getObjectId()); all = refdir.getRefs(RefDatabase.ALL); - refdir.pack(new ArrayList<String>(all.keySet())); + refdir.pack(new ArrayList<>(all.keySet())); all = refdir.getRefs(RefDatabase.ALL); assertEquals(5, all.size()); @@ -1265,12 +1267,13 @@ public void testRefsChangedStackOverflow() throws Exception { final RefDatabase refDb = newRepo.getRefDatabase(); File packedRefs = new File(newRepo.getDirectory(), "packed-refs"); assertTrue(packedRefs.createNewFile()); - final AtomicReference<StackOverflowError> error = new AtomicReference<StackOverflowError>(); - final AtomicReference<IOException> exception = new AtomicReference<IOException>(); + final AtomicReference<StackOverflowError> error = new AtomicReference<>(); + final AtomicReference<IOException> exception = new AtomicReference<>(); final AtomicInteger changeCount = new AtomicInteger(); newRepo.getListenerList().addRefsChangedListener( new RefsChangedListener() { + @Override public void onRefsChanged(RefsChangedEvent event) { try { refDb.getRefs("ref"); @@ -1440,23 +1443,28 @@ private void deleteLooseRef(String name) { private static final class StrictWorkMonitor implements ProgressMonitor { private int lastWork, totalWork; + @Override public void start(int totalTasks) { // empty } + @Override public void beginTask(String title, int total) { this.totalWork = total; lastWork = 0; } + @Override public void update(int completed) { lastWork += completed; } + @Override public void endTask() { assertEquals("Units of work recorded", totalWork, lastWork); } + @Override public boolean isCancelled() { return false; }
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 4be1d6d..0f26b0f 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
@@ -46,6 +46,7 @@ package org.eclipse.jgit.internal.storage.file; import static org.eclipse.jgit.junit.Assert.assertEquals; +import static org.eclipse.jgit.lib.Constants.LOCK_SUFFIX; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertNotNull; @@ -239,14 +240,14 @@ public void testDeleteHead() throws IOException { @Test public void testDeleteHeadInBareRepo() throws IOException { - try (Repository bareRepo = createBareRepository()) { - RefUpdate ref = bareRepo.updateRef(Constants.HEAD); - ref.setNewObjectId(ObjectId.fromString("0123456789012345678901234567890123456789")); - // Create the HEAD ref so we can delete it. - assertEquals(Result.NEW, ref.update()); - ref = bareRepo.updateRef(Constants.HEAD); - delete(bareRepo, ref, Result.NO_CHANGE, true, true); - } + Repository bareRepo = createBareRepository(); + RefUpdate ref = bareRepo.updateRef(Constants.HEAD); + ref.setNewObjectId(ObjectId + .fromString("0123456789012345678901234567890123456789")); + // Create the HEAD ref so we can delete it. + assertEquals(Result.NEW, ref.update()); + ref = bareRepo.updateRef(Constants.HEAD); + delete(bareRepo, ref, Result.NO_CHANGE, true, true); } /** * Delete a loose ref and make sure the directory in refs is deleted too, @@ -758,11 +759,11 @@ public void tryRenameWhenLocked(String toLock, String fromName, // Check that the involved refs are the same despite the failure assertExists(false, toName); if (!toLock.equals(toName)) - assertExists(false, toName + ".lock"); - assertExists(true, toLock + ".lock"); + assertExists(false, toName + LOCK_SUFFIX); + assertExists(true, toLock + LOCK_SUFFIX); if (!toLock.equals(fromName)) - assertExists(false, "logs/" + fromName + ".lock"); - assertExists(false, "logs/" + toName + ".lock"); + assertExists(false, "logs/" + fromName + LOCK_SUFFIX); + assertExists(false, "logs/" + toName + LOCK_SUFFIX); assertEquals(oldHeadId, db.resolve(Constants.HEAD)); assertEquals(oldfromId, db.resolve(fromName)); assertNull(db.resolve(toName));
diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/file/UnpackedObjectTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/file/UnpackedObjectTest.java index c6653bf..c5ab766 100644 --- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/file/UnpackedObjectTest.java +++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/file/UnpackedObjectTest.java
@@ -93,6 +93,7 @@ private TestRng getRng() { return rng; } + @Override @Before public void setUp() throws Exception { super.setUp(); @@ -105,6 +106,7 @@ public void setUp() throws Exception { wc = (WindowCursor) repo.newObjectReader(); } + @Override @After public void tearDown() throws Exception { if (wc != null)
diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/file/WindowCacheGetTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/file/WindowCacheGetTest.java index aa061ba..cc34838 100644 --- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/file/WindowCacheGetTest.java +++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/file/WindowCacheGetTest.java
@@ -73,7 +73,7 @@ public class WindowCacheGetTest extends SampleDataRepositoryTestCase { public void setUp() throws Exception { super.setUp(); - toLoad = new ArrayList<TestObject>(); + toLoad = new ArrayList<>(); final BufferedReader br = new BufferedReader(new InputStreamReader( new FileInputStream(JGitTestUtil .getTestResourceFile("all_packed_objects.txt")),
diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/reftree/LocalDiskRefTreeDatabaseTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/reftree/LocalDiskRefTreeDatabaseTest.java index 47f70d7..67a7819 100644 --- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/reftree/LocalDiskRefTreeDatabaseTest.java +++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/reftree/LocalDiskRefTreeDatabaseTest.java
@@ -77,6 +77,7 @@ public class LocalDiskRefTreeDatabaseTest extends LocalDiskRepositoryTestCase { private RevCommit A; private RevCommit B; + @Override @Before public void setUp() throws Exception { FileRepository init = createWorkRepository();
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 e4d0f1d..9aef943 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
@@ -711,6 +711,7 @@ private class InMemRefTreeRepo extends InMemoryRepository { RefTreeDatabaseTest.this.refdb = refs; } + @Override public RefDatabase getRefDatabase() { return refs; }
diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/lib/BranchTrackingStatusTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/lib/BranchTrackingStatusTest.java index e261b96..8e56419 100644 --- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/lib/BranchTrackingStatusTest.java +++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/lib/BranchTrackingStatusTest.java
@@ -60,7 +60,7 @@ public class BranchTrackingStatusTest extends RepositoryTestCase { @Override public void setUp() throws Exception { super.setUp(); - util = new TestRepository<Repository>(db); + util = new TestRepository<>(db); StoredConfig config = util.getRepository().getConfig(); config.setString(ConfigConstants.CONFIG_BRANCH_SECTION, "master", ConfigConstants.CONFIG_KEY_REMOTE, "origin");
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 aebbafe..e9505f6 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
@@ -139,7 +139,7 @@ public void test004_PutGetSimple() { @Test public void test005_PutGetStringList() { Config c = new Config(); - final LinkedList<String> values = new LinkedList<String>(); + final LinkedList<String> values = new LinkedList<>(); values.add("value1"); values.add("value2"); c.setStringList("my", null, "somename", values);
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 bb553a4..75b574e 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
@@ -130,7 +130,7 @@ private static HashMap<String, String> mkmap(String... args) { if ((args.length % 2) > 0) throw new IllegalArgumentException("needs to be pairs"); - HashMap<String, String> map = new HashMap<String, String>(); + HashMap<String, String> map = new HashMap<>(); for (int i = 0; i < args.length; i += 2) { map.put(args[i], args[i + 1]); } @@ -228,7 +228,7 @@ public void testResetHardFromIndexEntryWithoutFileToTreeWithoutFile() @Test public void testInitialCheckout() throws Exception { try (Git git = new Git(db)) { - TestRepository<Repository> db_t = new TestRepository<Repository>(db); + TestRepository<Repository> db_t = new TestRepository<>(db); BranchBuilder master = db_t.branch("master"); master.commit().add("f", "1").message("m0").create(); assertFalse(new File(db.getWorkTree(), "f").exists()); @@ -377,7 +377,7 @@ public void testRules4thru13_IndexEntryNotInHead() throws IOException { // rules 4 and 5 HashMap<String, String> idxMap; - idxMap = new HashMap<String, String>(); + idxMap = new HashMap<>(); idxMap.put("foo", "foo"); setupCase(null, null, idxMap); go(); @@ -387,7 +387,7 @@ public void testRules4thru13_IndexEntryNotInHead() throws IOException { assertTrue(getConflicts().isEmpty()); // rules 6 and 7 - idxMap = new HashMap<String, String>(); + idxMap = new HashMap<>(); idxMap.put("foo", "foo"); setupCase(null, idxMap, idxMap); go(); @@ -396,7 +396,7 @@ public void testRules4thru13_IndexEntryNotInHead() throws IOException { // rules 8 and 9 HashMap<String, String> mergeMap; - mergeMap = new HashMap<String, String>(); + mergeMap = new HashMap<>(); mergeMap.put("foo", "merge"); setupCase(null, mergeMap, idxMap); @@ -408,7 +408,7 @@ public void testRules4thru13_IndexEntryNotInHead() throws IOException { // rule 10 - HashMap<String, String> headMap = new HashMap<String, String>(); + HashMap<String, String> headMap = new HashMap<>(); headMap.put("foo", "foo"); setupCase(headMap, null, idxMap); go(); @@ -1705,7 +1705,8 @@ public void assertWorkDir(Map<String, String> i) + " in workDir. ", buffer, i.get(path).getBytes()); nrFiles++; } else if (file.isDirectory()) { - if (file.list().length == 0) { + String[] files = file.list(); + if (files != null && files.length == 0) { assertEquals("found unexpected empty folder for path " + path + " in workDir. ", "/", i.get(path)); nrFiles++;
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 3259f62..0111b94 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
@@ -90,7 +90,6 @@ public void setUp() throws Exception { .setPath("modules/submodule") .setURI(submoduleStandalone.getDirectory().toURI().toString()) .call(); - submoduleStandalone.close(); submodule_trash = submodule_db.getWorkTree(); addRepoToClose(submodule_db); writeTrashFile("fileInRoot", "root");
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 733f166..2cb8f86 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
@@ -86,6 +86,7 @@ static PathEdit add(final Repository db, final File workdir, final ObjectId id = inserter.insert(Constants.OBJ_BLOB, IO.readFully(f)); return new PathEdit(path) { + @Override public void apply(DirCacheEntry ent) { ent.setFileMode(FileMode.REGULAR_FILE); ent.setLength(f.length()); @@ -209,7 +210,7 @@ public void testConflicting() throws Exception { diff.diff(); assertEquals("[b]", - new TreeSet<String>(diff.getChanged()).toString()); + new TreeSet<>(diff.getChanged()).toString()); assertEquals("[]", diff.getAdded().toString()); assertEquals("[]", diff.getRemoved().toString()); assertEquals("[]", diff.getMissing().toString()); @@ -250,7 +251,7 @@ public void testConflictingDeletedAndModified() throws Exception { IndexDiff diff = new IndexDiff(db, Constants.HEAD, iterator); diff.diff(); - assertEquals("[]", new TreeSet<String>(diff.getChanged()).toString()); + assertEquals("[]", new TreeSet<>(diff.getChanged()).toString()); assertEquals("[]", diff.getAdded().toString()); assertEquals("[]", diff.getRemoved().toString()); assertEquals("[]", diff.getMissing().toString()); @@ -290,7 +291,7 @@ public void testConflictingFromMultipleCreations() throws Exception { IndexDiff diff = new IndexDiff(db, Constants.HEAD, iterator); diff.diff(); - assertEquals("[]", new TreeSet<String>(diff.getChanged()).toString()); + assertEquals("[]", new TreeSet<>(diff.getChanged()).toString()); assertEquals("[]", diff.getAdded().toString()); assertEquals("[]", diff.getRemoved().toString()); assertEquals("[]", diff.getMissing().toString()); @@ -443,7 +444,7 @@ public void testUntrackedFolders() throws Exception { diff = new IndexDiff(db, Constants.HEAD, new FileTreeIterator(db)); diff.diff(); - assertEquals(new HashSet<String>(Arrays.asList("target")), + assertEquals(new HashSet<>(Arrays.asList("target")), diff.getUntrackedFolders()); writeTrashFile("src/tst/A.java", ""); @@ -451,7 +452,7 @@ public void testUntrackedFolders() throws Exception { diff = new IndexDiff(db, Constants.HEAD, new FileTreeIterator(db)); diff.diff(); - assertEquals(new HashSet<String>(Arrays.asList("target", "src/tst")), + assertEquals(new HashSet<>(Arrays.asList("target", "src/tst")), diff.getUntrackedFolders()); git.rm().addFilepattern("src/com/B.java").addFilepattern("src/org") @@ -462,7 +463,7 @@ public void testUntrackedFolders() throws Exception { diff = new IndexDiff(db, Constants.HEAD, new FileTreeIterator(db)); diff.diff(); assertEquals( - new HashSet<String>(Arrays.asList("src/org", "src/tst", + new HashSet<>(Arrays.asList("src/org", "src/tst", "target")), diff.getUntrackedFolders()); } @@ -496,7 +497,7 @@ public void testUntrackedNotIgnoredFolders() throws Exception { diff = new IndexDiff(db, Constants.HEAD, new FileTreeIterator(db)); diff.diff(); - assertEquals(new HashSet<String>(Arrays.asList("src")), + assertEquals(new HashSet<>(Arrays.asList("src")), diff.getUntrackedFolders()); git.add().addFilepattern("src").call(); @@ -509,7 +510,7 @@ public void testUntrackedNotIgnoredFolders() throws Exception { diff = new IndexDiff(db, Constants.HEAD, new FileTreeIterator(db)); diff.diff(); assertEquals( - new HashSet<String>(Arrays.asList("srcs/com", "sr", "src/tst", + new HashSet<>(Arrays.asList("srcs/com", "sr", "src/tst", "target")), diff.getUntrackedFolders()); }
diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/lib/ObjectCheckerTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/lib/ObjectCheckerTest.java index 43160fb..7d298ed 100644 --- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/lib/ObjectCheckerTest.java +++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/lib/ObjectCheckerTest.java
@@ -768,6 +768,112 @@ public void testValidTree6() throws CorruptObjectException { } @Test + public void testValidTreeWithGitmodules() throws CorruptObjectException { + ObjectId treeId = ObjectId + .fromString("0123012301230123012301230123012301230123"); + StringBuilder b = new StringBuilder(); + ObjectId blobId = entry(b, "100644 .gitmodules"); + + byte[] data = encodeASCII(b.toString()); + checker.checkTree(treeId, data); + assertEquals(1, checker.getGitsubmodules().size()); + assertEquals(treeId, checker.getGitsubmodules().get(0).getTreeId()); + assertEquals(blobId, checker.getGitsubmodules().get(0).getBlobId()); + } + + /* + * Windows case insensitivity and long file name handling + * means that .gitmodules has many synonyms. + * + * Examples inspired by git.git's t/t0060-path-utils.sh, by + * Johannes Schindelin and Congyi Wu. + */ + @Test + public void testNTFSGitmodules() throws CorruptObjectException { + for (String gitmodules : new String[] { + ".GITMODULES", + ".gitmodules", + ".Gitmodules", + ".gitmoduleS", + "gitmod~1", + "GITMOD~1", + "gitmod~4", + "GI7EBA~1", + "gi7eba~9", + "GI7EB~10", + "GI7E~123", + "~1000000", + "~9999999" + }) { + checker = new ObjectChecker(); // Reset the ObjectChecker state. + checker.setSafeForWindows(true); + ObjectId treeId = ObjectId + .fromString("0123012301230123012301230123012301230123"); + StringBuilder b = new StringBuilder(); + ObjectId blobId = entry(b, "100644 " + gitmodules); + + byte[] data = encodeASCII(b.toString()); + checker.checkTree(treeId, data); + assertEquals(1, checker.getGitsubmodules().size()); + assertEquals(treeId, checker.getGitsubmodules().get(0).getTreeId()); + assertEquals(blobId, checker.getGitsubmodules().get(0).getBlobId()); + } + } + + @Test + public void testNotGitmodules() throws CorruptObjectException { + for (String notGitmodules : new String[] { + ".gitmodu", + ".gitmodules oh never mind", + }) { + checker = new ObjectChecker(); // Reset the ObjectChecker state. + checker.setSafeForWindows(true); + ObjectId treeId = ObjectId + .fromString("0123012301230123012301230123012301230123"); + StringBuilder b = new StringBuilder(); + entry(b, "100644 " + notGitmodules); + + byte[] data = encodeASCII(b.toString()); + checker.checkTree(treeId, data); + assertEquals(0, checker.getGitsubmodules().size()); + } + } + + /* + * TODO HFS: match ".gitmodules" case-insensitively, after stripping out + * certain zero-length Unicode code points that HFS+ strips out + */ + + @Test + public void testValidTreeWithGitmodulesUppercase() + throws CorruptObjectException { + ObjectId treeId = ObjectId + .fromString("0123012301230123012301230123012301230123"); + StringBuilder b = new StringBuilder(); + ObjectId blobId = entry(b, "100644 .GITMODULES"); + + byte[] data = encodeASCII(b.toString()); + checker.setSafeForWindows(true); + checker.checkTree(treeId, data); + assertEquals(1, checker.getGitsubmodules().size()); + assertEquals(treeId, checker.getGitsubmodules().get(0).getTreeId()); + assertEquals(blobId, checker.getGitsubmodules().get(0).getBlobId()); + } + + @Test + public void testTreeWithInvalidGitmodules() throws CorruptObjectException { + ObjectId treeId = ObjectId + .fromString("0123012301230123012301230123012301230123"); + StringBuilder b = new StringBuilder(); + entry(b, "100644 .gitmodulez"); + + byte[] data = encodeASCII(b.toString()); + checker.checkTree(treeId, data); + checker.setSafeForWindows(true); + assertEquals(0, checker.getGitsubmodules().size()); + } + + @Test public void testNullSha1InTreeEntry() throws CorruptObjectException { byte[] data = concat( encodeASCII("100644 A"), new byte[] { '\0' }, @@ -1551,11 +1657,20 @@ private void checkOneName(String name) throws CorruptObjectException { checker.checkTree(encodeASCII(b.toString())); } - private static void entry(StringBuilder b, final String modeName) { + /* + * Returns the id generated for the entry + */ + private static ObjectId entry(StringBuilder b, String modeName) { + byte[] id = new byte[OBJECT_ID_LENGTH]; + b.append(modeName); b.append('\0'); - for (int i = 0; i < OBJECT_ID_LENGTH; i++) + for (int i = 0; i < OBJECT_ID_LENGTH; i++) { b.append((char) i); + id[i] = (byte) i; + } + + return ObjectId.fromRaw(id); } private void assertCorrupt(String msg, int type, StringBuilder b) {
diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/lib/ObjectIdOwnerMapTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/lib/ObjectIdOwnerMapTest.java index a36a5e9..898fcb6 100644 --- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/lib/ObjectIdOwnerMapTest.java +++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/lib/ObjectIdOwnerMapTest.java
@@ -73,7 +73,7 @@ public void init() { @Test public void testEmptyMap() { - ObjectIdOwnerMap<SubId> m = new ObjectIdOwnerMap<SubId>(); + ObjectIdOwnerMap<SubId> m = new ObjectIdOwnerMap<>(); assertTrue(m.isEmpty()); assertEquals(0, m.size()); @@ -86,7 +86,7 @@ public void testEmptyMap() { @Test public void testAddGetAndContains() { - ObjectIdOwnerMap<SubId> m = new ObjectIdOwnerMap<SubId>(); + ObjectIdOwnerMap<SubId> m = new ObjectIdOwnerMap<>(); m.add(id_1); m.add(id_2); m.add(id_3); @@ -108,7 +108,7 @@ public void testAddGetAndContains() { @Test public void testClear() { - ObjectIdOwnerMap<SubId> m = new ObjectIdOwnerMap<SubId>(); + ObjectIdOwnerMap<SubId> m = new ObjectIdOwnerMap<>(); m.add(id_1); assertSame(id_1, m.get(id_1)); @@ -126,7 +126,7 @@ public void testClear() { @Test public void testAddIfAbsent() { - ObjectIdOwnerMap<SubId> m = new ObjectIdOwnerMap<SubId>(); + ObjectIdOwnerMap<SubId> m = new ObjectIdOwnerMap<>(); m.add(id_1); assertSame(id_1, m.addIfAbsent(new SubId(id_1))); @@ -145,7 +145,7 @@ public void testAddIfAbsent() { @Test public void testAddGrowsWithObjects() { int n = 16384; - ObjectIdOwnerMap<SubId> m = new ObjectIdOwnerMap<SubId>(); + ObjectIdOwnerMap<SubId> m = new ObjectIdOwnerMap<>(); m.add(id_1); for (int i = 32; i < n; i++) m.add(new SubId(id(i))); @@ -159,7 +159,7 @@ public void testAddGrowsWithObjects() { @Test public void testAddIfAbsentGrowsWithObjects() { int n = 16384; - ObjectIdOwnerMap<SubId> m = new ObjectIdOwnerMap<SubId>(); + ObjectIdOwnerMap<SubId> m = new ObjectIdOwnerMap<>(); m.add(id_1); for (int i = 32; i < n; i++) m.addIfAbsent(new SubId(id(i))); @@ -172,7 +172,7 @@ public void testAddIfAbsentGrowsWithObjects() { @Test public void testIterator() { - ObjectIdOwnerMap<SubId> m = new ObjectIdOwnerMap<SubId>(); + ObjectIdOwnerMap<SubId> m = new ObjectIdOwnerMap<>(); m.add(id_1); m.add(id_2); m.add(id_3);
diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/lib/ObjectIdSubclassMapTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/lib/ObjectIdSubclassMapTest.java index 07561de..adb2b12 100644 --- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/lib/ObjectIdSubclassMapTest.java +++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/lib/ObjectIdSubclassMapTest.java
@@ -73,7 +73,7 @@ public void init() { @Test public void testEmptyMap() { - ObjectIdSubclassMap<SubId> m = new ObjectIdSubclassMap<SubId>(); + ObjectIdSubclassMap<SubId> m = new ObjectIdSubclassMap<>(); assertTrue(m.isEmpty()); assertEquals(0, m.size()); @@ -86,7 +86,7 @@ public void testEmptyMap() { @Test public void testAddGetAndContains() { - ObjectIdSubclassMap<SubId> m = new ObjectIdSubclassMap<SubId>(); + ObjectIdSubclassMap<SubId> m = new ObjectIdSubclassMap<>(); m.add(id_1); m.add(id_2); m.add(id_3); @@ -108,7 +108,7 @@ public void testAddGetAndContains() { @Test public void testClear() { - ObjectIdSubclassMap<SubId> m = new ObjectIdSubclassMap<SubId>(); + ObjectIdSubclassMap<SubId> m = new ObjectIdSubclassMap<>(); m.add(id_1); assertSame(id_1, m.get(id_1)); @@ -126,7 +126,7 @@ public void testClear() { @Test public void testAddIfAbsent() { - ObjectIdSubclassMap<SubId> m = new ObjectIdSubclassMap<SubId>(); + ObjectIdSubclassMap<SubId> m = new ObjectIdSubclassMap<>(); m.add(id_1); assertSame(id_1, m.addIfAbsent(new SubId(id_1))); @@ -144,7 +144,7 @@ public void testAddIfAbsent() { @Test public void testAddGrowsWithObjects() { - ObjectIdSubclassMap<SubId> m = new ObjectIdSubclassMap<SubId>(); + ObjectIdSubclassMap<SubId> m = new ObjectIdSubclassMap<>(); m.add(id_1); for (int i = 32; i < 8000; i++) m.add(new SubId(id(i))); @@ -157,7 +157,7 @@ public void testAddGrowsWithObjects() { @Test public void testAddIfAbsentGrowsWithObjects() { - ObjectIdSubclassMap<SubId> m = new ObjectIdSubclassMap<SubId>(); + ObjectIdSubclassMap<SubId> m = new ObjectIdSubclassMap<>(); m.add(id_1); for (int i = 32; i < 8000; i++) m.addIfAbsent(new SubId(id(i))); @@ -170,7 +170,7 @@ public void testAddIfAbsentGrowsWithObjects() { @Test public void testIterator() { - ObjectIdSubclassMap<SubId> m = new ObjectIdSubclassMap<SubId>(); + ObjectIdSubclassMap<SubId> m = new ObjectIdSubclassMap<>(); m.add(id_1); m.add(id_2); m.add(id_3);
diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/lib/ObjectIdTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/lib/ObjectIdTest.java index 80ece1c..0adea0b 100644 --- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/lib/ObjectIdTest.java +++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/lib/ObjectIdTest.java
@@ -49,6 +49,8 @@ import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; +import java.util.Locale; + import org.eclipse.jgit.errors.InvalidObjectIdException; import org.junit.Test; @@ -122,7 +124,7 @@ public void test010_toString() { public void test011_toString() { final String x = "0123456789ABCDEFabcdef1234567890abcdefAB"; final ObjectId oid = ObjectId.fromString(x); - assertEquals(x.toLowerCase(), oid.name()); + assertEquals(x.toLowerCase(Locale.ROOT), oid.name()); } @Test(expected = InvalidObjectIdException.class)
diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/lib/RacyGitTests.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/lib/RacyGitTests.java index aa46d1a..9236b4e 100644 --- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/lib/RacyGitTests.java +++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/lib/RacyGitTests.java
@@ -51,16 +51,19 @@ import java.io.IOException; import java.util.TreeSet; +import org.eclipse.jgit.api.Git; import org.eclipse.jgit.junit.RepositoryTestCase; import org.eclipse.jgit.treewalk.FileTreeIterator; import org.eclipse.jgit.treewalk.FileTreeIteratorWithTimeControl; import org.eclipse.jgit.treewalk.NameConflictTreeWalk; import org.eclipse.jgit.util.FileUtils; +import org.junit.Test; public class RacyGitTests extends RepositoryTestCase { + @Test public void testIterator() throws IllegalStateException, IOException, InterruptedException { - TreeSet<Long> modTimes = new TreeSet<Long>(); + TreeSet<Long> modTimes = new TreeSet<>(); File lastFile = null; for (int i = 0; i < 10; i++) { lastFile = new File(db.getWorkTree(), "0." + i); @@ -121,11 +124,16 @@ public void testIterator() throws IllegalStateException, IOException, } } - public void testRacyGitDetection() throws IOException, - IllegalStateException, InterruptedException { - TreeSet<Long> modTimes = new TreeSet<Long>(); + @Test + public void testRacyGitDetection() throws Exception { + TreeSet<Long> modTimes = new TreeSet<>(); File lastFile; + // Reset to force creation of index file + try (Git git = new Git(db)) { + git.reset().call(); + } + // wait to ensure that modtimes of the file doesn't match last index // file modtime modTimes.add(valueOf(fsTick(db.getIndexFile())));
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 c88eb3b..1c21194 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
@@ -63,7 +63,7 @@ public class RefDatabaseConflictingNamesTest { @Override public Map<String, Ref> getRefs(String prefix) throws IOException { if (ALL.equals(prefix)) { - Map<String, Ref> existing = new HashMap<String, Ref>(); + Map<String, Ref> existing = new HashMap<>(); existing.put("refs/heads/a/b", null /* not used */); existing.put("refs/heads/q", null /* not used */); return existing; @@ -141,8 +141,8 @@ private void assertNoConflictingNames(String proposed) throws IOException { private void assertConflictingNames(String proposed, String... conflicts) throws IOException { - Set<String> expected = new HashSet<String>(Arrays.asList(conflicts)); + Set<String> expected = new HashSet<>(Arrays.asList(conflicts)); assertEquals(expected, - new HashSet<String>(refDatabase.getConflictingNames(proposed))); + new HashSet<>(refDatabase.getConflictingNames(proposed))); } }
diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/lib/RefTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/lib/RefTest.java index 707757b..7fb3309 100644 --- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/lib/RefTest.java +++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/lib/RefTest.java
@@ -99,7 +99,7 @@ public void testRemoteNames() throws Exception { "ab/c", "dummy", true); config.save(); assertEquals("[ab/c, origin]", - new TreeSet<String>(db.getRemoteNames()).toString()); + new TreeSet<>(db.getRemoteNames()).toString()); // one-level deep remote branch assertEquals("master",
diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/lib/RepositoryCacheTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/lib/RepositoryCacheTest.java index b44b4c3..1107c2c 100644 --- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/lib/RepositoryCacheTest.java +++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/lib/RepositoryCacheTest.java
@@ -109,7 +109,7 @@ public void testFileKeyOpenExisting() throws IOException { @Test public void testFileKeyOpenNew() throws IOException { - final Repository n = createBareRepository(); + final Repository n = createRepository(true, false); final File gitdir = n.getDirectory(); n.close(); recursiveDelete(gitdir); @@ -187,12 +187,14 @@ public void testRepositoryUsageCount() throws Exception { } @Test - public void testRepositoryUsageCountWithRegisteredRepository() { - assertEquals(1, ((Repository) db).useCnt.get()); - RepositoryCache.register(db); - assertEquals(1, ((Repository) db).useCnt.get()); - db.close(); - assertEquals(0, ((Repository) db).useCnt.get()); + public void testRepositoryUsageCountWithRegisteredRepository() + throws IOException { + Repository repo = createRepository(false, false); + assertEquals(1, repo.useCnt.get()); + RepositoryCache.register(repo); + assertEquals(1, repo.useCnt.get()); + repo.close(); + assertEquals(0, repo.useCnt.get()); } @Test @@ -232,8 +234,8 @@ public void testRepositoryUnregisteringWhenExpiredAndUsageCountNegative() @Test public void testRepositoryUnregisteringWhenExpired() throws Exception { - Repository repoA = createBareRepository(); - Repository repoB = createBareRepository(); + Repository repoA = createRepository(true, false); + Repository repoB = createRepository(true, false); Repository repoC = createBareRepository(); RepositoryCache.register(repoA); RepositoryCache.register(repoB); @@ -265,11 +267,12 @@ public void testRepositoryUnregisteringWhenExpired() throws Exception { } @Test - public void testReconfigure() throws InterruptedException { - RepositoryCache.register(db); - assertTrue(RepositoryCache.isCached(db)); - db.close(); - assertTrue(RepositoryCache.isCached(db)); + public void testReconfigure() throws InterruptedException, IOException { + Repository repo = createRepository(false, false); + RepositoryCache.register(repo); + assertTrue(RepositoryCache.isCached(repo)); + repo.close(); + assertTrue(RepositoryCache.isCached(repo)); // Actually, we would only need to validate that // WorkQueue.getExecutor().scheduleWithFixedDelay is called with proper @@ -287,7 +290,7 @@ public void testReconfigure() throws InterruptedException { // This wait will time out after 2048 ms for (int i = 0; i <= 10; i++) { Thread.sleep(1 << i); - if (!RepositoryCache.isCached(db)) { + if (!RepositoryCache.isCached(repo)) { return; } }
diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/lib/ThreadSafeProgressMonitorTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/lib/ThreadSafeProgressMonitorTest.java index 2845f8a..545a188 100644 --- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/lib/ThreadSafeProgressMonitorTest.java +++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/lib/ThreadSafeProgressMonitorTest.java
@@ -62,6 +62,7 @@ public void testFailsMethodsOnBackgroundThread() final ThreadSafeProgressMonitor pm = new ThreadSafeProgressMonitor(mock); runOnThread(new Runnable() { + @Override public void run() { try { pm.start(1); @@ -128,6 +129,7 @@ public void testUpdateOnBackgroundThreads() throws InterruptedException { final CountDownLatch doEndWorker = new CountDownLatch(1); final Thread bg = new Thread() { + @Override public void run() { assertFalse(pm.isCancelled()); @@ -175,24 +177,29 @@ private static class MockProgressMonitor implements ProgressMonitor { int value; + @Override public void update(int completed) { value += completed; } + @Override public void start(int totalTasks) { value = totalTasks; } + @Override public void beginTask(String title, int totalWork) { taskTitle = title; value = totalWork; } + @Override public void endTask() { taskTitle = null; value = 0; } + @Override public boolean isCancelled() { return false; }
diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/lib/ValidRefNameTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/lib/ValidRefNameTest.java index e9d46bb..d431a89 100644 --- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/lib/ValidRefNameTest.java +++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/lib/ValidRefNameTest.java
@@ -44,6 +44,7 @@ package org.eclipse.jgit.lib; import static org.eclipse.jgit.junit.Assert.assertEquals; +import static org.junit.Assert.assertEquals; import org.eclipse.jgit.junit.MockSystemReader; import org.eclipse.jgit.util.SystemReader; @@ -94,6 +95,25 @@ private static void assertInvalidOnWindows(final String name) { } } + private static void assertNormalized(final String name, + final String expected) { + SystemReader instance = SystemReader.getInstance(); + try { + setUnixSystemReader(); + String normalized = Repository.normalizeBranchName(name); + assertEquals("Normalization of " + name, expected, normalized); + assertEquals("\"" + normalized + "\"", true, + Repository.isValidRefName(Constants.R_HEADS + normalized)); + setWindowsSystemReader(); + normalized = Repository.normalizeBranchName(name); + assertEquals("Normalization of " + name, expected, normalized); + assertEquals("\"" + normalized + "\"", true, + Repository.isValidRefName(Constants.R_HEADS + normalized)); + } finally { + SystemReader.setInstance(instance); + } + } + @Test public void testEmptyString() { assertValid(false, ""); @@ -247,4 +267,59 @@ public void testWindowsReservedNames() { assertValid(true, "refs/heads/conx"); assertValid(true, "refs/heads/xcon"); } + + @Test + public void testNormalizeBranchName() { + assertEquals(true, Repository.normalizeBranchName(null) == ""); + assertEquals(true, Repository.normalizeBranchName("").equals("")); + assertNormalized("Bug 12345::::Hello World", "Bug_12345-Hello_World"); + assertNormalized("Bug 12345 :::: Hello World", "Bug_12345_Hello_World"); + assertNormalized("Bug 12345 :::: Hello::: World", + "Bug_12345_Hello-World"); + assertNormalized(":::Bug 12345 - Hello World", "Bug_12345_Hello_World"); + assertNormalized("---Bug 12345 - Hello World", "Bug_12345_Hello_World"); + assertNormalized("Bug 12345 ---- Hello --- World", + "Bug_12345_Hello_World"); + assertNormalized("Bug 12345 - Hello World!", "Bug_12345_Hello_World!"); + assertNormalized("Bug 12345 : Hello World!", "Bug_12345_Hello_World!"); + assertNormalized("Bug 12345 _ Hello World!", "Bug_12345_Hello_World!"); + assertNormalized("Bug 12345 - Hello World!", + "Bug_12345_Hello_World!"); + assertNormalized(" Bug 12345 - Hello World! ", + "Bug_12345_Hello_World!"); + assertNormalized(" Bug 12345 - Hello World! ", + "Bug_12345_Hello_World!"); + assertNormalized("Bug 12345 - Hello______ World!", + "Bug_12345_Hello_World!"); + assertNormalized("_Bug 12345 - Hello World!", "Bug_12345_Hello_World!"); + } + + @Test + public void testNormalizeWithSlashes() { + assertNormalized("foo/bar/baz", "foo/bar/baz"); + assertNormalized("foo/bar.lock/baz.lock", "foo/bar_lock/baz_lock"); + assertNormalized("foo/.git/.git~1/bar", "foo/git/git-1/bar"); + assertNormalized(".foo/aux/con/com3.txt/com0/prn/lpt1", + "foo/+aux/+con/+com3.txt/com0/+prn/+lpt1"); + assertNormalized("foo/../bar///.--ba...z", "foo/bar/ba.z"); + } + + @Test + public void testNormalizeWithUnicode() { + assertNormalized("f\u00f6\u00f6/.b\u00e0r/*[<>|^~/b\u00e9\\z", + "f\u00f6\u00f6/b\u00e0r/b\u00e9-z"); + assertNormalized("\u5165\u53e3 entrance;/.\u51fa\u53e3_*ex*it*/", + "\u5165\u53e3_entrance;/\u51fa\u53e3_ex-it"); + } + + @Test + public void testNormalizeAlreadyValidRefName() { + assertNormalized("refs/heads/m.a.s.t.e.r", "refs/heads/m.a.s.t.e.r"); + assertNormalized("refs/tags/v1.0-20170223", "refs/tags/v1.0-20170223"); + } + + @Test + public void testNormalizeTrimmedUnicodeAlreadyValidRefName() { + assertNormalized(" \u00e5ngstr\u00f6m\t", "\u00e5ngstr\u00f6m"); + } }
diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/merge/RecursiveMergerTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/merge/RecursiveMergerTest.java index 0e7109c..039a6e8 100644 --- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/merge/RecursiveMergerTest.java +++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/merge/RecursiveMergerTest.java
@@ -110,7 +110,7 @@ public enum WorktreeState { @Before public void setUp() throws Exception { super.setUp(); - db_t = new TestRepository<FileRepository>(db); + db_t = new TestRepository<>(db); } @Theory @@ -778,7 +778,7 @@ void modifyIndex(IndexState indexState, String path, String other) db.close(); file.delete(); db = new FileRepository(db.getDirectory()); - db_t = new TestRepository<FileRepository>(db); + db_t = new TestRepository<>(db); break; } } @@ -846,7 +846,7 @@ void modifyWorktree(WorktreeState worktreeState, String path, String other) db.getConfig().setBoolean("core", null, "bare", true); db.getDirectory().renameTo(new File(workTreeFile, "test.git")); db = new FileRepository(new File(workTreeFile, "test.git")); - db_t = new TestRepository<FileRepository>(db); + db_t = new TestRepository<>(db); } } finally { if (fos != null)
diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/nls/NLSTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/nls/NLSTest.java index a74ea98..65f2d09 100644 --- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/nls/NLSTest.java +++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/nls/NLSTest.java
@@ -123,6 +123,7 @@ class GetBundle implements Callable<TranslationBundle> { this.locale = locale; } + @Override public TranslationBundle call() throws Exception { NLS.setLocale(locale); barrier.await(); // wait for the other thread to set its locale
diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/notes/DefaultNoteMergerTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/notes/DefaultNoteMergerTest.java index d3a6f18..a8d3904 100644 --- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/notes/DefaultNoteMergerTest.java +++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/notes/DefaultNoteMergerTest.java
@@ -75,7 +75,7 @@ public class DefaultNoteMergerTest extends RepositoryTestCase { @Before public void setUp() throws Exception { super.setUp(); - tr = new TestRepository<Repository>(db); + tr = new TestRepository<>(db); reader = db.newObjectReader(); inserter = db.newObjectInserter(); merger = new DefaultNoteMerger();
diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/notes/NoteMapMergerTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/notes/NoteMapMergerTest.java index be7bead..117ea0c 100644 --- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/notes/NoteMapMergerTest.java +++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/notes/NoteMapMergerTest.java
@@ -97,7 +97,7 @@ public class NoteMapMergerTest extends RepositoryTestCase { @Before public void setUp() throws Exception { super.setUp(); - tr = new TestRepository<Repository>(db); + tr = new TestRepository<>(db); reader = db.newObjectReader(); inserter = db.newObjectInserter();
diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/notes/NoteMapTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/notes/NoteMapTest.java index 325c9e2..a4a4909 100644 --- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/notes/NoteMapTest.java +++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/notes/NoteMapTest.java
@@ -83,7 +83,7 @@ public class NoteMapTest extends RepositoryTestCase { public void setUp() throws Exception { super.setUp(); - tr = new TestRepository<Repository>(db); + tr = new TestRepository<>(db); reader = db.newObjectReader(); inserter = db.newObjectInserter(); }
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 d32172a..f265315 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
@@ -96,7 +96,7 @@ private PlotCommitList<PlotLane> createCommitList(ObjectId start) throws IOException { TestPlotWalk walk = new TestPlotWalk(db); walk.markStart(walk.parseCommit(start)); - PlotCommitList<PlotLane> commitList = new PlotCommitList<PlotLane>(); + PlotCommitList<PlotLane> commitList = new PlotCommitList<>(); commitList.source(walk); commitList.fillTo(1000); return commitList; @@ -116,7 +116,7 @@ public TestPlotWalk(Repository repo) { private static class TestPlotRenderer extends AbstractPlotRenderer<PlotLane, Object> { - List<Integer> indentations = new LinkedList<Integer>(); + List<Integer> indentations = new LinkedList<>(); @Override protected int drawLabel(int x, int y, Ref ref) {
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 ecc119b..9a6043f 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
@@ -123,7 +123,7 @@ public CommitListAssert noMoreCommits() { } private static Set<Integer> asSet(int... numbers) { - Set<Integer> result = new HashSet<Integer>(); + Set<Integer> result = new HashSet<>(); for (int n : numbers) result.add(Integer.valueOf(n)); return result; @@ -138,7 +138,7 @@ public void testLinear() throws Exception { PlotWalk pw = new PlotWalk(db); pw.markStart(pw.lookupCommit(c.getId())); - PlotCommitList<PlotLane> pcl = new PlotCommitList<PlotLane>(); + PlotCommitList<PlotLane> pcl = new PlotCommitList<>(); pcl.source(pw); pcl.fillTo(Integer.MAX_VALUE); @@ -159,7 +159,7 @@ public void testMerged() throws Exception { PlotWalk pw = new PlotWalk(db); pw.markStart(pw.lookupCommit(d.getId())); - PlotCommitList<PlotLane> pcl = new PlotCommitList<PlotLane>(); + PlotCommitList<PlotLane> pcl = new PlotCommitList<>(); pcl.source(pw); pcl.fillTo(Integer.MAX_VALUE); @@ -181,7 +181,7 @@ public void testSideBranch() throws Exception { pw.markStart(pw.lookupCommit(b.getId())); pw.markStart(pw.lookupCommit(c.getId())); - PlotCommitList<PlotLane> pcl = new PlotCommitList<PlotLane>(); + PlotCommitList<PlotLane> pcl = new PlotCommitList<>(); pcl.source(pw); pcl.fillTo(Integer.MAX_VALUE); @@ -205,7 +205,7 @@ public void test2SideBranches() throws Exception { pw.markStart(pw.lookupCommit(c.getId())); pw.markStart(pw.lookupCommit(d.getId())); - PlotCommitList<PlotLane> pcl = new PlotCommitList<PlotLane>(); + PlotCommitList<PlotLane> pcl = new PlotCommitList<>(); pcl.source(pw); pcl.fillTo(Integer.MAX_VALUE); @@ -240,7 +240,7 @@ public void testBug300282_1() throws Exception { // pw.markStart(pw.lookupCommit(f.getId())); pw.markStart(pw.lookupCommit(g.getId())); - PlotCommitList<PlotLane> pcl = new PlotCommitList<PlotLane>(); + PlotCommitList<PlotLane> pcl = new PlotCommitList<>(); pcl.source(pw); pcl.fillTo(Integer.MAX_VALUE); @@ -274,7 +274,7 @@ public void testBug368927() throws Exception { pw.markStart(pw.lookupCommit(i.getId())); pw.markStart(pw.lookupCommit(g.getId())); - PlotCommitList<PlotLane> pcl = new PlotCommitList<PlotLane>(); + PlotCommitList<PlotLane> pcl = new PlotCommitList<>(); pcl.source(pw); pcl.fillTo(Integer.MAX_VALUE); Set<Integer> childPositions = asSet(0, 1); @@ -333,7 +333,7 @@ public void testEgitHistory() throws Exception { PlotWalk pw = new PlotWalk(db); pw.markStart(pw.lookupCommit(merge_fixed_logged_npe.getId())); - PlotCommitList<PlotLane> pcl = new PlotCommitList<PlotLane>(); + PlotCommitList<PlotLane> pcl = new PlotCommitList<>(); pcl.source(pw); pcl.fillTo(Integer.MAX_VALUE); @@ -406,7 +406,7 @@ public void testDuplicateParents() throws Exception { PlotWalk pw = new PlotWalk(db); pw.markStart(pw.lookupCommit(m3)); pw.markStart(pw.lookupCommit(s2)); - PlotCommitList<PlotLane> pcl = new PlotCommitList<PlotLane>(); + PlotCommitList<PlotLane> pcl = new PlotCommitList<>(); pcl.source(pw); pcl.fillTo(Integer.MAX_VALUE); @@ -471,7 +471,7 @@ public void testBug419359() throws Exception { pw.markStart(pw.lookupCommit(e.getId())); pw.markStart(pw.lookupCommit(a5.getId())); - PlotCommitList<PlotLane> pcl = new PlotCommitList<PlotLane>(); + PlotCommitList<PlotLane> pcl = new PlotCommitList<>(); pcl.source(pw); pcl.fillTo(Integer.MAX_VALUE); @@ -520,7 +520,7 @@ public void testMultipleMerges() throws Exception { PlotWalk pw = new PlotWalk(db); pw.markStart(pw.lookupCommit(a4)); pw.markStart(pw.lookupCommit(b3)); - PlotCommitList<PlotLane> pcl = new PlotCommitList<PlotLane>(); + PlotCommitList<PlotLane> pcl = new PlotCommitList<>(); pcl.source(pw); pcl.fillTo(Integer.MAX_VALUE); @@ -565,7 +565,7 @@ public void testMergeBlockedBySelf() throws Exception { PlotWalk pw = new PlotWalk(db); pw.markStart(pw.lookupCommit(a4)); pw.markStart(pw.lookupCommit(b3)); - PlotCommitList<PlotLane> pcl = new PlotCommitList<PlotLane>(); + PlotCommitList<PlotLane> pcl = new PlotCommitList<>(); pcl.source(pw); pcl.fillTo(Integer.MAX_VALUE); @@ -615,7 +615,7 @@ public void testMergeBlockedByOther() throws Exception { pw.markStart(pw.lookupCommit(a4)); pw.markStart(pw.lookupCommit(b2)); pw.markStart(pw.lookupCommit(c)); - PlotCommitList<PlotLane> pcl = new PlotCommitList<PlotLane>(); + PlotCommitList<PlotLane> pcl = new PlotCommitList<>(); pcl.source(pw); pcl.fillTo(Integer.MAX_VALUE); @@ -654,7 +654,7 @@ public void testDanglingCommitShouldContinueLane() throws Exception { PlotWalk pw = new PlotWalk(db); pw.markStart(pw.lookupCommit(a3)); pw.markStart(pw.lookupCommit(b1)); - PlotCommitList<PlotLane> pcl = new PlotCommitList<PlotLane>(); + PlotCommitList<PlotLane> pcl = new PlotCommitList<>(); pcl.source(pw); pcl.fillTo(2); // don't process a1 @@ -677,7 +677,7 @@ public void testTwoRoots1() throws Exception { PlotWalk pw = new PlotWalk(db); pw.markStart(pw.lookupCommit(a)); pw.markStart(pw.lookupCommit(b)); - PlotCommitList<PlotLane> pcl = new PlotCommitList<PlotLane>(); + PlotCommitList<PlotLane> pcl = new PlotCommitList<>(); pcl.source(pw); pcl.fillTo(Integer.MAX_VALUE); @@ -696,7 +696,7 @@ public void testTwoRoots2() throws Exception { PlotWalk pw = new PlotWalk(db); pw.markStart(pw.lookupCommit(a)); pw.markStart(pw.lookupCommit(b2)); - PlotCommitList<PlotLane> pcl = new PlotCommitList<PlotLane>(); + PlotCommitList<PlotLane> pcl = new PlotCommitList<>(); pcl.source(pw); pcl.fillTo(Integer.MAX_VALUE);
diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/revwalk/DateRevQueueTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/revwalk/DateRevQueueTest.java index 766a279..e5e51f7 100644 --- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/revwalk/DateRevQueueTest.java +++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/revwalk/DateRevQueueTest.java
@@ -50,10 +50,12 @@ import org.junit.Test; public class DateRevQueueTest extends RevQueueTestCase<DateRevQueue> { + @Override protected DateRevQueue create() { return new DateRevQueue(); } + @Override @Test public void testEmpty() throws Exception { super.testEmpty();
diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/revwalk/FIFORevQueueTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/revwalk/FIFORevQueueTest.java index 8877c38..a280045 100644 --- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/revwalk/FIFORevQueueTest.java +++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/revwalk/FIFORevQueueTest.java
@@ -52,10 +52,12 @@ import org.junit.Test; public class FIFORevQueueTest extends RevQueueTestCase<FIFORevQueue> { + @Override protected FIFORevQueue create() { return new FIFORevQueue(); } + @Override @Test public void testEmpty() throws Exception { super.testEmpty(); @@ -70,7 +72,7 @@ public void testCloneEmpty() throws Exception { @Test public void testAddLargeBlocks() throws Exception { - final ArrayList<RevCommit> lst = new ArrayList<RevCommit>(); + final ArrayList<RevCommit> lst = new ArrayList<>(); for (int i = 0; i < 3 * BlockRevQueue.Block.BLOCK_SIZE; i++) { final RevCommit c = commit(); lst.add(c);
diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/revwalk/LIFORevQueueTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/revwalk/LIFORevQueueTest.java index 1b2c5e2..ed8bc70 100644 --- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/revwalk/LIFORevQueueTest.java +++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/revwalk/LIFORevQueueTest.java
@@ -53,10 +53,12 @@ import org.junit.Test; public class LIFORevQueueTest extends RevQueueTestCase<LIFORevQueue> { + @Override protected LIFORevQueue create() { return new LIFORevQueue(); } + @Override @Test public void testEmpty() throws Exception { super.testEmpty(); @@ -71,7 +73,7 @@ public void testCloneEmpty() throws Exception { @Test public void testAddLargeBlocks() throws Exception { - final ArrayList<RevCommit> lst = new ArrayList<RevCommit>(); + final ArrayList<RevCommit> lst = new ArrayList<>(); for (int i = 0; i < 3 * BlockRevQueue.Block.BLOCK_SIZE; i++) { final RevCommit c = commit(); lst.add(c);
diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/revwalk/RevCommitListTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/revwalk/RevCommitListTest.java index 4d75322..c069ba8 100644 --- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/revwalk/RevCommitListTest.java +++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/revwalk/RevCommitListTest.java
@@ -62,7 +62,7 @@ public void setup(int count) throws Exception { for (int i = 0; i < count; i++) git.commit().setCommitter(committer).setAuthor(author) .setMessage("commit " + i).call(); - list = new RevCommitList<RevCommit>(); + list = new RevCommitList<>(); w.markStart(w.lookupCommit(db.resolve(Constants.HEAD))); list.source(w); }
diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/revwalk/RevFlagSetTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/revwalk/RevFlagSetTest.java index 154fcdf..2b5fc00 100644 --- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/revwalk/RevFlagSetTest.java +++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/revwalk/RevFlagSetTest.java
@@ -146,6 +146,5 @@ public void testContains() { set.add(flag1); assertTrue(set.contains(flag1)); assertFalse(set.contains(flag2)); - assertFalse(set.contains("bob")); } }
diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/revwalk/RevQueueTestCase.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/revwalk/RevQueueTestCase.java index 51cf2f1..bedbedd 100644 --- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/revwalk/RevQueueTestCase.java +++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/revwalk/RevQueueTestCase.java
@@ -53,6 +53,7 @@ public abstract class RevQueueTestCase<T extends AbstractRevQueue> extends RevWalkTestCase { protected T q; + @Override public void setUp() throws Exception { super.setUp(); q = create();
diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/revwalk/RevWalkFollowFilterTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/revwalk/RevWalkFollowFilterTest.java index 05e552e..1860185 100644 --- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/revwalk/RevWalkFollowFilterTest.java +++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/revwalk/RevWalkFollowFilterTest.java
@@ -58,7 +58,7 @@ public class RevWalkFollowFilterTest extends RevWalkTestCase { private static class DiffCollector extends RenameCallback { - List<DiffEntry> diffs = new ArrayList<DiffEntry>(); + List<DiffEntry> diffs = new ArrayList<>(); @Override public void renamed(DiffEntry diff) {
diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/revwalk/RevWalkPathFilter6012Test.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/revwalk/RevWalkPathFilter6012Test.java index db19f00..631e395 100644 --- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/revwalk/RevWalkPathFilter6012Test.java +++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/revwalk/RevWalkPathFilter6012Test.java
@@ -69,6 +69,7 @@ public class RevWalkPathFilter6012Test extends RevWalkTestCase { private HashMap<RevCommit, String> byName; + @Override @Before public void setUp() throws Exception { super.setUp(); @@ -94,7 +95,7 @@ public void setUp() throws Exception { h = commit(f.getTree(), g, f); i = commit(tree(file(pA, zS), file(pE, zY), file(pF, zF)), h); - byName = new HashMap<RevCommit, String>(); + byName = new HashMap<>(); for (Field z : RevWalkPathFilter6012Test.class.getDeclaredFields()) { if (z.getType() == RevCommit.class) byName.put((RevCommit) z.get(this), z.getName());
diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/revwalk/RevWalkTestCase.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/revwalk/RevWalkTestCase.java index 30586ee..f12cc08 100644 --- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/revwalk/RevWalkTestCase.java +++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/revwalk/RevWalkTestCase.java
@@ -62,7 +62,7 @@ public abstract class RevWalkTestCase extends RepositoryTestCase { @Override public void setUp() throws Exception { super.setUp(); - util = new TestRepository<Repository>(db, createRevWalk()); + util = new TestRepository<>(db, createRevWalk()); rw = util.getRevWalk(); }
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 a131e5e..93f4709 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
@@ -161,6 +161,7 @@ public void addExistentSubmodule() throws Exception { DirCacheEditor editor = cache.editor(); editor.add(new PathEdit(path) { + @Override public void apply(DirCacheEntry ent) { ent.setFileMode(FileMode.GITLINK); ent.setObjectId(id); @@ -182,6 +183,37 @@ public void apply(DirCacheEntry ent) { } @Test + public void addSubmoduleWithInvalidPath() throws Exception { + SubmoduleAddCommand command = new SubmoduleAddCommand(db); + command.setPath("-invalid-path"); + // TODO(ms) set name to a valid value in 5.1.0 and adapt expected + // message below + command.setURI("http://example.com/repo/x.git"); + try { + command.call().close(); + fail("Exception not thrown"); + } catch (IllegalArgumentException e) { + // TODO(ms) should check for submodule path, but can't set name + // before 5.1.0 + assertEquals("Invalid submodule name '-invalid-path'", + e.getMessage()); + } + } + + @Test + public void addSubmoduleWithInvalidUri() throws Exception { + SubmoduleAddCommand command = new SubmoduleAddCommand(db); + command.setPath("valid-path"); + command.setURI("-upstream"); + try { + command.call().close(); + fail("Exception not thrown"); + } catch (IllegalArgumentException e) { + assertEquals("Invalid submodule URL '-upstream'", e.getMessage()); + } + } + + @Test public void addSubmoduleWithRelativeUri() throws Exception { try (Git git = new Git(db)) { writeTrashFile("file.txt", "content"); @@ -268,4 +300,4 @@ public void addSubmoduleWithExistingSubmoduleDefined() throws Exception { ConfigConstants.CONFIG_KEY_URL)); } } -} \ No newline at end of file +}
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 2b46498..c7a009c 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
@@ -321,6 +321,7 @@ private String addSubmoduleToIndex() throws IOException { DirCacheEditor editor = cache.editor(); editor.add(new PathEdit(path) { + @Override public void apply(DirCacheEntry ent) { ent.setFileMode(FileMode.GITLINK); ent.setObjectId(id);
diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/submodule/SubmoduleStatusTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/submodule/SubmoduleStatusTest.java index 51c180c..61df9d9 100644 --- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/submodule/SubmoduleStatusTest.java +++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/submodule/SubmoduleStatusTest.java
@@ -92,6 +92,7 @@ public void repositoryWithMissingSubmodule() throws IOException, DirCacheEditor editor = cache.editor(); editor.add(new PathEdit(path) { + @Override public void apply(DirCacheEntry ent) { ent.setFileMode(FileMode.GITLINK); ent.setObjectId(id); @@ -124,6 +125,7 @@ public void repositoryWithUninitializedSubmodule() throws IOException, DirCacheEditor editor = cache.editor(); editor.add(new PathEdit(path) { + @Override public void apply(DirCacheEntry ent) { ent.setFileMode(FileMode.GITLINK); ent.setObjectId(id); @@ -164,6 +166,7 @@ public void repositoryWithNoHeadInSubmodule() throws IOException, DirCacheEditor editor = cache.editor(); editor.add(new PathEdit(path) { + @Override public void apply(DirCacheEntry ent) { ent.setFileMode(FileMode.GITLINK); ent.setObjectId(id); @@ -215,6 +218,7 @@ public void repositoryWithNoSubmoduleRepository() throws IOException, DirCacheEditor editor = cache.editor(); editor.add(new PathEdit(path) { + @Override public void apply(DirCacheEntry ent) { ent.setFileMode(FileMode.GITLINK); ent.setObjectId(id); @@ -261,6 +265,7 @@ public void repositoryWithInitializedSubmodule() throws IOException, DirCacheEditor editor = cache.editor(); editor.add(new PathEdit(path) { + @Override public void apply(DirCacheEntry ent) { ent.setFileMode(FileMode.GITLINK); ent.setObjectId(id); @@ -316,6 +321,7 @@ public void repositoryWithDifferentRevCheckedOutSubmodule() DirCacheEditor editor = cache.editor(); editor.add(new PathEdit(path) { + @Override public void apply(DirCacheEntry ent) { ent.setFileMode(FileMode.GITLINK); ent.setObjectId(id);
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 54a6f77..13db44a 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
@@ -95,6 +95,7 @@ public void repositoryWithSubmodule() throws Exception { DirCacheEditor editor = cache.editor(); editor.add(new PathEdit(path) { + @Override public void apply(DirCacheEntry ent) { ent.setFileMode(FileMode.GITLINK); ent.setObjectId(id); @@ -156,6 +157,7 @@ public void repositoryWithRelativeUriSubmodule() throws Exception { DirCacheEditor editor = cache.editor(); editor.add(new PathEdit(path) { + @Override public void apply(DirCacheEntry ent) { ent.setFileMode(FileMode.GITLINK); ent.setObjectId(id);
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 bcdd5e2..7064f60 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
@@ -93,6 +93,7 @@ public void repositoryWithSubmodule() throws Exception { DirCacheEditor editor = cache.editor(); editor.add(new PathEdit(path) { + @Override public void apply(DirCacheEntry ent) { ent.setFileMode(FileMode.GITLINK); ent.setObjectId(commit); @@ -136,6 +137,7 @@ public void repositoryWithUnconfiguredSubmodule() throws IOException, DirCacheEditor editor = cache.editor(); editor.add(new PathEdit(path) { + @Override public void apply(DirCacheEntry ent) { ent.setFileMode(FileMode.GITLINK); ent.setObjectId(id); @@ -171,6 +173,7 @@ public void repositoryWithInitializedSubmodule() throws IOException, DirCacheEditor editor = cache.editor(); editor.add(new PathEdit(path) { + @Override public void apply(DirCacheEntry ent) { ent.setFileMode(FileMode.GITLINK); ent.setObjectId(id);
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 72b4611..8998a85 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
@@ -87,10 +87,11 @@ public class SubmoduleWalkTest extends RepositoryTestCase { private TestRepository<Repository> testDb; + @Override @Before public void setUp() throws Exception { super.setUp(); - testDb = new TestRepository<Repository>(db); + testDb = new TestRepository<>(db); } @Test @@ -118,6 +119,7 @@ public void repositoryWithRootLevelSubmodule() throws IOException, DirCacheEditor editor = cache.editor(); editor.add(new PathEdit(path) { + @Override public void apply(DirCacheEntry ent) { ent.setFileMode(FileMode.GITLINK); ent.setObjectId(id); @@ -165,6 +167,7 @@ public void repositoryWithRootLevelSubmoduleAbsoluteRef() DirCacheEditor editor = cache.editor(); editor.add(new PathEdit(path) { + @Override public void apply(DirCacheEntry ent) { ent.setFileMode(FileMode.GITLINK); ent.setObjectId(id); @@ -217,6 +220,7 @@ public void repositoryWithRootLevelSubmoduleRelativeRef() DirCacheEditor editor = cache.editor(); editor.add(new PathEdit(path) { + @Override public void apply(DirCacheEntry ent) { ent.setFileMode(FileMode.GITLINK); ent.setObjectId(id); @@ -253,6 +257,7 @@ public void repositoryWithNestedSubmodule() throws IOException, DirCacheEditor editor = cache.editor(); editor.add(new PathEdit(path) { + @Override public void apply(DirCacheEntry ent) { ent.setFileMode(FileMode.GITLINK); ent.setObjectId(id); @@ -286,6 +291,7 @@ public void generatorFilteredToOneOfTwoSubmodules() throws IOException { DirCacheEditor editor = cache.editor(); editor.add(new PathEdit(path1) { + @Override public void apply(DirCacheEntry ent) { ent.setFileMode(FileMode.GITLINK); ent.setObjectId(id1); @@ -293,6 +299,7 @@ public void apply(DirCacheEntry ent) { }); editor.add(new PathEdit(path2) { + @Override public void apply(DirCacheEntry ent) { ent.setFileMode(FileMode.GITLINK); ent.setObjectId(id2); @@ -330,6 +337,7 @@ public void indexWithGitmodules() throws Exception { DirCacheEditor editor = cache.editor(); editor.add(new PathEdit(path) { + @Override public void apply(DirCacheEntry ent) { ent.setFileMode(FileMode.GITLINK); ent.setObjectId(subId); @@ -337,6 +345,7 @@ public void apply(DirCacheEntry ent) { }); editor.add(new PathEdit(DOT_GIT_MODULES) { + @Override public void apply(DirCacheEntry ent) { ent.setFileMode(FileMode.REGULAR_FILE); ent.setObjectId(gitmodulesBlob); @@ -375,6 +384,7 @@ public void treeIdWithGitmodules() throws Exception { .add(DOT_GIT_MODULES, gitmodules.toText()) .edit(new PathEdit(path) { + @Override public void apply(DirCacheEntry ent) { ent.setFileMode(FileMode.GITLINK); ent.setObjectId(subId); @@ -412,6 +422,7 @@ public void testTreeIteratorWithGitmodules() throws Exception { .add(DOT_GIT_MODULES, gitmodules.toText()) .edit(new PathEdit(path) { + @Override public void apply(DirCacheEntry ent) { ent.setFileMode(FileMode.GITLINK); ent.setObjectId(subId);
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 3dc022d..ea15ebe 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
@@ -113,7 +113,7 @@ private static String getAuthMethodName(HttpAuthMethod authMethod) { } private static class AuthHeadersResponse extends JDKHttpConnection { - Map<String, List<String>> headerFields = new HashMap<String, List<String>>(); + Map<String, List<String>> headerFields = new HashMap<>(); public AuthHeadersResponse(String[] authHeaders) throws MalformedURLException, IOException {
diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/transport/LongMapTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/transport/LongMapTest.java index 3e427e5..1a86aaf 100644 --- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/transport/LongMapTest.java +++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/transport/LongMapTest.java
@@ -57,7 +57,7 @@ public class LongMapTest { @Before public void setUp() throws Exception { - map = new LongMap<Long>(); + map = new LongMap<>(); } @Test
diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/transport/NetRCTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/transport/NetRCTest.java index ba44950..2fea8a9 100644 --- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/transport/NetRCTest.java +++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/transport/NetRCTest.java
@@ -62,6 +62,7 @@ public class NetRCTest extends RepositoryTestCase { private File configFile; + @Override @Before public void setUp() throws Exception { super.setUp();
diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/transport/OpenSshConfigTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/transport/OpenSshConfigTest.java index 8ec39bf..fc520ab 100644 --- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/transport/OpenSshConfigTest.java +++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/transport/OpenSshConfigTest.java
@@ -68,6 +68,7 @@ public class OpenSshConfigTest extends RepositoryTestCase { private OpenSshConfig osc; + @Override @Before public void setUp() throws Exception { super.setUp();
diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/transport/PackParserTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/transport/PackParserTest.java index c829be9..b2497b8 100644 --- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/transport/PackParserTest.java +++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/transport/PackParserTest.java
@@ -169,7 +169,7 @@ public void testTinyThinPack() throws Exception { @Test public void testPackWithDuplicateBlob() throws Exception { final byte[] data = Constants.encode("0123456789abcdefg"); - TestRepository<Repository> d = new TestRepository<Repository>(db); + TestRepository<Repository> d = new TestRepository<>(db); assertTrue(db.hasObject(d.blob(data))); TemporaryBuffer.Heap pack = new TemporaryBuffer.Heap(1024);
diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/transport/PushConnectionTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/transport/PushConnectionTest.java index 33a9105..0e4e9cc 100644 --- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/transport/PushConnectionTest.java +++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/transport/PushConnectionTest.java
@@ -173,4 +173,27 @@ public void invalidCommand() throws IOException { } } } + + @Test + public void limitCommandBytes() throws IOException { + Map<String, RemoteRefUpdate> updates = new HashMap<>(); + for (int i = 0; i < 4; i++) { + RemoteRefUpdate rru = new RemoteRefUpdate( + null, null, obj2, "refs/test/T" + i, + false, null, ObjectId.zeroId()); + updates.put(rru.getRemoteName(), rru); + } + + server.getConfig().setInt("receive", null, "maxCommandBytes", 190); + try (Transport tn = testProtocol.open(uri, client, "server"); + PushConnection connection = tn.openPush()) { + try { + connection.push(NullProgressMonitor.INSTANCE, updates); + fail("server did not abort"); + } catch (TransportException e) { + String msg = e.getMessage(); + assertEquals("remote: Too many commands", msg); + } + } + } }
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 c346d79..f26201d 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
@@ -86,6 +86,7 @@ public class PushOptionsTest extends RepositoryTestCase { private ObjectId obj2; private ReceivePack receivePack; + @Override @Before public void setUp() throws Exception { super.setUp(); @@ -115,6 +116,7 @@ public ReceivePack create(Object req, Repository git) } } + @Override @After public void tearDown() { Transport.unregister(testProtocol);
diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/transport/PushProcessTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/transport/PushProcessTest.java index 28473c7..104a69c 100644 --- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/transport/PushProcessTest.java +++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/transport/PushProcessTest.java
@@ -83,8 +83,8 @@ public class PushProcessTest extends SampleDataRepositoryTestCase { public void setUp() throws Exception { super.setUp(); transport = new MockTransport(db, new URIish()); - refUpdates = new HashSet<RemoteRefUpdate>(); - advertisedRefs = new HashSet<Ref>(); + refUpdates = new HashSet<>(); + advertisedRefs = new HashSet<>(); connectionUpdateStatus = Status.OK; } @@ -421,7 +421,7 @@ public void close() { private class MockPushConnection extends BaseConnection implements PushConnection { MockPushConnection() { - final Map<String, Ref> refsMap = new HashMap<String, Ref>(); + final Map<String, Ref> refsMap = new HashMap<>(); for (final Ref r : advertisedRefs) refsMap.put(r.getName(), r); available(refsMap); @@ -432,12 +432,14 @@ public void close() { // nothing here } + @Override public void push(ProgressMonitor monitor, Map<String, RemoteRefUpdate> refsToUpdate, OutputStream out) throws TransportException { push(monitor, refsToUpdate); } + @Override public void push(ProgressMonitor monitor, Map<String, RemoteRefUpdate> refsToUpdate) throws TransportException {
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 94bc383..abd2840 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
@@ -108,7 +108,7 @@ public void setUp() throws Exception { // Fill dst with a some common history. // - TestRepository<Repository> d = new TestRepository<Repository>(dst); + TestRepository<Repository> d = new TestRepository<>(dst); a = d.blob("a"); A = d.commit(d.tree(d.file("a", a))); B = d.commit().parent(A).create(); @@ -128,16 +128,6 @@ public void setUp() throws Exception { d.update(R_PRIVATE, P); } - @Override - @After - public void tearDown() throws Exception { - if (src != null) - src.close(); - if (dst != null) - dst.close(); - super.tearDown(); - } - @Test public void testFilterHidesPrivate() throws Exception { Map<String, Ref> refs; @@ -193,7 +183,7 @@ public void testSuccess() throws Exception { // Now use b but in a different commit than what is hidden. // - TestRepository<Repository> s = new TestRepository<Repository>(src); + TestRepository<Repository> s = new TestRepository<>(src); RevCommit N = s.commit().parent(B).add("q", b).create(); s.update(R_MASTER, N); @@ -284,7 +274,7 @@ private static void receive(final ReceivePack rp, @Test public void testUsingHiddenDeltaBaseFails() throws Exception { byte[] delta = { 0x1, 0x1, 0x1, 'c' }; - TestRepository<Repository> s = new TestRepository<Repository>(src); + TestRepository<Repository> s = new TestRepository<>(src); RevCommit N = s.commit().parent(B).add("q", s.blob(BinaryDelta.apply(dst.open(b).getCachedBytes(), delta))) .create(); @@ -337,7 +327,7 @@ public void testUsingHiddenDeltaBaseFails() throws Exception { public void testUsingHiddenCommonBlobFails() throws Exception { // Try to use the 'b' blob that is hidden. // - TestRepository<Repository> s = new TestRepository<Repository>(src); + TestRepository<Repository> s = new TestRepository<>(src); RevCommit N = s.commit().parent(B).add("q", s.blob("b")).create(); // But don't include it in the pack. @@ -387,7 +377,7 @@ public void testUsingHiddenCommonBlobFails() throws Exception { public void testUsingUnknownBlobFails() throws Exception { // Try to use the 'n' blob that is not on the server. // - TestRepository<Repository> s = new TestRepository<Repository>(src); + TestRepository<Repository> s = new TestRepository<>(src); RevBlob n = s.blob("n"); RevCommit N = s.commit().parent(B).add("q", n).create(); @@ -435,8 +425,73 @@ public void testUsingUnknownBlobFails() throws Exception { } @Test + public void testIncludesInvalidGitmodules() throws Exception { + final TemporaryBuffer.Heap inBuf = setupSourceRepoInvalidGitmodules(); + final TemporaryBuffer.Heap outBuf = new TemporaryBuffer.Heap(1024); + final ReceivePack rp = new ReceivePack(dst); + rp.setCheckReceivedObjects(true); + rp.setCheckReferencedObjectsAreReachable(true); + rp.setAdvertiseRefsHook(new HidePrivateHook()); + try { + receive(rp, inBuf, outBuf); + fail("Expected UnpackException"); + } catch (UnpackException failed) { + Throwable err = failed.getCause(); + assertTrue(err instanceof IOException); + } + + final PacketLineIn r = asPacketLineIn(outBuf); + String master = r.readString(); + int nul = master.indexOf('\0'); + assertTrue("has capability list", nul > 0); + assertEquals(B.name() + ' ' + R_MASTER, master.substring(0, nul)); + assertSame(PacketLineIn.END, r.readString()); + + String errorLine = r.readString(); + System.out.println(errorLine); + assertTrue(errorLine.startsWith( + "unpack error Invalid submodule URL '-")); + assertEquals("ng refs/heads/s n/a (unpacker error)", r.readString()); + assertSame(PacketLineIn.END, r.readString()); + } + + private TemporaryBuffer.Heap setupSourceRepoInvalidGitmodules() + throws IOException, Exception, MissingObjectException { + String fakeGitmodules = new StringBuilder() + .append("[submodule \"test\"]\n") + .append(" path = xlib\n") + .append(" url = https://example.com/repo/xlib.git\n\n") + .append("[submodule \"test2\"]\n") + .append(" path = zlib\n") + .append(" url = -upayload.sh\n") + .toString(); + + TestRepository<Repository> s = new TestRepository<>(src); + RevBlob blob = s.blob(fakeGitmodules); + RevCommit N = s.commit().parent(B) + .add(".gitmodules", blob).create(); + RevTree t = s.parseBody(N).getTree(); + + final TemporaryBuffer.Heap pack = new TemporaryBuffer.Heap(1024); + packHeader(pack, 3); + copy(pack, src.open(N)); + copy(pack, src.open(t)); + copy(pack, src.open(blob)); + digest(pack); + + final TemporaryBuffer.Heap inBuf = new TemporaryBuffer.Heap(1024); + final PacketLineOut inPckLine = new PacketLineOut(inBuf); + inPckLine.writeString(ObjectId.zeroId().name() + ' ' + N.name() + ' ' + + "refs/heads/s" + '\0' + + BasePackPushConnection.CAPABILITY_REPORT_STATUS); + inPckLine.end(); + pack.writeTo(inBuf, PM); + return inBuf; + } + + @Test public void testUsingUnknownTreeFails() throws Exception { - TestRepository<Repository> s = new TestRepository<Repository>(src); + TestRepository<Repository> s = new TestRepository<>(src); RevCommit N = s.commit().parent(B).add("q", s.blob("a")).create(); RevTree t = s.parseBody(N).getTree(); @@ -556,8 +611,9 @@ private static PacketLineIn asPacketLineIn(TemporaryBuffer.Heap buf) } private static final class HidePrivateHook extends AbstractAdvertiseRefsHook { + @Override public Map<String, Ref> getAdvertisedRefs(Repository r, RevWalk revWalk) { - Map<String, Ref> refs = new HashMap<String, Ref>(r.getAllRefs()); + Map<String, Ref> refs = new HashMap<>(r.getAllRefs()); assertNotNull(refs.remove(R_PRIVATE)); return refs; }
diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/transport/SpiTransport.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/transport/SpiTransport.java index bb6c738..71b909e 100644 --- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/transport/SpiTransport.java +++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/transport/SpiTransport.java
@@ -64,14 +64,17 @@ public class SpiTransport extends Transport { */ public static final TransportProtocol PROTO = new TransportProtocol() { + @Override public String getName() { return "Test SPI Transport Protocol"; } + @Override public Set<String> getSchemes() { return Collections.singleton(SCHEME); } + @Override public Transport open(URIish uri, Repository local, String remoteName) throws NotSupportedException, TransportException { throw new NotSupportedException("not supported"); @@ -82,16 +85,19 @@ private SpiTransport(Repository local, URIish uri) { super(local, uri); } + @Override public FetchConnection openFetch() throws NotSupportedException, TransportException { throw new NotSupportedException("not supported"); } + @Override public PushConnection openPush() throws NotSupportedException, TransportException { throw new NotSupportedException("not supported"); } + @Override public void close() { // Intentionally left blank }
diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/transport/TestProtocolTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/transport/TestProtocolTest.java index 31b6418..b926e48 100644 --- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/transport/TestProtocolTest.java +++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/transport/TestProtocolTest.java
@@ -98,10 +98,10 @@ public ReceivePack create(User req, Repository db) { @Before public void setUp() throws Exception { - protos = new ArrayList<TransportProtocol>(); - local = new TestRepository<InMemoryRepository>( + protos = new ArrayList<>(); + local = new TestRepository<>( new InMemoryRepository(new DfsRepositoryDescription("local"))); - remote = new TestRepository<InMemoryRepository>( + remote = new TestRepository<>( new InMemoryRepository(new DfsRepositoryDescription("remote"))); } @@ -240,7 +240,7 @@ private TestProtocol<User> registerDefault() { private TestProtocol<User> registerProto(UploadPackFactory<User> upf, ReceivePackFactory<User> rpf) { - TestProtocol<User> proto = new TestProtocol<User>(upf, rpf); + TestProtocol<User> proto = new TestProtocol<>(upf, rpf); protos.add(proto); Transport.register(proto); return proto;
diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/transport/TransportTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/transport/TransportTest.java index 5519f61..d4c47d3 100644 --- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/transport/TransportTest.java +++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/transport/TransportTest.java
@@ -53,7 +53,9 @@ import java.util.Arrays; import java.util.Collection; import java.util.Collections; +import java.util.HashMap; import java.util.List; +import java.util.Map; import org.eclipse.jgit.lib.Config; import org.eclipse.jgit.lib.Constants; @@ -209,6 +211,45 @@ public void testFindRemoteRefUpdatesTrackingRef() throws IOException { assertEquals(ObjectId.zeroId(), tru.getOldObjectId()); } + /** + * Test RefSpec to RemoteRefUpdate conversion with leases. + * + * @throws IOException + */ + @Test + public void testFindRemoteRefUpdatesWithLeases() throws IOException { + final RefSpec specA = new RefSpec("+refs/heads/a:refs/heads/b"); + final RefSpec specC = new RefSpec("+refs/heads/c:refs/heads/d"); + final Collection<RefSpec> specs = Arrays.asList(specA, specC); + final Map<String, RefLeaseSpec> leases = new HashMap<>(); + leases.put("refs/heads/b", + new RefLeaseSpec("refs/heads/b", "refs/heads/c")); + + Collection<RemoteRefUpdate> result; + try (Transport transport = Transport.open(db, remoteConfig)) { + result = transport.findRemoteRefUpdatesFor(specs, leases); + } + + assertEquals(2, result.size()); + boolean foundA = false; + boolean foundC = false; + for (final RemoteRefUpdate rru : result) { + if ("refs/heads/a".equals(rru.getSrcRef()) + && "refs/heads/b".equals(rru.getRemoteName())) { + foundA = true; + assertEquals(db.exactRef("refs/heads/c").getObjectId(), + rru.getExpectedOldObjectId()); + } + if ("refs/heads/c".equals(rru.getSrcRef()) + && "refs/heads/d".equals(rru.getRemoteName())) { + foundC = true; + assertNull(rru.getExpectedOldObjectId()); + } + } + assertTrue(foundA); + assertTrue(foundC); + } + @Test public void testLocalTransportWithRelativePath() throws Exception { Repository other = createWorkRepository();
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 cc5870e..1b434d3 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
@@ -85,12 +85,12 @@ import java.util.ArrayList; import java.util.Collection; import java.util.List; +import java.util.Locale; import java.util.Properties; import java.util.Set; import java.util.TreeSet; import java.util.UUID; -import javax.crypto.Cipher; import javax.crypto.SecretKeyFactory; import org.eclipse.jgit.api.Git; @@ -459,14 +459,14 @@ static String securityProviderName(String algorithm) throws Exception { static List<String> cryptoCipherList(String regex) { Set<String> source = Security.getAlgorithms("Cipher"); - Set<String> target = new TreeSet<String>(); + Set<String> target = new TreeSet<>(); for (String algo : source) { - algo = algo.toUpperCase(); + algo = algo.toUpperCase(Locale.ROOT); if (algo.matches(regex)) { target.add(algo); } } - return new ArrayList<String>(target); + return new ArrayList<>(target); } /** @@ -598,7 +598,7 @@ static void reportPolicy() { } static List<Object[]> product(List<String> one, List<String> two) { - List<Object[]> result = new ArrayList<Object[]>(); + List<Object[]> result = new ArrayList<>(); for (String s1 : one) { for (String s2 : two) { result.add(new Object[] { s1, s2 }); @@ -759,7 +759,7 @@ static boolean isAlgorithmPresent(String algorithm) { for (String source : cipherSet) { // Standard names are not case-sensitive. // http://docs.oracle.com/javase/8/docs/technotes/guides/security/StandardNames.html - String target = algorithm.toUpperCase(); + String target = algorithm.toUpperCase(Locale.ROOT); if (source.equalsIgnoreCase(target)) { return true; } @@ -771,16 +771,16 @@ static boolean isAlgorithmPresent(Properties props) { String profile = props.getProperty(AmazonS3.Keys.CRYPTO_ALG); String version = props.getProperty(AmazonS3.Keys.CRYPTO_VER, WalkEncryption.Vals.DEFAULT_VERS); - String crytoAlgo; + String cryptoAlgo; String keyAlgo; switch (version) { case WalkEncryption.Vals.DEFAULT_VERS: case WalkEncryption.JGitV1.VERSION: - crytoAlgo = profile; + cryptoAlgo = profile; keyAlgo = profile; break; case WalkEncryption.JGitV2.VERSION: - crytoAlgo = props + cryptoAlgo = props .getProperty(profile + WalkEncryption.Keys.X_ALGO); keyAlgo = props .getProperty(profile + WalkEncryption.Keys.X_KEY_ALGO); @@ -789,7 +789,7 @@ static boolean isAlgorithmPresent(Properties props) { return false; } try { - Cipher.getInstance(crytoAlgo); + InsecureCipherFactory.create(cryptoAlgo); SecretKeyFactory.getInstance(keyAlgo); return true; } catch (Throwable e) { @@ -1240,10 +1240,10 @@ public static class TestablePBE extends Base { @Parameters(name = "Profile: {0} Version: {1}") public static Collection<Object[]> argsList() { - List<String> algorithmList = new ArrayList<String>(); + List<String> algorithmList = new ArrayList<>(); algorithmList.addAll(cryptoCipherListPBE()); - List<String> versionList = new ArrayList<String>(); + List<String> versionList = new ArrayList<>(); versionList.add("0"); versionList.add("1"); @@ -1283,10 +1283,10 @@ public static class TestableTransformation extends Base { @Parameters(name = "Profile: {0} Version: {1}") public static Collection<Object[]> argsList() { - List<String> algorithmList = new ArrayList<String>(); + List<String> algorithmList = new ArrayList<>(); algorithmList.addAll(cryptoCipherListTrans()); - List<String> versionList = new ArrayList<String>(); + List<String> versionList = new ArrayList<>(); versionList.add("1"); return product(algorithmList, versionList);
diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/treewalk/FileTreeIteratorJava7Test.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/treewalk/FileTreeIteratorJava7Test.java deleted file mode 100644 index cd55cba..0000000 --- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/treewalk/FileTreeIteratorJava7Test.java +++ /dev/null
@@ -1,207 +0,0 @@ -/* - * Copyright (C) 2012-2013, Robin Rosenberg <robin.rosenberg@dewire.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.treewalk; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertTrue; - -import java.io.File; -import java.io.IOException; - -import org.eclipse.jgit.api.Git; -import org.eclipse.jgit.api.ResetCommand.ResetType; -import org.eclipse.jgit.dircache.DirCache; -import org.eclipse.jgit.dircache.DirCacheEditor; -import org.eclipse.jgit.dircache.DirCacheEntry; -import org.eclipse.jgit.dircache.DirCacheIterator; -import org.eclipse.jgit.junit.RepositoryTestCase; -import org.eclipse.jgit.lib.Constants; -import org.eclipse.jgit.lib.FileMode; -import org.eclipse.jgit.lib.ObjectId; -import org.eclipse.jgit.lib.ObjectInserter; -import org.eclipse.jgit.util.FS; -import org.eclipse.jgit.util.FileUtils; -import org.junit.Test; - -public class FileTreeIteratorJava7Test extends RepositoryTestCase { - @Test - public void testFileModeSymLinkIsNotATree() throws IOException { - org.junit.Assume.assumeTrue(FS.DETECTED.supportsSymlinks()); - FS fs = db.getFS(); - // mål = target in swedish, just to get som unicode in here - writeTrashFile("mål/data", "targetdata"); - fs.createSymLink(new File(trash, "länk"), "mål"); - FileTreeIterator fti = new FileTreeIterator(db); - assertFalse(fti.eof()); - assertEquals("länk", fti.getEntryPathString()); - assertEquals(FileMode.SYMLINK, fti.getEntryFileMode()); - fti.next(1); - assertFalse(fti.eof()); - assertEquals("mål", fti.getEntryPathString()); - assertEquals(FileMode.TREE, fti.getEntryFileMode()); - fti.next(1); - assertTrue(fti.eof()); - } - - @Test - public void testSymlinkNotModifiedThoughNormalized() throws Exception { - DirCache dc = db.lockDirCache(); - DirCacheEditor dce = dc.editor(); - final String UNNORMALIZED = "target/"; - final byte[] UNNORMALIZED_BYTES = Constants.encode(UNNORMALIZED); - try (ObjectInserter oi = db.newObjectInserter()) { - final ObjectId linkid = oi.insert(Constants.OBJ_BLOB, - UNNORMALIZED_BYTES, 0, UNNORMALIZED_BYTES.length); - dce.add(new DirCacheEditor.PathEdit("link") { - @Override - public void apply(DirCacheEntry ent) { - ent.setFileMode(FileMode.SYMLINK); - ent.setObjectId(linkid); - ent.setLength(UNNORMALIZED_BYTES.length); - } - }); - assertTrue(dce.commit()); - } - try (Git git = new Git(db)) { - git.commit().setMessage("Adding link").call(); - git.reset().setMode(ResetType.HARD).call(); - DirCacheIterator dci = new DirCacheIterator(db.readDirCache()); - FileTreeIterator fti = new FileTreeIterator(db); - - // self-check - assertEquals("link", fti.getEntryPathString()); - assertEquals("link", dci.getEntryPathString()); - - // test - assertFalse(fti.isModified(dci.getDirCacheEntry(), true, - db.newObjectReader())); - } - } - - /** - * Like #testSymlinkNotModifiedThoughNormalized but there is no - * normalization being done. - * - * @throws Exception - */ - @Test - public void testSymlinkModifiedNotNormalized() throws Exception { - DirCache dc = db.lockDirCache(); - DirCacheEditor dce = dc.editor(); - final String NORMALIZED = "target"; - final byte[] NORMALIZED_BYTES = Constants.encode(NORMALIZED); - try (ObjectInserter oi = db.newObjectInserter()) { - final ObjectId linkid = oi.insert(Constants.OBJ_BLOB, - NORMALIZED_BYTES, 0, NORMALIZED_BYTES.length); - dce.add(new DirCacheEditor.PathEdit("link") { - @Override - public void apply(DirCacheEntry ent) { - ent.setFileMode(FileMode.SYMLINK); - ent.setObjectId(linkid); - ent.setLength(NORMALIZED_BYTES.length); - } - }); - assertTrue(dce.commit()); - } - try (Git git = new Git(db)) { - git.commit().setMessage("Adding link").call(); - git.reset().setMode(ResetType.HARD).call(); - DirCacheIterator dci = new DirCacheIterator(db.readDirCache()); - FileTreeIterator fti = new FileTreeIterator(db); - - // self-check - assertEquals("link", fti.getEntryPathString()); - assertEquals("link", dci.getEntryPathString()); - - // test - assertFalse(fti.isModified(dci.getDirCacheEntry(), true, - db.newObjectReader())); - } - } - - /** - * Like #testSymlinkNotModifiedThoughNormalized but here the link is - * modified. - * - * @throws Exception - */ - @Test - public void testSymlinkActuallyModified() throws Exception { - org.junit.Assume.assumeTrue(FS.DETECTED.supportsSymlinks()); - final String NORMALIZED = "target"; - final byte[] NORMALIZED_BYTES = Constants.encode(NORMALIZED); - try (ObjectInserter oi = db.newObjectInserter()) { - final ObjectId linkid = oi.insert(Constants.OBJ_BLOB, - NORMALIZED_BYTES, 0, NORMALIZED_BYTES.length); - DirCache dc = db.lockDirCache(); - DirCacheEditor dce = dc.editor(); - dce.add(new DirCacheEditor.PathEdit("link") { - @Override - public void apply(DirCacheEntry ent) { - ent.setFileMode(FileMode.SYMLINK); - ent.setObjectId(linkid); - ent.setLength(NORMALIZED_BYTES.length); - } - }); - assertTrue(dce.commit()); - } - try (Git git = new Git(db)) { - git.commit().setMessage("Adding link").call(); - git.reset().setMode(ResetType.HARD).call(); - - FileUtils.delete(new File(trash, "link"), FileUtils.NONE); - FS.DETECTED.createSymLink(new File(trash, "link"), "newtarget"); - DirCacheIterator dci = new DirCacheIterator(db.readDirCache()); - FileTreeIterator fti = new FileTreeIterator(db); - - // self-check - assertEquals("link", fti.getEntryPathString()); - assertEquals("link", dci.getEntryPathString()); - - // test - assertTrue(fti.isModified(dci.getDirCacheEntry(), true, - db.newObjectReader())); - } - } -}
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 ef0f2d9..e34cb97 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
@@ -1,5 +1,5 @@ /* - * Copyright (C) 2008, Google Inc. + * Copyright (C) 2008, 2017, Google Inc. * and other copyright owners as documented in the project's IP log. * * This program and the accompanying materials are made available @@ -53,6 +53,7 @@ import java.security.MessageDigest; import org.eclipse.jgit.api.Git; +import org.eclipse.jgit.api.ResetCommand.ResetType; import org.eclipse.jgit.dircache.DirCache; import org.eclipse.jgit.dircache.DirCacheCheckout; import org.eclipse.jgit.dircache.DirCacheEditor; @@ -68,6 +69,7 @@ import org.eclipse.jgit.lib.Constants; import org.eclipse.jgit.lib.FileMode; import org.eclipse.jgit.lib.ObjectId; +import org.eclipse.jgit.lib.ObjectInserter; import org.eclipse.jgit.lib.ObjectReader; import org.eclipse.jgit.lib.Repository; import org.eclipse.jgit.revwalk.RevCommit; @@ -85,6 +87,7 @@ public class FileTreeIteratorTest extends RepositoryTestCase { private long[] mtime; + @Override @Before public void setUp() throws Exception { super.setUp(); @@ -381,6 +384,7 @@ public void submoduleHeadMatchesIndex() throws Exception { DirCacheEditor editor = cache.editor(); editor.add(new PathEdit(path) { + @Override public void apply(DirCacheEntry ent) { ent.setFileMode(FileMode.GITLINK); ent.setObjectId(id); @@ -415,6 +419,7 @@ public void submoduleWithNoGitDirectory() throws Exception { DirCacheEditor editor = cache.editor(); editor.add(new PathEdit(path) { + @Override public void apply(DirCacheEntry ent) { ent.setFileMode(FileMode.GITLINK); ent.setObjectId(id); @@ -450,6 +455,7 @@ public void submoduleWithNoHead() throws Exception { DirCacheEditor editor = cache.editor(); editor.add(new PathEdit(path) { + @Override public void apply(DirCacheEntry ent) { ent.setFileMode(FileMode.GITLINK); ent.setObjectId(id); @@ -484,6 +490,7 @@ public void submoduleDirectoryIterator() throws Exception { DirCacheEditor editor = cache.editor(); editor.add(new PathEdit(path) { + @Override public void apply(DirCacheEntry ent) { ent.setFileMode(FileMode.GITLINK); ent.setObjectId(id); @@ -519,6 +526,7 @@ public void submoduleNestedWithHeadMatchingIndex() throws Exception { DirCacheEditor editor = cache.editor(); editor.add(new PathEdit(path) { + @Override public void apply(DirCacheEntry ent) { ent.setFileMode(FileMode.GITLINK); ent.setObjectId(id); @@ -653,6 +661,157 @@ public void testCustomFileModeStrategyFromParentIterator() throws Exception { } } + @Test + public void testFileModeSymLinkIsNotATree() throws IOException { + org.junit.Assume.assumeTrue(FS.DETECTED.supportsSymlinks()); + FS fs = db.getFS(); + // mål = target in swedish, just to get som unicode in here + writeTrashFile("mål/data", "targetdata"); + fs.createSymLink(new File(trash, "länk"), "mål"); + FileTreeIterator fti = new FileTreeIterator(db); + assertFalse(fti.eof()); + while (!fti.getEntryPathString().equals("länk")) { + fti.next(1); + } + assertEquals("länk", fti.getEntryPathString()); + assertEquals(FileMode.SYMLINK, fti.getEntryFileMode()); + fti.next(1); + assertFalse(fti.eof()); + assertEquals("mål", fti.getEntryPathString()); + assertEquals(FileMode.TREE, fti.getEntryFileMode()); + fti.next(1); + assertTrue(fti.eof()); + } + + @Test + public void testSymlinkNotModifiedThoughNormalized() throws Exception { + DirCache dc = db.lockDirCache(); + DirCacheEditor dce = dc.editor(); + final String UNNORMALIZED = "target/"; + final byte[] UNNORMALIZED_BYTES = Constants.encode(UNNORMALIZED); + try (ObjectInserter oi = db.newObjectInserter()) { + final ObjectId linkid = oi.insert(Constants.OBJ_BLOB, + UNNORMALIZED_BYTES, 0, UNNORMALIZED_BYTES.length); + dce.add(new DirCacheEditor.PathEdit("link") { + @Override + public void apply(DirCacheEntry ent) { + ent.setFileMode(FileMode.SYMLINK); + ent.setObjectId(linkid); + ent.setLength(UNNORMALIZED_BYTES.length); + } + }); + assertTrue(dce.commit()); + } + try (Git git = new Git(db)) { + git.commit().setMessage("Adding link").call(); + git.reset().setMode(ResetType.HARD).call(); + DirCacheIterator dci = new DirCacheIterator(db.readDirCache()); + FileTreeIterator fti = new FileTreeIterator(db); + + // self-check + while (!fti.getEntryPathString().equals("link")) { + fti.next(1); + } + assertEquals("link", fti.getEntryPathString()); + assertEquals("link", dci.getEntryPathString()); + + // test + assertFalse(fti.isModified(dci.getDirCacheEntry(), true, + db.newObjectReader())); + } + } + + /** + * Like #testSymlinkNotModifiedThoughNormalized but there is no + * normalization being done. + * + * @throws Exception + */ + @Test + public void testSymlinkModifiedNotNormalized() throws Exception { + DirCache dc = db.lockDirCache(); + DirCacheEditor dce = dc.editor(); + final String NORMALIZED = "target"; + final byte[] NORMALIZED_BYTES = Constants.encode(NORMALIZED); + try (ObjectInserter oi = db.newObjectInserter()) { + final ObjectId linkid = oi.insert(Constants.OBJ_BLOB, + NORMALIZED_BYTES, 0, NORMALIZED_BYTES.length); + dce.add(new DirCacheEditor.PathEdit("link") { + @Override + public void apply(DirCacheEntry ent) { + ent.setFileMode(FileMode.SYMLINK); + ent.setObjectId(linkid); + ent.setLength(NORMALIZED_BYTES.length); + } + }); + assertTrue(dce.commit()); + } + try (Git git = new Git(db)) { + git.commit().setMessage("Adding link").call(); + git.reset().setMode(ResetType.HARD).call(); + DirCacheIterator dci = new DirCacheIterator(db.readDirCache()); + FileTreeIterator fti = new FileTreeIterator(db); + + // self-check + while (!fti.getEntryPathString().equals("link")) { + fti.next(1); + } + assertEquals("link", fti.getEntryPathString()); + assertEquals("link", dci.getEntryPathString()); + + // test + assertFalse(fti.isModified(dci.getDirCacheEntry(), true, + db.newObjectReader())); + } + } + + /** + * Like #testSymlinkNotModifiedThoughNormalized but here the link is + * modified. + * + * @throws Exception + */ + @Test + public void testSymlinkActuallyModified() throws Exception { + org.junit.Assume.assumeTrue(FS.DETECTED.supportsSymlinks()); + final String NORMALIZED = "target"; + final byte[] NORMALIZED_BYTES = Constants.encode(NORMALIZED); + try (ObjectInserter oi = db.newObjectInserter()) { + final ObjectId linkid = oi.insert(Constants.OBJ_BLOB, + NORMALIZED_BYTES, 0, NORMALIZED_BYTES.length); + DirCache dc = db.lockDirCache(); + DirCacheEditor dce = dc.editor(); + dce.add(new DirCacheEditor.PathEdit("link") { + @Override + public void apply(DirCacheEntry ent) { + ent.setFileMode(FileMode.SYMLINK); + ent.setObjectId(linkid); + ent.setLength(NORMALIZED_BYTES.length); + } + }); + assertTrue(dce.commit()); + } + try (Git git = new Git(db)) { + git.commit().setMessage("Adding link").call(); + git.reset().setMode(ResetType.HARD).call(); + + FileUtils.delete(new File(trash, "link"), FileUtils.NONE); + FS.DETECTED.createSymLink(new File(trash, "link"), "newtarget"); + DirCacheIterator dci = new DirCacheIterator(db.readDirCache()); + FileTreeIterator fti = new FileTreeIterator(db); + + // self-check + while (!fti.getEntryPathString().equals("link")) { + fti.next(1); + } + assertEquals("link", fti.getEntryPathString()); + assertEquals("link", dci.getEntryPathString()); + + // test + assertTrue(fti.isModified(dci.getDirCacheEntry(), true, + db.newObjectReader())); + } + } private static void assertEntry(String sha1string, String path, TreeWalk tw) throws MissingObjectException, IncorrectObjectTypeException,
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 bb4b066..2f797e3 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
@@ -89,6 +89,7 @@ public class IndexDiffFilterTest extends RepositoryTestCase { private Git git; + @Override @Before public void setUp() throws Exception { super.setUp();
diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/treewalk/filter/InterIndexDiffFilterTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/treewalk/filter/InterIndexDiffFilterTest.java index 9f0f067..cba35d8 100644 --- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/treewalk/filter/InterIndexDiffFilterTest.java +++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/treewalk/filter/InterIndexDiffFilterTest.java
@@ -66,6 +66,7 @@ public class InterIndexDiffFilterTest extends LocalDiskRepositoryTestCase { private Repository db; + @Override @Before public void setUp() throws Exception { super.setUp();
diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/treewalk/filter/PathFilterGroupTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/treewalk/filter/PathFilterGroupTest.java index 5edc192..d921aab 100644 --- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/treewalk/filter/PathFilterGroupTest.java +++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/treewalk/filter/PathFilterGroupTest.java
@@ -259,6 +259,7 @@ TreeWalk fakeWalk(final String path) throws IOException { DirCacheEditor dce = dc.editor(); dce.add(new DirCacheEditor.PathEdit(path) { + @Override public void apply(DirCacheEntry ent) { ent.setFileMode(FileMode.REGULAR_FILE); } @@ -277,6 +278,7 @@ TreeWalk fakeWalkAtSubtree(final String path) throws IOException { DirCache dc = DirCache.newInCore(); DirCacheEditor dce = dc.editor(); dce.add(new DirCacheEditor.PathEdit(path + "/README") { + @Override public void apply(DirCacheEntry ent) { ent.setFileMode(FileMode.REGULAR_FILE); }
diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/treewalk/filter/PathFilterLogicTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/treewalk/filter/PathFilterLogicTest.java new file mode 100644 index 0000000..7c819c5 --- /dev/null +++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/treewalk/filter/PathFilterLogicTest.java
@@ -0,0 +1,360 @@ +/* + * Copyright (C) 2017 Magnus Vigerlöf (magnus.vigerlof@gmail.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.treewalk.filter; + +import org.eclipse.jgit.dircache.DirCache; +import org.eclipse.jgit.dircache.DirCacheBuilder; +import org.eclipse.jgit.dircache.DirCacheEntry; +import org.eclipse.jgit.junit.RepositoryTestCase; +import org.eclipse.jgit.lib.FileMode; +import org.eclipse.jgit.lib.ObjectId; +import org.eclipse.jgit.lib.ObjectInserter; +import org.eclipse.jgit.treewalk.TreeWalk; +import org.junit.Before; +import org.junit.Test; + +import java.io.IOException; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.List; + +import static org.junit.Assert.assertEquals; + +public class PathFilterLogicTest extends RepositoryTestCase { + + private ObjectId treeId; + + @Before + public void setup() throws IOException { + String[] paths = new String[] { + "a.txt", + "sub1.txt", + "sub1/suba/a.txt", + "sub1/subb/b.txt", + "sub2/suba/a.txt" + }; + treeId = createTree(paths); + } + + @Test + public void testSinglePath() throws IOException { + List<String> expected = Arrays.asList("sub1/suba/a.txt", + "sub1/subb/b.txt"); + + TreeFilter tf = PathFilter.create("sub1"); + List<String> paths = getMatchingPaths(treeId, tf); + + assertEquals(expected, paths); + } + + @Test + public void testSingleSubPath() throws IOException { + List<String> expected = Collections.singletonList("sub1/suba/a.txt"); + + TreeFilter tf = PathFilter.create("sub1/suba"); + List<String> paths = getMatchingPaths(treeId, tf); + + assertEquals(expected, paths); + } + + @Test + public void testSinglePathNegate() throws IOException { + List<String> expected = Arrays.asList("a.txt", "sub1.txt", + "sub2/suba/a.txt"); + + TreeFilter tf = PathFilter.create("sub1").negate(); + List<String> paths = getMatchingPaths(treeId, tf); + + assertEquals(expected, paths); + } + + @Test + public void testSingleSubPathNegate() throws IOException { + List<String> expected = Arrays.asList("a.txt", "sub1.txt", + "sub1/subb/b.txt", "sub2/suba/a.txt"); + + TreeFilter tf = PathFilter.create("sub1/suba").negate(); + List<String> paths = getMatchingPaths(treeId, tf); + + assertEquals(expected, paths); + } + + @Test + public void testOrMultiTwoPath() throws IOException { + List<String> expected = Arrays.asList("sub1/suba/a.txt", + "sub1/subb/b.txt", "sub2/suba/a.txt"); + + TreeFilter[] tf = new TreeFilter[] {PathFilter.create("sub1"), + PathFilter.create("sub2")}; + List<String> paths = getMatchingPaths(treeId, OrTreeFilter.create(tf)); + + assertEquals(expected, paths); + } + + @Test + public void testOrMultiThreePath() throws IOException { + List<String> expected = Arrays.asList("sub1.txt", "sub1/suba/a.txt", + "sub1/subb/b.txt", "sub2/suba/a.txt"); + + TreeFilter[] tf = new TreeFilter[] {PathFilter.create("sub1"), + PathFilter.create("sub2"), PathFilter.create("sub1.txt")}; + List<String> paths = getMatchingPaths(treeId, OrTreeFilter.create(tf)); + + assertEquals(expected, paths); + } + + @Test + public void testOrMultiTwoSubPath() throws IOException { + List<String> expected = Arrays.asList("sub1/subb/b.txt", + "sub2/suba/a.txt"); + + TreeFilter[] tf = new TreeFilter[] {PathFilter.create("sub1/subb"), + PathFilter.create("sub2/suba")}; + List<String> paths = getMatchingPaths(treeId, OrTreeFilter.create(tf)); + + assertEquals(expected, paths); + } + + @Test + public void testOrMultiTwoMixSubPath() throws IOException { + List<String> expected = Arrays.asList("sub1/subb/b.txt", + "sub2/suba/a.txt"); + + TreeFilter[] tf = new TreeFilter[] {PathFilter.create("sub1/subb"), + PathFilter.create("sub2")}; + List<String> paths = getMatchingPaths(treeId, OrTreeFilter.create(tf)); + + assertEquals(expected, paths); + } + + @Test + public void testOrMultiTwoMixSubPathNegate() throws IOException { + List<String> expected = Arrays.asList("a.txt", "sub1.txt", + "sub1/suba/a.txt", "sub2/suba/a.txt"); + + TreeFilter[] tf = new TreeFilter[] {PathFilter.create("sub1").negate(), + PathFilter.create("sub1/suba")}; + List<String> paths = getMatchingPaths(treeId, OrTreeFilter.create(tf)); + + assertEquals(expected, paths); + } + + @Test + public void testOrMultiThreeMixSubPathNegate() throws IOException { + List<String> expected = Arrays.asList("a.txt", "sub1.txt", + "sub1/suba/a.txt", "sub2/suba/a.txt"); + + TreeFilter[] tf = new TreeFilter[] {PathFilter.create("sub1").negate(), + PathFilter.create("sub1/suba"), PathFilter.create("no/path")}; + List<String> paths = getMatchingPaths(treeId, OrTreeFilter.create(tf)); + + assertEquals(expected, paths); + } + + @Test + public void testPatternParentFileMatch() throws IOException { + List<String> expected = Collections.emptyList(); + + TreeFilter tf = PathFilter.create("a.txt/test/path"); + List<String> paths = getMatchingPaths(treeId, tf); + + assertEquals(expected, paths); + } + + @Test + public void testAndMultiPath() throws IOException { + List<String> expected = Collections.emptyList(); + + TreeFilter[] tf = new TreeFilter[] {PathFilter.create("sub1"), + PathFilter.create("sub2")}; + List<String> paths = getMatchingPaths(treeId, AndTreeFilter.create(tf)); + + assertEquals(expected, paths); + } + + @Test + public void testAndMultiPathNegate() throws IOException { + List<String> expected = Arrays.asList("sub1/suba/a.txt", + "sub1/subb/b.txt"); + + TreeFilter[] tf = new TreeFilter[] {PathFilter.create("sub1"), + PathFilter.create("sub2").negate()}; + List<String> paths = getMatchingPaths(treeId, AndTreeFilter.create(tf)); + + assertEquals(expected, paths); + } + + @Test + public void testAndMultiSubPathDualNegate() throws IOException { + List<String> expected = Arrays.asList("a.txt", "sub1.txt", + "sub1/subb/b.txt"); + + TreeFilter[] tf = new TreeFilter[] {PathFilter.create("sub1/suba").negate(), + PathFilter.create("sub2").negate()}; + List<String> paths = getMatchingPaths(treeId, AndTreeFilter.create(tf)); + + assertEquals(expected, paths); + } + + @Test + public void testAndMultiSubPath() throws IOException { + List<String> expected = Collections.emptyList(); + + TreeFilter[] tf = new TreeFilter[] {PathFilter.create("sub1"), + PathFilter.create("sub2/suba")}; + List<String> paths = getMatchingPaths(treeId, AndTreeFilter.create(tf)); + + assertEquals(expected, paths); + } + + @Test + public void testAndMultiSubPathNegate() throws IOException { + List<String> expected = Collections.singletonList("sub1/subb/b.txt"); + + TreeFilter[] tf = new TreeFilter[] {PathFilter.create("sub1"), + PathFilter.create("sub1/suba").negate()}; + List<String> paths = getMatchingPaths(treeId, AndTreeFilter.create(tf)); + + assertEquals(expected, paths); + } + + @Test + public void testAndMultiThreeSubPathNegate() throws IOException { + List<String> expected = Collections.singletonList("sub1/subb/b.txt"); + + TreeFilter[] tf = new TreeFilter[]{PathFilter.create("sub1"), + PathFilter.create("sub1/suba").negate(), + PathFilter.create("no/path").negate()}; + List<String> paths = getMatchingPaths(treeId, AndTreeFilter.create(tf)); + + assertEquals(expected, paths); + } + + @Test + public void testTopAndMultiPathDualNegate() throws IOException { + List<String> expected = Arrays.asList("a.txt", "sub1.txt"); + + TreeFilter[] tf = new TreeFilter[] {PathFilter.create("sub1").negate(), + PathFilter.create("sub2").negate()}; + List<String> paths = getMatchingPathsFlat(treeId, AndTreeFilter.create(tf)); + + assertEquals(expected, paths); + } + + @Test + public void testTopAndMultiSubPathDualNegate() throws IOException { + List<String> expected = Arrays.asList("a.txt", "sub1.txt", "sub1"); + + // Filter on 'sub1/suba' is kind of silly for a non-recursive walk. + // The result is interesting though as the 'sub1' path should be + // returned, due to the fact that there may be hits once the pattern + // is tested with one of the leaf paths. + TreeFilter[] tf = new TreeFilter[] {PathFilter.create("sub1/suba").negate(), + PathFilter.create("sub2").negate()}; + List<String> paths = getMatchingPathsFlat(treeId, AndTreeFilter.create(tf)); + + assertEquals(expected, paths); + } + + @Test + public void testTopOrMultiPathDual() throws IOException { + List<String> expected = Arrays.asList("sub1.txt", "sub2"); + + TreeFilter[] tf = new TreeFilter[] {PathFilter.create("sub1.txt"), + PathFilter.create("sub2")}; + List<String> paths = getMatchingPathsFlat(treeId, OrTreeFilter.create(tf)); + + assertEquals(expected, paths); + } + + @Test + public void testTopNotPath() throws IOException { + List<String> expected = Arrays.asList("a.txt", "sub1.txt", "sub2"); + + TreeFilter tf = PathFilter.create("sub1"); + List<String> paths = getMatchingPathsFlat(treeId, NotTreeFilter.create(tf)); + + assertEquals(expected, paths); + } + + private List<String> getMatchingPaths(final ObjectId objId, + TreeFilter tf) throws IOException { + return getMatchingPaths(objId, tf, true); + } + + private List<String> getMatchingPathsFlat(final ObjectId objId, + TreeFilter tf) throws IOException { + return getMatchingPaths(objId, tf, false); + } + + private List<String> getMatchingPaths(final ObjectId objId, + TreeFilter tf, boolean recursive) throws IOException { + try (TreeWalk tw = new TreeWalk(db)) { + tw.setFilter(tf); + tw.setRecursive(recursive); + tw.addTree(objId); + + List<String> paths = new ArrayList<>(); + while (tw.next()) { + paths.add(tw.getPathString()); + } + return paths; + } + } + + private ObjectId createTree(String... paths) throws IOException { + final ObjectInserter odi = db.newObjectInserter(); + final DirCache dc = db.readDirCache(); + final DirCacheBuilder builder = dc.builder(); + for (String path : paths) { + DirCacheEntry entry = createEntry(path, FileMode.REGULAR_FILE); + builder.add(entry); + } + builder.finish(); + final ObjectId objId = dc.writeTree(odi); + odi.flush(); + return objId; + } +} +
diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/treewalk/filter/PathSuffixFilterTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/treewalk/filter/PathSuffixFilterTest.java index 3885c41..38adda3 100644 --- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/treewalk/filter/PathSuffixFilterTest.java +++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/treewalk/filter/PathSuffixFilterTest.java
@@ -118,7 +118,7 @@ private List<String> getMatchingPaths(String suffixFilter, tw.setRecursive(recursiveWalk); tw.addTree(treeId); - List<String> paths = new ArrayList<String>(); + List<String> paths = new ArrayList<>(); while (tw.next()) paths.add(tw.getPathString()); return paths;
diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/util/BlockListTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/util/BlockListTest.java index 8b042bd..0a3de85 100644 --- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/util/BlockListTest.java +++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/util/BlockListTest.java
@@ -57,22 +57,22 @@ public class BlockListTest { public void testEmptyList() { BlockList<String> empty; - empty = new BlockList<String>(); + empty = new BlockList<>(); assertEquals(0, empty.size()); assertTrue(empty.isEmpty()); assertFalse(empty.iterator().hasNext()); - empty = new BlockList<String>(0); + empty = new BlockList<>(0); assertEquals(0, empty.size()); assertTrue(empty.isEmpty()); assertFalse(empty.iterator().hasNext()); - empty = new BlockList<String>(1); + empty = new BlockList<>(1); assertEquals(0, empty.size()); assertTrue(empty.isEmpty()); assertFalse(empty.iterator().hasNext()); - empty = new BlockList<String>(64); + empty = new BlockList<>(64); assertEquals(0, empty.size()); assertTrue(empty.isEmpty()); assertFalse(empty.iterator().hasNext()); @@ -80,7 +80,7 @@ public void testEmptyList() { @Test public void testGet() { - BlockList<String> list = new BlockList<String>(4); + BlockList<String> list = new BlockList<>(4); try { list.get(-1); @@ -121,7 +121,7 @@ public void testGet() { @Test public void testSet() { - BlockList<String> list = new BlockList<String>(4); + BlockList<String> list = new BlockList<>(4); try { list.set(-1, "foo"); @@ -168,7 +168,7 @@ public void testSet() { @Test public void testAddToEnd() { - BlockList<Integer> list = new BlockList<Integer>(4); + BlockList<Integer> list = new BlockList<>(4); int cnt = BlockList.BLOCK_SIZE * 3; for (int i = 0; i < cnt; i++) @@ -192,7 +192,7 @@ public void testAddToEnd() { @Test public void testAddSlowPath() { - BlockList<String> list = new BlockList<String>(4); + BlockList<String> list = new BlockList<>(4); String fooStr = "foo"; String barStr = "bar"; @@ -223,7 +223,7 @@ public void testAddSlowPath() { @Test public void testRemoveFromEnd() { - BlockList<String> list = new BlockList<String>(4); + BlockList<String> list = new BlockList<>(4); String fooStr = "foo"; String barStr = "bar"; @@ -245,7 +245,7 @@ public void testRemoveFromEnd() { @Test public void testRemoveSlowPath() { - BlockList<String> list = new BlockList<String>(4); + BlockList<String> list = new BlockList<>(4); String fooStr = "foo"; String barStr = "bar"; @@ -270,7 +270,7 @@ public void testRemoveSlowPath() { @Test public void testAddRemoveAdd() { - BlockList<Integer> list = new BlockList<Integer>(); + BlockList<Integer> list = new BlockList<>(); for (int i = 0; i < BlockList.BLOCK_SIZE + 1; i++) list.add(Integer.valueOf(i)); assertEquals(Integer.valueOf(BlockList.BLOCK_SIZE), @@ -283,14 +283,14 @@ public void testAddRemoveAdd() { @Test public void testAddAllFromOtherList() { - BlockList<Integer> src = new BlockList<Integer>(4); + BlockList<Integer> src = new BlockList<>(4); int cnt = BlockList.BLOCK_SIZE * 2; for (int i = 0; i < cnt; i++) src.add(Integer.valueOf(42 + i)); src.add(Integer.valueOf(1)); - BlockList<Integer> dst = new BlockList<Integer>(4); + BlockList<Integer> dst = new BlockList<>(4); dst.add(Integer.valueOf(255)); dst.addAll(src); assertEquals(cnt + 2, dst.size()); @@ -301,7 +301,7 @@ public void testAddAllFromOtherList() { @Test public void testFastIterator() { - BlockList<Integer> list = new BlockList<Integer>(4); + BlockList<Integer> list = new BlockList<>(4); int cnt = BlockList.BLOCK_SIZE * 3; for (int i = 0; i < cnt; i++) @@ -318,7 +318,7 @@ public void testFastIterator() { @Test public void testAddRejectsBadIndexes() { - BlockList<Integer> list = new BlockList<Integer>(4); + BlockList<Integer> list = new BlockList<>(4); list.add(Integer.valueOf(41)); try { @@ -336,7 +336,7 @@ public void testAddRejectsBadIndexes() { @Test public void testRemoveRejectsBadIndexes() { - BlockList<Integer> list = new BlockList<Integer>(4); + BlockList<Integer> list = new BlockList<>(4); list.add(Integer.valueOf(41)); try {
diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/util/ChangeIdUtilTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/util/ChangeIdUtilTest.java index aaeb79c..6fed233 100644 --- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/util/ChangeIdUtilTest.java +++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/util/ChangeIdUtilTest.java
@@ -583,23 +583,6 @@ public void testChangeIdAfterBugOrIssue() throws Exception { SOB1)); } - public void notestCommitDashV() throws Exception { - assertEquals("a\n" + // - "\n" + // - "Change-Id: I7fc3876fee63c766a2063df97fbe04a2dddd8d7c\n" + // - SOB1 + // - SOB2, // - call("a\n" + // - "\n" + // - SOB1 + // - SOB2 + // - "\n" + // - "# on branch master\n" + // - "diff --git a/src b/src\n" + // - "new file mode 100644\n" + // - "index 0000000..c78b7f0\n")); - } - @Test public void testWithEndingURL() throws Exception { assertEquals("a\n" + //
diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/util/FileUtils7Test.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/util/FileUtils7Test.java deleted file mode 100644 index cc1fdc2..0000000 --- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/util/FileUtils7Test.java +++ /dev/null
@@ -1,99 +0,0 @@ -/* - * Copyright (C) 2013, Robin Rosenberg <robin.rosenberg@dewire.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.util; - -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertTrue; - -import java.io.File; -import java.io.IOException; -import java.nio.file.Files; -import java.nio.file.StandardCopyOption; - -import org.junit.After; -import org.junit.Before; -import org.junit.Test; - -public class FileUtils7Test { - - private final File trash = new File(new File("target"), "trash"); - - @Before - public void setUp() throws Exception { - FileUtils.delete(trash, FileUtils.RECURSIVE | FileUtils.RETRY | FileUtils.SKIP_MISSING); - assertTrue(trash.mkdirs()); - } - - @After - public void tearDown() throws Exception { - FileUtils.delete(trash, FileUtils.RECURSIVE | FileUtils.RETRY); - } - - @Test - public void testDeleteSymlinkToDirectoryDoesNotDeleteTarget() - throws IOException { - org.junit.Assume.assumeTrue(FS.DETECTED.supportsSymlinks()); - FS fs = FS.DETECTED; - File dir = new File(trash, "dir"); - File file = new File(dir, "file"); - File link = new File(trash, "link"); - FileUtils.mkdirs(dir); - FileUtils.createNewFile(file); - fs.createSymLink(link, "dir"); - FileUtils.delete(link, FileUtils.RECURSIVE); - assertFalse(link.exists()); - assertTrue(dir.exists()); - assertTrue(file.exists()); - } - - @Test - public void testAtomicMove() throws IOException { - File src = new File(trash, "src"); - Files.createFile(src.toPath()); - File dst = new File(trash, "dst"); - FileUtils.rename(src, dst, StandardCopyOption.ATOMIC_MOVE); - assertFalse(Files.exists(src.toPath())); - assertTrue(Files.exists(dst.toPath())); - } -}
diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/util/FileUtilTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/util/FileUtilsTest.java similarity index 87% rename from org.eclipse.jgit.test/tst/org/eclipse/jgit/util/FileUtilTest.java rename to org.eclipse.jgit.test/tst/org/eclipse/jgit/util/FileUtilsTest.java index 1f78e02..109d0e6 100644 --- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/util/FileUtilTest.java +++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/util/FileUtilsTest.java
@@ -50,15 +50,32 @@ import java.io.File; import java.io.IOException; +import java.io.UnsupportedEncodingException; +import java.nio.file.Files; +import java.nio.file.StandardCopyOption; +import java.rmi.RemoteException; import java.util.regex.Matcher; +import javax.management.remote.JMXProviderException; + import org.eclipse.jgit.junit.JGitTestUtil; import org.junit.After; import org.junit.Assume; import org.junit.Before; import org.junit.Test; -public class FileUtilTest { +public class FileUtilsTest { + private static final String MSG = "Stale file handle"; + + private static final String SOME_ERROR_MSG = "some error message"; + + private static final IOException IO_EXCEPTION = new UnsupportedEncodingException( + MSG); + + private static final IOException IO_EXCEPTION_WITH_CAUSE = new RemoteException( + SOME_ERROR_MSG, + new JMXProviderException(SOME_ERROR_MSG, IO_EXCEPTION)); + private File trash; @Before @@ -508,8 +525,60 @@ public void testRelativize_whitespaces() { assertEquals(expected, actual); } + @Test + public void testDeleteSymlinkToDirectoryDoesNotDeleteTarget() + throws IOException { + org.junit.Assume.assumeTrue(FS.DETECTED.supportsSymlinks()); + FS fs = FS.DETECTED; + File dir = new File(trash, "dir"); + File file = new File(dir, "file"); + File link = new File(trash, "link"); + FileUtils.mkdirs(dir); + FileUtils.createNewFile(file); + fs.createSymLink(link, "dir"); + FileUtils.delete(link, FileUtils.RECURSIVE); + assertFalse(link.exists()); + assertTrue(dir.exists()); + assertTrue(file.exists()); + } + + @Test + public void testAtomicMove() throws IOException { + File src = new File(trash, "src"); + Files.createFile(src.toPath()); + File dst = new File(trash, "dst"); + FileUtils.rename(src, dst, StandardCopyOption.ATOMIC_MOVE); + assertFalse(Files.exists(src.toPath())); + assertTrue(Files.exists(dst.toPath())); + } + private String toOSPathString(String path) { return path.replaceAll("/|\\\\", Matcher.quoteReplacement(File.separator)); } + + @Test + public void testIsStaleFileHandleWithDirectCause() throws Exception { + assertTrue(FileUtils.isStaleFileHandle(IO_EXCEPTION)); + } + + @Test + public void testIsStaleFileHandleWithIndirectCause() throws Exception { + assertFalse( + FileUtils.isStaleFileHandle(IO_EXCEPTION_WITH_CAUSE)); + } + + @Test + public void testIsStaleFileHandleInCausalChainWithDirectCause() + throws Exception { + assertTrue( + FileUtils.isStaleFileHandleInCausalChain(IO_EXCEPTION)); + } + + @Test + public void testIsStaleFileHandleInCausalChainWithIndirectCause() + throws Exception { + assertTrue(FileUtils + .isStaleFileHandleInCausalChain(IO_EXCEPTION_WITH_CAUSE)); + } }
diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/util/ReadLinesTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/util/ReadLinesTest.java index 1fe3dbd..796af99 100644 --- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/util/ReadLinesTest.java +++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/util/ReadLinesTest.java
@@ -51,7 +51,7 @@ import org.junit.Test; public class ReadLinesTest { - List<String> l = new ArrayList<String>(); + List<String> l = new ArrayList<>(); @Before public void clearList() {
diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/util/RefListTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/util/RefListTest.java index 4b7ab26..5a1468a 100644 --- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/util/RefListTest.java +++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/util/RefListTest.java
@@ -89,7 +89,7 @@ public void testEmpty() { @Test public void testEmptyBuilder() { - RefList<Ref> list = new RefList.Builder<Ref>().toRefList(); + RefList<Ref> list = new RefList.Builder<>().toRefList(); assertEquals(0, list.size()); assertFalse(list.iterator().hasNext()); assertEquals(-1, list.find("a")); @@ -111,7 +111,7 @@ public void testEmptyBuilder() { @Test public void testBuilder_AddThenSort() { - RefList.Builder<Ref> builder = new RefList.Builder<Ref>(1); + RefList.Builder<Ref> builder = new RefList.Builder<>(1); builder.add(REF_B); builder.add(REF_A); @@ -129,7 +129,7 @@ public void testBuilder_AddThenSort() { @Test public void testBuilder_AddAll() { - RefList.Builder<Ref> builder = new RefList.Builder<Ref>(1); + RefList.Builder<Ref> builder = new RefList.Builder<>(1); Ref[] src = { REF_A, REF_B, REF_c, REF_A }; builder.addAll(src, 1, 2); @@ -141,7 +141,7 @@ public void testBuilder_AddAll() { @Test public void testBuilder_Set() { - RefList.Builder<Ref> builder = new RefList.Builder<Ref>(); + RefList.Builder<Ref> builder = new RefList.Builder<>(); builder.add(REF_A); builder.add(REF_A); @@ -163,7 +163,7 @@ public void testBuilder_Set() { @Test public void testBuilder_Remove() { - RefList.Builder<Ref> builder = new RefList.Builder<Ref>(); + RefList.Builder<Ref> builder = new RefList.Builder<>(); builder.add(REF_A); builder.add(REF_B); builder.remove(0); @@ -364,7 +364,7 @@ public void testBuilder_ToString() { exp.append(REF_B); exp.append("]"); - RefList.Builder<Ref> list = new RefList.Builder<Ref>(); + RefList.Builder<Ref> list = new RefList.Builder<>(); list.add(REF_A); list.add(REF_B); assertEquals(exp.toString(), list.toString()); @@ -442,16 +442,16 @@ public void testCopyLeadingPrefix() { @Test public void testCopyConstructorReusesArray() { - RefList.Builder<Ref> one = new RefList.Builder<Ref>(); + RefList.Builder<Ref> one = new RefList.Builder<>(); one.add(REF_A); - RefList<Ref> two = new RefList<Ref>(one.toRefList()); + RefList<Ref> two = new RefList<>(one.toRefList()); one.set(0, REF_B); assertSame(REF_B, two.get(0)); } private static RefList<Ref> toList(Ref... refs) { - RefList.Builder<Ref> b = new RefList.Builder<Ref>(refs.length); + RefList.Builder<Ref> b = new RefList.Builder<>(refs.length); b.addAll(refs, 0, refs.length); return b.toRefList(); }
diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/util/RefMapTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/util/RefMapTest.java index 78ab27a..e6402a4 100644 --- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/util/RefMapTest.java +++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/util/RefMapTest.java
@@ -481,7 +481,7 @@ public void testEntryTypeSet() { } private static RefList<Ref> toList(Ref... refs) { - RefList.Builder<Ref> b = new RefList.Builder<Ref>(refs.length); + RefList.Builder<Ref> b = new RefList.Builder<>(refs.length); b.addAll(refs, 0, refs.length); return b.toRefList(); }
diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/util/io/UnionInputStreamTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/util/io/UnionInputStreamTest.java index c213157..6b5ef7e 100644 --- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/util/io/UnionInputStreamTest.java +++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/util/io/UnionInputStreamTest.java
@@ -166,6 +166,7 @@ public void testSkip() throws IOException { assertEquals(-1, u.read()); u.add(new ByteArrayInputStream(new byte[] { 20, 30 }) { + @Override public long skip(long n) { return 0; } @@ -180,11 +181,13 @@ public void testAutoCloseDuringRead() throws IOException { final UnionInputStream u = new UnionInputStream(); final boolean closed[] = new boolean[2]; u.add(new ByteArrayInputStream(new byte[] { 1 }) { + @Override public void close() { closed[0] = true; } }); u.add(new ByteArrayInputStream(new byte[] { 2 }) { + @Override public void close() { closed[1] = true; } @@ -211,11 +214,13 @@ public void testCloseDuringClose() throws IOException { final UnionInputStream u = new UnionInputStream(); final boolean closed[] = new boolean[2]; u.add(new ByteArrayInputStream(new byte[] { 1 }) { + @Override public void close() { closed[0] = true; } }); u.add(new ByteArrayInputStream(new byte[] { 2 }) { + @Override public void close() { closed[1] = true; } @@ -234,6 +239,7 @@ public void close() { public void testExceptionDuringClose() { final UnionInputStream u = new UnionInputStream(); u.add(new ByteArrayInputStream(new byte[] { 1 }) { + @Override public void close() throws IOException { throw new IOException("I AM A TEST"); }
diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/util/sha1/SHA1Test.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/util/sha1/SHA1Test.java new file mode 100644 index 0000000..0778989 --- /dev/null +++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/util/sha1/SHA1Test.java
@@ -0,0 +1,238 @@ +/* + * 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.util.sha1; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; +import static org.junit.Assume.assumeTrue; + +import java.io.IOException; +import java.io.InputStream; +import java.nio.ByteBuffer; +import java.nio.charset.StandardCharsets; +import java.security.MessageDigest; +import java.security.NoSuchAlgorithmException; + +import org.eclipse.jgit.lib.Constants; +import org.eclipse.jgit.lib.ObjectId; +import org.eclipse.jgit.util.IO; +import org.junit.Test; + +public class SHA1Test { + private static final String TEST1 = "abc"; + + private static final String TEST2a = "abcdbcdecdefdefgefghfghighijhi"; + private static final String TEST2b = "jkijkljklmklmnlmnomnopnopq"; + private static final String TEST2 = TEST2a + TEST2b; + + @Test + public void test0() throws NoSuchAlgorithmException { + ObjectId exp = ObjectId + .fromString("da39a3ee5e6b4b0d3255bfef95601890afd80709"); + + MessageDigest m = MessageDigest.getInstance("SHA-1"); + m.update(new byte[] {}); + ObjectId m1 = ObjectId.fromRaw(m.digest()); + + SHA1 s = SHA1.newInstance(); + s.update(new byte[] {}); + ObjectId s1 = ObjectId.fromRaw(s.digest()); + + s.reset(); + s.update(new byte[] {}); + ObjectId s2 = s.toObjectId(); + + assertEquals(m1, s1); + assertEquals(exp, s1); + assertEquals(exp, s2); + } + + @Test + public void test1() throws NoSuchAlgorithmException { + ObjectId exp = ObjectId + .fromString("a9993e364706816aba3e25717850c26c9cd0d89d"); + + MessageDigest m = MessageDigest.getInstance("SHA-1"); + m.update(TEST1.getBytes(StandardCharsets.UTF_8)); + ObjectId m1 = ObjectId.fromRaw(m.digest()); + + SHA1 s = SHA1.newInstance(); + s.update(TEST1.getBytes(StandardCharsets.UTF_8)); + ObjectId s1 = ObjectId.fromRaw(s.digest()); + + s.reset(); + s.update(TEST1.getBytes(StandardCharsets.UTF_8)); + ObjectId s2 = s.toObjectId(); + + assertEquals(m1, s1); + assertEquals(exp, s1); + assertEquals(exp, s2); + } + + @Test + public void test2() throws NoSuchAlgorithmException { + ObjectId exp = ObjectId + .fromString("84983e441c3bd26ebaae4aa1f95129e5e54670f1"); + + MessageDigest m = MessageDigest.getInstance("SHA-1"); + m.update(TEST2.getBytes(StandardCharsets.UTF_8)); + ObjectId m1 = ObjectId.fromRaw(m.digest()); + + SHA1 s = SHA1.newInstance(); + s.update(TEST2.getBytes(StandardCharsets.UTF_8)); + ObjectId s1 = ObjectId.fromRaw(s.digest()); + + s.reset(); + s.update(TEST2.getBytes(StandardCharsets.UTF_8)); + ObjectId s2 = s.toObjectId(); + + assertEquals(m1, s1); + assertEquals(exp, s1); + assertEquals(exp, s2); + } + + @Test + public void shatteredCollision() + throws IOException, NoSuchAlgorithmException { + byte[] pdf1 = read("shattered-1.pdf", 422435); + byte[] pdf2 = read("shattered-2.pdf", 422435); + MessageDigest md; + SHA1 s; + + // SHAttered attack generated these PDFs to have identical SHA-1. + ObjectId bad = ObjectId + .fromString("38762cf7f55934b34d179ae6a4c80cadccbb7f0a"); + md = MessageDigest.getInstance("SHA-1"); + md.update(pdf1); + assertEquals("shattered-1 collides", bad, + ObjectId.fromRaw(md.digest())); + s = SHA1.newInstance().setDetectCollision(false); + s.update(pdf1); + assertEquals("shattered-1 collides", bad, s.toObjectId()); + + md = MessageDigest.getInstance("SHA-1"); + md.update(pdf2); + assertEquals("shattered-2 collides", bad, + ObjectId.fromRaw(md.digest())); + s = SHA1.newInstance().setDetectCollision(false); + s.update(pdf2); + assertEquals("shattered-2 collides", bad, s.toObjectId()); + + // SHA1 with detectCollision shouldn't be fooled. + s = SHA1.newInstance().setDetectCollision(true); + s.update(pdf1); + try { + s.digest(); + fail("expected " + Sha1CollisionException.class.getSimpleName()); + } catch (Sha1CollisionException e) { + assertEquals(e.getMessage(), + "SHA-1 collision detected on " + bad.name()); + } + + s = SHA1.newInstance().setDetectCollision(true); + s.update(pdf2); + try { + s.digest(); + fail("expected " + Sha1CollisionException.class.getSimpleName()); + } catch (Sha1CollisionException e) { + assertEquals(e.getMessage(), + "SHA-1 collision detected on " + bad.name()); + } + } + + @Test + public void shatteredStoredInGitBlob() throws IOException { + byte[] pdf1 = read("shattered-1.pdf", 422435); + byte[] pdf2 = read("shattered-2.pdf", 422435); + + // Although the prior test detects the chance of a collision, adding + // the Git blob header permutes the data enough for this specific + // attack example to not be detected as a collision. (A different file + // pair that takes the Git header into account however, would.) + ObjectId id1 = blob(pdf1, SHA1.newInstance().setDetectCollision(true)); + ObjectId id2 = blob(pdf2, SHA1.newInstance().setDetectCollision(true)); + + assertEquals( + ObjectId.fromString("ba9aaa145ccd24ef760cf31c74d8f7ca1a2e47b0"), + id1); + assertEquals( + ObjectId.fromString("b621eeccd5c7edac9b7dcba35a8d5afd075e24f2"), + id2); + } + + @Test + public void detectsShatteredByDefault() throws IOException { + assumeTrue(System.getProperty("org.eclipse.jgit.util.sha1.detectCollision") == null); + assumeTrue(System.getProperty("org.eclipse.jgit.util.sha1.safeHash") == null); + + byte[] pdf1 = read("shattered-1.pdf", 422435); + SHA1 s = SHA1.newInstance(); + s.update(pdf1); + try { + s.digest(); + fail("expected " + Sha1CollisionException.class.getSimpleName()); + } catch (Sha1CollisionException e) { + assertTrue("shattered-1 detected", true); + } + } + + private static ObjectId blob(byte[] pdf1, SHA1 s) { + s.update(Constants.encodedTypeString(Constants.OBJ_BLOB)); + s.update((byte) ' '); + s.update(Constants.encodeASCII(pdf1.length)); + s.update((byte) 0); + s.update(pdf1); + return s.toObjectId(); + } + + private byte[] read(String name, int sizeHint) throws IOException { + try (InputStream in = getClass().getResourceAsStream(name)) { + ByteBuffer buf = IO.readWholeStream(in, sizeHint); + byte[] r = new byte[buf.remaining()]; + buf.get(r); + return r; + } + } +}
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 808ec3a..ede0f7d 100644 --- a/org.eclipse.jgit.ui/.settings/org.eclipse.jdt.core.prefs +++ b/org.eclipse.jgit.ui/.settings/org.eclipse.jdt.core.prefs
@@ -56,7 +56,7 @@ org.eclipse.jdt.core.compiler.problem.missingJavadocTagsMethodTypeParameters=disabled org.eclipse.jdt.core.compiler.problem.missingJavadocTagsOverriding=disabled org.eclipse.jdt.core.compiler.problem.missingJavadocTagsVisibility=private -org.eclipse.jdt.core.compiler.problem.missingOverrideAnnotation=ignore +org.eclipse.jdt.core.compiler.problem.missingOverrideAnnotation=warning org.eclipse.jdt.core.compiler.problem.missingOverrideAnnotationForInterfaceMethodImplementation=enabled org.eclipse.jdt.core.compiler.problem.missingSerialVersion=warning org.eclipse.jdt.core.compiler.problem.missingSynchronizedOnInheritedMethod=ignore @@ -76,7 +76,7 @@ org.eclipse.jdt.core.compiler.problem.rawTypeReference=ignore org.eclipse.jdt.core.compiler.problem.redundantNullAnnotation=warning org.eclipse.jdt.core.compiler.problem.redundantNullCheck=warning -org.eclipse.jdt.core.compiler.problem.redundantSpecificationOfTypeArguments=ignore +org.eclipse.jdt.core.compiler.problem.redundantSpecificationOfTypeArguments=warning org.eclipse.jdt.core.compiler.problem.redundantSuperinterface=error org.eclipse.jdt.core.compiler.problem.reportMethodCanBePotentiallyStatic=ignore org.eclipse.jdt.core.compiler.problem.reportMethodCanBeStatic=ignore
diff --git a/org.eclipse.jgit.ui/BUCK b/org.eclipse.jgit.ui/BUCK deleted file mode 100644 index fcd87cf..0000000 --- a/org.eclipse.jgit.ui/BUCK +++ /dev/null
@@ -1,7 +0,0 @@ -java_library( - name = 'ui', - srcs = glob(['src/**']), - resources = glob(['resources/**']), - deps = ['//org.eclipse.jgit:jgit'], - visibility = ['PUBLIC'], -)
diff --git a/org.eclipse.jgit.ui/BUILD b/org.eclipse.jgit.ui/BUILD new file mode 100644 index 0000000..85ae5c0 --- /dev/null +++ b/org.eclipse.jgit.ui/BUILD
@@ -0,0 +1,9 @@ +package(default_visibility = ["//visibility:public"]) + +java_library( + name = "ui", + srcs = glob(["src/**"]), + resource_strip_prefix = "org.eclipse.jgit.ui/resources", + resources = glob(["resources/**"]), + deps = ["//org.eclipse.jgit:jgit"], +)
diff --git a/org.eclipse.jgit.ui/META-INF/MANIFEST.MF b/org.eclipse.jgit.ui/META-INF/MANIFEST.MF index 667e3b2..a290cd1 100644 --- a/org.eclipse.jgit.ui/META-INF/MANIFEST.MF +++ b/org.eclipse.jgit.ui/META-INF/MANIFEST.MF
@@ -3,14 +3,14 @@ Bundle-ManifestVersion: 2 Bundle-Name: %plugin_name Bundle-SymbolicName: org.eclipse.jgit.ui -Bundle-Version: 4.6.2.qualifier +Bundle-Version: 4.7.6.qualifier Bundle-Vendor: %provider_name Bundle-RequiredExecutionEnvironment: JavaSE-1.8 -Export-Package: org.eclipse.jgit.awtui;version="4.6.2" -Import-Package: org.eclipse.jgit.errors;version="[4.6.2,4.7.0)", - org.eclipse.jgit.lib;version="[4.6.2,4.7.0)", - org.eclipse.jgit.nls;version="[4.6.2,4.7.0)", - org.eclipse.jgit.revplot;version="[4.6.2,4.7.0)", - org.eclipse.jgit.revwalk;version="[4.6.2,4.7.0)", - org.eclipse.jgit.transport;version="[4.6.2,4.7.0)", - org.eclipse.jgit.util;version="[4.6.2,4.7.0)" +Export-Package: org.eclipse.jgit.awtui;version="4.7.6" +Import-Package: org.eclipse.jgit.errors;version="[4.7.6,4.8.0)", + org.eclipse.jgit.lib;version="[4.7.6,4.8.0)", + org.eclipse.jgit.nls;version="[4.7.6,4.8.0)", + org.eclipse.jgit.revplot;version="[4.7.6,4.8.0)", + org.eclipse.jgit.revwalk;version="[4.7.6,4.8.0)", + org.eclipse.jgit.transport;version="[4.7.6,4.8.0)", + org.eclipse.jgit.util;version="[4.7.6,4.8.0)"
diff --git a/org.eclipse.jgit.ui/pom.xml b/org.eclipse.jgit.ui/pom.xml index 280399b..fb13760 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>4.6.2-SNAPSHOT</version> + <version>4.7.6-SNAPSHOT</version> </parent> <artifactId>org.eclipse.jgit.ui</artifactId>
diff --git a/org.eclipse.jgit.ui/src/org/eclipse/jgit/awtui/CommitGraphPane.java b/org.eclipse.jgit.ui/src/org/eclipse/jgit/awtui/CommitGraphPane.java index 4d32235..4c8cf53 100644 --- a/org.eclipse.jgit.ui/src/org/eclipse/jgit/awtui/CommitGraphPane.java +++ b/org.eclipse.jgit.ui/src/org/eclipse/jgit/awtui/CommitGraphPane.java
@@ -146,14 +146,17 @@ class CommitTableModel extends AbstractTableModel { PersonIdent lastAuthor; + @Override public int getColumnCount() { return 3; } + @Override public int getRowCount() { return allCommits != null ? allCommits.size() : 0; } + @Override public Object getValueAt(final int rowIndex, final int columnIndex) { final PlotCommit<SwingLane> c = allCommits.get(rowIndex); switch (columnIndex) { @@ -180,6 +183,7 @@ PersonIdent authorFor(final PlotCommit<SwingLane> c) { static class NameCellRender extends DefaultTableCellRenderer { private static final long serialVersionUID = 1L; + @Override public Component getTableCellRendererComponent(final JTable table, final Object value, final boolean isSelected, final boolean hasFocus, final int row, final int column) { @@ -201,6 +205,7 @@ static class DateCellRender extends DefaultTableCellRenderer { private final DateFormat fmt = new SimpleDateFormat( "yyyy-MM-dd HH:mm:ss"); //$NON-NLS-1$ + @Override public Component getTableCellRendererComponent(final JTable table, final Object value, final boolean isSelected, final boolean hasFocus, final int row, final int column) { @@ -223,6 +228,7 @@ static class GraphCellRender extends DefaultTableCellRenderer { PlotCommit<SwingLane> commit; + @Override @SuppressWarnings("unchecked") public Component getTableCellRendererComponent(final JTable table, final Object value, final boolean isSelected,
diff --git a/org.eclipse.jgit.ui/src/org/eclipse/jgit/awtui/SwingCommitList.java b/org.eclipse.jgit.ui/src/org/eclipse/jgit/awtui/SwingCommitList.java index 7359093..fe0c486 100644 --- a/org.eclipse.jgit.ui/src/org/eclipse/jgit/awtui/SwingCommitList.java +++ b/org.eclipse.jgit.ui/src/org/eclipse/jgit/awtui/SwingCommitList.java
@@ -53,7 +53,7 @@ class SwingCommitList extends PlotCommitList<SwingCommitList.SwingLane> { final LinkedList<Color> colors; SwingCommitList() { - colors = new LinkedList<Color>(); + colors = new LinkedList<>(); repackColors(); }
diff --git a/org.eclipse.jgit/.settings/.api_filters b/org.eclipse.jgit/.settings/.api_filters index c6af42e..81aa9c2 100644 --- a/org.eclipse.jgit/.settings/.api_filters +++ b/org.eclipse.jgit/.settings/.api_filters
@@ -3,35 +3,8 @@ <resource path="META-INF/MANIFEST.MF"> <filter id="924844039"> <message_arguments> - <message_argument value="4.6.2"/> - <message_argument value="4.6.0"/> - </message_arguments> - </filter> - </resource> - <resource path="src/org/eclipse/jgit/errors/NoPackSignatureException.java" type="org.eclipse.jgit.errors.NoPackSignatureException"> - <filter id="1108344834"> - <message_arguments> - <message_argument value="4.5"/> - <message_argument value="4.6"/> - <message_argument value="org.eclipse.jgit.errors.NoPackSignatureException"/> - </message_arguments> - </filter> - </resource> - <resource path="src/org/eclipse/jgit/errors/UnsupportedPackIndexVersionException.java" type="org.eclipse.jgit.errors.UnsupportedPackIndexVersionException"> - <filter id="1108344834"> - <message_arguments> - <message_argument value="4.5"/> - <message_argument value="4.6"/> - <message_argument value="org.eclipse.jgit.errors.UnsupportedPackIndexVersionException"/> - </message_arguments> - </filter> - </resource> - <resource path="src/org/eclipse/jgit/errors/UnsupportedPackVersionException.java" type="org.eclipse.jgit.errors.UnsupportedPackVersionException"> - <filter id="1108344834"> - <message_arguments> - <message_argument value="4.5"/> - <message_argument value="4.6"/> - <message_argument value="org.eclipse.jgit.errors.UnsupportedPackVersionException"/> + <message_argument value="4.7.5"/> + <message_argument value="4.7.0"/> </message_arguments> </filter> </resource> @@ -39,29 +12,57 @@ <filter id="336658481"> <message_arguments> <message_argument value="org.eclipse.jgit.lib.ConfigConstants"/> + <message_argument value="CONFIG_KEY_AUTODETACH"/> + </message_arguments> + </filter> + <filter id="336658481"> + <message_arguments> + <message_argument value="org.eclipse.jgit.lib.ConfigConstants"/> + <message_argument value="CONFIG_KEY_LOGEXPIRY"/> + </message_arguments> + </filter> + <filter id="336658481"> + <message_arguments> + <message_argument value="org.eclipse.jgit.lib.ConfigConstants"/> <message_argument value="CONFIG_KEY_SUPPORTSATOMICFILECREATION"/> </message_arguments> </filter> <filter id="1141899266"> <message_arguments> <message_argument value="4.5"/> - <message_argument value="4.6"/> + <message_argument value="4.7"/> <message_argument value="CONFIG_KEY_SUPPORTSATOMICFILECREATION"/> </message_arguments> </filter> </resource> + <resource path="src/org/eclipse/jgit/lib/GitmoduleEntry.java" type="org.eclipse.jgit.lib.GitmoduleEntry"> + <filter id="1109393411"> + <message_arguments> + <message_argument value="4.7.5"/> + <message_argument value="org.eclipse.jgit.lib.GitmoduleEntry"/> + </message_arguments> + </filter> + </resource> + <resource path="src/org/eclipse/jgit/lib/ObjectChecker.java" type="org.eclipse.jgit.lib.ObjectChecker"> + <filter id="1142947843"> + <message_arguments> + <message_argument value="4.7.5"/> + <message_argument value="getGitsubmodules()"/> + </message_arguments> + </filter> + </resource> <resource path="src/org/eclipse/jgit/util/FS.java" type="org.eclipse.jgit.util.FS"> <filter id="1141899266"> <message_arguments> <message_argument value="4.5"/> - <message_argument value="4.6"/> + <message_argument value="4.7"/> <message_argument value="createNewFile(File)"/> </message_arguments> </filter> <filter id="1141899266"> <message_arguments> <message_argument value="4.5"/> - <message_argument value="4.6"/> + <message_argument value="4.7"/> <message_argument value="supportsAtomicCreateNewFile()"/> </message_arguments> </filter>
diff --git a/org.eclipse.jgit/.settings/org.eclipse.jdt.core.prefs b/org.eclipse.jgit/.settings/org.eclipse.jdt.core.prefs index 4f1759f..06ddbab 100644 --- a/org.eclipse.jgit/.settings/org.eclipse.jdt.core.prefs +++ b/org.eclipse.jgit/.settings/org.eclipse.jdt.core.prefs
@@ -56,7 +56,7 @@ org.eclipse.jdt.core.compiler.problem.missingJavadocTagsMethodTypeParameters=disabled org.eclipse.jdt.core.compiler.problem.missingJavadocTagsOverriding=disabled org.eclipse.jdt.core.compiler.problem.missingJavadocTagsVisibility=private -org.eclipse.jdt.core.compiler.problem.missingOverrideAnnotation=ignore +org.eclipse.jdt.core.compiler.problem.missingOverrideAnnotation=warning org.eclipse.jdt.core.compiler.problem.missingOverrideAnnotationForInterfaceMethodImplementation=enabled org.eclipse.jdt.core.compiler.problem.missingSerialVersion=warning org.eclipse.jdt.core.compiler.problem.missingSynchronizedOnInheritedMethod=ignore @@ -76,7 +76,7 @@ org.eclipse.jdt.core.compiler.problem.rawTypeReference=ignore org.eclipse.jdt.core.compiler.problem.redundantNullAnnotation=warning org.eclipse.jdt.core.compiler.problem.redundantNullCheck=warning -org.eclipse.jdt.core.compiler.problem.redundantSpecificationOfTypeArguments=ignore +org.eclipse.jdt.core.compiler.problem.redundantSpecificationOfTypeArguments=warning org.eclipse.jdt.core.compiler.problem.redundantSuperinterface=error org.eclipse.jdt.core.compiler.problem.reportMethodCanBePotentiallyStatic=ignore org.eclipse.jdt.core.compiler.problem.reportMethodCanBeStatic=ignore
diff --git a/org.eclipse.jgit/BUCK b/org.eclipse.jgit/BUCK deleted file mode 100644 index 2bae6dc..0000000 --- a/org.eclipse.jgit/BUCK +++ /dev/null
@@ -1,21 +0,0 @@ -SRCS = glob(['src/**']) -RESOURCES = glob(['resources/**']) - -java_library( - name = 'jgit', - srcs = SRCS, - resources = RESOURCES, - deps = [ - '//lib:javaewah', - '//lib:jsch', - '//lib:httpcomponents', - '//lib:servlet-api', - '//lib:slf4j-api', - ], - visibility = ['PUBLIC'], -) - -java_sources( - name = 'jgit_src', - srcs = SRCS + RESOURCES, -)
diff --git a/org.eclipse.jgit/BUILD b/org.eclipse.jgit/BUILD new file mode 100644 index 0000000..75f4fe6 --- /dev/null +++ b/org.eclipse.jgit/BUILD
@@ -0,0 +1,31 @@ +package(default_visibility = ["//visibility:public"]) + +INSECURE_CIPHER_FACTORY = [ + "src/org/eclipse/jgit/transport/InsecureCipherFactory.java", +] + +SRCS = glob( + ["src/**"], + exclude = INSECURE_CIPHER_FACTORY, +) + +RESOURCES = glob(["resources/**"]) + +java_library( + name = "jgit", + srcs = SRCS, + resource_strip_prefix = "org.eclipse.jgit/resources", + resources = RESOURCES, + deps = [ + ":insecure_cipher_factory", + "//lib:javaewah", + "//lib:jsch", + "//lib:slf4j-api", + ], +) + +java_library( + name = "insecure_cipher_factory", + srcs = INSECURE_CIPHER_FACTORY, + javacopts = ["-Xep:InsecureCryptoUsage:OFF"], +)
diff --git a/org.eclipse.jgit/META-INF/MANIFEST.MF b/org.eclipse.jgit/META-INF/MANIFEST.MF index 701efcf..1b1abd9 100644 --- a/org.eclipse.jgit/META-INF/MANIFEST.MF +++ b/org.eclipse.jgit/META-INF/MANIFEST.MF
@@ -2,12 +2,12 @@ Bundle-ManifestVersion: 2 Bundle-Name: %plugin_name Bundle-SymbolicName: org.eclipse.jgit -Bundle-Version: 4.6.2.qualifier +Bundle-Version: 4.7.6.qualifier Bundle-Localization: plugin Bundle-Vendor: %provider_name Bundle-ActivationPolicy: lazy -Export-Package: org.eclipse.jgit.annotations;version="4.6.2", - org.eclipse.jgit.api;version="4.6.2"; +Export-Package: org.eclipse.jgit.annotations;version="4.7.6", + org.eclipse.jgit.api;version="4.7.6"; uses:="org.eclipse.jgit.revwalk, org.eclipse.jgit.treewalk.filter, org.eclipse.jgit.diff, @@ -21,47 +21,51 @@ org.eclipse.jgit.submodule, org.eclipse.jgit.transport, org.eclipse.jgit.merge", - org.eclipse.jgit.api.errors;version="4.6.2";uses:="org.eclipse.jgit.lib,org.eclipse.jgit.errors", - org.eclipse.jgit.attributes;version="4.6.2", - org.eclipse.jgit.blame;version="4.6.2"; + org.eclipse.jgit.api.errors;version="4.7.6";uses:="org.eclipse.jgit.lib,org.eclipse.jgit.errors", + org.eclipse.jgit.attributes;version="4.7.6", + org.eclipse.jgit.blame;version="4.7.6"; uses:="org.eclipse.jgit.lib, org.eclipse.jgit.revwalk, org.eclipse.jgit.treewalk.filter, org.eclipse.jgit.diff", - org.eclipse.jgit.diff;version="4.6.2"; + org.eclipse.jgit.diff;version="4.7.6"; 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="4.6.2"; + org.eclipse.jgit.dircache;version="4.7.6"; 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="4.6.2"; + org.eclipse.jgit.errors;version="4.7.6"; uses:="org.eclipse.jgit.lib, org.eclipse.jgit.internal.storage.pack, org.eclipse.jgit.transport, org.eclipse.jgit.dircache", - org.eclipse.jgit.events;version="4.6.2";uses:="org.eclipse.jgit.lib", - org.eclipse.jgit.fnmatch;version="4.6.2", - org.eclipse.jgit.gitrepo;version="4.6.2"; + org.eclipse.jgit.events;version="4.7.6";uses:="org.eclipse.jgit.lib", + org.eclipse.jgit.fnmatch;version="4.7.6", + org.eclipse.jgit.gitrepo;version="4.7.6"; 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="4.6.2";x-internal:=true, - org.eclipse.jgit.hooks;version="4.6.2";uses:="org.eclipse.jgit.lib", - org.eclipse.jgit.ignore;version="4.6.2", - org.eclipse.jgit.ignore.internal;version="4.6.2";x-friends:="org.eclipse.jgit.test", - org.eclipse.jgit.internal;version="4.6.2";x-friends:="org.eclipse.jgit.test,org.eclipse.jgit.http.test", - org.eclipse.jgit.internal.ketch;version="4.6.2";x-friends:="org.eclipse.jgit.junit,org.eclipse.jgit.test,org.eclipse.jgit.pgm", - org.eclipse.jgit.internal.storage.dfs;version="4.6.2";x-friends:="org.eclipse.jgit.test,org.eclipse.jgit.http.server,org.eclipse.jgit.http.test", - org.eclipse.jgit.internal.storage.file;version="4.6.2"; + org.eclipse.jgit.gitrepo.internal;version="4.7.6";x-internal:=true, + org.eclipse.jgit.hooks;version="4.7.6";uses:="org.eclipse.jgit.lib", + org.eclipse.jgit.ignore;version="4.7.6", + org.eclipse.jgit.ignore.internal;version="4.7.6";x-friends:="org.eclipse.jgit.test", + org.eclipse.jgit.internal;version="4.7.6";x-friends:="org.eclipse.jgit.test,org.eclipse.jgit.http.test", + org.eclipse.jgit.internal.ketch;version="4.7.6";x-friends:="org.eclipse.jgit.junit,org.eclipse.jgit.test,org.eclipse.jgit.pgm", + org.eclipse.jgit.internal.storage.dfs;version="4.7.6"; + 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="4.7.6"; x-friends:="org.eclipse.jgit.test, org.eclipse.jgit.junit, org.eclipse.jgit.junit.http, @@ -69,9 +73,9 @@ org.eclipse.jgit.lfs, org.eclipse.jgit.pgm, org.eclipse.jgit.pgm.test", - org.eclipse.jgit.internal.storage.pack;version="4.6.2";x-friends:="org.eclipse.jgit.junit,org.eclipse.jgit.test,org.eclipse.jgit.pgm", - org.eclipse.jgit.internal.storage.reftree;version="4.6.2";x-friends:="org.eclipse.jgit.junit,org.eclipse.jgit.test,org.eclipse.jgit.pgm", - org.eclipse.jgit.lib;version="4.6.2"; + org.eclipse.jgit.internal.storage.pack;version="4.7.6";x-friends:="org.eclipse.jgit.junit,org.eclipse.jgit.test,org.eclipse.jgit.pgm", + org.eclipse.jgit.internal.storage.reftree;version="4.7.6";x-friends:="org.eclipse.jgit.junit,org.eclipse.jgit.test,org.eclipse.jgit.pgm", + org.eclipse.jgit.lib;version="4.7.6"; uses:="org.eclipse.jgit.revwalk, org.eclipse.jgit.treewalk.filter, org.eclipse.jgit.util, @@ -81,32 +85,32 @@ org.eclipse.jgit.treewalk, org.eclipse.jgit.transport, org.eclipse.jgit.submodule", - org.eclipse.jgit.merge;version="4.6.2"; + org.eclipse.jgit.merge;version="4.7.6"; 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="4.6.2", - org.eclipse.jgit.notes;version="4.6.2"; + org.eclipse.jgit.nls;version="4.7.6", + org.eclipse.jgit.notes;version="4.7.6"; uses:="org.eclipse.jgit.lib, org.eclipse.jgit.treewalk, org.eclipse.jgit.revwalk, org.eclipse.jgit.merge", - org.eclipse.jgit.patch;version="4.6.2";uses:="org.eclipse.jgit.lib,org.eclipse.jgit.diff", - org.eclipse.jgit.revplot;version="4.6.2";uses:="org.eclipse.jgit.lib,org.eclipse.jgit.revwalk", - org.eclipse.jgit.revwalk;version="4.6.2"; + org.eclipse.jgit.patch;version="4.7.6";uses:="org.eclipse.jgit.lib,org.eclipse.jgit.diff", + org.eclipse.jgit.revplot;version="4.7.6";uses:="org.eclipse.jgit.lib,org.eclipse.jgit.revwalk", + org.eclipse.jgit.revwalk;version="4.7.6"; 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="4.6.2";uses:="org.eclipse.jgit.revwalk,org.eclipse.jgit.lib,org.eclipse.jgit.util", - org.eclipse.jgit.storage.file;version="4.6.2";uses:="org.eclipse.jgit.lib,org.eclipse.jgit.util", - org.eclipse.jgit.storage.pack;version="4.6.2";uses:="org.eclipse.jgit.lib", - org.eclipse.jgit.submodule;version="4.6.2";uses:="org.eclipse.jgit.lib,org.eclipse.jgit.treewalk.filter,org.eclipse.jgit.treewalk", - org.eclipse.jgit.transport;version="4.6.2"; + org.eclipse.jgit.revwalk.filter;version="4.7.6";uses:="org.eclipse.jgit.revwalk,org.eclipse.jgit.lib,org.eclipse.jgit.util", + org.eclipse.jgit.storage.file;version="4.7.6";uses:="org.eclipse.jgit.lib,org.eclipse.jgit.util", + org.eclipse.jgit.storage.pack;version="4.7.6";uses:="org.eclipse.jgit.lib", + org.eclipse.jgit.submodule;version="4.7.6";uses:="org.eclipse.jgit.lib,org.eclipse.jgit.treewalk.filter,org.eclipse.jgit.treewalk", + org.eclipse.jgit.transport;version="4.7.6"; uses:="org.eclipse.jgit.transport.resolver, org.eclipse.jgit.revwalk, org.eclipse.jgit.internal.storage.pack, @@ -118,29 +122,29 @@ org.eclipse.jgit.transport.http, org.eclipse.jgit.errors, org.eclipse.jgit.storage.pack", - org.eclipse.jgit.transport.http;version="4.6.2";uses:="javax.net.ssl", - org.eclipse.jgit.transport.resolver;version="4.6.2";uses:="org.eclipse.jgit.lib,org.eclipse.jgit.transport", - org.eclipse.jgit.treewalk;version="4.6.2"; + org.eclipse.jgit.transport.http;version="4.7.6";uses:="javax.net.ssl", + org.eclipse.jgit.transport.resolver;version="4.7.6";uses:="org.eclipse.jgit.lib,org.eclipse.jgit.transport", + org.eclipse.jgit.treewalk;version="4.7.6"; 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="4.6.2";uses:="org.eclipse.jgit.treewalk", - org.eclipse.jgit.util;version="4.6.2"; + org.eclipse.jgit.treewalk.filter;version="4.7.6";uses:="org.eclipse.jgit.treewalk", + org.eclipse.jgit.util;version="4.7.6"; uses:="org.eclipse.jgit.lib, org.eclipse.jgit.transport.http, org.eclipse.jgit.storage.file, org.ietf.jgss", - org.eclipse.jgit.util.io;version="4.6.2", - org.eclipse.jgit.util.time;version="4.6.2" + org.eclipse.jgit.util.io;version="4.7.6", + org.eclipse.jgit.util.sha1;version="4.7.6", + org.eclipse.jgit.util.time;version="4.7.6" 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)", javax.crypto, javax.net.ssl, - javax.servlet.http;version="[2.5.0,3.2.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 c863b04..253e3a1 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: 4.6.2.qualifier -Eclipse-SourceBundle: org.eclipse.jgit;version="4.6.2.qualifier";roots="." +Bundle-Version: 4.7.6.qualifier +Eclipse-SourceBundle: org.eclipse.jgit;version="4.7.6.qualifier";roots="."
diff --git a/org.eclipse.jgit/about.html b/org.eclipse.jgit/about.html index 01a2671..f971af1 100644 --- a/org.eclipse.jgit/about.html +++ b/org.eclipse.jgit/about.html
@@ -21,6 +21,10 @@ margin-top: 0.05em; margin-bottom: 0.05em; } + .ubc-name { + margin-left: 0.5in; + white-space: pre; + } </style> </head> @@ -54,6 +58,39 @@ ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.</p> +<hr> +<p><b>SHA-1 UbcCheck - MIT</b></p> + +<p>Copyright (c) 2017:</p> +<div class="ubc-name"> +Marc Stevens +Cryptology Group +Centrum Wiskunde & Informatica +P.O. Box 94079, 1090 GB Amsterdam, Netherlands +marc@marc-stevens.nl +</div> +<div class="ubc-name"> +Dan Shumow +Microsoft Research +danshu@microsoft.com +</div> +<p>Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: +</p> +<ul><li>The above copyright notice and this permission notice shall be included +in all copies or substantial portions of the Software.</li></ul> +<p>THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE.</p> + </body> </html>
diff --git a/org.eclipse.jgit/pom.xml b/org.eclipse.jgit/pom.xml index 4e31e0b..ac335c3 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>4.6.2-SNAPSHOT</version> + <version>4.7.6-SNAPSHOT</version> </parent> <artifactId>org.eclipse.jgit</artifactId> @@ -89,11 +89,6 @@ <artifactId>slf4j-api</artifactId> </dependency> - <dependency> - <groupId>javax.servlet</groupId> - <artifactId>javax.servlet-api</artifactId> - <scope>provided</scope> - </dependency> </dependencies> <build>
diff --git a/org.eclipse.jgit/resources/org/eclipse/jgit/gitrepo/internal/RepoText.properties b/org.eclipse.jgit/resources/org/eclipse/jgit/gitrepo/internal/RepoText.properties index 7443ad3..e942038 100644 --- a/org.eclipse.jgit/resources/org/eclipse/jgit/gitrepo/internal/RepoText.properties +++ b/org.eclipse.jgit/resources/org/eclipse/jgit/gitrepo/internal/RepoText.properties
@@ -3,6 +3,7 @@ errorIncludeNotImplemented=Error: <include> tag not supported as no callback defined. errorNoDefault=Error: no default remote in manifest file. errorNoDefaultFilename=Error: no default remote in manifest file {0}. +errorNoFetch=Error: remote {0} is missing fetch attribute. errorParsingManifestFile=Error occurred during parsing manifest file. errorRemoteUnavailable=Error remote {0} is unavailable. invalidManifest=Invalid manifest.
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 cde45cf..55e786c 100644 --- a/org.eclipse.jgit/resources/org/eclipse/jgit/internal/JGitText.properties +++ b/org.eclipse.jgit/resources/org/eclipse/jgit/internal/JGitText.properties
@@ -31,6 +31,7 @@ badObjectType=Bad object type: {0} badRef=Bad ref: {0}: {1} badSectionEntry=Bad section entry: {0} +badShallowLine=Bad shallow line: {0} bareRepositoryNoWorkdirAndIndex=Bare Repository has neither a working tree, nor an index base64InputNotProperlyPadded=Base64 input not properly padded. baseLengthIncorrect=base length incorrect @@ -44,6 +45,7 @@ buildingBitmaps=Building bitmaps cachedPacksPreventsIndexCreation=Using cached packs prevents index creation cachedPacksPreventsListingObjects=Using cached packs prevents listing objects +cannotAccessLastModifiedForSafeDeletion=Unable to access lastModifiedTime of file {0}, skip deletion since we cannot safely avoid race condition cannotBeCombined=Cannot be combined. cannotBeRecursiveWhenTreesAreIncluded=TreeWalk shouldn't be recursive when tree objects are included. cannotChangeActionOnComment=Cannot change action on comment line in git-rebase-todo file, old action: {0}, new action: {1}. @@ -76,7 +78,7 @@ cannotListObjectsPath=Cannot ls {0}/{1}: {2} cannotListPackPath=Cannot ls {0}/pack: {1} cannotListRefs=cannot list refs -cannotLock=Cannot lock {0} +cannotLock=Cannot lock {0}. Ensure that no other process has an open file handle on the lock file {0}.lock, then you may delete the lock file and retry. cannotLockPackIn=Cannot lock pack in {0} cannotMatchOnEmptyString=Cannot match on empty string. cannotMkdirObjectPath=Cannot mkdir {0}/{1}: {2} @@ -117,6 +119,7 @@ classCastNotA=Not a {0} cloneNonEmptyDirectory=Destination path "{0}" already exists and is not an empty directory closed=closed +closeLockTokenFailed=Closing LockToken ''{0}'' failed collisionOn=Collision on {0} commandRejectedByHook=Rejected by "{0}" hook.\n{1} commandWasCalledInTheWrongState=Command {0} was called in the wrong state @@ -188,7 +191,7 @@ corruptObjectTruncatedInName=truncated in name corruptObjectTruncatedInObjectId=truncated in object id corruptObjectZeroId=entry points to null SHA-1 -corruptUseCnt=close() called when useCnt is already zero +corruptUseCnt=close() called when useCnt is already zero for {0} couldNotCheckOutBecauseOfConflicts=Could not check out because of conflicts couldNotDeleteLockFileShouldNotHappen=Could not delete lock file. Should not happen couldNotDeleteTemporaryIndexFileShouldNotHappen=Could not delete temporary index file. Should not happen @@ -282,6 +285,7 @@ expectedPktLineWithService=expected pkt-line with ''# service=-'', got ''{0}'' expectedReceivedContentType=expected Content-Type {0}; received Content-Type {1} 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}" failedToDetermineFilterDefinition=An exception occured while determining filter definitions failedUpdatingRefs=failed updating refs failureDueToOneOfTheFollowing=Failure due to one of the following: @@ -299,6 +303,8 @@ flagsAlreadyCreated={0} flags already created. funnyRefname=funny refname gcFailed=Garbage collection failed. +gcLogExists=A previous GC run reported an error: ''{0}''. Automatic gc will fail until ''{1}'' is removed. +gcTooManyUnpruned=Too many loose, unpruneable objects after garbage collection. Consider adjusting gc.auto or gc.pruneExpire. gitmodulesNotFound=.gitmodules not found in tree. headRequiredToStash=HEAD required to stash local changes hoursAgo={0} hours ago @@ -341,6 +347,7 @@ invalidEncryption=Invalid encryption invalidExpandWildcard=ExpandFromSource on a refspec that can have mismatched wildcards does not make sense. invalidGitdirRef = Invalid .git reference in file ''{0}'' +invalidGitModules=Invalid .gitmodules file invalidGitType=invalid git type: {0} invalidId=Invalid id: {0} invalidId0=Invalid id @@ -352,6 +359,7 @@ invalidLineInConfigFile=Invalid line in config file invalidModeFor=Invalid mode {0} for {1} {2} in {3}. invalidModeForPath=Invalid mode {0} for path {1} +invalidNameContainsDotDot=Invalid name (contains ".."): {0} invalidObject=Invalid {0} {1}: {2} invalidOldIdSent=invalid old id sent invalidPacketLineHeader=Invalid packet line header: {0} @@ -564,6 +572,7 @@ sequenceTooLargeForDiffAlgorithm=Sequence too large for difference algorithm. serviceNotEnabledNoName=Service not enabled serviceNotPermitted={0} not permitted +sha1CollisionDetected1=SHA-1 collision detected on {0} shallowCommitsAlreadyInitialized=Shallow commits have already been initialized shallowPacksRequireDepthWalk=Shallow packs require a DepthWalk shortCompressedStreamAt=Short compressed stream at {0} @@ -598,7 +607,10 @@ storePushCertOneRef=Store push certificate for {0} storePushCertReflog=Store push certificate submoduleExists=Submodule ''{0}'' already exists in the index +submoduleNameInvalid=Invalid submodule name ''{0}'' submoduleParentRemoteUrlInvalid=Cannot remove segment from remote url ''{0}'' +submodulePathInvalid=Invalid submodule path ''{0}'' +submoduleUrlInvalid=Invalid submodule URL ''{0}'' submodulesNotSupported=Submodules are not supported supportOnlyPackIndexVersion2=Only support index version 2 symlinkCannotBeWrittenAsTheLinkTarget=Symlink "{0}" cannot be written as the link target cannot be read from within Java. @@ -609,6 +621,7 @@ theFactoryMustNotBeNull=The factory must not be null timeIsUncertain=Time is uncertain timerAlreadyTerminated=Timer already terminated +tooManyCommands=Too many commands tooManyIncludeRecursions=Too many recursions; circular includes in config file(s)? topologicalSortRequired=Topological sort required. transactionAborted=transaction aborted @@ -639,6 +652,7 @@ tSizeMustBeGreaterOrEqual1=tSize must be >= 1 unableToCheckConnectivity=Unable to check connectivity. unableToCreateNewObject=Unable to create new object: {0} +unableToRemovePath=Unable to remove path ''{0}'' unableToStore=Unable to store {0}. unableToWrite=Unable to write {0} unauthorized=Unauthorized @@ -661,6 +675,7 @@ unknownRepositoryFormat=Unknown repository format unknownRepositoryFormat2=Unknown repository format "{0}"; expected "0". unknownZlibError=Unknown zlib error. +unlockLockFileFailed=Unlocking LockFile ''{0}'' failed unmergedPath=Unmerged path: {0} unmergedPaths=Repository contains unmerged paths unpackException=Exception while parsing pack stream
diff --git a/org.eclipse.jgit/resources/org/eclipse/jgit/util/sha1/SHA1.compress b/org.eclipse.jgit/resources/org/eclipse/jgit/util/sha1/SHA1.compress new file mode 100644 index 0000000..3a80fd2 --- /dev/null +++ b/org.eclipse.jgit/resources/org/eclipse/jgit/util/sha1/SHA1.compress
@@ -0,0 +1,92 @@ +/* Template for compress method; run through cpp. */ + +#define ROUND1_STEP(a, b, c, d, e, T) e += s1(a,b,c,d,w[T]); b = rotateLeft(b, 30) +#define ROUND2_STEP(a, b, c, d, e, T) e += s2(a,b,c,d,w[T]); b = rotateLeft(b, 30) +#define ROUND3_STEP(a, b, c, d, e, T) e += s3(a,b,c,d,w[T]); b = rotateLeft(b, 30) +#define ROUND4_STEP(a, b, c, d, e, T) e += s4(a,b,c,d,w[T]); b = rotateLeft(b, 30) + + ROUND1_STEP(a, b, c, d, e, 0); + ROUND1_STEP(e, a, b, c, d, 1); + ROUND1_STEP(d, e, a, b, c, 2); + ROUND1_STEP(c, d, e, a, b, 3); + ROUND1_STEP(b, c, d, e, a, 4); + ROUND1_STEP(a, b, c, d, e, 5); + ROUND1_STEP(e, a, b, c, d, 6); + ROUND1_STEP(d, e, a, b, c, 7); + ROUND1_STEP(c, d, e, a, b, 8); + ROUND1_STEP(b, c, d, e, a, 9); + ROUND1_STEP(a, b, c, d, e, 10); + ROUND1_STEP(e, a, b, c, d, 11); + ROUND1_STEP(d, e, a, b, c, 12); + ROUND1_STEP(c, d, e, a, b, 13); + ROUND1_STEP(b, c, d, e, a, 14); + ROUND1_STEP(a, b, c, d, e, 15); + ROUND1_STEP(e, a, b, c, d, 16); + ROUND1_STEP(d, e, a, b, c, 17); + ROUND1_STEP(c, d, e, a, b, 18); + ROUND1_STEP(b, c, d, e, a, 19); + + ROUND2_STEP(a, b, c, d, e, 20); + ROUND2_STEP(e, a, b, c, d, 21); + ROUND2_STEP(d, e, a, b, c, 22); + ROUND2_STEP(c, d, e, a, b, 23); + ROUND2_STEP(b, c, d, e, a, 24); + ROUND2_STEP(a, b, c, d, e, 25); + ROUND2_STEP(e, a, b, c, d, 26); + ROUND2_STEP(d, e, a, b, c, 27); + ROUND2_STEP(c, d, e, a, b, 28); + ROUND2_STEP(b, c, d, e, a, 29); + ROUND2_STEP(a, b, c, d, e, 30); + ROUND2_STEP(e, a, b, c, d, 31); + ROUND2_STEP(d, e, a, b, c, 32); + ROUND2_STEP(c, d, e, a, b, 33); + ROUND2_STEP(b, c, d, e, a, 34); + ROUND2_STEP(a, b, c, d, e, 35); + ROUND2_STEP(e, a, b, c, d, 36); + ROUND2_STEP(d, e, a, b, c, 37); + ROUND2_STEP(c, d, e, a, b, 38); + ROUND2_STEP(b, c, d, e, a, 39); + + ROUND3_STEP(a, b, c, d, e, 40); + ROUND3_STEP(e, a, b, c, d, 41); + ROUND3_STEP(d, e, a, b, c, 42); + ROUND3_STEP(c, d, e, a, b, 43); + ROUND3_STEP(b, c, d, e, a, 44); + ROUND3_STEP(a, b, c, d, e, 45); + ROUND3_STEP(e, a, b, c, d, 46); + ROUND3_STEP(d, e, a, b, c, 47); + ROUND3_STEP(c, d, e, a, b, 48); + ROUND3_STEP(b, c, d, e, a, 49); + ROUND3_STEP(a, b, c, d, e, 50); + ROUND3_STEP(e, a, b, c, d, 51); + ROUND3_STEP(d, e, a, b, c, 52); + ROUND3_STEP(c, d, e, a, b, 53); + ROUND3_STEP(b, c, d, e, a, 54); + ROUND3_STEP(a, b, c, d, e, 55); + ROUND3_STEP(e, a, b, c, d, 56); + ROUND3_STEP(d, e, a, b, c, 57); + state58.save(a, b, c, d, e); + ROUND3_STEP(c, d, e, a, b, 58); + ROUND3_STEP(b, c, d, e, a, 59); + + ROUND4_STEP(a, b, c, d, e, 60); + ROUND4_STEP(e, a, b, c, d, 61); + ROUND4_STEP(d, e, a, b, c, 62); + ROUND4_STEP(c, d, e, a, b, 63); + ROUND4_STEP(b, c, d, e, a, 64); + state65.save(a, b, c, d, e); + ROUND4_STEP(a, b, c, d, e, 65); + ROUND4_STEP(e, a, b, c, d, 66); + ROUND4_STEP(d, e, a, b, c, 67); + ROUND4_STEP(c, d, e, a, b, 68); + ROUND4_STEP(b, c, d, e, a, 69); + ROUND4_STEP(a, b, c, d, e, 70); + ROUND4_STEP(e, a, b, c, d, 71); + ROUND4_STEP(d, e, a, b, c, 72); + ROUND4_STEP(c, d, e, a, b, 73); + ROUND4_STEP(b, c, d, e, a, 74); + ROUND4_STEP(a, b, c, d, e, 75); + ROUND4_STEP(e, a, b, c, d, 76); + ROUND4_STEP(d, e, a, b, c, 77); + ROUND4_STEP(c, d, e, a, b, 78); + ROUND4_STEP(b, c, d, e, a, 79);
diff --git a/org.eclipse.jgit/resources/org/eclipse/jgit/util/sha1/SHA1.recompress b/org.eclipse.jgit/resources/org/eclipse/jgit/util/sha1/SHA1.recompress new file mode 100644 index 0000000..44d3d6d --- /dev/null +++ b/org.eclipse.jgit/resources/org/eclipse/jgit/util/sha1/SHA1.recompress
@@ -0,0 +1,192 @@ +/* Template for recompress method; run through cpp. */ + +#define ROUND1_STEP(a, b, c, d, e, T) {e += s1(a,b,c,d,w2[T]); b = rotateLeft(b, 30);} +#define ROUND2_STEP(a, b, c, d, e, T) {e += s2(a,b,c,d,w2[T]); b = rotateLeft(b, 30);} +#define ROUND3_STEP(a, b, c, d, e, T) {e += s3(a,b,c,d,w2[T]); b = rotateLeft(b, 30);} +#define ROUND4_STEP(a, b, c, d, e, T) {e += s4(a,b,c,d,w2[T]); b = rotateLeft(b, 30);} + +#define ROUND1_STEP_BW(a, b, c, d, e, T) {b = rotateRight(b, 30); e -= s1(a,b,c,d,w2[T]);} +#define ROUND2_STEP_BW(a, b, c, d, e, T) {b = rotateRight(b, 30); e -= s2(a,b,c,d,w2[T]);} +#define ROUND3_STEP_BW(a, b, c, d, e, T) {b = rotateRight(b, 30); e -= s3(a,b,c,d,w2[T]);} +#define ROUND4_STEP_BW(a, b, c, d, e, T) {b = rotateRight(b, 30); e -= s4(a,b,c,d,w2[T]);} + + /* Condition to go backwards: if (t > step) */ + /* t=80-66 have no identified DV; skip. + ROUND4_STEP_BW(b, c, d, e, a, 79) + ROUND4_STEP_BW(c, d, e, a, b, 78) + ROUND4_STEP_BW(d, e, a, b, c, 77) + ROUND4_STEP_BW(e, a, b, c, d, 76) + ROUND4_STEP_BW(a, b, c, d, e, 75) + ROUND4_STEP_BW(b, c, d, e, a, 74) + ROUND4_STEP_BW(c, d, e, a, b, 73) + ROUND4_STEP_BW(d, e, a, b, c, 72) + ROUND4_STEP_BW(e, a, b, c, d, 71) + ROUND4_STEP_BW(a, b, c, d, e, 70) + ROUND4_STEP_BW(b, c, d, e, a, 69) + ROUND4_STEP_BW(c, d, e, a, b, 68) + ROUND4_STEP_BW(d, e, a, b, c, 67) + ROUND4_STEP_BW(e, a, b, c, d, 66) + ROUND4_STEP_BW(a, b, c, d, e, 65) + */ + if (t == 65) { + ROUND4_STEP_BW(b, c, d, e, a, 64) + ROUND4_STEP_BW(c, d, e, a, b, 63) + ROUND4_STEP_BW(d, e, a, b, c, 62) + ROUND4_STEP_BW(e, a, b, c, d, 61) + ROUND4_STEP_BW(a, b, c, d, e, 60) + + ROUND3_STEP_BW(b, c, d, e, a, 59) + ROUND3_STEP_BW(c, d, e, a, b, 58) + } + ROUND3_STEP_BW(d, e, a, b, c, 57) + ROUND3_STEP_BW(e, a, b, c, d, 56) + ROUND3_STEP_BW(a, b, c, d, e, 55) + ROUND3_STEP_BW(b, c, d, e, a, 54) + ROUND3_STEP_BW(c, d, e, a, b, 53) + ROUND3_STEP_BW(d, e, a, b, c, 52) + ROUND3_STEP_BW(e, a, b, c, d, 51) + ROUND3_STEP_BW(a, b, c, d, e, 50) + ROUND3_STEP_BW(b, c, d, e, a, 49) + ROUND3_STEP_BW(c, d, e, a, b, 48) + ROUND3_STEP_BW(d, e, a, b, c, 47) + ROUND3_STEP_BW(e, a, b, c, d, 46) + ROUND3_STEP_BW(a, b, c, d, e, 45) + ROUND3_STEP_BW(b, c, d, e, a, 44) + ROUND3_STEP_BW(c, d, e, a, b, 43) + ROUND3_STEP_BW(d, e, a, b, c, 42) + ROUND3_STEP_BW(e, a, b, c, d, 41) + ROUND3_STEP_BW(a, b, c, d, e, 40) + + ROUND2_STEP_BW(b, c, d, e, a, 39) + ROUND2_STEP_BW(c, d, e, a, b, 38) + ROUND2_STEP_BW(d, e, a, b, c, 37) + ROUND2_STEP_BW(e, a, b, c, d, 36) + ROUND2_STEP_BW(a, b, c, d, e, 35) + ROUND2_STEP_BW(b, c, d, e, a, 34) + ROUND2_STEP_BW(c, d, e, a, b, 33) + ROUND2_STEP_BW(d, e, a, b, c, 32) + ROUND2_STEP_BW(e, a, b, c, d, 31) + ROUND2_STEP_BW(a, b, c, d, e, 30) + ROUND2_STEP_BW(b, c, d, e, a, 29) + ROUND2_STEP_BW(c, d, e, a, b, 28) + ROUND2_STEP_BW(d, e, a, b, c, 27) + ROUND2_STEP_BW(e, a, b, c, d, 26) + ROUND2_STEP_BW(a, b, c, d, e, 25) + ROUND2_STEP_BW(b, c, d, e, a, 24) + ROUND2_STEP_BW(c, d, e, a, b, 23) + ROUND2_STEP_BW(d, e, a, b, c, 22) + ROUND2_STEP_BW(e, a, b, c, d, 21) + ROUND2_STEP_BW(a, b, c, d, e, 20) + + ROUND1_STEP_BW(b, c, d, e, a, 19) + ROUND1_STEP_BW(c, d, e, a, b, 18) + ROUND1_STEP_BW(d, e, a, b, c, 17) + ROUND1_STEP_BW(e, a, b, c, d, 16) + ROUND1_STEP_BW(a, b, c, d, e, 15) + ROUND1_STEP_BW(b, c, d, e, a, 14) + ROUND1_STEP_BW(c, d, e, a, b, 13) + ROUND1_STEP_BW(d, e, a, b, c, 12) + ROUND1_STEP_BW(e, a, b, c, d, 11) + ROUND1_STEP_BW(a, b, c, d, e, 10) + ROUND1_STEP_BW(b, c, d, e, a, 9) + ROUND1_STEP_BW(c, d, e, a, b, 8) + ROUND1_STEP_BW(d, e, a, b, c, 7) + ROUND1_STEP_BW(e, a, b, c, d, 6) + ROUND1_STEP_BW(a, b, c, d, e, 5) + ROUND1_STEP_BW(b, c, d, e, a, 4) + ROUND1_STEP_BW(c, d, e, a, b, 3) + ROUND1_STEP_BW(d, e, a, b, c, 2) + ROUND1_STEP_BW(e, a, b, c, d, 1) + ROUND1_STEP_BW(a, b, c, d, e, 0) + + hIn.save(a, b, c, d, e); + a = s.a; b = s.b; c = s.c; d = s.d; e = s.e; + + /* Condition to go fowards: if (t <= step) */ + /* Earliest restart is T=58; skip. + ROUND1_STEP(a, b, c, d, e, 0) + ROUND1_STEP(e, a, b, c, d, 1) + ROUND1_STEP(d, e, a, b, c, 2) + ROUND1_STEP(c, d, e, a, b, 3) + ROUND1_STEP(b, c, d, e, a, 4) + ROUND1_STEP(a, b, c, d, e, 5) + ROUND1_STEP(e, a, b, c, d, 6) + ROUND1_STEP(d, e, a, b, c, 7) + ROUND1_STEP(c, d, e, a, b, 8) + ROUND1_STEP(b, c, d, e, a, 9) + ROUND1_STEP(a, b, c, d, e, 10) + ROUND1_STEP(e, a, b, c, d, 11) + ROUND1_STEP(d, e, a, b, c, 12) + ROUND1_STEP(c, d, e, a, b, 13) + ROUND1_STEP(b, c, d, e, a, 14) + ROUND1_STEP(a, b, c, d, e, 15) + ROUND1_STEP(e, a, b, c, d, 16) + ROUND1_STEP(d, e, a, b, c, 17) + ROUND1_STEP(c, d, e, a, b, 18) + ROUND1_STEP(b, c, d, e, a, 19) + + ROUND2_STEP(a, b, c, d, e, 20) + ROUND2_STEP(e, a, b, c, d, 21) + ROUND2_STEP(d, e, a, b, c, 22) + ROUND2_STEP(c, d, e, a, b, 23) + ROUND2_STEP(b, c, d, e, a, 24) + ROUND2_STEP(a, b, c, d, e, 25) + ROUND2_STEP(e, a, b, c, d, 26) + ROUND2_STEP(d, e, a, b, c, 27) + ROUND2_STEP(c, d, e, a, b, 28) + ROUND2_STEP(b, c, d, e, a, 29) + ROUND2_STEP(a, b, c, d, e, 30) + ROUND2_STEP(e, a, b, c, d, 31) + ROUND2_STEP(d, e, a, b, c, 32) + ROUND2_STEP(c, d, e, a, b, 33) + ROUND2_STEP(b, c, d, e, a, 34) + ROUND2_STEP(a, b, c, d, e, 35) + ROUND2_STEP(e, a, b, c, d, 36) + ROUND2_STEP(d, e, a, b, c, 37) + ROUND2_STEP(c, d, e, a, b, 38) + ROUND2_STEP(b, c, d, e, a, 39) + + ROUND3_STEP(a, b, c, d, e, 40) + ROUND3_STEP(e, a, b, c, d, 41) + ROUND3_STEP(d, e, a, b, c, 42) + ROUND3_STEP(c, d, e, a, b, 43) + ROUND3_STEP(b, c, d, e, a, 44) + ROUND3_STEP(a, b, c, d, e, 45) + ROUND3_STEP(e, a, b, c, d, 46) + ROUND3_STEP(d, e, a, b, c, 47) + ROUND3_STEP(c, d, e, a, b, 48) + ROUND3_STEP(b, c, d, e, a, 49) + ROUND3_STEP(a, b, c, d, e, 50) + ROUND3_STEP(e, a, b, c, d, 51) + ROUND3_STEP(d, e, a, b, c, 52) + ROUND3_STEP(c, d, e, a, b, 53) + ROUND3_STEP(b, c, d, e, a, 54) + ROUND3_STEP(a, b, c, d, e, 55) + ROUND3_STEP(e, a, b, c, d, 56) + ROUND3_STEP(d, e, a, b, c, 57) + */ + if (t == 58) { + ROUND3_STEP(c, d, e, a, b, 58) + ROUND3_STEP(b, c, d, e, a, 59) + + ROUND4_STEP(a, b, c, d, e, 60) + ROUND4_STEP(e, a, b, c, d, 61) + ROUND4_STEP(d, e, a, b, c, 62) + ROUND4_STEP(c, d, e, a, b, 63) + ROUND4_STEP(b, c, d, e, a, 64) + } + ROUND4_STEP(a, b, c, d, e, 65) + ROUND4_STEP(e, a, b, c, d, 66) + ROUND4_STEP(d, e, a, b, c, 67) + ROUND4_STEP(c, d, e, a, b, 68) + ROUND4_STEP(b, c, d, e, a, 69) + ROUND4_STEP(a, b, c, d, e, 70) + ROUND4_STEP(e, a, b, c, d, 71) + ROUND4_STEP(d, e, a, b, c, 72) + ROUND4_STEP(c, d, e, a, b, 73) + ROUND4_STEP(b, c, d, e, a, 74) + ROUND4_STEP(a, b, c, d, e, 75) + ROUND4_STEP(e, a, b, c, d, 76) + ROUND4_STEP(d, e, a, b, c, 77) + ROUND4_STEP(c, d, e, a, b, 78) + ROUND4_STEP(b, c, d, e, a, 79)
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/api/AddCommand.java b/org.eclipse.jgit/src/org/eclipse/jgit/api/AddCommand.java index 16ec146..1ed7944 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/api/AddCommand.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/api/AddCommand.java
@@ -96,7 +96,7 @@ public class AddCommand extends GitCommand<DirCache> { */ public AddCommand(Repository repo) { super(repo); - filepatterns = new LinkedList<String>(); + filepatterns = new LinkedList<>(); } /** @@ -134,6 +134,7 @@ public AddCommand setWorkingTreeIterator(WorkingTreeIterator f) { * * @return the DirCache after Add */ + @Override public DirCache call() throws GitAPIException, NoFilepatternException { if (filepatterns.isEmpty())
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/api/AddNoteCommand.java b/org.eclipse.jgit/src/org/eclipse/jgit/api/AddNoteCommand.java index 4235e37..fa88fb7 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/api/AddNoteCommand.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/api/AddNoteCommand.java
@@ -81,6 +81,7 @@ protected AddNoteCommand(Repository repo) { super(repo); } + @Override public Note call() throws GitAPIException { checkCallable(); NoteMap map = NoteMap.newEmptyMap();
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/api/ApplyCommand.java b/org.eclipse.jgit/src/org/eclipse/jgit/api/ApplyCommand.java index d74e991..ba5673d 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/api/ApplyCommand.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/api/ApplyCommand.java
@@ -109,6 +109,7 @@ public ApplyCommand setPatch(InputStream in) { * @throws PatchFormatException * @throws PatchApplyException */ + @Override public ApplyResult call() throws GitAPIException, PatchFormatException, PatchApplyException { checkCallable(); @@ -197,10 +198,10 @@ private File getFile(String path, boolean create) private void apply(File f, FileHeader fh) throws IOException, PatchApplyException { RawText rt = new RawText(f); - List<String> oldLines = new ArrayList<String>(rt.size()); + List<String> oldLines = new ArrayList<>(rt.size()); for (int i = 0; i < rt.size(); i++) oldLines.add(rt.getString(i)); - List<String> newLines = new ArrayList<String>(oldLines); + List<String> newLines = new ArrayList<>(oldLines); for (HunkHeader hh : fh.getHunks()) { byte[] b = new byte[hh.getEndOffset() - hh.getStartOffset()]; @@ -208,7 +209,7 @@ private void apply(File f, FileHeader fh) b.length); RawText hrt = new RawText(b); - List<String> hunkLines = new ArrayList<String>(hrt.size()); + List<String> hunkLines = new ArrayList<>(hrt.size()); for (int i = 0; i < hrt.size(); i++) hunkLines.add(hrt.getString(i)); int pos = 0;
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/api/ApplyResult.java b/org.eclipse.jgit/src/org/eclipse/jgit/api/ApplyResult.java index 558ef0f..2ef6650 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/api/ApplyResult.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/api/ApplyResult.java
@@ -53,7 +53,7 @@ */ public class ApplyResult { - private List<File> updatedFiles = new ArrayList<File>(); + private List<File> updatedFiles = new ArrayList<>(); /** * @param f
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/api/ArchiveCommand.java b/org.eclipse.jgit/src/org/eclipse/jgit/api/ArchiveCommand.java index 8543bd5..7ea8e73 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/api/ArchiveCommand.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/api/ArchiveCommand.java
@@ -162,8 +162,8 @@ T createArchiveOutputStream(OutputStream s, Map<String, Object> o) * @param out * archive object from createArchiveOutputStream * @param path - * full filename relative to the root of the archive - * (with trailing '/' for directories) + * full filename relative to the root of the archive (with + * trailing '/' for directories) * @param mode * mode (for example FileMode.REGULAR_FILE or * FileMode.SYMLINK) @@ -171,9 +171,36 @@ T createArchiveOutputStream(OutputStream s, Map<String, Object> o) * blob object with data for this entry (null for * directories) * @throws IOException - * thrown by the underlying output stream for I/O errors + * thrown by the underlying output stream for I/O errors + * @deprecated use + * {@link #putEntry(Closeable, ObjectId, String, FileMode, ObjectLoader)} + * instead */ + @Deprecated void putEntry(T out, String path, FileMode mode, + ObjectLoader loader) throws IOException; + + /** + * Write an entry to an archive. + * + * @param out + * archive object from createArchiveOutputStream + * @param tree + * the tag, commit, or tree object to produce an archive for + * @param path + * full filename relative to the root of the archive (with + * trailing '/' for directories) + * @param mode + * mode (for example FileMode.REGULAR_FILE or + * FileMode.SYMLINK) + * @param loader + * blob object with data for this entry (null for + * directories) + * @throws IOException + * thrown by the underlying output stream for I/O errors + * @since 4.7 + */ + void putEntry(T out, ObjectId tree, String path, FileMode mode, ObjectLoader loader) throws IOException; /** @@ -232,7 +259,7 @@ public FormatEntry(Format<?> format, int refcnt) { * the --format= option) */ private static final ConcurrentMap<String, FormatEntry> formats = - new ConcurrentHashMap<String, FormatEntry>(); + new ConcurrentHashMap<>(); /** * Replaces the entry for a key only if currently mapped to a given @@ -350,7 +377,7 @@ private static Format<?> lookupFormat(String formatName) throws UnsupportedForma private String prefix; private String format; private Map<String, Object> formatOptions = new HashMap<>(); - private List<String> paths = new ArrayList<String>(); + private List<String> paths = new ArrayList<>(); /** Filename suffix, for automatically choosing a format. */ private String suffix; @@ -376,6 +403,12 @@ private <T extends Closeable> OutputStream writeArchive(Format<T> fmt) { if (!paths.isEmpty()) walk.setFilter(PathFilterGroup.createFromStrings(paths)); + // Put base directory into archive + if (pfx.endsWith("/")) { //$NON-NLS-1$ + fmt.putEntry(outa, tree, pfx.replaceAll("[/]+$", "/"), //$NON-NLS-1$ //$NON-NLS-2$ + FileMode.TREE, null); + } + while (walk.next()) { String name = pfx + walk.getPathString(); FileMode mode = walk.getFileMode(0); @@ -389,11 +422,11 @@ private <T extends Closeable> OutputStream writeArchive(Format<T> fmt) { mode = FileMode.TREE; if (mode == FileMode.TREE) { - fmt.putEntry(outa, name + "/", mode, null); //$NON-NLS-1$ + fmt.putEntry(outa, tree, name + "/", mode, null); //$NON-NLS-1$ continue; } walk.getObjectId(idBuf, 0); - fmt.putEntry(outa, name, mode, reader.open(idBuf)); + fmt.putEntry(outa, tree, name, mode, reader.open(idBuf)); } outa.close(); return out;
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 2a2e07d..b1c81ff 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/api/BlameCommand.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/api/BlameCommand.java
@@ -188,7 +188,7 @@ public BlameCommand reverse(AnyObjectId start, AnyObjectId end) public BlameCommand reverse(AnyObjectId start, Collection<ObjectId> end) throws IOException { startCommit = start.toObjectId(); - reverseEndCommits = new ArrayList<ObjectId>(end); + reverseEndCommits = new ArrayList<>(end); return this; } @@ -198,6 +198,7 @@ public BlameCommand reverse(AnyObjectId start, Collection<ObjectId> end) * * @return list of lines */ + @Override public BlameResult call() throws GitAPIException { checkCallable(); try (BlameGenerator gen = new BlameGenerator(repo, path)) {
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 c17ae5c..21d6283 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/api/CheckoutCommand.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/api/CheckoutCommand.java
@@ -180,7 +180,7 @@ private Stage(int number) { */ protected CheckoutCommand(Repository repo) { super(repo); - this.paths = new LinkedList<String>(); + this.paths = new LinkedList<>(); } /** @@ -196,6 +196,7 @@ protected CheckoutCommand(Repository repo) { * if the checkout results in a conflict * @return the newly created branch */ + @Override public Ref call() throws GitAPIException, RefAlreadyExistsException, RefNotFoundException, InvalidRefNameException, CheckoutConflictException { @@ -319,10 +320,10 @@ else if (orphan) { if (!dco.getToBeDeleted().isEmpty()) { status = new CheckoutResult(Status.NONDELETED, dco.getToBeDeleted(), - new ArrayList<String>(dco.getUpdated().keySet()), + new ArrayList<>(dco.getUpdated().keySet()), dco.getRemoved()); } else - status = new CheckoutResult(new ArrayList<String>(dco + status = new CheckoutResult(new ArrayList<>(dco .getUpdated().keySet()), dco.getRemoved()); return ref; @@ -455,6 +456,7 @@ private void checkoutPathsFromIndex(TreeWalk treeWalk, DirCache dc) final String filterCommand = treeWalk .getFilterCommand(Constants.ATTR_FILTER_TYPE_SMUDGE); editor.add(new PathEdit(path) { + @Override public void apply(DirCacheEntry ent) { int stage = ent.getStage(); if (stage > DirCacheEntry.STAGE_0) { @@ -491,6 +493,7 @@ private void checkoutPathsFromCommit(TreeWalk treeWalk, DirCache dc, final String filterCommand = treeWalk .getFilterCommand(Constants.ATTR_FILTER_TYPE_SMUDGE); editor.add(new PathEdit(treeWalk.getPathString()) { + @Override public void apply(DirCacheEntry ent) { ent.setObjectId(blobId); ent.setFileMode(mode);
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/api/CheckoutResult.java b/org.eclipse.jgit/src/org/eclipse/jgit/api/CheckoutResult.java index 92a67f4..2186eb4 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/api/CheckoutResult.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/api/CheckoutResult.java
@@ -139,11 +139,11 @@ public enum Status { if (status == Status.CONFLICTS) this.conflictList = fileList; else - this.conflictList = new ArrayList<String>(0); + this.conflictList = new ArrayList<>(0); if (status == Status.NONDELETED) this.undeletedList = fileList; else - this.undeletedList = new ArrayList<String>(0); + this.undeletedList = new ArrayList<>(0); this.modifiedList = modified; this.removedList = removed; @@ -160,8 +160,8 @@ public enum Status { CheckoutResult(List<String> modified, List<String> removed) { myStatus = Status.OK; - this.conflictList = new ArrayList<String>(0); - this.undeletedList = new ArrayList<String>(0); + this.conflictList = new ArrayList<>(0); + this.undeletedList = new ArrayList<>(0); this.modifiedList = modified; this.removedList = removed;
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 276bf96..eed7b2a 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/api/CherryPickCommand.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/api/CherryPickCommand.java
@@ -85,7 +85,7 @@ public class CherryPickCommand extends GitCommand<CherryPickResult> { private String reflogPrefix = "cherry-pick:"; //$NON-NLS-1$ - private List<Ref> commits = new LinkedList<Ref>(); + private List<Ref> commits = new LinkedList<>(); private String ourCommitName = null; @@ -116,11 +116,12 @@ protected CherryPickCommand(Repository repo) { * @throws NoMessageException * @throws NoHeadException */ + @Override public CherryPickResult call() throws GitAPIException, NoMessageException, UnmergedPathsException, ConcurrentRefUpdateException, WrongRepositoryStateException, NoHeadException { RevCommit newHead = null; - List<Ref> cherryPickedRefs = new LinkedList<Ref>(); + List<Ref> cherryPickedRefs = new LinkedList<>(); checkCallable(); try (RevWalk revWalk = new RevWalk(repo)) {
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/api/CleanCommand.java b/org.eclipse.jgit/src/org/eclipse/jgit/api/CleanCommand.java index 7e331fd..c58efb1 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/api/CleanCommand.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/api/CleanCommand.java
@@ -94,15 +94,16 @@ protected CleanCommand(Repository repo) { * @throws GitAPIException * @throws NoWorkTreeException */ + @Override public Set<String> call() throws NoWorkTreeException, GitAPIException { - Set<String> files = new TreeSet<String>(); + Set<String> files = new TreeSet<>(); try { StatusCommand command = new StatusCommand(repo); Status status = command.call(); - Set<String> untrackedAndIgnoredFiles = new TreeSet<String>( + Set<String> untrackedAndIgnoredFiles = new TreeSet<>( status.getUntracked()); - Set<String> untrackedAndIgnoredDirs = new TreeSet<String>( + Set<String> untrackedAndIgnoredDirs = new TreeSet<>( status.getUntrackedFolders()); FS fs = getRepository().getFS(); @@ -191,7 +192,7 @@ private Set<String> cleanPath(String path, Set<String> inFiles) private Set<String> filterIgnorePaths(Set<String> inputPaths, Set<String> ignoredNotInIndex, boolean exact) { if (ignore) { - Set<String> filtered = new TreeSet<String>(inputPaths); + Set<String> filtered = new TreeSet<>(inputPaths); for (String path : inputPaths) for (String ignored : ignoredNotInIndex) if ((exact && path.equals(ignored)) @@ -207,7 +208,7 @@ private Set<String> filterIgnorePaths(Set<String> inputPaths, private Set<String> filterFolders(Set<String> untracked, Set<String> untrackedFolders) { - Set<String> filtered = new TreeSet<String>(untracked); + Set<String> filtered = new TreeSet<>(untracked); for (String file : untracked) for (String folder : untrackedFolders) if (file.startsWith(folder)) {
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 dd5da15..4b815b4 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/api/CloneCommand.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/api/CloneCommand.java
@@ -127,6 +127,7 @@ public CloneCommand() { * @throws org.eclipse.jgit.api.errors.TransportException * @throws GitAPIException */ + @Override public Git call() throws GitAPIException, InvalidRemoteException, org.eclipse.jgit.api.errors.TransportException { Repository repository = null; @@ -151,23 +152,35 @@ public Git call() throws GitAPIException, InvalidRemoteException, } } + private static boolean isNonEmptyDirectory(File dir) { + if (dir != null && dir.exists()) { + File[] files = dir.listFiles(); + return files != null && files.length != 0; + } + return false; + } + private Repository init(URIish u) throws GitAPIException { InitCommand command = Git.init(); command.setBare(bare); - if (directory == null && gitDir == null) + if (directory == null && gitDir == null) { directory = new File(u.getHumanishName(), Constants.DOT_GIT); + } validateDirs(directory, gitDir, bare); - if (directory != null && directory.exists() - && directory.listFiles().length != 0) + if (isNonEmptyDirectory(directory)) { throw new JGitInternalException(MessageFormat.format( JGitText.get().cloneNonEmptyDirectory, directory.getName())); - if (gitDir != null && gitDir.exists() && gitDir.listFiles().length != 0) + } + if (isNonEmptyDirectory(gitDir)) { throw new JGitInternalException(MessageFormat.format( JGitText.get().cloneNonEmptyDirectory, gitDir.getName())); - if (directory != null) + } + if (directory != null) { command.setDirectory(directory); - if (gitDir != null) + } + if (gitDir != null) { command.setGitDir(gitDir); + } return command.call().getRepository(); } @@ -207,7 +220,7 @@ private List<RefSpec> calculateRefSpecs(final String dst) { RefSpec wcrs = new RefSpec(); wcrs = wcrs.setForceUpdate(true); wcrs = wcrs.setSourceDestination(Constants.R_HEADS + "*", dst); //$NON-NLS-1$ - List<RefSpec> specs = new ArrayList<RefSpec>(); + List<RefSpec> specs = new ArrayList<>(); if (cloneAllBranches) specs.add(wcrs); else if (branchesToClone != null
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 e1793f3..274ece6 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/api/CommitCommand.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/api/CommitCommand.java
@@ -112,7 +112,7 @@ public class CommitCommand extends GitCommand<RevCommit> { private boolean all; - private List<String> only = new ArrayList<String>(); + private List<String> only = new ArrayList<>(); private boolean[] onlyProcessed; @@ -124,7 +124,7 @@ public class CommitCommand extends GitCommand<RevCommit> { * parents this commit should have. The current HEAD will be in this list * and also all commits mentioned in .git/MERGE_HEAD */ - private List<ObjectId> parents = new LinkedList<ObjectId>(); + private List<ObjectId> parents = new LinkedList<>(); private String reflogComment; @@ -168,6 +168,7 @@ protected CommitCommand(Repository repo) { * if there are either pre-commit or commit-msg hooks present in * the repository and one of them rejects the commit. */ + @Override public RevCommit call() throws GitAPIException, NoHeadException, NoMessageException, UnmergedPathsException, ConcurrentRefUpdateException, WrongRepositoryStateException,
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/api/CreateBranchCommand.java b/org.eclipse.jgit/src/org/eclipse/jgit/api/CreateBranchCommand.java index 69d82bc..39420d0 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/api/CreateBranchCommand.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/api/CreateBranchCommand.java
@@ -120,6 +120,7 @@ protected CreateBranchCommand(Repository repo) { * invalid * @return the newly created branch */ + @Override public Ref call() throws GitAPIException, RefAlreadyExistsException, RefNotFoundException, InvalidRefNameException { checkCallable();
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/api/DeleteBranchCommand.java b/org.eclipse.jgit/src/org/eclipse/jgit/api/DeleteBranchCommand.java index ecc1ce5..d7e7e5c 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/api/DeleteBranchCommand.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/api/DeleteBranchCommand.java
@@ -79,7 +79,7 @@ * >Git documentation about Branch</a> */ public class DeleteBranchCommand extends GitCommand<List<String>> { - private final Set<String> branchNames = new HashSet<String>(); + private final Set<String> branchNames = new HashSet<>(); private boolean force; @@ -97,10 +97,11 @@ protected DeleteBranchCommand(Repository repo) { * @throws CannotDeleteCurrentBranchException * @return the list with the (full) names of the deleted branches */ + @Override public List<String> call() throws GitAPIException, NotMergedException, CannotDeleteCurrentBranchException { checkCallable(); - List<String> result = new ArrayList<String>(); + List<String> result = new ArrayList<>(); if (branchNames.isEmpty()) return result; try {
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/api/DeleteTagCommand.java b/org.eclipse.jgit/src/org/eclipse/jgit/api/DeleteTagCommand.java index 3aeec48..77e3539 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/api/DeleteTagCommand.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/api/DeleteTagCommand.java
@@ -68,7 +68,7 @@ */ public class DeleteTagCommand extends GitCommand<List<String>> { - private final Set<String> tags = new HashSet<String>(); + private final Set<String> tags = new HashSet<>(); /** * @param repo @@ -80,9 +80,10 @@ protected DeleteTagCommand(Repository repo) { /** * @return the list with the full names of the deleted tags */ + @Override public List<String> call() throws GitAPIException { checkCallable(); - List<String> result = new ArrayList<String>(); + List<String> result = new ArrayList<>(); if (tags.isEmpty()) return result; try {
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/api/DescribeCommand.java b/org.eclipse.jgit/src/org/eclipse/jgit/api/DescribeCommand.java index be45666..389c511 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/api/DescribeCommand.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/api/DescribeCommand.java
@@ -189,7 +189,7 @@ public String call() throws GitAPIException { if (target == null) setTarget(Constants.HEAD); - Map<ObjectId, Ref> tags = new HashMap<ObjectId, Ref>(); + Map<ObjectId, Ref> tags = new HashMap<>(); for (Ref r : repo.getRefDatabase().getRefs(R_TAGS).values()) { ObjectId key = repo.peel(r).getPeeledObjectId(); @@ -240,7 +240,7 @@ String describe(ObjectId tip) throws IOException { } } - List<Candidate> candidates = new ArrayList<Candidate>(); // all the candidates we find + List<Candidate> candidates = new ArrayList<>(); // all the candidates we find // is the target already pointing to a tag? if so, we are done! Ref lucky = tags.get(target); @@ -305,6 +305,7 @@ String describe(ObjectId tip) throws IOException { return null; Candidate best = Collections.min(candidates, new Comparator<Candidate>() { + @Override public int compare(Candidate o1, Candidate o2) { return o1.depth - o2.depth; }
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 3e3a7a8..b137fc5 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/api/DiffCommand.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/api/DiffCommand.java
@@ -109,6 +109,7 @@ protected DiffCommand(Repository repo) { * * @return a DiffEntry for each path which is different */ + @Override public List<DiffEntry> call() throws GitAPIException { final DiffFormatter diffFmt; if (out != null && !showNameAndStatusOnly)
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 de51276..cc3302b 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/api/FetchCommand.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/api/FetchCommand.java
@@ -42,14 +42,17 @@ */ package org.eclipse.jgit.api; +import java.io.IOException; import java.net.URISyntaxException; import java.text.MessageFormat; import java.util.ArrayList; import java.util.List; import org.eclipse.jgit.api.errors.GitAPIException; +import org.eclipse.jgit.api.errors.InvalidConfigurationException; import org.eclipse.jgit.api.errors.InvalidRemoteException; import org.eclipse.jgit.api.errors.JGitInternalException; +import org.eclipse.jgit.errors.ConfigInvalidException; import org.eclipse.jgit.errors.NoRemoteRepositoryException; import org.eclipse.jgit.errors.NotSupportedException; import org.eclipse.jgit.errors.TransportException; @@ -57,9 +60,13 @@ import org.eclipse.jgit.lib.ConfigConstants; import org.eclipse.jgit.lib.Constants; import org.eclipse.jgit.lib.NullProgressMonitor; +import org.eclipse.jgit.lib.ObjectId; import org.eclipse.jgit.lib.ProgressMonitor; import org.eclipse.jgit.lib.Repository; import org.eclipse.jgit.lib.StoredConfig; +import org.eclipse.jgit.lib.SubmoduleConfig.FetchRecurseSubmodulesMode; +import org.eclipse.jgit.revwalk.RevWalk; +import org.eclipse.jgit.submodule.SubmoduleWalk; import org.eclipse.jgit.transport.FetchResult; import org.eclipse.jgit.transport.RefSpec; import org.eclipse.jgit.transport.TagOpt; @@ -74,7 +81,6 @@ * >Git documentation about Fetch</a> */ public class FetchCommand extends TransportCommand<FetchCommand, FetchResult> { - private String remote = Constants.DEFAULT_REMOTE_NAME; private List<RefSpec> refSpecs; @@ -91,12 +97,90 @@ public class FetchCommand extends TransportCommand<FetchCommand, FetchResult> { private TagOpt tagOption; + private FetchRecurseSubmodulesMode submoduleRecurseMode = null; + /** * @param repo */ protected FetchCommand(Repository repo) { super(repo); - refSpecs = new ArrayList<RefSpec>(3); + refSpecs = new ArrayList<>(3); + } + + private FetchRecurseSubmodulesMode getRecurseMode(String path) { + // Use the caller-specified mode, if set + if (submoduleRecurseMode != null) { + return submoduleRecurseMode; + } + + // Fall back to submodule.name.fetchRecurseSubmodules, if set + FetchRecurseSubmodulesMode mode = repo.getConfig().getEnum( + FetchRecurseSubmodulesMode.values(), + ConfigConstants.CONFIG_SUBMODULE_SECTION, path, + ConfigConstants.CONFIG_KEY_FETCH_RECURSE_SUBMODULES, null); + if (mode != null) { + return mode; + } + + // Fall back to fetch.recurseSubmodules, if set + mode = repo.getConfig().getEnum(FetchRecurseSubmodulesMode.values(), + ConfigConstants.CONFIG_FETCH_SECTION, null, + ConfigConstants.CONFIG_KEY_RECURSE_SUBMODULES, null); + if (mode != null) { + return mode; + } + + // Default to on-demand mode + return FetchRecurseSubmodulesMode.ON_DEMAND; + } + + private void fetchSubmodules(FetchResult results) + throws org.eclipse.jgit.api.errors.TransportException, + GitAPIException, InvalidConfigurationException { + try (SubmoduleWalk walk = new SubmoduleWalk(repo); + RevWalk revWalk = new RevWalk(repo)) { + // Walk over submodules in the parent repository's FETCH_HEAD. + ObjectId fetchHead = repo.resolve(Constants.FETCH_HEAD); + if (fetchHead == null) { + return; + } + walk.setTree(revWalk.parseTree(fetchHead)); + while (walk.next()) { + Repository submoduleRepo = walk.getRepository(); + + // Skip submodules that don't exist locally (have not been + // cloned), are not registered in the .gitmodules file, or + // not registered in the parent repository's config. + if (submoduleRepo == null || walk.getModulesPath() == null + || walk.getConfigUrl() == null) { + continue; + } + + FetchRecurseSubmodulesMode recurseMode = getRecurseMode( + walk.getPath()); + + // When the fetch mode is "yes" we always fetch. When the mode + // is "on demand", we only fetch if the submodule's revision was + // updated to an object that is not currently present in the + // submodule. + if ((recurseMode == FetchRecurseSubmodulesMode.ON_DEMAND + && !submoduleRepo.hasObject(walk.getObjectId())) + || recurseMode == FetchRecurseSubmodulesMode.YES) { + FetchCommand f = new FetchCommand(submoduleRepo) + .setProgressMonitor(monitor).setTagOpt(tagOption) + .setCheckFetchedObjects(checkFetchedObjects) + .setRemoveDeletedRefs(isRemoveDeletedRefs()) + .setThin(thin).setRefSpecs(refSpecs) + .setDryRun(dryRun) + .setRecurseSubmodules(recurseMode); + results.addSubmodule(walk.getPath(), f.call()); + } + } + } catch (IOException e) { + throw new JGitInternalException(e.getMessage(), e); + } catch (ConfigInvalidException e) { + throw new InvalidConfigurationException(e.getMessage(), e); + } } /** @@ -112,6 +196,7 @@ protected FetchCommand(Repository repo) { * @throws org.eclipse.jgit.api.errors.TransportException * when an error occurs during transport */ + @Override public FetchResult call() throws GitAPIException, InvalidRemoteException, org.eclipse.jgit.api.errors.TransportException { checkCallable(); @@ -126,6 +211,10 @@ public FetchResult call() throws GitAPIException, InvalidRemoteException, configure(transport); FetchResult result = transport.fetch(monitor, refSpecs); + if (!repo.isBare()) { + fetchSubmodules(result); + } + return result; } catch (NoRemoteRepositoryException e) { throw new InvalidRemoteException(MessageFormat.format( @@ -145,6 +234,20 @@ public FetchResult call() throws GitAPIException, InvalidRemoteException, } /** + * Set the mode to be used for recursing into submodules. + * + * @param recurse + * @return {@code this} + * @since 4.7 + */ + public FetchCommand setRecurseSubmodules( + FetchRecurseSubmodulesMode recurse) { + checkCallable(); + submoduleRecurseMode = recurse; + return this; + } + + /** * The remote (uri or name) used for the fetch operation. If no remote is * set, the default value of <code>Constants.DEFAULT_REMOTE_NAME</code> will * be used.
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 d0f729c..0f38db5 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/api/GarbageCollectCommand.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/api/GarbageCollectCommand.java
@@ -159,6 +159,38 @@ public GarbageCollectCommand setAggressive(boolean aggressive) { return this; } + /** + * Whether to preserve old pack files instead of deleting them. + * + * @since 4.7 + * @param preserveOldPacks + * whether to preserve old pack files + * @return this instance + */ + public GarbageCollectCommand setPreserveOldPacks(boolean preserveOldPacks) { + if (pconfig == null) + pconfig = new PackConfig(repo); + + pconfig.setPreserveOldPacks(preserveOldPacks); + return this; + } + + /** + * Whether to prune preserved pack files in the preserved directory. + * + * @since 4.7 + * @param prunePreserved + * whether to prune preserved pack files + * @return this instance + */ + public GarbageCollectCommand setPrunePreserved(boolean prunePreserved) { + if (pconfig == null) + pconfig = new PackConfig(repo); + + pconfig.setPrunePreserved(prunePreserved); + return this; + } + @Override public Properties call() throws GitAPIException { checkCallable();
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/api/Git.java b/org.eclipse.jgit/src/org/eclipse/jgit/api/Git.java index 2cd5f59..9699569 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/api/Git.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/api/Git.java
@@ -147,6 +147,7 @@ public static Git wrap(Repository repo) { * * @since 3.2 */ + @Override public void close() { if (closeRepo) repo.close();
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/api/GitCommand.java b/org.eclipse.jgit/src/org/eclipse/jgit/api/GitCommand.java index e9751f9..2a23408 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/api/GitCommand.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/api/GitCommand.java
@@ -126,5 +126,6 @@ protected void checkCallable() { * @throws GitAPIException * or subclass thereof when an error occurs */ + @Override public abstract T call() throws GitAPIException; }
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/api/InitCommand.java b/org.eclipse.jgit/src/org/eclipse/jgit/api/InitCommand.java index 37a788e..649484c 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/api/InitCommand.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/api/InitCommand.java
@@ -73,6 +73,7 @@ public class InitCommand implements Callable<Git> { * * @return the newly created {@code Git} object with associated repository */ + @Override public Git call() throws GitAPIException { try { RepositoryBuilder builder = new RepositoryBuilder();
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/api/ListBranchCommand.java b/org.eclipse.jgit/src/org/eclipse/jgit/api/ListBranchCommand.java index efcfd16..961eeaa 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/api/ListBranchCommand.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/api/ListBranchCommand.java
@@ -101,11 +101,12 @@ protected ListBranchCommand(Repository repo) { super(repo); } + @Override public List<Ref> call() throws GitAPIException { checkCallable(); List<Ref> resultRefs; try { - Collection<Ref> refs = new ArrayList<Ref>(); + Collection<Ref> refs = new ArrayList<>(); // Also return HEAD if it's detached Ref head = repo.exactRef(Constants.HEAD); @@ -120,12 +121,13 @@ public List<Ref> call() throws GitAPIException { refs.addAll(getRefs(Constants.R_HEADS)); refs.addAll(getRefs(Constants.R_REMOTES)); } - resultRefs = new ArrayList<Ref>(filterRefs(refs)); + resultRefs = new ArrayList<>(filterRefs(refs)); } catch (IOException e) { throw new JGitInternalException(e.getMessage(), e); } Collections.sort(resultRefs, new Comparator<Ref>() { + @Override public int compare(Ref o1, Ref o2) { return o1.getName().compareTo(o2.getName()); }
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/api/ListNotesCommand.java b/org.eclipse.jgit/src/org/eclipse/jgit/api/ListNotesCommand.java index ff963ed..476c10b 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/api/ListNotesCommand.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/api/ListNotesCommand.java
@@ -77,9 +77,10 @@ protected ListNotesCommand(Repository repo) { /** * @return the requested notes */ + @Override public List<Note> call() throws GitAPIException { checkCallable(); - List<Note> notes = new ArrayList<Note>(); + List<Note> notes = new ArrayList<>(); NoteMap map = NoteMap.newEmptyMap(); try (RevWalk walk = new RevWalk(repo)) { Ref ref = repo.findRef(notesRef);
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/api/ListTagCommand.java b/org.eclipse.jgit/src/org/eclipse/jgit/api/ListTagCommand.java index a3b701b..d649a53 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/api/ListTagCommand.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/api/ListTagCommand.java
@@ -74,10 +74,11 @@ protected ListTagCommand(Repository repo) { /** * @return the tags available */ + @Override public List<Ref> call() throws GitAPIException { checkCallable(); Map<String, Ref> refList; - List<Ref> tags = new ArrayList<Ref>(); + List<Ref> tags = new ArrayList<>(); try (RevWalk revWalk = new RevWalk(repo)) { refList = repo.getRefDatabase().getRefs(Constants.R_TAGS); for (Ref ref : refList.values()) { @@ -87,6 +88,7 @@ public List<Ref> call() throws GitAPIException { throw new JGitInternalException(e.getMessage(), e); } Collections.sort(tags, new Comparator<Ref>() { + @Override public int compare(Ref o1, Ref o2) { return o1.getName().compareTo(o2.getName()); }
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 bb1a738..f8fe95a 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/api/LogCommand.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/api/LogCommand.java
@@ -107,7 +107,7 @@ public class LogCommand extends GitCommand<Iterable<RevCommit>> { private RevFilter revFilter; - private final List<PathFilter> pathFilters = new ArrayList<PathFilter>(); + private final List<PathFilter> pathFilters = new ArrayList<>(); private int maxCount = -1; @@ -132,6 +132,7 @@ protected LogCommand(Repository repo) { * @throws NoHeadException * of the references ref cannot be resolved */ + @Override public Iterable<RevCommit> call() throws GitAPIException, NoHeadException { checkCallable(); if (pathFilters.size() > 0)
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/api/LsRemoteCommand.java b/org.eclipse.jgit/src/org/eclipse/jgit/api/LsRemoteCommand.java index f3527fd..5157a41 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/api/LsRemoteCommand.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/api/LsRemoteCommand.java
@@ -153,6 +153,7 @@ public LsRemoteCommand setUploadPack(String uploadPack) { * @throws org.eclipse.jgit.api.errors.TransportException * for errors that occurs during transport */ + @Override public Collection<Ref> call() throws GitAPIException, InvalidRemoteException, org.eclipse.jgit.api.errors.TransportException { @@ -187,14 +188,14 @@ private Map<String, Ref> execute() throws GitAPIException, : Transport.open(new URIish(remote))) { transport.setOptionUploadPack(uploadPack); configure(transport); - Collection<RefSpec> refSpecs = new ArrayList<RefSpec>(1); + Collection<RefSpec> refSpecs = new ArrayList<>(1); if (tags) refSpecs.add(new RefSpec( "refs/tags/*:refs/remotes/origin/tags/*")); //$NON-NLS-1$ if (heads) refSpecs.add(new RefSpec("refs/heads/*:refs/remotes/origin/*")); //$NON-NLS-1$ Collection<Ref> refs; - Map<String, Ref> refmap = new HashMap<String, Ref>(); + Map<String, Ref> refmap = new HashMap<>(); try (FetchConnection fc = transport.openFetch()) { refs = fc.getRefs(); if (refSpecs.isEmpty())
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/api/MergeCommand.java b/org.eclipse.jgit/src/org/eclipse/jgit/api/MergeCommand.java index ced1863..b5d9e8a 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/api/MergeCommand.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/api/MergeCommand.java
@@ -50,6 +50,7 @@ import java.util.Collections; import java.util.LinkedList; import java.util.List; +import java.util.Locale; import java.util.Map; import org.eclipse.jgit.api.MergeResult.MergeStatus; @@ -101,7 +102,7 @@ public class MergeCommand extends GitCommand<MergeResult> { private MergeStrategy mergeStrategy = MergeStrategy.RECURSIVE; - private List<Ref> commits = new LinkedList<Ref>(); + private List<Ref> commits = new LinkedList<>(); private Boolean squash; @@ -133,10 +134,12 @@ public enum FastForwardMode implements ConfigEnum { */ FF_ONLY; + @Override public String toConfigValue() { - return "--" + name().toLowerCase().replace('_', '-'); //$NON-NLS-1$ + return "--" + name().toLowerCase(Locale.ROOT).replace('_', '-'); //$NON-NLS-1$ } + @Override public boolean matchConfigValue(String in) { if (StringUtils.isEmptyOrNull(in)) return false; @@ -220,6 +223,7 @@ protected MergeCommand(Repository repo) { * * @return the result of the merge */ + @Override @SuppressWarnings("boxing") public MergeResult call() throws GitAPIException, NoHeadException, ConcurrentRefUpdateException, CheckoutConflictException,
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/api/MergeResult.java b/org.eclipse.jgit/src/org/eclipse/jgit/api/MergeResult.java index 6141e0c..c487ef6 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/api/MergeResult.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/api/MergeResult.java
@@ -185,6 +185,7 @@ public boolean isSuccessful() { * @since 3.0 **/ MERGED_NOT_COMMITTED { + @Override public String toString() { return "Merged-not-committed"; //$NON-NLS-1$ } @@ -212,6 +213,7 @@ public boolean isSuccessful() { * files (i.e. local modifications prevent checkout of files). */ CHECKOUT_CONFLICT { + @Override public String toString() { return "Checkout Conflict"; //$NON-NLS-1$ } @@ -414,7 +416,7 @@ public void setConflicts(Map<String, int[][]> conflicts) { */ public void addConflict(String path, int[][] conflictingRanges) { if (conflicts == null) - conflicts = new HashMap<String, int[][]>(); + conflicts = new HashMap<>(); conflicts.put(path, conflictingRanges); } @@ -426,7 +428,7 @@ public void addConflict(String path, org.eclipse.jgit.merge.MergeResult<?> lowLe if (!lowLevelResult.containsConflicts()) return; if (conflicts == null) - conflicts = new HashMap<String, int[][]>(); + conflicts = new HashMap<>(); int nrOfConflicts = 0; // just counting for (MergeChunk mergeChunk : lowLevelResult) {
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/api/NameRevCommand.java b/org.eclipse.jgit/src/org/eclipse/jgit/api/NameRevCommand.java index fd28d0e..2a86fab 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/api/NameRevCommand.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/api/NameRevCommand.java
@@ -124,8 +124,8 @@ public String toString() { protected NameRevCommand(Repository repo) { super(repo); mergeCost = MERGE_COST; - prefixes = new ArrayList<String>(2); - revs = new ArrayList<ObjectId>(2); + prefixes = new ArrayList<>(2); + revs = new ArrayList<>(2); walk = new RevWalk(repo) { @Override public NameRevCommit createCommit(AnyObjectId id) { @@ -137,7 +137,7 @@ public NameRevCommit createCommit(AnyObjectId id) { @Override public Map<ObjectId, String> call() throws GitAPIException { try { - Map<ObjectId, String> nonCommits = new HashMap<ObjectId, String>(); + Map<ObjectId, String> nonCommits = new HashMap<>(); FIFORevQueue pending = new FIFORevQueue(); if (refs != null) { for (Ref ref : refs) @@ -170,7 +170,7 @@ public Map<ObjectId, String> call() throws GitAPIException { } Map<ObjectId, String> result = - new LinkedHashMap<ObjectId, String>(revs.size()); + new LinkedHashMap<>(revs.size()); for (ObjectId id : revs) { RevObject o = walk.parseAny(id); if (o instanceof NameRevCommit) { @@ -275,7 +275,7 @@ public NameRevCommand addPrefix(String prefix) { public NameRevCommand addAnnotatedTags() { checkCallable(); if (refs == null) - refs = new ArrayList<Ref>(); + refs = new ArrayList<>(); try { for (Ref ref : repo.getRefDatabase().getRefs(Constants.R_TAGS).values()) { ObjectId id = ref.getObjectId(); @@ -302,7 +302,7 @@ public NameRevCommand addAnnotatedTags() { public NameRevCommand addRef(Ref ref) { checkCallable(); if (refs == null) - refs = new ArrayList<Ref>(); + refs = new ArrayList<>(); refs.add(ref); return this; }
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 a4d9ec1..ae822da 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/api/PullCommand.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/api/PullCommand.java
@@ -69,8 +69,10 @@ import org.eclipse.jgit.lib.Ref; import org.eclipse.jgit.lib.Repository; import org.eclipse.jgit.lib.RepositoryState; +import org.eclipse.jgit.lib.SubmoduleConfig.FetchRecurseSubmodulesMode; import org.eclipse.jgit.merge.MergeStrategy; import org.eclipse.jgit.transport.FetchResult; +import org.eclipse.jgit.transport.TagOpt; /** * The Pull command @@ -92,6 +94,10 @@ public class PullCommand extends TransportCommand<PullCommand, PullResult> { private MergeStrategy strategy = MergeStrategy.RECURSIVE; + private TagOpt tagOption; + + private FetchRecurseSubmodulesMode submoduleRecurseMode = null; + /** * @param repo */ @@ -194,6 +200,7 @@ public PullCommand setRebase(BranchRebaseMode rebaseMode) { * @throws org.eclipse.jgit.api.errors.TransportException * @throws GitAPIException */ + @Override public PullResult call() throws GitAPIException, WrongRepositoryStateException, InvalidConfigurationException, DetachedHeadException, InvalidRemoteException, CanceledException, @@ -272,9 +279,9 @@ public PullResult call() throws GitAPIException, JGitText.get().operationCanceled, JGitText.get().pullTaskName)); - FetchCommand fetch = new FetchCommand(repo); - fetch.setRemote(remote); - fetch.setProgressMonitor(monitor); + FetchCommand fetch = new FetchCommand(repo).setRemote(remote) + .setProgressMonitor(monitor).setTagOpt(tagOption) + .setRecurseSubmodules(submoduleRecurseMode); configure(fetch); fetchRes = fetch.call(); @@ -412,6 +419,32 @@ public PullCommand setStrategy(MergeStrategy strategy) { } /** + * Sets the specification of annotated tag behavior during fetch + * + * @param tagOpt + * @return {@code this} + * @since 4.7 + */ + public PullCommand setTagOpt(TagOpt tagOpt) { + checkCallable(); + this.tagOption = tagOpt; + return this; + } + + /** + * Set the mode to be used for recursing into submodules. + * + * @param recurse + * @return {@code this} + * @since 4.7 + */ + public PullCommand setRecurseSubmodules( + FetchRecurseSubmodulesMode recurse) { + this.submoduleRecurseMode = recurse; + return this; + } + + /** * Reads the rebase mode to use for a pull command from the repository * configuration. This is the value defined for the configurations * {@code branch.[branchName].rebase}, or,if not set, {@code pull.rebase}.
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/api/PushCommand.java b/org.eclipse.jgit/src/org/eclipse/jgit/api/PushCommand.java index bd4521b..bf88842 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/api/PushCommand.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/api/PushCommand.java
@@ -47,9 +47,12 @@ import java.net.URISyntaxException; import java.text.MessageFormat; import java.util.ArrayList; +import java.util.Arrays; import java.util.Collection; import java.util.Collections; +import java.util.HashMap; import java.util.List; +import java.util.Map; import org.eclipse.jgit.api.errors.GitAPIException; import org.eclipse.jgit.api.errors.InvalidRemoteException; @@ -65,6 +68,7 @@ import org.eclipse.jgit.lib.Ref; import org.eclipse.jgit.lib.Repository; import org.eclipse.jgit.transport.PushResult; +import org.eclipse.jgit.transport.RefLeaseSpec; import org.eclipse.jgit.transport.RefSpec; import org.eclipse.jgit.transport.RemoteConfig; import org.eclipse.jgit.transport.RemoteRefUpdate; @@ -85,6 +89,8 @@ public class PushCommand extends private final List<RefSpec> refSpecs; + private final Map<String, RefLeaseSpec> refLeaseSpecs; + private ProgressMonitor monitor = NullProgressMonitor.INSTANCE; private String receivePack = RemoteConfig.DEFAULT_RECEIVE_PACK; @@ -103,7 +109,8 @@ public class PushCommand extends */ protected PushCommand(Repository repo) { super(repo); - refSpecs = new ArrayList<RefSpec>(3); + refSpecs = new ArrayList<>(3); + refLeaseSpecs = new HashMap<>(); } /** @@ -119,12 +126,13 @@ protected PushCommand(Repository repo) { * when an error occurs with the transport * @throws GitAPIException */ + @Override public Iterable<PushResult> call() throws GitAPIException, InvalidRemoteException, org.eclipse.jgit.api.errors.TransportException { checkCallable(); - ArrayList<PushResult> pushResults = new ArrayList<PushResult>(3); + ArrayList<PushResult> pushResults = new ArrayList<>(3); try { if (refSpecs.isEmpty()) { @@ -155,7 +163,7 @@ public Iterable<PushResult> call() throws GitAPIException, configure(transport); final Collection<RemoteRefUpdate> toPush = transport - .findRemoteRefUpdatesFor(refSpecs); + .findRemoteRefUpdatesFor(refSpecs, refLeaseSpecs); try { PushResult result = transport.push(monitor, toPush, out); @@ -271,6 +279,43 @@ public PushCommand setProgressMonitor(ProgressMonitor monitor) { } /** + * @return the ref lease specs + * @since 4.7 + */ + public List<RefLeaseSpec> getRefLeaseSpecs() { + return new ArrayList<>(refLeaseSpecs.values()); + } + + /** + * The ref lease specs to be used in the push operation, + * for a force-with-lease push operation. + * + * @param specs + * @return {@code this} + * @since 4.7 + */ + public PushCommand setRefLeaseSpecs(RefLeaseSpec... specs) { + return setRefLeaseSpecs(Arrays.asList(specs)); + } + + /** + * The ref lease specs to be used in the push operation, + * for a force-with-lease push operation. + * + * @param specs + * @return {@code this} + * @since 4.7 + */ + public PushCommand setRefLeaseSpecs(List<RefLeaseSpec> specs) { + checkCallable(); + this.refLeaseSpecs.clear(); + for (RefLeaseSpec spec : specs) { + refLeaseSpecs.put(spec.getRef(), spec); + } + return this; + } + + /** * @return the ref specs */ public List<RefSpec> getRefSpecs() {
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 d10cc3d..850ff49 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/api/RebaseCommand.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/api/RebaseCommand.java
@@ -258,6 +258,7 @@ protected RebaseCommand(Repository repo) { * @throws NoHeadException * @throws RefNotFoundException */ + @Override public RebaseResult call() throws GitAPIException, NoHeadException, RefNotFoundException, WrongRepositoryStateException { newHead = null; @@ -298,7 +299,7 @@ public RebaseResult call() throws GitAPIException, NoHeadException, org.eclipse.jgit.api.Status status = Git.wrap(repo) .status().setIgnoreSubmodules(IgnoreSubmoduleMode.ALL).call(); if (status.hasUncommittedChanges()) { - List<String> list = new ArrayList<String>(); + List<String> list = new ArrayList<>(); list.addAll(status.getUncommittedChanges()); return RebaseResult.uncommittedChanges(list); } @@ -649,7 +650,7 @@ private void writeMergeInfo(RevCommit commitToPick, // Get the rewritten equivalents for the parents of the given commit private List<RevCommit> getNewParents(RevCommit commitToPick) throws IOException { - List<RevCommit> newParents = new ArrayList<RevCommit>(); + List<RevCommit> newParents = new ArrayList<>(); for (int p = 0; p < commitToPick.getParentCount(); p++) { String parentHash = commitToPick.getParent(p).getName(); if (!new File(rebaseState.getRewrittenDir(), parentHash).exists()) @@ -805,8 +806,12 @@ private static String stripCommentLines(String commitMessage) { if (!line.trim().startsWith("#")) //$NON-NLS-1$ result.append(line).append("\n"); //$NON-NLS-1$ } - if (!commitMessage.endsWith("\n")) //$NON-NLS-1$ - result.deleteCharAt(result.length() - 1); + if (!commitMessage.endsWith("\n")) { //$NON-NLS-1$ + int bufferSize = result.length(); + if (bufferSize > 0 && result.charAt(bufferSize - 1) == '\n') { + result.deleteCharAt(bufferSize - 1); + } + } return result.toString(); } @@ -1055,8 +1060,8 @@ String toAuthorScript(PersonIdent author) { private void popSteps(int numSteps) throws IOException { if (numSteps == 0) return; - List<RebaseTodoLine> todoLines = new LinkedList<RebaseTodoLine>(); - List<RebaseTodoLine> poppedLines = new LinkedList<RebaseTodoLine>(); + List<RebaseTodoLine> todoLines = new LinkedList<>(); + List<RebaseTodoLine> poppedLines = new LinkedList<>(); for (RebaseTodoLine line : repo.readRebaseTodo( rebaseState.getPath(GIT_REBASE_TODO), true)) { @@ -1121,7 +1126,7 @@ else if (!isInteractive() && walk.isMergedInto(headCommit, upstream)) { } rebaseState.createFile(QUIET, ""); //$NON-NLS-1$ - ArrayList<RebaseTodoLine> toDoSteps = new ArrayList<RebaseTodoLine>(); + ArrayList<RebaseTodoLine> toDoSteps = new ArrayList<>(); toDoSteps.add(new RebaseTodoLine("# Created by EGit: rebasing " + headId.name() //$NON-NLS-1$ + " onto " + upstreamCommit.name())); //$NON-NLS-1$ // determine the commits to be applied @@ -1157,7 +1162,7 @@ private List<RevCommit> calculatePickList(RevCommit headCommit) LogCommand cmd = git.log().addRange(upstreamCommit, headCommit); commitsToUse = cmd.call(); } - List<RevCommit> cherryPickList = new ArrayList<RevCommit>(); + List<RevCommit> cherryPickList = new ArrayList<>(); for (RevCommit commit : commitsToUse) { if (preserveMerges || commit.getParentCount() == 1) cherryPickList.add(commit); @@ -1604,7 +1609,7 @@ PersonIdent parseAuthor(byte[] raw) { if (raw.length == 0) return null; - Map<String, String> keyValueMap = new HashMap<String, String>(); + Map<String, String> keyValueMap = new HashMap<>(); for (int p = 0; p < raw.length;) { int end = RawParseUtils.nextLF(raw, p); if (end == p)
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/api/ReflogCommand.java b/org.eclipse.jgit/src/org/eclipse/jgit/api/ReflogCommand.java index 4536af1..04caa0f 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/api/ReflogCommand.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/api/ReflogCommand.java
@@ -92,6 +92,7 @@ public ReflogCommand setRef(String ref) { * @throws GitAPIException * @throws InvalidRefNameException */ + @Override public Collection<ReflogEntry> call() throws GitAPIException, InvalidRefNameException { checkCallable();
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/api/RemoveNoteCommand.java b/org.eclipse.jgit/src/org/eclipse/jgit/api/RemoveNoteCommand.java index 1c4880c..fd8aac7 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/api/RemoveNoteCommand.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/api/RemoveNoteCommand.java
@@ -79,6 +79,7 @@ protected RemoveNoteCommand(Repository repo) { super(repo); } + @Override public Note call() throws GitAPIException { checkCallable(); try (RevWalk walk = new RevWalk(repo);
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/api/RenameBranchCommand.java b/org.eclipse.jgit/src/org/eclipse/jgit/api/RenameBranchCommand.java index 044a486..ce3a29f 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/api/RenameBranchCommand.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/api/RenameBranchCommand.java
@@ -96,6 +96,7 @@ protected RenameBranchCommand(Repository repo) { * if rename is tried without specifying the old name and HEAD * is detached */ + @Override public Ref call() throws GitAPIException, RefNotFoundException, InvalidRefNameException, RefAlreadyExistsException, DetachedHeadException { checkCallable();
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 106988d..c5222c2 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/api/ResetCommand.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/api/ResetCommand.java
@@ -121,7 +121,7 @@ public enum ResetType { private ResetType mode; - private Collection<String> filepaths = new LinkedList<String>(); + private Collection<String> filepaths = new LinkedList<>(); private boolean isReflogDisabled; @@ -141,6 +141,7 @@ public ResetCommand(Repository repo) { * @return the Ref after reset * @throws GitAPIException */ + @Override public Ref call() throws GitAPIException, CheckoutConflictException { checkCallable();
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 9d79ed0..c3152a9 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/api/RevertCommand.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/api/RevertCommand.java
@@ -85,11 +85,11 @@ * >Git documentation about revert</a> */ public class RevertCommand extends GitCommand<RevCommit> { - private List<Ref> commits = new LinkedList<Ref>(); + private List<Ref> commits = new LinkedList<>(); private String ourCommitName = null; - private List<Ref> revertedRefs = new LinkedList<Ref>(); + private List<Ref> revertedRefs = new LinkedList<>(); private MergeResult failingResult; @@ -120,6 +120,7 @@ protected RevertCommand(Repository repo) { * @throws UnmergedPathsException * @throws NoMessageException */ + @Override public RevCommit call() throws NoMessageException, UnmergedPathsException, ConcurrentRefUpdateException, WrongRepositoryStateException, GitAPIException {
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/api/RmCommand.java b/org.eclipse.jgit/src/org/eclipse/jgit/api/RmCommand.java index fd2cbe0..9e2cf31 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/api/RmCommand.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/api/RmCommand.java
@@ -99,7 +99,7 @@ public class RmCommand extends GitCommand<DirCache> { */ public RmCommand(Repository repo) { super(repo); - filepatterns = new LinkedList<String>(); + filepatterns = new LinkedList<>(); } /** @@ -136,6 +136,7 @@ public RmCommand setCached(boolean cached) { * * @return the DirCache after Rm */ + @Override public DirCache call() throws GitAPIException, NoFilepatternException {
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/api/ShowNoteCommand.java b/org.eclipse.jgit/src/org/eclipse/jgit/api/ShowNoteCommand.java index 168ea51..dbff463 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/api/ShowNoteCommand.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/api/ShowNoteCommand.java
@@ -74,6 +74,7 @@ protected ShowNoteCommand(Repository repo) { super(repo); } + @Override public Note call() throws GitAPIException { checkCallable(); NoteMap map = NoteMap.newEmptyMap();
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/api/StashApplyCommand.java b/org.eclipse.jgit/src/org/eclipse/jgit/api/StashApplyCommand.java index b8ee1ec..10ec2a6 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/api/StashApplyCommand.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/api/StashApplyCommand.java
@@ -157,6 +157,7 @@ private ObjectId getStashId() throws GitAPIException { * @throws NoHeadException * @throws StashApplyFailureException */ + @Override public ObjectId call() throws GitAPIException, WrongRepositoryStateException, NoHeadException, StashApplyFailureException { @@ -232,19 +233,19 @@ public ObjectId call() throws GitAPIException, untrackedMerger.setBase(null); boolean ok = untrackedMerger.merge(headCommit, untrackedCommit); - if (ok) + if (ok) { try { RevTree untrackedTree = revWalk - .parseTree(untrackedMerger - .getResultTreeId()); + .parseTree(untrackedCommit); resetUntracked(untrackedTree); } catch (CheckoutConflictException e) { throw new StashApplyFailureException( - JGitText.get().stashApplyConflict); + JGitText.get().stashApplyConflict, e); } - else + } else { throw new StashApplyFailureException( JGitText.get().stashApplyConflict); + } } } else { throw new StashApplyFailureException(
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/api/StashCreateCommand.java b/org.eclipse.jgit/src/org/eclipse/jgit/api/StashCreateCommand.java index ee9b7fc..681f8e6 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/api/StashCreateCommand.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/api/StashCreateCommand.java
@@ -236,6 +236,7 @@ private Ref getHead() throws GitAPIException { * @return stashed commit or null if no changes to stash * @throws GitAPIException */ + @Override public RevCommit call() throws GitAPIException { checkCallable(); @@ -261,9 +262,9 @@ public RevCommit call() throws GitAPIException { return null; MutableObjectId id = new MutableObjectId(); - List<PathEdit> wtEdits = new ArrayList<PathEdit>(); - List<String> wtDeletes = new ArrayList<String>(); - List<DirCacheEntry> untracked = new ArrayList<DirCacheEntry>(); + List<PathEdit> wtEdits = new ArrayList<>(); + List<String> wtDeletes = new ArrayList<>(); + List<DirCacheEntry> untracked = new ArrayList<>(); boolean hasChanges = false; do { AbstractTreeIterator headIter = treeWalk.getTree(0, @@ -305,6 +306,7 @@ public RevCommit call() throws GitAPIException { untracked.add(entry); else wtEdits.add(new PathEdit(entry) { + @Override public void apply(DirCacheEntry ent) { ent.copyMetaData(entry); }
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/api/StashDropCommand.java b/org.eclipse.jgit/src/org/eclipse/jgit/api/StashDropCommand.java index 6e1d0f2..e215bdf 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/api/StashDropCommand.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/api/StashDropCommand.java
@@ -171,6 +171,7 @@ private void updateRef(Ref stashRef, ObjectId newId) { * @return commit id of stash reference or null if no more stashed changes * @throws GitAPIException */ + @Override public ObjectId call() throws GitAPIException { checkCallable();
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/api/StashListCommand.java b/org.eclipse.jgit/src/org/eclipse/jgit/api/StashListCommand.java index aedc9a6..8420dd2 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/api/StashListCommand.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/api/StashListCommand.java
@@ -76,6 +76,7 @@ public StashListCommand(final Repository repo) { super(repo); } + @Override public Collection<RevCommit> call() throws GitAPIException, InvalidRefNameException { checkCallable(); @@ -94,7 +95,7 @@ public Collection<RevCommit> call() throws GitAPIException, if (stashEntries.isEmpty()) return Collections.emptyList(); - final List<RevCommit> stashCommits = new ArrayList<RevCommit>( + final List<RevCommit> stashCommits = new ArrayList<>( stashEntries.size()); try (RevWalk walk = new RevWalk(repo)) { for (ReflogEntry entry : stashEntries) {
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/api/Status.java b/org.eclipse.jgit/src/org/eclipse/jgit/api/Status.java index 48759c2..5b7c73b 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/api/Status.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/api/Status.java
@@ -189,7 +189,7 @@ public Set<String> getIgnoredNotInIndex() { * @since 3.2 */ public Set<String> getUncommittedChanges() { - Set<String> uncommittedChanges = new HashSet<String>(); + Set<String> uncommittedChanges = new HashSet<>(); uncommittedChanges.addAll(diff.getAdded()); uncommittedChanges.addAll(diff.getChanged()); uncommittedChanges.addAll(diff.getRemoved());
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/api/StatusCommand.java b/org.eclipse.jgit/src/org/eclipse/jgit/api/StatusCommand.java index 9752195..8f7804a 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/api/StatusCommand.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/api/StatusCommand.java
@@ -109,7 +109,7 @@ public StatusCommand setIgnoreSubmodules(IgnoreSubmoduleMode mode) { */ public StatusCommand addPath(String path) { if (paths == null) - paths = new LinkedList<String>(); + paths = new LinkedList<>(); paths.add(path); return this; } @@ -134,6 +134,7 @@ public List<String> getPaths() { * @return a {@link Status} object telling about each path where working * tree, index or HEAD differ from each other. */ + @Override public Status call() throws GitAPIException, NoWorkTreeException { if (workingTreeIt == null) workingTreeIt = new FileTreeIterator(repo);
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/api/SubmoduleAddCommand.java b/org.eclipse.jgit/src/org/eclipse/jgit/api/SubmoduleAddCommand.java index b0f772e..e3ba894 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/api/SubmoduleAddCommand.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/api/SubmoduleAddCommand.java
@@ -51,6 +51,7 @@ import org.eclipse.jgit.api.errors.NoFilepatternException; import org.eclipse.jgit.errors.ConfigInvalidException; import org.eclipse.jgit.internal.JGitText; +import org.eclipse.jgit.internal.submodule.SubmoduleValidator; import org.eclipse.jgit.lib.ConfigConstants; import org.eclipse.jgit.lib.Constants; import org.eclipse.jgit.lib.NullProgressMonitor; @@ -149,6 +150,7 @@ protected boolean submoduleExists() throws IOException { * @return the newly created {@link Repository} * @throws GitAPIException */ + @Override public Repository call() throws GitAPIException { checkCallable(); if (path == null || path.length() == 0) @@ -157,6 +159,14 @@ public Repository call() throws GitAPIException { throw new IllegalArgumentException(JGitText.get().uriNotConfigured); try { + SubmoduleValidator.assertValidSubmoduleName(path); + SubmoduleValidator.assertValidSubmodulePath(path); + SubmoduleValidator.assertValidSubmoduleUri(uri); + } catch (SubmoduleValidator.SubmoduleValidationException e) { + throw new IllegalArgumentException(e.getMessage()); + } + + try { if (submoduleExists()) throw new JGitInternalException(MessageFormat.format( JGitText.get().submoduleExists, path));
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/api/SubmoduleInitCommand.java b/org.eclipse.jgit/src/org/eclipse/jgit/api/SubmoduleInitCommand.java index 1dbe368..4c5e317 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/api/SubmoduleInitCommand.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/api/SubmoduleInitCommand.java
@@ -76,7 +76,7 @@ public class SubmoduleInitCommand extends GitCommand<Collection<String>> { */ public SubmoduleInitCommand(final Repository repo) { super(repo); - paths = new ArrayList<String>(); + paths = new ArrayList<>(); } /** @@ -91,6 +91,7 @@ public SubmoduleInitCommand addPath(final String path) { return this; } + @Override public Collection<String> call() throws GitAPIException { checkCallable(); @@ -98,7 +99,7 @@ public Collection<String> call() throws GitAPIException { if (!paths.isEmpty()) generator.setFilter(PathFilterGroup.createFromStrings(paths)); StoredConfig config = repo.getConfig(); - List<String> initialized = new ArrayList<String>(); + List<String> initialized = new ArrayList<>(); while (generator.next()) { // Ignore entry if URL is already present in config file if (generator.getConfigUrl() != null)
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/api/SubmoduleStatusCommand.java b/org.eclipse.jgit/src/org/eclipse/jgit/api/SubmoduleStatusCommand.java index a1ea790..8b27e4c 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/api/SubmoduleStatusCommand.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/api/SubmoduleStatusCommand.java
@@ -76,7 +76,7 @@ public class SubmoduleStatusCommand extends */ public SubmoduleStatusCommand(final Repository repo) { super(repo); - paths = new ArrayList<String>(); + paths = new ArrayList<>(); } /** @@ -91,13 +91,14 @@ public SubmoduleStatusCommand addPath(final String path) { return this; } + @Override public Map<String, SubmoduleStatus> call() throws GitAPIException { checkCallable(); try (SubmoduleWalk generator = SubmoduleWalk.forIndex(repo)) { if (!paths.isEmpty()) generator.setFilter(PathFilterGroup.createFromStrings(paths)); - Map<String, SubmoduleStatus> statuses = new HashMap<String, SubmoduleStatus>(); + Map<String, SubmoduleStatus> statuses = new HashMap<>(); while (generator.next()) { SubmoduleStatus status = getStatus(generator); statuses.put(status.getPath(), status);
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 088eedc..f97dce9 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/api/SubmoduleSyncCommand.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/api/SubmoduleSyncCommand.java
@@ -78,7 +78,7 @@ public class SubmoduleSyncCommand extends GitCommand<Map<String, String>> { */ public SubmoduleSyncCommand(final Repository repo) { super(repo); - paths = new ArrayList<String>(); + paths = new ArrayList<>(); } /** @@ -108,13 +108,14 @@ protected String getHeadBranch(final Repository subRepo) throws IOException { return null; } + @Override public Map<String, String> call() throws GitAPIException { checkCallable(); try (SubmoduleWalk generator = SubmoduleWalk.forIndex(repo)) { if (!paths.isEmpty()) generator.setFilter(PathFilterGroup.createFromStrings(paths)); - Map<String, String> synced = new HashMap<String, String>(); + Map<String, String> synced = new HashMap<>(); StoredConfig config = repo.getConfig(); while (generator.next()) { String remoteUrl = generator.getRemoteUrl();
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/api/SubmoduleUpdateCommand.java b/org.eclipse.jgit/src/org/eclipse/jgit/api/SubmoduleUpdateCommand.java index 342d7f4..29d5d49 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/api/SubmoduleUpdateCommand.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/api/SubmoduleUpdateCommand.java
@@ -94,7 +94,7 @@ public class SubmoduleUpdateCommand extends */ public SubmoduleUpdateCommand(final Repository repo) { super(repo); - paths = new ArrayList<String>(); + paths = new ArrayList<>(); } /** @@ -137,6 +137,7 @@ public SubmoduleUpdateCommand addPath(final String path) { * @throws WrongRepositoryStateException * @throws GitAPIException */ + @Override public Collection<String> call() throws InvalidConfigurationException, NoHeadException, ConcurrentRefUpdateException, CheckoutConflictException, InvalidMergeHeadsException, @@ -147,7 +148,7 @@ public Collection<String> call() throws InvalidConfigurationException, try (SubmoduleWalk generator = SubmoduleWalk.forIndex(repo)) { if (!paths.isEmpty()) generator.setFilter(PathFilterGroup.createFromStrings(paths)); - List<String> updated = new ArrayList<String>(); + List<String> updated = new ArrayList<>(); while (generator.next()) { // Skip submodules not registered in .gitmodules file if (generator.getModulesPath() == null)
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/api/TagCommand.java b/org.eclipse.jgit/src/org/eclipse/jgit/api/TagCommand.java index 39dd42c..bdbb862 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/api/TagCommand.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/api/TagCommand.java
@@ -121,6 +121,7 @@ protected TagCommand(Repository repo) { * when called on a git repo without a HEAD reference * @since 2.0 */ + @Override public Ref call() throws GitAPIException, ConcurrentRefUpdateException, InvalidTagNameException, NoHeadException { checkCallable();
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/api/errors/CheckoutConflictException.java b/org.eclipse.jgit/src/org/eclipse/jgit/api/errors/CheckoutConflictException.java index e317507..7df35c9 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/api/errors/CheckoutConflictException.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/api/errors/CheckoutConflictException.java
@@ -95,7 +95,7 @@ public List<String> getConflictingPaths() { */ CheckoutConflictException addConflictingPath(String conflictingPath) { if (conflictingPaths == null) - conflictingPaths = new LinkedList<String>(); + conflictingPaths = new LinkedList<>(); conflictingPaths.add(conflictingPath); return this; }
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/attributes/AttributesNode.java b/org.eclipse.jgit/src/org/eclipse/jgit/attributes/AttributesNode.java index 7196502..13aeaee 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/attributes/AttributesNode.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/attributes/AttributesNode.java
@@ -65,7 +65,7 @@ public class AttributesNode { /** Create an empty ignore node with no rules. */ public AttributesNode() { - rules = new ArrayList<AttributesRule>(); + rules = new ArrayList<>(); } /**
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 0532250..c9c69db 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/attributes/AttributesRule.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/attributes/AttributesRule.java
@@ -71,7 +71,7 @@ public class AttributesRule { private static List<Attribute> parseAttributes(String attributesLine) { // the C implementation oddly enough allows \r between attributes too. - ArrayList<Attribute> result = new ArrayList<Attribute>(); + ArrayList<Attribute> result = new ArrayList<>(); for (String attribute : attributesLine.split(ATTRIBUTES_SPLIT_REGEX)) { attribute = attribute.trim(); if (attribute.length() == 0)
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 fa6fe75..4ad58c3 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/blame/BlameGenerator.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/blame/BlameGenerator.java
@@ -51,6 +51,7 @@ import java.util.Collection; import java.util.Collections; +import org.eclipse.jgit.annotations.Nullable; import org.eclipse.jgit.blame.Candidate.BlobCandidate; import org.eclipse.jgit.blame.Candidate.ReverseCandidate; import org.eclipse.jgit.blame.ReverseWalk.ReverseCommit; @@ -238,11 +239,13 @@ public BlameGenerator setFollowFileRenames(boolean follow) { } /** - * Obtain the RenameDetector if {@code setFollowFileRenames(true)}. + * Obtain the RenameDetector, allowing the application to configure its + * settings for rename score and breaking behavior. * - * @return the rename detector, allowing the application to configure its - * settings for rename score and breaking behavior. + * @return the rename detector, or {@code null} if + * {@code setFollowFileRenames(false)}. */ + @Nullable public RenameDetector getRenameDetector() { return renameDetector; }
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/diff/DiffAlgorithm.java b/org.eclipse.jgit/src/org/eclipse/jgit/diff/DiffAlgorithm.java index 39421c6..bd6e5c8 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/diff/DiffAlgorithm.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/diff/DiffAlgorithm.java
@@ -117,7 +117,7 @@ public <S extends Sequence> EditList diff( if (region.getLengthA() == 1 && region.getLengthB() == 1) return EditList.singleton(region); - SubsequenceComparator<S> cs = new SubsequenceComparator<S>(cmp); + SubsequenceComparator<S> cs = new SubsequenceComparator<>(cmp); Subsequence<S> as = Subsequence.a(a, region); Subsequence<S> bs = Subsequence.b(b, region); EditList e = Subsequence.toBase(diffNonCommon(cs, as, bs), as, bs);
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 b1cbb91..324b99e 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/diff/DiffConfig.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/diff/DiffConfig.java
@@ -55,6 +55,7 @@ public class DiffConfig { /** Key for {@link Config#get(SectionParser)}. */ public static final Config.SectionParser<DiffConfig> KEY = new SectionParser<DiffConfig>() { + @Override public DiffConfig parse(final Config cfg) { return new DiffConfig(cfg); }
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 24409ee..e1dfcff 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/diff/DiffEntry.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/diff/DiffEntry.java
@@ -179,7 +179,7 @@ public static List<DiffEntry> scan(TreeWalk walk, boolean includeTrees, else treeFilterMarker = null; - List<DiffEntry> r = new ArrayList<DiffEntry>(); + List<DiffEntry> r = new ArrayList<>(); MutableObjectId idBuf = new MutableObjectId(); while (walk.next()) { DiffEntry entry = new DiffEntry();
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 819442c..fa7cc0d 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/diff/DiffFormatter.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/diff/DiffFormatter.java
@@ -682,7 +682,7 @@ public void format(DiffEntry ent) throws IOException { } private static byte[] writeGitLinkText(AbbreviatedObjectId id) { - if (id.toObjectId().equals(ObjectId.zeroId())) { + if (ObjectId.zeroId().equals(id.toObjectId())) { return EMPTY; } return encodeASCII("Subproject commit " + id.name() //$NON-NLS-1$
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/diff/HashedSequencePair.java b/org.eclipse.jgit/src/org/eclipse/jgit/diff/HashedSequencePair.java index 74bbca1..bf6d967 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/diff/HashedSequencePair.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/diff/HashedSequencePair.java
@@ -81,7 +81,7 @@ public HashedSequencePair(SequenceComparator<? super S> cmp, S a, S b) { /** @return obtain a comparator that uses the cached hash codes. */ public HashedSequenceComparator<S> getComparator() { - return new HashedSequenceComparator<S>(cmp); + return new HashedSequenceComparator<>(cmp); } /** @return wrapper around A that includes cached hash codes. */ @@ -103,6 +103,6 @@ private HashedSequence<S> wrap(S base) { final int[] hashes = new int[end]; for (int ptr = 0; ptr < end; ptr++) hashes[ptr] = cmp.hash(base, ptr); - return new HashedSequence<S>(base, hashes); + return new HashedSequence<>(base, hashes); } }
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/diff/HistogramDiff.java b/org.eclipse.jgit/src/org/eclipse/jgit/diff/HistogramDiff.java index 2f5c9ea..4ef5845 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/diff/HistogramDiff.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/diff/HistogramDiff.java
@@ -130,17 +130,18 @@ public void setMaxChainLength(int maxLen) { maxChainLength = maxLen; } + @Override public <S extends Sequence> void diffNonCommon(EditList edits, HashedSequenceComparator<S> cmp, HashedSequence<S> a, HashedSequence<S> b, Edit region) { - new State<S>(edits, cmp, a, b).diffRegion(region); + new State<>(edits, cmp, a, b).diffRegion(region); } private class State<S extends Sequence> { private final HashedSequenceComparator<S> cmp; private final HashedSequence<S> a; private final HashedSequence<S> b; - private final List<Edit> queue = new ArrayList<Edit>(); + private final List<Edit> queue = new ArrayList<>(); /** Result edits we have determined that must be made to convert a to b. */ final EditList edits; @@ -160,7 +161,7 @@ void diffRegion(Edit r) { } private void diffReplace(Edit r) { - Edit lcs = new HistogramDiffIndex<S>(maxChainLength, cmp, a, b, r) + Edit lcs = new HistogramDiffIndex<>(maxChainLength, cmp, a, b, r) .findLongestCommonSequence(); if (lcs != null) { // If we were given an edit, we can prove a result here. @@ -213,7 +214,7 @@ private void diff(Edit r) { } private SubsequenceComparator<HashedSequence<S>> subcmp() { - return new SubsequenceComparator<HashedSequence<S>>(cmp); + return new SubsequenceComparator<>(cmp); } } }
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/diff/LowLevelDiffAlgorithm.java b/org.eclipse.jgit/src/org/eclipse/jgit/diff/LowLevelDiffAlgorithm.java index e3861cd..55ceec8 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/diff/LowLevelDiffAlgorithm.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/diff/LowLevelDiffAlgorithm.java
@@ -48,7 +48,7 @@ public abstract class LowLevelDiffAlgorithm extends DiffAlgorithm { @Override public <S extends Sequence> EditList diffNonCommon( SequenceComparator<? super S> cmp, S a, S b) { - HashedSequencePair<S> p = new HashedSequencePair<S>(cmp, a, b); + HashedSequencePair<S> p = new HashedSequencePair<>(cmp, a, b); HashedSequenceComparator<S> hc = p.getComparator(); HashedSequence<S> ha = p.getA(); HashedSequence<S> hb = p.getB();
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/diff/MyersDiff.java b/org.eclipse.jgit/src/org/eclipse/jgit/diff/MyersDiff.java index 9810a6a..e1bda11 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/diff/MyersDiff.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/diff/MyersDiff.java
@@ -460,6 +460,7 @@ boolean calculate(int d) { } class ForwardEditPaths extends EditPaths { + @Override final int snake(int k, int x) { for (; x < endA && k + x < endB; x++) if (!cmp.equals(a, x, b, k + x)) @@ -467,18 +468,22 @@ final int snake(int k, int x) { return x; } + @Override final int getLeft(final int x) { return x; } + @Override final int getRight(final int x) { return x + 1; } + @Override final boolean isBetter(final int left, final int right) { return left > right; } + @Override final void adjustMinMaxK(final int k, final int x) { if (x >= endA || k + x >= endB) { if (k > backward.middleK) @@ -488,6 +493,7 @@ final void adjustMinMaxK(final int k, final int x) { } } + @Override final boolean meets(int d, int k, int x, long snake) { if (k < backward.beginK || k > backward.endK) return false; @@ -502,6 +508,7 @@ final boolean meets(int d, int k, int x, long snake) { } class BackwardEditPaths extends EditPaths { + @Override final int snake(int k, int x) { for (; x > beginA && k + x > beginB; x--) if (!cmp.equals(a, x - 1, b, k + x - 1)) @@ -509,18 +516,22 @@ final int snake(int k, int x) { return x; } + @Override final int getLeft(final int x) { return x - 1; } + @Override final int getRight(final int x) { return x; } + @Override final boolean isBetter(final int left, final int right) { return left < right; } + @Override final void adjustMinMaxK(final int k, final int x) { if (x <= beginA || k + x <= beginB) { if (k > forward.middleK) @@ -530,6 +541,7 @@ final void adjustMinMaxK(final int k, final int x) { } } + @Override final boolean meets(int d, int k, int x, long snake) { if (k < forward.beginK || k > forward.endK) return false;
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 b26e1bc..5bfee75 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/diff/RawText.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/diff/RawText.java
@@ -107,6 +107,7 @@ public RawText(File file) throws IOException { } /** @return total number of items in the sequence. */ + @Override public int size() { // The line map is always 2 entries larger than the number of lines in // the file. Index 0 is padded out/unused. The last index is the total
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/diff/RenameDetector.java b/org.eclipse.jgit/src/org/eclipse/jgit/diff/RenameDetector.java index 8865b62..bc52473 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/diff/RenameDetector.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/diff/RenameDetector.java
@@ -70,6 +70,7 @@ public class RenameDetector { private static final int EXACT_RENAME_SCORE = 100; private static final Comparator<DiffEntry> DIFF_COMPARATOR = new Comparator<DiffEntry>() { + @Override public int compare(DiffEntry a, DiffEntry b) { int cmp = nameOf(a).compareTo(nameOf(b)); if (cmp == 0) @@ -392,15 +393,15 @@ public List<DiffEntry> compute(ContentSource.Pair reader, ProgressMonitor pm) /** Reset this rename detector for another rename detection pass. */ public void reset() { - entries = new ArrayList<DiffEntry>(); - deleted = new ArrayList<DiffEntry>(); - added = new ArrayList<DiffEntry>(); + entries = new ArrayList<>(); + deleted = new ArrayList<>(); + added = new ArrayList<>(); done = false; } private void breakModifies(ContentSource.Pair reader, ProgressMonitor pm) throws IOException { - ArrayList<DiffEntry> newEntries = new ArrayList<DiffEntry>(entries.size()); + ArrayList<DiffEntry> newEntries = new ArrayList<>(entries.size()); pm.beginTask(JGitText.get().renamesBreakingModifies, entries.size()); @@ -427,8 +428,8 @@ private void breakModifies(ContentSource.Pair reader, ProgressMonitor pm) } private void rejoinModifies(ProgressMonitor pm) { - HashMap<String, DiffEntry> nameMap = new HashMap<String, DiffEntry>(); - ArrayList<DiffEntry> newAdded = new ArrayList<DiffEntry>(added.size()); + HashMap<String, DiffEntry> nameMap = new HashMap<>(); + ArrayList<DiffEntry> newAdded = new ArrayList<>(added.size()); pm.beginTask(JGitText.get().renamesRejoiningModifies, added.size() + deleted.size()); @@ -455,7 +456,7 @@ private void rejoinModifies(ProgressMonitor pm) { } added = newAdded; - deleted = new ArrayList<DiffEntry>(nameMap.values()); + deleted = new ArrayList<>(nameMap.values()); } private int calculateModifyScore(ContentSource.Pair reader, DiffEntry d) @@ -507,8 +508,8 @@ private void findExactRenames(ProgressMonitor pm) { HashMap<AbbreviatedObjectId, Object> deletedMap = populateMap(deleted, pm); HashMap<AbbreviatedObjectId, Object> addedMap = populateMap(added, pm); - ArrayList<DiffEntry> uniqueAdds = new ArrayList<DiffEntry>(added.size()); - ArrayList<List<DiffEntry>> nonUniqueAdds = new ArrayList<List<DiffEntry>>(); + ArrayList<DiffEntry> uniqueAdds = new ArrayList<>(added.size()); + ArrayList<List<DiffEntry>> nonUniqueAdds = new ArrayList<>(); for (Object o : addedMap.values()) { if (o instanceof DiffEntry) @@ -517,7 +518,7 @@ private void findExactRenames(ProgressMonitor pm) { nonUniqueAdds.add((List<DiffEntry>) o); } - ArrayList<DiffEntry> left = new ArrayList<DiffEntry>(added.size()); + ArrayList<DiffEntry> left = new ArrayList<>(added.size()); for (DiffEntry a : uniqueAdds) { Object del = deletedMap.get(a.newId); @@ -626,7 +627,7 @@ private void findExactRenames(ProgressMonitor pm) { } added = left; - deleted = new ArrayList<DiffEntry>(deletedMap.size()); + deleted = new ArrayList<>(deletedMap.size()); for (Object o : deletedMap.values()) { if (o instanceof DiffEntry) { DiffEntry e = (DiffEntry) o; @@ -676,11 +677,11 @@ private static DiffEntry bestPathMatch(DiffEntry src, List<DiffEntry> list) { @SuppressWarnings("unchecked") private HashMap<AbbreviatedObjectId, Object> populateMap( List<DiffEntry> diffEntries, ProgressMonitor pm) { - HashMap<AbbreviatedObjectId, Object> map = new HashMap<AbbreviatedObjectId, Object>(); + HashMap<AbbreviatedObjectId, Object> map = new HashMap<>(); for (DiffEntry de : diffEntries) { Object old = map.put(id(de), de); if (old instanceof DiffEntry) { - ArrayList<DiffEntry> list = new ArrayList<DiffEntry>(2); + ArrayList<DiffEntry> list = new ArrayList<>(2); list.add((DiffEntry) old); list.add(de); map.put(id(de), list);
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 6088d72..653658b 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/diff/SimilarityRenameDetector.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/diff/SimilarityRenameDetector.java
@@ -136,7 +136,7 @@ void compute(ProgressMonitor pm) throws IOException { 2 * srcs.size() * dsts.size()); int mNext = buildMatrix(pm); - out = new ArrayList<DiffEntry>(Math.min(mNext, dsts.size())); + out = new ArrayList<>(Math.min(mNext, dsts.size())); // Match rename pairs on a first come, first serve basis until // we have looked at everything that is above our minimum score. @@ -192,7 +192,7 @@ boolean isTableOverflow() { } private static List<DiffEntry> compactSrcList(List<DiffEntry> in) { - ArrayList<DiffEntry> r = new ArrayList<DiffEntry>(in.size()); + ArrayList<DiffEntry> r = new ArrayList<>(in.size()); for (DiffEntry e : in) { if (e.changeType == ChangeType.DELETE) r.add(e); @@ -201,7 +201,7 @@ private static List<DiffEntry> compactSrcList(List<DiffEntry> in) { } private static List<DiffEntry> compactDstList(List<DiffEntry> in) { - ArrayList<DiffEntry> r = new ArrayList<DiffEntry>(in.size()); + ArrayList<DiffEntry> r = new ArrayList<>(in.size()); for (DiffEntry e : in) { if (e != null) r.add(e);
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/diff/Subsequence.java b/org.eclipse.jgit/src/org/eclipse/jgit/diff/Subsequence.java index 017fe69..50ca613 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/diff/Subsequence.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/diff/Subsequence.java
@@ -66,7 +66,7 @@ public final class Subsequence<S extends Sequence> extends Sequence { * @return subsequence of {@code base} as described by A in {@code region}. */ public static <S extends Sequence> Subsequence<S> a(S a, Edit region) { - return new Subsequence<S>(a, region.beginA, region.endA); + return new Subsequence<>(a, region.beginA, region.endA); } /** @@ -81,7 +81,7 @@ public static <S extends Sequence> Subsequence<S> a(S a, Edit region) { * @return subsequence of {@code base} as described by B in {@code region}. */ public static <S extends Sequence> Subsequence<S> b(S b, Edit region) { - return new Subsequence<S>(b, region.beginB, region.endB); + return new Subsequence<>(b, region.beginB, region.endB); } /**
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/dircache/DirCache.java b/org.eclipse.jgit/src/org/eclipse/jgit/dircache/DirCache.java index b0cf8be..ce52fed 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/dircache/DirCache.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/dircache/DirCache.java
@@ -111,6 +111,7 @@ public class DirCache { private static final byte[] NO_CHECKSUM = {}; static final Comparator<DirCacheEntry> ENT_CMP = new Comparator<DirCacheEntry>() { + @Override public int compare(final DirCacheEntry o1, final DirCacheEntry o2) { final int cr = cmp(o1, o2); if (cr != 0) @@ -992,7 +993,7 @@ private void registerIndexChangedListener(IndexChangedListener listener) { * @throws IOException */ private void updateSmudgedEntries() throws IOException { - List<String> paths = new ArrayList<String>(128); + List<String> paths = new ArrayList<>(128); try (TreeWalk walk = new TreeWalk(repository)) { walk.setOperationType(OperationType.CHECKIN_OP); for (int i = 0; i < entryCnt; i++)
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/dircache/DirCacheBuilder.java b/org.eclipse.jgit/src/org/eclipse/jgit/dircache/DirCacheBuilder.java index cfebe2d..676a6ab 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/dircache/DirCacheBuilder.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/dircache/DirCacheBuilder.java
@@ -218,6 +218,7 @@ private static DirCacheEntry toEntry(int stage, CanonicalTreeParser i) { return e; } + @Override public void finish() { if (!sorted) resort();
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 c318443..84f0da9 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/dircache/DirCacheCheckout.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/dircache/DirCacheCheckout.java
@@ -127,11 +127,11 @@ public CheckoutMetadata(EolStreamType eolStreamType, private Repository repo; - private HashMap<String, CheckoutMetadata> updated = new HashMap<String, CheckoutMetadata>(); + private HashMap<String, CheckoutMetadata> updated = new HashMap<>(); - private ArrayList<String> conflicts = new ArrayList<String>(); + private ArrayList<String> conflicts = new ArrayList<>(); - private ArrayList<String> removed = new ArrayList<String>(); + private ArrayList<String> removed = new ArrayList<>(); private ObjectId mergeCommitTree; @@ -147,7 +147,7 @@ public CheckoutMetadata(EolStreamType eolStreamType, private boolean failOnConflict = true; - private ArrayList<String> toBeDeleted = new ArrayList<String>(); + private ArrayList<String> toBeDeleted = new ArrayList<>(); private boolean emptyDirCache;
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/dircache/DirCacheEditor.java b/org.eclipse.jgit/src/org/eclipse/jgit/dircache/DirCacheEditor.java index c987c96..22bedcf 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/dircache/DirCacheEditor.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/dircache/DirCacheEditor.java
@@ -74,6 +74,7 @@ */ public class DirCacheEditor extends BaseDirCacheEditor { private static final Comparator<PathEdit> EDIT_CMP = new Comparator<PathEdit>() { + @Override public int compare(final PathEdit o1, final PathEdit o2) { final byte[] a = o1.path; final byte[] b = o2.path; @@ -95,7 +96,7 @@ public int compare(final PathEdit o1, final PathEdit o2) { */ protected DirCacheEditor(final DirCache dc, final int ecnt) { super(dc, ecnt); - edits = new ArrayList<PathEdit>(); + edits = new ArrayList<>(); } /** @@ -123,6 +124,7 @@ public boolean commit() throws IOException { return super.commit(); } + @Override public void finish() { if (!edits.isEmpty()) { applyEdits(); @@ -383,6 +385,7 @@ public DeletePath(final DirCacheEntry ent) { super(ent); } + @Override public void apply(final DirCacheEntry ent) { throw new UnsupportedOperationException(JGitText.get().noApplyInDelete); } @@ -432,6 +435,7 @@ public DeleteTree(String entryPath) { return path; } + @Override public void apply(final DirCacheEntry ent) { throw new UnsupportedOperationException(JGitText.get().noApplyInDelete); }
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/dircache/DirCacheTree.java b/org.eclipse.jgit/src/org/eclipse/jgit/dircache/DirCacheTree.java index 8bcf4bf..a06f9d3 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/dircache/DirCacheTree.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/dircache/DirCacheTree.java
@@ -80,6 +80,7 @@ public class DirCacheTree { private static final DirCacheTree[] NO_CHILDREN = {}; private static final Comparator<DirCacheTree> TREE_CMP = new Comparator<DirCacheTree>() { + @Override public int compare(final DirCacheTree o1, final DirCacheTree o2) { final byte[] a = o1.encodedName; final byte[] b = o2.encodedName;
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/errors/CancelledException.java b/org.eclipse.jgit/src/org/eclipse/jgit/errors/CancelledException.java new file mode 100644 index 0000000..c2833a1 --- /dev/null +++ b/org.eclipse.jgit/src/org/eclipse/jgit/errors/CancelledException.java
@@ -0,0 +1,62 @@ +/* + * Copyright (C) 2017 Ericsson + * 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.errors; + +import java.io.IOException; + +/** + * Thrown when an operation was canceled + * + * @since 4.7 + */ +public class CancelledException extends IOException { + private static final long serialVersionUID = 1L; + + /** + * @param message + */ + public CancelledException(String message) { + super(message); + } +}
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/errors/CompoundException.java b/org.eclipse.jgit/src/org/eclipse/jgit/errors/CompoundException.java index 55b64ee..3a7b2c6 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/errors/CompoundException.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/errors/CompoundException.java
@@ -75,7 +75,7 @@ private static String format(final Collection<Throwable> causes) { */ public CompoundException(final Collection<Throwable> why) { super(format(why)); - causeList = Collections.unmodifiableList(new ArrayList<Throwable>(why)); + causeList = Collections.unmodifiableList(new ArrayList<>(why)); } /**
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/events/ListenerList.java b/org.eclipse.jgit/src/org/eclipse/jgit/events/ListenerList.java index 6ac4b0f..12ef533 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/events/ListenerList.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/events/ListenerList.java
@@ -50,7 +50,7 @@ /** Manages a thread-safe list of {@link RepositoryListener}s. */ public class ListenerList { - private final ConcurrentMap<Class<? extends RepositoryListener>, CopyOnWriteArrayList<ListenerHandle>> lists = new ConcurrentHashMap<Class<? extends RepositoryListener>, CopyOnWriteArrayList<ListenerHandle>>(); + private final ConcurrentMap<Class<? extends RepositoryListener>, CopyOnWriteArrayList<ListenerHandle>> lists = new ConcurrentHashMap<>(); /** * Register an IndexChangedListener. @@ -126,7 +126,7 @@ private void add(ListenerHandle handle) { if (list == null) { CopyOnWriteArrayList<ListenerHandle> newList; - newList = new CopyOnWriteArrayList<ListenerHandle>(); + newList = new CopyOnWriteArrayList<>(); list = lists.putIfAbsent(handle.type, newList); if (list == null) list = newList;
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 0aa0075..10c84c4 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/fnmatch/AbstractHead.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/fnmatch/AbstractHead.java
@@ -70,6 +70,7 @@ public final void setNewHeads(List<Head> newHeads) { this.newHeads = newHeads; } + @Override public List<Head> getNextHeads(char c) { if (matches(c)) return newHeads;
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 f9c2394..856d74e 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/fnmatch/FileNameMatcher.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/fnmatch/FileNameMatcher.java
@@ -120,9 +120,9 @@ private FileNameMatcher(final List<Head> headsStartValue) { private FileNameMatcher(final List<Head> headsStartValue, final List<Head> heads) { this.headsStartValue = headsStartValue; - this.heads = new ArrayList<Head>(heads.size()); + this.heads = new ArrayList<>(heads.size()); this.heads.addAll(heads); - this.listForLocalUseage = new ArrayList<Head>(heads.size()); + this.listForLocalUseage = new ArrayList<>(heads.size()); } /** @@ -158,7 +158,7 @@ private static List<Head> createHeadsStartValues( final List<AbstractHead> allHeads = parseHeads(patternString, invalidWildgetCharacter); - List<Head> nextHeadsSuggestion = new ArrayList<Head>(2); + List<Head> nextHeadsSuggestion = new ArrayList<>(2); nextHeadsSuggestion.add(LastHead.INSTANCE); for (int i = allHeads.size() - 1; i >= 0; i--) { final AbstractHead head = allHeads.get(i); @@ -172,7 +172,7 @@ private static List<Head> createHeadsStartValues( head.setNewHeads(nextHeadsSuggestion); } else { head.setNewHeads(nextHeadsSuggestion); - nextHeadsSuggestion = new ArrayList<Head>(2); + nextHeadsSuggestion = new ArrayList<>(2); nextHeadsSuggestion.add(head); } } @@ -236,7 +236,7 @@ private static List<AbstractHead> parseHeads(final String pattern, throws InvalidPatternException { int currentIndex = 0; - List<AbstractHead> heads = new ArrayList<AbstractHead>(); + List<AbstractHead> heads = new ArrayList<>(); while (currentIndex < pattern.length()) { final int groupStart = indexOfUnescaped(pattern, '[', currentIndex); if (groupStart == -1) { @@ -262,7 +262,7 @@ private static List<AbstractHead> parseHeads(final String pattern, private static List<AbstractHead> createSimpleHeads( final String patternPart, final Character invalidWildgetCharacter) { - final List<AbstractHead> heads = new ArrayList<AbstractHead>( + final List<AbstractHead> heads = new ArrayList<>( patternPart.length()); boolean escaped = false; @@ -375,7 +375,7 @@ public void reset() { * reset and start point. */ public FileNameMatcher createMatcherForSuffix() { - final List<Head> copyOfHeads = new ArrayList<Head>(heads.size()); + final List<Head> copyOfHeads = new ArrayList<>(heads.size()); copyOfHeads.addAll(heads); return new FileNameMatcher(copyOfHeads); }
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/fnmatch/GroupHead.java b/org.eclipse.jgit/src/org/eclipse/jgit/fnmatch/GroupHead.java index 8af5228..5c18756 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/fnmatch/GroupHead.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/fnmatch/GroupHead.java
@@ -64,7 +64,7 @@ final class GroupHead extends AbstractHead { GroupHead(String pattern, final String wholePattern) throws InvalidPatternException { super(false); - this.characterClasses = new ArrayList<CharacterPattern>(); + this.characterClasses = new ArrayList<>(); this.inverse = pattern.startsWith("!"); //$NON-NLS-1$ if (inverse) { pattern = pattern.substring(1); @@ -159,6 +159,7 @@ private static final class CharacterRange implements CharacterPattern { this.end = end; } + @Override public final boolean matches(char c) { return start <= c && c <= end; } @@ -167,6 +168,7 @@ public final boolean matches(char c) { private static final class DigitPattern implements CharacterPattern { static final GroupHead.DigitPattern INSTANCE = new DigitPattern(); + @Override public final boolean matches(char c) { return Character.isDigit(c); } @@ -175,6 +177,7 @@ public final boolean matches(char c) { private static final class LetterPattern implements CharacterPattern { static final GroupHead.LetterPattern INSTANCE = new LetterPattern(); + @Override public final boolean matches(char c) { return Character.isLetter(c); } @@ -183,6 +186,7 @@ public final boolean matches(char c) { private static final class LowerPattern implements CharacterPattern { static final GroupHead.LowerPattern INSTANCE = new LowerPattern(); + @Override public final boolean matches(char c) { return Character.isLowerCase(c); } @@ -191,6 +195,7 @@ public final boolean matches(char c) { private static final class UpperPattern implements CharacterPattern { static final GroupHead.UpperPattern INSTANCE = new UpperPattern(); + @Override public final boolean matches(char c) { return Character.isUpperCase(c); } @@ -199,6 +204,7 @@ public final boolean matches(char c) { private static final class WhitespacePattern implements CharacterPattern { static final GroupHead.WhitespacePattern INSTANCE = new WhitespacePattern(); + @Override public final boolean matches(char c) { return Character.isWhitespace(c); } @@ -211,6 +217,7 @@ private static final class OneCharacterPattern implements CharacterPattern { this.expectedCharacter = c; } + @Override public final boolean matches(char c) { return this.expectedCharacter == c; } @@ -221,6 +228,7 @@ private static final class PunctPattern implements CharacterPattern { private static String punctCharacters = "-!\"#$%&'()*+,./:;<=>?@[\\]_`{|}~"; //$NON-NLS-1$ + @Override public boolean matches(char c) { return punctCharacters.indexOf(c) != -1; }
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/fnmatch/LastHead.java b/org.eclipse.jgit/src/org/eclipse/jgit/fnmatch/LastHead.java index 78a61b9..f9ddd9e 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/fnmatch/LastHead.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/fnmatch/LastHead.java
@@ -56,6 +56,7 @@ private LastHead() { // defined because of javadoc and visibility modifier. } + @Override public List<Head> getNextHeads(char c) { return FileNameMatcher.EMPTY_HEAD_LIST; }
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 8a35d35..94c8e43 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/gitrepo/ManifestParser.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/gitrepo/ManifestParser.java
@@ -57,6 +57,7 @@ import java.util.Map; import java.util.Set; +import org.eclipse.jgit.annotations.NonNull; import org.eclipse.jgit.api.errors.GitAPIException; import org.eclipse.jgit.gitrepo.RepoProject.CopyFile; import org.eclipse.jgit.gitrepo.internal.RepoText; @@ -77,7 +78,7 @@ */ public class ManifestParser extends DefaultHandler { private final String filename; - private final String baseUrl; + private final URI baseUrl; private final String defaultBranch; private final Repository rootRepo; private final Map<String, Remote> remotes; @@ -124,15 +125,10 @@ public ManifestParser(IncludedFileReader includedReader, String filename, this.filename = filename; this.defaultBranch = defaultBranch; this.rootRepo = rootRepo; + this.baseUrl = normalizeEmptyPath(URI.create(baseUrl)); - // Strip trailing /s to match repo behavior. - int lastIndex = baseUrl.length() - 1; - while (lastIndex >= 0 && baseUrl.charAt(lastIndex) == '/') - lastIndex--; - this.baseUrl = baseUrl.substring(0, lastIndex + 1); - - plusGroups = new HashSet<String>(); - minusGroups = new HashSet<String>(); + plusGroups = new HashSet<>(); + minusGroups = new HashSet<>(); if (groups == null || groups.length() == 0 || groups.equals("default")) { //$NON-NLS-1$ // default means "all,-notdefault" @@ -146,9 +142,9 @@ public ManifestParser(IncludedFileReader includedReader, String filename, } } - remotes = new HashMap<String, Remote>(); - projects = new ArrayList<RepoProject>(); - filteredProjects = new ArrayList<RepoProject>(); + remotes = new HashMap<>(); + projects = new ArrayList<>(); + filteredProjects = new ArrayList<>(); } /** @@ -257,13 +253,7 @@ public void endDocument() throws SAXException { return; // Only do the following after we finished reading everything. - Map<String, String> remoteUrls = new HashMap<String, String>(); - URI baseUri; - try { - baseUri = new URI(baseUrl); - } catch (URISyntaxException e) { - throw new SAXException(e); - } + Map<String, URI> remoteUrls = new HashMap<>(); if (defaultRevision == null && defaultRemote != null) { Remote remote = remotes.get(defaultRemote); if (remote != null) { @@ -293,16 +283,18 @@ public void endDocument() throws SAXException { revision = r.revision; } } - String remoteUrl = remoteUrls.get(remote); + URI remoteUrl = remoteUrls.get(remote); if (remoteUrl == null) { - remoteUrl = - baseUri.resolve(remotes.get(remote).fetch).toString(); - if (!remoteUrl.endsWith("/")) //$NON-NLS-1$ - remoteUrl = remoteUrl + "/"; //$NON-NLS-1$ + String fetch = remotes.get(remote).fetch; + if (fetch == null) { + throw new SAXException(MessageFormat + .format(RepoText.get().errorNoFetch, remote)); + } + remoteUrl = normalizeEmptyPath(baseUrl.resolve(fetch)); remoteUrls.put(remote, remoteUrl); } - proj.setUrl(remoteUrl + proj.getName()) - .setDefaultRevision(revision); + proj.setUrl(remoteUrl.resolve(proj.getName()).toString()) + .setDefaultRevision(revision); } filteredProjects.addAll(projects); @@ -310,6 +302,23 @@ public void endDocument() throws SAXException { removeOverlaps(); } + static URI normalizeEmptyPath(URI u) { + // URI.create("scheme://host").resolve("a/b") => "scheme://hosta/b" + // That seems like bug https://bugs.openjdk.java.net/browse/JDK-4666701. + // We workaround this by special casing the empty path case. + if (u.getHost() != null && !u.getHost().isEmpty() && + (u.getPath() == null || u.getPath().isEmpty())) { + try { + return new URI(u.getScheme(), + u.getUserInfo(), u.getHost(), u.getPort(), + "/", u.getQuery(), u.getFragment()); //$NON-NLS-1$ + } catch (URISyntaxException x) { + throw new IllegalArgumentException(x.getMessage(), x); + } + } + return u; + } + /** * Getter for projects. * @@ -324,7 +333,7 @@ public List<RepoProject> getProjects() { * * @return filtered projects list reference, never null */ - public List<RepoProject> getFilteredProjects() { + public @NonNull List<RepoProject> getFilteredProjects() { return filteredProjects; }
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 86dbabc..e105dc0 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/gitrepo/RepoCommand.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/gitrepo/RepoCommand.java
@@ -96,8 +96,8 @@ * If called against a bare repository, it will replace all the existing content * of the repository with the contents populated from the manifest. * - * repo manifest allows projects overlapping, e.g. one project's path is - * "foo" and another project's path is "foo/bar". This won't + * repo manifest allows projects overlapping, e.g. one project's manifestPath is + * "foo" and another project's manifestPath is "foo/bar". This won't * work in git submodule, so we'll skip all the sub projects * ("foo/bar" in the example) while converting. * @@ -105,7 +105,7 @@ * @since 3.4 */ public class RepoCommand extends GitCommand<RevCommit> { - private String path; + private String manifestPath; private String uri; private String groupsParam; private String branch; @@ -168,6 +168,7 @@ public interface RemoteReader { /** A default implementation of {@link RemoteReader} callback. */ public static class DefaultRemoteReader implements RemoteReader { + @Override public ObjectId sha1(String uri, String ref) throws GitAPIException { Map<String, Ref> map = Git .lsRemoteRepository() @@ -177,13 +178,13 @@ public ObjectId sha1(String uri, String ref) throws GitAPIException { return r != null ? r.getObjectId() : null; } + @Override public byte[] readFile(String uri, String ref, String path) throws GitAPIException, IOException { File dir = FileUtils.createTempDir("jgit_", ".git", null); //$NON-NLS-1$ //$NON-NLS-2$ try (Git git = Git.cloneRepository().setBare(true).setDirectory(dir) - .setURI(uri).call(); - Repository repo = git.getRepository()) { - return readFileFromRepo(repo, ref, path); + .setURI(uri).call()) { + return readFileFromRepo(git.getRepository(), ref, path); } finally { FileUtils.delete(dir, FileUtils.RECURSIVE); } @@ -243,7 +244,7 @@ public RepoCommand(Repository repo) { * @return this command */ public RepoCommand setPath(String path) { - this.path = path; + this.manifestPath = path; return this; } @@ -263,7 +264,11 @@ public RepoCommand setInputStream(InputStream inputStream) { } /** - * Set base URI of the pathes inside the XML + * Set base URI of the paths inside the XML. This is typically the name of + * the directory holding the manifest repository, eg. for + * https://android.googlesource.com/platform/manifest, this should be + * /platform (if you would run this on android.googlesource.com) + * or https://android.googlesource.com/platform elsewhere. * * @param uri * @return this command @@ -447,15 +452,16 @@ public RepoCommand setIncludedFileReader(IncludedFileReader reader) { public RevCommit call() throws GitAPIException { try { checkCallable(); - if (uri == null || uri.length() == 0) + if (uri == null || uri.length() == 0) { throw new IllegalArgumentException( - JGitText.get().uriNotConfigured); + JGitText.get().uriNotConfigured); + } if (inputStream == null) { - if (path == null || path.length() == 0) + if (manifestPath == null || manifestPath.length() == 0) throw new IllegalArgumentException( JGitText.get().pathNotConfigured); try { - inputStream = new FileInputStream(path); + inputStream = new FileInputStream(manifestPath); } catch (IOException e) { throw new IllegalArgumentException( JGitText.get().pathNotConfigured); @@ -463,7 +469,7 @@ public RevCommit call() throws GitAPIException { } if (repo.isBare()) { - bareProjects = new ArrayList<RepoProject>(); + bareProjects = new ArrayList<>(); if (author == null) author = new PersonIdent(repo); if (callback == null) @@ -472,7 +478,7 @@ public RevCommit call() throws GitAPIException { git = new Git(repo); ManifestParser parser = new ManifestParser( - includedReader, path, branch, uri, groupsParam, repo); + includedReader, manifestPath, branch, uri, groupsParam, repo); try { parser.read(inputStream); for (RepoProject proj : parser.getFilteredProjects()) { @@ -503,7 +509,7 @@ public RevCommit call() throws GitAPIException { Config cfg = new Config(); StringBuilder attributes = new StringBuilder(); for (RepoProject proj : bareProjects) { - String name = proj.getPath(); + String path = proj.getPath(); String nameUri = proj.getName(); ObjectId objectId; if (ObjectId.isId(proj.getRevision()) @@ -519,7 +525,7 @@ public RevCommit call() throws GitAPIException { } if (recordRemoteBranch) { // can be branch or tag - cfg.setString("submodule", name, "branch", //$NON-NLS-1$ //$NON-NLS-2$ + cfg.setString("submodule", path, "branch", //$NON-NLS-1$ //$NON-NLS-2$ proj.getRevision()); } @@ -529,14 +535,14 @@ public RevCommit call() throws GitAPIException { // depth in the 'clone-depth' field, while // git core only uses a binary 'shallow = true/false' // hint, we'll map any depth to 'shallow = true' - cfg.setBoolean("submodule", name, "shallow", //$NON-NLS-1$ //$NON-NLS-2$ + cfg.setBoolean("submodule", path, "shallow", //$NON-NLS-1$ //$NON-NLS-2$ true); } } if (recordSubmoduleLabels) { StringBuilder rec = new StringBuilder(); rec.append("/"); //$NON-NLS-1$ - rec.append(name); + rec.append(path); for (String group : proj.getGroups()) { rec.append(" "); //$NON-NLS-1$ rec.append(group); @@ -544,11 +550,11 @@ public RevCommit call() throws GitAPIException { rec.append("\n"); //$NON-NLS-1$ attributes.append(rec.toString()); } - cfg.setString("submodule", name, "path", name); //$NON-NLS-1$ //$NON-NLS-2$ - cfg.setString("submodule", name, "url", nameUri); //$NON-NLS-1$ //$NON-NLS-2$ + cfg.setString("submodule", path, "path", path); //$NON-NLS-1$ //$NON-NLS-2$ + cfg.setString("submodule", path, "url", nameUri); //$NON-NLS-1$ //$NON-NLS-2$ // create gitlink - DirCacheEntry dcEntry = new DirCacheEntry(name); + DirCacheEntry dcEntry = new DirCacheEntry(path); dcEntry.setObjectId(objectId); dcEntry.setFileMode(FileMode.GITLINK); builder.add(dcEntry); @@ -635,17 +641,17 @@ public RevCommit call() throws GitAPIException { } } - private void addSubmodule(String url, String name, String revision, + private void addSubmodule(String url, String path, String revision, List<CopyFile> copyfiles, Set<String> groups, String recommendShallow) throws GitAPIException, IOException { if (repo.isBare()) { - RepoProject proj = new RepoProject(url, name, revision, null, groups, recommendShallow); + RepoProject proj = new RepoProject(url, path, revision, null, groups, recommendShallow); proj.addCopyFiles(copyfiles); bareProjects.add(proj); } else { SubmoduleAddCommand add = git .submoduleAdd() - .setPath(name) + .setPath(path) .setURI(url); if (monitor != null) add.setProgressMonitor(monitor); @@ -657,7 +663,7 @@ private void addSubmodule(String url, String name, String revision, .call(); } subRepo.close(); - git.add().addFilepattern(name).call(); + git.add().addFilepattern(path).call(); } for (CopyFile copyfile : copyfiles) { copyfile.copy();
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 ff4a3ed..700cf11 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/gitrepo/RepoProject.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/gitrepo/RepoProject.java
@@ -155,7 +155,7 @@ public RepoProject(String name, String path, String revision, this.remote = remote; this.groups = groups; this.recommendShallow = recommendShallow; - copyfiles = new ArrayList<CopyFile>(); + copyfiles = new ArrayList<>(); } /**
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/gitrepo/internal/RepoText.java b/org.eclipse.jgit/src/org/eclipse/jgit/gitrepo/internal/RepoText.java index 36b6e3a..02a2565 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/gitrepo/internal/RepoText.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/gitrepo/internal/RepoText.java
@@ -64,6 +64,7 @@ public static RepoText get() { /***/ public String errorIncludeNotImplemented; /***/ public String errorNoDefault; /***/ public String errorNoDefaultFilename; + /***/ public String errorNoFetch; /***/ public String errorParsingManifestFile; /***/ public String errorRemoteUnavailable; /***/ public String invalidManifest;
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 ad2eeb0..c1aca6a 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/hooks/GitHook.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/hooks/GitHook.java
@@ -95,6 +95,7 @@ protected GitHook(Repository repo, PrintStream outputStream) { * If the hook has been run and a returned an exit code * different from zero. */ + @Override public abstract T call() throws IOException, AbortedByHookException; /**
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 8b1244e..6314c63 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/ignore/IgnoreNode.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/ignore/IgnoreNode.java
@@ -83,7 +83,7 @@ public static enum MatchResult { /** Create an empty ignore node with no rules. */ public IgnoreNode() { - rules = new ArrayList<FastIgnoreRule>(); + rules = new ArrayList<>(); } /**
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/ignore/internal/AbstractMatcher.java b/org.eclipse.jgit/src/org/eclipse/jgit/ignore/internal/AbstractMatcher.java index 4e90d8c..64c2a74 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/ignore/internal/AbstractMatcher.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/ignore/internal/AbstractMatcher.java
@@ -46,8 +46,6 @@ * Base class for default methods as {@link #toString()} and such. * <p> * This class is immutable and thread safe. - * - * @since 3.6 */ public abstract class AbstractMatcher implements IMatcher {
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/ignore/internal/IMatcher.java b/org.eclipse.jgit/src/org/eclipse/jgit/ignore/internal/IMatcher.java index 8bb4dfb..61f7b83 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/ignore/internal/IMatcher.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/ignore/internal/IMatcher.java
@@ -44,8 +44,6 @@ /** * Generic string matcher - * - * @since 3.6 */ public interface IMatcher { @@ -53,10 +51,12 @@ public interface IMatcher { * Matcher that does not match any pattern. */ public static final IMatcher NO_MATCH = new IMatcher() { + @Override public boolean matches(String path, boolean assumeDirectory) { return false; } + @Override public boolean matches(String segment, int startIncl, int endExcl, boolean assumeDirectory) { return false;
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/ignore/internal/LeadingAsteriskMatcher.java b/org.eclipse.jgit/src/org/eclipse/jgit/ignore/internal/LeadingAsteriskMatcher.java index 3d0ad09..cc0fe93 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/ignore/internal/LeadingAsteriskMatcher.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/ignore/internal/LeadingAsteriskMatcher.java
@@ -44,8 +44,6 @@ /** * Matcher for simple regex patterns starting with an asterisk, e.g. "*.tmp" - * - * @since 3.6 */ public class LeadingAsteriskMatcher extends NameMatcher { @@ -57,6 +55,7 @@ public class LeadingAsteriskMatcher extends NameMatcher { "Pattern must have leading asterisk: " + pattern); //$NON-NLS-1$ } + @Override public boolean matches(String segment, int startIncl, int endExcl, boolean assumeDirectory) { // faster local access, same as in string.indexOf()
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/ignore/internal/NameMatcher.java b/org.eclipse.jgit/src/org/eclipse/jgit/ignore/internal/NameMatcher.java index 8beae83..0065123 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/ignore/internal/NameMatcher.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/ignore/internal/NameMatcher.java
@@ -47,8 +47,6 @@ /** * Matcher built from patterns for file names (single path segments). This class * is immutable and thread safe. - * - * @since 3.6 */ public class NameMatcher extends AbstractMatcher { @@ -72,6 +70,7 @@ public class NameMatcher extends AbstractMatcher { this.subPattern = pattern.substring(1); } + @Override public boolean matches(String path, boolean assumeDirectory) { int end = 0; int firstChar = 0; @@ -88,6 +87,7 @@ public boolean matches(String path, boolean assumeDirectory) { return false; } + @Override public boolean matches(String segment, int startIncl, int endExcl, boolean assumeDirectory) { // faster local access, same as in string.indexOf()
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 c3f6694..65224ea 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
@@ -59,8 +59,6 @@ * Matcher built by patterns consists of multiple path segments. * <p> * This class is immutable and thread safe. - * - * @since 3.6 */ public class PathMatcher extends AbstractMatcher { @@ -92,7 +90,7 @@ private boolean isSimplePathWithSegments(String path) { static private List<IMatcher> createMatchers(List<String> segments, Character pathSeparator, boolean dirOnly) throws InvalidPatternException { - List<IMatcher> matchers = new ArrayList<IMatcher>(segments.size()); + List<IMatcher> matchers = new ArrayList<>(segments.size()); for (int i = 0; i < segments.size(); i++) { String segment = segments.get(i); IMatcher matcher = createNameMatcher0(segment, pathSeparator, @@ -172,6 +170,7 @@ private static IMatcher createNameMatcher0(String segment, } } + @Override public boolean matches(String path, boolean assumeDirectory) { if (matchers == null) return simpleMatch(path, assumeDirectory); @@ -211,6 +210,7 @@ private boolean simpleMatch(String path, boolean assumeDirectory) { return false; } + @Override public boolean matches(String segment, int startIncl, int endExcl, boolean assumeDirectory) { throw new UnsupportedOperationException(
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 70c5199..da482fa 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
@@ -58,8 +58,6 @@ /** * Various {@link String} related utility methods, written mostly to avoid * generation of new String objects (e.g. via splitting Strings etc). - * - * @since 3.6 */ public class Strings { @@ -150,7 +148,7 @@ public static List<String> split(String pattern, char slash) { if (count < 1) throw new IllegalStateException( "Pattern must have at least two segments: " + pattern); //$NON-NLS-1$ - List<String> segments = new ArrayList<String>(count); + List<String> segments = new ArrayList<>(count); int right = 0; while (true) { int left = right;
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/ignore/internal/TrailingAsteriskMatcher.java b/org.eclipse.jgit/src/org/eclipse/jgit/ignore/internal/TrailingAsteriskMatcher.java index b927d27..2e148f4 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/ignore/internal/TrailingAsteriskMatcher.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/ignore/internal/TrailingAsteriskMatcher.java
@@ -44,8 +44,6 @@ /** * Matcher for simple patterns ending with an asterisk, e.g. "Makefile.*" - * - * @since 3.6 */ public class TrailingAsteriskMatcher extends NameMatcher { @@ -57,6 +55,7 @@ public class TrailingAsteriskMatcher extends NameMatcher { "Pattern must have trailing asterisk: " + pattern); //$NON-NLS-1$ } + @Override public boolean matches(String segment, int startIncl, int endExcl, boolean assumeDirectory) { // faster local access, same as in string.indexOf()
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/ignore/internal/WildCardMatcher.java b/org.eclipse.jgit/src/org/eclipse/jgit/ignore/internal/WildCardMatcher.java index 8f98152..f64050f 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/ignore/internal/WildCardMatcher.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/ignore/internal/WildCardMatcher.java
@@ -53,8 +53,6 @@ * glob wildcards to Java {@link Pattern}'s. * <p> * This class is immutable and thread safe. - * - * @since 3.6 */ public class WildCardMatcher extends NameMatcher {
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/ignore/internal/WildMatcher.java b/org.eclipse.jgit/src/org/eclipse/jgit/ignore/internal/WildMatcher.java index d578654..93ea13c 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/ignore/internal/WildMatcher.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/ignore/internal/WildMatcher.java
@@ -47,8 +47,6 @@ * matcher matches any path. * <p> * This class is immutable and thread safe. - * - * @since 3.6 */ public final class WildMatcher extends AbstractMatcher { @@ -63,10 +61,12 @@ private WildMatcher() { super(WILDMATCH, false); } + @Override public final boolean matches(String path, boolean assumeDirectory) { return true; } + @Override public final boolean matches(String segment, int startIncl, int endExcl, boolean assumeDirectory) { return true;
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/internal/JGitText.java b/org.eclipse.jgit/src/org/eclipse/jgit/internal/JGitText.java index df2cc50..1bf55e3 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/internal/JGitText.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/internal/JGitText.java
@@ -90,6 +90,7 @@ public static JGitText get() { /***/ public String badObjectType; /***/ public String badRef; /***/ public String badSectionEntry; + /***/ public String badShallowLine; /***/ public String bareRepositoryNoWorkdirAndIndex; /***/ public String base64InputNotProperlyPadded; /***/ public String baseLengthIncorrect; @@ -103,6 +104,7 @@ public static JGitText get() { /***/ public String buildingBitmaps; /***/ public String cachedPacksPreventsIndexCreation; /***/ public String cachedPacksPreventsListingObjects; + /***/ public String cannotAccessLastModifiedForSafeDeletion; /***/ public String cannotBeCombined; /***/ public String cannotBeRecursiveWhenTreesAreIncluded; /***/ public String cannotChangeActionOnComment; @@ -175,6 +177,7 @@ public static JGitText get() { /***/ public String checkoutUnexpectedResult; /***/ public String classCastNotA; /***/ public String cloneNonEmptyDirectory; + /***/ public String closeLockTokenFailed; /***/ public String closed; /***/ public String collisionOn; /***/ public String commandRejectedByHook; @@ -341,6 +344,7 @@ public static JGitText get() { /***/ public String expectedPktLineWithService; /***/ public String expectedReceivedContentType; /***/ public String expectedReportForRefNotReceived; + /***/ public String failedAtomicFileCreation; /***/ public String failedToDetermineFilterDefinition; /***/ public String failedUpdatingRefs; /***/ public String failureDueToOneOfTheFollowing; @@ -358,6 +362,8 @@ public static JGitText get() { /***/ public String flagsAlreadyCreated; /***/ public String funnyRefname; /***/ public String gcFailed; + /***/ public String gcLogExists; + /***/ public String gcTooManyUnpruned; /***/ public String gitmodulesNotFound; /***/ public String headRequiredToStash; /***/ public String hoursAgo; @@ -400,6 +406,7 @@ public static JGitText get() { /***/ public String invalidEncryption; /***/ public String invalidExpandWildcard; /***/ public String invalidGitdirRef; + /***/ public String invalidGitModules; /***/ public String invalidGitType; /***/ public String invalidId; /***/ public String invalidId0; @@ -411,6 +418,7 @@ public static JGitText get() { /***/ public String invalidLineInConfigFile; /***/ public String invalidModeFor; /***/ public String invalidModeForPath; + /***/ public String invalidNameContainsDotDot; /***/ public String invalidObject; /***/ public String invalidOldIdSent; /***/ public String invalidPacketLineHeader; @@ -623,6 +631,7 @@ public static JGitText get() { /***/ public String sequenceTooLargeForDiffAlgorithm; /***/ public String serviceNotEnabledNoName; /***/ public String serviceNotPermitted; + /***/ public String sha1CollisionDetected1; /***/ public String shallowCommitsAlreadyInitialized; /***/ public String shallowPacksRequireDepthWalk; /***/ public String shortCompressedStreamAt; @@ -657,8 +666,11 @@ public static JGitText get() { /***/ public String storePushCertOneRef; /***/ public String storePushCertReflog; /***/ public String submoduleExists; - /***/ public String submodulesNotSupported; + /***/ public String submoduleNameInvalid; /***/ public String submoduleParentRemoteUrlInvalid; + /***/ public String submodulePathInvalid; + /***/ public String submodulesNotSupported; + /***/ public String submoduleUrlInvalid; /***/ public String supportOnlyPackIndexVersion2; /***/ public String symlinkCannotBeWrittenAsTheLinkTarget; /***/ public String systemConfigFileInvalid; @@ -669,6 +681,7 @@ public static JGitText get() { /***/ public String theFactoryMustNotBeNull; /***/ public String timeIsUncertain; /***/ public String timerAlreadyTerminated; + /***/ public String tooManyCommands; /***/ public String tooManyIncludeRecursions; /***/ public String topologicalSortRequired; /***/ public String transportExceptionBadRef; @@ -698,6 +711,7 @@ public static JGitText get() { /***/ public String tSizeMustBeGreaterOrEqual1; /***/ public String unableToCheckConnectivity; /***/ public String unableToCreateNewObject; + /***/ public String unableToRemovePath; /***/ public String unableToStore; /***/ public String unableToWrite; /***/ public String unauthorized; @@ -720,6 +734,7 @@ public static JGitText get() { /***/ public String unknownRepositoryFormat; /***/ public String unknownRepositoryFormat2; /***/ public String unknownZlibError; + /***/ public String unlockLockFileFailed; /***/ public String unmergedPath; /***/ public String unmergedPaths; /***/ public String unpackException;
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 35327ea..757c19a 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
@@ -86,6 +86,7 @@ private void initRevWalk() { rw.setRetainBody(false); } + @Override public void close() { if (rw != null) { rw.close();
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/internal/ketch/ProposalRound.java b/org.eclipse.jgit/src/org/eclipse/jgit/internal/ketch/ProposalRound.java index ddd7059..1eaa33d 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/internal/ketch/ProposalRound.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/internal/ketch/ProposalRound.java
@@ -122,6 +122,7 @@ private static boolean canCombine(@Nullable PersonIdent a, return a == null && b == null; } + @Override void start() throws IOException { for (Proposal p : todo) { p.notifyState(RUNNING); @@ -268,6 +269,7 @@ void abort() { } } + @Override void success() { for (Proposal p : todo) { p.success();
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/internal/ketch/RemoteGitReplica.java b/org.eclipse.jgit/src/org/eclipse/jgit/internal/ketch/RemoteGitReplica.java index 396fbdd..a0ac608 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/internal/ketch/RemoteGitReplica.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/internal/ketch/RemoteGitReplica.java
@@ -240,6 +240,7 @@ private static void abort(List<RemoteCommand> cmds) { ReceiveCommand.abort(tmp); } + @Override protected void blockingFetch(Repository repo, ReplicaFetchRequest req) throws NotSupportedException, TransportException { try (Transport transport = Transport.open(repo, uri)) {
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/dfs/BeforeDfsPackIndexLoadedListener.java b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/dfs/BeforeDfsPackIndexLoadedListener.java index 047c86f..9f7f350 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/dfs/BeforeDfsPackIndexLoadedListener.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/dfs/BeforeDfsPackIndexLoadedListener.java
@@ -47,8 +47,6 @@ /** * Receives {@link BeforeDfsPackIndexLoadedEvent}s. - * - * @since 2.2 */ public interface BeforeDfsPackIndexLoadedListener extends RepositoryListener { /**
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 f7decf1..ef0b80c 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
@@ -183,7 +183,7 @@ private DfsBlockCache(final DfsBlockCacheConfig cfg) { if (tableSize < 1) throw new IllegalArgumentException(JGitText.get().tSizeMustBeGreaterOrEqual1); - table = new AtomicReferenceArray<HashEntry>(tableSize); + table = new AtomicReferenceArray<>(tableSize); loadLocks = new ReentrantLock[cfg.getConcurrencyLevel()]; for (int i = 0; i < loadLocks.length; i++) loadLocks[i] = new ReentrantLock(true /* fair */); @@ -194,10 +194,10 @@ private DfsBlockCache(final DfsBlockCacheConfig cfg) { blockSizeShift = Integer.numberOfTrailingZeros(blockSize); clockLock = new ReentrantLock(true /* fair */); - clockHand = new Ref<Object>(new DfsPackKey(), -1, 0, null); + clockHand = new Ref<>(new DfsPackKey(), -1, 0, null); clockHand.next = clockHand; - packCache = new ConcurrentHashMap<DfsPackDescription, DfsPackFile>( + packCache = new ConcurrentHashMap<>( 16, 0.75f, 1); packFiles = Collections.unmodifiableCollection(packCache.values()); @@ -357,7 +357,7 @@ DfsBlock getOrLoad(DfsPackFile pack, long position, DfsReader ctx) } key.cachedSize.addAndGet(v.size()); - Ref<DfsBlock> ref = new Ref<DfsBlock>(key, position, v.size(), v); + Ref<DfsBlock> ref = new Ref<>(key, position, v.size(), v); ref.hot = true; for (;;) { HashEntry n = new HashEntry(clean(e2), ref); @@ -461,7 +461,7 @@ <T> Ref<T> put(DfsPackKey key, long pos, int size, T v) { } key.cachedSize.addAndGet(size); - ref = new Ref<T>(key, pos, size, v); + ref = new Ref<>(key, pos, size, v); ref.hot = true; for (;;) { HashEntry n = new HashEntry(clean(e2), ref);
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/dfs/DfsBlockCacheConfig.java b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/dfs/DfsBlockCacheConfig.java index 089bfa4..feadedb 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/dfs/DfsBlockCacheConfig.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/dfs/DfsBlockCacheConfig.java
@@ -122,7 +122,6 @@ public DfsBlockCacheConfig setBlockSize(final int newSize) { /** * @return the estimated number of threads concurrently accessing the cache. * <b>Default is 32.</b> - * @since 4.6 */ public int getConcurrencyLevel() { return concurrencyLevel; @@ -133,7 +132,6 @@ public int getConcurrencyLevel() { * the estimated number of threads concurrently accessing the * cache. * @return {@code this} - * @since 4.6 */ public DfsBlockCacheConfig setConcurrencyLevel( final int newConcurrencyLevel) { @@ -145,7 +143,6 @@ public DfsBlockCacheConfig setConcurrencyLevel( * @return highest percentage of {@link #getBlockLimit()} a single pack can * occupy while being copied by the pack reuse strategy. <b>Default * is 0.30, or 30%</b>. - * @since 4.0 */ public double getStreamRatio() { return streamRatio; @@ -155,7 +152,6 @@ public double getStreamRatio() { * @param ratio * percentage of cache to occupy with a copied pack. * @return {@code this} - * @since 4.0 */ public DfsBlockCacheConfig setStreamRatio(double ratio) { streamRatio = Math.max(0, Math.min(ratio, 1.0));
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 6f760ca..d380302 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
@@ -43,9 +43,12 @@ package org.eclipse.jgit.internal.storage.dfs; +import static org.eclipse.jgit.internal.storage.dfs.DfsObjDatabase.PackSource.COMPACT; import static org.eclipse.jgit.internal.storage.dfs.DfsObjDatabase.PackSource.GC; import static org.eclipse.jgit.internal.storage.dfs.DfsObjDatabase.PackSource.GC_REST; import static org.eclipse.jgit.internal.storage.dfs.DfsObjDatabase.PackSource.GC_TXN; +import static org.eclipse.jgit.internal.storage.dfs.DfsObjDatabase.PackSource.INSERT; +import static org.eclipse.jgit.internal.storage.dfs.DfsObjDatabase.PackSource.RECEIVE; import static org.eclipse.jgit.internal.storage.dfs.DfsObjDatabase.PackSource.UNREACHABLE_GARBAGE; import static org.eclipse.jgit.internal.storage.pack.PackExt.BITMAP_INDEX; import static org.eclipse.jgit.internal.storage.pack.PackExt.INDEX; @@ -53,8 +56,11 @@ import java.io.IOException; import java.util.ArrayList; +import java.util.Calendar; import java.util.Collection; import java.util.Collections; +import java.util.EnumSet; +import java.util.GregorianCalendar; import java.util.HashSet; import java.util.List; import java.util.Set; @@ -63,6 +69,7 @@ import org.eclipse.jgit.internal.JGitText; import org.eclipse.jgit.internal.storage.dfs.DfsObjDatabase.PackSource; import org.eclipse.jgit.internal.storage.file.PackIndex; +import org.eclipse.jgit.internal.storage.file.PackReverseIndex; import org.eclipse.jgit.internal.storage.pack.PackExt; import org.eclipse.jgit.internal.storage.pack.PackWriter; import org.eclipse.jgit.internal.storage.reftree.RefTreeNames; @@ -77,6 +84,7 @@ import org.eclipse.jgit.revwalk.RevWalk; import org.eclipse.jgit.storage.pack.PackConfig; import org.eclipse.jgit.storage.pack.PackStatistics; +import org.eclipse.jgit.util.SystemReader; import org.eclipse.jgit.util.io.CountingOutputStream; /** Repack and garbage collect a repository. */ @@ -95,7 +103,8 @@ public class DfsGarbageCollector { private PackConfig packConfig; - // See pack(), below, for how these two variables interact. + // See packIsCoalesceableGarbage(), below, for how these two variables + // interact. private long coalesceGarbageLimit = 50 << 20; private long garbageTtlMillis = TimeUnit.DAYS.toMillis(1); @@ -118,9 +127,9 @@ public DfsGarbageCollector(DfsRepository repository) { repo = repository; refdb = repo.getRefDatabase(); objdb = repo.getObjectDatabase(); - newPackDesc = new ArrayList<DfsPackDescription>(4); - newPackStats = new ArrayList<PackStatistics>(4); - newPackObj = new ArrayList<ObjectIdSet>(4); + newPackDesc = new ArrayList<>(4); + newPackStats = new ArrayList<>(4); + newPackObj = new ArrayList<>(4); packConfig = new PackConfig(repo); packConfig.setIndexVersion(2); @@ -223,14 +232,8 @@ public boolean pack(ProgressMonitor pm) throws IOException { if (packConfig.getIndexVersion() != 2) throw new IllegalStateException( JGitText.get().supportOnlyPackIndexVersion2); - if (garbageTtlMillis > 0) { - // We disable coalescing because the coalescing step will keep - // refreshing the UNREACHABLE_GARBAGE pack and we wouldn't - // actually prune anything. - coalesceGarbageLimit = 0; - } - startTimeMillis = System.currentTimeMillis(); + startTimeMillis = SystemReader.getInstance().getCurrentTime(); ctx = (DfsReader) objdb.newReader(); try { refdb.refresh(); @@ -246,14 +249,14 @@ public boolean pack(ProgressMonitor pm) throws IOException { return true; } - allHeads = new HashSet<ObjectId>(); - nonHeads = new HashSet<ObjectId>(); - txnHeads = new HashSet<ObjectId>(); - tagTargets = new HashSet<ObjectId>(); + allHeads = new HashSet<>(); + nonHeads = new HashSet<>(); + txnHeads = new HashSet<>(); + tagTargets = new HashSet<>(); for (Ref ref : refsBefore) { if (ref.isSymbolic() || ref.getObjectId() == null) continue; - if (isHead(ref)) + if (isHead(ref) || isTag(ref)) allHeads.add(ref.getObjectId()); else if (RefTreeNames.isRefTree(refdb, ref.getName())) txnHeads.add(ref.getObjectId()); @@ -301,18 +304,18 @@ private Collection<Ref> getAllRefs() throws IOException { private void readPacksBefore() throws IOException { DfsPackFile[] packs = objdb.getPacks(); - packsBefore = new ArrayList<DfsPackFile>(packs.length); - expiredGarbagePacks = new ArrayList<DfsPackFile>(packs.length); + packsBefore = new ArrayList<>(packs.length); + expiredGarbagePacks = new ArrayList<>(packs.length); long mostRecentGC = mostRecentGC(packs); - long now = System.currentTimeMillis(); + long now = SystemReader.getInstance().getCurrentTime(); for (DfsPackFile p : packs) { DfsPackDescription d = p.getPackDescription(); if (d.getPackSource() != UNREACHABLE_GARBAGE) { packsBefore.add(p); } else if (packIsExpiredGarbage(d, mostRecentGC, now)) { expiredGarbagePacks.add(p); - } else if (d.getFileSize(PackExt.PACK) < coalesceGarbageLimit) { + } else if (packIsCoalesceableGarbage(d, now)) { packsBefore.add(p); } } @@ -355,6 +358,68 @@ private boolean packIsExpiredGarbage(DfsPackDescription d, && now - d.getLastModified() >= garbageTtlMillis; } + private boolean packIsCoalesceableGarbage(DfsPackDescription d, long now) { + // An UNREACHABLE_GARBAGE pack can be coalesced if its size is less than + // the coalesceGarbageLimit and either garbageTtl is zero or if the pack + // is created in a close time interval (on a single calendar day when + // the garbageTtl is more than one day or one third of the garbageTtl). + // + // When the garbageTtl is more than 24 hours, garbage packs that are + // created within a single calendar day are coalesced together. This + // would make the effective ttl of the garbage pack as garbageTtl+23:59 + // and limit the number of garbage to a maximum number of + // garbageTtl_in_days + 1 (assuming all of them are less than the size + // of coalesceGarbageLimit). + // + // When the garbageTtl is less than or equal to 24 hours, garbage packs + // that are created within a one third of garbageTtl are coalesced + // together. This would make the effective ttl of the garbage packs as + // garbageTtl + (garbageTtl / 3) and would limit the number of garbage + // packs to a maximum number of 4 (assuming all of them are less than + // the size of coalesceGarbageLimit). + + if (d.getPackSource() != UNREACHABLE_GARBAGE + || d.getFileSize(PackExt.PACK) >= coalesceGarbageLimit) { + return false; + } + + if (garbageTtlMillis == 0) { + return true; + } + + long lastModified = d.getLastModified(); + long dayStartLastModified = dayStartInMillis(lastModified); + long dayStartToday = dayStartInMillis(now); + + if (dayStartLastModified != dayStartToday) { + return false; // this pack is not created today. + } + + if (garbageTtlMillis > TimeUnit.DAYS.toMillis(1)) { + return true; // ttl is more than one day and pack is created today. + } + + long timeInterval = garbageTtlMillis / 3; + if (timeInterval == 0) { + return false; // ttl is too small, don't try to coalesce. + } + + long modifiedTimeSlot = (lastModified - dayStartLastModified) / timeInterval; + long presentTimeSlot = (now - dayStartToday) / timeInterval; + return modifiedTimeSlot == presentTimeSlot; + } + + private static long dayStartInMillis(long timeInMillis) { + Calendar cal = new GregorianCalendar( + SystemReader.getInstance().getTimeZone()); + cal.setTimeInMillis(timeInMillis); + cal.set(Calendar.HOUR_OF_DAY, 0); + cal.set(Calendar.MINUTE, 0); + cal.set(Calendar.SECOND, 0); + cal.set(Calendar.MILLISECOND, 0); + return cal.getTimeInMillis(); + } + /** @return all of the source packs that fed into this compaction. */ public List<DfsPackDescription> getSourcePacks() { return toPrune(); @@ -372,7 +437,7 @@ public List<PackStatistics> getNewPackStatistics() { private List<DfsPackDescription> toPrune() { int cnt = packsBefore.size(); - List<DfsPackDescription> all = new ArrayList<DfsPackDescription>(cnt); + List<DfsPackDescription> all = new ArrayList<>(cnt); for (DfsPackFile pack : packsBefore) { all.add(pack.getPackDescription()); } @@ -390,7 +455,8 @@ private void packHeads(ProgressMonitor pm) throws IOException { pw.setTagTargets(tagTargets); pw.preparePack(pm, allHeads, PackWriter.NONE); if (0 < pw.getObjectCount()) - writePack(GC, pw, pm); + writePack(GC, pw, pm, + estimateGcPackSize(INSERT, RECEIVE, COMPACT, GC)); } } @@ -403,7 +469,8 @@ private void packRest(ProgressMonitor pm) throws IOException { pw.excludeObjects(packedObjs); pw.preparePack(pm, nonHeads, allHeads); if (0 < pw.getObjectCount()) - writePack(GC_REST, pw, pm); + writePack(GC_REST, pw, pm, + estimateGcPackSize(INSERT, RECEIVE, COMPACT, GC_REST)); } } @@ -416,7 +483,7 @@ private void packRefTreeGraph(ProgressMonitor pm) throws IOException { pw.excludeObjects(packedObjs); pw.preparePack(pm, txnHeads, PackWriter.NONE); if (0 < pw.getObjectCount()) - writePack(GC_TXN, pw, pm); + writePack(GC_TXN, pw, pm, 0 /* unknown pack size */); } } @@ -432,21 +499,29 @@ private void packGarbage(ProgressMonitor pm) throws IOException { pw.setDeltaBaseAsOffset(true); pw.setReuseDeltaCommits(true); pm.beginTask(JGitText.get().findingGarbage, objectsBefore()); + long estimatedPackSize = 12 + 20; // header and trailer sizes. for (DfsPackFile oldPack : packsBefore) { PackIndex oldIdx = oldPack.getPackIndex(ctx); + PackReverseIndex oldRevIdx = oldPack.getReverseIdx(ctx); + long maxOffset = oldPack.getPackDescription().getFileSize(PACK) + - 20; // pack size - trailer size. for (PackIndex.MutableEntry ent : oldIdx) { pm.update(1); ObjectId id = ent.toObjectId(); if (pool.lookupOrNull(id) != null || anyPackHas(id)) continue; - int type = oldPack.getObjectType(ctx, ent.getOffset()); + long offset = ent.getOffset(); + int type = oldPack.getObjectType(ctx, offset); pw.addObject(pool.lookupAny(id, type)); + long objSize = oldRevIdx.findNextOffset(offset, maxOffset) + - offset; + estimatedPackSize += objSize; } } pm.endTask(); if (0 < pw.getObjectCount()) - writePack(UNREACHABLE_GARBAGE, pw, pm); + writePack(UNREACHABLE_GARBAGE, pw, pm, estimatedPackSize); } } @@ -461,6 +536,10 @@ private static boolean isHead(Ref ref) { return ref.getName().startsWith(Constants.R_HEADS); } + private static boolean isTag(Ref ref) { + return ref.getName().startsWith(Constants.R_TAGS); + } + private int objectsBefore() { int cnt = 0; for (DfsPackFile p : packsBefore) @@ -475,9 +554,24 @@ private PackWriter newPackWriter() { return pw; } + private long estimateGcPackSize(PackSource first, PackSource... rest) { + EnumSet<PackSource> sourceSet = EnumSet.of(first, rest); + // Every pack file contains 12 bytes of header and 20 bytes of trailer. + // Include the final pack file header and trailer size here and ignore + // the same from individual pack files. + long size = 32; + for (DfsPackDescription pack : getSourcePacks()) { + if (sourceSet.contains(pack.getPackSource())) { + size += pack.getFileSize(PACK) - 32; + } + } + return size; + } + private DfsPackDescription writePack(PackSource source, PackWriter pw, - ProgressMonitor pm) throws IOException { - DfsPackDescription pack = repo.getObjectDatabase().newPack(source); + ProgressMonitor pm, long estimatedPackSize) throws IOException { + DfsPackDescription pack = repo.getObjectDatabase().newPack(source, + estimatedPackSize); newPackDesc.add(pack); try (DfsOutputStream out = objdb.writeFile(pack, PACK)) {
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/dfs/DfsInserter.java b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/dfs/DfsInserter.java index c179e77..fd72756 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/dfs/DfsInserter.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/dfs/DfsInserter.java
@@ -90,6 +90,7 @@ import org.eclipse.jgit.util.NB; import org.eclipse.jgit.util.TemporaryBuffer; import org.eclipse.jgit.util.io.CountingOutputStream; +import org.eclipse.jgit.util.sha1.SHA1; /** Inserts objects into the DFS. */ public class DfsInserter extends ObjectInserter { @@ -168,7 +169,7 @@ public ObjectId insert(int type, long len, InputStream in) } long offset = beginObject(type, len); - MessageDigest md = digest(); + SHA1 md = digest(); md.update(Constants.encodedTypeString(type)); md.update((byte) ' '); md.update(Constants.encodeASCII(len)); @@ -183,7 +184,7 @@ public ObjectId insert(int type, long len, InputStream in) len -= n; } packOut.compress.finish(); - return endObject(ObjectId.fromRaw(md.digest()), offset); + return endObject(md.toObjectId(), offset); } private byte[] insertBuffer(long len) { @@ -274,8 +275,8 @@ private ObjectId endObject(ObjectId id, long offset) { } private void beginPack() throws IOException { - objectList = new BlockList<PackedObjectInfo>(); - objectMap = new ObjectIdOwnerMap<PackedObjectInfo>(); + objectList = new BlockList<>(); + objectMap = new ObjectIdOwnerMap<>(); cache = DfsBlockCache.getInstance(); rollback = true; @@ -543,7 +544,7 @@ public Collection<ObjectId> resolve(AbbreviatedObjectId id) if (objectList == null) return stored; - Set<ObjectId> r = new HashSet<ObjectId>(stored.size() + 2); + Set<ObjectId> r = new HashSet<>(stored.size() + 2); r.addAll(stored); for (PackedObjectInfo obj : objectList) { if (id.prefixCompare(obj) == 0)
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 b1d6c0d..b1cb72d 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
@@ -160,7 +160,7 @@ public static enum PackSource { protected DfsObjDatabase(DfsRepository repository, DfsReaderOptions options) { this.repository = repository; - this.packList = new AtomicReference<PackList>(NO_PACKS); + this.packList = new AtomicReference<>(NO_PACKS); this.readerOptions = options; } @@ -266,6 +266,32 @@ protected abstract DfsPackDescription newPack(PackSource source) throws IOException; /** + * Generate a new unique name for a pack file. + * + * <p> + * Default implementation of this method would be equivalent to + * {@code newPack(source).setEstimatedPackSize(estimatedPackSize)}. But the + * clients can override this method to use the given + * {@code estomatedPackSize} value more efficiently in the process of + * creating a new {@link DfsPackDescription} object. + * + * @param source + * where the pack stream is created. + * @param estimatedPackSize + * the estimated size of the pack. + * @return a unique name for the pack file. Must not collide with any other + * pack file name in the same DFS. + * @throws IOException + * a new unique pack description cannot be generated. + */ + protected DfsPackDescription newPack(PackSource source, + long estimatedPackSize) throws IOException { + DfsPackDescription pack = newPack(source); + pack.setEstimatedPackSize(estimatedPackSize); + return pack; + } + + /** * Commit a pack and index pair that was written to the DFS. * <p> * Committing the pack/index pair makes them visible to readers. The JGit @@ -432,7 +458,7 @@ private PackList scanPacksImpl(PackList old) throws IOException { List<DfsPackDescription> scanned = listPacks(); Collections.sort(scanned); - List<DfsPackFile> list = new ArrayList<DfsPackFile>(scanned.size()); + List<DfsPackFile> list = new ArrayList<>(scanned.size()); boolean foundNew = false; for (DfsPackDescription dsc : scanned) { DfsPackFile oldPack = forReuse.remove(dsc); @@ -457,7 +483,7 @@ private PackList scanPacksImpl(PackList old) throws IOException { private static Map<DfsPackDescription, DfsPackFile> reuseMap(PackList old) { Map<DfsPackDescription, DfsPackFile> forReuse - = new HashMap<DfsPackDescription, DfsPackFile>(); + = new HashMap<>(); for (DfsPackFile p : old.packs) { if (p.invalid()) { // The pack instance is corrupted, and cannot be safely used
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/dfs/DfsObjectRepresentation.java b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/dfs/DfsObjectRepresentation.java index 7edae88..ddcfff6 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/dfs/DfsObjectRepresentation.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/dfs/DfsObjectRepresentation.java
@@ -43,8 +43,6 @@ package org.eclipse.jgit.internal.storage.dfs; -import static org.eclipse.jgit.internal.storage.dfs.DfsObjDatabase.PackSource.GC; - import org.eclipse.jgit.internal.storage.pack.StoredObjectRepresentation; import org.eclipse.jgit.lib.ObjectId; @@ -76,6 +74,13 @@ public ObjectId getDeltaBase() { @Override public boolean wasDeltaAttempted() { - return pack.getPackDescription().getPackSource() == GC; + switch (pack.getPackDescription().getPackSource()) { + case GC: + case GC_REST: + case GC_TXN: + return true; + default: + return false; + } } }
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 11aef7f..0a29ac5 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
@@ -113,10 +113,10 @@ public class DfsPackCompactor { public DfsPackCompactor(DfsRepository repository) { repo = repository; autoAddSize = 5 * 1024 * 1024; // 5 MiB - srcPacks = new ArrayList<DfsPackFile>(); - exclude = new ArrayList<ObjectIdSet>(4); - newPacks = new ArrayList<DfsPackDescription>(1); - newStats = new ArrayList<PackStatistics>(1); + srcPacks = new ArrayList<>(); + exclude = new ArrayList<>(4); + newPacks = new ArrayList<>(1); + newStats = new ArrayList<>(1); } /** @@ -224,7 +224,8 @@ public void compact(ProgressMonitor pm) throws IOException { } boolean rollback = true; - DfsPackDescription pack = objdb.newPack(COMPACT); + DfsPackDescription pack = objdb.newPack(COMPACT, + estimatePackSize()); try { writePack(objdb, pack, pw, pm); writeIndex(objdb, pack, pw); @@ -251,6 +252,17 @@ public void compact(ProgressMonitor pm) throws IOException { } } + private long estimatePackSize() { + // Every pack file contains 12 bytes of header and 20 bytes of trailer. + // Include the final pack file header and trailer size here and ignore + // the same from individual pack files. + long size = 32; + for (DfsPackFile pack : srcPacks) { + size += pack.getPackDescription().getFileSize(PACK) - 32; + } + return size; + } + /** @return all of the source packs that fed into this compaction. */ public List<DfsPackDescription> getSourcePacks() { return toPrune(); @@ -268,7 +280,7 @@ public List<PackStatistics> getNewPackStatistics() { private List<DfsPackDescription> toPrune() { int cnt = srcPacks.size(); - List<DfsPackDescription> all = new ArrayList<DfsPackDescription>(cnt); + List<DfsPackDescription> all = new ArrayList<>(cnt); for (DfsPackFile pack : srcPacks) all.add(pack.getPackDescription()); return all; @@ -281,6 +293,7 @@ private void addObjectsToPack(PackWriter pw, DfsReader ctx, // older packs, allowing the PackWriter to be handed newer objects // first and older objects last. Collections.sort(srcPacks, new Comparator<DfsPackFile>() { + @Override public int compare(DfsPackFile a, DfsPackFile b) { return a.getPackDescription().compareTo(b.getPackDescription()); } @@ -289,7 +302,7 @@ public int compare(DfsPackFile a, DfsPackFile b) { rw = new RevWalk(ctx); added = rw.newFlag("ADDED"); //$NON-NLS-1$ isBase = rw.newFlag("IS_BASE"); //$NON-NLS-1$ - List<RevObject> baseObjects = new BlockList<RevObject>(); + List<RevObject> baseObjects = new BlockList<>(); pm.beginTask(JGitText.get().countingObjects, ProgressMonitor.UNKNOWN); for (DfsPackFile src : srcPacks) { @@ -333,7 +346,7 @@ public int compare(DfsPackFile a, DfsPackFile b) { private List<ObjectIdWithOffset> toInclude(DfsPackFile src, DfsReader ctx) throws IOException { PackIndex srcIdx = src.getPackIndex(ctx); - List<ObjectIdWithOffset> want = new BlockList<ObjectIdWithOffset>( + List<ObjectIdWithOffset> want = new BlockList<>( (int) srcIdx.getObjectCount()); SCAN: for (PackIndex.MutableEntry ent : srcIdx) { ObjectId id = ent.toObjectId(); @@ -346,6 +359,7 @@ private List<ObjectIdWithOffset> toInclude(DfsPackFile src, DfsReader ctx) want.add(new ObjectIdWithOffset(id, ent.getOffset())); } Collections.sort(want, new Comparator<ObjectIdWithOffset>() { + @Override public int compare(ObjectIdWithOffset a, ObjectIdWithOffset b) { return Long.signum(a.offset - b.offset); }
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/dfs/DfsPackDescription.java b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/dfs/DfsPackDescription.java index 2b9d0e5..e825f1a 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/dfs/DfsPackDescription.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/dfs/DfsPackDescription.java
@@ -81,6 +81,8 @@ public class DfsPackDescription implements Comparable<DfsPackDescription> { private int indexVersion; + private long estimatedPackSize; + /** * Initialize a description by pack name and repository. * <p> @@ -100,7 +102,7 @@ public DfsPackDescription(DfsRepositoryDescription repoDesc, String name) { this.repoDesc = repoDesc; int dot = name.lastIndexOf('.'); this.packName = (dot < 0) ? name : name.substring(0, dot); - this.sizeMap = new HashMap<PackExt, Long>(PackExt.values().length * 2); + this.sizeMap = new HashMap<>(PackExt.values().length * 2); } /** @return description of the repository. */ @@ -189,6 +191,25 @@ public long getFileSize(PackExt ext) { return size == null ? 0 : size.longValue(); } + /** + * @param estimatedPackSize + * estimated size of the .pack file in bytes. If 0 the pack file + * size is unknown. + * @return {@code this} + */ + public DfsPackDescription setEstimatedPackSize(long estimatedPackSize) { + this.estimatedPackSize = Math.max(0, estimatedPackSize); + return this; + } + + /** + * @return estimated size of the .pack file in bytes. If 0 the pack file + * size is unknown. + */ + public long getEstimatedPackSize() { + return estimatedPackSize; + } + /** @return number of objects in the pack. */ public long getObjectCount() { return objectCount; @@ -288,6 +309,7 @@ public boolean equals(Object b) { * @param b * the other pack. */ + @Override public int compareTo(DfsPackDescription b) { // Cluster by PackSource, pushing UNREACHABLE_GARBAGE to the end. PackSource as = getPackSource(); @@ -298,6 +320,17 @@ public int compareTo(DfsPackDescription b) { return cmp; } + // Tie break GC type packs by smallest first. There should be at most + // one of each source, but when multiple exist concurrent GCs may have + // run. Preferring the smaller file selects higher quality delta + // compression, placing less demand on the DfsBlockCache. + if (as != null && as == bs && isGC(as)) { + int cmp = Long.signum(getFileSize(PACK) - b.getFileSize(PACK)); + if (cmp != 0) { + return cmp; + } + } + // Newer packs should sort first. int cmp = Long.signum(b.getLastModified() - getLastModified()); if (cmp != 0) @@ -309,6 +342,17 @@ public int compareTo(DfsPackDescription b) { return Long.signum(getObjectCount() - b.getObjectCount()); } + static boolean isGC(PackSource s) { + switch (s) { + case GC: + case GC_REST: + case GC_TXN: + return true; + default: + return false; + } + } + @Override public String toString() { return getFileName(PackExt.PACK);
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 4eabb03..f15d427 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
@@ -187,7 +187,6 @@ public DfsPackDescription getPackDescription() { /** * @return whether the pack index file is loaded and cached in memory. - * @since 2.2 */ public boolean isIndexLoaded() { DfsBlockCache.Ref<PackIndex> idxref = index; @@ -499,6 +498,7 @@ private long copyPackBypassCache(PackOutputStream out, DfsReader ctx) rc.setReadAheadBytes(ctx.getOptions().getStreamPackBufferSize()); long position = 12; long remaining = length - (12 + 20); + boolean packHeadSkipped = false; while (0 < remaining) { DfsBlock b = cache.get(key, alignToBlock(position)); if (b != null) { @@ -508,6 +508,7 @@ private long copyPackBypassCache(PackOutputStream out, DfsReader ctx) position += n; remaining -= n; rc.position(position); + packHeadSkipped = true; continue; } @@ -517,7 +518,14 @@ private long copyPackBypassCache(PackOutputStream out, DfsReader ctx) throw packfileIsTruncated(); else if (n > remaining) n = (int) remaining; - out.write(buf.array(), 0, n); + + if (!packHeadSkipped) { + // Need skip the 'PACK' header for the first read + out.write(buf.array(), 12, n - 12); + packHeadSkipped = true; + } else { + out.write(buf.array(), 0, n); + } position += n; remaining -= n; }
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/dfs/DfsReader.java b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/dfs/DfsReader.java index 8c93295..755b163 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/dfs/DfsReader.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/dfs/DfsReader.java
@@ -44,10 +44,12 @@ package org.eclipse.jgit.internal.storage.dfs; +import static org.eclipse.jgit.internal.storage.pack.PackExt.PACK; import static org.eclipse.jgit.lib.Constants.OBJECT_ID_LENGTH; import java.io.IOException; import java.util.ArrayList; +import java.util.Arrays; import java.util.Collection; import java.util.Collections; import java.util.Comparator; @@ -64,6 +66,7 @@ import org.eclipse.jgit.errors.StoredObjectRepresentationNotAvailableException; import org.eclipse.jgit.internal.JGitText; import org.eclipse.jgit.internal.storage.dfs.DfsObjDatabase.PackList; +import org.eclipse.jgit.internal.storage.dfs.DfsObjDatabase.PackSource; import org.eclipse.jgit.internal.storage.file.BitmapIndexImpl; import org.eclipse.jgit.internal.storage.file.PackBitmapIndex; import org.eclipse.jgit.internal.storage.file.PackIndex; @@ -146,6 +149,7 @@ public BitmapIndex getBitmapIndex() throws IOException { return null; } + @Override public Collection<CachedPack> getCachedPacksAndUpdate( BitmapBuilder needBitmap) throws IOException { for (DfsPackFile pack : db.getPacks()) { @@ -162,20 +166,19 @@ public Collection<ObjectId> resolve(AbbreviatedObjectId id) throws IOException { if (id.isComplete()) return Collections.singleton(id.toObjectId()); - boolean noGarbage = avoidUnreachable; - HashSet<ObjectId> matches = new HashSet<ObjectId>(4); + HashSet<ObjectId> matches = new HashSet<>(4); PackList packList = db.getPackList(); - resolveImpl(packList, id, noGarbage, matches); + resolveImpl(packList, id, matches); if (matches.size() < MAX_RESOLVE_MATCHES && packList.dirty()) { - resolveImpl(db.scanPacks(packList), id, noGarbage, matches); + resolveImpl(db.scanPacks(packList), id, matches); } return matches; } private void resolveImpl(PackList packList, AbbreviatedObjectId id, - boolean noGarbage, HashSet<ObjectId> matches) throws IOException { + HashSet<ObjectId> matches) throws IOException { for (DfsPackFile pack : packList.packs) { - if (noGarbage && pack.isGarbage()) { + if (skipGarbagePack(pack)) { continue; } pack.resolve(this, matches, id, MAX_RESOLVE_MATCHES); @@ -187,22 +190,23 @@ private void resolveImpl(PackList packList, AbbreviatedObjectId id, @Override public boolean has(AnyObjectId objectId) throws IOException { - if (last != null && last.hasObject(this, objectId)) + if (last != null + && !skipGarbagePack(last) + && last.hasObject(this, objectId)) return true; - boolean noGarbage = avoidUnreachable; PackList packList = db.getPackList(); - if (hasImpl(packList, objectId, noGarbage)) { + if (hasImpl(packList, objectId)) { return true; } else if (packList.dirty()) { - return hasImpl(db.scanPacks(packList), objectId, noGarbage); + return hasImpl(db.scanPacks(packList), objectId); } return false; } - private boolean hasImpl(PackList packList, AnyObjectId objectId, - boolean noGarbage) throws IOException { + private boolean hasImpl(PackList packList, AnyObjectId objectId) + throws IOException { for (DfsPackFile pack : packList.packs) { - if (pack == last || (noGarbage && pack.isGarbage())) + if (pack == last || skipGarbagePack(pack)) continue; if (pack.hasObject(this, objectId)) { last = pack; @@ -217,7 +221,7 @@ public ObjectLoader open(AnyObjectId objectId, int typeHint) throws MissingObjectException, IncorrectObjectTypeException, IOException { ObjectLoader ldr; - if (last != null) { + if (last != null && !skipGarbagePack(last)) { ldr = last.get(this, objectId); if (ldr != null) { return checkType(ldr, objectId, typeHint); @@ -225,13 +229,12 @@ public ObjectLoader open(AnyObjectId objectId, int typeHint) } PackList packList = db.getPackList(); - boolean noGarbage = avoidUnreachable; - ldr = openImpl(packList, objectId, noGarbage); + ldr = openImpl(packList, objectId); if (ldr != null) { return checkType(ldr, objectId, typeHint); } if (packList.dirty()) { - ldr = openImpl(db.scanPacks(packList), objectId, noGarbage); + ldr = openImpl(db.scanPacks(packList), objectId); if (ldr != null) { return checkType(ldr, objectId, typeHint); } @@ -251,10 +254,10 @@ private static ObjectLoader checkType(ObjectLoader ldr, AnyObjectId id, return ldr; } - private ObjectLoader openImpl(PackList packList, AnyObjectId objectId, - boolean noGarbage) throws IOException { + private ObjectLoader openImpl(PackList packList, AnyObjectId objectId) + throws IOException { for (DfsPackFile pack : packList.packs) { - if (pack == last || (noGarbage && pack.isGarbage())) { + if (pack == last || skipGarbagePack(pack)) { continue; } ObjectLoader ldr = pack.get(this, objectId); @@ -272,6 +275,7 @@ public Set<ObjectId> getShallowCommits() { } private static final Comparator<FoundObject<?>> FOUND_OBJECT_SORT = new Comparator<FoundObject<?>>() { + @Override public int compare(FoundObject<?> a, FoundObject<?> b) { int cmp = a.packIndex - b.packIndex; if (cmp == 0) @@ -315,7 +319,7 @@ private <T extends ObjectId> Iterable<FoundObject<T>> findAll( findAllImpl(db.scanPacks(packList), pending, r); } for (T t : pending) { - r.add(new FoundObject<T>(t)); + r.add(new FoundObject<>(t)); } Collections.sort(r, FOUND_OBJECT_SORT); return r; @@ -329,31 +333,32 @@ private <T extends ObjectId> void findAllImpl(PackList packList, } int lastIdx = 0; DfsPackFile lastPack = packs[lastIdx]; - boolean noGarbage = avoidUnreachable; OBJECT_SCAN: for (Iterator<T> it = pending.iterator(); it.hasNext();) { T t = it.next(); - try { - long p = lastPack.findOffset(this, t); - if (0 < p) { - r.add(new FoundObject<T>(t, lastIdx, lastPack, p)); - it.remove(); - continue; + if (!skipGarbagePack(lastPack)) { + try { + long p = lastPack.findOffset(this, t); + if (0 < p) { + r.add(new FoundObject<>(t, lastIdx, lastPack, p)); + it.remove(); + continue; + } + } catch (IOException e) { + // Fall though and try to examine other packs. } - } catch (IOException e) { - // Fall though and try to examine other packs. } for (int i = 0; i < packs.length; i++) { if (i == lastIdx) continue; DfsPackFile pack = packs[i]; - if (noGarbage && pack.isGarbage()) + if (skipGarbagePack(pack)) continue; try { long p = pack.findOffset(this, t); if (0 < p) { - r.add(new FoundObject<T>(t, i, pack, p)); + r.add(new FoundObject<>(t, i, pack, p)); it.remove(); lastIdx = i; lastPack = pack; @@ -368,6 +373,10 @@ private <T extends ObjectId> void findAllImpl(PackList packList, last = lastPack; } + private boolean skipGarbagePack(DfsPackFile pack) { + return avoidUnreachable && pack.isGarbage(); + } + @Override public <T extends ObjectId> AsyncObjectLoaderQueue<T> open( Iterable<T> objectIds, final boolean reportMissing) { @@ -385,6 +394,7 @@ public <T extends ObjectId> AsyncObjectLoaderQueue<T> open( return new AsyncObjectLoaderQueue<T>() { private FoundObject<T> cur; + @Override public boolean next() throws MissingObjectException, IOException { if (idItr.hasNext()) { cur = idItr.next(); @@ -396,14 +406,17 @@ public boolean next() throws MissingObjectException, IOException { } } + @Override public T getCurrent() { return cur.id; } + @Override public ObjectId getObjectId() { return cur.id; } + @Override public ObjectLoader open() throws IOException { if (cur.pack == null) throw new MissingObjectException(cur.id, @@ -411,10 +424,12 @@ public ObjectLoader open() throws IOException { return cur.pack.load(DfsReader.this, cur.offset); } + @Override public boolean cancel(boolean mayInterruptIfRunning) { return true; } + @Override public void release() { // Nothing to clean up. } @@ -440,6 +455,7 @@ public <T extends ObjectId> AsyncObjectSizeQueue<T> getObjectSize( private long sz; + @Override public boolean next() throws MissingObjectException, IOException { if (idItr.hasNext()) { cur = idItr.next(); @@ -455,22 +471,27 @@ public boolean next() throws MissingObjectException, IOException { } } + @Override public T getCurrent() { return cur.id; } + @Override public ObjectId getObjectId() { return cur.id; } + @Override public long getSize() { return sz; } + @Override public boolean cancel(boolean mayInterruptIfRunning) { return true; } + @Override public void release() { // Nothing to clean up. } @@ -481,7 +502,7 @@ public void release() { public long getObjectSize(AnyObjectId objectId, int typeHint) throws MissingObjectException, IncorrectObjectTypeException, IOException { - if (last != null) { + if (last != null && !skipGarbagePack(last)) { long sz = last.getObjectSize(this, objectId); if (0 <= sz) { return sz; @@ -510,7 +531,7 @@ public long getObjectSize(AnyObjectId objectId, int typeHint) private long getObjectSizeImpl(PackList packList, AnyObjectId objectId) throws IOException { for (DfsPackFile pack : packList.packs) { - if (pack == last) { + if (pack == last || skipGarbagePack(pack)) { continue; } long sz = pack.getObjectSize(this, objectId); @@ -522,22 +543,25 @@ private long getObjectSizeImpl(PackList packList, AnyObjectId objectId) return -1; } + @Override public DfsObjectToPack newObjectToPack(AnyObjectId objectId, int type) { return new DfsObjectToPack(objectId, type); } private static final Comparator<DfsObjectToPack> OFFSET_SORT = new Comparator<DfsObjectToPack>() { + @Override public int compare(DfsObjectToPack a, DfsObjectToPack b) { return Long.signum(a.getOffset() - b.getOffset()); } }; + @Override public void selectObjectRepresentation(PackWriter packer, ProgressMonitor monitor, Iterable<ObjectToPack> objects) throws IOException, MissingObjectException { // Don't check dirty bit on PackList; assume ObjectToPacks all came from the // current list. - for (DfsPackFile pack : db.getPacks()) { + for (DfsPackFile pack : sortPacksForSelectRepresentation()) { List<DfsObjectToPack> tmp = findAllFromPack(pack, objects); if (tmp.isEmpty()) continue; @@ -556,9 +580,39 @@ public void selectObjectRepresentation(PackWriter packer, } } + private static final Comparator<DfsPackFile> PACK_SORT_FOR_REUSE = new Comparator<DfsPackFile>() { + @Override + public int compare(DfsPackFile af, DfsPackFile bf) { + DfsPackDescription ad = af.getPackDescription(); + DfsPackDescription bd = bf.getPackDescription(); + PackSource as = ad.getPackSource(); + PackSource bs = bd.getPackSource(); + + if (as != null && as == bs && DfsPackDescription.isGC(as)) { + // Push smaller GC files last; these likely have higher quality + // delta compression and the contained representation should be + // favored over other files. + return Long.signum(bd.getFileSize(PACK) - ad.getFileSize(PACK)); + } + + // DfsPackDescription.compareTo already did a reasonable sort. + // Rely on Arrays.sort being stable, leaving equal elements. + return 0; + } + }; + + private DfsPackFile[] sortPacksForSelectRepresentation() + throws IOException { + DfsPackFile[] packs = db.getPacks(); + DfsPackFile[] sorted = new DfsPackFile[packs.length]; + System.arraycopy(packs, 0, sorted, 0, packs.length); + Arrays.sort(sorted, PACK_SORT_FOR_REUSE); + return sorted; + } + private List<DfsObjectToPack> findAllFromPack(DfsPackFile pack, Iterable<ObjectToPack> objects) throws IOException { - List<DfsObjectToPack> tmp = new BlockList<DfsObjectToPack>(); + List<DfsObjectToPack> tmp = new BlockList<>(); PackIndex idx = pack.getPackIndex(this); for (ObjectToPack otp : objects) { long p = idx.findOffset(otp); @@ -570,6 +624,7 @@ private List<DfsObjectToPack> findAllFromPack(DfsPackFile pack, return tmp; } + @Override public void copyObjectAsIs(PackOutputStream out, ObjectToPack otp, boolean validate) throws IOException, StoredObjectRepresentationNotAvailableException { @@ -577,12 +632,14 @@ public void copyObjectAsIs(PackOutputStream out, ObjectToPack otp, src.pack.copyAsIs(out, src, validate, this); } + @Override public void writeObjects(PackOutputStream out, List<ObjectToPack> list) throws IOException { for (ObjectToPack otp : list) out.writeObject(otp); } + @Override public void copyPackAsIs(PackOutputStream out, CachedPack pack) throws IOException { ((DfsCachedPack) pack).copyAsIs(out, this);
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/dfs/DfsReaderOptions.java b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/dfs/DfsReaderOptions.java index 8419807..d07c13d 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/dfs/DfsReaderOptions.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/dfs/DfsReaderOptions.java
@@ -109,7 +109,6 @@ public DfsReaderOptions setStreamFileThreshold(final int newLimit) { /** * @return number of bytes to use for buffering when streaming a pack file * during copying. If 0 the block size of the pack is used. - * @since 4.0 */ public int getStreamPackBufferSize() { return streamPackBufferSize; @@ -120,7 +119,6 @@ public int getStreamPackBufferSize() { * new buffer size in bytes for buffers used when streaming pack * files during copying. * @return {@code this} - * @since 4.0 */ public DfsReaderOptions setStreamPackBufferSize(int bufsz) { streamPackBufferSize = Math.max(0, bufsz);
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 4ddcec1..b41c18b 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
@@ -78,7 +78,7 @@ public abstract class DfsRefDatabase extends RefDatabase { */ protected DfsRefDatabase(DfsRepository repository) { this.repository = repository; - this.cache = new AtomicReference<RefCache>(); + this.cache = new AtomicReference<>(); } /** @return the repository the database holds the references of. */ @@ -120,7 +120,7 @@ public Map<String, Ref> getRefs(String prefix) throws IOException { RefCache curr = read(); RefList<Ref> packed = RefList.emptyList(); RefList<Ref> loose = curr.ids; - RefList.Builder<Ref> sym = new RefList.Builder<Ref>(curr.sym.size()); + RefList.Builder<Ref> sym = new RefList.Builder<>(curr.sym.size()); for (int idx = 0; idx < curr.sym.size(); idx++) { Ref ref = curr.sym.get(idx);
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/dfs/DfsRepository.java b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/dfs/DfsRepository.java index ef88450..a5dd514 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/dfs/DfsRepository.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/dfs/DfsRepository.java
@@ -143,10 +143,12 @@ private static class EmptyAttributesNodeProvider implements AttributesNodeProvider { private EmptyAttributesNode emptyAttributesNode = new EmptyAttributesNode(); + @Override public AttributesNode getInfoAttributesNode() throws IOException { return emptyAttributesNode; } + @Override public AttributesNode getGlobalAttributesNode() throws IOException { return emptyAttributesNode; }
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/dfs/InMemoryRepository.java b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/dfs/InMemoryRepository.java index fd21397..527e46b 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/dfs/InMemoryRepository.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/dfs/InMemoryRepository.java
@@ -63,7 +63,6 @@ public InMemoryRepository build() throws IOException { * * @param repoDesc * description of the repository. - * @since 2.0 */ public InMemoryRepository(DfsRepositoryDescription repoDesc) { this(new Builder().setRepositoryDescription(repoDesc)); @@ -108,7 +107,7 @@ public void setGitwebDescription(@Nullable String d) { } private class MemObjDatabase extends DfsObjDatabase { - private List<DfsPackDescription> packs = new ArrayList<DfsPackDescription>(); + private List<DfsPackDescription> packs = new ArrayList<>(); MemObjDatabase(DfsRepository repo) { super(repo, new DfsReaderOptions()); @@ -133,7 +132,7 @@ protected synchronized void commitPackImpl( Collection<DfsPackDescription> desc, Collection<DfsPackDescription> replace) { List<DfsPackDescription> n; - n = new ArrayList<DfsPackDescription>(desc.size() + packs.size()); + n = new ArrayList<>(desc.size() + packs.size()); n.addAll(desc); n.addAll(packs); if (replace != null) @@ -171,7 +170,7 @@ public void flush() { private static class MemPack extends DfsPackDescription { final Map<PackExt, byte[]> - fileMap = new HashMap<PackExt, byte[]>(); + fileMap = new HashMap<>(); MemPack(String name, DfsRepositoryDescription repoDesc) { super(repoDesc, name); @@ -226,6 +225,7 @@ private static class ByteArrayReadableChannel implements ReadableChannel { data = buf; } + @Override public int read(ByteBuffer dst) { int n = Math.min(dst.remaining(), data.length - position); if (n == 0) @@ -235,30 +235,37 @@ public int read(ByteBuffer dst) { return n; } + @Override public void close() { open = false; } + @Override public boolean isOpen() { return open; } + @Override public long position() { return position; } + @Override public void position(long newPosition) { position = (int) newPosition; } + @Override public long size() { return data.length; } + @Override public int blockSize() { return 0; } + @Override public void setReadAheadBytes(int b) { // Unnecessary on a byte array. } @@ -271,7 +278,7 @@ public void setReadAheadBytes(int b) { * subclasses of InMemoryRepository. */ protected class MemRefDatabase extends DfsRefDatabase { - private final ConcurrentMap<String, Ref> refs = new ConcurrentHashMap<String, Ref>(); + private final ConcurrentMap<String, Ref> refs = new ConcurrentHashMap<>(); private final ReadWriteLock lock = new ReentrantReadWriteLock(true /* fair */); /** @@ -308,8 +315,8 @@ public void execute(RevWalk walk, ProgressMonitor monitor) @Override protected RefCache scanAllRefs() throws IOException { - RefList.Builder<Ref> ids = new RefList.Builder<Ref>(); - RefList.Builder<Ref> sym = new RefList.Builder<Ref>(); + RefList.Builder<Ref> ids = new RefList.Builder<>(); + RefList.Builder<Ref> sym = new RefList.Builder<>(); try { lock.readLock().lock(); for (Ref ref : refs.values()) {
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/BasePackBitmapIndex.java b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/BasePackBitmapIndex.java index 30e973e..b78ff2a 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/BasePackBitmapIndex.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/BasePackBitmapIndex.java
@@ -58,6 +58,7 @@ abstract class BasePackBitmapIndex extends PackBitmapIndex { this.bitmaps = bitmaps; } + @Override public EWAHCompressedBitmap getBitmap(AnyObjectId objectId) { StoredBitmap sb = bitmaps.get(objectId); return sb != null ? sb.getBitmap() : null;
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/BitmapIndexImpl.java b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/BitmapIndexImpl.java index b18a06f..88eef4c 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/BitmapIndexImpl.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/BitmapIndexImpl.java
@@ -370,6 +370,7 @@ public Iterator<BitmapObject> iterator() { private int type; private IntIterator cached = dynamic; + @Override public boolean hasNext() { if (!cached.hasNext()) { if (commits.hasNext()) { @@ -391,6 +392,7 @@ public boolean hasNext() { return true; } + @Override public BitmapObject next() { if (!hasNext()) throw new NoSuchElementException(); @@ -408,6 +410,7 @@ public BitmapObject next() { return out; } + @Override public void remove() { throw new UnsupportedOperationException(); } @@ -439,10 +442,10 @@ private EWAHCompressedBitmap ewahBitmap(Bitmap other) { private static final class MutableBitmapIndex { private final ObjectIdOwnerMap<MutableEntry> - revMap = new ObjectIdOwnerMap<MutableEntry>(); + revMap = new ObjectIdOwnerMap<>(); private final BlockList<MutableEntry> - revList = new BlockList<MutableEntry>(); + revList = new BlockList<>(); int findPosition(AnyObjectId objectId) { MutableEntry entry = revMap.get(objectId);
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/CachedObjectDirectory.java b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/CachedObjectDirectory.java index a81d8ec..d47b304 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/CachedObjectDirectory.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/CachedObjectDirectory.java
@@ -90,7 +90,7 @@ class CachedObjectDirectory extends FileObjectDatabase { } private ObjectIdOwnerMap<UnpackedObjectId> scanLoose() { - ObjectIdOwnerMap<UnpackedObjectId> m = new ObjectIdOwnerMap<UnpackedObjectId>(); + ObjectIdOwnerMap<UnpackedObjectId> m = new ObjectIdOwnerMap<>(); File objects = wrapped.getDirectory(); String[] fanout = objects.list(); if (fanout == null)
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/CheckoutEntryImpl.java b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/CheckoutEntryImpl.java index e968119..4b4337d 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/CheckoutEntryImpl.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/CheckoutEntryImpl.java
@@ -65,10 +65,12 @@ public class CheckoutEntryImpl implements CheckoutEntry { to = comment.substring(p2 + " to ".length(), p3); //$NON-NLS-1$ } + @Override public String getFromBranch() { return from; } + @Override public String getToBranch() { return to; }
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/DeltaBaseCache.java b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/DeltaBaseCache.java index a95dea7..b397989 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/DeltaBaseCache.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/DeltaBaseCache.java
@@ -69,7 +69,7 @@ private static int hash(final long position) { private int openByteCount; static { - DEAD = new SoftReference<Entry>(null); + DEAD = new SoftReference<>(null); reconfigure(new WindowCacheConfig()); } @@ -115,7 +115,7 @@ void store(final PackFile pack, final long position, e.provider = pack; e.position = position; e.sz = data.length; - e.data = new SoftReference<Entry>(new Entry(data, objectType)); + e.data = new SoftReference<>(new Entry(data, objectType)); moveToHead(e); }
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 0388acb..ef9aa37 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
@@ -55,6 +55,7 @@ import java.text.MessageFormat; import java.text.ParseException; import java.util.HashSet; +import java.util.Locale; import java.util.Objects; import java.util.Set; @@ -342,7 +343,7 @@ && getDirectory().getName().startsWith(".")) //$NON-NLS-1$ if (symLinks != null) cfg.setString(ConfigConstants.CONFIG_CORE_SECTION, null, ConfigConstants.CONFIG_KEY_SYMLINKS, symLinks.name() - .toLowerCase()); + .toLowerCase(Locale.ROOT)); cfg.setInt(ConfigConstants.CONFIG_CORE_SECTION, null, ConfigConstants.CONFIG_KEY_REPO_FORMAT_VERSION, 0); cfg.setBoolean(ConfigConstants.CONFIG_CORE_SECTION, null, @@ -489,7 +490,7 @@ private File descriptionFile() { */ @Override public Set<ObjectId> getAdditionalHaves() { - HashSet<ObjectId> r = new HashSet<ObjectId>(); + HashSet<ObjectId> r = new HashSet<>(); for (AlternateHandle d : objectDatabase.myAlternates()) { if (d instanceof AlternateRepository) { Repository repo; @@ -618,12 +619,18 @@ static void loadRulesFromFile(AttributesNode r, File attrs) } + private boolean shouldAutoDetach() { + return getConfig().getBoolean(ConfigConstants.CONFIG_GC_SECTION, + ConfigConstants.CONFIG_KEY_AUTODETACH, true); + } + @Override public void autoGC(ProgressMonitor monitor) { GC gc = new GC(this); gc.setPackConfig(new PackConfig(this)); gc.setProgressMonitor(monitor); gc.setAuto(true); + gc.setBackground(shouldAutoDetach()); try { gc.gc(); } catch (ParseException | IOException e) {
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 b608416..a4a2baa 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
@@ -50,8 +50,11 @@ import java.io.FileOutputStream; import java.io.IOException; import java.io.OutputStream; +import java.io.PrintWriter; +import java.io.StringWriter; import java.nio.channels.Channels; import java.nio.channels.FileChannel; +import java.nio.file.DirectoryNotEmptyException; import java.nio.file.DirectoryStream; import java.nio.file.Files; import java.nio.file.Path; @@ -59,6 +62,8 @@ import java.nio.file.StandardCopyOption; import java.text.MessageFormat; import java.text.ParseException; +import java.time.Instant; +import java.time.temporal.ChronoUnit; import java.util.ArrayList; import java.util.Collection; import java.util.Collections; @@ -73,12 +78,16 @@ import java.util.Objects; import java.util.Set; import java.util.TreeMap; +import java.util.concurrent.Callable; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; import java.util.regex.Pattern; import java.util.stream.Collectors; import java.util.stream.Stream; import org.eclipse.jgit.annotations.NonNull; import org.eclipse.jgit.dircache.DirCacheIterator; +import org.eclipse.jgit.errors.CancelledException; import org.eclipse.jgit.errors.CorruptObjectException; import org.eclipse.jgit.errors.IncorrectObjectTypeException; import org.eclipse.jgit.errors.MissingObjectException; @@ -93,6 +102,8 @@ import org.eclipse.jgit.lib.NullProgressMonitor; import org.eclipse.jgit.lib.ObjectId; import org.eclipse.jgit.lib.ObjectIdSet; +import org.eclipse.jgit.lib.ObjectLoader; +import org.eclipse.jgit.lib.ObjectReader; import org.eclipse.jgit.lib.ProgressMonitor; import org.eclipse.jgit.lib.Ref; import org.eclipse.jgit.lib.Ref.Storage; @@ -140,6 +151,8 @@ public class GC { private static final int DEFAULT_AUTOLIMIT = 6700; + private static ExecutorService executor = Executors.newFixedThreadPool(1); + private final FileRepository repo; private ProgressMonitor pm; @@ -175,6 +188,11 @@ public class GC { private boolean automatic; /** + * Whether to run gc in a background thread + */ + private boolean background; + + /** * Creates a new garbage collector with default values. An expirationTime of * two weeks and <code>null</code> as progress monitor will be used. * @@ -199,13 +217,59 @@ public GC(FileRepository repo) { * first check whether any housekeeping is required; if not, it exits * without performing any work. * + * If {@link #setBackground(boolean)} was set to {@code true} + * {@code collectGarbage} will start the gc in the background, and then + * return immediately. In this case, errors will not be reported except in + * gc.log. + * * @return the collection of {@link PackFile}'s which are newly created * @throws IOException * @throws ParseException * If the configuration parameter "gc.pruneexpire" couldn't be * parsed */ + // TODO(ms): in 5.0 change signature and return Future<Collection<PackFile>> public Collection<PackFile> gc() throws IOException, ParseException { + if (!background) { + return doGc(); + } + final GcLog gcLog = new GcLog(repo); + if (!gcLog.lock()) { + // there is already a background gc running + return Collections.emptyList(); + } + + Callable<Collection<PackFile>> gcTask = () -> { + try { + Collection<PackFile> newPacks = doGc(); + if (automatic && tooManyLooseObjects()) { + String message = JGitText.get().gcTooManyUnpruned; + gcLog.write(message); + gcLog.commit(); + } + return newPacks; + } catch (IOException | ParseException e) { + try { + gcLog.write(e.getMessage()); + StringWriter sw = new StringWriter(); + e.printStackTrace(new PrintWriter(sw)); + gcLog.write(sw.toString()); + gcLog.commit(); + } catch (IOException e2) { + e2.addSuppressed(e); + LOG.error(e2.getMessage(), e2); + } + } finally { + gcLog.unlock(); + } + return Collections.emptyList(); + }; + // TODO(ms): in 5.0 change signature and return the Future + executor.submit(gcTask); + return Collections.emptyList(); + } + + private Collection<PackFile> doGc() throws IOException, ParseException { if (automatic && !needGc()) { return Collections.emptyList(); } @@ -219,11 +283,41 @@ public Collection<PackFile> gc() throws IOException, ParseException { } /** + * Loosen objects in a pack file which are not also in the newly-created + * pack files. + * + * @param inserter + * @param reader + * @param pack + * @param existing + * @throws IOException + */ + private void loosen(ObjectDirectoryInserter inserter, ObjectReader reader, PackFile pack, HashSet<ObjectId> existing) + throws IOException { + for (PackIndex.MutableEntry entry : pack) { + ObjectId oid = entry.toObjectId(); + if (existing.contains(oid)) { + continue; + } + existing.add(oid); + ObjectLoader loader = reader.open(oid); + inserter.insert(loader.getType(), + loader.getSize(), + loader.openStream(), + true /* create this object even though it's a duplicate */); + } + } + + /** * Delete old pack files. What is 'old' is defined by specifying a set of * old pack files and a set of new pack files. Each pack file contained in - * old pack files but not contained in new pack files will be deleted. If an - * expirationDate is set then pack files which are younger than the - * expirationDate will not be deleted. + * old pack files but not contained in new pack files will be deleted. If + * preserveOldPacks is set, keep a copy of the pack file in the preserve + * directory. If an expirationDate is set then pack files which are younger + * than the expirationDate will not be deleted nor preserved. + * <p> + * If we're not immediately expiring loose objects, loosen any objects + * in the old pack files which aren't in the new pack files. * * @param oldPacks * @param newPacks @@ -232,8 +326,22 @@ public Collection<PackFile> gc() throws IOException, ParseException { */ private void deleteOldPacks(Collection<PackFile> oldPacks, Collection<PackFile> newPacks) throws ParseException, IOException { + HashSet<ObjectId> ids = new HashSet<>(); + for (PackFile pack : newPacks) { + for (PackIndex.MutableEntry entry : pack) { + ids.add(entry.toObjectId()); + } + } + ObjectReader reader = repo.newObjectReader(); + ObjectDirectory dir = repo.getObjectDatabase(); + ObjectDirectoryInserter inserter = dir.newInserter(); + boolean shouldLoosen = !"now".equals(getPruneExpireStr()) && //$NON-NLS-1$ + getExpireDate() < Long.MAX_VALUE; + + prunePreserved(); long packExpireDate = getPackExpireDate(); oldPackLoop: for (PackFile oldPack : oldPacks) { + checkCancelled(); String oldName = oldPack.getPackName(); // check whether an old pack file is also among the list of new // pack files. Then we must not delete it. @@ -245,15 +353,57 @@ private void deleteOldPacks(Collection<PackFile> oldPacks, && repo.getFS().lastModified( oldPack.getPackFile()) < packExpireDate) { oldPack.close(); + if (shouldLoosen) { + loosen(inserter, reader, oldPack, ids); + } prunePack(oldName); } } - // close the complete object database. Thats my only chance to force + + // close the complete object database. That's my only chance to force // rescanning and to detect that certain pack files are now deleted. repo.getObjectDatabase().close(); } /** + * Deletes old pack file, unless 'preserve-oldpacks' is set, in which case it + * moves the pack file to the preserved directory + * + * @param packFile + * @param packName + * @param ext + * @param deleteOptions + * @throws IOException + */ + private void removeOldPack(File packFile, String packName, PackExt ext, + int deleteOptions) throws IOException { + if (pconfig != null && pconfig.isPreserveOldPacks()) { + File oldPackDir = repo.getObjectDatabase().getPreservedDirectory(); + FileUtils.mkdir(oldPackDir, true); + + String oldPackName = "pack-" + packName + ".old-" + ext.getExtension(); //$NON-NLS-1$ //$NON-NLS-2$ + File oldPackFile = new File(oldPackDir, oldPackName); + FileUtils.rename(packFile, oldPackFile); + } else { + FileUtils.delete(packFile, deleteOptions); + } + } + + /** + * Delete the preserved directory including all pack files within + */ + private void prunePreserved() { + if (pconfig != null && pconfig.isPrunePreserved()) { + try { + FileUtils.delete(repo.getObjectDatabase().getPreservedDirectory(), + FileUtils.RECURSIVE | FileUtils.RETRY | FileUtils.SKIP_MISSING); + } catch (IOException e) { + // Deletion of the preserved pack files failed. Silently return. + } + } + } + + /** * Delete files associated with a single pack file. First try to delete the * ".pack" file because on some platforms the ".pack" file may be locked and * can't be deleted. In such a case it is better to detect this early and @@ -272,7 +422,7 @@ private void prunePack(String packName) { for (PackExt ext : extensions) if (PackExt.PACK.equals(ext)) { File f = nameFor(packName, "." + ext.getExtension()); //$NON-NLS-1$ - FileUtils.delete(f, deleteOptions); + removeOldPack(f, packName, ext, deleteOptions); break; } // The .pack file has been deleted. Delete as many as the other @@ -281,7 +431,7 @@ private void prunePack(String packName) { for (PackExt ext : extensions) { if (!PackExt.PACK.equals(ext)) { File f = nameFor(packName, "." + ext.getExtension()); //$NON-NLS-1$ - FileUtils.delete(f, deleteOptions); + removeOldPack(f, packName, ext, deleteOptions); } } } catch (IOException e) { @@ -306,6 +456,7 @@ public void prunePacked() throws IOException { pm.beginTask(JGitText.get().pruneLoosePackedObjects, fanout.length); try { for (String d : fanout) { + checkCancelled(); pm.update(1); if (d.length() != 2) continue; @@ -313,6 +464,7 @@ public void prunePacked() throws IOException { if (entries == null) continue; for (String e : entries) { + checkCancelled(); if (e.length() != Constants.OBJECT_ID_STRING_LENGTH - 2) continue; ObjectId id; @@ -324,11 +476,13 @@ public void prunePacked() throws IOException { continue; } boolean found = false; - for (PackFile p : packs) + for (PackFile p : packs) { + checkCancelled(); if (p.hasObject(id)) { found = true; break; } + } if (found) FileUtils.delete(objdb.fileFor(id), FileUtils.RETRY | FileUtils.SKIP_MISSING @@ -360,7 +514,7 @@ public void prune(Set<ObjectId> objectsToKeep) throws IOException, // Collect all loose objects which are old enough, not referenced from // the index and not in objectsToKeep - Map<ObjectId, File> deletionCandidates = new HashMap<ObjectId, File>(); + Map<ObjectId, File> deletionCandidates = new HashMap<>(); Set<ObjectId> indexObjects = null; File objects = repo.getObjectsDirectory(); String[] fanout = objects.list(); @@ -371,6 +525,7 @@ public void prune(Set<ObjectId> objectsToKeep) throws IOException, fanout.length); try { for (String d : fanout) { + checkCancelled(); pm.update(1); if (d.length() != 2) continue; @@ -378,6 +533,7 @@ public void prune(Set<ObjectId> objectsToKeep) throws IOException, if (entries == null) continue; for (File f : entries) { + checkCancelled(); String fName = f.getName(); if (fName.length() != Constants.OBJECT_ID_STRING_LENGTH - 2) continue; @@ -407,6 +563,8 @@ public void prune(Set<ObjectId> objectsToKeep) throws IOException, return; } + checkCancelled(); + // From the set of current refs remove all those which have been handled // during last repack(). Only those refs will survive which have been // added or modified since the last repack. Only these can save existing @@ -436,11 +594,14 @@ public void prune(Set<ObjectId> objectsToKeep) throws IOException, // leave this method. ObjectWalk w = new ObjectWalk(repo); try { - for (Ref cr : newRefs) + for (Ref cr : newRefs) { + checkCancelled(); w.markStart(w.parseAny(cr.getObjectId())); + } if (lastPackedRefs != null) - for (Ref lpr : lastPackedRefs) + for (Ref lpr : lastPackedRefs) { w.markUninteresting(w.parseAny(lpr.getObjectId())); + } removeReferenced(deletionCandidates, w); } finally { w.dispose(); @@ -458,11 +619,15 @@ public void prune(Set<ObjectId> objectsToKeep) throws IOException, ObjectWalk w = new ObjectWalk(repo); try { for (Ref ar : getAllRefs()) - for (ObjectId id : listRefLogObjects(ar, lastRepackTime)) + for (ObjectId id : listRefLogObjects(ar, lastRepackTime)) { + checkCancelled(); w.markStart(w.parseAny(id)); + } if (lastPackedRefs != null) - for (Ref lpr : lastPackedRefs) + for (Ref lpr : lastPackedRefs) { + checkCancelled(); w.markUninteresting(w.parseAny(lpr.getObjectId())); + } removeReferenced(deletionCandidates, w); } finally { w.dispose(); @@ -471,6 +636,8 @@ public void prune(Set<ObjectId> objectsToKeep) throws IOException, if (deletionCandidates.isEmpty()) return; + checkCancelled(); + // delete all candidates which have survived: these are unreferenced // loose objects. Make a last check, though, to avoid deleting objects // that could have been referenced while the candidates list was being @@ -495,9 +662,7 @@ private long getExpireDate() throws ParseException { long expireDate = Long.MAX_VALUE; if (expire == null && expireAgeMillis == -1) { - String pruneExpireStr = repo.getConfig().getString( - ConfigConstants.CONFIG_GC_SECTION, null, - ConfigConstants.CONFIG_KEY_PRUNEEXPIRE); + String pruneExpireStr = getPruneExpireStr(); if (pruneExpireStr == null) pruneExpireStr = PRUNE_EXPIRE_DEFAULT; expire = GitDateParser.parse(pruneExpireStr, null, SystemReader @@ -511,6 +676,12 @@ private long getExpireDate() throws ParseException { return expireDate; } + private String getPruneExpireStr() { + return repo.getConfig().getString( + ConfigConstants.CONFIG_GC_SECTION, null, + ConfigConstants.CONFIG_KEY_PRUNEEXPIRE); + } + private long getPackExpireDate() throws ParseException { long packExpireDate = Long.MAX_VALUE; @@ -546,6 +717,7 @@ private void removeReferenced(Map<ObjectId, File> id2File, IncorrectObjectTypeException, IOException { RevObject ro = w.next(); while (ro != null) { + checkCancelled(); if (id2File.remove(ro.getId()) != null) if (id2File.isEmpty()) return; @@ -553,6 +725,7 @@ private void removeReferenced(Map<ObjectId, File> id2File, } ro = w.nextObject(); while (ro != null) { + checkCancelled(); if (id2File.remove(ro.getId()) != null) if (id2File.isEmpty()) return; @@ -582,10 +755,11 @@ private static boolean equals(Ref r1, Ref r2) { */ public void packRefs() throws IOException { Collection<Ref> refs = repo.getRefDatabase().getRefs(Constants.R_REFS).values(); - List<String> refsToBePacked = new ArrayList<String>(refs.size()); + List<String> refsToBePacked = new ArrayList<>(refs.size()); pm.beginTask(JGitText.get().packRefs, refs.size()); try { for (Ref ref : refs) { + checkCancelled(); if (!ref.isSymbolic() && ref.getStorage().isLoose()) refsToBePacked.add(ref.getName()); pm.update(1); @@ -616,18 +790,19 @@ public Collection<PackFile> repack() throws IOException { long time = System.currentTimeMillis(); Collection<Ref> refsBefore = getAllRefs(); - Set<ObjectId> allHeads = new HashSet<ObjectId>(); - Set<ObjectId> nonHeads = new HashSet<ObjectId>(); - Set<ObjectId> txnHeads = new HashSet<ObjectId>(); - Set<ObjectId> tagTargets = new HashSet<ObjectId>(); + Set<ObjectId> allHeads = new HashSet<>(); + Set<ObjectId> nonHeads = new HashSet<>(); + Set<ObjectId> txnHeads = new HashSet<>(); + Set<ObjectId> tagTargets = new HashSet<>(); Set<ObjectId> indexObjects = listNonHEADIndexObjects(); RefDatabase refdb = repo.getRefDatabase(); for (Ref ref : refsBefore) { + checkCancelled(); nonHeads.addAll(listRefLogObjects(ref, 0)); if (ref.isSymbolic() || ref.getObjectId() == null) continue; - if (ref.getName().startsWith(Constants.R_HEADS)) + if (isHead(ref) || isTag(ref)) allHeads.add(ref.getObjectId()); else if (RefTreeNames.isRefTree(refdb, ref.getName())) txnHeads.add(ref.getObjectId()); @@ -637,15 +812,17 @@ else if (RefTreeNames.isRefTree(refdb, ref.getName())) tagTargets.add(ref.getPeeledObjectId()); } - List<ObjectIdSet> excluded = new LinkedList<ObjectIdSet>(); - for (final PackFile f : repo.getObjectDatabase().getPacks()) + List<ObjectIdSet> excluded = new LinkedList<>(); + for (final PackFile f : repo.getObjectDatabase().getPacks()) { + checkCancelled(); if (f.shouldBeKept()) excluded.add(f.getIndex()); + } tagTargets.addAll(allHeads); nonHeads.addAll(indexObjects); - List<PackFile> ret = new ArrayList<PackFile>(2); + List<PackFile> ret = new ArrayList<>(2); PackFile heads = null; if (!allHeads.isEmpty()) { heads = writePack(allHeads, Collections.<ObjectId> emptySet(), @@ -674,6 +851,7 @@ else if (RefTreeNames.isRefTree(refdb, ref.getName())) throw new IOException(e); } prunePacked(); + deleteEmptyRefsFolders(); deleteOrphans(); lastPackedRefs = refsBefore; @@ -681,6 +859,65 @@ else if (RefTreeNames.isRefTree(refdb, ref.getName())) return ret; } + private static boolean isHead(Ref ref) { + return ref.getName().startsWith(Constants.R_HEADS); + } + + private static boolean isTag(Ref ref) { + return ref.getName().startsWith(Constants.R_TAGS); + } + + private void deleteEmptyRefsFolders() throws IOException { + Path refs = repo.getDirectory().toPath().resolve(Constants.R_REFS); + // Avoid deleting a folder that was created after the threshold so that concurrent + // operations trying to create a reference are not impacted + Instant threshold = Instant.now().minus(30, ChronoUnit.SECONDS); + try (Stream<Path> entries = Files.list(refs)) { + Iterator<Path> iterator = entries.iterator(); + while (iterator.hasNext()) { + try (Stream<Path> s = Files.list(iterator.next())) { + s.filter(path -> canBeSafelyDeleted(path, threshold)).forEach(this::deleteDir); + } + } + } + } + + private boolean canBeSafelyDeleted(Path path, Instant threshold) { + try { + return Files.getLastModifiedTime(path).toInstant().isBefore(threshold); + } + catch (IOException e) { + LOG.warn(MessageFormat.format( + JGitText.get().cannotAccessLastModifiedForSafeDeletion, + path), e); + return false; + } + } + + private void deleteDir(Path dir) { + try (Stream<Path> dirs = Files.walk(dir)) { + dirs.filter(this::isDirectory).sorted(Comparator.reverseOrder()) + .forEach(this::delete); + } catch (IOException e) { + LOG.error(e.getMessage(), e); + } + } + + private boolean isDirectory(Path p) { + return p.toFile().isDirectory(); + } + + private void delete(Path d) { + try { + Files.delete(d); + } catch (DirectoryNotEmptyException e) { + // Don't log + } catch (IOException e) { + LOG.error(MessageFormat.format(JGitText.get().cannotDeleteFile, d), + e); + } + } + /** * Deletes orphans * <p> @@ -739,7 +976,7 @@ private Set<ObjectId> listRefLogObjects(Ref ref, long minTime) throws IOExceptio .getReverseEntries(); if (rlEntries == null || rlEntries.isEmpty()) return Collections.<ObjectId> emptySet(); - Set<ObjectId> ret = new HashSet<ObjectId>(); + Set<ObjectId> ret = new HashSet<>(); for (ReflogEntry e : rlEntries) { if (e.getWho().getWhen().getTime() < minTime) break; @@ -773,6 +1010,7 @@ private Collection<Ref> getAllRefs() throws IOException { all.addAll(refs); // add additional refs which start with refs/ for (Ref r : addl) { + checkCancelled(); if (r.getName().startsWith(Constants.R_REFS)) { all.add(r); } @@ -807,9 +1045,10 @@ private Set<ObjectId> listNonHEADIndexObjects() treeWalk.setFilter(TreeFilter.ANY_DIFF); treeWalk.setRecursive(true); - Set<ObjectId> ret = new HashSet<ObjectId>(); + Set<ObjectId> ret = new HashSet<>(); while (treeWalk.next()) { + checkCancelled(); ObjectId objectId = treeWalk.getObjectId(0); switch (treeWalk.getRawMode(0) & FileMode.TYPE_MASK) { case FileMode.TYPE_MISSING: @@ -837,9 +1076,11 @@ private Set<ObjectId> listNonHEADIndexObjects() private PackFile writePack(@NonNull Set<? extends ObjectId> want, @NonNull Set<? extends ObjectId> have, Set<ObjectId> tagTargets, List<ObjectIdSet> excludeObjects) throws IOException { + checkCancelled(); File tmpPack = null; - Map<PackExt, File> tmpExts = new TreeMap<PackExt, File>( + Map<PackExt, File> tmpExts = new TreeMap<>( new Comparator<PackExt>() { + @Override public int compare(PackExt o1, PackExt o2) { // INDEX entries must be returned last, so the pack // scanner does pick up the new pack until all the @@ -868,6 +1109,7 @@ public int compare(PackExt o1, PackExt o2) { pw.preparePack(pm, want, have); if (pw.getObjectCount() == 0) return null; + checkCancelled(); // create temporary files String id = pw.computeName().getName(); @@ -984,6 +1226,12 @@ private File nameFor(String name, String ext) { return new File(packdir, "pack-" + name + ext); //$NON-NLS-1$ } + private void checkCancelled() throws CancelledException { + if (pm.isCancelled()) { + throw new CancelledException(JGitText.get().operationCanceled); + } + } + /** * A class holding statistical data for a FileRepository regarding how many * objects are stored as loose or packed objects @@ -1031,6 +1279,7 @@ public static class RepoStatistics { */ public long numberOfBitmaps; + @Override public String toString() { final StringBuilder b = new StringBuilder(); b.append("numberOfPackedObjects=").append(numberOfPackedObjects); //$NON-NLS-1$ @@ -1135,7 +1384,6 @@ public void setPackExpireAgeMillis(long packExpireAgeMillis) { * influence how packs are written and to implement something similar to * "git gc --aggressive" * - * @since 3.6 * @param pconfig * the {@link PackConfig} used when writing packs */ @@ -1208,12 +1456,19 @@ public void setPackExpire(Date packExpire) { * * @param auto * defines whether gc should do automatic housekeeping - * @since 4.5 */ public void setAuto(boolean auto) { this.automatic = auto; } + /** + * @param background + * whether to run the gc in a background thread. + */ + void setBackground(boolean background) { + this.background = background; + } + private boolean needGc() { if (tooManyPacks()) { addRepackAllOption(); @@ -1252,8 +1507,7 @@ boolean tooManyPacks() { * @return {@code true} if number of loose objects > gc.auto (default 6700) */ boolean tooManyLooseObjects() { - int auto = repo.getConfig().getInt(ConfigConstants.CONFIG_GC_SECTION, - ConfigConstants.CONFIG_KEY_AUTO, DEFAULT_AUTOLIMIT); + int auto = getLooseObjectLimit(); if (auto <= 0) { return false; } @@ -1266,10 +1520,12 @@ boolean tooManyLooseObjects() { try (DirectoryStream<Path> stream = Files.newDirectoryStream(dir, new DirectoryStream.Filter<Path>() { + @Override public boolean accept(Path file) throws IOException { - return Files.isRegularFile(file) && PATTERN_LOOSE_OBJECT - .matcher(file.getFileName().toString()) - .matches(); + Path fileName = file.getFileName(); + return Files.isRegularFile(file) && fileName != null + && PATTERN_LOOSE_OBJECT + .matcher(fileName.toString()).matches(); } })) { for (Iterator<Path> iter = stream.iterator(); iter.hasNext(); @@ -1283,4 +1539,9 @@ public boolean accept(Path file) throws IOException { } return false; } + + private int getLooseObjectLimit() { + return repo.getConfig().getInt(ConfigConstants.CONFIG_GC_SECTION, + ConfigConstants.CONFIG_KEY_AUTO, DEFAULT_AUTOLIMIT); + } }
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 new file mode 100644 index 0000000..35049d4 --- /dev/null +++ b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/GcLog.java
@@ -0,0 +1,175 @@ +/* + * Copyright (C) 2017 Two Sigma Open Source + * 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 org.eclipse.jgit.api.errors.JGitInternalException; +import org.eclipse.jgit.lib.ConfigConstants; +import org.eclipse.jgit.util.GitDateParser; +import org.eclipse.jgit.util.SystemReader; + +import static java.nio.charset.StandardCharsets.UTF_8; + +import java.io.File; +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.NoSuchFileException; +import java.nio.file.attribute.FileTime; +import java.text.ParseException; +import java.time.Instant; + +/** + * This class manages the gc.log file for a {@link FileRepository}. + */ +class GcLog { + private final FileRepository repo; + + private final File logFile; + + private final LockFile lock; + + private Instant gcLogExpire; + + private static final String LOG_EXPIRY_DEFAULT = "1.day.ago"; //$NON-NLS-1$ + + private boolean nonEmpty = false; + + /** + * Construct a GcLog object for a {@link FileRepository} + * + * @param repo + * the repository + */ + GcLog(FileRepository repo) { + this.repo = repo; + logFile = new File(repo.getDirectory(), "gc.log"); //$NON-NLS-1$ + lock = new LockFile(logFile); + } + + private Instant getLogExpiry() throws ParseException { + if (gcLogExpire == null) { + String logExpiryStr = repo.getConfig().getString( + ConfigConstants.CONFIG_GC_SECTION, null, + ConfigConstants.CONFIG_KEY_LOGEXPIRY); + if (logExpiryStr == null) { + logExpiryStr = LOG_EXPIRY_DEFAULT; + } + gcLogExpire = GitDateParser.parse(logExpiryStr, null, + SystemReader.getInstance().getLocale()).toInstant(); + } + return gcLogExpire; + } + + private boolean autoGcBlockedByOldLockFile() { + try { + FileTime lastModified = Files.getLastModifiedTime(logFile.toPath()); + if (lastModified.toInstant().compareTo(getLogExpiry()) > 0) { + // There is an existing log file, which is too recent to ignore + return true; + } + } catch (NoSuchFileException e) { + // No existing log file, OK. + } catch (IOException | ParseException e) { + throw new JGitInternalException(e.getMessage(), e); + } + return false; + } + + /** + * Lock the GC log file for updates + * + * @return {@code true} if we hold the lock + */ + boolean lock() { + try { + if (!lock.lock()) { + return false; + } + } catch (IOException e) { + throw new JGitInternalException(e.getMessage(), e); + } + if (autoGcBlockedByOldLockFile()) { + lock.unlock(); + return false; + } + return true; + } + + /** + * Unlock (roll back) the GC log lock + */ + void unlock() { + lock.unlock(); + } + + /** + * Commit changes to the gc log, if there have been any writes. Otherwise, + * just unlock and delete the existing file (if any) + * + * @return true if committing (or unlocking/deleting) succeeds. + */ + boolean commit() { + if (nonEmpty) { + return lock.commit(); + } else { + logFile.delete(); + lock.unlock(); + return true; + } + } + + /** + * Write to the pending gc log. Content will be committed upon a call to + * commit() + * + * @param content + * The content to write + * @throws IOException + */ + void write(String content) throws IOException { + if (content.length() > 0) { + nonEmpty = true; + } + lock.write(content.getBytes(UTF_8)); + } +}
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 51af67e..15c5280 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
@@ -44,6 +44,8 @@ package org.eclipse.jgit.internal.storage.file; +import static org.eclipse.jgit.lib.Constants.LOCK_SUFFIX; + import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; @@ -62,7 +64,10 @@ import org.eclipse.jgit.lib.Constants; import org.eclipse.jgit.lib.ObjectId; import org.eclipse.jgit.util.FS; +import org.eclipse.jgit.util.FS.LockToken; import org.eclipse.jgit.util.FileUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; /** * Git style file locking and replacement. @@ -75,7 +80,7 @@ * name. */ public class LockFile { - static final String SUFFIX = ".lock"; //$NON-NLS-1$ + private final static Logger LOG = LoggerFactory.getLogger(LockFile.class); /** * Unlock the given file. @@ -105,13 +110,15 @@ public static boolean unlock(final File file) { * @return lock file */ static File getLockFile(File file) { - return new File(file.getParentFile(), file.getName() + SUFFIX); + return new File(file.getParentFile(), + file.getName() + LOCK_SUFFIX); } /** Filter to skip over active lock files when listing a directory. */ static final FilenameFilter FILTER = new FilenameFilter() { + @Override public boolean accept(File dir, String name) { - return !name.endsWith(SUFFIX); + return !name.endsWith(LOCK_SUFFIX); } }; @@ -129,6 +136,8 @@ public boolean accept(File dir, String name) { private FileSnapshot commitSnapshot; + private LockToken token; + /** * Create a new lock for any file. * @@ -150,7 +159,6 @@ public LockFile(final File f, final FS fs) { * * @param f * the file that will be locked. - * @since 4.2 */ public LockFile(final File f) { ref = f; @@ -168,7 +176,8 @@ public LockFile(final File f) { */ public boolean lock() throws IOException { FileUtils.mkdirs(lck.getParentFile(), true); - if (FS.DETECTED.createNewFile(lck)) { + token = FS.DETECTED.createNewFileAtomic(lck); + if (token.isCreated()) { haveLck = true; try { os = new FileOutputStream(lck); @@ -176,6 +185,8 @@ public boolean lock() throws IOException { unlock(); throw ioe; } + } else { + closeToken(); } return haveLck; } @@ -456,6 +467,7 @@ public boolean commit() { try { FileUtils.rename(lck, ref, StandardCopyOption.ATOMIC_MOVE); haveLck = false; + closeToken(); return true; } catch (IOException e) { unlock(); @@ -463,6 +475,13 @@ public boolean commit() { } } + private void closeToken() { + if (token != null) { + token.close(); + token = null; + } + } + private void saveStatInformation() { if (needSnapshot) commitSnapshot = FileSnapshot.save(lck); @@ -501,8 +520,9 @@ public void unlock() { if (os != null) { try { os.close(); - } catch (IOException ioe) { - // Ignore this + } catch (IOException e) { + LOG.error(MessageFormat + .format(JGitText.get().unlockLockFileFailed, lck), e); } os = null; } @@ -512,7 +532,10 @@ public void unlock() { try { FileUtils.delete(lck, FileUtils.RETRY); } catch (IOException e) { - // couldn't delete the file even after retry. + LOG.error(MessageFormat + .format(JGitText.get().unlockLockFileFailed, lck), e); + } finally { + closeToken(); } } }
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 6489415..00e3953 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
@@ -125,6 +125,8 @@ public class ObjectDirectory extends FileObjectDatabase { private final File packDirectory; + private final File preservedDirectory; + private final File alternatesFile; private final AtomicReference<PackList> packList; @@ -165,13 +167,14 @@ public ObjectDirectory(final Config cfg, final File dir, objects = dir; infoDirectory = new File(objects, "info"); //$NON-NLS-1$ packDirectory = new File(objects, "pack"); //$NON-NLS-1$ + preservedDirectory = new File(packDirectory, "preserved"); //$NON-NLS-1$ alternatesFile = new File(infoDirectory, "alternates"); //$NON-NLS-1$ - packList = new AtomicReference<PackList>(NO_PACKS); + packList = new AtomicReference<>(NO_PACKS); unpackedObjectCache = new UnpackedObjectCache(); this.fs = fs; this.shallowFile = shallowFile; - alternates = new AtomicReference<AlternateHandle[]>(); + alternates = new AtomicReference<>(); if (alternatePaths != null) { AlternateHandle[] alt; @@ -185,10 +188,18 @@ public ObjectDirectory(final Config cfg, final File dir, /** * @return the location of the <code>objects</code> directory. */ + @Override public final File getDirectory() { return objects; } + /** + * @return the location of the <code>preserved</code> directory. + */ + public final File getPreservedDirectory() { + return preservedDirectory; + } + @Override public boolean exists() { return fs.exists(objects); @@ -250,6 +261,7 @@ public Collection<PackFile> getPacks() { * index file could not be opened, read, or is not recognized as * a Git pack file index. */ + @Override public PackFile openPack(final File pack) throws IOException { final String p = pack.getName(); @@ -436,6 +448,7 @@ ObjectLoader openPackedObject(WindowCursor curs, AnyObjectId objectId) { return null; } + @Override ObjectLoader openLooseObject(WindowCursor curs, AnyObjectId id) throws IOException { File path = fileFor(id); @@ -451,6 +464,7 @@ ObjectLoader openLooseObject(WindowCursor curs, AnyObjectId id) } } + @Override long getObjectSize(WindowCursor curs, AnyObjectId id) throws IOException { if (unpackedObjectCache.isUnpacked(id)) { @@ -574,7 +588,7 @@ private void handlePackError(IOException e, PackFile p) { warnTmpl = JGitText.get().packWasDeleted; removePack(p); } - } else if (FileUtils.isStaleFileHandle(e)) { + } else if (FileUtils.isStaleFileHandleInCausalChain(e)) { warnTmpl = JGitText.get().packHandleIsStale; removePack(p); } else { @@ -689,6 +703,7 @@ private boolean searchPacksAgain(PackList old) { && old != scanPacks(old); } + @Override Config getConfig() { return config; } @@ -705,13 +720,19 @@ Set<ObjectId> getShallowCommits() throws IOException { if (shallowFileSnapshot == null || shallowFileSnapshot.isModified(shallowFile)) { - shallowCommitsIds = new HashSet<ObjectId>(); + shallowCommitsIds = new HashSet<>(); final BufferedReader reader = open(shallowFile); try { String line; - while ((line = reader.readLine()) != null) - shallowCommitsIds.add(ObjectId.fromString(line)); + while ((line = reader.readLine()) != null) { + try { + shallowCommitsIds.add(ObjectId.fromString(line)); + } catch (IllegalArgumentException ex) { + throw new IOException(MessageFormat + .format(JGitText.get().badShallowLine, line)); + } + } } finally { reader.close(); } @@ -796,7 +817,7 @@ private PackList scanPacksImpl(final PackList old) { final Map<String, PackFile> forReuse = reuseMap(old); final FileSnapshot snapshot = FileSnapshot.save(packDirectory); final Set<String> names = listPackDirectory(); - final List<PackFile> list = new ArrayList<PackFile>(names.size() >> 2); + final List<PackFile> list = new ArrayList<>(names.size() >> 2); boolean foundNew = false; for (final String indexName : names) { // Must match "pack-[0-9a-f]{40}.idx" to be an index. @@ -854,7 +875,7 @@ private PackList scanPacksImpl(final PackList old) { } private static Map<String, PackFile> reuseMap(final PackList old) { - final Map<String, PackFile> forReuse = new HashMap<String, PackFile>(); + final Map<String, PackFile> forReuse = new HashMap<>(); for (final PackFile p : old.packs) { if (p.invalid()) { // The pack instance is corrupted, and cannot be safely used @@ -883,7 +904,7 @@ private Set<String> listPackDirectory() { final String[] nameList = packDirectory.list(); if (nameList == null) return Collections.emptySet(); - final Set<String> nameSet = new HashSet<String>(nameList.length << 1); + final Set<String> nameSet = new HashSet<>(nameList.length << 1); for (final String name : nameList) { if (name.startsWith("pack-")) //$NON-NLS-1$ nameSet.add(name); @@ -910,7 +931,7 @@ private Set<String> listPackDirectory() { } private AlternateHandle[] loadAlternates() throws IOException { - final List<AlternateHandle> l = new ArrayList<AlternateHandle>(4); + final List<AlternateHandle> l = new ArrayList<>(4); final BufferedReader br = open(alternatesFile); try { String line; @@ -953,6 +974,7 @@ private AlternateHandle openAlternate(File objdir) throws IOException { * identity of the loose object to map to the directory. * @return location of the object, if it were to exist as a loose object. */ + @Override public File fileFor(AnyObjectId objectId) { String n = objectId.name(); String d = n.substring(0, 2); @@ -993,6 +1015,7 @@ static class AlternateRepository extends AlternateHandle { repository = r; } + @Override void close() { repository.close(); }
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 9820e0e..aa435bf 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
@@ -49,12 +49,11 @@ import java.io.File; import java.io.FileNotFoundException; import java.io.FileOutputStream; +import java.io.FilterOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.nio.channels.Channels; -import java.security.DigestOutputStream; -import java.security.MessageDigest; import java.text.MessageFormat; import java.util.zip.Deflater; import java.util.zip.DeflaterOutputStream; @@ -69,6 +68,7 @@ import org.eclipse.jgit.transport.PackParser; import org.eclipse.jgit.util.FileUtils; import org.eclipse.jgit.util.IO; +import org.eclipse.jgit.util.sha1.SHA1; /** Creates loose objects in a {@link ObjectDirectory}. */ class ObjectDirectoryInserter extends ObjectInserter { @@ -86,34 +86,71 @@ class ObjectDirectoryInserter extends ObjectInserter { @Override public ObjectId insert(int type, byte[] data, int off, int len) throws IOException { + return insert(type, data, off, len, false); + } + + /** + * Insert a loose object into the database. If createDuplicate is true, + * write the loose object even if we already have it in the loose or packed + * ODB. + * + * @param type + * @param data + * @param off + * @param len + * @param createDuplicate + * @return ObjectId + * @throws IOException + */ + private ObjectId insert( + int type, byte[] data, int off, int len, boolean createDuplicate) + throws IOException { ObjectId id = idFor(type, data, off, len); - if (db.has(id)) { + if (!createDuplicate && db.has(id)) { return id; } else { File tmp = toTemp(type, data, off, len); - return insertOneObject(tmp, id); + return insertOneObject(tmp, id, createDuplicate); } } @Override public ObjectId insert(final int type, long len, final InputStream is) throws IOException { + return insert(type, len, is, false); + } + + /** + * Insert a loose object into the database. If createDuplicate is true, + * write the loose object even if we already have it in the loose or packed + * ODB. + * + * @param type + * @param len + * @param is + * @param createDuplicate + * @return ObjectId + * @throws IOException + */ + ObjectId insert(int type, long len, InputStream is, boolean createDuplicate) + throws IOException { if (len <= buffer().length) { byte[] buf = buffer(); int actLen = IO.readFully(is, buf, 0); - return insert(type, buf, 0, actLen); + return insert(type, buf, 0, actLen, createDuplicate); } else { - MessageDigest md = digest(); + SHA1 md = digest(); File tmp = toTemp(md, type, len, is); - ObjectId id = ObjectId.fromRaw(md.digest()); - return insertOneObject(tmp, id); + ObjectId id = md.toObjectId(); + return insertOneObject(tmp, id, createDuplicate); } } - private ObjectId insertOneObject(final File tmp, final ObjectId id) + private ObjectId insertOneObject( + File tmp, ObjectId id, boolean createDuplicate) throws IOException, ObjectWritingException { - switch (db.insertUnpackedObject(tmp, id, false /* no duplicate */)) { + switch (db.insertUnpackedObject(tmp, id, createDuplicate)) { case INSERTED: case EXISTS_PACKED: case EXISTS_LOOSE: @@ -156,7 +193,7 @@ public void close() { } @SuppressWarnings("resource" /* java 7 */) - private File toTemp(final MessageDigest md, final int type, long len, + private File toTemp(final SHA1 md, final int type, long len, final InputStream is) throws IOException, FileNotFoundException, Error { boolean delete = true; @@ -168,7 +205,7 @@ private File toTemp(final MessageDigest md, final int type, long len, if (config.getFSyncObjectFiles()) out = Channels.newOutputStream(fOut.getChannel()); DeflaterOutputStream cOut = compress(out); - DigestOutputStream dOut = new DigestOutputStream(cOut, md); + SHA1OutputStream dOut = new SHA1OutputStream(cOut, md); writeHeader(dOut, type, len); final byte[] buf = buffer(); @@ -248,4 +285,25 @@ private static EOFException shortInput(long missing) { return new EOFException(MessageFormat.format( JGitText.get().inputDidntMatchLength, Long.valueOf(missing))); } + + private static class SHA1OutputStream extends FilterOutputStream { + private final SHA1 md; + + SHA1OutputStream(OutputStream out, SHA1 md) { + super(out); + this.md = md; + } + + @Override + public void write(int b) throws IOException { + md.update((byte) b); + out.write(b); + } + + @Override + public void write(byte[] in, int p, int n) throws IOException { + md.update(in, p, n); + out.write(in, p, n); + } + } }
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/PackBitmapIndexBuilder.java b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/PackBitmapIndexBuilder.java index 956e8de..bfd60fc 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/PackBitmapIndexBuilder.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/PackBitmapIndexBuilder.java
@@ -75,9 +75,9 @@ public class PackBitmapIndexBuilder extends BasePackBitmapIndex { private final EWAHCompressedBitmap tags; private final BlockList<PositionEntry> byOffset; final BlockList<StoredBitmap> - byAddOrder = new BlockList<StoredBitmap>(); + byAddOrder = new BlockList<>(); final ObjectIdOwnerMap<PositionEntry> - positionEntries = new ObjectIdOwnerMap<PositionEntry>(); + positionEntries = new ObjectIdOwnerMap<>(); /** * Creates a PackBitmapIndex used for building the contents of an index @@ -133,6 +133,7 @@ private static void sortByOffsetAndIndex(BlockList<PositionEntry> byOffset, positionEntries.add(new PositionEntry(entries.get(i), i)); } Collections.sort(entries, new Comparator<ObjectToPack>() { + @Override public int compare(ObjectToPack a, ObjectToPack b) { return Long.signum(a.getOffset() - b.getOffset()); } @@ -274,14 +275,17 @@ public Iterable<StoredEntry> getCompressedBitmaps() { // Add order is from oldest to newest. The reverse add order is the // output order. return new Iterable<StoredEntry>() { + @Override public Iterator<StoredEntry> iterator() { return new Iterator<StoredEntry>() { private int index = byAddOrder.size() - 1; + @Override public boolean hasNext() { return index >= 0; } + @Override public StoredEntry next() { if (!hasNext()) throw new NoSuchElementException(); @@ -315,6 +319,7 @@ public StoredEntry next() { bestXorOffset, item.getFlags()); } + @Override public void remove() { throw new UnsupportedOperationException(); }
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/PackBitmapIndexRemapper.java b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/PackBitmapIndexRemapper.java index 2c462a7..9a8c275 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/PackBitmapIndexRemapper.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/PackBitmapIndexRemapper.java
@@ -107,7 +107,7 @@ private PackBitmapIndexRemapper( BasePackBitmapIndex oldPackIndex, PackBitmapIndex newPackIndex) { this.oldPackIndex = oldPackIndex; this.newPackIndex = newPackIndex; - convertedBitmaps = new ObjectIdOwnerMap<StoredBitmap>(); + convertedBitmaps = new ObjectIdOwnerMap<>(); inflated = new BitSet(newPackIndex.getObjectCount()); prevToNewMapping = new int[oldPackIndex.getObjectCount()]; @@ -137,6 +137,7 @@ public EWAHCompressedBitmap ofObjectType( return newPackIndex.ofObjectType(bitmap, type); } + @Override public Iterator<Entry> iterator() { if (oldPackIndex == null) return Collections.<Entry> emptyList().iterator(); @@ -145,6 +146,7 @@ public Iterator<Entry> iterator() { return new Iterator<Entry>() { private Entry entry; + @Override public boolean hasNext() { while (entry == null && it.hasNext()) { StoredBitmap sb = it.next(); @@ -154,6 +156,7 @@ public boolean hasNext() { return entry != null; } + @Override public Entry next() { if (!hasNext()) throw new NoSuchElementException(); @@ -163,6 +166,7 @@ public Entry next() { return res; } + @Override public void remove() { throw new UnsupportedOperationException(); }
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 b5889f2..0611d3e 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
@@ -47,6 +47,7 @@ import static org.eclipse.jgit.internal.storage.pack.PackExt.BITMAP_INDEX; import static org.eclipse.jgit.internal.storage.pack.PackExt.INDEX; +import static org.eclipse.jgit.internal.storage.pack.PackExt.KEEP; import java.io.EOFException; import java.io.File; @@ -101,6 +102,7 @@ public class PackFile implements Iterable<PackIndex.MutableEntry> { /** Sorts PackFiles to be most recently created to least recently created. */ public static final Comparator<PackFile> SORT = new Comparator<PackFile>() { + @Override public int compare(final PackFile a, final PackFile b) { return b.packLastModified - a.packLastModified; } @@ -251,7 +253,7 @@ public boolean hasObject(final AnyObjectId id) throws IOException { */ public boolean shouldBeKept() { if (keepFile == null) - keepFile = new File(packFile.getPath() + ".keep"); //$NON-NLS-1$ + keepFile = extFile(KEEP); return keepFile.exists(); } @@ -301,6 +303,7 @@ public void close() { * * @see PackIndex#iterator() */ + @Override public Iterator<PackIndex.MutableEntry> iterator() { try { return idx().iterator();
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/PackIndex.java b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/PackIndex.java index 5d4a30f..2252778 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/PackIndex.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/PackIndex.java
@@ -183,6 +183,7 @@ public boolean contains(AnyObjectId id) { * * @return iterator over pack index entries */ + @Override public abstract Iterator<MutableEntry> iterator(); /** @@ -365,6 +366,7 @@ abstract class EntriesIterator implements Iterator<MutableEntry> { protected abstract MutableEntry initEntry(); + @Override public boolean hasNext() { return returnedNumber < getObjectCount(); } @@ -373,8 +375,10 @@ public boolean hasNext() { * Implementation must update {@link #returnedNumber} before returning * element. */ + @Override public abstract MutableEntry next(); + @Override public void remove() { throw new UnsupportedOperationException(); }
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/PackIndexV1.java b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/PackIndexV1.java index e5a729d..8a08456 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/PackIndexV1.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/PackIndexV1.java
@@ -240,6 +240,7 @@ private class IndexV1Iterator extends EntriesIterator { @Override protected MutableEntry initEntry() { return new MutableEntry() { + @Override protected void ensureId() { idBuffer.fromRaw(idxdata[levelOne], levelTwo - Constants.OBJECT_ID_LENGTH); @@ -247,6 +248,7 @@ protected void ensureId() { }; } + @Override public MutableEntry next() { for (; levelOne < idxdata.length; levelOne++) { if (idxdata[levelOne] == null)
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/PackIndexV2.java b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/PackIndexV2.java index d87336f..5c2986a 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/PackIndexV2.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/PackIndexV2.java
@@ -311,6 +311,7 @@ private class EntriesIteratorV2 extends EntriesIterator { @Override protected MutableEntry initEntry() { return new MutableEntry() { + @Override protected void ensureId() { idBuffer.fromRaw(names[levelOne], levelTwo - Constants.OBJECT_ID_LENGTH / 4); @@ -318,6 +319,7 @@ protected void ensureId() { }; } + @Override public MutableEntry next() { for (; levelOne < names.length; levelOne++) { if (levelTwo < names[levelOne].length) {
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 a5d380d..8338b2c 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
@@ -63,6 +63,8 @@ import java.io.FileNotFoundException; import java.io.IOException; import java.io.InputStreamReader; +import java.nio.file.DirectoryNotEmptyException; +import java.nio.file.Files; import java.security.DigestInputStream; import java.security.MessageDigest; import java.text.MessageFormat; @@ -154,10 +156,10 @@ public class RefDirectory extends RefDatabase { * converted into resolved references during a get operation, ensuring the * live value is always returned. */ - private final AtomicReference<RefList<LooseRef>> looseRefs = new AtomicReference<RefList<LooseRef>>(); + private final AtomicReference<RefList<LooseRef>> looseRefs = new AtomicReference<>(); /** Immutable sorted list of packed references. */ - final AtomicReference<PackedRefList> packedRefs = new AtomicReference<PackedRefList>(); + final AtomicReference<PackedRefList> packedRefs = new AtomicReference<>(); /** * Number of modifications made to this database. @@ -195,6 +197,7 @@ ReflogWriter getLogWriter() { return logWriter; } + @Override public void create() throws IOException { FileUtils.mkdir(refsDir); FileUtils.mkdir(new File(refsDir, R_HEADS.substring(R_REFS.length()))); @@ -352,7 +355,7 @@ public Map<String, Ref> getRefs(String prefix) throws IOException { @Override public List<Ref> getAdditionalRefs() throws IOException { - List<Ref> ret = new LinkedList<Ref>(); + List<Ref> ret = new LinkedList<>(); for (String name : additionalRefsNames) { Ref r = getRef(name); if (r != null) @@ -371,7 +374,7 @@ private class LooseScanner { private int curIdx; - final RefList.Builder<Ref> symbolic = new RefList.Builder<Ref>(4); + final RefList.Builder<Ref> symbolic = new RefList.Builder<>(4); RefList.Builder<LooseRef> newLoose; @@ -535,6 +538,7 @@ void storedSymbolicRef(RefDirectoryUpdate u, FileSnapshot snapshot, fireRefsChanged(); } + @Override public RefDirectoryUpdate newUpdate(String name, boolean detach) throws IOException { boolean detachingSymbolicRef = false; @@ -805,7 +809,8 @@ private PackedRefList readPackedRefs() throws IOException { return new PackedRefList(parsePackedRefs(br), snapshot, ObjectId.fromRaw(digest.digest())); } catch (IOException e) { - if (FileUtils.isStaleFileHandle(e) && retries < maxStaleRetries) { + if (FileUtils.isStaleFileHandleInCausalChain(e) + && retries < maxStaleRetries) { if (LOG.isDebugEnabled()) { LOG.debug(MessageFormat.format( JGitText.get().packedRefsHandleIsStale, @@ -823,7 +828,7 @@ private PackedRefList readPackedRefs() throws IOException { private RefList<Ref> parsePackedRefs(final BufferedReader br) throws IOException { - RefList.Builder<Ref> all = new RefList.Builder<Ref>(); + RefList.Builder<Ref> all = new RefList.Builder<>(); Ref last = null; boolean peeled = false; boolean needSort = false; @@ -1087,8 +1092,16 @@ private static void delete(final File file, final int depth, LockFile rLck) } File dir = file.getParentFile(); for (int i = 0; i < depth; ++i) { - if (!dir.delete()) { - break; // ignore problem here + try { + Files.deleteIfExists(dir.toPath()); + } catch (DirectoryNotEmptyException e) { + // Don't log; normal case when there are other refs with the + // same prefix + break; + } catch (IOException e) { + LOG.warn(MessageFormat.format(JGitText.get().unableToRemovePath, + dir), e); + break; } dir = dir.getParentFile(); } @@ -1132,10 +1145,12 @@ private final static class LoosePeeledTag extends ObjectIdRef.PeeledTag this.snapShot = snapshot; } + @Override public FileSnapshot getSnapShot() { return snapShot; } + @Override public LooseRef peel(ObjectIdRef newLeaf) { return this; } @@ -1151,10 +1166,12 @@ private final static class LooseNonTag extends ObjectIdRef.PeeledNonTag this.snapShot = snapshot; } + @Override public FileSnapshot getSnapShot() { return snapShot; } + @Override public LooseRef peel(ObjectIdRef newLeaf) { return this; } @@ -1170,6 +1187,7 @@ private final static class LooseUnpeeled extends ObjectIdRef.Unpeeled this.snapShot = snapShot; } + @Override public FileSnapshot getSnapShot() { return snapShot; } @@ -1182,6 +1200,7 @@ public ObjectId getObjectId() { return id; } + @Override public LooseRef peel(ObjectIdRef newLeaf) { ObjectId peeledObjectId = newLeaf.getPeeledObjectId(); ObjectId objectId = getObjectId(); @@ -1205,10 +1224,12 @@ private final static class LooseSymbolicRef extends SymbolicRef implements this.snapShot = snapshot; } + @Override public FileSnapshot getSnapShot() { return snapShot; } + @Override public LooseRef peel(ObjectIdRef newLeaf) { // We should never try to peel the symbolic references. throw new UnsupportedOperationException();
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 60f04b8..16b2a46 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
@@ -93,6 +93,7 @@ public class ReflogEntryImpl implements Serializable, ReflogEntry { /* (non-Javadoc) * @see org.eclipse.jgit.internal.storage.file.ReflogEntry#getOldId() */ + @Override public ObjectId getOldId() { return oldId; } @@ -100,6 +101,7 @@ public ObjectId getOldId() { /* (non-Javadoc) * @see org.eclipse.jgit.internal.storage.file.ReflogEntry#getNewId() */ + @Override public ObjectId getNewId() { return newId; } @@ -107,6 +109,7 @@ public ObjectId getNewId() { /* (non-Javadoc) * @see org.eclipse.jgit.internal.storage.file.ReflogEntry#getWho() */ + @Override public PersonIdent getWho() { return who; } @@ -114,6 +117,7 @@ public PersonIdent getWho() { /* (non-Javadoc) * @see org.eclipse.jgit.internal.storage.file.ReflogEntry#getComment() */ + @Override public String getComment() { return comment; } @@ -128,6 +132,7 @@ public String toString() { /* (non-Javadoc) * @see org.eclipse.jgit.internal.storage.file.ReflogEntry#parseCheckout() */ + @Override public CheckoutEntry parseCheckout() { if (getComment().startsWith(CheckoutEntryImpl.CHECKOUT_MOVING_FROM)) return new CheckoutEntryImpl(this);
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/ReflogReaderImpl.java b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/ReflogReaderImpl.java index 2f583b2..c3702fe 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/ReflogReaderImpl.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/ReflogReaderImpl.java
@@ -74,6 +74,7 @@ class ReflogReaderImpl implements ReflogReader { /* (non-Javadoc) * @see org.eclipse.jgit.internal.storage.file.ReflogReaader#getLastEntry() */ + @Override public ReflogEntry getLastEntry() throws IOException { return getReverseEntry(0); } @@ -81,6 +82,7 @@ public ReflogEntry getLastEntry() throws IOException { /* (non-Javadoc) * @see org.eclipse.jgit.internal.storage.file.ReflogReaader#getReverseEntries() */ + @Override public List<ReflogEntry> getReverseEntries() throws IOException { return getReverseEntries(Integer.MAX_VALUE); } @@ -88,6 +90,7 @@ public List<ReflogEntry> getReverseEntries() throws IOException { /* (non-Javadoc) * @see org.eclipse.jgit.internal.storage.file.ReflogReaader#getReverseEntry(int) */ + @Override public ReflogEntry getReverseEntry(int number) throws IOException { if (number < 0) throw new IllegalArgumentException(); @@ -116,6 +119,7 @@ public ReflogEntry getReverseEntry(int number) throws IOException { /* (non-Javadoc) * @see org.eclipse.jgit.internal.storage.file.ReflogReaader#getReverseEntries(int) */ + @Override public List<ReflogEntry> getReverseEntries(int max) throws IOException { final byte[] log; try { @@ -128,7 +132,7 @@ public List<ReflogEntry> getReverseEntries(int max) throws IOException { } int rs = RawParseUtils.prevLF(log, log.length); - List<ReflogEntry> ret = new ArrayList<ReflogEntry>(); + List<ReflogEntry> ret = new ArrayList<>(); while (rs >= 0 && max-- > 0) { rs = RawParseUtils.prevLF(log, rs); ReflogEntry entry = new ReflogEntryImpl(log, rs < 0 ? 0 : rs + 2);
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 fc80266..892c1c8 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
@@ -47,6 +47,7 @@ import static org.eclipse.jgit.lib.Constants.HEAD; import static org.eclipse.jgit.lib.Constants.LOGS; +import static org.eclipse.jgit.lib.Constants.LOCK_SUFFIX; import static org.eclipse.jgit.lib.Constants.R_HEADS; import static org.eclipse.jgit.lib.Constants.R_REFS; import static org.eclipse.jgit.lib.Constants.R_REMOTES; @@ -74,8 +75,6 @@ /** * Utility for writing reflog entries - * - * @since 2.0 */ public class ReflogWriter { @@ -88,7 +87,7 @@ public class ReflogWriter { * @return the name of the ref's lock ref */ public static String refLockFor(final String name) { - return name + LockFile.SUFFIX; + return name + LOCK_SUFFIX; } private final Repository parent; @@ -289,4 +288,4 @@ private boolean shouldAutoCreateLog(final String refName) { || refName.startsWith(R_REMOTES) // || refName.equals(R_STASH); } -} \ No newline at end of file +}
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/SimpleDataInput.java b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/SimpleDataInput.java index a733068..452636d 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/SimpleDataInput.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/SimpleDataInput.java
@@ -64,11 +64,13 @@ class SimpleDataInput implements DataInput { this.fd = fd; } + @Override public int readInt() throws IOException { readFully(buf, 0, 4); return NB.decodeInt32(buf, 0); } + @Override public long readLong() throws IOException { readFully(buf, 0, 8); return NB.decodeInt64(buf, 0); @@ -79,54 +81,67 @@ public long readUnsignedInt() throws IOException { return NB.decodeUInt32(buf, 0); } + @Override public void readFully(byte[] b) throws IOException { readFully(b, 0, b.length); } + @Override public void readFully(byte[] b, int off, int len) throws IOException { IO.readFully(fd, b, off, len); } + @Override public int skipBytes(int n) throws IOException { throw new UnsupportedOperationException(); } + @Override public boolean readBoolean() throws IOException { throw new UnsupportedOperationException(); } + @Override public byte readByte() throws IOException { throw new UnsupportedOperationException(); } + @Override public int readUnsignedByte() throws IOException { throw new UnsupportedOperationException(); } + @Override public short readShort() throws IOException { throw new UnsupportedOperationException(); } + @Override public int readUnsignedShort() throws IOException { throw new UnsupportedOperationException(); } + @Override public char readChar() throws IOException { throw new UnsupportedOperationException(); } + @Override public float readFloat() throws IOException { throw new UnsupportedOperationException(); } + @Override public double readDouble() throws IOException { throw new UnsupportedOperationException(); } + @Override public String readLine() throws IOException { throw new UnsupportedOperationException(); } + @Override public String readUTF() throws IOException { throw new UnsupportedOperationException(); }
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/SimpleDataOutput.java b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/SimpleDataOutput.java index d9c899a..373a494 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/SimpleDataOutput.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/SimpleDataOutput.java
@@ -64,61 +64,75 @@ class SimpleDataOutput implements DataOutput { this.fd = fd; } + @Override public void writeShort(int v) throws IOException { NB.encodeInt16(buf, 0, v); fd.write(buf, 0, 2); } + @Override public void writeInt(int v) throws IOException { NB.encodeInt32(buf, 0, v); fd.write(buf, 0, 4); } + @Override public void writeLong(long v) throws IOException { NB.encodeInt64(buf, 0, v); fd.write(buf, 0, 8); } + @Override public void write(int b) throws IOException { throw new UnsupportedOperationException(); } + @Override public void write(byte[] b) throws IOException { throw new UnsupportedOperationException(); } + @Override public void write(byte[] b, int off, int len) throws IOException { throw new UnsupportedOperationException(); } + @Override public void writeBoolean(boolean v) throws IOException { throw new UnsupportedOperationException(); } + @Override public void writeByte(int v) throws IOException { throw new UnsupportedOperationException(); } + @Override public void writeChar(int v) throws IOException { throw new UnsupportedOperationException(); } + @Override public void writeFloat(float v) throws IOException { throw new UnsupportedOperationException(); } + @Override public void writeDouble(double v) throws IOException { throw new UnsupportedOperationException(); } + @Override public void writeBytes(String s) throws IOException { throw new UnsupportedOperationException(); } + @Override public void writeChars(String s) throws IOException { throw new UnsupportedOperationException(); } + @Override public void writeUTF(String s) throws IOException { throw new UnsupportedOperationException(); }
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 ce67ae0..967754a 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
@@ -100,7 +100,7 @@ private static class Table { final int bits; Table(int bits) { - this.ids = new AtomicReferenceArray<ObjectId>(1 << bits); + this.ids = new AtomicReferenceArray<>(1 << bits); this.shift = 32 - bits; this.bits = bits; }
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/WindowCache.java b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/WindowCache.java index e1b7606..a525c85 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/WindowCache.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/WindowCache.java
@@ -235,9 +235,9 @@ private WindowCache(final WindowCacheConfig cfg) { if (lockCount < 1) throw new IllegalArgumentException(JGitText.get().lockCountMustBeGreaterOrEqual1); - queue = new ReferenceQueue<ByteWindow>(); + queue = new ReferenceQueue<>(); clock = new AtomicLong(1); - table = new AtomicReferenceArray<Entry>(tableSize); + table = new AtomicReferenceArray<>(tableSize); locks = new Lock[lockCount]; for (int i = 0; i < locks.length; i++) locks[i] = new Lock();
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/WindowCursor.java b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/WindowCursor.java index a742d17..83b236e 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/WindowCursor.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/WindowCursor.java
@@ -125,6 +125,7 @@ public BitmapIndex getBitmapIndex() throws IOException { return null; } + @Override public Collection<CachedPack> getCachedPacksAndUpdate( BitmapBuilder needBitmap) throws IOException { for (PackFile pack : db.getPacks()) { @@ -141,15 +142,17 @@ public Collection<ObjectId> resolve(AbbreviatedObjectId id) throws IOException { if (id.isComplete()) return Collections.singleton(id.toObjectId()); - HashSet<ObjectId> matches = new HashSet<ObjectId>(4); + HashSet<ObjectId> matches = new HashSet<>(4); db.resolve(matches, id); return matches; } + @Override public boolean has(AnyObjectId objectId) throws IOException { return db.has(objectId); } + @Override public ObjectLoader open(AnyObjectId objectId, int typeHint) throws MissingObjectException, IncorrectObjectTypeException, IOException { @@ -170,6 +173,7 @@ public Set<ObjectId> getShallowCommits() throws IOException { return db.getShallowCommits(); } + @Override public long getObjectSize(AnyObjectId objectId, int typeHint) throws MissingObjectException, IncorrectObjectTypeException, IOException { @@ -183,10 +187,12 @@ public long getObjectSize(AnyObjectId objectId, int typeHint) return sz; } + @Override public LocalObjectToPack newObjectToPack(AnyObjectId objectId, int type) { return new LocalObjectToPack(objectId, type); } + @Override public void selectObjectRepresentation(PackWriter packer, ProgressMonitor monitor, Iterable<ObjectToPack> objects) throws IOException, MissingObjectException { @@ -196,6 +202,7 @@ public void selectObjectRepresentation(PackWriter packer, } } + @Override public void copyObjectAsIs(PackOutputStream out, ObjectToPack otp, boolean validate) throws IOException, StoredObjectRepresentationNotAvailableException { @@ -203,6 +210,7 @@ public void copyObjectAsIs(PackOutputStream out, ObjectToPack otp, src.pack.copyAsIs(out, src, validate, this); } + @Override public void writeObjects(PackOutputStream out, List<ObjectToPack> list) throws IOException { for (ObjectToPack otp : list) @@ -245,6 +253,7 @@ int copy(final PackFile pack, long position, final byte[] dstbuf, return cnt - need; } + @Override public void copyPackAsIs(PackOutputStream out, CachedPack pack) throws IOException { ((LocalCachedPack) pack).copyAsIs(out, this);
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/WriteConfig.java b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/WriteConfig.java index 4f79ea9..1e2b239 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/WriteConfig.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/WriteConfig.java
@@ -50,6 +50,7 @@ class WriteConfig { /** Key for {@link Config#get(SectionParser)}. */ static final Config.SectionParser<WriteConfig> KEY = new SectionParser<WriteConfig>() { + @Override public WriteConfig parse(final Config cfg) { return new WriteConfig(cfg); }
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/pack/BaseSearch.java b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/pack/BaseSearch.java index b6af0b0..d231ccb 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/pack/BaseSearch.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/pack/BaseSearch.java
@@ -96,7 +96,7 @@ class BaseSearch { edgeObjects = edges; alreadyProcessed = new IntSet(); - treeCache = new ObjectIdOwnerMap<TreeWithData>(); + treeCache = new ObjectIdOwnerMap<>(); parser = new CanonicalTreeParser(); idBuf = new MutableObjectId(); }
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/pack/DeltaCache.java b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/pack/DeltaCache.java index 91917b2..973dd1d 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/pack/DeltaCache.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/pack/DeltaCache.java
@@ -60,7 +60,7 @@ class DeltaCache { DeltaCache(PackConfig pc) { size = pc.getDeltaCacheSize(); entryLimit = pc.getDeltaCacheLimit(); - queue = new ReferenceQueue<byte[]>(); + queue = new ReferenceQueue<>(); } boolean canCache(int length, ObjectToPack src, ObjectToPack res) {
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/pack/DeltaIndex.java b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/pack/DeltaIndex.java index 2a2a463..0f22de0 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/pack/DeltaIndex.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/pack/DeltaIndex.java
@@ -421,6 +421,7 @@ private static int negmatch(byte[] res, int resPtr, byte[] src, int srcPtr, return start - resPtr; } + @Override @SuppressWarnings("nls") public String toString() { String[] units = { "bytes", "KiB", "MiB", "GiB" };
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/pack/DeltaTask.java b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/pack/DeltaTask.java index 4292742..0c4e444 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/pack/DeltaTask.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/pack/DeltaTask.java
@@ -78,7 +78,7 @@ static final class Block { Block(int threads, PackConfig config, ObjectReader reader, DeltaCache dc, ThreadSafeProgressMonitor pm, ObjectToPack[] list, int begin, int end) { - this.tasks = new ArrayList<DeltaTask>(threads); + this.tasks = new ArrayList<>(threads); this.threads = threads; this.config = config; this.templateReader = reader; @@ -176,7 +176,7 @@ void partitionTasks() { } private ArrayList<WeightedPath> computeTopPaths() { - ArrayList<WeightedPath> topPaths = new ArrayList<WeightedPath>( + ArrayList<WeightedPath> topPaths = new ArrayList<>( threads); int cp = beginIndex; int ch = list[cp].getPathHash(); @@ -213,6 +213,7 @@ private ArrayList<WeightedPath> computeTopPaths() { // Sort by starting index to identify gaps later. Collections.sort(topPaths, new Comparator<WeightedPath>() { + @Override public int compare(WeightedPath a, WeightedPath b) { return a.slice.beginIndex - b.slice.beginIndex; } @@ -244,6 +245,7 @@ static final class WeightedPath implements Comparable<WeightedPath> { this.slice = s; } + @Override public int compareTo(WeightedPath o) { int cmp = Long.signum(weight - o.weight); if (cmp != 0) { @@ -275,7 +277,7 @@ final int size() { DeltaTask(Block b) { this.block = b; - this.slices = new LinkedList<Slice>(); + this.slices = new LinkedList<>(); } void add(Slice s) { @@ -290,6 +292,7 @@ void add(Slice s) { slices.add(s); } + @Override public Object call() throws Exception { or = block.templateReader.newReader(); try {
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/pack/DeltaWindow.java b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/pack/DeltaWindow.java index 19d06a2..73b285a 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/pack/DeltaWindow.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/pack/DeltaWindow.java
@@ -160,6 +160,7 @@ void search() throws IOException { clear(n); } res.set(next); + clearWindowOnTypeSwitch(); if (res.object.isEdge() || res.object.doNotAttemptDelta()) { // We don't actually want to make a delta for @@ -194,6 +195,15 @@ private static long estimateIndexSize(DeltaWindowEntry ent) { return DeltaIndex.estimateIndexSize(len) - len; } + private void clearWindowOnTypeSwitch() { + DeltaWindowEntry p = res.prev; + if (!p.empty() && res.type() != p.type()) { + for (; p != res; p = p.prev) { + clear(p); + } + } + } + private void clear(DeltaWindowEntry ent) { if (ent.index != null) loaded -= ent.index.getIndexSize(); @@ -258,12 +268,6 @@ private void searchInWindow() throws IOException { private boolean delta(final DeltaWindowEntry src) throws IOException { - // Objects must use only the same type as their delta base. - if (src.type() != res.type()) { - keepInWindow(); - return NEXT_RES; - } - // If the sizes are radically different, this is a bad pairing. if (res.size() < src.size() >>> 4) return NEXT_SRC;
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 4ee27cc..248692f 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
@@ -53,6 +53,9 @@ public class PackExt { /** A pack index file extension. */ public static final PackExt INDEX = newPackExt("idx"); //$NON-NLS-1$ + /** A keep pack file extension. */ + public static final PackExt KEEP = newPackExt("keep"); //$NON-NLS-1$ + /** A pack bitmap index file extension. */ public static final PackExt BITMAP_INDEX = newPackExt("bitmap"); //$NON-NLS-1$
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 8b4d2e6..93dbee3 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
@@ -164,18 +164,20 @@ public class PackWriter implements AutoCloseable { private static final int PACK_VERSION_GENERATED = 2; /** Empty set of objects for {@code preparePack()}. */ - public static Set<ObjectId> NONE = Collections.emptySet(); + public static final Set<ObjectId> NONE = Collections.emptySet(); private static final Map<WeakReference<PackWriter>, Boolean> instances = - new ConcurrentHashMap<WeakReference<PackWriter>, Boolean>(); + new ConcurrentHashMap<>(); private static final Iterable<PackWriter> instancesIterable = new Iterable<PackWriter>() { + @Override public Iterator<PackWriter> iterator() { return new Iterator<PackWriter>() { private final Iterator<WeakReference<PackWriter>> it = instances.keySet().iterator(); private PackWriter next; + @Override public boolean hasNext() { if (next != null) return true; @@ -189,6 +191,7 @@ public boolean hasNext() { return false; } + @Override public PackWriter next() { if (hasNext()) { PackWriter result = next; @@ -198,6 +201,7 @@ public PackWriter next() { throw new NoSuchElementException(); } + @Override public void remove() { throw new UnsupportedOperationException(); } @@ -213,21 +217,21 @@ public static Iterable<PackWriter> getInstances() { @SuppressWarnings("unchecked") BlockList<ObjectToPack> objectsLists[] = new BlockList[OBJ_TAG + 1]; { - objectsLists[OBJ_COMMIT] = new BlockList<ObjectToPack>(); - objectsLists[OBJ_TREE] = new BlockList<ObjectToPack>(); - objectsLists[OBJ_BLOB] = new BlockList<ObjectToPack>(); - objectsLists[OBJ_TAG] = new BlockList<ObjectToPack>(); + objectsLists[OBJ_COMMIT] = new BlockList<>(); + objectsLists[OBJ_TREE] = new BlockList<>(); + objectsLists[OBJ_BLOB] = new BlockList<>(); + objectsLists[OBJ_TAG] = new BlockList<>(); } - private ObjectIdOwnerMap<ObjectToPack> objectsMap = new ObjectIdOwnerMap<ObjectToPack>(); + private ObjectIdOwnerMap<ObjectToPack> objectsMap = new ObjectIdOwnerMap<>(); // edge objects for thin packs - private List<ObjectToPack> edgeObjects = new BlockList<ObjectToPack>(); + private List<ObjectToPack> edgeObjects = new BlockList<>(); // Objects the client is known to have already. private BitmapBuilder haveObjects; - private List<CachedPack> cachedPacks = new ArrayList<CachedPack>(2); + private List<CachedPack> cachedPacks = new ArrayList<>(2); private Set<ObjectId> tagTargets = Collections.emptySet(); @@ -355,7 +359,7 @@ public PackWriter(final PackConfig config, final ObjectReader reader) { reuseValidate = true; // be paranoid by default stats = new PackStatistics.Accumulator(); state = new MutableState(); - selfRef = new WeakReference<PackWriter>(this); + selfRef = new WeakReference<>(this); instances.put(selfRef, Boolean.TRUE); } @@ -369,7 +373,6 @@ public PackWriter(final PackConfig config, final ObjectReader reader) { * the callback to set * * @return this object for chaining. - * @since 4.1 */ public PackWriter setObjectCountCallback(ObjectCountCallback callback) { this.callback = callback; @@ -381,11 +384,10 @@ public PackWriter setObjectCountCallback(ObjectCountCallback callback) { * * @param clientShallowCommits * the shallow commits in the client - * @since 4.1 */ public void setClientShallowCommits(Set<ObjectId> clientShallowCommits) { stats.clientShallowCommits = Collections - .unmodifiableSet(new HashSet<ObjectId>(clientShallowCommits)); + .unmodifiableSet(new HashSet<>(clientShallowCommits)); } /** @@ -742,21 +744,20 @@ public void preparePack(ProgressMonitor countingMonitor, * Must not be {@code null}. * @throws IOException * an I/O problem occured while reading objects. - * - * @since 4.5 */ public void preparePack(ProgressMonitor countingMonitor, @NonNull Set<? extends ObjectId> want, @NonNull Set<? extends ObjectId> have, @NonNull Set<? extends ObjectId> shallow) throws IOException { - ObjectWalk ow; - if (shallowPack) { - ow = new DepthWalk.ObjectWalk(reader, depth - 1); - } else { - ow = new ObjectWalk(reader); + try (ObjectWalk ow = getObjectWalk()) { + ow.assumeShallow(shallow); + preparePack(countingMonitor, ow, want, have); } - ow.assumeShallow(shallow); - preparePack(countingMonitor, ow, want, have); + } + + private ObjectWalk getObjectWalk() { + return shallowPack ? new DepthWalk.ObjectWalk(reader, depth - 1) + : new ObjectWalk(reader); } /** @@ -917,7 +918,7 @@ private List<ObjectToPack> sortByName() { cnt += objectsLists[OBJ_BLOB].size(); cnt += objectsLists[OBJ_TAG].size(); - sortedByName = new BlockList<ObjectToPack>(cnt); + sortedByName = new BlockList<>(cnt); sortedByName.addAll(objectsLists[OBJ_COMMIT]); sortedByName.addAll(objectsLists[OBJ_TREE]); sortedByName.addAll(objectsLists[OBJ_BLOB]); @@ -1089,8 +1090,6 @@ public State getState() { /** * Release all resources used by this writer. - * - * @since 4.0 */ @Override public void close() { @@ -1113,7 +1112,7 @@ private void searchForReuse(ProgressMonitor monitor) throws IOException { beginPhase(PackingPhase.FINDING_SOURCES, monitor, cnt); if (cnt <= 4096) { // For small object counts, do everything as one list. - BlockList<ObjectToPack> tmp = new BlockList<ObjectToPack>((int) cnt); + BlockList<ObjectToPack> tmp = new BlockList<>((int) cnt); tmp.addAll(objectsLists[OBJ_TAG]); tmp.addAll(objectsLists[OBJ_COMMIT]); tmp.addAll(objectsLists[OBJ_TREE]); @@ -1259,6 +1258,7 @@ private void searchForDeltas(ProgressMonitor monitor) // bigger ones, because source files grow and hardly ever shrink. // Arrays.sort(list, 0, cnt, new Comparator<ObjectToPack>() { + @Override public int compare(ObjectToPack a, ObjectToPack b) { int cmp = (a.isDoNotDelta() ? 1 : 0) - (b.isDoNotDelta() ? 1 : 0); @@ -1404,6 +1404,7 @@ private void parallelDeltaSearch(ProgressMonitor monitor, // can schedule these for us. for (final DeltaTask task : taskBlock.tasks) { executor.execute(new Runnable() { + @Override public void run() { try { task.call(); @@ -1446,7 +1447,7 @@ public void run() { private static void runTasks(ExecutorService pool, ThreadSafeProgressMonitor pm, DeltaTask.Block tb, List<Throwable> errors) throws IOException { - List<Future<?>> futures = new ArrayList<Future<?>>(tb.tasks.size()); + List<Future<?>> futures = new ArrayList<>(tb.tasks.size()); for (DeltaTask task : tb.tasks) futures.add(pool.submit(task)); @@ -1675,7 +1676,7 @@ private void findObjectsToPack(@NonNull ProgressMonitor countingMonitor, } } - List<ObjectId> all = new ArrayList<ObjectId>(want.size() + have.size()); + List<ObjectId> all = new ArrayList<>(want.size() + have.size()); all.addAll(want); all.addAll(have); @@ -1693,9 +1694,9 @@ private void findObjectsToPack(@NonNull ProgressMonitor countingMonitor, walker.sort(RevSort.BOUNDARY, true); } - List<RevObject> wantObjs = new ArrayList<RevObject>(want.size()); - List<RevObject> haveObjs = new ArrayList<RevObject>(haveEst); - List<RevTag> wantTags = new ArrayList<RevTag>(want.size()); + List<RevObject> wantObjs = new ArrayList<>(want.size()); + List<RevObject> haveObjs = new ArrayList<>(haveEst); + List<RevTag> wantTags = new ArrayList<>(want.size()); // Retrieve the RevWalk's versions of "want" and "have" objects to // maintain any state previously set in the RevWalk. @@ -1726,7 +1727,7 @@ private void findObjectsToPack(@NonNull ProgressMonitor countingMonitor, } if (!wantTags.isEmpty()) { - all = new ArrayList<ObjectId>(wantTags.size()); + all = new ArrayList<>(wantTags.size()); for (RevTag tag : wantTags) all.add(tag.getObject()); q = walker.parseAny(all, true); @@ -1769,8 +1770,8 @@ private void findObjectsToPack(@NonNull ProgressMonitor countingMonitor, walker.markUninteresting(obj); final int maxBases = config.getDeltaSearchWindowSize(); - Set<RevTree> baseTrees = new HashSet<RevTree>(); - BlockList<RevCommit> commits = new BlockList<RevCommit>(); + Set<RevTree> baseTrees = new HashSet<>(); + BlockList<RevCommit> commits = new BlockList<>(); Set<ObjectId> roots = new HashSet<>(); RevCommit c; while ((c = walker.next()) != null) { @@ -2258,8 +2259,6 @@ public long getTotalObjects() { * @return the count of objects that needed to be discovered through an * object walk because they were not found in bitmap indices. * Returns -1 if no bitmap indices were found. - * - * @since 4.0 */ public long getBitmapIndexMisses() { return statistics.getBitmapIndexMisses();
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/pack/PackWriterBitmapPreparer.java b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/pack/PackWriterBitmapPreparer.java index 77311ab..07a03b4 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/pack/PackWriterBitmapPreparer.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/pack/PackWriterBitmapPreparer.java
@@ -91,6 +91,7 @@ class PackWriterBitmapPreparer { private static final int DAY_IN_SECONDS = 24 * 60 * 60; private static final Comparator<BitmapBuilderEntry> ORDER_BY_CARDINALITY = new Comparator<BitmapBuilderEntry>() { + @Override public int compare(BitmapBuilderEntry a, BitmapBuilderEntry b) { return Integer.signum(a.getBuilder().cardinality() - b.getBuilder().cardinality()); @@ -167,7 +168,7 @@ Collection<BitmapCommit> selectCommits(int expectedCommitCount) pm.endTask(); int totCommits = selectionHelper.getCommitCount(); - BlockList<BitmapCommit> selections = new BlockList<BitmapCommit>( + BlockList<BitmapCommit> selections = new BlockList<>( totCommits / recentCommitSpan + 1); for (BitmapCommit reuse : selectionHelper.reusedCommits) { selections.add(reuse); @@ -194,7 +195,7 @@ Collection<BitmapCommit> selectCommits(int expectedCommitCount) // better compression/on the run-length encoding of the XORs between // them. List<List<BitmapCommit>> chains = - new ArrayList<List<BitmapCommit>>(); + new ArrayList<>(); // Mark the current branch as inactive if its tip commit isn't // recent and there are an excessive number of branches, to @@ -286,7 +287,7 @@ Collection<BitmapCommit> selectCommits(int expectedCommitCount) } if (longestAncestorChain == null) { - longestAncestorChain = new ArrayList<BitmapCommit>(); + longestAncestorChain = new ArrayList<>(); chains.add(longestAncestorChain); } longestAncestorChain.add(new BitmapCommit( @@ -375,7 +376,7 @@ private CommitSelectionHelper setupTipCommitBitmaps(RevWalk rw, int expectedCommitCount) throws IncorrectObjectTypeException, IOException, MissingObjectException { BitmapBuilder reuse = commitBitmapIndex.newBitmapBuilder(); - List<BitmapCommit> reuseCommits = new ArrayList<BitmapCommit>(); + List<BitmapCommit> reuseCommits = new ArrayList<>(); for (PackBitmapIndexRemapper.Entry entry : bitmapRemapper) { // More recent commits did not have the reuse flag set, so skip them if ((entry.getFlags() & FLAG_REUSE) != FLAG_REUSE) { @@ -397,9 +398,9 @@ private CommitSelectionHelper setupTipCommitBitmaps(RevWalk rw, // Add branch tips that are not represented in old bitmap indices. Set // up the RevWalk to walk the new commits not in the old packs. - List<BitmapBuilderEntry> tipCommitBitmaps = new ArrayList<BitmapBuilderEntry>( + List<BitmapBuilderEntry> tipCommitBitmaps = new ArrayList<>( want.size()); - Set<RevCommit> peeledWant = new HashSet<RevCommit>(want.size()); + Set<RevCommit> peeledWant = new HashSet<>(want.size()); for (AnyObjectId objectId : want) { RevObject ro = rw.peel(rw.parseAny(objectId)); if (!(ro instanceof RevCommit) || reuse.contains(ro)) { @@ -579,20 +580,24 @@ private static final class CommitSelectionHelper implements Iterable<RevCommit> this.reusedCommits = reuse; } + @Override public Iterator<RevCommit> iterator() { // Member variables referenced by this iterator will have synthetic // accessors generated for them if they are made private. return new Iterator<RevCommit>() { int pos = commitStartPos; + @Override public boolean hasNext() { return pos < commitsByOldest.length; } + @Override public RevCommit next() { return commitsByOldest[pos++]; } + @Override public void remove() { throw new UnsupportedOperationException(); }
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/internal/submodule/SubmoduleValidator.java b/org.eclipse.jgit/src/org/eclipse/jgit/internal/submodule/SubmoduleValidator.java new file mode 100644 index 0000000..3651631 --- /dev/null +++ b/org.eclipse.jgit/src/org/eclipse/jgit/internal/submodule/SubmoduleValidator.java
@@ -0,0 +1,184 @@ +/* + * Copyright (C) 2018, 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.submodule; + +import static org.eclipse.jgit.lib.ConfigConstants.CONFIG_KEY_PATH; +import static org.eclipse.jgit.lib.ConfigConstants.CONFIG_KEY_URL; +import static org.eclipse.jgit.lib.ConfigConstants.CONFIG_SUBMODULE_SECTION; + +import java.io.IOException; +import java.text.MessageFormat; + +import org.eclipse.jgit.errors.ConfigInvalidException; +import org.eclipse.jgit.internal.JGitText; +import org.eclipse.jgit.lib.Config; + +/** + * Validations for the git submodule fields (name, path, uri). + * + * Invalid values in these fields can cause security problems as reported in + * CVE-2018-11235 and and CVE-2018-17456 + */ +public class SubmoduleValidator { + + /** + * Error validating a git submodule declaration + */ + public static class SubmoduleValidationException extends Exception { + + /** + * @param message + * Description of the problem + */ + public SubmoduleValidationException(String message) { + super(message); + } + + private static final long serialVersionUID = 1L; + } + + /** + * Validate name for a submodule + * + * @param name + * name of a submodule + * @throws SubmoduleValidationException + * name doesn't seem valid (detail in message) + */ + public static void assertValidSubmoduleName(String name) + throws SubmoduleValidationException { + if (name.contains("/../") || name.contains("\\..\\") //$NON-NLS-1$ //$NON-NLS-2$ + || name.startsWith("../") || name.startsWith("..\\") //$NON-NLS-1$ //$NON-NLS-2$ + || name.endsWith("/..") || name.endsWith("\\..")) { //$NON-NLS-1$ //$NON-NLS-2$ + // Submodule names are used to store the submodule repositories + // under $GIT_DIR/modules. Having ".." in submodule names makes a + // vulnerability (CVE-2018-11235 + // https://bugs.eclipse.org/bugs/show_bug.cgi?id=535027#c0) + // Reject names containing ".." path segments. We don't + // automatically replace these characters or canonicalize by + // regarding the name as a file path. + // Since Path class is platform dependent, we manually check '/' and + // '\\' patterns here. + throw new SubmoduleValidationException(MessageFormat + .format(JGitText.get().invalidNameContainsDotDot, name)); + } + + if (name.startsWith("-")) { //$NON-NLS-1$ + throw new SubmoduleValidationException( + MessageFormat.format( + JGitText.get().submoduleNameInvalid, name)); + } + } + + /** + * Validate URI for a submodule + * + * @param uri + * uri of a submodule + * @throws SubmoduleValidationException + * uri doesn't seem valid + */ + public static void assertValidSubmoduleUri(String uri) + throws SubmoduleValidationException { + if (uri.startsWith("-")) { //$NON-NLS-1$ + throw new SubmoduleValidationException( + MessageFormat.format( + JGitText.get().submoduleUrlInvalid, uri)); + } + } + + /** + * Validate path for a submodule + * + * @param path + * path of a submodule + * @throws SubmoduleValidationException + * path doesn't look right + */ + public static void assertValidSubmodulePath(String path) + throws SubmoduleValidationException { + if (path.startsWith("-")) { //$NON-NLS-1$ + throw new SubmoduleValidationException( + MessageFormat.format( + JGitText.get().submodulePathInvalid, path)); + } + } + + /** + * @param gitModulesContents + * Contents of a .gitmodule file. They will be parsed internally. + * @throws IOException + * If the contents + */ + public static void assertValidGitModulesFile(String gitModulesContents) + throws IOException { + // Validate .gitmodules file + Config c = new Config(); + try { + c.fromText(gitModulesContents); + for (String subsection : + c.getSubsections(CONFIG_SUBMODULE_SECTION)) { + assertValidSubmoduleName(subsection); + + String url = c.getString( + CONFIG_SUBMODULE_SECTION, subsection, CONFIG_KEY_URL); + if (url != null) { + assertValidSubmoduleUri(url); + } + + String path = c.getString( + CONFIG_SUBMODULE_SECTION, subsection, CONFIG_KEY_PATH); + if (path != null) { + assertValidSubmodulePath(path); + } + } + } catch (ConfigInvalidException e) { + throw new IOException( + MessageFormat.format( + JGitText.get().invalidGitModules, + e)); + } catch (SubmoduleValidationException e) { + throw new IOException(e.getMessage(), e); + } + } +}
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 11081d5..f964bf2 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/lib/AnyObjectId.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/lib/AnyObjectId.java
@@ -159,6 +159,7 @@ public final int getByte(int index) { * @return < 0 if this id comes before other; 0 if this id is equal to * other; > 0 if this id comes after other. */ + @Override public final int compareTo(final AnyObjectId other) { if (this == other) return 0; @@ -261,6 +262,7 @@ public boolean startsWith(final AbbreviatedObjectId abbr) { return abbr.prefixCompare(this) == 0; } + @Override public final int hashCode() { return w2; } @@ -276,6 +278,7 @@ public final boolean equals(final AnyObjectId other) { return other != null ? equals(this, other) : false; } + @Override public final boolean equals(final Object o) { if (o instanceof AnyObjectId) return equals((AnyObjectId) o);
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 670f9a9..de1003b 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/lib/BaseRepositoryBuilder.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/lib/BaseRepositoryBuilder.java
@@ -218,7 +218,7 @@ public File getObjectDirectory() { public B addAlternateObjectDirectory(File other) { if (other != null) { if (alternateObjectDirectories == null) - alternateObjectDirectories = new LinkedList<File>(); + alternateObjectDirectories = new LinkedList<>(); alternateObjectDirectories.add(other); } return self(); @@ -429,7 +429,7 @@ public B readEnvironment(SystemReader sr) { public B addCeilingDirectory(File root) { if (root != null) { if (ceilingDirectories == null) - ceilingDirectories = new LinkedList<File>(); + ceilingDirectories = new LinkedList<>(); ceilingDirectories.add(root); } return self();
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/lib/BatchRefUpdate.java b/org.eclipse.jgit/src/org/eclipse/jgit/lib/BatchRefUpdate.java index 653c9f6..3f6995d 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/lib/BatchRefUpdate.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/lib/BatchRefUpdate.java
@@ -120,7 +120,7 @@ public class BatchRefUpdate { */ protected BatchRefUpdate(RefDatabase refdb) { this.refdb = refdb; - this.commands = new ArrayList<ReceiveCommand>(); + this.commands = new ArrayList<>(); this.atomic = refdb.performsAtomicTransactions(); } @@ -400,7 +400,7 @@ public void execute(RevWalk walk, ProgressMonitor monitor, } monitor.beginTask(JGitText.get().updatingReferences, commands.size()); - List<ReceiveCommand> commands2 = new ArrayList<ReceiveCommand>( + List<ReceiveCommand> commands2 = new ArrayList<>( commands.size()); // First delete refs. This may free the name space for some of the // updates. @@ -431,7 +431,7 @@ public void execute(RevWalk walk, ProgressMonitor monitor, } if (!commands2.isEmpty()) { // What part of the name space is already taken - Collection<String> takenNames = new HashSet<String>(refdb.getRefs( + Collection<String> takenNames = new HashSet<>(refdb.getRefs( RefDatabase.ALL).keySet()); Collection<String> takenPrefixes = getTakenPrefixes(takenNames); @@ -525,7 +525,7 @@ public void execute(RevWalk walk, ProgressMonitor monitor) private static Collection<String> getTakenPrefixes( final Collection<String> names) { - Collection<String> ref = new HashSet<String>(); + Collection<String> ref = new HashSet<>(); for (String name : names) ref.addAll(getPrefixes(name)); return ref; @@ -539,7 +539,7 @@ private static void addRefToPrefixes(Collection<String> prefixes, } static Collection<String> getPrefixes(String s) { - Collection<String> ret = new HashSet<String>(); + Collection<String> ret = new HashSet<>(); int p1 = s.indexOf('/'); while (p1 > 0) { ret.add(s.substring(0, p1));
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/lib/BatchingProgressMonitor.java b/org.eclipse.jgit/src/org/eclipse/jgit/lib/BatchingProgressMonitor.java index a3859ab..54c8052 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/lib/BatchingProgressMonitor.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/lib/BatchingProgressMonitor.java
@@ -68,10 +68,12 @@ public void setDelayStart(long time, TimeUnit unit) { delayStartUnit = unit; } + @Override public void start(int totalTasks) { // Ignore the number of tasks. } + @Override public void beginTask(String title, int work) { endTask(); task = new Task(title, work); @@ -79,11 +81,13 @@ public void beginTask(String title, int work) { task.delay(delayStartTime, delayStartUnit); } + @Override public void update(int completed) { if (task != null) task.update(this, completed); } + @Override public void endTask() { if (task != null) { task.end(this); @@ -91,6 +95,7 @@ public void endTask() { } } + @Override public boolean isCancelled() { return false; } @@ -178,6 +183,7 @@ void delay(long time, TimeUnit unit) { timerFuture = WorkQueue.getExecutor().schedule(this, time, unit); } + @Override public void run() { display = true; }
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/lib/BitmapIndex.java b/org.eclipse.jgit/src/org/eclipse/jgit/lib/BitmapIndex.java index 9ddff25..00f42a4 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/lib/BitmapIndex.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/lib/BitmapIndex.java
@@ -108,6 +108,7 @@ public interface Bitmap extends Iterable<BitmapObject> { * * @return an Iterator. */ + @Override Iterator<BitmapObject> iterator(); } @@ -166,6 +167,7 @@ public interface BitmapBuilder extends Bitmap { * the other bitmap * @return the current builder. */ + @Override BitmapBuilder or(Bitmap other); /** @@ -176,6 +178,7 @@ public interface BitmapBuilder extends Bitmap { * the other bitmap * @return the current builder. */ + @Override BitmapBuilder andNot(Bitmap other); /** @@ -185,6 +188,7 @@ public interface BitmapBuilder extends Bitmap { * the other bitmap * @return the current builder. */ + @Override BitmapBuilder xor(Bitmap other); /** @return the fully built immutable bitmap */
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 8fe8a96..f45c71c 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/lib/Config.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/lib/Config.java
@@ -58,6 +58,7 @@ import java.util.ArrayList; import java.util.Collections; import java.util.List; +import java.util.Locale; import java.util.Set; import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicReference; @@ -121,7 +122,7 @@ public Config() { */ public Config(Config defaultConfig) { baseConfig = defaultConfig; - state = new AtomicReference<ConfigSnapshot>(newState()); + state = new AtomicReference<>(newState()); } /** @@ -895,7 +896,7 @@ public <T extends Enum<?>> void setEnum(final String section, if (value instanceof ConfigEnum) n = ((ConfigEnum) value).toConfigValue(); else - n = value.name().toLowerCase().replace('_', ' '); + n = value.name().toLowerCase(Locale.ROOT).replace('_', ' '); setString(section, subsection, name, n); } @@ -959,7 +960,7 @@ private ConfigSnapshot unsetSection(final ConfigSnapshot srcState, final String section, final String subsection) { final int max = srcState.entryList.size(); - final ArrayList<ConfigLine> r = new ArrayList<ConfigLine>(max); + final ArrayList<ConfigLine> r = new ArrayList<>(max); boolean lastWasMatch = false; for (ConfigLine e : srcState.entryList) { @@ -1074,7 +1075,7 @@ private static List<ConfigLine> copy(final ConfigSnapshot src, // for a new section header. Assume that and allocate the space. // final int max = src.entryList.size() + values.size() + 1; - final ArrayList<ConfigLine> r = new ArrayList<ConfigLine>(max); + final ArrayList<ConfigLine> r = new ArrayList<>(max); r.addAll(src.entryList); return r; } @@ -1162,7 +1163,7 @@ private List<ConfigLine> fromTextRecurse(final String text, int depth) throw new ConfigInvalidException( JGitText.get().tooManyIncludeRecursions); } - final List<ConfigLine> newEntries = new ArrayList<ConfigLine>(); + final List<ConfigLine> newEntries = new ArrayList<>(); final StringReader in = new StringReader(text); ConfigLine last = null; ConfigLine e = new ConfigLine();
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 87a95b9..2618180 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/lib/ConfigConstants.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/lib/ConfigConstants.java
@@ -291,6 +291,20 @@ public class ConfigConstants { public static final String CONFIG_KEY_PRUNEPACKEXPIRE = "prunepackexpire"; /** + * The "logexpiry" key + * + * @since 4.7 + */ + public static final String CONFIG_KEY_LOGEXPIRY = "logExpiry"; + + /** + * The "autodetach" key + * + * @since 4.7 + */ + public static final String CONFIG_KEY_AUTODETACH = "autoDetach"; + + /** * The "aggressiveDepth" key * @since 3.6 */ @@ -381,4 +395,16 @@ public class ConfigConstants { * @since 4.6 */ public static final String CONFIG_KEY_USEJGITBUILTIN = "useJGitBuiltin"; + + /** + * The "fetchRecurseSubmodules" key + * @since 4.7 + */ + public static final String CONFIG_KEY_FETCH_RECURSE_SUBMODULES = "fetchRecurseSubmodules"; + + /** + * The "recurseSubmodules" key + * @since 4.7 + */ + public static final String CONFIG_KEY_RECURSE_SUBMODULES = "recurseSubmodules"; }
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/lib/ConfigSnapshot.java b/org.eclipse.jgit/src/org/eclipse/jgit/lib/ConfigSnapshot.java index 5ed129e..f5ada13 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/lib/ConfigSnapshot.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/lib/ConfigSnapshot.java
@@ -78,7 +78,7 @@ class ConfigSnapshot { ConfigSnapshot(List<ConfigLine> entries, ConfigSnapshot base) { entryList = entries; - cache = new ConcurrentHashMap<Object, Object>(16, 0.75f, 1); + cache = new ConcurrentHashMap<>(16, 0.75f, 1); baseState = base; } @@ -112,7 +112,7 @@ private Map<String, String> getNamesInternal(String section, if (idx < 0) idx = -(idx + 1); - Map<String, String> m = new LinkedHashMap<String, String>(); + Map<String, String> m = new LinkedHashMap<>(); while (idx < s.size()) { ConfigLine e = s.get(idx++); if (!e.match(section, subsection)) @@ -187,7 +187,7 @@ private List<ConfigLine> sorted() { } private static List<ConfigLine> sort(List<ConfigLine> in) { - List<ConfigLine> sorted = new ArrayList<ConfigLine>(in.size()); + List<ConfigLine> sorted = new ArrayList<>(in.size()); for (ConfigLine line : in) { if (line.section != null && line.name != null) sorted.add(line); @@ -217,6 +217,7 @@ private static int compare2( } private static class LineComparator implements Comparator<ConfigLine> { + @Override public int compare(ConfigLine a, ConfigLine b) { return compare2( a.section, a.subsection, a.name, @@ -236,8 +237,8 @@ private static class SectionNames { final Map<String, Set<String>> subsections; SectionNames(ConfigSnapshot cfg) { - Map<String, String> sec = new LinkedHashMap<String, String>(); - Map<String, Set<String>> sub = new HashMap<String, Set<String>>(); + Map<String, String> sec = new LinkedHashMap<>(); + Map<String, Set<String>> sub = new HashMap<>(); while (cfg != null) { for (ConfigLine e : cfg.entryList) { if (e.section == null) @@ -252,7 +253,7 @@ private static class SectionNames { Set<String> m = sub.get(l1); if (m == null) { - m = new LinkedHashSet<String>(); + m = new LinkedHashSet<>(); sub.put(l1, m); } m.add(e.subsection); @@ -286,14 +287,17 @@ public boolean contains(Object needle) { public Iterator<String> iterator() { final Iterator<String> i = names.values().iterator(); return new Iterator<String>() { + @Override public boolean hasNext() { return i.hasNext(); } + @Override public String next() { return i.next(); } + @Override public void remove() { throw new UnsupportedOperationException(); }
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 ff80672..bda1a27 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/lib/Constants.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/lib/Constants.java
@@ -665,6 +665,13 @@ public static int decodeTypeString(final AnyObjectId id, public static final ObjectId EMPTY_BLOB_ID = ObjectId .fromString("e69de29bb2d1d6434b8b29ae775ad8c2e48c5391"); + /** + * Suffix of lock file name + * + * @since 4.7 + */ + public static final String LOCK_SUFFIX = ".lock"; //$NON-NLS-1$ + private Constants() { // Hide the default constructor }
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 83efd43..40aba63 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/lib/CoreConfig.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/lib/CoreConfig.java
@@ -58,6 +58,7 @@ public class CoreConfig { /** Key for {@link Config#get(SectionParser)}. */ public static final Config.SectionParser<CoreConfig> KEY = new SectionParser<CoreConfig>() { + @Override public CoreConfig parse(final Config cfg) { return new CoreConfig(cfg); }
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/lib/EmptyProgressMonitor.java b/org.eclipse.jgit/src/org/eclipse/jgit/lib/EmptyProgressMonitor.java index eabcbbf..c236c35 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/lib/EmptyProgressMonitor.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/lib/EmptyProgressMonitor.java
@@ -51,22 +51,27 @@ */ public abstract class EmptyProgressMonitor implements ProgressMonitor { + @Override public void start(int totalTasks) { // empty } + @Override public void beginTask(String title, int totalWork) { // empty } + @Override public void update(int completed) { // empty } + @Override public void endTask() { // empty } + @Override public boolean isCancelled() { return false; }
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/lib/FileMode.java b/org.eclipse.jgit/src/org/eclipse/jgit/lib/FileMode.java index f295f5b..a489461 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/lib/FileMode.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/lib/FileMode.java
@@ -86,6 +86,7 @@ public abstract class FileMode { @SuppressWarnings("synthetic-access") public static final FileMode TREE = new FileMode(TYPE_TREE, Constants.OBJ_TREE) { + @Override public boolean equals(final int modeBits) { return (modeBits & TYPE_MASK) == TYPE_TREE; } @@ -95,6 +96,7 @@ public boolean equals(final int modeBits) { @SuppressWarnings("synthetic-access") public static final FileMode SYMLINK = new FileMode(TYPE_SYMLINK, Constants.OBJ_BLOB) { + @Override public boolean equals(final int modeBits) { return (modeBits & TYPE_MASK) == TYPE_SYMLINK; } @@ -104,6 +106,7 @@ public boolean equals(final int modeBits) { @SuppressWarnings("synthetic-access") public static final FileMode REGULAR_FILE = new FileMode(0100644, Constants.OBJ_BLOB) { + @Override public boolean equals(final int modeBits) { return (modeBits & TYPE_MASK) == TYPE_FILE && (modeBits & 0111) == 0; } @@ -113,6 +116,7 @@ public boolean equals(final int modeBits) { @SuppressWarnings("synthetic-access") public static final FileMode EXECUTABLE_FILE = new FileMode(0100755, Constants.OBJ_BLOB) { + @Override public boolean equals(final int modeBits) { return (modeBits & TYPE_MASK) == TYPE_FILE && (modeBits & 0111) != 0; } @@ -122,6 +126,7 @@ public boolean equals(final int modeBits) { @SuppressWarnings("synthetic-access") public static final FileMode GITLINK = new FileMode(TYPE_GITLINK, Constants.OBJ_COMMIT) { + @Override public boolean equals(final int modeBits) { return (modeBits & TYPE_MASK) == TYPE_GITLINK; } @@ -131,6 +136,7 @@ public boolean equals(final int modeBits) { @SuppressWarnings("synthetic-access") public static final FileMode MISSING = new FileMode(TYPE_MISSING, Constants.OBJ_BAD) { + @Override public boolean equals(final int modeBits) { return modeBits == 0; } @@ -258,6 +264,7 @@ public int getObjectType() { } /** Format this mode as an octal string (for debugging only). */ + @Override public String toString() { return Integer.toOctalString(modeBits); }
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/lib/GitmoduleEntry.java b/org.eclipse.jgit/src/org/eclipse/jgit/lib/GitmoduleEntry.java new file mode 100644 index 0000000..bded527 --- /dev/null +++ b/org.eclipse.jgit/src/org/eclipse/jgit/lib/GitmoduleEntry.java
@@ -0,0 +1,86 @@ +/* + * Copyright (C) 2018, 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.lib; + +import org.eclipse.jgit.lib.AnyObjectId; + +/** + * A .gitmodules file found in the pack. Store the blob of the file itself (e.g. + * to access its contents) and the tree where it was found (e.g. to check if it + * is in the root) + * + * @since 4.7.5 + */ +public final class GitmoduleEntry { + private final AnyObjectId treeId; + + private final AnyObjectId blobId; + + /** + * A record of (tree, blob) for a .gitmodule file in a pack + * + * @param treeId + * tree id containing a .gitmodules entry + * @param blobId + * id of the blob of the .gitmodules file + */ + public GitmoduleEntry(AnyObjectId treeId, AnyObjectId blobId) { + // AnyObjectId's are reused, must keep a copy. + this.treeId = treeId.copy(); + this.blobId = blobId.copy(); + } + + /** + * @return Id of a .gitmodules file found in the pack + */ + public AnyObjectId getBlobId() { + return blobId; + } + + /** + * @return Id of a tree object where the .gitmodules file was found + */ + public AnyObjectId getTreeId() { + return treeId; + } +} \ No newline at end of file
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 af6a4fb..e544b72 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/lib/IndexDiff.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/lib/IndexDiff.java
@@ -253,19 +253,19 @@ public TreeFilter clone() { private final WorkingTreeIterator initialWorkingTreeIterator; - private Set<String> added = new HashSet<String>(); + private Set<String> added = new HashSet<>(); - private Set<String> changed = new HashSet<String>(); + private Set<String> changed = new HashSet<>(); - private Set<String> removed = new HashSet<String>(); + private Set<String> removed = new HashSet<>(); - private Set<String> missing = new HashSet<String>(); + private Set<String> missing = new HashSet<>(); - private Set<String> modified = new HashSet<String>(); + private Set<String> modified = new HashSet<>(); - private Set<String> untracked = new HashSet<String>(); + private Set<String> untracked = new HashSet<>(); - private Map<String, StageState> conflicts = new HashMap<String, StageState>(); + private Map<String, StageState> conflicts = new HashMap<>(); private Set<String> ignored; @@ -275,11 +275,11 @@ public TreeFilter clone() { private IndexDiffFilter indexDiffFilter; - private Map<String, IndexDiff> submoduleIndexDiffs = new HashMap<String, IndexDiff>(); + private Map<String, IndexDiff> submoduleIndexDiffs = new HashMap<>(); private IgnoreSubmoduleMode ignoreSubmoduleMode = null; - private Map<FileMode, Set<String>> fileModes = new HashMap<FileMode, Set<String>>(); + private Map<FileMode, Set<String>> fileModes = new HashMap<>(); /** * Construct an IndexDiff @@ -342,6 +342,7 @@ public interface WorkingTreeIteratorFactory { } private WorkingTreeIteratorFactory wTreeIt = new WorkingTreeIteratorFactory() { + @Override public WorkingTreeIterator getWorkingTreeIterator(Repository repo) { return new FileTreeIterator(repo); } @@ -416,7 +417,7 @@ public boolean diff(final ProgressMonitor monitor, int estWorkTreeSize, treeWalk.addTree(new DirCacheIterator(dirCache)); treeWalk.addTree(initialWorkingTreeIterator); initialWorkingTreeIterator.setDirCacheIterator(treeWalk, 1); - Collection<TreeFilter> filters = new ArrayList<TreeFilter>(4); + Collection<TreeFilter> filters = new ArrayList<>(4); if (monitor != null) { // Get the maximum size of the work tree and index @@ -517,7 +518,7 @@ public boolean diff(final ProgressMonitor monitor, int estWorkTreeSize, String path = treeWalk.getPathString(); if (path != null) { if (values == null) - values = new HashSet<String>(); + values = new HashSet<>(); values.add(path); fileModes.put(treeWalk.getFileMode(i), values); } @@ -686,7 +687,7 @@ public Set<String> getIgnoredNotInIndex() { */ public Set<String> getAssumeUnchanged() { if (assumeUnchanged == null) { - HashSet<String> unchanged = new HashSet<String>(); + HashSet<String> unchanged = new HashSet<>(); for (int i = 0; i < dirCache.getEntryCount(); i++) if (dirCache.getEntry(i).isAssumeValid()) unchanged.add(dirCache.getEntry(i).getPathString()); @@ -700,7 +701,7 @@ public Set<String> getAssumeUnchanged() { */ public Set<String> getUntrackedFolders() { return ((indexDiffFilter == null) ? Collections.<String> emptySet() - : new HashSet<String>(indexDiffFilter.getUntrackedFolders())); + : new HashSet<>(indexDiffFilter.getUntrackedFolders())); } /** @@ -726,7 +727,7 @@ public FileMode getIndexMode(final String path) { public Set<String> getPathsWithIndexMode(final FileMode mode) { Set<String> paths = fileModes.get(mode); if (paths == null) - paths = new HashSet<String>(); + paths = new HashSet<>(); return paths; } }
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/lib/MutableObjectId.java b/org.eclipse.jgit/src/org/eclipse/jgit/lib/MutableObjectId.java index 1a49ae9..4b14d12 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/lib/MutableObjectId.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/lib/MutableObjectId.java
@@ -209,6 +209,24 @@ public void fromRaw(final int[] ints, final int p) { } /** + * Convert an ObjectId from binary representation expressed in integers. + * + * @param a + * @param b + * @param c + * @param d + * @param e + * @since 4.7 + */ + public void set(int a, int b, int c, int d, int e) { + w1 = a; + w2 = b; + w3 = c; + w4 = d; + w5 = e; + } + + /** * Convert an ObjectId from hex characters (US-ASCII). * * @param buf
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/lib/NullProgressMonitor.java b/org.eclipse.jgit/src/org/eclipse/jgit/lib/NullProgressMonitor.java index d05c8c6..497beb0 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/lib/NullProgressMonitor.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/lib/NullProgressMonitor.java
@@ -56,22 +56,27 @@ private NullProgressMonitor() { // Do not let others instantiate } + @Override public void start(int totalTasks) { // Do not report. } + @Override public void beginTask(String title, int totalWork) { // Do not report. } + @Override public void update(int completed) { // Do not report. } + @Override public boolean isCancelled() { return false; } + @Override public void endTask() { // Do not report. }
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/lib/ObjectChecker.java b/org.eclipse.jgit/src/org/eclipse/jgit/lib/ObjectChecker.java index feecbd8..d8ddcd5 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/lib/ObjectChecker.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/lib/ObjectChecker.java
@@ -44,6 +44,7 @@ package org.eclipse.jgit.lib; +import static org.eclipse.jgit.lib.Constants.DOT_GIT_MODULES; import static org.eclipse.jgit.lib.Constants.OBJECT_ID_LENGTH; import static org.eclipse.jgit.lib.Constants.OBJECT_ID_STRING_LENGTH; import static org.eclipse.jgit.lib.Constants.OBJ_BAD; @@ -84,8 +85,10 @@ import java.text.MessageFormat; import java.text.Normalizer; +import java.util.ArrayList; import java.util.EnumSet; import java.util.HashSet; +import java.util.List; import java.util.Locale; import java.util.Set; @@ -136,6 +139,9 @@ public class ObjectChecker { /** Header "tagger " */ public static final byte[] tagger = Constants.encodeASCII("tagger "); //$NON-NLS-1$ + /** Path ".gitmodules" */ + private static final byte[] dotGitmodules = Constants.encodeASCII(DOT_GIT_MODULES); + /** * Potential issues identified by the checker. * @@ -199,6 +205,8 @@ public String getMessageId() { private boolean windows; private boolean macosx; + private final List<GitmoduleEntry> gitsubmodules = new ArrayList<>(); + /** * Enable accepting specific malformed (but not horribly broken) objects. * @@ -611,7 +619,7 @@ public void checkTree(@Nullable AnyObjectId id, byte[] raw) int ptr = 0; int lastNameB = 0, lastNameE = 0, lastMode = 0; Set<String> normalized = windows || macosx - ? new HashSet<String>() + ? new HashSet<>() : null; while (ptr < sz) { @@ -678,9 +686,15 @@ public void checkTree(@Nullable AnyObjectId id, byte[] raw) throw new CorruptObjectException( JGitText.get().corruptObjectTruncatedInObjectId); } + if (ObjectId.zeroId().compareTo(raw, ptr - OBJECT_ID_LENGTH) == 0) { report(NULL_SHA1, id, JGitText.get().corruptObjectZeroId); } + + if (id != null && isGitmodules(raw, lastNameB, lastNameE, id)) { + ObjectId blob = ObjectId.fromRaw(raw, ptr - OBJECT_ID_LENGTH); + gitsubmodules.add(new GitmoduleEntry(id, blob)); + } } } @@ -845,10 +859,9 @@ private void checkPathSegment2(byte[] raw, int ptr, int end, // Mac's HFS+ folds permutations of ".git" and Unicode ignorable characters // to ".git" therefore we should prevent such names - private boolean isMacHFSGit(byte[] raw, int ptr, int end, + private boolean isMacHFSPath(byte[] raw, int ptr, int end, byte[] path, @Nullable AnyObjectId id) throws CorruptObjectException { boolean ignorable = false; - byte[] git = new byte[] { '.', 'g', 'i', 't' }; int g = 0; while (ptr < end) { switch (raw[ptr]) { @@ -904,17 +917,31 @@ private boolean isMacHFSGit(byte[] raw, int ptr, int end, } return false; default: - if (g == 4) + if (g == path.length) { return false; - if (raw[ptr++] != git[g++]) + } + if (toLower(raw[ptr++]) != path[g++]) { return false; + } } } - if (g == 4 && ignorable) + if (g == path.length && ignorable) { return true; + } return false; } + private boolean isMacHFSGit(byte[] raw, int ptr, int end, + @Nullable AnyObjectId id) throws CorruptObjectException { + byte[] git = new byte[] { '.', 'g', 'i', 't' }; + return isMacHFSPath(raw, ptr, end, git, id); + } + + private boolean isMacHFSGitmodules(byte[] raw, int ptr, int end, + @Nullable AnyObjectId id) throws CorruptObjectException { + return isMacHFSPath(raw, ptr, end, dotGitmodules, id); + } + private boolean checkTruncatedIgnorableUTF8(byte[] raw, int ptr, int end, @Nullable AnyObjectId id) throws CorruptObjectException { if ((ptr + 2) >= end) { @@ -1021,6 +1048,104 @@ && toLower(buf[p + 1]) == 'i' && toLower(buf[p + 2]) == 't'; } + /** + * Check if the filename contained in buf[start:end] could be read as a + * .gitmodules file when checked out to the working directory. + * + * This ought to be a simple comparison, but some filesystems have peculiar + * rules for normalizing filenames: + * + * NTFS has backward-compatibility support for 8.3 synonyms of long file + * names (see + * https://web.archive.org/web/20160318181041/https://usn.pw/blog/gen/2015/06/09/filenames/ + * for details). NTFS is also case-insensitive. + * + * MacOS's HFS+ folds away ignorable Unicode characters in addition to case + * folding. + * + * @param buf + * byte array to decode + * @param start + * position where a supposed filename is starting + * @param end + * position where a supposed filename is ending + * @param id + * object id for error reporting + * + * @return true if the filename in buf could be a ".gitmodules" file + * @throws CorruptObjectException + */ + private boolean isGitmodules(byte[] buf, int start, int end, @Nullable AnyObjectId id) + throws CorruptObjectException { + // Simple cases first. + if (end - start < 8) { + return false; + } + return (end - start == dotGitmodules.length + && RawParseUtils.match(buf, start, dotGitmodules) != -1) + || (macosx && isMacHFSGitmodules(buf, start, end, id)) + || (windows && isNTFSGitmodules(buf, start, end)); + } + + private boolean matchLowerCase(byte[] b, int ptr, byte[] src) { + if (ptr + src.length > b.length) { + return false; + } + for (int i = 0; i < src.length; i++, ptr++) { + if (toLower(b[ptr]) != src[i]) { + return false; + } + } + return true; + } + + // .gitmodules, case-insensitive, or an 8.3 abbreviation of the same. + private boolean isNTFSGitmodules(byte[] buf, int start, int end) { + if (end - start == 11) { + return matchLowerCase(buf, start, dotGitmodules); + } + + if (end - start != 8) { + return false; + } + + // "gitmod" or a prefix of "gi7eba", followed by... + byte[] gitmod = new byte[]{'g', 'i', 't', 'm', 'o', 'd', '~'}; + if (matchLowerCase(buf, start, gitmod)) { + start += 6; + } else { + byte[] gi7eba = new byte[]{'g', 'i', '7', 'e', 'b', 'a'}; + for (int i = 0; i < gi7eba.length; i++, start++) { + byte c = (byte) toLower(buf[start]); + if (c == '~') { + break; + } + if (c != gi7eba[i]) { + return false; + } + } + } + + // ... ~ and a number + if (end - start < 2) { + return false; + } + if (buf[start] != '~') { + return false; + } + start++; + if (buf[start] < '1' || buf[start] > '9') { + return false; + } + start++; + for (; start != end; start++) { + if (buf[start] < '0' || buf[start] > '9') { + return false; + } + } + return true; + } + private static boolean isGitTilde1(byte[] buf, int p, int end) { if (end - p != 5) return false; @@ -1082,4 +1207,17 @@ private String normalize(byte[] raw, int ptr, int end) { String n = RawParseUtils.decode(raw, ptr, end).toLowerCase(Locale.US); return macosx ? Normalizer.normalize(n, Normalizer.Form.NFC) : n; } + + /** + * Get the list of ".gitmodules" files found in the pack. For each, report + * its blob id (e.g. to validate its contents) and the tree where it was + * found (e.g. to check if it is in the root) + * + * @return List of pairs of ids {@literal <tree, blob>}. + * + * @since 4.7.5 + */ + public List<GitmoduleEntry> getGitsubmodules() { + return gitsubmodules; + } }
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/lib/ObjectId.java b/org.eclipse.jgit/src/org/eclipse/jgit/lib/ObjectId.java index 2a2d67d..991f03f 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/lib/ObjectId.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/lib/ObjectId.java
@@ -248,8 +248,17 @@ private static final ObjectId fromHexString(final byte[] bs, int p) { } } - ObjectId(final int new_1, final int new_2, final int new_3, - final int new_4, final int new_5) { + /** + * Construct an ObjectId from 160 bits provided in 5 words. + * + * @param new_1 + * @param new_2 + * @param new_3 + * @param new_4 + * @param new_5 + * @since 4.7 + */ + public ObjectId(int new_1, int new_2, int new_3, int new_4, int new_5) { w1 = new_1; w2 = new_2; w3 = new_3;
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/lib/ObjectIdRef.java b/org.eclipse.jgit/src/org/eclipse/jgit/lib/ObjectIdRef.java index c286f5e..636716b 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/lib/ObjectIdRef.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/lib/ObjectIdRef.java
@@ -67,11 +67,13 @@ public Unpeeled(@NonNull Storage st, @NonNull String name, super(st, name, id); } + @Override @Nullable public ObjectId getPeeledObjectId() { return null; } + @Override public boolean isPeeled() { return false; } @@ -99,11 +101,13 @@ public PeeledTag(@NonNull Storage st, @NonNull String name, peeledObjectId = p; } + @Override @NonNull public ObjectId getPeeledObjectId() { return peeledObjectId; } + @Override public boolean isPeeled() { return true; } @@ -127,11 +131,13 @@ public PeeledNonTag(@NonNull Storage st, @NonNull String name, super(st, name, id); } + @Override @Nullable public ObjectId getPeeledObjectId() { return null; } + @Override public boolean isPeeled() { return true; } @@ -161,30 +167,36 @@ protected ObjectIdRef(@NonNull Storage st, @NonNull String name, this.objectId = id; } + @Override @NonNull public String getName() { return name; } + @Override public boolean isSymbolic() { return false; } + @Override @NonNull public Ref getLeaf() { return this; } + @Override @NonNull public Ref getTarget() { return this; } + @Override @Nullable public ObjectId getObjectId() { return objectId; } + @Override @NonNull public Storage getStorage() { return storage;
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/lib/ObjectIdSubclassMap.java b/org.eclipse.jgit/src/org/eclipse/jgit/lib/ObjectIdSubclassMap.java index faed64b..43fc7bf 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/lib/ObjectIdSubclassMap.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/lib/ObjectIdSubclassMap.java
@@ -111,6 +111,7 @@ public V get(final AnyObjectId toFind) { * object to find. * @return true if the mapping exists for this object; false otherwise. */ + @Override public boolean contains(final AnyObjectId toFind) { return get(toFind) != null; } @@ -187,16 +188,19 @@ public boolean isEmpty() { return size == 0; } + @Override public Iterator<V> iterator() { return new Iterator<V>() { private int found; private int i; + @Override public boolean hasNext() { return found < size; } + @Override public V next() { while (i < table.length) { final V v = table[i++]; @@ -208,6 +212,7 @@ public V next() { throw new NoSuchElementException(); } + @Override public void remove() { throw new UnsupportedOperationException(); }
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 4c51279..857ec9b 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/lib/ObjectInserter.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/lib/ObjectInserter.java
@@ -50,10 +50,10 @@ import java.io.EOFException; import java.io.IOException; import java.io.InputStream; -import java.security.MessageDigest; import org.eclipse.jgit.internal.JGitText; import org.eclipse.jgit.transport.PackParser; +import org.eclipse.jgit.util.sha1.SHA1; /** * Inserts objects into an existing {@code ObjectDatabase}. @@ -107,41 +107,50 @@ public static abstract class Filter extends ObjectInserter { return delegate().buffer(); } + @Override public ObjectId idFor(int type, byte[] data) { return delegate().idFor(type, data); } + @Override public ObjectId idFor(int type, byte[] data, int off, int len) { return delegate().idFor(type, data, off, len); } + @Override public ObjectId idFor(int objectType, long length, InputStream in) throws IOException { return delegate().idFor(objectType, length, in); } + @Override public ObjectId idFor(TreeFormatter formatter) { return delegate().idFor(formatter); } + @Override public ObjectId insert(int type, byte[] data) throws IOException { return delegate().insert(type, data); } + @Override public ObjectId insert(int type, byte[] data, int off, int len) throws IOException { return delegate().insert(type, data, off, len); } + @Override public ObjectId insert(int objectType, long length, InputStream in) throws IOException { return delegate().insert(objectType, length, in); } + @Override public PackParser newPackParser(InputStream in) throws IOException { return delegate().newPackParser(in); } + @Override public ObjectReader newReader() { final ObjectReader dr = delegate().newReader(); return new ObjectReader.Filter() { @@ -157,24 +166,24 @@ public ObjectInserter getCreatedFromInserter() { }; } + @Override public void flush() throws IOException { delegate().flush(); } + @Override public void close() { delegate().close(); } } - /** Digest to compute the name of an object. */ - private final MessageDigest digest; + private final SHA1 hasher = SHA1.newInstance(); /** Temporary working buffer for streaming data through. */ private byte[] tempBuffer; /** Create a new inserter for a database. */ protected ObjectInserter() { - digest = Constants.newMessageDigest(); } /** @@ -208,10 +217,12 @@ protected ObjectInserter() { return b; } - /** @return digest to help compute an ObjectId */ - protected MessageDigest digest() { - digest.reset(); - return digest; + /** + * @return digest to help compute an ObjectId + * @since 4.7 + */ + protected SHA1 digest() { + return hasher.reset(); } /** @@ -241,13 +252,13 @@ public ObjectId idFor(int type, byte[] data) { * @return the name of the object. */ public ObjectId idFor(int type, byte[] data, int off, int len) { - MessageDigest md = digest(); + SHA1 md = SHA1.newInstance(); md.update(Constants.encodedTypeString(type)); md.update((byte) ' '); md.update(Constants.encodeASCII(len)); md.update((byte) 0); md.update(data, off, len); - return ObjectId.fromRaw(md.digest()); + return md.toObjectId(); } /** @@ -266,7 +277,7 @@ public ObjectId idFor(int type, byte[] data, int off, int len) { */ public ObjectId idFor(int objectType, long length, InputStream in) throws IOException { - MessageDigest md = digest(); + SHA1 md = SHA1.newInstance(); md.update(Constants.encodedTypeString(objectType)); md.update((byte) ' '); md.update(Constants.encodeASCII(length)); @@ -279,7 +290,7 @@ public ObjectId idFor(int objectType, long length, InputStream in) md.update(buf, 0, n); length -= n; } - return ObjectId.fromRaw(md.digest()); + return md.toObjectId(); } /**
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 372da98..f39f291 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/lib/ObjectReader.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/lib/ObjectReader.java
@@ -134,7 +134,7 @@ public AbbreviatedObjectId abbreviate(AnyObjectId objectId, int len) Collection<ObjectId> matches = resolve(abbrev); while (1 < matches.size() && len < Constants.OBJECT_ID_STRING_LENGTH) { abbrev = objectId.abbreviate(++len); - List<ObjectId> n = new ArrayList<ObjectId>(8); + List<ObjectId> n = new ArrayList<>(8); for (ObjectId candidate : matches) { if (abbrev.prefixCompare(candidate) == 0) n.add(candidate); @@ -286,6 +286,7 @@ public <T extends ObjectId> AsyncObjectLoaderQueue<T> open( return new AsyncObjectLoaderQueue<T>() { private T cur; + @Override public boolean next() throws MissingObjectException, IOException { if (idItr.hasNext()) { cur = idItr.next(); @@ -295,22 +296,27 @@ public boolean next() throws MissingObjectException, IOException { } } + @Override public T getCurrent() { return cur; } + @Override public ObjectId getObjectId() { return cur; } + @Override public ObjectLoader open() throws IOException { return ObjectReader.this.open(cur, OBJ_ANY); } + @Override public boolean cancel(boolean mayInterruptIfRunning) { return true; } + @Override public void release() { // Since we are sequential by default, we don't // have any state to clean up if we terminate early. @@ -370,6 +376,7 @@ public <T extends ObjectId> AsyncObjectSizeQueue<T> getObjectSize( private long sz; + @Override public boolean next() throws MissingObjectException, IOException { if (idItr.hasNext()) { cur = idItr.next(); @@ -380,22 +387,27 @@ public boolean next() throws MissingObjectException, IOException { } } + @Override public T getCurrent() { return cur; } + @Override public ObjectId getObjectId() { return cur; } + @Override public long getSize() { return sz; } + @Override public boolean cancel(boolean mayInterruptIfRunning) { return true; } + @Override public void release() { // Since we are sequential by default, we don't // have any state to clean up if we terminate early.
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/lib/PersonIdent.java b/org.eclipse.jgit/src/org/eclipse/jgit/lib/PersonIdent.java index 627ccaa..45757e4 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/lib/PersonIdent.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/lib/PersonIdent.java
@@ -336,6 +336,7 @@ public int getTimeZoneOffset() { /** * Hashcode is based only on the email address and timestamp. */ + @Override public int hashCode() { int hc = getEmailAddress().hashCode(); hc *= 31; @@ -343,6 +344,7 @@ public int hashCode() { return hc; } + @Override public boolean equals(final Object o) { if (o instanceof PersonIdent) { final PersonIdent p = (PersonIdent) o; @@ -370,6 +372,7 @@ public String toExternalString() { return r.toString(); } + @Override @SuppressWarnings("nls") public String toString() { final StringBuilder r = new StringBuilder();
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/lib/RebaseTodoFile.java b/org.eclipse.jgit/src/org/eclipse/jgit/lib/RebaseTodoFile.java index 75a3592..1047a6d 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/lib/RebaseTodoFile.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/lib/RebaseTodoFile.java
@@ -89,7 +89,7 @@ public List<RebaseTodoLine> readRebaseTodo(String path, byte[] buf = IO.readFully(new File(repo.getDirectory(), path)); int ptr = 0; int tokenBegin = 0; - List<RebaseTodoLine> r = new LinkedList<RebaseTodoLine>(); + List<RebaseTodoLine> r = new LinkedList<>(); while (ptr < buf.length) { tokenBegin = ptr; ptr = RawParseUtils.nextLF(buf, ptr);
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/lib/RefComparator.java b/org.eclipse.jgit/src/org/eclipse/jgit/lib/RefComparator.java index c6e1029..95e3386 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/lib/RefComparator.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/lib/RefComparator.java
@@ -60,6 +60,7 @@ public class RefComparator implements Comparator<Ref> { /** Singleton instance of RefComparator */ public static final RefComparator INSTANCE = new RefComparator(); + @Override public int compare(final Ref o1, final Ref o2) { return compareTo(o1, o2); } @@ -72,7 +73,7 @@ public int compare(final Ref o1, final Ref o2) { * @return sorted collection of refs */ public static Collection<Ref> sort(final Collection<Ref> refs) { - final List<Ref> r = new ArrayList<Ref>(refs); + final List<Ref> r = new ArrayList<>(refs); Collections.sort(r, INSTANCE); return r; }
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 517c8aa..59a104b 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/lib/RefDatabase.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/lib/RefDatabase.java
@@ -150,7 +150,7 @@ public Collection<String> getConflictingNames(String name) lastSlash = name.lastIndexOf('/', lastSlash - 1); } - List<String> conflicting = new ArrayList<String>(); + List<String> conflicting = new ArrayList<>(); // Cannot be the container of an existing reference. String prefix = name + '/'; for (String existing : allRefs.keySet())
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 c5b2ef8..aa70f42 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/lib/Repository.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/lib/Repository.java
@@ -4,6 +4,7 @@ * Copyright (C) 2006-2010, Robin Rosenberg <robin.rosenberg@dewire.com> * Copyright (C) 2006-2012, Shawn O. Pearce <spearce@spearce.org> * Copyright (C) 2012, Daniel Megert <daniel_megert@ch.ibm.com> + * Copyright (C) 2017, Wim Jongman <wim.jongman@remainsoftware.com> * and other copyright owners as documented in the project's IP log. * * This program and the accompanying materials are made available @@ -47,6 +48,8 @@ package org.eclipse.jgit.lib; +import static org.eclipse.jgit.lib.Constants.LOCK_SUFFIX; + import java.io.BufferedOutputStream; import java.io.File; import java.io.FileNotFoundException; @@ -65,6 +68,7 @@ import java.util.Set; import java.util.concurrent.atomic.AtomicInteger; import java.util.concurrent.atomic.AtomicLong; +import java.util.regex.Pattern; import org.eclipse.jgit.annotations.NonNull; import org.eclipse.jgit.annotations.Nullable; @@ -110,6 +114,17 @@ public abstract class Repository implements AutoCloseable { private static final Logger LOG = LoggerFactory.getLogger(Repository.class); private static final ListenerList globalListeners = new ListenerList(); + /** + * Branch names containing slashes should not have a name component that is + * one of the reserved device names on Windows. + * + * @see #normalizeBranchName(String) + */ + private static final Pattern FORBIDDEN_BRANCH_NAME_COMPONENTS = Pattern + .compile( + "(^|/)(aux|com[1-9]|con|lpt[1-9]|nul|prn)(\\.[^/]*)?", //$NON-NLS-1$ + Pattern.CASE_INSENSITIVE); + /** @return the global listener list observing all events in this JVM. */ public static ListenerList getGlobalListenerList() { return globalListeners; @@ -888,11 +903,12 @@ public void close() { } else if (newCount == -1) { // should not happen, only log when useCnt became negative to // minimize number of log entries + String message = MessageFormat.format(JGitText.get().corruptUseCnt, + toString()); if (LOG.isDebugEnabled()) { - IllegalStateException e = new IllegalStateException(); - LOG.debug(JGitText.get().corruptUseCnt, e); + LOG.debug(message, new IllegalStateException()); } else { - LOG.warn(JGitText.get().corruptUseCnt); + LOG.warn(message); } if (RepositoryCache.isCached(this)) { closedAt.set(System.currentTimeMillis()); @@ -910,7 +926,6 @@ protected void doClose() { getRefDatabase().close(); } - @SuppressWarnings("nls") @Override @NonNull public String toString() { @@ -921,7 +936,7 @@ public String toString() { else desc = getClass().getSimpleName() + "-" //$NON-NLS-1$ + System.identityHashCode(this); - return "Repository[" + desc + "]"; //$NON-NLS-1$ + return "Repository[" + desc + "]"; //$NON-NLS-1$ //$NON-NLS-2$ } /** @@ -1051,7 +1066,7 @@ public Map<String, Ref> getAllRefs() { try { return getRefDatabase().getRefs(RefDatabase.ALL); } catch (IOException e) { - return new HashMap<String, Ref>(); + return new HashMap<>(); } } @@ -1065,7 +1080,7 @@ public Map<String, Ref> getTags() { try { return getRefDatabase().getRefs(Constants.R_TAGS); } catch (IOException e) { - return new HashMap<String, Ref>(); + return new HashMap<>(); } } @@ -1100,7 +1115,7 @@ public Ref peel(final Ref ref) { @NonNull public Map<AnyObjectId, Set<Ref>> getAllRefsByPeeledObjectId() { Map<String, Ref> allRefs = getAllRefs(); - Map<AnyObjectId, Set<Ref>> ret = new HashMap<AnyObjectId, Set<Ref>>(allRefs.size()); + Map<AnyObjectId, Set<Ref>> ret = new HashMap<>(allRefs.size()); for (Ref ref : allRefs.values()) { ref = peel(ref); AnyObjectId target = ref.getPeeledObjectId(); @@ -1112,7 +1127,7 @@ public Map<AnyObjectId, Set<Ref>> getAllRefsByPeeledObjectId() { // that was not the case (rare) if (oset.size() == 1) { // Was a read-only singleton, we must copy to a new Set - oset = new HashSet<Ref>(oset); + oset = new HashSet<>(oset); } ret.put(target, oset); oset.add(ref); @@ -1280,10 +1295,12 @@ public RepositoryState getRepositoryState() { */ public static boolean isValidRefName(final String refName) { final int len = refName.length(); - if (len == 0) + if (len == 0) { return false; - if (refName.endsWith(".lock")) //$NON-NLS-1$ + } + if (refName.endsWith(LOCK_SUFFIX)) { return false; + } // Refs may be stored as loose files so invalid paths // on the local system must also be invalid refs. @@ -1331,12 +1348,105 @@ public static boolean isValidRefName(final String refName) { } /** + * Normalizes the passed branch name into a possible valid branch name. The + * validity of the returned name should be checked by a subsequent call to + * {@link #isValidRefName(String)}. + * <p/> + * Future implementations of this method could be more restrictive or more + * lenient about the validity of specific characters in the returned name. + * <p/> + * The current implementation returns the trimmed input string if this is + * already a valid branch name. Otherwise it returns a trimmed string with + * special characters not allowed by {@link #isValidRefName(String)} + * replaced by hyphens ('-') and blanks replaced by underscores ('_'). + * Leading and trailing slashes, dots, hyphens, and underscores are removed. + * + * @param name + * to normalize + * + * @return The normalized name or an empty String if it is {@code null} or + * empty. + * @since 4.7 + * @see #isValidRefName(String) + */ + public static String normalizeBranchName(String name) { + if (name == null || name.isEmpty()) { + return ""; //$NON-NLS-1$ + } + String result = name.trim(); + String fullName = result.startsWith(Constants.R_HEADS) ? result + : Constants.R_HEADS + result; + if (isValidRefName(fullName)) { + return result; + } + + // All Unicode blanks to underscore + result = result.replaceAll("(?:\\h|\\v)+", "_"); //$NON-NLS-1$ //$NON-NLS-2$ + StringBuilder b = new StringBuilder(); + char p = '/'; + for (int i = 0, len = result.length(); i < len; i++) { + char c = result.charAt(i); + if (c < ' ' || c == 127) { + continue; + } + // Substitute a dash for problematic characters + switch (c) { + case '\\': + case '^': + case '~': + case ':': + case '?': + case '*': + case '[': + case '@': + case '<': + case '>': + case '|': + case '"': + c = '-'; + break; + default: + break; + } + // Collapse multiple slashes, dashes, dots, underscores, and omit + // dashes, dots, and underscores following a slash. + switch (c) { + case '/': + if (p == '/') { + continue; + } + p = '/'; + break; + case '.': + case '_': + case '-': + if (p == '/' || p == '-') { + continue; + } + p = '-'; + break; + default: + p = c; + break; + } + b.append(c); + } + // Strip trailing special characters, and avoid the .lock extension + result = b.toString().replaceFirst("[/_.-]+$", "") //$NON-NLS-1$ //$NON-NLS-2$ + .replaceAll("\\.lock($|/)", "_lock$1"); //$NON-NLS-1$ //$NON-NLS-2$ + return FORBIDDEN_BRANCH_NAME_COMPONENTS.matcher(result) + .replaceAll("$1+$2$3"); //$NON-NLS-1$ + } + + /** * Strip work dir and return normalized repository path. * - * @param workDir Work dir - * @param file File whose path shall be stripped of its workdir - * @return normalized repository relative path or the empty - * string if the file is not relative to the work directory. + * @param workDir + * Work dir + * @param file + * File whose path shall be stripped of its workdir + * @return normalized repository relative path or the empty string if the + * file is not relative to the work directory. */ @NonNull public static String stripWorkDir(File workDir, File file) { @@ -1574,7 +1684,7 @@ public List<ObjectId> readMergeHeads() throws IOException, NoWorkTreeException { if (raw == null) return null; - LinkedList<ObjectId> heads = new LinkedList<ObjectId>(); + LinkedList<ObjectId> heads = new LinkedList<>(); for (int p = 0; p < raw.length;) { heads.add(ObjectId.fromString(raw, p)); p = RawParseUtils
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 2f1a9e1..baa5286 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/lib/RepositoryCache.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/lib/RepositoryCache.java
@@ -300,7 +300,7 @@ private void unregisterAndCloseRepository(final Key location) { } private Collection<Key> getKeys() { - return new ArrayList<Key>(cacheMap.keySet()); + return new ArrayList<>(cacheMap.keySet()); } private void clearAllExpired() {
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/lib/SubmoduleConfig.java b/org.eclipse.jgit/src/org/eclipse/jgit/lib/SubmoduleConfig.java new file mode 100644 index 0000000..3126160 --- /dev/null +++ b/org.eclipse.jgit/src/org/eclipse/jgit/lib/SubmoduleConfig.java
@@ -0,0 +1,86 @@ +/* + * Copyright (C) 2017, David Pursehouse <david.pursehouse@gmail.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.lib; + +/** + * Submodule section of a Git configuration file. + * + * @since 4.7 + */ +public class SubmoduleConfig { + + /** + * Config values for submodule.[name].fetchRecurseSubmodules. + */ + public enum FetchRecurseSubmodulesMode implements Config.ConfigEnum { + /** Unconditionally recurse into all populated submodules. */ + YES("true"), //$NON-NLS-1$ + + /** + * Only recurse into a populated submodule when the superproject + * retrieves a commit that updates the submodule's reference to a commit + * that isn't already in the local submodule clone. + */ + ON_DEMAND("on-demand"), //$NON-NLS-1$ + + /** Completely disable recursion. */ + NO("false"); //$NON-NLS-1$ + + private final String configValue; + + private FetchRecurseSubmodulesMode(String configValue) { + this.configValue = configValue; + } + + @Override + public String toConfigValue() { + return configValue; + } + + @Override + public boolean matchConfigValue(String s) { + return configValue.equals(s); + } + } +}
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/lib/SymbolicRef.java b/org.eclipse.jgit/src/org/eclipse/jgit/lib/SymbolicRef.java index eeab921..71d5cd7 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/lib/SymbolicRef.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/lib/SymbolicRef.java
@@ -70,15 +70,18 @@ public SymbolicRef(@NonNull String refName, @NonNull Ref target) { this.target = target; } + @Override @NonNull public String getName() { return name; } + @Override public boolean isSymbolic() { return true; } + @Override @NonNull public Ref getLeaf() { Ref dst = getTarget(); @@ -87,26 +90,31 @@ public Ref getLeaf() { return dst; } + @Override @NonNull public Ref getTarget() { return target; } + @Override @Nullable public ObjectId getObjectId() { return getLeaf().getObjectId(); } + @Override @NonNull public Storage getStorage() { return Storage.LOOSE; } + @Override @Nullable public ObjectId getPeeledObjectId() { return getLeaf().getPeeledObjectId(); } + @Override public boolean isPeeled() { return getLeaf().isPeeled(); }
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/lib/ThreadSafeProgressMonitor.java b/org.eclipse.jgit/src/org/eclipse/jgit/lib/ThreadSafeProgressMonitor.java index ff85f9b..5824a55 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/lib/ThreadSafeProgressMonitor.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/lib/ThreadSafeProgressMonitor.java
@@ -87,12 +87,14 @@ public ThreadSafeProgressMonitor(ProgressMonitor pm) { this.process = new Semaphore(0); } + @Override public void start(int totalTasks) { if (!isMainThread()) throw new IllegalStateException(); pm.start(totalTasks); } + @Override public void beginTask(String title, int totalWork) { if (!isMainThread()) throw new IllegalStateException(); @@ -156,11 +158,13 @@ private void doUpdates() { pm.update(cnt); } + @Override public void update(int completed) { if (0 == pendingUpdates.getAndAdd(completed)) process.release(); } + @Override public boolean isCancelled() { lock.lock(); try { @@ -170,6 +174,7 @@ public boolean isCancelled() { } } + @Override public void endTask() { if (!isMainThread()) throw new IllegalStateException();
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/lib/UserConfig.java b/org.eclipse.jgit/src/org/eclipse/jgit/lib/UserConfig.java index b8d236c..bd393dd 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/lib/UserConfig.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/lib/UserConfig.java
@@ -52,6 +52,7 @@ public class UserConfig { /** Key for {@link Config#get(SectionParser)}. */ public static final Config.SectionParser<UserConfig> KEY = new SectionParser<UserConfig>() { + @Override public UserConfig parse(final Config cfg) { return new UserConfig(cfg); }
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/lib/WorkQueue.java b/org.eclipse.jgit/src/org/eclipse/jgit/lib/WorkQueue.java index 9735d19..07b87f5 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/lib/WorkQueue.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/lib/WorkQueue.java
@@ -67,6 +67,7 @@ class WorkQueue { private final ThreadFactory baseFactory = Executors .defaultThreadFactory(); + @Override public Thread newThread(Runnable taskBody) { Thread thr = baseFactory.newThread(taskBody); thr.setName("JGit-WorkQueue"); //$NON-NLS-1$
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 112550a..04c65ef 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/merge/MergeAlgorithm.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/merge/MergeAlgorithm.java
@@ -98,11 +98,11 @@ public MergeAlgorithm(DiffAlgorithm diff) { */ public <S extends Sequence> MergeResult<S> merge( SequenceComparator<S> cmp, S base, S ours, S theirs) { - List<S> sequences = new ArrayList<S>(3); + List<S> sequences = new ArrayList<>(3); sequences.add(base); sequences.add(ours); sequences.add(theirs); - MergeResult<S> result = new MergeResult<S>(sequences); + MergeResult<S> result = new MergeResult<>(sequences); if (ours.size() == 0) { if (theirs.size() != 0) {
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 83b143b..d059391 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/merge/MergeConfig.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/merge/MergeConfig.java
@@ -167,6 +167,7 @@ public MergeConfigSectionParser(String branch) { this.branch = branch; } + @Override public MergeConfig parse(Config cfg) { return new MergeConfig(branch, cfg); }
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/merge/MergeFormatter.java b/org.eclipse.jgit/src/org/eclipse/jgit/merge/MergeFormatter.java index ee6095a..43876a6 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/merge/MergeFormatter.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/merge/MergeFormatter.java
@@ -105,7 +105,7 @@ public void formatMerge(OutputStream out, MergeResult<RawText> res, @SuppressWarnings("unchecked") public void formatMerge(OutputStream out, MergeResult res, String baseName, String oursName, String theirsName, String charsetName) throws IOException { - List<String> names = new ArrayList<String>(3); + List<String> names = new ArrayList<>(3); names.add(baseName); names.add(oursName); names.add(theirsName);
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 82cbf36..ca0e18a 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/merge/MergeMessageFormatter.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/merge/MergeMessageFormatter.java
@@ -71,11 +71,11 @@ public String format(List<Ref> refsToMerge, Ref target) { StringBuilder sb = new StringBuilder(); sb.append("Merge "); //$NON-NLS-1$ - List<String> branches = new ArrayList<String>(); - List<String> remoteBranches = new ArrayList<String>(); - List<String> tags = new ArrayList<String>(); - List<String> commits = new ArrayList<String>(); - List<String> others = new ArrayList<String>(); + List<String> branches = new ArrayList<>(); + List<String> remoteBranches = new ArrayList<>(); + List<String> tags = new ArrayList<>(); + List<String> commits = new ArrayList<>(); + List<String> others = new ArrayList<>(); for (Ref ref : refsToMerge) { if (ref.getName().startsWith(Constants.R_HEADS)) { branches.add("'" + Repository.shortenRefName(ref.getName()) //$NON-NLS-1$ @@ -95,7 +95,7 @@ public String format(List<Ref> refsToMerge, Ref target) { } } - List<String> listings = new ArrayList<String>(); + List<String> listings = new ArrayList<>(); if (!branches.isEmpty()) listings.add(joinNames(branches, "branch", "branches")); //$NON-NLS-1$//$NON-NLS-2$
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/merge/MergeResult.java b/org.eclipse.jgit/src/org/eclipse/jgit/merge/MergeResult.java index 106f9c7..ff3c8ab 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/merge/MergeResult.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/merge/MergeResult.java
@@ -133,14 +133,17 @@ public List<S> getSequences() { * @return an iterator over the MergeChunks. The iterator does not support * the remove operation */ + @Override public Iterator<MergeChunk> iterator() { return new Iterator<MergeChunk>() { int idx; + @Override public boolean hasNext() { return (idx < chunks.size()); } + @Override public MergeChunk next() { ConflictState state = states[chunks.get(idx++)]; int srcIdx = chunks.get(idx++); @@ -149,6 +152,7 @@ public MergeChunk next() { return new MergeChunk(srcIdx, begin, end, state); } + @Override public void remove() { throw new UnsupportedOperationException(); }
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/merge/MergeStrategy.java b/org.eclipse.jgit/src/org/eclipse/jgit/merge/MergeStrategy.java index c5e615e..656480e 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/merge/MergeStrategy.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/merge/MergeStrategy.java
@@ -80,7 +80,7 @@ public abstract class MergeStrategy { */ public static final ThreeWayMergeStrategy RECURSIVE = new StrategyRecursive(); - private static final HashMap<String, MergeStrategy> STRATEGIES = new HashMap<String, MergeStrategy>(); + private static final HashMap<String, MergeStrategy> STRATEGIES = new HashMap<>(); static { register(OURS);
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/merge/RecursiveMerger.java b/org.eclipse.jgit/src/org/eclipse/jgit/merge/RecursiveMerger.java index e055644..f8e1998 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/merge/RecursiveMerger.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/merge/RecursiveMerger.java
@@ -147,7 +147,7 @@ protected RevCommit getBaseCommit(RevCommit a, RevCommit b) */ protected RevCommit getBaseCommit(RevCommit a, RevCommit b, int callDepth) throws IOException { - ArrayList<RevCommit> baseCommits = new ArrayList<RevCommit>(); + ArrayList<RevCommit> baseCommits = new ArrayList<>(); walk.reset(); walk.setRevFilter(RevFilter.MERGE_BASE); walk.markStart(a); @@ -181,7 +181,7 @@ protected RevCommit getBaseCommit(RevCommit a, RevCommit b, int callDepth) dircache = DirCache.read(reader, currentBase.getTree()); inCore = true; - List<RevCommit> parents = new ArrayList<RevCommit>(); + List<RevCommit> parents = new ArrayList<>(); parents.add(currentBase); for (int commitIdx = 1; commitIdx < baseCommits.size(); commitIdx++) { RevCommit nextBase = baseCommits.get(commitIdx);
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 fd5e7ef..90107be 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/merge/ResolveMerger.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/merge/ResolveMerger.java
@@ -180,14 +180,14 @@ public enum MergeFailureReason { * * @since 3.4 */ - protected List<String> unmergedPaths = new ArrayList<String>(); + protected List<String> unmergedPaths = new ArrayList<>(); /** * Files modified during this merge operation. * * @since 3.4 */ - protected List<String> modifiedFiles = new LinkedList<String>(); + protected List<String> modifiedFiles = new LinkedList<>(); /** * If the merger has nothing to do for a file but check it out at the end of @@ -195,7 +195,7 @@ public enum MergeFailureReason { * * @since 3.4 */ - protected Map<String, DirCacheEntry> toBeCheckedOut = new HashMap<String, DirCacheEntry>(); + protected Map<String, DirCacheEntry> toBeCheckedOut = new HashMap<>(); /** * Paths in this list will be deleted from the local copy at the end of the @@ -203,7 +203,7 @@ public enum MergeFailureReason { * * @since 3.4 */ - protected List<String> toBeDeleted = new ArrayList<String>(); + protected List<String> toBeDeleted = new ArrayList<>(); /** * Low-level textual merge results. Will be passed on to the callers in case @@ -211,14 +211,14 @@ public enum MergeFailureReason { * * @since 3.4 */ - protected Map<String, MergeResult<? extends Sequence>> mergeResults = new HashMap<String, MergeResult<? extends Sequence>>(); + protected Map<String, MergeResult<? extends Sequence>> mergeResults = new HashMap<>(); /** * Paths for which the merge failed altogether. * * @since 3.4 */ - protected Map<String, MergeFailureReason> failingPaths = new HashMap<String, MergeFailureReason>(); + protected Map<String, MergeFailureReason> failingPaths = new HashMap<>(); /** * Updated as we merge entries of the tree walk. Tells us whether we should @@ -393,7 +393,7 @@ private DirCacheEntry add(byte[] path, CanonicalTreeParser p, int stage, * @return the entry which was added to the index */ private DirCacheEntry keep(DirCacheEntry e) { - DirCacheEntry newEntry = new DirCacheEntry(e.getPathString(), + DirCacheEntry newEntry = new DirCacheEntry(e.getRawPath(), e.getStage()); newEntry.setFileMode(e.getFileMode()); newEntry.setObjectId(e.getObjectId()); @@ -518,7 +518,7 @@ protected boolean processEntry(CanonicalTreeParser base, unmergedPaths.add(tw.getPathString()); mergeResults.put( tw.getPathString(), - new MergeResult<RawText>(Collections + new MergeResult<>(Collections .<RawText> emptyList())); } return true;
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/nls/GlobalBundleCache.java b/org.eclipse.jgit/src/org/eclipse/jgit/nls/GlobalBundleCache.java index d880d9b..fd425ab 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/nls/GlobalBundleCache.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/nls/GlobalBundleCache.java
@@ -65,7 +65,7 @@ */ class GlobalBundleCache { private static final Map<Locale, Map<Class, TranslationBundle>> cachedBundles - = new HashMap<Locale, Map<Class, TranslationBundle>>(); + = new HashMap<>(); /** * Looks up for a translation bundle in the global cache. If found returns @@ -87,7 +87,7 @@ static synchronized <T extends TranslationBundle> T lookupBundle(Locale locale, try { Map<Class, TranslationBundle> bundles = cachedBundles.get(locale); if (bundles == null) { - bundles = new HashMap<Class, TranslationBundle>(); + bundles = new HashMap<>(); cachedBundles.put(locale, bundles); } TranslationBundle bundle = bundles.get(type);
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 a768c25..5e7beed 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/nls/NLS.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/nls/NLS.java
@@ -72,6 +72,7 @@ public class NLS { public static final Locale ROOT_LOCALE = new Locale("", "", ""); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ private static final InheritableThreadLocal<NLS> local = new InheritableThreadLocal<NLS>() { + @Override protected NLS initialValue() { return new NLS(Locale.getDefault()); } @@ -119,7 +120,7 @@ public static <T extends TranslationBundle> T getBundleFor(Class<T> type) { } final private Locale locale; - final private ConcurrentHashMap<Class, TranslationBundle> map = new ConcurrentHashMap<Class, TranslationBundle>(); + final private ConcurrentHashMap<Class, TranslationBundle> map = new ConcurrentHashMap<>(); private NLS(Locale locale) { this.locale = locale;
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/notes/DefaultNoteMerger.java b/org.eclipse.jgit/src/org/eclipse/jgit/notes/DefaultNoteMerger.java index db49448..2e7327c 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/notes/DefaultNoteMerger.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/notes/DefaultNoteMerger.java
@@ -67,6 +67,7 @@ */ public class DefaultNoteMerger implements NoteMerger { + @Override public Note merge(Note base, Note ours, Note theirs, ObjectReader reader, ObjectInserter inserter) throws IOException { if (ours == null)
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 79fbb09..7827a9a 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/notes/FanoutBucket.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/notes/FanoutBucket.java
@@ -140,6 +140,7 @@ Iterator<Note> iterator(AnyObjectId objId, final ObjectReader reader) private Iterator<Note> itr; + @Override public boolean hasNext() { if (itr != null && itr.hasNext()) return true; @@ -164,6 +165,7 @@ public boolean hasNext() { return false; } + @Override public Note next() { if (hasNext()) return itr.next(); @@ -171,6 +173,7 @@ public Note next() { throw new NoSuchElementException(); } + @Override public void remove() { throw new UnsupportedOperationException(); } @@ -259,6 +262,7 @@ ObjectId writeTree(ObjectInserter inserter) throws IOException { return inserter.insert(build(true, inserter)); } + @Override ObjectId getTreeId() { try (ObjectInserter.Formatter f = new ObjectInserter.Formatter()) { return f.idFor(build(false, null));
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 41f7501..1be5251 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/notes/LeafBucket.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/notes/LeafBucket.java
@@ -122,10 +122,12 @@ Iterator<Note> iterator(AnyObjectId objId, ObjectReader reader) { return new Iterator<Note>() { private int idx; + @Override public boolean hasNext() { return idx < cnt; } + @Override public Note next() { if (hasNext()) return notes[idx++]; @@ -133,6 +135,7 @@ public Note next() { throw new NoSuchElementException(); } + @Override public void remove() { throw new UnsupportedOperationException(); } @@ -144,6 +147,7 @@ int estimateSize(AnyObjectId noteOn, ObjectReader or) throws IOException { return cnt; } + @Override InMemoryNoteBucket set(AnyObjectId noteOn, AnyObjectId noteData, ObjectReader or) throws IOException { int p = search(noteOn);
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 25b2ae8..44c5926 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/notes/NoteMap.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/notes/NoteMap.java
@@ -201,6 +201,7 @@ private NoteMap(ObjectReader reader) { * @return an iterator that iterates over notes of this NoteMap. Non note * entries are ignored by this iterator. */ + @Override public Iterator<Note> iterator() { try { return root.iterator(new MutableObjectId(), reader);
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/patch/CombinedFileHeader.java b/org.eclipse.jgit/src/org/eclipse/jgit/patch/CombinedFileHeader.java index b104a49..2c8f34e 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/patch/CombinedFileHeader.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/patch/CombinedFileHeader.java
@@ -183,7 +183,7 @@ int parseGitHeaders(int ptr, final int end) { protected void parseIndexLine(int ptr, final int eol) { // "index $asha1,$bsha1..$csha1" // - final List<AbbreviatedObjectId> ids = new ArrayList<AbbreviatedObjectId>(); + final List<AbbreviatedObjectId> ids = new ArrayList<>(); while (ptr < eol) { final int comma = nextLF(buf, ptr, ','); if (eol <= comma)
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 eb2bfac..ed79787 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/patch/CombinedHunkHeader.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/patch/CombinedHunkHeader.java
@@ -266,6 +266,7 @@ void extractFileLines(final OutputStream[] out) throws IOException { } } + @Override void extractFileLines(final StringBuilder sb, final String[] text, final int[] offsets) { final byte[] buf = file.buf;
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 534c827..eb28a0e 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/patch/FileHeader.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/patch/FileHeader.java
@@ -305,7 +305,7 @@ void addHunk(final HunkHeader h) { if (h.getFileHeader() != this) throw new IllegalArgumentException(JGitText.get().hunkBelongsToAnotherFile); if (hunks == null) - hunks = new ArrayList<HunkHeader>(); + hunks = new ArrayList<>(); hunks.add(h); }
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 245b3ee..767cb24 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/patch/FormatError.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/patch/FormatError.java
@@ -43,6 +43,8 @@ package org.eclipse.jgit.patch; +import java.util.Locale; + import org.eclipse.jgit.lib.Constants; import org.eclipse.jgit.util.RawParseUtils; @@ -102,7 +104,7 @@ public String getLineText() { @Override public String toString() { final StringBuilder r = new StringBuilder(); - r.append(getSeverity().name().toLowerCase()); + r.append(getSeverity().name().toLowerCase(Locale.ROOT)); r.append(": at offset "); //$NON-NLS-1$ r.append(getOffset()); r.append(": "); //$NON-NLS-1$
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/patch/Patch.java b/org.eclipse.jgit/src/org/eclipse/jgit/patch/Patch.java index 40ea77e..10ac449d 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/patch/Patch.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/patch/Patch.java
@@ -83,8 +83,8 @@ public class Patch { /** Create an empty patch. */ public Patch() { - files = new ArrayList<FileHeader>(); - errors = new ArrayList<FormatError>(0); + files = new ArrayList<>(); + errors = new ArrayList<>(0); } /**
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 6102a81..a8eb86e 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/revplot/PlotCommitList.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/revplot/PlotCommitList.java
@@ -74,12 +74,12 @@ public class PlotCommitList<L extends PlotLane> extends private int positionsAllocated; - private final TreeSet<Integer> freePositions = new TreeSet<Integer>(); + private final TreeSet<Integer> freePositions = new TreeSet<>(); - private final HashSet<PlotLane> activeLanes = new HashSet<PlotLane>(32); + private final HashSet<PlotLane> activeLanes = new HashSet<>(32); /** number of (child) commits on a lane */ - private final HashMap<PlotLane, Integer> laneLength = new HashMap<PlotLane, Integer>( + private final HashMap<PlotLane, Integer> laneLength = new HashMap<>( 32); @Override
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 55cf235..be1f07a 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/revplot/PlotWalk.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/revplot/PlotWalk.java
@@ -107,7 +107,7 @@ public void addAdditionalRefs(Iterable<Ref> refs) throws IOException { if (set == null) set = Collections.singleton(ref); else { - set = new HashSet<Ref>(set); + set = new HashSet<>(set); set.add(ref); } reverseRefMap.put(ref.getObjectId(), set); @@ -147,6 +147,7 @@ public RevCommit next() throws MissingObjectException, } class PlotRefComparator implements Comparator<Ref> { + @Override public int compare(Ref o1, Ref o2) { try { RevObject obj1 = parseAny(o1.getObjectId());
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/AbstractRevQueue.java b/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/AbstractRevQueue.java index 843c2af..4923d0f 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/AbstractRevQueue.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/AbstractRevQueue.java
@@ -107,6 +107,7 @@ public final void addParents(final RevCommit c, final RevFlag queueControl) { * * @return the first commit of this queue. */ + @Override public abstract RevCommit next(); /** Remove all entries from this queue. */
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/BlockRevQueue.java b/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/BlockRevQueue.java index 30d140a..db5379e 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/BlockRevQueue.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/BlockRevQueue.java
@@ -83,6 +83,7 @@ protected BlockRevQueue() { * @param q * the other queue we will steal entries from. */ + @Override public void shareFreeList(final BlockRevQueue q) { free = q.free; }
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/DateRevQueue.java b/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/DateRevQueue.java index 0802bfa..cd7c074 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/DateRevQueue.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/DateRevQueue.java
@@ -82,6 +82,7 @@ public DateRevQueue() { } } + @Override public void add(final RevCommit c) { sinceLastIndex++; if (++inQueue > REBUILD_INDEX_COUNT @@ -126,6 +127,7 @@ else if (t > when) } } + @Override public RevCommit next() { final Entry q = head; if (q == null) @@ -161,6 +163,7 @@ public RevCommit peek() { return head != null ? head.commit : null; } + @Override public void clear() { head = null; free = null; @@ -170,6 +173,7 @@ public void clear() { last = -1; } + @Override boolean everbodyHasFlag(final int f) { for (Entry q = head; q != null; q = q.next) { if ((q.commit.flags & f) == 0) @@ -178,6 +182,7 @@ boolean everbodyHasFlag(final int f) { return true; } + @Override boolean anybodyHasFlag(final int f) { for (Entry q = head; q != null; q = q.next) { if ((q.commit.flags & f) != 0) @@ -191,6 +196,7 @@ int outputType() { return outputType | SORT_COMMIT_TIME_DESC; } + @Override public String toString() { final StringBuilder s = new StringBuilder(); for (Entry q = head; q != null; q = q.next)
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/DepthWalk.java b/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/DepthWalk.java index 59a360f..f932593 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/DepthWalk.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/DepthWalk.java
@@ -138,14 +138,17 @@ protected RevCommit createCommit(AnyObjectId id) { return new Commit(id); } + @Override public int getDepth() { return depth; } + @Override public RevFlag getUnshallowFlag() { return UNSHALLOW; } + @Override public RevFlag getReinterestingFlag() { return REINTERESTING; } @@ -239,14 +242,17 @@ protected RevCommit createCommit(AnyObjectId id) { return new Commit(id); } + @Override public int getDepth() { return depth; } + @Override public RevFlag getUnshallowFlag() { return UNSHALLOW; } + @Override public RevFlag getReinterestingFlag() { return REINTERESTING; }
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/FIFORevQueue.java b/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/FIFORevQueue.java index b8f63aa..1415604 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/FIFORevQueue.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/FIFORevQueue.java
@@ -64,6 +64,7 @@ public FIFORevQueue() { super(s); } + @Override public void add(final RevCommit c) { Block b = tail; if (b == null) { @@ -107,6 +108,7 @@ public void unpop(final RevCommit c) { head = b; } + @Override public RevCommit next() { final Block b = head; if (b == null) @@ -122,12 +124,14 @@ public RevCommit next() { return c; } + @Override public void clear() { head = null; tail = null; free.clear(); } + @Override boolean everbodyHasFlag(final int f) { for (Block b = head; b != null; b = b.next) { for (int i = b.headIndex; i < b.tailIndex; i++) @@ -137,6 +141,7 @@ boolean everbodyHasFlag(final int f) { return true; } + @Override boolean anybodyHasFlag(final int f) { for (Block b = head; b != null; b = b.next) { for (int i = b.headIndex; i < b.tailIndex; i++) @@ -154,6 +159,7 @@ void removeFlag(final int f) { } } + @Override public String toString() { final StringBuilder s = new StringBuilder(); for (Block q = head; q != null; q = q.next) {
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/FooterKey.java b/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/FooterKey.java index 319b819..36965f4 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/FooterKey.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/FooterKey.java
@@ -43,6 +43,8 @@ package org.eclipse.jgit.revwalk; +import java.util.Locale; + import org.eclipse.jgit.lib.Constants; /** Case insensitive key for a {@link FooterLine}. */ @@ -68,7 +70,7 @@ public final class FooterKey { */ public FooterKey(final String keyName) { name = keyName; - raw = Constants.encode(keyName.toLowerCase()); + raw = Constants.encode(keyName.toLowerCase(Locale.ROOT)); } /** @return name of this footer line. */
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/LIFORevQueue.java b/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/LIFORevQueue.java index 9abaf8d..f9da5b1 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/LIFORevQueue.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/LIFORevQueue.java
@@ -63,6 +63,7 @@ public LIFORevQueue() { super(s); } + @Override public void add(final RevCommit c) { Block b = head; if (b == null || !b.canUnpop()) { @@ -74,6 +75,7 @@ public void add(final RevCommit c) { b.unpop(c); } + @Override public RevCommit next() { final Block b = head; if (b == null) @@ -87,11 +89,13 @@ public RevCommit next() { return c; } + @Override public void clear() { head = null; free.clear(); } + @Override boolean everbodyHasFlag(final int f) { for (Block b = head; b != null; b = b.next) { for (int i = b.headIndex; i < b.tailIndex; i++) @@ -101,6 +105,7 @@ boolean everbodyHasFlag(final int f) { return true; } + @Override boolean anybodyHasFlag(final int f) { for (Block b = head; b != null; b = b.next) { for (int i = b.headIndex; i < b.tailIndex; i++) @@ -110,6 +115,7 @@ boolean anybodyHasFlag(final int f) { return false; } + @Override public String toString() { final StringBuilder s = new StringBuilder(); for (Block q = head; q != null; q = q.next) {
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/MergeBaseGenerator.java b/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/MergeBaseGenerator.java index 3609d46..5d7e72d 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/MergeBaseGenerator.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/MergeBaseGenerator.java
@@ -87,7 +87,7 @@ class MergeBaseGenerator extends Generator { private int recarryMask; private int mergeBaseAncestor = -1; - private LinkedList<RevCommit> ret = new LinkedList<RevCommit>(); + private LinkedList<RevCommit> ret = new LinkedList<>(); MergeBaseGenerator(final RevWalk w) { walker = w;
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/ObjectWalk.java b/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/ObjectWalk.java index 9c3af5a..5868998 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/ObjectWalk.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/ObjectWalk.java
@@ -133,7 +133,7 @@ public ObjectWalk(final Repository repo) { public ObjectWalk(ObjectReader or) { super(or); setRetainBody(false); - rootObjects = new ArrayList<RevObject>(); + rootObjects = new ArrayList<>(); pendingObjects = new BlockObjQueue(); objectFilter = ObjectFilter.ALL; pathBuf = new byte[256]; @@ -243,6 +243,7 @@ else if (o instanceof RevTree) addObject(o); } + @Override public void sort(RevSort s) { super.sort(s); boundary = hasRevSort(RevSort.BOUNDARY); @@ -681,7 +682,7 @@ protected void reset(final int retainFlags) { for (RevObject obj : rootObjects) obj.flags &= ~IN_PENDING; - rootObjects = new ArrayList<RevObject>(); + rootObjects = new ArrayList<>(); pendingObjects = new BlockObjQueue(); currVisit = null; freeVisit = null;
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/RevCommit.java b/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/RevCommit.java index 1e91006..c641a13 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/RevCommit.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/RevCommit.java
@@ -565,7 +565,7 @@ public final List<FooterLine> getFooterLines() { ptr--; final int msgB = RawParseUtils.commitMessage(raw, 0); - final ArrayList<FooterLine> r = new ArrayList<FooterLine>(4); + final ArrayList<FooterLine> r = new ArrayList<>(4); final Charset enc = guessEncoding(); for (;;) { ptr = RawParseUtils.prevLF(raw, ptr); @@ -628,7 +628,7 @@ public final List<String> getFooterLines(final FooterKey keyName) { final List<FooterLine> src = getFooterLines(); if (src.isEmpty()) return Collections.emptyList(); - final ArrayList<String> r = new ArrayList<String>(src.size()); + final ArrayList<String> r = new ArrayList<>(src.size()); for (final FooterLine f : src) { if (f.matches(keyName)) r.add(f.getValue());
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/RevFlag.java b/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/RevFlag.java index 0998a3a..dae52f8 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/RevFlag.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/RevFlag.java
@@ -99,6 +99,7 @@ public RevWalk getRevWalk() { return walker; } + @Override public String toString() { return name; }
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/RevFlagSet.java b/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/RevFlagSet.java index ca30fd9..bb699e0 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/RevFlagSet.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/RevFlagSet.java
@@ -61,7 +61,7 @@ public class RevFlagSet extends AbstractSet<RevFlag> { /** Create an empty set of flags. */ public RevFlagSet() { - active = new ArrayList<RevFlag>(); + active = new ArrayList<>(); } /** @@ -72,7 +72,7 @@ public RevFlagSet() { */ public RevFlagSet(final RevFlagSet s) { mask = s.mask; - active = new ArrayList<RevFlag>(s.active); + active = new ArrayList<>(s.active); } /** @@ -132,14 +132,17 @@ public Iterator<RevFlag> iterator() { return new Iterator<RevFlag>() { private RevFlag current; + @Override public boolean hasNext() { return i.hasNext(); } + @Override public RevFlag next() { return current = i.next(); } + @Override public void remove() { mask &= ~current.mask; i.remove();
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/RevObjectList.java b/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/RevObjectList.java index 5052a4d..9598678 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/RevObjectList.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/RevObjectList.java
@@ -78,6 +78,7 @@ public RevObjectList() { // Initialized above. } + @Override public void add(final int index, final E element) { if (index != size) throw new UnsupportedOperationException(MessageFormat.format( @@ -87,6 +88,7 @@ public void add(final int index, final E element) { size++; } + @Override @SuppressWarnings("unchecked") public E set(int index, E element) { Block s = contents; @@ -107,6 +109,7 @@ public E set(int index, E element) { return (E) old; } + @Override @SuppressWarnings("unchecked") public E get(int index) { Block s = contents; @@ -120,6 +123,7 @@ public E get(int index) { return s != null ? (E) s.contents[index] : null; } + @Override public int size() { return size; }
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/RevWalk.java b/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/RevWalk.java index a7f7cd4..320f05f 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/RevWalk.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/RevWalk.java
@@ -226,8 +226,8 @@ public RevWalk(ObjectReader or) { private RevWalk(ObjectReader or, boolean closeReader) { reader = or; idBuffer = new MutableObjectId(); - objects = new ObjectIdOwnerMap<RevObject>(); - roots = new ArrayList<RevCommit>(); + objects = new ObjectIdOwnerMap<>(); + roots = new ArrayList<>(); queue = new DateRevQueue(); pending = new StartGenerator(this); sorting = EnumSet.of(RevSort.NONE); @@ -931,8 +931,8 @@ private RevObject parseNew(AnyObjectId id, ObjectLoader ldr) */ public <T extends ObjectId> AsyncRevObjectQueue parseAny( Iterable<T> objectIds, boolean reportMissing) { - List<T> need = new ArrayList<T>(); - List<RevObject> have = new ArrayList<RevObject>(); + List<T> need = new ArrayList<>(); + List<RevObject> have = new ArrayList<>(); for (T id : objectIds) { RevObject r = objects.get(id); if (r != null && (r.flags & PARSED) != 0) @@ -944,14 +944,17 @@ public <T extends ObjectId> AsyncRevObjectQueue parseAny( final Iterator<RevObject> objItr = have.iterator(); if (need.isEmpty()) { return new AsyncRevObjectQueue() { + @Override public RevObject next() { return objItr.hasNext() ? objItr.next() : null; } + @Override public boolean cancel(boolean mayInterruptIfRunning) { return true; } + @Override public void release() { // In-memory only, no action required. } @@ -960,6 +963,7 @@ public void release() { final AsyncObjectLoaderQueue<T> lItr = reader.open(need, reportMissing); return new AsyncRevObjectQueue() { + @Override public RevObject next() throws MissingObjectException, IncorrectObjectTypeException, IOException { if (objItr.hasNext()) @@ -983,10 +987,12 @@ else if (r instanceof RevCommit) { return r; } + @Override public boolean cancel(boolean mayInterruptIfRunning) { return lItr.cancel(mayInterruptIfRunning); } + @Override public void release() { lItr.release(); } @@ -1316,6 +1322,7 @@ public void dispose() { * @return an iterator over this walker's commits. * @see RevWalkException */ + @Override public Iterator<RevCommit> iterator() { final RevCommit first; try { @@ -1331,10 +1338,12 @@ public Iterator<RevCommit> iterator() { return new Iterator<RevCommit>() { RevCommit next = first; + @Override public boolean hasNext() { return next != null; } + @Override public RevCommit next() { try { final RevCommit r = next; @@ -1349,6 +1358,7 @@ public RevCommit next() { } } + @Override public void remove() { throw new UnsupportedOperationException(); }
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/RevWalkUtils.java b/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/RevWalkUtils.java index 11fec31..e751d77 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/RevWalkUtils.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/RevWalkUtils.java
@@ -121,7 +121,7 @@ public static List<RevCommit> find(final RevWalk walk, if (end != null) walk.markUninteresting(end); - List<RevCommit> commits = new ArrayList<RevCommit>(); + List<RevCommit> commits = new ArrayList<>(); for (RevCommit c : walk) commits.add(c); return commits; @@ -155,7 +155,7 @@ public static List<Ref> findBranchesReachableFrom(RevCommit commit, // Make sure commit is from the same RevWalk commit = revWalk.parseCommit(commit.getId()); revWalk.reset(); - List<Ref> result = new ArrayList<Ref>(); + List<Ref> result = new ArrayList<>(); final int SKEW = 24*3600; // one day clock skew
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/filter/RevFilter.java b/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/filter/RevFilter.java index 14a98a1..6b90d29 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/filter/RevFilter.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/filter/RevFilter.java
@@ -286,6 +286,7 @@ public abstract boolean include(RevWalk walker, RevCommit cmit) * * @return another copy of this filter, suitable for another thread. */ + @Override public abstract RevFilter clone(); @Override
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 2d02ad5..b268979 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
@@ -208,6 +208,7 @@ public void load() throws IOException, ConfigInvalidException { * @throws IOException * the file could not be written. */ + @Override public void save() throws IOException { final byte[] out; final String text = toText();
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/storage/pack/PackConfig.java b/org.eclipse.jgit/src/org/eclipse/jgit/storage/pack/PackConfig.java index d594e97..c64aa2d 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/storage/pack/PackConfig.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/storage/pack/PackConfig.java
@@ -75,6 +75,20 @@ public class PackConfig { public static final boolean DEFAULT_REUSE_OBJECTS = true; /** + * Default value of keep old packs option: {@value} + * @see #setPreserveOldPacks(boolean) + * @since 4.7 + */ + public static final boolean DEFAULT_PRESERVE_OLD_PACKS = false; + + /** + * Default value of prune old packs option: {@value} + * @see #setPrunePreserved(boolean) + * @since 4.7 + */ + public static final boolean DEFAULT_PRUNE_PRESERVED = false; + + /** * Default value of delta compress option: {@value} * * @see #setDeltaCompress(boolean) @@ -204,6 +218,10 @@ public class PackConfig { private boolean reuseObjects = DEFAULT_REUSE_OBJECTS; + private boolean preserveOldPacks = DEFAULT_PRESERVE_OLD_PACKS; + + private boolean prunePreserved = DEFAULT_PRUNE_PRESERVED; + private boolean deltaBaseAsOffset = DEFAULT_DELTA_BASE_AS_OFFSET; private boolean deltaCompress = DEFAULT_DELTA_COMPRESS; @@ -281,6 +299,8 @@ public PackConfig(PackConfig cfg) { this.compressionLevel = cfg.compressionLevel; this.reuseDeltas = cfg.reuseDeltas; this.reuseObjects = cfg.reuseObjects; + this.preserveOldPacks = cfg.preserveOldPacks; + this.prunePreserved = cfg.prunePreserved; this.deltaBaseAsOffset = cfg.deltaBaseAsOffset; this.deltaCompress = cfg.deltaCompress; this.maxDeltaDepth = cfg.maxDeltaDepth; @@ -364,6 +384,61 @@ public void setReuseObjects(boolean reuseObjects) { } /** + * Checks whether to preserve old packs in a preserved directory + * + * Default setting: {@value #DEFAULT_PRESERVE_OLD_PACKS} + * + * @return true if repacking will preserve old pack files. + * @since 4.7 + */ + public boolean isPreserveOldPacks() { + return preserveOldPacks; + } + + /** + * Set preserve old packs configuration option for repacking. + * + * If enabled, old pack files are moved into a preserved subdirectory instead + * of being deleted + * + * Default setting: {@value #DEFAULT_PRESERVE_OLD_PACKS} + * + * @param preserveOldPacks + * boolean indicating whether or not preserve old pack files + * @since 4.7 + */ + public void setPreserveOldPacks(boolean preserveOldPacks) { + this.preserveOldPacks = preserveOldPacks; + } + + /** + * Checks whether to remove preserved pack files in a preserved directory + * + * Default setting: {@value #DEFAULT_PRUNE_PRESERVED} + * + * @return true if repacking will remove preserved pack files. + * @since 4.7 + */ + public boolean isPrunePreserved() { + return prunePreserved; + } + + /** + * Set prune preserved configuration option for repacking. + * + * If enabled, preserved pack files are removed from a preserved subdirectory + * + * Default setting: {@value #DEFAULT_PRESERVE_OLD_PACKS} + * + * @param prunePreserved + * boolean indicating whether or not preserve old pack files + * @since 4.7 + */ + public void setPrunePreserved(boolean prunePreserved) { + this.prunePreserved = prunePreserved; + } + + /** * True if writer can use offsets to point to a delta base. * * If true the writer may choose to use an offset to point to a delta base @@ -969,6 +1044,7 @@ public void fromConfig(final Config rc) { getBitmapInactiveBranchAgeInDays())); } + @Override public String toString() { final StringBuilder b = new StringBuilder(); b.append("maxDeltaDepth=").append(getMaxDeltaDepth()); //$NON-NLS-1$
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 5b9e8d9..a10f3d7 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/submodule/SubmoduleWalk.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/submodule/SubmoduleWalk.java
@@ -45,6 +45,7 @@ import java.io.File; import java.io.IOException; import java.text.MessageFormat; +import java.util.Locale; import org.eclipse.jgit.dircache.DirCache; import org.eclipse.jgit.dircache.DirCacheIterator; @@ -663,7 +664,8 @@ public IgnoreSubmoduleMode getModulesIgnore() throws IOException, ConfigConstants.CONFIG_KEY_IGNORE); if (name == null) return null; - return IgnoreSubmoduleMode.valueOf(name.trim().toUpperCase()); + return IgnoreSubmoduleMode + .valueOf(name.trim().toUpperCase(Locale.ROOT)); } /**
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 2d730a1..6f13694 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/transport/AbstractAdvertiseRefsHook.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/transport/AbstractAdvertiseRefsHook.java
@@ -57,12 +57,14 @@ * @since 2.0 */ public abstract class AbstractAdvertiseRefsHook implements AdvertiseRefsHook { + @Override public void advertiseRefs(UploadPack uploadPack) throws ServiceMayNotContinueException { uploadPack.setAdvertisedRefs(getAdvertisedRefs( uploadPack.getRepository(), uploadPack.getRevWalk())); } + @Override public void advertiseRefs(BaseReceivePack receivePack) throws ServiceMayNotContinueException { Map<String, Ref> refs = getAdvertisedRefs(receivePack.getRepository(),
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 c3af74a..96d7c24 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/transport/AdvertiseRefsHook.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/transport/AdvertiseRefsHook.java
@@ -56,10 +56,12 @@ public interface AdvertiseRefsHook { * {@link BaseReceivePack#setAdvertisedRefs(java.util.Map,java.util.Set)}. */ public static final AdvertiseRefsHook DEFAULT = new AdvertiseRefsHook() { + @Override public void advertiseRefs(UploadPack uploadPack) { // Do nothing. } + @Override public void advertiseRefs(BaseReceivePack receivePack) { // Do nothing. }
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 00942ab..22ea5cb 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/transport/AdvertiseRefsHookChain.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/transport/AdvertiseRefsHookChain.java
@@ -79,12 +79,14 @@ else if (i == 1) return new AdvertiseRefsHookChain(newHooks, i); } + @Override public void advertiseRefs(BaseReceivePack rp) throws ServiceMayNotContinueException { for (int i = 0; i < count; i++) hooks[i].advertiseRefs(rp); } + @Override public void advertiseRefs(UploadPack rp) throws ServiceMayNotContinueException { for (int i = 0; i < count; i++)
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/transport/AmazonS3.java b/org.eclipse.jgit/src/org/eclipse/jgit/transport/AmazonS3.java index 1aebadd..64cb4dd 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/transport/AmazonS3.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/transport/AmazonS3.java
@@ -120,7 +120,7 @@ public class AmazonS3 { private static final String X_AMZ_META = "x-amz-meta-"; //$NON-NLS-1$ static { - SIGNED_HEADERS = new HashSet<String>(); + SIGNED_HEADERS = new HashSet<>(); SIGNED_HEADERS.add("content-type"); //$NON-NLS-1$ SIGNED_HEADERS.add("content-md5"); //$NON-NLS-1$ SIGNED_HEADERS.add("date"); //$NON-NLS-1$ @@ -606,7 +606,7 @@ HttpURLConnection open(final String method, final String bucket, void authorize(final HttpURLConnection c) throws IOException { final Map<String, List<String>> reqHdr = c.getRequestProperties(); - final SortedMap<String, String> sigHdr = new TreeMap<String, String>(); + final SortedMap<String, String> sigHdr = new TreeMap<>(); for (final Map.Entry<String, List<String>> entry : reqHdr.entrySet()) { final String hdr = entry.getKey(); if (isSignedHeader(hdr)) @@ -664,7 +664,7 @@ static Properties properties(final File authFile) } private final class ListParser extends DefaultHandler { - final List<String> entries = new ArrayList<String>(); + final List<String> entries = new ArrayList<>(); private final String bucket; @@ -680,7 +680,7 @@ private final class ListParser extends DefaultHandler { } void list() throws IOException { - final Map<String, String> args = new TreeMap<String, String>(); + final Map<String, String> args = new TreeMap<>(); if (prefix.length() > 0) args.put("prefix", prefix); //$NON-NLS-1$ if (!entries.isEmpty())
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/transport/BaseConnection.java b/org.eclipse.jgit/src/org/eclipse/jgit/transport/BaseConnection.java index 59ff1bd..69028fa 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/transport/BaseConnection.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/transport/BaseConnection.java
@@ -71,18 +71,22 @@ public abstract class BaseConnection implements Connection { private Writer messageWriter; + @Override public Map<String, Ref> getRefsMap() { return advertisedRefs; } + @Override public final Collection<Ref> getRefs() { return advertisedRefs.values(); } + @Override public final Ref getRef(final String name) { return advertisedRefs.get(name); } + @Override public String getMessages() { return messageWriter != null ? messageWriter.toString() : ""; //$NON-NLS-1$ } @@ -94,6 +98,7 @@ public String getMessages() { * server does not advertise this version. * @since 4.0 */ + @Override public String getPeerUserAgent() { return peerUserAgent; } @@ -109,6 +114,7 @@ protected void setPeerUserAgent(String agent) { peerUserAgent = agent; } + @Override public abstract void close(); /**
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/transport/BaseFetchConnection.java b/org.eclipse.jgit/src/org/eclipse/jgit/transport/BaseFetchConnection.java index cc27707..41b8c2d 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/transport/BaseFetchConnection.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/transport/BaseFetchConnection.java
@@ -64,12 +64,14 @@ */ abstract class BaseFetchConnection extends BaseConnection implements FetchConnection { + @Override public final void fetch(final ProgressMonitor monitor, final Collection<Ref> want, final Set<ObjectId> have) throws TransportException { fetch(monitor, want, have, null); } + @Override public final void fetch(final ProgressMonitor monitor, final Collection<Ref> want, final Set<ObjectId> have, OutputStream out) throws TransportException { @@ -81,6 +83,7 @@ public final void fetch(final ProgressMonitor monitor, * Default implementation of {@link FetchConnection#didFetchIncludeTags()} - * returning false. */ + @Override public boolean didFetchIncludeTags() { return false; }
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/transport/BasePackConnection.java b/org.eclipse.jgit/src/org/eclipse/jgit/transport/BasePackConnection.java index aa36aeb..c695449 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/transport/BasePackConnection.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/transport/BasePackConnection.java
@@ -117,10 +117,10 @@ abstract class BasePackConnection extends BaseConnection { protected boolean statelessRPC; /** Capability tokens advertised by the remote side. */ - private final Set<String> remoteCapablities = new HashSet<String>(); + private final Set<String> remoteCapablities = new HashSet<>(); /** Extra objects the remote has, but which aren't offered as refs. */ - protected final Set<ObjectId> additionalHaves = new HashSet<ObjectId>(); + protected final Set<ObjectId> additionalHaves = new HashSet<>(); BasePackConnection(final PackTransport packTransport) { transport = (Transport) packTransport; @@ -191,7 +191,7 @@ protected void readAdvertisedRefs() throws TransportException { } private void readAdvertisedRefsImpl() throws IOException { - final LinkedHashMap<String, Ref> avail = new LinkedHashMap<String, Ref>(); + final LinkedHashMap<String, Ref> avail = new LinkedHashMap<>(); for (;;) { String line;
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/transport/BasePackFetchConnection.java b/org.eclipse.jgit/src/org/eclipse/jgit/transport/BasePackFetchConnection.java index 0dd907f..e8d1881 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/transport/BasePackFetchConnection.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/transport/BasePackFetchConnection.java
@@ -260,7 +260,7 @@ public BasePackFetchConnection(final PackTransport packTransport) { if (local != null) { walk = new RevWalk(local); - reachableCommits = new RevCommitList<RevCommit>(); + reachableCommits = new RevCommitList<>(); REACHABLE = walk.newFlag("REACHABLE"); //$NON-NLS-1$ COMMON = walk.newFlag("COMMON"); //$NON-NLS-1$ STATE = walk.newFlag("STATE"); //$NON-NLS-1$ @@ -280,6 +280,7 @@ public BasePackFetchConnection(final PackTransport packTransport) { private static class FetchConfig { static final SectionParser<FetchConfig> KEY = new SectionParser<FetchConfig>() { + @Override public FetchConfig parse(final Config cfg) { return new FetchConfig(cfg); } @@ -292,6 +293,7 @@ public FetchConfig parse(final Config cfg) { } } + @Override public final void fetch(final ProgressMonitor monitor, final Collection<Ref> want, final Set<ObjectId> have) throws TransportException { @@ -301,6 +303,7 @@ public final void fetch(final ProgressMonitor monitor, /** * @since 3.0 */ + @Override public final void fetch(final ProgressMonitor monitor, final Collection<Ref> want, final Set<ObjectId> have, OutputStream outputStream) throws TransportException { @@ -308,18 +311,22 @@ public final void fetch(final ProgressMonitor monitor, doFetch(monitor, want, have, outputStream); } + @Override public boolean didFetchIncludeTags() { return false; } + @Override public boolean didFetchTestConnectivity() { return false; } + @Override public void setPackLockMessage(final String message) { lockMessage = message; } + @Override public Collection<PackLock> getPackLocks() { if (packLock != null) return Collections.singleton(packLock);
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 86cc484..679ea0c 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/transport/BasePackPushConnection.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/transport/BasePackPushConnection.java
@@ -152,6 +152,7 @@ public BasePackPushConnection(final PackTransport packTransport) { pushOptions = transport.getPushOptions(); } + @Override public void push(final ProgressMonitor monitor, final Map<String, RemoteRefUpdate> refUpdates) throws TransportException { @@ -161,6 +162,7 @@ public void push(final ProgressMonitor monitor, /** * @since 3.0 */ + @Override public void push(final ProgressMonitor monitor, final Map<String, RemoteRefUpdate> refUpdates, OutputStream outputStream) throws TransportException { @@ -326,8 +328,8 @@ private String enableCapabilities(final ProgressMonitor monitor, private void writePack(final Map<String, RemoteRefUpdate> refUpdates, final ProgressMonitor monitor) throws IOException { - Set<ObjectId> remoteObjects = new HashSet<ObjectId>(); - Set<ObjectId> newObjects = new HashSet<ObjectId>(); + Set<ObjectId> remoteObjects = new HashSet<>(); + Set<ObjectId> newObjects = new HashSet<>(); try (final PackWriter writer = new PackWriter(transport.getPackConfig(), local.newObjectReader())) {
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/transport/BaseReceivePack.java b/org.eclipse.jgit/src/org/eclipse/jgit/transport/BaseReceivePack.java index 4d0803a..14b683f 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/transport/BaseReceivePack.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/transport/BaseReceivePack.java
@@ -43,6 +43,7 @@ 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; @@ -76,15 +77,20 @@ 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.lib.AnyObjectId; import org.eclipse.jgit.lib.BatchRefUpdate; import org.eclipse.jgit.lib.Config; import org.eclipse.jgit.lib.Config.SectionParser; 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; @@ -97,6 +103,7 @@ 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; @@ -123,7 +130,7 @@ public static class FirstLine { * line from the client. */ public FirstLine(String line) { - final HashSet<String> caps = new HashSet<String>(); + final HashSet<String> caps = new HashSet<>(); final int nul = line.indexOf('\0'); if (nul >= 0) { for (String c : line.substring(nul + 1).split(" ")) //$NON-NLS-1$ @@ -244,6 +251,8 @@ public Set<String> getCapabilities() { String userAgent; private Set<ObjectId> clientShallowCommits; private List<ReceiveCommand> commands; + private long maxCommandBytes; + private long maxDiscardBytes; private StringBuilder advertiseError; @@ -318,16 +327,19 @@ protected BaseReceivePack(final Repository into) { allowNonFastForwards = rc.allowNonFastForwards; allowOfsDelta = rc.allowOfsDelta; allowPushOptions = rc.allowPushOptions; + maxCommandBytes = rc.maxCommandBytes; + maxDiscardBytes = rc.maxDiscardBytes; advertiseRefsHook = AdvertiseRefsHook.DEFAULT; refFilter = RefFilter.DEFAULT; - advertisedHaves = new HashSet<ObjectId>(); - clientShallowCommits = new HashSet<ObjectId>(); + advertisedHaves = new HashSet<>(); + clientShallowCommits = new HashSet<>(); signedPushConfig = rc.signedPush; } /** Configuration for receive operations. */ protected static class ReceiveConfig { static final SectionParser<ReceiveConfig> KEY = new SectionParser<ReceiveConfig>() { + @Override public ReceiveConfig parse(final Config cfg) { return new ReceiveConfig(cfg); } @@ -338,7 +350,8 @@ public ReceiveConfig parse(final Config cfg) { final boolean allowNonFastForwards; final boolean allowOfsDelta; final boolean allowPushOptions; - + final long maxCommandBytes; + final long maxDiscardBytes; final SignedPushConfig signedPush; ReceiveConfig(final Config config) { @@ -350,6 +363,12 @@ public ReceiveConfig parse(final Config cfg) { 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); } } @@ -729,6 +748,38 @@ public void setTimeout(final int 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 @@ -741,7 +792,6 @@ public void setMaxObjectSizeLimit(final long limit) { maxObjectSizeLimit = limit; } - /** * Set the maximum allowed pack size. * <p> @@ -1014,20 +1064,12 @@ protected void init(final InputStream input, final OutputStream output, rawOut = o; } - if (maxPackSizeLimit >= 0) - rawIn = new LimitedInputStream(rawIn, maxPackSizeLimit) { - @Override - protected void limitExceeded() throws TooLargePackException { - throw new TooLargePackException(limit); - } - }; - pckIn = new PacketLineIn(rawIn); pckOut = new PacketLineOut(rawOut); pckOut.setFlushOnEnd(false); - enabledCapabilities = new HashSet<String>(); - commands = new ArrayList<ReceiveCommand>(); + enabledCapabilities = new HashSet<>(); + commands = new ArrayList<>(); } /** @return advertised refs, or the default if not explicitly advertised. */ @@ -1045,8 +1087,10 @@ protected Map<String, Ref> getAdvertisedOrDefaultRefs() { */ protected void receivePackAndCheckConnectivity() throws IOException { receivePack(); - if (needCheckConnectivity()) + if (needCheckConnectivity()) { + checkSubmodules(); checkConnectivity(); + } parser = null; } @@ -1134,13 +1178,16 @@ public ReceivedPackStatistics getReceivedPackStatistics() { * @throws 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 = pckIn.readString(); + line = pck.readString(); } catch (EOFException eof) { if (commands.isEmpty()) return; @@ -1163,13 +1210,13 @@ protected void recvCommands() throws IOException { enableCapabilities(); if (line.equals(GitProtocolConstants.OPTION_PUSH_CERT)) { - certParser.receiveHeader(pckIn, !isBiDirectionalPipe()); + certParser.receiveHeader(pck, !isBiDirectionalPipe()); continue; } } if (line.equals(PushCertificateParser.BEGIN_SIGNATURE)) { - certParser.receiveSignature(pckIn); + certParser.receiveSignature(pck); continue; } @@ -1186,18 +1233,31 @@ protected void recvCommands() throws IOException { } pushCert = certParser.build(); if (hasCommands()) { - readPostCommands(pckIn); + readPostCommands(pck); } } catch (PackProtocolException e) { - if (sideBand) { - try { - pckIn.discardUntilEnd(); - } catch (IOException e2) { - // Ignore read failures attempting to discard. - } - } + 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. + } } } @@ -1309,7 +1369,7 @@ private void receivePack() throws IOException { if (getRefLogIdent() != null) lockMsg += " from " + getRefLogIdent().toExternalString(); //$NON-NLS-1$ - parser = ins.newPackParser(rawIn); + parser = ins.newPackParser(packInputStream()); parser.setAllowThin(true); parser.setNeedNewObjectIds(checkReferencedIsReachable); parser.setNeedBaseObjectIds(checkReferencedIsReachable); @@ -1329,12 +1389,40 @@ private void receivePack() throws IOException { 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); + + SubmoduleValidator.assertValidGitModulesFile( + new String(blob.getBytes(), UTF_8)); + } + } + private void checkConnectivity() throws IOException { ObjectIdSubclassMap<ObjectId> baseObjects = null; ObjectIdSubclassMap<ObjectId> providedObjects = null;
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/transport/BundleFetchConnection.java b/org.eclipse.jgit/src/org/eclipse/jgit/transport/BundleFetchConnection.java index 8038fa4..f37ba01 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/transport/BundleFetchConnection.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/transport/BundleFetchConnection.java
@@ -92,7 +92,7 @@ class BundleFetchConnection extends BaseFetchConnection { InputStream bin; - final Map<ObjectId, String> prereqs = new HashMap<ObjectId, String>(); + final Map<ObjectId, String> prereqs = new HashMap<>(); private String lockMessage; @@ -130,7 +130,7 @@ private int readSignature() throws IOException { private void readBundleV2() throws IOException { final byte[] hdrbuf = new byte[1024]; - final LinkedHashMap<String, Ref> avail = new LinkedHashMap<String, Ref>(); + final LinkedHashMap<String, Ref> avail = new LinkedHashMap<>(); for (;;) { String line = readLine(hdrbuf); if (line.length() == 0) @@ -180,6 +180,7 @@ private String readLine(final byte[] hdrbuf) throws IOException { return line.toString(); } + @Override public boolean didFetchTestConnectivity() { return false; } @@ -207,10 +208,12 @@ protected void doFetch(final ProgressMonitor monitor, } } + @Override public void setPackLockMessage(final String message) { lockMessage = message; } + @Override public Collection<PackLock> getPackLocks() { if (packLock != null) return Collections.singleton(packLock); @@ -225,8 +228,8 @@ private void verifyPrerequisites() throws TransportException { final RevFlag PREREQ = rw.newFlag("PREREQ"); //$NON-NLS-1$ final RevFlag SEEN = rw.newFlag("SEEN"); //$NON-NLS-1$ - final Map<ObjectId, String> missing = new HashMap<ObjectId, String>(); - final List<RevObject> commits = new ArrayList<RevObject>(); + final Map<ObjectId, String> missing = new HashMap<>(); + final List<RevObject> commits = new ArrayList<>(); for (final Map.Entry<ObjectId, String> e : prereqs.entrySet()) { ObjectId p = e.getKey(); try {
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/transport/BundleWriter.java b/org.eclipse.jgit/src/org/eclipse/jgit/transport/BundleWriter.java index ca624c0..37d70e3 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/transport/BundleWriter.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/transport/BundleWriter.java
@@ -102,9 +102,9 @@ public class BundleWriter { */ public BundleWriter(final Repository repo) { db = repo; - include = new TreeMap<String, ObjectId>(); - assume = new HashSet<RevCommit>(); - tagTargets = new HashSet<ObjectId>(); + include = new TreeMap<>(); + assume = new HashSet<>(); + tagTargets = new HashSet<>(); } /** @@ -202,8 +202,8 @@ public void writeBundle(ProgressMonitor monitor, OutputStream os) try (PackWriter packWriter = new PackWriter(pc, db.newObjectReader())) { packWriter.setObjectCountCallback(callback); - final HashSet<ObjectId> inc = new HashSet<ObjectId>(); - final HashSet<ObjectId> exc = new HashSet<ObjectId>(); + final HashSet<ObjectId> inc = new HashSet<>(); + final HashSet<ObjectId> exc = new HashSet<>(); inc.addAll(include.values()); for (final RevCommit r : assume) exc.add(r.getId());
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/transport/ChainingCredentialsProvider.java b/org.eclipse.jgit/src/org/eclipse/jgit/transport/ChainingCredentialsProvider.java index 739ddcc..8cb3d60 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/transport/ChainingCredentialsProvider.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/transport/ChainingCredentialsProvider.java
@@ -68,7 +68,7 @@ public class ChainingCredentialsProvider extends CredentialsProvider { * here */ public ChainingCredentialsProvider(CredentialsProvider... providers) { - this.credentialProviders = new ArrayList<CredentialsProvider>( + this.credentialProviders = new ArrayList<>( Arrays.asList(providers)); }
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/transport/Connection.java b/org.eclipse.jgit/src/org/eclipse/jgit/transport/Connection.java index da288ec..9a272a4 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/transport/Connection.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/transport/Connection.java
@@ -112,6 +112,7 @@ public interface Connection extends AutoCloseable { * Implementers shouldn't throw checked exceptions. This override narrows * the signature to prevent them from doing so. */ + @Override public void close(); /**
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 6757aaf..8358635 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/transport/CredentialsProviderUserInfo.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/transport/CredentialsProviderUserInfo.java
@@ -85,14 +85,17 @@ private static URIish createURI(Session session) { return uri; } + @Override public String getPassword() { return password; } + @Override public String getPassphrase() { return passphrase; } + @Override public boolean promptPassphrase(String msg) { CredentialItem.StringType v = newPrompt(msg); if (provider.get(uri, v)) { @@ -104,6 +107,7 @@ public boolean promptPassphrase(String msg) { } } + @Override public boolean promptPassword(String msg) { CredentialItem.Password p = new CredentialItem.Password(msg); if (provider.get(uri, p)) { @@ -119,22 +123,25 @@ private CredentialItem.StringType newPrompt(String msg) { return new CredentialItem.StringType(msg, true); } + @Override public boolean promptYesNo(String msg) { CredentialItem.YesNoType v = new CredentialItem.YesNoType(msg); return provider.get(uri, v) && v.getValue(); } + @Override public void showMessage(String msg) { provider.get(uri, new CredentialItem.InformationalMessage(msg)); } + @Override public String[] promptKeyboardInteractive(String destination, String name, String instruction, String[] prompt, boolean[] echo) { CredentialItem.StringType[] v = new CredentialItem.StringType[prompt.length]; for (int i = 0; i < prompt.length; i++) v[i] = new CredentialItem.StringType(prompt[i], !echo[i]); - List<CredentialItem> items = new ArrayList<CredentialItem>(); + List<CredentialItem> items = new ArrayList<>(); if (instruction != null && instruction.length() > 0) items.add(new CredentialItem.InformationalMessage(instruction)); items.addAll(Arrays.asList(v));
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/transport/Daemon.java b/org.eclipse.jgit/src/org/eclipse/jgit/transport/Daemon.java index 1beec90..40b2c47 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/transport/Daemon.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/transport/Daemon.java
@@ -111,6 +111,7 @@ public Daemon(final InetSocketAddress addr) { repositoryResolver = (RepositoryResolver<DaemonClient>) RepositoryResolver.NONE; uploadPackFactory = new UploadPackFactory<DaemonClient>() { + @Override public UploadPack create(DaemonClient req, Repository db) throws ServiceNotEnabledException, ServiceNotAuthorizedException { @@ -122,6 +123,7 @@ public UploadPack create(DaemonClient req, Repository db) }; receivePackFactory = new ReceivePackFactory<DaemonClient>() { + @Override public ReceivePack create(DaemonClient req, Repository db) throws ServiceNotEnabledException, ServiceNotAuthorizedException { @@ -298,6 +300,7 @@ public synchronized void start() throws IOException { run = true; acceptThread = new Thread(processors, "Git-Daemon-Accept") { //$NON-NLS-1$ + @Override public void run() { while (isRunning()) { try { @@ -344,6 +347,7 @@ void startClient(final Socket s) { dc.setRemoteAddress(((InetSocketAddress) peer).getAddress()); new Thread(processors, "Git-Daemon-Client " + peer.toString()) { //$NON-NLS-1$ + @Override public void run() { try { dc.execute(s);
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/transport/DaemonService.java b/org.eclipse.jgit/src/org/eclipse/jgit/transport/DaemonService.java index ec6f242..80b2cae 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/transport/DaemonService.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/transport/DaemonService.java
@@ -65,6 +65,7 @@ public abstract class DaemonService { DaemonService(final String cmdName, final String cfgName) { command = cmdName.startsWith("git-") ? cmdName : "git-" + cmdName; //$NON-NLS-1$ //$NON-NLS-2$ configKey = new SectionParser<ServiceConfig>() { + @Override public ServiceConfig parse(final Config cfg) { return new ServiceConfig(DaemonService.this, cfg, cfgName); }
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/transport/DefaultSshSessionFactory.java b/org.eclipse.jgit/src/org/eclipse/jgit/transport/DefaultSshSessionFactory.java index 7012807..23fd7e3 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/transport/DefaultSshSessionFactory.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/transport/DefaultSshSessionFactory.java
@@ -59,6 +59,7 @@ * connection will immediately fail. */ class DefaultSshSessionFactory extends JschConfigSessionFactory { + @Override protected void configure(final OpenSshConfig.Host hc, final Session session) { // No additional configuration required. }
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/transport/FetchProcess.java b/org.eclipse.jgit/src/org/eclipse/jgit/transport/FetchProcess.java index 8cb36c7..280e6d4 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/transport/FetchProcess.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/transport/FetchProcess.java
@@ -88,18 +88,18 @@ class FetchProcess { private final Collection<RefSpec> toFetch; /** Set of refs we will actually wind up asking to obtain. */ - private final HashMap<ObjectId, Ref> askFor = new HashMap<ObjectId, Ref>(); + private final HashMap<ObjectId, Ref> askFor = new HashMap<>(); /** Objects we know we have locally. */ - private final HashSet<ObjectId> have = new HashSet<ObjectId>(); + private final HashSet<ObjectId> have = new HashSet<>(); /** Updates to local tracking branches (if any). */ - private final ArrayList<TrackingRefUpdate> localUpdates = new ArrayList<TrackingRefUpdate>(); + private final ArrayList<TrackingRefUpdate> localUpdates = new ArrayList<>(); /** Records to be recorded into FETCH_HEAD. */ - private final ArrayList<FetchHeadRecord> fetchHeadUpdates = new ArrayList<FetchHeadRecord>(); + private final ArrayList<FetchHeadRecord> fetchHeadUpdates = new ArrayList<>(); - private final ArrayList<PackLock> packLocks = new ArrayList<PackLock>(); + private final ArrayList<PackLock> packLocks = new ArrayList<>(); private FetchConnection conn; @@ -137,7 +137,7 @@ private void executeImp(final ProgressMonitor monitor, try { result.setAdvertisedRefs(transport.getURI(), conn.getRefsMap()); result.peerUserAgent = conn.getPeerUserAgent(); - final Set<Ref> matched = new HashSet<Ref>(); + final Set<Ref> matched = new HashSet<>(); for (final RefSpec spec : toFetch) { if (spec.getSource() == null) throw new TransportException(MessageFormat.format( @@ -275,11 +275,11 @@ private void reopenConnection() throws NotSupportedException, // We rebuild our askFor list using only the refs that the // new connection has offered to us. // - final HashMap<ObjectId, Ref> avail = new HashMap<ObjectId, Ref>(); + final HashMap<ObjectId, Ref> avail = new HashMap<>(); for (final Ref r : conn.getRefs()) avail.put(r.getObjectId(), r); - final Collection<Ref> wants = new ArrayList<Ref>(askFor.values()); + final Collection<Ref> wants = new ArrayList<>(askFor.values()); askFor.clear(); for (final Ref want : wants) { final Ref newRef = avail.get(want.getObjectId()); @@ -369,7 +369,7 @@ private void expandSingle(final RefSpec spec, final Set<Ref> matched) } private Collection<Ref> expandAutoFollowTags() throws TransportException { - final Collection<Ref> additionalTags = new ArrayList<Ref>(); + final Collection<Ref> additionalTags = new ArrayList<>(); final Map<String, Ref> haveRefs = localRefs(); for (final Ref r : conn.getRefs()) { if (!isTag(r))
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/transport/FetchResult.java b/org.eclipse.jgit/src/org/eclipse/jgit/transport/FetchResult.java index 3d95edd..2667ec3 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/transport/FetchResult.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/transport/FetchResult.java
@@ -48,7 +48,10 @@ import java.util.ArrayList; import java.util.Collection; +import java.util.Collections; +import java.util.HashMap; import java.util.List; +import java.util.Map; /** * Final status after a successful fetch from a remote repository. @@ -58,12 +61,39 @@ public class FetchResult extends OperationResult { private final List<FetchHeadRecord> forMerge; + private final Map<String, FetchResult> submodules; + FetchResult() { - forMerge = new ArrayList<FetchHeadRecord>(); + forMerge = new ArrayList<>(); + submodules = new HashMap<>(); } void add(final FetchHeadRecord r) { if (!r.notForMerge) forMerge.add(r); } + + /** + * Add fetch results for a submodule. + * + * @param path + * the submodule path + * @param result + * the fetch result + * @since 4.7 + */ + public void addSubmodule(String path, FetchResult result) { + submodules.put(path, result); + } + + /** + * Get fetch results for submodules. + * + * @return Fetch results for submodules as a map of submodule paths to fetch + * results. + * @since 4.7 + */ + public Map<String, FetchResult> submoduleResults() { + return Collections.unmodifiableMap(submodules); + } }
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 319ae1e..d43be89 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/transport/HMACSHA1NonceGenerator.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/transport/HMACSHA1NonceGenerator.java
@@ -82,6 +82,7 @@ public HMACSHA1NonceGenerator(String seed) throws IllegalStateException { } } + @Override public synchronized String createNonce(Repository repo, long timestamp) throws IllegalStateException { String path;
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/transport/HttpAuthMethod.java b/org.eclipse.jgit/src/org/eclipse/jgit/transport/HttpAuthMethod.java index 81e6904..c97daa9 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/transport/HttpAuthMethod.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/transport/HttpAuthMethod.java
@@ -56,6 +56,7 @@ import java.util.HashMap; import java.util.LinkedHashMap; import java.util.List; +import java.util.Locale; import java.util.Map; import java.util.Map.Entry; import java.util.Random; @@ -168,7 +169,8 @@ static HttpAuthMethod scanResponse(final HttpConnection conn, SCHEMA_NAME_SEPARATOR, 2); try { - Type methodType = Type.valueOf(valuePart[0].toUpperCase()); + Type methodType = Type.valueOf( + valuePart[0].toUpperCase(Locale.ROOT)); if ((ignoreTypes != null) && (ignoreTypes.contains(methodType))) { @@ -346,7 +348,7 @@ void authorize(final String username, final String password) { @SuppressWarnings("boxing") @Override void configureRequest(final HttpConnection conn) throws IOException { - final Map<String, String> r = new LinkedHashMap<String, String>(); + final Map<String, String> r = new LinkedHashMap<>(); final String realm = params.get("realm"); //$NON-NLS-1$ final String nonce = params.get("nonce"); //$NON-NLS-1$ @@ -465,7 +467,7 @@ private static String LHEX(byte[] bin) { } private static Map<String, String> parse(String auth) { - Map<String, String> p = new HashMap<String, String>(); + Map<String, String> p = new HashMap<>(); int next = 0; while (next < auth.length()) { if (next < auth.length() && auth.charAt(next) == ',') { @@ -540,7 +542,7 @@ void configureRequest(HttpConnection conn) throws IOException { GSSManager gssManager = GSS_MANAGER_FACTORY.newInstance(conn .getURL()); String host = conn.getURL().getHost(); - String peerName = "HTTP@" + host.toLowerCase(); //$NON-NLS-1$ + String peerName = "HTTP@" + host.toLowerCase(Locale.ROOT); //$NON-NLS-1$ try { GSSName gssName = gssManager.createName(peerName, GSSName.NT_HOSTBASED_SERVICE);
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/transport/InternalFetchConnection.java b/org.eclipse.jgit/src/org/eclipse/jgit/transport/InternalFetchConnection.java index 7fc4048..bea8d60 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/transport/InternalFetchConnection.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/transport/InternalFetchConnection.java
@@ -87,6 +87,7 @@ public InternalFetchConnection(PackTransport transport, } worker = new Thread("JGit-Upload-Pack") { //$NON-NLS-1$ + @Override public void run() { try { final UploadPack rp = uploadPackFactory.create(req, remote);
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/transport/InternalPushConnection.java b/org.eclipse.jgit/src/org/eclipse/jgit/transport/InternalPushConnection.java index ab76e0f..8a1884e 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/transport/InternalPushConnection.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/transport/InternalPushConnection.java
@@ -79,6 +79,7 @@ public InternalPushConnection(PackTransport transport, } worker = new Thread("JGit-Receive-Pack") { //$NON-NLS-1$ + @Override public void run() { try { final ReceivePack rp = receivePackFactory.create(req, remote);
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/transport/JschConfigSessionFactory.java b/org.eclipse.jgit/src/org/eclipse/jgit/transport/JschConfigSessionFactory.java index d1cbd8d..ce14183 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/transport/JschConfigSessionFactory.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/transport/JschConfigSessionFactory.java
@@ -80,7 +80,7 @@ * to supply appropriate {@link UserInfo} to the session. */ public abstract class JschConfigSessionFactory extends SshSessionFactory { - private final Map<String, JSch> byIdentityFile = new HashMap<String, JSch>(); + private final Map<String, JSch> byIdentityFile = new HashMap<>(); private JSch defaultJSch;
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/transport/JschSession.java b/org.eclipse.jgit/src/org/eclipse/jgit/transport/JschSession.java index fa27bfc..f445bcb 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/transport/JschSession.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/transport/JschSession.java
@@ -87,10 +87,12 @@ public JschSession(final Session session, URIish uri) { this.uri = uri; } + @Override public Process exec(String command, int timeout) throws IOException { return new JschProcess(command, timeout); } + @Override public void disconnect() { if (sock.isConnected()) sock.disconnect();
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/transport/LongMap.java b/org.eclipse.jgit/src/org/eclipse/jgit/transport/LongMap.java index 88b4b07..4d60202 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/transport/LongMap.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/transport/LongMap.java
@@ -106,7 +106,7 @@ V put(final long key, final V value) { if (++size == growAt) grow(); - insert(new Node<V>(key, value)); + insert(new Node<>(key, value)); return null; }
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/transport/NetRC.java b/org.eclipse.jgit/src/org/eclipse/jgit/transport/NetRC.java index bacab7e..bab5bf0 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/transport/NetRC.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/transport/NetRC.java
@@ -48,6 +48,7 @@ import java.io.IOException; import java.util.Collection; import java.util.HashMap; +import java.util.Locale; import java.util.Map; import java.util.TreeMap; import java.util.regex.Matcher; @@ -124,7 +125,7 @@ boolean complete() { private long lastModified; - private Map<String, NetRCEntry> hosts = new HashMap<String, NetRCEntry>(); + private Map<String, NetRCEntry> hosts = new HashMap<>(); private static final TreeMap<String, State> STATE = new TreeMap<String, NetRC.State>() { private static final long serialVersionUID = -4285910831814853334L; @@ -230,7 +231,7 @@ private void parse() { matcher.reset(line); while (matcher.find()) { - String command = matcher.group().toLowerCase(); + String command = matcher.group().toLowerCase(Locale.ROOT); if (command.startsWith("#")) { //$NON-NLS-1$ matcher.reset(""); //$NON-NLS-1$ continue;
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/transport/OpenSshConfig.java b/org.eclipse.jgit/src/org/eclipse/jgit/transport/OpenSshConfig.java index 38f3a2a..8b7b60d 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/transport/OpenSshConfig.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/transport/OpenSshConfig.java
@@ -175,9 +175,9 @@ private synchronized Map<String, Host> refresh() { } private Map<String, Host> parse(final InputStream in) throws IOException { - final Map<String, Host> m = new LinkedHashMap<String, Host>(); + final Map<String, Host> m = new LinkedHashMap<>(); final BufferedReader br = new BufferedReader(new InputStreamReader(in)); - final List<Host> current = new ArrayList<Host>(4); + final List<Host> current = new ArrayList<>(4); String line; while ((line = br.readLine()) != null) { @@ -311,6 +311,7 @@ private File toFile(final String path) { static String userName() { return AccessController.doPrivileged(new PrivilegedAction<String>() { + @Override public String run() { return System.getProperty("user.name"); //$NON-NLS-1$ }
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/transport/OperationResult.java b/org.eclipse.jgit/src/org/eclipse/jgit/transport/OperationResult.java index ad51f3e..4231798 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/transport/OperationResult.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/transport/OperationResult.java
@@ -64,7 +64,7 @@ public abstract class OperationResult { URIish uri; - final SortedMap<String, TrackingRefUpdate> updates = new TreeMap<String, TrackingRefUpdate>(); + final SortedMap<String, TrackingRefUpdate> updates = new TreeMap<>(); StringBuilder messageBuffer;
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 4bbe3f8..c82b389 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/transport/PackParser.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/transport/PackParser.java
@@ -83,6 +83,7 @@ import org.eclipse.jgit.util.BlockList; import org.eclipse.jgit.util.IO; import org.eclipse.jgit.util.NB; +import org.eclipse.jgit.util.sha1.SHA1; /** * Parses a pack stream and imports it for an {@link ObjectInserter}. @@ -116,8 +117,7 @@ public static enum Source { private byte[] hdrBuf; - private final MessageDigest objectDigest; - + private final SHA1 objectHasher = SHA1.newInstance(); private final MutableObjectId tempObjectId; private InputStream in; @@ -206,7 +206,6 @@ protected PackParser(final ObjectDatabase odb, final InputStream src) { buf = new byte[BUFFER_SIZE]; tempBuffer = new byte[BUFFER_SIZE]; hdrBuf = new byte[64]; - objectDigest = Constants.newMessageDigest(); tempObjectId = new MutableObjectId(); packDigest = Constants.newMessageDigest(); checkObjectCollisions = true; @@ -275,7 +274,7 @@ protected void setCheckObjectCollisions(boolean check) { */ public void setNeedNewObjectIds(boolean b) { if (b) - newObjectIds = new ObjectIdSubclassMap<ObjectId>(); + newObjectIds = new ObjectIdSubclassMap<>(); else newObjectIds = null; } @@ -333,14 +332,14 @@ public void setExpectDataAfterPackFooter(boolean e) { public ObjectIdSubclassMap<ObjectId> getNewObjectIds() { if (newObjectIds != null) return newObjectIds; - return new ObjectIdSubclassMap<ObjectId>(); + return new ObjectIdSubclassMap<>(); } /** @return set of objects the incoming pack assumed for delta purposes */ public ObjectIdSubclassMap<ObjectId> getBaseObjectIds() { if (baseObjectIds != null) return baseObjectIds; - return new ObjectIdSubclassMap<ObjectId>(); + return new ObjectIdSubclassMap<>(); } /** @@ -527,9 +526,9 @@ public PackLock parse(ProgressMonitor receiving, ProgressMonitor resolving) readPackHeader(); entries = new PackedObjectInfo[(int) objectCount]; - baseById = new ObjectIdOwnerMap<DeltaChain>(); - baseByPos = new LongMap<UnresolvedDelta>(); - deferredCheckBlobs = new BlockList<PackedObjectInfo>(); + baseById = new ObjectIdOwnerMap<>(); + baseByPos = new LongMap<>(); + deferredCheckBlobs = new BlockList<>(); receiving.beginTask(JGitText.get().receivingObjects, (int) objectCount); @@ -667,12 +666,13 @@ private void resolveDeltas(DeltaVisit visit, final int type, JGitText.get().corruptionDetectedReReadingAt, Long.valueOf(visit.delta.position))); + SHA1 objectDigest = objectHasher.reset(); objectDigest.update(Constants.encodedTypeString(type)); objectDigest.update((byte) ' '); objectDigest.update(Constants.encodeASCII(visit.data.length)); objectDigest.update((byte) 0); objectDigest.update(visit.data); - tempObjectId.fromRaw(objectDigest.digest(), 0); + objectDigest.digest(tempObjectId); verifySafeObject(tempObjectId, type, visit.data); @@ -826,9 +826,9 @@ private void resolveDeltasWithExternalBases(final ProgressMonitor progress) growEntries(baseById.size()); if (needBaseObjectIds) - baseObjectIds = new ObjectIdSubclassMap<ObjectId>(); + baseObjectIds = new ObjectIdSubclassMap<>(); - final List<DeltaChain> missing = new ArrayList<DeltaChain>(64); + final List<DeltaChain> missing = new ArrayList<>(64); for (final DeltaChain baseId : baseById) { if (baseId.head == null) continue; @@ -1024,6 +1024,7 @@ private void indexOneObject() throws IOException { private void whole(final long pos, final int type, final long sz) throws IOException { + SHA1 objectDigest = objectHasher.reset(); objectDigest.update(Constants.encodedTypeString(type)); objectDigest.update((byte) ' '); objectDigest.update(Constants.encodeASCII(sz)); @@ -1043,7 +1044,7 @@ private void whole(final long pos, final int type, final long sz) cnt += r; } inf.close(); - tempObjectId.fromRaw(objectDigest.digest(), 0); + objectDigest.digest(tempObjectId); checkContentLater = isCheckObjectCollisions() && readCurs.has(tempObjectId); data = null; @@ -1051,7 +1052,7 @@ private void whole(final long pos, final int type, final long sz) } else { data = inflateAndReturn(Source.INPUT, sz); objectDigest.update(data); - tempObjectId.fromRaw(objectDigest.digest(), 0); + objectDigest.digest(tempObjectId); verifySafeObject(tempObjectId, type, data); }
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 e142bab..e709256 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/transport/PacketLineIn.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/transport/PacketLineIn.java
@@ -87,19 +87,32 @@ static enum AckNackResult { ACK_READY; } + private final byte[] lineBuffer = new byte[SideBandOutputStream.SMALL_BUF]; private final InputStream in; - - private final byte[] lineBuffer; + private long limit; /** * Create a new packet line reader. * - * @param i + * @param in * the input stream to consume. */ - public PacketLineIn(final InputStream i) { - in = i; - lineBuffer = new byte[SideBandOutputStream.SMALL_BUF]; + public PacketLineIn(InputStream in) { + this(in, 0); + } + + /** + * Create a new packet line reader. + * + * @param in + * the input stream to consume. + * @param limit + * bytes to read from the input; unlimited if set to 0. + * @since 4.7 + */ + public PacketLineIn(InputStream in, long limit) { + this.in = in; + this.limit = limit; } AckNackResult readACK(final MutableObjectId returnedId) throws IOException { @@ -210,15 +223,48 @@ void discardUntilEnd() throws IOException { int readLength() throws IOException { IO.readFully(in, lineBuffer, 0, 4); + int len; try { - final int len = RawParseUtils.parseHexInt16(lineBuffer, 0); - if (len != 0 && len < 4) - throw new ArrayIndexOutOfBoundsException(); - return len; + len = RawParseUtils.parseHexInt16(lineBuffer, 0); } catch (ArrayIndexOutOfBoundsException err) { - throw new IOException(MessageFormat.format(JGitText.get().invalidPacketLineHeader, - "" + (char) lineBuffer[0] + (char) lineBuffer[1] //$NON-NLS-1$ - + (char) lineBuffer[2] + (char) lineBuffer[3])); + throw invalidHeader(); } + + if (len == 0) { + return 0; + } else if (len < 4) { + throw invalidHeader(); + } + + if (limit != 0) { + int n = len - 4; + if (limit < n) { + limit = -1; + try { + IO.skipFully(in, n); + } catch (IOException e) { + // Ignore failure discarding packet over limit. + } + throw new InputOverLimitIOException(); + } + // if set limit must not be 0 (means unlimited). + limit = n < limit ? limit - n : -1; + } + return len; + } + + private IOException invalidHeader() { + return new IOException(MessageFormat.format(JGitText.get().invalidPacketLineHeader, + "" + (char) lineBuffer[0] + (char) lineBuffer[1] //$NON-NLS-1$ + + (char) lineBuffer[2] + (char) lineBuffer[3])); + } + + /** + * IOException thrown by read when the configured input limit is exceeded. + * + * @since 4.7 + */ + public static class InputOverLimitIOException extends IOException { + private static final long serialVersionUID = 1L; } }
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/transport/PostReceiveHook.java b/org.eclipse.jgit/src/org/eclipse/jgit/transport/PostReceiveHook.java index 1e66275..8e39501 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/transport/PostReceiveHook.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/transport/PostReceiveHook.java
@@ -62,6 +62,7 @@ public interface PostReceiveHook { /** A simple no-op hook. */ public static final PostReceiveHook NULL = new PostReceiveHook() { + @Override public void onPostReceive(final ReceivePack rp, final Collection<ReceiveCommand> commands) { // Do nothing.
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/transport/PostReceiveHookChain.java b/org.eclipse.jgit/src/org/eclipse/jgit/transport/PostReceiveHookChain.java index da86525..3bdcd68 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/transport/PostReceiveHookChain.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/transport/PostReceiveHookChain.java
@@ -77,6 +77,7 @@ else if (i == 1) return new PostReceiveHookChain(newHooks, i); } + @Override public void onPostReceive(ReceivePack rp, Collection<ReceiveCommand> commands) { for (int i = 0; i < count; i++)
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/transport/PostUploadHook.java b/org.eclipse.jgit/src/org/eclipse/jgit/transport/PostUploadHook.java index 53eeab1..5b37bcd 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/transport/PostUploadHook.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/transport/PostUploadHook.java
@@ -58,6 +58,7 @@ public interface PostUploadHook { /** A simple no-op hook. */ public static final PostUploadHook NULL = new PostUploadHook() { + @Override public void onPostUpload(PackStatistics stats) { // Do nothing. }
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/transport/PostUploadHookChain.java b/org.eclipse.jgit/src/org/eclipse/jgit/transport/PostUploadHookChain.java index 4e2eaea..26323ba 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/transport/PostUploadHookChain.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/transport/PostUploadHookChain.java
@@ -78,6 +78,7 @@ else if (i == 1) return new PostUploadHookChain(newHooks, i); } + @Override public void onPostUpload(PackStatistics stats) { for (int i = 0; i < count; i++) hooks[i].onPostUpload(stats);
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/transport/PreReceiveHook.java b/org.eclipse.jgit/src/org/eclipse/jgit/transport/PreReceiveHook.java index 9a743a5..27b2df0 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/transport/PreReceiveHook.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/transport/PreReceiveHook.java
@@ -78,6 +78,7 @@ public interface PreReceiveHook { /** A simple no-op hook. */ public static final PreReceiveHook NULL = new PreReceiveHook() { + @Override public void onPreReceive(final ReceivePack rp, final Collection<ReceiveCommand> commands) { // Do nothing.
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/transport/PreReceiveHookChain.java b/org.eclipse.jgit/src/org/eclipse/jgit/transport/PreReceiveHookChain.java index bd4441f..7b1c8fb 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/transport/PreReceiveHookChain.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/transport/PreReceiveHookChain.java
@@ -76,6 +76,7 @@ else if (i == 1) return new PreReceiveHookChain(newHooks, i); } + @Override public void onPreReceive(ReceivePack rp, Collection<ReceiveCommand> commands) { for (int i = 0; i < count; i++)
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/transport/PreUploadHook.java b/org.eclipse.jgit/src/org/eclipse/jgit/transport/PreUploadHook.java index 0360f12..7d9638c 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/transport/PreUploadHook.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/transport/PreUploadHook.java
@@ -58,12 +58,14 @@ public interface PreUploadHook { /** A simple no-op hook. */ public static final PreUploadHook NULL = new PreUploadHook() { + @Override public void onBeginNegotiateRound(UploadPack up, Collection<? extends ObjectId> wants, int cntOffered) throws ServiceMayNotContinueException { // Do nothing. } + @Override public void onEndNegotiateRound(UploadPack up, Collection<? extends ObjectId> wants, int cntCommon, int cntNotFound, boolean ready) @@ -71,6 +73,7 @@ public void onEndNegotiateRound(UploadPack up, // Do nothing. } + @Override public void onSendPack(UploadPack up, Collection<? extends ObjectId> wants, Collection<? extends ObjectId> haves)
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/transport/PreUploadHookChain.java b/org.eclipse.jgit/src/org/eclipse/jgit/transport/PreUploadHookChain.java index 7f515e0..c9f88dd 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/transport/PreUploadHookChain.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/transport/PreUploadHookChain.java
@@ -79,6 +79,7 @@ else if (i == 1) return new PreUploadHookChain(newHooks, i); } + @Override public void onBeginNegotiateRound(UploadPack up, Collection<? extends ObjectId> wants, int cntOffered) throws ServiceMayNotContinueException { @@ -86,6 +87,7 @@ public void onBeginNegotiateRound(UploadPack up, hooks[i].onBeginNegotiateRound(up, wants, cntOffered); } + @Override public void onEndNegotiateRound(UploadPack up, Collection<? extends ObjectId> wants, int cntCommon, int cntNotFound, boolean ready) @@ -94,6 +96,7 @@ public void onEndNegotiateRound(UploadPack up, hooks[i].onEndNegotiateRound(up, wants, cntCommon, cntNotFound, ready); } + @Override public void onSendPack(UploadPack up, Collection<? extends ObjectId> wants, Collection<? extends ObjectId> haves)
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/transport/PushCertificateStore.java b/org.eclipse.jgit/src/org/eclipse/jgit/transport/PushCertificateStore.java index d436e08..706e727 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/transport/PushCertificateStore.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/transport/PushCertificateStore.java
@@ -140,6 +140,7 @@ public PushCertificateStore(Repository db) { * If {@link #get(String)} was called, closes the cached object reader created * by that method. Does not close the underlying repository. */ + @Override public void close() { if (reader != null) { reader.close();
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/transport/PushProcess.java b/org.eclipse.jgit/src/org/eclipse/jgit/transport/PushProcess.java index 5590c2d..3201732 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/transport/PushProcess.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/transport/PushProcess.java
@@ -124,7 +124,7 @@ class PushProcess { throws TransportException { this.walker = new RevWalk(transport.local); this.transport = transport; - this.toPush = new HashMap<String, RemoteRefUpdate>(); + this.toPush = new HashMap<>(); this.out = out; this.pushOptions = transport.getPushOptions(); for (final RemoteRefUpdate rru : toPush) { @@ -190,7 +190,7 @@ else if (!preprocessed.isEmpty()) private Map<String, RemoteRefUpdate> prepareRemoteUpdates() throws TransportException { boolean atomic = transport.isPushAtomic(); - final Map<String, RemoteRefUpdate> result = new HashMap<String, RemoteRefUpdate>(); + final Map<String, RemoteRefUpdate> result = new HashMap<>(); for (final RemoteRefUpdate rru : toPush.values()) { final Ref advertisedRef = connection.getRef(rru.getRemoteName()); ObjectId advertisedOld = 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 393e25a..169df3b 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/transport/ReceivePack.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/transport/ReceivePack.java
@@ -273,6 +273,7 @@ private void service() throws IOException { if (reportStatus) { if (echoCommandFailures && msgOut != null) { sendStatusReport(false, unpackError, new Reporter() { + @Override void sendString(final String s) throws IOException { msgOut.write(Constants.encode(s + "\n")); //$NON-NLS-1$ } @@ -285,6 +286,7 @@ void sendString(final String s) throws IOException { } } sendStatusReport(true, unpackError, new Reporter() { + @Override void sendString(final String s) throws IOException { pckOut.writeString(s + "\n"); //$NON-NLS-1$ } @@ -292,6 +294,7 @@ void sendString(final String s) throws IOException { pckOut.end(); } else if (msgOut != null) { sendStatusReport(false, unpackError, new Reporter() { + @Override void sendString(final String s) throws IOException { msgOut.write(Constants.encode(s + "\n")); //$NON-NLS-1$ }
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/transport/RefAdvertiser.java b/org.eclipse.jgit/src/org/eclipse/jgit/transport/RefAdvertiser.java index 0cd720c..745e813 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/transport/RefAdvertiser.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/transport/RefAdvertiser.java
@@ -163,9 +163,9 @@ protected void end() throws IOException { private final char[] tmpId = new char[Constants.OBJECT_ID_STRING_LENGTH]; - final Set<String> capablities = new LinkedHashSet<String>(); + final Set<String> capablities = new LinkedHashSet<>(); - private final Set<ObjectId> sent = new HashSet<ObjectId>(); + private final Set<ObjectId> sent = new HashSet<>(); private Repository repository;
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/transport/RefFilter.java b/org.eclipse.jgit/src/org/eclipse/jgit/transport/RefFilter.java index e46195f..d4f85f2 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/transport/RefFilter.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/transport/RefFilter.java
@@ -59,6 +59,7 @@ public interface RefFilter { /** The default filter, allows all refs to be shown. */ public static final RefFilter DEFAULT = new RefFilter() { + @Override public Map<String, Ref> filter (final Map<String, Ref> refs) { return refs; }
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/transport/RefLeaseSpec.java b/org.eclipse.jgit/src/org/eclipse/jgit/transport/RefLeaseSpec.java new file mode 100644 index 0000000..734f523 --- /dev/null +++ b/org.eclipse.jgit/src/org/eclipse/jgit/transport/RefLeaseSpec.java
@@ -0,0 +1,100 @@ +/* + * Copyright (C) 2017 Two Sigma Open Source + * 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.Serializable; + +/** + * Describes the expected value for a ref being pushed. + * @since 4.7 + */ +public class RefLeaseSpec implements Serializable { + private static final long serialVersionUID = 1L; + + /** Name of the ref whose value we want to check. */ + private final String ref; + + /** Local commitish to get expected value from. */ + private final String expected; + + /** + * + * @param ref + * ref being pushed + * @param expected + * the expected value of the ref + */ + public RefLeaseSpec(String ref, String expected) { + this.ref = ref; + this.expected = expected; + } + + /** + * Get the ref to protect. + * + * @return name of ref to check. + */ + public String getRef() { + return ref; + } + + /** + * Get the expected value of the ref, in the form + * of a local committish + * + * @return expected ref value. + */ + public String getExpected() { + return expected; + } + + @Override + public String toString() { + final StringBuilder r = new StringBuilder(); + r.append(getRef()); + r.append(':'); + r.append(getExpected()); + return r.toString(); + } +}
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/transport/RefSpec.java b/org.eclipse.jgit/src/org/eclipse/jgit/transport/RefSpec.java index 1440b83..64f6c3f 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/transport/RefSpec.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/transport/RefSpec.java
@@ -556,6 +556,7 @@ private static boolean isValid(final String s) { return true; } + @Override public int hashCode() { int hc = 0; if (getSource() != null) @@ -565,6 +566,7 @@ public int hashCode() { return hc; } + @Override public boolean equals(final Object obj) { if (!(obj instanceof RefSpec)) return false; @@ -588,6 +590,7 @@ private static boolean eq(final String a, final String b) { return a.equals(b); } + @Override public String toString() { final StringBuilder r = new StringBuilder(); if (isForceUpdate())
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 ba0931b..d91684e 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/transport/RemoteConfig.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/transport/RemoteConfig.java
@@ -114,11 +114,11 @@ public class RemoteConfig implements Serializable { */ public static List<RemoteConfig> getAllRemoteConfigs(final Config rc) throws URISyntaxException { - final List<String> names = new ArrayList<String>(rc + final List<String> names = new ArrayList<>(rc .getSubsections(SECTION)); Collections.sort(names); - final List<RemoteConfig> result = new ArrayList<RemoteConfig>(names + final List<RemoteConfig> result = new ArrayList<>(names .size()); for (final String name : names) result.add(new RemoteConfig(rc, name)); @@ -169,24 +169,24 @@ public RemoteConfig(final Config rc, final String remoteName) vlst = rc.getStringList(SECTION, name, KEY_URL); Map<String, String> insteadOf = getReplacements(rc, KEY_INSTEADOF); - uris = new ArrayList<URIish>(vlst.length); + uris = new ArrayList<>(vlst.length); for (final String s : vlst) uris.add(new URIish(replaceUri(s, insteadOf))); Map<String, String> pushInsteadOf = getReplacements(rc, KEY_PUSHINSTEADOF); vlst = rc.getStringList(SECTION, name, KEY_PUSHURL); - pushURIs = new ArrayList<URIish>(vlst.length); + pushURIs = new ArrayList<>(vlst.length); for (final String s : vlst) pushURIs.add(new URIish(replaceUri(s, pushInsteadOf))); vlst = rc.getStringList(SECTION, name, KEY_FETCH); - fetch = new ArrayList<RefSpec>(vlst.length); + fetch = new ArrayList<>(vlst.length); for (final String s : vlst) fetch.add(new RefSpec(s)); vlst = rc.getStringList(SECTION, name, KEY_PUSH); - push = new ArrayList<RefSpec>(vlst.length); + push = new ArrayList<>(vlst.length); for (final String s : vlst) push.add(new RefSpec(s)); @@ -213,7 +213,7 @@ public RemoteConfig(final Config rc, final String remoteName) * the configuration file to store ourselves into. */ public void update(final Config rc) { - final List<String> vlst = new ArrayList<String>(); + final List<String> vlst = new ArrayList<>(); vlst.clear(); for (final URIish u : getURIs()) @@ -272,7 +272,7 @@ private void unset(final Config rc, final String key) { private Map<String, String> getReplacements(final Config config, final String keyName) { - final Map<String, String> replacements = new HashMap<String, String>(); + final Map<String, String> replacements = new HashMap<>(); for (String url : config.getSubsections(KEY_URL)) for (String insteadOf : config.getStringList(KEY_URL, url, keyName)) replacements.put(insteadOf, url);
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/transport/ServiceMayNotContinueException.java b/org.eclipse.jgit/src/org/eclipse/jgit/transport/ServiceMayNotContinueException.java index 81c5da3..87c9a500 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/transport/ServiceMayNotContinueException.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/transport/ServiceMayNotContinueException.java
@@ -45,8 +45,6 @@ import java.io.IOException; -import javax.servlet.http.HttpServletResponse; - import org.eclipse.jgit.internal.JGitText; /** @@ -55,6 +53,7 @@ * @since 2.0 */ public class ServiceMayNotContinueException extends IOException { + private static final int FORBIDDEN = 403; private static final long serialVersionUID = 1L; private final int statusCode; @@ -63,7 +62,7 @@ public class ServiceMayNotContinueException extends IOException { /** Initialize with no message. */ public ServiceMayNotContinueException() { // Do not set a message. - statusCode = HttpServletResponse.SC_FORBIDDEN; + statusCode = FORBIDDEN; } /** @@ -73,7 +72,7 @@ public ServiceMayNotContinueException() { */ public ServiceMayNotContinueException(String msg) { super(msg); - statusCode = HttpServletResponse.SC_FORBIDDEN; + statusCode = FORBIDDEN; } /** @@ -99,7 +98,7 @@ public ServiceMayNotContinueException(String msg, int statusCode) { */ public ServiceMayNotContinueException(String msg, Throwable cause) { super(msg, cause); - statusCode = HttpServletResponse.SC_FORBIDDEN; + statusCode = FORBIDDEN; } /**
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/transport/SignedPushConfig.java b/org.eclipse.jgit/src/org/eclipse/jgit/transport/SignedPushConfig.java index 942e7d7..83b4aca 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/transport/SignedPushConfig.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/transport/SignedPushConfig.java
@@ -55,6 +55,7 @@ public class SignedPushConfig { /** Key for {@link Config#get(SectionParser)}. */ public static final SectionParser<SignedPushConfig> KEY = new SectionParser<SignedPushConfig>() { + @Override public SignedPushConfig parse(Config cfg) { return new SignedPushConfig(cfg); }
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/transport/TestProtocol.java b/org.eclipse.jgit/src/org/eclipse/jgit/transport/TestProtocol.java index 5fd2f84..8a28e3a 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/transport/TestProtocol.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/transport/TestProtocol.java
@@ -103,7 +103,7 @@ public TestProtocol(UploadPackFactory<C> uploadPackFactory, ReceivePackFactory<C> receivePackFactory) { this.uploadPackFactory = uploadPackFactory; this.receivePackFactory = receivePackFactory; - this.handles = new HashMap<URIish, Handle>(); + this.handles = new HashMap<>(); } @Override @@ -174,7 +174,7 @@ private class TransportInternal extends Transport implements PackTransport { public FetchConnection openFetch() throws NotSupportedException, TransportException { handle.remote.incrementOpen(); - return new InternalFetchConnection<C>( + return new InternalFetchConnection<>( this, uploadPackFactory, handle.req, handle.remote); } @@ -182,7 +182,7 @@ public FetchConnection openFetch() throws NotSupportedException, public PushConnection openPush() throws NotSupportedException, TransportException { handle.remote.incrementOpen(); - return new InternalPushConnection<C>( + return new InternalPushConnection<>( this, receivePackFactory, handle.req, handle.remote); }
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 72c9c8b..2198b50 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/transport/TransferConfig.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/transport/TransferConfig.java
@@ -70,6 +70,7 @@ public class TransferConfig { /** Key for {@link Config#get(SectionParser)}. */ public static final Config.SectionParser<TransferConfig> KEY = new SectionParser<TransferConfig>() { + @Override public TransferConfig parse(final Config cfg) { return new TransferConfig(cfg); } @@ -207,8 +208,9 @@ public RefFilter getRefFilter() { return RefFilter.DEFAULT; return new RefFilter() { + @Override public Map<String, Ref> filter(Map<String, Ref> refs) { - Map<String, Ref> result = new HashMap<String, Ref>(); + Map<String, Ref> result = new HashMap<>(); for (Map.Entry<String, Ref> e : refs.entrySet()) { boolean add = true; for (String hide : hideRefs) {
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 df86069..649e840 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/transport/Transport.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/transport/Transport.java
@@ -80,6 +80,7 @@ import org.eclipse.jgit.lib.Constants; import org.eclipse.jgit.lib.NullProgressMonitor; import org.eclipse.jgit.lib.ObjectChecker; +import org.eclipse.jgit.lib.ObjectId; import org.eclipse.jgit.lib.ProgressMonitor; import org.eclipse.jgit.lib.Ref; import org.eclipse.jgit.lib.Repository; @@ -108,7 +109,7 @@ public enum Operation { } private static final List<WeakReference<TransportProtocol>> protocols = - new CopyOnWriteArrayList<WeakReference<TransportProtocol>>(); + new CopyOnWriteArrayList<>(); static { // Registration goes backwards in order of priority. @@ -225,7 +226,7 @@ private static void load(ClassLoader ldr, String cn) { * the protocol definition. Must not be null. */ public static void register(TransportProtocol proto) { - protocols.add(0, new WeakReference<TransportProtocol>(proto)); + protocols.add(0, new WeakReference<>(proto)); } /** @@ -255,7 +256,7 @@ public static void unregister(TransportProtocol proto) { */ public static List<TransportProtocol> getTransportProtocols() { int cnt = protocols.size(); - List<TransportProtocol> res = new ArrayList<TransportProtocol>(cnt); + List<TransportProtocol> res = new ArrayList<>(cnt); for (WeakReference<TransportProtocol> ref : protocols) { TransportProtocol proto = ref.get(); if (proto != null) @@ -379,7 +380,7 @@ public static List<Transport> openAll(final Repository local, TransportException { final RemoteConfig cfg = new RemoteConfig(local.getConfig(), remote); if (doesNotExist(cfg)) { - final ArrayList<Transport> transports = new ArrayList<Transport>(1); + final ArrayList<Transport> transports = new ArrayList<>(1); transports.add(open(local, new URIish(remote), null)); return transports; } @@ -489,7 +490,7 @@ public static List<Transport> openAll(final Repository local, final RemoteConfig cfg, final Operation op) throws NotSupportedException, TransportException { final List<URIish> uris = getURIs(cfg, op); - final List<Transport> transports = new ArrayList<Transport>(uris.size()); + final List<Transport> transports = new ArrayList<>(uris.size()); for (final URIish uri : uris) { final Transport tn = open(local, uri, cfg.getName()); tn.applyConfig(cfg); @@ -603,14 +604,16 @@ public static Transport open(URIish uri) throws NotSupportedException, Transport * Convert push remote refs update specification from {@link RefSpec} form * to {@link RemoteRefUpdate}. Conversion expands wildcards by matching * source part to local refs. expectedOldObjectId in RemoteRefUpdate is - * always set as null. Tracking branch is configured if RefSpec destination - * matches source of any fetch ref spec for this transport remote - * configuration. + * set when specified in leases. Tracking branch is configured if RefSpec + * destination matches source of any fetch ref spec for this transport + * remote configuration. * * @param db * local database. * @param specs * collection of RefSpec to convert. + * @param leases + * map from ref to lease (containing expected old object id) * @param fetchSpecs * fetch specifications used for finding localtracking refs. May * be null or empty collection. @@ -618,13 +621,15 @@ public static Transport open(URIish uri) throws NotSupportedException, Transport * @throws IOException * when problem occurred during conversion or specification set * up: most probably, missing objects or refs. + * @since 4.7 */ public static Collection<RemoteRefUpdate> findRemoteRefUpdatesFor( final Repository db, final Collection<RefSpec> specs, + final Map<String, RefLeaseSpec> leases, Collection<RefSpec> fetchSpecs) throws IOException { if (fetchSpecs == null) fetchSpecs = Collections.emptyList(); - final List<RemoteRefUpdate> result = new LinkedList<RemoteRefUpdate>(); + final List<RemoteRefUpdate> result = new LinkedList<>(); final Collection<RefSpec> procRefs = expandPushWildcardsFor(db, specs); for (final RefSpec spec : procRefs) { @@ -652,18 +657,48 @@ public static Collection<RemoteRefUpdate> findRemoteRefUpdatesFor( final boolean forceUpdate = spec.isForceUpdate(); final String localName = findTrackingRefName(destSpec, fetchSpecs); + final RefLeaseSpec leaseSpec = leases.get(destSpec); + final ObjectId expected = leaseSpec == null ? null : + db.resolve(leaseSpec.getExpected()); final RemoteRefUpdate rru = new RemoteRefUpdate(db, srcSpec, - destSpec, forceUpdate, localName, null); + destSpec, forceUpdate, localName, expected); result.add(rru); } return result; } + /** + * Convert push remote refs update specification from {@link RefSpec} form + * to {@link RemoteRefUpdate}. Conversion expands wildcards by matching + * source part to local refs. expectedOldObjectId in RemoteRefUpdate is + * always set as null. Tracking branch is configured if RefSpec destination + * matches source of any fetch ref spec for this transport remote + * configuration. + * + * @param db + * local database. + * @param specs + * collection of RefSpec to convert. + * @param fetchSpecs + * fetch specifications used for finding localtracking refs. May + * be null or empty collection. + * @return collection of set up {@link RemoteRefUpdate}. + * @throws IOException + * when problem occurred during conversion or specification set + * up: most probably, missing objects or refs. + */ + public static Collection<RemoteRefUpdate> findRemoteRefUpdatesFor( + final Repository db, final Collection<RefSpec> specs, + Collection<RefSpec> fetchSpecs) throws IOException { + return findRemoteRefUpdatesFor(db, specs, Collections.emptyMap(), + fetchSpecs); + } + private static Collection<RefSpec> expandPushWildcardsFor( final Repository db, final Collection<RefSpec> specs) throws IOException { final Map<String, Ref> localRefs = db.getRefDatabase().getRefs(ALL); - final Collection<RefSpec> procRefs = new HashSet<RefSpec>(); + final Collection<RefSpec> procRefs = new HashSet<>(); for (final RefSpec spec : specs) { if (spec.isWildcard()) { @@ -1182,7 +1217,7 @@ public FetchResult fetch(final ProgressMonitor monitor, // the local tracking branches without incurring additional // object transfer overheads. // - final Collection<RefSpec> tmp = new ArrayList<RefSpec>(toFetch); + final Collection<RefSpec> tmp = new ArrayList<>(toFetch); for (final RefSpec requested : toFetch) { final String reqSrc = requested.getSource(); for (final RefSpec configured : fetch) { @@ -1341,7 +1376,36 @@ public PushResult push(final ProgressMonitor monitor, */ public Collection<RemoteRefUpdate> findRemoteRefUpdatesFor( final Collection<RefSpec> specs) throws IOException { - return findRemoteRefUpdatesFor(local, specs, fetch); + return findRemoteRefUpdatesFor(local, specs, Collections.emptyMap(), + fetch); + } + + /** + * Convert push remote refs update specification from {@link RefSpec} form + * to {@link RemoteRefUpdate}. Conversion expands wildcards by matching + * source part to local refs. expectedOldObjectId in RemoteRefUpdate is + * set according to leases. Tracking branch is configured if RefSpec destination + * matches source of any fetch ref spec for this transport remote + * configuration. + * <p> + * Conversion is performed for context of this transport (database, fetch + * specifications). + * + * @param specs + * collection of RefSpec to convert. + * @param leases + * map from ref to lease (containing expected old object id) + * @return collection of set up {@link RemoteRefUpdate}. + * @throws IOException + * when problem occurred during conversion or specification set + * up: most probably, missing objects or refs. + * @since 4.7 + */ + public Collection<RemoteRefUpdate> findRemoteRefUpdatesFor( + final Collection<RefSpec> specs, + final Map<String, RefLeaseSpec> leases) throws IOException { + return findRemoteRefUpdatesFor(local, specs, leases, + fetch); } /** @@ -1383,5 +1447,6 @@ public abstract PushConnection openPush() throws NotSupportedException, * Implementers shouldn't throw checked exceptions. This override narrows * the signature to prevent them from doing so. */ + @Override public abstract void close(); }
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/transport/TransportAmazonS3.java b/org.eclipse.jgit/src/org/eclipse/jgit/transport/TransportAmazonS3.java index 23c506b..6cd119b 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/transport/TransportAmazonS3.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/transport/TransportAmazonS3.java
@@ -101,23 +101,28 @@ public class TransportAmazonS3 extends HttpTransport implements WalkTransport { static final String S3_SCHEME = "amazon-s3"; //$NON-NLS-1$ static final TransportProtocol PROTO_S3 = new TransportProtocol() { + @Override public String getName() { return "Amazon S3"; //$NON-NLS-1$ } + @Override public Set<String> getSchemes() { return Collections.singleton(S3_SCHEME); } + @Override public Set<URIishField> getRequiredFields() { return Collections.unmodifiableSet(EnumSet.of(URIishField.USER, URIishField.HOST, URIishField.PATH)); } + @Override public Set<URIishField> getOptionalFields() { return Collections.unmodifiableSet(EnumSet.of(URIishField.PASS)); } + @Override public Transport open(URIish uri, Repository local, String remoteName) throws NotSupportedException { return new TransportAmazonS3(local, uri); @@ -265,10 +270,10 @@ WalkRemoteObjectDatabase openAlternate(final String location) @Override Collection<String> getPackNames() throws IOException { - final HashSet<String> have = new HashSet<String>(); + final HashSet<String> have = new HashSet<>(); have.addAll(s3.list(bucket, resolveKey("pack"))); //$NON-NLS-1$ - final Collection<String> packs = new ArrayList<String>(); + final Collection<String> packs = new ArrayList<>(); for (final String n : have) { if (!n.startsWith("pack-") || !n.endsWith(".pack")) //$NON-NLS-1$ //$NON-NLS-2$ continue; @@ -307,7 +312,7 @@ void writeFile(final String path, final byte[] data) throws IOException { } Map<String, Ref> readAdvertisedRefs() throws TransportException { - final TreeMap<String, Ref> avail = new TreeMap<String, Ref>(); + final TreeMap<String, Ref> avail = new TreeMap<>(); readPackedRefs(avail); readLooseRefs(avail); readRef(avail, Constants.HEAD);
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/transport/TransportBundleFile.java b/org.eclipse.jgit/src/org/eclipse/jgit/transport/TransportBundleFile.java index 9b08341..f2ddc0d 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/transport/TransportBundleFile.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/transport/TransportBundleFile.java
@@ -66,7 +66,7 @@ class TransportBundleFile extends Transport implements TransportBundle { private final String[] schemeNames = { "bundle", "file" }; //$NON-NLS-1$ //$NON-NLS-2$ private final Set<String> schemeSet = Collections - .unmodifiableSet(new LinkedHashSet<String>(Arrays + .unmodifiableSet(new LinkedHashSet<>(Arrays .asList(schemeNames))); @Override @@ -74,6 +74,7 @@ public String getName() { return JGitText.get().transportProtoBundleFile; } + @Override public Set<String> getSchemes() { return schemeSet; } @@ -106,6 +107,7 @@ public Transport open(URIish uri, Repository local, String remoteName) return TransportLocal.PROTO_LOCAL.open(uri, local, remoteName); } + @Override public Transport open(URIish uri) throws NotSupportedException, TransportException { if ("bundle".equals(uri.getScheme())) { //$NON-NLS-1$
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/transport/TransportGitAnon.java b/org.eclipse.jgit/src/org/eclipse/jgit/transport/TransportGitAnon.java index c6e4c50..7bf5b94 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/transport/TransportGitAnon.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/transport/TransportGitAnon.java
@@ -75,27 +75,33 @@ class TransportGitAnon extends TcpTransport implements PackTransport { static final int GIT_PORT = Daemon.DEFAULT_PORT; static final TransportProtocol PROTO_GIT = new TransportProtocol() { + @Override public String getName() { return JGitText.get().transportProtoGitAnon; } + @Override public Set<String> getSchemes() { return Collections.singleton("git"); //$NON-NLS-1$ } + @Override public Set<URIishField> getRequiredFields() { return Collections.unmodifiableSet(EnumSet.of(URIishField.HOST, URIishField.PATH)); } + @Override public Set<URIishField> getOptionalFields() { return Collections.unmodifiableSet(EnumSet.of(URIishField.PORT)); } + @Override public int getDefaultPort() { return GIT_PORT; } + @Override public Transport open(URIish uri, Repository local, String remoteName) throws NotSupportedException { return new TransportGitAnon(local, uri);
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/transport/TransportGitSsh.java b/org.eclipse.jgit/src/org/eclipse/jgit/transport/TransportGitSsh.java index da98e8c..9a40f47 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/transport/TransportGitSsh.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/transport/TransportGitSsh.java
@@ -56,6 +56,7 @@ import java.util.EnumSet; import java.util.LinkedHashSet; import java.util.List; +import java.util.Locale; import java.util.Set; import org.eclipse.jgit.errors.NoRemoteRepositoryException; @@ -86,27 +87,32 @@ public class TransportGitSsh extends SshTransport implements PackTransport { private final String[] schemeNames = { "ssh", "ssh+git", "git+ssh" }; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ private final Set<String> schemeSet = Collections - .unmodifiableSet(new LinkedHashSet<String>(Arrays + .unmodifiableSet(new LinkedHashSet<>(Arrays .asList(schemeNames))); + @Override public String getName() { return JGitText.get().transportProtoSSH; } + @Override public Set<String> getSchemes() { return schemeSet; } + @Override public Set<URIishField> getRequiredFields() { return Collections.unmodifiableSet(EnumSet.of(URIishField.HOST, URIishField.PATH)); } + @Override public Set<URIishField> getOptionalFields() { return Collections.unmodifiableSet(EnumSet.of(URIishField.USER, URIishField.PASS, URIishField.PORT)); } + @Override public int getDefaultPort() { return 22; } @@ -123,6 +129,7 @@ public boolean canHandle(URIish uri, Repository local, String remoteName) { return super.canHandle(uri, local, remoteName); } + @Override public Transport open(URIish uri, Repository local, String remoteName) throws NotSupportedException { return new TransportGitSsh(local, uri); @@ -214,14 +221,16 @@ private static boolean useExtSession() { } private class ExtSession implements RemoteSession { + @Override public Process exec(String command, int timeout) throws TransportException { String ssh = SystemReader.getInstance().getenv("GIT_SSH"); //$NON-NLS-1$ - boolean putty = ssh.toLowerCase().contains("plink"); //$NON-NLS-1$ + boolean putty = ssh.toLowerCase(Locale.ROOT).contains("plink"); //$NON-NLS-1$ - List<String> args = new ArrayList<String>(); + List<String> args = new ArrayList<>(); args.add(ssh); - if (putty && !ssh.toLowerCase().contains("tortoiseplink")) //$NON-NLS-1$ + if (putty + && !ssh.toLowerCase(Locale.ROOT).contains("tortoiseplink")) //$NON-NLS-1$ args.add("-batch"); //$NON-NLS-1$ if (0 < getURI().getPort()) { args.add(putty ? "-P" : "-p"); //$NON-NLS-1$ //$NON-NLS-2$ @@ -248,6 +257,7 @@ public Process exec(String command, int timeout) } } + @Override public void disconnect() { // Nothing to do }
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 96a6fe1..26a254d 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/transport/TransportHttp.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/transport/TransportHttp.java
@@ -52,6 +52,7 @@ import static org.eclipse.jgit.util.HttpSupport.HDR_ACCEPT_ENCODING; import static org.eclipse.jgit.util.HttpSupport.HDR_CONTENT_ENCODING; import static org.eclipse.jgit.util.HttpSupport.HDR_CONTENT_TYPE; +import static org.eclipse.jgit.util.HttpSupport.HDR_LOCATION; import static org.eclipse.jgit.util.HttpSupport.HDR_PRAGMA; import static org.eclipse.jgit.util.HttpSupport.HDR_USER_AGENT; import static org.eclipse.jgit.util.HttpSupport.HDR_WWW_AUTHENTICATE; @@ -153,64 +154,77 @@ public enum AcceptEncoding { private final String[] schemeNames = { "http", "https" }; //$NON-NLS-1$ //$NON-NLS-2$ private final Set<String> schemeSet = Collections - .unmodifiableSet(new LinkedHashSet<String>(Arrays + .unmodifiableSet(new LinkedHashSet<>(Arrays .asList(schemeNames))); + @Override public String getName() { return JGitText.get().transportProtoHTTP; } + @Override public Set<String> getSchemes() { return schemeSet; } + @Override public Set<URIishField> getRequiredFields() { return Collections.unmodifiableSet(EnumSet.of(URIishField.HOST, URIishField.PATH)); } + @Override public Set<URIishField> getOptionalFields() { return Collections.unmodifiableSet(EnumSet.of(URIishField.USER, URIishField.PASS, URIishField.PORT)); } + @Override public int getDefaultPort() { return 80; } + @Override public Transport open(URIish uri, Repository local, String remoteName) throws NotSupportedException { return new TransportHttp(local, uri); } + @Override public Transport open(URIish uri) throws NotSupportedException { return new TransportHttp(uri); } }; static final TransportProtocol PROTO_FTP = new TransportProtocol() { + @Override public String getName() { return JGitText.get().transportProtoFTP; } + @Override public Set<String> getSchemes() { return Collections.singleton("ftp"); //$NON-NLS-1$ } + @Override public Set<URIishField> getRequiredFields() { return Collections.unmodifiableSet(EnumSet.of(URIishField.HOST, URIishField.PATH)); } + @Override public Set<URIishField> getOptionalFields() { return Collections.unmodifiableSet(EnumSet.of(URIishField.USER, URIishField.PASS, URIishField.PORT)); } + @Override public int getDefaultPort() { return 21; } + @Override public Transport open(URIish uri, Repository local, String remoteName) throws NotSupportedException { return new TransportHttp(local, uri); @@ -218,6 +232,7 @@ public Transport open(URIish uri, Repository local, String remoteName) }; private static final Config.SectionParser<HttpConfig> HTTP_KEY = new SectionParser<HttpConfig>() { + @Override public HttpConfig parse(final Config cfg) { return new HttpConfig(cfg); } @@ -536,7 +551,7 @@ private HttpConnection connect(final String service) } catch (IOException e) { if (authMethod.getType() != HttpAuthMethod.Type.NONE) { if (ignoreTypes == null) { - ignoreTypes = new HashSet<Type>(); + ignoreTypes = new HashSet<>(); } ignoreTypes.add(authMethod.getType()); @@ -711,7 +726,7 @@ BufferedReader openReader(String path) throws IOException { @Override Collection<String> getPackNames() throws IOException { - final Collection<String> packs = new ArrayList<String>(); + final Collection<String> packs = new ArrayList<>(); try { final BufferedReader br = openReader(INFO_PACKS); try { @@ -764,7 +779,7 @@ FileStream open(String path, AcceptEncoding acceptEncoding) Map<String, Ref> readAdvertisedImpl(final BufferedReader br) throws IOException, PackProtocolException { - final TreeMap<String, Ref> avail = new TreeMap<String, Ref>(); + final TreeMap<String, Ref> avail = new TreeMap<>(); for (;;) { String line = br.readLine(); if (line == null) @@ -862,6 +877,7 @@ class SmartHttpPushConnection extends BasePackPushConnection { readAdvertisedRefs(); } + @Override protected void doPush(final ProgressMonitor monitor, final Map<String, RemoteRefUpdate> refUpdates, OutputStream outputStream) throws TransportException { @@ -898,9 +914,13 @@ abstract class Service { } void openStream() throws IOException { + openStream(null); + } + + void openStream(final String redirectUrl) throws IOException { conn = httpOpen( METHOD_POST, - new URL(baseUrl, serviceName), + redirectUrl == null ? new URL(baseUrl, serviceName) : new URL(redirectUrl), AcceptEncoding.GZIP); conn.setInstanceFollowRedirects(false); conn.setDoOutput(true); @@ -909,6 +929,10 @@ void openStream() throws IOException { } void sendRequest() throws IOException { + sendRequest(null); + } + + void sendRequest(final String redirectUrl) throws IOException { // Try to compress the content, but only if that is smaller. TemporaryBuffer buf = new TemporaryBuffer.Heap(http.postBuffer); try { @@ -923,7 +947,7 @@ void sendRequest() throws IOException { buf = out; } - openStream(); + openStream(redirectUrl); if (buf != out) conn.setRequestProperty(HDR_CONTENT_ENCODING, ENCODING_GZIP); conn.setFixedLengthStreamingMode((int) buf.length()); @@ -933,6 +957,12 @@ void sendRequest() throws IOException { } finally { httpOut.close(); } + + final int status = HttpSupport.response(conn); + if (status == HttpConnection.HTTP_MOVED_PERM) { + String locationHeader = HttpSupport.responseHeader(conn, HDR_LOCATION); + sendRequest(locationHeader); + } } void openResponse() throws IOException { @@ -960,16 +990,19 @@ InputStream getInputStream() { abstract void execute() throws IOException; class HttpExecuteStream extends InputStream { + @Override public int read() throws IOException { execute(); return -1; } + @Override public int read(byte[] b, int off, int len) throws IOException { execute(); return -1; } + @Override public long skip(long n) throws IOException { execute(); return 0;
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/transport/TransportLocal.java b/org.eclipse.jgit/src/org/eclipse/jgit/transport/TransportLocal.java index 1528c71..f483ec7 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/transport/TransportLocal.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/transport/TransportLocal.java
@@ -100,6 +100,7 @@ public String getName() { return JGitText.get().transportProtoLocal; } + @Override public Set<String> getSchemes() { return Collections.singleton("file"); //$NON-NLS-1$ } @@ -132,6 +133,7 @@ public Transport open(URIish uri, Repository local, String remoteName) return new TransportLocal(local, uri, gitDir); } + @Override public Transport open(URIish uri) throws NotSupportedException, TransportException { File path = FS.DETECTED.resolve(new File("."), uri.getPath()); //$NON-NLS-1$ @@ -189,7 +191,7 @@ public UploadPack create(Void req, Repository db) { return createUploadPack(db); } }; - return new InternalFetchConnection<Void>(this, upf, null, openRepo()); + return new InternalFetchConnection<>(this, upf, null, openRepo()); } @Override @@ -205,7 +207,7 @@ public ReceivePack create(Void req, Repository db) { return createReceivePack(db); } }; - return new InternalPushConnection<Void>(this, rpf, null, openRepo()); + return new InternalPushConnection<>(this, rpf, null, openRepo()); } @Override
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/transport/TransportSftp.java b/org.eclipse.jgit/src/org/eclipse/jgit/transport/TransportSftp.java index fa073ae..99e4809 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/transport/TransportSftp.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/transport/TransportSftp.java
@@ -43,6 +43,8 @@ package org.eclipse.jgit.transport; +import static org.eclipse.jgit.lib.Constants.LOCK_SUFFIX; + import java.io.BufferedReader; import java.io.FileNotFoundException; import java.io.IOException; @@ -99,28 +101,34 @@ */ public class TransportSftp extends SshTransport implements WalkTransport { static final TransportProtocol PROTO_SFTP = new TransportProtocol() { + @Override public String getName() { return JGitText.get().transportProtoSFTP; } + @Override public Set<String> getSchemes() { return Collections.singleton("sftp"); //$NON-NLS-1$ } + @Override public Set<URIishField> getRequiredFields() { return Collections.unmodifiableSet(EnumSet.of(URIishField.HOST, URIishField.PATH)); } + @Override public Set<URIishField> getOptionalFields() { return Collections.unmodifiableSet(EnumSet.of(URIishField.USER, URIishField.PASS, URIishField.PORT)); } + @Override public int getDefaultPort() { return 22; } + @Override public Transport open(URIish uri, Repository local, String remoteName) throws NotSupportedException { return new TransportSftp(local, uri); @@ -225,15 +233,15 @@ WalkRemoteObjectDatabase openAlternate(final String location) @Override Collection<String> getPackNames() throws IOException { - final List<String> packs = new ArrayList<String>(); + final List<String> packs = new ArrayList<>(); try { @SuppressWarnings("unchecked") final Collection<ChannelSftp.LsEntry> list = ftp.ls("pack"); //$NON-NLS-1$ final HashMap<String, ChannelSftp.LsEntry> files; final HashMap<String, Integer> mtimes; - files = new HashMap<String, ChannelSftp.LsEntry>(); - mtimes = new HashMap<String, Integer>(); + files = new HashMap<>(); + mtimes = new HashMap<>(); for (final ChannelSftp.LsEntry ent : list) files.put(ent.getFilename(), ent); @@ -251,6 +259,7 @@ Collection<String> getPackNames() throws IOException { } Collections.sort(packs, new Comparator<String>() { + @Override public int compare(final String o1, final String o2) { return mtimes.get(o2).intValue() - mtimes.get(o1).intValue(); @@ -334,7 +343,7 @@ OutputStream writeFile(final String path, @Override void writeFile(final String path, final byte[] data) throws IOException { - final String lock = path + ".lock"; //$NON-NLS-1$ + final String lock = path + LOCK_SUFFIX; try { super.writeFile(lock, data); try { @@ -381,7 +390,7 @@ private void mkdir_p(String path) throws IOException { } Map<String, Ref> readAdvertisedRefs() throws TransportException { - final TreeMap<String, Ref> avail = new TreeMap<String, Ref>(); + final TreeMap<String, Ref> avail = new TreeMap<>(); readPackedRefs(avail); readRef(avail, ROOT_DIR + Constants.HEAD, Constants.HEAD); readLooseRefs(avail, ROOT_DIR + "refs", "refs/"); //$NON-NLS-1$ //$NON-NLS-2$
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 3c5c8da..ffd4d41 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/transport/URIish.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/transport/URIish.java
@@ -560,6 +560,7 @@ public URIish setPort(final int n) { return r; } + @Override public int hashCode() { int hc = 0; if (getScheme() != null) @@ -577,6 +578,7 @@ public int hashCode() { return hc; } + @Override public boolean equals(final Object obj) { if (!(obj instanceof URIish)) return false; @@ -615,6 +617,7 @@ public String toPrivateString() { return format(true, false); } + @Override public String toString() { return format(false, false); }
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 201fb18..58fdd25 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/transport/UploadPack.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/transport/UploadPack.java
@@ -177,7 +177,7 @@ public static class FirstLine { */ public FirstLine(String line) { if (line.length() > 45) { - final HashSet<String> opts = new HashSet<String>(); + final HashSet<String> opts = new HashSet<>(); String opt = line.substring(45); if (opt.startsWith(" ")) //$NON-NLS-1$ opt = opt.substring(1); @@ -263,19 +263,19 @@ public Set<String> getOptions() { String userAgent; /** Raw ObjectIds the client has asked for, before validating them. */ - private final Set<ObjectId> wantIds = new HashSet<ObjectId>(); + private final Set<ObjectId> wantIds = new HashSet<>(); /** Objects the client wants to obtain. */ - private final Set<RevObject> wantAll = new HashSet<RevObject>(); + private final Set<RevObject> wantAll = new HashSet<>(); /** Objects on both sides, these don't have to be sent. */ - private final Set<RevObject> commonBase = new HashSet<RevObject>(); + private final Set<RevObject> commonBase = new HashSet<>(); /** Shallow commits the client already has. */ - private final Set<ObjectId> clientShallowCommits = new HashSet<ObjectId>(); + private final Set<ObjectId> clientShallowCommits = new HashSet<>(); /** Shallow commits on the client which are now becoming unshallow */ - private final List<ObjectId> unshallowCommits = new ArrayList<ObjectId>(); + private final List<ObjectId> unshallowCommits = new ArrayList<>(); /** Desired depth from the client on a shallow request. */ private int depth; @@ -776,7 +776,7 @@ else if (requestValidator instanceof AnyRequestValidator) } private static Set<ObjectId> refIdSet(Collection<Ref> refs) { - Set<ObjectId> ids = new HashSet<ObjectId>(refs.size()); + Set<ObjectId> ids = new HashSet<>(refs.size()); for (Ref ref : refs) { ObjectId id = ref.getObjectId(); if (id != null) { @@ -1018,7 +1018,7 @@ private boolean negotiate() throws IOException { okToGiveUp = Boolean.FALSE; ObjectId last = ObjectId.zeroId(); - List<ObjectId> peerHas = new ArrayList<ObjectId>(64); + List<ObjectId> peerHas = new ArrayList<>(64); for (;;) { String line; try { @@ -1172,7 +1172,7 @@ private void parseWants() throws IOException { for (ObjectId obj : wantIds) { if (!advertised.contains(obj)) { if (notAdvertisedWants == null) - notAdvertisedWants = new ArrayList<ObjectId>(); + notAdvertisedWants = new ArrayList<>(); notAdvertisedWants.add(obj); } } @@ -1215,6 +1215,7 @@ private void want(RevObject obj) { */ public static final class AdvertisedRequestValidator implements RequestValidator { + @Override public void checkWants(UploadPack up, List<ObjectId> wants) throws PackProtocolException, IOException { if (!up.isBiDirectionalPipe()) @@ -1231,6 +1232,7 @@ else if (!wants.isEmpty()) */ public static final class ReachableCommitRequestValidator implements RequestValidator { + @Override public void checkWants(UploadPack up, List<ObjectId> wants) throws PackProtocolException, IOException { checkNotAdvertisedWants(up.getRevWalk(), wants, @@ -1244,6 +1246,7 @@ public void checkWants(UploadPack up, List<ObjectId> wants) * @since 3.1 */ public static final class TipRequestValidator implements RequestValidator { + @Override public void checkWants(UploadPack up, List<ObjectId> wants) throws PackProtocolException, IOException { if (!up.isBiDirectionalPipe()) @@ -1266,6 +1269,7 @@ else if (!wants.isEmpty()) { */ public static final class ReachableCommitTipRequestValidator implements RequestValidator { + @Override public void checkWants(UploadPack up, List<ObjectId> wants) throws PackProtocolException, IOException { checkNotAdvertisedWants(up.getRevWalk(), wants, @@ -1279,6 +1283,7 @@ public void checkWants(UploadPack up, List<ObjectId> wants) * @since 3.1 */ public static final class AnyRequestValidator implements RequestValidator { + @Override public void checkWants(UploadPack up, List<ObjectId> wants) throws PackProtocolException, IOException { // All requests are valid. @@ -1483,7 +1488,7 @@ private void sendPack(final boolean sideband) throws IOException { pw.setReuseValidatingObjects(false); if (commonBase.isEmpty() && refs != null) { - Set<ObjectId> tagTargets = new HashSet<ObjectId>(); + Set<ObjectId> tagTargets = new HashSet<>(); for (Ref ref : refs.values()) { if (ref.getPeeledObjectId() != null) tagTargets.add(ref.getPeeledObjectId());
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/transport/UploadPackLogger.java b/org.eclipse.jgit/src/org/eclipse/jgit/transport/UploadPackLogger.java index 0588634..afc9965 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/transport/UploadPackLogger.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/transport/UploadPackLogger.java
@@ -59,6 +59,7 @@ public interface UploadPackLogger { // TODO remove in JGit 5.0 /** A simple no-op logger. */ public static final UploadPackLogger NULL = new UploadPackLogger() { + @Override public void onPackStatistics(PackWriter.Statistics stats) { // Do nothing. }
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/transport/UploadPackLoggerChain.java b/org.eclipse.jgit/src/org/eclipse/jgit/transport/UploadPackLoggerChain.java index 4ea0319..9a8c12c 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/transport/UploadPackLoggerChain.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/transport/UploadPackLoggerChain.java
@@ -84,6 +84,7 @@ else if (i == 1) /** * @since 3.0 */ + @Override public void onPackStatistics(PackWriter.Statistics stats) { for (int i = 0; i < count; i++) loggers[i].onPackStatistics(stats);
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 4c3fdd8..333e09d 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/transport/WalkEncryption.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/transport/WalkEncryption.java
@@ -52,6 +52,7 @@ import java.security.spec.AlgorithmParameterSpec; import java.security.spec.KeySpec; import java.text.MessageFormat; +import java.util.Locale; import java.util.Properties; import java.util.regex.Matcher; import java.util.regex.Pattern; @@ -192,7 +193,7 @@ static class JetS3tV2 extends WalkEncryption { // Standard names are not case-sensitive. // http://docs.oracle.com/javase/8/docs/technotes/guides/security/StandardNames.html - String cryptoName = cryptoAlg.toUpperCase(); + String cryptoName = cryptoAlg.toUpperCase(Locale.ROOT); if (!cryptoName.startsWith("PBE")) //$NON-NLS-1$ throw new GeneralSecurityException(JGitText.get().encryptionOnlyPBE); @@ -373,7 +374,7 @@ static abstract class SymmetricEncryption extends WalkEncryption SecretKey keyBase = factory.generateSecret(keySpec); - String name = cipherAlgo.toUpperCase(); + String name = cipherAlgo.toUpperCase(Locale.ROOT); Matcher matcherPBE = Pattern.compile(REGEX_PBE).matcher(name); Matcher matcherTrans = Pattern.compile(REGEX_TRANS).matcher(name); if (matcherPBE.matches()) { @@ -506,7 +507,7 @@ static Properties wrap(String algo, String pass) { JGitV1(String algo, String pass) throws GeneralSecurityException { super(wrap(algo, pass)); - String name = cipherAlgo.toUpperCase(); + String name = cipherAlgo.toUpperCase(Locale.ROOT); Matcher matcherPBE = Pattern.compile(REGEX_PBE).matcher(name); if (!matcherPBE.matches()) throw new GeneralSecurityException(
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/transport/WalkFetchConnection.java b/org.eclipse.jgit/src/org/eclipse/jgit/transport/WalkFetchConnection.java index 13d4a24..3d60aed 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/transport/WalkFetchConnection.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/transport/WalkFetchConnection.java
@@ -197,20 +197,20 @@ class WalkFetchConnection extends BaseFetchConnection { inserter = local.newObjectInserter(); reader = inserter.newReader(); - remotes = new ArrayList<WalkRemoteObjectDatabase>(); + remotes = new ArrayList<>(); remotes.add(w); - unfetchedPacks = new LinkedList<RemotePack>(); - packsConsidered = new HashSet<String>(); + unfetchedPacks = new LinkedList<>(); + packsConsidered = new HashSet<>(); - noPacksYet = new LinkedList<WalkRemoteObjectDatabase>(); + noPacksYet = new LinkedList<>(); noPacksYet.add(w); - noAlternatesYet = new LinkedList<WalkRemoteObjectDatabase>(); + noAlternatesYet = new LinkedList<>(); noAlternatesYet.add(w); - fetchErrors = new HashMap<ObjectId, List<Throwable>>(); - packLocks = new ArrayList<PackLock>(4); + fetchErrors = new HashMap<>(); + packLocks = new ArrayList<>(4); revWalk = new RevWalk(reader); revWalk.setRetainBody(false); @@ -220,9 +220,10 @@ class WalkFetchConnection extends BaseFetchConnection { LOCALLY_SEEN = revWalk.newFlag("LOCALLY_SEEN"); //$NON-NLS-1$ localCommitQueue = new DateRevQueue(); - workQueue = new LinkedList<ObjectId>(); + workQueue = new LinkedList<>(); } + @Override public boolean didFetchTestConnectivity() { return true; } @@ -248,10 +249,12 @@ protected void doFetch(final ProgressMonitor monitor, } } + @Override public Collection<PackLock> getPackLocks() { return packLocks; } + @Override public void setPackLockMessage(final String message) { lockMessage = message; } @@ -270,7 +273,7 @@ public void close() { private void queueWants(final Collection<Ref> want) throws TransportException { - final HashSet<ObjectId> inWorkQueue = new HashSet<ObjectId>(); + final HashSet<ObjectId> inWorkQueue = new HashSet<>(); for (final Ref r : want) { final ObjectId id = r.getObjectId(); if (id == null) { @@ -594,7 +597,7 @@ private boolean downloadPackedObject(final ProgressMonitor monitor, private Iterator<ObjectId> swapFetchQueue() { final Iterator<ObjectId> r = workQueue.iterator(); - workQueue = new LinkedList<ObjectId>(); + workQueue = new LinkedList<>(); return r; } @@ -791,7 +794,7 @@ private void recordError(final AnyObjectId id, final Throwable what) { final ObjectId objId = id.copy(); List<Throwable> errors = fetchErrors.get(objId); if (errors == null) { - errors = new ArrayList<Throwable>(2); + errors = new ArrayList<>(2); fetchErrors.put(objId, errors); } errors.add(what);
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/transport/WalkPushConnection.java b/org.eclipse.jgit/src/org/eclipse/jgit/transport/WalkPushConnection.java index 7b449c7..5c4e14c 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/transport/WalkPushConnection.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/transport/WalkPushConnection.java
@@ -134,25 +134,27 @@ class WalkPushConnection extends BaseConnection implements PushConnection { dest = w; } + @Override public void push(final ProgressMonitor monitor, final Map<String, RemoteRefUpdate> refUpdates) throws TransportException { push(monitor, refUpdates, null); } + @Override public void push(final ProgressMonitor monitor, final Map<String, RemoteRefUpdate> refUpdates, OutputStream out) throws TransportException { markStartedOperation(); packNames = null; - newRefs = new TreeMap<String, Ref>(getRefsMap()); - packedRefUpdates = new ArrayList<RemoteRefUpdate>(refUpdates.size()); + newRefs = new TreeMap<>(getRefsMap()); + packedRefUpdates = new ArrayList<>(refUpdates.size()); // Filter the commands and issue all deletes first. This way we // can correctly handle a directory being cleared out and a new // ref using the directory name being created. // - final List<RemoteRefUpdate> updates = new ArrayList<RemoteRefUpdate>(); + final List<RemoteRefUpdate> updates = new ArrayList<>(); for (final RemoteRefUpdate u : refUpdates.values()) { final String n = u.getRemoteName(); if (!n.startsWith("refs/") || !Repository.isValidRefName(n)) { //$NON-NLS-1$ @@ -223,8 +225,8 @@ private void sendpack(final List<RemoteRefUpdate> updates, try (final PackWriter writer = new PackWriter(transport.getPackConfig(), local.newObjectReader())) { - final Set<ObjectId> need = new HashSet<ObjectId>(); - final Set<ObjectId> have = new HashSet<ObjectId>(); + final Set<ObjectId> need = new HashSet<>(); + final Set<ObjectId> have = new HashSet<>(); for (final RemoteRefUpdate r : updates) need.add(r.getNewObjectId()); for (final Ref r : getRefs()) { @@ -241,7 +243,7 @@ private void sendpack(final List<RemoteRefUpdate> updates, if (writer.getObjectCount() == 0) return; - packNames = new LinkedHashMap<String, String>(); + packNames = new LinkedHashMap<>(); for (final String n : dest.getPackNames()) packNames.put(n, n); @@ -277,7 +279,7 @@ private void sendpack(final List<RemoteRefUpdate> updates, // way clients are likely to consult the newest pack first, // and discover the most recent objects there. // - final ArrayList<String> infoPacks = new ArrayList<String>(); + final ArrayList<String> infoPacks = new ArrayList<>(); infoPacks.add(packName); infoPacks.addAll(packNames.keySet()); dest.writeInfoPacks(infoPacks);
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/transport/WalkRemoteObjectDatabase.java b/org.eclipse.jgit/src/org/eclipse/jgit/transport/WalkRemoteObjectDatabase.java index 24f30ed..17f8c3e 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/transport/WalkRemoteObjectDatabase.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/transport/WalkRemoteObjectDatabase.java
@@ -396,7 +396,7 @@ Collection<WalkRemoteObjectDatabase> readAlternates(final String listPath) throws IOException { final BufferedReader br = openReader(listPath); try { - final Collection<WalkRemoteObjectDatabase> alts = new ArrayList<WalkRemoteObjectDatabase>(); + final Collection<WalkRemoteObjectDatabase> alts = new ArrayList<>(); for (;;) { String line = br.readLine(); if (line == null)
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/transport/http/HttpConnection.java b/org.eclipse.jgit/src/org/eclipse/jgit/transport/http/HttpConnection.java index 09613fd..58081c1 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/transport/http/HttpConnection.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/transport/http/HttpConnection.java
@@ -73,6 +73,12 @@ public interface HttpConnection { public static final int HTTP_OK = java.net.HttpURLConnection.HTTP_OK; /** + * @see HttpURLConnection#HTTP_MOVED_PERM + * @since 4.7 + */ + public static final int HTTP_MOVED_PERM = java.net.HttpURLConnection.HTTP_MOVED_PERM; + + /** * @see HttpURLConnection#HTTP_NOT_FOUND */ public static final int HTTP_NOT_FOUND = java.net.HttpURLConnection.HTTP_NOT_FOUND;
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/transport/http/JDKHttpConnection.java b/org.eclipse.jgit/src/org/eclipse/jgit/transport/http/JDKHttpConnection.java index ed37fea..534e3d7 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/transport/http/JDKHttpConnection.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/transport/http/JDKHttpConnection.java
@@ -94,95 +94,118 @@ protected JDKHttpConnection(URL url, Proxy proxy) .openConnection(proxy); } + @Override public int getResponseCode() throws IOException { return wrappedUrlConnection.getResponseCode(); } + @Override public URL getURL() { return wrappedUrlConnection.getURL(); } + @Override public String getResponseMessage() throws IOException { return wrappedUrlConnection.getResponseMessage(); } + @Override public Map<String, List<String>> getHeaderFields() { return wrappedUrlConnection.getHeaderFields(); } + @Override public void setRequestProperty(String key, String value) { wrappedUrlConnection.setRequestProperty(key, value); } + @Override public void setRequestMethod(String method) throws ProtocolException { wrappedUrlConnection.setRequestMethod(method); } + @Override public void setUseCaches(boolean usecaches) { wrappedUrlConnection.setUseCaches(usecaches); } + @Override public void setConnectTimeout(int timeout) { wrappedUrlConnection.setConnectTimeout(timeout); } + @Override public void setReadTimeout(int timeout) { wrappedUrlConnection.setReadTimeout(timeout); } + @Override public String getContentType() { return wrappedUrlConnection.getContentType(); } + @Override public InputStream getInputStream() throws IOException { return wrappedUrlConnection.getInputStream(); } + @Override public String getHeaderField(String name) { return wrappedUrlConnection.getHeaderField(name); } + @Override public int getContentLength() { return wrappedUrlConnection.getContentLength(); } + @Override public void setInstanceFollowRedirects(boolean followRedirects) { wrappedUrlConnection.setInstanceFollowRedirects(followRedirects); } + @Override public void setDoOutput(boolean dooutput) { wrappedUrlConnection.setDoOutput(dooutput); } + @Override public void setFixedLengthStreamingMode(int contentLength) { wrappedUrlConnection.setFixedLengthStreamingMode(contentLength); } + @Override public OutputStream getOutputStream() throws IOException { return wrappedUrlConnection.getOutputStream(); } + @Override public void setChunkedStreamingMode(int chunklen) { wrappedUrlConnection.setChunkedStreamingMode(chunklen); } + @Override public String getRequestMethod() { return wrappedUrlConnection.getRequestMethod(); } + @Override public boolean usingProxy() { return wrappedUrlConnection.usingProxy(); } + @Override public void connect() throws IOException { wrappedUrlConnection.connect(); } + @Override public void setHostnameVerifier(HostnameVerifier hostnameverifier) { ((HttpsURLConnection) wrappedUrlConnection) .setHostnameVerifier(hostnameverifier); } + @Override public void configure(KeyManager[] km, TrustManager[] tm, SecureRandom random) throws NoSuchAlgorithmException, KeyManagementException {
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/transport/http/JDKHttpConnectionFactory.java b/org.eclipse.jgit/src/org/eclipse/jgit/transport/http/JDKHttpConnectionFactory.java index d1c875d..b9f009f 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/transport/http/JDKHttpConnectionFactory.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/transport/http/JDKHttpConnectionFactory.java
@@ -52,10 +52,12 @@ * @since 3.3 */ public class JDKHttpConnectionFactory implements HttpConnectionFactory { + @Override public HttpConnection create(URL url) throws IOException { return new JDKHttpConnection(url); } + @Override public HttpConnection create(URL url, Proxy proxy) throws IOException { return new JDKHttpConnection(url, proxy);
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 6964e7f..7654d46 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
@@ -72,8 +72,8 @@ public class FileResolver<C> implements RepositoryResolver<C> { /** Initialize an empty file based resolver. */ public FileResolver() { - exports = new ConcurrentHashMap<String, Repository>(); - exportBase = new CopyOnWriteArrayList<File>(); + exports = new ConcurrentHashMap<>(); + exportBase = new CopyOnWriteArrayList<>(); } /** @@ -91,6 +91,7 @@ public FileResolver(final File basePath, final boolean exportAll) { setExportAll(exportAll); } + @Override public Repository open(final C req, final String name) throws RepositoryNotFoundException, ServiceNotEnabledException { if (isUnreasonableName(name))
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/transport/resolver/ReceivePackFactory.java b/org.eclipse.jgit/src/org/eclipse/jgit/transport/resolver/ReceivePackFactory.java index 4cf49f5..73c2ed8 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/transport/resolver/ReceivePackFactory.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/transport/resolver/ReceivePackFactory.java
@@ -55,6 +55,7 @@ public interface ReceivePackFactory<C> { /** A factory disabling the ReceivePack service for all repositories */ public static final ReceivePackFactory<?> DISABLED = new ReceivePackFactory<Object>() { + @Override public ReceivePack create(Object req, Repository db) throws ServiceNotEnabledException { throw new ServiceNotEnabledException();
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/transport/resolver/RepositoryResolver.java b/org.eclipse.jgit/src/org/eclipse/jgit/transport/resolver/RepositoryResolver.java index c7f0d32..80211e5 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/transport/resolver/RepositoryResolver.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/transport/resolver/RepositoryResolver.java
@@ -56,6 +56,7 @@ public interface RepositoryResolver<C> { /** Resolver configured to open nothing. */ public static final RepositoryResolver<?> NONE = new RepositoryResolver<Object>() { + @Override public Repository open(Object req, String name) throws RepositoryNotFoundException { throw new RepositoryNotFoundException(name);
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/transport/resolver/UploadPackFactory.java b/org.eclipse.jgit/src/org/eclipse/jgit/transport/resolver/UploadPackFactory.java index f0d2ba8..d7ed0f6 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/transport/resolver/UploadPackFactory.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/transport/resolver/UploadPackFactory.java
@@ -55,6 +55,7 @@ public interface UploadPackFactory<C> { /** A factory disabling the UploadPack service for all repositories. */ public static final UploadPackFactory<?> DISABLED = new UploadPackFactory<Object>() { + @Override public UploadPack create(Object req, Repository db) throws ServiceNotEnabledException { throw new ServiceNotEnabledException();
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/treewalk/CanonicalTreeParser.java b/org.eclipse.jgit/src/org/eclipse/jgit/treewalk/CanonicalTreeParser.java index c038f07..2d6abd1 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/treewalk/CanonicalTreeParser.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/treewalk/CanonicalTreeParser.java
@@ -249,6 +249,7 @@ public final CanonicalTreeParser createSubtreeIterator0( return p; } + @Override public CanonicalTreeParser createSubtreeIterator(final ObjectReader reader) throws IncorrectObjectTypeException, IOException { return createSubtreeIterator(reader, new MutableObjectId()); @@ -280,6 +281,7 @@ public boolean first() { return currPtr == 0; } + @Override public boolean eof() { return currPtr == raw.length; }
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/treewalk/NameConflictTreeWalk.java b/org.eclipse.jgit/src/org/eclipse/jgit/treewalk/NameConflictTreeWalk.java index b9293eb..c0b29ef 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/treewalk/NameConflictTreeWalk.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/treewalk/NameConflictTreeWalk.java
@@ -353,6 +353,7 @@ void skipEntriesEqual() throws CorruptObjectException { dfConflict = null; } + @Override void stopWalk() throws IOException { if (!needsStopWalk()) { return;
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 5dfebe9..c54e148 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/treewalk/TreeWalk.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/treewalk/TreeWalk.java
@@ -128,7 +128,7 @@ public static enum OperationType { * The filter command as defined in gitattributes. The keys are * filterName+"."+filterCommandType. E.g. "lfs.clean" */ - private Map<String, String> filterCommandsByNameDotType = new HashMap<String, String>(); + private Map<String, String> filterCommandsByNameDotType = new HashMap<>(); /** * @param operationType @@ -559,6 +559,7 @@ public AttributesNodeProvider getAttributesNodeProvider() { * @return a {@link Set} of {@link Attribute}s that match the current entry. * @since 4.2 */ + @Override public Attributes getAttributes() { if (attrs != null) return attrs; @@ -825,7 +826,7 @@ public boolean next() throws MissingObjectException, } currentHead = t; - if (!filter.include(this)) { + if (filter.matchFilter(this) == 1) { skipEntriesEqual(); continue; } @@ -1061,6 +1062,60 @@ public int getPathLength() { /** * Test if the supplied path matches the current entry's path. * <p> + * This method detects if the supplied path is equal to, a subtree of, or + * not similar at all to the current entry. It is faster to use this + * method than to use {@link #getPathString()} to first create a String + * object, then test <code>startsWith</code> or some other type of string + * match function. + * <p> + * If the current entry is a subtree, then all paths within the subtree + * are considered to match it. + * + * @param p + * path buffer to test. Callers should ensure the path does not + * end with '/' prior to invocation. + * @param pLen + * number of bytes from <code>buf</code> to test. + * @return -1 if the current path is a parent to p; 0 if p matches the current + * path; 1 if the current path is different and will never match + * again on this tree walk. + * @since 4.7 + */ + public int isPathMatch(final byte[] p, final int pLen) { + final AbstractTreeIterator t = currentHead; + final byte[] c = t.path; + final int cLen = t.pathLen; + int ci; + + for (ci = 0; ci < cLen && ci < pLen; ci++) { + final int c_value = (c[ci] & 0xff) - (p[ci] & 0xff); + if (c_value != 0) { + // Paths do not and will never match + return 1; + } + } + + if (ci < cLen) { + // Ran out of pattern but we still had current data. + // If c[ci] == '/' then pattern matches the subtree. + // Otherwise it is a partial match == miss + return c[ci] == '/' ? 0 : 1; + } + + if (ci < pLen) { + // Ran out of current, but we still have pattern data. + // If p[ci] == '/' then this subtree is a parent in the pattern, + // otherwise it's a miss. + return p[ci] == '/' && FileMode.TREE.equals(t.mode) ? -1 : 1; + } + + // Both strings are identical. + return 0; + } + + /** + * Test if the supplied path matches the current entry's path. + * <p> * This method tests that the supplied path is exactly equal to the current * entry or is one of its parent directories. It is faster to use this * method then to use {@link #getPathString()} to first create a String
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 52477cb..b1b146c 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/treewalk/WorkingTreeIterator.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/treewalk/WorkingTreeIterator.java
@@ -56,7 +56,6 @@ import java.nio.CharBuffer; import java.nio.charset.CharacterCodingException; import java.nio.charset.CharsetEncoder; -import java.security.MessageDigest; import java.text.MessageFormat; import java.util.Arrays; import java.util.Collections; @@ -99,6 +98,7 @@ 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; /** * Walks a working directory tree as part of a {@link TreeWalk}. @@ -364,7 +364,7 @@ public boolean isWorkTree() { if (is == null) return zeroid; try { - state.initializeDigestAndReadBuffer(); + state.initializeReadBuffer(); final long len = e.getLength(); InputStream filteredIs = possiblyFilteredInputStream(e, is, len, @@ -715,6 +715,7 @@ public AttributesNode getEntryAttributesNode() throws IOException { } private static final Comparator<Entry> ENTRY_CMP = new Comparator<Entry>() { + @Override public int compare(Entry a, Entry b) { return Paths.compare( a.encodedName, 0, a.encodedNameLen, a.getMode().getBits(), @@ -1098,10 +1099,9 @@ private static long computeLength(InputStream in) throws IOException { } private byte[] computeHash(InputStream in, long length) throws IOException { - final MessageDigest contentDigest = state.contentDigest; + SHA1 contentDigest = SHA1.newInstance(); final byte[] contentReadBuffer = state.contentReadBuffer; - contentDigest.reset(); contentDigest.update(hblob); contentDigest.update((byte) ' '); @@ -1154,6 +1154,7 @@ void encodeName(final CharsetEncoder enc) { b.get(encodedName = new byte[encodedNameLen]); } + @Override public String toString() { return getMode().toString() + " " + getName(); //$NON-NLS-1$ } @@ -1328,9 +1329,6 @@ private static final class IteratorState { /** File name character encoder. */ final CharsetEncoder nameEncoder; - /** Digest computer for {@link #contentId} computations. */ - MessageDigest contentDigest; - /** Buffer used to perform {@link #contentId} computations. */ byte[] contentReadBuffer; @@ -1345,9 +1343,8 @@ private static final class IteratorState { this.nameEncoder = Constants.CHARSET.newEncoder(); } - void initializeDigestAndReadBuffer() { - if (contentDigest == null) { - contentDigest = Constants.newMessageDigest(); + void initializeReadBuffer() { + if (contentReadBuffer == null) { contentReadBuffer = new byte[BUFFER_SIZE]; } } @@ -1366,7 +1363,7 @@ public String getCleanFilterCommand() throws IOException { cmd = state.walk .getFilterCommand(Constants.ATTR_FILTER_TYPE_CLEAN); } - cleanFilterCommandHolder = new Holder<String>(cmd); + cleanFilterCommandHolder = new Holder<>(cmd); } return cleanFilterCommandHolder.get(); } @@ -1413,7 +1410,7 @@ private EolStreamType getEolStreamType(OperationType opType) break; } } - eolStreamTypeHolder = new Holder<EolStreamType>(type); + eolStreamTypeHolder = new Holder<>(type); } return eolStreamTypeHolder.get(); }
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/treewalk/WorkingTreeOptions.java b/org.eclipse.jgit/src/org/eclipse/jgit/treewalk/WorkingTreeOptions.java index 112ce8f..7d2b33f 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/treewalk/WorkingTreeOptions.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/treewalk/WorkingTreeOptions.java
@@ -56,6 +56,7 @@ public class WorkingTreeOptions { /** Key for {@link Config#get(SectionParser)}. */ public static final Config.SectionParser<WorkingTreeOptions> KEY = new SectionParser<WorkingTreeOptions>() { + @Override public WorkingTreeOptions parse(final Config cfg) { return new WorkingTreeOptions(cfg); }
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/treewalk/filter/AndTreeFilter.java b/org.eclipse.jgit/src/org/eclipse/jgit/treewalk/filter/AndTreeFilter.java index d5e7464..9658166 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/treewalk/filter/AndTreeFilter.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/treewalk/filter/AndTreeFilter.java
@@ -128,7 +128,25 @@ private static class Binary extends AndTreeFilter { public boolean include(final TreeWalk walker) throws MissingObjectException, IncorrectObjectTypeException, IOException { - return a.include(walker) && b.include(walker); + return matchFilter(walker) <= 0; + } + + @Override + public int matchFilter(TreeWalk walker) + throws MissingObjectException, IncorrectObjectTypeException, + IOException { + final int ra = a.matchFilter(walker); + if (ra == 1) { + return 1; + } + final int rb = b.matchFilter(walker); + if (rb == 1) { + return 1; + } + if (ra == -1 || rb == -1) { + return -1; + } + return 0; } @Override @@ -159,11 +177,24 @@ private static class List extends AndTreeFilter { public boolean include(final TreeWalk walker) throws MissingObjectException, IncorrectObjectTypeException, IOException { + return matchFilter(walker) <= 0; + } + + @Override + public int matchFilter(TreeWalk walker) + throws MissingObjectException, IncorrectObjectTypeException, + IOException { + int m = 0; for (final TreeFilter f : subfilters) { - if (!f.include(walker)) - return false; + int r = f.matchFilter(walker); + if (r == 1) { + return 1; + } + if (r == -1) { + m = -1; + } } - return true; + return m; } @Override
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 42725bc..b821a16 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
@@ -86,11 +86,11 @@ public class IndexDiffFilter extends TreeFilter { private final boolean honorIgnores; - private final Set<String> ignoredPaths = new HashSet<String>(); + private final Set<String> ignoredPaths = new HashSet<>(); - private final LinkedList<String> untrackedParentFolders = new LinkedList<String>(); + private final LinkedList<String> untrackedParentFolders = new LinkedList<>(); - private final LinkedList<String> untrackedFolders = new LinkedList<String>(); + private final LinkedList<String> untrackedFolders = new LinkedList<>(); /** * Creates a new instance of this filter. Do not use an instance of this @@ -292,7 +292,7 @@ public Set<String> getIgnoredPaths() { * empty list will be returned. */ public List<String> getUntrackedFolders() { - LinkedList<String> ret = new LinkedList<String>(untrackedFolders); + LinkedList<String> ret = new LinkedList<>(untrackedFolders); if (!untrackedParentFolders.isEmpty()) { String toBeAdded = untrackedParentFolders.getLast(); while (!ret.isEmpty() && ret.getLast().startsWith(toBeAdded))
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/treewalk/filter/NotTreeFilter.java b/org.eclipse.jgit/src/org/eclipse/jgit/treewalk/filter/NotTreeFilter.java index 8ec04bb..80c0b87 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/treewalk/filter/NotTreeFilter.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/treewalk/filter/NotTreeFilter.java
@@ -78,7 +78,23 @@ public TreeFilter negate() { public boolean include(final TreeWalk walker) throws MissingObjectException, IncorrectObjectTypeException, IOException { - return !a.include(walker); + return matchFilter(walker) == 0; + } + + @Override + public int matchFilter(TreeWalk walker) + throws MissingObjectException, IncorrectObjectTypeException, + IOException { + final int r = a.matchFilter(walker); + // switch 0 and 1, keep -1 as that defines a subpath that must be + // traversed before a final verdict can be made. + if (r == 0) { + return 1; + } + if (r == 1) { + return 0; + } + return -1; } @Override
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/treewalk/filter/OrTreeFilter.java b/org.eclipse.jgit/src/org/eclipse/jgit/treewalk/filter/OrTreeFilter.java index 270633c..2c1a9d4 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/treewalk/filter/OrTreeFilter.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/treewalk/filter/OrTreeFilter.java
@@ -126,7 +126,25 @@ private static class Binary extends OrTreeFilter { public boolean include(final TreeWalk walker) throws MissingObjectException, IncorrectObjectTypeException, IOException { - return a.include(walker) || b.include(walker); + return matchFilter(walker) <= 0; + } + + @Override + public int matchFilter(TreeWalk walker) + throws MissingObjectException, IncorrectObjectTypeException, + IOException { + final int ra = a.matchFilter(walker); + if (ra == 0) { + return 0; + } + final int rb = b.matchFilter(walker); + if (rb == 0) { + return 0; + } + if (ra == -1 || rb == -1) { + return -1; + } + return 1; } @Override @@ -157,11 +175,24 @@ private static class List extends OrTreeFilter { public boolean include(final TreeWalk walker) throws MissingObjectException, IncorrectObjectTypeException, IOException { + return matchFilter(walker) <= 0; + } + + @Override + public int matchFilter(TreeWalk walker) + throws MissingObjectException, IncorrectObjectTypeException, + IOException { + int m = 1; for (final TreeFilter f : subfilters) { - if (f.include(walker)) - return true; + int r = f.matchFilter(walker); + if (r == 0) { + return 0; + } + if (r == -1) { + m = -1; + } } - return false; + return m; } @Override
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/treewalk/filter/PathFilter.java b/org.eclipse.jgit/src/org/eclipse/jgit/treewalk/filter/PathFilter.java index d85ea8c..445ba15 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/treewalk/filter/PathFilter.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/treewalk/filter/PathFilter.java
@@ -97,7 +97,12 @@ public String getPath() { @Override public boolean include(final TreeWalk walker) { - return walker.isPathPrefix(pathRaw, pathRaw.length) == 0; + return matchFilter(walker) <= 0; + } + + @Override + public int matchFilter(final TreeWalk walker) { + return walker.isPathMatch(pathRaw, pathRaw.length); } @Override @@ -113,6 +118,7 @@ public PathFilter clone() { return this; } + @Override @SuppressWarnings("nls") public String toString() { return "PATH(\"" + pathStr + "\")";
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/treewalk/filter/PathFilterGroup.java b/org.eclipse.jgit/src/org/eclipse/jgit/treewalk/filter/PathFilterGroup.java index 7601956..174a4f5 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/treewalk/filter/PathFilterGroup.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/treewalk/filter/PathFilterGroup.java
@@ -173,6 +173,7 @@ public TreeFilter clone() { return this; } + @Override public String toString() { return "FAST_" + path.toString(); //$NON-NLS-1$ } @@ -267,6 +268,7 @@ public TreeFilter clone() { return this; } + @Override public String toString() { final StringBuilder r = new StringBuilder(); r.append("FAST("); //$NON-NLS-1$
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/treewalk/filter/TreeFilter.java b/org.eclipse.jgit/src/org/eclipse/jgit/treewalk/filter/TreeFilter.java index 7d99e58..2c2fb47 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/treewalk/filter/TreeFilter.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/treewalk/filter/TreeFilter.java
@@ -199,6 +199,34 @@ public abstract boolean include(TreeWalk walker) IOException; /** + * Determine if the current entry is a parent, a match, or no match. + * <p> + * This method extends the result returned by {@link #include(TreeWalk)} + * with a third option (-1), splitting the value true. This gives the + * application a possibility to distinguish between an exact match + * and the case when a subtree to the current entry might be a match. + * + * @param walker + * the walker the filter needs to examine. + * @return -1 if the current entry is a parent of the filter but no + * exact match has been made; 0 if the current entry should + * be seen by the application; 1 if it should be hidden. + * @throws MissingObjectException + * as thrown by {@link #include(TreeWalk)} + * @throws IncorrectObjectTypeException + * as thrown by {@link #include(TreeWalk)} + * @throws IOException + * as thrown by {@link #include(TreeWalk)} + * @since 4.7 + */ + public int matchFilter(final TreeWalk walker) + throws MissingObjectException, IncorrectObjectTypeException, + IOException + { + return include(walker) ? 0 : 1; + } + + /** * Does this tree filter require a recursive walk to match everything? * <p> * If this tree filter is matching on full entry path names and its pattern @@ -220,6 +248,7 @@ public abstract boolean include(TreeWalk walker) * * @return another copy of this filter, suitable for another thread. */ + @Override public abstract TreeFilter clone(); @Override
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 ed5838a..c05570b 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/util/Base64.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/util/Base64.java
@@ -7,6 +7,7 @@ package org.eclipse.jgit.util; import java.io.UnsupportedEncodingException; +import java.nio.charset.StandardCharsets; import java.text.MessageFormat; import java.util.Arrays; @@ -184,11 +185,7 @@ public static String encodeBytes(byte[] source, int off, int len) { e += 4; } - try { - return new String(outBuff, 0, e, UTF_8); - } catch (UnsupportedEncodingException uue) { - return new String(outBuff, 0, e); - } + return new String(outBuff, 0, e, StandardCharsets.UTF_8); } /** @@ -304,12 +301,7 @@ else if (source[srcOffset + 3] == EQUALS_SIGN) { * @return the decoded data */ public static byte[] decode(String s) { - byte[] bytes; - try { - bytes = s.getBytes(UTF_8); - } catch (UnsupportedEncodingException uee) { - bytes = s.getBytes(); - } + byte[] bytes = s.getBytes(StandardCharsets.UTF_8); return decode(bytes, 0, bytes.length); } }
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/util/BlockList.java b/org.eclipse.jgit/src/org/eclipse/jgit/util/BlockList.java index 9d0ad73..c86c588 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/util/BlockList.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/util/BlockList.java
@@ -309,10 +309,12 @@ private class MyIterator implements Iterator<T> { private T[] block = directory[0]; + @Override public boolean hasNext() { return index < size; } + @Override public T next() { if (size <= index) throw new NoSuchElementException(); @@ -329,6 +331,7 @@ public T next() { return res; } + @Override public void remove() { if (index == 0) throw new IllegalStateException();
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/util/CachedAuthenticator.java b/org.eclipse.jgit/src/org/eclipse/jgit/util/CachedAuthenticator.java index 6828185..8677c69 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/util/CachedAuthenticator.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/util/CachedAuthenticator.java
@@ -51,7 +51,7 @@ /** Abstract authenticator which remembers prior authentications. */ public abstract class CachedAuthenticator extends Authenticator { - private static final Collection<CachedAuthentication> cached = new CopyOnWriteArrayList<CachedAuthentication>(); + private static final Collection<CachedAuthentication> cached = new CopyOnWriteArrayList<>(); /** * Add a cached authentication for future use.
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 be60390..8d4e5e5 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/util/FS.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/util/FS.java
@@ -45,6 +45,7 @@ import java.io.BufferedReader; import java.io.ByteArrayInputStream; +import java.io.Closeable; import java.io.File; import java.io.IOException; import java.io.InputStream; @@ -52,6 +53,8 @@ import java.io.OutputStream; import java.io.PrintStream; import java.nio.charset.Charset; +import java.nio.file.Files; +import java.nio.file.Path; import java.security.AccessController; import java.security.PrivilegedAction; import java.text.MessageFormat; @@ -59,7 +62,7 @@ import java.util.HashMap; import java.util.Map; import java.util.Objects; -import java.util.concurrent.Callable; +import java.util.Optional; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.TimeUnit; @@ -391,7 +394,7 @@ public File resolve(final File dir, final String name) { public File userHome() { Holder<File> p = userHome; if (p == null) { - p = new Holder<File>(userHomeImpl()); + p = new Holder<>(userHomeImpl()); userHome = p; } return p.value; @@ -406,7 +409,7 @@ public File userHome() { * @return {@code this}. */ public FS setUserHome(File path) { - userHome = new Holder<File>(path); + userHome = new Holder<>(path); return this; } @@ -425,6 +428,7 @@ public FS setUserHome(File path) { protected File userHomeImpl() { final String home = AccessController .doPrivileged(new PrivilegedAction<String>() { + @Override public String run() { return System.getProperty("user.home"); //$NON-NLS-1$ } @@ -665,7 +669,7 @@ protected File discoverGitSystemConfig() { */ public File getGitSystemConfig() { if (gitSystemConfig == null) { - gitSystemConfig = new Holder<File>(discoverGitSystemConfig()); + gitSystemConfig = new Holder<>(discoverGitSystemConfig()); } return gitSystemConfig.value; } @@ -679,7 +683,7 @@ public File getGitSystemConfig() { * @since 4.0 */ public FS setGitSystemConfig(File configFile) { - gitSystemConfig = new Holder<File>(configFile); + gitSystemConfig = new Holder<>(configFile); return this; } @@ -800,14 +804,84 @@ public void createSymLink(File path, String target) throws IOException { * the file to be created * @return <code>true</code> if the file was created, <code>false</code> if * the file already existed - * @throws IOException + * @throws java.io.IOException + * @deprecated use {@link #createNewFileAtomic(File)} instead * @since 4.5 */ + @Deprecated public boolean createNewFile(File path) throws IOException { return path.createNewFile(); } /** + * A token representing a file created by + * {@link #createNewFileAtomic(File)}. The token must be retained until the + * file has been deleted in order to guarantee that the unique file was + * created atomically. As soon as the file is no longer needed the lock + * token must be closed. + * + * @since 4.7 + */ + public static class LockToken implements Closeable { + private boolean isCreated; + + private Optional<Path> link; + + LockToken(boolean isCreated, Optional<Path> link) { + this.isCreated = isCreated; + this.link = link; + } + + /** + * @return {@code true} if the file was created successfully + */ + public boolean isCreated() { + return isCreated; + } + + @Override + public void close() { + if (!link.isPresent()) { + return; + } + Path p = link.get(); + if (!Files.exists(p)) { + return; + } + try { + Files.delete(p); + } catch (IOException e) { + LOG.error(MessageFormat + .format(JGitText.get().closeLockTokenFailed, this), e); + } + } + + @Override + public String toString() { + return "LockToken [lockCreated=" + isCreated + //$NON-NLS-1$ + ", link=" //$NON-NLS-1$ + + (link.isPresent() ? link.get().getFileName() + "]" //$NON-NLS-1$ + : "<null>]"); //$NON-NLS-1$ + } + } + + /** + * Create a new file. See {@link java.io.File#createNewFile()}. Subclasses + * of this class may take care to provide a safe implementation for this + * even if {@link #supportsAtomicCreateNewFile()} is <code>false</code> + * + * @param path + * the file to be created + * @return LockToken this token must be closed after the created file was + * deleted + * @throws IOException + * @since 4.7 + */ + public LockToken createNewFileAtomic(File path) throws IOException { + return new LockToken(path.createNewFile(), Optional.empty()); + } + + /** * See {@link FileUtils#relativize(String, String)}. * * @param base @@ -1042,16 +1116,13 @@ public int runProcess(ProcessBuilder processBuilder, IOException ioException = null; try { process = processBuilder.start(); - final Callable<Void> errorGobbler = new StreamGobbler( - process.getErrorStream(), errRedirect); - final Callable<Void> outputGobbler = new StreamGobbler( - process.getInputStream(), outRedirect); - executor.submit(errorGobbler); - executor.submit(outputGobbler); + executor.execute( + new StreamGobbler(process.getErrorStream(), errRedirect)); + executor.execute( + new StreamGobbler(process.getInputStream(), outRedirect)); OutputStream outputStream = process.getOutputStream(); if (inRedirect != null) { - new StreamGobbler(inRedirect, outputStream) - .call(); + new StreamGobbler(inRedirect, outputStream).copy(); } try { outputStream.close(); @@ -1367,7 +1438,7 @@ public String normalize(String name) { * streams. * </p> */ - private static class StreamGobbler implements Callable<Void> { + private static class StreamGobbler implements Runnable { private InputStream in; private OutputStream out; @@ -1377,7 +1448,16 @@ public StreamGobbler(InputStream stream, OutputStream output) { this.out = output; } - public Void call() throws IOException { + @Override + public void run() { + try { + copy(); + } catch (IOException e) { + // Do nothing on read failure; leave streams open. + } + } + + void copy() throws IOException { boolean writeFailure = false; byte buffer[] = new byte[4096]; int readBytes; @@ -1394,7 +1474,6 @@ public Void call() throws IOException { } } } - return null; } } }
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 f63c437..607e078 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
@@ -52,14 +52,19 @@ import java.nio.file.Path; import java.nio.file.Paths; import java.nio.file.attribute.PosixFilePermission; +import java.text.MessageFormat; import java.util.ArrayList; import java.util.Arrays; import java.util.List; +import java.util.Optional; import java.util.Set; +import java.util.UUID; +import org.eclipse.jgit.annotations.Nullable; import org.eclipse.jgit.api.errors.JGitInternalException; import org.eclipse.jgit.errors.CommandFailedException; import org.eclipse.jgit.errors.ConfigInvalidException; +import org.eclipse.jgit.internal.JGitText; import org.eclipse.jgit.lib.ConfigConstants; import org.eclipse.jgit.lib.Constants; import org.eclipse.jgit.lib.Repository; @@ -261,7 +266,7 @@ private static void apply(Set<PosixFilePermission> set, @Override public ProcessBuilder runInShell(String cmd, String[] args) { - List<String> argv = new ArrayList<String>(4 + args.length); + List<String> argv = new ArrayList<>(4 + args.length); argv.add("sh"); //$NON-NLS-1$ argv.add("-c"); //$NON-NLS-1$ argv.add(cmd + " \"$@\""); //$NON-NLS-1$ @@ -346,6 +351,7 @@ public boolean supportsAtomicCreateNewFile() { return supportsAtomicCreateNewFile.booleanValue(); } + @Override @SuppressWarnings("boxing") /** * An implementation of the File#createNewFile() semantics which works also @@ -359,9 +365,12 @@ public boolean supportsAtomicCreateNewFile() { * multiple clients manage to create the same lock file nlink would be * greater than 2 showing the error. * - * @see https://www.time-travellers.org/shane/papers/NFS_considered_harmful.html + * @see "https://www.time-travellers.org/shane/papers/NFS_considered_harmful.html" + * + * @deprecated use {@link FS_POSIX#createNewFileAtomic(File)} instead * @since 4.5 */ + @Deprecated public boolean createNewFile(File lock) throws IOException { if (!lock.createNewFile()) { return false; @@ -370,22 +379,94 @@ public boolean createNewFile(File lock) throws IOException { return true; } Path lockPath = lock.toPath(); - Path link = Files.createLink(Paths.get(lock.getAbsolutePath() + ".lnk"), //$NON-NLS-1$ - lockPath); + Path link = null; try { + link = Files.createLink( + Paths.get(lock.getAbsolutePath() + ".lnk"), //$NON-NLS-1$ + lockPath); Integer nlink = (Integer) (Files.getAttribute(lockPath, "unix:nlink")); //$NON-NLS-1$ - if (nlink != 2) { + if (nlink > 2) { LOG.warn("nlink of link to lock file {0} was not 2 but {1}", //$NON-NLS-1$ lock.getPath(), nlink); return false; + } else if (nlink < 2) { + supportsUnixNLink = false; } return true; } catch (UnsupportedOperationException | IllegalArgumentException e) { supportsUnixNLink = false; return true; } finally { - Files.delete(link); + if (link != null) { + Files.delete(link); + } } } + + /** + * {@inheritDoc} + * <p> + * An implementation of the File#createNewFile() semantics which can create + * a unique file atomically also on NFS. If the config option + * {@code core.supportsAtomicCreateNewFile = true} (which is the default) + * then simply File#createNewFile() is called. + * + * But if {@code core.supportsAtomicCreateNewFile = false} then after + * successful creation of the lock file a hard link to that lock file is + * created and the attribute nlink of the lock file is checked to be 2. If + * multiple clients manage to create the same lock file nlink would be + * greater than 2 showing the error. The hard link needs to be retained + * until the corresponding file is no longer needed in order to prevent that + * another process can create the same file concurrently using another NFS + * client which might not yet see the file due to caching. + * + * @see "https://www.time-travellers.org/shane/papers/NFS_considered_harmful.html" + * @param file + * the unique file to be created atomically + * @return LockToken this lock token must be held until the file is no + * longer needed + * @throws IOException + * @since 5.0 + */ + @Override + public LockToken createNewFileAtomic(File file) throws IOException { + if (!file.createNewFile()) { + return token(false, null); + } + if (supportsAtomicCreateNewFile() || !supportsUnixNLink) { + return token(true, null); + } + Path link = null; + Path path = file.toPath(); + try { + link = Files.createLink(Paths.get(uniqueLinkPath(file)), path); + Integer nlink = (Integer) (Files.getAttribute(path, + "unix:nlink")); //$NON-NLS-1$ + if (nlink.intValue() > 2) { + LOG.warn(MessageFormat.format( + JGitText.get().failedAtomicFileCreation, path, nlink)); + return token(false, link); + } else if (nlink.intValue() < 2) { + supportsUnixNLink = false; + } + return token(true, link); + } catch (UnsupportedOperationException | IllegalArgumentException e) { + supportsUnixNLink = false; + return token(true, link); + } + } + + private static LockToken token(boolean created, @Nullable Path p) { + return ((p != null) && Files.exists(p)) + ? new LockToken(created, Optional.of(p)) + : new LockToken(created, Optional.empty()); + } + + private static String uniqueLinkPath(File file) { + UUID id = UUID.randomUUID(); + return file.getAbsolutePath() + "." //$NON-NLS-1$ + + Long.toHexString(id.getMostSignificantBits()) + + Long.toHexString(id.getLeastSignificantBits()); + } }
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 0e9172e..0602921 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
@@ -83,18 +83,22 @@ protected FS_Win32(FS src) { super(src); } + @Override public FS newInstance() { return new FS_Win32(this); } + @Override public boolean supportsExecute() { return false; } + @Override public boolean canExecute(final File f) { return false; } + @Override public boolean setExecute(final File f, final boolean canExec) { return false; } @@ -158,7 +162,7 @@ protected File userHomeImpl() { @Override public ProcessBuilder runInShell(String cmd, String[] args) { - List<String> argv = new ArrayList<String>(3 + args.length); + List<String> argv = new ArrayList<>(3 + args.length); argv.add("cmd.exe"); //$NON-NLS-1$ argv.add("/c"); //$NON-NLS-1$ argv.add(cmd);
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 f8ea5d0..545cc01 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
@@ -77,6 +77,7 @@ public class FS_Win32_Cygwin extends FS_Win32 { public static boolean isCygwin() { final String path = AccessController .doPrivileged(new PrivilegedAction<String>() { + @Override public String run() { return System.getProperty("java.library.path"); //$NON-NLS-1$ } @@ -106,10 +107,12 @@ protected FS_Win32_Cygwin(FS src) { super(src); } + @Override public FS newInstance() { return new FS_Win32_Cygwin(this); } + @Override public File resolve(final File dir, final String pn) { String useCygPath = System.getProperty("jgit.usecygpath"); //$NON-NLS-1$ if (useCygPath != null && useCygPath.equals("true")) { //$NON-NLS-1$ @@ -133,6 +136,7 @@ public File resolve(final File dir, final String pn) { protected File userHomeImpl() { final String home = AccessController .doPrivileged(new PrivilegedAction<String>() { + @Override public String run() { return System.getenv("HOME"); //$NON-NLS-1$ } @@ -144,7 +148,7 @@ public String run() { @Override public ProcessBuilder runInShell(String cmd, String[] args) { - List<String> argv = new ArrayList<String>(4 + args.length); + List<String> argv = new ArrayList<>(4 + args.length); argv.add("sh.exe"); //$NON-NLS-1$ argv.add("-c"); //$NON-NLS-1$ argv.add(cmd + " \"$@\""); //$NON-NLS-1$
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 aa101f7..1f20e97 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/util/FileUtils.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/util/FileUtils.java
@@ -65,6 +65,7 @@ import java.text.Normalizer.Form; import java.util.ArrayList; import java.util.List; +import java.util.Locale; import java.util.regex.Pattern; import org.eclipse.jgit.internal.JGitText; @@ -150,8 +151,8 @@ public static void delete(final File f, int options) throws IOException { if ((options & RECURSIVE) != 0 && fs.isDirectory(f)) { final File[] items = f.listFiles(); if (items != null) { - List<File> files = new ArrayList<File>(); - List<File> dirs = new ArrayList<File>(); + List<File> files = new ArrayList<>(); + List<File> dirs = new ArrayList<>(); for (File c : items) if (c.isFile()) files.add(c); @@ -542,7 +543,28 @@ else if (!ignoreCase public static boolean isStaleFileHandle(IOException ioe) { String msg = ioe.getMessage(); return msg != null - && msg.toLowerCase().matches("stale .*file .*handle"); //$NON-NLS-1$ + && msg.toLowerCase(Locale.ROOT) + .matches("stale .*file .*handle"); //$NON-NLS-1$ + } + + /** + * Determine if a throwable or a cause in its causal chain is a Stale NFS + * File Handle + * + * @param throwable + * @return a boolean true if the throwable or a cause in its causal chain is + * a Stale NFS File Handle + * @since 4.7 + */ + public static boolean isStaleFileHandleInCausalChain(Throwable throwable) { + while (throwable != null) { + if (throwable instanceof IOException + && isStaleFileHandle((IOException) throwable)) { + return true; + } + throwable = throwable.getCause(); + } + return false; } /**
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 7bc3c88..da78008 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/util/GitDateParser.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/util/GitDateParser.java
@@ -75,8 +75,9 @@ public class GitDateParser { private static ThreadLocal<Map<Locale, Map<ParseableSimpleDateFormat, SimpleDateFormat>>> formatCache = new ThreadLocal<Map<Locale, Map<ParseableSimpleDateFormat, SimpleDateFormat>>>() { + @Override protected Map<Locale, Map<ParseableSimpleDateFormat, SimpleDateFormat>> initialValue() { - return new HashMap<Locale, Map<ParseableSimpleDateFormat, SimpleDateFormat>>(); + return new HashMap<>(); } }; @@ -90,7 +91,7 @@ private static SimpleDateFormat getDateFormat(ParseableSimpleDateFormat f, Map<ParseableSimpleDateFormat, SimpleDateFormat> map = cache .get(locale); if (map == null) { - map = new HashMap<ParseableSimpleDateFormat, SimpleDateFormat>(); + map = new HashMap<>(); cache.put(locale, map); return getNewSimpleDateFormat(f, locale, map); }
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 251381a..13e61a7 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/util/HttpSupport.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/util/HttpSupport.java
@@ -141,6 +141,12 @@ public class HttpSupport { /** The {@code Accept-Encoding} header. */ public static final String HDR_ACCEPT_ENCODING = "Accept-Encoding"; //$NON-NLS-1$ + /** + * The {@code Location} header. + * @since 4.7 + */ + public static final String HDR_LOCATION = "Location"; //$NON-NLS-1$ + /** The {@code gzip} encoding value for {@link #HDR_ACCEPT_ENCODING}. */ public static final String ENCODING_GZIP = "gzip"; //$NON-NLS-1$ @@ -235,6 +241,23 @@ public static int response(final java.net.HttpURLConnection c) } /** + * Extract a HTTP header from the response. + * + * @param c + * connection the header should be obtained from. + * @param headerName + * the header name + * @return the header value + * @throws IOException + * communications error prevented obtaining the header. + * @since 4.7 + */ + public static String responseHeader(final HttpConnection c, + final String headerName) throws IOException { + return c.getHeaderField(headerName); + } + + /** * Determine the proxy server (if any) needed to obtain a URL. * * @param proxySelector @@ -280,15 +303,18 @@ public static void disableSslVerify(HttpConnection conn) } private static class DummyX509TrustManager implements X509TrustManager { + @Override public X509Certificate[] getAcceptedIssuers() { return null; } + @Override public void checkClientTrusted(X509Certificate[] certs, String authType) { // no check } + @Override public void checkServerTrusted(X509Certificate[] certs, String authType) { // no check @@ -296,6 +322,7 @@ public void checkServerTrusted(X509Certificate[] certs, } private static class DummyHostnameVerifier implements HostnameVerifier { + @Override public boolean verify(String hostname, SSLSession session) { // always accept return true;
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 0d283fd..6cff76c 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/util/IO.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/util/IO.java
@@ -344,7 +344,7 @@ public static void skipFully(final InputStream fd, long toSkip) * @since 2.0 */ public static List<String> readLines(final String s) { - List<String> l = new ArrayList<String>(); + List<String> l = new ArrayList<>(); StringBuilder sb = new StringBuilder(); for (int i = 0; i < s.length(); i++) { char c = s.charAt(i);
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/util/IntList.java b/org.eclipse.jgit/src/org/eclipse/jgit/util/IntList.java index f7688e3..658dd06 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/util/IntList.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/util/IntList.java
@@ -138,6 +138,7 @@ private void grow() { entries = n; } + @Override public String toString() { final StringBuilder r = new StringBuilder(); r.append('[');
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/util/LongList.java b/org.eclipse.jgit/src/org/eclipse/jgit/util/LongList.java index dc4004f..e3639f5 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/util/LongList.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/util/LongList.java
@@ -159,6 +159,7 @@ private void grow() { entries = n; } + @Override public String toString() { final StringBuilder r = new StringBuilder(); r.append('[');
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/util/RawCharSequence.java b/org.eclipse.jgit/src/org/eclipse/jgit/util/RawCharSequence.java index 4eeecdb..e85bd65 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/util/RawCharSequence.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/util/RawCharSequence.java
@@ -74,14 +74,17 @@ public RawCharSequence(final byte[] buf, final int start, final int end) { endPtr = end; } + @Override public char charAt(final int index) { return (char) (buffer[startPtr + index] & 0xff); } + @Override public int length() { return endPtr - startPtr; } + @Override public CharSequence subSequence(final int start, final int end) { return new RawCharSequence(buffer, startPtr + start, startPtr + end); }
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/util/RefList.java b/org.eclipse.jgit/src/org/eclipse/jgit/util/RefList.java index 0853e95..1597817 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/util/RefList.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/util/RefList.java
@@ -68,7 +68,7 @@ * the type of reference being stored in the collection. */ public class RefList<T extends Ref> implements Iterable<Ref> { - private static final RefList<Ref> EMPTY = new RefList<Ref>(new Ref[0], 0); + private static final RefList<Ref> EMPTY = new RefList<>(new Ref[0], 0); /** * @return an empty unmodifiable reference list. @@ -100,20 +100,24 @@ protected RefList(RefList<T> src) { this.cnt = src.cnt; } + @Override public Iterator<Ref> iterator() { return new Iterator<Ref>() { private int idx; + @Override public boolean hasNext() { return idx < cnt; } + @Override public Ref next() { if (idx < cnt) return list[idx++]; throw new NoSuchElementException(); } + @Override public void remove() { throw new UnsupportedOperationException(); } @@ -209,7 +213,7 @@ public final T get(int idx) { * @return a new builder with the first {@code n} elements already added. */ public final Builder<T> copy(int n) { - Builder<T> r = new Builder<T>(Math.max(16, n)); + Builder<T> r = new Builder<>(Math.max(16, n)); r.addAll(list, 0, n); return r; } @@ -230,7 +234,7 @@ public final RefList<T> set(int idx, T ref) { Ref[] newList = new Ref[cnt]; System.arraycopy(list, 0, newList, 0, cnt); newList[idx] = ref; - return new RefList<T>(newList, cnt); + return new RefList<>(newList, cnt); } /** @@ -257,7 +261,7 @@ public final RefList<T> add(int idx, T ref) { newList[idx] = ref; if (idx < cnt) System.arraycopy(list, idx, newList, idx + 1, cnt - idx); - return new RefList<T>(newList, cnt + 1); + return new RefList<>(newList, cnt + 1); } /** @@ -278,7 +282,7 @@ public final RefList<T> remove(int idx) { System.arraycopy(list, 0, newList, 0, idx); if (idx + 1 < cnt) System.arraycopy(list, idx + 1, newList, idx, cnt - (idx + 1)); - return new RefList<T>(newList, cnt - 1); + return new RefList<>(newList, cnt - 1); } /** @@ -427,7 +431,7 @@ public void sort() { /** @return an unmodifiable list using this collection's backing array. */ public RefList<T> toRefList() { - return new RefList<T>(list, size); + return new RefList<>(list, size); } @Override
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 c72727b..510e818 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/util/RefMap.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/util/RefMap.java
@@ -304,12 +304,14 @@ private class SetIterator implements Iterator<Entry<String, Ref>> { } } + @Override public boolean hasNext() { if (next == null) next = peek(); return next != null; } + @Override public Entry<String, Ref> next() { if (hasNext()) { Entry<String, Ref> r = next; @@ -367,6 +369,7 @@ private Ent toEntry(Ref p) { return null; } + @Override public void remove() { throw new UnsupportedOperationException(); } @@ -379,14 +382,17 @@ private class Ent implements Entry<String, Ref> { this.ref = ref; } + @Override public String getKey() { return toMapKey(ref); } + @Override public Ref getValue() { return ref; } + @Override public Ref setValue(Ref value) { Ref prior = put(getKey(), value); ref = value;
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 b36fc23..2cd8035 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/util/SystemReader.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/util/SystemReader.java
@@ -87,22 +87,27 @@ public abstract class SystemReader { private static class Default extends SystemReader { private volatile String hostname; + @Override public String getenv(String variable) { return System.getenv(variable); } + @Override public String getProperty(String key) { return System.getProperty(key); } + @Override public FileBasedConfig openSystemConfig(Config parent, FS fs) { File configFile = fs.getGitSystemConfig(); if (configFile == null) { return new FileBasedConfig(null, fs) { + @Override public void load() { // empty, do not load } + @Override public boolean isOutdated() { // regular class would bomb here return false; @@ -112,11 +117,13 @@ public boolean isOutdated() { return new FileBasedConfig(parent, configFile, fs); } + @Override public FileBasedConfig openUserConfig(Config parent, FS fs) { final File home = fs.userHome(); return new FileBasedConfig(parent, new File(home, ".gitconfig"), fs); //$NON-NLS-1$ } + @Override public String getHostname() { if (hostname == null) { try { @@ -331,6 +338,7 @@ public boolean isMacOS() { private String getOsName() { return AccessController.doPrivileged(new PrivilegedAction<String>() { + @Override public String run() { return getProperty("os.name"); //$NON-NLS-1$ }
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/util/TemporaryBuffer.java b/org.eclipse.jgit/src/org/eclipse/jgit/util/TemporaryBuffer.java index 57bcfbd..e3f1916 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/util/TemporaryBuffer.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/util/TemporaryBuffer.java
@@ -325,7 +325,7 @@ public void reset() { if (blocks != null) blocks.clear(); else - blocks = new ArrayList<Block>(initialBlocks); + blocks = new ArrayList<>(initialBlocks); blocks.add(new Block(Math.min(inCoreLimit, Block.SZ))); } @@ -363,6 +363,7 @@ private void switchToOverflow() throws IOException { overflow.write(last.buffer, 0, last.count); } + @Override public void close() throws IOException { if (overflow != null) { try { @@ -441,11 +442,13 @@ public LocalFile(final File directory, final int inCoreLimit) { this.directory = directory; } + @Override protected OutputStream overflow() throws IOException { onDiskFile = File.createTempFile("jgit_", ".buf", directory); //$NON-NLS-1$ //$NON-NLS-2$ return new BufferedOutputStream(new FileOutputStream(onDiskFile)); } + @Override public long length() { if (onDiskFile == null) { return super.length(); @@ -453,6 +456,7 @@ public long length() { return onDiskFile.length(); } + @Override public byte[] toByteArray() throws IOException { if (onDiskFile == null) { return super.toByteArray(); @@ -471,6 +475,7 @@ public long length() { return out; } + @Override public void writeTo(final OutputStream os, ProgressMonitor pm) throws IOException { if (onDiskFile == null) {
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/util/io/InterruptTimer.java b/org.eclipse.jgit/src/org/eclipse/jgit/util/io/InterruptTimer.java index 1024380..0c5edb0 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/util/io/InterruptTimer.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/util/io/InterruptTimer.java
@@ -176,6 +176,7 @@ static final class AlarmState implements Runnable { callingThread = Thread.currentThread(); } + @Override public synchronized void run() { while (!terminated && callingThread.isAlive()) { try {
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/util/io/TeeInputStream.java b/org.eclipse.jgit/src/org/eclipse/jgit/util/io/TeeInputStream.java index 6adadbb..a7a0347 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/util/io/TeeInputStream.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/util/io/TeeInputStream.java
@@ -115,6 +115,7 @@ public int read(byte[] b, int off, int len) throws IOException { return n; } + @Override public void close() throws IOException { byte[] b = skipBuffer(); for (;;) {
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/util/io/ThrowingPrintWriter.java b/org.eclipse.jgit/src/org/eclipse/jgit/util/io/ThrowingPrintWriter.java index c34c1fb..5eca0d9 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/util/io/ThrowingPrintWriter.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/util/io/ThrowingPrintWriter.java
@@ -69,6 +69,7 @@ public class ThrowingPrintWriter extends Writer { public ThrowingPrintWriter(Writer out) { this.out = out; LF = AccessController.doPrivileged(new PrivilegedAction<String>() { + @Override public String run() { return SystemReader.getInstance().getProperty("line.separator"); //$NON-NLS-1$ }
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/util/io/UnionInputStream.java b/org.eclipse.jgit/src/org/eclipse/jgit/util/io/UnionInputStream.java index 0319afd..1c46310 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/util/io/UnionInputStream.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/util/io/UnionInputStream.java
@@ -67,7 +67,7 @@ public int read() throws IOException { } }; - private final LinkedList<InputStream> streams = new LinkedList<InputStream>(); + private final LinkedList<InputStream> streams = new LinkedList<>(); /** Create an empty InputStream that is currently at EOF state. */ public UnionInputStream() {
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 new file mode 100644 index 0000000..5449711 --- /dev/null +++ b/org.eclipse.jgit/src/org/eclipse/jgit/util/sha1/SHA1.java
@@ -0,0 +1,601 @@ +/* + * 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.util.sha1; + +import static java.lang.Integer.lowestOneBit; +import static java.lang.Integer.numberOfTrailingZeros; +import static java.lang.Integer.rotateLeft; +import static java.lang.Integer.rotateRight; + +import java.util.Arrays; + +import org.eclipse.jgit.lib.MutableObjectId; +import org.eclipse.jgit.lib.ObjectId; +import org.eclipse.jgit.util.NB; +import org.eclipse.jgit.util.SystemReader; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * Pure Java implementation of SHA-1 from FIPS 180-1 / RFC 3174. + * + * <p> + * See <a href="https://tools.ietf.org/html/rfc3174">RFC 3174</a>. + * <p> + * Unlike MessageDigest, this implementation includes the algorithm used by + * {@code sha1dc} to detect cryptanalytic collision attacks against SHA-1, such + * as the one used by <a href="https://shattered.it/">SHAttered</a>. See + * <a href="https://github.com/cr-marcstevens/sha1collisiondetection"> + * sha1collisiondetection</a> for more information. + * <p> + * When detectCollision is true (default), this implementation throws + * {@link Sha1CollisionException} from any digest method if a potential + * collision was detected. + * + * @since 4.7 + */ +public class SHA1 { + private static Logger LOG = LoggerFactory.getLogger(SHA1.class); + private static final boolean DETECT_COLLISIONS; + + static { + SystemReader sr = SystemReader.getInstance(); + String v = sr.getProperty("org.eclipse.jgit.util.sha1.detectCollision"); //$NON-NLS-1$ + DETECT_COLLISIONS = v != null ? Boolean.parseBoolean(v) : true; + } + + /** @return a new context to compute a SHA-1 hash of data. */ + public static SHA1 newInstance() { + return new SHA1(); + } + + private final State h = new State(); + private final int[] w = new int[80]; + + /** Buffer to accumulate partial blocks to 64 byte alignment. */ + private final byte[] buffer = new byte[64]; + + /** Total number of bytes in the message. */ + private long length; + + private boolean detectCollision = DETECT_COLLISIONS; + private boolean foundCollision; + + private final int[] w2 = new int[80]; + private final State state58 = new State(); + private final State state65 = new State(); + private final State hIn = new State(); + private final State hTmp = new State(); + + private SHA1() { + h.init(); + } + + /** + * Enable likely collision detection. + * <p> + * Default is {@code true}. + * <p> + * May also be set by system property: + * {@code -Dorg.eclipse.jgit.util.sha1.detectCollision=true}. + * + * @param detect + * @return {@code this} + */ + public SHA1 setDetectCollision(boolean detect) { + detectCollision = detect; + return this; + } + + /** + * Update the digest computation by adding a byte. + * + * @param b + */ + public void update(byte b) { + int bufferLen = (int) (length & 63); + length++; + buffer[bufferLen] = b; + if (bufferLen == 63) { + compress(buffer, 0); + } + } + + /** + * Update the digest computation by adding bytes to the message. + * + * @param in + * input array of bytes. + */ + public void update(byte[] in) { + update(in, 0, in.length); + } + + /** + * Update the digest computation by adding bytes to the message. + * + * @param in + * input array of bytes. + * @param p + * offset to start at from {@code in}. + * @param len + * number of bytes to hash. + */ + public void update(byte[] in, int p, int len) { + // SHA-1 compress can only process whole 64 byte blocks. + // Hold partial updates in buffer, whose length is the low bits. + int bufferLen = (int) (length & 63); + length += len; + + if (bufferLen > 0) { + int n = Math.min(64 - bufferLen, len); + System.arraycopy(in, p, buffer, bufferLen, n); + p += n; + len -= n; + if (bufferLen + n < 64) { + return; + } + compress(buffer, 0); + } + while (len >= 64) { + compress(in, p); + p += 64; + len -= 64; + } + if (len > 0) { + System.arraycopy(in, p, buffer, 0, len); + } + } + + private void compress(byte[] block, int p) { + initBlock(block, p); + int ubcDvMask = detectCollision ? UbcCheck.check(w) : 0; + compress(); + + while (ubcDvMask != 0) { + int b = numberOfTrailingZeros(lowestOneBit(ubcDvMask)); + UbcCheck.DvInfo dv = UbcCheck.DV[b]; + for (int i = 0; i < 80; i++) { + w2[i] = w[i] ^ dv.dm[i]; + } + recompress(dv.testt); + if (eq(hTmp, h)) { + foundCollision = true; + break; + } + ubcDvMask &= ~(1 << b); + } + } + + private void initBlock(byte[] block, int p) { + for (int t = 0; t < 16; t++) { + w[t] = NB.decodeInt32(block, p + (t << 2)); + } + + // RFC 3174 6.1.b, extend state vector to 80 words. + for (int t = 16; t < 80; t++) { + int x = w[t - 3] ^ w[t - 8] ^ w[t - 14] ^ w[t - 16]; + w[t] = rotateLeft(x, 1); // S^1(...) + } + } + + private void compress() { + // Method 1 from RFC 3174 section 6.1. + // Method 2 (circular queue of 16 words) is slower. + int a = h.a, b = h.b, c = h.c, d = h.d, e = h.e; + + // @formatter:off + e += s1(a, b, c, d,w[ 0]); b = rotateLeft( b, 30); + d += s1(e, a, b, c,w[ 1]); a = rotateLeft( a, 30); + c += s1(d, e, a, b,w[ 2]); e = rotateLeft( e, 30); + b += s1(c, d, e, a,w[ 3]); d = rotateLeft( d, 30); + a += s1(b, c, d, e,w[ 4]); c = rotateLeft( c, 30); + e += s1(a, b, c, d,w[ 5]); b = rotateLeft( b, 30); + d += s1(e, a, b, c,w[ 6]); a = rotateLeft( a, 30); + c += s1(d, e, a, b,w[ 7]); e = rotateLeft( e, 30); + b += s1(c, d, e, a,w[ 8]); d = rotateLeft( d, 30); + a += s1(b, c, d, e,w[ 9]); c = rotateLeft( c, 30); + e += s1(a, b, c, d,w[ 10]); b = rotateLeft( b, 30); + d += s1(e, a, b, c,w[ 11]); a = rotateLeft( a, 30); + c += s1(d, e, a, b,w[ 12]); e = rotateLeft( e, 30); + b += s1(c, d, e, a,w[ 13]); d = rotateLeft( d, 30); + a += s1(b, c, d, e,w[ 14]); c = rotateLeft( c, 30); + e += s1(a, b, c, d,w[ 15]); b = rotateLeft( b, 30); + d += s1(e, a, b, c,w[ 16]); a = rotateLeft( a, 30); + c += s1(d, e, a, b,w[ 17]); e = rotateLeft( e, 30); + b += s1(c, d, e, a,w[ 18]); d = rotateLeft( d, 30); + a += s1(b, c, d, e,w[ 19]); c = rotateLeft( c, 30); + + e += s2(a, b, c, d,w[ 20]); b = rotateLeft( b, 30); + d += s2(e, a, b, c,w[ 21]); a = rotateLeft( a, 30); + c += s2(d, e, a, b,w[ 22]); e = rotateLeft( e, 30); + b += s2(c, d, e, a,w[ 23]); d = rotateLeft( d, 30); + a += s2(b, c, d, e,w[ 24]); c = rotateLeft( c, 30); + e += s2(a, b, c, d,w[ 25]); b = rotateLeft( b, 30); + d += s2(e, a, b, c,w[ 26]); a = rotateLeft( a, 30); + c += s2(d, e, a, b,w[ 27]); e = rotateLeft( e, 30); + b += s2(c, d, e, a,w[ 28]); d = rotateLeft( d, 30); + a += s2(b, c, d, e,w[ 29]); c = rotateLeft( c, 30); + e += s2(a, b, c, d,w[ 30]); b = rotateLeft( b, 30); + d += s2(e, a, b, c,w[ 31]); a = rotateLeft( a, 30); + c += s2(d, e, a, b,w[ 32]); e = rotateLeft( e, 30); + b += s2(c, d, e, a,w[ 33]); d = rotateLeft( d, 30); + a += s2(b, c, d, e,w[ 34]); c = rotateLeft( c, 30); + e += s2(a, b, c, d,w[ 35]); b = rotateLeft( b, 30); + d += s2(e, a, b, c,w[ 36]); a = rotateLeft( a, 30); + c += s2(d, e, a, b,w[ 37]); e = rotateLeft( e, 30); + b += s2(c, d, e, a,w[ 38]); d = rotateLeft( d, 30); + a += s2(b, c, d, e,w[ 39]); c = rotateLeft( c, 30); + + e += s3(a, b, c, d,w[ 40]); b = rotateLeft( b, 30); + d += s3(e, a, b, c,w[ 41]); a = rotateLeft( a, 30); + c += s3(d, e, a, b,w[ 42]); e = rotateLeft( e, 30); + b += s3(c, d, e, a,w[ 43]); d = rotateLeft( d, 30); + a += s3(b, c, d, e,w[ 44]); c = rotateLeft( c, 30); + e += s3(a, b, c, d,w[ 45]); b = rotateLeft( b, 30); + d += s3(e, a, b, c,w[ 46]); a = rotateLeft( a, 30); + c += s3(d, e, a, b,w[ 47]); e = rotateLeft( e, 30); + b += s3(c, d, e, a,w[ 48]); d = rotateLeft( d, 30); + a += s3(b, c, d, e,w[ 49]); c = rotateLeft( c, 30); + e += s3(a, b, c, d,w[ 50]); b = rotateLeft( b, 30); + d += s3(e, a, b, c,w[ 51]); a = rotateLeft( a, 30); + c += s3(d, e, a, b,w[ 52]); e = rotateLeft( e, 30); + b += s3(c, d, e, a,w[ 53]); d = rotateLeft( d, 30); + a += s3(b, c, d, e,w[ 54]); c = rotateLeft( c, 30); + e += s3(a, b, c, d,w[ 55]); b = rotateLeft( b, 30); + d += s3(e, a, b, c,w[ 56]); a = rotateLeft( a, 30); + c += s3(d, e, a, b,w[ 57]); e = rotateLeft( e, 30); + state58.save(a, b, c, d, e); + b += s3(c, d, e, a,w[ 58]); d = rotateLeft( d, 30); + a += s3(b, c, d, e,w[ 59]); c = rotateLeft( c, 30); + + e += s4(a, b, c, d,w[ 60]); b = rotateLeft( b, 30); + d += s4(e, a, b, c,w[ 61]); a = rotateLeft( a, 30); + c += s4(d, e, a, b,w[ 62]); e = rotateLeft( e, 30); + b += s4(c, d, e, a,w[ 63]); d = rotateLeft( d, 30); + a += s4(b, c, d, e,w[ 64]); c = rotateLeft( c, 30); + state65.save(a, b, c, d, e); + e += s4(a, b, c, d,w[ 65]); b = rotateLeft( b, 30); + d += s4(e, a, b, c,w[ 66]); a = rotateLeft( a, 30); + c += s4(d, e, a, b,w[ 67]); e = rotateLeft( e, 30); + b += s4(c, d, e, a,w[ 68]); d = rotateLeft( d, 30); + a += s4(b, c, d, e,w[ 69]); c = rotateLeft( c, 30); + e += s4(a, b, c, d,w[ 70]); b = rotateLeft( b, 30); + d += s4(e, a, b, c,w[ 71]); a = rotateLeft( a, 30); + c += s4(d, e, a, b,w[ 72]); e = rotateLeft( e, 30); + b += s4(c, d, e, a,w[ 73]); d = rotateLeft( d, 30); + a += s4(b, c, d, e,w[ 74]); c = rotateLeft( c, 30); + e += s4(a, b, c, d,w[ 75]); b = rotateLeft( b, 30); + d += s4(e, a, b, c,w[ 76]); a = rotateLeft( a, 30); + c += s4(d, e, a, b,w[ 77]); e = rotateLeft( e, 30); + b += s4(c, d, e, a,w[ 78]); d = rotateLeft( d, 30); + a += s4(b, c, d, e,w[ 79]); c = rotateLeft( c, 30); + + // @formatter:on + h.save(h.a + a, h.b + b, h.c + c, h.d + d, h.e + e); + } + + private void recompress(int t) { + State s; + if (t == 58) { + s = state58; + } else if (t == 65) { + s = state65; + } else { + throw new IllegalStateException(); + } + int a = s.a, b = s.b, c = s.c, d = s.d, e = s.e; + + // @formatter:off + if (t == 65) { + { c = rotateRight( c, 30); a -= s4(b, c, d, e,w2[ 64]);} + { d = rotateRight( d, 30); b -= s4(c, d, e, a,w2[ 63]);} + { e = rotateRight( e, 30); c -= s4(d, e, a, b,w2[ 62]);} + { a = rotateRight( a, 30); d -= s4(e, a, b, c,w2[ 61]);} + { b = rotateRight( b, 30); e -= s4(a, b, c, d,w2[ 60]);} + + { c = rotateRight( c, 30); a -= s3(b, c, d, e,w2[ 59]);} + { d = rotateRight( d, 30); b -= s3(c, d, e, a,w2[ 58]);} + } + { e = rotateRight( e, 30); c -= s3(d, e, a, b,w2[ 57]);} + { a = rotateRight( a, 30); d -= s3(e, a, b, c,w2[ 56]);} + { b = rotateRight( b, 30); e -= s3(a, b, c, d,w2[ 55]);} + { c = rotateRight( c, 30); a -= s3(b, c, d, e,w2[ 54]);} + { d = rotateRight( d, 30); b -= s3(c, d, e, a,w2[ 53]);} + { e = rotateRight( e, 30); c -= s3(d, e, a, b,w2[ 52]);} + { a = rotateRight( a, 30); d -= s3(e, a, b, c,w2[ 51]);} + { b = rotateRight( b, 30); e -= s3(a, b, c, d,w2[ 50]);} + { c = rotateRight( c, 30); a -= s3(b, c, d, e,w2[ 49]);} + { d = rotateRight( d, 30); b -= s3(c, d, e, a,w2[ 48]);} + { e = rotateRight( e, 30); c -= s3(d, e, a, b,w2[ 47]);} + { a = rotateRight( a, 30); d -= s3(e, a, b, c,w2[ 46]);} + { b = rotateRight( b, 30); e -= s3(a, b, c, d,w2[ 45]);} + { c = rotateRight( c, 30); a -= s3(b, c, d, e,w2[ 44]);} + { d = rotateRight( d, 30); b -= s3(c, d, e, a,w2[ 43]);} + { e = rotateRight( e, 30); c -= s3(d, e, a, b,w2[ 42]);} + { a = rotateRight( a, 30); d -= s3(e, a, b, c,w2[ 41]);} + { b = rotateRight( b, 30); e -= s3(a, b, c, d,w2[ 40]);} + + { c = rotateRight( c, 30); a -= s2(b, c, d, e,w2[ 39]);} + { d = rotateRight( d, 30); b -= s2(c, d, e, a,w2[ 38]);} + { e = rotateRight( e, 30); c -= s2(d, e, a, b,w2[ 37]);} + { a = rotateRight( a, 30); d -= s2(e, a, b, c,w2[ 36]);} + { b = rotateRight( b, 30); e -= s2(a, b, c, d,w2[ 35]);} + { c = rotateRight( c, 30); a -= s2(b, c, d, e,w2[ 34]);} + { d = rotateRight( d, 30); b -= s2(c, d, e, a,w2[ 33]);} + { e = rotateRight( e, 30); c -= s2(d, e, a, b,w2[ 32]);} + { a = rotateRight( a, 30); d -= s2(e, a, b, c,w2[ 31]);} + { b = rotateRight( b, 30); e -= s2(a, b, c, d,w2[ 30]);} + { c = rotateRight( c, 30); a -= s2(b, c, d, e,w2[ 29]);} + { d = rotateRight( d, 30); b -= s2(c, d, e, a,w2[ 28]);} + { e = rotateRight( e, 30); c -= s2(d, e, a, b,w2[ 27]);} + { a = rotateRight( a, 30); d -= s2(e, a, b, c,w2[ 26]);} + { b = rotateRight( b, 30); e -= s2(a, b, c, d,w2[ 25]);} + { c = rotateRight( c, 30); a -= s2(b, c, d, e,w2[ 24]);} + { d = rotateRight( d, 30); b -= s2(c, d, e, a,w2[ 23]);} + { e = rotateRight( e, 30); c -= s2(d, e, a, b,w2[ 22]);} + { a = rotateRight( a, 30); d -= s2(e, a, b, c,w2[ 21]);} + { b = rotateRight( b, 30); e -= s2(a, b, c, d,w2[ 20]);} + + { c = rotateRight( c, 30); a -= s1(b, c, d, e,w2[ 19]);} + { d = rotateRight( d, 30); b -= s1(c, d, e, a,w2[ 18]);} + { e = rotateRight( e, 30); c -= s1(d, e, a, b,w2[ 17]);} + { a = rotateRight( a, 30); d -= s1(e, a, b, c,w2[ 16]);} + { b = rotateRight( b, 30); e -= s1(a, b, c, d,w2[ 15]);} + { c = rotateRight( c, 30); a -= s1(b, c, d, e,w2[ 14]);} + { d = rotateRight( d, 30); b -= s1(c, d, e, a,w2[ 13]);} + { e = rotateRight( e, 30); c -= s1(d, e, a, b,w2[ 12]);} + { a = rotateRight( a, 30); d -= s1(e, a, b, c,w2[ 11]);} + { b = rotateRight( b, 30); e -= s1(a, b, c, d,w2[ 10]);} + { c = rotateRight( c, 30); a -= s1(b, c, d, e,w2[ 9]);} + { d = rotateRight( d, 30); b -= s1(c, d, e, a,w2[ 8]);} + { e = rotateRight( e, 30); c -= s1(d, e, a, b,w2[ 7]);} + { a = rotateRight( a, 30); d -= s1(e, a, b, c,w2[ 6]);} + { b = rotateRight( b, 30); e -= s1(a, b, c, d,w2[ 5]);} + { c = rotateRight( c, 30); a -= s1(b, c, d, e,w2[ 4]);} + { d = rotateRight( d, 30); b -= s1(c, d, e, a,w2[ 3]);} + { e = rotateRight( e, 30); c -= s1(d, e, a, b,w2[ 2]);} + { a = rotateRight( a, 30); d -= s1(e, a, b, c,w2[ 1]);} + { b = rotateRight( b, 30); e -= s1(a, b, c, d,w2[ 0]);} + + hIn.save(a, b, c, d, e); + a = s.a; b = s.b; c = s.c; d = s.d; e = s.e; + + if (t == 58) { + { b += s3(c, d, e, a,w2[ 58]); d = rotateLeft( d, 30);} + { a += s3(b, c, d, e,w2[ 59]); c = rotateLeft( c, 30);} + + { e += s4(a, b, c, d,w2[ 60]); b = rotateLeft( b, 30);} + { d += s4(e, a, b, c,w2[ 61]); a = rotateLeft( a, 30);} + { c += s4(d, e, a, b,w2[ 62]); e = rotateLeft( e, 30);} + { b += s4(c, d, e, a,w2[ 63]); d = rotateLeft( d, 30);} + { a += s4(b, c, d, e,w2[ 64]); c = rotateLeft( c, 30);} + } + { e += s4(a, b, c, d,w2[ 65]); b = rotateLeft( b, 30);} + { d += s4(e, a, b, c,w2[ 66]); a = rotateLeft( a, 30);} + { c += s4(d, e, a, b,w2[ 67]); e = rotateLeft( e, 30);} + { b += s4(c, d, e, a,w2[ 68]); d = rotateLeft( d, 30);} + { a += s4(b, c, d, e,w2[ 69]); c = rotateLeft( c, 30);} + { e += s4(a, b, c, d,w2[ 70]); b = rotateLeft( b, 30);} + { d += s4(e, a, b, c,w2[ 71]); a = rotateLeft( a, 30);} + { c += s4(d, e, a, b,w2[ 72]); e = rotateLeft( e, 30);} + { b += s4(c, d, e, a,w2[ 73]); d = rotateLeft( d, 30);} + { a += s4(b, c, d, e,w2[ 74]); c = rotateLeft( c, 30);} + { e += s4(a, b, c, d,w2[ 75]); b = rotateLeft( b, 30);} + { d += s4(e, a, b, c,w2[ 76]); a = rotateLeft( a, 30);} + { c += s4(d, e, a, b,w2[ 77]); e = rotateLeft( e, 30);} + { b += s4(c, d, e, a,w2[ 78]); d = rotateLeft( d, 30);} + { a += s4(b, c, d, e,w2[ 79]); c = rotateLeft( c, 30);} + + // @formatter:on + hTmp.save(hIn.a + a, hIn.b + b, hIn.c + c, hIn.d + d, hIn.e + e); + } + + private static int s1(int a, int b, int c, int d, int w_t) { + return rotateLeft(a, 5) + // f: 0 <= t <= 19 + + ((b & c) | ((~b) & d)) + + 0x5A827999 + w_t; + } + + private static int s2(int a, int b, int c, int d, int w_t) { + return rotateLeft(a, 5) + // f: 20 <= t <= 39 + + (b ^ c ^ d) + + 0x6ED9EBA1 + w_t; + } + + private static int s3(int a, int b, int c, int d, int w_t) { + return rotateLeft(a, 5) + // f: 40 <= t <= 59 + + ((b & c) | (b & d) | (c & d)) + + 0x8F1BBCDC + w_t; + } + + private static int s4(int a, int b, int c, int d, int w_t) { + return rotateLeft(a, 5) + // f: 60 <= t <= 79 + + (b ^ c ^ d) + + 0xCA62C1D6 + w_t; + } + + private static boolean eq(State q, State r) { + return q.a == r.a + && q.b == r.b + && q.c == r.c + && q.d == r.d + && q.e == r.e; + } + + private void finish() { + int bufferLen = (int) (length & 63); + if (bufferLen > 55) { + // Last block is too small; pad, compress, pad another block. + buffer[bufferLen++] = (byte) 0x80; + Arrays.fill(buffer, bufferLen, 64, (byte) 0); + compress(buffer, 0); + Arrays.fill(buffer, 0, 56, (byte) 0); + } else { + // Last block can hold padding and length. + buffer[bufferLen++] = (byte) 0x80; + Arrays.fill(buffer, bufferLen, 56, (byte) 0); + } + + // SHA-1 appends the length of the message in bits after the + // padding block (above). Here length is in bytes. Multiply by + // 8 by shifting by 3 as part of storing the 64 bit byte length + // into the two words expected in the trailer. + NB.encodeInt32(buffer, 56, (int) (length >>> (32 - 3))); + NB.encodeInt32(buffer, 60, (int) (length << 3)); + compress(buffer, 0); + + if (foundCollision) { + ObjectId id = h.toObjectId(); + LOG.warn("possible SHA-1 collision " + id.name()); //$NON-NLS-1$ + throw new Sha1CollisionException(id); + } + } + + /** + * Finish the digest and return the resulting hash. + * <p> + * Once {@code digest()} is called, this instance should be discarded. + * + * @return the bytes for the resulting hash. + * @throws Sha1CollisionException + * if a collision was detected and safeHash is false. + */ + public byte[] digest() throws Sha1CollisionException { + finish(); + + byte[] b = new byte[20]; + NB.encodeInt32(b, 0, h.a); + NB.encodeInt32(b, 4, h.b); + NB.encodeInt32(b, 8, h.c); + NB.encodeInt32(b, 12, h.d); + NB.encodeInt32(b, 16, h.e); + return b; + } + + /** + * Finish the digest and return the resulting hash. + * <p> + * Once {@code digest()} is called, this instance should be discarded. + * + * @return the ObjectId for the resulting hash. + * @throws Sha1CollisionException + * if a collision was detected and safeHash is false. + */ + public ObjectId toObjectId() throws Sha1CollisionException { + finish(); + return h.toObjectId(); + } + + /** + * Finish the digest and return the resulting hash. + * <p> + * Once {@code digest()} is called, this instance should be discarded. + * + * @param id + * destination to copy the digest to. + * @throws Sha1CollisionException + * if a collision was detected and safeHash is false. + */ + public void digest(MutableObjectId id) throws Sha1CollisionException { + finish(); + id.set(h.a, h.b, h.c, h.d, h.e); + } + + /** + * Check if a collision was detected. + * + * <p> + * This method only returns an accurate result after the digest was obtained + * through {@link #digest()}, {@link #digest(MutableObjectId)} or + * {@link #toObjectId()}, as the hashing function must finish processing to + * know the final state. + * + * @return {@code true} if a likely collision was detected. + */ + public boolean hasCollision() { + return foundCollision; + } + + /** + * Reset this instance to compute another hash. + * + * @return {@code this}. + */ + public SHA1 reset() { + h.init(); + length = 0; + foundCollision = false; + return this; + } + + private static final class State { + int a; + int b; + int c; + int d; + int e; + + final void init() { + // Magic initialization constants defined by FIPS180. + save(0x67452301, 0xEFCDAB89, 0x98BADCFE, 0x10325476, 0xC3D2E1F0); + } + + final void save(int a1, int b1, int c1, int d1, int e1) { + a = a1; + b = b1; + c = c1; + d = d1; + e = e1; + } + + ObjectId toObjectId() { + return new ObjectId(a, b, c, d, e); + } + } +}
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/util/sha1/Sha1CollisionException.java b/org.eclipse.jgit/src/org/eclipse/jgit/util/sha1/Sha1CollisionException.java new file mode 100644 index 0000000..be126a5 --- /dev/null +++ b/org.eclipse.jgit/src/org/eclipse/jgit/util/sha1/Sha1CollisionException.java
@@ -0,0 +1,70 @@ +/* + * 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.util.sha1; + +import java.text.MessageFormat; + +import org.eclipse.jgit.internal.JGitText; +import org.eclipse.jgit.lib.ObjectId; + +/** + * Thrown by {@link SHA1} if it detects a likely hash collision. + * + * @since 4.7 + */ +public class Sha1CollisionException extends RuntimeException { + private static final long serialVersionUID = 1L; + + /** + * Initialize with default message. + * + * @param id + * object whose contents are a hash collision. + */ + public Sha1CollisionException(ObjectId id) { + super(MessageFormat.format( + JGitText.get().sha1CollisionDetected1, + id.name())); + } +}
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/util/sha1/UbcCheck.java b/org.eclipse.jgit/src/org/eclipse/jgit/util/sha1/UbcCheck.java new file mode 100644 index 0000000..cebdbee --- /dev/null +++ b/org.eclipse.jgit/src/org/eclipse/jgit/util/sha1/UbcCheck.java
@@ -0,0 +1,1040 @@ +/* +* Copyright 2017 Marc Stevens <marc@marc-stevens.nl>, Dan Shumow <danshu@microsoft.com> +* Distributed under the MIT Software License. +* MIT License +* +* Copyright (c) 2017: +* Marc Stevens +* Cryptology Group +* Centrum Wiskunde & Informatica +* P.O. Box 94079, 1090 GB Amsterdam, Netherlands +* marc@marc-stevens.nl +* +* Dan Shumow +* Microsoft Research +* danshu@microsoft.com +* +* Permission is hereby granted, free of charge, to any person obtaining a copy +* of this software and associated documentation files (the "Software"), to deal +* in the Software without restriction, including without limitation the rights +* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +* copies of the Software, and to permit persons to whom the Software is +* furnished to do so, subject to the following conditions: +* +* The above copyright notice and this permission notice shall be included in all +* copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +* SOFTWARE. +*/ + +package org.eclipse.jgit.util.sha1; + +// Converted by hand by Shawn Pearce (Google), using lib/ubc_check.c from +// https://github.com/cr-marcstevens/sha1collisiondetection/ +// +// this file was generated by the 'parse_bitrel' program in the tools section +// using the data files from directory 'tools/data/3565' +// +// Array DV contains a list of SHA-1 Disturbance Vectors (DV) to check +// dvType, dvK and dvB define the DV: I(K,B) or II(K,B) (see the paper) +// dm[80] is the expanded message block XOR-difference defined by the DV +// testt is the step to do the recompression from for collision detection +// maski and maskb define the bit to check for each DV in the dvmask returned by ubc_check +// +// ubc_check takes as input an expanded message block and verifies the unavoidable bitconditions for all listed DVs +// it returns a dvmask where each bit belonging to a DV is set if all unavoidable bitconditions for that DV have been met +// thus one needs to do the recompression check for each DV that has its bit set +// +// ubc_check is programmatically generated and the unavoidable bitconditions have been hardcoded +// a directly verifiable version named ubc_check_verify can be found in ubc_check_verify.c +// ubc_check has been verified against ubc_check_verify using the 'ubc_check_test' program in the tools section + +final class UbcCheck { + private static final int DV_I_43_0_bit = 1 << 0; + private static final int DV_I_44_0_bit = 1 << 1; + private static final int DV_I_45_0_bit = 1 << 2; + private static final int DV_I_46_0_bit = 1 << 3; + private static final int DV_I_46_2_bit = 1 << 4; + private static final int DV_I_47_0_bit = 1 << 5; + private static final int DV_I_47_2_bit = 1 << 6; + private static final int DV_I_48_0_bit = 1 << 7; + private static final int DV_I_48_2_bit = 1 << 8; + private static final int DV_I_49_0_bit = 1 << 9; + private static final int DV_I_49_2_bit = 1 << 10; + private static final int DV_I_50_0_bit = 1 << 11; + private static final int DV_I_50_2_bit = 1 << 12; + private static final int DV_I_51_0_bit = 1 << 13; + private static final int DV_I_51_2_bit = 1 << 14; + private static final int DV_I_52_0_bit = 1 << 15; + private static final int DV_II_45_0_bit = 1 << 16; + private static final int DV_II_46_0_bit = 1 << 17; + private static final int DV_II_46_2_bit = 1 << 18; + private static final int DV_II_47_0_bit = 1 << 19; + private static final int DV_II_48_0_bit = 1 << 20; + private static final int DV_II_49_0_bit = 1 << 21; + private static final int DV_II_49_2_bit = 1 << 22; + private static final int DV_II_50_0_bit = 1 << 23; + private static final int DV_II_50_2_bit = 1 << 24; + private static final int DV_II_51_0_bit = 1 << 25; + private static final int DV_II_51_2_bit = 1 << 26; + private static final int DV_II_52_0_bit = 1 << 27; + private static final int DV_II_53_0_bit = 1 << 28; + private static final int DV_II_54_0_bit = 1 << 29; + private static final int DV_II_55_0_bit = 1 << 30; + private static final int DV_II_56_0_bit = 1 << 31; + + static int check(int[] w) { + int mask = ~0; + mask &= (((((w[44] ^ w[45]) >>> 29) & 1) - 1) | ~(DV_I_48_0_bit + | DV_I_51_0_bit | DV_I_52_0_bit | DV_II_45_0_bit + | DV_II_46_0_bit | DV_II_50_0_bit | DV_II_51_0_bit)); + mask &= (((((w[49] ^ w[50]) >>> 29) & 1) - 1) + | ~(DV_I_46_0_bit | DV_II_45_0_bit | DV_II_50_0_bit + | DV_II_51_0_bit | DV_II_55_0_bit | DV_II_56_0_bit)); + mask &= (((((w[48] ^ w[49]) >>> 29) & 1) - 1) + | ~(DV_I_45_0_bit | DV_I_52_0_bit | DV_II_49_0_bit + | DV_II_50_0_bit | DV_II_54_0_bit | DV_II_55_0_bit)); + mask &= ((((w[47] ^ (w[50] >>> 25)) & (1 << 4)) - (1 << 4)) + | ~(DV_I_47_0_bit | DV_I_49_0_bit | DV_I_51_0_bit + | DV_II_45_0_bit | DV_II_51_0_bit | DV_II_56_0_bit)); + mask &= (((((w[47] ^ w[48]) >>> 29) & 1) - 1) + | ~(DV_I_44_0_bit | DV_I_51_0_bit | DV_II_48_0_bit + | DV_II_49_0_bit | DV_II_53_0_bit | DV_II_54_0_bit)); + mask &= (((((w[46] >>> 4) ^ (w[49] >>> 29)) & 1) - 1) + | ~(DV_I_46_0_bit | DV_I_48_0_bit | DV_I_50_0_bit + | DV_I_52_0_bit | DV_II_50_0_bit | DV_II_55_0_bit)); + mask &= (((((w[46] ^ w[47]) >>> 29) & 1) - 1) + | ~(DV_I_43_0_bit | DV_I_50_0_bit | DV_II_47_0_bit + | DV_II_48_0_bit | DV_II_52_0_bit | DV_II_53_0_bit)); + mask &= (((((w[45] >>> 4) ^ (w[48] >>> 29)) & 1) - 1) + | ~(DV_I_45_0_bit | DV_I_47_0_bit | DV_I_49_0_bit + | DV_I_51_0_bit | DV_II_49_0_bit | DV_II_54_0_bit)); + mask &= (((((w[45] ^ w[46]) >>> 29) & 1) - 1) + | ~(DV_I_49_0_bit | DV_I_52_0_bit | DV_II_46_0_bit + | DV_II_47_0_bit | DV_II_51_0_bit | DV_II_52_0_bit)); + mask &= (((((w[44] >>> 4) ^ (w[47] >>> 29)) & 1) - 1) + | ~(DV_I_44_0_bit | DV_I_46_0_bit | DV_I_48_0_bit + | DV_I_50_0_bit | DV_II_48_0_bit | DV_II_53_0_bit)); + mask &= (((((w[43] >>> 4) ^ (w[46] >>> 29)) & 1) - 1) + | ~(DV_I_43_0_bit | DV_I_45_0_bit | DV_I_47_0_bit + | DV_I_49_0_bit | DV_II_47_0_bit | DV_II_52_0_bit)); + mask &= (((((w[43] ^ w[44]) >>> 29) & 1) - 1) + | ~(DV_I_47_0_bit | DV_I_50_0_bit | DV_I_51_0_bit + | DV_II_45_0_bit | DV_II_49_0_bit | DV_II_50_0_bit)); + mask &= (((((w[42] >>> 4) ^ (w[45] >>> 29)) & 1) - 1) + | ~(DV_I_44_0_bit | DV_I_46_0_bit | DV_I_48_0_bit + | DV_I_52_0_bit | DV_II_46_0_bit | DV_II_51_0_bit)); + mask &= (((((w[41] >>> 4) ^ (w[44] >>> 29)) & 1) - 1) + | ~(DV_I_43_0_bit | DV_I_45_0_bit | DV_I_47_0_bit + | DV_I_51_0_bit | DV_II_45_0_bit | DV_II_50_0_bit)); + mask &= (((((w[40] ^ w[41]) >>> 29) & 1) - 1) + | ~(DV_I_44_0_bit | DV_I_47_0_bit | DV_I_48_0_bit + | DV_II_46_0_bit | DV_II_47_0_bit | DV_II_56_0_bit)); + mask &= (((((w[54] ^ w[55]) >>> 29) & 1) - 1) + | ~(DV_I_51_0_bit | DV_II_47_0_bit | DV_II_50_0_bit + | DV_II_55_0_bit | DV_II_56_0_bit)); + mask &= (((((w[53] ^ w[54]) >>> 29) & 1) - 1) + | ~(DV_I_50_0_bit | DV_II_46_0_bit | DV_II_49_0_bit + | DV_II_54_0_bit | DV_II_55_0_bit)); + mask &= (((((w[52] ^ w[53]) >>> 29) & 1) - 1) + | ~(DV_I_49_0_bit | DV_II_45_0_bit | DV_II_48_0_bit + | DV_II_53_0_bit | DV_II_54_0_bit)); + mask &= ((((w[50] ^ (w[53] >>> 25)) & (1 << 4)) - (1 << 4)) + | ~(DV_I_50_0_bit | DV_I_52_0_bit | DV_II_46_0_bit + | DV_II_48_0_bit | DV_II_54_0_bit)); + mask &= (((((w[50] ^ w[51]) >>> 29) & 1) - 1) + | ~(DV_I_47_0_bit | DV_II_46_0_bit | DV_II_51_0_bit + | DV_II_52_0_bit | DV_II_56_0_bit)); + mask &= ((((w[49] ^ (w[52] >>> 25)) & (1 << 4)) - (1 << 4)) + | ~(DV_I_49_0_bit | DV_I_51_0_bit | DV_II_45_0_bit + | DV_II_47_0_bit | DV_II_53_0_bit)); + mask &= ((((w[48] ^ (w[51] >>> 25)) & (1 << 4)) - (1 << 4)) + | ~(DV_I_48_0_bit | DV_I_50_0_bit | DV_I_52_0_bit + | DV_II_46_0_bit | DV_II_52_0_bit)); + mask &= (((((w[42] ^ w[43]) >>> 29) & 1) - 1) + | ~(DV_I_46_0_bit | DV_I_49_0_bit | DV_I_50_0_bit + | DV_II_48_0_bit | DV_II_49_0_bit)); + mask &= (((((w[41] ^ w[42]) >>> 29) & 1) - 1) + | ~(DV_I_45_0_bit | DV_I_48_0_bit | DV_I_49_0_bit + | DV_II_47_0_bit | DV_II_48_0_bit)); + mask &= (((((w[40] >>> 4) ^ (w[43] >>> 29)) & 1) - 1) + | ~(DV_I_44_0_bit | DV_I_46_0_bit | DV_I_50_0_bit + | DV_II_49_0_bit | DV_II_56_0_bit)); + mask &= (((((w[39] >>> 4) ^ (w[42] >>> 29)) & 1) - 1) + | ~(DV_I_43_0_bit | DV_I_45_0_bit | DV_I_49_0_bit + | DV_II_48_0_bit | DV_II_55_0_bit)); + if ((mask & (DV_I_44_0_bit | DV_I_48_0_bit | DV_II_47_0_bit + | DV_II_54_0_bit | DV_II_56_0_bit)) != 0) + mask &= (((((w[38] >>> 4) ^ (w[41] >>> 29)) & 1) - 1) + | ~(DV_I_44_0_bit | DV_I_48_0_bit | DV_II_47_0_bit + | DV_II_54_0_bit | DV_II_56_0_bit)); + mask &= (((((w[37] >>> 4) ^ (w[40] >>> 29)) & 1) - 1) + | ~(DV_I_43_0_bit | DV_I_47_0_bit | DV_II_46_0_bit + | DV_II_53_0_bit | DV_II_55_0_bit)); + if ((mask & (DV_I_52_0_bit | DV_II_48_0_bit | DV_II_51_0_bit + | DV_II_56_0_bit)) != 0) + mask &= (((((w[55] ^ w[56]) >>> 29) & 1) - 1) | ~(DV_I_52_0_bit + | DV_II_48_0_bit | DV_II_51_0_bit | DV_II_56_0_bit)); + if ((mask & (DV_I_52_0_bit | DV_II_48_0_bit | DV_II_50_0_bit + | DV_II_56_0_bit)) != 0) + mask &= ((((w[52] ^ (w[55] >>> 25)) & (1 << 4)) - (1 << 4)) + | ~(DV_I_52_0_bit | DV_II_48_0_bit | DV_II_50_0_bit + | DV_II_56_0_bit)); + if ((mask & (DV_I_51_0_bit | DV_II_47_0_bit | DV_II_49_0_bit + | DV_II_55_0_bit)) != 0) + mask &= ((((w[51] ^ (w[54] >>> 25)) & (1 << 4)) - (1 << 4)) + | ~(DV_I_51_0_bit | DV_II_47_0_bit | DV_II_49_0_bit + | DV_II_55_0_bit)); + if ((mask & (DV_I_48_0_bit | DV_II_47_0_bit | DV_II_52_0_bit + | DV_II_53_0_bit)) != 0) + mask &= (((((w[51] ^ w[52]) >>> 29) & 1) - 1) | ~(DV_I_48_0_bit + | DV_II_47_0_bit | DV_II_52_0_bit | DV_II_53_0_bit)); + if ((mask & (DV_I_46_0_bit | DV_I_49_0_bit | DV_II_45_0_bit + | DV_II_48_0_bit)) != 0) + mask &= (((((w[36] >>> 4) ^ (w[40] >>> 29)) & 1) - 1) + | ~(DV_I_46_0_bit | DV_I_49_0_bit | DV_II_45_0_bit + | DV_II_48_0_bit)); + if ((mask & (DV_I_52_0_bit | DV_II_48_0_bit | DV_II_49_0_bit)) != 0) + mask &= ((0 - (((w[53] ^ w[56]) >>> 29) & 1)) + | ~(DV_I_52_0_bit | DV_II_48_0_bit | DV_II_49_0_bit)); + if ((mask & (DV_I_50_0_bit | DV_II_46_0_bit | DV_II_47_0_bit)) != 0) + mask &= ((0 - (((w[51] ^ w[54]) >>> 29) & 1)) + | ~(DV_I_50_0_bit | DV_II_46_0_bit | DV_II_47_0_bit)); + if ((mask & (DV_I_49_0_bit | DV_I_51_0_bit | DV_II_45_0_bit)) != 0) + mask &= ((0 - (((w[50] ^ w[52]) >>> 29) & 1)) + | ~(DV_I_49_0_bit | DV_I_51_0_bit | DV_II_45_0_bit)); + if ((mask & (DV_I_48_0_bit | DV_I_50_0_bit | DV_I_52_0_bit)) != 0) + mask &= ((0 - (((w[49] ^ w[51]) >>> 29) & 1)) + | ~(DV_I_48_0_bit | DV_I_50_0_bit | DV_I_52_0_bit)); + if ((mask & (DV_I_47_0_bit | DV_I_49_0_bit | DV_I_51_0_bit)) != 0) + mask &= ((0 - (((w[48] ^ w[50]) >>> 29) & 1)) + | ~(DV_I_47_0_bit | DV_I_49_0_bit | DV_I_51_0_bit)); + if ((mask & (DV_I_46_0_bit | DV_I_48_0_bit | DV_I_50_0_bit)) != 0) + mask &= ((0 - (((w[47] ^ w[49]) >>> 29) & 1)) + | ~(DV_I_46_0_bit | DV_I_48_0_bit | DV_I_50_0_bit)); + if ((mask & (DV_I_45_0_bit | DV_I_47_0_bit | DV_I_49_0_bit)) != 0) + mask &= ((0 - (((w[46] ^ w[48]) >>> 29) & 1)) + | ~(DV_I_45_0_bit | DV_I_47_0_bit | DV_I_49_0_bit)); + mask &= ((((w[45] ^ w[47]) & (1 << 6)) - (1 << 6)) + | ~(DV_I_47_2_bit | DV_I_49_2_bit | DV_I_51_2_bit)); + if ((mask & (DV_I_44_0_bit | DV_I_46_0_bit | DV_I_48_0_bit)) != 0) + mask &= ((0 - (((w[45] ^ w[47]) >>> 29) & 1)) + | ~(DV_I_44_0_bit | DV_I_46_0_bit | DV_I_48_0_bit)); + mask &= (((((w[44] ^ w[46]) >>> 6) & 1) - 1) + | ~(DV_I_46_2_bit | DV_I_48_2_bit | DV_I_50_2_bit)); + if ((mask & (DV_I_43_0_bit | DV_I_45_0_bit | DV_I_47_0_bit)) != 0) + mask &= ((0 - (((w[44] ^ w[46]) >>> 29) & 1)) + | ~(DV_I_43_0_bit | DV_I_45_0_bit | DV_I_47_0_bit)); + mask &= ((0 - ((w[41] ^ (w[42] >>> 5)) & (1 << 1))) + | ~(DV_I_48_2_bit | DV_II_46_2_bit | DV_II_51_2_bit)); + mask &= ((0 - ((w[40] ^ (w[41] >>> 5)) & (1 << 1))) + | ~(DV_I_47_2_bit | DV_I_51_2_bit | DV_II_50_2_bit)); + if ((mask & (DV_I_44_0_bit | DV_I_46_0_bit | DV_II_56_0_bit)) != 0) + mask &= ((0 - (((w[40] ^ w[42]) >>> 4) & 1)) + | ~(DV_I_44_0_bit | DV_I_46_0_bit | DV_II_56_0_bit)); + mask &= ((0 - ((w[39] ^ (w[40] >>> 5)) & (1 << 1))) + | ~(DV_I_46_2_bit | DV_I_50_2_bit | DV_II_49_2_bit)); + if ((mask & (DV_I_43_0_bit | DV_I_45_0_bit | DV_II_55_0_bit)) != 0) + mask &= ((0 - (((w[39] ^ w[41]) >>> 4) & 1)) + | ~(DV_I_43_0_bit | DV_I_45_0_bit | DV_II_55_0_bit)); + if ((mask & (DV_I_44_0_bit | DV_II_54_0_bit | DV_II_56_0_bit)) != 0) + mask &= ((0 - (((w[38] ^ w[40]) >>> 4) & 1)) + | ~(DV_I_44_0_bit | DV_II_54_0_bit | DV_II_56_0_bit)); + if ((mask & (DV_I_43_0_bit | DV_II_53_0_bit | DV_II_55_0_bit)) != 0) + mask &= ((0 - (((w[37] ^ w[39]) >>> 4) & 1)) + | ~(DV_I_43_0_bit | DV_II_53_0_bit | DV_II_55_0_bit)); + mask &= ((0 - ((w[36] ^ (w[37] >>> 5)) & (1 << 1))) + | ~(DV_I_47_2_bit | DV_I_50_2_bit | DV_II_46_2_bit)); + if ((mask & (DV_I_45_0_bit | DV_I_48_0_bit | DV_II_47_0_bit)) != 0) + mask &= (((((w[35] >>> 4) ^ (w[39] >>> 29)) & 1) - 1) + | ~(DV_I_45_0_bit | DV_I_48_0_bit | DV_II_47_0_bit)); + if ((mask & (DV_I_48_0_bit | DV_II_48_0_bit)) != 0) + mask &= ((0 - ((w[63] ^ (w[64] >>> 5)) & (1 << 0))) + | ~(DV_I_48_0_bit | DV_II_48_0_bit)); + if ((mask & (DV_I_45_0_bit | DV_II_45_0_bit)) != 0) + mask &= ((0 - ((w[63] ^ (w[64] >>> 5)) & (1 << 1))) + | ~(DV_I_45_0_bit | DV_II_45_0_bit)); + if ((mask & (DV_I_47_0_bit | DV_II_47_0_bit)) != 0) + mask &= ((0 - ((w[62] ^ (w[63] >>> 5)) & (1 << 0))) + | ~(DV_I_47_0_bit | DV_II_47_0_bit)); + if ((mask & (DV_I_46_0_bit | DV_II_46_0_bit)) != 0) + mask &= ((0 - ((w[61] ^ (w[62] >>> 5)) & (1 << 0))) + | ~(DV_I_46_0_bit | DV_II_46_0_bit)); + mask &= ((0 - ((w[61] ^ (w[62] >>> 5)) & (1 << 2))) + | ~(DV_I_46_2_bit | DV_II_46_2_bit)); + if ((mask & (DV_I_45_0_bit | DV_II_45_0_bit)) != 0) + mask &= ((0 - ((w[60] ^ (w[61] >>> 5)) & (1 << 0))) + | ~(DV_I_45_0_bit | DV_II_45_0_bit)); + if ((mask & (DV_II_51_0_bit | DV_II_54_0_bit)) != 0) + mask &= (((((w[58] ^ w[59]) >>> 29) & 1) - 1) + | ~(DV_II_51_0_bit | DV_II_54_0_bit)); + if ((mask & (DV_II_50_0_bit | DV_II_53_0_bit)) != 0) + mask &= (((((w[57] ^ w[58]) >>> 29) & 1) - 1) + | ~(DV_II_50_0_bit | DV_II_53_0_bit)); + if ((mask & (DV_II_52_0_bit | DV_II_54_0_bit)) != 0) + mask &= ((((w[56] ^ (w[59] >>> 25)) & (1 << 4)) - (1 << 4)) + | ~(DV_II_52_0_bit | DV_II_54_0_bit)); + if ((mask & (DV_II_51_0_bit | DV_II_52_0_bit)) != 0) + mask &= ((0 - (((w[56] ^ w[59]) >>> 29) & 1)) + | ~(DV_II_51_0_bit | DV_II_52_0_bit)); + if ((mask & (DV_II_49_0_bit | DV_II_52_0_bit)) != 0) + mask &= (((((w[56] ^ w[57]) >>> 29) & 1) - 1) + | ~(DV_II_49_0_bit | DV_II_52_0_bit)); + if ((mask & (DV_II_51_0_bit | DV_II_53_0_bit)) != 0) + mask &= ((((w[55] ^ (w[58] >>> 25)) & (1 << 4)) - (1 << 4)) + | ~(DV_II_51_0_bit | DV_II_53_0_bit)); + if ((mask & (DV_II_50_0_bit | DV_II_52_0_bit)) != 0) + mask &= ((((w[54] ^ (w[57] >>> 25)) & (1 << 4)) - (1 << 4)) + | ~(DV_II_50_0_bit | DV_II_52_0_bit)); + if ((mask & (DV_II_49_0_bit | DV_II_51_0_bit)) != 0) + mask &= ((((w[53] ^ (w[56] >>> 25)) & (1 << 4)) - (1 << 4)) + | ~(DV_II_49_0_bit | DV_II_51_0_bit)); + mask &= ((((w[51] ^ (w[50] >>> 5)) & (1 << 1)) - (1 << 1)) + | ~(DV_I_50_2_bit | DV_II_46_2_bit)); + mask &= ((((w[48] ^ w[50]) & (1 << 6)) - (1 << 6)) + | ~(DV_I_50_2_bit | DV_II_46_2_bit)); + if ((mask & (DV_I_51_0_bit | DV_I_52_0_bit)) != 0) + mask &= ((0 - (((w[48] ^ w[55]) >>> 29) & 1)) + | ~(DV_I_51_0_bit | DV_I_52_0_bit)); + mask &= ((((w[47] ^ w[49]) & (1 << 6)) - (1 << 6)) + | ~(DV_I_49_2_bit | DV_I_51_2_bit)); + mask &= ((((w[48] ^ (w[47] >>> 5)) & (1 << 1)) - (1 << 1)) + | ~(DV_I_47_2_bit | DV_II_51_2_bit)); + mask &= ((((w[46] ^ w[48]) & (1 << 6)) - (1 << 6)) + | ~(DV_I_48_2_bit | DV_I_50_2_bit)); + mask &= ((((w[47] ^ (w[46] >>> 5)) & (1 << 1)) - (1 << 1)) + | ~(DV_I_46_2_bit | DV_II_50_2_bit)); + mask &= ((0 - ((w[44] ^ (w[45] >>> 5)) & (1 << 1))) + | ~(DV_I_51_2_bit | DV_II_49_2_bit)); + mask &= ((((w[43] ^ w[45]) & (1 << 6)) - (1 << 6)) + | ~(DV_I_47_2_bit | DV_I_49_2_bit)); + mask &= (((((w[42] ^ w[44]) >>> 6) & 1) - 1) + | ~(DV_I_46_2_bit | DV_I_48_2_bit)); + mask &= ((((w[43] ^ (w[42] >>> 5)) & (1 << 1)) - (1 << 1)) + | ~(DV_II_46_2_bit | DV_II_51_2_bit)); + mask &= ((((w[42] ^ (w[41] >>> 5)) & (1 << 1)) - (1 << 1)) + | ~(DV_I_51_2_bit | DV_II_50_2_bit)); + mask &= ((((w[41] ^ (w[40] >>> 5)) & (1 << 1)) - (1 << 1)) + | ~(DV_I_50_2_bit | DV_II_49_2_bit)); + if ((mask & (DV_I_52_0_bit | DV_II_51_0_bit)) != 0) + mask &= ((((w[39] ^ (w[43] >>> 25)) & (1 << 4)) - (1 << 4)) + | ~(DV_I_52_0_bit | DV_II_51_0_bit)); + if ((mask & (DV_I_51_0_bit | DV_II_50_0_bit)) != 0) + mask &= ((((w[38] ^ (w[42] >>> 25)) & (1 << 4)) - (1 << 4)) + | ~(DV_I_51_0_bit | DV_II_50_0_bit)); + if ((mask & (DV_I_48_2_bit | DV_I_51_2_bit)) != 0) + mask &= ((0 - ((w[37] ^ (w[38] >>> 5)) & (1 << 1))) + | ~(DV_I_48_2_bit | DV_I_51_2_bit)); + if ((mask & (DV_I_50_0_bit | DV_II_49_0_bit)) != 0) + mask &= ((((w[37] ^ (w[41] >>> 25)) & (1 << 4)) - (1 << 4)) + | ~(DV_I_50_0_bit | DV_II_49_0_bit)); + if ((mask & (DV_II_52_0_bit | DV_II_54_0_bit)) != 0) + mask &= ((0 - ((w[36] ^ w[38]) & (1 << 4))) + | ~(DV_II_52_0_bit | DV_II_54_0_bit)); + mask &= ((0 - ((w[35] ^ (w[36] >>> 5)) & (1 << 1))) + | ~(DV_I_46_2_bit | DV_I_49_2_bit)); + if ((mask & (DV_I_51_0_bit | DV_II_47_0_bit)) != 0) + mask &= ((((w[35] ^ (w[39] >>> 25)) & (1 << 3)) - (1 << 3)) + | ~(DV_I_51_0_bit | DV_II_47_0_bit)); + + if (mask == 0) { + return mask; + } + + if ((mask & DV_I_43_0_bit) != 0) + if (0 == ((w[61] ^ (w[62] >>> 5)) & (1 << 1)) + || 0 != ((w[59] ^ (w[63] >>> 25)) & (1 << 5)) + || 0 == ((w[58] ^ (w[63] >>> 30)) & (1 << 0))) + mask &= ~DV_I_43_0_bit; + if ((mask & DV_I_44_0_bit) != 0) + if (0 == ((w[62] ^ (w[63] >>> 5)) & (1 << 1)) + || 0 != ((w[60] ^ (w[64] >>> 25)) & (1 << 5)) + || 0 == ((w[59] ^ (w[64] >>> 30)) & (1 << 0))) + mask &= ~DV_I_44_0_bit; + if ((mask & DV_I_46_2_bit) != 0) + mask &= ((~((w[40] ^ w[42]) >>> 2)) | ~DV_I_46_2_bit); + if ((mask & DV_I_47_2_bit) != 0) + if (0 == ((w[62] ^ (w[63] >>> 5)) & (1 << 2)) + || 0 != ((w[41] ^ w[43]) & (1 << 6))) + mask &= ~DV_I_47_2_bit; + if ((mask & DV_I_48_2_bit) != 0) + if (0 == ((w[63] ^ (w[64] >>> 5)) & (1 << 2)) + || 0 != ((w[48] ^ (w[49] << 5)) & (1 << 6))) + mask &= ~DV_I_48_2_bit; + if ((mask & DV_I_49_2_bit) != 0) + if (0 != ((w[49] ^ (w[50] << 5)) & (1 << 6)) + || 0 == ((w[42] ^ w[50]) & (1 << 1)) + || 0 != ((w[39] ^ (w[40] << 5)) & (1 << 6)) + || 0 == ((w[38] ^ w[40]) & (1 << 1))) + mask &= ~DV_I_49_2_bit; + if ((mask & DV_I_50_0_bit) != 0) + mask &= ((((w[36] ^ w[37]) << 7)) | ~DV_I_50_0_bit); + if ((mask & DV_I_50_2_bit) != 0) + mask &= ((((w[43] ^ w[51]) << 11)) | ~DV_I_50_2_bit); + if ((mask & DV_I_51_0_bit) != 0) + mask &= ((((w[37] ^ w[38]) << 9)) | ~DV_I_51_0_bit); + if ((mask & DV_I_51_2_bit) != 0) + if (0 != ((w[51] ^ (w[52] << 5)) & (1 << 6)) + || 0 != ((w[49] ^ w[51]) & (1 << 6)) + || 0 != ((w[37] ^ (w[37] >>> 5)) & (1 << 1)) + || 0 != ((w[35] ^ (w[39] >>> 25)) & (1 << 5))) + mask &= ~DV_I_51_2_bit; + if ((mask & DV_I_52_0_bit) != 0) + mask &= ((((w[38] ^ w[39]) << 11)) | ~DV_I_52_0_bit); + if ((mask & DV_II_46_2_bit) != 0) + mask &= ((((w[47] ^ w[51]) << 17)) | ~DV_II_46_2_bit); + if ((mask & DV_II_48_0_bit) != 0) + if (0 != ((w[36] ^ (w[40] >>> 25)) & (1 << 3)) + || 0 == ((w[35] ^ (w[40] << 2)) & (1 << 30))) + mask &= ~DV_II_48_0_bit; + if ((mask & DV_II_49_0_bit) != 0) + if (0 != ((w[37] ^ (w[41] >>> 25)) & (1 << 3)) + || 0 == ((w[36] ^ (w[41] << 2)) & (1 << 30))) + mask &= ~DV_II_49_0_bit; + if ((mask & DV_II_49_2_bit) != 0) + if (0 != ((w[53] ^ (w[54] << 5)) & (1 << 6)) + || 0 != ((w[51] ^ w[53]) & (1 << 6)) + || 0 == ((w[50] ^ w[54]) & (1 << 1)) + || 0 != ((w[45] ^ (w[46] << 5)) & (1 << 6)) + || 0 != ((w[37] ^ (w[41] >>> 25)) & (1 << 5)) + || 0 == ((w[36] ^ (w[41] >>> 30)) & (1 << 0))) + mask &= ~DV_II_49_2_bit; + if ((mask & DV_II_50_0_bit) != 0) + if (0 == ((w[55] ^ w[58]) & (1 << 29)) + || 0 != ((w[38] ^ (w[42] >>> 25)) & (1 << 3)) + || 0 == ((w[37] ^ (w[42] << 2)) & (1 << 30))) + mask &= ~DV_II_50_0_bit; + if ((mask & DV_II_50_2_bit) != 0) + if (0 != ((w[54] ^ (w[55] << 5)) & (1 << 6)) + || 0!=((w[52] ^ w[54]) & (1 << 6)) + || 0==((w[51] ^ w[55]) & (1 << 1)) + || 0==((w[45] ^ w[47]) & (1 << 1)) + || 0!=((w[38] ^ (w[42] >>> 25)) & (1 << 5)) + || 0==((w[37] ^ (w[42] >>> 30)) & (1 << 0))) + mask &= ~DV_II_50_2_bit; + if ((mask & DV_II_51_0_bit) != 0) + if (0 != ((w[39] ^ (w[43] >>> 25)) & (1 << 3)) + || 0 == ((w[38] ^ (w[43] << 2)) & (1 << 30))) + mask &= ~DV_II_51_0_bit; + if ((mask & DV_II_51_2_bit) != 0) + if (0 != ((w[55] ^ (w[56] << 5)) & (1 << 6)) + || 0 != ((w[53] ^ w[55]) & (1 << 6)) + || 0 == ((w[52] ^ w[56]) & (1 << 1)) + || 0 == ((w[46] ^ w[48]) & (1 << 1)) + || 0 != ((w[39] ^ (w[43] >>> 25)) & (1 << 5)) + || 0 == ((w[38] ^ (w[43] >>> 30)) & (1 << 0))) + mask &= ~DV_II_51_2_bit; + if ((mask & DV_II_52_0_bit) != 0) + if (0 != ((w[59] ^ w[60]) & (1 << 29)) + || 0 != ((w[40] ^ (w[44] >>> 25)) & (1 << 3)) + || 0 != ((w[40] ^ (w[44] >>> 25)) & (1 << 4)) + || 0==((w[39] ^ (w[44] << 2)) & (1 << 30))) + mask &= ~DV_II_52_0_bit; + if ((mask & DV_II_53_0_bit) != 0) + if (0==((w[58] ^ w[61]) & (1 << 29)) + || 0!=((w[57] ^ (w[61] >>> 25)) & (1 << 4)) + || 0!=((w[41] ^ (w[45] >>> 25)) & (1 << 3)) + || 0!=((w[41] ^ (w[45] >>> 25)) & (1 << 4))) + mask &= ~DV_II_53_0_bit; + if ((mask & DV_II_54_0_bit) != 0) + if (0 != ((w[58] ^ (w[62] >>> 25)) & (1 << 4)) + || 0 != ((w[42] ^ (w[46] >>> 25)) & (1 << 3)) + || 0 != ((w[42] ^ (w[46] >>> 25)) & (1 << 4))) + mask &= ~DV_II_54_0_bit; + if ((mask & DV_II_55_0_bit) != 0) + if (0 != ((w[59] ^ (w[63] >>> 25)) & (1 << 4)) + || 0 != ((w[57] ^ (w[59] >>> 25)) & (1 << 4)) + || 0 != ((w[43] ^ (w[47] >>> 25)) & (1 << 3)) + || 0 != ((w[43] ^ (w[47] >>> 25)) & (1 << 4))) + mask &= ~DV_II_55_0_bit; + if ((mask & DV_II_56_0_bit) != 0) + if (0 != ((w[60] ^ (w[64] >>> 25)) & (1 << 4)) + || 0 != ((w[44] ^ (w[48] >>> 25)) & (1 << 3)) + || 0 != ((w[44] ^ (w[48] >>> 25)) & (1 << 4))) + mask &= ~DV_II_56_0_bit; + return mask; + } + + private UbcCheck() { + } + + static final class DvInfo { + final int testt; + final int maskb; + final int[] dm; + + @SuppressWarnings("unused") + DvInfo(int dvType, int dvK, int dvB, int testt, int maskb, int[] dm) { + this.testt = testt; + this.maskb = maskb; + this.dm = dm; + + // Only states 58 and 65 are saved. + if (testt != 58 && testt != 65) { + throw new IllegalArgumentException(); + } + } + } + + static final DvInfo[] DV = new DvInfo[] { + new DvInfo(1, 43, 0, 58, 0, new int[] { 0x08000000, 0x9800000c, + 0xd8000010, 0x08000010, 0xb8000010, 0x98000000, 0x60000000, + 0x00000008, 0xc0000000, 0x90000014, 0x10000010, 0xb8000014, + 0x28000000, 0x20000010, 0x48000000, 0x08000018, 0x60000000, + 0x90000010, 0xf0000010, 0x90000008, 0xc0000000, 0x90000010, + 0xf0000010, 0xb0000008, 0x40000000, 0x90000000, 0xf0000010, + 0x90000018, 0x60000000, 0x90000010, 0x90000010, 0x90000000, + 0x80000000, 0x00000010, 0xa0000000, 0x20000000, 0xa0000000, + 0x20000010, 0x00000000, 0x20000010, 0x20000000, 0x00000010, + 0x20000000, 0x00000010, 0xa0000000, 0x00000000, 0x20000000, + 0x20000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000001, 0x00000020, 0x00000001, 0x40000002, + 0x40000040, 0x40000002, 0x80000004, 0x80000080, 0x80000006, + 0x00000049, 0x00000103, 0x80000009, 0x80000012, 0x80000202, + 0x00000018, 0x00000164, 0x00000408, 0x800000e6, 0x8000004c, + 0x00000803, 0x80000161, 0x80000599 }), + new DvInfo(1, 44, 0, 58, 1, new int[] { 0xb4000008, 0x08000000, + 0x9800000c, 0xd8000010, 0x08000010, 0xb8000010, 0x98000000, + 0x60000000, 0x00000008, 0xc0000000, 0x90000014, 0x10000010, + 0xb8000014, 0x28000000, 0x20000010, 0x48000000, 0x08000018, + 0x60000000, 0x90000010, 0xf0000010, 0x90000008, 0xc0000000, + 0x90000010, 0xf0000010, 0xb0000008, 0x40000000, 0x90000000, + 0xf0000010, 0x90000018, 0x60000000, 0x90000010, 0x90000010, + 0x90000000, 0x80000000, 0x00000010, 0xa0000000, 0x20000000, + 0xa0000000, 0x20000010, 0x00000000, 0x20000010, 0x20000000, + 0x00000010, 0x20000000, 0x00000010, 0xa0000000, 0x00000000, + 0x20000000, 0x20000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000001, 0x00000020, 0x00000001, + 0x40000002, 0x40000040, 0x40000002, 0x80000004, 0x80000080, + 0x80000006, 0x00000049, 0x00000103, 0x80000009, 0x80000012, + 0x80000202, 0x00000018, 0x00000164, 0x00000408, 0x800000e6, + 0x8000004c, 0x00000803, 0x80000161 }), + new DvInfo(1, 45, 0, 58, 2, new int[] { 0xf4000014, 0xb4000008, + 0x08000000, 0x9800000c, 0xd8000010, 0x08000010, 0xb8000010, + 0x98000000, 0x60000000, 0x00000008, 0xc0000000, 0x90000014, + 0x10000010, 0xb8000014, 0x28000000, 0x20000010, 0x48000000, + 0x08000018, 0x60000000, 0x90000010, 0xf0000010, 0x90000008, + 0xc0000000, 0x90000010, 0xf0000010, 0xb0000008, 0x40000000, + 0x90000000, 0xf0000010, 0x90000018, 0x60000000, 0x90000010, + 0x90000010, 0x90000000, 0x80000000, 0x00000010, 0xa0000000, + 0x20000000, 0xa0000000, 0x20000010, 0x00000000, 0x20000010, + 0x20000000, 0x00000010, 0x20000000, 0x00000010, 0xa0000000, + 0x00000000, 0x20000000, 0x20000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000001, 0x00000020, + 0x00000001, 0x40000002, 0x40000040, 0x40000002, 0x80000004, + 0x80000080, 0x80000006, 0x00000049, 0x00000103, 0x80000009, + 0x80000012, 0x80000202, 0x00000018, 0x00000164, 0x00000408, + 0x800000e6, 0x8000004c, 0x00000803 }), + new DvInfo(1, 46, 0, 58, 3, new int[] { 0x2c000010, 0xf4000014, + 0xb4000008, 0x08000000, 0x9800000c, 0xd8000010, 0x08000010, + 0xb8000010, 0x98000000, 0x60000000, 0x00000008, 0xc0000000, + 0x90000014, 0x10000010, 0xb8000014, 0x28000000, 0x20000010, + 0x48000000, 0x08000018, 0x60000000, 0x90000010, 0xf0000010, + 0x90000008, 0xc0000000, 0x90000010, 0xf0000010, 0xb0000008, + 0x40000000, 0x90000000, 0xf0000010, 0x90000018, 0x60000000, + 0x90000010, 0x90000010, 0x90000000, 0x80000000, 0x00000010, + 0xa0000000, 0x20000000, 0xa0000000, 0x20000010, 0x00000000, + 0x20000010, 0x20000000, 0x00000010, 0x20000000, 0x00000010, + 0xa0000000, 0x00000000, 0x20000000, 0x20000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000001, + 0x00000020, 0x00000001, 0x40000002, 0x40000040, 0x40000002, + 0x80000004, 0x80000080, 0x80000006, 0x00000049, 0x00000103, + 0x80000009, 0x80000012, 0x80000202, 0x00000018, 0x00000164, + 0x00000408, 0x800000e6, 0x8000004c }), + new DvInfo(1, 46, 2, 58, 4, new int[] { 0xb0000040, 0xd0000053, + 0xd0000022, 0x20000000, 0x60000032, 0x60000043, 0x20000040, + 0xe0000042, 0x60000002, 0x80000001, 0x00000020, 0x00000003, + 0x40000052, 0x40000040, 0xe0000052, 0xa0000000, 0x80000040, + 0x20000001, 0x20000060, 0x80000001, 0x40000042, 0xc0000043, + 0x40000022, 0x00000003, 0x40000042, 0xc0000043, 0xc0000022, + 0x00000001, 0x40000002, 0xc0000043, 0x40000062, 0x80000001, + 0x40000042, 0x40000042, 0x40000002, 0x00000002, 0x00000040, + 0x80000002, 0x80000000, 0x80000002, 0x80000040, 0x00000000, + 0x80000040, 0x80000000, 0x00000040, 0x80000000, 0x00000040, + 0x80000002, 0x00000000, 0x80000000, 0x80000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000004, + 0x00000080, 0x00000004, 0x00000009, 0x00000101, 0x00000009, + 0x00000012, 0x00000202, 0x0000001a, 0x00000124, 0x0000040c, + 0x00000026, 0x0000004a, 0x0000080a, 0x00000060, 0x00000590, + 0x00001020, 0x0000039a, 0x00000132 }), + new DvInfo(1, 47, 0, 58, 5, new int[] { 0xc8000010, 0x2c000010, + 0xf4000014, 0xb4000008, 0x08000000, 0x9800000c, 0xd8000010, + 0x08000010, 0xb8000010, 0x98000000, 0x60000000, 0x00000008, + 0xc0000000, 0x90000014, 0x10000010, 0xb8000014, 0x28000000, + 0x20000010, 0x48000000, 0x08000018, 0x60000000, 0x90000010, + 0xf0000010, 0x90000008, 0xc0000000, 0x90000010, 0xf0000010, + 0xb0000008, 0x40000000, 0x90000000, 0xf0000010, 0x90000018, + 0x60000000, 0x90000010, 0x90000010, 0x90000000, 0x80000000, + 0x00000010, 0xa0000000, 0x20000000, 0xa0000000, 0x20000010, + 0x00000000, 0x20000010, 0x20000000, 0x00000010, 0x20000000, + 0x00000010, 0xa0000000, 0x00000000, 0x20000000, 0x20000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000001, 0x00000020, 0x00000001, 0x40000002, 0x40000040, + 0x40000002, 0x80000004, 0x80000080, 0x80000006, 0x00000049, + 0x00000103, 0x80000009, 0x80000012, 0x80000202, 0x00000018, + 0x00000164, 0x00000408, 0x800000e6 }), + new DvInfo(1, 47, 2, 58, 6, new int[] { 0x20000043, 0xb0000040, + 0xd0000053, 0xd0000022, 0x20000000, 0x60000032, 0x60000043, + 0x20000040, 0xe0000042, 0x60000002, 0x80000001, 0x00000020, + 0x00000003, 0x40000052, 0x40000040, 0xe0000052, 0xa0000000, + 0x80000040, 0x20000001, 0x20000060, 0x80000001, 0x40000042, + 0xc0000043, 0x40000022, 0x00000003, 0x40000042, 0xc0000043, + 0xc0000022, 0x00000001, 0x40000002, 0xc0000043, 0x40000062, + 0x80000001, 0x40000042, 0x40000042, 0x40000002, 0x00000002, + 0x00000040, 0x80000002, 0x80000000, 0x80000002, 0x80000040, + 0x00000000, 0x80000040, 0x80000000, 0x00000040, 0x80000000, + 0x00000040, 0x80000002, 0x00000000, 0x80000000, 0x80000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000004, 0x00000080, 0x00000004, 0x00000009, 0x00000101, + 0x00000009, 0x00000012, 0x00000202, 0x0000001a, 0x00000124, + 0x0000040c, 0x00000026, 0x0000004a, 0x0000080a, 0x00000060, + 0x00000590, 0x00001020, 0x0000039a }), + new DvInfo(1, 48, 0, 58, 7, new int[] { 0xb800000a, 0xc8000010, + 0x2c000010, 0xf4000014, 0xb4000008, 0x08000000, 0x9800000c, + 0xd8000010, 0x08000010, 0xb8000010, 0x98000000, 0x60000000, + 0x00000008, 0xc0000000, 0x90000014, 0x10000010, 0xb8000014, + 0x28000000, 0x20000010, 0x48000000, 0x08000018, 0x60000000, + 0x90000010, 0xf0000010, 0x90000008, 0xc0000000, 0x90000010, + 0xf0000010, 0xb0000008, 0x40000000, 0x90000000, 0xf0000010, + 0x90000018, 0x60000000, 0x90000010, 0x90000010, 0x90000000, + 0x80000000, 0x00000010, 0xa0000000, 0x20000000, 0xa0000000, + 0x20000010, 0x00000000, 0x20000010, 0x20000000, 0x00000010, + 0x20000000, 0x00000010, 0xa0000000, 0x00000000, 0x20000000, + 0x20000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000001, 0x00000020, 0x00000001, 0x40000002, + 0x40000040, 0x40000002, 0x80000004, 0x80000080, 0x80000006, + 0x00000049, 0x00000103, 0x80000009, 0x80000012, 0x80000202, + 0x00000018, 0x00000164, 0x00000408 }), + new DvInfo(1, 48, 2, 58, 8, new int[] { 0xe000002a, 0x20000043, + 0xb0000040, 0xd0000053, 0xd0000022, 0x20000000, 0x60000032, + 0x60000043, 0x20000040, 0xe0000042, 0x60000002, 0x80000001, + 0x00000020, 0x00000003, 0x40000052, 0x40000040, 0xe0000052, + 0xa0000000, 0x80000040, 0x20000001, 0x20000060, 0x80000001, + 0x40000042, 0xc0000043, 0x40000022, 0x00000003, 0x40000042, + 0xc0000043, 0xc0000022, 0x00000001, 0x40000002, 0xc0000043, + 0x40000062, 0x80000001, 0x40000042, 0x40000042, 0x40000002, + 0x00000002, 0x00000040, 0x80000002, 0x80000000, 0x80000002, + 0x80000040, 0x00000000, 0x80000040, 0x80000000, 0x00000040, + 0x80000000, 0x00000040, 0x80000002, 0x00000000, 0x80000000, + 0x80000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000004, 0x00000080, 0x00000004, 0x00000009, + 0x00000101, 0x00000009, 0x00000012, 0x00000202, 0x0000001a, + 0x00000124, 0x0000040c, 0x00000026, 0x0000004a, 0x0000080a, + 0x00000060, 0x00000590, 0x00001020 }), + new DvInfo(1, 49, 0, 58, 9, new int[] { 0x18000000, 0xb800000a, + 0xc8000010, 0x2c000010, 0xf4000014, 0xb4000008, 0x08000000, + 0x9800000c, 0xd8000010, 0x08000010, 0xb8000010, 0x98000000, + 0x60000000, 0x00000008, 0xc0000000, 0x90000014, 0x10000010, + 0xb8000014, 0x28000000, 0x20000010, 0x48000000, 0x08000018, + 0x60000000, 0x90000010, 0xf0000010, 0x90000008, 0xc0000000, + 0x90000010, 0xf0000010, 0xb0000008, 0x40000000, 0x90000000, + 0xf0000010, 0x90000018, 0x60000000, 0x90000010, 0x90000010, + 0x90000000, 0x80000000, 0x00000010, 0xa0000000, 0x20000000, + 0xa0000000, 0x20000010, 0x00000000, 0x20000010, 0x20000000, + 0x00000010, 0x20000000, 0x00000010, 0xa0000000, 0x00000000, + 0x20000000, 0x20000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000001, 0x00000020, 0x00000001, + 0x40000002, 0x40000040, 0x40000002, 0x80000004, 0x80000080, + 0x80000006, 0x00000049, 0x00000103, 0x80000009, 0x80000012, + 0x80000202, 0x00000018, 0x00000164 }), + new DvInfo(1, 49, 2, 58, 10, new int[] { 0x60000000, 0xe000002a, + 0x20000043, 0xb0000040, 0xd0000053, 0xd0000022, 0x20000000, + 0x60000032, 0x60000043, 0x20000040, 0xe0000042, 0x60000002, + 0x80000001, 0x00000020, 0x00000003, 0x40000052, 0x40000040, + 0xe0000052, 0xa0000000, 0x80000040, 0x20000001, 0x20000060, + 0x80000001, 0x40000042, 0xc0000043, 0x40000022, 0x00000003, + 0x40000042, 0xc0000043, 0xc0000022, 0x00000001, 0x40000002, + 0xc0000043, 0x40000062, 0x80000001, 0x40000042, 0x40000042, + 0x40000002, 0x00000002, 0x00000040, 0x80000002, 0x80000000, + 0x80000002, 0x80000040, 0x00000000, 0x80000040, 0x80000000, + 0x00000040, 0x80000000, 0x00000040, 0x80000002, 0x00000000, + 0x80000000, 0x80000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000004, 0x00000080, 0x00000004, + 0x00000009, 0x00000101, 0x00000009, 0x00000012, 0x00000202, + 0x0000001a, 0x00000124, 0x0000040c, 0x00000026, 0x0000004a, + 0x0000080a, 0x00000060, 0x00000590 }), + new DvInfo(1, 50, 0, 65, 11, new int[] { 0x0800000c, 0x18000000, + 0xb800000a, 0xc8000010, 0x2c000010, 0xf4000014, 0xb4000008, + 0x08000000, 0x9800000c, 0xd8000010, 0x08000010, 0xb8000010, + 0x98000000, 0x60000000, 0x00000008, 0xc0000000, 0x90000014, + 0x10000010, 0xb8000014, 0x28000000, 0x20000010, 0x48000000, + 0x08000018, 0x60000000, 0x90000010, 0xf0000010, 0x90000008, + 0xc0000000, 0x90000010, 0xf0000010, 0xb0000008, 0x40000000, + 0x90000000, 0xf0000010, 0x90000018, 0x60000000, 0x90000010, + 0x90000010, 0x90000000, 0x80000000, 0x00000010, 0xa0000000, + 0x20000000, 0xa0000000, 0x20000010, 0x00000000, 0x20000010, + 0x20000000, 0x00000010, 0x20000000, 0x00000010, 0xa0000000, + 0x00000000, 0x20000000, 0x20000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000001, 0x00000020, + 0x00000001, 0x40000002, 0x40000040, 0x40000002, 0x80000004, + 0x80000080, 0x80000006, 0x00000049, 0x00000103, 0x80000009, + 0x80000012, 0x80000202, 0x00000018 }), + new DvInfo(1, 50, 2, 65, 12, new int[] { 0x20000030, 0x60000000, + 0xe000002a, 0x20000043, 0xb0000040, 0xd0000053, 0xd0000022, + 0x20000000, 0x60000032, 0x60000043, 0x20000040, 0xe0000042, + 0x60000002, 0x80000001, 0x00000020, 0x00000003, 0x40000052, + 0x40000040, 0xe0000052, 0xa0000000, 0x80000040, 0x20000001, + 0x20000060, 0x80000001, 0x40000042, 0xc0000043, 0x40000022, + 0x00000003, 0x40000042, 0xc0000043, 0xc0000022, 0x00000001, + 0x40000002, 0xc0000043, 0x40000062, 0x80000001, 0x40000042, + 0x40000042, 0x40000002, 0x00000002, 0x00000040, 0x80000002, + 0x80000000, 0x80000002, 0x80000040, 0x00000000, 0x80000040, + 0x80000000, 0x00000040, 0x80000000, 0x00000040, 0x80000002, + 0x00000000, 0x80000000, 0x80000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000004, 0x00000080, + 0x00000004, 0x00000009, 0x00000101, 0x00000009, 0x00000012, + 0x00000202, 0x0000001a, 0x00000124, 0x0000040c, 0x00000026, + 0x0000004a, 0x0000080a, 0x00000060 }), + new DvInfo(1, 51, 0, 65, 13, new int[] { 0xe8000000, 0x0800000c, + 0x18000000, 0xb800000a, 0xc8000010, 0x2c000010, 0xf4000014, + 0xb4000008, 0x08000000, 0x9800000c, 0xd8000010, 0x08000010, + 0xb8000010, 0x98000000, 0x60000000, 0x00000008, 0xc0000000, + 0x90000014, 0x10000010, 0xb8000014, 0x28000000, 0x20000010, + 0x48000000, 0x08000018, 0x60000000, 0x90000010, 0xf0000010, + 0x90000008, 0xc0000000, 0x90000010, 0xf0000010, 0xb0000008, + 0x40000000, 0x90000000, 0xf0000010, 0x90000018, 0x60000000, + 0x90000010, 0x90000010, 0x90000000, 0x80000000, 0x00000010, + 0xa0000000, 0x20000000, 0xa0000000, 0x20000010, 0x00000000, + 0x20000010, 0x20000000, 0x00000010, 0x20000000, 0x00000010, + 0xa0000000, 0x00000000, 0x20000000, 0x20000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000001, + 0x00000020, 0x00000001, 0x40000002, 0x40000040, 0x40000002, + 0x80000004, 0x80000080, 0x80000006, 0x00000049, 0x00000103, + 0x80000009, 0x80000012, 0x80000202 }), + new DvInfo(1, 51, 2, 65, 14, new int[] { 0xa0000003, 0x20000030, + 0x60000000, 0xe000002a, 0x20000043, 0xb0000040, 0xd0000053, + 0xd0000022, 0x20000000, 0x60000032, 0x60000043, 0x20000040, + 0xe0000042, 0x60000002, 0x80000001, 0x00000020, 0x00000003, + 0x40000052, 0x40000040, 0xe0000052, 0xa0000000, 0x80000040, + 0x20000001, 0x20000060, 0x80000001, 0x40000042, 0xc0000043, + 0x40000022, 0x00000003, 0x40000042, 0xc0000043, 0xc0000022, + 0x00000001, 0x40000002, 0xc0000043, 0x40000062, 0x80000001, + 0x40000042, 0x40000042, 0x40000002, 0x00000002, 0x00000040, + 0x80000002, 0x80000000, 0x80000002, 0x80000040, 0x00000000, + 0x80000040, 0x80000000, 0x00000040, 0x80000000, 0x00000040, + 0x80000002, 0x00000000, 0x80000000, 0x80000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000004, + 0x00000080, 0x00000004, 0x00000009, 0x00000101, 0x00000009, + 0x00000012, 0x00000202, 0x0000001a, 0x00000124, 0x0000040c, + 0x00000026, 0x0000004a, 0x0000080a }), + new DvInfo(1, 52, 0, 65, 15, new int[] { 0x04000010, 0xe8000000, + 0x0800000c, 0x18000000, 0xb800000a, 0xc8000010, 0x2c000010, + 0xf4000014, 0xb4000008, 0x08000000, 0x9800000c, 0xd8000010, + 0x08000010, 0xb8000010, 0x98000000, 0x60000000, 0x00000008, + 0xc0000000, 0x90000014, 0x10000010, 0xb8000014, 0x28000000, + 0x20000010, 0x48000000, 0x08000018, 0x60000000, 0x90000010, + 0xf0000010, 0x90000008, 0xc0000000, 0x90000010, 0xf0000010, + 0xb0000008, 0x40000000, 0x90000000, 0xf0000010, 0x90000018, + 0x60000000, 0x90000010, 0x90000010, 0x90000000, 0x80000000, + 0x00000010, 0xa0000000, 0x20000000, 0xa0000000, 0x20000010, + 0x00000000, 0x20000010, 0x20000000, 0x00000010, 0x20000000, + 0x00000010, 0xa0000000, 0x00000000, 0x20000000, 0x20000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000001, 0x00000020, 0x00000001, 0x40000002, 0x40000040, + 0x40000002, 0x80000004, 0x80000080, 0x80000006, 0x00000049, + 0x00000103, 0x80000009, 0x80000012 }), + new DvInfo(2, 45, 0, 58, 16, new int[] { 0xec000014, 0x0c000002, + 0xc0000010, 0xb400001c, 0x2c000004, 0xbc000018, 0xb0000010, + 0x0000000c, 0xb8000010, 0x08000018, 0x78000010, 0x08000014, + 0x70000010, 0xb800001c, 0xe8000000, 0xb0000004, 0x58000010, + 0xb000000c, 0x48000000, 0xb0000000, 0xb8000010, 0x98000010, + 0xa0000000, 0x00000000, 0x00000000, 0x20000000, 0x80000000, + 0x00000010, 0x00000000, 0x20000010, 0x20000000, 0x00000010, + 0x60000000, 0x00000018, 0xe0000000, 0x90000000, 0x30000010, + 0xb0000000, 0x20000000, 0x20000000, 0xa0000000, 0x00000010, + 0x80000000, 0x20000000, 0x20000000, 0x20000000, 0x80000000, + 0x00000010, 0x00000000, 0x20000010, 0xa0000000, 0x00000000, + 0x20000000, 0x20000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000001, 0x00000020, + 0x00000001, 0x40000002, 0x40000041, 0x40000022, 0x80000005, + 0xc0000082, 0xc0000046, 0x4000004b, 0x80000107, 0x00000089, + 0x00000014, 0x8000024b, 0x0000011b, 0x8000016d, 0x8000041a, + 0x000002e4, 0x80000054, 0x00000967 }), + new DvInfo(2, 46, 0, 58, 17, new int[] { 0x2400001c, 0xec000014, + 0x0c000002, 0xc0000010, 0xb400001c, 0x2c000004, 0xbc000018, + 0xb0000010, 0x0000000c, 0xb8000010, 0x08000018, 0x78000010, + 0x08000014, 0x70000010, 0xb800001c, 0xe8000000, 0xb0000004, + 0x58000010, 0xb000000c, 0x48000000, 0xb0000000, 0xb8000010, + 0x98000010, 0xa0000000, 0x00000000, 0x00000000, 0x20000000, + 0x80000000, 0x00000010, 0x00000000, 0x20000010, 0x20000000, + 0x00000010, 0x60000000, 0x00000018, 0xe0000000, 0x90000000, + 0x30000010, 0xb0000000, 0x20000000, 0x20000000, 0xa0000000, + 0x00000010, 0x80000000, 0x20000000, 0x20000000, 0x20000000, + 0x80000000, 0x00000010, 0x00000000, 0x20000010, 0xa0000000, + 0x00000000, 0x20000000, 0x20000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000001, + 0x00000020, 0x00000001, 0x40000002, 0x40000041, 0x40000022, + 0x80000005, 0xc0000082, 0xc0000046, 0x4000004b, 0x80000107, + 0x00000089, 0x00000014, 0x8000024b, 0x0000011b, 0x8000016d, + 0x8000041a, 0x000002e4, 0x80000054 }), + new DvInfo(2, 46, 2, 58, 18, new int[] { 0x90000070, 0xb0000053, + 0x30000008, 0x00000043, 0xd0000072, 0xb0000010, 0xf0000062, + 0xc0000042, 0x00000030, 0xe0000042, 0x20000060, 0xe0000041, + 0x20000050, 0xc0000041, 0xe0000072, 0xa0000003, 0xc0000012, + 0x60000041, 0xc0000032, 0x20000001, 0xc0000002, 0xe0000042, + 0x60000042, 0x80000002, 0x00000000, 0x00000000, 0x80000000, + 0x00000002, 0x00000040, 0x00000000, 0x80000040, 0x80000000, + 0x00000040, 0x80000001, 0x00000060, 0x80000003, 0x40000002, + 0xc0000040, 0xc0000002, 0x80000000, 0x80000000, 0x80000002, + 0x00000040, 0x00000002, 0x80000000, 0x80000000, 0x80000000, + 0x00000002, 0x00000040, 0x00000000, 0x80000040, 0x80000002, + 0x00000000, 0x80000000, 0x80000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000004, + 0x00000080, 0x00000004, 0x00000009, 0x00000105, 0x00000089, + 0x00000016, 0x0000020b, 0x0000011b, 0x0000012d, 0x0000041e, + 0x00000224, 0x00000050, 0x0000092e, 0x0000046c, 0x000005b6, + 0x0000106a, 0x00000b90, 0x00000152 }), + new DvInfo(2, 47, 0, 58, 19, new int[] { 0x20000010, 0x2400001c, + 0xec000014, 0x0c000002, 0xc0000010, 0xb400001c, 0x2c000004, + 0xbc000018, 0xb0000010, 0x0000000c, 0xb8000010, 0x08000018, + 0x78000010, 0x08000014, 0x70000010, 0xb800001c, 0xe8000000, + 0xb0000004, 0x58000010, 0xb000000c, 0x48000000, 0xb0000000, + 0xb8000010, 0x98000010, 0xa0000000, 0x00000000, 0x00000000, + 0x20000000, 0x80000000, 0x00000010, 0x00000000, 0x20000010, + 0x20000000, 0x00000010, 0x60000000, 0x00000018, 0xe0000000, + 0x90000000, 0x30000010, 0xb0000000, 0x20000000, 0x20000000, + 0xa0000000, 0x00000010, 0x80000000, 0x20000000, 0x20000000, + 0x20000000, 0x80000000, 0x00000010, 0x00000000, 0x20000010, + 0xa0000000, 0x00000000, 0x20000000, 0x20000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000001, 0x00000020, 0x00000001, 0x40000002, 0x40000041, + 0x40000022, 0x80000005, 0xc0000082, 0xc0000046, 0x4000004b, + 0x80000107, 0x00000089, 0x00000014, 0x8000024b, 0x0000011b, + 0x8000016d, 0x8000041a, 0x000002e4 }), + new DvInfo(2, 48, 0, 58, 20, new int[] { 0xbc00001a, 0x20000010, + 0x2400001c, 0xec000014, 0x0c000002, 0xc0000010, 0xb400001c, + 0x2c000004, 0xbc000018, 0xb0000010, 0x0000000c, 0xb8000010, + 0x08000018, 0x78000010, 0x08000014, 0x70000010, 0xb800001c, + 0xe8000000, 0xb0000004, 0x58000010, 0xb000000c, 0x48000000, + 0xb0000000, 0xb8000010, 0x98000010, 0xa0000000, 0x00000000, + 0x00000000, 0x20000000, 0x80000000, 0x00000010, 0x00000000, + 0x20000010, 0x20000000, 0x00000010, 0x60000000, 0x00000018, + 0xe0000000, 0x90000000, 0x30000010, 0xb0000000, 0x20000000, + 0x20000000, 0xa0000000, 0x00000010, 0x80000000, 0x20000000, + 0x20000000, 0x20000000, 0x80000000, 0x00000010, 0x00000000, + 0x20000010, 0xa0000000, 0x00000000, 0x20000000, 0x20000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000001, 0x00000020, 0x00000001, 0x40000002, + 0x40000041, 0x40000022, 0x80000005, 0xc0000082, 0xc0000046, + 0x4000004b, 0x80000107, 0x00000089, 0x00000014, 0x8000024b, + 0x0000011b, 0x8000016d, 0x8000041a }), + new DvInfo(2, 49, 0, 58, 21, new int[] { 0x3c000004, 0xbc00001a, + 0x20000010, 0x2400001c, 0xec000014, 0x0c000002, 0xc0000010, + 0xb400001c, 0x2c000004, 0xbc000018, 0xb0000010, 0x0000000c, + 0xb8000010, 0x08000018, 0x78000010, 0x08000014, 0x70000010, + 0xb800001c, 0xe8000000, 0xb0000004, 0x58000010, 0xb000000c, + 0x48000000, 0xb0000000, 0xb8000010, 0x98000010, 0xa0000000, + 0x00000000, 0x00000000, 0x20000000, 0x80000000, 0x00000010, + 0x00000000, 0x20000010, 0x20000000, 0x00000010, 0x60000000, + 0x00000018, 0xe0000000, 0x90000000, 0x30000010, 0xb0000000, + 0x20000000, 0x20000000, 0xa0000000, 0x00000010, 0x80000000, + 0x20000000, 0x20000000, 0x20000000, 0x80000000, 0x00000010, + 0x00000000, 0x20000010, 0xa0000000, 0x00000000, 0x20000000, + 0x20000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000001, 0x00000020, 0x00000001, + 0x40000002, 0x40000041, 0x40000022, 0x80000005, 0xc0000082, + 0xc0000046, 0x4000004b, 0x80000107, 0x00000089, 0x00000014, + 0x8000024b, 0x0000011b, 0x8000016d }), + new DvInfo(2, 49, 2, 58, 22, new int[] { 0xf0000010, 0xf000006a, + 0x80000040, 0x90000070, 0xb0000053, 0x30000008, 0x00000043, + 0xd0000072, 0xb0000010, 0xf0000062, 0xc0000042, 0x00000030, + 0xe0000042, 0x20000060, 0xe0000041, 0x20000050, 0xc0000041, + 0xe0000072, 0xa0000003, 0xc0000012, 0x60000041, 0xc0000032, + 0x20000001, 0xc0000002, 0xe0000042, 0x60000042, 0x80000002, + 0x00000000, 0x00000000, 0x80000000, 0x00000002, 0x00000040, + 0x00000000, 0x80000040, 0x80000000, 0x00000040, 0x80000001, + 0x00000060, 0x80000003, 0x40000002, 0xc0000040, 0xc0000002, + 0x80000000, 0x80000000, 0x80000002, 0x00000040, 0x00000002, + 0x80000000, 0x80000000, 0x80000000, 0x00000002, 0x00000040, + 0x00000000, 0x80000040, 0x80000002, 0x00000000, 0x80000000, + 0x80000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000004, 0x00000080, 0x00000004, + 0x00000009, 0x00000105, 0x00000089, 0x00000016, 0x0000020b, + 0x0000011b, 0x0000012d, 0x0000041e, 0x00000224, 0x00000050, + 0x0000092e, 0x0000046c, 0x000005b6 }), + new DvInfo(2, 50, 0, 65, 23, new int[] { 0xb400001c, 0x3c000004, + 0xbc00001a, 0x20000010, 0x2400001c, 0xec000014, 0x0c000002, + 0xc0000010, 0xb400001c, 0x2c000004, 0xbc000018, 0xb0000010, + 0x0000000c, 0xb8000010, 0x08000018, 0x78000010, 0x08000014, + 0x70000010, 0xb800001c, 0xe8000000, 0xb0000004, 0x58000010, + 0xb000000c, 0x48000000, 0xb0000000, 0xb8000010, 0x98000010, + 0xa0000000, 0x00000000, 0x00000000, 0x20000000, 0x80000000, + 0x00000010, 0x00000000, 0x20000010, 0x20000000, 0x00000010, + 0x60000000, 0x00000018, 0xe0000000, 0x90000000, 0x30000010, + 0xb0000000, 0x20000000, 0x20000000, 0xa0000000, 0x00000010, + 0x80000000, 0x20000000, 0x20000000, 0x20000000, 0x80000000, + 0x00000010, 0x00000000, 0x20000010, 0xa0000000, 0x00000000, + 0x20000000, 0x20000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000001, 0x00000020, + 0x00000001, 0x40000002, 0x40000041, 0x40000022, 0x80000005, + 0xc0000082, 0xc0000046, 0x4000004b, 0x80000107, 0x00000089, + 0x00000014, 0x8000024b, 0x0000011b }), + new DvInfo(2, 50, 2, 65, 24, new int[] { 0xd0000072, 0xf0000010, + 0xf000006a, 0x80000040, 0x90000070, 0xb0000053, 0x30000008, + 0x00000043, 0xd0000072, 0xb0000010, 0xf0000062, 0xc0000042, + 0x00000030, 0xe0000042, 0x20000060, 0xe0000041, 0x20000050, + 0xc0000041, 0xe0000072, 0xa0000003, 0xc0000012, 0x60000041, + 0xc0000032, 0x20000001, 0xc0000002, 0xe0000042, 0x60000042, + 0x80000002, 0x00000000, 0x00000000, 0x80000000, 0x00000002, + 0x00000040, 0x00000000, 0x80000040, 0x80000000, 0x00000040, + 0x80000001, 0x00000060, 0x80000003, 0x40000002, 0xc0000040, + 0xc0000002, 0x80000000, 0x80000000, 0x80000002, 0x00000040, + 0x00000002, 0x80000000, 0x80000000, 0x80000000, 0x00000002, + 0x00000040, 0x00000000, 0x80000040, 0x80000002, 0x00000000, + 0x80000000, 0x80000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000004, 0x00000080, + 0x00000004, 0x00000009, 0x00000105, 0x00000089, 0x00000016, + 0x0000020b, 0x0000011b, 0x0000012d, 0x0000041e, 0x00000224, + 0x00000050, 0x0000092e, 0x0000046c }), + new DvInfo(2, 51, 0, 65, 25, new int[] { 0xc0000010, 0xb400001c, + 0x3c000004, 0xbc00001a, 0x20000010, 0x2400001c, 0xec000014, + 0x0c000002, 0xc0000010, 0xb400001c, 0x2c000004, 0xbc000018, + 0xb0000010, 0x0000000c, 0xb8000010, 0x08000018, 0x78000010, + 0x08000014, 0x70000010, 0xb800001c, 0xe8000000, 0xb0000004, + 0x58000010, 0xb000000c, 0x48000000, 0xb0000000, 0xb8000010, + 0x98000010, 0xa0000000, 0x00000000, 0x00000000, 0x20000000, + 0x80000000, 0x00000010, 0x00000000, 0x20000010, 0x20000000, + 0x00000010, 0x60000000, 0x00000018, 0xe0000000, 0x90000000, + 0x30000010, 0xb0000000, 0x20000000, 0x20000000, 0xa0000000, + 0x00000010, 0x80000000, 0x20000000, 0x20000000, 0x20000000, + 0x80000000, 0x00000010, 0x00000000, 0x20000010, 0xa0000000, + 0x00000000, 0x20000000, 0x20000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000001, + 0x00000020, 0x00000001, 0x40000002, 0x40000041, 0x40000022, + 0x80000005, 0xc0000082, 0xc0000046, 0x4000004b, 0x80000107, + 0x00000089, 0x00000014, 0x8000024b }), + new DvInfo(2, 51, 2, 65, 26, new int[] { 0x00000043, 0xd0000072, + 0xf0000010, 0xf000006a, 0x80000040, 0x90000070, 0xb0000053, + 0x30000008, 0x00000043, 0xd0000072, 0xb0000010, 0xf0000062, + 0xc0000042, 0x00000030, 0xe0000042, 0x20000060, 0xe0000041, + 0x20000050, 0xc0000041, 0xe0000072, 0xa0000003, 0xc0000012, + 0x60000041, 0xc0000032, 0x20000001, 0xc0000002, 0xe0000042, + 0x60000042, 0x80000002, 0x00000000, 0x00000000, 0x80000000, + 0x00000002, 0x00000040, 0x00000000, 0x80000040, 0x80000000, + 0x00000040, 0x80000001, 0x00000060, 0x80000003, 0x40000002, + 0xc0000040, 0xc0000002, 0x80000000, 0x80000000, 0x80000002, + 0x00000040, 0x00000002, 0x80000000, 0x80000000, 0x80000000, + 0x00000002, 0x00000040, 0x00000000, 0x80000040, 0x80000002, + 0x00000000, 0x80000000, 0x80000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000004, + 0x00000080, 0x00000004, 0x00000009, 0x00000105, 0x00000089, + 0x00000016, 0x0000020b, 0x0000011b, 0x0000012d, 0x0000041e, + 0x00000224, 0x00000050, 0x0000092e }), + new DvInfo(2, 52, 0, 65, 27, new int[] { 0x0c000002, 0xc0000010, + 0xb400001c, 0x3c000004, 0xbc00001a, 0x20000010, 0x2400001c, + 0xec000014, 0x0c000002, 0xc0000010, 0xb400001c, 0x2c000004, + 0xbc000018, 0xb0000010, 0x0000000c, 0xb8000010, 0x08000018, + 0x78000010, 0x08000014, 0x70000010, 0xb800001c, 0xe8000000, + 0xb0000004, 0x58000010, 0xb000000c, 0x48000000, 0xb0000000, + 0xb8000010, 0x98000010, 0xa0000000, 0x00000000, 0x00000000, + 0x20000000, 0x80000000, 0x00000010, 0x00000000, 0x20000010, + 0x20000000, 0x00000010, 0x60000000, 0x00000018, 0xe0000000, + 0x90000000, 0x30000010, 0xb0000000, 0x20000000, 0x20000000, + 0xa0000000, 0x00000010, 0x80000000, 0x20000000, 0x20000000, + 0x20000000, 0x80000000, 0x00000010, 0x00000000, 0x20000010, + 0xa0000000, 0x00000000, 0x20000000, 0x20000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000001, 0x00000020, 0x00000001, 0x40000002, 0x40000041, + 0x40000022, 0x80000005, 0xc0000082, 0xc0000046, 0x4000004b, + 0x80000107, 0x00000089, 0x00000014 }), + new DvInfo(2, 53, 0, 65, 28, new int[] { 0xcc000014, 0x0c000002, + 0xc0000010, 0xb400001c, 0x3c000004, 0xbc00001a, 0x20000010, + 0x2400001c, 0xec000014, 0x0c000002, 0xc0000010, 0xb400001c, + 0x2c000004, 0xbc000018, 0xb0000010, 0x0000000c, 0xb8000010, + 0x08000018, 0x78000010, 0x08000014, 0x70000010, 0xb800001c, + 0xe8000000, 0xb0000004, 0x58000010, 0xb000000c, 0x48000000, + 0xb0000000, 0xb8000010, 0x98000010, 0xa0000000, 0x00000000, + 0x00000000, 0x20000000, 0x80000000, 0x00000010, 0x00000000, + 0x20000010, 0x20000000, 0x00000010, 0x60000000, 0x00000018, + 0xe0000000, 0x90000000, 0x30000010, 0xb0000000, 0x20000000, + 0x20000000, 0xa0000000, 0x00000010, 0x80000000, 0x20000000, + 0x20000000, 0x20000000, 0x80000000, 0x00000010, 0x00000000, + 0x20000010, 0xa0000000, 0x00000000, 0x20000000, 0x20000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000001, 0x00000020, 0x00000001, 0x40000002, + 0x40000041, 0x40000022, 0x80000005, 0xc0000082, 0xc0000046, + 0x4000004b, 0x80000107, 0x00000089 }), + new DvInfo(2, 54, 0, 65, 29, new int[] { 0x0400001c, 0xcc000014, + 0x0c000002, 0xc0000010, 0xb400001c, 0x3c000004, 0xbc00001a, + 0x20000010, 0x2400001c, 0xec000014, 0x0c000002, 0xc0000010, + 0xb400001c, 0x2c000004, 0xbc000018, 0xb0000010, 0x0000000c, + 0xb8000010, 0x08000018, 0x78000010, 0x08000014, 0x70000010, + 0xb800001c, 0xe8000000, 0xb0000004, 0x58000010, 0xb000000c, + 0x48000000, 0xb0000000, 0xb8000010, 0x98000010, 0xa0000000, + 0x00000000, 0x00000000, 0x20000000, 0x80000000, 0x00000010, + 0x00000000, 0x20000010, 0x20000000, 0x00000010, 0x60000000, + 0x00000018, 0xe0000000, 0x90000000, 0x30000010, 0xb0000000, + 0x20000000, 0x20000000, 0xa0000000, 0x00000010, 0x80000000, + 0x20000000, 0x20000000, 0x20000000, 0x80000000, 0x00000010, + 0x00000000, 0x20000010, 0xa0000000, 0x00000000, 0x20000000, + 0x20000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000001, 0x00000020, 0x00000001, + 0x40000002, 0x40000041, 0x40000022, 0x80000005, 0xc0000082, + 0xc0000046, 0x4000004b, 0x80000107 }), + new DvInfo(2, 55, 0, 65, 30, new int[] { 0x00000010, 0x0400001c, + 0xcc000014, 0x0c000002, 0xc0000010, 0xb400001c, 0x3c000004, + 0xbc00001a, 0x20000010, 0x2400001c, 0xec000014, 0x0c000002, + 0xc0000010, 0xb400001c, 0x2c000004, 0xbc000018, 0xb0000010, + 0x0000000c, 0xb8000010, 0x08000018, 0x78000010, 0x08000014, + 0x70000010, 0xb800001c, 0xe8000000, 0xb0000004, 0x58000010, + 0xb000000c, 0x48000000, 0xb0000000, 0xb8000010, 0x98000010, + 0xa0000000, 0x00000000, 0x00000000, 0x20000000, 0x80000000, + 0x00000010, 0x00000000, 0x20000010, 0x20000000, 0x00000010, + 0x60000000, 0x00000018, 0xe0000000, 0x90000000, 0x30000010, + 0xb0000000, 0x20000000, 0x20000000, 0xa0000000, 0x00000010, + 0x80000000, 0x20000000, 0x20000000, 0x20000000, 0x80000000, + 0x00000010, 0x00000000, 0x20000010, 0xa0000000, 0x00000000, + 0x20000000, 0x20000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000001, 0x00000020, + 0x00000001, 0x40000002, 0x40000041, 0x40000022, 0x80000005, + 0xc0000082, 0xc0000046, 0x4000004b }), + new DvInfo(2, 56, 0, 65, 31, new int[] { 0x2600001a, 0x00000010, + 0x0400001c, 0xcc000014, 0x0c000002, 0xc0000010, 0xb400001c, + 0x3c000004, 0xbc00001a, 0x20000010, 0x2400001c, 0xec000014, + 0x0c000002, 0xc0000010, 0xb400001c, 0x2c000004, 0xbc000018, + 0xb0000010, 0x0000000c, 0xb8000010, 0x08000018, 0x78000010, + 0x08000014, 0x70000010, 0xb800001c, 0xe8000000, 0xb0000004, + 0x58000010, 0xb000000c, 0x48000000, 0xb0000000, 0xb8000010, + 0x98000010, 0xa0000000, 0x00000000, 0x00000000, 0x20000000, + 0x80000000, 0x00000010, 0x00000000, 0x20000010, 0x20000000, + 0x00000010, 0x60000000, 0x00000018, 0xe0000000, 0x90000000, + 0x30000010, 0xb0000000, 0x20000000, 0x20000000, 0xa0000000, + 0x00000010, 0x80000000, 0x20000000, 0x20000000, 0x20000000, + 0x80000000, 0x00000010, 0x00000000, 0x20000010, 0xa0000000, + 0x00000000, 0x20000000, 0x20000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000001, + 0x00000020, 0x00000001, 0x40000002, 0x40000041, 0x40000022, + 0x80000005, 0xc0000082, 0xc0000046 }), }; + + static { + // Assert the DV array is indexed by maskb; that is DV block using + // maskb = N must be at array index N. + for (int i = 0; i < DV.length; i++) { + if (i != DV[i].maskb) { + throw new IllegalStateException("must be indexed by maskb"); //$NON-NLS-1$ + } + } + } +}
diff --git a/pom.xml b/pom.xml index 588f364..8584f0f 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>4.6.2-SNAPSHOT</version> + <version>4.7.6-SNAPSHOT</version> <name>JGit - Parent</name> <url>${jgit-url}</url> @@ -191,8 +191,8 @@ <maven.build.timestamp.format>yyyyMMddHHmm</maven.build.timestamp.format> <bundle-manifest>${project.build.directory}/META-INF/MANIFEST.MF</bundle-manifest> - <jgit-last-release-version>4.2.0.201601211800-r</jgit-last-release-version> - <jsch-version>0.1.53</jsch-version> + <jgit-last-release-version>4.6.0.201612231935-r</jgit-last-release-version> + <jsch-version>0.1.54</jsch-version> <javaewah-version>1.1.6</javaewah-version> <junit-version>4.12</junit-version> <test-fork-count>1C</test-fork-count> @@ -259,7 +259,7 @@ <plugin> <artifactId>maven-compiler-plugin</artifactId> - <version>3.6.0</version> + <version>3.6.1</version> <configuration> <encoding>UTF-8</encoding> <source>1.8</source> @@ -309,7 +309,7 @@ <dependency> <groupId>com.google.errorprone</groupId> <artifactId>error_prone_core</artifactId> - <version>2.0.15</version> + <version>2.0.19</version> </dependency> </dependencies> </plugin> @@ -322,7 +322,7 @@ <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-shade-plugin</artifactId> - <version>2.4.3</version> + <version>3.0.0</version> </plugin> <plugin> @@ -362,7 +362,7 @@ <plugin> <groupId>org.codehaus.mojo</groupId> <artifactId>build-helper-maven-plugin</artifactId> - <version>1.12</version> + <version>3.0.0</version> </plugin> <plugin> @@ -420,7 +420,7 @@ <plugin> <groupId>org.jacoco</groupId> <artifactId>jacoco-maven-plugin</artifactId> - <version>0.7.8</version> + <version>0.7.9</version> </plugin> <plugin> <groupId>org.apache.maven.plugins</groupId>
diff --git a/tools/BUILD b/tools/BUILD new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/tools/BUILD
diff --git a/tools/bazlets.bzl b/tools/bazlets.bzl new file mode 100644 index 0000000..f97b72c --- /dev/null +++ b/tools/bazlets.bzl
@@ -0,0 +1,16 @@ +NAME = "com_googlesource_gerrit_bazlets" + +def load_bazlets( + commit, + local_path = None): + if not local_path: + native.git_repository( + name = NAME, + remote = "https://gerrit.googlesource.com/bazlets", + commit = commit, + ) + else: + native.local_repository( + name = NAME, + path = local_path, + )